2 * Copyright (c) 2003 - 2007 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
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.
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.
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
35 RCSID("$Id: cms.c 20937 2007-06-06 20:50:55Z lha $");
37 #define ALLOC(X, N) (X) = calloc((N), sizeof(*(X)))
38 #define ALLOC_SEQ(X, N) do { (X)->len = (N); ALLOC((X)->val, (N)); } while(0)
41 hx509_cms_wrap_ContentInfo(const heim_oid *oid,
42 const heim_octet_string *buf,
43 heim_octet_string *res)
49 memset(res, 0, sizeof(*res));
50 memset(&ci, 0, sizeof(ci));
52 ret = der_copy_oid(oid, &ci.contentType);
56 if (ci.content == NULL) {
57 free_ContentInfo(&ci);
60 ci.content->data = malloc(buf->length);
61 if (ci.content->data == NULL) {
62 free_ContentInfo(&ci);
65 memcpy(ci.content->data, buf->data, buf->length);
66 ci.content->length = buf->length;
68 ASN1_MALLOC_ENCODE(ContentInfo, res->data, res->length, &ci, &size, ret);
69 free_ContentInfo(&ci);
72 if (res->length != size)
73 _hx509_abort("internal ASN.1 encoder error");
79 hx509_cms_unwrap_ContentInfo(const heim_octet_string *in,
81 heim_octet_string *out,
88 memset(oid, 0, sizeof(*oid));
89 memset(out, 0, sizeof(*out));
91 ret = decode_ContentInfo(in->data, in->length, &ci, &size);
95 ret = der_copy_oid(&ci.contentType, oid);
97 free_ContentInfo(&ci);
101 ret = der_copy_octet_string(ci.content, out);
104 free_ContentInfo(&ci);
108 memset(out, 0, sizeof(*out));
111 *have_data = (ci.content != NULL) ? 1 : 0;
113 free_ContentInfo(&ci);
119 fill_CMSIdentifier(const hx509_cert cert, CMSIdentifier *id)
124 id->element = choice_CMSIdentifier_issuerAndSerialNumber;
125 ret = hx509_cert_get_issuer(cert, &name);
128 ret = copy_Name(&name->der_name,
129 &id->u.issuerAndSerialNumber.issuer);
130 hx509_name_free(&name);
134 ret = hx509_cert_get_serialnumber(cert,
135 &id->u.issuerAndSerialNumber.serialNumber);
140 unparse_CMSIdentifier(hx509_context context,
147 switch (id->element) {
148 case choice_CMSIdentifier_issuerAndSerialNumber: {
149 IssuerAndSerialNumber *iasn;
152 iasn = &id->u.issuerAndSerialNumber;
154 ret = _hx509_Name_to_string(&iasn->issuer, &name);
157 ret = der_print_hex_heim_integer(&iasn->serialNumber, &serial);
162 asprintf(str, "certificate issued by %s with serial number %s",
168 case choice_CMSIdentifier_subjectKeyIdentifier: {
169 KeyIdentifier *ki = &id->u.subjectKeyIdentifier;
173 len = hex_encode(ki->data, ki->length, &keyid);
177 asprintf(str, "certificate with id %s", keyid);
182 asprintf(str, "certificate have unknown CMSidentifier type");
191 find_CMSIdentifier(hx509_context context,
192 CMSIdentifier *client,
194 hx509_cert *signer_cert,
202 memset(&c, 0, sizeof(c));
203 _hx509_query_clear(&q);
207 switch (client->element) {
208 case choice_CMSIdentifier_issuerAndSerialNumber:
209 q.serial = &client->u.issuerAndSerialNumber.serialNumber;
210 q.issuer_name = &client->u.issuerAndSerialNumber.issuer;
211 q.match = HX509_QUERY_MATCH_SERIALNUMBER|HX509_QUERY_MATCH_ISSUER_NAME;
213 case choice_CMSIdentifier_subjectKeyIdentifier:
214 q.subject_id = &client->u.subjectKeyIdentifier;
215 q.match = HX509_QUERY_MATCH_SUBJECT_KEY_ID;
218 hx509_set_error_string(context, 0, HX509_CMS_NO_RECIPIENT_CERTIFICATE,
219 "unknown CMS identifier element");
220 return HX509_CMS_NO_RECIPIENT_CERTIFICATE;
225 q.match |= HX509_QUERY_MATCH_TIME;
226 q.timenow = time(NULL);
228 ret = hx509_certs_find(context, certs, &q, &cert);
229 if (ret == HX509_CERT_NOT_FOUND) {
232 ret = unparse_CMSIdentifier(context, client, &str);
234 hx509_set_error_string(context, 0,
235 HX509_CMS_NO_RECIPIENT_CERTIFICATE,
236 "Failed to find %s", str);
238 hx509_clear_error_string(context);
239 return HX509_CMS_NO_RECIPIENT_CERTIFICATE;
241 hx509_set_error_string(context, HX509_ERROR_APPEND,
242 HX509_CMS_NO_RECIPIENT_CERTIFICATE,
243 "Failed to find CMS id in cert store");
244 return HX509_CMS_NO_RECIPIENT_CERTIFICATE;
253 hx509_cms_unenvelope(hx509_context context,
258 const heim_octet_string *encryptedContent,
259 heim_oid *contentType,
260 heim_octet_string *content)
262 heim_octet_string key;
265 AlgorithmIdentifier *ai;
266 const heim_octet_string *enccontent;
267 heim_octet_string *params, params_data;
268 heim_octet_string ivec;
270 int ret, i, matched = 0, findflags = 0;
273 memset(&key, 0, sizeof(key));
274 memset(&ed, 0, sizeof(ed));
275 memset(&ivec, 0, sizeof(ivec));
276 memset(content, 0, sizeof(*content));
277 memset(contentType, 0, sizeof(*contentType));
279 if ((flags & HX509_CMS_UE_DONT_REQUIRE_KU_ENCIPHERMENT) == 0)
280 findflags |= HX509_QUERY_KU_ENCIPHERMENT;
282 ret = decode_EnvelopedData(data, length, &ed, &size);
284 hx509_set_error_string(context, 0, ret,
285 "Failed to decode EnvelopedData");
289 if (ed.recipientInfos.len == 0) {
290 ret = HX509_CMS_NO_RECIPIENT_CERTIFICATE;
291 hx509_set_error_string(context, 0, ret,
292 "No recipient info in enveloped data");
296 enccontent = ed.encryptedContentInfo.encryptedContent;
297 if (enccontent == NULL) {
298 if (encryptedContent == NULL) {
299 ret = HX509_CMS_NO_DATA_AVAILABLE;
300 hx509_set_error_string(context, 0, ret,
301 "Content missing from encrypted data");
304 enccontent = encryptedContent;
305 } else if (encryptedContent != NULL) {
306 ret = HX509_CMS_NO_DATA_AVAILABLE;
307 hx509_set_error_string(context, 0, ret,
308 "Both internal and external encrypted data");
313 for (i = 0; i < ed.recipientInfos.len; i++) {
314 KeyTransRecipientInfo *ri;
318 ri = &ed.recipientInfos.val[i];
320 /* ret = search_keyset(ri,
322 * ki->keyEncryptionAlgorithm.algorithm);
325 ret = find_CMSIdentifier(context, &ri->rid, certs, &cert,
326 HX509_QUERY_PRIVATE_KEY|findflags);
330 matched = 1; /* found a matching certificate, let decrypt */
332 ret = _hx509_cert_private_decrypt(context,
334 &ri->keyEncryptionAlgorithm.algorithm,
337 hx509_cert_free(cert);
339 break; /* succuessfully decrypted cert */
341 ret2 = unparse_CMSIdentifier(context, &ri->rid, &str);
343 hx509_set_error_string(context, HX509_ERROR_APPEND, ret,
344 "Failed to decrypt with %s", str);
350 ret = HX509_CMS_NO_RECIPIENT_CERTIFICATE;
351 hx509_set_error_string(context, 0, ret,
352 "No private key matched any certificate");
357 ret = HX509_CMS_NO_RECIPIENT_CERTIFICATE;
358 hx509_set_error_string(context, HX509_ERROR_APPEND, ret,
359 "No private key decrypted the transfer key");
363 ret = der_copy_oid(&ed.encryptedContentInfo.contentType, contentType);
365 hx509_set_error_string(context, 0, ret,
366 "Failed to copy EnvelopedData content oid");
370 ai = &ed.encryptedContentInfo.contentEncryptionAlgorithm;
371 if (ai->parameters) {
372 params_data.data = ai->parameters->data;
373 params_data.length = ai->parameters->length;
374 params = ¶ms_data;
381 ret = hx509_crypto_init(context, NULL, &ai->algorithm, &crypto);
386 ret = hx509_crypto_set_params(context, crypto, params, &ivec);
388 hx509_crypto_destroy(crypto);
393 ret = hx509_crypto_set_key_data(crypto, key.data, key.length);
395 hx509_crypto_destroy(crypto);
396 hx509_set_error_string(context, 0, ret,
397 "Failed to set key for decryption "
402 ret = hx509_crypto_decrypt(crypto,
405 ivec.length ? &ivec : NULL,
407 hx509_crypto_destroy(crypto);
409 hx509_set_error_string(context, 0, ret,
410 "Failed to decrypt EnvelopedData");
417 free_EnvelopedData(&ed);
418 der_free_octet_string(&key);
420 der_free_octet_string(&ivec);
422 der_free_oid(contentType);
423 der_free_octet_string(content);
430 hx509_cms_envelope_1(hx509_context context,
435 const heim_oid *encryption_type,
436 const heim_oid *contentType,
437 heim_octet_string *content)
439 KeyTransRecipientInfo *ri;
440 heim_octet_string ivec;
441 heim_octet_string key;
442 hx509_crypto crypto = NULL;
447 memset(&ivec, 0, sizeof(ivec));
448 memset(&key, 0, sizeof(key));
449 memset(&ed, 0, sizeof(ed));
450 memset(content, 0, sizeof(*content));
452 if (encryption_type == NULL)
453 encryption_type = oid_id_aes_256_cbc();
455 ret = _hx509_check_key_usage(context, cert, 1 << 2, TRUE);
459 ret = hx509_crypto_init(context, NULL, encryption_type, &crypto);
463 ret = hx509_crypto_set_random_key(crypto, &key);
465 hx509_set_error_string(context, 0, ret,
466 "Create random key for EnvelopedData content");
470 ret = hx509_crypto_encrypt(crypto,
474 &ed.encryptedContentInfo.encryptedContent);
476 hx509_set_error_string(context, 0, ret,
477 "Failed to encrypt EnvelopedData content");
482 AlgorithmIdentifier *enc_alg;
483 enc_alg = &ed.encryptedContentInfo.contentEncryptionAlgorithm;
484 ret = der_copy_oid(encryption_type, &enc_alg->algorithm);
486 hx509_set_error_string(context, 0, ret,
487 "Failed to set crypto oid "
488 "for EnvelopedData");
491 ALLOC(enc_alg->parameters, 1);
492 if (enc_alg->parameters == NULL) {
494 hx509_set_error_string(context, 0, ret,
495 "Failed to allocate crypto paramaters "
496 "for EnvelopedData");
500 ret = hx509_crypto_get_params(context,
503 enc_alg->parameters);
509 ALLOC_SEQ(&ed.recipientInfos, 1);
510 if (ed.recipientInfos.val == NULL) {
512 hx509_set_error_string(context, 0, ret,
513 "Failed to allocate recipients info "
514 "for EnvelopedData");
518 ri = &ed.recipientInfos.val[0];
521 ret = fill_CMSIdentifier(cert, &ri->rid);
523 hx509_set_error_string(context, 0, ret,
524 "Failed to set CMS identifier info "
525 "for EnvelopedData");
529 ret = _hx509_cert_public_encrypt(context,
531 &ri->keyEncryptionAlgorithm.algorithm,
534 hx509_set_error_string(context, HX509_ERROR_APPEND, ret,
535 "Failed to encrypt transport key for "
545 ed.originatorInfo = NULL;
547 ret = der_copy_oid(contentType, &ed.encryptedContentInfo.contentType);
549 hx509_set_error_string(context, 0, ret,
550 "Failed to copy content oid for "
555 ed.unprotectedAttrs = NULL;
557 ASN1_MALLOC_ENCODE(EnvelopedData, content->data, content->length,
560 hx509_set_error_string(context, 0, ret,
561 "Failed to encode EnvelopedData");
564 if (size != content->length)
565 _hx509_abort("internal ASN.1 encoder error");
569 hx509_crypto_destroy(crypto);
571 der_free_octet_string(content);
572 der_free_octet_string(&key);
573 der_free_octet_string(&ivec);
574 free_EnvelopedData(&ed);
580 any_to_certs(hx509_context context, const SignedData *sd, hx509_certs certs)
584 if (sd->certificates == NULL)
587 for (i = 0; i < sd->certificates->len; i++) {
591 const void *p = sd->certificates->val[i].data;
592 size_t size, length = sd->certificates->val[i].length;
594 ret = decode_Certificate(p, length, &cert, &size);
596 hx509_set_error_string(context, 0, ret,
597 "Failed to decode certificate %d "
598 "in SignedData.certificates", i);
602 ret = hx509_cert_init(context, &cert, &c);
603 free_Certificate(&cert);
606 ret = hx509_certs_add(context, certs, c);
615 static const Attribute *
616 find_attribute(const CMSAttributes *attr, const heim_oid *oid)
619 for (i = 0; i < attr->len; i++)
620 if (der_heim_oid_cmp(&attr->val[i].type, oid) == 0)
621 return &attr->val[i];
626 hx509_cms_verify_signed(hx509_context context,
627 hx509_verify_ctx ctx,
630 const heim_octet_string *signedContent,
632 heim_oid *contentType,
633 heim_octet_string *content,
634 hx509_certs *signer_certs)
636 SignerInfo *signer_info;
637 hx509_cert cert = NULL;
638 hx509_certs certs = NULL;
641 int ret, i, found_valid_sig;
643 *signer_certs = NULL;
644 content->data = NULL;
646 contentType->length = 0;
647 contentType->components = NULL;
649 memset(&sd, 0, sizeof(sd));
651 ret = decode_SignedData(data, length, &sd, &size);
653 hx509_set_error_string(context, 0, ret,
654 "Failed to decode SignedData");
658 if (sd.encapContentInfo.eContent == NULL && signedContent == NULL) {
659 ret = HX509_CMS_NO_DATA_AVAILABLE;
660 hx509_set_error_string(context, 0, ret,
661 "No content data in SignedData");
664 if (sd.encapContentInfo.eContent && signedContent) {
665 ret = HX509_CMS_NO_DATA_AVAILABLE;
666 hx509_set_error_string(context, 0, ret,
667 "Both external and internal SignedData");
670 if (sd.encapContentInfo.eContent)
671 signedContent = sd.encapContentInfo.eContent;
673 ret = hx509_certs_init(context, "MEMORY:cms-cert-buffer",
678 ret = hx509_certs_init(context, "MEMORY:cms-signer-certs",
679 0, NULL, signer_certs);
683 /* XXX Check CMS version */
685 ret = any_to_certs(context, &sd, certs);
690 ret = hx509_certs_merge(context, certs, store);
695 for (found_valid_sig = 0, i = 0; i < sd.signerInfos.len; i++) {
696 heim_octet_string *signed_data;
697 const heim_oid *match_oid;
700 signer_info = &sd.signerInfos.val[i];
703 if (signer_info->signature.length == 0) {
704 ret = HX509_CMS_MISSING_SIGNER_DATA;
705 hx509_set_error_string(context, 0, ret,
706 "SignerInfo %d in SignedData "
707 "missing sigature", i);
711 ret = find_CMSIdentifier(context, &signer_info->sid, certs, &cert,
712 HX509_QUERY_KU_DIGITALSIGNATURE);
716 if (signer_info->signedAttrs) {
717 const Attribute *attr;
720 heim_octet_string os;
722 sa.val = signer_info->signedAttrs->val;
723 sa.len = signer_info->signedAttrs->len;
725 /* verify that sigature exists */
726 attr = find_attribute(&sa, oid_id_pkcs9_messageDigest());
728 ret = HX509_CRYPTO_SIGNATURE_MISSING;
729 hx509_set_error_string(context, 0, ret,
730 "SignerInfo have signed attributes "
731 "but messageDigest (signature) "
735 if (attr->value.len != 1) {
736 ret = HX509_CRYPTO_SIGNATURE_MISSING;
737 hx509_set_error_string(context, 0, ret,
738 "SignerInfo have more then one "
739 "messageDigest (signature)");
743 ret = decode_MessageDigest(attr->value.val[0].data,
744 attr->value.val[0].length,
748 hx509_set_error_string(context, 0, ret,
750 "messageDigest (signature)");
754 ret = _hx509_verify_signature(context,
756 &signer_info->digestAlgorithm,
759 der_free_octet_string(&os);
761 hx509_set_error_string(context, HX509_ERROR_APPEND, ret,
762 "Failed to verify messageDigest");
767 * Fetch content oid inside signedAttrs or set it to
770 attr = find_attribute(&sa, oid_id_pkcs9_contentType());
772 match_oid = oid_id_pkcs7_data();
774 if (attr->value.len != 1) {
775 ret = HX509_CMS_DATA_OID_MISMATCH;
776 hx509_set_error_string(context, 0, ret,
777 "More then one oid in signedAttrs");
781 ret = decode_ContentType(attr->value.val[0].data,
782 attr->value.val[0].length,
786 hx509_set_error_string(context, 0, ret,
788 "oid in signedAttrs");
791 match_oid = &decode_oid;
794 ALLOC(signed_data, 1);
795 if (signed_data == NULL) {
796 if (match_oid == &decode_oid)
797 der_free_oid(&decode_oid);
799 hx509_clear_error_string(context);
803 ASN1_MALLOC_ENCODE(CMSAttributes,
809 if (match_oid == &decode_oid)
810 der_free_oid(&decode_oid);
812 hx509_clear_error_string(context);
815 if (size != signed_data->length)
816 _hx509_abort("internal ASN.1 encoder error");
819 signed_data = rk_UNCONST(signedContent);
820 match_oid = oid_id_pkcs7_data();
823 if (der_heim_oid_cmp(match_oid, &sd.encapContentInfo.eContentType)) {
824 ret = HX509_CMS_DATA_OID_MISMATCH;
825 hx509_set_error_string(context, 0, ret,
826 "Oid in message mismatch from the expected");
828 if (match_oid == &decode_oid)
829 der_free_oid(&decode_oid);
832 ret = hx509_verify_signature(context,
834 &signer_info->signatureAlgorithm,
836 &signer_info->signature);
838 hx509_set_error_string(context, HX509_ERROR_APPEND, ret,
839 "Failed to verify sigature in "
842 if (signed_data != signedContent) {
843 der_free_octet_string(signed_data);
849 ret = hx509_verify_path(context, ctx, cert, certs);
853 ret = hx509_certs_add(context, *signer_certs, cert);
861 hx509_cert_free(cert);
864 if (found_valid_sig == 0) {
866 ret = HX509_CMS_SIGNER_NOT_FOUND;
867 hx509_set_error_string(context, 0, ret,
868 "No signers where found");
873 ret = der_copy_oid(&sd.encapContentInfo.eContentType, contentType);
875 hx509_clear_error_string(context);
879 content->data = malloc(signedContent->length);
880 if (content->data == NULL) {
881 hx509_clear_error_string(context);
885 content->length = signedContent->length;
886 memcpy(content->data, signedContent->data, content->length);
889 free_SignedData(&sd);
891 hx509_certs_free(&certs);
894 hx509_certs_free(signer_certs);
895 der_free_oid(contentType);
896 der_free_octet_string(content);
903 add_one_attribute(Attribute **attr,
906 heim_octet_string *data)
911 d = realloc(*attr, sizeof((*attr)[0]) * (*len + 1));
916 ret = der_copy_oid(oid, &(*attr)[*len].type);
920 ALLOC_SEQ(&(*attr)[*len].value, 1);
921 if ((*attr)[*len].value.val == NULL) {
922 der_free_oid(&(*attr)[*len].type);
926 (*attr)[*len].value.val[0].data = data->data;
927 (*attr)[*len].value.val[0].length = data->length;
935 hx509_cms_create_signed_1(hx509_context context,
937 const heim_oid *eContentType,
938 const void *data, size_t length,
939 const AlgorithmIdentifier *digest_alg,
941 hx509_peer_info peer,
944 heim_octet_string *signed_data)
946 AlgorithmIdentifier digest;
948 SignerInfo *signer_info;
949 heim_octet_string buf, content, sigdata = { 0, NULL };
955 memset(&sd, 0, sizeof(sd));
956 memset(&name, 0, sizeof(name));
957 memset(&path, 0, sizeof(path));
958 memset(&digest, 0, sizeof(digest));
960 content.data = rk_UNCONST(data);
961 content.length = length;
963 if (_hx509_cert_private_key(cert) == NULL) {
964 hx509_set_error_string(context, 0, HX509_PRIVATE_KEY_MISSING,
965 "Private key missing for signing");
966 return HX509_PRIVATE_KEY_MISSING;
969 if (digest_alg == NULL) {
970 ret = hx509_crypto_select(context, HX509_SELECT_DIGEST,
971 _hx509_cert_private_key(cert), peer, &digest);
973 ret = copy_AlgorithmIdentifier(digest_alg, &digest);
975 hx509_clear_error_string(context);
980 sd.version = CMSVersion_v3;
982 if (eContentType == NULL)
983 eContentType = oid_id_pkcs7_data();
985 der_copy_oid(eContentType, &sd.encapContentInfo.eContentType);
988 if ((flags & HX509_CMS_SIGATURE_DETACHED) == 0) {
989 ALLOC(sd.encapContentInfo.eContent, 1);
990 if (sd.encapContentInfo.eContent == NULL) {
991 hx509_clear_error_string(context);
996 sd.encapContentInfo.eContent->data = malloc(length);
997 if (sd.encapContentInfo.eContent->data == NULL) {
998 hx509_clear_error_string(context);
1002 memcpy(sd.encapContentInfo.eContent->data, data, length);
1003 sd.encapContentInfo.eContent->length = length;
1006 ALLOC_SEQ(&sd.signerInfos, 1);
1007 if (sd.signerInfos.val == NULL) {
1008 hx509_clear_error_string(context);
1013 signer_info = &sd.signerInfos.val[0];
1015 signer_info->version = 1;
1017 ret = fill_CMSIdentifier(cert, &signer_info->sid);
1019 hx509_clear_error_string(context);
1023 signer_info->signedAttrs = NULL;
1024 signer_info->unsignedAttrs = NULL;
1027 ret = copy_AlgorithmIdentifier(&digest, &signer_info->digestAlgorithm);
1029 hx509_clear_error_string(context);
1034 * If its not pkcs7-data send signedAttributes
1037 if (der_heim_oid_cmp(eContentType, oid_id_pkcs7_data()) != 0) {
1039 heim_octet_string sig;
1041 ALLOC(signer_info->signedAttrs, 1);
1042 if (signer_info->signedAttrs == NULL) {
1047 ret = _hx509_create_signature(context,
1056 ASN1_MALLOC_ENCODE(MessageDigest,
1062 der_free_octet_string(&sig);
1064 hx509_clear_error_string(context);
1067 if (size != buf.length)
1068 _hx509_abort("internal ASN.1 encoder error");
1070 ret = add_one_attribute(&signer_info->signedAttrs->val,
1071 &signer_info->signedAttrs->len,
1072 oid_id_pkcs9_messageDigest(),
1075 hx509_clear_error_string(context);
1080 ASN1_MALLOC_ENCODE(ContentType,
1088 if (size != buf.length)
1089 _hx509_abort("internal ASN.1 encoder error");
1091 ret = add_one_attribute(&signer_info->signedAttrs->val,
1092 &signer_info->signedAttrs->len,
1093 oid_id_pkcs9_contentType(),
1096 hx509_clear_error_string(context);
1100 sa.val = signer_info->signedAttrs->val;
1101 sa.len = signer_info->signedAttrs->len;
1103 ASN1_MALLOC_ENCODE(CMSAttributes,
1110 hx509_clear_error_string(context);
1113 if (size != sigdata.length)
1114 _hx509_abort("internal ASN.1 encoder error");
1116 sigdata.data = content.data;
1117 sigdata.length = content.length;
1122 AlgorithmIdentifier sigalg;
1124 ret = hx509_crypto_select(context, HX509_SELECT_PUBLIC_SIG,
1125 _hx509_cert_private_key(cert), peer,
1130 ret = _hx509_create_signature(context,
1131 _hx509_cert_private_key(cert),
1134 &signer_info->signatureAlgorithm,
1135 &signer_info->signature);
1136 free_AlgorithmIdentifier(&sigalg);
1141 ALLOC_SEQ(&sd.digestAlgorithms, 1);
1142 if (sd.digestAlgorithms.val == NULL) {
1144 hx509_clear_error_string(context);
1148 ret = copy_AlgorithmIdentifier(&digest, &sd.digestAlgorithms.val[0]);
1150 hx509_clear_error_string(context);
1155 * Provide best effort path
1158 _hx509_calculate_path(context,
1159 HX509_CALCULATE_PATH_NO_ANCHOR,
1167 _hx509_path_append(context, &path, cert);
1173 ALLOC(sd.certificates, 1);
1174 if (sd.certificates == NULL) {
1175 hx509_clear_error_string(context);
1179 ALLOC_SEQ(sd.certificates, path.len);
1180 if (sd.certificates->val == NULL) {
1181 hx509_clear_error_string(context);
1186 for (i = 0; i < path.len; i++) {
1187 ret = hx509_cert_binary(context, path.val[i],
1188 &sd.certificates->val[i]);
1190 hx509_clear_error_string(context);
1196 ASN1_MALLOC_ENCODE(SignedData,
1197 signed_data->data, signed_data->length,
1200 hx509_clear_error_string(context);
1203 if (signed_data->length != size)
1204 _hx509_abort("internal ASN.1 encoder error");
1207 if (sigdata.data != content.data)
1208 der_free_octet_string(&sigdata);
1209 free_AlgorithmIdentifier(&digest);
1210 _hx509_path_free(&path);
1211 free_SignedData(&sd);
1217 hx509_cms_decrypt_encrypted(hx509_context context,
1221 heim_oid *contentType,
1222 heim_octet_string *content)
1224 heim_octet_string cont;
1225 CMSEncryptedData ed;
1226 AlgorithmIdentifier *ai;
1229 memset(content, 0, sizeof(*content));
1230 memset(&cont, 0, sizeof(cont));
1232 ret = decode_CMSEncryptedData(data, length, &ed, NULL);
1234 hx509_set_error_string(context, 0, ret,
1235 "Failed to decode CMSEncryptedData");
1239 if (ed.encryptedContentInfo.encryptedContent == NULL) {
1240 ret = HX509_CMS_NO_DATA_AVAILABLE;
1241 hx509_set_error_string(context, 0, ret,
1242 "No content in EncryptedData");
1246 ret = der_copy_oid(&ed.encryptedContentInfo.contentType, contentType);
1248 hx509_clear_error_string(context);
1252 ai = &ed.encryptedContentInfo.contentEncryptionAlgorithm;
1253 if (ai->parameters == NULL) {
1254 ret = HX509_ALG_NOT_SUPP;
1255 hx509_clear_error_string(context);
1259 ret = _hx509_pbe_decrypt(context,
1262 ed.encryptedContentInfo.encryptedContent,
1274 free_CMSEncryptedData(&ed);