~ubuntu-branches/ubuntu/lucid/openssl/lucid-proposed

« back to all changes in this revision

Viewing changes to crypto/cms/cms_lib.c

  • Committer: Bazaar Package Importer
  • Author(s): Kurt Roeckx
  • Date: 2009-06-13 18:15:46 UTC
  • mto: (11.1.5 squeeze)
  • mto: This revision was merged to the branch mainline in revision 34.
  • Revision ID: james.westby@ubuntu.com-20090613181546-vbfntai3b009dl1u
Tags: upstream-0.9.8k
ImportĀ upstreamĀ versionĀ 0.9.8k

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* crypto/cms/cms_lib.c */
 
2
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
 
3
 * project.
 
4
 */
 
5
/* ====================================================================
 
6
 * Copyright (c) 2008 The OpenSSL Project.  All rights reserved.
 
7
 *
 
8
 * Redistribution and use in source and binary forms, with or without
 
9
 * modification, are permitted provided that the following conditions
 
10
 * are met:
 
11
 *
 
12
 * 1. Redistributions of source code must retain the above copyright
 
13
 *    notice, this list of conditions and the following disclaimer. 
 
14
 *
 
15
 * 2. Redistributions in binary form must reproduce the above copyright
 
16
 *    notice, this list of conditions and the following disclaimer in
 
17
 *    the documentation and/or other materials provided with the
 
18
 *    distribution.
 
19
 *
 
20
 * 3. All advertising materials mentioning features or use of this
 
21
 *    software must display the following acknowledgment:
 
22
 *    "This product includes software developed by the OpenSSL Project
 
23
 *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
 
24
 *
 
25
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 
26
 *    endorse or promote products derived from this software without
 
27
 *    prior written permission. For written permission, please contact
 
28
 *    licensing@OpenSSL.org.
 
29
 *
 
30
 * 5. Products derived from this software may not be called "OpenSSL"
 
31
 *    nor may "OpenSSL" appear in their names without prior written
 
32
 *    permission of the OpenSSL Project.
 
33
 *
 
34
 * 6. Redistributions of any form whatsoever must retain the following
 
35
 *    acknowledgment:
 
36
 *    "This product includes software developed by the OpenSSL Project
 
37
 *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
 
38
 *
 
39
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 
40
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 
41
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 
42
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 
43
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 
44
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 
45
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 
46
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 
47
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 
48
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 
49
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 
50
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 
51
 * ====================================================================
 
52
 */
 
53
 
 
54
#include <openssl/asn1t.h>
 
55
#include <openssl/x509.h>
 
56
#include <openssl/err.h>
 
57
#include <openssl/pem.h>
 
58
#include <openssl/bio.h>
 
59
#include <openssl/asn1.h>
 
60
#include "cms.h"
 
61
#include "cms_lcl.h"
 
62
 
 
63
IMPLEMENT_ASN1_FUNCTIONS_const(CMS_ContentInfo)
 
64
 
 
65
DECLARE_ASN1_ITEM(CMS_CertificateChoices)
 
66
DECLARE_ASN1_ITEM(CMS_RevocationInfoChoice)
 
67
DECLARE_STACK_OF(CMS_CertificateChoices)
 
68
DECLARE_STACK_OF(CMS_RevocationInfoChoice)
 
69
 
 
70
const ASN1_OBJECT *CMS_get0_type(CMS_ContentInfo *cms)
 
71
        {
 
72
        return cms->contentType;
 
73
        }
 
74
 
 
75
CMS_ContentInfo *cms_Data_create(void)
 
76
        {
 
77
        CMS_ContentInfo *cms;
 
78
        cms = CMS_ContentInfo_new();
 
79
        if (cms)
 
80
                {
 
81
                cms->contentType = OBJ_nid2obj(NID_pkcs7_data);
 
82
                /* Never detached */
 
83
                CMS_set_detached(cms, 0);
 
84
                }
 
85
        return cms;
 
86
        }
 
