xref: /openssl/crypto/cms/cms_smime.c (revision 7ed6de99)
1 /*
2  * Copyright 2008-2024 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 "internal/cryptlib.h"
11 #include <openssl/asn1t.h>
12 #include <openssl/x509.h>
13 #include <openssl/x509v3.h>
14 #include <openssl/err.h>
15 #include <openssl/cms.h>
16 #include "cms_local.h"
17 #include "crypto/asn1.h"
18 #include "crypto/x509.h"
19 
cms_get_text_bio(BIO * out,unsigned int flags)20 static BIO *cms_get_text_bio(BIO *out, unsigned int flags)
21 {
22     BIO *rbio;
23 
24     if (out == NULL)
25         rbio = BIO_new(BIO_s_null());
26     else if (flags & CMS_TEXT) {
27         rbio = BIO_new(BIO_s_mem());
28         BIO_set_mem_eof_return(rbio, 0);
29     } else
30         rbio = out;
31     return rbio;
32 }
33 
cms_copy_content(BIO * out,BIO * in,unsigned int flags)34 static int cms_copy_content(BIO *out, BIO *in, unsigned int flags)
35 {
36     unsigned char buf[4096];
37     int r = 0, i;
38     BIO *tmpout;
39 
40     tmpout = cms_get_text_bio(out, flags);
41 
42     if (tmpout == NULL) {
43         ERR_raise(ERR_LIB_CMS, ERR_R_CMS_LIB);
44         goto err;
45     }
46 
47     /* Read all content through chain to process digest, decrypt etc */
48     for (;;) {
49         i = BIO_read(in, buf, sizeof(buf));
50         if (i <= 0) {
51             if (BIO_method_type(in) == BIO_TYPE_CIPHER) {
52                 if (BIO_get_cipher_status(in) <= 0)
53                     goto err;
54             }
55             if (i < 0)
56                 goto err;
57             break;
58         }
59 
60         if (tmpout != NULL && (BIO_write(tmpout, buf, i) != i))
61             goto err;
62     }
63 
64     if (flags & CMS_TEXT) {
65         if (!SMIME_text(tmpout, out)) {
66             ERR_raise(ERR_LIB_CMS, CMS_R_SMIME_TEXT_ERROR);
67             goto err;
68         }
69     }
70 
71     r = 1;
72  err:
73     if (tmpout != out)
74         BIO_free(tmpout);
75     return r;
76 
77 }
78 
check_content(CMS_ContentInfo * cms)79 static int check_content(CMS_ContentInfo *cms)
80 {
81     ASN1_OCTET_STRING **pos = CMS_get0_content(cms);
82 
83     if (pos == NULL || *pos == NULL) {
84         ERR_raise(ERR_LIB_CMS, CMS_R_NO_CONTENT);
85         return 0;
86     }
87     return 1;
88 }
89 
do_free_upto(BIO * f,BIO * upto)90 static void do_free_upto(BIO *f, BIO *upto)
91 {
92     if (upto != NULL) {
93         BIO *tbio;
94 
95         do {
96             tbio = BIO_pop(f);
97             BIO_free(f);
98             f = tbio;
99         } while (f != NULL && f != upto);
100     } else {
101         BIO_free_all(f);
102     }
103 }
104 
CMS_data(CMS_ContentInfo * cms,BIO * out,unsigned int flags)105 int CMS_data(CMS_ContentInfo *cms, BIO *out, unsigned int flags)
106 {
107     BIO *cont;
108     int r;
109 
110     if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_data) {
111         ERR_raise(ERR_LIB_CMS, CMS_R_TYPE_NOT_DATA);
112         return 0;
113     }
114     cont = CMS_dataInit(cms, NULL);
115     if (cont == NULL)
116         return 0;
117     r = cms_copy_content(out, cont, flags);
118     BIO_free_all(cont);
119     return r;
120 }
121 
CMS_data_create_ex(BIO * in,unsigned int flags,OSSL_LIB_CTX * libctx,const char * propq)122 CMS_ContentInfo *CMS_data_create_ex(BIO *in, unsigned int flags,
123                                     OSSL_LIB_CTX *libctx, const char *propq)
124 {
125     CMS_ContentInfo *cms = ossl_cms_Data_create(libctx, propq);
126 
127     if (cms == NULL)
128         return NULL;
129 
130     if ((flags & CMS_STREAM) || CMS_final(cms, in, NULL, flags))
131         return cms;
132 
133     CMS_ContentInfo_free(cms);
134     return NULL;
135 }
136 
CMS_data_create(BIO * in,unsigned int flags)137 CMS_ContentInfo *CMS_data_create(BIO *in, unsigned int flags)
138 {
139     return CMS_data_create_ex(in, flags, NULL, NULL);
140 }
141 
CMS_digest_verify(CMS_ContentInfo * cms,BIO * dcont,BIO * out,unsigned int flags)142 int CMS_digest_verify(CMS_ContentInfo *cms, BIO *dcont, BIO *out,
143                       unsigned int flags)
144 {
145     BIO *cont;
146     int r;
147 
148     if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_digest) {
149         ERR_raise(ERR_LIB_CMS, CMS_R_TYPE_NOT_DIGESTED_DATA);
150         return 0;
151     }
152 
153     if (dcont == NULL && !check_content(cms))
154         return 0;
155 
156     cont = CMS_dataInit(cms, dcont);
157     if (cont == NULL)
158         return 0;
159 
160     r = cms_copy_content(out, cont, flags);
161     if (r)
162         r = ossl_cms_DigestedData_do_final(cms, cont, 1);
163     do_free_upto(cont, dcont);
164     return r;
165 }
166 
CMS_digest_create_ex(BIO * in,const EVP_MD * md,unsigned int flags,OSSL_LIB_CTX * ctx,const char * propq)167 CMS_ContentInfo *CMS_digest_create_ex(BIO *in, const EVP_MD *md,
168                                       unsigned int flags, OSSL_LIB_CTX *ctx,
169                                       const char *propq)
170 {
171     CMS_ContentInfo *cms;
172 
173     /*
174      * Because the EVP_MD is cached and can be a legacy algorithm, we
175      * cannot fetch the algorithm if it isn't supplied.
176      */
177     if (md == NULL)
178         md = EVP_sha1();
179     cms = ossl_cms_DigestedData_create(md, ctx, propq);
180     if (cms == NULL)
181         return NULL;
182 
183     if (!(flags & CMS_DETACHED))
184         CMS_set_detached(cms, 0);
185 
186     if ((flags & CMS_STREAM) || CMS_final(cms, in, NULL, flags))
187         return cms;
188 
189     CMS_ContentInfo_free(cms);
190     return NULL;
191 }
192 
CMS_digest_create(BIO * in,const EVP_MD * md,unsigned int flags)193 CMS_ContentInfo *CMS_digest_create(BIO *in, const EVP_MD *md,
194                                    unsigned int flags)
195 {
196     return CMS_digest_create_ex(in, md, flags, NULL, NULL);
197 }
198 
CMS_EncryptedData_decrypt(CMS_ContentInfo * cms,const unsigned char * key,size_t keylen,BIO * dcont,BIO * out,unsigned int flags)199 int CMS_EncryptedData_decrypt(CMS_ContentInfo *cms,
200                               const unsigned char *key, size_t keylen,
201                               BIO *dcont, BIO *out, unsigned int flags)
202 {
203     BIO *cont;
204     int r;
205 
206     if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_encrypted) {
207         ERR_raise(ERR_LIB_CMS, CMS_R_TYPE_NOT_ENCRYPTED_DATA);
208         return 0;
209     }
210 
211     if (dcont == NULL && !check_content(cms))
212         return 0;
213 
214     if (CMS_EncryptedData_set1_key(cms, NULL, key, keylen) <= 0)
215         return 0;
216     cont = CMS_dataInit(cms, dcont);
217     if (cont == NULL)
218         return 0;
219     r = cms_copy_content(out, cont, flags);
220     do_free_upto(cont, dcont);
221     return r;
222 }
223 
CMS_EncryptedData_encrypt_ex(BIO * in,const EVP_CIPHER * cipher,const unsigned char * key,size_t keylen,unsigned int flags,OSSL_LIB_CTX * libctx,const char * propq)224 CMS_ContentInfo *CMS_EncryptedData_encrypt_ex(BIO *in, const EVP_CIPHER *cipher,
225                                               const unsigned char *key,
226                                               size_t keylen, unsigned int flags,
227                                               OSSL_LIB_CTX *libctx,
228                                               const char *propq)
229 {
230     CMS_ContentInfo *cms;
231 
232     if (cipher == NULL) {
233         ERR_raise(ERR_LIB_CMS, CMS_R_NO_CIPHER);
234         return NULL;
235     }
236     cms = CMS_ContentInfo_new_ex(libctx, propq);
237     if (cms == NULL)
238         return NULL;
239     if (!CMS_EncryptedData_set1_key(cms, cipher, key, keylen))
240         goto err;
241 
242     if (!(flags & CMS_DETACHED))
243         CMS_set_detached(cms, 0);
244 
245     if ((flags & (CMS_STREAM | CMS_PARTIAL))
246         || CMS_final(cms, in, NULL, flags))
247         return cms;
248 
249  err:
250     CMS_ContentInfo_free(cms);
251     return NULL;
252 }
253 
CMS_EncryptedData_encrypt(BIO * in,const EVP_CIPHER * cipher,const unsigned char * key,size_t keylen,unsigned int flags)254 CMS_ContentInfo *CMS_EncryptedData_encrypt(BIO *in, const EVP_CIPHER *cipher,
255                                            const unsigned char *key,
256                                            size_t keylen, unsigned int flags)
257 {
258     return CMS_EncryptedData_encrypt_ex(in, cipher, key, keylen, flags, NULL,
259                                         NULL);
260 }
261 
cms_signerinfo_verify_cert(CMS_SignerInfo * si,X509_STORE * store,STACK_OF (X509)* untrusted,STACK_OF (X509_CRL)* crls,STACK_OF (X509)** chain,const CMS_CTX * cms_ctx)262 static int cms_signerinfo_verify_cert(CMS_SignerInfo *si,
263                                       X509_STORE *store,
264                                       STACK_OF(X509) *untrusted,
265                                       STACK_OF(X509_CRL) *crls,
266                                       STACK_OF(X509) **chain,
267                                       const CMS_CTX *cms_ctx)
268 {
269     X509_STORE_CTX *ctx;
270     X509 *signer;
271     int i, j, r = 0;
272 
273     ctx = X509_STORE_CTX_new_ex(ossl_cms_ctx_get0_libctx(cms_ctx),
274                                 ossl_cms_ctx_get0_propq(cms_ctx));
275     if (ctx == NULL) {
276         ERR_raise(ERR_LIB_CMS, ERR_R_X509_LIB);
277         goto err;
278     }
279     CMS_SignerInfo_get0_algs(si, NULL, &signer, NULL, NULL);
280     if (!X509_STORE_CTX_init(ctx, store, signer, untrusted)) {
281         ERR_raise(ERR_LIB_CMS, CMS_R_STORE_INIT_ERROR);
282         goto err;
283     }
284     X509_STORE_CTX_set_default(ctx, "smime_sign");
285     if (crls != NULL)
286         X509_STORE_CTX_set0_crls(ctx, crls);
287 
288     i = X509_verify_cert(ctx);
289     if (i <= 0) {
290         j = X509_STORE_CTX_get_error(ctx);
291         ERR_raise_data(ERR_LIB_CMS, CMS_R_CERTIFICATE_VERIFY_ERROR,
292                        "Verify error: %s", X509_verify_cert_error_string(j));
293         goto err;
294     }
295     r = 1;
296 
297     /* also send back the trust chain when required */
298     if (chain != NULL)
299         *chain = X509_STORE_CTX_get1_chain(ctx);
300  err:
301     X509_STORE_CTX_free(ctx);
302     return r;
303 
304 }
305 
306 /* This strongly overlaps with PKCS7_verify() */
CMS_verify(CMS_ContentInfo * cms,STACK_OF (X509)* certs,X509_STORE * store,BIO * dcont,BIO * out,unsigned int flags)307 int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs,
308                X509_STORE *store, BIO *dcont, BIO *out, unsigned int flags)
309 {
310     CMS_SignerInfo *si;
311     STACK_OF(CMS_SignerInfo) *sinfos;
312     STACK_OF(X509) *untrusted = NULL;
313     STACK_OF(X509_CRL) *crls = NULL;
314     STACK_OF(X509) **si_chains = NULL;
315     X509 *signer;
316     int i, scount = 0, ret = 0;
317     BIO *cmsbio = NULL, *tmpin = NULL, *tmpout = NULL;
318     int cadesVerify = (flags & CMS_CADES) != 0;
319     const CMS_CTX *ctx = ossl_cms_get0_cmsctx(cms);
320 
321     if (dcont == NULL && !check_content(cms))
322         return 0;
323     if (dcont != NULL && !(flags & CMS_BINARY)) {
324         const ASN1_OBJECT *coid = CMS_get0_eContentType(cms);
325 
326         if (OBJ_obj2nid(coid) == NID_id_ct_asciiTextWithCRLF)
327             flags |= CMS_ASCIICRLF;
328     }
329 
330     /* Attempt to find all signer certificates */
331 
332     sinfos = CMS_get0_SignerInfos(cms);
333 
334     if (sk_CMS_SignerInfo_num(sinfos) <= 0) {
335         ERR_raise(ERR_LIB_CMS, CMS_R_NO_SIGNERS);
336         goto err;
337     }
338 
339     for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) {
340         si = sk_CMS_SignerInfo_value(sinfos, i);
341         CMS_SignerInfo_get0_algs(si, NULL, &signer, NULL, NULL);
342         if (signer != NULL)
343             scount++;
344     }
345 
346     if (scount != sk_CMS_SignerInfo_num(sinfos))
347         scount += CMS_set1_signers_certs(cms, certs, flags);
348 
349     if (scount != sk_CMS_SignerInfo_num(sinfos)) {
350         ERR_raise(ERR_LIB_CMS, CMS_R_SIGNER_CERTIFICATE_NOT_FOUND);
351         goto err;
352     }
353 
354     /* Attempt to verify all signers certs */
355     /* at this point scount == sk_CMS_SignerInfo_num(sinfos) */
356 
357     if ((flags & CMS_NO_SIGNER_CERT_VERIFY) == 0 || cadesVerify) {
358         if (cadesVerify) {
359             /* Certificate trust chain is required to check CAdES signature */
360             si_chains = OPENSSL_zalloc(scount * sizeof(si_chains[0]));
361             if (si_chains == NULL)
362                 goto err;
363         }
364         if ((untrusted = CMS_get1_certs(cms)) == NULL)
365             goto err;
366         if (sk_X509_num(certs) > 0
367             && !ossl_x509_add_certs_new(&untrusted, certs,
368                                         X509_ADD_FLAG_UP_REF |
369                                         X509_ADD_FLAG_NO_DUP))
370             goto err;
371 
372         if ((flags & CMS_NOCRL) == 0
373             && (crls = CMS_get1_crls(cms)) == NULL)
374             goto err;
375         for (i = 0; i < scount; i++) {
376             si = sk_CMS_SignerInfo_value(sinfos, i);
377 
378             if (!cms_signerinfo_verify_cert(si, store, untrusted, crls,
379                                             si_chains ? &si_chains[i] : NULL,
380                                             ctx))
381                 goto err;
382         }
383     }
384 
385     /* Attempt to verify all SignerInfo signed attribute signatures */
386 
387     if ((flags & CMS_NO_ATTR_VERIFY) == 0 || cadesVerify) {
388         for (i = 0; i < scount; i++) {
389             si = sk_CMS_SignerInfo_value(sinfos, i);
390             if (CMS_signed_get_attr_count(si) < 0)
391                 continue;
392             if (CMS_SignerInfo_verify(si) <= 0)
393                 goto err;
394             if (cadesVerify) {
395                 STACK_OF(X509) *si_chain = si_chains ? si_chains[i] : NULL;
396 
397                 if (ossl_cms_check_signing_certs(si, si_chain) <= 0)
398                     goto err;
399             }
400         }
401     }
402 
403     /*
404      * Performance optimization: if the content is a memory BIO then store
405      * its contents in a temporary read only memory BIO. This avoids
406      * potentially large numbers of slow copies of data which will occur when
407      * reading from a read write memory BIO when signatures are calculated.
408      */
409 
410     if (dcont != NULL && (BIO_method_type(dcont) == BIO_TYPE_MEM)) {
411         char *ptr;
412         long len;
413 
414         len = BIO_get_mem_data(dcont, &ptr);
415         tmpin = (len == 0) ? dcont : BIO_new_mem_buf(ptr, len);
416         if (tmpin == NULL) {
417             ERR_raise(ERR_LIB_CMS, ERR_R_BIO_LIB);
418             goto err2;
419         }
420     } else {
421         tmpin = dcont;
422     }
423     /*
424      * If not binary mode and detached generate digests by *writing* through
425      * the BIO. That makes it possible to canonicalise the input.
426      */
427     if (!(flags & SMIME_BINARY) && dcont) {
428         /*
429          * Create output BIO so we can either handle text or to ensure
430          * included content doesn't override detached content.
431          */
432         tmpout = cms_get_text_bio(out, flags);
433         if (tmpout == NULL) {
434             ERR_raise(ERR_LIB_CMS, ERR_R_CMS_LIB);
435             goto err;
436         }
437         cmsbio = CMS_dataInit(cms, tmpout);
438         if (cmsbio == NULL)
439             goto err;
440         /*
441          * Don't use SMIME_TEXT for verify: it adds headers and we want to
442          * remove them.
443          */
444         if (!SMIME_crlf_copy(dcont, cmsbio, flags & ~SMIME_TEXT))
445             goto err;
446 
447         if (flags & CMS_TEXT) {
448             if (!SMIME_text(tmpout, out)) {
449                 ERR_raise(ERR_LIB_CMS, CMS_R_SMIME_TEXT_ERROR);
450                 goto err;
451             }
452         }
453     } else {
454         cmsbio = CMS_dataInit(cms, tmpin);
455         if (cmsbio == NULL)
456             goto err;
457 
458         if (!cms_copy_content(out, cmsbio, flags))
459             goto err;
460 
461     }
462     if (!(flags & CMS_NO_CONTENT_VERIFY)) {
463         for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) {
464             si = sk_CMS_SignerInfo_value(sinfos, i);
465             if (CMS_SignerInfo_verify_content(si, cmsbio) <= 0) {
466                 ERR_raise(ERR_LIB_CMS, CMS_R_CONTENT_VERIFY_ERROR);
467                 goto err;
468             }
469         }
470     }
471 
472     ret = 1;
473  err:
474     if (!(flags & SMIME_BINARY) && dcont) {
475         do_free_upto(cmsbio, tmpout);
476         if (tmpin != dcont)
477             BIO_free(tmpin);
478     } else {
479         if (dcont && (tmpin == dcont))
480             do_free_upto(cmsbio, dcont);
481         else
482             BIO_free_all(cmsbio);
483     }
484 
485     if (out != tmpout)
486         BIO_free_all(tmpout);
487 
488  err2:
489     if (si_chains != NULL) {
490         for (i = 0; i < scount; ++i)
491             OSSL_STACK_OF_X509_free(si_chains[i]);
492         OPENSSL_free(si_chains);
493     }
494     sk_X509_pop_free(untrusted, X509_free);
495     sk_X509_CRL_pop_free(crls, X509_CRL_free);
496 
497     return ret;
498 }
499 
CMS_verify_receipt(CMS_ContentInfo * rcms,CMS_ContentInfo * ocms,STACK_OF (X509)* certs,X509_STORE * store,unsigned int flags)500 int CMS_verify_receipt(CMS_ContentInfo *rcms, CMS_ContentInfo *ocms,
501                        STACK_OF(X509) *certs,
502                        X509_STORE *store, unsigned int flags)
503 {
504     int r;
505 
506     flags &= ~(CMS_DETACHED | CMS_TEXT);
507     r = CMS_verify(rcms, certs, store, NULL, NULL, flags);
508     if (r <= 0)
509         return r;
510     return ossl_cms_Receipt_verify(rcms, ocms);
511 }
512 
CMS_sign_ex(X509 * signcert,EVP_PKEY * pkey,STACK_OF (X509)* certs,BIO * data,unsigned int flags,OSSL_LIB_CTX * libctx,const char * propq)513 CMS_ContentInfo *CMS_sign_ex(X509 *signcert, EVP_PKEY *pkey,
514                              STACK_OF(X509) *certs, BIO *data,
515                              unsigned int flags, OSSL_LIB_CTX *libctx,
516                              const char *propq)
517 {
518     CMS_ContentInfo *cms;
519     int i;
520 
521     cms = CMS_ContentInfo_new_ex(libctx, propq);
522     if (cms == NULL || !CMS_SignedData_init(cms)) {
523         ERR_raise(ERR_LIB_CMS, ERR_R_CMS_LIB);
524         goto err;
525     }
526     if (flags & CMS_ASCIICRLF
527         && !CMS_set1_eContentType(cms,
528                                   OBJ_nid2obj(NID_id_ct_asciiTextWithCRLF))) {
529         ERR_raise(ERR_LIB_CMS, ERR_R_CMS_LIB);
530         goto err;
531     }
532 
533     if (pkey != NULL && !CMS_add1_signer(cms, signcert, pkey, NULL, flags)) {
534         ERR_raise(ERR_LIB_CMS, CMS_R_ADD_SIGNER_ERROR);
535         goto err;
536     }
537 
538     for (i = 0; i < sk_X509_num(certs); i++) {
539         X509 *x = sk_X509_value(certs, i);
540 
541         if (!CMS_add1_cert(cms, x)) {
542             ERR_raise(ERR_LIB_CMS, ERR_R_CMS_LIB);
543             goto err;
544         }
545     }
546 
547     if (!(flags & CMS_DETACHED))
548         CMS_set_detached(cms, 0);
549 
550     if ((flags & (CMS_STREAM | CMS_PARTIAL))
551         || CMS_final(cms, data, NULL, flags))
552         return cms;
553     else
554         goto err;
555 
556  err:
557     CMS_ContentInfo_free(cms);
558     return NULL;
559 }
560 
CMS_sign(X509 * signcert,EVP_PKEY * pkey,STACK_OF (X509)* certs,BIO * data,unsigned int flags)561 CMS_ContentInfo *CMS_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs,
562                           BIO *data, unsigned int flags)
563 {
564     return CMS_sign_ex(signcert, pkey, certs, data, flags, NULL, NULL);
565 }
566 
CMS_sign_receipt(CMS_SignerInfo * si,X509 * signcert,EVP_PKEY * pkey,STACK_OF (X509)* certs,unsigned int flags)567 CMS_ContentInfo *CMS_sign_receipt(CMS_SignerInfo *si,
568                                   X509 *signcert, EVP_PKEY *pkey,
569                                   STACK_OF(X509) *certs, unsigned int flags)
570 {
571     CMS_SignerInfo *rct_si;
572     CMS_ContentInfo *cms = NULL;
573     ASN1_OCTET_STRING **pos, *os = NULL;
574     BIO *rct_cont = NULL;
575     int r = 0;
576     const CMS_CTX *ctx = si->cms_ctx;
577 
578     flags &= ~(CMS_STREAM | CMS_TEXT);
579     /* Not really detached but avoids content being allocated */
580     flags |= CMS_PARTIAL | CMS_BINARY | CMS_DETACHED;
581     if (pkey == NULL || signcert == NULL) {
582         ERR_raise(ERR_LIB_CMS, CMS_R_NO_KEY_OR_CERT);
583         return NULL;
584     }
585 
586     /* Initialize signed data */
587 
588     cms = CMS_sign_ex(NULL, NULL, certs, NULL, flags,
589                       ossl_cms_ctx_get0_libctx(ctx),
590                       ossl_cms_ctx_get0_propq(ctx));
591     if (cms == NULL)
592         goto err;
593 
594     /* Set inner content type to signed receipt */
595     if (!CMS_set1_eContentType(cms, OBJ_nid2obj(NID_id_smime_ct_receipt)))
596         goto err;
597 
598     rct_si = CMS_add1_signer(cms, signcert, pkey, NULL, flags);
599     if (!rct_si) {
600         ERR_raise(ERR_LIB_CMS, CMS_R_ADD_SIGNER_ERROR);
601         goto err;
602     }
603 
604     os = ossl_cms_encode_Receipt(si);
605     if (os == NULL)
606         goto err;
607 
608     /* Set content to digest */
609     rct_cont = BIO_new_mem_buf(os->data, os->length);
610     if (rct_cont == NULL)
611         goto err;
612 
613     /* Add msgSigDigest attribute */
614 
615     if (!ossl_cms_msgSigDigest_add1(rct_si, si))
616         goto err;
617 
618     /* Finalize structure */
619     if (!CMS_final(cms, rct_cont, NULL, flags))
620         goto err;
621 
622     /* Set embedded content */
623     pos = CMS_get0_content(cms);
624     if (pos == NULL)
625         goto err;
626     *pos = os;
627 
628     r = 1;
629 
630  err:
631     BIO_free(rct_cont);
632     if (r)
633         return cms;
634     CMS_ContentInfo_free(cms);
635     ASN1_OCTET_STRING_free(os);
636     return NULL;
637 
638 }
639 
CMS_encrypt_ex(STACK_OF (X509)* certs,BIO * data,const EVP_CIPHER * cipher,unsigned int flags,OSSL_LIB_CTX * libctx,const char * propq)640 CMS_ContentInfo *CMS_encrypt_ex(STACK_OF(X509) *certs, BIO *data,
641                                 const EVP_CIPHER *cipher, unsigned int flags,
642                                 OSSL_LIB_CTX *libctx, const char *propq)
643 {
644     CMS_ContentInfo *cms;
645     int i;
646     X509 *recip;
647 
648 
649     cms = (EVP_CIPHER_get_flags(cipher) & EVP_CIPH_FLAG_AEAD_CIPHER)
650           ? CMS_AuthEnvelopedData_create_ex(cipher, libctx, propq)
651           : CMS_EnvelopedData_create_ex(cipher, libctx, propq);
652     if (cms == NULL) {
653         ERR_raise(ERR_LIB_CMS, ERR_R_CMS_LIB);
654         goto err;
655     }
656     for (i = 0; i < sk_X509_num(certs); i++) {
657         recip = sk_X509_value(certs, i);
658         if (!CMS_add1_recipient_cert(cms, recip, flags)) {
659             ERR_raise(ERR_LIB_CMS, CMS_R_RECIPIENT_ERROR);
660             goto err;
661         }
662     }
663 
664     if (!(flags & CMS_DETACHED))
665         CMS_set_detached(cms, 0);
666 
667     if ((flags & (CMS_STREAM | CMS_PARTIAL))
668         || CMS_final(cms, data, NULL, flags))
669         return cms;
670     else
671         ERR_raise(ERR_LIB_CMS, ERR_R_CMS_LIB);
672 
673  err:
674     CMS_ContentInfo_free(cms);
675     return NULL;
676 }
677 
CMS_encrypt(STACK_OF (X509)* certs,BIO * data,const EVP_CIPHER * cipher,unsigned int flags)678 CMS_ContentInfo *CMS_encrypt(STACK_OF(X509) *certs, BIO *data,
679                              const EVP_CIPHER *cipher, unsigned int flags)
680 {
681     return CMS_encrypt_ex(certs, data, cipher, flags, NULL, NULL);
682 }
683 
cms_kari_set1_pkey_and_peer(CMS_ContentInfo * cms,CMS_RecipientInfo * ri,EVP_PKEY * pk,X509 * cert,X509 * peer)684 static int cms_kari_set1_pkey_and_peer(CMS_ContentInfo *cms,
685                                        CMS_RecipientInfo *ri,
686                                        EVP_PKEY *pk, X509 *cert, X509 *peer)
687 {
688     int i;
689     STACK_OF(CMS_RecipientEncryptedKey) *reks;
690     CMS_RecipientEncryptedKey *rek;
691 
692     reks = CMS_RecipientInfo_kari_get0_reks(ri);
693     for (i = 0; i < sk_CMS_RecipientEncryptedKey_num(reks); i++) {
694         int rv;
695 
696         rek = sk_CMS_RecipientEncryptedKey_value(reks, i);
697         if (cert != NULL && CMS_RecipientEncryptedKey_cert_cmp(rek, cert))
698             continue;
699         CMS_RecipientInfo_kari_set0_pkey_and_peer(ri, pk, peer);
700         rv = CMS_RecipientInfo_kari_decrypt(cms, ri, rek);
701         CMS_RecipientInfo_kari_set0_pkey(ri, NULL);
702         if (rv > 0)
703             return 1;
704         return cert == NULL ? 0 : -1;
705     }
706     return 0;
707 }
708 
CMS_decrypt_set1_pkey(CMS_ContentInfo * cms,EVP_PKEY * pk,X509 * cert)709 int CMS_decrypt_set1_pkey(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert)
710 {
711      return CMS_decrypt_set1_pkey_and_peer(cms, pk, cert, NULL);
712 }
713 
CMS_decrypt_set1_pkey_and_peer(CMS_ContentInfo * cms,EVP_PKEY * pk,X509 * cert,X509 * peer)714 int CMS_decrypt_set1_pkey_and_peer(CMS_ContentInfo *cms, EVP_PKEY *pk,
715                                    X509 *cert, X509 *peer)
716 {
717     STACK_OF(CMS_RecipientInfo) *ris = CMS_get0_RecipientInfos(cms);
718     CMS_RecipientInfo *ri;
719     int i, r, cms_pkey_ri_type;
720     int debug = 0, match_ri = 0;
721     CMS_EncryptedContentInfo *ec = ossl_cms_get0_env_enc_content(cms);
722 
723     /* Prevent mem leak on earlier CMS_decrypt_set1_{pkey_and_peer,password} */
724     if (ec != NULL) {
725         OPENSSL_clear_free(ec->key, ec->keylen);
726         ec->key = NULL;
727         ec->keylen = 0;
728     }
729 
730     if (ris != NULL && ec != NULL)
731         debug = ec->debug;
732 
733     cms_pkey_ri_type = ossl_cms_pkey_get_ri_type(pk);
734     if (cms_pkey_ri_type == CMS_RECIPINFO_NONE) {
735          ERR_raise(ERR_LIB_CMS, CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
736          return 0;
737     }
738 
739     for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++) {
740         int ri_type;
741 
742         ri = sk_CMS_RecipientInfo_value(ris, i);
743         ri_type = CMS_RecipientInfo_type(ri);
744         if (!ossl_cms_pkey_is_ri_type_supported(pk, ri_type))
745             continue;
746         match_ri = 1;
747         if (ri_type == CMS_RECIPINFO_AGREE) {
748             r = cms_kari_set1_pkey_and_peer(cms, ri, pk, cert, peer);
749             if (r > 0)
750                 return 1;
751             if (r < 0)
752                 return 0;
753         }
754         /* If we have a cert, try matching RecipientInfo, else try them all */
755         else if (cert == NULL || !CMS_RecipientInfo_ktri_cert_cmp(ri, cert)) {
756             EVP_PKEY_up_ref(pk);
757             CMS_RecipientInfo_set0_pkey(ri, pk);
758             r = CMS_RecipientInfo_decrypt(cms, ri);
759             CMS_RecipientInfo_set0_pkey(ri, NULL);
760             if (cert != NULL) {
761                 /*
762                  * If not debugging clear any error and return success to
763                  * avoid leaking of information useful to MMA
764                  */
765                 if (!debug) {
766                     ERR_clear_error();
767                     return 1;
768                 }
769                 if (r > 0)
770                     return 1;
771                 ERR_raise(ERR_LIB_CMS, CMS_R_DECRYPT_ERROR);
772                 return 0;
773             }
774             /*
775              * If no cert and not debugging don't leave loop after first
776              * successful decrypt. Always attempt to decrypt all recipients
777              * to avoid leaking timing of a successful decrypt.
778              */
779             else if (r > 0 && (debug || cms_pkey_ri_type != CMS_RECIPINFO_TRANS))
780                 return 1;
781         }
782     }
783     /* If no cert, key transport and not debugging always return success */
784     if (cert == NULL
785         && cms_pkey_ri_type == CMS_RECIPINFO_TRANS
786         && match_ri
787         && !debug) {
788         ERR_clear_error();
789         return 1;
790     }
791 
792     if (!match_ri)
793         ERR_raise(ERR_LIB_CMS, CMS_R_NO_MATCHING_RECIPIENT);
794     return 0;
795 
796 }
797 
CMS_decrypt_set1_key(CMS_ContentInfo * cms,unsigned char * key,size_t keylen,const unsigned char * id,size_t idlen)798 int CMS_decrypt_set1_key(CMS_ContentInfo *cms,
799                          unsigned char *key, size_t keylen,
800                          const unsigned char *id, size_t idlen)
801 {
802     STACK_OF(CMS_RecipientInfo) *ris;
803     CMS_RecipientInfo *ri;
804     int i, r, match_ri = 0;
805 
806     ris = CMS_get0_RecipientInfos(cms);
807     for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++) {
808         ri = sk_CMS_RecipientInfo_value(ris, i);
809         if (CMS_RecipientInfo_type(ri) != CMS_RECIPINFO_KEK)
810             continue;
811 
812         /* If we have an id, try matching RecipientInfo, else try them all */
813         if (id == NULL
814                 || (CMS_RecipientInfo_kekri_id_cmp(ri, id, idlen) == 0)) {
815             match_ri = 1;
816             CMS_RecipientInfo_set0_key(ri, key, keylen);
817             r = CMS_RecipientInfo_decrypt(cms, ri);
818             CMS_RecipientInfo_set0_key(ri, NULL, 0);
819             if (r > 0)
820                 return 1;
821             if (id != NULL) {
822                 ERR_raise(ERR_LIB_CMS, CMS_R_DECRYPT_ERROR);
823                 return 0;
824             }
825             ERR_clear_error();
826         }
827     }
828 
829     if (!match_ri)
830         ERR_raise(ERR_LIB_CMS, CMS_R_NO_MATCHING_RECIPIENT);
831     return 0;
832 
833 }
834 
CMS_decrypt_set1_password(CMS_ContentInfo * cms,unsigned char * pass,ossl_ssize_t passlen)835 int CMS_decrypt_set1_password(CMS_ContentInfo *cms,
836                               unsigned char *pass, ossl_ssize_t passlen)
837 {
838     STACK_OF(CMS_RecipientInfo) *ris = CMS_get0_RecipientInfos(cms);
839     CMS_RecipientInfo *ri;
840     int i, r, match_ri = 0;
841     CMS_EncryptedContentInfo *ec = ossl_cms_get0_env_enc_content(cms);
842 
843     /* Prevent mem leak on earlier CMS_decrypt_set1_{pkey_and_peer,password} */
844     if (ec != NULL) {
845         OPENSSL_clear_free(ec->key, ec->keylen);
846         ec->key = NULL;
847         ec->keylen = 0;
848     }
849 
850     for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++) {
851         ri = sk_CMS_RecipientInfo_value(ris, i);
852         if (CMS_RecipientInfo_type(ri) != CMS_RECIPINFO_PASS)
853             continue;
854 
855         /* Must try each PasswordRecipientInfo */
856         match_ri = 1;
857         CMS_RecipientInfo_set0_password(ri, pass, passlen);
858         r = CMS_RecipientInfo_decrypt(cms, ri);
859         CMS_RecipientInfo_set0_password(ri, NULL, 0);
860         if (r > 0)
861             return 1;
862     }
863 
864     if (!match_ri)
865         ERR_raise(ERR_LIB_CMS, CMS_R_NO_MATCHING_RECIPIENT);
866     return 0;
867 
868 }
869 
CMS_decrypt(CMS_ContentInfo * cms,EVP_PKEY * pk,X509 * cert,BIO * dcont,BIO * out,unsigned int flags)870 int CMS_decrypt(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert,
871                 BIO *dcont, BIO *out, unsigned int flags)
872 {
873     int r;
874     BIO *cont;
875     CMS_EncryptedContentInfo *ec;
876     int nid = OBJ_obj2nid(CMS_get0_type(cms));
877 
878     if (nid != NID_pkcs7_enveloped
879             && nid != NID_id_smime_ct_authEnvelopedData) {
880         ERR_raise(ERR_LIB_CMS, CMS_R_TYPE_NOT_ENVELOPED_DATA);
881         return 0;
882     }
883     if (dcont == NULL && !check_content(cms))
884         return 0;
885     ec = ossl_cms_get0_env_enc_content(cms);
886     ec->debug = (flags & CMS_DEBUG_DECRYPT) != 0;
887     ec->havenocert = cert == NULL;
888     if (pk == NULL && cert == NULL && dcont == NULL && out == NULL)
889         return 1;
890     if (pk != NULL && !CMS_decrypt_set1_pkey(cms, pk, cert))
891         return 0;
892     cont = CMS_dataInit(cms, dcont);
893     if (cont == NULL)
894         return 0;
895     r = cms_copy_content(out, cont, flags);
896     do_free_upto(cont, dcont);
897     return r;
898 }
899 
CMS_final(CMS_ContentInfo * cms,BIO * data,BIO * dcont,unsigned int flags)900 int CMS_final(CMS_ContentInfo *cms, BIO *data, BIO *dcont, unsigned int flags)
901 {
902     BIO *cmsbio;
903     int ret = 0;
904 
905     if ((cmsbio = CMS_dataInit(cms, dcont)) == NULL) {
906         ERR_raise(ERR_LIB_CMS, CMS_R_CMS_LIB);
907         return 0;
908     }
909 
910     if (!SMIME_crlf_copy(data, cmsbio, flags)) {
911         goto err;
912     }
913 
914     (void)BIO_flush(cmsbio);
915 
916     if (!CMS_dataFinal(cms, cmsbio)) {
917         ERR_raise(ERR_LIB_CMS, CMS_R_CMS_DATAFINAL_ERROR);
918         goto err;
919     }
920 
921     ret = 1;
922 
923 err:
924     do_free_upto(cmsbio, dcont);
925 
926     return ret;
927 
928 }
929 
CMS_final_digest(CMS_ContentInfo * cms,const unsigned char * md,unsigned int mdlen,BIO * dcont,unsigned int flags)930 int CMS_final_digest(CMS_ContentInfo *cms,
931                      const unsigned char *md, unsigned int mdlen,
932                      BIO *dcont, unsigned int flags)
933 {
934     BIO *cmsbio;
935     int ret = 0;
936 
937     if ((cmsbio = CMS_dataInit(cms, dcont)) == NULL) {
938         ERR_raise(ERR_LIB_CMS, CMS_R_CMS_LIB);
939         return 0;
940     }
941 
942     (void)BIO_flush(cmsbio);
943 
944     if (!ossl_cms_DataFinal(cms, cmsbio, md, mdlen)) {
945         ERR_raise(ERR_LIB_CMS, CMS_R_CMS_DATAFINAL_ERROR);
946         goto err;
947     }
948     ret = 1;
949 
950 err:
951     do_free_upto(cmsbio, dcont);
952     return ret;
953 }
954 
955 #ifndef OPENSSL_NO_ZLIB
956 
CMS_uncompress(CMS_ContentInfo * cms,BIO * dcont,BIO * out,unsigned int flags)957 int CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out,
958                    unsigned int flags)
959 {
960     BIO *cont;
961     int r;
962 
963     if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_id_smime_ct_compressedData) {
964         ERR_raise(ERR_LIB_CMS, CMS_R_TYPE_NOT_COMPRESSED_DATA);
965         return 0;
966     }
967 
968     if (dcont == NULL && !check_content(cms))
969         return 0;
970 
971     cont = CMS_dataInit(cms, dcont);
972     if (cont == NULL)
973         return 0;
974     r = cms_copy_content(out, cont, flags);
975     do_free_upto(cont, dcont);
976     return r;
977 }
978 
CMS_compress(BIO * in,int comp_nid,unsigned int flags)979 CMS_ContentInfo *CMS_compress(BIO *in, int comp_nid, unsigned int flags)
980 {
981     CMS_ContentInfo *cms;
982 
983     if (comp_nid <= 0)
984         comp_nid = NID_zlib_compression;
985     cms = ossl_cms_CompressedData_create(comp_nid, NULL, NULL);
986     if (cms == NULL)
987         return NULL;
988 
989     if (!(flags & CMS_DETACHED))
990         CMS_set_detached(cms, 0);
991 
992     if ((flags & CMS_STREAM) || CMS_final(cms, in, NULL, flags))
993         return cms;
994 
995     CMS_ContentInfo_free(cms);
996     return NULL;
997 }
998 
999 #else
1000 
CMS_uncompress(CMS_ContentInfo * cms,BIO * dcont,BIO * out,unsigned int flags)1001 int CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out,
1002                    unsigned int flags)
1003 {
1004     ERR_raise(ERR_LIB_CMS, CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM);
1005     return 0;
1006 }
1007 
CMS_compress(BIO * in,int comp_nid,unsigned int flags)1008 CMS_ContentInfo *CMS_compress(BIO *in, int comp_nid, unsigned int flags)
1009 {
1010     ERR_raise(ERR_LIB_CMS, CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM);
1011     return NULL;
1012 }
1013 
1014 #endif
1015