X-Git-Url: https://git.openssl.org/gitweb/?a=blobdiff_plain;f=crypto%2Fasn1%2Fa_sign.c;h=de53b441448e4f9d44a07004790105b7a8a006c0;hb=d5492d9b47d4d55052f24c8a04c70a0516ac934d;hp=2925ce3ad3e41f3a9bfcce65dbbfbfb6d5d0bc28;hpb=b7896b3cb86d80206af14a14d69b0717786f2729;p=openssl.git diff --git a/crypto/asn1/a_sign.c b/crypto/asn1/a_sign.c index 2925ce3ad3..de53b44144 100644 --- a/crypto/asn1/a_sign.c +++ b/crypto/asn1/a_sign.c @@ -1,5 +1,5 @@ /* crypto/asn1/a_sign.c */ -/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * * This package is an SSL implementation written @@ -55,34 +55,87 @@ * copied and put under another distribution licence * [including the GNU Public Licence.] */ +/* ==================================================================== + * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ #include #include -#include -#include #include "cryptlib.h" -#include "bn.h" -#include "evp.h" -#include "x509.h" -#include "objects.h" -#include "buffer.h" -#include "pem.h" -int ASN1_sign(i2d,algor1,algor2,signature,data,pkey,type) -int (*i2d)(); -X509_ALGOR *algor1; -X509_ALGOR *algor2; -ASN1_BIT_STRING *signature; -char *data; -EVP_PKEY *pkey; -EVP_MD *type; +#ifndef NO_SYS_TYPES_H +# include +#endif + +#include +#include +#include +#include +#include + +#ifndef NO_ASN1_OLD + +int ASN1_sign(int (*i2d)(), X509_ALGOR *algor1, X509_ALGOR *algor2, + ASN1_BIT_STRING *signature, char *data, EVP_PKEY *pkey, + const EVP_MD *type) { EVP_MD_CTX ctx; unsigned char *p,*buf_in=NULL,*buf_out=NULL; int i,inl=0,outl=0,outll=0; X509_ALGOR *a; + EVP_MD_CTX_init(&ctx); for (i=0; i<2; i++) { if (i == 0) @@ -90,7 +143,14 @@ EVP_MD *type; else a=algor2; if (a == NULL) continue; - if ( (a->parameter == NULL) || + if (type->pkey_type == NID_dsaWithSHA1) + { + /* special case: RFC 2459 tells us to omit 'parameters' + * with id-dsa-with-sha1 */ + ASN1_TYPE_free(a->parameter); + a->parameter = NULL; + } + else if ((a->parameter == NULL) || (a->parameter->type != V_ASN1_NULL)) { ASN1_TYPE_free(a->parameter); @@ -111,9 +171,9 @@ EVP_MD *type; } } inl=i2d(data,NULL); - buf_in=(unsigned char *)Malloc((unsigned int)inl); + buf_in=(unsigned char *)OPENSSL_malloc((unsigned int)inl); outll=outl=EVP_PKEY_size(pkey); - buf_out=(unsigned char *)Malloc((unsigned int)outl); + buf_out=(unsigned char *)OPENSSL_malloc((unsigned int)outl); if ((buf_in == NULL) || (buf_out == NULL)) { outl=0; @@ -123,7 +183,7 @@ EVP_MD *type; p=buf_in; i2d(data,&p); - EVP_SignInit(&ctx,type); + EVP_SignInit_ex(&ctx,type, NULL); EVP_SignUpdate(&ctx,(unsigned char *)buf_in,inl); if (!EVP_SignFinal(&ctx,(unsigned char *)buf_out, (unsigned int *)&outl,pkey)) @@ -132,16 +192,103 @@ EVP_MD *type; ASN1err(ASN1_F_ASN1_SIGN,ERR_R_EVP_LIB); goto err; } - if (signature->data != NULL) Free((char *)signature->data); + if (signature->data != NULL) OPENSSL_free(signature->data); signature->data=buf_out; buf_out=NULL; signature->length=outl; + /* In the interests of compatibility, I'll make sure that + * the bit string has a 'not-used bits' value of 0 + */ + signature->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07); + signature->flags|=ASN1_STRING_FLAG_BITS_LEFT; +err: + EVP_MD_CTX_cleanup(&ctx); + if (buf_in != NULL) + { memset((char *)buf_in,0,(unsigned int)inl); OPENSSL_free(buf_in); } + if (buf_out != NULL) + { memset((char *)buf_out,0,outll); OPENSSL_free(buf_out); } + return(outl); + } + +#endif + +int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2, + ASN1_BIT_STRING *signature, void *asn, EVP_PKEY *pkey, + const EVP_MD *type) + { + EVP_MD_CTX ctx; + unsigned char *buf_in=NULL,*buf_out=NULL; + int i,inl=0,outl=0,outll=0; + X509_ALGOR *a; + + EVP_MD_CTX_init(&ctx); + for (i=0; i<2; i++) + { + if (i == 0) + a=algor1; + else + a=algor2; + if (a == NULL) continue; + if (type->pkey_type == NID_dsaWithSHA1) + { + /* special case: RFC 2459 tells us to omit 'parameters' + * with id-dsa-with-sha1 */ + ASN1_TYPE_free(a->parameter); + a->parameter = NULL; + } + else if ((a->parameter == NULL) || + (a->parameter->type != V_ASN1_NULL)) + { + ASN1_TYPE_free(a->parameter); + if ((a->parameter=ASN1_TYPE_new()) == NULL) goto err; + a->parameter->type=V_ASN1_NULL; + } + ASN1_OBJECT_free(a->algorithm); + a->algorithm=OBJ_nid2obj(type->pkey_type); + if (a->algorithm == NULL) + { + ASN1err(ASN1_F_ASN1_SIGN,ASN1_R_UNKNOWN_OBJECT_TYPE); + goto err; + } + if (a->algorithm->length == 0) + { + ASN1err(ASN1_F_ASN1_SIGN,ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD); + goto err; + } + } + inl=ASN1_item_i2d(asn,&buf_in, it); + outll=outl=EVP_PKEY_size(pkey); + buf_out=(unsigned char *)OPENSSL_malloc((unsigned int)outl); + if ((buf_in == NULL) || (buf_out == NULL)) + { + outl=0; + ASN1err(ASN1_F_ASN1_SIGN,ERR_R_MALLOC_FAILURE); + goto err; + } + EVP_SignInit_ex(&ctx,type, NULL); + EVP_SignUpdate(&ctx,(unsigned char *)buf_in,inl); + if (!EVP_SignFinal(&ctx,(unsigned char *)buf_out, + (unsigned int *)&outl,pkey)) + { + outl=0; + ASN1err(ASN1_F_ASN1_SIGN,ERR_R_EVP_LIB); + goto err; + } + if (signature->data != NULL) OPENSSL_free(signature->data); + signature->data=buf_out; + buf_out=NULL; + signature->length=outl; + /* In the interests of compatibility, I'll make sure that + * the bit string has a 'not-used bits' value of 0 + */ + signature->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07); + signature->flags|=ASN1_STRING_FLAG_BITS_LEFT; err: - memset(&ctx,0,sizeof(ctx)); + EVP_MD_CTX_cleanup(&ctx); if (buf_in != NULL) - { memset((char *)buf_in,0,(unsigned int)inl); Free((char *)buf_in); } + { memset((char *)buf_in,0,(unsigned int)inl); OPENSSL_free(buf_in); } if (buf_out != NULL) - { memset((char *)buf_out,0,outll); Free((char *)buf_out); } + { memset((char *)buf_out,0,outll); OPENSSL_free(buf_out); } return(outl); }