pk7_doit.c revision 284295
1/* crypto/pkcs7/pk7_doit.c */ 2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 3 * All rights reserved. 4 * 5 * This package is an SSL implementation written 6 * by Eric Young (eay@cryptsoft.com). 7 * The implementation was written so as to conform with Netscapes SSL. 8 * 9 * This library is free for commercial and non-commercial use as long as 10 * the following conditions are aheared to. The following conditions 11 * apply to all code found in this distribution, be it the RC4, RSA, 12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation 13 * included with this distribution is covered by the same copyright terms 14 * except that the holder is Tim Hudson (tjh@cryptsoft.com). 15 * 16 * Copyright remains Eric Young's, and as such any Copyright notices in 17 * the code are not to be removed. 18 * If this package is used in a product, Eric Young should be given attribution 19 * as the author of the parts of the library used. 20 * This can be in the form of a textual message at program startup or 21 * in documentation (online or textual) provided with the package. 22 * 23 * Redistribution and use in source and binary forms, with or without 24 * modification, are permitted provided that the following conditions 25 * are met: 26 * 1. Redistributions of source code must retain the copyright 27 * notice, this list of conditions and the following disclaimer. 28 * 2. Redistributions in binary form must reproduce the above copyright 29 * notice, this list of conditions and the following disclaimer in the 30 * documentation and/or other materials provided with the distribution. 31 * 3. All advertising materials mentioning features or use of this software 32 * must display the following acknowledgement: 33 * "This product includes cryptographic software written by 34 * Eric Young (eay@cryptsoft.com)" 35 * The word 'cryptographic' can be left out if the rouines from the library 36 * being used are not cryptographic related :-). 37 * 4. If you include any Windows specific code (or a derivative thereof) from 38 * the apps directory (application code) you must include an acknowledgement: 39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 40 * 41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 51 * SUCH DAMAGE. 52 * 53 * The licence and distribution terms for any publically available version or 54 * derivative of this code cannot be changed. i.e. this code cannot simply be 55 * copied and put under another distribution licence 56 * [including the GNU Public Licence.] 57 */ 58 59#include <stdio.h> 60#include "cryptlib.h" 61#include <openssl/rand.h> 62#include <openssl/objects.h> 63#include <openssl/x509.h> 64#include <openssl/x509v3.h> 65#include <openssl/err.h> 66 67static int add_attribute(STACK_OF(X509_ATTRIBUTE) **sk, int nid, int atrtype, 68 void *value); 69static ASN1_TYPE *get_attribute(STACK_OF(X509_ATTRIBUTE) *sk, int nid); 70 71static int PKCS7_type_is_other(PKCS7* p7) 72 { 73 int isOther=1; 74 75 int nid=OBJ_obj2nid(p7->type); 76 77 switch( nid ) 78 { 79 case NID_pkcs7_data: 80 case NID_pkcs7_signed: 81 case NID_pkcs7_enveloped: 82 case NID_pkcs7_signedAndEnveloped: 83 case NID_pkcs7_digest: 84 case NID_pkcs7_encrypted: 85 isOther=0; 86 break; 87 default: 88 isOther=1; 89 } 90 91 return isOther; 92 93 } 94 95static ASN1_OCTET_STRING *PKCS7_get_octet_string(PKCS7 *p7) 96 { 97 if ( PKCS7_type_is_data(p7)) 98 return p7->d.data; 99 if ( PKCS7_type_is_other(p7) && p7->d.other 100 && (p7->d.other->type == V_ASN1_OCTET_STRING)) 101 return p7->d.other->value.octet_string; 102 return NULL; 103 } 104 105static int PKCS7_bio_add_digest(BIO **pbio, X509_ALGOR *alg) 106 { 107 BIO *btmp; 108 const EVP_MD *md; 109 if ((btmp=BIO_new(BIO_f_md())) == NULL) 110 { 111 PKCS7err(PKCS7_F_PKCS7_BIO_ADD_DIGEST,ERR_R_BIO_LIB); 112 goto err; 113 } 114 115 md=EVP_get_digestbyobj(alg->algorithm); 116 if (md == NULL) 117 { 118 PKCS7err(PKCS7_F_PKCS7_BIO_ADD_DIGEST,PKCS7_R_UNKNOWN_DIGEST_TYPE); 119 goto err; 120 } 121 122 BIO_set_md(btmp,md); 123 if (*pbio == NULL) 124 *pbio=btmp; 125 else if (!BIO_push(*pbio,btmp)) 126 { 127 PKCS7err(PKCS7_F_PKCS7_BIO_ADD_DIGEST,ERR_R_BIO_LIB); 128 goto err; 129 } 130 btmp=NULL; 131 132 return 1; 133 134 err: 135 if (btmp) 136 BIO_free(btmp); 137 return 0; 138 139 } 140 141BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio) 142 { 143 int i; 144 BIO *out=NULL,*btmp=NULL; 145 X509_ALGOR *xa = NULL; 146 const EVP_CIPHER *evp_cipher=NULL; 147 STACK_OF(X509_ALGOR) *md_sk=NULL; 148 STACK_OF(PKCS7_RECIP_INFO) *rsk=NULL; 149 X509_ALGOR *xalg=NULL; 150 PKCS7_RECIP_INFO *ri=NULL; 151 EVP_PKEY *pkey; 152 ASN1_OCTET_STRING *os=NULL; 153 154 if (p7 == NULL) { 155 PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_INVALID_NULL_POINTER); 156 return NULL; 157 } 158 /* 159 * The content field in the PKCS7 ContentInfo is optional, but that really 160 * only applies to inner content (precisely, detached signatures). 161 * 162 * When reading content, missing outer content is therefore treated as an 163 * error. 164 * 165 * When creating content, PKCS7_content_new() must be called before 166 * calling this method, so a NULL p7->d is always an error. 167 */ 168 if (p7->d.ptr == NULL) { 169 PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_NO_CONTENT); 170 return NULL; 171 } 172 173 i=OBJ_obj2nid(p7->type); 174 p7->state=PKCS7_S_HEADER; 175 176 switch (i) 177 { 178 case NID_pkcs7_signed: 179 md_sk=p7->d.sign->md_algs; 180 os = PKCS7_get_octet_string(p7->d.sign->contents); 181 break; 182 case NID_pkcs7_signedAndEnveloped: 183 rsk=p7->d.signed_and_enveloped->recipientinfo; 184 md_sk=p7->d.signed_and_enveloped->md_algs; 185 xalg=p7->d.signed_and_enveloped->enc_data->algorithm; 186 evp_cipher=p7->d.signed_and_enveloped->enc_data->cipher; 187 if (evp_cipher == NULL) 188 { 189 PKCS7err(PKCS7_F_PKCS7_DATAINIT, 190 PKCS7_R_CIPHER_NOT_INITIALIZED); 191 goto err; 192 } 193 break; 194 case NID_pkcs7_enveloped: 195 rsk=p7->d.enveloped->recipientinfo; 196 xalg=p7->d.enveloped->enc_data->algorithm; 197 evp_cipher=p7->d.enveloped->enc_data->cipher; 198 if (evp_cipher == NULL) 199 { 200 PKCS7err(PKCS7_F_PKCS7_DATAINIT, 201 PKCS7_R_CIPHER_NOT_INITIALIZED); 202 goto err; 203 } 204 break; 205 case NID_pkcs7_digest: 206 xa = p7->d.digest->md; 207 os = PKCS7_get_octet_string(p7->d.digest->contents); 208 break; 209 default: 210 PKCS7err(PKCS7_F_PKCS7_DATAINIT,PKCS7_R_UNSUPPORTED_CONTENT_TYPE); 211 goto err; 212 } 213 214 for (i=0; i<sk_X509_ALGOR_num(md_sk); i++) 215 if (!PKCS7_bio_add_digest(&out, sk_X509_ALGOR_value(md_sk, i))) 216 goto err; 217 218 if (xa && !PKCS7_bio_add_digest(&out, xa)) 219 goto err; 220 221 if (evp_cipher != NULL) 222 { 223 unsigned char key[EVP_MAX_KEY_LENGTH]; 224 unsigned char iv[EVP_MAX_IV_LENGTH]; 225 int keylen,ivlen; 226 int jj,max; 227 unsigned char *tmp; 228 EVP_CIPHER_CTX *ctx; 229 230 if ((btmp=BIO_new(BIO_f_cipher())) == NULL) 231 { 232 PKCS7err(PKCS7_F_PKCS7_DATAINIT,ERR_R_BIO_LIB); 233 goto err; 234 } 235 BIO_get_cipher_ctx(btmp, &ctx); 236 keylen=EVP_CIPHER_key_length(evp_cipher); 237 ivlen=EVP_CIPHER_iv_length(evp_cipher); 238 xalg->algorithm = OBJ_nid2obj(EVP_CIPHER_type(evp_cipher)); 239 if (ivlen > 0) 240 if (RAND_pseudo_bytes(iv,ivlen) <= 0) 241 goto err; 242 if (EVP_CipherInit_ex(ctx, evp_cipher, NULL, NULL, NULL, 1)<=0) 243 goto err; 244 if (EVP_CIPHER_CTX_rand_key(ctx, key) <= 0) 245 goto err; 246 if (EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, 1) <= 0) 247 goto err; 248 249 if (ivlen > 0) { 250 if (xalg->parameter == NULL) { 251 xalg->parameter = ASN1_TYPE_new(); 252 if (xalg->parameter == NULL) 253 goto err; 254 } 255 if(EVP_CIPHER_param_to_asn1(ctx, xalg->parameter) < 0) 256 goto err; 257 } 258 259 /* Lets do the pub key stuff :-) */ 260 max=0; 261 for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++) 262 { 263 ri=sk_PKCS7_RECIP_INFO_value(rsk,i); 264 if (ri->cert == NULL) 265 { 266 PKCS7err(PKCS7_F_PKCS7_DATAINIT,PKCS7_R_MISSING_CERIPEND_INFO); 267 goto err; 268 } 269 if ((pkey=X509_get_pubkey(ri->cert)) == NULL) 270 goto err; 271 jj=EVP_PKEY_size(pkey); 272 EVP_PKEY_free(pkey); 273 if (max < jj) max=jj; 274 } 275 if ((tmp=(unsigned char *)OPENSSL_malloc(max)) == NULL) 276 { 277 PKCS7err(PKCS7_F_PKCS7_DATAINIT,ERR_R_MALLOC_FAILURE); 278 goto err; 279 } 280 for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++) 281 { 282 ri=sk_PKCS7_RECIP_INFO_value(rsk,i); 283 if ((pkey=X509_get_pubkey(ri->cert)) == NULL) 284 goto err; 285 jj=EVP_PKEY_encrypt(tmp,key,keylen,pkey); 286 EVP_PKEY_free(pkey); 287 if (jj <= 0) 288 { 289 PKCS7err(PKCS7_F_PKCS7_DATAINIT,ERR_R_EVP_LIB); 290 OPENSSL_free(tmp); 291 goto err; 292 } 293 if (!M_ASN1_OCTET_STRING_set(ri->enc_key,tmp,jj)) 294 { 295 PKCS7err(PKCS7_F_PKCS7_DATAINIT, 296 ERR_R_MALLOC_FAILURE); 297 OPENSSL_free(tmp); 298 goto err; 299 } 300 } 301 OPENSSL_free(tmp); 302 OPENSSL_cleanse(key, keylen); 303 304 if (out == NULL) 305 out=btmp; 306 else 307 BIO_push(out,btmp); 308 btmp=NULL; 309 } 310 311 if (bio == NULL) 312 { 313 if (PKCS7_is_detached(p7)) 314 bio=BIO_new(BIO_s_null()); 315 else if (os && os->length > 0) 316 bio = BIO_new_mem_buf(os->data, os->length); 317 if(bio == NULL) 318 { 319 bio=BIO_new(BIO_s_mem()); 320 if (bio == NULL) 321 goto err; 322 BIO_set_mem_eof_return(bio,0); 323 } 324 } 325 BIO_push(out,bio); 326 bio=NULL; 327 if (0) 328 { 329err: 330 if (out != NULL) 331 BIO_free_all(out); 332 if (btmp != NULL) 333 BIO_free_all(btmp); 334 out=NULL; 335 } 336 return(out); 337 } 338 339static int pkcs7_cmp_ri(PKCS7_RECIP_INFO *ri, X509 *pcert) 340 { 341 int ret; 342 ret = X509_NAME_cmp(ri->issuer_and_serial->issuer, 343 pcert->cert_info->issuer); 344 if (ret) 345 return ret; 346 return M_ASN1_INTEGER_cmp(pcert->cert_info->serialNumber, 347 ri->issuer_and_serial->serial); 348 } 349 350/* int */ 351BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) 352 { 353 int i,j; 354 BIO *out=NULL,*btmp=NULL,*etmp=NULL,*bio=NULL; 355 unsigned char *tmp=NULL; 356 X509_ALGOR *xa; 357 ASN1_OCTET_STRING *data_body=NULL; 358 const EVP_MD *evp_md; 359 const EVP_CIPHER *evp_cipher=NULL; 360 EVP_CIPHER_CTX *evp_ctx=NULL; 361 X509_ALGOR *enc_alg=NULL; 362 STACK_OF(X509_ALGOR) *md_sk=NULL; 363 STACK_OF(PKCS7_RECIP_INFO) *rsk=NULL; 364 PKCS7_RECIP_INFO *ri=NULL; 365 366 if (p7 == NULL) { 367 PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_INVALID_NULL_POINTER); 368 return NULL; 369 } 370 371 if (p7->d.ptr == NULL) { 372 PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_NO_CONTENT); 373 return NULL; 374 } 375 376 i=OBJ_obj2nid(p7->type); 377 p7->state=PKCS7_S_HEADER; 378 379 switch (i) 380 { 381 case NID_pkcs7_signed: 382 data_body=PKCS7_get_octet_string(p7->d.sign->contents); 383 md_sk=p7->d.sign->md_algs; 384 break; 385 case NID_pkcs7_signedAndEnveloped: 386 rsk=p7->d.signed_and_enveloped->recipientinfo; 387 md_sk=p7->d.signed_and_enveloped->md_algs; 388 data_body=p7->d.signed_and_enveloped->enc_data->enc_data; 389 enc_alg=p7->d.signed_and_enveloped->enc_data->algorithm; 390 evp_cipher=EVP_get_cipherbyobj(enc_alg->algorithm); 391 if (evp_cipher == NULL) 392 { 393 PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNSUPPORTED_CIPHER_TYPE); 394 goto err; 395 } 396 break; 397 case NID_pkcs7_enveloped: 398 rsk=p7->d.enveloped->recipientinfo; 399 enc_alg=p7->d.enveloped->enc_data->algorithm; 400 data_body=p7->d.enveloped->enc_data->enc_data; 401 evp_cipher=EVP_get_cipherbyobj(enc_alg->algorithm); 402 if (evp_cipher == NULL) 403 { 404 PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNSUPPORTED_CIPHER_TYPE); 405 goto err; 406 } 407 break; 408 default: 409 PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNSUPPORTED_CONTENT_TYPE); 410 goto err; 411 } 412 413 /* Detached content must be supplied via in_bio instead. */ 414 if (data_body == NULL && in_bio == NULL) { 415 PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_NO_CONTENT); 416 goto err; 417 } 418 419 /* We will be checking the signature */ 420 if (md_sk != NULL) 421 { 422 for (i=0; i<sk_X509_ALGOR_num(md_sk); i++) 423 { 424 xa=sk_X509_ALGOR_value(md_sk,i); 425 if ((btmp=BIO_new(BIO_f_md())) == NULL) 426 { 427 PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_BIO_LIB); 428 goto err; 429 } 430 431 j=OBJ_obj2nid(xa->algorithm); 432 evp_md=EVP_get_digestbynid(j); 433 if (evp_md == NULL) 434 { 435 PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNKNOWN_DIGEST_TYPE); 436 goto err; 437 } 438 439 BIO_set_md(btmp,evp_md); 440 if (out == NULL) 441 out=btmp; 442 else 443 BIO_push(out,btmp); 444 btmp=NULL; 445 } 446 } 447 448 if (evp_cipher != NULL) 449 { 450#if 0 451 unsigned char key[EVP_MAX_KEY_LENGTH]; 452 unsigned char iv[EVP_MAX_IV_LENGTH]; 453 unsigned char *p; 454 int keylen,ivlen; 455 int max; 456 X509_OBJECT ret; 457#endif 458 unsigned char *tkey = NULL; 459 int tkeylen; 460 int jj; 461 462 if ((etmp=BIO_new(BIO_f_cipher())) == NULL) 463 { 464 PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_BIO_LIB); 465 goto err; 466 } 467 468 /* It was encrypted, we need to decrypt the secret key 469 * with the private key */ 470 471 /* Find the recipientInfo which matches the passed certificate 472 * (if any) 473 */ 474 475 if (pcert) { 476 for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++) { 477 ri=sk_PKCS7_RECIP_INFO_value(rsk,i); 478 if (!pkcs7_cmp_ri(ri, pcert)) 479 break; 480 ri=NULL; 481 } 482 if (ri == NULL) { 483 PKCS7err(PKCS7_F_PKCS7_DATADECODE, 484 PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE); 485 goto err; 486 } 487 } 488 489 jj=EVP_PKEY_size(pkey); 490 tmp=(unsigned char *)OPENSSL_malloc(jj+10); 491 if (tmp == NULL) 492 { 493 PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_MALLOC_FAILURE); 494 goto err; 495 } 496 497 /* If we haven't got a certificate try each ri in turn */ 498 499 if (pcert == NULL) 500 { 501 /* Temporary storage in case EVP_PKEY_decrypt 502 * overwrites output buffer on error. 503 */ 504 unsigned char *tmp2; 505 tmp2 = OPENSSL_malloc(jj); 506 if (!tmp2) 507 goto err; 508 jj = -1; 509 /* Always attempt to decrypt all cases to avoid 510 * leaking timing information about a successful 511 * decrypt. 512 */ 513 for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++) 514 { 515 int tret; 516 ri=sk_PKCS7_RECIP_INFO_value(rsk,i); 517 tret=EVP_PKEY_decrypt(tmp2, 518 M_ASN1_STRING_data(ri->enc_key), 519 M_ASN1_STRING_length(ri->enc_key), 520 pkey); 521 if (tret > 0) 522 { 523 memcpy(tmp, tmp2, tret); 524 OPENSSL_cleanse(tmp2, tret); 525 jj = tret; 526 } 527 ERR_clear_error(); 528 } 529 OPENSSL_free(tmp2); 530 } 531 else 532 { 533 jj=EVP_PKEY_decrypt(tmp, 534 M_ASN1_STRING_data(ri->enc_key), 535 M_ASN1_STRING_length(ri->enc_key), pkey); 536 ERR_clear_error(); 537 } 538 539 evp_ctx=NULL; 540 BIO_get_cipher_ctx(etmp,&evp_ctx); 541 if (EVP_CipherInit_ex(evp_ctx,evp_cipher,NULL,NULL,NULL,0) <= 0) 542 goto err; 543 if (EVP_CIPHER_asn1_to_param(evp_ctx,enc_alg->parameter) < 0) 544 goto err; 545 /* Generate random key to counter MMA */ 546 tkeylen = EVP_CIPHER_CTX_key_length(evp_ctx); 547 tkey = OPENSSL_malloc(tkeylen); 548 if (!tkey) 549 goto err; 550 if (EVP_CIPHER_CTX_rand_key(evp_ctx, tkey) <= 0) 551 goto err; 552 /* If we have no key use random key */ 553 if (jj <= 0) 554 { 555 OPENSSL_free(tmp); 556 jj = tkeylen; 557 tmp = tkey; 558 tkey = NULL; 559 } 560 561 if (jj != tkeylen) { 562 /* Some S/MIME clients don't use the same key 563 * and effective key length. The key length is 564 * determined by the size of the decrypted RSA key. 565 */ 566 if(!EVP_CIPHER_CTX_set_key_length(evp_ctx, jj)) 567 { 568 /* As MMA defence use random key instead */ 569 OPENSSL_cleanse(tmp, jj); 570 OPENSSL_free(tmp); 571 jj = tkeylen; 572 tmp = tkey; 573 tkey = NULL; 574 } 575 } 576 ERR_clear_error(); 577 if (EVP_CipherInit_ex(evp_ctx,NULL,NULL,tmp,NULL,0) <= 0) 578 goto err; 579 580 OPENSSL_cleanse(tmp,jj); 581 582 if (tkey) 583 { 584 OPENSSL_cleanse(tkey, tkeylen); 585 OPENSSL_free(tkey); 586 } 587 588 if (out == NULL) 589 out=etmp; 590 else 591 BIO_push(out,etmp); 592 etmp=NULL; 593 } 594 595#if 1 596 if (in_bio != NULL) { 597 bio = in_bio; 598 } else { 599#if 0 600 bio=BIO_new(BIO_s_mem()); 601 /* We need to set this so that when we have read all 602 * the data, the encrypt BIO, if present, will read 603 * EOF and encode the last few bytes */ 604 BIO_set_mem_eof_return(bio,0); 605 606 if (data_body->length > 0) 607 BIO_write(bio,(char *)data_body->data,data_body->length); 608#else 609 if (data_body->length > 0) 610 bio = BIO_new_mem_buf(data_body->data,data_body->length); 611 else { 612 bio=BIO_new(BIO_s_mem()); 613 BIO_set_mem_eof_return(bio,0); 614 } 615 if (bio == NULL) 616 goto err; 617#endif 618 } 619 BIO_push(out,bio); 620 bio=NULL; 621#endif 622 if (0) 623 { 624err: 625 if (out != NULL) BIO_free_all(out); 626 if (btmp != NULL) BIO_free_all(btmp); 627 if (etmp != NULL) BIO_free_all(etmp); 628 if (bio != NULL) BIO_free_all(bio); 629 out=NULL; 630 } 631 if (tmp != NULL) 632 OPENSSL_free(tmp); 633 return(out); 634 } 635 636static BIO *PKCS7_find_digest(EVP_MD_CTX **pmd, BIO *bio, int nid) 637 { 638 for (;;) 639 { 640 bio=BIO_find_type(bio,BIO_TYPE_MD); 641 if (bio == NULL) 642 { 643 PKCS7err(PKCS7_F_PKCS7_FIND_DIGEST,PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST); 644 return NULL; 645 } 646 BIO_get_md_ctx(bio,pmd); 647 if (*pmd == NULL) 648 { 649 PKCS7err(PKCS7_F_PKCS7_FIND_DIGEST,ERR_R_INTERNAL_ERROR); 650 return NULL; 651 } 652 if (EVP_MD_CTX_type(*pmd) == nid) 653 return bio; 654 bio=BIO_next(bio); 655 } 656 return NULL; 657 } 658 659int PKCS7_dataFinal(PKCS7 *p7, BIO *bio) 660 { 661 int ret=0; 662 int i,j; 663 BIO *btmp; 664 BUF_MEM *buf_mem=NULL; 665 BUF_MEM *buf=NULL; 666 PKCS7_SIGNER_INFO *si; 667 EVP_MD_CTX *mdc,ctx_tmp; 668 STACK_OF(X509_ATTRIBUTE) *sk; 669 STACK_OF(PKCS7_SIGNER_INFO) *si_sk=NULL; 670 ASN1_OCTET_STRING *os=NULL; 671 672 if (p7 == NULL) { 673 PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_INVALID_NULL_POINTER); 674 return 0; 675 } 676 677 if (p7->d.ptr == NULL) { 678 PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_NO_CONTENT); 679 return 0; 680 } 681 682 EVP_MD_CTX_init(&ctx_tmp); 683 i=OBJ_obj2nid(p7->type); 684 p7->state=PKCS7_S_HEADER; 685 686 switch (i) 687 { 688 case NID_pkcs7_signedAndEnveloped: 689 /* XXXXXXXXXXXXXXXX */ 690 si_sk=p7->d.signed_and_enveloped->signer_info; 691 if (!(os=M_ASN1_OCTET_STRING_new())) 692 { 693 PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_MALLOC_FAILURE); 694 goto err; 695 } 696 p7->d.signed_and_enveloped->enc_data->enc_data=os; 697 break; 698 case NID_pkcs7_enveloped: 699 /* XXXXXXXXXXXXXXXX */ 700 if (!(os=M_ASN1_OCTET_STRING_new())) 701 { 702 PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_MALLOC_FAILURE); 703 goto err; 704 } 705 p7->d.enveloped->enc_data->enc_data=os; 706 break; 707 case NID_pkcs7_signed: 708 si_sk=p7->d.sign->signer_info; 709 os=PKCS7_get_octet_string(p7->d.sign->contents); 710 /* If detached data then the content is excluded */ 711 if(PKCS7_type_is_data(p7->d.sign->contents) && p7->detached) { 712 M_ASN1_OCTET_STRING_free(os); 713 os = NULL; 714 p7->d.sign->contents->d.data = NULL; 715 } 716 break; 717 718 case NID_pkcs7_digest: 719 os=PKCS7_get_octet_string(p7->d.digest->contents); 720 /* If detached data then the content is excluded */ 721 if(PKCS7_type_is_data(p7->d.digest->contents) && p7->detached) 722 { 723 M_ASN1_OCTET_STRING_free(os); 724 os = NULL; 725 p7->d.digest->contents->d.data = NULL; 726 } 727 break; 728 729 } 730 731 if (si_sk != NULL) 732 { 733 if ((buf=BUF_MEM_new()) == NULL) 734 { 735 PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_BIO_LIB); 736 goto err; 737 } 738 for (i=0; i<sk_PKCS7_SIGNER_INFO_num(si_sk); i++) 739 { 740 si=sk_PKCS7_SIGNER_INFO_value(si_sk,i); 741 if (si->pkey == NULL) continue; 742 743 j=OBJ_obj2nid(si->digest_alg->algorithm); 744 745 btmp=bio; 746 747 btmp = PKCS7_find_digest(&mdc, btmp, j); 748 749 if (btmp == NULL) 750 goto err; 751 752 /* We now have the EVP_MD_CTX, lets do the 753 * signing. */ 754 EVP_MD_CTX_copy_ex(&ctx_tmp,mdc); 755 if (!BUF_MEM_grow_clean(buf,EVP_PKEY_size(si->pkey))) 756 { 757 PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_BIO_LIB); 758 goto err; 759 } 760 761 sk=si->auth_attr; 762 763 /* If there are attributes, we add the digest 764 * attribute and only sign the attributes */ 765 if ((sk != NULL) && (sk_X509_ATTRIBUTE_num(sk) != 0)) 766 { 767 unsigned char md_data[EVP_MAX_MD_SIZE], *abuf=NULL; 768 unsigned int md_len, alen; 769 ASN1_OCTET_STRING *digest; 770 ASN1_UTCTIME *sign_time; 771 const EVP_MD *md_tmp; 772 773 /* Add signing time if not already present */ 774 if (!PKCS7_get_signed_attribute(si, 775 NID_pkcs9_signingTime)) 776 { 777 if (!(sign_time=X509_gmtime_adj(NULL,0))) 778 { 779 PKCS7err(PKCS7_F_PKCS7_DATAFINAL, 780 ERR_R_MALLOC_FAILURE); 781 goto err; 782 } 783 if (!PKCS7_add_signed_attribute(si, 784 NID_pkcs9_signingTime, 785 V_ASN1_UTCTIME,sign_time)) 786 { 787 M_ASN1_UTCTIME_free(sign_time); 788 goto err; 789 } 790 } 791 792 /* Add digest */ 793 md_tmp=EVP_MD_CTX_md(&ctx_tmp); 794 EVP_DigestFinal_ex(&ctx_tmp,md_data,&md_len); 795 if (!(digest=M_ASN1_OCTET_STRING_new())) 796 { 797 PKCS7err(PKCS7_F_PKCS7_DATAFINAL, 798 ERR_R_MALLOC_FAILURE); 799 goto err; 800 } 801 if (!M_ASN1_OCTET_STRING_set(digest,md_data, 802 md_len)) 803 { 804 PKCS7err(PKCS7_F_PKCS7_DATAFINAL, 805 ERR_R_MALLOC_FAILURE); 806 M_ASN1_OCTET_STRING_free(digest); 807 goto err; 808 } 809 if (!PKCS7_add_signed_attribute(si, 810 NID_pkcs9_messageDigest, 811 V_ASN1_OCTET_STRING,digest)) 812 { 813 M_ASN1_OCTET_STRING_free(digest); 814 goto err; 815 } 816 817 /* Now sign the attributes */ 818 EVP_SignInit_ex(&ctx_tmp,md_tmp,NULL); 819 alen = ASN1_item_i2d((ASN1_VALUE *)sk,&abuf, 820 ASN1_ITEM_rptr(PKCS7_ATTR_SIGN)); 821 if(!abuf) goto err; 822 EVP_SignUpdate(&ctx_tmp,abuf,alen); 823 OPENSSL_free(abuf); 824 } 825 826#ifndef OPENSSL_NO_DSA 827 if (si->pkey->type == EVP_PKEY_DSA) 828 ctx_tmp.digest=EVP_dss1(); 829#endif 830#ifndef OPENSSL_NO_ECDSA 831 if (si->pkey->type == EVP_PKEY_EC) 832 ctx_tmp.digest=EVP_ecdsa(); 833#endif 834 835 if (!EVP_SignFinal(&ctx_tmp,(unsigned char *)buf->data, 836 (unsigned int *)&buf->length,si->pkey)) 837 { 838 PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_EVP_LIB); 839 goto err; 840 } 841 if (!ASN1_STRING_set(si->enc_digest, 842 (unsigned char *)buf->data,buf->length)) 843 { 844 PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_ASN1_LIB); 845 goto err; 846 } 847 } 848 } 849 else if (i == NID_pkcs7_digest) 850 { 851 unsigned char md_data[EVP_MAX_MD_SIZE]; 852 unsigned int md_len; 853 if (!PKCS7_find_digest(&mdc, bio, 854 OBJ_obj2nid(p7->d.digest->md->algorithm))) 855 goto err; 856 EVP_DigestFinal_ex(mdc,md_data,&md_len); 857 M_ASN1_OCTET_STRING_set(p7->d.digest->digest, md_data, md_len); 858 } 859 860 if (!PKCS7_is_detached(p7)) { 861 /* 862 * NOTE(emilia): I think we only reach os == NULL here because detached 863 * digested data support is broken. 864 */ 865 if (os == NULL) 866 goto err; 867 btmp=BIO_find_type(bio,BIO_TYPE_MEM); 868 if (btmp == NULL) 869 { 870 PKCS7err(PKCS7_F_PKCS7_DATAFINAL,PKCS7_R_UNABLE_TO_FIND_MEM_BIO); 871 goto err; 872 } 873 BIO_get_mem_ptr(btmp,&buf_mem); 874 /* Mark the BIO read only then we can use its copy of the data 875 * instead of making an extra copy. 876 */ 877 BIO_set_flags(btmp, BIO_FLAGS_MEM_RDONLY); 878 BIO_set_mem_eof_return(btmp, 0); 879 os->data = (unsigned char *)buf_mem->data; 880 os->length = buf_mem->length; 881#if 0 882 M_ASN1_OCTET_STRING_set(os, 883 (unsigned char *)buf_mem->data,buf_mem->length); 884#endif 885 } 886 ret=1; 887err: 888 EVP_MD_CTX_cleanup(&ctx_tmp); 889 if (buf != NULL) BUF_MEM_free(buf); 890 return(ret); 891 } 892 893int PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx, BIO *bio, 894 PKCS7 *p7, PKCS7_SIGNER_INFO *si) 895 { 896 PKCS7_ISSUER_AND_SERIAL *ias; 897 int ret=0,i; 898 STACK_OF(X509) *cert; 899 X509 *x509; 900 901 if (p7 == NULL) { 902 PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, PKCS7_R_INVALID_NULL_POINTER); 903 return 0; 904 } 905 906 if (p7->d.ptr == NULL) { 907 PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, PKCS7_R_NO_CONTENT); 908 return 0; 909 } 910 911 if (PKCS7_type_is_signed(p7)) 912 { 913 cert=p7->d.sign->cert; 914 } 915 else if (PKCS7_type_is_signedAndEnveloped(p7)) 916 { 917 cert=p7->d.signed_and_enveloped->cert; 918 } 919 else 920 { 921 PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,PKCS7_R_WRONG_PKCS7_TYPE); 922 goto err; 923 } 924 /* XXXXXXXXXXXXXXXXXXXXXXX */ 925 ias=si->issuer_and_serial; 926 927 x509=X509_find_by_issuer_and_serial(cert,ias->issuer,ias->serial); 928 929 /* were we able to find the cert in passed to us */ 930 if (x509 == NULL) 931 { 932 PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,PKCS7_R_UNABLE_TO_FIND_CERTIFICATE); 933 goto err; 934 } 935 936 /* Lets verify */ 937 if(!X509_STORE_CTX_init(ctx,cert_store,x509,cert)) 938 { 939 PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,ERR_R_X509_LIB); 940 goto err; 941 } 942 X509_STORE_CTX_set_purpose(ctx, X509_PURPOSE_SMIME_SIGN); 943 i=X509_verify_cert(ctx); 944 if (i <= 0) 945 { 946 PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,ERR_R_X509_LIB); 947 X509_STORE_CTX_cleanup(ctx); 948 goto err; 949 } 950 X509_STORE_CTX_cleanup(ctx); 951 952 return PKCS7_signatureVerify(bio, p7, si, x509); 953 err: 954 return ret; 955 } 956 957int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si, 958 X509 *x509) 959 { 960 ASN1_OCTET_STRING *os; 961 EVP_MD_CTX mdc_tmp,*mdc; 962 int ret=0,i; 963 int md_type; 964 STACK_OF(X509_ATTRIBUTE) *sk; 965 BIO *btmp; 966 EVP_PKEY *pkey; 967 968 EVP_MD_CTX_init(&mdc_tmp); 969 970 if (!PKCS7_type_is_signed(p7) && 971 !PKCS7_type_is_signedAndEnveloped(p7)) { 972 PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, 973 PKCS7_R_WRONG_PKCS7_TYPE); 974 goto err; 975 } 976 977 md_type=OBJ_obj2nid(si->digest_alg->algorithm); 978 979 btmp=bio; 980 for (;;) 981 { 982 if ((btmp == NULL) || 983 ((btmp=BIO_find_type(btmp,BIO_TYPE_MD)) == NULL)) 984 { 985 PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, 986 PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST); 987 goto err; 988 } 989 BIO_get_md_ctx(btmp,&mdc); 990 if (mdc == NULL) 991 { 992 PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, 993 ERR_R_INTERNAL_ERROR); 994 goto err; 995 } 996 if (EVP_MD_CTX_type(mdc) == md_type) 997 break; 998 /* Workaround for some broken clients that put the signature 999 * OID instead of the digest OID in digest_alg->algorithm 1000 */ 1001 if (EVP_MD_pkey_type(EVP_MD_CTX_md(mdc)) == md_type) 1002 break; 1003 btmp=BIO_next(btmp); 1004 } 1005 1006 /* mdc is the digest ctx that we want, unless there are attributes, 1007 * in which case the digest is the signed attributes */ 1008 EVP_MD_CTX_copy_ex(&mdc_tmp,mdc); 1009 1010 sk=si->auth_attr; 1011 if ((sk != NULL) && (sk_X509_ATTRIBUTE_num(sk) != 0)) 1012 { 1013 unsigned char md_dat[EVP_MAX_MD_SIZE], *abuf = NULL; 1014 unsigned int md_len, alen; 1015 ASN1_OCTET_STRING *message_digest; 1016 1017 EVP_DigestFinal_ex(&mdc_tmp,md_dat,&md_len); 1018 message_digest=PKCS7_digest_from_attributes(sk); 1019 if (!message_digest) 1020 { 1021 PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, 1022 PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST); 1023 goto err; 1024 } 1025 if ((message_digest->length != (int)md_len) || 1026 (memcmp(message_digest->data,md_dat,md_len))) 1027 { 1028#if 0 1029{ 1030int ii; 1031for (ii=0; ii<message_digest->length; ii++) 1032 printf("%02X",message_digest->data[ii]); printf(" sent\n"); 1033for (ii=0; ii<md_len; ii++) printf("%02X",md_dat[ii]); printf(" calc\n"); 1034} 1035#endif 1036 PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, 1037 PKCS7_R_DIGEST_FAILURE); 1038 ret= -1; 1039 goto err; 1040 } 1041 1042 EVP_VerifyInit_ex(&mdc_tmp,EVP_get_digestbynid(md_type), NULL); 1043 1044 alen = ASN1_item_i2d((ASN1_VALUE *)sk, &abuf, 1045 ASN1_ITEM_rptr(PKCS7_ATTR_VERIFY)); 1046 EVP_VerifyUpdate(&mdc_tmp, abuf, alen); 1047 1048 OPENSSL_free(abuf); 1049 } 1050 1051 os=si->enc_digest; 1052 pkey = X509_get_pubkey(x509); 1053 if (!pkey) 1054 { 1055 ret = -1; 1056 goto err; 1057 } 1058#ifndef OPENSSL_NO_DSA 1059 if(pkey->type == EVP_PKEY_DSA) mdc_tmp.digest=EVP_dss1(); 1060#endif 1061#ifndef OPENSSL_NO_ECDSA 1062 if (pkey->type == EVP_PKEY_EC) mdc_tmp.digest=EVP_ecdsa(); 1063#endif 1064 1065 i=EVP_VerifyFinal(&mdc_tmp,os->data,os->length, pkey); 1066 EVP_PKEY_free(pkey); 1067 if (i <= 0) 1068 { 1069 PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, 1070 PKCS7_R_SIGNATURE_FAILURE); 1071 ret= -1; 1072 goto err; 1073 } 1074 else 1075 ret=1; 1076err: 1077 EVP_MD_CTX_cleanup(&mdc_tmp); 1078 return(ret); 1079 } 1080 1081PKCS7_ISSUER_AND_SERIAL *PKCS7_get_issuer_and_serial(PKCS7 *p7, int idx) 1082 { 1083 STACK_OF(PKCS7_RECIP_INFO) *rsk; 1084 PKCS7_RECIP_INFO *ri; 1085 int i; 1086 1087 i=OBJ_obj2nid(p7->type); 1088 if (i != NID_pkcs7_signedAndEnveloped) 1089 return NULL; 1090 if (p7->d.signed_and_enveloped == NULL) 1091 return NULL; 1092 rsk=p7->d.signed_and_enveloped->recipientinfo; 1093 if (rsk == NULL) 1094 return NULL; 1095 ri=sk_PKCS7_RECIP_INFO_value(rsk,0); 1096 if (sk_PKCS7_RECIP_INFO_num(rsk) <= idx) return(NULL); 1097 ri=sk_PKCS7_RECIP_INFO_value(rsk,idx); 1098 return(ri->issuer_and_serial); 1099 } 1100 1101ASN1_TYPE *PKCS7_get_signed_attribute(PKCS7_SIGNER_INFO *si, int nid) 1102 { 1103 return(get_attribute(si->auth_attr,nid)); 1104 } 1105 1106ASN1_TYPE *PKCS7_get_attribute(PKCS7_SIGNER_INFO *si, int nid) 1107 { 1108 return(get_attribute(si->unauth_attr,nid)); 1109 } 1110 1111static ASN1_TYPE *get_attribute(STACK_OF(X509_ATTRIBUTE) *sk, int nid) 1112 { 1113 int i; 1114 X509_ATTRIBUTE *xa; 1115 ASN1_OBJECT *o; 1116 1117 o=OBJ_nid2obj(nid); 1118 if (!o || !sk) return(NULL); 1119 for (i=0; i<sk_X509_ATTRIBUTE_num(sk); i++) 1120 { 1121 xa=sk_X509_ATTRIBUTE_value(sk,i); 1122 if (OBJ_cmp(xa->object,o) == 0) 1123 { 1124 if (!xa->single && sk_ASN1_TYPE_num(xa->value.set)) 1125 return(sk_ASN1_TYPE_value(xa->value.set,0)); 1126 else 1127 return(NULL); 1128 } 1129 } 1130 return(NULL); 1131 } 1132 1133ASN1_OCTET_STRING *PKCS7_digest_from_attributes(STACK_OF(X509_ATTRIBUTE) *sk) 1134{ 1135 ASN1_TYPE *astype; 1136 if(!(astype = get_attribute(sk, NID_pkcs9_messageDigest))) return NULL; 1137 return astype->value.octet_string; 1138} 1139 1140int PKCS7_set_signed_attributes(PKCS7_SIGNER_INFO *p7si, 1141 STACK_OF(X509_ATTRIBUTE) *sk) 1142 { 1143 int i; 1144 1145 if (p7si->auth_attr != NULL) 1146 sk_X509_ATTRIBUTE_pop_free(p7si->auth_attr,X509_ATTRIBUTE_free); 1147 p7si->auth_attr=sk_X509_ATTRIBUTE_dup(sk); 1148 if (p7si->auth_attr == NULL) 1149 return 0; 1150 for (i=0; i<sk_X509_ATTRIBUTE_num(sk); i++) 1151 { 1152 if ((sk_X509_ATTRIBUTE_set(p7si->auth_attr,i, 1153 X509_ATTRIBUTE_dup(sk_X509_ATTRIBUTE_value(sk,i)))) 1154 == NULL) 1155 return(0); 1156 } 1157 return(1); 1158 } 1159 1160int PKCS7_set_attributes(PKCS7_SIGNER_INFO *p7si, STACK_OF(X509_ATTRIBUTE) *sk) 1161 { 1162 int i; 1163 1164 if (p7si->unauth_attr != NULL) 1165 sk_X509_ATTRIBUTE_pop_free(p7si->unauth_attr, 1166 X509_ATTRIBUTE_free); 1167 p7si->unauth_attr=sk_X509_ATTRIBUTE_dup(sk); 1168 if (p7si->unauth_attr == NULL) 1169 return 0; 1170 for (i=0; i<sk_X509_ATTRIBUTE_num(sk); i++) 1171 { 1172 if ((sk_X509_ATTRIBUTE_set(p7si->unauth_attr,i, 1173 X509_ATTRIBUTE_dup(sk_X509_ATTRIBUTE_value(sk,i)))) 1174 == NULL) 1175 return(0); 1176 } 1177 return(1); 1178 } 1179 1180int PKCS7_add_signed_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int atrtype, 1181 void *value) 1182 { 1183 return(add_attribute(&(p7si->auth_attr),nid,atrtype,value)); 1184 } 1185 1186int PKCS7_add_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int atrtype, 1187 void *value) 1188 { 1189 return(add_attribute(&(p7si->unauth_attr),nid,atrtype,value)); 1190 } 1191 1192static int add_attribute(STACK_OF(X509_ATTRIBUTE) **sk, int nid, int atrtype, 1193 void *value) 1194 { 1195 X509_ATTRIBUTE *attr=NULL; 1196 1197 if (*sk == NULL) 1198 { 1199 if (!(*sk = sk_X509_ATTRIBUTE_new_null())) 1200 return 0; 1201new_attrib: 1202 if (!(attr=X509_ATTRIBUTE_create(nid,atrtype,value))) 1203 return 0; 1204 if (!sk_X509_ATTRIBUTE_push(*sk,attr)) 1205 { 1206 X509_ATTRIBUTE_free(attr); 1207 return 0; 1208 } 1209 } 1210 else 1211 { 1212 int i; 1213 1214 for (i=0; i<sk_X509_ATTRIBUTE_num(*sk); i++) 1215 { 1216 attr=sk_X509_ATTRIBUTE_value(*sk,i); 1217 if (OBJ_obj2nid(attr->object) == nid) 1218 { 1219 X509_ATTRIBUTE_free(attr); 1220 attr=X509_ATTRIBUTE_create(nid,atrtype,value); 1221 if (attr == NULL) 1222 return 0; 1223 if (!sk_X509_ATTRIBUTE_set(*sk,i,attr)) 1224 { 1225 X509_ATTRIBUTE_free(attr); 1226 return 0; 1227 } 1228 goto end; 1229 } 1230 } 1231 goto new_attrib; 1232 } 1233end: 1234 return(1); 1235 } 1236 1237