]>
Commit | Line | Data |
---|---|---|
0f113f3e | 1 | /* |
454afd98 | 2 | * Copyright 2008-2020 The OpenSSL Project Authors. All Rights Reserved. |
f4cc56f4 | 3 | * |
08ddd302 | 4 | * Licensed under the Apache License 2.0 (the "License"). You may not use |
b1322259 RS |
5 | * this file except in compliance with the License. You can obtain a copy |
6 | * in the file LICENSE in the source distribution or at | |
7 | * https://www.openssl.org/source/license.html | |
f4cc56f4 DSH |
8 | */ |
9 | ||
b39fc560 | 10 | #include "internal/cryptlib.h" |
f4cc56f4 DSH |
11 | #include <openssl/asn1t.h> |
12 | #include <openssl/pem.h> | |
13 | #include <openssl/rand.h> | |
14 | #include <openssl/x509v3.h> | |
15 | #include <openssl/err.h> | |
16 | #include <openssl/cms.h> | |
e85d19c6 | 17 | #include <openssl/ess.h> |
25f2138b DMSP |
18 | #include "crypto/ess.h" |
19 | #include "crypto/cms.h" | |
c1669f41 SL |
20 | #include "crypto/x509.h" |
21 | #include "cms_local.h" | |
f4cc56f4 | 22 | |
f4cc56f4 DSH |
23 | IMPLEMENT_ASN1_FUNCTIONS(CMS_ReceiptRequest) |
24 | ||
e85d19c6 | 25 | /* ESS services */ |
f4cc56f4 DSH |
26 | |
27 | int CMS_get1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest **prr) | |
0f113f3e MC |
28 | { |
29 | ASN1_STRING *str; | |
9e3c510b F |
30 | CMS_ReceiptRequest *rr; |
31 | ASN1_OBJECT *obj = OBJ_nid2obj(NID_id_smime_aa_receiptRequest); | |
32 | ||
33 | if (prr != NULL) | |
0f113f3e | 34 | *prr = NULL; |
9e3c510b F |
35 | str = CMS_signed_get0_data_by_OBJ(si, obj, -3, V_ASN1_SEQUENCE); |
36 | if (str == NULL) | |
0f113f3e MC |
37 | return 0; |
38 | ||
39 | rr = ASN1_item_unpack(str, ASN1_ITEM_rptr(CMS_ReceiptRequest)); | |
9e3c510b | 40 | if (rr == NULL) |
0f113f3e | 41 | return -1; |
9e3c510b | 42 | if (prr != NULL) |
0f113f3e MC |
43 | *prr = rr; |
44 | else | |
45 | CMS_ReceiptRequest_free(rr); | |
46 | return 1; | |
47 | } | |
f4cc56f4 | 48 | |
9e3c510b F |
49 | /* |
50 | First, get the ESS_SIGNING_CERT(V2) signed attribute from |si|. | |
51 | Then check matching of each cert of trust |chain| with one of | |
52 | the |cert_ids|(Hash+IssuerID) list from this ESS_SIGNING_CERT. | |
53 | Derived from ts_check_signing_certs() | |
54 | */ | |
55 | int ess_check_signing_certs(CMS_SignerInfo *si, STACK_OF(X509) *chain) | |
56 | { | |
57 | ESS_SIGNING_CERT *ss = NULL; | |
58 | ESS_SIGNING_CERT_V2 *ssv2 = NULL; | |
59 | X509 *cert; | |
60 | int i = 0, ret = 0; | |
61 | ||
62 | if (cms_signerinfo_get_signing_cert(si, &ss) > 0 && ss->cert_ids != NULL) { | |
63 | STACK_OF(ESS_CERT_ID) *cert_ids = ss->cert_ids; | |
64 | ||
65 | cert = sk_X509_value(chain, 0); | |
66 | if (ess_find_cert(cert_ids, cert) != 0) | |
67 | goto err; | |
68 | ||
69 | /* | |
70 | * Check the other certificates of the chain. | |
71 | * Fail if no signing certificate ids found for each certificate. | |
72 | */ | |
73 | if (sk_ESS_CERT_ID_num(cert_ids) > 1) { | |
74 | /* for each chain cert, try to find its cert id */ | |
75 | for (i = 1; i < sk_X509_num(chain); ++i) { | |
76 | cert = sk_X509_value(chain, i); | |
77 | if (ess_find_cert(cert_ids, cert) < 0) | |
78 | goto err; | |
79 | } | |
80 | } | |
81 | } else if (cms_signerinfo_get_signing_cert_v2(si, &ssv2) > 0 | |
82 | && ssv2->cert_ids!= NULL) { | |
83 | STACK_OF(ESS_CERT_ID_V2) *cert_ids_v2 = ssv2->cert_ids; | |
84 | ||
85 | cert = sk_X509_value(chain, 0); | |
86 | if (ess_find_cert_v2(cert_ids_v2, cert) != 0) | |
87 | goto err; | |
88 | ||
89 | /* | |
90 | * Check the other certificates of the chain. | |
91 | * Fail if no signing certificate ids found for each certificate. | |
92 | */ | |
93 | if (sk_ESS_CERT_ID_V2_num(cert_ids_v2) > 1) { | |
94 | /* for each chain cert, try to find its cert id */ | |
95 | for (i = 1; i < sk_X509_num(chain); ++i) { | |
96 | cert = sk_X509_value(chain, i); | |
97 | if (ess_find_cert_v2(cert_ids_v2, cert) < 0) | |
98 | goto err; | |
99 | } | |
100 | } | |
101 | } else { | |
102 | CMSerr(CMS_F_ESS_CHECK_SIGNING_CERTS, | |
103 | CMS_R_ESS_NO_SIGNING_CERTID_ATTRIBUTE); | |
104 | return 0; | |
105 | } | |
106 | ret = 1; | |
107 | err: | |
108 | if (!ret) | |
109 | CMSerr(CMS_F_ESS_CHECK_SIGNING_CERTS, | |
110 | CMS_R_ESS_SIGNING_CERTID_MISMATCH_ERROR); | |
111 | ||
112 | ESS_SIGNING_CERT_free(ss); | |
113 | ESS_SIGNING_CERT_V2_free(ssv2); | |
114 | return ret; | |
115 | } | |
116 | ||
d8652be0 | 117 | CMS_ReceiptRequest *CMS_ReceiptRequest_create0_ex( |
c1669f41 SL |
118 | unsigned char *id, int idlen, int allorfirst, |
119 | STACK_OF(GENERAL_NAMES) *receiptList, STACK_OF(GENERAL_NAMES) *receiptsTo, | |
b4250010 | 120 | OSSL_LIB_CTX *libctx, const char *propq) |
0f113f3e | 121 | { |
9e3c510b | 122 | CMS_ReceiptRequest *rr; |
0f113f3e MC |
123 | |
124 | rr = CMS_ReceiptRequest_new(); | |
90945fa3 | 125 | if (rr == NULL) |
0f113f3e MC |
126 | goto merr; |
127 | if (id) | |
128 | ASN1_STRING_set0(rr->signedContentIdentifier, id, idlen); | |
129 | else { | |
130 | if (!ASN1_STRING_set(rr->signedContentIdentifier, NULL, 32)) | |
131 | goto merr; | |
c1669f41 | 132 | if (RAND_bytes_ex(libctx, rr->signedContentIdentifier->data, 32) <= 0) |
0f113f3e MC |
133 | goto err; |
134 | } | |
135 | ||
136 | sk_GENERAL_NAMES_pop_free(rr->receiptsTo, GENERAL_NAMES_free); | |
137 | rr->receiptsTo = receiptsTo; | |
138 | ||
c1669f41 | 139 | if (receiptList != NULL) { |
0f113f3e MC |
140 | rr->receiptsFrom->type = 1; |
141 | rr->receiptsFrom->d.receiptList = receiptList; | |
142 | } else { | |
143 | rr->receiptsFrom->type = 0; | |
144 | rr->receiptsFrom->d.allOrFirstTier = allorfirst; | |
145 | } | |
146 | ||
147 | return rr; | |
148 | ||
149 | merr: | |
c1669f41 | 150 | CMSerr(0, ERR_R_MALLOC_FAILURE); |
0f113f3e MC |
151 | |
152 | err: | |
25aaa98a | 153 | CMS_ReceiptRequest_free(rr); |
0f113f3e MC |
154 | return NULL; |
155 | ||
156 | } | |
f5e2354c | 157 | |
c1669f41 SL |
158 | CMS_ReceiptRequest *CMS_ReceiptRequest_create0( |
159 | unsigned char *id, int idlen, int allorfirst, | |
160 | STACK_OF(GENERAL_NAMES) *receiptList, STACK_OF(GENERAL_NAMES) *receiptsTo) | |
161 | { | |
d8652be0 MC |
162 | return CMS_ReceiptRequest_create0_ex(id, idlen, allorfirst, receiptList, |
163 | receiptsTo, NULL, NULL); | |
c1669f41 SL |
164 | } |
165 | ||
f5e2354c | 166 | int CMS_add1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest *rr) |
0f113f3e MC |
167 | { |
168 | unsigned char *rrder = NULL; | |
169 | int rrderlen, r = 0; | |
f5e2354c | 170 | |
0f113f3e MC |
171 | rrderlen = i2d_CMS_ReceiptRequest(rr, &rrder); |
172 | if (rrderlen < 0) | |
173 | goto merr; | |
f5e2354c | 174 | |
0f113f3e MC |
175 | if (!CMS_signed_add1_attr_by_NID(si, NID_id_smime_aa_receiptRequest, |
176 | V_ASN1_SEQUENCE, rrder, rrderlen)) | |
177 | goto merr; | |
f5e2354c | 178 | |
0f113f3e | 179 | r = 1; |
f5e2354c | 180 | |
0f113f3e MC |
181 | merr: |
182 | if (!r) | |
183 | CMSerr(CMS_F_CMS_ADD1_RECEIPTREQUEST, ERR_R_MALLOC_FAILURE); | |
f5e2354c | 184 | |
b548a1f1 | 185 | OPENSSL_free(rrder); |
f4cc56f4 | 186 | |
0f113f3e MC |
187 | return r; |
188 | ||
189 | } | |
f4cc56f4 DSH |
190 | |
191 | void CMS_ReceiptRequest_get0_values(CMS_ReceiptRequest *rr, | |
0f113f3e MC |
192 | ASN1_STRING **pcid, |
193 | int *pallorfirst, | |
194 | STACK_OF(GENERAL_NAMES) **plist, | |
195 | STACK_OF(GENERAL_NAMES) **prto) | |
196 | { | |
c1669f41 | 197 | if (pcid != NULL) |
0f113f3e MC |
198 | *pcid = rr->signedContentIdentifier; |
199 | if (rr->receiptsFrom->type == 0) { | |
c1669f41 | 200 | if (pallorfirst != NULL) |
0f113f3e | 201 | *pallorfirst = (int)rr->receiptsFrom->d.allOrFirstTier; |
c1669f41 | 202 | if (plist != NULL) |
0f113f3e MC |
203 | *plist = NULL; |
204 | } else { | |
c1669f41 | 205 | if (pallorfirst != NULL) |
0f113f3e | 206 | *pallorfirst = -1; |
c1669f41 | 207 | if (plist != NULL) |
0f113f3e MC |
208 | *plist = rr->receiptsFrom->d.receiptList; |
209 | } | |
c1669f41 | 210 | if (prto != NULL) |
0f113f3e MC |
211 | *prto = rr->receiptsTo; |
212 | } | |
f4cc56f4 | 213 | |
36309aa2 DSH |
214 | /* Digest a SignerInfo structure for msgSigDigest attribute processing */ |
215 | ||
eb9d8d8c | 216 | static int cms_msgSigDigest(CMS_SignerInfo *si, |
0f113f3e MC |
217 | unsigned char *dig, unsigned int *diglen) |
218 | { | |
c1669f41 | 219 | const EVP_MD *md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm); |
9e3c510b | 220 | |
0f113f3e MC |
221 | if (md == NULL) |
222 | return 0; | |
d8652be0 MC |
223 | if (!asn1_item_digest_ex(ASN1_ITEM_rptr(CMS_Attributes_Verify), md, |
224 | si->signedAttrs, dig, diglen, si->cms_ctx->libctx, | |
225 | si->cms_ctx->propq)) | |
0f113f3e MC |
226 | return 0; |
227 | return 1; | |
228 | } | |
eb9d8d8c | 229 | |
36309aa2 DSH |
230 | /* Add a msgSigDigest attribute to a SignerInfo */ |
231 | ||
232 | int cms_msgSigDigest_add1(CMS_SignerInfo *dest, CMS_SignerInfo *src) | |
0f113f3e MC |
233 | { |
234 | unsigned char dig[EVP_MAX_MD_SIZE]; | |
235 | unsigned int diglen; | |
9e3c510b | 236 | |
0f113f3e MC |
237 | if (!cms_msgSigDigest(src, dig, &diglen)) { |
238 | CMSerr(CMS_F_CMS_MSGSIGDIGEST_ADD1, CMS_R_MSGSIGDIGEST_ERROR); | |
239 | return 0; | |
240 | } | |
241 | if (!CMS_signed_add1_attr_by_NID(dest, NID_id_smime_aa_msgSigDigest, | |
242 | V_ASN1_OCTET_STRING, dig, diglen)) { | |
243 | CMSerr(CMS_F_CMS_MSGSIGDIGEST_ADD1, ERR_R_MALLOC_FAILURE); | |
244 | return 0; | |
245 | } | |
246 | return 1; | |
247 | } | |
36309aa2 | 248 | |
eb9d8d8c DSH |
249 | /* Verify signed receipt after it has already passed normal CMS verify */ |
250 | ||
251 | int cms_Receipt_verify(CMS_ContentInfo *cms, CMS_ContentInfo *req_cms) | |
0f113f3e MC |
252 | { |
253 | int r = 0, i; | |
254 | CMS_ReceiptRequest *rr = NULL; | |
255 | CMS_Receipt *rct = NULL; | |
256 | STACK_OF(CMS_SignerInfo) *sis, *osis; | |
257 | CMS_SignerInfo *si, *osi = NULL; | |
258 | ASN1_OCTET_STRING *msig, **pcont; | |
259 | ASN1_OBJECT *octype; | |
260 | unsigned char dig[EVP_MAX_MD_SIZE]; | |
261 | unsigned int diglen; | |
262 | ||
263 | /* Get SignerInfos, also checks SignedData content type */ | |
264 | osis = CMS_get0_SignerInfos(req_cms); | |
265 | sis = CMS_get0_SignerInfos(cms); | |
266 | if (!osis || !sis) | |
267 | goto err; | |
268 | ||
269 | if (sk_CMS_SignerInfo_num(sis) != 1) { | |
270 | CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NEED_ONE_SIGNER); | |
271 | goto err; | |
272 | } | |
273 | ||
274 | /* Check receipt content type */ | |
275 | if (OBJ_obj2nid(CMS_get0_eContentType(cms)) != NID_id_smime_ct_receipt) { | |
276 | CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NOT_A_SIGNED_RECEIPT); | |
277 | goto err; | |
278 | } | |
279 | ||
280 | /* Extract and decode receipt content */ | |
281 | pcont = CMS_get0_content(cms); | |
12a765a5 | 282 | if (pcont == NULL || *pcont == NULL) { |
0f113f3e MC |
283 | CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_CONTENT); |
284 | goto err; | |
285 | } | |
286 | ||
287 | rct = ASN1_item_unpack(*pcont, ASN1_ITEM_rptr(CMS_Receipt)); | |
288 | ||
289 | if (!rct) { | |
290 | CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_RECEIPT_DECODE_ERROR); | |
291 | goto err; | |
292 | } | |
293 | ||
294 | /* Locate original request */ | |
295 | ||
296 | for (i = 0; i < sk_CMS_SignerInfo_num(osis); i++) { | |
297 | osi = sk_CMS_SignerInfo_value(osis, i); | |
298 | if (!ASN1_STRING_cmp(osi->signature, rct->originatorSignatureValue)) | |
299 | break; | |
300 | } | |
301 | ||
302 | if (i == sk_CMS_SignerInfo_num(osis)) { | |
303 | CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_MATCHING_SIGNATURE); | |
304 | goto err; | |
305 | } | |
306 | ||
307 | si = sk_CMS_SignerInfo_value(sis, 0); | |
308 | ||
309 | /* Get msgSigDigest value and compare */ | |
310 | ||
311 | msig = CMS_signed_get0_data_by_OBJ(si, | |
312 | OBJ_nid2obj | |
313 | (NID_id_smime_aa_msgSigDigest), -3, | |
314 | V_ASN1_OCTET_STRING); | |
315 | ||
316 | if (!msig) { | |
317 | CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_MSGSIGDIGEST); | |
318 | goto err; | |
319 | } | |
320 | ||
321 | if (!cms_msgSigDigest(osi, dig, &diglen)) { | |
322 | CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_MSGSIGDIGEST_ERROR); | |
323 | goto err; | |
324 | } | |
325 | ||
326 | if (diglen != (unsigned int)msig->length) { | |
327 | CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_MSGSIGDIGEST_WRONG_LENGTH); | |
328 | goto err; | |
329 | } | |
330 | ||
331 | if (memcmp(dig, msig->data, diglen)) { | |
332 | CMSerr(CMS_F_CMS_RECEIPT_VERIFY, | |
333 | CMS_R_MSGSIGDIGEST_VERIFICATION_FAILURE); | |
334 | goto err; | |
335 | } | |
336 | ||
337 | /* Compare content types */ | |
338 | ||
339 | octype = CMS_signed_get0_data_by_OBJ(osi, | |
340 | OBJ_nid2obj(NID_pkcs9_contentType), | |
341 | -3, V_ASN1_OBJECT); | |
342 | if (!octype) { | |
343 | CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_CONTENT_TYPE); | |
344 | goto err; | |
345 | } | |
346 | ||
347 | /* Compare details in receipt request */ | |
348 | ||
349 | if (OBJ_cmp(octype, rct->contentType)) { | |
350 | CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_CONTENT_TYPE_MISMATCH); | |
351 | goto err; | |
352 | } | |
353 | ||
354 | /* Get original receipt request details */ | |
355 | ||
356 | if (CMS_get1_ReceiptRequest(osi, &rr) <= 0) { | |
357 | CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_RECEIPT_REQUEST); | |
358 | goto err; | |
359 | } | |
360 | ||
361 | if (ASN1_STRING_cmp(rr->signedContentIdentifier, | |
362 | rct->signedContentIdentifier)) { | |
363 | CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_CONTENTIDENTIFIER_MISMATCH); | |
364 | goto err; | |
365 | } | |
366 | ||
367 | r = 1; | |
368 | ||
369 | err: | |
25aaa98a | 370 | CMS_ReceiptRequest_free(rr); |
2ace7450 | 371 | M_ASN1_free_of(rct, CMS_Receipt); |
0f113f3e MC |
372 | return r; |
373 | ||
374 | } | |
375 | ||
376 | /* | |
377 | * Encode a Receipt into an OCTET STRING read for including into content of a | |
378 | * SignedData ContentInfo. | |
36309aa2 DSH |
379 | */ |
380 | ||
381 | ASN1_OCTET_STRING *cms_encode_Receipt(CMS_SignerInfo *si) | |
0f113f3e MC |
382 | { |
383 | CMS_Receipt rct; | |
384 | CMS_ReceiptRequest *rr = NULL; | |
385 | ASN1_OBJECT *ctype; | |
386 | ASN1_OCTET_STRING *os = NULL; | |
36309aa2 | 387 | |
0f113f3e | 388 | /* Get original receipt request */ |
36309aa2 | 389 | |
0f113f3e | 390 | /* Get original receipt request details */ |
36309aa2 | 391 | |
0f113f3e MC |
392 | if (CMS_get1_ReceiptRequest(si, &rr) <= 0) { |
393 | CMSerr(CMS_F_CMS_ENCODE_RECEIPT, CMS_R_NO_RECEIPT_REQUEST); | |
394 | goto err; | |
395 | } | |
36309aa2 | 396 | |
0f113f3e | 397 | /* Get original content type */ |
36309aa2 | 398 | |
0f113f3e MC |
399 | ctype = CMS_signed_get0_data_by_OBJ(si, |
400 | OBJ_nid2obj(NID_pkcs9_contentType), | |
401 | -3, V_ASN1_OBJECT); | |
402 | if (!ctype) { | |
403 | CMSerr(CMS_F_CMS_ENCODE_RECEIPT, CMS_R_NO_CONTENT_TYPE); | |
404 | goto err; | |
405 | } | |
36309aa2 | 406 | |
0f113f3e MC |
407 | rct.version = 1; |
408 | rct.contentType = ctype; | |
409 | rct.signedContentIdentifier = rr->signedContentIdentifier; | |
410 | rct.originatorSignatureValue = si->signature; | |
36309aa2 | 411 | |
0f113f3e | 412 | os = ASN1_item_pack(&rct, ASN1_ITEM_rptr(CMS_Receipt), NULL); |
36309aa2 | 413 | |
0f113f3e | 414 | err: |
25aaa98a | 415 | CMS_ReceiptRequest_free(rr); |
0f113f3e | 416 | return os; |
0f113f3e | 417 | } |
e85d19c6 AI |
418 | |
419 | /* | |
8c00f267 | 420 | * Add signer certificate's V2 digest |sc| to a SignerInfo structure |si| |
e85d19c6 AI |
421 | */ |
422 | ||
8c00f267 | 423 | int cms_add1_signing_cert_v2(CMS_SignerInfo *si, ESS_SIGNING_CERT_V2 *sc) |
e85d19c6 AI |
424 | { |
425 | ASN1_STRING *seq = NULL; | |
5340c8ea | 426 | unsigned char *p, *pp = NULL; |
e85d19c6 AI |
427 | int len; |
428 | ||
429 | /* Add SigningCertificateV2 signed attribute to the signer info. */ | |
430 | len = i2d_ESS_SIGNING_CERT_V2(sc, NULL); | |
5340c8ea | 431 | if (len <= 0 || (pp = OPENSSL_malloc(len)) == NULL) |
e85d19c6 AI |
432 | goto err; |
433 | p = pp; | |
434 | i2d_ESS_SIGNING_CERT_V2(sc, &p); | |
435 | if (!(seq = ASN1_STRING_new()) || !ASN1_STRING_set(seq, pp, len)) | |
436 | goto err; | |
437 | OPENSSL_free(pp); | |
438 | pp = NULL; | |
439 | if (!CMS_signed_add1_attr_by_NID(si, NID_id_smime_aa_signingCertificateV2, | |
440 | V_ASN1_SEQUENCE, seq, -1)) | |
441 | goto err; | |
442 | ASN1_STRING_free(seq); | |
443 | return 1; | |
444 | err: | |
445 | CMSerr(CMS_F_CMS_ADD1_SIGNING_CERT_V2, ERR_R_MALLOC_FAILURE); | |
446 | ASN1_STRING_free(seq); | |
447 | OPENSSL_free(pp); | |
448 | return 0; | |
449 | } | |
450 | ||
451 | /* | |
8c00f267 | 452 | * Add signer certificate's digest |sc| to a SignerInfo structure |si| |
e85d19c6 AI |
453 | */ |
454 | ||
8c00f267 | 455 | int cms_add1_signing_cert(CMS_SignerInfo *si, ESS_SIGNING_CERT *sc) |
e85d19c6 AI |
456 | { |
457 | ASN1_STRING *seq = NULL; | |
5340c8ea | 458 | unsigned char *p, *pp = NULL; |
e85d19c6 AI |
459 | int len; |
460 | ||
461 | /* Add SigningCertificate signed attribute to the signer info. */ | |
462 | len = i2d_ESS_SIGNING_CERT(sc, NULL); | |
5340c8ea | 463 | if (len <= 0 || (pp = OPENSSL_malloc(len)) == NULL) |
e85d19c6 AI |
464 | goto err; |
465 | p = pp; | |
466 | i2d_ESS_SIGNING_CERT(sc, &p); | |
467 | if (!(seq = ASN1_STRING_new()) || !ASN1_STRING_set(seq, pp, len)) | |
468 | goto err; | |
469 | OPENSSL_free(pp); | |
470 | pp = NULL; | |
471 | if (!CMS_signed_add1_attr_by_NID(si, NID_id_smime_aa_signingCertificate, | |
472 | V_ASN1_SEQUENCE, seq, -1)) | |
473 | goto err; | |
474 | ASN1_STRING_free(seq); | |
475 | return 1; | |
476 | err: | |
477 | CMSerr(CMS_F_CMS_ADD1_SIGNING_CERT, ERR_R_MALLOC_FAILURE); | |
478 | ASN1_STRING_free(seq); | |
479 | OPENSSL_free(pp); | |
480 | return 0; | |
481 | } |