From 91a59d2a35540769c055da2341b5face0be6c286 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 18 Mar 2025 16:22:58 +0100 Subject: [PATCH] New decrypt flags GPGME_DECRYPT_LISTONLY. * src/gpgme.h.in (GPGME_DECRYPT_LISTONLY): New. * src/decrypt.c (op_data_t): Add member list_only. (_gpgme_decrypt_status_handler): Do not return NO_DATA in list_only mode. (_gpgme_op_decrypt_init_result): Add arg flags and set the list_only flag. (_gpgme_decrypt_start): Pss flags to the init function. * src/decrypt-verify.c (decrypt_verify_start): Ditto. * src/engine-gpg.c (gpg_decrypt): Add --list-only if flag is set. * tests/run-decrypt.c (main): Add option --list-only. --- NEWS | 4 ++++ doc/gpgme.texi | 9 +++++++++ src/decrypt-verify.c | 2 +- src/decrypt.c | 13 +++++++++---- src/engine-gpg.c | 3 +++ src/gpgme.h.in | 1 + src/ops.h | 3 ++- tests/run-decrypt.c | 8 +++++++- 8 files changed, 36 insertions(+), 7 deletions(-) diff --git a/NEWS b/NEWS index 7544d42c..6de14424 100644 --- a/NEWS +++ b/NEWS @@ -7,6 +7,9 @@ Noteworthy changes in version 2.0.0 (unreleased) * New function gpgme_op_random_value to get a cryptographically strong unsigned integer random value. [T6694] + * New decrypt flag to skip the actual decryption so that information + about the recipients can be retrieved. + * Removed the gpgme_attr_t enums and their functions which were deprecated since 2003. [rMd54d6eaa64] @@ -22,6 +25,7 @@ Noteworthy changes in version 2.0.0 (unreleased) gpgme_op_random_value NEW. GPGME_RANDOM_MODE_NORMAL NEW. GPGME_RANDOM_MODE_ZBASE32 NEW. + GPGME_DECRYPT_LISTONLY NEW. gpgme_attr_t REMOVED. gpgme_get_sig_ulong_attr REMOVED. gpgme_get_sig_string_attr REMOVED. diff --git a/doc/gpgme.texi b/doc/gpgme.texi index fa93083c..bc4b1ac5 100644 --- a/doc/gpgme.texi +++ b/doc/gpgme.texi @@ -5830,6 +5830,15 @@ be an OpenPGP message with only the encryption layer removed. This requires GnuPG 2.1.12 and works only for OpenPGP. This is the counterpart to @code{GPGME_ENCRYPT_WRAP}. +@item GPGME_DECRYPT_LIST +@since{2.0.0} + +The @code{GPGME_DECRYPT_LIST} symbol specifies that the actual +decryption step of an OpenPGP message shall be skipped. This can be +used to information on the keyids of the recipients of some encrypted +data. Note that most other result items have no or no useful +information in this case. + @end table The function returns the error codes as described for diff --git a/src/decrypt-verify.c b/src/decrypt-verify.c index 3ff15feb..94ebeb90 100644 --- a/src/decrypt-verify.c +++ b/src/decrypt-verify.c @@ -62,7 +62,7 @@ decrypt_verify_start (gpgme_ctx_t ctx, int synchronous, if (err) return err; - err = _gpgme_op_decrypt_init_result (ctx, plain); + err = _gpgme_op_decrypt_init_result (ctx, plain, flags); if (err) return err; diff --git a/src/decrypt.c b/src/decrypt.c index e5d2f7c7..c6030eef 100644 --- a/src/decrypt.c +++ b/src/decrypt.c @@ -44,7 +44,10 @@ typedef struct int okay; - /* A flag telling that the a decryption failed and two optional error + /* Indicates that list only mode is active. */ + int list_only; + + /* A flag telling that the decryption failed and two optional error * codes to further specify the failure for public key decryption and * symmetric decryption. */ int failed; @@ -419,7 +422,7 @@ _gpgme_decrypt_status_handler (void *priv, gpgme_status_code_t code, /* Generic decryption failed error code. */ return gpg_error (GPG_ERR_DECRYPT_FAILED); } - else if (!opd->okay) + else if (!opd->okay && !opd->list_only) { /* No data was found. */ return gpg_error (GPG_ERR_NO_DATA); @@ -540,7 +543,8 @@ decrypt_status_handler (void *priv, gpgme_status_code_t code, char *args) gpgme_error_t -_gpgme_op_decrypt_init_result (gpgme_ctx_t ctx, gpgme_data_t plaintext) +_gpgme_op_decrypt_init_result (gpgme_ctx_t ctx, gpgme_data_t plaintext, + gpgme_decrypt_flags_t flags) { gpgme_error_t err; void *hook; @@ -552,6 +556,7 @@ _gpgme_op_decrypt_init_result (gpgme_ctx_t ctx, gpgme_data_t plaintext) if (err) return err; + opd->list_only = !!(flags & GPGME_DECRYPT_LISTONLY); opd->last_recipient_p = &opd->result.recipients; opd->plaintext_dserial = _gpgme_data_get_dserial (plaintext); return 0; @@ -571,7 +576,7 @@ _gpgme_decrypt_start (gpgme_ctx_t ctx, int synchronous, if (err) return err; - err = _gpgme_op_decrypt_init_result (ctx, plain); + err = _gpgme_op_decrypt_init_result (ctx, plain, flags); if (err) return err; diff --git a/src/engine-gpg.c b/src/engine-gpg.c index 66303263..c0391d11 100644 --- a/src/engine-gpg.c +++ b/src/engine-gpg.c @@ -1952,6 +1952,9 @@ gpg_decrypt (void *engine, err = add_arg (gpg, "--unwrap"); } + if (!err && (flags & GPGME_DECRYPT_LISTONLY)) + err = add_arg (gpg, "--list-only"); + if (!err && export_session_key) err = add_gpg_arg (gpg, "--show-session-key"); diff --git a/src/gpgme.h.in b/src/gpgme.h.in index 705d9741..69d9f54c 100644 --- a/src/gpgme.h.in +++ b/src/gpgme.h.in @@ -1491,6 +1491,7 @@ typedef enum { GPGME_DECRYPT_VERIFY = 1, GPGME_DECRYPT_ARCHIVE = 2, + GPGME_DECRYPT_LISTONLY = 16, GPGME_DECRYPT_UNWRAP = 128 } gpgme_decrypt_flags_t; diff --git a/src/ops.h b/src/ops.h index f2333717..ff59fcc5 100644 --- a/src/ops.h +++ b/src/ops.h @@ -86,7 +86,8 @@ gpgme_error_t _gpgme_verify_status_handler (void *priv, /* From decrypt.c. */ gpgme_error_t _gpgme_op_decrypt_init_result (gpgme_ctx_t ctx, - gpgme_data_t plaintext); + gpgme_data_t plaintext, + gpgme_decrypt_flags_t flags); gpgme_error_t _gpgme_decrypt_status_handler (void *priv, gpgme_status_code_t code, char *args); diff --git a/tests/run-decrypt.c b/tests/run-decrypt.c index c724e407..cbde49dc 100644 --- a/tests/run-decrypt.c +++ b/tests/run-decrypt.c @@ -90,6 +90,7 @@ show_usage (int ex) " --no-symkey-cache disable the use of that cache\n" " --ignore-mdc-error allow decryption of legacy data\n" " --unwrap remove only the encryption layer\n" + " --list-only no actual decryption\n" " --large-buffers use large I/O buffer\n" " --sensitive mark data objects as sensitive\n" " --output FILE write output to FILE instead of stdout\n" @@ -215,6 +216,11 @@ main (int argc, char **argv) raw_output = 1; argc--; argv++; } + else if (!strcmp (*argv, "--list-only")) + { + flags |= GPGME_DECRYPT_LISTONLY; + argc--; argv++; + } else if (!strcmp (*argv, "--output")) { argc--; argv++; @@ -445,7 +451,7 @@ main (int argc, char **argv) { if (!raw_output) print_result (result); - if (!output) + if (!output && !(flags & GPGME_DECRYPT_LISTONLY)) { if (!raw_output) fputs ("Begin Output:\n", stdout);