Coverage Report

Created: 2022-11-30 06:20

/src/openssl/crypto/cms/cms_lib.c
Line
Count
Source (jump to first uncovered line)
1
/* crypto/cms/cms_lib.c */
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 <openssl/asn1t.h>
56
#include <openssl/x509v3.h>
57
#include <openssl/err.h>
58
#include <openssl/pem.h>
59
#include <openssl/bio.h>
60
#include <openssl/asn1.h>
61
#include "cms.h"
62
#include "cms_lcl.h"
63
64
IMPLEMENT_ASN1_FUNCTIONS(CMS_ContentInfo)
65
IMPLEMENT_ASN1_PRINT_FUNCTION(CMS_ContentInfo)
66
67
DECLARE_ASN1_ITEM(CMS_CertificateChoices)
68
DECLARE_ASN1_ITEM(CMS_RevocationInfoChoice)
69
DECLARE_STACK_OF(CMS_CertificateChoices)
70
DECLARE_STACK_OF(CMS_RevocationInfoChoice)
71
72
const ASN1_OBJECT *CMS_get0_type(CMS_ContentInfo *cms)
73
0
{
74
0
    return cms->contentType;
75
0
}
76
77
CMS_ContentInfo *cms_Data_create(void)
78
0
{
79
0
    CMS_ContentInfo *cms;
80
0
    cms = CMS_ContentInfo_new();
81
0
    if (cms) {
82
0
        cms->contentType = OBJ_nid2obj(NID_pkcs7_data);
83
        /* Never detached */
84
0
        CMS_set_detached(cms, 0);
85
0
    }
86
0
    return cms;
87
0
}
88
89
BIO *cms_content_bio(CMS_ContentInfo *cms)
90
0
{
91
0
    ASN1_OCTET_STRING **pos = CMS_get0_content(cms);
92
0
    if (!pos)
93
0
        return NULL;
94
    /* If content detached data goes nowhere: create NULL BIO */
95
0
    if (!*pos)
96
0
        return BIO_new(BIO_s_null());
97
    /*
98
     * If content not detached and created return memory BIO
99
     */
100
0
    if (!*pos || ((*pos)->flags == ASN1_STRING_FLAG_CONT))
101
0
        return BIO_new(BIO_s_mem());
102
    /* Else content was read in: return read only BIO for it */
103
0
    return BIO_new_mem_buf((*pos)->data, (*pos)->length);
104
0
}
105
106
BIO *CMS_dataInit(CMS_ContentInfo *cms, BIO *icont)
107
0
{
108
0
    BIO *cmsbio, *cont;
109
0
    if (icont)
110
0
        cont = icont;
111
0
    else
112
0
        cont = cms_content_bio(cms);
113
0
    if (!cont) {
114
0
        CMSerr(CMS_F_CMS_DATAINIT, CMS_R_NO_CONTENT);
115
0
        return NULL;
116
0
    }
117
0
    switch (OBJ_obj2nid(cms->contentType)) {
118
119
0
    case NID_pkcs7_data:
120
0
        return cont;
121
122
0
    case NID_pkcs7_signed:
123
0
        cmsbio = cms_SignedData_init_bio(cms);
124
0
        break;
125
126
0
    case NID_pkcs7_digest:
127
0
        cmsbio = cms_DigestedData_init_bio(cms);
128
0
        break;
129
#ifdef ZLIB
130
    case NID_id_smime_ct_compressedData:
131
        cmsbio = cms_CompressedData_init_bio(cms);
132
        break;
133
#endif
134
135
0
    case NID_pkcs7_encrypted:
136
0
        cmsbio = cms_EncryptedData_init_bio(cms);
137
0
        break;
138
139
0
    case NID_pkcs7_enveloped:
140
0
        cmsbio = cms_EnvelopedData_init_bio(cms);
141
0
        break;
142
143
0
    default:
144
0
        CMSerr(CMS_F_CMS_DATAINIT, CMS_R_UNSUPPORTED_TYPE);
145
0
        return NULL;
146
0
    }
147
148
0
    if (cmsbio)
149
0
        return BIO_push(cmsbio, cont);
150
151
0
    if (!icont)
152
0
        BIO_free(cont);
153
0
    return NULL;
154
155
0
}
156
157
int CMS_dataFinal(CMS_ContentInfo *cms, BIO *cmsbio)
158
0
{
159
0
    ASN1_OCTET_STRING **pos = CMS_get0_content(cms);
160
0
    if (!pos)
161
0
        return 0;
162
    /* If ebmedded content find memory BIO and set content */
163
0
    if (*pos && ((*pos)->flags & ASN1_STRING_FLAG_CONT)) {
164
0
        BIO *mbio;
165
0
        unsigned char *cont;
166
0
        long contlen;
167
0
        mbio = BIO_find_type(cmsbio, BIO_TYPE_MEM);
168
0
        if (!mbio) {
169
0
            CMSerr(CMS_F_CMS_DATAFINAL, CMS_R_CONTENT_NOT_FOUND);
170
0
            return 0;
171
0
        }
172
0
        contlen = BIO_get_mem_data(mbio, &cont);
173
        /* Set bio as read only so its content can't be clobbered */
174
0
        BIO_set_flags(mbio, BIO_FLAGS_MEM_RDONLY);
175
0
        BIO_set_mem_eof_return(mbio, 0);
176
0
        ASN1_STRING_set0(*pos, cont, contlen);
177
0
        (*pos)->flags &= ~ASN1_STRING_FLAG_CONT;
178
0
    }
179
180
0
    switch (OBJ_obj2nid(cms->contentType)) {
181
182
0
    case NID_pkcs7_data:
183
0
    case NID_pkcs7_enveloped:
184
0
    case NID_pkcs7_encrypted:
185
0
    case NID_id_smime_ct_compressedData:
186
        /* Nothing to do */
187
0
        return 1;
188
189
0
    case NID_pkcs7_signed:
190
0
        return cms_SignedData_final(cms, cmsbio);
191
192
0
    case NID_pkcs7_digest:
193
0
        return cms_DigestedData_do_final(cms, cmsbio, 0);
194
195
0
    default:
196
0
        CMSerr(CMS_F_CMS_DATAFINAL, CMS_R_UNSUPPORTED_TYPE);
197
0
        return 0;
198
0
    }
199
0
}
200
201
/*
202
 * Return an OCTET STRING pointer to content. This allows it to be accessed
203
 * or set later.
204
 */
