a_sign.c revision 109998
155714Skris/* crypto/asn1/a_sign.c */ 255714Skris/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 355714Skris * All rights reserved. 455714Skris * 555714Skris * This package is an SSL implementation written 655714Skris * by Eric Young (eay@cryptsoft.com). 755714Skris * The implementation was written so as to conform with Netscapes SSL. 855714Skris * 955714Skris * This library is free for commercial and non-commercial use as long as 1055714Skris * the following conditions are aheared to. The following conditions 1155714Skris * apply to all code found in this distribution, be it the RC4, RSA, 1255714Skris * lhash, DES, etc., code; not just the SSL code. The SSL documentation 1355714Skris * included with this distribution is covered by the same copyright terms 1455714Skris * except that the holder is Tim Hudson (tjh@cryptsoft.com). 1555714Skris * 1655714Skris * Copyright remains Eric Young's, and as such any Copyright notices in 1755714Skris * the code are not to be removed. 1855714Skris * If this package is used in a product, Eric Young should be given attribution 1955714Skris * as the author of the parts of the library used. 2055714Skris * This can be in the form of a textual message at program startup or 2155714Skris * in documentation (online or textual) provided with the package. 2255714Skris * 2355714Skris * Redistribution and use in source and binary forms, with or without 2455714Skris * modification, are permitted provided that the following conditions 2555714Skris * are met: 2655714Skris * 1. Redistributions of source code must retain the copyright 2755714Skris * notice, this list of conditions and the following disclaimer. 2855714Skris * 2. Redistributions in binary form must reproduce the above copyright 2955714Skris * notice, this list of conditions and the following disclaimer in the 3055714Skris * documentation and/or other materials provided with the distribution. 3155714Skris * 3. All advertising materials mentioning features or use of this software 3255714Skris * must display the following acknowledgement: 3355714Skris * "This product includes cryptographic software written by 3455714Skris * Eric Young (eay@cryptsoft.com)" 3555714Skris * The word 'cryptographic' can be left out if the rouines from the library 3655714Skris * being used are not cryptographic related :-). 3755714Skris * 4. If you include any Windows specific code (or a derivative thereof) from 3855714Skris * the apps directory (application code) you must include an acknowledgement: 3955714Skris * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 4055714Skris * 4155714Skris * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 4255714Skris * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 4355714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 4455714Skris * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 4555714Skris * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 4655714Skris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 4755714Skris * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 4855714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 4955714Skris * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 5055714Skris * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 5155714Skris * SUCH DAMAGE. 5255714Skris * 5355714Skris * The licence and distribution terms for any publically available version or 5455714Skris * derivative of this code cannot be changed. i.e. this code cannot simply be 5555714Skris * copied and put under another distribution licence 5655714Skris * [including the GNU Public Licence.] 5755714Skris */ 58100928Snectar/* ==================================================================== 59100928Snectar * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. 60100928Snectar * 61100928Snectar * Redistribution and use in source and binary forms, with or without 62100928Snectar * modification, are permitted provided that the following conditions 63100928Snectar * are met: 64100928Snectar * 65100928Snectar * 1. Redistributions of source code must retain the above copyright 66100928Snectar * notice, this list of conditions and the following disclaimer. 67100928Snectar * 68100928Snectar * 2. Redistributions in binary form must reproduce the above copyright 69100928Snectar * notice, this list of conditions and the following disclaimer in 70100928Snectar * the documentation and/or other materials provided with the 71100928Snectar * distribution. 72100928Snectar * 73100928Snectar * 3. All advertising materials mentioning features or use of this 74100928Snectar * software must display the following acknowledgment: 75100928Snectar * "This product includes software developed by the OpenSSL Project 76100928Snectar * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 77100928Snectar * 78100928Snectar * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 79100928Snectar * endorse or promote products derived from this software without 80100928Snectar * prior written permission. For written permission, please contact 81100928Snectar * openssl-core@openssl.org. 82100928Snectar * 83100928Snectar * 5. Products derived from this software may not be called "OpenSSL" 84100928Snectar * nor may "OpenSSL" appear in their names without prior written 85100928Snectar * permission of the OpenSSL Project. 86100928Snectar * 87100928Snectar * 6. Redistributions of any form whatsoever must retain the following 88100928Snectar * acknowledgment: 89100928Snectar * "This product includes software developed by the OpenSSL Project 90100928Snectar * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 91100928Snectar * 92100928Snectar * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 93100928Snectar * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 94100928Snectar * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 95100928Snectar * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 96100928Snectar * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 97100928Snectar * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 98100928Snectar * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 99100928Snectar * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 100100928Snectar * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 101100928Snectar * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 102100928Snectar * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 103100928Snectar * OF THE POSSIBILITY OF SUCH DAMAGE. 104100928Snectar * ==================================================================== 105100928Snectar * 106100928Snectar * This product includes cryptographic software written by Eric Young 107100928Snectar * (eay@cryptsoft.com). This product includes software written by Tim 108100928Snectar * Hudson (tjh@cryptsoft.com). 109100928Snectar * 110100928Snectar */ 11155714Skris 11255714Skris#include <stdio.h> 11355714Skris#include <time.h> 11455714Skris 11555714Skris#include "cryptlib.h" 11659191Skris 11759191Skris#ifndef NO_SYS_TYPES_H 11859191Skris# include <sys/types.h> 11959191Skris#endif 12059191Skris 12155714Skris#include <openssl/bn.h> 12255714Skris#include <openssl/evp.h> 12355714Skris#include <openssl/x509.h> 12455714Skris#include <openssl/objects.h> 12555714Skris#include <openssl/buffer.h> 12655714Skris 127109998Smarkm#ifndef NO_ASN1_OLD 128109998Smarkm 12955714Skrisint ASN1_sign(int (*i2d)(), X509_ALGOR *algor1, X509_ALGOR *algor2, 13055714Skris ASN1_BIT_STRING *signature, char *data, EVP_PKEY *pkey, 13155714Skris const EVP_MD *type) 13255714Skris { 13355714Skris EVP_MD_CTX ctx; 13455714Skris unsigned char *p,*buf_in=NULL,*buf_out=NULL; 13555714Skris int i,inl=0,outl=0,outll=0; 13655714Skris X509_ALGOR *a; 13755714Skris 138109998Smarkm EVP_MD_CTX_init(&ctx); 13955714Skris for (i=0; i<2; i++) 14055714Skris { 14155714Skris if (i == 0) 14255714Skris a=algor1; 14355714Skris else 14455714Skris a=algor2; 14555714Skris if (a == NULL) continue; 146100928Snectar if (type->pkey_type == NID_dsaWithSHA1) 147100928Snectar { 148100928Snectar /* special case: RFC 2459 tells us to omit 'parameters' 149100928Snectar * with id-dsa-with-sha1 */ 150100928Snectar ASN1_TYPE_free(a->parameter); 151100928Snectar a->parameter = NULL; 152100928Snectar } 153100928Snectar else if ((a->parameter == NULL) || 15455714Skris (a->parameter->type != V_ASN1_NULL)) 15555714Skris { 15655714Skris ASN1_TYPE_free(a->parameter); 15755714Skris if ((a->parameter=ASN1_TYPE_new()) == NULL) goto err; 15855714Skris a->parameter->type=V_ASN1_NULL; 15955714Skris } 16055714Skris ASN1_OBJECT_free(a->algorithm); 16155714Skris a->algorithm=OBJ_nid2obj(type->pkey_type); 16255714Skris if (a->algorithm == NULL) 16355714Skris { 16455714Skris ASN1err(ASN1_F_ASN1_SIGN,ASN1_R_UNKNOWN_OBJECT_TYPE); 16555714Skris goto err; 16655714Skris } 16755714Skris if (a->algorithm->length == 0) 16855714Skris { 16955714Skris ASN1err(ASN1_F_ASN1_SIGN,ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD); 17055714Skris goto err; 17155714Skris } 17255714Skris } 17355714Skris inl=i2d(data,NULL); 17468651Skris buf_in=(unsigned char *)OPENSSL_malloc((unsigned int)inl); 17555714Skris outll=outl=EVP_PKEY_size(pkey); 17668651Skris buf_out=(unsigned char *)OPENSSL_malloc((unsigned int)outl); 17755714Skris if ((buf_in == NULL) || (buf_out == NULL)) 17855714Skris { 17955714Skris outl=0; 18055714Skris ASN1err(ASN1_F_ASN1_SIGN,ERR_R_MALLOC_FAILURE); 18155714Skris goto err; 18255714Skris } 18355714Skris p=buf_in; 18455714Skris 18555714Skris i2d(data,&p); 186109998Smarkm EVP_SignInit_ex(&ctx,type, NULL); 18755714Skris EVP_SignUpdate(&ctx,(unsigned char *)buf_in,inl); 18855714Skris if (!EVP_SignFinal(&ctx,(unsigned char *)buf_out, 18955714Skris (unsigned int *)&outl,pkey)) 19055714Skris { 19155714Skris outl=0; 19255714Skris ASN1err(ASN1_F_ASN1_SIGN,ERR_R_EVP_LIB); 19355714Skris goto err; 19455714Skris } 19568651Skris if (signature->data != NULL) OPENSSL_free(signature->data); 19655714Skris signature->data=buf_out; 19755714Skris buf_out=NULL; 19855714Skris signature->length=outl; 19959191Skris /* In the interests of compatibility, I'll make sure that 20055714Skris * the bit string has a 'not-used bits' value of 0 20155714Skris */ 20255714Skris signature->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07); 20355714Skris signature->flags|=ASN1_STRING_FLAG_BITS_LEFT; 20455714Skriserr: 205109998Smarkm EVP_MD_CTX_cleanup(&ctx); 20655714Skris if (buf_in != NULL) 207109998Smarkm { OPENSSL_cleanse((char *)buf_in,(unsigned int)inl); OPENSSL_free(buf_in); } 20855714Skris if (buf_out != NULL) 209109998Smarkm { OPENSSL_cleanse((char *)buf_out,outll); OPENSSL_free(buf_out); } 21055714Skris return(outl); 21155714Skris } 212109998Smarkm 213109998Smarkm#endif 214109998Smarkm 215109998Smarkmint ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2, 216109998Smarkm ASN1_BIT_STRING *signature, void *asn, EVP_PKEY *pkey, 217109998Smarkm const EVP_MD *type) 218109998Smarkm { 219109998Smarkm EVP_MD_CTX ctx; 220109998Smarkm unsigned char *buf_in=NULL,*buf_out=NULL; 221109998Smarkm int i,inl=0,outl=0,outll=0; 222109998Smarkm X509_ALGOR *a; 223109998Smarkm 224109998Smarkm EVP_MD_CTX_init(&ctx); 225109998Smarkm for (i=0; i<2; i++) 226109998Smarkm { 227109998Smarkm if (i == 0) 228109998Smarkm a=algor1; 229109998Smarkm else 230109998Smarkm a=algor2; 231109998Smarkm if (a == NULL) continue; 232109998Smarkm if (type->pkey_type == NID_dsaWithSHA1) 233109998Smarkm { 234109998Smarkm /* special case: RFC 2459 tells us to omit 'parameters' 235109998Smarkm * with id-dsa-with-sha1 */ 236109998Smarkm ASN1_TYPE_free(a->parameter); 237109998Smarkm a->parameter = NULL; 238109998Smarkm } 239109998Smarkm else if ((a->parameter == NULL) || 240109998Smarkm (a->parameter->type != V_ASN1_NULL)) 241109998Smarkm { 242109998Smarkm ASN1_TYPE_free(a->parameter); 243109998Smarkm if ((a->parameter=ASN1_TYPE_new()) == NULL) goto err; 244109998Smarkm a->parameter->type=V_ASN1_NULL; 245109998Smarkm } 246109998Smarkm ASN1_OBJECT_free(a->algorithm); 247109998Smarkm a->algorithm=OBJ_nid2obj(type->pkey_type); 248109998Smarkm if (a->algorithm == NULL) 249109998Smarkm { 250109998Smarkm ASN1err(ASN1_F_ASN1_SIGN,ASN1_R_UNKNOWN_OBJECT_TYPE); 251109998Smarkm goto err; 252109998Smarkm } 253109998Smarkm if (a->algorithm->length == 0) 254109998Smarkm { 255109998Smarkm ASN1err(ASN1_F_ASN1_SIGN,ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD); 256109998Smarkm goto err; 257109998Smarkm } 258109998Smarkm } 259109998Smarkm inl=ASN1_item_i2d(asn,&buf_in, it); 260109998Smarkm outll=outl=EVP_PKEY_size(pkey); 261109998Smarkm buf_out=(unsigned char *)OPENSSL_malloc((unsigned int)outl); 262109998Smarkm if ((buf_in == NULL) || (buf_out == NULL)) 263109998Smarkm { 264109998Smarkm outl=0; 265109998Smarkm ASN1err(ASN1_F_ASN1_SIGN,ERR_R_MALLOC_FAILURE); 266109998Smarkm goto err; 267109998Smarkm } 268109998Smarkm 269109998Smarkm EVP_SignInit_ex(&ctx,type, NULL); 270109998Smarkm EVP_SignUpdate(&ctx,(unsigned char *)buf_in,inl); 271109998Smarkm if (!EVP_SignFinal(&ctx,(unsigned char *)buf_out, 272109998Smarkm (unsigned int *)&outl,pkey)) 273109998Smarkm { 274109998Smarkm outl=0; 275109998Smarkm ASN1err(ASN1_F_ASN1_SIGN,ERR_R_EVP_LIB); 276109998Smarkm goto err; 277109998Smarkm } 278109998Smarkm if (signature->data != NULL) OPENSSL_free(signature->data); 279109998Smarkm signature->data=buf_out; 280109998Smarkm buf_out=NULL; 281109998Smarkm signature->length=outl; 282109998Smarkm /* In the interests of compatibility, I'll make sure that 283109998Smarkm * the bit string has a 'not-used bits' value of 0 284109998Smarkm */ 285109998Smarkm signature->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07); 286109998Smarkm signature->flags|=ASN1_STRING_FLAG_BITS_LEFT; 287109998Smarkmerr: 288109998Smarkm EVP_MD_CTX_cleanup(&ctx); 289109998Smarkm if (buf_in != NULL) 290109998Smarkm { OPENSSL_cleanse((char *)buf_in,(unsigned int)inl); OPENSSL_free(buf_in); } 291109998Smarkm if (buf_out != NULL) 292109998Smarkm { OPENSSL_cleanse((char *)buf_out,outll); OPENSSL_free(buf_out); } 293109998Smarkm return(outl); 294109998Smarkm } 295