1 /* $OpenBSD: cms_env.c,v 1.9 2015/09/10 15:56:25 jsing Exp $ */ 2 /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 3 * project. 4 */ 5 /* ==================================================================== 6 * Copyright (c) 2008 The OpenSSL Project. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in 17 * the documentation and/or other materials provided with the 18 * distribution. 19 * 20 * 3. All advertising materials mentioning features or use of this 21 * software must display the following acknowledgment: 22 * "This product includes software developed by the OpenSSL Project 23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 24 * 25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 26 * endorse or promote products derived from this software without 27 * prior written permission. For written permission, please contact 28 * licensing@OpenSSL.org. 29 * 30 * 5. Products derived from this software may not be called "OpenSSL" 31 * nor may "OpenSSL" appear in their names without prior written 32 * permission of the OpenSSL Project. 33 * 34 * 6. Redistributions of any form whatsoever must retain the following 35 * acknowledgment: 36 * "This product includes software developed by the OpenSSL Project 37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 38 * 39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 50 * OF THE POSSIBILITY OF SUCH DAMAGE. 51 * ==================================================================== 52 */ 53 54 #include <openssl/aes.h> 55 #include <openssl/asn1t.h> 56 #include <openssl/cms.h> 57 #include <openssl/err.h> 58 #include <openssl/pem.h> 59 #include <openssl/x509v3.h> 60 61 #include "cms_lcl.h" 62 #include "asn1_locl.h" 63 64 /* CMS EnvelopedData Utilities */ 65 66 DECLARE_ASN1_ITEM(CMS_EnvelopedData) 67 DECLARE_ASN1_ITEM(CMS_KeyTransRecipientInfo) 68 DECLARE_ASN1_ITEM(CMS_KEKRecipientInfo) 69 DECLARE_ASN1_ITEM(CMS_OtherKeyAttribute) 70 71 DECLARE_STACK_OF(CMS_RecipientInfo) 72 73 CMS_EnvelopedData * 74 cms_get0_enveloped(CMS_ContentInfo *cms) 75 { 76 if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_enveloped) { 77 CMSerr(CMS_F_CMS_GET0_ENVELOPED, 78 CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA); 79 return NULL; 80 } 81 return cms->d.envelopedData; 82 } 83 84 static CMS_EnvelopedData * 85 cms_enveloped_data_init(CMS_ContentInfo *cms) 86 { 87 if (cms->d.other == NULL) { 88 cms->d.envelopedData = M_ASN1_new_of(CMS_EnvelopedData); 89 if (!cms->d.envelopedData) { 90 CMSerr(CMS_F_CMS_ENVELOPED_DATA_INIT, 91 ERR_R_MALLOC_FAILURE); 92 return NULL; 93 } 94 cms->d.envelopedData->version = 0; 95 cms->d.envelopedData->encryptedContentInfo->contentType = 96 OBJ_nid2obj(NID_pkcs7_data); 97 ASN1_OBJECT_free(cms->contentType); 98 cms->contentType = OBJ_nid2obj(NID_pkcs7_enveloped); 99 return cms->d.envelopedData; 100 } 101 return cms_get0_enveloped(cms); 102 } 103 104 STACK_OF(CMS_RecipientInfo) *CMS_get0_RecipientInfos(CMS_ContentInfo *cms) 105 { 106 CMS_EnvelopedData *env; 107 108 env = cms_get0_enveloped(cms); 109 if (!env) 110 return NULL; 111 return env->recipientInfos; 112 } 113 114 int 115 CMS_RecipientInfo_type(CMS_RecipientInfo *ri) 116 { 117 return ri->type; 118 } 119 120 CMS_ContentInfo * 121 CMS_EnvelopedData_create(const EVP_CIPHER *cipher) 122 { 123 CMS_ContentInfo *cms; 124 CMS_EnvelopedData *env; 125 126 cms = CMS_ContentInfo_new(); 127 if (!cms) 128 goto merr; 129 env = cms_enveloped_data_init(cms); 130 if (!env) 131 goto merr; 132 if (!cms_EncryptedContent_init(env->encryptedContentInfo, 133 cipher, NULL, 0)) 134 goto merr; 135 return cms; 136 137 merr: 138 if (cms) 139 CMS_ContentInfo_free(cms); 140 CMSerr(CMS_F_CMS_ENVELOPEDDATA_CREATE, ERR_R_MALLOC_FAILURE); 141 return NULL; 142 } 143 144 /* Key Transport Recipient Info (KTRI) routines */ 145 146 /* Add a recipient certificate. For now only handle key transport. 147 * If we ever handle key agreement will need updating. 148 */ 149 150 CMS_RecipientInfo * 151 CMS_add1_recipient_cert(CMS_ContentInfo *cms, X509 *recip, unsigned int flags) 152 { 153 CMS_RecipientInfo *ri = NULL; 154 CMS_KeyTransRecipientInfo *ktri; 155 CMS_EnvelopedData *env; 156 EVP_PKEY *pk = NULL; 157 int i, type; 158 159 env = cms_get0_enveloped(cms); 160 if (!env) 161 goto err; 162 163 /* Initialize recipient info */ 164 ri = M_ASN1_new_of(CMS_RecipientInfo); 165 if (!ri) 166 goto merr; 167 168 /* Initialize and add key transport recipient info */ 169 170 ri->d.ktri = M_ASN1_new_of(CMS_KeyTransRecipientInfo); 171 if (!ri->d.ktri) 172 goto merr; 173 ri->type = CMS_RECIPINFO_TRANS; 174 175 ktri = ri->d.ktri; 176 177 X509_check_purpose(recip, -1, -1); 178 pk = X509_get_pubkey(recip); 179 if (!pk) { 180 CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT, 181 CMS_R_ERROR_GETTING_PUBLIC_KEY); 182 goto err; 183 } 184 CRYPTO_add(&recip->references, 1, CRYPTO_LOCK_X509); 185 ktri->pkey = pk; 186 ktri->recip = recip; 187 188 if (flags & CMS_USE_KEYID) { 189 ktri->version = 2; 190 type = CMS_RECIPINFO_KEYIDENTIFIER; 191 } else { 192 ktri->version = 0; 193 type = CMS_RECIPINFO_ISSUER_SERIAL; 194 } 195 196 /* Not a typo: RecipientIdentifier and SignerIdentifier are the 197 * same structure. 198 */ 199 200 if (!cms_set1_SignerIdentifier(ktri->rid, recip, type)) 201 goto err; 202 203 if (pk->ameth && pk->ameth->pkey_ctrl) { 204 i = pk->ameth->pkey_ctrl(pk, ASN1_PKEY_CTRL_CMS_ENVELOPE, 205 0, ri); 206 if (i == -2) { 207 CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT, 208 CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); 209 goto err; 210 } 211 if (i <= 0) { 212 CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT, 213 CMS_R_CTRL_FAILURE); 214 goto err; 215 } 216 } 217 218 if (!sk_CMS_RecipientInfo_push(env->recipientInfos, ri)) 219 goto merr; 220 221 return ri; 222 223 merr: 224 CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT, ERR_R_MALLOC_FAILURE); 225 err: 226 if (ri) 227 M_ASN1_free_of(ri, CMS_RecipientInfo); 228 return NULL; 229 } 230 231 int 232 CMS_RecipientInfo_ktri_get0_algs(CMS_RecipientInfo *ri, EVP_PKEY **pk, 233 X509 **recip, X509_ALGOR **palg) 234 { 235 CMS_KeyTransRecipientInfo *ktri; 236 237 if (ri->type != CMS_RECIPINFO_TRANS) { 238 CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_ALGS, 239 CMS_R_NOT_KEY_TRANSPORT); 240 return 0; 241 } 242 243 ktri = ri->d.ktri; 244 245 if (pk) 246 *pk = ktri->pkey; 247 if (recip) 248 *recip = ktri->recip; 249 if (palg) 250 *palg = ktri->keyEncryptionAlgorithm; 251 return 1; 252 } 253 254 int 255 CMS_RecipientInfo_ktri_get0_signer_id(CMS_RecipientInfo *ri, 256 ASN1_OCTET_STRING **keyid, X509_NAME **issuer, ASN1_INTEGER **sno) 257 { 258 CMS_KeyTransRecipientInfo *ktri; 259 260 if (ri->type != CMS_RECIPINFO_TRANS) { 261 CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_SIGNER_ID, 262 CMS_R_NOT_KEY_TRANSPORT); 263 return 0; 264 } 265 ktri = ri->d.ktri; 266 267 return cms_SignerIdentifier_get0_signer_id(ktri->rid, keyid, 268 issuer, sno); 269 } 270 271 int 272 CMS_RecipientInfo_ktri_cert_cmp(CMS_RecipientInfo *ri, X509 *cert) 273 { 274 if (ri->type != CMS_RECIPINFO_TRANS) { 275 CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_CERT_CMP, 276 CMS_R_NOT_KEY_TRANSPORT); 277 return -2; 278 } 279 return cms_SignerIdentifier_cert_cmp(ri->d.ktri->rid, cert); 280 } 281 282 int 283 CMS_RecipientInfo_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pkey) 284 { 285 if (ri->type != CMS_RECIPINFO_TRANS) { 286 CMSerr(CMS_F_CMS_RECIPIENTINFO_SET0_PKEY, 287 CMS_R_NOT_KEY_TRANSPORT); 288 return 0; 289 } 290 ri->d.ktri->pkey = pkey; 291 return 1; 292 } 293 294 /* Encrypt content key in key transport recipient info */ 295 296 static int 297 cms_RecipientInfo_ktri_encrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri) 298 { 299 CMS_KeyTransRecipientInfo *ktri; 300 CMS_EncryptedContentInfo *ec; 301 EVP_PKEY_CTX *pctx = NULL; 302 unsigned char *ek = NULL; 303 size_t eklen; 304 305 int ret = 0; 306 307 if (ri->type != CMS_RECIPINFO_TRANS) { 308 CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT, 309 CMS_R_NOT_KEY_TRANSPORT); 310 return 0; 311 } 312 ktri = ri->d.ktri; 313 ec = cms->d.envelopedData->encryptedContentInfo; 314 315 pctx = EVP_PKEY_CTX_new(ktri->pkey, NULL); 316 if (!pctx) 317 return 0; 318 319 if (EVP_PKEY_encrypt_init(pctx) <= 0) 320 goto err; 321 322 if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_ENCRYPT, 323 EVP_PKEY_CTRL_CMS_ENCRYPT, 0, ri) <= 0) { 324 CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT, CMS_R_CTRL_ERROR); 325 goto err; 326 } 327 328 if (EVP_PKEY_encrypt(pctx, NULL, &eklen, ec->key, ec->keylen) <= 0) 329 goto err; 330 331 ek = malloc(eklen); 332 333 if (ek == NULL) { 334 CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT, 335 ERR_R_MALLOC_FAILURE); 336 goto err; 337 } 338 339 if (EVP_PKEY_encrypt(pctx, ek, &eklen, ec->key, ec->keylen) <= 0) 340 goto err; 341 342 ASN1_STRING_set0(ktri->encryptedKey, ek, eklen); 343 ek = NULL; 344 345 ret = 1; 346 347 err: 348 EVP_PKEY_CTX_free(pctx); 349 free(ek); 350 return ret; 351 } 352 353 /* Decrypt content key from KTRI */ 354 355 static int 356 cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri) 357 { 358 CMS_KeyTransRecipientInfo *ktri = ri->d.ktri; 359 EVP_PKEY_CTX *pctx = NULL; 360 unsigned char *ek = NULL; 361 size_t eklen; 362 int ret = 0; 363 CMS_EncryptedContentInfo *ec; 364 365 ec = cms->d.envelopedData->encryptedContentInfo; 366 367 if (ktri->pkey == NULL) { 368 CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, 369 CMS_R_NO_PRIVATE_KEY); 370 return 0; 371 } 372 373 pctx = EVP_PKEY_CTX_new(ktri->pkey, NULL); 374 if (!pctx) 375 return 0; 376 377 if (EVP_PKEY_decrypt_init(pctx) <= 0) 378 goto err; 379 380 if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DECRYPT, 381 EVP_PKEY_CTRL_CMS_DECRYPT, 0, ri) <= 0) { 382 CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_CTRL_ERROR); 383 goto err; 384 } 385 386 if (EVP_PKEY_decrypt(pctx, NULL, &eklen, 387 ktri->encryptedKey->data, 388 ktri->encryptedKey->length) <= 0) 389 goto err; 390 391 ek = malloc(eklen); 392 393 if (ek == NULL) { 394 CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, 395 ERR_R_MALLOC_FAILURE); 396 goto err; 397 } 398 399 if (EVP_PKEY_decrypt(pctx, ek, &eklen, 400 ktri->encryptedKey->data, 401 ktri->encryptedKey->length) <= 0) { 402 CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_CMS_LIB); 403 goto err; 404 } 405 406 ret = 1; 407 408 if (ec->key) { 409 explicit_bzero(ec->key, ec->keylen); 410 free(ec->key); 411 } 412 413 ec->key = ek; 414 ec->keylen = eklen; 415 416 err: 417 EVP_PKEY_CTX_free(pctx); 418 if (!ret && ek) 419 free(ek); 420 421 return ret; 422 } 423 424 /* Key Encrypted Key (KEK) RecipientInfo routines */ 425 426 int 427 CMS_RecipientInfo_kekri_id_cmp(CMS_RecipientInfo *ri, const unsigned char *id, 428 size_t idlen) 429 { 430 ASN1_OCTET_STRING tmp_os; 431 CMS_KEKRecipientInfo *kekri; 432 433 if (ri->type != CMS_RECIPINFO_KEK) { 434 CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ID_CMP, CMS_R_NOT_KEK); 435 return -2; 436 } 437 kekri = ri->d.kekri; 438 tmp_os.type = V_ASN1_OCTET_STRING; 439 tmp_os.flags = 0; 440 tmp_os.data = (unsigned char *)id; 441 tmp_os.length = (int)idlen; 442 return ASN1_OCTET_STRING_cmp(&tmp_os, kekri->kekid->keyIdentifier); 443 } 444 445 /* For now hard code AES key wrap info */ 446 447 static size_t 448 aes_wrap_keylen(int nid) 449 { 450 switch (nid) { 451 case NID_id_aes128_wrap: 452 return 16; 453 case NID_id_aes192_wrap: 454 return 24; 455 case NID_id_aes256_wrap: 456 return 32; 457 default: 458 return 0; 459 } 460 } 461 462 CMS_RecipientInfo * 463 CMS_add0_recipient_key(CMS_ContentInfo *cms, int nid, unsigned char *key, 464 size_t keylen, unsigned char *id, size_t idlen, ASN1_GENERALIZEDTIME *date, 465 ASN1_OBJECT *otherTypeId, ASN1_TYPE *otherType) 466 { 467 CMS_RecipientInfo *ri = NULL; 468 CMS_EnvelopedData *env; 469 CMS_KEKRecipientInfo *kekri; 470 471 env = cms_get0_enveloped(cms); 472 if (!env) 473 goto err; 474 475 if (nid == NID_undef) { 476 switch (keylen) { 477 case 16: 478 nid = NID_id_aes128_wrap; 479 break; 480 case 24: 481 nid = NID_id_aes192_wrap; 482 break; 483 case 32: 484 nid = NID_id_aes256_wrap; 485 break; 486 default: 487 CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY, 488 CMS_R_INVALID_KEY_LENGTH); 489 goto err; 490 } 491 } else { 492 size_t exp_keylen = aes_wrap_keylen(nid); 493 494 if (!exp_keylen) { 495 CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY, 496 CMS_R_UNSUPPORTED_KEK_ALGORITHM); 497 goto err; 498 } 499 500 if (keylen != exp_keylen) { 501 CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY, 502 CMS_R_INVALID_KEY_LENGTH); 503 goto err; 504 } 505 506 } 507 508 /* Initialize recipient info */ 509 ri = M_ASN1_new_of(CMS_RecipientInfo); 510 if (!ri) 511 goto merr; 512 513 ri->d.kekri = M_ASN1_new_of(CMS_KEKRecipientInfo); 514 if (!ri->d.kekri) 515 goto merr; 516 ri->type = CMS_RECIPINFO_KEK; 517 518 kekri = ri->d.kekri; 519 520 if (otherTypeId) { 521 kekri->kekid->other = M_ASN1_new_of(CMS_OtherKeyAttribute); 522 if (kekri->kekid->other == NULL) 523 goto merr; 524 } 525 526 if (!sk_CMS_RecipientInfo_push(env->recipientInfos, ri)) 527 goto merr; 528 529 /* After this point no calls can fail */ 530 531 kekri->version = 4; 532 533 kekri->key = key; 534 kekri->keylen = keylen; 535 536 ASN1_STRING_set0(kekri->kekid->keyIdentifier, id, idlen); 537 538 kekri->kekid->date = date; 539 540 if (kekri->kekid->other) { 541 kekri->kekid->other->keyAttrId = otherTypeId; 542 kekri->kekid->other->keyAttr = otherType; 543 } 544 545 X509_ALGOR_set0(kekri->keyEncryptionAlgorithm, 546 OBJ_nid2obj(nid), V_ASN1_UNDEF, NULL); 547 548 return ri; 549 550 merr: 551 CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY, ERR_R_MALLOC_FAILURE); 552 err: 553 if (ri) 554 M_ASN1_free_of(ri, CMS_RecipientInfo); 555 return NULL; 556 } 557 558 int 559 CMS_RecipientInfo_kekri_get0_id(CMS_RecipientInfo *ri, X509_ALGOR **palg, 560 ASN1_OCTET_STRING **pid, ASN1_GENERALIZEDTIME **pdate, 561 ASN1_OBJECT **potherid, ASN1_TYPE **pothertype) 562 { 563 CMS_KEKIdentifier *rkid; 564 565 if (ri->type != CMS_RECIPINFO_KEK) { 566 CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_GET0_ID, CMS_R_NOT_KEK); 567 return 0; 568 } 569 rkid = ri->d.kekri->kekid; 570 if (palg) 571 *palg = ri->d.kekri->keyEncryptionAlgorithm; 572 if (pid) 573 *pid = rkid->keyIdentifier; 574 if (pdate) 575 *pdate = rkid->date; 576 if (potherid) { 577 if (rkid->other) 578 *potherid = rkid->other->keyAttrId; 579 else 580 *potherid = NULL; 581 } 582 if (pothertype) { 583 if (rkid->other) 584 *pothertype = rkid->other->keyAttr; 585 else 586 *pothertype = NULL; 587 } 588 return 1; 589 } 590 591 int 592 CMS_RecipientInfo_set0_key(CMS_RecipientInfo *ri, unsigned char *key, 593 size_t keylen) 594 { 595 CMS_KEKRecipientInfo *kekri; 596 597 if (ri->type != CMS_RECIPINFO_KEK) { 598 CMSerr(CMS_F_CMS_RECIPIENTINFO_SET0_KEY, CMS_R_NOT_KEK); 599 return 0; 600 } 601 602 kekri = ri->d.kekri; 603 kekri->key = key; 604 kekri->keylen = keylen; 605 return 1; 606 } 607 608 /* Encrypt content key in KEK recipient info */ 609 610 static int 611 cms_RecipientInfo_kekri_encrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri) 612 { 613 CMS_EncryptedContentInfo *ec; 614 CMS_KEKRecipientInfo *kekri; 615 AES_KEY actx; 616 unsigned char *wkey = NULL; 617 int wkeylen; 618 int r = 0; 619 620 ec = cms->d.envelopedData->encryptedContentInfo; 621 622 kekri = ri->d.kekri; 623 624 if (!kekri->key) { 625 CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, CMS_R_NO_KEY); 626 return 0; 627 } 628 629 if (AES_set_encrypt_key(kekri->key, kekri->keylen << 3, &actx)) { 630 CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, 631 CMS_R_ERROR_SETTING_KEY); 632 goto err; 633 } 634 635 wkey = malloc(ec->keylen + 8); 636 637 if (!wkey) { 638 CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, 639 ERR_R_MALLOC_FAILURE); 640 goto err; 641 } 642 643 wkeylen = AES_wrap_key(&actx, NULL, wkey, ec->key, ec->keylen); 644 645 if (wkeylen <= 0) { 646 CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, CMS_R_WRAP_ERROR); 647 goto err; 648 } 649 650 ASN1_STRING_set0(kekri->encryptedKey, wkey, wkeylen); 651 652 r = 1; 653 654 err: 655 if (!r && wkey) 656 free(wkey); 657 explicit_bzero(&actx, sizeof(actx)); 658 659 return r; 660 } 661 662 /* Decrypt content key in KEK recipient info */ 663 664 static int 665 cms_RecipientInfo_kekri_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri) 666 { 667 CMS_EncryptedContentInfo *ec; 668 CMS_KEKRecipientInfo *kekri; 669 AES_KEY actx; 670 unsigned char *ukey = NULL; 671 int ukeylen; 672 int r = 0, wrap_nid; 673 674 ec = cms->d.envelopedData->encryptedContentInfo; 675 676 kekri = ri->d.kekri; 677 678 if (!kekri->key) { 679 CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, CMS_R_NO_KEY); 680 return 0; 681 } 682 683 wrap_nid = OBJ_obj2nid(kekri->keyEncryptionAlgorithm->algorithm); 684 if (aes_wrap_keylen(wrap_nid) != kekri->keylen) { 685 CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, 686 CMS_R_INVALID_KEY_LENGTH); 687 return 0; 688 } 689 690 /* If encrypted key length is invalid don't bother */ 691 692 if (kekri->encryptedKey->length < 16) { 693 CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, 694 CMS_R_INVALID_ENCRYPTED_KEY_LENGTH); 695 goto err; 696 } 697 698 if (AES_set_decrypt_key(kekri->key, kekri->keylen << 3, &actx)) { 699 CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, 700 CMS_R_ERROR_SETTING_KEY); 701 goto err; 702 } 703 704 ukey = malloc(kekri->encryptedKey->length - 8); 705 706 if (!ukey) { 707 CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, 708 ERR_R_MALLOC_FAILURE); 709 goto err; 710 } 711 712 ukeylen = AES_unwrap_key(&actx, NULL, ukey, 713 kekri->encryptedKey->data, 714 kekri->encryptedKey->length); 715 716 if (ukeylen <= 0) { 717 CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, 718 CMS_R_UNWRAP_ERROR); 719 goto err; 720 } 721 722 ec->key = ukey; 723 ec->keylen = ukeylen; 724 725 r = 1; 726 727 err: 728 if (!r && ukey) 729 free(ukey); 730 explicit_bzero(&actx, sizeof(actx)); 731 732 return r; 733 } 734 735 int 736 CMS_RecipientInfo_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri) 737 { 738 switch (ri->type) { 739 case CMS_RECIPINFO_TRANS: 740 return cms_RecipientInfo_ktri_decrypt(cms, ri); 741 case CMS_RECIPINFO_KEK: 742 return cms_RecipientInfo_kekri_decrypt(cms, ri); 743 case CMS_RECIPINFO_PASS: 744 return cms_RecipientInfo_pwri_crypt(cms, ri, 0); 745 default: 746 CMSerr(CMS_F_CMS_RECIPIENTINFO_DECRYPT, 747 CMS_R_UNSUPPORTED_RECPIENTINFO_TYPE); 748 return 0; 749 } 750 } 751 752 BIO * 753 cms_EnvelopedData_init_bio(CMS_ContentInfo *cms) 754 { 755 CMS_EncryptedContentInfo *ec; 756 STACK_OF(CMS_RecipientInfo) *rinfos; 757 CMS_RecipientInfo *ri; 758 int i, r, ok = 0; 759 BIO *ret; 760 761 /* Get BIO first to set up key */ 762 763 ec = cms->d.envelopedData->encryptedContentInfo; 764 ret = cms_EncryptedContent_init_bio(ec); 765 766 /* If error or no cipher end of processing */ 767 768 if (!ret || !ec->cipher) 769 return ret; 770 771 /* Now encrypt content key according to each RecipientInfo type */ 772 773 rinfos = cms->d.envelopedData->recipientInfos; 774 775 for (i = 0; i < sk_CMS_RecipientInfo_num(rinfos); i++) { 776 ri = sk_CMS_RecipientInfo_value(rinfos, i); 777 778 switch (ri->type) { 779 case CMS_RECIPINFO_TRANS: 780 r = cms_RecipientInfo_ktri_encrypt(cms, ri); 781 break; 782 783 case CMS_RECIPINFO_KEK: 784 r = cms_RecipientInfo_kekri_encrypt(cms, ri); 785 break; 786 787 case CMS_RECIPINFO_PASS: 788 r = cms_RecipientInfo_pwri_crypt(cms, ri, 1); 789 break; 790 791 default: 792 CMSerr(CMS_F_CMS_ENVELOPEDDATA_INIT_BIO, 793 CMS_R_UNSUPPORTED_RECIPIENT_TYPE); 794 goto err; 795 } 796 797 if (r <= 0) { 798 CMSerr(CMS_F_CMS_ENVELOPEDDATA_INIT_BIO, 799 CMS_R_ERROR_SETTING_RECIPIENTINFO); 800 goto err; 801 } 802 } 803 804 ok = 1; 805 806 err: 807 ec->cipher = NULL; 808 if (ec->key) { 809 explicit_bzero(ec->key, ec->keylen); 810 free(ec->key); 811 ec->key = NULL; 812 ec->keylen = 0; 813 } 814 if (ok) 815 return ret; 816 BIO_free(ret); 817 return NULL; 818 } 819