205
206
ASN1_OCTET_STRING **CMS_get0_content(CMS_ContentInfo *cms)
207
0
{
208
0
    switch (OBJ_obj2nid(cms->contentType)) {
209
210
0
    case NID_pkcs7_data:
211
0
        return &cms->d.data;
212
213
0
    case NID_pkcs7_signed:
214
0
        return &cms->d.signedData->encapContentInfo->eContent;
215
216
0
    case NID_pkcs7_enveloped:
217
0
        return &cms->d.envelopedData->encryptedContentInfo->encryptedContent;
218
219
0
    case NID_pkcs7_digest:
220
0
        return &cms->d.digestedData->encapContentInfo->eContent;
221
222
0
    case NID_pkcs7_encrypted:
223
0
        return &cms->d.encryptedData->encryptedContentInfo->encryptedContent;
224
225
0
    case NID_id_smime_ct_authData:
226
0
        return &cms->d.authenticatedData->encapContentInfo->eContent;
227
228
0
    case NID_id_smime_ct_compressedData:
229
0
        return &cms->d.compressedData->encapContentInfo->eContent;
230
231
0
    default:
232
0
        if (cms->d.other->type == V_ASN1_OCTET_STRING)
233
0
            return &cms->d.other->value.octet_string;
234
0
        CMSerr(CMS_F_CMS_GET0_CONTENT, CMS_R_UNSUPPORTED_CONTENT_TYPE);
235
0
        return NULL;
236
237
0
    }
238
0
}
239
240
/*
241
 * Return an ASN1_OBJECT pointer to content type. This allows it to be
242
 * accessed or set later.
243
 */
