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