87
 
 
88
BIO *cms_content_bio(CMS_ContentInfo *cms)
 
89
        {
 
90
        ASN1_OCTET_STRING **pos = CMS_get0_content(cms);
 
91
        if (!pos)
 
92
                return NULL;
 
93
        /* If content detached data goes nowhere: create NULL BIO */
 
94
        if (!*pos)
 
95
                return BIO_new(BIO_s_null());
 
96
        /* If content not detached and created return memory BIO
 
97
         */
 
98
        if (!*pos || ((*pos)->flags == ASN1_STRING_FLAG_CONT))
 
99
                return BIO_new(BIO_s_mem());
 
100
        /* Else content was read in: return read only BIO for it */
 
101
        return BIO_new_mem_buf((*pos)->data, (*pos)->length);
 
102
        }
 
103
 
 
104
BIO *CMS_dataInit(CMS_ContentInfo *cms, BIO *icont)
 
105
        {
 
106
        BIO *cmsbio, *cont;
 
107
        if (icont)
 
108
                cont = icont;
 
109
        else
 
110
                cont = cms_content_bio(cms);
 
111
        if (!cont)
 
112
                {
 
113
                CMSerr(CMS_F_CMS_DATAINIT, CMS_R_NO_CONTENT);
 
114
                return NULL;
 
115
                }
 
116
        switch (OBJ_obj2nid(cms->contentType))
 
117
                {
 
118
 
 
119
                case NID_pkcs7_data:
 
120
                return cont;
 
121
 
 
122
                case NID_pkcs7_signed:
 
123
                cmsbio = cms_SignedData_init_bio(cms);
 
124
                break;
 
125
 
 
126
                case NID_pkcs7_digest:
 
127
                cmsbio = cms_DigestedData_init_bio(cms);
 
128
                break;
 
129
#ifdef ZLIB
 
130
                case NID_id_smime_ct_compressedData:
 
131
                cmsbio = cms_CompressedData_init_bio(cms);
 
132
                break;
 
133
#endif
 
134
 
 
135
                case NID_pkcs7_encrypted:
 
136
                cmsbio = cms_EncryptedData_init_bio(cms);
 
137
                break;
 
138
 
 
139
                case NID_pkcs7_enveloped:
 
140
                cmsbio = cms_EnvelopedData_init_bio(cms);
 
141
                break;
 
142
 
 
143
                default:
 
144
                CMSerr(CMS_F_CMS_DATAINIT, CMS_R_UNSUPPORTED_TYPE);
 
145
                return NULL;
 
146
                }
 
147
 
 
148
        if (cmsbio)
 
149
                return BIO_push(cmsbio, cont);
 
150
 
 
151
        if (!icont)
 
152
                BIO_free(cont);
 
153
        return NULL;
 
154
 
 
155
        }
 
156
 
 
157
int CMS_dataFinal(CMS_ContentInfo *cms, BIO *cmsbio)
 
