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