From 0221d7f28a315d305409cf2dcae853c22ad94d31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ingo=20Kl=C3=B6cker?= Date: Thu, 14 Dec 2023 10:59:47 +0100 Subject: core: Support direct encryption of file with gpg * src/gpgme.h.in (GPGME_ENCRYPT_FILE): New encryption flag. * src/engine-gpg.c (gpg_encrypt, gpg_encrypt_sign): Check for incompatible flags. Pass filename instead of fd to gpg when new flag is set. * src/engine-gpgsm.c (gpgsm_encrypt): Return error if new flag is set. * src/engine-uiserver.c (uiserver_encrypt): Ditto. * tests/run-encrypt.c (show_usage): New option --direct-file-io. (main): Parse new option. Make gpg read the input file itself if the option is given. -- With this change the gpgme_op_encrypt* and gpgme_op_encrypt_sign* functions gain the possibility to make gpg read the data to (sign and) encrypt directly from a file instead of from an input FD to which it is written by gpgme. GnuPG-bug-id: 6550 --- src/engine-gpg.c | 34 ++++++++++++++++++++++++++++++---- src/engine-gpgsm.c | 2 +- src/engine-uiserver.c | 2 +- src/gpgme.h.in | 3 ++- 4 files changed, 34 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/engine-gpg.c b/src/engine-gpg.c index 8c9f62fb..123760be 100644 --- a/src/engine-gpg.c +++ b/src/engine-gpg.c @@ -2317,12 +2317,16 @@ gpg_encrypt (void *engine, gpgme_key_t recp[], const char *recpstring, { engine_gpg_t gpg = engine; gpgme_error_t err = 0; + const char *file_name = NULL; gpg->flags.use_gpgtar = !!(flags & GPGME_ENCRYPT_ARCHIVE); if (gpg->flags.use_gpgtar && !have_usable_gpgtar (gpg)) return gpg_error (GPG_ERR_NOT_SUPPORTED); + if (gpg->flags.use_gpgtar && (flags & GPGME_ENCRYPT_FILE)) + return gpg_error (GPG_ERR_INV_VALUE); + if (gpg->flags.use_gpgtar && (flags & GPGME_ENCRYPT_WRAP)) return gpg_error (GPG_ERR_INV_VALUE); @@ -2390,9 +2394,10 @@ gpg_encrypt (void *engine, gpgme_key_t recp[], const char *recpstring, err = add_data (gpg, ciph, 1, 1); } } + if (!err) + file_name = gpgme_data_get_file_name (plain); if (gpg->flags.use_gpgtar) { - const char *file_name = gpgme_data_get_file_name (plain); if (!err && file_name) { err = add_arg (gpg, "--directory"); @@ -2411,9 +2416,17 @@ gpg_encrypt (void *engine, gpgme_key_t recp[], const char *recpstring, if (!err) err = add_data (gpg, plain, 0, 0); } + else if (flags & GPGME_ENCRYPT_FILE) + { + if (!err) + err = add_arg (gpg, "--"); + if (!err && (!file_name || !*file_name)) + err = gpg_error (GPG_ERR_INV_VALUE); + if (!err) + err = add_arg (gpg, file_name); + } else { - const char *file_name = gpgme_data_get_file_name (plain); if (!err && file_name) err = add_gpg_arg_with_value (gpg, "--set-filename=", file_name, 0); if (!err) @@ -2440,12 +2453,16 @@ gpg_encrypt_sign (void *engine, gpgme_key_t recp[], { engine_gpg_t gpg = engine; gpgme_error_t err = 0; + const char *file_name = NULL; gpg->flags.use_gpgtar = !!(flags & GPGME_ENCRYPT_ARCHIVE); if (gpg->flags.use_gpgtar && !have_usable_gpgtar (gpg)) return gpg_error (GPG_ERR_NOT_SUPPORTED); + if (gpg->flags.use_gpgtar && (flags & GPGME_ENCRYPT_FILE)) + return gpg_error (GPG_ERR_INV_VALUE); + if (recp || recpstring) err = add_arg (gpg, "--encrypt"); @@ -2510,9 +2527,10 @@ gpg_encrypt_sign (void *engine, gpgme_key_t recp[], err = add_data (gpg, ciph, 1, 1); } } + if (!err) + file_name = gpgme_data_get_file_name (plain); if (gpg->flags.use_gpgtar) { - const char *file_name = gpgme_data_get_file_name (plain); if (!err && file_name) { err = add_arg (gpg, "--directory"); @@ -2531,9 +2549,17 @@ gpg_encrypt_sign (void *engine, gpgme_key_t recp[], if (!err) err = add_data (gpg, plain, 0, 0); } + else if (flags & GPGME_ENCRYPT_FILE) + { + if (!err) + err = add_arg (gpg, "--"); + if (!err && (!file_name || !*file_name)) + err = gpg_error (GPG_ERR_INV_VALUE); + if (!err) + err = add_arg (gpg, file_name); + } else { - const char *file_name = gpgme_data_get_file_name (plain); if (!err && file_name) err = add_gpg_arg_with_value (gpg, "--set-filename=", file_name, 0); if (!err) diff --git a/src/engine-gpgsm.c b/src/engine-gpgsm.c index 24b142c5..014507d4 100644 --- a/src/engine-gpgsm.c +++ b/src/engine-gpgsm.c @@ -1536,7 +1536,7 @@ gpgsm_encrypt (void *engine, gpgme_key_t recp[], const char *recpstring, if (!recp && !recpstring) /* Symmetric only */ return gpg_error (GPG_ERR_NOT_IMPLEMENTED); - if (flags & GPGME_ENCRYPT_ARCHIVE) + if (flags & (GPGME_ENCRYPT_ARCHIVE | GPGME_ENCRYPT_FILE)) return gpg_error (GPG_ERR_NOT_IMPLEMENTED); if ((flags & GPGME_ENCRYPT_NO_ENCRYPT_TO)) diff --git a/src/engine-uiserver.c b/src/engine-uiserver.c index a298bec6..a116feb9 100644 --- a/src/engine-uiserver.c +++ b/src/engine-uiserver.c @@ -1145,7 +1145,7 @@ uiserver_encrypt (void *engine, gpgme_key_t recp[], const char *recpstring, else return gpgme_error (GPG_ERR_UNSUPPORTED_PROTOCOL); - if (flags & GPGME_ENCRYPT_ARCHIVE) + if (flags & (GPGME_ENCRYPT_ARCHIVE | GPGME_ENCRYPT_FILE)) return gpg_error (GPG_ERR_NOT_IMPLEMENTED); if (flags & GPGME_ENCRYPT_PREPARE) diff --git a/src/gpgme.h.in b/src/gpgme.h.in index d44994a6..ccc7b026 100644 --- a/src/gpgme.h.in +++ b/src/gpgme.h.in @@ -1326,7 +1326,8 @@ typedef enum GPGME_ENCRYPT_THROW_KEYIDS = 64, GPGME_ENCRYPT_WRAP = 128, GPGME_ENCRYPT_WANT_ADDRESS = 256, - GPGME_ENCRYPT_ARCHIVE = 512 + GPGME_ENCRYPT_ARCHIVE = 512, + GPGME_ENCRYPT_FILE = 1024 } gpgme_encrypt_flags_t; -- cgit v1.2.3