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 i=OBJ_obj2nid(p7->type); 155 p7->state=PKCS7_S_HEADER; 156 157 switch (i) 158 { 159 case NID_pkcs7_signed: 160 md_sk=p7->d.sign->md_algs; 161 os = PKCS7_get_octet_string(p7->d.sign->contents); 162 break; 163 case NID_pkcs7_signedAndEnveloped: 164 rsk=p7->d.signed_and_enveloped->recipientinfo; 165 md_sk=p7->d.signed_and_enveloped->md_algs; 166 xalg=p7->d.signed_and_enveloped->enc_data->algorithm; 167 evp_cipher=p7->d.signed_and_enveloped->enc_data->cipher; 168 if (evp_cipher == NULL) 169 { 170 PKCS7err(PKCS7_F_PKCS7_DATAINIT, 171 PKCS7_R_CIPHER_NOT_INITIALIZED); 172 goto err; 173 } 174 break; 175 case NID_pkcs7_enveloped: 176 rsk=p7->d.enveloped->recipientinfo; 177 xalg=p7->d.enveloped->enc_data->algorithm; 178 evp_cipher=p7->d.enveloped->enc_data->cipher; 179 if (evp_cipher == NULL) 180 { 181 PKCS7err(PKCS7_F_PKCS7_DATAINIT, 182 PKCS7_R_CIPHER_NOT_INITIALIZED); 183 goto err; 184 } 185 break; 186 case NID_pkcs7_digest: 187 xa = p7->d.digest->md; 188 os = PKCS7_get_octet_string(p7->d.digest->contents); 189 break; 190 default: 191 PKCS7err(PKCS7_F_PKCS7_DATAINIT,PKCS7_R_UNSUPPORTED_CONTENT_TYPE); 192 goto err; 193 } 194 195 for (i=0; i<sk_X509_ALGOR_num(md_sk); i++) 196 if (!PKCS7_bio_add_digest(&out, sk_X509_ALGOR_value(md_sk, i))) 197 goto err; 198 199 if (xa && !PKCS7_bio_add_digest(&out, xa)) 200 goto err; 201 202 if (evp_cipher != NULL) 203 { 204 unsigned char key[EVP_MAX_KEY_LENGTH]; 205 unsigned char iv[EVP_MAX_IV_LENGTH]; 206 int keylen,ivlen; 207 int jj,max; 208 unsigned char *tmp; 209 EVP_CIPHER_CTX *ctx; 210 211 if ((btmp=BIO_new(BIO_f_cipher())) == NULL) 212 { 213 PKCS7err(PKCS7_F_PKCS7_DATAINIT,ERR_R_BIO_LIB); 214 goto err; 215 } 216 BIO_get_cipher_ctx(btmp, &ctx); 217 keylen=EVP_CIPHER_key_length(evp_cipher); 218 ivlen=EVP_CIPHER_iv_length(evp_cipher); 219 xalg->algorithm = OBJ_nid2obj(EVP_CIPHER_type(evp_cipher)); 220 if (ivlen > 0) 221 if (RAND_pseudo_bytes(iv,ivlen) <= 0) 222 goto err; 223 if (EVP_CipherInit_ex(ctx, evp_cipher, NULL, NULL, NULL, 1)<=0) 224 goto err; 225 if (EVP_CIPHER_CTX_rand_key(ctx, key) <= 0) 226 goto err; 227 if (EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, 1) <= 0) 228 goto err; 229 230 if (ivlen > 0) { 231 if (xalg->parameter == NULL) { 232 xalg->parameter = ASN1_TYPE_new(); 233 if (xalg->parameter == NULL) 234 goto err; 235 } 236 if(EVP_CIPHER_param_to_asn1(ctx, xalg->parameter) < 0) 237 goto err; 238 } 239 240 /* Lets do the pub key stuff :-) */ 241 max=0; 242 for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++) 243 { 244 ri=sk_PKCS7_RECIP_INFO_value(rsk,i); 245 if (ri->cert == NULL) 246 { 247 PKCS7err(PKCS7_F_PKCS7_DATAINIT,PKCS7_R_MISSING_CERIPEND_INFO); 248 goto err; 249 } 250 if ((pkey=X509_get_pubkey(ri->cert)) == NULL) 251 goto err; 252 jj=EVP_PKEY_size(pkey); 253 EVP_PKEY_free(pkey); 254 if (max < jj) max=jj; 255 } 256 if ((tmp=(unsigned char *)OPENSSL_malloc(max)) == NULL) 257 { 258 PKCS7err(PKCS7_F_PKCS7_DATAINIT,ERR_R_MALLOC_FAILURE); 259 goto err; 260 } 261 for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++) 262 { 263 ri=sk_PKCS7_RECIP_INFO_value(rsk,i); 264 if ((pkey=X509_get_pubkey(ri->cert)) == NULL) 265 goto err; 266 jj=EVP_PKEY_encrypt(tmp,key,keylen,pkey); 267 EVP_PKEY_free(pkey); 268 if (jj <= 0) 269 { 270 PKCS7err(PKCS7_F_PKCS7_DATAINIT,ERR_R_EVP_LIB); 271 OPENSSL_free(tmp); 272 goto err; 273 } 274 if (!M_ASN1_OCTET_STRING_set(ri->enc_key,tmp,jj)) 275 { 276 PKCS7err(PKCS7_F_PKCS7_DATAINIT, 277 ERR_R_MALLOC_FAILURE); 278 OPENSSL_free(tmp); 279 goto err; 280 } 281 } 282 OPENSSL_free(tmp); 283 OPENSSL_cleanse(key, keylen); 284 285 if (out == NULL) 286 out=btmp; 287 else 288 BIO_push(out,btmp); 289 btmp=NULL; 290 } 291 292 if (bio == NULL) 293 { 294 if (PKCS7_is_detached(p7)) 295 bio=BIO_new(BIO_s_null()); 296 else if (os && os->length > 0) 297 bio = BIO_new_mem_buf(os->data, os->length); 298 if(bio == NULL) 299 { 300 bio=BIO_new(BIO_s_mem()); 301 if (bio == NULL) 302 goto err; 303 BIO_set_mem_eof_return(bio,0); 304 } 305 } 306 BIO_push(out,bio); 307 bio=NULL; 308 if (0) 309 { 310err: 311 if (out != NULL) 312 BIO_free_all(out); 313 if (btmp != NULL) 314 BIO_free_all(btmp); 315 out=NULL; 316 } 317 return(out); 318 } 319 320static int pkcs7_cmp_ri(PKCS7_RECIP_INFO *ri, X509 *pcert) 321 { 322 int ret; 323 ret = X509_NAME_cmp(ri->issuer_and_serial->issuer, 324 pcert->cert_info->issuer); 325 if (ret) 326 return ret; 327 return M_ASN1_INTEGER_cmp(pcert->cert_info->serialNumber, 328 ri->issuer_and_serial->serial); 329 } 330 331/* int */ 332BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) 333 { 334 int i,j; 335 BIO *out=NULL,*btmp=NULL,*etmp=NULL,*bio=NULL; 336 unsigned char *tmp=NULL; 337 X509_ALGOR *xa; 338 ASN1_OCTET_STRING *data_body=NULL; 339 const EVP_MD *evp_md; 340 const EVP_CIPHER *evp_cipher=NULL; 341 EVP_CIPHER_CTX *evp_ctx=NULL; 342 X509_ALGOR *enc_alg=NULL; 343 STACK_OF(X509_ALGOR) *md_sk=NULL; 344 STACK_OF(PKCS7_RECIP_INFO) *rsk=NULL; 345 X509_ALGOR *xalg=NULL; 346 PKCS7_RECIP_INFO *ri=NULL; 347 348 i=OBJ_obj2nid(p7->type); 349 p7->state=PKCS7_S_HEADER; 350 351 switch (i) 352 { 353 case NID_pkcs7_signed: 354 data_body=PKCS7_get_octet_string(p7->d.sign->contents); 355 md_sk=p7->d.sign->md_algs; 356 break; 357 case NID_pkcs7_signedAndEnveloped: 358 rsk=p7->d.signed_and_enveloped->recipientinfo; 359 md_sk=p7->d.signed_and_enveloped->md_algs; 360 data_body=p7->d.signed_and_enveloped->enc_data->enc_data; 361 enc_alg=p7->d.signed_and_enveloped->enc_data->algorithm; 362 evp_cipher=EVP_get_cipherbyobj(enc_alg->algorithm); 363 if (evp_cipher == NULL) 364 { 365 PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNSUPPORTED_CIPHER_TYPE); 366 goto err; 367 } 368 xalg=p7->d.signed_and_enveloped->enc_data->algorithm; 369 break; 370 case NID_pkcs7_enveloped: 371 rsk=p7->d.enveloped->recipientinfo; 372 enc_alg=p7->d.enveloped->enc_data->algorithm; 373 data_body=p7->d.enveloped->enc_data->enc_data; 374 evp_cipher=EVP_get_cipherbyobj(enc_alg->algorithm); 375 if (evp_cipher == NULL) 376 { 377 PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNSUPPORTED_CIPHER_TYPE); 378 goto err; 379 } 380 xalg=p7->d.enveloped->enc_data->algorithm; 381 break; 382 default: 383 PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNSUPPORTED_CONTENT_TYPE); 384 goto err; 385 } 386 387 /* We will be checking the signature */ 388 if (md_sk != NULL) 389 { 390 for (i=0; i<sk_X509_ALGOR_num(md_sk); i++) 391 { 392 xa=sk_X509_ALGOR_value(md_sk,i); 393 if ((btmp=BIO_new(BIO_f_md())) == NULL) 394 { 395 PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_BIO_LIB); 396 goto err; 397 } 398 399 j=OBJ_obj2nid(xa->algorithm); 400 evp_md=EVP_get_digestbynid(j); 401 if (evp_md == NULL) 402 { 403 PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNKNOWN_DIGEST_TYPE); 404 goto err; 405 } 406 407 BIO_set_md(btmp,evp_md); 408 if (out == NULL) 409 out=btmp; 410 else 411 BIO_push(out,btmp); 412 btmp=NULL; 413 } 414 } 415 416 if (evp_cipher != NULL) 417 { 418#if 0 419 unsigned char key[EVP_MAX_KEY_LENGTH]; 420 unsigned char iv[EVP_MAX_IV_LENGTH]; 421 unsigned char *p; 422 int keylen,ivlen; 423 int max; 424 X509_OBJECT ret; 425#endif 426 int jj; 427 428 if ((etmp=BIO_new(BIO_f_cipher())) == NULL) 429 { 430 PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_BIO_LIB); 431 goto err; 432 } 433 434 /* It was encrypted, we need to decrypt the secret key 435 * with the private key */ 436 437 /* Find the recipientInfo which matches the passed certificate 438 * (if any) 439 */ 440 441 if (pcert) { 442 for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++) { 443 ri=sk_PKCS7_RECIP_INFO_value(rsk,i); 444 if (!pkcs7_cmp_ri(ri, pcert)) 445 break; 446 ri=NULL; 447 } 448 if (ri == NULL) { 449 PKCS7err(PKCS7_F_PKCS7_DATADECODE, 450 PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE); 451 goto err; 452 } 453 } 454 455 jj=EVP_PKEY_size(pkey); 456 tmp=(unsigned char *)OPENSSL_malloc(jj+10); 457 if (tmp == NULL) 458 { 459 PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_MALLOC_FAILURE); 460 goto err; 461 } 462 463 /* If we haven't got a certificate try each ri in turn */ 464 465 if (pcert == NULL) 466 { 467 for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++) 468 { 469 ri=sk_PKCS7_RECIP_INFO_value(rsk,i); 470 jj=EVP_PKEY_decrypt(tmp, 471 M_ASN1_STRING_data(ri->enc_key), 472 M_ASN1_STRING_length(ri->enc_key), 473 pkey); 474 if (jj > 0) 475 break; 476 ERR_clear_error(); 477 ri = NULL; 478 } 479 if (ri == NULL) 480 { 481 PKCS7err(PKCS7_F_PKCS7_DATADECODE, 482 PKCS7_R_NO_RECIPIENT_MATCHES_KEY); 483 goto err; 484 } 485 } 486 else 487 { 488 jj=EVP_PKEY_decrypt(tmp, 489 M_ASN1_STRING_data(ri->enc_key), 490 M_ASN1_STRING_length(ri->enc_key), pkey); 491 if (jj <= 0) 492 { 493 PKCS7err(PKCS7_F_PKCS7_DATADECODE, 494 ERR_R_EVP_LIB); 495 goto err; 496 } 497 } 498 499 evp_ctx=NULL; 500 BIO_get_cipher_ctx(etmp,&evp_ctx); 501 if (EVP_CipherInit_ex(evp_ctx,evp_cipher,NULL,NULL,NULL,0) <= 0) 502 goto err; 503 if (EVP_CIPHER_asn1_to_param(evp_ctx,enc_alg->parameter) < 0) 504 goto err; 505 506 if (jj != EVP_CIPHER_CTX_key_length(evp_ctx)) { 507 /* Some S/MIME clients don't use the same key 508 * and effective key length. The key length is 509 * determined by the size of the decrypted RSA key. 510 */ 511 if(!EVP_CIPHER_CTX_set_key_length(evp_ctx, jj)) 512 { 513 PKCS7err(PKCS7_F_PKCS7_DATADECODE, 514 PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH); 515 goto err; 516 } 517 } 518 if (EVP_CipherInit_ex(evp_ctx,NULL,NULL,tmp,NULL,0) <= 0) 519 goto err; 520 521 OPENSSL_cleanse(tmp,jj); 522 523 if (out == NULL) 524 out=etmp; 525 else 526 BIO_push(out,etmp); 527 etmp=NULL; 528 } 529 530#if 1 531 if (PKCS7_is_detached(p7) || (in_bio != NULL)) 532 { 533 bio=in_bio; 534 } 535 else 536 { 537#if 0 538 bio=BIO_new(BIO_s_mem()); 539 /* We need to set this so that when we have read all 540 * the data, the encrypt BIO, if present, will read 541 * EOF and encode the last few bytes */ 542 BIO_set_mem_eof_return(bio,0); 543 544 if (data_body->length > 0) 545 BIO_write(bio,(char *)data_body->data,data_body->length); 546#else 547 if (data_body->length > 0) 548 bio = BIO_new_mem_buf(data_body->data,data_body->length); 549 else { 550 bio=BIO_new(BIO_s_mem()); 551 BIO_set_mem_eof_return(bio,0); 552 } 553 if (bio == NULL) 554 goto err; 555#endif 556 } 557 BIO_push(out,bio); 558 bio=NULL; 559#endif 560 if (0) 561 { 562err: 563 if (out != NULL) BIO_free_all(out); 564 if (btmp != NULL) BIO_free_all(btmp); 565 if (etmp != NULL) BIO_free_all(etmp); 566 if (bio != NULL) BIO_free_all(bio); 567 out=NULL; 568 } 569 if (tmp != NULL) 570 OPENSSL_free(tmp); 571 return(out); 572 } 573 574static BIO *PKCS7_find_digest(EVP_MD_CTX **pmd, BIO *bio, int nid) 575 { 576 for (;;) 577 { 578 bio=BIO_find_type(bio,BIO_TYPE_MD); 579 if (bio == NULL) 580 { 581 PKCS7err(PKCS7_F_PKCS7_FIND_DIGEST,PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST); 582 return NULL; 583 } 584 BIO_get_md_ctx(bio,pmd); 585 if (*pmd == NULL) 586 { 587 PKCS7err(PKCS7_F_PKCS7_FIND_DIGEST,ERR_R_INTERNAL_ERROR); 588 return NULL; 589 } 590 if (EVP_MD_CTX_type(*pmd) == nid) 591 return bio; 592 bio=BIO_next(bio); 593 } 594 return NULL; 595 } 596 597int PKCS7_dataFinal(PKCS7 *p7, BIO *bio) 598 { 599 int ret=0; 600 int i,j; 601 BIO *btmp; 602 BUF_MEM *buf_mem=NULL; 603 BUF_MEM *buf=NULL; 604 PKCS7_SIGNER_INFO *si; 605 EVP_MD_CTX *mdc,ctx_tmp; 606 STACK_OF(X509_ATTRIBUTE) *sk; 607 STACK_OF(PKCS7_SIGNER_INFO) *si_sk=NULL; 608 ASN1_OCTET_STRING *os=NULL; 609 610 EVP_MD_CTX_init(&ctx_tmp); 611 i=OBJ_obj2nid(p7->type); 612 p7->state=PKCS7_S_HEADER; 613 614 switch (i) 615 { 616 case NID_pkcs7_signedAndEnveloped: 617 /* XXXXXXXXXXXXXXXX */ 618 si_sk=p7->d.signed_and_enveloped->signer_info; 619 if (!(os=M_ASN1_OCTET_STRING_new())) 620 { 621 PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_MALLOC_FAILURE); 622 goto err; 623 } 624 p7->d.signed_and_enveloped->enc_data->enc_data=os; 625 break; 626 case NID_pkcs7_enveloped: 627 /* XXXXXXXXXXXXXXXX */ 628 if (!(os=M_ASN1_OCTET_STRING_new())) 629 { 630 PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_MALLOC_FAILURE); 631 goto err; 632 } 633 p7->d.enveloped->enc_data->enc_data=os; 634 break; 635 case NID_pkcs7_signed: 636 si_sk=p7->d.sign->signer_info; 637 os=PKCS7_get_octet_string(p7->d.sign->contents); 638 /* If detached data then the content is excluded */ 639 if(PKCS7_type_is_data(p7->d.sign->contents) && p7->detached) { 640 M_ASN1_OCTET_STRING_free(os); 641 p7->d.sign->contents->d.data = NULL; 642 } 643 break; 644 645 case NID_pkcs7_digest: 646 os=PKCS7_get_octet_string(p7->d.digest->contents); 647 /* If detached data then the content is excluded */ 648 if(PKCS7_type_is_data(p7->d.digest->contents) && p7->detached) 649 { 650 M_ASN1_OCTET_STRING_free(os); 651 p7->d.digest->contents->d.data = NULL; 652 } 653 break; 654 655 } 656 657 if (si_sk != NULL) 658 { 659 if ((buf=BUF_MEM_new()) == NULL) 660 { 661 PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_BIO_LIB); 662 goto err; 663 } 664 for (i=0; i<sk_PKCS7_SIGNER_INFO_num(si_sk); i++) 665 { 666 si=sk_PKCS7_SIGNER_INFO_value(si_sk,i); 667 if (si->pkey == NULL) continue; 668 669 j=OBJ_obj2nid(si->digest_alg->algorithm); 670 671 btmp=bio; 672 673 btmp = PKCS7_find_digest(&mdc, btmp, j); 674 675 if (btmp == NULL) 676 goto err; 677 678 /* We now have the EVP_MD_CTX, lets do the 679 * signing. */ 680 EVP_MD_CTX_copy_ex(&ctx_tmp,mdc); 681 if (!BUF_MEM_grow_clean(buf,EVP_PKEY_size(si->pkey))) 682 { 683 PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_BIO_LIB); 684 goto err; 685 } 686 687 sk=si->auth_attr; 688 689 /* If there are attributes, we add the digest 690 * attribute and only sign the attributes */ 691 if ((sk != NULL) && (sk_X509_ATTRIBUTE_num(sk) != 0)) 692 { 693 unsigned char md_data[EVP_MAX_MD_SIZE], *abuf=NULL; 694 unsigned int md_len, alen; 695 ASN1_OCTET_STRING *digest; 696 ASN1_UTCTIME *sign_time; 697 const EVP_MD *md_tmp; 698 699 /* Add signing time if not already present */ 700 if (!PKCS7_get_signed_attribute(si, 701 NID_pkcs9_signingTime)) 702 { 703 if (!(sign_time=X509_gmtime_adj(NULL,0))) 704 { 705 PKCS7err(PKCS7_F_PKCS7_DATAFINAL, 706 ERR_R_MALLOC_FAILURE); 707 goto err; 708 } 709 if (!PKCS7_add_signed_attribute(si, 710 NID_pkcs9_signingTime, 711 V_ASN1_UTCTIME,sign_time)) 712 { 713 M_ASN1_UTCTIME_free(sign_time); 714 goto err; 715 } 716 } 717 718 /* Add digest */ 719 md_tmp=EVP_MD_CTX_md(&ctx_tmp); 720 EVP_DigestFinal_ex(&ctx_tmp,md_data,&md_len); 721 if (!(digest=M_ASN1_OCTET_STRING_new())) 722 { 723 PKCS7err(PKCS7_F_PKCS7_DATAFINAL, 724 ERR_R_MALLOC_FAILURE); 725 goto err; 726 } 727 if (!M_ASN1_OCTET_STRING_set(digest,md_data, 728 md_len)) 729 { 730 PKCS7err(PKCS7_F_PKCS7_DATAFINAL, 731 ERR_R_MALLOC_FAILURE); 732 M_ASN1_OCTET_STRING_free(digest); 733 goto err; 734 } 735 if (!PKCS7_add_signed_attribute(si, 736 NID_pkcs9_messageDigest, 737 V_ASN1_OCTET_STRING,digest)) 738 { 739 M_ASN1_OCTET_STRING_free(digest); 740 goto err; 741 } 742 743 /* Now sign the attributes */ 744 EVP_SignInit_ex(&ctx_tmp,md_tmp,NULL); 745 alen = ASN1_item_i2d((ASN1_VALUE *)sk,&abuf, 746 ASN1_ITEM_rptr(PKCS7_ATTR_SIGN)); 747 if(!abuf) goto err; 748 EVP_SignUpdate(&ctx_tmp,abuf,alen); 749 OPENSSL_free(abuf); 750 } 751 752#ifndef OPENSSL_NO_DSA 753 if (si->pkey->type == EVP_PKEY_DSA) 754 ctx_tmp.digest=EVP_dss1(); 755#endif 756#ifndef OPENSSL_NO_ECDSA 757 if (si->pkey->type == EVP_PKEY_EC) 758 ctx_tmp.digest=EVP_ecdsa(); 759#endif 760 761 if (!EVP_SignFinal(&ctx_tmp,(unsigned char *)buf->data, 762 (unsigned int *)&buf->length,si->pkey)) 763 { 764 PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_EVP_LIB); 765 goto err; 766 } 767 if (!ASN1_STRING_set(si->enc_digest, 768 (unsigned char *)buf->data,buf->length)) 769 { 770 PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_ASN1_LIB); 771 goto err; 772 } 773 } 774 } 775 else if (i == NID_pkcs7_digest) 776 { 777 unsigned char md_data[EVP_MAX_MD_SIZE]; 778 unsigned int md_len; 779 if (!PKCS7_find_digest(&mdc, bio, 780 OBJ_obj2nid(p7->d.digest->md->algorithm))) 781 goto err; 782 EVP_DigestFinal_ex(mdc,md_data,&md_len); 783 M_ASN1_OCTET_STRING_set(p7->d.digest->digest, md_data, md_len); 784 } 785 786 if (!PKCS7_is_detached(p7)) 787 { 788 btmp=BIO_find_type(bio,BIO_TYPE_MEM); 789 if (btmp == NULL) 790 { 791 PKCS7err(PKCS7_F_PKCS7_DATAFINAL,PKCS7_R_UNABLE_TO_FIND_MEM_BIO); 792 goto err; 793 } 794 BIO_get_mem_ptr(btmp,&buf_mem); 795 /* Mark the BIO read only then we can use its copy of the data 796 * instead of making an extra copy. 797 */ 798 BIO_set_flags(btmp, BIO_FLAGS_MEM_RDONLY); 799 BIO_set_mem_eof_return(btmp, 0); 800 os->data = (unsigned char *)buf_mem->data; 801 os->length = buf_mem->length; 802#if 0 803 M_ASN1_OCTET_STRING_set(os, 804 (unsigned char *)buf_mem->data,buf_mem->length); 805#endif 806 } 807 ret=1; 808err: 809 EVP_MD_CTX_cleanup(&ctx_tmp); 810 if (buf != NULL) BUF_MEM_free(buf); 811 return(ret); 812 } 813 814int PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx, BIO *bio, 815 PKCS7 *p7, PKCS7_SIGNER_INFO *si) 816 { 817 PKCS7_ISSUER_AND_SERIAL *ias; 818 int ret=0,i; 819 STACK_OF(X509) *cert; 820 X509 *x509; 821 822 if (PKCS7_type_is_signed(p7)) 823 { 824 cert=p7->d.sign->cert; 825 } 826 else if (PKCS7_type_is_signedAndEnveloped(p7)) 827 { 828 cert=p7->d.signed_and_enveloped->cert; 829 } 830 else 831 { 832 PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,PKCS7_R_WRONG_PKCS7_TYPE); 833 goto err; 834 } 835 /* XXXXXXXXXXXXXXXXXXXXXXX */ 836 ias=si->issuer_and_serial; 837 838 x509=X509_find_by_issuer_and_serial(cert,ias->issuer,ias->serial); 839 840 /* were we able to find the cert in passed to us */ 841 if (x509 == NULL) 842 { 843 PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,PKCS7_R_UNABLE_TO_FIND_CERTIFICATE); 844 goto err; 845 } 846 847 /* Lets verify */ 848 if(!X509_STORE_CTX_init(ctx,cert_store,x509,cert)) 849 { 850 PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,ERR_R_X509_LIB); 851 goto err; 852 } 853 X509_STORE_CTX_set_purpose(ctx, X509_PURPOSE_SMIME_SIGN); 854 i=X509_verify_cert(ctx); 855 if (i <= 0) 856 { 857 PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,ERR_R_X509_LIB); 858 X509_STORE_CTX_cleanup(ctx); 859 goto err; 860 } 861 X509_STORE_CTX_cleanup(ctx); 862 863 return PKCS7_signatureVerify(bio, p7, si, x509); 864 err: 865 return ret; 866 } 867 868int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si, 869 X509 *x509) 870 { 871 ASN1_OCTET_STRING *os; 872 EVP_MD_CTX mdc_tmp,*mdc; 873 int ret=0,i; 874 int md_type; 875 STACK_OF(X509_ATTRIBUTE) *sk; 876 BIO *btmp; 877 EVP_PKEY *pkey; 878 879 EVP_MD_CTX_init(&mdc_tmp); 880 881 if (!PKCS7_type_is_signed(p7) && 882 !PKCS7_type_is_signedAndEnveloped(p7)) { 883 PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, 884 PKCS7_R_WRONG_PKCS7_TYPE); 885 goto err; 886 } 887 888 md_type=OBJ_obj2nid(si->digest_alg->algorithm); 889 890 btmp=bio; 891 for (;;) 892 { 893 if ((btmp == NULL) || 894 ((btmp=BIO_find_type(btmp,BIO_TYPE_MD)) == NULL)) 895 { 896 PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, 897 PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST); 898 goto err; 899 } 900 BIO_get_md_ctx(btmp,&mdc); 901 if (mdc == NULL) 902 { 903 PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, 904 ERR_R_INTERNAL_ERROR); 905 goto err; 906 } 907 if (EVP_MD_CTX_type(mdc) == md_type) 908 break; 909 /* Workaround for some broken clients that put the signature 910 * OID instead of the digest OID in digest_alg->algorithm 911 */ 912 if (EVP_MD_pkey_type(EVP_MD_CTX_md(mdc)) == md_type) 913 break; 914 btmp=BIO_next(btmp); 915 } 916 917 /* mdc is the digest ctx that we want, unless there are attributes, 918 * in which case the digest is the signed attributes */ 919 EVP_MD_CTX_copy_ex(&mdc_tmp,mdc); 920 921 sk=si->auth_attr; 922 if ((sk != NULL) && (sk_X509_ATTRIBUTE_num(sk) != 0)) 923 { 924 unsigned char md_dat[EVP_MAX_MD_SIZE], *abuf = NULL; 925 unsigned int md_len, alen; 926 ASN1_OCTET_STRING *message_digest; 927 928 EVP_DigestFinal_ex(&mdc_tmp,md_dat,&md_len); 929 message_digest=PKCS7_digest_from_attributes(sk); 930 if (!message_digest) 931 { 932 PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, 933 PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST); 934 goto err; 935 } 936 if ((message_digest->length != (int)md_len) || 937 (memcmp(message_digest->data,md_dat,md_len))) 938 { 939#if 0 940{ 941int ii; 942for (ii=0; ii<message_digest->length; ii++) 943 printf("%02X",message_digest->data[ii]); printf(" sent\n"); 944for (ii=0; ii<md_len; ii++) printf("%02X",md_dat[ii]); printf(" calc\n"); 945} 946#endif 947 PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, 948 PKCS7_R_DIGEST_FAILURE); 949 ret= -1; 950 goto err; 951 } 952 953 EVP_VerifyInit_ex(&mdc_tmp,EVP_get_digestbynid(md_type), NULL); 954 955 alen = ASN1_item_i2d((ASN1_VALUE *)sk, &abuf, 956 ASN1_ITEM_rptr(PKCS7_ATTR_VERIFY)); 957 EVP_VerifyUpdate(&mdc_tmp, abuf, alen); 958 959 OPENSSL_free(abuf); 960 } 961 962 os=si->enc_digest; 963 pkey = X509_get_pubkey(x509); 964 if (!pkey) 965 { 966 ret = -1; 967 goto err; 968 } 969#ifndef OPENSSL_NO_DSA 970 if(pkey->type == EVP_PKEY_DSA) mdc_tmp.digest=EVP_dss1(); 971#endif 972#ifndef OPENSSL_NO_ECDSA 973 if (pkey->type == EVP_PKEY_EC) mdc_tmp.digest=EVP_ecdsa(); 974#endif 975 976 i=EVP_VerifyFinal(&mdc_tmp,os->data,os->length, pkey); 977 EVP_PKEY_free(pkey); 978 if (i <= 0) 979 { 980 PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, 981 PKCS7_R_SIGNATURE_FAILURE); 982 ret= -1; 983 goto err; 984 } 985 else 986 ret=1; 987err: 988 EVP_MD_CTX_cleanup(&mdc_tmp); 989 return(ret); 990 } 991 992PKCS7_ISSUER_AND_SERIAL *PKCS7_get_issuer_and_serial(PKCS7 *p7, int idx) 993 { 994 STACK_OF(PKCS7_RECIP_INFO) *rsk; 995 PKCS7_RECIP_INFO *ri; 996 int i; 997 998 i=OBJ_obj2nid(p7->type); 999 if (i != NID_pkcs7_signedAndEnveloped) 1000 return NULL; 1001 if (p7->d.signed_and_enveloped == NULL) 1002 return NULL; 1003 rsk=p7->d.signed_and_enveloped->recipientinfo; 1004 if (rsk == NULL) 1005 return NULL; 1006 ri=sk_PKCS7_RECIP_INFO_value(rsk,0); 1007 if (sk_PKCS7_RECIP_INFO_num(rsk) <= idx) return(NULL); 1008 ri=sk_PKCS7_RECIP_INFO_value(rsk,idx); 1009 return(ri->issuer_and_serial); 1010 } 1011 1012ASN1_TYPE *PKCS7_get_signed_attribute(PKCS7_SIGNER_INFO *si, int nid) 1013 { 1014 return(get_attribute(si->auth_attr,nid)); 1015 } 1016 1017ASN1_TYPE *PKCS7_get_attribute(PKCS7_SIGNER_INFO *si, int nid) 1018 { 1019 return(get_attribute(si->unauth_attr,nid)); 1020 } 1021 1022static ASN1_TYPE *get_attribute(STACK_OF(X509_ATTRIBUTE) *sk, int nid) 1023 { 1024 int i; 1025 X509_ATTRIBUTE *xa; 1026 ASN1_OBJECT *o; 1027 1028 o=OBJ_nid2obj(nid); 1029 if (!o || !sk) return(NULL); 1030 for (i=0; i<sk_X509_ATTRIBUTE_num(sk); i++) 1031 { 1032 xa=sk_X509_ATTRIBUTE_value(sk,i); 1033 if (OBJ_cmp(xa->object,o) == 0) 1034 { 1035 if (!xa->single && sk_ASN1_TYPE_num(xa->value.set)) 1036 return(sk_ASN1_TYPE_value(xa->value.set,0)); 1037 else 1038 return(NULL); 1039 } 1040 } 1041 return(NULL); 1042 } 1043 1044ASN1_OCTET_STRING *PKCS7_digest_from_attributes(STACK_OF(X509_ATTRIBUTE) *sk) 1045{ 1046 ASN1_TYPE *astype; 1047 if(!(astype = get_attribute(sk, NID_pkcs9_messageDigest))) return NULL; 1048 return astype->value.octet_string; 1049} 1050 1051int PKCS7_set_signed_attributes(PKCS7_SIGNER_INFO *p7si, 1052 STACK_OF(X509_ATTRIBUTE) *sk) 1053 { 1054 int i; 1055 1056 if (p7si->auth_attr != NULL) 1057 sk_X509_ATTRIBUTE_pop_free(p7si->auth_attr,X509_ATTRIBUTE_free); 1058 p7si->auth_attr=sk_X509_ATTRIBUTE_dup(sk); 1059 if (p7si->auth_attr == NULL) 1060 return 0; 1061 for (i=0; i<sk_X509_ATTRIBUTE_num(sk); i++) 1062 { 1063 if ((sk_X509_ATTRIBUTE_set(p7si->auth_attr,i, 1064 X509_ATTRIBUTE_dup(sk_X509_ATTRIBUTE_value(sk,i)))) 1065 == NULL) 1066 return(0); 1067 } 1068 return(1); 1069 } 1070 1071int PKCS7_set_attributes(PKCS7_SIGNER_INFO *p7si, STACK_OF(X509_ATTRIBUTE) *sk) 1072 { 1073 int i; 1074 1075 if (p7si->unauth_attr != NULL) 1076 sk_X509_ATTRIBUTE_pop_free(p7si->unauth_attr, 1077 X509_ATTRIBUTE_free); 1078 p7si->unauth_attr=sk_X509_ATTRIBUTE_dup(sk); 1079 if (p7si->unauth_attr == NULL) 1080 return 0; 1081 for (i=0; i<sk_X509_ATTRIBUTE_num(sk); i++) 1082 { 1083 if ((sk_X509_ATTRIBUTE_set(p7si->unauth_attr,i, 1084 X509_ATTRIBUTE_dup(sk_X509_ATTRIBUTE_value(sk,i)))) 1085 == NULL) 1086 return(0); 1087 } 1088 return(1); 1089 } 1090 1091int PKCS7_add_signed_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int atrtype, 1092 void *value) 1093 { 1094 return(add_attribute(&(p7si->auth_attr),nid,atrtype,value)); 1095 } 1096 1097int PKCS7_add_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int atrtype, 1098 void *value) 1099 { 1100 return(add_attribute(&(p7si->unauth_attr),nid,atrtype,value)); 1101 } 1102 1103static int add_attribute(STACK_OF(X509_ATTRIBUTE) **sk, int nid, int atrtype, 1104 void *value) 1105 { 1106 X509_ATTRIBUTE *attr=NULL; 1107 1108 if (*sk == NULL) 1109 { 1110 if (!(*sk = sk_X509_ATTRIBUTE_new_null())) 1111 return 0; 1112new_attrib: 1113 if (!(attr=X509_ATTRIBUTE_create(nid,atrtype,value))) 1114 return 0; 1115 if (!sk_X509_ATTRIBUTE_push(*sk,attr)) 1116 { 1117 X509_ATTRIBUTE_free(attr); 1118 return 0; 1119 } 1120 } 1121 else 1122 { 1123 int i; 1124 1125 for (i=0; i<sk_X509_ATTRIBUTE_num(*sk); i++) 1126 { 1127 attr=sk_X509_ATTRIBUTE_value(*sk,i); 1128 if (OBJ_obj2nid(attr->object) == nid) 1129 { 1130 X509_ATTRIBUTE_free(attr); 1131 attr=X509_ATTRIBUTE_create(nid,atrtype,value); 1132 if (attr == NULL) 1133 return 0; 1134 if (!sk_X509_ATTRIBUTE_set(*sk,i,attr)) 1135 { 1136 X509_ATTRIBUTE_free(attr); 1137 return 0; 1138 } 1139 goto end; 1140 } 1141 } 1142 goto new_attrib; 1143 } 1144end: 1145 return(1); 1146 } 1147 1148