244
245
static ASN1_OBJECT **cms_get0_econtent_type(CMS_ContentInfo *cms)
246
0
{
247
0
    switch (OBJ_obj2nid(cms->contentType)) {
248
249
0
    case NID_pkcs7_signed:
250
0
        return &cms->d.signedData->encapContentInfo->eContentType;
251
252
0
    case NID_pkcs7_enveloped:
253
0
        return &cms->d.envelopedData->encryptedContentInfo->contentType;
254
255
0
    case NID_pkcs7_digest:
256
0
        return &cms->d.digestedData->encapContentInfo->eContentType;
257
258
0
    case NID_pkcs7_encrypted:
259
0
        return &cms->d.encryptedData->encryptedContentInfo->contentType;
260
261
0
    case NID_id_smime_ct_authData:
262
0
        return &cms->d.authenticatedData->encapContentInfo->eContentType;
263
264
0
    case NID_id_smime_ct_compressedData:
265
0
        return &cms->d.compressedData->encapContentInfo->eContentType;
266
267
0
    default:
268
0
        CMSerr(CMS_F_CMS_GET0_ECONTENT_TYPE, CMS_R_UNSUPPORTED_CONTENT_TYPE);
269
0
        return NULL;
270
271
0
    }
272
0
}
273
274
const ASN1_OBJECT *CMS_get0_eContentType(CMS_ContentInfo *cms)
275
0
{
276
0
    ASN1_OBJECT **petype;
277
0
    petype = cms_get0_econtent_type(cms);
278
0
    if (petype)
279
0
        return *petype;
280
0
    return NULL;
281
0
}
282
283
int CMS_set1_eContentType(CMS_ContentInfo *cms, const ASN1_OBJECT *oid)
284
0
{
285
0
    ASN1_OBJECT **petype, *etype;
286
0
    petype = cms_get0_econtent_type(cms);
287
0
    if (!petype)
288
0
        return 0;
289
0
    if (!oid)
290
0
        return 1;
291
0
    etype = OBJ_dup(oid);
292
0
    if (!etype)
293
0
        return 0;
294
0
    ASN1_OBJECT_free(*petype);
295
0
    *petype = etype;
296
0
    return 1;
297
0
}
298
299
int CMS_is_detached(CMS_ContentInfo *cms)
300
0
{
301
0
    ASN1_OCTET_STRING **pos;
302
0
    pos = CMS_get0_content(cms);
303
0
    if (!pos)
304
0
        return -1;
305
0
    if (*pos)
306
0
        return 0;
307
0
    return 1;
308
0
}
309
310
int CMS_set_detached(CMS_ContentInfo *cms, int detached)
311
0
{
312
0
    ASN1_OCTET_STRING **pos;
313
0
    pos = CMS_get0_content(cms);
314
0
    if (!pos)
315
0
        return 0;
316
0
    if (detached) {
317
0
        if (*pos) {
318
0
            ASN1_OCTET_STRING_free(*pos);
319
0
            *pos = NULL;
320
0
        }
321
0
        return 1;
322
0
    }
323
0
    if (!*pos)
324
0
        *pos = ASN1_OCTET_STRING_new();
325
0
    if (*pos) {
326
        /*
327
         * NB: special flag to show content is created and not read in.
328
         */
329
0
        (*pos)->flags |= ASN1_STRING_FLAG_CONT;
330
0
        return 1;
331
0
    }
332
0
    CMSerr(CMS_F_CMS_SET_DETACHED, ERR_R_MALLOC_FAILURE);
333
0
    return 0;
334
0
}
335
336
/* Set up an X509_ALGOR DigestAlgorithmIdentifier from an EVP_MD */
337
338
void cms_DigestAlgorithm_set(X509_ALGOR *alg, const EVP_MD *md)
339
0
{
340
0
    int param_type;
341
342
0
    if (md->flags & EVP_MD_FLAG_DIGALGID_ABSENT)
343
0
        param_type = V_ASN1_UNDEF;
344
0
    else
345
0
        param_type = V_ASN1_NULL;
346
347
0
    X509_ALGOR_set0(alg, OBJ_nid2obj(EVP_MD_type(md)), param_type, NULL);
348
349
0
}
350
351
/* Create a digest BIO from an X509_ALGOR structure */
352
353
BIO *cms_DigestAlgorithm_init_bio(X509_ALGOR *digestAlgorithm)
354
0
{
355
0
    BIO *mdbio = NULL;
356
0
    ASN1_OBJECT *digestoid;
357
0
    const EVP_MD *digest;
358
0
    X509_ALGOR_get0(&digestoid, NULL, NULL, digestAlgorithm);
359
0
    digest = EVP_get_digestbyobj(digestoid);
360
0
    if (!digest) {
361
0
        CMSerr(CMS_F_CMS_DIGESTALGORITHM_INIT_BIO,
362
0
               CMS_R_UNKNOWN_DIGEST_ALGORIHM);
363
0
        goto err;
364
0
    }
365
0
    mdbio = BIO_new(BIO_f_md());
366
0
    if (!mdbio || !BIO_set_md(mdbio, digest)) {
367
0
        CMSerr(CMS_F_CMS_DIGESTALGORITHM_INIT_BIO, CMS_R_MD_BIO_INIT_ERROR);
368
0
        goto err;
369
0
    }
370
0
    return mdbio;
371
0
 err:
372
0
    if (mdbio)
373
0
        BIO_free(mdbio);
374
0
    return NULL;
375
0
}
376
377
/* Locate a message digest content from a BIO chain based on SignerInfo */
378
379
int cms_DigestAlgorithm_find_ctx(EVP_MD_CTX *mctx, BIO *chain,
380
                                 X509_ALGOR *mdalg)
