diff options
author | Daniel Kahn Gillmor <[email protected]> | 2019-05-20 19:06:57 +0000 |
---|---|---|
committer | Daniel Kahn Gillmor <[email protected]> | 2019-05-20 21:38:12 +0000 |
commit | bf2724880fe54d0dbf34bfa9fef2f31fa6809f55 (patch) | |
tree | 3d27cd1600f19ac9ee72cdb948aa9eaf85093728 | |
parent | gpg: Do not delete any keys if --dry-run is passed. (diff) | |
download | gnupg-dkg/fix-T4522.tar.gz gnupg-dkg/fix-T4522.zip |
gpg-agent: add new CACHE_MODE_EXPORTdkg/fix-T4522
* agent/agent.h: define CACHE_MODE_EXPORT
* agent/call-pinentry.c (agent_askpin, agent_get_passphrase): use "e/"
as the prefix for SETKEYINFO when in CACHE_MODE_EXPORT.
(agent_clear_passphrase): allow clearing the export cache.
* agent/command.c (cmd_clear_passphrase): add --mode=export.
(cmd_export_key): use CACHE_MODE_EXPORT.
* tests/openpgp/export.scm: no need to feed passphrases during export,
already cached.
----
We don't want secret keys to be able to be exported automatically
based on the same system passphrase cache used by standard decryption
or signing operations.
So we introduce a "export" cache mode which can be used by EXPORT_KEY.
I confess i don't fully understand the changes made to
tests/openpgp/export.scm -- i'm not sure why the passphrase is already
supplied in this case.
Gnupg-Bug-Id: 4522
Signed-off-by: Daniel Kahn Gillmor <[email protected]>
-rw-r--r-- | agent/agent.h | 3 | ||||
-rw-r--r-- | agent/call-pinentry.c | 15 | ||||
-rw-r--r-- | agent/command.c | 7 | ||||
-rwxr-xr-x | tests/openpgp/export.scm | 38 |
4 files changed, 19 insertions, 44 deletions
diff --git a/agent/agent.h b/agent/agent.h index 77672bd50..8c4a1d4ba 100644 --- a/agent/agent.h +++ b/agent/agent.h @@ -322,7 +322,8 @@ typedef enum CACHE_MODE_USER, /* GET_PASSPHRASE related cache. */ CACHE_MODE_SSH, /* SSH related cache. */ CACHE_MODE_NONCE, /* This is a non-predictable nonce. */ - CACHE_MODE_DATA /* Arbitrary data. */ + CACHE_MODE_DATA, /* Arbitrary data. */ + CACHE_MODE_EXPORT, /* Exporting secret keys. */ } cache_mode_t; diff --git a/agent/call-pinentry.c b/agent/call-pinentry.c index 5b4713f41..bf75bb4a7 100644 --- a/agent/call-pinentry.c +++ b/agent/call-pinentry.c @@ -1120,10 +1120,12 @@ agent_askpin (ctrl_t ctrl, we do not error out in this case. */ if (keyinfo && (cache_mode == CACHE_MODE_NORMAL || cache_mode == CACHE_MODE_USER - || cache_mode == CACHE_MODE_SSH)) + || cache_mode == CACHE_MODE_SSH + || cache_mode == CACHE_MODE_EXPORT)) snprintf (line, DIM(line), "SETKEYINFO %c/%s", cache_mode == CACHE_MODE_USER? 'u' : - cache_mode == CACHE_MODE_SSH? 's' : 'n', + cache_mode == CACHE_MODE_SSH? 's' : + cache_mode == CACHE_MODE_EXPORT? 'e' : 'n', keyinfo); else snprintf (line, DIM(line), "SETKEYINFO --clear"); @@ -1313,10 +1315,12 @@ agent_get_passphrase (ctrl_t ctrl, we do not error out in this case. */ if (keyinfo && (cache_mode == CACHE_MODE_NORMAL || cache_mode == CACHE_MODE_USER - || cache_mode == CACHE_MODE_SSH)) + || cache_mode == CACHE_MODE_SSH + || cache_mode == CACHE_MODE_EXPORT)) snprintf (line, DIM(line), "SETKEYINFO %c/%s", cache_mode == CACHE_MODE_USER? 'u' : - cache_mode == CACHE_MODE_SSH? 's' : 'n', + cache_mode == CACHE_MODE_SSH? 's' : + cache_mode == CACHE_MODE_EXPORT? 'e' : 'n', keyinfo); else snprintf (line, DIM(line), "SETKEYINFO --clear"); @@ -1635,7 +1639,8 @@ agent_clear_passphrase (ctrl_t ctrl, if (! (keyinfo && (cache_mode == CACHE_MODE_NORMAL || cache_mode == CACHE_MODE_USER - || cache_mode == CACHE_MODE_SSH))) + || cache_mode == CACHE_MODE_SSH + || cache_mode == CACHE_MODE_EXPORT))) return gpg_error (GPG_ERR_NOT_SUPPORTED); rc = start_pinentry (ctrl); diff --git a/agent/command.c b/agent/command.c index c056eb3f0..a86c9fff5 100644 --- a/agent/command.c +++ b/agent/command.c @@ -1611,7 +1611,8 @@ static const char hlp_clear_passphrase[] = "function returns with OK even when there is no cached passphrase.\n" "The --mode=normal option is used to clear an entry for a cacheid\n" "added by the agent. The --mode=ssh option is used for a cacheid\n" - "added for ssh.\n"; + "added for ssh. The --mode=export option is used for a cacheid\n" + "added for secret key export.\n"; static gpg_error_t cmd_clear_passphrase (assuan_context_t ctx, char *line) { @@ -1627,6 +1628,8 @@ cmd_clear_passphrase (assuan_context_t ctx, char *line) cache_mode = CACHE_MODE_NORMAL; else if (has_option (line, "--mode=ssh")) cache_mode = CACHE_MODE_SSH; + else if (has_option (line, "--mode=export")) + cache_mode = CACHE_MODE_EXPORT; line = skip_options (line); @@ -2347,7 +2350,7 @@ cmd_export_key (assuan_context_t ctx, char *line) the passphrase so that we can use it to re-encrypt it. */ err = agent_key_from_file (ctrl, cache_nonce, ctrl->server_local->keydesc, grip, - &shadow_info, CACHE_MODE_IGNORE, NULL, &s_skey, + &shadow_info, CACHE_MODE_EXPORT, NULL, &s_skey, openpgp ? &passphrase : NULL); if (err) goto leave; diff --git a/tests/openpgp/export.scm b/tests/openpgp/export.scm index aa6fa7828..60cc2faea 100755 --- a/tests/openpgp/export.scm +++ b/tests/openpgp/export.scm @@ -49,32 +49,6 @@ "Secret key packet not found") (check-exported-key dump keyid))) -(lettmp - ;; Prepare two temporary files for communication with the fake - ;; pinentry program. - (logfile ppfile) - - (define (prepare-passphrases . passphrases) - (call-with-output-file ppfile - (lambda (port) - (for-each (lambda (passphrase) - (display passphrase port) - (display #\newline port)) passphrases)))) - - (define CONFIRM "fake-entry being started to CONFIRM the weak phrase") - - (define (assert-passphrases-consumed) - (call-with-input-file ppfile - (lambda (port) - (unless - (eof-object? (peek-char port)) - (fail (string-append - "Expected all passphrases to be consumed, but found: " - (read-all port))))))) - - (setenv "PINENTRY_USER_DATA" - (string-append "--logfile=" logfile " --passphrasefile=" ppfile) #t) - (for-each-p "Checking key export" (lambda (keyid) @@ -84,17 +58,9 @@ (pipe:gpg '(--list-packets))) (tr:call-with-content check-exported-public-key keyid)) - (if (string=? "D74C5F22" keyid) - ;; Key D74C5F22 is protected by a passphrase. Prepare this - ;; one. Currently, GnuPG does not ask for an export passphrase - ;; in this case. - (prepare-passphrases usrpass1)) - (tr:do (tr:pipe-do (pipe:gpg `(--export-secret-keys ,keyid)) (pipe:gpg '(--list-packets))) - (tr:call-with-content check-exported-private-key keyid)) - - (assert-passphrases-consumed)) - '("D74C5F22" "C40FDECF" "ECABF51D"))) + (tr:call-with-content check-exported-private-key keyid))) + '("D74C5F22" "C40FDECF" "ECABF51D")) |