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