381
0
{
382
0
    int nid;
383
0
    ASN1_OBJECT *mdoid;
384
0
    X509_ALGOR_get0(&mdoid, NULL, NULL, mdalg);
385
0
    nid = OBJ_obj2nid(mdoid);
386
    /* Look for digest type to match signature */
387
0
    for (;;) {
388
0
        EVP_MD_CTX *mtmp;
389
0
        chain = BIO_find_type(chain, BIO_TYPE_MD);
390
0
        if (chain == NULL) {
391
0
            CMSerr(CMS_F_CMS_DIGESTALGORITHM_FIND_CTX,
392
0
                   CMS_R_NO_MATCHING_DIGEST);
393
0
            return 0;
394
0
        }
395
0
        BIO_get_md_ctx(chain, &mtmp);
396
0
        if (EVP_MD_CTX_type(mtmp) == nid
397
            /*
398
             * Workaround for broken implementations that use signature
399
             * algorithm OID instead of digest.
400
             */
401
0
            || EVP_MD_pkey_type(EVP_MD_CTX_md(mtmp)) == nid)
402
0
            return EVP_MD_CTX_copy_ex(mctx, mtmp);
403
0
        chain = BIO_next(chain);
404
0
    }
405
0
}
406
407
static STACK_OF(CMS_CertificateChoices)
408
**cms_get0_certificate_choices(CMS_ContentInfo *cms)
409
0
{
410
0
    switch (OBJ_obj2nid(cms->contentType)) {
411
412
0
    case NID_pkcs7_signed:
413
0
        return &cms->d.signedData->certificates;
414
415
0
    case NID_pkcs7_enveloped:
416
0
        if (cms->d.envelopedData->originatorInfo == NULL)
417
0
            return NULL;
418
0
        return &cms->d.envelopedData->originatorInfo->certificates;
419
420
0
    default:
421
0
        CMSerr(CMS_F_CMS_GET0_CERTIFICATE_CHOICES,
422
0
               CMS_R_UNSUPPORTED_CONTENT_TYPE);
423
0
        return NULL;
424
425
0
    }
426
0
}
427
428
CMS_CertificateChoices *CMS_add0_CertificateChoices(CMS_ContentInfo *cms)
429
0
{
430
0
    STACK_OF(CMS_CertificateChoices) **pcerts;
431
0
    CMS_CertificateChoices *cch;
432
0
    pcerts = cms_get0_certificate_choices(cms);
433
0
    if (!pcerts)
434
0
        return NULL;
435
0
    if (!*pcerts)
436
0
        *pcerts = sk_CMS_CertificateChoices_new_null();
437
0
    if (!*pcerts)
438
0
        return NULL;
439
0
    cch = M_ASN1_new_of(CMS_CertificateChoices);
440
0
    if (!cch)
441
0
        return NULL;
442
0
    if (!sk_CMS_CertificateChoices_push(*pcerts, cch)) {
443
0
        M_ASN1_free_of(cch, CMS_CertificateChoices);
444
0
        return NULL;
445
0
    }
446
0
    return cch;
447
0
}
448
449
int CMS_add0_cert(CMS_ContentInfo *cms, X509 *cert)
450
0
{
451
0
    CMS_CertificateChoices *cch;
452
0
    STACK_OF(CMS_CertificateChoices) **pcerts;
453
0
    int i;
454
0
    pcerts = cms_get0_certificate_choices(cms);
455
0
    if (!pcerts)
456
0
        return 0;
457
0
    for (i = 0; i < sk_CMS_CertificateChoices_num(*pcerts); i++) {
458
0
        cch = sk_CMS_CertificateChoices_value(*pcerts, i);
459
0
        if (cch->type == CMS_CERTCHOICE_CERT) {
460
0
            if (!X509_cmp(cch->d.certificate, cert)) {
461
0
                CMSerr(CMS_F_CMS_ADD0_CERT,
462
0
                       CMS_R_CERTIFICATE_ALREADY_PRESENT);
463
0
                return 0;
464
0
            }
465
0
        }
466
0
    }
467
0
    cch = CMS_add0_CertificateChoices(cms);
468
0
    if (!cch)
469
0
        return 0;
470
0
    cch->type = CMS_CERTCHOICE_CERT;
471
0
    cch->d.certificate = cert;
472
0
    return 1;
473
0
}
474
475
int CMS_add1_cert(CMS_ContentInfo *cms, X509 *cert)
476
0
{
477
0
    int r;
478
0
    r = CMS_add0_cert(cms, cert);
479
0
    if (r > 0)
480
0
        CRYPTO_add(&cert->references, 1, CRYPTO_LOCK_X509);
481
0
    return r;
482
0
}
483
484
static STACK_OF(CMS_RevocationInfoChoice)
485
**cms_get0_revocation_choices(CMS_ContentInfo *cms)
486
0
{
487
0
    switch (OBJ_obj2nid(cms->contentType)) {
488
489
0
    case NID_pkcs7_signed:
490
0
        return &cms->d.signedData->crls;
491
492
0
    case NID_pkcs7_enveloped:
493
0
        if (cms->d.envelopedData->originatorInfo == NULL)
494
0
            return NULL;
495
0
        return &cms->d.envelopedData->originatorInfo->crls;
496
497
0
    default:
498
0
        CMSerr(CMS_F_CMS_GET0_REVOCATION_CHOICES,
499
0
               CMS_R_UNSUPPORTED_CONTENT_TYPE);
500
0
        return NULL;
501
502
0
    }
503
0
}
504
505
CMS_RevocationInfoChoice *CMS_add0_RevocationInfoChoice(CMS_ContentInfo *cms)
506
0
{
507
0
    STACK_OF(CMS_RevocationInfoChoice) **pcrls;
508
0
    CMS_RevocationInfoChoice *rch;
509
0
    pcrls = cms_get0_revocation_choices(cms);
510
0
    if (!pcrls)
511
0
        return NULL;
512
0
    if (!*pcrls)
513
0
        *pcrls = sk_CMS_RevocationInfoChoice_new_null();
514
0
    if (!*pcrls)
515
0
        return NULL;
516
0
    rch = M_ASN1_new_of(CMS_RevocationInfoChoice);
517
0
    if (!rch)
518
0
        return NULL;
519
0
    if (!sk_CMS_RevocationInfoChoice_push(*pcrls, rch)) {
520
0
        M_ASN1_free_of(rch, CMS_RevocationInfoChoice);
521
0
        return NULL;
522
0
    }
523
0
    return rch;
524
0
}
525
526
int CMS_add0_crl(CMS_ContentInfo *cms, X509_CRL *crl)
527
0
{
528
0
    CMS_RevocationInfoChoice *rch;
529
0
    rch = CMS_add0_RevocationInfoChoice(cms);
530
0
    if (!rch)
531
0
        return 0;
532
0
    rch->type = CMS_REVCHOICE_CRL;
533
0
    rch->d.crl = crl;
534
0
    return 1;
535
0
}
536
537
int CMS_add1_crl(CMS_ContentInfo *cms, X509_CRL *crl)
538
0
{
539
0
    int r;
540
0
    r = CMS_add0_crl(cms, crl);
541
0
    if (r > 0)
542
0
        CRYPTO_add(&crl->references, 1, CRYPTO_LOCK_X509_CRL);
543
0
    return r;
544
0
}
545
546
STACK_OF(X509) *CMS_get1_certs(CMS_ContentInfo *cms)
547
0
{
548
0
    STACK_OF(X509) *certs = NULL;
549
0
    CMS_CertificateChoices *cch;
550
0
    STACK_OF(CMS_CertificateChoices) **pcerts;
551
0
    int i;
552
0
    pcerts = cms_get0_certificate_choices(cms);
553
0
    if (!pcerts)
554
0
        return NULL;
555
0
    for (i = 0; i < sk_CMS_CertificateChoices_num(*pcerts); i++) {
556
0
        cch = sk_CMS_CertificateChoices_value(*pcerts, i);
557
0
        if (cch->type == 0) {
558
0
            if (!certs) {
559
0
                certs = sk_X509_new_null();
560
0
                if (!certs)
561
0
                    return NULL;
562
0
            }
563
0
            if (!sk_X509_push(certs, cch->d.certificate)) {
564
0
                sk_X509_pop_free(certs, X509_free);
565
0
                return NULL;
566
0
            }
567
0
            CRYPTO_add(&cch->d.certificate->references, 1, CRYPTO_LOCK_X509);
568
0
        }
569
0
    }
570
0
    return certs;
571
572
0
}
573
574
STACK_OF(X509_CRL) *CMS_get1_crls(CMS_ContentInfo *cms)
575
0
{
576
0
    STACK_OF(X509_CRL) *crls = NULL;
577
0
    STACK_OF(CMS_RevocationInfoChoice) **pcrls;
578
0
    CMS_RevocationInfoChoice *rch;
579
0
    int i;
580
0
    pcrls = cms_get0_revocation_choices(cms);
581
0
    if (!pcrls)
582
0
        return NULL;
583
0
    for (i = 0; i < sk_CMS_RevocationInfoChoice_num(*pcrls); i++) {
584
0
        rch = sk_CMS_RevocationInfoChoice_value(*pcrls, i);
585
0
        if (rch->type == 0) {
586
0
            if (!crls) {
587
0
                crls = sk_X509_CRL_new_null();
588
0
                if (!crls)
589
0
                    return NULL;
590
0
            }
591
0
            if (!sk_X509_CRL_push(crls, rch->d.crl)) {
592
0
                sk_X509_CRL_pop_free(crls, X509_CRL_free);
593
0
                return NULL;
594
0
            }
595
0
            CRYPTO_add(&rch->d.crl->references, 1, CRYPTO_LOCK_X509_CRL);
596
0
        }
597
0
    }
598
0
    return crls;
599
0
}
600
601
int cms_ias_cert_cmp(CMS_IssuerAndSerialNumber *ias, X509 *cert)
602
0
{
603
0
    int ret;
604
0
    ret = X509_NAME_cmp(ias->issuer, X509_get_issuer_name(cert));
605
0
    if (ret)
606
0
        return ret;
607
0
    return ASN1_INTEGER_cmp(ias->serialNumber, X509_get_serialNumber(cert));
608
0
}
609
610
int cms_keyid_cert_cmp(ASN1_OCTET_STRING *keyid, X509 *cert)
611
0
{
612
0
    X509_check_purpose(cert, -1, -1);
613
0
    if (!cert->skid)
614
0
        return -1;
615
0
    return ASN1_OCTET_STRING_cmp(keyid, cert->skid);
616
0
}
617
618
int cms_set1_ias(CMS_IssuerAndSerialNumber **pias, X509 *cert)
619
0
{
620
0
    CMS_IssuerAndSerialNumber *ias;
621
0
    ias = M_ASN1_new_of(CMS_IssuerAndSerialNumber);
622
0
    if (!ias)
623
0
        goto err;
624
0
    if (!X509_NAME_set(&ias->issuer, X509_get_issuer_name(cert)))
625
0
        goto err;
626
0
    if (!ASN1_STRING_copy(ias->serialNumber, X509_get_serialNumber(cert)))
627
0
        goto err;
628
0
    if (*pias)
629
0
        M_ASN1_free_of(*pias, CMS_IssuerAndSerialNumber);
630
0
    *pias = ias;
631
0
    return 1;
632
0
 err:
633
0
    if (ias)
634
0
        M_ASN1_free_of(ias, CMS_IssuerAndSerialNumber);
635
0
    CMSerr(CMS_F_CMS_SET1_IAS, ERR_R_MALLOC_FAILURE);
636
0
    return 0;
637
0
}
638
639
int cms_set1_keyid(ASN1_OCTET_STRING **pkeyid, X509 *cert)
640
0
{
641
0
    ASN1_OCTET_STRING *keyid = NULL;
642
0
    X509_check_purpose(cert, -1, -1);
643
0
    if (!cert->skid) {
644
0
        CMSerr(CMS_F_CMS_SET1_KEYID, CMS_R_CERTIFICATE_HAS_NO_KEYID);
645
0
        return 0;
646
0
    }
647
0
    keyid = ASN1_STRING_dup(cert->skid);
648
0
    if (!keyid) {
649
0
        CMSerr(CMS_F_CMS_SET1_KEYID, ERR_R_MALLOC_FAILURE);
650
0
        return 0;
651
0
    }
652
0
    if (*pkeyid)
653
0
        ASN1_OCTET_STRING_free(*pkeyid);
654
0
    *pkeyid = keyid;
655
0
    return 1;
656
0
}