aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIngo Klöcker <[email protected]>2023-12-14 09:59:47 +0000
committerIngo Klöcker <[email protected]>2023-12-19 12:07:45 +0000
commit0221d7f28a315d305409cf2dcae853c22ad94d31 (patch)
treef7ae74a09d54e224a69dd6689d30e79c643c02e7
parentdoc: Fix documentation for creating encrypted/signed archive (diff)
downloadgpgme-0221d7f28a315d305409cf2dcae853c22ad94d31.tar.gz
gpgme-0221d7f28a315d305409cf2dcae853c22ad94d31.zip
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
-rw-r--r--NEWS7
-rw-r--r--doc/gpgme.texi18
-rw-r--r--src/engine-gpg.c34
-rw-r--r--src/engine-gpgsm.c2
-rw-r--r--src/engine-uiserver.c2
-rw-r--r--src/gpgme.h.in3
-rw-r--r--tests/run-encrypt.c15
7 files changed, 73 insertions, 8 deletions
diff --git a/NEWS b/NEWS
index 2475a877..81bd564a 100644
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,13 @@
Noteworthy changes in version 1.23.3 (unrelease)
-------------------------------------------------
+ * Extended gpgme_op_encrypt* and gpgme_op_encrypt_sign* to allow reading
+ the input data directly from a file. [T6550]
+
+ * Interface changes relative to the 1.23.2 release:
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ GPGME_ENCRYPT_FILE NEW.
+
Noteworthy changes in version 1.23.2 (2023-11-28)
-------------------------------------------------
diff --git a/doc/gpgme.texi b/doc/gpgme.texi
index 11f90133..0ec70a55 100644
--- a/doc/gpgme.texi
+++ b/doc/gpgme.texi
@@ -6557,7 +6557,14 @@ file set with @code{gpgme_data_set_file_name} for the data object
@var{cipher}. The type of the ciphertext created is determined by the
@acronym{ASCII} armor (or, if that is not set, by the encoding specified
for @var{cipher}) and the text mode attributes set for the context
-@var{ctx}.
+@var{ctx}. If a filename has been set with @code{gpgme_data_set_file_name}
+for the data object @var{plain} then this filename is stored in the
+ciphertext.
+
+If the flag @code{GPGME_ENCRYPT_FILE} is set and a filename has been set
+with @code{gpgme_data_set_file_name} for the data object @var{plain},
+then this filename is passed to gpg, so that gpg reads the plaintext
+directly from this file instead of from the data object @var{plain}.
If the flag @code{GPGME_ENCRYPT_ARCHIVE} is set, then an encrypted
archive is created from the files and directories given as NUL-separated
@@ -6653,6 +6660,15 @@ NUL-separated list of file paths and directory paths that shall be
encrypted into an archive. This feature is currently only supported
for the OpenPGP crypto engine and requires GnuPG 2.4.1.
+@item GPGME_ENCRYPT_FILE
+@since{1.24.0}
+
+The @code{GPGME_ENCRYPT_FILE} symbol specifies that the filename set
+with @code{gpgme_data_set_file_name} for the data object @var{plain}
+is passed to gpg, so that gpg reads the plaintext directly from this
+file instead of from the data object @var{plain}. This feature is
+currently only supported for the OpenPGP crypto engine.
+
@end table
If @code{GPG_ERR_UNUSABLE_PUBKEY} is returned, some recipients in
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;
diff --git a/tests/run-encrypt.c b/tests/run-encrypt.c
index 80c40729..8e8b559c 100644
--- a/tests/run-encrypt.c
+++ b/tests/run-encrypt.c
@@ -151,6 +151,7 @@ show_usage (int ex)
" --no-symkey-cache disable the use of that cache\n"
" --wrap assume input is valid OpenPGP message\n"
" --symmetric encrypt symmetric (OpenPGP only)\n"
+ " --direct-file-io pass FILE instead of stream with content of FILE to backend\n"
" --archive encrypt given file or directory into an archive\n"
" --directory DIR switch to directory DIR before encrypting into an archive\n"
" --output FILE write output to FILE instead of stdout\n"
@@ -186,6 +187,7 @@ main (int argc, char **argv)
int no_symkey_cache = 0;
int diagnostics = 0;
int sign = 0;
+ int direct_file_io = 0;
if (argc)
{ argc--; argv++; }
@@ -289,6 +291,11 @@ main (int argc, char **argv)
no_symkey_cache = 1;
argc--; argv++;
}
+ else if (!strcmp (*argv, "--direct-file-io"))
+ {
+ direct_file_io = 1;
+ argc--; argv++;
+ }
else if (!strcmp (*argv, "--archive"))
{
flags |= GPGME_ENCRYPT_ARCHIVE;
@@ -378,6 +385,14 @@ main (int argc, char **argv)
fail_if_err (err);
}
}
+ else if (direct_file_io)
+ {
+ flags |= GPGME_ENCRYPT_FILE;
+ err = gpgme_data_new (&in);
+ fail_if_err (err);
+ err = gpgme_data_set_file_name (in, *argv);
+ fail_if_err (err);
+ }
else
{
err = gpgme_data_new_from_file (&in, *argv, 1);