1 /*
2 * Copyright 2008-2025 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the Apache License 2.0 (the "License"). You may not use
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
8 */
9
10 #include <openssl/asn1t.h>
11 #include <openssl/x509v3.h>
12 #include <openssl/err.h>
13 #include <openssl/pem.h>
14 #include <openssl/bio.h>
15 #include <openssl/asn1.h>
16 #include <openssl/cms.h>
17 #include <openssl/core_names.h>
18 #include "internal/sizes.h"
19 #include "internal/cryptlib.h"
20 #include "crypto/x509.h"
21 #include "cms_local.h"
22 #include "internal/cms.h"
23
24 static STACK_OF(CMS_CertificateChoices)
25 **cms_get0_certificate_choices(CMS_ContentInfo *cms);
26
27 IMPLEMENT_ASN1_ALLOC_FUNCTIONS(CMS_ContentInfo)
IMPLEMENT_ASN1_PRINT_FUNCTION(CMS_ContentInfo)28 IMPLEMENT_ASN1_PRINT_FUNCTION(CMS_ContentInfo)
29
30 CMS_ContentInfo *d2i_CMS_ContentInfo(CMS_ContentInfo **a,
31 const unsigned char **in, long len)
32 {
33 CMS_ContentInfo *ci;
34 const CMS_CTX *ctx = ossl_cms_get0_cmsctx(a == NULL ? NULL : *a);
35
36 ci = (CMS_ContentInfo *)ASN1_item_d2i_ex((ASN1_VALUE **)a, in, len,
37 (CMS_ContentInfo_it()),
38 ossl_cms_ctx_get0_libctx(ctx),
39 ossl_cms_ctx_get0_propq(ctx));
40 if (ci != NULL) {
41 ERR_set_mark();
42 ossl_cms_resolve_libctx(ci);
43 ERR_pop_to_mark();
44 }
45 return ci;
46 }
47
i2d_CMS_ContentInfo(const CMS_ContentInfo * a,unsigned char ** out)48 int i2d_CMS_ContentInfo(const CMS_ContentInfo *a, unsigned char **out)
49 {
50 return ASN1_item_i2d((const ASN1_VALUE *)a, out, (CMS_ContentInfo_it()));
51 }
52
CMS_ContentInfo_new_ex(OSSL_LIB_CTX * libctx,const char * propq)53 CMS_ContentInfo *CMS_ContentInfo_new_ex(OSSL_LIB_CTX *libctx, const char *propq)
54 {
55 CMS_ContentInfo *ci;
56
57 ci = (CMS_ContentInfo *)ASN1_item_new_ex(ASN1_ITEM_rptr(CMS_ContentInfo),
58 libctx, propq);
59 if (ci != NULL) {
60 ci->ctx.libctx = libctx;
61 ci->ctx.propq = NULL;
62 if (propq != NULL) {
63 ci->ctx.propq = OPENSSL_strdup(propq);
64 if (ci->ctx.propq == NULL) {
65 CMS_ContentInfo_free(ci);
66 ci = NULL;
67 }
68 }
69 }
70 return ci;
71 }
72
ossl_cms_get0_cmsctx(const CMS_ContentInfo * cms)73 const CMS_CTX *ossl_cms_get0_cmsctx(const CMS_ContentInfo *cms)
74 {
75 return cms != NULL ? &cms->ctx : NULL;
76 }
77
ossl_cms_ctx_get0_libctx(const CMS_CTX * ctx)78 OSSL_LIB_CTX *ossl_cms_ctx_get0_libctx(const CMS_CTX *ctx)
79 {
80 return ctx != NULL ? ctx->libctx : NULL;
81 }
82
ossl_cms_ctx_get0_propq(const CMS_CTX * ctx)83 const char *ossl_cms_ctx_get0_propq(const CMS_CTX *ctx)
84 {
85 return ctx != NULL ? ctx->propq : NULL;
86 }
87
ossl_cms_resolve_libctx(CMS_ContentInfo * ci)88 void ossl_cms_resolve_libctx(CMS_ContentInfo *ci)
89 {
90 int i;
91 CMS_CertificateChoices *cch;
92 STACK_OF(CMS_CertificateChoices) **pcerts;
93 const CMS_CTX *ctx = ossl_cms_get0_cmsctx(ci);
94 OSSL_LIB_CTX *libctx = ossl_cms_ctx_get0_libctx(ctx);
95 const char *propq = ossl_cms_ctx_get0_propq(ctx);
96
97 ossl_cms_SignerInfos_set_cmsctx(ci);
98 ossl_cms_RecipientInfos_set_cmsctx(ci);
99
100 pcerts = cms_get0_certificate_choices(ci);
101 if (pcerts != NULL) {
102 for (i = 0; i < sk_CMS_CertificateChoices_num(*pcerts); i++) {
103 cch = sk_CMS_CertificateChoices_value(*pcerts, i);
104 if (cch->type == CMS_CERTCHOICE_CERT)
105 ossl_x509_set0_libctx(cch->d.certificate, libctx, propq);
106 }
107 }
108 }
109
CMS_get0_type(const CMS_ContentInfo * cms)110 const ASN1_OBJECT *CMS_get0_type(const CMS_ContentInfo *cms)
111 {
112 return cms->contentType;
113 }
114
ossl_cms_Data_create(OSSL_LIB_CTX * libctx,const char * propq)115 CMS_ContentInfo *ossl_cms_Data_create(OSSL_LIB_CTX *libctx, const char *propq)
116 {
117 CMS_ContentInfo *cms = CMS_ContentInfo_new_ex(libctx, propq);
118
119 if (cms != NULL) {
120 cms->contentType = OBJ_nid2obj(NID_pkcs7_data);
121 /* Never detached */
122 CMS_set_detached(cms, 0);
123 }
124 return cms;
125 }
126
ossl_cms_content_bio(CMS_ContentInfo * cms)127 BIO *ossl_cms_content_bio(CMS_ContentInfo *cms)
128 {
129 ASN1_OCTET_STRING **pos = CMS_get0_content(cms);
130
131 if (pos == NULL)
132 return NULL;
133 /* If content detached data goes nowhere: create NULL BIO */
134 if (*pos == NULL)
135 return BIO_new(BIO_s_null());
136 /*
137 * If content not detached and created return memory BIO
138 */
139 if (*pos == NULL || ((*pos)->flags == ASN1_STRING_FLAG_CONT))
140 return BIO_new(BIO_s_mem());
141 /* Else content was read in: return read only BIO for it */
142 return BIO_new_mem_buf((*pos)->data, (*pos)->length);
143 }
144
CMS_dataInit(CMS_ContentInfo * cms,BIO * icont)145 BIO *CMS_dataInit(CMS_ContentInfo *cms, BIO *icont)
146 {
147 BIO *cmsbio, *cont;
148 if (icont)
149 cont = icont;
150 else
151 cont = ossl_cms_content_bio(cms);
152 if (!cont) {
153 ERR_raise(ERR_LIB_CMS, CMS_R_NO_CONTENT);
154 return NULL;
155 }
156 switch (OBJ_obj2nid(cms->contentType)) {
157
158 case NID_pkcs7_data:
159 return cont;
160
161 case NID_pkcs7_signed:
162 cmsbio = ossl_cms_SignedData_init_bio(cms);
163 break;
164
165 case NID_pkcs7_digest:
166 cmsbio = ossl_cms_DigestedData_init_bio(cms);
167 break;
168 #ifndef OPENSSL_NO_ZLIB
169 case NID_id_smime_ct_compressedData:
170 cmsbio = ossl_cms_CompressedData_init_bio(cms);
171 break;
172 #endif
173
174 case NID_pkcs7_encrypted:
175 cmsbio = ossl_cms_EncryptedData_init_bio(cms);
176 break;
177
178 case NID_pkcs7_enveloped:
179 cmsbio = ossl_cms_EnvelopedData_init_bio(cms);
180 break;
181
182 case NID_id_smime_ct_authEnvelopedData:
183 cmsbio = ossl_cms_AuthEnvelopedData_init_bio(cms);
184 break;
185
186 default:
187 ERR_raise(ERR_LIB_CMS, CMS_R_UNSUPPORTED_TYPE);
188 goto err;
189 }
190
191 if (cmsbio)
192 return BIO_push(cmsbio, cont);
193 err:
194 if (!icont)
195 BIO_free(cont);
196 return NULL;
197
198 }
199
200 /* unfortunately cannot constify SMIME_write_ASN1() due to this function */
CMS_dataFinal(CMS_ContentInfo * cms,BIO * cmsbio)201 int CMS_dataFinal(CMS_ContentInfo *cms, BIO *cmsbio)
202 {
203 return ossl_cms_DataFinal(cms, cmsbio, NULL, 0);
204 }
205
ossl_cms_DataFinal(CMS_ContentInfo * cms,BIO * cmsbio,const unsigned char * precomp_md,unsigned int precomp_mdlen)206 int ossl_cms_DataFinal(CMS_ContentInfo *cms, BIO *cmsbio,
207 const unsigned char *precomp_md,
208 unsigned int precomp_mdlen)
209 {
210 ASN1_OCTET_STRING **pos = CMS_get0_content(cms);
211
212 if (pos == NULL)
213 return 0;
214 /* If embedded content find memory BIO and set content */
215 if (*pos && ((*pos)->flags & ASN1_STRING_FLAG_CONT)) {
216 BIO *mbio;
217 unsigned char *cont;
218 long contlen;
219 mbio = BIO_find_type(cmsbio, BIO_TYPE_MEM);
220 if (!mbio) {
221 ERR_raise(ERR_LIB_CMS, CMS_R_CONTENT_NOT_FOUND);
222 return 0;
223 }
224 contlen = BIO_get_mem_data(mbio, &cont);
225 /* Set bio as read only so its content can't be clobbered */
226 BIO_set_flags(mbio, BIO_FLAGS_MEM_RDONLY);
227 BIO_set_mem_eof_return(mbio, 0);
228 ASN1_STRING_set0(*pos, cont, contlen);
229 (*pos)->flags &= ~ASN1_STRING_FLAG_CONT;
230 }
231
232 switch (OBJ_obj2nid(cms->contentType)) {
233
234 case NID_pkcs7_data:
235 case NID_pkcs7_encrypted:
236 case NID_id_smime_ct_compressedData:
237 /* Nothing to do */
238 return 1;
239
240 case NID_pkcs7_enveloped:
241 return ossl_cms_EnvelopedData_final(cms, cmsbio);
242
243 case NID_id_smime_ct_authEnvelopedData:
244 return ossl_cms_AuthEnvelopedData_final(cms, cmsbio);
245
246 case NID_pkcs7_signed:
247 return ossl_cms_SignedData_final(cms, cmsbio, precomp_md, precomp_mdlen);
248
249 case NID_pkcs7_digest:
250 return ossl_cms_DigestedData_do_final(cms, cmsbio, 0);
251
252 default:
253 ERR_raise(ERR_LIB_CMS, CMS_R_UNSUPPORTED_TYPE);
254 return 0;
255 }
256 }
257
258 /*
259 * Return an OCTET STRING pointer to content. This allows it to be accessed
260 * or set later.
261 */
262
CMS_get0_content(CMS_ContentInfo * cms)263 ASN1_OCTET_STRING **CMS_get0_content(CMS_ContentInfo *cms)
264 {
265 switch (OBJ_obj2nid(cms->contentType)) {
266
267 case NID_pkcs7_data:
268 return &cms->d.data;
269
270 case NID_pkcs7_signed:
271 return &cms->d.signedData->encapContentInfo->eContent;
272
273 case NID_pkcs7_enveloped:
274 return &cms->d.envelopedData->encryptedContentInfo->encryptedContent;
275
276 case NID_pkcs7_digest:
277 return &cms->d.digestedData->encapContentInfo->eContent;
278
279 case NID_pkcs7_encrypted:
280 return &cms->d.encryptedData->encryptedContentInfo->encryptedContent;
281
282 case NID_id_smime_ct_authEnvelopedData:
283 return &cms->d.authEnvelopedData->authEncryptedContentInfo
284 ->encryptedContent;
285
286 case NID_id_smime_ct_authData:
287 return &cms->d.authenticatedData->encapContentInfo->eContent;
288
289 case NID_id_smime_ct_compressedData:
290 return &cms->d.compressedData->encapContentInfo->eContent;
291
292 default:
293 if (cms->d.other->type == V_ASN1_OCTET_STRING)
294 return &cms->d.other->value.octet_string;
295 ERR_raise(ERR_LIB_CMS, CMS_R_UNSUPPORTED_CONTENT_TYPE);
296 return NULL;
297
298 }
299 }
300
301 /*
302 * Return an ASN1_OBJECT pointer to content type. This allows it to be
303 * accessed or set later.
304 */
305
cms_get0_econtent_type(CMS_ContentInfo * cms)306 static ASN1_OBJECT **cms_get0_econtent_type(CMS_ContentInfo *cms)
307 {
308 switch (OBJ_obj2nid(cms->contentType)) {
309
310 case NID_pkcs7_signed:
311 return &cms->d.signedData->encapContentInfo->eContentType;
312
313 case NID_pkcs7_enveloped:
314 return &cms->d.envelopedData->encryptedContentInfo->contentType;
315
316 case NID_pkcs7_digest:
317 return &cms->d.digestedData->encapContentInfo->eContentType;
318
319 case NID_pkcs7_encrypted:
320 return &cms->d.encryptedData->encryptedContentInfo->contentType;
321
322 case NID_id_smime_ct_authEnvelopedData:
323 return &cms->d.authEnvelopedData->authEncryptedContentInfo
324 ->contentType;
325 case NID_id_smime_ct_authData:
326 return &cms->d.authenticatedData->encapContentInfo->eContentType;
327
328 case NID_id_smime_ct_compressedData:
329 return &cms->d.compressedData->encapContentInfo->eContentType;
330
331 default:
332 ERR_raise(ERR_LIB_CMS, CMS_R_UNSUPPORTED_CONTENT_TYPE);
333 return NULL;
334
335 }
336 }
337
CMS_get0_eContentType(CMS_ContentInfo * cms)338 const ASN1_OBJECT *CMS_get0_eContentType(CMS_ContentInfo *cms)
339 {
340 ASN1_OBJECT **petype;
341 petype = cms_get0_econtent_type(cms);
342 if (petype)
343 return *petype;
344 return NULL;
345 }
346
CMS_set1_eContentType(CMS_ContentInfo * cms,const ASN1_OBJECT * oid)347 int CMS_set1_eContentType(CMS_ContentInfo *cms, const ASN1_OBJECT *oid)
348 {
349 ASN1_OBJECT **petype, *etype;
350
351 petype = cms_get0_econtent_type(cms);
352 if (petype == NULL)
353 return 0;
354 if (oid == NULL)
355 return 1;
356 etype = OBJ_dup(oid);
357 if (etype == NULL)
358 return 0;
359 ASN1_OBJECT_free(*petype);
360 *petype = etype;
361 return 1;
362 }
363
CMS_is_detached(CMS_ContentInfo * cms)364 int CMS_is_detached(CMS_ContentInfo *cms)
365 {
366 ASN1_OCTET_STRING **pos;
367
368 pos = CMS_get0_content(cms);
369 if (pos == NULL)
370 return -1;
371 if (*pos != NULL)
372 return 0;
373 return 1;
374 }
375
CMS_set_detached(CMS_ContentInfo * cms,int detached)376 int CMS_set_detached(CMS_ContentInfo *cms, int detached)
377 {
378 ASN1_OCTET_STRING **pos;
379
380 pos = CMS_get0_content(cms);
381 if (pos == NULL)
382 return 0;
383 if (detached) {
384 ASN1_OCTET_STRING_free(*pos);
385 *pos = NULL;
386 return 1;
387 }
388 if (*pos == NULL)
389 *pos = ASN1_OCTET_STRING_new();
390 if (*pos != NULL) {
391 /*
392 * NB: special flag to show content is created and not read in.
393 */
394 (*pos)->flags |= ASN1_STRING_FLAG_CONT;
395 return 1;
396 }
397 ERR_raise(ERR_LIB_CMS, ERR_R_ASN1_LIB);
398 return 0;
399 }
400
401 /* Create a digest BIO from an X509_ALGOR structure */
402
ossl_cms_DigestAlgorithm_init_bio(X509_ALGOR * digestAlgorithm,const CMS_CTX * ctx)403 BIO *ossl_cms_DigestAlgorithm_init_bio(X509_ALGOR *digestAlgorithm,
404 const CMS_CTX *ctx)
405 {
406 BIO *mdbio = NULL;
407 const ASN1_OBJECT *digestoid;
408 const EVP_MD *digest = NULL;
409 EVP_MD *fetched_digest = NULL;
410 char alg[OSSL_MAX_NAME_SIZE];
411 size_t xof_len = 0;
412
413 X509_ALGOR_get0(&digestoid, NULL, NULL, digestAlgorithm);
414 OBJ_obj2txt(alg, sizeof(alg), digestoid, 0);
415
416 (void)ERR_set_mark();
417 fetched_digest = EVP_MD_fetch(ossl_cms_ctx_get0_libctx(ctx), alg,
418 ossl_cms_ctx_get0_propq(ctx));
419
420 if (fetched_digest != NULL)
421 digest = fetched_digest;
422 else
423 digest = EVP_get_digestbyobj(digestoid);
424 if (digest == NULL) {
425 (void)ERR_clear_last_mark();
426 ERR_raise(ERR_LIB_CMS, CMS_R_UNKNOWN_DIGEST_ALGORITHM);
427 goto err;
428 }
429 (void)ERR_pop_to_mark();
430
431 mdbio = BIO_new(BIO_f_md());
432 if (mdbio == NULL || BIO_set_md(mdbio, digest) <= 0) {
433 ERR_raise(ERR_LIB_CMS, CMS_R_MD_BIO_INIT_ERROR);
434 goto err;
435 }
436 if (EVP_MD_xof(digest)) {
437 if (EVP_MD_is_a(digest, SN_shake128))
438 xof_len = 32;
439 else if (EVP_MD_is_a(digest, SN_shake256))
440 xof_len = 64;
441 if (xof_len > 0) {
442 EVP_MD_CTX *mdctx;
443 OSSL_PARAM params[2];
444
445 if (BIO_get_md_ctx(mdbio, &mdctx) <= 0 || mdctx == NULL)
446 goto err;
447 params[0] = OSSL_PARAM_construct_size_t(OSSL_DIGEST_PARAM_XOFLEN,
448 &xof_len);
449 params[1] = OSSL_PARAM_construct_end();
450 if (!EVP_MD_CTX_set_params(mdctx, params))
451 goto err;
452 }
453 }
454 EVP_MD_free(fetched_digest);
455 return mdbio;
456 err:
457 EVP_MD_free(fetched_digest);
458 BIO_free(mdbio);
459 return NULL;
460 }
461
462 /* Locate a message digest content from a BIO chain based on SignerInfo */
463
ossl_cms_DigestAlgorithm_find_ctx(EVP_MD_CTX * mctx,BIO * chain,X509_ALGOR * mdalg)464 int ossl_cms_DigestAlgorithm_find_ctx(EVP_MD_CTX *mctx, BIO *chain,
465 X509_ALGOR *mdalg)
466 {
467 int nid;
468 const ASN1_OBJECT *mdoid;
469 X509_ALGOR_get0(&mdoid, NULL, NULL, mdalg);
470 nid = OBJ_obj2nid(mdoid);
471 /* Look for digest type to match signature */
472 for (;;) {
473 EVP_MD_CTX *mtmp;
474 chain = BIO_find_type(chain, BIO_TYPE_MD);
475 if (chain == NULL) {
476 ERR_raise(ERR_LIB_CMS, CMS_R_NO_MATCHING_DIGEST);
477 return 0;
478 }
479 BIO_get_md_ctx(chain, &mtmp);
480 if (EVP_MD_CTX_get_type(mtmp) == nid
481 /*
482 * Workaround for broken implementations that use signature
483 * algorithm OID instead of digest.
484 */
485 || EVP_MD_get_pkey_type(EVP_MD_CTX_get0_md(mtmp)) == nid)
486 return EVP_MD_CTX_copy_ex(mctx, mtmp);
487 chain = BIO_next(chain);
488 }
489 }
490
STACK_OF(CMS_CertificateChoices)491 static STACK_OF(CMS_CertificateChoices)
492 **cms_get0_certificate_choices(CMS_ContentInfo *cms)
493 {
494 switch (OBJ_obj2nid(cms->contentType)) {
495
496 case NID_pkcs7_signed:
497 return &cms->d.signedData->certificates;
498
499 case NID_pkcs7_enveloped:
500 if (cms->d.envelopedData->originatorInfo == NULL)
501 return NULL;
502 return &cms->d.envelopedData->originatorInfo->certificates;
503
504 case NID_id_smime_ct_authEnvelopedData:
505 if (cms->d.authEnvelopedData->originatorInfo == NULL)
506 return NULL;
507 return &cms->d.authEnvelopedData->originatorInfo->certificates;
508
509 default:
510 ERR_raise(ERR_LIB_CMS, CMS_R_UNSUPPORTED_CONTENT_TYPE);
511 return NULL;
512
513 }
514 }
515
CMS_add0_CertificateChoices(CMS_ContentInfo * cms)516 CMS_CertificateChoices *CMS_add0_CertificateChoices(CMS_ContentInfo *cms)
517 {
518 STACK_OF(CMS_CertificateChoices) **pcerts;
519 CMS_CertificateChoices *cch;
520
521 pcerts = cms_get0_certificate_choices(cms);
522 if (pcerts == NULL)
523 return NULL;
524 if (*pcerts == NULL)
525 *pcerts = sk_CMS_CertificateChoices_new_null();
526 if (*pcerts == NULL)
527 return NULL;
528 cch = M_ASN1_new_of(CMS_CertificateChoices);
529 if (!cch)
530 return NULL;
531 if (!sk_CMS_CertificateChoices_push(*pcerts, cch)) {
532 M_ASN1_free_of(cch, CMS_CertificateChoices);
533 return NULL;
534 }
535 return cch;
536 }
537
CMS_add0_cert(CMS_ContentInfo * cms,X509 * cert)538 int CMS_add0_cert(CMS_ContentInfo *cms, X509 *cert)
539 {
540 CMS_CertificateChoices *cch;
541 STACK_OF(CMS_CertificateChoices) **pcerts;
542 int i;
543
544 pcerts = cms_get0_certificate_choices(cms);
545 if (pcerts == NULL)
546 return 0;
547 for (i = 0; i < sk_CMS_CertificateChoices_num(*pcerts); i++) {
548 cch = sk_CMS_CertificateChoices_value(*pcerts, i);
549 if (cch->type == CMS_CERTCHOICE_CERT) {
550 if (X509_cmp(cch->d.certificate, cert) == 0) {
551 X509_free(cert);
552 return 1; /* cert already present */
553 }
554 }
555 }
556 cch = CMS_add0_CertificateChoices(cms);
557 if (!cch)
558 return 0;
559 cch->type = CMS_CERTCHOICE_CERT;
560 cch->d.certificate = cert;
561 return 1;
562 }
563
CMS_add1_cert(CMS_ContentInfo * cms,X509 * cert)564 int CMS_add1_cert(CMS_ContentInfo *cms, X509 *cert)
565 {
566 if (!X509_up_ref(cert))
567 return 0;
568 if (CMS_add0_cert(cms, cert))
569 return 1;
570 X509_free(cert);
571 return 0;
572 }
573
STACK_OF(CMS_RevocationInfoChoice)574 static STACK_OF(CMS_RevocationInfoChoice)
575 **cms_get0_revocation_choices(CMS_ContentInfo *cms)
576 {
577 switch (OBJ_obj2nid(cms->contentType)) {
578
579 case NID_pkcs7_signed:
580 return &cms->d.signedData->crls;
581
582 case NID_pkcs7_enveloped:
583 if (cms->d.envelopedData->originatorInfo == NULL)
584 return NULL;
585 return &cms->d.envelopedData->originatorInfo->crls;
586
587 case NID_id_smime_ct_authEnvelopedData:
588 if (cms->d.authEnvelopedData->originatorInfo == NULL)
589 return NULL;
590 return &cms->d.authEnvelopedData->originatorInfo->crls;
591
592 default:
593 ERR_raise(ERR_LIB_CMS, CMS_R_UNSUPPORTED_CONTENT_TYPE);
594 return NULL;
595
596 }
597 }
598
CMS_add0_RevocationInfoChoice(CMS_ContentInfo * cms)599 CMS_RevocationInfoChoice *CMS_add0_RevocationInfoChoice(CMS_ContentInfo *cms)
600 {
601 STACK_OF(CMS_RevocationInfoChoice) **pcrls;
602 CMS_RevocationInfoChoice *rch;
603
604 pcrls = cms_get0_revocation_choices(cms);
605 if (pcrls == NULL)
606 return NULL;
607 if (*pcrls == NULL)
608 *pcrls = sk_CMS_RevocationInfoChoice_new_null();
609 if (*pcrls == NULL)
610 return NULL;
611 rch = M_ASN1_new_of(CMS_RevocationInfoChoice);
612 if (rch == NULL)
613 return NULL;
614 if (!sk_CMS_RevocationInfoChoice_push(*pcrls, rch)) {
615 M_ASN1_free_of(rch, CMS_RevocationInfoChoice);
616 return NULL;
617 }
618 return rch;
619 }
620
CMS_add0_crl(CMS_ContentInfo * cms,X509_CRL * crl)621 int CMS_add0_crl(CMS_ContentInfo *cms, X509_CRL *crl)
622 {
623 CMS_RevocationInfoChoice *rch = CMS_add0_RevocationInfoChoice(cms);
624
625 if (rch == NULL)
626 return 0;
627 rch->type = CMS_REVCHOICE_CRL;
628 rch->d.crl = crl;
629 return 1;
630 }
631
CMS_add1_crl(CMS_ContentInfo * cms,X509_CRL * crl)632 int CMS_add1_crl(CMS_ContentInfo *cms, X509_CRL *crl)
633 {
634 if (!X509_CRL_up_ref(crl))
635 return 0;
636 if (CMS_add0_crl(cms, crl))
637 return 1;
638 X509_CRL_free(crl);
639 return 0;
640 }
641
STACK_OF(X509)642 STACK_OF(X509) *CMS_get1_certs(CMS_ContentInfo *cms)
643 {
644 STACK_OF(X509) *certs = NULL;
645
646 if (!ossl_cms_get1_certs_ex(cms, &certs))
647 return NULL;
648 if (sk_X509_num(certs) == 0) {
649 sk_X509_free(certs);
650 return NULL;
651 }
652 return certs;
653 }
654
ossl_cms_get1_certs_ex(CMS_ContentInfo * cms,STACK_OF (X509)** certs)655 int ossl_cms_get1_certs_ex(CMS_ContentInfo *cms, STACK_OF(X509) **certs)
656 {
657 CMS_CertificateChoices *cch;
658 STACK_OF(CMS_CertificateChoices) **pcerts;
659 int i, n;
660
661 if (certs == NULL)
662 return 0;
663 *certs = NULL;
664 pcerts = cms_get0_certificate_choices(cms);
665 if (pcerts == NULL)
666 return 0;
667
668 /* make sure to return NULL *certs only on error */
669 n = sk_CMS_CertificateChoices_num(*pcerts);
670 if ((*certs = sk_X509_new_reserve(NULL, n)) == NULL)
671 return 0;
672
673 for (i = 0; i < n; i++) {
674 cch = sk_CMS_CertificateChoices_value(*pcerts, i);
675 if (cch->type == 0) {
676 if (!X509_add_cert(*certs, cch->d.certificate,
677 X509_ADD_FLAG_UP_REF)) {
678 OSSL_STACK_OF_X509_free(*certs);
679 *certs = NULL;
680 return 0;
681 }
682 }
683 }
684 return 1;
685 }
686
STACK_OF(X509_CRL)687 STACK_OF(X509_CRL) *CMS_get1_crls(CMS_ContentInfo *cms)
688 {
689 STACK_OF(X509_CRL) *crls = NULL;
690
691 if (!ossl_cms_get1_crls_ex(cms, &crls))
692 return NULL;
693 if (sk_X509_CRL_num(crls) == 0) {
694 sk_X509_CRL_free(crls);
695 return NULL;
696 }
697 return crls;
698 }
699
ossl_cms_get1_crls_ex(CMS_ContentInfo * cms,STACK_OF (X509_CRL)** crls)700 int ossl_cms_get1_crls_ex(CMS_ContentInfo *cms, STACK_OF(X509_CRL) **crls)
701 {
702 STACK_OF(CMS_RevocationInfoChoice) **pcrls;
703 CMS_RevocationInfoChoice *rch;
704 int i, n;
705
706 if (crls == NULL)
707 return 0;
708 *crls = NULL;
709 pcrls = cms_get0_revocation_choices(cms);
710 if (pcrls == NULL)
711 return 0;
712
713 /* make sure to return NULL *crls only on error */
714 n = sk_CMS_RevocationInfoChoice_num(*pcrls);
715 if ((*crls = sk_X509_CRL_new_reserve(NULL, n)) == NULL)
716 return 0;
717
718 for (i = 0; i < n; i++) {
719 rch = sk_CMS_RevocationInfoChoice_value(*pcrls, i);
720 if (rch->type == 0) {
721 if (!X509_CRL_up_ref(rch->d.crl)
722 || !ossl_assert(sk_X509_CRL_push(*crls, rch->d.crl))) {
723 /* push cannot fail on reserved stack */
724 sk_X509_CRL_pop_free(*crls, X509_CRL_free);
725 *crls = NULL;
726 return 0;
727 }
728 }
729 }
730 return 1;
731 }
732
ossl_cms_ias_cert_cmp(CMS_IssuerAndSerialNumber * ias,X509 * cert)733 int ossl_cms_ias_cert_cmp(CMS_IssuerAndSerialNumber *ias, X509 *cert)
734 {
735 int ret;
736 ret = X509_NAME_cmp(ias->issuer, X509_get_issuer_name(cert));
737 if (ret)
738 return ret;
739 return ASN1_INTEGER_cmp(ias->serialNumber, X509_get0_serialNumber(cert));
740 }
741
ossl_cms_keyid_cert_cmp(ASN1_OCTET_STRING * keyid,X509 * cert)742 int ossl_cms_keyid_cert_cmp(ASN1_OCTET_STRING *keyid, X509 *cert)
743 {
744 const ASN1_OCTET_STRING *cert_keyid = X509_get0_subject_key_id(cert);
745
746 if (cert_keyid == NULL)
747 return -1;
748 return ASN1_OCTET_STRING_cmp(keyid, cert_keyid);
749 }
750
ossl_cms_set1_ias(CMS_IssuerAndSerialNumber ** pias,X509 * cert)751 int ossl_cms_set1_ias(CMS_IssuerAndSerialNumber **pias, X509 *cert)
752 {
753 CMS_IssuerAndSerialNumber *ias;
754 ias = M_ASN1_new_of(CMS_IssuerAndSerialNumber);
755 if (!ias) {
756 ERR_raise(ERR_LIB_CMS, ERR_R_ASN1_LIB);
757 goto err;
758 }
759 if (!X509_NAME_set(&ias->issuer, X509_get_issuer_name(cert))) {
760 ERR_raise(ERR_LIB_CMS, ERR_R_X509_LIB);
761 goto err;
762 }
763 if (!ASN1_STRING_copy(ias->serialNumber, X509_get0_serialNumber(cert))) {
764 ERR_raise(ERR_LIB_CMS, ERR_R_ASN1_LIB);
765 goto err;
766 }
767 M_ASN1_free_of(*pias, CMS_IssuerAndSerialNumber);
768 *pias = ias;
769 return 1;
770 err:
771 M_ASN1_free_of(ias, CMS_IssuerAndSerialNumber);
772 return 0;
773 }
774
ossl_cms_set1_keyid(ASN1_OCTET_STRING ** pkeyid,X509 * cert)775 int ossl_cms_set1_keyid(ASN1_OCTET_STRING **pkeyid, X509 *cert)
776 {
777 ASN1_OCTET_STRING *keyid = NULL;
778 const ASN1_OCTET_STRING *cert_keyid;
779 cert_keyid = X509_get0_subject_key_id(cert);
780 if (cert_keyid == NULL) {
781 ERR_raise(ERR_LIB_CMS, CMS_R_CERTIFICATE_HAS_NO_KEYID);
782 return 0;
783 }
784 keyid = ASN1_STRING_dup(cert_keyid);
785 if (!keyid) {
786 ERR_raise(ERR_LIB_CMS, ERR_R_ASN1_LIB);
787 return 0;
788 }
789 ASN1_OCTET_STRING_free(*pkeyid);
790 *pkeyid = keyid;
791 return 1;
792 }
793
ossl_cms_sign_encrypt(BIO * data,X509 * sign_cert,STACK_OF (X509)* certs,EVP_PKEY * sign_key,unsigned int sign_flags,STACK_OF (X509)* enc_recip,const EVP_CIPHER * cipher,unsigned int enc_flags,OSSL_LIB_CTX * libctx,const char * propq)794 CMS_EnvelopedData *ossl_cms_sign_encrypt(BIO *data, X509 *sign_cert, STACK_OF(X509) *certs,
795 EVP_PKEY *sign_key, unsigned int sign_flags,
796 STACK_OF(X509) *enc_recip, const EVP_CIPHER *cipher,
797 unsigned int enc_flags, OSSL_LIB_CTX *libctx,
798 const char *propq)
799 {
800 CMS_EnvelopedData *evd = NULL;
801 BIO *privbio = NULL, *signbio = NULL;
802 CMS_ContentInfo *signcms = NULL, *evpcms = NULL;
803
804 if (data == NULL || sign_key == NULL || sign_cert == NULL || enc_recip == NULL) {
805 ERR_raise(ERR_LIB_CMS, ERR_R_PASSED_NULL_PARAMETER);
806 return NULL;
807 }
808 signcms = CMS_sign_ex(sign_cert, sign_key, certs, data, sign_flags, libctx, propq);
809 if (signcms == NULL)
810 goto err;
811
812 signbio = BIO_new(BIO_s_mem());
813 if (signbio == NULL
814 || ASN1_item_i2d_bio(ASN1_ITEM_rptr(CMS_SignedData), signbio, signcms->d.signedData) <= 0)
815 goto err;
816
817 evpcms = CMS_encrypt_ex(enc_recip, signbio, cipher, enc_flags, libctx, propq);
818 if (evpcms == NULL)
819 goto err;
820 evd = CMS_EnvelopedData_dup(evpcms->d.envelopedData);
821
822 err:
823 BIO_free(privbio);
824 BIO_free(signbio);
825 CMS_ContentInfo_free(signcms);
826 CMS_ContentInfo_free(evpcms);
827
828 return evd;
829 }
830