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