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