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