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
|
gpgme_op_sign* to allow creating an encrypted and/or signed
|
||||||
archive. [T6342]
|
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: Handle error when trying to sign expired keys. [T6155]
|
||||||
|
|
||||||
* cpp, qt: Fix building with C++11. [T6141]
|
* 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_get_ctx_flag EXTENDED: New flag 'no-auto-check-trustdb'.
|
||||||
gpgme_set_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_ENCRYPT_ARCHIVE NEW.
|
||||||
GPGME_SIG_MODE_ARCHIVE NEW.
|
GPGME_SIG_MODE_ARCHIVE NEW.
|
||||||
cpp: GpgGenCardKeyInteractor::Curve 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
|
the session key for decryption. The format of that session key is
|
||||||
specific to GnuPG and can be retrieved during a decrypt operation when
|
specific to GnuPG and can be retrieved during a decrypt operation when
|
||||||
the context flag "export-session-key" is enabled. Please be aware that
|
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
|
using this feature with GnuPG < 2.1.16 or when decrypting an archive
|
||||||
many platforms via ps(1).
|
will leak the session key on many platforms via ps(1).
|
||||||
|
|
||||||
@item "auto-key-retrieve"
|
@item "auto-key-retrieve"
|
||||||
Setting the @var{value} to "1" asks the backend to automatically
|
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
|
data object @var{cipher} and stores it into the data object
|
||||||
@var{plain}.
|
@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
|
The function returns the error code @code{GPG_ERR_NO_ERROR} if the
|
||||||
ciphertext could be decrypted successfully, @code{GPG_ERR_INV_VALUE}
|
ciphertext could be decrypted successfully, @code{GPG_ERR_INV_VALUE}
|
||||||
if @var{ctx}, @var{cipher} or @var{plain} is not a valid pointer,
|
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
|
The @code{GPGME_DECRYPT_VERIFY} symbol specifies that this function
|
||||||
shall exactly act as @code{gpgme_op_decrypt_verify}.
|
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
|
@item GPGME_DECRYPT_UNWRAP
|
||||||
@since{1.8.0}
|
@since{1.8.0}
|
||||||
|
|
||||||
|
@ -310,7 +310,8 @@ add_gpg_arg (engine_gpg_t gpg, const char *arg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static gpgme_error_t
|
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);
|
return _add_arg (gpg, arg, value, strlen (value), front, NULL, 1);
|
||||||
}
|
}
|
||||||
@ -1829,6 +1830,14 @@ gpg_decrypt (void *engine,
|
|||||||
engine_gpg_t gpg = engine;
|
engine_gpg_t gpg = engine;
|
||||||
gpgme_error_t err;
|
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");
|
err = add_arg (gpg, "--decrypt");
|
||||||
|
|
||||||
if (!err && (flags & GPGME_DECRYPT_UNWRAP))
|
if (!err && (flags & GPGME_DECRYPT_UNWRAP))
|
||||||
@ -1840,17 +1849,17 @@ gpg_decrypt (void *engine,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!err && export_session_key)
|
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)
|
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)
|
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 (!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);
|
gpgme_data_release (gpg->override_session_key);
|
||||||
TRACE (DEBUG_ENGINE, "override", gpg, "seskey='%s' len=%zu\n",
|
TRACE (DEBUG_ENGINE, "override", gpg, "seskey='%s' len=%zu\n",
|
||||||
@ -1880,13 +1889,30 @@ gpg_decrypt (void *engine,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Using that option may leak the session key via ps(1). */
|
/* Using that option may leak the session key via ps(1). */
|
||||||
err = add_arg (gpg, "--override-session-key");
|
err = add_gpg_arg_with_value (gpg, "--override-session-key=",
|
||||||
if (!err)
|
override_session_key, 0);
|
||||||
err = add_arg (gpg, override_session_key);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Tell the gpg object about the data. */
|
/* Tell the gpg object about the data. */
|
||||||
|
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)
|
if (!err)
|
||||||
err = add_arg (gpg, "--output");
|
err = add_arg (gpg, "--output");
|
||||||
if (!err)
|
if (!err)
|
||||||
@ -1899,6 +1925,7 @@ gpg_decrypt (void *engine,
|
|||||||
err = add_arg (gpg, "--");
|
err = add_arg (gpg, "--");
|
||||||
if (!err)
|
if (!err)
|
||||||
err = add_data (gpg, ciph, -1, 0);
|
err = add_data (gpg, ciph, -1, 0);
|
||||||
|
}
|
||||||
|
|
||||||
if (!err)
|
if (!err)
|
||||||
err = start (gpg);
|
err = start (gpg);
|
||||||
|
@ -1426,6 +1426,7 @@ gpgme_decrypt_result_t gpgme_op_decrypt_result (gpgme_ctx_t ctx);
|
|||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
GPGME_DECRYPT_VERIFY = 1,
|
GPGME_DECRYPT_VERIFY = 1,
|
||||||
|
GPGME_DECRYPT_ARCHIVE = 2,
|
||||||
GPGME_DECRYPT_UNWRAP = 128
|
GPGME_DECRYPT_UNWRAP = 128
|
||||||
}
|
}
|
||||||
gpgme_decrypt_flags_t;
|
gpgme_decrypt_flags_t;
|
||||||
|
@ -91,6 +91,8 @@ show_usage (int ex)
|
|||||||
" --unwrap remove only the encryption layer\n"
|
" --unwrap remove only the encryption layer\n"
|
||||||
" --large-buffers use large I/O buffer\n"
|
" --large-buffers use large I/O buffer\n"
|
||||||
" --sensitive mark data objects as sensitive\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"
|
" --diagnostics print diagnostics\n"
|
||||||
, stderr);
|
, stderr);
|
||||||
exit (ex);
|
exit (ex);
|
||||||
@ -113,6 +115,7 @@ main (int argc, char **argv)
|
|||||||
int export_session_key = 0;
|
int export_session_key = 0;
|
||||||
const char *override_session_key = NULL;
|
const char *override_session_key = NULL;
|
||||||
const char *request_origin = NULL;
|
const char *request_origin = NULL;
|
||||||
|
const char *directory = NULL;
|
||||||
int no_symkey_cache = 0;
|
int no_symkey_cache = 0;
|
||||||
int ignore_mdc_error = 0;
|
int ignore_mdc_error = 0;
|
||||||
int raw_output = 0;
|
int raw_output = 0;
|
||||||
@ -205,6 +208,19 @@ main (int argc, char **argv)
|
|||||||
raw_output = 1;
|
raw_output = 1;
|
||||||
argc--; argv++;
|
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))
|
else if (!strncmp (*argv, "--", 2))
|
||||||
show_usage (1);
|
show_usage (1);
|
||||||
|
|
||||||
@ -302,6 +318,16 @@ main (int argc, char **argv)
|
|||||||
gpgme_strerror (err));
|
gpgme_strerror (err));
|
||||||
exit (1);
|
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)
|
if (large_buffers)
|
||||||
{
|
{
|
||||||
err = gpgme_data_set_flag (out, "io-buffer-size", "1000000");
|
err = gpgme_data_set_flag (out, "io-buffer-size", "1000000");
|
||||||
|
Loading…
Reference in New Issue
Block a user