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