core: Support usage of gpgtar for decrypting an encrypted archive
* src/gpgme.h.in (GPGME_DECRYPT_ARCHIVE): New decryption flag. * src/engine-gpg.c (gpg_decrypt): Set use_gpgtar engine flag if GPGME_DECRYPT_ARCHIVE flag is set. Check for new enough gpg and incompatible flags. Use add_gpg_arg_with_value for gpg-only options with a value and add_gpg_arg for gpg-only options without a value. Set extra options for gpgtar and pass input data to stdin when using gpgtar. * tests/run-decrypt.c (show_usage): New options --archive and --directory. (main): Parse new options. Decrypt with gpgtar if --archive is given. Set file name of output data to value of --directory option. -- GnuPG-bug-id: 6342
This commit is contained in:
parent
419adf41af
commit
95ea3bf831
4
NEWS
4
NEWS
@ -11,6 +11,9 @@ Noteworthy changes in version 1.18.1 (unreleased)
|
||||
gpgme_op_sign* to allow creating an encrypted and/or signed
|
||||
archive. [T6342]
|
||||
|
||||
* Extended gpgme_op_decrypt* and gpgme_op_decrypt_verify* to allow
|
||||
extracting an encrypted and/or signed archive. [T6342]
|
||||
|
||||
* cpp: Handle error when trying to sign expired keys. [T6155]
|
||||
|
||||
* cpp, qt: Fix building with C++11. [T6141]
|
||||
@ -30,6 +33,7 @@ Noteworthy changes in version 1.18.1 (unreleased)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
gpgme_get_ctx_flag EXTENDED: New flag 'no-auto-check-trustdb'.
|
||||
gpgme_set_ctx_flag EXTENDED: New flag 'no-auto-check-trustdb'.
|
||||
GPGME_DECRYPT_ARCHIVE NEW.
|
||||
GPGME_ENCRYPT_ARCHIVE NEW.
|
||||
GPGME_SIG_MODE_ARCHIVE NEW.
|
||||
cpp: GpgGenCardKeyInteractor::Curve NEW.
|
||||
|
@ -3172,8 +3172,8 @@ The string given in @var{value} is passed to the GnuPG engine to override
|
||||
the session key for decryption. The format of that session key is
|
||||
specific to GnuPG and can be retrieved during a decrypt operation when
|
||||
the context flag "export-session-key" is enabled. Please be aware that
|
||||
using this feature with GnuPG < 2.1.16 will leak the session key on
|
||||
many platforms via ps(1).
|
||||
using this feature with GnuPG < 2.1.16 or when decrypting an archive
|
||||
will leak the session key on many platforms via ps(1).
|
||||
|
||||
@item "auto-key-retrieve"
|
||||
Setting the @var{value} to "1" asks the backend to automatically
|
||||
@ -5589,6 +5589,12 @@ The function @code{gpgme_op_decrypt} decrypts the ciphertext in the
|
||||
data object @var{cipher} and stores it into the data object
|
||||
@var{plain}.
|
||||
|
||||
If the flag @code(GPGME_DECRYPT_ARCHIVE) is set, then an encrypted
|
||||
archive in the data object @var{cipher} is decrypted and extracted.
|
||||
The content of the archive is extracted into a directory named
|
||||
@code{GPGARCH_n_} (where @code{n} is a number) or into the directory
|
||||
set with @code{gpgme_data_set_file_name} for the data object @var{plain}.
|
||||
|
||||
The function returns the error code @code{GPG_ERR_NO_ERROR} if the
|
||||
ciphertext could be decrypted successfully, @code{GPG_ERR_INV_VALUE}
|
||||
if @var{ctx}, @var{cipher} or @var{plain} is not a valid pointer,
|
||||
@ -5632,6 +5638,13 @@ multiple of the following bit values:
|
||||
The @code{GPGME_DECRYPT_VERIFY} symbol specifies that this function
|
||||
shall exactly act as @code{gpgme_op_decrypt_verify}.
|
||||
|
||||
@item GPGME_DECRYPT_ARCHIVE
|
||||
@since{1.19.0}
|
||||
|
||||
The @code{GPGME_DECRYPT_ARCHIVE} symbol specifies that the input is an
|
||||
encrypted archive that shall be decrypted and extracted. This feature
|
||||
is currently only supported for the OpenPGP crypto engine.
|
||||
|
||||
@item GPGME_DECRYPT_UNWRAP
|
||||
@since{1.8.0}
|
||||
|
||||
|
@ -310,7 +310,8 @@ add_gpg_arg (engine_gpg_t gpg, const char *arg)
|
||||
}
|
||||
|
||||
static gpgme_error_t
|
||||
add_gpg_arg_with_value (engine_gpg_t gpg, const char *arg, const char *value, int front)
|
||||
add_gpg_arg_with_value (engine_gpg_t gpg, const char *arg, const char *value,
|
||||
int front)
|
||||
{
|
||||
return _add_arg (gpg, arg, value, strlen (value), front, NULL, 1);
|
||||
}
|
||||
@ -1829,6 +1830,14 @@ gpg_decrypt (void *engine,
|
||||
engine_gpg_t gpg = engine;
|
||||
gpgme_error_t err;
|
||||
|
||||
gpg->flags.use_gpgtar = !!(flags & GPGME_DECRYPT_ARCHIVE);
|
||||
|
||||
if (gpg->flags.use_gpgtar && !have_gpg_version (gpg, "2.3.5"))
|
||||
return gpg_error (GPG_ERR_NOT_SUPPORTED);
|
||||
|
||||
if (gpg->flags.use_gpgtar && (flags & GPGME_DECRYPT_UNWRAP))
|
||||
return gpg_error (GPG_ERR_INV_VALUE);
|
||||
|
||||
err = add_arg (gpg, "--decrypt");
|
||||
|
||||
if (!err && (flags & GPGME_DECRYPT_UNWRAP))
|
||||
@ -1840,17 +1849,17 @@ gpg_decrypt (void *engine,
|
||||
}
|
||||
|
||||
if (!err && export_session_key)
|
||||
err = add_arg (gpg, "--show-session-key");
|
||||
err = add_gpg_arg (gpg, "--show-session-key");
|
||||
|
||||
if (!err && auto_key_retrieve)
|
||||
err = add_arg (gpg, "--auto-key-retrieve");
|
||||
err = add_gpg_arg (gpg, "--auto-key-retrieve");
|
||||
|
||||
if (!err && gpg->flags.auto_key_import)
|
||||
err = add_arg (gpg, "--auto-key-import");
|
||||
err = add_gpg_arg (gpg, "--auto-key-import");
|
||||
|
||||
if (!err && override_session_key && *override_session_key)
|
||||
{
|
||||
if (have_gpg_version (gpg, "2.1.16"))
|
||||
if (have_gpg_version (gpg, "2.1.16") && !gpg->flags.use_gpgtar)
|
||||
{
|
||||
gpgme_data_release (gpg->override_session_key);
|
||||
TRACE (DEBUG_ENGINE, "override", gpg, "seskey='%s' len=%zu\n",
|
||||
@ -1880,25 +1889,43 @@ gpg_decrypt (void *engine,
|
||||
else
|
||||
{
|
||||
/* Using that option may leak the session key via ps(1). */
|
||||
err = add_arg (gpg, "--override-session-key");
|
||||
if (!err)
|
||||
err = add_arg (gpg, override_session_key);
|
||||
err = add_gpg_arg_with_value (gpg, "--override-session-key=",
|
||||
override_session_key, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/* Tell the gpg object about the data. */
|
||||
if (!err)
|
||||
err = add_arg (gpg, "--output");
|
||||
if (!err)
|
||||
err = add_arg (gpg, "-");
|
||||
if (!err)
|
||||
err = add_data (gpg, plain, 1, 1);
|
||||
if (!err)
|
||||
err = add_input_size_hint (gpg, ciph);
|
||||
if (!err)
|
||||
err = add_arg (gpg, "--");
|
||||
if (!err)
|
||||
err = add_data (gpg, ciph, -1, 0);
|
||||
if (gpg->flags.use_gpgtar)
|
||||
{
|
||||
const char *file_name = gpgme_data_get_file_name (plain);
|
||||
if (!err && file_name)
|
||||
{
|
||||
err = add_arg (gpg, "--directory");
|
||||
if (!err)
|
||||
err = add_arg (gpg, file_name);
|
||||
}
|
||||
if (!err)
|
||||
err = add_input_size_hint (gpg, ciph);
|
||||
if (!err)
|
||||
err = add_arg (gpg, "--");
|
||||
if (!err)
|
||||
err = add_data (gpg, ciph, 0, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!err)
|
||||
err = add_arg (gpg, "--output");
|
||||
if (!err)
|
||||
err = add_arg (gpg, "-");
|
||||
if (!err)
|
||||
err = add_data (gpg, plain, 1, 1);
|
||||
if (!err)
|
||||
err = add_input_size_hint (gpg, ciph);
|
||||
if (!err)
|
||||
err = add_arg (gpg, "--");
|
||||
if (!err)
|
||||
err = add_data (gpg, ciph, -1, 0);
|
||||
}
|
||||
|
||||
if (!err)
|
||||
err = start (gpg);
|
||||
|
@ -1426,6 +1426,7 @@ gpgme_decrypt_result_t gpgme_op_decrypt_result (gpgme_ctx_t ctx);
|
||||
typedef enum
|
||||
{
|
||||
GPGME_DECRYPT_VERIFY = 1,
|
||||
GPGME_DECRYPT_ARCHIVE = 2,
|
||||
GPGME_DECRYPT_UNWRAP = 128
|
||||
}
|
||||
gpgme_decrypt_flags_t;
|
||||
|
@ -91,6 +91,8 @@ show_usage (int ex)
|
||||
" --unwrap remove only the encryption layer\n"
|
||||
" --large-buffers use large I/O buffer\n"
|
||||
" --sensitive mark data objects as sensitive\n"
|
||||
" --archive extract files from an encrypted archive\n"
|
||||
" --directory DIR extract the files into the directory DIR\n"
|
||||
" --diagnostics print diagnostics\n"
|
||||
, stderr);
|
||||
exit (ex);
|
||||
@ -113,6 +115,7 @@ main (int argc, char **argv)
|
||||
int export_session_key = 0;
|
||||
const char *override_session_key = NULL;
|
||||
const char *request_origin = NULL;
|
||||
const char *directory = NULL;
|
||||
int no_symkey_cache = 0;
|
||||
int ignore_mdc_error = 0;
|
||||
int raw_output = 0;
|
||||
@ -205,6 +208,19 @@ main (int argc, char **argv)
|
||||
raw_output = 1;
|
||||
argc--; argv++;
|
||||
}
|
||||
else if (!strcmp (*argv, "--archive"))
|
||||
{
|
||||
flags |= GPGME_DECRYPT_ARCHIVE;
|
||||
argc--; argv++;
|
||||
}
|
||||
else if (!strcmp (*argv, "--directory"))
|
||||
{
|
||||
argc--; argv++;
|
||||
if (!argc)
|
||||
show_usage (1);
|
||||
directory = *argv;
|
||||
argc--; argv++;
|
||||
}
|
||||
else if (!strncmp (*argv, "--", 2))
|
||||
show_usage (1);
|
||||
|
||||
@ -302,6 +318,16 @@ main (int argc, char **argv)
|
||||
gpgme_strerror (err));
|
||||
exit (1);
|
||||
}
|
||||
if (directory && (flags & GPGME_DECRYPT_ARCHIVE))
|
||||
{
|
||||
err = gpgme_data_set_file_name (out, directory);
|
||||
if (err)
|
||||
{
|
||||
fprintf (stderr, PGM ": error setting file name (out): %s\n",
|
||||
gpgme_strerror (err));
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
if (large_buffers)
|
||||
{
|
||||
err = gpgme_data_set_flag (out, "io-buffer-size", "1000000");
|
||||
|
Loading…
Reference in New Issue
Block a user