pk7_doit.c revision 280268
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 /* We will be checking the signature */ 414 if (md_sk != NULL) 415 { 416 for (i=0; i<sk_X509_ALGOR_num(md_sk); i++) 417 { 418 xa=sk_X509_ALGOR_value(md_sk,i); 419 if ((btmp=BIO_new(BIO_f_md())) == NULL) 420 { 421 PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_BIO_LIB); 422 goto err; 423 } 424 425 j=OBJ_obj2nid(xa->algorithm); 426 evp_md=EVP_get_digestbynid(j); 427 if (evp_md == NULL) 428 { 429 PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNKNOWN_DIGEST_TYPE); 430 goto err; 431 } 432 433 BIO_set_md(btmp,evp_md); 434 if (out == NULL) 435 out=btmp; 436 else 437 BIO_push(out,btmp); 438 btmp=NULL; 439 } 440 } 441 442 if (evp_cipher != NULL) 443 { 444#if 0 445 unsigned char key[EVP_MAX_KEY_LENGTH]; 446 unsigned char iv[EVP_MAX_IV_LENGTH]; 447 unsigned char *p; 448 int keylen,ivlen; 449 int max; 450 X509_OBJECT ret; 451#endif 452 unsigned char *tkey = NULL; 453 int tkeylen; 454 int jj; 455 456 if ((etmp=BIO_new(BIO_f_cipher())) == NULL) 457 { 458 PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_BIO_LIB); 459 goto err; 460 } 461 462 /* It was encrypted, we need to decrypt the secret key 463 * with the private key */ 464 465 /* Find the recipientInfo which matches the passed certificate 466 * (if any) 467 */ 468 469 if (pcert) { 470 for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++) { 471 ri=sk_PKCS7_RECIP_INFO_value(rsk,i); 472 if (!pkcs7_cmp_ri(ri, pcert)) 473 break; 474 ri=NULL; 475 } 476 if (ri == NULL) { 477 PKCS7err(PKCS7_F_PKCS7_DATADECODE, 478 PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE); 479 goto err; 480 } 481 } 482 483 jj=EVP_PKEY_size(pkey); 484 tmp=(unsigned char *)OPENSSL_malloc(jj+10); 485 if (tmp == NULL) 486 { 487 PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_MALLOC_FAILURE); 488 goto err; 489 } 490 491 /* If we haven't got a certificate try each ri in turn */ 492 493 if (pcert == NULL) 494 { 495 /* Temporary storage in case EVP_PKEY_decrypt 496 * overwrites output buffer on error. 497 */ 498 unsigned char *tmp2; 499 tmp2 = OPENSSL_malloc(jj); 500 if (!tmp2) 501 goto err; 502 jj = -1; 503 /* Always attempt to decrypt all cases to avoid 504 * leaking timing information about a successful 505 * decrypt. 506 */ 507 for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++) 508 { 509 int tret; 510 ri=sk_PKCS7_RECIP_INFO_value(rsk,i); 511 tret=EVP_PKEY_decrypt(tmp2, 512 M_ASN1_STRING_data(ri->enc_key), 513 M_ASN1_STRING_length(ri->enc_key), 514 pkey); 515 if (tret > 0) 516 { 517 memcpy(tmp, tmp2, tret); 518 OPENSSL_cleanse(tmp2, tret); 519 jj = tret; 520 } 521 ERR_clear_error(); 522 } 523 OPENSSL_free(tmp2); 524 } 525 else 526 { 527 jj=EVP_PKEY_decrypt(tmp, 528 M_ASN1_STRING_data(ri->enc_key), 529 M_ASN1_STRING_length(ri->enc_key), pkey); 530 ERR_clear_error(); 531 } 532 533 evp_ctx=NULL; 534 BIO_get_cipher_ctx(etmp,&evp_ctx); 535 if (EVP_CipherInit_ex(evp_ctx,evp_cipher,NULL,NULL,NULL,0) <= 0) 536 goto err; 537 if (EVP_CIPHER_asn1_to_param(evp_ctx,enc_alg->parameter) < 0) 538 goto err; 539 /* Generate random key to counter MMA */ 540 tkeylen = EVP_CIPHER_CTX_key_length(evp_ctx); 541 tkey = OPENSSL_malloc(tkeylen); 542 if (!tkey) 543 goto err; 544 if (EVP_CIPHER_CTX_rand_key(evp_ctx, tkey) <= 0) 545 goto err; 546 /* If we have no key use random key */ 547 if (jj <= 0) 548 { 549 OPENSSL_free(tmp); 550 jj = tkeylen; 551 tmp = tkey; 552 tkey = NULL; 553 } 554 555 if (jj != tkeylen) { 556 /* Some S/MIME clients don't use the same key 557 * and effective key length. The key length is 558 * determined by the size of the decrypted RSA key. 559 */ 560 if(!EVP_CIPHER_CTX_set_key_length(evp_ctx, jj)) 561 { 562 /* As MMA defence use random key instead */ 563 OPENSSL_cleanse(tmp, jj); 564 OPENSSL_free(tmp); 565 jj = tkeylen; 566 tmp = tkey; 567 tkey = NULL; 568 } 569 } 570 ERR_clear_error(); 571 if (EVP_CipherInit_ex(evp_ctx,NULL,NULL,tmp,NULL,0) <= 0) 572 goto err; 573 574 OPENSSL_cleanse(tmp,jj); 575 576 if (tkey) 577 { 578 OPENSSL_cleanse(tkey, tkeylen); 579 OPENSSL_free(tkey); 580 } 581 582 if (out == NULL) 583 out=etmp; 584 else 585 BIO_push(out,etmp); 586 etmp=NULL; 587 } 588 589#if 1 590 if (PKCS7_is_detached(p7) || (in_bio != NULL)) 591 { 592 bio=in_bio; 593 } 594 else 595 { 596#if 0 597 bio=BIO_new(BIO_s_mem()); 598 /* We need to set this so that when we have read all 599 * the data, the encrypt BIO, if present, will read 600 * EOF and encode the last few bytes */ 601 BIO_set_mem_eof_return(bio,0); 602 603 if (data_body->length > 0) 604 BIO_write(bio,(char *)data_body->data,data_body->length); 605#else 606 if (data_body->length > 0) 607 bio = BIO_new_mem_buf(data_body->data,data_body->length); 608 else { 609 bio=BIO_new(BIO_s_mem()); 610 BIO_set_mem_eof_return(bio,0); 611 } 612 if (bio == NULL) 613 goto err; 614#endif 615 } 616 BIO_push(out,bio); 617 bio=NULL; 618#endif 619 if (0) 620 { 621err: 622 if (out != NULL) BIO_free_all(out); 623 if (btmp != NULL) BIO_free_all(btmp); 624 if (etmp != NULL) BIO_free_all(etmp); 625 if (bio != NULL) BIO_free_all(bio); 626 out=NULL; 627 } 628 if (tmp != NULL) 629 OPENSSL_free(tmp); 630 return(out); 631 } 632 633static BIO *PKCS7_find_digest(EVP_MD_CTX **pmd, BIO *bio, int nid) 634 { 635 for (;;) 636 { 637 bio=BIO_find_type(bio,BIO_TYPE_MD); 638 if (bio == NULL) 639 { 640 PKCS7err(PKCS7_F_PKCS7_FIND_DIGEST,PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST); 641 return NULL; 642 } 643 BIO_get_md_ctx(bio,pmd); 644 if (*pmd == NULL) 645 { 646 PKCS7err(PKCS7_F_PKCS7_FIND_DIGEST,ERR_R_INTERNAL_ERROR); 647 return NULL; 648 } 649 if (EVP_MD_CTX_type(*pmd) == nid) 650 return bio; 651 bio=BIO_next(bio); 652 } 653 return NULL; 654 } 655 656int PKCS7_dataFinal(PKCS7 *p7, BIO *bio) 657 { 658 int ret=0; 659 int i,j; 660 BIO *btmp; 661 BUF_MEM *buf_mem=NULL; 662 BUF_MEM *buf=NULL; 663 PKCS7_SIGNER_INFO *si; 664 EVP_MD_CTX *mdc,ctx_tmp; 665 STACK_OF(X509_ATTRIBUTE) *sk; 666 STACK_OF(PKCS7_SIGNER_INFO) *si_sk=NULL; 667 ASN1_OCTET_STRING *os=NULL; 668 669 if (p7 == NULL) { 670 PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_INVALID_NULL_POINTER); 671 return 0; 672 } 673 674 if (p7->d.ptr == NULL) { 675 PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_NO_CONTENT); 676 return 0; 677 } 678 679 EVP_MD_CTX_init(&ctx_tmp); 680 i=OBJ_obj2nid(p7->type); 681 p7->state=PKCS7_S_HEADER; 682 683 switch (i) 684 { 685 case NID_pkcs7_signedAndEnveloped: 686 /* XXXXXXXXXXXXXXXX */ 687 si_sk=p7->d.signed_and_enveloped->signer_info; 688 if (!(os=M_ASN1_OCTET_STRING_new())) 689 { 690 PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_MALLOC_FAILURE); 691 goto err; 692 } 693 p7->d.signed_and_enveloped->enc_data->enc_data=os; 694 break; 695 case NID_pkcs7_enveloped: 696 /* XXXXXXXXXXXXXXXX */ 697 if (!(os=M_ASN1_OCTET_STRING_new())) 698 { 699 PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_MALLOC_FAILURE); 700 goto err; 701 } 702 p7->d.enveloped->enc_data->enc_data=os; 703 break; 704 case NID_pkcs7_signed: 705 si_sk=p7->d.sign->signer_info; 706 os=PKCS7_get_octet_string(p7->d.sign->contents); 707 /* If detached data then the content is excluded */ 708 if(PKCS7_type_is_data(p7->d.sign->contents) && p7->detached) { 709 M_ASN1_OCTET_STRING_free(os); 710 os = NULL; 711 p7->d.sign->contents->d.data = NULL; 712 } 713 break; 714 715 case NID_pkcs7_digest: 716 os=PKCS7_get_octet_string(p7->d.digest->contents); 717 /* If detached data then the content is excluded */ 718 if(PKCS7_type_is_data(p7->d.digest->contents) && p7->detached) 719 { 720 M_ASN1_OCTET_STRING_free(os); 721 os = NULL; 722 p7->d.digest->contents->d.data = NULL; 723 } 724 break; 725 726 } 727 728 if (si_sk != NULL) 729 { 730 if ((buf=BUF_MEM_new()) == NULL) 731 { 732 PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_BIO_LIB); 733 goto err; 734 } 735 for (i=0; i<sk_PKCS7_SIGNER_INFO_num(si_sk); i++) 736 { 737 si=sk_PKCS7_SIGNER_INFO_value(si_sk,i); 738 if (si->pkey == NULL) continue; 739 740 j=OBJ_obj2nid(si->digest_alg->algorithm); 741 742 btmp=bio; 743 744 btmp = PKCS7_find_digest(&mdc, btmp, j); 745 746 if (btmp == NULL) 747 goto err; 748 749 /* We now have the EVP_MD_CTX, lets do the 750 * signing. */ 751 EVP_MD_CTX_copy_ex(&ctx_tmp,mdc); 752 if (!BUF_MEM_grow_clean(buf,EVP_PKEY_size(si->pkey))) 753 { 754 PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_BIO_LIB); 755 goto err; 756 } 757 758 sk=si->auth_attr; 759 760 /* If there are attributes, we add the digest 761 * attribute and only sign the attributes */ 762 if ((sk != NULL) && (sk_X509_ATTRIBUTE_num(sk) != 0)) 763 { 764 unsigned char md_data[EVP_MAX_MD_SIZE], *abuf=NULL; 765 unsigned int md_len, alen; 766 ASN1_OCTET_STRING *digest; 767 ASN1_UTCTIME *sign_time; 768 const EVP_MD *md_tmp; 769 770 /* Add signing time if not already present */ 771 if (!PKCS7_get_signed_attribute(si, 772 NID_pkcs9_signingTime)) 773 { 774 if (!(sign_time=X509_gmtime_adj(NULL,0))) 775 { 776 PKCS7err(PKCS7_F_PKCS7_DATAFINAL, 777 ERR_R_MALLOC_FAILURE); 778 goto err; 779 } 780 if (!PKCS7_add_signed_attribute(si, 781 NID_pkcs9_signingTime, 782 V_ASN1_UTCTIME,sign_time)) 783 { 784 M_ASN1_UTCTIME_free(sign_time); 785 goto err; 786 } 787 } 788 789 /* Add digest */ 790 md_tmp=EVP_MD_CTX_md(&ctx_tmp); 791 EVP_DigestFinal_ex(&ctx_tmp,md_data,&md_len); 792 if (!(digest=M_ASN1_OCTET_STRING_new())) 793 { 794 PKCS7err(PKCS7_F_PKCS7_DATAFINAL, 795 ERR_R_MALLOC_FAILURE); 796 goto err; 797 } 798 if (!M_ASN1_OCTET_STRING_set(digest,md_data, 799 md_len)) 800 { 801 PKCS7err(PKCS7_F_PKCS7_DATAFINAL, 802 ERR_R_MALLOC_FAILURE); 803 M_ASN1_OCTET_STRING_free(digest); 804 goto err; 805 } 806 if (!PKCS7_add_signed_attribute(si, 807 NID_pkcs9_messageDigest, 808 V_ASN1_OCTET_STRING,digest)) 809 { 810 M_ASN1_OCTET_STRING_free(digest); 811 goto err; 812 } 813 814 /* Now sign the attributes */ 815 EVP_SignInit_ex(&ctx_tmp,md_tmp,NULL); 816 alen = ASN1_item_i2d((ASN1_VALUE *)sk,&abuf, 817 ASN1_ITEM_rptr(PKCS7_ATTR_SIGN)); 818 if(!abuf) goto err; 819 EVP_SignUpdate(&ctx_tmp,abuf,alen); 820 OPENSSL_free(abuf); 821 } 822 823#ifndef OPENSSL_NO_DSA 824 if (si->pkey->type == EVP_PKEY_DSA) 825 ctx_tmp.digest=EVP_dss1(); 826#endif 827#ifndef OPENSSL_NO_ECDSA 828 if (si->pkey->type == EVP_PKEY_EC) 829 ctx_tmp.digest=EVP_ecdsa(); 830#endif 831 832 if (!EVP_SignFinal(&ctx_tmp,(unsigned char *)buf->data, 833 (unsigned int *)&buf->length,si->pkey)) 834 { 835 PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_EVP_LIB); 836 goto err; 837 } 838 if (!ASN1_STRING_set(si->enc_digest, 839 (unsigned char *)buf->data,buf->length)) 840 { 841 PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_ASN1_LIB); 842 goto err; 843 } 844 } 845 } 846 else if (i == NID_pkcs7_digest) 847 { 848 unsigned char md_data[EVP_MAX_MD_SIZE]; 849 unsigned int md_len; 850 if (!PKCS7_find_digest(&mdc, bio, 851 OBJ_obj2nid(p7->d.digest->md->algorithm))) 852 goto err; 853 EVP_DigestFinal_ex(mdc,md_data,&md_len); 854 M_ASN1_OCTET_STRING_set(p7->d.digest->digest, md_data, md_len); 855 } 856 857 if (!PKCS7_is_detached(p7)) { 858 /* 859 * NOTE(emilia): I think we only reach os == NULL here because detached 860 * digested data support is broken. 861 */ 862 if (os == NULL) 863 goto err; 864 btmp=BIO_find_type(bio,BIO_TYPE_MEM); 865 if (btmp == NULL) 866 { 867 PKCS7err(PKCS7_F_PKCS7_DATAFINAL,PKCS7_R_UNABLE_TO_FIND_MEM_BIO); 868 goto err; 869 } 870 BIO_get_mem_ptr(btmp,&buf_mem); 871 /* Mark the BIO read only then we can use its copy of the data 872 * instead of making an extra copy. 873 */ 874 BIO_set_flags(btmp, BIO_FLAGS_MEM_RDONLY); 875 BIO_set_mem_eof_return(btmp, 0); 876 os->data = (unsigned char *)buf_mem->data; 877 os->length = buf_mem->length; 878#if 0 879 M_ASN1_OCTET_STRING_set(os, 880 (unsigned char *)buf_mem->data,buf_mem->length); 881#endif 882 } 883 ret=1; 884err: 885 EVP_MD_CTX_cleanup(&ctx_tmp); 886 if (buf != NULL) BUF_MEM_free(buf); 887 return(ret); 888 } 889 890int PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx, BIO *bio, 891 PKCS7 *p7, PKCS7_SIGNER_INFO *si) 892 { 893 PKCS7_ISSUER_AND_SERIAL *ias; 894 int ret=0,i; 895 STACK_OF(X509) *cert; 896 X509 *x509; 897 898 if (p7 == NULL) { 899 PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, PKCS7_R_INVALID_NULL_POINTER); 900 return 0; 901 } 902 903 if (p7->d.ptr == NULL) { 904 PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, PKCS7_R_NO_CONTENT); 905 return 0; 906 } 907 908 if (PKCS7_type_is_signed(p7)) 909 { 910 cert=p7->d.sign->cert; 911 } 912 else if (PKCS7_type_is_signedAndEnveloped(p7)) 913 { 914 cert=p7->d.signed_and_enveloped->cert; 915 } 916 else 917 { 918 PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,PKCS7_R_WRONG_PKCS7_TYPE); 919 goto err; 920 } 921 /* XXXXXXXXXXXXXXXXXXXXXXX */ 922 ias=si->issuer_and_serial; 923 924 x509=X509_find_by_issuer_and_serial(cert,ias->issuer,ias->serial); 925 926 /* were we able to find the cert in passed to us */ 927 if (x509 == NULL) 928 { 929 PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,PKCS7_R_UNABLE_TO_FIND_CERTIFICATE); 930 goto err; 931 } 932 933 /* Lets verify */ 934 if(!X509_STORE_CTX_init(ctx,cert_store,x509,cert)) 935 { 936 PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,ERR_R_X509_LIB); 937 goto err; 938 } 939 X509_STORE_CTX_set_purpose(ctx, X509_PURPOSE_SMIME_SIGN); 940 i=X509_verify_cert(ctx); 941 if (i <= 0) 942 { 943 PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,ERR_R_X509_LIB); 944 X509_STORE_CTX_cleanup(ctx); 945 goto err; 946 } 947 X509_STORE_CTX_cleanup(ctx); 948 949 return PKCS7_signatureVerify(bio, p7, si, x509); 950 err: 951 return ret; 952 } 953 954int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si, 955 X509 *x509) 956 { 957 ASN1_OCTET_STRING *os; 958 EVP_MD_CTX mdc_tmp,*mdc; 959 int ret=0,i; 960 int md_type; 961 STACK_OF(X509_ATTRIBUTE) *sk; 962 BIO *btmp; 963 EVP_PKEY *pkey; 964 965 EVP_MD_CTX_init(&mdc_tmp); 966 967 if (!PKCS7_type_is_signed(p7) && 968 !PKCS7_type_is_signedAndEnveloped(p7)) { 969 PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, 970 PKCS7_R_WRONG_PKCS7_TYPE); 971 goto err; 972 } 973 974 md_type=OBJ_obj2nid(si->digest_alg->algorithm); 975 976 btmp=bio; 977 for (;;) 978 { 979 if ((btmp == NULL) || 980 ((btmp=BIO_find_type(btmp,BIO_TYPE_MD)) == NULL)) 981 { 982 PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, 983 PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST); 984 goto err; 985 } 986 BIO_get_md_ctx(btmp,&mdc); 987 if (mdc == NULL) 988 { 989 PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, 990 ERR_R_INTERNAL_ERROR); 991 goto err; 992 } 993 if (EVP_MD_CTX_type(mdc) == md_type) 994 break; 995 /* Workaround for some broken clients that put the signature 996 * OID instead of the digest OID in digest_alg->algorithm 997 */ 998 if (EVP_MD_pkey_type(EVP_MD_CTX_md(mdc)) == md_type) 999 break; 1000 btmp=BIO_next(btmp); 1001 } 1002 1003 /* mdc is the digest ctx that we want, unless there are attributes, 1004 * in which case the digest is the signed attributes */ 1005 EVP_MD_CTX_copy_ex(&mdc_tmp,mdc); 1006 1007 sk=si->auth_attr; 1008 if ((sk != NULL) && (sk_X509_ATTRIBUTE_num(sk) != 0)) 1009 { 1010 unsigned char md_dat[EVP_MAX_MD_SIZE], *abuf = NULL; 1011 unsigned int md_len, alen; 1012 ASN1_OCTET_STRING *message_digest; 1013 1014 EVP_DigestFinal_ex(&mdc_tmp,md_dat,&md_len); 1015 message_digest=PKCS7_digest_from_attributes(sk); 1016 if (!message_digest) 1017 { 1018 PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, 1019 PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST); 1020 goto err; 1021 } 1022 if ((message_digest->length != (int)md_len) || 1023 (memcmp(message_digest->data,md_dat,md_len))) 1024 { 1025#if 0 1026{ 1027int ii; 1028for (ii=0; ii<message_digest->length; ii++) 1029 printf("%02X",message_digest->data[ii]); printf(" sent\n"); 1030for (ii=0; ii<md_len; ii++) printf("%02X",md_dat[ii]); printf(" calc\n"); 1031} 1032#endif 1033 PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, 1034 PKCS7_R_DIGEST_FAILURE); 1035 ret= -1; 1036 goto err; 1037 } 1038 1039 EVP_VerifyInit_ex(&mdc_tmp,EVP_get_digestbynid(md_type), NULL); 1040 1041 alen = ASN1_item_i2d((ASN1_VALUE *)sk, &abuf, 1042 ASN1_ITEM_rptr(PKCS7_ATTR_VERIFY)); 1043 EVP_VerifyUpdate(&mdc_tmp, abuf, alen); 1044 1045 OPENSSL_free(abuf); 1046 } 1047 1048 os=si->enc_digest; 1049 pkey = X509_get_pubkey(x509); 1050 if (!pkey) 1051 { 1052 ret = -1; 1053 goto err; 1054 } 1055#ifndef OPENSSL_NO_DSA 1056 if(pkey->type == EVP_PKEY_DSA) mdc_tmp.digest=EVP_dss1(); 1057#endif 1058#ifndef OPENSSL_NO_ECDSA 1059 if (pkey->type == EVP_PKEY_EC) mdc_tmp.digest=EVP_ecdsa(); 1060#endif 1061 1062 i=EVP_VerifyFinal(&mdc_tmp,os->data,os->length, pkey); 1063 EVP_PKEY_free(pkey); 1064 if (i <= 0) 1065 { 1066 PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, 1067 PKCS7_R_SIGNATURE_FAILURE); 1068 ret= -1; 1069 goto err; 1070 } 1071 else 1072 ret=1; 1073err: 1074 EVP_MD_CTX_cleanup(&mdc_tmp); 1075 return(ret); 1076 } 1077 1078PKCS7_ISSUER_AND_SERIAL *PKCS7_get_issuer_and_serial(PKCS7 *p7, int idx) 1079 { 1080 STACK_OF(PKCS7_RECIP_INFO) *rsk; 1081 PKCS7_RECIP_INFO *ri; 1082 int i; 1083 1084 i=OBJ_obj2nid(p7->type); 1085 if (i != NID_pkcs7_signedAndEnveloped) 1086 return NULL; 1087 if (p7->d.signed_and_enveloped == NULL) 1088 return NULL; 1089 rsk=p7->d.signed_and_enveloped->recipientinfo; 1090 if (rsk == NULL) 1091 return NULL; 1092 ri=sk_PKCS7_RECIP_INFO_value(rsk,0); 1093 if (sk_PKCS7_RECIP_INFO_num(rsk) <= idx) return(NULL); 1094 ri=sk_PKCS7_RECIP_INFO_value(rsk,idx); 1095 return(ri->issuer_and_serial); 1096 } 1097 1098ASN1_TYPE *PKCS7_get_signed_attribute(PKCS7_SIGNER_INFO *si, int nid) 1099 { 1100 return(get_attribute(si->auth_attr,nid)); 1101 } 1102 1103ASN1_TYPE *PKCS7_get_attribute(PKCS7_SIGNER_INFO *si, int nid) 1104 { 1105 return(get_attribute(si->unauth_attr,nid)); 1106 } 1107 1108static ASN1_TYPE *get_attribute(STACK_OF(X509_ATTRIBUTE) *sk, int nid) 1109 { 1110 int i; 1111 X509_ATTRIBUTE *xa; 1112 ASN1_OBJECT *o; 1113 1114 o=OBJ_nid2obj(nid); 1115 if (!o || !sk) return(NULL); 1116 for (i=0; i<sk_X509_ATTRIBUTE_num(sk); i++) 1117 { 1118 xa=sk_X509_ATTRIBUTE_value(sk,i); 1119 if (OBJ_cmp(xa->object,o) == 0) 1120 { 1121 if (!xa->single && sk_ASN1_TYPE_num(xa->value.set)) 1122 return(sk_ASN1_TYPE_value(xa->value.set,0)); 1123 else 1124 return(NULL); 1125 } 1126 } 1127 return(NULL); 1128 } 1129 1130ASN1_OCTET_STRING *PKCS7_digest_from_attributes(STACK_OF(X509_ATTRIBUTE) *sk) 1131{ 1132 ASN1_TYPE *astype; 1133 if(!(astype = get_attribute(sk, NID_pkcs9_messageDigest))) return NULL; 1134 return astype->value.octet_string; 1135} 1136 1137int PKCS7_set_signed_attributes(PKCS7_SIGNER_INFO *p7si, 1138 STACK_OF(X509_ATTRIBUTE) *sk) 1139 { 1140 int i; 1141 1142 if (p7si->auth_attr != NULL) 1143 sk_X509_ATTRIBUTE_pop_free(p7si->auth_attr,X509_ATTRIBUTE_free); 1144 p7si->auth_attr=sk_X509_ATTRIBUTE_dup(sk); 1145 if (p7si->auth_attr == NULL) 1146 return 0; 1147 for (i=0; i<sk_X509_ATTRIBUTE_num(sk); i++) 1148 { 1149 if ((sk_X509_ATTRIBUTE_set(p7si->auth_attr,i, 1150 X509_ATTRIBUTE_dup(sk_X509_ATTRIBUTE_value(sk,i)))) 1151 == NULL) 1152 return(0); 1153 } 1154 return(1); 1155 } 1156 1157int PKCS7_set_attributes(PKCS7_SIGNER_INFO *p7si, STACK_OF(X509_ATTRIBUTE) *sk) 1158 { 1159 int i; 1160 1161 if (p7si->unauth_attr != NULL) 1162 sk_X509_ATTRIBUTE_pop_free(p7si->unauth_attr, 1163 X509_ATTRIBUTE_free); 1164 p7si->unauth_attr=sk_X509_ATTRIBUTE_dup(sk); 1165 if (p7si->unauth_attr == NULL) 1166 return 0; 1167 for (i=0; i<sk_X509_ATTRIBUTE_num(sk); i++) 1168 { 1169 if ((sk_X509_ATTRIBUTE_set(p7si->unauth_attr,i, 1170 X509_ATTRIBUTE_dup(sk_X509_ATTRIBUTE_value(sk,i)))) 1171 == NULL) 1172 return(0); 1173 } 1174 return(1); 1175 } 1176 1177int PKCS7_add_signed_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int atrtype, 1178 void *value) 1179 { 1180 return(add_attribute(&(p7si->auth_attr),nid,atrtype,value)); 1181 } 1182 1183int PKCS7_add_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int atrtype, 1184 void *value) 1185 { 1186 return(add_attribute(&(p7si->unauth_attr),nid,atrtype,value)); 1187 } 1188 1189static int add_attribute(STACK_OF(X509_ATTRIBUTE) **sk, int nid, int atrtype, 1190 void *value) 1191 { 1192 X509_ATTRIBUTE *attr=NULL; 1193 1194 if (*sk == NULL) 1195 { 1196 if (!(*sk = sk_X509_ATTRIBUTE_new_null())) 1197 return 0; 1198new_attrib: 1199 if (!(attr=X509_ATTRIBUTE_create(nid,atrtype,value))) 1200 return 0; 1201 if (!sk_X509_ATTRIBUTE_push(*sk,attr)) 1202 { 1203 X509_ATTRIBUTE_free(attr); 1204 return 0; 1205 } 1206 } 1207 else 1208 { 1209 int i; 1210 1211 for (i=0; i<sk_X509_ATTRIBUTE_num(*sk); i++) 1212 { 1213 attr=sk_X509_ATTRIBUTE_value(*sk,i); 1214 if (OBJ_obj2nid(attr->object) == nid) 1215 { 1216 X509_ATTRIBUTE_free(attr); 1217 attr=X509_ATTRIBUTE_create(nid,atrtype,value); 1218 if (attr == NULL) 1219 return 0; 1220 if (!sk_X509_ATTRIBUTE_set(*sk,i,attr)) 1221 { 1222 X509_ATTRIBUTE_free(attr); 1223 return 0; 1224 } 1225 goto end; 1226 } 1227 } 1228 goto new_attrib; 1229 } 1230end: 1231 return(1); 1232 } 1233 1234