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