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/* ==================================================================== 59160814Ssimon * Copyright (c) 1998-2003 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> 126238405Sjkim#include "asn1_locl.h" 12755714Skris 128109998Smarkm#ifndef NO_ASN1_OLD 129109998Smarkm 130160814Ssimonint ASN1_sign(i2d_of_void *i2d, X509_ALGOR *algor1, X509_ALGOR *algor2, 131160814Ssimon ASN1_BIT_STRING *signature, char *data, EVP_PKEY *pkey, 132160814Ssimon const EVP_MD *type) 13355714Skris { 13455714Skris EVP_MD_CTX ctx; 13555714Skris unsigned char *p,*buf_in=NULL,*buf_out=NULL; 13655714Skris int i,inl=0,outl=0,outll=0; 13755714Skris X509_ALGOR *a; 13855714Skris 139109998Smarkm EVP_MD_CTX_init(&ctx); 14055714Skris for (i=0; i<2; i++) 14155714Skris { 14255714Skris if (i == 0) 14355714Skris a=algor1; 14455714Skris else 14555714Skris a=algor2; 14655714Skris if (a == NULL) continue; 147100928Snectar if (type->pkey_type == NID_dsaWithSHA1) 148100928Snectar { 149100928Snectar /* special case: RFC 2459 tells us to omit 'parameters' 150100928Snectar * with id-dsa-with-sha1 */ 151100928Snectar ASN1_TYPE_free(a->parameter); 152100928Snectar a->parameter = NULL; 153100928Snectar } 154100928Snectar else if ((a->parameter == NULL) || 15555714Skris (a->parameter->type != V_ASN1_NULL)) 15655714Skris { 15755714Skris ASN1_TYPE_free(a->parameter); 15855714Skris if ((a->parameter=ASN1_TYPE_new()) == NULL) goto err; 15955714Skris a->parameter->type=V_ASN1_NULL; 16055714Skris } 16155714Skris ASN1_OBJECT_free(a->algorithm); 16255714Skris a->algorithm=OBJ_nid2obj(type->pkey_type); 16355714Skris if (a->algorithm == NULL) 16455714Skris { 16555714Skris ASN1err(ASN1_F_ASN1_SIGN,ASN1_R_UNKNOWN_OBJECT_TYPE); 16655714Skris goto err; 16755714Skris } 16855714Skris if (a->algorithm->length == 0) 16955714Skris { 17055714Skris ASN1err(ASN1_F_ASN1_SIGN,ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD); 17155714Skris goto err; 17255714Skris } 17355714Skris } 17455714Skris inl=i2d(data,NULL); 17568651Skris buf_in=(unsigned char *)OPENSSL_malloc((unsigned int)inl); 17655714Skris outll=outl=EVP_PKEY_size(pkey); 17768651Skris buf_out=(unsigned char *)OPENSSL_malloc((unsigned int)outl); 17855714Skris if ((buf_in == NULL) || (buf_out == NULL)) 17955714Skris { 18055714Skris outl=0; 18155714Skris ASN1err(ASN1_F_ASN1_SIGN,ERR_R_MALLOC_FAILURE); 18255714Skris goto err; 18355714Skris } 18455714Skris p=buf_in; 18555714Skris 18655714Skris i2d(data,&p); 187238405Sjkim if (!EVP_SignInit_ex(&ctx,type, NULL) 188238405Sjkim || !EVP_SignUpdate(&ctx,(unsigned char *)buf_in,inl) 189238405Sjkim || !EVP_SignFinal(&ctx,(unsigned char *)buf_out, 19055714Skris (unsigned int *)&outl,pkey)) 19155714Skris { 19255714Skris outl=0; 19355714Skris ASN1err(ASN1_F_ASN1_SIGN,ERR_R_EVP_LIB); 19455714Skris goto err; 19555714Skris } 19668651Skris if (signature->data != NULL) OPENSSL_free(signature->data); 19755714Skris signature->data=buf_out; 19855714Skris buf_out=NULL; 19955714Skris signature->length=outl; 20059191Skris /* In the interests of compatibility, I'll make sure that 20155714Skris * the bit string has a 'not-used bits' value of 0 20255714Skris */ 20355714Skris signature->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07); 20455714Skris signature->flags|=ASN1_STRING_FLAG_BITS_LEFT; 20555714Skriserr: 206109998Smarkm EVP_MD_CTX_cleanup(&ctx); 20755714Skris if (buf_in != NULL) 208109998Smarkm { OPENSSL_cleanse((char *)buf_in,(unsigned int)inl); OPENSSL_free(buf_in); } 20955714Skris if (buf_out != NULL) 210109998Smarkm { OPENSSL_cleanse((char *)buf_out,outll); OPENSSL_free(buf_out); } 21155714Skris return(outl); 21255714Skris } 213109998Smarkm 214109998Smarkm#endif 215109998Smarkm 216109998Smarkmint ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2, 217109998Smarkm ASN1_BIT_STRING *signature, void *asn, EVP_PKEY *pkey, 218109998Smarkm const EVP_MD *type) 219109998Smarkm { 220109998Smarkm EVP_MD_CTX ctx; 221238405Sjkim EVP_MD_CTX_init(&ctx); 222238405Sjkim if (!EVP_DigestSignInit(&ctx, NULL, type, NULL, pkey)) 223238405Sjkim { 224238405Sjkim EVP_MD_CTX_cleanup(&ctx); 225238405Sjkim return 0; 226238405Sjkim } 227238405Sjkim return ASN1_item_sign_ctx(it, algor1, algor2, signature, asn, &ctx); 228238405Sjkim } 229238405Sjkim 230238405Sjkim 231238405Sjkimint ASN1_item_sign_ctx(const ASN1_ITEM *it, 232238405Sjkim X509_ALGOR *algor1, X509_ALGOR *algor2, 233238405Sjkim ASN1_BIT_STRING *signature, void *asn, EVP_MD_CTX *ctx) 234238405Sjkim { 235238405Sjkim const EVP_MD *type; 236238405Sjkim EVP_PKEY *pkey; 237109998Smarkm unsigned char *buf_in=NULL,*buf_out=NULL; 238238405Sjkim size_t inl=0,outl=0,outll=0; 239238405Sjkim int signid, paramtype; 240238405Sjkim int rv; 241109998Smarkm 242238405Sjkim type = EVP_MD_CTX_md(ctx); 243238405Sjkim pkey = EVP_PKEY_CTX_get0_pkey(ctx->pctx); 244238405Sjkim 245238405Sjkim if (!type || !pkey) 246109998Smarkm { 247238405Sjkim ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ASN1_R_CONTEXT_NOT_INITIALISED); 248238405Sjkim return 0; 249238405Sjkim } 250238405Sjkim 251238405Sjkim if (pkey->ameth->item_sign) 252238405Sjkim { 253238405Sjkim rv = pkey->ameth->item_sign(ctx, it, asn, algor1, algor2, 254238405Sjkim signature); 255238405Sjkim if (rv == 1) 256238405Sjkim outl = signature->length; 257238405Sjkim /* Return value meanings: 258238405Sjkim * <=0: error. 259238405Sjkim * 1: method does everything. 260238405Sjkim * 2: carry on as normal. 261238405Sjkim * 3: ASN1 method sets algorithm identifiers: just sign. 262238405Sjkim */ 263238405Sjkim if (rv <= 0) 264238405Sjkim ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ERR_R_EVP_LIB); 265238405Sjkim if (rv <= 1) 266109998Smarkm goto err; 267238405Sjkim } 268238405Sjkim else 269238405Sjkim rv = 2; 270238405Sjkim 271238405Sjkim if (rv == 2) 272238405Sjkim { 273238405Sjkim if (type->flags & EVP_MD_FLAG_PKEY_METHOD_SIGNATURE) 274109998Smarkm { 275238405Sjkim if (!pkey->ameth || 276238405Sjkim !OBJ_find_sigid_by_algs(&signid, 277238405Sjkim EVP_MD_nid(type), 278238405Sjkim pkey->ameth->pkey_id)) 279238405Sjkim { 280238405Sjkim ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, 281238405Sjkim ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED); 282238405Sjkim return 0; 283238405Sjkim } 284109998Smarkm } 285238405Sjkim else 286238405Sjkim signid = type->pkey_type; 287238405Sjkim 288238405Sjkim if (pkey->ameth->pkey_flags & ASN1_PKEY_SIGPARAM_NULL) 289238405Sjkim paramtype = V_ASN1_NULL; 290238405Sjkim else 291238405Sjkim paramtype = V_ASN1_UNDEF; 292238405Sjkim 293238405Sjkim if (algor1) 294238405Sjkim X509_ALGOR_set0(algor1, OBJ_nid2obj(signid), paramtype, NULL); 295238405Sjkim if (algor2) 296238405Sjkim X509_ALGOR_set0(algor2, OBJ_nid2obj(signid), paramtype, NULL); 297238405Sjkim 298109998Smarkm } 299238405Sjkim 300109998Smarkm inl=ASN1_item_i2d(asn,&buf_in, it); 301109998Smarkm outll=outl=EVP_PKEY_size(pkey); 302238405Sjkim buf_out=OPENSSL_malloc((unsigned int)outl); 303109998Smarkm if ((buf_in == NULL) || (buf_out == NULL)) 304109998Smarkm { 305109998Smarkm outl=0; 306238405Sjkim ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX,ERR_R_MALLOC_FAILURE); 307109998Smarkm goto err; 308109998Smarkm } 309109998Smarkm 310238405Sjkim if (!EVP_DigestSignUpdate(ctx, buf_in, inl) 311238405Sjkim || !EVP_DigestSignFinal(ctx, buf_out, &outl)) 312194206Ssimon { 313194206Ssimon outl=0; 314238405Sjkim ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX,ERR_R_EVP_LIB); 315194206Ssimon goto err; 316194206Ssimon } 317109998Smarkm if (signature->data != NULL) OPENSSL_free(signature->data); 318109998Smarkm signature->data=buf_out; 319109998Smarkm buf_out=NULL; 320109998Smarkm signature->length=outl; 321109998Smarkm /* In the interests of compatibility, I'll make sure that 322109998Smarkm * the bit string has a 'not-used bits' value of 0 323109998Smarkm */ 324109998Smarkm signature->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07); 325109998Smarkm signature->flags|=ASN1_STRING_FLAG_BITS_LEFT; 326109998Smarkmerr: 327238405Sjkim EVP_MD_CTX_cleanup(ctx); 328109998Smarkm if (buf_in != NULL) 329109998Smarkm { OPENSSL_cleanse((char *)buf_in,(unsigned int)inl); OPENSSL_free(buf_in); } 330109998Smarkm if (buf_out != NULL) 331109998Smarkm { OPENSSL_cleanse((char *)buf_out,outll); OPENSSL_free(buf_out); } 332109998Smarkm return(outl); 333109998Smarkm } 334