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