158
        {
 
159
        ASN1_OCTET_STRING **pos = CMS_get0_content(cms);
 
160
        if (!pos)
 
161
                return 0;
 
162
        /* If ebmedded content find memory BIO and set content */
 
163
        if (*pos && ((*pos)->flags & ASN1_STRING_FLAG_CONT))
 
164
                {
 
165
                BIO *mbio;
 
166
                unsigned char *cont;
 
167
                long contlen;
 
168
                mbio = BIO_find_type(cmsbio, BIO_TYPE_MEM);
 
169
                if (!mbio)
 
170
                        {
 
171
                        CMSerr(CMS_F_CMS_DATAFINAL, CMS_R_CONTENT_NOT_FOUND);
 
172
                        return 0;
 
173
                        }
 
174
                contlen = BIO_get_mem_data(mbio, &cont);
 
175
                /* Set bio as read only so its content can't be clobbered */
 
176
                BIO_set_flags(mbio, BIO_FLAGS_MEM_RDONLY);
 
177
                BIO_set_mem_eof_return(mbio, 0);
 
178
                ASN1_STRING_set0(*pos, cont, contlen);
 
179
                (*pos)->flags &= ~ASN1_STRING_FLAG_CONT;
 
180
                }
 
181
 
 
182
        switch (OBJ_obj2nid(cms->contentType))
 
183
                {
 
184
 
 
185
                case NID_pkcs7_data:
 
186
                case NID_pkcs7_enveloped:
 
187
                case NID_pkcs7_encrypted:
 
188
                case NID_id_smime_ct_compressedData:
 
189
                /* Nothing to do */
 
190
                return 1;
 
191
 
 
192
                case NID_pkcs7_signed:
 
193
                return cms_SignedData_final(cms, cmsbio);
 
194
 
 
195
                case NID_pkcs7_digest:
 
196
                return cms_DigestedData_do_final(cms, cmsbio, 0);
 
197
 
 
198
                default:
 
199
                CMSerr(CMS_F_CMS_DATAFINAL, CMS_R_UNSUPPORTED_TYPE);
 
200
                return 0;
 
201
                }
 
202
        }
 
203
 
 
204
/* Return an OCTET STRING pointer to content. This allows it to
 
205
 * be accessed or set later.
 
206
 */
 
207
 
 
208
ASN1_OCTET_STRING **CMS_get0_content(CMS_ContentInfo *cms)
 
209
        {
 
210
        switch (OBJ_obj2nid(cms->contentType))
 
211
                {
 
212
 
 
213
                case NID_pkcs7_data:
 
214
                return &cms->d.data;
 
215
 
 
216
                case NID_pkcs7_signed:
 
217
                return &cms->d.signedData->encapContentInfo->eContent;
 
218
 
 
219
                case NID_pkcs7_enveloped:
 
220
                return &cms->d.envelopedData->encryptedContentInfo->encryptedContent;
 
221
 
 
222
                case NID_pkcs7_digest:
 
223
                return &cms->d.digestedData->encapContentInfo->eContent;
 
224
 
 
225
                case NID_pkcs7_encrypted:
 
226
                return &cms->d.encryptedData->encryptedContentInfo->encryptedContent;
 
227
 
 
228
                case NID_id_smime_ct_authData:
 
229
                return &cms->d.authenticatedData->encapContentInfo->eContent;
 
230
 
 
231
                case NID_id_smime_ct_compressedData:
 
232
                return &cms->d.compressedData->encapContentInfo->eContent;
 
233
 
 
234
                default:
 
235
                if (cms->d.other->type == V_ASN1_OCTET_STRING)
 
236
                        return &cms->d.other->value.octet_string;
 
237
                CMSerr(CMS_F_CMS_GET0_CONTENT, CMS_R_UNSUPPORTED_CONTENT_TYPE);
 
238
                return NULL;
 
239
 
 
240
                }
 
241
        }
 
242
 
 
243
/* Return an ASN1_OBJECT pointer to content type. This allows it to
 
244
 * be accessed or set later.
 
245
 */
 
246
 
 
247
static ASN1_OBJECT **cms_get0_econtent_type(CMS_ContentInfo *cms)
 
248
        {
 
249
        switch (OBJ_obj2nid(cms->contentType))
 
250
                {
 
251
 
 
252
                case NID_pkcs7_signed:
 
253
                return &cms->d.signedData->encapContentInfo->eContentType;
 
254
 
 
255
                case NID_pkcs7_enveloped:
 
256
                return &cms->d.envelopedData->encryptedContentInfo->contentType;
 
257
 
 
258
                case NID_pkcs7_digest:
 
259
                return &cms->d.digestedData->encapContentInfo->eContentType;
 
260
 
 
261
                case NID_pkcs7_encrypted:
 
262
                return &cms->d.encryptedData->encryptedContentInfo->contentType;
 
263
 
 
264
                case NID_id_smime_ct_authData:
 
265
                return &cms->d.authenticatedData->encapContentInfo->eContentType;
 
266
 
 
267
                case NID_id_smime_ct_compressedData:
 
268
                return &cms->d.compressedData->encapContentInfo->eContentType;
 
269
 
 
270
                default:
 
271
                CMSerr(CMS_F_CMS_GET0_ECONTENT_TYPE,
 
272
                                        CMS_R_UNSUPPORTED_CONTENT_TYPE);
 
273
                return NULL;
 
274
 
 
275
                }
 
276
        }
 
