summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/cms/cms_lib.c
diff options
context:
space:
mode:
authorcvs2svn <admin@example.com>2025-04-14 17:32:06 +0000
committercvs2svn <admin@example.com>2025-04-14 17:32:06 +0000
commiteb8dd9dca1228af0cd132f515509051ecfabf6f6 (patch)
treeedb6da6af7e865d488dc1a29309f1e1ec226e603 /src/lib/libcrypto/cms/cms_lib.c
parent247f0352e0ed72a4f476db9dc91f4d982bc83eb2 (diff)
downloadopenbsd-tb_20250414.tar.gz
openbsd-tb_20250414.tar.bz2
openbsd-tb_20250414.zip
This commit was manufactured by cvs2git to create tag 'tb_20250414'.tb_20250414
Diffstat (limited to 'src/lib/libcrypto/cms/cms_lib.c')
-rw-r--r--src/lib/libcrypto/cms/cms_lib.c780
1 files changed, 0 insertions, 780 deletions
diff --git a/src/lib/libcrypto/cms/cms_lib.c b/src/lib/libcrypto/cms/cms_lib.c
deleted file mode 100644
index 2d7a8d9f21..0000000000
--- a/src/lib/libcrypto/cms/cms_lib.c
+++ /dev/null
@@ -1,780 +0,0 @@
1/* $OpenBSD: cms_lib.c,v 1.26 2024/11/01 18:53:35 tb Exp $ */
2/*
3 * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
4 * project.
5 */
6/* ====================================================================
7 * Copyright (c) 2008 The OpenSSL Project. All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 *
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 *
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in
18 * the documentation and/or other materials provided with the
19 * distribution.
20 *
21 * 3. All advertising materials mentioning features or use of this
22 * software must display the following acknowledgment:
23 * "This product includes software developed by the OpenSSL Project
24 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
25 *
26 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
27 * endorse or promote products derived from this software without
28 * prior written permission. For written permission, please contact
29 * licensing@OpenSSL.org.
30 *
31 * 5. Products derived from this software may not be called "OpenSSL"
32 * nor may "OpenSSL" appear in their names without prior written
33 * permission of the OpenSSL Project.
34 *
35 * 6. Redistributions of any form whatsoever must retain the following
36 * acknowledgment:
37 * "This product includes software developed by the OpenSSL Project
38 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
39 *
40 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
41 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
43 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
44 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
46 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
47 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
49 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
50 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
51 * OF THE POSSIBILITY OF SUCH DAMAGE.
52 * ====================================================================
53 */
54
55#include <stddef.h>
56
57#include <openssl/asn1.h>
58#include <openssl/bio.h>
59#include <openssl/cms.h>
60#include <openssl/err.h>
61#include <openssl/evp.h>
62#include <openssl/objects.h>
63#include <openssl/x509.h>
64#include <openssl/x509v3.h>
65
66#include "cms_local.h"
67#include "x509_local.h"
68
69CMS_ContentInfo *
70d2i_CMS_ContentInfo(CMS_ContentInfo **a, const unsigned char **in, long len)
71{
72 return (CMS_ContentInfo *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
73 &CMS_ContentInfo_it);
74}
75LCRYPTO_ALIAS(d2i_CMS_ContentInfo);
76
77int
78i2d_CMS_ContentInfo(CMS_ContentInfo *a, unsigned char **out)
79{
80 return ASN1_item_i2d((ASN1_VALUE *)a, out, &CMS_ContentInfo_it);
81}
82LCRYPTO_ALIAS(i2d_CMS_ContentInfo);
83
84CMS_ContentInfo *
85CMS_ContentInfo_new(void)
86{
87 return (CMS_ContentInfo *)ASN1_item_new(&CMS_ContentInfo_it);
88}
89LCRYPTO_ALIAS(CMS_ContentInfo_new);
90
91void
92CMS_ContentInfo_free(CMS_ContentInfo *a)
93{
94 ASN1_item_free((ASN1_VALUE *)a, &CMS_ContentInfo_it);
95}
96LCRYPTO_ALIAS(CMS_ContentInfo_free);
97
98int
99CMS_ContentInfo_print_ctx(BIO *out, CMS_ContentInfo *x, int indent, const ASN1_PCTX *pctx)
100{
101 return ASN1_item_print(out, (ASN1_VALUE *)x, indent,
102 &CMS_ContentInfo_it, pctx);
103}
104LCRYPTO_ALIAS(CMS_ContentInfo_print_ctx);
105
106const ASN1_OBJECT *
107CMS_get0_type(const CMS_ContentInfo *cms)
108{
109 return cms->contentType;
110}
111LCRYPTO_ALIAS(CMS_get0_type);
112
113CMS_ContentInfo *
114cms_Data_create(void)
115{
116 CMS_ContentInfo *cms;
117
118 cms = CMS_ContentInfo_new();
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
127static BIO *
128cms_content_bio(CMS_ContentInfo *cms)
129{
130 ASN1_OCTET_STRING **pos;
131
132 if ((pos = CMS_get0_content(cms)) == NULL)
133 return NULL;
134
135 /* If content is detached, data goes nowhere: create null BIO. */
136 if (*pos == NULL)
137 return BIO_new(BIO_s_null());
138
139 /* If content is not detached and was created, return memory BIO. */
140 if ((*pos)->flags == ASN1_STRING_FLAG_CONT)
141 return BIO_new(BIO_s_mem());
142
143 /* Else content was read in: return read-only BIO for it. */
144 return BIO_new_mem_buf((*pos)->data, (*pos)->length);
145}
146
147BIO *
148CMS_dataInit(CMS_ContentInfo *cms, BIO *in_content_bio)
149{
150 BIO *cms_bio = NULL, *content_bio = NULL;
151
152 if ((content_bio = in_content_bio) == NULL)
153 content_bio = cms_content_bio(cms);
154 if (content_bio == NULL) {
155 CMSerror(CMS_R_NO_CONTENT);
156 goto err;
157 }
158
159 switch (OBJ_obj2nid(cms->contentType)) {
160 case NID_pkcs7_data:
161 return content_bio;
162 case NID_pkcs7_signed:
163 if ((cms_bio = cms_SignedData_init_bio(cms)) == NULL)
164 goto err;
165 break;
166 case NID_pkcs7_digest:
167 if ((cms_bio = cms_DigestedData_init_bio(cms)) == NULL)
168 goto err;
169 break;
170 case NID_pkcs7_encrypted:
171 if ((cms_bio = cms_EncryptedData_init_bio(cms)) == NULL)
172 goto err;
173 break;
174 case NID_pkcs7_enveloped:
175 if ((cms_bio = cms_EnvelopedData_init_bio(cms)) == NULL)
176 goto err;
177 break;
178 default:
179 CMSerror(CMS_R_UNSUPPORTED_TYPE);
180 goto err;
181 }
182
183 return BIO_push(cms_bio, content_bio);
184
185 err:
186 if (content_bio != in_content_bio)
187 BIO_free(content_bio);
188
189 return NULL;
190}
191LCRYPTO_ALIAS(CMS_dataInit);
192
193int
194CMS_dataFinal(CMS_ContentInfo *cms, BIO *cmsbio)
195{
196 ASN1_OCTET_STRING **pos = CMS_get0_content(cms);
197
198 if (!pos)
199 return 0;
200 /* If embedded content find memory BIO and set content */
201 if (*pos && ((*pos)->flags & ASN1_STRING_FLAG_CONT)) {
202 BIO *mbio;
203 unsigned char *cont;
204 long contlen;
205 mbio = BIO_find_type(cmsbio, BIO_TYPE_MEM);
206 if (!mbio) {
207 CMSerror(CMS_R_CONTENT_NOT_FOUND);
208 return 0;
209 }
210 contlen = BIO_get_mem_data(mbio, &cont);
211 /* Set bio as read only so its content can't be clobbered */
212 BIO_set_flags(mbio, BIO_FLAGS_MEM_RDONLY);
213 BIO_set_mem_eof_return(mbio, 0);
214 ASN1_STRING_set0(*pos, cont, contlen);
215 (*pos)->flags &= ~ASN1_STRING_FLAG_CONT;
216 }
217
218 switch (OBJ_obj2nid(cms->contentType)) {
219
220 case NID_pkcs7_data:
221 case NID_pkcs7_enveloped:
222 case NID_pkcs7_encrypted:
223 case NID_id_smime_ct_compressedData:
224 /* Nothing to do */
225 return 1;
226
227 case NID_pkcs7_signed:
228 return cms_SignedData_final(cms, cmsbio);
229
230 case NID_pkcs7_digest:
231 return cms_DigestedData_do_final(cms, cmsbio, 0);
232
233 default:
234 CMSerror(CMS_R_UNSUPPORTED_TYPE);
235 return 0;
236 }
237}
238LCRYPTO_ALIAS(CMS_dataFinal);
239
240int
241CMS_get_version(const CMS_ContentInfo *cms, long *version)
242{
243 switch (OBJ_obj2nid(cms->contentType)) {
244 case NID_pkcs7_signed:
245 *version = cms->d.signedData->version;
246 return 1;
247
248 case NID_pkcs7_enveloped:
249 *version = cms->d.envelopedData->version;
250 return 1;
251
252 case NID_pkcs7_digest:
253 *version = cms->d.digestedData->version;
254 return 1;
255
256 case NID_pkcs7_encrypted:
257 *version = cms->d.encryptedData->version;
258 return 1;
259
260 case NID_id_smime_ct_authData:
261 *version = cms->d.authenticatedData->version;
262 return 1;
263
264 case NID_id_smime_ct_compressedData:
265 *version = cms->d.compressedData->version;
266 return 1;
267
268 default:
269 CMSerror(CMS_R_UNSUPPORTED_TYPE);
270 return 0;
271 }
272}
273LCRYPTO_ALIAS(CMS_get_version);
274
275int
276CMS_SignerInfo_get_version(const CMS_SignerInfo *si, long *version)
277{
278 *version = si->version;
279 return 1;
280}
281LCRYPTO_ALIAS(CMS_SignerInfo_get_version);
282
283/*
284 * Return an OCTET STRING pointer to content. This allows it to be accessed
285 * or set later.
286 */
287
288ASN1_OCTET_STRING **
289CMS_get0_content(CMS_ContentInfo *cms)
290{
291 switch (OBJ_obj2nid(cms->contentType)) {
292 case NID_pkcs7_data:
293 return &cms->d.data;
294
295 case NID_pkcs7_signed:
296 return &cms->d.signedData->encapContentInfo->eContent;
297
298 case NID_pkcs7_enveloped:
299 return &cms->d.envelopedData->encryptedContentInfo->encryptedContent;
300
301 case NID_pkcs7_digest:
302 return &cms->d.digestedData->encapContentInfo->eContent;
303
304 case NID_pkcs7_encrypted:
305 return &cms->d.encryptedData->encryptedContentInfo->encryptedContent;
306
307 case NID_id_smime_ct_authData:
308 return &cms->d.authenticatedData->encapContentInfo->eContent;
309
310 case NID_id_smime_ct_compressedData:
311 return &cms->d.compressedData->encapContentInfo->eContent;
312
313 default:
314 if (cms->d.other->type == V_ASN1_OCTET_STRING)
315 return &cms->d.other->value.octet_string;
316 CMSerror(CMS_R_UNSUPPORTED_CONTENT_TYPE);
317 return NULL;
318 }
319}
320LCRYPTO_ALIAS(CMS_get0_content);
321
322/*
323 * Return an ASN1_OBJECT pointer to content type. This allows it to be
324 * accessed or set later.
325 */
326
327static ASN1_OBJECT **
328cms_get0_econtent_type(CMS_ContentInfo *cms)
329{
330 switch (OBJ_obj2nid(cms->contentType)) {
331 case NID_pkcs7_signed:
332 return &cms->d.signedData->encapContentInfo->eContentType;
333
334 case NID_pkcs7_enveloped:
335 return &cms->d.envelopedData->encryptedContentInfo->contentType;
336
337 case NID_pkcs7_digest:
338 return &cms->d.digestedData->encapContentInfo->eContentType;
339
340 case NID_pkcs7_encrypted:
341 return &cms->d.encryptedData->encryptedContentInfo->contentType;
342
343 case NID_id_smime_ct_authData:
344 return &cms->d.authenticatedData->encapContentInfo->eContentType;
345
346 case NID_id_smime_ct_compressedData:
347 return &cms->d.compressedData->encapContentInfo->eContentType;
348
349 default:
350 CMSerror(CMS_R_UNSUPPORTED_CONTENT_TYPE);
351 return NULL;
352 }
353}
354
355const ASN1_OBJECT *
356CMS_get0_eContentType(CMS_ContentInfo *cms)
357{
358 ASN1_OBJECT **petype;
359
360 petype = cms_get0_econtent_type(cms);
361 if (petype)
362 return *petype;
363
364 return NULL;
365}
366LCRYPTO_ALIAS(CMS_get0_eContentType);
367
368int
369CMS_set1_eContentType(CMS_ContentInfo *cms, const ASN1_OBJECT *oid)
370{
371 ASN1_OBJECT **petype, *etype;
372
373 petype = cms_get0_econtent_type(cms);
374 if (!petype)
375 return 0;
376 if (!oid)
377 return 1;
378 etype = OBJ_dup(oid);
379 if (!etype)
380 return 0;
381 ASN1_OBJECT_free(*petype);
382 *petype = etype;
383
384 return 1;
385}
386LCRYPTO_ALIAS(CMS_set1_eContentType);
387
388int
389CMS_is_detached(CMS_ContentInfo *cms)
390{
391 ASN1_OCTET_STRING **pos;
392
393 pos = CMS_get0_content(cms);
394 if (!pos)
395 return -1;
396 if (*pos)
397 return 0;
398
399 return 1;
400}
401LCRYPTO_ALIAS(CMS_is_detached);
402
403int
404CMS_set_detached(CMS_ContentInfo *cms, int detached)
405{
406 ASN1_OCTET_STRING **pos;
407
408 pos = CMS_get0_content(cms);
409 if (!pos)
410 return 0;
411 if (detached) {
412 ASN1_OCTET_STRING_free(*pos);
413 *pos = NULL;
414 return 1;
415 }
416 if (*pos == NULL)
417 *pos = ASN1_OCTET_STRING_new();
418 if (*pos != NULL) {
419 /*
420 * NB: special flag to show content is created and not read in.
421 */
422 (*pos)->flags |= ASN1_STRING_FLAG_CONT;
423 return 1;
424 }
425 CMSerror(ERR_R_MALLOC_FAILURE);
426
427 return 0;
428}
429LCRYPTO_ALIAS(CMS_set_detached);
430
431/* Create a digest BIO from an X509_ALGOR structure */
432
433BIO *
434cms_DigestAlgorithm_init_bio(X509_ALGOR *digestAlgorithm)
435{
436 BIO *mdbio = NULL;
437 const ASN1_OBJECT *digestoid;
438 const EVP_MD *digest;
439
440 X509_ALGOR_get0(&digestoid, NULL, NULL, digestAlgorithm);
441 digest = EVP_get_digestbyobj(digestoid);
442 if (!digest) {
443 CMSerror(CMS_R_UNKNOWN_DIGEST_ALGORITHM);
444 goto err;
445 }
446 mdbio = BIO_new(BIO_f_md());
447 if (mdbio == NULL || !BIO_set_md(mdbio, digest)) {
448 CMSerror(CMS_R_MD_BIO_INIT_ERROR);
449 goto err;
450 }
451 return mdbio;
452
453 err:
454 BIO_free(mdbio);
455
456 return NULL;
457}
458
459/* Locate a message digest content from a BIO chain based on SignerInfo */
460
461int
462cms_DigestAlgorithm_find_ctx(EVP_MD_CTX *mctx, BIO *chain, X509_ALGOR *mdalg)
463{
464 int nid;
465 const ASN1_OBJECT *mdoid;
466
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 CMSerror(CMS_R_NO_MATCHING_DIGEST);
475 return 0;
476 }
477 BIO_get_md_ctx(chain, &mtmp);
478 if (EVP_MD_CTX_type(mtmp) == nid
479 /*
480 * Workaround for broken implementations that use signature
481 * algorithm OID instead of digest.
482 */
483 || EVP_MD_pkey_type(EVP_MD_CTX_md(mtmp)) == nid)
484 return EVP_MD_CTX_copy_ex(mctx, mtmp);
485 chain = BIO_next(chain);
486 }
487}
488
489static STACK_OF(CMS_CertificateChoices) **
490cms_get0_certificate_choices(CMS_ContentInfo *cms)
491{
492 switch (OBJ_obj2nid(cms->contentType)) {
493 case NID_pkcs7_signed:
494 return &cms->d.signedData->certificates;
495
496 case NID_pkcs7_enveloped:
497 if (cms->d.envelopedData->originatorInfo == NULL)
498 return NULL;
499 return &cms->d.envelopedData->originatorInfo->certificates;
500
501 default:
502 CMSerror(CMS_R_UNSUPPORTED_CONTENT_TYPE);
503 return NULL;
504 }
505}
506
507CMS_CertificateChoices *
508CMS_add0_CertificateChoices(CMS_ContentInfo *cms)
509{
510 STACK_OF(CMS_CertificateChoices) **pcerts;
511 CMS_CertificateChoices *cch;
512
513 pcerts = cms_get0_certificate_choices(cms);
514 if (!pcerts)
515 return NULL;
516 if (!*pcerts)
517 *pcerts = sk_CMS_CertificateChoices_new_null();
518 if (!*pcerts)
519 return NULL;
520 cch = (CMS_CertificateChoices *)ASN1_item_new(&CMS_CertificateChoices_it);
521 if (!cch)
522 return NULL;
523 if (!sk_CMS_CertificateChoices_push(*pcerts, cch)) {
524 ASN1_item_free((ASN1_VALUE *)cch, &CMS_CertificateChoices_it);
525 return NULL;
526 }
527
528 return cch;
529}
530LCRYPTO_ALIAS(CMS_add0_CertificateChoices);
531
532int
533CMS_add0_cert(CMS_ContentInfo *cms, X509 *cert)
534{
535 CMS_CertificateChoices *cch;
536 STACK_OF(CMS_CertificateChoices) **pcerts;
537 int i;
538
539 pcerts = cms_get0_certificate_choices(cms);
540 if (!pcerts)
541 return 0;
542 for (i = 0; i < sk_CMS_CertificateChoices_num(*pcerts); i++) {
543 cch = sk_CMS_CertificateChoices_value(*pcerts, i);
544 if (cch->type == CMS_CERTCHOICE_CERT) {
545 if (!X509_cmp(cch->d.certificate, cert)) {
546 CMSerror(CMS_R_CERTIFICATE_ALREADY_PRESENT);
547 return 0;
548 }
549 }
550 }
551 cch = CMS_add0_CertificateChoices(cms);
552 if (!cch)
553 return 0;
554 cch->type = CMS_CERTCHOICE_CERT;
555 cch->d.certificate = cert;
556
557 return 1;
558}
559LCRYPTO_ALIAS(CMS_add0_cert);
560
561int
562CMS_add1_cert(CMS_ContentInfo *cms, X509 *cert)
563{
564 int r;
565
566 r = CMS_add0_cert(cms, cert);
567 if (r > 0)
568 X509_up_ref(cert);
569
570 return r;
571}
572LCRYPTO_ALIAS(CMS_add1_cert);
573
574static STACK_OF(CMS_RevocationInfoChoice) **
575cms_get0_revocation_choices(CMS_ContentInfo *cms)
576{
577 switch (OBJ_obj2nid(cms->contentType)) {
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 default:
587 CMSerror(CMS_R_UNSUPPORTED_CONTENT_TYPE);
588 return NULL;
589 }
590}
591
592CMS_RevocationInfoChoice *
593CMS_add0_RevocationInfoChoice(CMS_ContentInfo *cms)
594{
595 STACK_OF(CMS_RevocationInfoChoice) **pcrls;
596 CMS_RevocationInfoChoice *rch;
597
598 pcrls = cms_get0_revocation_choices(cms);
599 if (!pcrls)
600 return NULL;
601 if (!*pcrls)
602 *pcrls = sk_CMS_RevocationInfoChoice_new_null();
603 if (!*pcrls)
604 return NULL;
605 rch = (CMS_RevocationInfoChoice *)ASN1_item_new(&CMS_RevocationInfoChoice_it);
606 if (!rch)
607 return NULL;
608 if (!sk_CMS_RevocationInfoChoice_push(*pcrls, rch)) {
609 ASN1_item_free((ASN1_VALUE *)rch, &CMS_RevocationInfoChoice_it);
610 return NULL;
611 }
612
613 return rch;
614}
615LCRYPTO_ALIAS(CMS_add0_RevocationInfoChoice);
616
617int
618CMS_add0_crl(CMS_ContentInfo *cms, X509_CRL *crl)
619{
620 CMS_RevocationInfoChoice *rch;
621
622 rch = CMS_add0_RevocationInfoChoice(cms);
623 if (!rch)
624 return 0;
625 rch->type = CMS_REVCHOICE_CRL;
626 rch->d.crl = crl;
627
628 return 1;
629}
630LCRYPTO_ALIAS(CMS_add0_crl);
631
632int
633CMS_add1_crl(CMS_ContentInfo *cms, X509_CRL *crl)
634{
635 int r;
636
637 r = CMS_add0_crl(cms, crl);
638 if (r > 0)
639 X509_CRL_up_ref(crl);
640
641 return r;
642}
643LCRYPTO_ALIAS(CMS_add1_crl);
644
645STACK_OF(X509) *
646CMS_get1_certs(CMS_ContentInfo *cms)
647{
648 STACK_OF(X509) *certs = NULL;
649 CMS_CertificateChoices *cch;
650 STACK_OF(CMS_CertificateChoices) **pcerts;
651 int i;
652
653 pcerts = cms_get0_certificate_choices(cms);
654 if (!pcerts)
655 return NULL;
656 for (i = 0; i < sk_CMS_CertificateChoices_num(*pcerts); i++) {
657 cch = sk_CMS_CertificateChoices_value(*pcerts, i);
658 if (cch->type == 0) {
659 if (!certs) {
660 certs = sk_X509_new_null();
661 if (!certs)
662 return NULL;
663 }
664 if (!sk_X509_push(certs, cch->d.certificate)) {
665 sk_X509_pop_free(certs, X509_free);
666 return NULL;
667 }
668 X509_up_ref(cch->d.certificate);
669 }
670 }
671 return certs;
672}
673LCRYPTO_ALIAS(CMS_get1_certs);
674
675STACK_OF(X509_CRL) *
676CMS_get1_crls(CMS_ContentInfo *cms)
677{
678 STACK_OF(X509_CRL) *crls = NULL;
679 STACK_OF(CMS_RevocationInfoChoice) **pcrls;
680 CMS_RevocationInfoChoice *rch;
681 int i;
682
683 pcrls = cms_get0_revocation_choices(cms);
684 if (!pcrls)
685 return NULL;
686 for (i = 0; i < sk_CMS_RevocationInfoChoice_num(*pcrls); i++) {
687 rch = sk_CMS_RevocationInfoChoice_value(*pcrls, i);
688 if (rch->type == 0) {
689 if (!crls) {
690 crls = sk_X509_CRL_new_null();
691 if (!crls)
692 return NULL;
693 }
694 if (!sk_X509_CRL_push(crls, rch->d.crl)) {
695 sk_X509_CRL_pop_free(crls, X509_CRL_free);
696 return NULL;
697 }
698 X509_CRL_up_ref(rch->d.crl);
699 }
700 }
701 return crls;
702}
703LCRYPTO_ALIAS(CMS_get1_crls);
704
705static const ASN1_OCTET_STRING *
706cms_X509_get0_subject_key_id(X509 *x)
707{
708 /* Call for side-effect of computing hash and caching extensions */
709 X509_check_purpose(x, -1, -1);
710 return x->skid;
711}
712
713int
714cms_ias_cert_cmp(CMS_IssuerAndSerialNumber *ias, X509 *cert)
715{
716 int ret;
717
718 ret = X509_NAME_cmp(ias->issuer, X509_get_issuer_name(cert));
719 if (ret)
720 return ret;
721
722 return ASN1_INTEGER_cmp(ias->serialNumber, X509_get_serialNumber(cert));
723}
724
725int
726cms_keyid_cert_cmp(ASN1_OCTET_STRING *keyid, X509 *cert)
727{
728 const ASN1_OCTET_STRING *cert_keyid = cms_X509_get0_subject_key_id(cert);
729
730 if (cert_keyid == NULL)
731 return -1;
732
733 return ASN1_OCTET_STRING_cmp(keyid, cert_keyid);
734}
735
736int
737cms_set1_ias(CMS_IssuerAndSerialNumber **pias, X509 *cert)
738{
739 CMS_IssuerAndSerialNumber *ias;
740
741 ias = (CMS_IssuerAndSerialNumber *)ASN1_item_new(&CMS_IssuerAndSerialNumber_it);
742 if (!ias)
743 goto err;
744 if (!X509_NAME_set(&ias->issuer, X509_get_issuer_name(cert)))
745 goto err;
746 if (!ASN1_STRING_copy(ias->serialNumber, X509_get_serialNumber(cert)))
747 goto err;
748 ASN1_item_free((ASN1_VALUE *)*pias, &CMS_IssuerAndSerialNumber_it);
749 *pias = ias;
750
751 return 1;
752
753 err:
754 ASN1_item_free((ASN1_VALUE *)ias, &CMS_IssuerAndSerialNumber_it);
755 CMSerror(ERR_R_MALLOC_FAILURE);
756
757 return 0;
758}
759
760int
761cms_set1_keyid(ASN1_OCTET_STRING **pkeyid, X509 *cert)
762{
763 ASN1_OCTET_STRING *keyid = NULL;
764 const ASN1_OCTET_STRING *cert_keyid;
765
766 cert_keyid = cms_X509_get0_subject_key_id(cert);
767 if (cert_keyid == NULL) {
768 CMSerror(CMS_R_CERTIFICATE_HAS_NO_KEYID);
769 return 0;
770 }
771 keyid = ASN1_STRING_dup(cert_keyid);
772 if (!keyid) {
773 CMSerror(ERR_R_MALLOC_FAILURE);
774 return 0;
775 }
776 ASN1_OCTET_STRING_free(*pkeyid);
777 *pkeyid = keyid;
778
779 return 1;
780}