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