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