Fix safestack issues in asn1.h
[openssl.git] / crypto / pkcs7 / pk7_smime.c
1 /*
2  * Copyright 1999-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 /* Simple PKCS#7 processing functions */
11
12 #include <stdio.h>
13 #include "internal/cryptlib.h"
14 #include <openssl/x509.h>
15 #include <openssl/x509v3.h>
16 #include "pk7_local.h"
17
18 #define BUFFERSIZE 4096
19
20 DEFINE_STACK_OF(PKCS7_SIGNER_INFO)
21
22 static int pkcs7_copy_existing_digest(PKCS7 *p7, PKCS7_SIGNER_INFO *si);
23
24 PKCS7 *PKCS7_sign_with_libctx(X509 *signcert, EVP_PKEY *pkey,
25                               STACK_OF(X509) *certs, BIO *data, int flags,
26                               OPENSSL_CTX *libctx, const char *propq)
27 {
28     PKCS7 *p7;
29     int i;
30
31     if ((p7 = PKCS7_new_with_libctx(libctx, propq)) == NULL) {
32         PKCS7err(0, ERR_R_MALLOC_FAILURE);
33         return NULL;
34     }
35
36     if (!PKCS7_set_type(p7, NID_pkcs7_signed))
37         goto err;
38
39     if (!PKCS7_content_new(p7, NID_pkcs7_data))
40         goto err;
41
42     if (pkey && !PKCS7_sign_add_signer(p7, signcert, pkey, NULL, flags)) {
43         PKCS7err(0, PKCS7_R_PKCS7_ADD_SIGNER_ERROR);
44         goto err;
45     }
46
47     if (!(flags & PKCS7_NOCERTS)) {
48         for (i = 0; i < sk_X509_num(certs); i++) {
49             if (!PKCS7_add_certificate(p7, sk_X509_value(certs, i)))
50                 goto err;
51         }
52     }
53
54     if (flags & PKCS7_DETACHED)
55         PKCS7_set_detached(p7, 1);
56
57     if (flags & (PKCS7_STREAM | PKCS7_PARTIAL))
58         return p7;
59
60     if (PKCS7_final(p7, data, flags))
61         return p7;
62
63  err:
64     PKCS7_free(p7);
65     return NULL;
66 }
67
68 PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs,
69                   BIO *data, int flags)
70 {
71     return PKCS7_sign_with_libctx(signcert, pkey, certs, data, flags, NULL, NULL);
72 }
73
74
75 int PKCS7_final(PKCS7 *p7, BIO *data, int flags)
76 {
77     BIO *p7bio;
78     int ret = 0;
79
80     if ((p7bio = PKCS7_dataInit(p7, NULL)) == NULL) {
81         PKCS7err(PKCS7_F_PKCS7_FINAL, ERR_R_MALLOC_FAILURE);
82         return 0;
83     }
84
85     SMIME_crlf_copy(data, p7bio, flags);
86
87     (void)BIO_flush(p7bio);
88
89     if (!PKCS7_dataFinal(p7, p7bio)) {
90         PKCS7err(PKCS7_F_PKCS7_FINAL, PKCS7_R_PKCS7_DATASIGN);
91         goto err;
92     }
93     ret = 1;
94 err:
95     BIO_free_all(p7bio);
96
97     return ret;
98
99 }
100
101 /* Check to see if a cipher exists and if so add S/MIME capabilities */
102
103 static int add_cipher_smcap(STACK_OF(X509_ALGOR) *sk, int nid, int arg)
104 {
105     if (EVP_get_cipherbynid(nid))
106         return PKCS7_simple_smimecap(sk, nid, arg);
107     return 1;
108 }
109
110 static int add_digest_smcap(STACK_OF(X509_ALGOR) *sk, int nid, int arg)
111 {
112     if (EVP_get_digestbynid(nid))
113         return PKCS7_simple_smimecap(sk, nid, arg);
114     return 1;
115 }
116
117 PKCS7_SIGNER_INFO *PKCS7_sign_add_signer(PKCS7 *p7, X509 *signcert,
118                                          EVP_PKEY *pkey, const EVP_MD *md,
119                                          int flags)
120 {
121     PKCS7_SIGNER_INFO *si = NULL;
122     STACK_OF(X509_ALGOR) *smcap = NULL;
123
124     if (!X509_check_private_key(signcert, pkey)) {
125         PKCS7err(PKCS7_F_PKCS7_SIGN_ADD_SIGNER,
126                  PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE);
127         return NULL;
128     }
129
130     if ((si = PKCS7_add_signature(p7, signcert, pkey, md)) == NULL) {
131         PKCS7err(PKCS7_F_PKCS7_SIGN_ADD_SIGNER,
132                  PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR);
133         return NULL;
134     }
135
136     si->ctx = pkcs7_get0_ctx(p7);
137     if (!(flags & PKCS7_NOCERTS)) {
138         if (!PKCS7_add_certificate(p7, signcert))
139             goto err;
140     }
141
142     if (!(flags & PKCS7_NOATTR)) {
143         if (!PKCS7_add_attrib_content_type(si, NULL))
144             goto err;
145         /* Add SMIMECapabilities */
146         if (!(flags & PKCS7_NOSMIMECAP)) {
147             if ((smcap = sk_X509_ALGOR_new_null()) == NULL) {
148                 PKCS7err(PKCS7_F_PKCS7_SIGN_ADD_SIGNER, ERR_R_MALLOC_FAILURE);
149                 goto err;
150             }
151             if (!add_cipher_smcap(smcap, NID_aes_256_cbc, -1)
152                 || !add_digest_smcap(smcap, NID_id_GostR3411_2012_256, -1)
153                 || !add_digest_smcap(smcap, NID_id_GostR3411_2012_512, -1)
154                 || !add_digest_smcap(smcap, NID_id_GostR3411_94, -1)
155                 || !add_cipher_smcap(smcap, NID_id_Gost28147_89, -1)
156                 || !add_cipher_smcap(smcap, NID_aes_192_cbc, -1)
157                 || !add_cipher_smcap(smcap, NID_aes_128_cbc, -1)
158                 || !add_cipher_smcap(smcap, NID_des_ede3_cbc, -1)
159                 || !add_cipher_smcap(smcap, NID_rc2_cbc, 128)
160                 || !add_cipher_smcap(smcap, NID_rc2_cbc, 64)
161                 || !add_cipher_smcap(smcap, NID_des_cbc, -1)
162                 || !add_cipher_smcap(smcap, NID_rc2_cbc, 40)
163                 || !PKCS7_add_attrib_smimecap(si, smcap))
164                 goto err;
165             sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free);
166             smcap = NULL;
167         }
168         if (flags & PKCS7_REUSE_DIGEST) {
169             if (!pkcs7_copy_existing_digest(p7, si))
170                 goto err;
171             if (!(flags & PKCS7_PARTIAL)
172                 && !PKCS7_SIGNER_INFO_sign(si))
173                 goto err;
174         }
175     }
176     return si;
177  err:
178     sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free);
179     return NULL;
180 }
181
182 /*
183  * Search for a digest matching SignerInfo digest type and if found copy
184  * across.
185  */
186
187 static int pkcs7_copy_existing_digest(PKCS7 *p7, PKCS7_SIGNER_INFO *si)
188 {
189     int i;
190     STACK_OF(PKCS7_SIGNER_INFO) *sinfos;
191     PKCS7_SIGNER_INFO *sitmp;
192     ASN1_OCTET_STRING *osdig = NULL;
193     sinfos = PKCS7_get_signer_info(p7);
194     for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(sinfos); i++) {
195         sitmp = sk_PKCS7_SIGNER_INFO_value(sinfos, i);
196         if (si == sitmp)
197             break;
198         if (sk_X509_ATTRIBUTE_num(sitmp->auth_attr) <= 0)
199             continue;
200         if (!OBJ_cmp(si->digest_alg->algorithm, sitmp->digest_alg->algorithm)) {
201             osdig = PKCS7_digest_from_attributes(sitmp->auth_attr);
202             break;
203         }
204
205     }
206
207     if (osdig != NULL)
208         return PKCS7_add1_attrib_digest(si, osdig->data, osdig->length);
209
210     PKCS7err(PKCS7_F_PKCS7_COPY_EXISTING_DIGEST,
211              PKCS7_R_NO_MATCHING_DIGEST_TYPE_FOUND);
212     return 0;
213 }
214
215 int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store,
216                  BIO *indata, BIO *out, int flags)
217 {
218     STACK_OF(X509) *signers;
219     X509 *signer;
220     STACK_OF(PKCS7_SIGNER_INFO) *sinfos;
221     PKCS7_SIGNER_INFO *si;
222     X509_STORE_CTX *cert_ctx = NULL;
223     char *buf = NULL;
224     int i, j = 0, k, ret = 0;
225     BIO *p7bio = NULL;
226     BIO *tmpin = NULL, *tmpout = NULL;
227     const PKCS7_CTX *p7_ctx;
228
229     if (p7 == NULL) {
230         PKCS7err(0, PKCS7_R_INVALID_NULL_POINTER);
231         return 0;
232     }
233
234     if (!PKCS7_type_is_signed(p7)) {
235         PKCS7err(0, PKCS7_R_WRONG_CONTENT_TYPE);
236         return 0;
237     }
238
239     /* Check for no data and no content: no data to verify signature */
240     if (PKCS7_get_detached(p7) && !indata) {
241         PKCS7err(0, PKCS7_R_NO_CONTENT);
242         return 0;
243     }
244
245     if (flags & PKCS7_NO_DUAL_CONTENT) {
246         /*
247          * This was originally "#if 0" because we thought that only old broken
248          * Netscape did this.  It turns out that Authenticode uses this kind
249          * of "extended" PKCS7 format, and things like UEFI secure boot and
250          * tools like osslsigncode need it.  In Authenticode the verification
251          * process is different, but the existing PKCs7 verification works.
252          */
253         if (!PKCS7_get_detached(p7) && indata) {
254             PKCS7err(0, PKCS7_R_CONTENT_AND_DATA_PRESENT);
255             return 0;
256         }
257     }
258
259     sinfos = PKCS7_get_signer_info(p7);
260
261     if (!sinfos || !sk_PKCS7_SIGNER_INFO_num(sinfos)) {
262         PKCS7err(0, PKCS7_R_NO_SIGNATURES_ON_DATA);
263         return 0;
264     }
265
266     signers = PKCS7_get0_signers(p7, certs, flags);
267     if (signers == NULL)
268         return 0;
269
270     /* Now verify the certificates */
271     p7_ctx = pkcs7_get0_ctx(p7);
272     cert_ctx = X509_STORE_CTX_new_with_libctx(p7_ctx->libctx, p7_ctx->propq);
273     if (cert_ctx == NULL)
274         goto err;
275     if (!(flags & PKCS7_NOVERIFY))
276         for (k = 0; k < sk_X509_num(signers); k++) {
277             signer = sk_X509_value(signers, k);
278             if (!(flags & PKCS7_NOCHAIN)) {
279                 if (!X509_STORE_CTX_init(cert_ctx, store, signer,
280                                          p7->d.sign->cert)) {
281                     PKCS7err(0, ERR_R_X509_LIB);
282                     goto err;
283                 }
284                 X509_STORE_CTX_set_default(cert_ctx, "smime_sign");
285             } else if (!X509_STORE_CTX_init(cert_ctx, store, signer, NULL)) {
286                 PKCS7err(0, ERR_R_X509_LIB);
287                 goto err;
288             }
289             if (!(flags & PKCS7_NOCRL))
290                 X509_STORE_CTX_set0_crls(cert_ctx, p7->d.sign->crl);
291             i = X509_verify_cert(cert_ctx);
292             if (i <= 0)
293                 j = X509_STORE_CTX_get_error(cert_ctx);
294             X509_STORE_CTX_cleanup(cert_ctx);
295             if (i <= 0) {
296                 PKCS7err(0, PKCS7_R_CERTIFICATE_VERIFY_ERROR);
297                 ERR_add_error_data(2, "Verify error:",
298                                    X509_verify_cert_error_string(j));
299                 goto err;
300             }
301             /* Check for revocation status here */
302         }
303
304     /*
305      * Performance optimization: if the content is a memory BIO then store
306      * its contents in a temporary read only memory BIO. This avoids
307      * potentially large numbers of slow copies of data which will occur when
308      * reading from a read write memory BIO when signatures are calculated.
309      */
310
311     if (indata && (BIO_method_type(indata) == BIO_TYPE_MEM)) {
312         char *ptr;
313         long len;
314         len = BIO_get_mem_data(indata, &ptr);
315         tmpin = BIO_new_mem_buf(ptr, len);
316         if (tmpin == NULL) {
317             PKCS7err(0, ERR_R_MALLOC_FAILURE);
318             goto err;
319         }
320     } else
321         tmpin = indata;
322
323     if ((p7bio = PKCS7_dataInit(p7, tmpin)) == NULL)
324         goto err;
325
326     if (flags & PKCS7_TEXT) {
327         if ((tmpout = BIO_new(BIO_s_mem())) == NULL) {
328             PKCS7err(0, ERR_R_MALLOC_FAILURE);
329             goto err;
330         }
331         BIO_set_mem_eof_return(tmpout, 0);
332     } else
333         tmpout = out;
334
335     /* We now have to 'read' from p7bio to calculate digests etc. */
336     if ((buf = OPENSSL_malloc(BUFFERSIZE)) == NULL) {
337         PKCS7err(0, ERR_R_MALLOC_FAILURE);
338         goto err;
339     }
340     for (;;) {
341         i = BIO_read(p7bio, buf, BUFFERSIZE);
342         if (i <= 0)
343             break;
344         if (tmpout)
345             BIO_write(tmpout, buf, i);
346     }
347
348     if (flags & PKCS7_TEXT) {
349         if (!SMIME_text(tmpout, out)) {
350             PKCS7err(0, PKCS7_R_SMIME_TEXT_ERROR);
351             BIO_free(tmpout);
352             goto err;
353         }
354         BIO_free(tmpout);
355     }
356
357     /* Now Verify All Signatures */
358     if (!(flags & PKCS7_NOSIGS))
359         for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(sinfos); i++) {
360             si = sk_PKCS7_SIGNER_INFO_value(sinfos, i);
361             signer = sk_X509_value(signers, i);
362             j = PKCS7_signatureVerify(p7bio, p7, si, signer);
363             if (j <= 0) {
364                 PKCS7err(0, PKCS7_R_SIGNATURE_FAILURE);
365                 goto err;
366             }
367         }
368
369     ret = 1;
370
371  err:
372     X509_STORE_CTX_free(cert_ctx);
373     OPENSSL_free(buf);
374     if (tmpin == indata) {
375         if (indata)
376             BIO_pop(p7bio);
377     }
378     BIO_free_all(p7bio);
379     sk_X509_free(signers);
380     return ret;
381 }
382
383 STACK_OF(X509) *PKCS7_get0_signers(PKCS7 *p7, STACK_OF(X509) *certs,
384                                    int flags)
385 {
386     STACK_OF(X509) *signers;
387     STACK_OF(PKCS7_SIGNER_INFO) *sinfos;
388     PKCS7_SIGNER_INFO *si;
389     PKCS7_ISSUER_AND_SERIAL *ias;
390     X509 *signer;
391     int i;
392
393     if (p7 == NULL) {
394         PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS, PKCS7_R_INVALID_NULL_POINTER);
395         return NULL;
396     }
397
398     if (!PKCS7_type_is_signed(p7)) {
399         PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS, PKCS7_R_WRONG_CONTENT_TYPE);
400         return NULL;
401     }
402
403     /* Collect all the signers together */
404
405     sinfos = PKCS7_get_signer_info(p7);
406
407     if (sk_PKCS7_SIGNER_INFO_num(sinfos) <= 0) {
408         PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS, PKCS7_R_NO_SIGNERS);
409         return 0;
410     }
411
412     if ((signers = sk_X509_new_null()) == NULL) {
413         PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS, ERR_R_MALLOC_FAILURE);
414         return NULL;
415     }
416
417     for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(sinfos); i++) {
418         si = sk_PKCS7_SIGNER_INFO_value(sinfos, i);
419         ias = si->issuer_and_serial;
420         signer = NULL;
421         /* If any certificates passed they take priority */
422         if (certs)
423             signer = X509_find_by_issuer_and_serial(certs,
424                                                     ias->issuer, ias->serial);
425         if (!signer && !(flags & PKCS7_NOINTERN)
426             && p7->d.sign->cert)
427             signer =
428                 X509_find_by_issuer_and_serial(p7->d.sign->cert,
429                                                ias->issuer, ias->serial);
430         if (!signer) {
431             PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS,
432                      PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND);
433             sk_X509_free(signers);
434             return 0;
435         }
436
437         if (!sk_X509_push(signers, signer)) {
438             sk_X509_free(signers);
439             return NULL;
440         }
441     }
442     return signers;
443 }
444
445 /* Build a complete PKCS#7 enveloped data */
446
447 PKCS7 *PKCS7_encrypt_with_libctx(STACK_OF(X509) *certs, BIO *in,
448                                  const EVP_CIPHER *cipher, int flags,
449                                  OPENSSL_CTX *libctx, const char *propq)
450 {
451     PKCS7 *p7;
452     BIO *p7bio = NULL;
453     int i;
454     X509 *x509;
455
456     if ((p7 = PKCS7_new_with_libctx(libctx, propq)) == NULL) {
457         PKCS7err(0, ERR_R_MALLOC_FAILURE);
458         return NULL;
459     }
460
461     if (!PKCS7_set_type(p7, NID_pkcs7_enveloped))
462         goto err;
463     if (!PKCS7_set_cipher(p7, cipher)) {
464         PKCS7err(0, PKCS7_R_ERROR_SETTING_CIPHER);
465         goto err;
466     }
467
468     for (i = 0; i < sk_X509_num(certs); i++) {
469         x509 = sk_X509_value(certs, i);
470         if (!PKCS7_add_recipient(p7, x509)) {
471             PKCS7err(0, PKCS7_R_ERROR_ADDING_RECIPIENT);
472             goto err;
473         }
474     }
475
476     if (flags & PKCS7_STREAM)
477         return p7;
478
479     if (PKCS7_final(p7, in, flags))
480         return p7;
481
482  err:
483
484     BIO_free_all(p7bio);
485     PKCS7_free(p7);
486     return NULL;
487
488 }
489
490 PKCS7 *PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER *cipher,
491                      int flags)
492 {
493     return PKCS7_encrypt_with_libctx(certs, in, cipher, flags, NULL, NULL);
494 }
495
496
497 int PKCS7_decrypt(PKCS7 *p7, EVP_PKEY *pkey, X509 *cert, BIO *data, int flags)
498 {
499     BIO *tmpmem;
500     int ret = 0, i;
501     char *buf = NULL;
502
503     if (p7 == NULL) {
504         PKCS7err(PKCS7_F_PKCS7_DECRYPT, PKCS7_R_INVALID_NULL_POINTER);
505         return 0;
506     }
507
508     if (!PKCS7_type_is_enveloped(p7)) {
509         PKCS7err(PKCS7_F_PKCS7_DECRYPT, PKCS7_R_WRONG_CONTENT_TYPE);
510         return 0;
511     }
512
513     if (cert && !X509_check_private_key(cert, pkey)) {
514         PKCS7err(PKCS7_F_PKCS7_DECRYPT,
515                  PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE);
516         return 0;
517     }
518
519     if ((tmpmem = PKCS7_dataDecode(p7, pkey, NULL, cert)) == NULL) {
520         PKCS7err(PKCS7_F_PKCS7_DECRYPT, PKCS7_R_DECRYPT_ERROR);
521         return 0;
522     }
523
524     if (flags & PKCS7_TEXT) {
525         BIO *tmpbuf, *bread;
526         /* Encrypt BIOs can't do BIO_gets() so add a buffer BIO */
527         if ((tmpbuf = BIO_new(BIO_f_buffer())) == NULL) {
528             PKCS7err(PKCS7_F_PKCS7_DECRYPT, ERR_R_MALLOC_FAILURE);
529             BIO_free_all(tmpmem);
530             return 0;
531         }
532         if ((bread = BIO_push(tmpbuf, tmpmem)) == NULL) {
533             PKCS7err(PKCS7_F_PKCS7_DECRYPT, ERR_R_MALLOC_FAILURE);
534             BIO_free_all(tmpbuf);
535             BIO_free_all(tmpmem);
536             return 0;
537         }
538         ret = SMIME_text(bread, data);
539         if (ret > 0 && BIO_method_type(tmpmem) == BIO_TYPE_CIPHER) {
540             if (!BIO_get_cipher_status(tmpmem))
541                 ret = 0;
542         }
543         BIO_free_all(bread);
544         return ret;
545     }
546     if ((buf = OPENSSL_malloc(BUFFERSIZE)) == NULL) {
547         PKCS7err(PKCS7_F_PKCS7_DECRYPT, ERR_R_MALLOC_FAILURE);
548         goto err;
549     }
550     for (;;) {
551         i = BIO_read(tmpmem, buf, BUFFERSIZE);
552         if (i <= 0) {
553             ret = 1;
554             if (BIO_method_type(tmpmem) == BIO_TYPE_CIPHER) {
555                 if (!BIO_get_cipher_status(tmpmem))
556                     ret = 0;
557             }
558
559             break;
560         }
561         if (BIO_write(data, buf, i) != i) {
562             break;
563         }
564     }
565 err:
566     OPENSSL_free(buf);
567     BIO_free_all(tmpmem);
568     return ret;
569 }