pk7_doit.c revision 280304
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 case NID_pkcs7_data: 79 case NID_pkcs7_signed: 80 case NID_pkcs7_enveloped: 81 case NID_pkcs7_signedAndEnveloped: 82 case NID_pkcs7_digest: 83 case NID_pkcs7_encrypted: 84 isOther = 0; 85 break; 86 default: 87 isOther = 1; 88 } 89 90 return isOther; 91 92} 93 94static ASN1_OCTET_STRING *PKCS7_get_octet_string(PKCS7 *p7) 95{ 96 if (PKCS7_type_is_data(p7)) 97 return p7->d.data; 98 if (PKCS7_type_is_other(p7) && p7->d.other 99 && (p7->d.other->type == V_ASN1_OCTET_STRING)) 100 return p7->d.other->value.octet_string; 101 return NULL; 102} 103 104static int PKCS7_bio_add_digest(BIO **pbio, X509_ALGOR *alg) 105{ 106 BIO *btmp; 107 const EVP_MD *md; 108 if ((btmp = BIO_new(BIO_f_md())) == NULL) { 109 PKCS7err(PKCS7_F_PKCS7_BIO_ADD_DIGEST, ERR_R_BIO_LIB); 110 goto err; 111 } 112 113 md = EVP_get_digestbyobj(alg->algorithm); 114 if (md == NULL) { 115 PKCS7err(PKCS7_F_PKCS7_BIO_ADD_DIGEST, PKCS7_R_UNKNOWN_DIGEST_TYPE); 116 goto err; 117 } 118 119 BIO_set_md(btmp, md); 120 if (*pbio == NULL) 121 *pbio = btmp; 122 else if (!BIO_push(*pbio, btmp)) { 123 PKCS7err(PKCS7_F_PKCS7_BIO_ADD_DIGEST, ERR_R_BIO_LIB); 124 goto err; 125 } 126 btmp = NULL; 127 128 return 1; 129 130 err: 131 if (btmp) 132 BIO_free(btmp); 133 return 0; 134 135} 136 137static int pkcs7_encode_rinfo(PKCS7_RECIP_INFO *ri, 138 unsigned char *key, int keylen) 139{ 140 EVP_PKEY_CTX *pctx = NULL; 141 EVP_PKEY *pkey = NULL; 142 unsigned char *ek = NULL; 143 int ret = 0; 144 size_t eklen; 145 146 pkey = X509_get_pubkey(ri->cert); 147 148 if (!pkey) 149 return 0; 150 151 pctx = EVP_PKEY_CTX_new(pkey, NULL); 152 if (!pctx) 153 return 0; 154 155 if (EVP_PKEY_encrypt_init(pctx) <= 0) 156 goto err; 157 158 if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_ENCRYPT, 159 EVP_PKEY_CTRL_PKCS7_ENCRYPT, 0, ri) <= 0) { 160 PKCS7err(PKCS7_F_PKCS7_ENCODE_RINFO, PKCS7_R_CTRL_ERROR); 161 goto err; 162 } 163 164 if (EVP_PKEY_encrypt(pctx, NULL, &eklen, key, keylen) <= 0) 165 goto err; 166 167 ek = OPENSSL_malloc(eklen); 168 169 if (ek == NULL) { 170 PKCS7err(PKCS7_F_PKCS7_ENCODE_RINFO, ERR_R_MALLOC_FAILURE); 171 goto err; 172 } 173 174 if (EVP_PKEY_encrypt(pctx, ek, &eklen, key, keylen) <= 0) 175 goto err; 176 177 ASN1_STRING_set0(ri->enc_key, ek, eklen); 178 ek = NULL; 179 180 ret = 1; 181 182 err: 183 if (pkey) 184 EVP_PKEY_free(pkey); 185 if (pctx) 186 EVP_PKEY_CTX_free(pctx); 187 if (ek) 188 OPENSSL_free(ek); 189 return ret; 190 191} 192 193static int pkcs7_decrypt_rinfo(unsigned char **pek, int *peklen, 194 PKCS7_RECIP_INFO *ri, EVP_PKEY *pkey) 195{ 196 EVP_PKEY_CTX *pctx = NULL; 197 unsigned char *ek = NULL; 198 size_t eklen; 199 200 int ret = -1; 201 202 pctx = EVP_PKEY_CTX_new(pkey, NULL); 203 if (!pctx) 204 return -1; 205 206 if (EVP_PKEY_decrypt_init(pctx) <= 0) 207 goto err; 208 209 if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DECRYPT, 210 EVP_PKEY_CTRL_PKCS7_DECRYPT, 0, ri) <= 0) { 211 PKCS7err(PKCS7_F_PKCS7_DECRYPT_RINFO, PKCS7_R_CTRL_ERROR); 212 goto err; 213 } 214 215 if (EVP_PKEY_decrypt(pctx, NULL, &eklen, 216 ri->enc_key->data, ri->enc_key->length) <= 0) 217 goto err; 218 219 ek = OPENSSL_malloc(eklen); 220 221 if (ek == NULL) { 222 PKCS7err(PKCS7_F_PKCS7_DECRYPT_RINFO, ERR_R_MALLOC_FAILURE); 223 goto err; 224 } 225 226 if (EVP_PKEY_decrypt(pctx, ek, &eklen, 227 ri->enc_key->data, ri->enc_key->length) <= 0) { 228 ret = 0; 229 PKCS7err(PKCS7_F_PKCS7_DECRYPT_RINFO, ERR_R_EVP_LIB); 230 goto err; 231 } 232 233 ret = 1; 234 235 if (*pek) { 236 OPENSSL_cleanse(*pek, *peklen); 237 OPENSSL_free(*pek); 238 } 239 240 *pek = ek; 241 *peklen = eklen; 242 243 err: 244 if (pctx) 245 EVP_PKEY_CTX_free(pctx); 246 if (!ret && ek) 247 OPENSSL_free(ek); 248 249 return ret; 250} 251 252BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio) 253{ 254 int i; 255 BIO *out = NULL, *btmp = NULL; 256 X509_ALGOR *xa = NULL; 257 const EVP_CIPHER *evp_cipher = NULL; 258 STACK_OF(X509_ALGOR) *md_sk = NULL; 259 STACK_OF(PKCS7_RECIP_INFO) *rsk = NULL; 260 X509_ALGOR *xalg = NULL; 261 PKCS7_RECIP_INFO *ri = NULL; 262 ASN1_OCTET_STRING *os = NULL; 263 264 if (p7 == NULL) { 265 PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_INVALID_NULL_POINTER); 266 return NULL; 267 } 268 /* 269 * The content field in the PKCS7 ContentInfo is optional, but that really 270 * only applies to inner content (precisely, detached signatures). 271 * 272 * When reading content, missing outer content is therefore treated as an 273 * error. 274 * 275 * When creating content, PKCS7_content_new() must be called before 276 * calling this method, so a NULL p7->d is always an error. 277 */ 278 if (p7->d.ptr == NULL) { 279 PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_NO_CONTENT); 280 return NULL; 281 } 282 283 i = OBJ_obj2nid(p7->type); 284 p7->state = PKCS7_S_HEADER; 285 286 switch (i) { 287 case NID_pkcs7_signed: 288 md_sk = p7->d.sign->md_algs; 289 os = PKCS7_get_octet_string(p7->d.sign->contents); 290 break; 291 case NID_pkcs7_signedAndEnveloped: 292 rsk = p7->d.signed_and_enveloped->recipientinfo; 293 md_sk = p7->d.signed_and_enveloped->md_algs; 294 xalg = p7->d.signed_and_enveloped->enc_data->algorithm; 295 evp_cipher = p7->d.signed_and_enveloped->enc_data->cipher; 296 if (evp_cipher == NULL) { 297 PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_CIPHER_NOT_INITIALIZED); 298 goto err; 299 } 300 break; 301 case NID_pkcs7_enveloped: 302 rsk = p7->d.enveloped->recipientinfo; 303 xalg = p7->d.enveloped->enc_data->algorithm; 304 evp_cipher = p7->d.enveloped->enc_data->cipher; 305 if (evp_cipher == NULL) { 306 PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_CIPHER_NOT_INITIALIZED); 307 goto err; 308 } 309 break; 310 case NID_pkcs7_digest: 311 xa = p7->d.digest->md; 312 os = PKCS7_get_octet_string(p7->d.digest->contents); 313 break; 314 case NID_pkcs7_data: 315 break; 316 default: 317 PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_UNSUPPORTED_CONTENT_TYPE); 318 goto err; 319 } 320 321 for (i = 0; i < sk_X509_ALGOR_num(md_sk); i++) 322 if (!PKCS7_bio_add_digest(&out, sk_X509_ALGOR_value(md_sk, i))) 323 goto err; 324 325 if (xa && !PKCS7_bio_add_digest(&out, xa)) 326 goto err; 327 328 if (evp_cipher != NULL) { 329 unsigned char key[EVP_MAX_KEY_LENGTH]; 330 unsigned char iv[EVP_MAX_IV_LENGTH]; 331 int keylen, ivlen; 332 EVP_CIPHER_CTX *ctx; 333 334 if ((btmp = BIO_new(BIO_f_cipher())) == NULL) { 335 PKCS7err(PKCS7_F_PKCS7_DATAINIT, ERR_R_BIO_LIB); 336 goto err; 337 } 338 BIO_get_cipher_ctx(btmp, &ctx); 339 keylen = EVP_CIPHER_key_length(evp_cipher); 340 ivlen = EVP_CIPHER_iv_length(evp_cipher); 341 xalg->algorithm = OBJ_nid2obj(EVP_CIPHER_type(evp_cipher)); 342 if (ivlen > 0) 343 if (RAND_pseudo_bytes(iv, ivlen) <= 0) 344 goto err; 345 if (EVP_CipherInit_ex(ctx, evp_cipher, NULL, NULL, NULL, 1) <= 0) 346 goto err; 347 if (EVP_CIPHER_CTX_rand_key(ctx, key) <= 0) 348 goto err; 349 if (EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, 1) <= 0) 350 goto err; 351 352 if (ivlen > 0) { 353 if (xalg->parameter == NULL) { 354 xalg->parameter = ASN1_TYPE_new(); 355 if (xalg->parameter == NULL) 356 goto err; 357 } 358 if (EVP_CIPHER_param_to_asn1(ctx, xalg->parameter) < 0) 359 goto err; 360 } 361 362 /* Lets do the pub key stuff :-) */ 363 for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rsk); i++) { 364 ri = sk_PKCS7_RECIP_INFO_value(rsk, i); 365 if (pkcs7_encode_rinfo(ri, key, keylen) <= 0) 366 goto err; 367 } 368 OPENSSL_cleanse(key, keylen); 369 370 if (out == NULL) 371 out = btmp; 372 else 373 BIO_push(out, btmp); 374 btmp = NULL; 375 } 376 377 if (bio == NULL) { 378 if (PKCS7_is_detached(p7)) 379 bio = BIO_new(BIO_s_null()); 380 else if (os && os->length > 0) 381 bio = BIO_new_mem_buf(os->data, os->length); 382 if (bio == NULL) { 383 bio = BIO_new(BIO_s_mem()); 384 if (bio == NULL) 385 goto err; 386 BIO_set_mem_eof_return(bio, 0); 387 } 388 } 389 if (out) 390 BIO_push(out, bio); 391 else 392 out = bio; 393 bio = NULL; 394 if (0) { 395 err: 396 if (out != NULL) 397 BIO_free_all(out); 398 if (btmp != NULL) 399 BIO_free_all(btmp); 400 out = NULL; 401 } 402 return (out); 403} 404 405static int pkcs7_cmp_ri(PKCS7_RECIP_INFO *ri, X509 *pcert) 406{ 407 int ret; 408 ret = X509_NAME_cmp(ri->issuer_and_serial->issuer, 409 pcert->cert_info->issuer); 410 if (ret) 411 return ret; 412 return M_ASN1_INTEGER_cmp(pcert->cert_info->serialNumber, 413 ri->issuer_and_serial->serial); 414} 415 416/* int */ 417BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) 418{ 419 int i, j; 420 BIO *out = NULL, *btmp = NULL, *etmp = NULL, *bio = NULL; 421 X509_ALGOR *xa; 422 ASN1_OCTET_STRING *data_body = NULL; 423 const EVP_MD *evp_md; 424 const EVP_CIPHER *evp_cipher = NULL; 425 EVP_CIPHER_CTX *evp_ctx = NULL; 426 X509_ALGOR *enc_alg = NULL; 427 STACK_OF(X509_ALGOR) *md_sk = NULL; 428 STACK_OF(PKCS7_RECIP_INFO) *rsk = NULL; 429 PKCS7_RECIP_INFO *ri = NULL; 430 unsigned char *ek = NULL, *tkey = NULL; 431 int eklen = 0, tkeylen = 0; 432 433 if (p7 == NULL) { 434 PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_INVALID_NULL_POINTER); 435 return NULL; 436 } 437 438 if (p7->d.ptr == NULL) { 439 PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_NO_CONTENT); 440 return NULL; 441 } 442 443 i = OBJ_obj2nid(p7->type); 444 p7->state = PKCS7_S_HEADER; 445 446 switch (i) { 447 case NID_pkcs7_signed: 448 data_body = PKCS7_get_octet_string(p7->d.sign->contents); 449 if (!PKCS7_is_detached(p7) && data_body == NULL) { 450 PKCS7err(PKCS7_F_PKCS7_DATADECODE, 451 PKCS7_R_INVALID_SIGNED_DATA_TYPE); 452 goto err; 453 } 454 md_sk = p7->d.sign->md_algs; 455 break; 456 case NID_pkcs7_signedAndEnveloped: 457 rsk = p7->d.signed_and_enveloped->recipientinfo; 458 md_sk = p7->d.signed_and_enveloped->md_algs; 459 data_body = p7->d.signed_and_enveloped->enc_data->enc_data; 460 enc_alg = p7->d.signed_and_enveloped->enc_data->algorithm; 461 evp_cipher = EVP_get_cipherbyobj(enc_alg->algorithm); 462 if (evp_cipher == NULL) { 463 PKCS7err(PKCS7_F_PKCS7_DATADECODE, 464 PKCS7_R_UNSUPPORTED_CIPHER_TYPE); 465 goto err; 466 } 467 break; 468 case NID_pkcs7_enveloped: 469 rsk = p7->d.enveloped->recipientinfo; 470 enc_alg = p7->d.enveloped->enc_data->algorithm; 471 data_body = p7->d.enveloped->enc_data->enc_data; 472 evp_cipher = EVP_get_cipherbyobj(enc_alg->algorithm); 473 if (evp_cipher == NULL) { 474 PKCS7err(PKCS7_F_PKCS7_DATADECODE, 475 PKCS7_R_UNSUPPORTED_CIPHER_TYPE); 476 goto err; 477 } 478 break; 479 default: 480 PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_UNSUPPORTED_CONTENT_TYPE); 481 goto err; 482 } 483 484 /* We will be checking the signature */ 485 if (md_sk != NULL) { 486 for (i = 0; i < sk_X509_ALGOR_num(md_sk); i++) { 487 xa = sk_X509_ALGOR_value(md_sk, i); 488 if ((btmp = BIO_new(BIO_f_md())) == NULL) { 489 PKCS7err(PKCS7_F_PKCS7_DATADECODE, ERR_R_BIO_LIB); 490 goto err; 491 } 492 493 j = OBJ_obj2nid(xa->algorithm); 494 evp_md = EVP_get_digestbynid(j); 495 if (evp_md == NULL) { 496 PKCS7err(PKCS7_F_PKCS7_DATADECODE, 497 PKCS7_R_UNKNOWN_DIGEST_TYPE); 498 goto err; 499 } 500 501 BIO_set_md(btmp, evp_md); 502 if (out == NULL) 503 out = btmp; 504 else 505 BIO_push(out, btmp); 506 btmp = NULL; 507 } 508 } 509 510 if (evp_cipher != NULL) { 511#if 0 512 unsigned char key[EVP_MAX_KEY_LENGTH]; 513 unsigned char iv[EVP_MAX_IV_LENGTH]; 514 unsigned char *p; 515 int keylen, ivlen; 516 int max; 517 X509_OBJECT ret; 518#endif 519 520 if ((etmp = BIO_new(BIO_f_cipher())) == NULL) { 521 PKCS7err(PKCS7_F_PKCS7_DATADECODE, ERR_R_BIO_LIB); 522 goto err; 523 } 524 525 /* 526 * It was encrypted, we need to decrypt the secret key with the 527 * private key 528 */ 529 530 /* 531 * Find the recipientInfo which matches the passed certificate (if 532 * any) 533 */ 534 535 if (pcert) { 536 for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rsk); i++) { 537 ri = sk_PKCS7_RECIP_INFO_value(rsk, i); 538 if (!pkcs7_cmp_ri(ri, pcert)) 539 break; 540 ri = NULL; 541 } 542 if (ri == NULL) { 543 PKCS7err(PKCS7_F_PKCS7_DATADECODE, 544 PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE); 545 goto err; 546 } 547 } 548 549 /* If we haven't got a certificate try each ri in turn */ 550 if (pcert == NULL) { 551 /* 552 * Always attempt to decrypt all rinfo even after sucess as a 553 * defence against MMA timing attacks. 554 */ 555 for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rsk); i++) { 556 ri = sk_PKCS7_RECIP_INFO_value(rsk, i); 557 558 if (pkcs7_decrypt_rinfo(&ek, &eklen, ri, pkey) < 0) 559 goto err; 560 ERR_clear_error(); 561 } 562 } else { 563 /* Only exit on fatal errors, not decrypt failure */ 564 if (pkcs7_decrypt_rinfo(&ek, &eklen, ri, pkey) < 0) 565 goto err; 566 ERR_clear_error(); 567 } 568 569 evp_ctx = NULL; 570 BIO_get_cipher_ctx(etmp, &evp_ctx); 571 if (EVP_CipherInit_ex(evp_ctx, evp_cipher, NULL, NULL, NULL, 0) <= 0) 572 goto err; 573 if (EVP_CIPHER_asn1_to_param(evp_ctx, enc_alg->parameter) < 0) 574 goto err; 575 /* Generate random key as MMA defence */ 576 tkeylen = EVP_CIPHER_CTX_key_length(evp_ctx); 577 tkey = OPENSSL_malloc(tkeylen); 578 if (!tkey) 579 goto err; 580 if (EVP_CIPHER_CTX_rand_key(evp_ctx, tkey) <= 0) 581 goto err; 582 if (ek == NULL) { 583 ek = tkey; 584 eklen = tkeylen; 585 tkey = NULL; 586 } 587 588 if (eklen != EVP_CIPHER_CTX_key_length(evp_ctx)) { 589 /* 590 * Some S/MIME clients don't use the same key and effective key 591 * length. The key length is determined by the size of the 592 * decrypted RSA key. 593 */ 594 if (!EVP_CIPHER_CTX_set_key_length(evp_ctx, eklen)) { 595 /* Use random key as MMA defence */ 596 OPENSSL_cleanse(ek, eklen); 597 OPENSSL_free(ek); 598 ek = tkey; 599 eklen = tkeylen; 600 tkey = NULL; 601 } 602 } 603 /* Clear errors so we don't leak information useful in MMA */ 604 ERR_clear_error(); 605 if (EVP_CipherInit_ex(evp_ctx, NULL, NULL, ek, NULL, 0) <= 0) 606 goto err; 607 608 if (ek) { 609 OPENSSL_cleanse(ek, eklen); 610 OPENSSL_free(ek); 611 ek = NULL; 612 } 613 if (tkey) { 614 OPENSSL_cleanse(tkey, tkeylen); 615 OPENSSL_free(tkey); 616 tkey = NULL; 617 } 618 619 if (out == NULL) 620 out = etmp; 621 else 622 BIO_push(out, etmp); 623 etmp = NULL; 624 } 625#if 1 626 if (PKCS7_is_detached(p7) || (in_bio != NULL)) { 627 bio = in_bio; 628 } else { 629# if 0 630 bio = BIO_new(BIO_s_mem()); 631 /* 632 * We need to set this so that when we have read all the data, the 633 * encrypt BIO, if present, will read EOF and encode the last few 634 * bytes 635 */ 636 BIO_set_mem_eof_return(bio, 0); 637 638 if (data_body->length > 0) 639 BIO_write(bio, (char *)data_body->data, data_body->length); 640# else 641 if (data_body->length > 0) 642 bio = BIO_new_mem_buf(data_body->data, data_body->length); 643 else { 644 bio = BIO_new(BIO_s_mem()); 645 BIO_set_mem_eof_return(bio, 0); 646 } 647 if (bio == NULL) 648 goto err; 649# endif 650 } 651 BIO_push(out, bio); 652 bio = NULL; 653#endif 654 if (0) { 655 err: 656 if (ek) { 657 OPENSSL_cleanse(ek, eklen); 658 OPENSSL_free(ek); 659 } 660 if (tkey) { 661 OPENSSL_cleanse(tkey, tkeylen); 662 OPENSSL_free(tkey); 663 } 664 if (out != NULL) 665 BIO_free_all(out); 666 if (btmp != NULL) 667 BIO_free_all(btmp); 668 if (etmp != NULL) 669 BIO_free_all(etmp); 670 if (bio != NULL) 671 BIO_free_all(bio); 672 out = NULL; 673 } 674 return (out); 675} 676 677static BIO *PKCS7_find_digest(EVP_MD_CTX **pmd, BIO *bio, int nid) 678{ 679 for (;;) { 680 bio = BIO_find_type(bio, BIO_TYPE_MD); 681 if (bio == NULL) { 682 PKCS7err(PKCS7_F_PKCS7_FIND_DIGEST, 683 PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST); 684 return NULL; 685 } 686 BIO_get_md_ctx(bio, pmd); 687 if (*pmd == NULL) { 688 PKCS7err(PKCS7_F_PKCS7_FIND_DIGEST, ERR_R_INTERNAL_ERROR); 689 return NULL; 690 } 691 if (EVP_MD_CTX_type(*pmd) == nid) 692 return bio; 693 bio = BIO_next(bio); 694 } 695 return NULL; 696} 697 698static int do_pkcs7_signed_attrib(PKCS7_SIGNER_INFO *si, EVP_MD_CTX *mctx) 699{ 700 unsigned char md_data[EVP_MAX_MD_SIZE]; 701 unsigned int md_len; 702 703 /* Add signing time if not already present */ 704 if (!PKCS7_get_signed_attribute(si, NID_pkcs9_signingTime)) { 705 if (!PKCS7_add0_attrib_signing_time(si, NULL)) { 706 PKCS7err(PKCS7_F_DO_PKCS7_SIGNED_ATTRIB, ERR_R_MALLOC_FAILURE); 707 return 0; 708 } 709 } 710 711 /* Add digest */ 712 if (!EVP_DigestFinal_ex(mctx, md_data, &md_len)) { 713 PKCS7err(PKCS7_F_DO_PKCS7_SIGNED_ATTRIB, ERR_R_EVP_LIB); 714 return 0; 715 } 716 if (!PKCS7_add1_attrib_digest(si, md_data, md_len)) { 717 PKCS7err(PKCS7_F_DO_PKCS7_SIGNED_ATTRIB, ERR_R_MALLOC_FAILURE); 718 return 0; 719 } 720 721 /* Now sign the attributes */ 722 if (!PKCS7_SIGNER_INFO_sign(si)) 723 return 0; 724 725 return 1; 726} 727 728int PKCS7_dataFinal(PKCS7 *p7, BIO *bio) 729{ 730 int ret = 0; 731 int i, j; 732 BIO *btmp; 733 PKCS7_SIGNER_INFO *si; 734 EVP_MD_CTX *mdc, ctx_tmp; 735 STACK_OF(X509_ATTRIBUTE) *sk; 736 STACK_OF(PKCS7_SIGNER_INFO) *si_sk = NULL; 737 ASN1_OCTET_STRING *os = NULL; 738 739 if (p7 == NULL) { 740 PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_INVALID_NULL_POINTER); 741 return 0; 742 } 743 744 if (p7->d.ptr == NULL) { 745 PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_NO_CONTENT); 746 return 0; 747 } 748 749 EVP_MD_CTX_init(&ctx_tmp); 750 i = OBJ_obj2nid(p7->type); 751 p7->state = PKCS7_S_HEADER; 752 753 switch (i) { 754 case NID_pkcs7_data: 755 os = p7->d.data; 756 break; 757 case NID_pkcs7_signedAndEnveloped: 758 /* XXXXXXXXXXXXXXXX */ 759 si_sk = p7->d.signed_and_enveloped->signer_info; 760 os = p7->d.signed_and_enveloped->enc_data->enc_data; 761 if (!os) { 762 os = M_ASN1_OCTET_STRING_new(); 763 if (!os) { 764 PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_MALLOC_FAILURE); 765 goto err; 766 } 767 p7->d.signed_and_enveloped->enc_data->enc_data = os; 768 } 769 break; 770 case NID_pkcs7_enveloped: 771 /* XXXXXXXXXXXXXXXX */ 772 os = p7->d.enveloped->enc_data->enc_data; 773 if (!os) { 774 os = M_ASN1_OCTET_STRING_new(); 775 if (!os) { 776 PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_MALLOC_FAILURE); 777 goto err; 778 } 779 p7->d.enveloped->enc_data->enc_data = os; 780 } 781 break; 782 case NID_pkcs7_signed: 783 si_sk = p7->d.sign->signer_info; 784 os = PKCS7_get_octet_string(p7->d.sign->contents); 785 /* If detached data then the content is excluded */ 786 if (PKCS7_type_is_data(p7->d.sign->contents) && p7->detached) { 787 M_ASN1_OCTET_STRING_free(os); 788 os = NULL; 789 p7->d.sign->contents->d.data = NULL; 790 } 791 break; 792 793 case NID_pkcs7_digest: 794 os = PKCS7_get_octet_string(p7->d.digest->contents); 795 /* If detached data then the content is excluded */ 796 if (PKCS7_type_is_data(p7->d.digest->contents) && p7->detached) { 797 M_ASN1_OCTET_STRING_free(os); 798 os = NULL; 799 p7->d.digest->contents->d.data = NULL; 800 } 801 break; 802 803 default: 804 PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_UNSUPPORTED_CONTENT_TYPE); 805 goto err; 806 } 807 808 if (si_sk != NULL) { 809 for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(si_sk); i++) { 810 si = sk_PKCS7_SIGNER_INFO_value(si_sk, i); 811 if (si->pkey == NULL) 812 continue; 813 814 j = OBJ_obj2nid(si->digest_alg->algorithm); 815 816 btmp = bio; 817 818 btmp = PKCS7_find_digest(&mdc, btmp, j); 819 820 if (btmp == NULL) 821 goto err; 822 823 /* 824 * We now have the EVP_MD_CTX, lets do the signing. 825 */ 826 if (!EVP_MD_CTX_copy_ex(&ctx_tmp, mdc)) 827 goto err; 828 829 sk = si->auth_attr; 830 831 /* 832 * If there are attributes, we add the digest attribute and only 833 * sign the attributes 834 */ 835 if (sk_X509_ATTRIBUTE_num(sk) > 0) { 836 if (!do_pkcs7_signed_attrib(si, &ctx_tmp)) 837 goto err; 838 } else { 839 unsigned char *abuf = NULL; 840 unsigned int abuflen; 841 abuflen = EVP_PKEY_size(si->pkey); 842 abuf = OPENSSL_malloc(abuflen); 843 if (!abuf) 844 goto err; 845 846 if (!EVP_SignFinal(&ctx_tmp, abuf, &abuflen, si->pkey)) { 847 PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_EVP_LIB); 848 goto err; 849 } 850 ASN1_STRING_set0(si->enc_digest, abuf, abuflen); 851 } 852 } 853 } else if (i == NID_pkcs7_digest) { 854 unsigned char md_data[EVP_MAX_MD_SIZE]; 855 unsigned int md_len; 856 if (!PKCS7_find_digest(&mdc, bio, 857 OBJ_obj2nid(p7->d.digest->md->algorithm))) 858 goto err; 859 if (!EVP_DigestFinal_ex(mdc, md_data, &md_len)) 860 goto err; 861 M_ASN1_OCTET_STRING_set(p7->d.digest->digest, md_data, md_len); 862 } 863 864 if (!PKCS7_is_detached(p7)) { 865 /* 866 * NOTE(emilia): I think we only reach os == NULL here because detached 867 * digested data support is broken. 868 */ 869 if (os == NULL) 870 goto err; 871 if (!(os->flags & ASN1_STRING_FLAG_NDEF)) { 872 char *cont; 873 long contlen; 874 btmp = BIO_find_type(bio, BIO_TYPE_MEM); 875 if (btmp == NULL) { 876 PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_UNABLE_TO_FIND_MEM_BIO); 877 goto err; 878 } 879 contlen = BIO_get_mem_data(btmp, &cont); 880 /* 881 * Mark the BIO read only then we can use its copy of the data 882 * instead of making an extra copy. 883 */ 884 BIO_set_flags(btmp, BIO_FLAGS_MEM_RDONLY); 885 BIO_set_mem_eof_return(btmp, 0); 886 ASN1_STRING_set0(os, (unsigned char *)cont, contlen); 887 } 888 } 889 ret = 1; 890 err: 891 EVP_MD_CTX_cleanup(&ctx_tmp); 892 return (ret); 893} 894 895int PKCS7_SIGNER_INFO_sign(PKCS7_SIGNER_INFO *si) 896{ 897 EVP_MD_CTX mctx; 898 EVP_PKEY_CTX *pctx; 899 unsigned char *abuf = NULL; 900 int alen; 901 size_t siglen; 902 const EVP_MD *md = NULL; 903 904 md = EVP_get_digestbyobj(si->digest_alg->algorithm); 905 if (md == NULL) 906 return 0; 907 908 EVP_MD_CTX_init(&mctx); 909 if (EVP_DigestSignInit(&mctx, &pctx, md, NULL, si->pkey) <= 0) 910 goto err; 911 912 if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN, 913 EVP_PKEY_CTRL_PKCS7_SIGN, 0, si) <= 0) { 914 PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SIGN, PKCS7_R_CTRL_ERROR); 915 goto err; 916 } 917 918 alen = ASN1_item_i2d((ASN1_VALUE *)si->auth_attr, &abuf, 919 ASN1_ITEM_rptr(PKCS7_ATTR_SIGN)); 920 if (!abuf) 921 goto err; 922 if (EVP_DigestSignUpdate(&mctx, abuf, alen) <= 0) 923 goto err; 924 OPENSSL_free(abuf); 925 abuf = NULL; 926 if (EVP_DigestSignFinal(&mctx, NULL, &siglen) <= 0) 927 goto err; 928 abuf = OPENSSL_malloc(siglen); 929 if (!abuf) 930 goto err; 931 if (EVP_DigestSignFinal(&mctx, abuf, &siglen) <= 0) 932 goto err; 933 934 if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN, 935 EVP_PKEY_CTRL_PKCS7_SIGN, 1, si) <= 0) { 936 PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SIGN, PKCS7_R_CTRL_ERROR); 937 goto err; 938 } 939 940 EVP_MD_CTX_cleanup(&mctx); 941 942 ASN1_STRING_set0(si->enc_digest, abuf, siglen); 943 944 return 1; 945 946 err: 947 if (abuf) 948 OPENSSL_free(abuf); 949 EVP_MD_CTX_cleanup(&mctx); 950 return 0; 951 952} 953 954int PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx, BIO *bio, 955 PKCS7 *p7, PKCS7_SIGNER_INFO *si) 956{ 957 PKCS7_ISSUER_AND_SERIAL *ias; 958 int ret = 0, i; 959 STACK_OF(X509) *cert; 960 X509 *x509; 961 962 if (p7 == NULL) { 963 PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, PKCS7_R_INVALID_NULL_POINTER); 964 return 0; 965 } 966 967 if (p7->d.ptr == NULL) { 968 PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, PKCS7_R_NO_CONTENT); 969 return 0; 970 } 971 972 if (PKCS7_type_is_signed(p7)) { 973 cert = p7->d.sign->cert; 974 } else if (PKCS7_type_is_signedAndEnveloped(p7)) { 975 cert = p7->d.signed_and_enveloped->cert; 976 } else { 977 PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, PKCS7_R_WRONG_PKCS7_TYPE); 978 goto err; 979 } 980 /* XXXXXXXXXXXXXXXXXXXXXXX */ 981 ias = si->issuer_and_serial; 982 983 x509 = X509_find_by_issuer_and_serial(cert, ias->issuer, ias->serial); 984 985 /* were we able to find the cert in passed to us */ 986 if (x509 == NULL) { 987 PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, 988 PKCS7_R_UNABLE_TO_FIND_CERTIFICATE); 989 goto err; 990 } 991 992 /* Lets verify */ 993 if (!X509_STORE_CTX_init(ctx, cert_store, x509, cert)) { 994 PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, ERR_R_X509_LIB); 995 goto err; 996 } 997 X509_STORE_CTX_set_purpose(ctx, X509_PURPOSE_SMIME_SIGN); 998 i = X509_verify_cert(ctx); 999 if (i <= 0) { 1000 PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, ERR_R_X509_LIB); 1001 X509_STORE_CTX_cleanup(ctx); 1002 goto err; 1003 } 1004 X509_STORE_CTX_cleanup(ctx); 1005 1006 return PKCS7_signatureVerify(bio, p7, si, x509); 1007 err: 1008 return ret; 1009} 1010 1011int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si, 1012 X509 *x509) 1013{ 1014 ASN1_OCTET_STRING *os; 1015 EVP_MD_CTX mdc_tmp, *mdc; 1016 int ret = 0, i; 1017 int md_type; 1018 STACK_OF(X509_ATTRIBUTE) *sk; 1019 BIO *btmp; 1020 EVP_PKEY *pkey; 1021 1022 EVP_MD_CTX_init(&mdc_tmp); 1023 1024 if (!PKCS7_type_is_signed(p7) && !PKCS7_type_is_signedAndEnveloped(p7)) { 1025 PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, PKCS7_R_WRONG_PKCS7_TYPE); 1026 goto err; 1027 } 1028 1029 md_type = OBJ_obj2nid(si->digest_alg->algorithm); 1030 1031 btmp = bio; 1032 for (;;) { 1033 if ((btmp == NULL) || 1034 ((btmp = BIO_find_type(btmp, BIO_TYPE_MD)) == NULL)) { 1035 PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, 1036 PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST); 1037 goto err; 1038 } 1039 BIO_get_md_ctx(btmp, &mdc); 1040 if (mdc == NULL) { 1041 PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, ERR_R_INTERNAL_ERROR); 1042 goto err; 1043 } 1044 if (EVP_MD_CTX_type(mdc) == md_type) 1045 break; 1046 /* 1047 * Workaround for some broken clients that put the signature OID 1048 * instead of the digest OID in digest_alg->algorithm 1049 */ 1050 if (EVP_MD_pkey_type(EVP_MD_CTX_md(mdc)) == md_type) 1051 break; 1052 btmp = BIO_next(btmp); 1053 } 1054 1055 /* 1056 * mdc is the digest ctx that we want, unless there are attributes, in 1057 * which case the digest is the signed attributes 1058 */ 1059 if (!EVP_MD_CTX_copy_ex(&mdc_tmp, mdc)) 1060 goto err; 1061 1062 sk = si->auth_attr; 1063 if ((sk != NULL) && (sk_X509_ATTRIBUTE_num(sk) != 0)) { 1064 unsigned char md_dat[EVP_MAX_MD_SIZE], *abuf = NULL; 1065 unsigned int md_len; 1066 int alen; 1067 ASN1_OCTET_STRING *message_digest; 1068 1069 if (!EVP_DigestFinal_ex(&mdc_tmp, md_dat, &md_len)) 1070 goto err; 1071 message_digest = PKCS7_digest_from_attributes(sk); 1072 if (!message_digest) { 1073 PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, 1074 PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST); 1075 goto err; 1076 } 1077 if ((message_digest->length != (int)md_len) || 1078 (memcmp(message_digest->data, md_dat, md_len))) { 1079#if 0 1080 { 1081 int ii; 1082 for (ii = 0; ii < message_digest->length; ii++) 1083 printf("%02X", message_digest->data[ii]); 1084 printf(" sent\n"); 1085 for (ii = 0; ii < md_len; ii++) 1086 printf("%02X", md_dat[ii]); 1087 printf(" calc\n"); 1088 } 1089#endif 1090 PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, PKCS7_R_DIGEST_FAILURE); 1091 ret = -1; 1092 goto err; 1093 } 1094 1095 if (!EVP_VerifyInit_ex(&mdc_tmp, EVP_get_digestbynid(md_type), NULL)) 1096 goto err; 1097 1098 alen = ASN1_item_i2d((ASN1_VALUE *)sk, &abuf, 1099 ASN1_ITEM_rptr(PKCS7_ATTR_VERIFY)); 1100 if (alen <= 0) { 1101 PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, ERR_R_ASN1_LIB); 1102 ret = -1; 1103 goto err; 1104 } 1105 if (!EVP_VerifyUpdate(&mdc_tmp, abuf, alen)) 1106 goto err; 1107 1108 OPENSSL_free(abuf); 1109 } 1110 1111 os = si->enc_digest; 1112 pkey = X509_get_pubkey(x509); 1113 if (!pkey) { 1114 ret = -1; 1115 goto err; 1116 } 1117 1118 i = EVP_VerifyFinal(&mdc_tmp, os->data, os->length, pkey); 1119 EVP_PKEY_free(pkey); 1120 if (i <= 0) { 1121 PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, PKCS7_R_SIGNATURE_FAILURE); 1122 ret = -1; 1123 goto err; 1124 } else 1125 ret = 1; 1126 err: 1127 EVP_MD_CTX_cleanup(&mdc_tmp); 1128 return (ret); 1129} 1130 1131PKCS7_ISSUER_AND_SERIAL *PKCS7_get_issuer_and_serial(PKCS7 *p7, int idx) 1132{ 1133 STACK_OF(PKCS7_RECIP_INFO) *rsk; 1134 PKCS7_RECIP_INFO *ri; 1135 int i; 1136 1137 i = OBJ_obj2nid(p7->type); 1138 if (i != NID_pkcs7_signedAndEnveloped) 1139 return NULL; 1140 if (p7->d.signed_and_enveloped == NULL) 1141 return NULL; 1142 rsk = p7->d.signed_and_enveloped->recipientinfo; 1143 if (rsk == NULL) 1144 return NULL; 1145 ri = sk_PKCS7_RECIP_INFO_value(rsk, 0); 1146 if (sk_PKCS7_RECIP_INFO_num(rsk) <= idx) 1147 return (NULL); 1148 ri = sk_PKCS7_RECIP_INFO_value(rsk, idx); 1149 return (ri->issuer_and_serial); 1150} 1151 1152ASN1_TYPE *PKCS7_get_signed_attribute(PKCS7_SIGNER_INFO *si, int nid) 1153{ 1154 return (get_attribute(si->auth_attr, nid)); 1155} 1156 1157ASN1_TYPE *PKCS7_get_attribute(PKCS7_SIGNER_INFO *si, int nid) 1158{ 1159 return (get_attribute(si->unauth_attr, nid)); 1160} 1161 1162static ASN1_TYPE *get_attribute(STACK_OF(X509_ATTRIBUTE) *sk, int nid) 1163{ 1164 int i; 1165 X509_ATTRIBUTE *xa; 1166 ASN1_OBJECT *o; 1167 1168 o = OBJ_nid2obj(nid); 1169 if (!o || !sk) 1170 return (NULL); 1171 for (i = 0; i < sk_X509_ATTRIBUTE_num(sk); i++) { 1172 xa = sk_X509_ATTRIBUTE_value(sk, i); 1173 if (OBJ_cmp(xa->object, o) == 0) { 1174 if (!xa->single && sk_ASN1_TYPE_num(xa->value.set)) 1175 return (sk_ASN1_TYPE_value(xa->value.set, 0)); 1176 else 1177 return (NULL); 1178 } 1179 } 1180 return (NULL); 1181} 1182 1183ASN1_OCTET_STRING *PKCS7_digest_from_attributes(STACK_OF(X509_ATTRIBUTE) *sk) 1184{ 1185 ASN1_TYPE *astype; 1186 if (!(astype = get_attribute(sk, NID_pkcs9_messageDigest))) 1187 return NULL; 1188 return astype->value.octet_string; 1189} 1190 1191int PKCS7_set_signed_attributes(PKCS7_SIGNER_INFO *p7si, 1192 STACK_OF(X509_ATTRIBUTE) *sk) 1193{ 1194 int i; 1195 1196 if (p7si->auth_attr != NULL) 1197 sk_X509_ATTRIBUTE_pop_free(p7si->auth_attr, X509_ATTRIBUTE_free); 1198 p7si->auth_attr = sk_X509_ATTRIBUTE_dup(sk); 1199 if (p7si->auth_attr == NULL) 1200 return 0; 1201 for (i = 0; i < sk_X509_ATTRIBUTE_num(sk); i++) { 1202 if ((sk_X509_ATTRIBUTE_set(p7si->auth_attr, i, 1203 X509_ATTRIBUTE_dup(sk_X509_ATTRIBUTE_value 1204 (sk, i)))) 1205 == NULL) 1206 return (0); 1207 } 1208 return (1); 1209} 1210 1211int PKCS7_set_attributes(PKCS7_SIGNER_INFO *p7si, 1212 STACK_OF(X509_ATTRIBUTE) *sk) 1213{ 1214 int i; 1215 1216 if (p7si->unauth_attr != NULL) 1217 sk_X509_ATTRIBUTE_pop_free(p7si->unauth_attr, X509_ATTRIBUTE_free); 1218 p7si->unauth_attr = sk_X509_ATTRIBUTE_dup(sk); 1219 if (p7si->unauth_attr == NULL) 1220 return 0; 1221 for (i = 0; i < sk_X509_ATTRIBUTE_num(sk); i++) { 1222 if ((sk_X509_ATTRIBUTE_set(p7si->unauth_attr, i, 1223 X509_ATTRIBUTE_dup(sk_X509_ATTRIBUTE_value 1224 (sk, i)))) 1225 == NULL) 1226 return (0); 1227 } 1228 return (1); 1229} 1230 1231int PKCS7_add_signed_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int atrtype, 1232 void *value) 1233{ 1234 return (add_attribute(&(p7si->auth_attr), nid, atrtype, value)); 1235} 1236 1237int PKCS7_add_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int atrtype, 1238 void *value) 1239{ 1240 return (add_attribute(&(p7si->unauth_attr), nid, atrtype, value)); 1241} 1242 1243static int add_attribute(STACK_OF(X509_ATTRIBUTE) **sk, int nid, int atrtype, 1244 void *value) 1245{ 1246 X509_ATTRIBUTE *attr = NULL; 1247 1248 if (*sk == NULL) { 1249 *sk = sk_X509_ATTRIBUTE_new_null(); 1250 if (*sk == NULL) 1251 return 0; 1252 new_attrib: 1253 if (!(attr = X509_ATTRIBUTE_create(nid, atrtype, value))) 1254 return 0; 1255 if (!sk_X509_ATTRIBUTE_push(*sk, attr)) { 1256 X509_ATTRIBUTE_free(attr); 1257 return 0; 1258 } 1259 } else { 1260 int i; 1261 1262 for (i = 0; i < sk_X509_ATTRIBUTE_num(*sk); i++) { 1263 attr = sk_X509_ATTRIBUTE_value(*sk, i); 1264 if (OBJ_obj2nid(attr->object) == nid) { 1265 X509_ATTRIBUTE_free(attr); 1266 attr = X509_ATTRIBUTE_create(nid, atrtype, value); 1267 if (attr == NULL) 1268 return 0; 1269 if (!sk_X509_ATTRIBUTE_set(*sk, i, attr)) { 1270 X509_ATTRIBUTE_free(attr); 1271 return 0; 1272 } 1273 goto end; 1274 } 1275 } 1276 goto new_attrib; 1277 } 1278 end: 1279 return (1); 1280} 1281