277
 
 
278
const ASN1_OBJECT *CMS_get0_eContentType(CMS_ContentInfo *cms)
 
279
        {
 
280
        ASN1_OBJECT **petype;
 
281
        petype = cms_get0_econtent_type(cms);
 
282
        if (petype)
 
283
                return *petype;
 
284
        return NULL;
 
285
        }
 
286
 
 
287
int CMS_set1_eContentType(CMS_ContentInfo *cms, const ASN1_OBJECT *oid)
 
288
        {
 
289
        ASN1_OBJECT **petype, *etype;
 
290
        petype = cms_get0_econtent_type(cms);
 
291
        if (!petype)
 
292
                return 0;
 
293
        if (!oid)
 
294
                return 1;
 
295
        etype = OBJ_dup(oid);
 
296
        if (!etype)
 
297
                return 0;
 
298
        ASN1_OBJECT_free(*petype);
 
299
        *petype = etype;
 
300
        return 1;
 
301
        }
 
302
 
 
303
int CMS_is_detached(CMS_ContentInfo *cms)
 
304
        {
 
305
        ASN1_OCTET_STRING **pos;
 
306
        pos = CMS_get0_content(cms);
 
307
        if (!pos)
 
308
                return -1;
 
309
        if (*pos)
 
310
                return 0;
 
311
        return 1;
 
312
        }
 
313
 
 
314
int CMS_set_detached(CMS_ContentInfo *cms, int detached)
 
315
        {
 
316
        ASN1_OCTET_STRING **pos;
 
317
        pos = CMS_get0_content(cms);
 
318
        if (!pos)
 
319
                return 0;
 
320
        if (detached)
 
321
                {
 
322
                if (*pos)
 
323
                        {
 
324
                        ASN1_OCTET_STRING_free(*pos);
 
325
                        *pos = NULL;
 
326
                        }
 
327
                return 1;
 
328
                }
 
329
        if (!*pos)
 
330
                *pos = ASN1_OCTET_STRING_new();
 
331
        if (*pos)
 
332
                {
 
333
                /* NB: special flag to show content is created and not
 
334
                 * read in.
 
335
                 */
 
336
                (*pos)->flags |= ASN1_STRING_FLAG_CONT;
 
337
                return 1;
 
338
                }
 
339
        CMSerr(CMS_F_CMS_SET_DETACHED, ERR_R_MALLOC_FAILURE);
 
340
        return 0;
 
341
        }
 
342
 
 
343
/* Set up an X509_ALGOR DigestAlgorithmIdentifier from an EVP_MD */
 
344
 
 
345
void cms_DigestAlgorithm_set(X509_ALGOR *alg, const EVP_MD *md)
 
346
        {
 
347
        int param_type;
 
348
 
 
349
        switch (EVP_MD_type(md))
 
350
                {
 
351
                case NID_sha1:
 
352
                case NID_sha224:
 
353
                case NID_sha256:
 
354
                case NID_sha384:
 
355
                case NID_sha512:
 
356
                param_type = V_ASN1_UNDEF;
 
357
                break;
 
358
        
 
359
                default:
 
360
                param_type = V_ASN1_NULL;
 
361
                break;
 
362
                }
 
363
 
 
364
        X509_ALGOR_set0(alg, OBJ_nid2obj(EVP_MD_type(md)), param_type, NULL);
 
365
 
 
366
        }
 
