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