From 1695cf267edf85bc451b59bf012083feb250bf59 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 24 Jun 2024 16:31:24 +0200 Subject: [PATCH] gpg: New option --show-only-session-key * g10/options.h (opt): Add show_only_session_key and turn show_session_key into a bit flag. * g10/gpg.c (oShowOnlySessionKey): New. (opts): Add "show-only-session-key". (main): Set flag. * g10/mainproc.c (proc_encrypted): Handle the new option. * g10/decrypt-data.c (decrypt_data): Ditto. Add compliance error flag to the DECRYPTION_INFO status line. -- This new option is somehow related to GnuPG-bug-id: 1825 --- doc/DETAILS | 8 +++++--- doc/gpg.texi | 4 ++++ g10/decrypt-data.c | 16 ++++++++++++---- g10/gpg.c | 10 +++++++++- g10/mainproc.c | 14 ++++++++++---- g10/options.h | 3 ++- 6 files changed, 42 insertions(+), 13 deletions(-) diff --git a/doc/DETAILS b/doc/DETAILS index a8c0edf9d..d50de6d60 100644 --- a/doc/DETAILS +++ b/doc/DETAILS @@ -569,11 +569,13 @@ pkd:0:1024:B665B1435F4C2 .... FF26ABB: actual key used for decryption. is the fingerprint of the primary key. is the letter with the ownertrust; this is in general a 'u' which stands for ultimately trusted. -*** DECRYPTION_INFO [] +*** DECRYPTION_INFO [ ] Print information about the symmetric encryption algorithm and the MDC method. This will be emitted even if the decryption fails. - For an AEAD algorithm AEAD_ALGO is not 0. GPGSM currently does - not print such a status. + For an AEAD algorithm AEAD_ALGO is not 0. COMPLERR is set to a + non-zero integer if a compliance check for the cipher failed. + GPGSM currently prints only the first two items and thus they are + marked as optional *** DECRYPTION_FAILED The symmetric decryption failed - one reason could be a wrong diff --git a/doc/gpg.texi b/doc/gpg.texi index 3eecc7d64..a65039c1a 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -3794,9 +3794,13 @@ This is not for normal use. Use the source to see for what it might be useful. This is not for normal use. Use the source to see for what it might be useful. @item --show-session-key +@itemx --show-only-session-key @opindex show-session-key +@opindex show-only-session-key Display the session key used for one message. See @option{--override-session-key} for the counterpart of this option. +The variant @option{--show-only-session-key} does not actually use the +session key but stops processing after having printed the session key. We think that Key Escrow is a Bad Thing; however the user should have the freedom to decide whether to go to prison or to reveal the content diff --git a/g10/decrypt-data.c b/g10/decrypt-data.c index ea4d48955..81209f66f 100644 --- a/g10/decrypt-data.c +++ b/g10/decrypt-data.c @@ -263,11 +263,13 @@ decrypt_data (ctrl_t ctrl, void *procctx, PKT_encrypted *ed, DEK *dek, /* Check compliance. */ if (!gnupg_cipher_is_allowed (opt.compliance, 0, dek->algo, ciphermode)) { - log_error (_("cipher algorithm '%s' may not be used in %s mode\n"), + gpgrt_log (opt.show_only_session_key? GPGRT_LOGLVL_INFO + /* */: GPGRT_LOGLVL_ERROR, + _("cipher algorithm '%s' may not be used in %s mode\n"), openpgp_cipher_algo_mode_name (dek->algo,ed->aead_algo), gnupg_compliance_option_string (opt.compliance)); *compliance_error = 1; - if (opt.flags.require_compliance) + if (opt.flags.require_compliance && !opt.show_only_session_key) { /* We fail early in this case because it does not make sense * to first decrypt everything. */ @@ -276,8 +278,9 @@ decrypt_data (ctrl_t ctrl, void *procctx, PKT_encrypted *ed, DEK *dek, } } - write_status_printf (STATUS_DECRYPTION_INFO, "%d %d %d", - ed->mdc_method, dek->algo, ed->aead_algo); + write_status_printf (STATUS_DECRYPTION_INFO, "%d %d %d %d", + ed->mdc_method, dek->algo, ed->aead_algo, + *compliance_error); if (opt.show_session_key) { @@ -297,6 +300,11 @@ decrypt_data (ctrl_t ctrl, void *procctx, PKT_encrypted *ed, DEK *dek, log_info ("session key: '%s%s'\n", numbuf, hexbuf); write_status_strings (STATUS_SESSION_KEY, numbuf, hexbuf, NULL); xfree (hexbuf); + if (opt.show_only_session_key) + { + rc = 0; + goto leave; + } } rc = openpgp_cipher_test_algo (dek->algo); diff --git a/g10/gpg.c b/g10/gpg.c index 65e32c097..7abebbc6e 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -367,6 +367,7 @@ enum cmd_and_opt_values oIgnoreCrcError, oIgnoreMDCError, oShowSessionKey, + oShowOnlySessionKey, oOverrideSessionKey, oOverrideSessionKeyFD, oNoRandomSeedFile, @@ -770,6 +771,7 @@ static gpgrt_opt_t opts[] = { ARGPARSE_s_n (oShowNotation, "show-notation", "@"), ARGPARSE_s_n (oNoShowNotation, "no-show-notation", "@"), ARGPARSE_s_n (oShowSessionKey, "show-session-key", "@"), + ARGPARSE_s_n (oShowOnlySessionKey, "show-only-session-key", "@"), ARGPARSE_s_n (oUseEmbeddedFilename, "use-embedded-filename", "@"), ARGPARSE_s_n (oNoUseEmbeddedFilename, "no-use-embedded-filename", "@"), ARGPARSE_s_n (oUnwrap, "unwrap", "@"), @@ -3564,7 +3566,13 @@ main (int argc, char **argv) opt.keyserver_options.options &= ~KEYSERVER_AUTO_KEY_RETRIEVE; break; - case oShowSessionKey: opt.show_session_key = 1; break; + case oShowOnlySessionKey: + opt.show_only_session_key = 1; + /* fallthru */ + case oShowSessionKey: + opt.show_session_key = 1; + break; + case oOverrideSessionKey: opt.override_session_key = pargs.r.ret_str; break; diff --git a/g10/mainproc.c b/g10/mainproc.c index 0fd32aead..29e5188f5 100644 --- a/g10/mainproc.c +++ b/g10/mainproc.c @@ -664,7 +664,8 @@ proc_encrypted (CTX c, PACKET *pkt) if (c->dek && opt.verbose > 1) log_info (_("public key encrypted data: good DEK\n")); - write_status (STATUS_BEGIN_DECRYPTION); + if (!opt.show_only_session_key) + write_status (STATUS_BEGIN_DECRYPTION); /*log_debug("dat: %sencrypted data\n", c->dek?"":"conventional ");*/ if (opt.list_only) @@ -794,6 +795,8 @@ proc_encrypted (CTX c, PACKET *pkt) * log_error printed in the cry_cipher_checktag never gets ignored. */ if (!result && early_plaintext) result = gpg_error (GPG_ERR_BAD_DATA); + else if (!result && opt.show_only_session_key) + result = -1; else if (!result && pkt->pkt.encrypted->aead_algo && log_get_errorcount (0)) result = gpg_error (GPG_ERR_BAD_SIGNATURE); @@ -903,7 +906,9 @@ proc_encrypted (CTX c, PACKET *pkt) c->dek = NULL; free_packet (pkt, NULL); c->last_was_session_key = 0; - write_status (STATUS_END_DECRYPTION); + + if (!opt.show_only_session_key) + write_status (STATUS_END_DECRYPTION); /* Bump the counter even if we have not seen a literal data packet * inside an encryption container. This acts as a sentinel in case @@ -915,7 +920,8 @@ proc_encrypted (CTX c, PACKET *pkt) * de-vs compliance mode by just looking at the exit status. */ if (opt.flags.require_compliance && opt.compliance == CO_DE_VS - && compliance_de_vs != (4|2|1)) + && compliance_de_vs != (4|2|1) + && !opt.show_only_session_key) { log_error (_("operation forced to fail due to" " unfulfilled compliance rules\n")); @@ -2203,7 +2209,7 @@ check_sig_and_print (CTX c, kbnode_t node) } } - /* Do do something with the result of the signature checking. */ + /* Do something with the result of the signature checking. */ if (!rc || gpg_err_code (rc) == GPG_ERR_BAD_SIGNATURE) { /* We have checked the signature and the result is either a good diff --git a/g10/options.h b/g10/options.h index 02c49c4e5..5168a788f 100644 --- a/g10/options.h +++ b/g10/options.h @@ -234,7 +234,8 @@ struct int ignore_expiration; int command_fd; const char *override_session_key; - int show_session_key; + unsigned int show_session_key:1; + unsigned int show_only_session_key:1; const char *gpg_agent_info; int try_all_secrets;