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