367
 
 
368
/* Create a digest BIO from an X509_ALGOR structure */
 
369
 
 
370
BIO *cms_DigestAlgorithm_init_bio(X509_ALGOR *digestAlgorithm)
 
371
        {
 
372
        BIO *mdbio = NULL;
 
373
        ASN1_OBJECT *digestoid;
 
374
        const EVP_MD *digest;
 
375
        X509_ALGOR_get0(&digestoid, NULL, NULL, digestAlgorithm);
 
376
        digest = EVP_get_digestbyobj(digestoid);
 
377
        if (!digest)
 
378
                {
 
379
                CMSerr(CMS_F_CMS_DIGESTALGORITHM_INIT_BIO,
 
380
                                CMS_R_UNKNOWN_DIGEST_ALGORIHM);
 
381
                goto err;       
 
382
                }
 
383
        mdbio = BIO_new(BIO_f_md());
 
384
        if (!mdbio || !BIO_set_md(mdbio, digest))
 
385
                {
 
386
                CMSerr(CMS_F_CMS_DIGESTALGORITHM_INIT_BIO,
 
387
                                CMS_R_MD_BIO_INIT_ERROR);
 
388
                goto err;       
 
389
                }
 
390
        return mdbio;
 
391
        err:
 
392
        if (mdbio)
 
393
                BIO_free(mdbio);
 
394
        return NULL;
 
395
        }
 
396
 
 
397
/* Locate a message digest content from a BIO chain based on SignerInfo */
 
398
 
 
399
int cms_DigestAlgorithm_find_ctx(EVP_MD_CTX *mctx, BIO *chain,
 
400
                                        X509_ALGOR *mdalg)
 
401
        {
 
402
        int nid;
 
403
        ASN1_OBJECT *mdoid;
 
404
        X509_ALGOR_get0(&mdoid, NULL, NULL, mdalg);
 
405
        nid = OBJ_obj2nid(mdoid);
 
406
        /* Look for digest type to match signature */
 
407
        for (;;)
 
408
                {
 
409
                EVP_MD_CTX *mtmp;
 
410
                chain = BIO_find_type(chain, BIO_TYPE_MD);
 
411
                if (chain == NULL)
 
412
                        {
 
413
                        CMSerr(CMS_F_CMS_DIGESTALGORITHM_FIND_CTX,
 
414
                                                CMS_R_NO_MATCHING_DIGEST);
 
415
                        return 0;
 
416
                        }
 
417
                BIO_get_md_ctx(chain, &mtmp);
 
418
                if (EVP_MD_CTX_type(mtmp) == nid)
 
419
                        {
 
420
                        EVP_MD_CTX_copy_ex(mctx, mtmp);
 
421
                        return 1;
 
422
                        }
 
423
                chain = BIO_next(chain);
 
424
                }
 
425
        }
 
426
 
 
427
static STACK_OF(CMS_CertificateChoices) **cms_get0_certificate_choices(CMS_ContentInfo *cms)
 
428
        {
 
429
        switch (OBJ_obj2nid(cms->contentType))
 
430
                {
 
431
 
 
432
                case NID_pkcs7_signed:
 
433
                return &cms->d.signedData->certificates;
 
434
 
 
435
                case NID_pkcs7_enveloped:
 
436
                return &cms->d.envelopedData->originatorInfo->certificates;
 
437
 
 
438
                default:
 
439
                CMSerr(CMS_F_CMS_GET0_CERTIFICATE_CHOICES,
 
440
                                        CMS_R_UNSUPPORTED_CONTENT_TYPE);
 
441
                return NULL;
 
442
 
 
443
                }
 
444
        }
 
445
 
 
446
CMS_CertificateChoices *CMS_add0_CertificateChoices(CMS_ContentInfo *cms)
 
