X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=crypto%2Fasn1%2Fa_sign.c;h=ff63bfc7be9427181a86e8c5c133409d0ceecfaa;hp=9ae9370c04755f22f1d13fb00167699131216afa;hb=03919683f9bade36ef1b58e64638ac3ccbbf371a;hpb=f33fbc2e1e64a202476c29080636ee989871e7f7 diff --git a/crypto/asn1/a_sign.c b/crypto/asn1/a_sign.c index 9ae9370c04..ff63bfc7be 100644 --- a/crypto/asn1/a_sign.c +++ b/crypto/asn1/a_sign.c @@ -55,33 +55,88 @@ * copied and put under another distribution licence * [including the GNU Public Licence.] */ +/* ==================================================================== + * Copyright (c) 1998-2003 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" - -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 +#include "asn1_locl.h" + +#ifndef NO_ASN1_OLD + +int ASN1_sign(i2d_of_void *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) @@ -89,7 +144,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); @@ -110,9 +172,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; @@ -122,7 +184,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)) @@ -131,20 +193,106 @@ 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) + { OPENSSL_cleanse((char *)buf_in,(unsigned int)inl); OPENSSL_free(buf_in); } + if (buf_out != NULL) + { OPENSSL_cleanse((char *)buf_out,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 inl=0,outl=0,outll=0; + int signid, paramtype; + + if (type == NULL) + { + int def_nid; + if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) > 0) + type = EVP_get_digestbynid(def_nid); + } + + if (type == NULL) + { + ASN1err(ASN1_F_ASN1_ITEM_SIGN, ASN1_R_NO_DEFAULT_DIGEST); + return 0; + } + + if (type->flags & EVP_MD_FLAG_PKEY_METHOD_SIGNATURE) + { + if (!pkey->ameth || + !OBJ_find_sigid_by_algs(&signid, EVP_MD_nid(type), + pkey->ameth->pkey_id)) + { + ASN1err(ASN1_F_ASN1_ITEM_SIGN, + ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED); + return 0; + } + } + else + signid = type->pkey_type; + + if (pkey->ameth->pkey_flags & ASN1_PKEY_SIGPARAM_NULL) + paramtype = V_ASN1_NULL; + else + paramtype = V_ASN1_UNDEF; + + if (algor1) + X509_ALGOR_set0(algor1, OBJ_nid2obj(signid), paramtype, NULL); + if (algor2) + X509_ALGOR_set0(algor2, OBJ_nid2obj(signid), paramtype, NULL); + + EVP_MD_CTX_init(&ctx); + 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_ITEM_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_ITEM_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 compatability, I'll make sure that + /* 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); } + { OPENSSL_cleanse((char *)buf_in,(unsigned int)inl); OPENSSL_free(buf_in); } if (buf_out != NULL) - { memset((char *)buf_out,0,outll); Free((char *)buf_out); } + { OPENSSL_cleanse((char *)buf_out,outll); OPENSSL_free(buf_out); } return(outl); }