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