447
        {
 
448
        STACK_OF(CMS_CertificateChoices) **pcerts;
 
449
        CMS_CertificateChoices *cch;
 
450
        pcerts = cms_get0_certificate_choices(cms);
 
451
        if (!pcerts)
 
452
                return NULL;
 
453
        if (!*pcerts)
 
454
                *pcerts = sk_CMS_CertificateChoices_new_null();
 
455
        if (!*pcerts)
 
456
                return NULL;
 
457
        cch = M_ASN1_new_of(CMS_CertificateChoices);
 
458
        if (!cch)
 
459
                return NULL;
 
460
        if (!sk_CMS_CertificateChoices_push(*pcerts, cch))
 
461
                {
 
462
                M_ASN1_free_of(cch, CMS_CertificateChoices);
 
463
                return NULL;
 
464
                }
 
465
        return cch;
 
466
        }
 
467
 
 
468
int CMS_add0_cert(CMS_ContentInfo *cms, X509 *cert)
 
469
        {
 
470
        CMS_CertificateChoices *cch;
 
471
        STACK_OF(CMS_CertificateChoices) **pcerts;
 
472
        int i;
 
473
        pcerts = cms_get0_certificate_choices(cms);
 
474
        if (!pcerts)
 
475
                return 0;
 
476
        if (!pcerts)
 
477
                return 0;
 
478
        for (i = 0; i < sk_CMS_CertificateChoices_num(*pcerts); i++)
 
479
                {
 
480
                cch = sk_CMS_CertificateChoices_value(*pcerts, i);
 
481
                if (cch->type == CMS_CERTCHOICE_CERT)
 
482
                        {
 
483
                        if (!X509_cmp(cch->d.certificate, cert))
 
484
                                {
 
485
                                CMSerr(CMS_F_CMS_ADD0_CERT, 
 
486
                                        CMS_R_CERTIFICATE_ALREADY_PRESENT);
 
487
                                return 0;
 
488
                                }
 
489
                        }
 
490
                }
 
491
        cch = CMS_add0_CertificateChoices(cms);
 
492
        if (!cch)
 
493
                return 0;
 
494
        cch->type = CMS_CERTCHOICE_CERT;
 
495
        cch->d.certificate = cert;
 
496
        return 1;
 
497
        }
 
498
 
 
499
int CMS_add1_cert(CMS_ContentInfo *cms, X509 *cert)
 
500
        {
 
501
        int r;
 
502
        r = CMS_add0_cert(cms, cert);
 
503
        if (r > 0)
 
504
                CRYPTO_add(&cert->references, 1, CRYPTO_LOCK_X509);
 
505
        return r;
 
506
        }
 
507
 
 
508
static STACK_OF(CMS_RevocationInfoChoice) **cms_get0_revocation_choices(CMS_ContentInfo *cms)
 
509
        {
 
510
        switch (OBJ_obj2nid(cms->contentType))
 
511
                {
 
512
 
 
513
                case NID_pkcs7_signed:
 
514
                return &cms->d.signedData->crls;
 
515
 
 
516
                case NID_pkcs7_enveloped:
 
517
                return &cms->d.envelopedData->originatorInfo->crls;
 
518
 
 
519
                default:
 
520
                CMSerr(CMS_F_CMS_GET0_REVOCATION_CHOICES,
 
521
                                        CMS_R_UNSUPPORTED_CONTENT_TYPE);
 
522
                return NULL;
 
523
 
 
524
                }
 
525
        }
 
526
 
 
527
CMS_RevocationInfoChoice *CMS_add0_RevocationInfoChoice(CMS_ContentInfo *cms)
 
