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