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