1 /* $NetBSD: cms.c,v 1.4 2023/06/19 21:41:44 christos Exp $ */ 2 3 /* 4 * Copyright (c) 2003 - 2007 Kungliga Tekniska Högskolan 5 * (Royal Institute of Technology, Stockholm, Sweden). 6 * 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 the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * 3. Neither the name of the Institute nor the names of its contributors 20 * may be used to endorse or promote products derived from this software 21 * without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 */ 35 36 #include "hx_locl.h" 37 38 /** 39 * @page page_cms CMS/PKCS7 message functions. 40 * 41 * CMS is defined in RFC 3369 and is an continuation of the RSA Labs 42 * standard PKCS7. The basic messages in CMS is 43 * 44 * - SignedData 45 * Data signed with private key (RSA, DSA, ECDSA) or secret 46 * (symmetric) key 47 * - EnvelopedData 48 * Data encrypted with private key (RSA) 49 * - EncryptedData 50 * Data encrypted with secret (symmetric) key. 51 * - ContentInfo 52 * Wrapper structure including type and data. 53 * 54 * 55 * See the library functions here: @ref hx509_cms 56 */ 57 58 #define ALLOC(X, N) (X) = calloc((N), sizeof(*(X))) 59 #define ALLOC_SEQ(X, N) do { (X)->len = (N); ALLOC((X)->val, (N)); } while(0) 60 61 /** 62 * Wrap data and oid in a ContentInfo and encode it. 63 * 64 * @param oid type of the content. 65 * @param buf data to be wrapped. If a NULL pointer is passed in, the 66 * optional content field in the ContentInfo is not going be filled 67 * in. 68 * @param res the encoded buffer, the result should be freed with 69 * der_free_octet_string(). 70 * 71 * @return Returns an hx509 error code. 72 * 73 * @ingroup hx509_cms 74 */ 75 76 int 77 hx509_cms_wrap_ContentInfo(const heim_oid *oid, 78 const heim_octet_string *buf, 79 heim_octet_string *res) 80 { 81 ContentInfo ci; 82 size_t size; 83 int ret; 84 85 memset(res, 0, sizeof(*res)); 86 memset(&ci, 0, sizeof(ci)); 87 88 ret = der_copy_oid(oid, &ci.contentType); 89 if (ret) 90 return ret; 91 if (buf) { 92 ALLOC(ci.content, 1); 93 if (ci.content == NULL) { 94 free_ContentInfo(&ci); 95 return ENOMEM; 96 } 97 ci.content->data = malloc(buf->length); 98 if (ci.content->data == NULL) { 99 free_ContentInfo(&ci); 100 return ENOMEM; 101 } 102 memcpy(ci.content->data, buf->data, buf->length); 103 ci.content->length = buf->length; 104 } 105 106 ASN1_MALLOC_ENCODE(ContentInfo, res->data, res->length, &ci, &size, ret); 107 free_ContentInfo(&ci); 108 if (ret) 109 return ret; 110 if (res->length != size) 111 _hx509_abort("internal ASN.1 encoder error"); 112 113 return 0; 114 } 115 116 /** 117 * Decode an ContentInfo and unwrap data and oid it. 118 * 119 * @param in the encoded buffer. 120 * @param oid type of the content. 121 * @param out data to be wrapped. 122 * @param have_data since the data is optional, this flags show dthe 123 * diffrence between no data and the zero length data. 124 * 125 * @return Returns an hx509 error code. 126 * 127 * @ingroup hx509_cms 128 */ 129 130 int 131 hx509_cms_unwrap_ContentInfo(const heim_octet_string *in, 132 heim_oid *oid, 133 heim_octet_string *out, 134 int *have_data) 135 { 136 ContentInfo ci; 137 size_t size; 138 int ret; 139 140 memset(oid, 0, sizeof(*oid)); 141 memset(out, 0, sizeof(*out)); 142 143 ret = decode_ContentInfo(in->data, in->length, &ci, &size); 144 if (ret) 145 return ret; 146 147 ret = der_copy_oid(&ci.contentType, oid); 148 if (ret) { 149 free_ContentInfo(&ci); 150 return ret; 151 } 152 if (ci.content) { 153 ret = der_copy_octet_string(ci.content, out); 154 if (ret) { 155 der_free_oid(oid); 156 free_ContentInfo(&ci); 157 return ret; 158 } 159 } else 160 memset(out, 0, sizeof(*out)); 161 162 if (have_data) 163 *have_data = (ci.content != NULL) ? 1 : 0; 164 165 free_ContentInfo(&ci); 166 167 return 0; 168 } 169 170 #define CMS_ID_SKI 0 171 #define CMS_ID_NAME 1 172 173 static int 174 fill_CMSIdentifier(const hx509_cert cert, 175 int type, 176 CMSIdentifier *id) 177 { 178 int ret; 179 180 switch (type) { 181 case CMS_ID_SKI: 182 id->element = choice_CMSIdentifier_subjectKeyIdentifier; 183 ret = _hx509_find_extension_subject_key_id(_hx509_get_cert(cert), 184 &id->u.subjectKeyIdentifier); 185 if (ret == 0) 186 break; 187 /* FALLTHROUGH */ 188 case CMS_ID_NAME: { 189 hx509_name name; 190 191 id->element = choice_CMSIdentifier_issuerAndSerialNumber; 192 ret = hx509_cert_get_issuer(cert, &name); 193 if (ret) 194 return ret; 195 ret = hx509_name_to_Name(name, &id->u.issuerAndSerialNumber.issuer); 196 hx509_name_free(&name); 197 if (ret) 198 return ret; 199 200 ret = hx509_cert_get_serialnumber(cert, &id->u.issuerAndSerialNumber.serialNumber); 201 break; 202 } 203 default: 204 _hx509_abort("CMS fill identifier with unknown type"); 205 } 206 return ret; 207 } 208 209 static int 210 unparse_CMSIdentifier(hx509_context context, 211 CMSIdentifier *id, 212 char **str) 213 { 214 int ret = -1; 215 216 *str = NULL; 217 switch (id->element) { 218 case choice_CMSIdentifier_issuerAndSerialNumber: { 219 IssuerAndSerialNumber *iasn; 220 char *serial, *name; 221 222 iasn = &id->u.issuerAndSerialNumber; 223 224 ret = _hx509_Name_to_string(&iasn->issuer, &name); 225 if(ret) 226 return ret; 227 ret = der_print_hex_heim_integer(&iasn->serialNumber, &serial); 228 if (ret) { 229 free(name); 230 return ret; 231 } 232 ret = asprintf(str, "certificate issued by %s with serial number %s", 233 name, serial); 234 free(name); 235 free(serial); 236 break; 237 } 238 case choice_CMSIdentifier_subjectKeyIdentifier: { 239 KeyIdentifier *ki = &id->u.subjectKeyIdentifier; 240 char *keyid; 241 ssize_t len; 242 243 len = hex_encode(ki->data, ki->length, &keyid); 244 if (len < 0) 245 return ENOMEM; 246 247 ret = asprintf(str, "certificate with id %s", keyid); 248 free(keyid); 249 break; 250 } 251 default: 252 ret = asprintf(str, "certificate have unknown CMSidentifier type"); 253 break; 254 } 255 /* 256 * In the following if, we check ret and *str which should be returned/set 257 * by asprintf(3) in every branch of the switch statement. 258 */ 259 if (ret == -1 || *str == NULL) 260 return ENOMEM; 261 return 0; 262 } 263 264 static int 265 find_CMSIdentifier(hx509_context context, 266 CMSIdentifier *client, 267 hx509_certs certs, 268 time_t time_now, 269 hx509_cert *signer_cert, 270 int match) 271 { 272 hx509_query q; 273 hx509_cert cert; 274 Certificate c; 275 int ret; 276 277 memset(&c, 0, sizeof(c)); 278 _hx509_query_clear(&q); 279 280 *signer_cert = NULL; 281 282 switch (client->element) { 283 case choice_CMSIdentifier_issuerAndSerialNumber: 284 q.serial = &client->u.issuerAndSerialNumber.serialNumber; 285 q.issuer_name = &client->u.issuerAndSerialNumber.issuer; 286 q.match = HX509_QUERY_MATCH_SERIALNUMBER|HX509_QUERY_MATCH_ISSUER_NAME; 287 break; 288 case choice_CMSIdentifier_subjectKeyIdentifier: 289 q.subject_id = &client->u.subjectKeyIdentifier; 290 q.match = HX509_QUERY_MATCH_SUBJECT_KEY_ID; 291 break; 292 default: 293 hx509_set_error_string(context, 0, HX509_CMS_NO_RECIPIENT_CERTIFICATE, 294 "unknown CMS identifier element"); 295 return HX509_CMS_NO_RECIPIENT_CERTIFICATE; 296 } 297 298 q.match |= match; 299 300 q.match |= HX509_QUERY_MATCH_TIME; 301 if (time_now) 302 q.timenow = time_now; 303 else 304 q.timenow = time(NULL); 305 306 ret = hx509_certs_find(context, certs, &q, &cert); 307 if (ret == HX509_CERT_NOT_FOUND) { 308 char *str; 309 310 ret = unparse_CMSIdentifier(context, client, &str); 311 if (ret == 0) { 312 hx509_set_error_string(context, 0, 313 HX509_CMS_NO_RECIPIENT_CERTIFICATE, 314 "Failed to find %s", str); 315 } else 316 hx509_clear_error_string(context); 317 return HX509_CMS_NO_RECIPIENT_CERTIFICATE; 318 } else if (ret) { 319 hx509_set_error_string(context, HX509_ERROR_APPEND, 320 HX509_CMS_NO_RECIPIENT_CERTIFICATE, 321 "Failed to find CMS id in cert store"); 322 return HX509_CMS_NO_RECIPIENT_CERTIFICATE; 323 } 324 325 *signer_cert = cert; 326 327 return 0; 328 } 329 330 /** 331 * Decode and unencrypt EnvelopedData. 332 * 333 * Extract data and parameteres from from the EnvelopedData. Also 334 * supports using detached EnvelopedData. 335 * 336 * @param context A hx509 context. 337 * @param certs Certificate that can decrypt the EnvelopedData 338 * encryption key. 339 * @param flags HX509_CMS_UE flags to control the behavior. 340 * @param data pointer the structure the contains the DER/BER encoded 341 * EnvelopedData stucture. 342 * @param length length of the data that data point to. 343 * @param encryptedContent in case of detached signature, this 344 * contains the actual encrypted data, othersize its should be NULL. 345 * @param time_now set the current time, if zero the library uses now as the date. 346 * @param contentType output type oid, should be freed with der_free_oid(). 347 * @param content the data, free with der_free_octet_string(). 348 * 349 * @return an hx509 error code. 350 * 351 * @ingroup hx509_cms 352 */ 353 354 int 355 hx509_cms_unenvelope(hx509_context context, 356 hx509_certs certs, 357 int flags, 358 const void *data, 359 size_t length, 360 const heim_octet_string *encryptedContent, 361 time_t time_now, 362 heim_oid *contentType, 363 heim_octet_string *content) 364 { 365 heim_octet_string key; 366 EnvelopedData ed; 367 hx509_cert cert; 368 AlgorithmIdentifier *ai; 369 const heim_octet_string *enccontent; 370 heim_octet_string *params, params_data; 371 heim_octet_string ivec; 372 size_t size; 373 int ret, matched = 0, findflags = 0; 374 size_t i; 375 376 377 memset(&key, 0, sizeof(key)); 378 memset(&ed, 0, sizeof(ed)); 379 memset(&ivec, 0, sizeof(ivec)); 380 memset(content, 0, sizeof(*content)); 381 memset(contentType, 0, sizeof(*contentType)); 382 383 if ((flags & HX509_CMS_UE_DONT_REQUIRE_KU_ENCIPHERMENT) == 0) 384 findflags |= HX509_QUERY_KU_ENCIPHERMENT; 385 386 ret = decode_EnvelopedData(data, length, &ed, &size); 387 if (ret) { 388 hx509_set_error_string(context, 0, ret, 389 "Failed to decode EnvelopedData"); 390 return ret; 391 } 392 393 if (ed.recipientInfos.len == 0) { 394 ret = HX509_CMS_NO_RECIPIENT_CERTIFICATE; 395 hx509_set_error_string(context, 0, ret, 396 "No recipient info in enveloped data"); 397 goto out; 398 } 399 400 enccontent = ed.encryptedContentInfo.encryptedContent; 401 if (enccontent == NULL) { 402 if (encryptedContent == NULL) { 403 ret = HX509_CMS_NO_DATA_AVAILABLE; 404 hx509_set_error_string(context, 0, ret, 405 "Content missing from encrypted data"); 406 goto out; 407 } 408 enccontent = encryptedContent; 409 } else if (encryptedContent != NULL) { 410 ret = HX509_CMS_NO_DATA_AVAILABLE; 411 hx509_set_error_string(context, 0, ret, 412 "Both internal and external encrypted data"); 413 goto out; 414 } 415 416 cert = NULL; 417 for (i = 0; i < ed.recipientInfos.len; i++) { 418 KeyTransRecipientInfo *ri; 419 char *str; 420 int ret2; 421 422 ri = &ed.recipientInfos.val[i]; 423 424 ret = find_CMSIdentifier(context, &ri->rid, certs, 425 time_now, &cert, 426 HX509_QUERY_PRIVATE_KEY|findflags); 427 if (ret) 428 continue; 429 430 matched = 1; /* found a matching certificate, let decrypt */ 431 432 ret = _hx509_cert_private_decrypt(context, 433 &ri->encryptedKey, 434 &ri->keyEncryptionAlgorithm.algorithm, 435 cert, &key); 436 437 hx509_cert_free(cert); 438 if (ret == 0) 439 break; /* succuessfully decrypted cert */ 440 cert = NULL; 441 ret2 = unparse_CMSIdentifier(context, &ri->rid, &str); 442 if (ret2 == 0) { 443 hx509_set_error_string(context, HX509_ERROR_APPEND, ret, 444 "Failed to decrypt with %s", str); 445 free(str); 446 } 447 } 448 449 if (!matched) { 450 ret = HX509_CMS_NO_RECIPIENT_CERTIFICATE; 451 hx509_set_error_string(context, 0, ret, 452 "No private key matched any certificate"); 453 goto out; 454 } 455 456 if (cert == NULL) { 457 ret = HX509_CMS_NO_RECIPIENT_CERTIFICATE; 458 hx509_set_error_string(context, HX509_ERROR_APPEND, ret, 459 "No private key decrypted the transfer key"); 460 goto out; 461 } 462 463 ret = der_copy_oid(&ed.encryptedContentInfo.contentType, contentType); 464 if (ret) { 465 hx509_set_error_string(context, 0, ret, 466 "Failed to copy EnvelopedData content oid"); 467 goto out; 468 } 469 470 ai = &ed.encryptedContentInfo.contentEncryptionAlgorithm; 471 if (ai->parameters) { 472 params_data.data = ai->parameters->data; 473 params_data.length = ai->parameters->length; 474 params = ¶ms_data; 475 } else 476 params = NULL; 477 478 { 479 hx509_crypto crypto; 480 481 ret = hx509_crypto_init(context, NULL, &ai->algorithm, &crypto); 482 if (ret) 483 goto out; 484 485 if (flags & HX509_CMS_UE_ALLOW_WEAK) 486 hx509_crypto_allow_weak(crypto); 487 488 if (params) { 489 ret = hx509_crypto_set_params(context, crypto, params, &ivec); 490 if (ret) { 491 hx509_crypto_destroy(crypto); 492 goto out; 493 } 494 } 495 496 ret = hx509_crypto_set_key_data(crypto, key.data, key.length); 497 if (ret) { 498 hx509_crypto_destroy(crypto); 499 hx509_set_error_string(context, 0, ret, 500 "Failed to set key for decryption " 501 "of EnvelopedData"); 502 goto out; 503 } 504 505 ret = hx509_crypto_decrypt(crypto, 506 enccontent->data, 507 enccontent->length, 508 ivec.length ? &ivec : NULL, 509 content); 510 hx509_crypto_destroy(crypto); 511 if (ret) { 512 hx509_set_error_string(context, 0, ret, 513 "Failed to decrypt EnvelopedData"); 514 goto out; 515 } 516 } 517 518 out: 519 520 free_EnvelopedData(&ed); 521 der_free_octet_string(&key); 522 if (ivec.length) 523 der_free_octet_string(&ivec); 524 if (ret) { 525 der_free_oid(contentType); 526 der_free_octet_string(content); 527 } 528 529 return ret; 530 } 531 532 /** 533 * Encrypt end encode EnvelopedData. 534 * 535 * Encrypt and encode EnvelopedData. The data is encrypted with a 536 * random key and the the random key is encrypted with the 537 * certificates private key. This limits what private key type can be 538 * used to RSA. 539 * 540 * @param context A hx509 context. 541 * @param flags flags to control the behavior. 542 * - HX509_CMS_EV_NO_KU_CHECK - Don't check KU on certificate 543 * - HX509_CMS_EV_ALLOW_WEAK - Allow weak crytpo 544 * - HX509_CMS_EV_ID_NAME - prefer issuer name and serial number 545 * @param cert Certificate to encrypt the EnvelopedData encryption key 546 * with. 547 * @param data pointer the data to encrypt. 548 * @param length length of the data that data point to. 549 * @param encryption_type Encryption cipher to use for the bulk data, 550 * use NULL to get default. 551 * @param contentType type of the data that is encrypted 552 * @param content the output of the function, 553 * free with der_free_octet_string(). 554 * 555 * @return an hx509 error code. 556 * 557 * @ingroup hx509_cms 558 */ 559 560 int 561 hx509_cms_envelope_1(hx509_context context, 562 int flags, 563 hx509_cert cert, 564 const void *data, 565 size_t length, 566 const heim_oid *encryption_type, 567 const heim_oid *contentType, 568 heim_octet_string *content) 569 { 570 KeyTransRecipientInfo *ri; 571 heim_octet_string ivec; 572 heim_octet_string key; 573 hx509_crypto crypto = NULL; 574 int ret, cmsidflag; 575 EnvelopedData ed; 576 size_t size; 577 578 memset(&ivec, 0, sizeof(ivec)); 579 memset(&key, 0, sizeof(key)); 580 memset(&ed, 0, sizeof(ed)); 581 memset(content, 0, sizeof(*content)); 582 583 if (encryption_type == NULL) 584 encryption_type = &asn1_oid_id_aes_256_cbc; 585 586 if ((flags & HX509_CMS_EV_NO_KU_CHECK) == 0) { 587 ret = _hx509_check_key_usage(context, cert, 1 << 2, TRUE); 588 if (ret) 589 goto out; 590 } 591 592 ret = hx509_crypto_init(context, NULL, encryption_type, &crypto); 593 if (ret) 594 goto out; 595 596 if (flags & HX509_CMS_EV_ALLOW_WEAK) 597 hx509_crypto_allow_weak(crypto); 598 599 ret = hx509_crypto_set_random_key(crypto, &key); 600 if (ret) { 601 hx509_set_error_string(context, 0, ret, 602 "Create random key for EnvelopedData content"); 603 goto out; 604 } 605 606 ret = hx509_crypto_random_iv(crypto, &ivec); 607 if (ret) { 608 hx509_set_error_string(context, 0, ret, 609 "Failed to create a random iv"); 610 goto out; 611 } 612 613 ret = hx509_crypto_encrypt(crypto, 614 data, 615 length, 616 &ivec, 617 &ed.encryptedContentInfo.encryptedContent); 618 if (ret) { 619 hx509_set_error_string(context, 0, ret, 620 "Failed to encrypt EnvelopedData content"); 621 goto out; 622 } 623 624 { 625 AlgorithmIdentifier *enc_alg; 626 enc_alg = &ed.encryptedContentInfo.contentEncryptionAlgorithm; 627 ret = der_copy_oid(encryption_type, &enc_alg->algorithm); 628 if (ret) { 629 hx509_set_error_string(context, 0, ret, 630 "Failed to set crypto oid " 631 "for EnvelopedData"); 632 goto out; 633 } 634 ALLOC(enc_alg->parameters, 1); 635 if (enc_alg->parameters == NULL) { 636 ret = ENOMEM; 637 hx509_set_error_string(context, 0, ret, 638 "Failed to allocate crypto paramaters " 639 "for EnvelopedData"); 640 goto out; 641 } 642 643 ret = hx509_crypto_get_params(context, 644 crypto, 645 &ivec, 646 enc_alg->parameters); 647 if (ret) { 648 goto out; 649 } 650 } 651 652 ALLOC_SEQ(&ed.recipientInfos, 1); 653 if (ed.recipientInfos.val == NULL) { 654 ret = ENOMEM; 655 hx509_set_error_string(context, 0, ret, 656 "Failed to allocate recipients info " 657 "for EnvelopedData"); 658 goto out; 659 } 660 661 ri = &ed.recipientInfos.val[0]; 662 663 if (flags & HX509_CMS_EV_ID_NAME) { 664 ri->version = 0; 665 cmsidflag = CMS_ID_NAME; 666 } else { 667 ri->version = 2; 668 cmsidflag = CMS_ID_SKI; 669 } 670 671 ret = fill_CMSIdentifier(cert, cmsidflag, &ri->rid); 672 if (ret) { 673 hx509_set_error_string(context, 0, ret, 674 "Failed to set CMS identifier info " 675 "for EnvelopedData"); 676 goto out; 677 } 678 679 ret = hx509_cert_public_encrypt(context, 680 &key, cert, 681 &ri->keyEncryptionAlgorithm.algorithm, 682 &ri->encryptedKey); 683 if (ret) { 684 hx509_set_error_string(context, HX509_ERROR_APPEND, ret, 685 "Failed to encrypt transport key for " 686 "EnvelopedData"); 687 goto out; 688 } 689 690 /* 691 * 692 */ 693 694 ed.version = 0; 695 ed.originatorInfo = NULL; 696 697 ret = der_copy_oid(contentType, &ed.encryptedContentInfo.contentType); 698 if (ret) { 699 hx509_set_error_string(context, 0, ret, 700 "Failed to copy content oid for " 701 "EnvelopedData"); 702 goto out; 703 } 704 705 ed.unprotectedAttrs = NULL; 706 707 ASN1_MALLOC_ENCODE(EnvelopedData, content->data, content->length, 708 &ed, &size, ret); 709 if (ret) { 710 hx509_set_error_string(context, 0, ret, 711 "Failed to encode EnvelopedData"); 712 goto out; 713 } 714 if (size != content->length) 715 _hx509_abort("internal ASN.1 encoder error"); 716 717 out: 718 if (crypto) 719 hx509_crypto_destroy(crypto); 720 if (ret) 721 der_free_octet_string(content); 722 der_free_octet_string(&key); 723 der_free_octet_string(&ivec); 724 free_EnvelopedData(&ed); 725 726 return ret; 727 } 728 729 static int 730 any_to_certs(hx509_context context, const SignedData *sd, hx509_certs certs) 731 { 732 int ret; 733 size_t i; 734 735 if (sd->certificates == NULL) 736 return 0; 737 738 for (i = 0; i < sd->certificates->len; i++) { 739 heim_error_t error; 740 hx509_cert c; 741 742 c = hx509_cert_init_data(context, 743 sd->certificates->val[i].data, 744 sd->certificates->val[i].length, 745 &error); 746 if (c == NULL) { 747 ret = heim_error_get_code(error); 748 heim_release(error); 749 return ret; 750 } 751 ret = hx509_certs_add(context, certs, c); 752 hx509_cert_free(c); 753 if (ret) 754 return ret; 755 } 756 757 return 0; 758 } 759 760 static const Attribute * 761 find_attribute(const CMSAttributes *attr, const heim_oid *oid) 762 { 763 size_t i; 764 for (i = 0; i < attr->len; i++) 765 if (der_heim_oid_cmp(&attr->val[i].type, oid) == 0) 766 return &attr->val[i]; 767 return NULL; 768 } 769 770 /** 771 * Decode SignedData and verify that the signature is correct. 772 * 773 * @param context A hx509 context. 774 * @param ctx a hx509 verify context. 775 * @param flags to control the behaivor of the function. 776 * - HX509_CMS_VS_NO_KU_CHECK - Don't check KeyUsage 777 * - HX509_CMS_VS_ALLOW_DATA_OID_MISMATCH - allow oid mismatch 778 * - HX509_CMS_VS_ALLOW_ZERO_SIGNER - no signer, see below. 779 * @param data pointer to CMS SignedData encoded data. 780 * @param length length of the data that data point to. 781 * @param signedContent external data used for signature. 782 * @param pool certificate pool to build certificates paths. 783 * @param contentType free with der_free_oid(). 784 * @param content the output of the function, free with 785 * der_free_octet_string(). 786 * @param signer_certs list of the cerficates used to sign this 787 * request, free with hx509_certs_free(). 788 * 789 * @return an hx509 error code. 790 * 791 * @ingroup hx509_cms 792 */ 793 794 int 795 hx509_cms_verify_signed(hx509_context context, 796 hx509_verify_ctx ctx, 797 unsigned int flags, 798 const void *data, 799 size_t length, 800 const heim_octet_string *signedContent, 801 hx509_certs pool, 802 heim_oid *contentType, 803 heim_octet_string *content, 804 hx509_certs *signer_certs) 805 { 806 SignerInfo *signer_info; 807 hx509_cert cert = NULL; 808 hx509_certs certs = NULL; 809 SignedData sd; 810 size_t size; 811 int ret, found_valid_sig; 812 size_t i; 813 814 *signer_certs = NULL; 815 content->data = NULL; 816 content->length = 0; 817 contentType->length = 0; 818 contentType->components = NULL; 819 820 memset(&sd, 0, sizeof(sd)); 821 822 ret = decode_SignedData(data, length, &sd, &size); 823 if (ret) { 824 hx509_set_error_string(context, 0, ret, 825 "Failed to decode SignedData"); 826 goto out; 827 } 828 829 if (sd.encapContentInfo.eContent == NULL && signedContent == NULL) { 830 ret = HX509_CMS_NO_DATA_AVAILABLE; 831 hx509_set_error_string(context, 0, ret, 832 "No content data in SignedData"); 833 goto out; 834 } 835 if (sd.encapContentInfo.eContent && signedContent) { 836 ret = HX509_CMS_NO_DATA_AVAILABLE; 837 hx509_set_error_string(context, 0, ret, 838 "Both external and internal SignedData"); 839 goto out; 840 } 841 842 if (sd.encapContentInfo.eContent) 843 ret = der_copy_octet_string(sd.encapContentInfo.eContent, content); 844 else 845 ret = der_copy_octet_string(signedContent, content); 846 if (ret) { 847 hx509_set_error_string(context, 0, ret, "malloc: out of memory"); 848 goto out; 849 } 850 851 ret = hx509_certs_init(context, "MEMORY:cms-cert-buffer", 852 0, NULL, &certs); 853 if (ret) 854 goto out; 855 856 ret = hx509_certs_init(context, "MEMORY:cms-signer-certs", 857 0, NULL, signer_certs); 858 if (ret) 859 goto out; 860 861 /* XXX Check CMS version */ 862 863 ret = any_to_certs(context, &sd, certs); 864 if (ret) 865 goto out; 866 867 if (pool) { 868 ret = hx509_certs_merge(context, certs, pool); 869 if (ret) 870 goto out; 871 } 872 873 for (found_valid_sig = 0, i = 0; i < sd.signerInfos.len; i++) { 874 heim_octet_string signed_data = { 0, 0 }; 875 const heim_oid *match_oid; 876 heim_oid decode_oid; 877 878 signer_info = &sd.signerInfos.val[i]; 879 match_oid = NULL; 880 881 if (signer_info->signature.length == 0) { 882 ret = HX509_CMS_MISSING_SIGNER_DATA; 883 hx509_set_error_string(context, 0, ret, 884 "SignerInfo %d in SignedData " 885 "missing sigature", i); 886 continue; 887 } 888 889 ret = find_CMSIdentifier(context, &signer_info->sid, certs, 890 _hx509_verify_get_time(ctx), &cert, 891 HX509_QUERY_KU_DIGITALSIGNATURE); 892 if (ret) { 893 /** 894 * If HX509_CMS_VS_NO_KU_CHECK is set, allow more liberal 895 * search for matching certificates by not considering 896 * KeyUsage bits on the certificates. 897 */ 898 if ((flags & HX509_CMS_VS_NO_KU_CHECK) == 0) 899 continue; 900 901 ret = find_CMSIdentifier(context, &signer_info->sid, certs, 902 _hx509_verify_get_time(ctx), &cert, 903 0); 904 if (ret) 905 continue; 906 907 } 908 909 if (signer_info->signedAttrs) { 910 const Attribute *attr; 911 912 CMSAttributes sa; 913 heim_octet_string os; 914 915 sa.val = signer_info->signedAttrs->val; 916 sa.len = signer_info->signedAttrs->len; 917 918 /* verify that sigature exists */ 919 attr = find_attribute(&sa, &asn1_oid_id_pkcs9_messageDigest); 920 if (attr == NULL) { 921 ret = HX509_CRYPTO_SIGNATURE_MISSING; 922 hx509_set_error_string(context, 0, ret, 923 "SignerInfo have signed attributes " 924 "but messageDigest (signature) " 925 "is missing"); 926 goto next_sigature; 927 } 928 if (attr->value.len != 1) { 929 ret = HX509_CRYPTO_SIGNATURE_MISSING; 930 hx509_set_error_string(context, 0, ret, 931 "SignerInfo have more then one " 932 "messageDigest (signature)"); 933 goto next_sigature; 934 } 935 936 ret = decode_MessageDigest(attr->value.val[0].data, 937 attr->value.val[0].length, 938 &os, 939 &size); 940 if (ret) { 941 hx509_set_error_string(context, 0, ret, 942 "Failed to decode " 943 "messageDigest (signature)"); 944 goto next_sigature; 945 } 946 947 ret = _hx509_verify_signature(context, 948 NULL, 949 &signer_info->digestAlgorithm, 950 content, 951 &os); 952 der_free_octet_string(&os); 953 if (ret) { 954 hx509_set_error_string(context, HX509_ERROR_APPEND, ret, 955 "Failed to verify messageDigest"); 956 goto next_sigature; 957 } 958 959 /* 960 * Fetch content oid inside signedAttrs or set it to 961 * id-pkcs7-data. 962 */ 963 attr = find_attribute(&sa, &asn1_oid_id_pkcs9_contentType); 964 if (attr == NULL) { 965 match_oid = &asn1_oid_id_pkcs7_data; 966 } else { 967 if (attr->value.len != 1) { 968 ret = HX509_CMS_DATA_OID_MISMATCH; 969 hx509_set_error_string(context, 0, ret, 970 "More then one oid in signedAttrs"); 971 goto next_sigature; 972 973 } 974 ret = decode_ContentType(attr->value.val[0].data, 975 attr->value.val[0].length, 976 &decode_oid, 977 &size); 978 if (ret) { 979 hx509_set_error_string(context, 0, ret, 980 "Failed to decode " 981 "oid in signedAttrs"); 982 goto next_sigature; 983 } 984 match_oid = &decode_oid; 985 } 986 987 ASN1_MALLOC_ENCODE(CMSAttributes, 988 signed_data.data, 989 signed_data.length, 990 &sa, 991 &size, ret); 992 if (ret) { 993 if (match_oid == &decode_oid) 994 der_free_oid(&decode_oid); 995 hx509_clear_error_string(context); 996 goto next_sigature; 997 } 998 if (size != signed_data.length) 999 _hx509_abort("internal ASN.1 encoder error"); 1000 1001 } else { 1002 signed_data.data = content->data; 1003 signed_data.length = content->length; 1004 match_oid = &asn1_oid_id_pkcs7_data; 1005 } 1006 1007 /** 1008 * If HX509_CMS_VS_ALLOW_DATA_OID_MISMATCH, allow 1009 * encapContentInfo mismatch with the oid in signedAttributes 1010 * (or if no signedAttributes where use, pkcs7-data oid). 1011 * This is only needed to work with broken CMS implementations 1012 * that doesn't follow CMS signedAttributes rules. 1013 */ 1014 1015 if (der_heim_oid_cmp(match_oid, &sd.encapContentInfo.eContentType) && 1016 (flags & HX509_CMS_VS_ALLOW_DATA_OID_MISMATCH) == 0) { 1017 ret = HX509_CMS_DATA_OID_MISMATCH; 1018 hx509_set_error_string(context, 0, ret, 1019 "Oid in message mismatch from the expected"); 1020 } 1021 if (match_oid == &decode_oid) 1022 der_free_oid(&decode_oid); 1023 1024 if (ret == 0) { 1025 ret = hx509_verify_signature(context, 1026 cert, 1027 &signer_info->signatureAlgorithm, 1028 &signed_data, 1029 &signer_info->signature); 1030 if (ret) 1031 hx509_set_error_string(context, HX509_ERROR_APPEND, ret, 1032 "Failed to verify signature in " 1033 "CMS SignedData"); 1034 } 1035 if (signed_data.data != NULL && content->data != signed_data.data) { 1036 free(signed_data.data); 1037 signed_data.data = NULL; 1038 } 1039 if (ret) 1040 goto next_sigature; 1041 1042 /** 1043 * If HX509_CMS_VS_NO_VALIDATE flags is set, do not verify the 1044 * signing certificates and leave that up to the caller. 1045 */ 1046 1047 if ((flags & HX509_CMS_VS_NO_VALIDATE) == 0) { 1048 ret = hx509_verify_path(context, ctx, cert, certs); 1049 if (ret) 1050 goto next_sigature; 1051 } 1052 1053 ret = hx509_certs_add(context, *signer_certs, cert); 1054 if (ret) 1055 goto next_sigature; 1056 1057 found_valid_sig++; 1058 1059 next_sigature: 1060 if (cert) 1061 hx509_cert_free(cert); 1062 cert = NULL; 1063 } 1064 /** 1065 * If HX509_CMS_VS_ALLOW_ZERO_SIGNER is set, allow empty 1066 * SignerInfo (no signatures). If SignedData have no signatures, 1067 * the function will return 0 with signer_certs set to NULL. Zero 1068 * signers is allowed by the standard, but since its only useful 1069 * in corner cases, it make into a flag that the caller have to 1070 * turn on. 1071 */ 1072 if (sd.signerInfos.len == 0 && (flags & HX509_CMS_VS_ALLOW_ZERO_SIGNER)) { 1073 if (*signer_certs) 1074 hx509_certs_free(signer_certs); 1075 } else if (found_valid_sig == 0) { 1076 if (ret == 0) { 1077 ret = HX509_CMS_SIGNER_NOT_FOUND; 1078 hx509_set_error_string(context, 0, ret, 1079 "No signers where found"); 1080 } 1081 goto out; 1082 } 1083 1084 ret = der_copy_oid(&sd.encapContentInfo.eContentType, contentType); 1085 if (ret) { 1086 hx509_clear_error_string(context); 1087 goto out; 1088 } 1089 1090 out: 1091 free_SignedData(&sd); 1092 if (certs) 1093 hx509_certs_free(&certs); 1094 if (ret) { 1095 if (content->data) 1096 der_free_octet_string(content); 1097 if (*signer_certs) 1098 hx509_certs_free(signer_certs); 1099 der_free_oid(contentType); 1100 der_free_octet_string(content); 1101 } 1102 1103 return ret; 1104 } 1105 1106 static int 1107 add_one_attribute(Attribute **attr, 1108 unsigned int *len, 1109 const heim_oid *oid, 1110 heim_octet_string *data) 1111 { 1112 void *d; 1113 int ret; 1114 1115 d = realloc(*attr, sizeof((*attr)[0]) * (*len + 1)); 1116 if (d == NULL) 1117 return ENOMEM; 1118 (*attr) = d; 1119 1120 ret = der_copy_oid(oid, &(*attr)[*len].type); 1121 if (ret) 1122 return ret; 1123 1124 ALLOC_SEQ(&(*attr)[*len].value, 1); 1125 if ((*attr)[*len].value.val == NULL) { 1126 der_free_oid(&(*attr)[*len].type); 1127 return ENOMEM; 1128 } 1129 1130 (*attr)[*len].value.val[0].data = data->data; 1131 (*attr)[*len].value.val[0].length = data->length; 1132 1133 *len += 1; 1134 1135 return 0; 1136 } 1137 1138 /** 1139 * Decode SignedData and verify that the signature is correct. 1140 * 1141 * @param context A hx509 context. 1142 * @param flags 1143 * @param eContentType the type of the data. 1144 * @param data data to sign 1145 * @param length length of the data that data point to. 1146 * @param digest_alg digest algorithm to use, use NULL to get the 1147 * default or the peer determined algorithm. 1148 * @param cert certificate to use for sign the data. 1149 * @param peer info about the peer the message to send the message to, 1150 * like what digest algorithm to use. 1151 * @param anchors trust anchors that the client will use, used to 1152 * polulate the certificates included in the message 1153 * @param pool certificates to use in try to build the path to the 1154 * trust anchors. 1155 * @param signed_data the output of the function, free with 1156 * der_free_octet_string(). 1157 * 1158 * @return Returns an hx509 error code. 1159 * 1160 * @ingroup hx509_cms 1161 */ 1162 1163 int 1164 hx509_cms_create_signed_1(hx509_context context, 1165 int flags, 1166 const heim_oid *eContentType, 1167 const void *data, size_t length, 1168 const AlgorithmIdentifier *digest_alg, 1169 hx509_cert cert, 1170 hx509_peer_info peer, 1171 hx509_certs anchors, 1172 hx509_certs pool, 1173 heim_octet_string *signed_data) 1174 { 1175 hx509_certs certs; 1176 int ret = 0; 1177 1178 signed_data->data = NULL; 1179 signed_data->length = 0; 1180 1181 ret = hx509_certs_init(context, "MEMORY:certs", 0, NULL, &certs); 1182 if (ret) 1183 return ret; 1184 ret = hx509_certs_add(context, certs, cert); 1185 if (ret) 1186 goto out; 1187 1188 ret = hx509_cms_create_signed(context, flags, eContentType, data, length, 1189 digest_alg, certs, peer, anchors, pool, 1190 signed_data); 1191 1192 out: 1193 hx509_certs_free(&certs); 1194 return ret; 1195 } 1196 1197 struct sigctx { 1198 SignedData sd; 1199 const AlgorithmIdentifier *digest_alg; 1200 const heim_oid *eContentType; 1201 heim_octet_string content; 1202 hx509_peer_info peer; 1203 int cmsidflag; 1204 int leafonly; 1205 hx509_certs certs; 1206 hx509_certs anchors; 1207 hx509_certs pool; 1208 }; 1209 1210 static int 1211 sig_process(hx509_context context, void *ctx, hx509_cert cert) 1212 { 1213 struct sigctx *sigctx = ctx; 1214 heim_octet_string buf, sigdata = { 0, NULL }; 1215 SignerInfo *signer_info = NULL; 1216 AlgorithmIdentifier digest; 1217 size_t size; 1218 void *ptr; 1219 int ret; 1220 SignedData *sd = &sigctx->sd; 1221 hx509_path path; 1222 1223 memset(&digest, 0, sizeof(digest)); 1224 memset(&path, 0, sizeof(path)); 1225 1226 if (_hx509_cert_private_key(cert) == NULL) { 1227 hx509_set_error_string(context, 0, HX509_PRIVATE_KEY_MISSING, 1228 "Private key missing for signing"); 1229 return HX509_PRIVATE_KEY_MISSING; 1230 } 1231 1232 if (sigctx->digest_alg) { 1233 ret = copy_AlgorithmIdentifier(sigctx->digest_alg, &digest); 1234 if (ret) 1235 hx509_clear_error_string(context); 1236 } else { 1237 ret = hx509_crypto_select(context, HX509_SELECT_DIGEST, 1238 _hx509_cert_private_key(cert), 1239 sigctx->peer, &digest); 1240 } 1241 if (ret) 1242 goto out; 1243 1244 /* 1245 * Allocate on more signerInfo and do the signature processing 1246 */ 1247 1248 ptr = realloc(sd->signerInfos.val, 1249 (sd->signerInfos.len + 1) * sizeof(sd->signerInfos.val[0])); 1250 if (ptr == NULL) { 1251 ret = ENOMEM; 1252 goto out; 1253 } 1254 sd->signerInfos.val = ptr; 1255 1256 signer_info = &sd->signerInfos.val[sd->signerInfos.len]; 1257 1258 memset(signer_info, 0, sizeof(*signer_info)); 1259 1260 signer_info->version = 1; 1261 1262 ret = fill_CMSIdentifier(cert, sigctx->cmsidflag, &signer_info->sid); 1263 if (ret) { 1264 hx509_clear_error_string(context); 1265 goto out; 1266 } 1267 1268 signer_info->signedAttrs = NULL; 1269 signer_info->unsignedAttrs = NULL; 1270 1271 ret = copy_AlgorithmIdentifier(&digest, &signer_info->digestAlgorithm); 1272 if (ret) { 1273 hx509_clear_error_string(context); 1274 goto out; 1275 } 1276 1277 /* 1278 * If it isn't pkcs7-data send signedAttributes 1279 */ 1280 1281 if (der_heim_oid_cmp(sigctx->eContentType, &asn1_oid_id_pkcs7_data) != 0) { 1282 CMSAttributes sa; 1283 heim_octet_string sig; 1284 1285 ALLOC(signer_info->signedAttrs, 1); 1286 if (signer_info->signedAttrs == NULL) { 1287 ret = ENOMEM; 1288 goto out; 1289 } 1290 1291 ret = _hx509_create_signature(context, 1292 NULL, 1293 &digest, 1294 &sigctx->content, 1295 NULL, 1296 &sig); 1297 if (ret) 1298 goto out; 1299 1300 ASN1_MALLOC_ENCODE(MessageDigest, 1301 buf.data, 1302 buf.length, 1303 &sig, 1304 &size, 1305 ret); 1306 der_free_octet_string(&sig); 1307 if (ret) { 1308 hx509_clear_error_string(context); 1309 goto out; 1310 } 1311 if (size != buf.length) 1312 _hx509_abort("internal ASN.1 encoder error"); 1313 1314 ret = add_one_attribute(&signer_info->signedAttrs->val, 1315 &signer_info->signedAttrs->len, 1316 &asn1_oid_id_pkcs9_messageDigest, 1317 &buf); 1318 if (ret) { 1319 free(buf.data); 1320 hx509_clear_error_string(context); 1321 goto out; 1322 } 1323 1324 1325 ASN1_MALLOC_ENCODE(ContentType, 1326 buf.data, 1327 buf.length, 1328 sigctx->eContentType, 1329 &size, 1330 ret); 1331 if (ret) 1332 goto out; 1333 if (size != buf.length) 1334 _hx509_abort("internal ASN.1 encoder error"); 1335 1336 ret = add_one_attribute(&signer_info->signedAttrs->val, 1337 &signer_info->signedAttrs->len, 1338 &asn1_oid_id_pkcs9_contentType, 1339 &buf); 1340 if (ret) { 1341 free(buf.data); 1342 hx509_clear_error_string(context); 1343 goto out; 1344 } 1345 1346 sa.val = signer_info->signedAttrs->val; 1347 sa.len = signer_info->signedAttrs->len; 1348 1349 ASN1_MALLOC_ENCODE(CMSAttributes, 1350 sigdata.data, 1351 sigdata.length, 1352 &sa, 1353 &size, 1354 ret); 1355 if (ret) { 1356 hx509_clear_error_string(context); 1357 goto out; 1358 } 1359 if (size != sigdata.length) 1360 _hx509_abort("internal ASN.1 encoder error"); 1361 } else { 1362 sigdata.data = sigctx->content.data; 1363 sigdata.length = sigctx->content.length; 1364 } 1365 1366 { 1367 AlgorithmIdentifier sigalg; 1368 1369 ret = hx509_crypto_select(context, HX509_SELECT_PUBLIC_SIG, 1370 _hx509_cert_private_key(cert), sigctx->peer, 1371 &sigalg); 1372 if (ret) 1373 goto out; 1374 1375 ret = _hx509_create_signature(context, 1376 _hx509_cert_private_key(cert), 1377 &sigalg, 1378 &sigdata, 1379 &signer_info->signatureAlgorithm, 1380 &signer_info->signature); 1381 free_AlgorithmIdentifier(&sigalg); 1382 if (ret) 1383 goto out; 1384 } 1385 1386 sigctx->sd.signerInfos.len++; 1387 signer_info = NULL; 1388 1389 /* 1390 * Provide best effort path 1391 */ 1392 if (sigctx->certs) { 1393 unsigned int i; 1394 1395 if (sigctx->pool && sigctx->leafonly == 0) { 1396 _hx509_calculate_path(context, 1397 HX509_CALCULATE_PATH_NO_ANCHOR, 1398 time(NULL), 1399 sigctx->anchors, 1400 0, 1401 cert, 1402 sigctx->pool, 1403 &path); 1404 } else 1405 _hx509_path_append(context, &path, cert); 1406 1407 for (i = 0; i < path.len; i++) { 1408 /* XXX remove dups */ 1409 ret = hx509_certs_add(context, sigctx->certs, path.val[i]); 1410 if (ret) { 1411 hx509_clear_error_string(context); 1412 goto out; 1413 } 1414 } 1415 } 1416 1417 out: 1418 if (signer_info) 1419 free_SignerInfo(signer_info); 1420 if (sigdata.data != sigctx->content.data) 1421 der_free_octet_string(&sigdata); 1422 _hx509_path_free(&path); 1423 free_AlgorithmIdentifier(&digest); 1424 1425 return ret; 1426 } 1427 1428 static int 1429 cert_process(hx509_context context, void *ctx, hx509_cert cert) 1430 { 1431 struct sigctx *sigctx = ctx; 1432 const unsigned int i = sigctx->sd.certificates->len; 1433 void *ptr; 1434 int ret; 1435 1436 ptr = realloc(sigctx->sd.certificates->val, 1437 (i + 1) * sizeof(sigctx->sd.certificates->val[0])); 1438 if (ptr == NULL) 1439 return ENOMEM; 1440 sigctx->sd.certificates->val = ptr; 1441 1442 ret = hx509_cert_binary(context, cert, 1443 &sigctx->sd.certificates->val[i]); 1444 if (ret == 0) 1445 sigctx->sd.certificates->len++; 1446 1447 return ret; 1448 } 1449 1450 static int 1451 cmp_AlgorithmIdentifier(const AlgorithmIdentifier *p, const AlgorithmIdentifier *q) 1452 { 1453 return der_heim_oid_cmp(&p->algorithm, &q->algorithm); 1454 } 1455 1456 int 1457 hx509_cms_create_signed(hx509_context context, 1458 int flags, 1459 const heim_oid *eContentType, 1460 const void *data, size_t length, 1461 const AlgorithmIdentifier *digest_alg, 1462 hx509_certs certs, 1463 hx509_peer_info peer, 1464 hx509_certs anchors, 1465 hx509_certs pool, 1466 heim_octet_string *signed_data) 1467 { 1468 unsigned int i, j; 1469 hx509_name name; 1470 int ret; 1471 size_t size; 1472 struct sigctx sigctx; 1473 1474 memset(&sigctx, 0, sizeof(sigctx)); 1475 memset(&name, 0, sizeof(name)); 1476 1477 if (eContentType == NULL) 1478 eContentType = &asn1_oid_id_pkcs7_data; 1479 1480 sigctx.digest_alg = digest_alg; 1481 sigctx.content.data = rk_UNCONST(data); 1482 sigctx.content.length = length; 1483 sigctx.eContentType = eContentType; 1484 sigctx.peer = peer; 1485 /** 1486 * Use HX509_CMS_SIGNATURE_ID_NAME to preferred use of issuer name 1487 * and serial number if possible. Otherwise subject key identifier 1488 * will preferred. 1489 */ 1490 if (flags & HX509_CMS_SIGNATURE_ID_NAME) 1491 sigctx.cmsidflag = CMS_ID_NAME; 1492 else 1493 sigctx.cmsidflag = CMS_ID_SKI; 1494 1495 /** 1496 * Use HX509_CMS_SIGNATURE_LEAF_ONLY to only request leaf 1497 * certificates to be added to the SignedData. 1498 */ 1499 sigctx.leafonly = (flags & HX509_CMS_SIGNATURE_LEAF_ONLY) ? 1 : 0; 1500 1501 /** 1502 * Use HX509_CMS_NO_CERTS to make the SignedData contain no 1503 * certificates, overrides HX509_CMS_SIGNATURE_LEAF_ONLY. 1504 */ 1505 1506 if ((flags & HX509_CMS_SIGNATURE_NO_CERTS) == 0) { 1507 ret = hx509_certs_init(context, "MEMORY:certs", 0, NULL, &sigctx.certs); 1508 if (ret) 1509 return ret; 1510 } 1511 1512 sigctx.anchors = anchors; 1513 sigctx.pool = pool; 1514 1515 sigctx.sd.version = CMSVersion_v3; 1516 1517 der_copy_oid(eContentType, &sigctx.sd.encapContentInfo.eContentType); 1518 1519 /** 1520 * Use HX509_CMS_SIGNATURE_DETACHED to create detached signatures. 1521 */ 1522 if ((flags & HX509_CMS_SIGNATURE_DETACHED) == 0) { 1523 ALLOC(sigctx.sd.encapContentInfo.eContent, 1); 1524 if (sigctx.sd.encapContentInfo.eContent == NULL) { 1525 hx509_clear_error_string(context); 1526 ret = ENOMEM; 1527 goto out; 1528 } 1529 1530 sigctx.sd.encapContentInfo.eContent->data = malloc(length); 1531 if (sigctx.sd.encapContentInfo.eContent->data == NULL) { 1532 hx509_clear_error_string(context); 1533 ret = ENOMEM; 1534 goto out; 1535 } 1536 memcpy(sigctx.sd.encapContentInfo.eContent->data, data, length); 1537 sigctx.sd.encapContentInfo.eContent->length = length; 1538 } 1539 1540 /** 1541 * Use HX509_CMS_SIGNATURE_NO_SIGNER to create no sigInfo (no 1542 * signatures). 1543 */ 1544 if ((flags & HX509_CMS_SIGNATURE_NO_SIGNER) == 0) { 1545 ret = hx509_certs_iter_f(context, certs, sig_process, &sigctx); 1546 if (ret) 1547 goto out; 1548 } 1549 1550 if (sigctx.sd.signerInfos.len) { 1551 1552 /* 1553 * For each signerInfo, collect all different digest types. 1554 */ 1555 for (i = 0; i < sigctx.sd.signerInfos.len; i++) { 1556 AlgorithmIdentifier *di = 1557 &sigctx.sd.signerInfos.val[i].digestAlgorithm; 1558 1559 for (j = 0; j < sigctx.sd.digestAlgorithms.len; j++) 1560 if (cmp_AlgorithmIdentifier(di, &sigctx.sd.digestAlgorithms.val[j]) == 0) 1561 break; 1562 if (j == sigctx.sd.digestAlgorithms.len) { 1563 ret = add_DigestAlgorithmIdentifiers(&sigctx.sd.digestAlgorithms, di); 1564 if (ret) { 1565 hx509_clear_error_string(context); 1566 goto out; 1567 } 1568 } 1569 } 1570 } 1571 1572 /* 1573 * Add certs we think are needed, build as part of sig_process 1574 */ 1575 if (sigctx.certs) { 1576 ALLOC(sigctx.sd.certificates, 1); 1577 if (sigctx.sd.certificates == NULL) { 1578 hx509_clear_error_string(context); 1579 ret = ENOMEM; 1580 goto out; 1581 } 1582 1583 ret = hx509_certs_iter_f(context, sigctx.certs, cert_process, &sigctx); 1584 if (ret) 1585 goto out; 1586 } 1587 1588 ASN1_MALLOC_ENCODE(SignedData, 1589 signed_data->data, signed_data->length, 1590 &sigctx.sd, &size, ret); 1591 if (ret) { 1592 hx509_clear_error_string(context); 1593 goto out; 1594 } 1595 if (signed_data->length != size) 1596 _hx509_abort("internal ASN.1 encoder error"); 1597 1598 out: 1599 hx509_certs_free(&sigctx.certs); 1600 free_SignedData(&sigctx.sd); 1601 1602 return ret; 1603 } 1604 1605 int 1606 hx509_cms_decrypt_encrypted(hx509_context context, 1607 hx509_lock lock, 1608 const void *data, 1609 size_t length, 1610 heim_oid *contentType, 1611 heim_octet_string *content) 1612 { 1613 heim_octet_string cont; 1614 CMSEncryptedData ed; 1615 AlgorithmIdentifier *ai; 1616 int ret; 1617 1618 memset(content, 0, sizeof(*content)); 1619 memset(&cont, 0, sizeof(cont)); 1620 1621 ret = decode_CMSEncryptedData(data, length, &ed, NULL); 1622 if (ret) { 1623 hx509_set_error_string(context, 0, ret, 1624 "Failed to decode CMSEncryptedData"); 1625 return ret; 1626 } 1627 1628 if (ed.encryptedContentInfo.encryptedContent == NULL) { 1629 ret = HX509_CMS_NO_DATA_AVAILABLE; 1630 hx509_set_error_string(context, 0, ret, 1631 "No content in EncryptedData"); 1632 goto out; 1633 } 1634 1635 ret = der_copy_oid(&ed.encryptedContentInfo.contentType, contentType); 1636 if (ret) { 1637 hx509_clear_error_string(context); 1638 goto out; 1639 } 1640 1641 ai = &ed.encryptedContentInfo.contentEncryptionAlgorithm; 1642 if (ai->parameters == NULL) { 1643 ret = HX509_ALG_NOT_SUPP; 1644 hx509_clear_error_string(context); 1645 goto out; 1646 } 1647 1648 ret = _hx509_pbe_decrypt(context, 1649 lock, 1650 ai, 1651 ed.encryptedContentInfo.encryptedContent, 1652 &cont); 1653 if (ret) 1654 goto out; 1655 1656 *content = cont; 1657 1658 out: 1659 if (ret) { 1660 if (cont.data) 1661 free(cont.data); 1662 } 1663 free_CMSEncryptedData(&ed); 1664 return ret; 1665 } 1666