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