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