528
        {
 
529
        STACK_OF(CMS_RevocationInfoChoice) **pcrls;
 
530
        CMS_RevocationInfoChoice *rch;
 
531
        pcrls = cms_get0_revocation_choices(cms);
 
532
        if (!pcrls)
 
533
                return NULL;
 
534
        if (!*pcrls)
 
535
                *pcrls = sk_CMS_RevocationInfoChoice_new_null();
 
536
        if (!*pcrls)
 
537
                return NULL;
 
538
        rch = M_ASN1_new_of(CMS_RevocationInfoChoice);
 
539
        if (!rch)
 
540
                return NULL;
 
541
        if (!sk_CMS_RevocationInfoChoice_push(*pcrls, rch))
 
542
                {
 
543
                M_ASN1_free_of(rch, CMS_RevocationInfoChoice);
 
544
                return NULL;
 
545
                }
 
546
        return rch;
 
547
        }
 
548
 
 
549
int CMS_add0_crl(CMS_ContentInfo *cms, X509_CRL *crl)
 
550
        {
 
551
        CMS_RevocationInfoChoice *rch;
 
552
        rch = CMS_add0_RevocationInfoChoice(cms);
 
553
        if (!rch)
 
554
                return 0;
 
555
        rch->type = CMS_REVCHOICE_CRL;
 
556
        rch->d.crl = crl;
 
557
        return 1;
 
558
        }
 
559
 
 
560
STACK_OF(X509) *CMS_get1_certs(CMS_ContentInfo *cms)
 
561
        {
 
562
        STACK_OF(X509) *certs = NULL;
 
563
        CMS_CertificateChoices *cch;
 
564
        STACK_OF(CMS_CertificateChoices) **pcerts;
 
565
        int i;
 
566
        pcerts = cms_get0_certificate_choices(cms);
 
567
        if (!pcerts)
 
568
                return NULL;
 
569
        for (i = 0; i < sk_CMS_CertificateChoices_num(*pcerts); i++)
 
570
                {
 
571
                cch = sk_CMS_CertificateChoices_value(*pcerts, i);
 
572
                if (cch->type == 0)
 
573
                        {
 
574
                        if (!certs)
 
575
                                {
 
576
                                certs = sk_X509_new_null();
 
577
                                if (!certs)
 
578
                                        return NULL;
 
579
                                }
 
580
                        if (!sk_X509_push(certs, cch->d.certificate))
 
581
                                {
 
582
                                sk_X509_pop_free(certs, X509_free);
 
583
                                return NULL;
 
584
                                }
 
585
                        CRYPTO_add(&cch->d.certificate->references,
 
586
                                                1, CRYPTO_LOCK_X509);
 
587
                        }
 
588
                }
 
589
        return certs;
 
590
 
 
591
        }
 
592
 
 
593
STACK_OF(X509_CRL) *CMS_get1_crls(CMS_ContentInfo *cms)
 
594
        {
 
595
        STACK_OF(X509_CRL) *crls = NULL;
 
596
        STACK_OF(CMS_RevocationInfoChoice) **pcrls;
 
597
        CMS_RevocationInfoChoice *rch;
 
598
        int i;
 
599
        pcrls = cms_get0_revocation_choices(cms);
 
600
        if (!pcrls)
 
601
                return NULL;
 
602
        for (i = 0; i < sk_CMS_RevocationInfoChoice_num(*pcrls); i++)
 
603
                {
 
604
                rch = sk_CMS_RevocationInfoChoice_value(*pcrls, i);
 
605
                if (rch->type == 0)
 
606
                        {
 
607
                        if (!crls)
 
608
                                {
 
609
                                crls = sk_X509_CRL_new_null();
 
610
                                if (!crls)
 
611
                                        return NULL;
 
612
                                }
 
613
                        if (!sk_X509_CRL_push(crls, rch->d.crl))
 
614
                                {
 
615
                                sk_X509_CRL_pop_free(crls, X509_CRL_free);
 
616
                                return NULL;
 
617
                                }
 
618
                        CRYPTO_add(&rch->d.crl->references,
 
619
                                                1, CRYPTO_LOCK_X509_CRL);
 
620
                        }
 
621
                }
 
622
        return crls;
 
623
        }