mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-22 10:19:57 +01:00
gpg-agent: add new CACHE_MODE_EXPORT
* 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 <dkg@fifthhorseman.net>
This commit is contained in:
parent
110a455017
commit
bf2724880f
@ -322,7 +322,8 @@ typedef enum
|
|||||||
CACHE_MODE_USER, /* GET_PASSPHRASE related cache. */
|
CACHE_MODE_USER, /* GET_PASSPHRASE related cache. */
|
||||||
CACHE_MODE_SSH, /* SSH related cache. */
|
CACHE_MODE_SSH, /* SSH related cache. */
|
||||||
CACHE_MODE_NONCE, /* This is a non-predictable nonce. */
|
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;
|
cache_mode_t;
|
||||||
|
|
||||||
|
@ -1120,10 +1120,12 @@ agent_askpin (ctrl_t ctrl,
|
|||||||
we do not error out in this case. */
|
we do not error out in this case. */
|
||||||
if (keyinfo && (cache_mode == CACHE_MODE_NORMAL
|
if (keyinfo && (cache_mode == CACHE_MODE_NORMAL
|
||||||
|| cache_mode == CACHE_MODE_USER
|
|| 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",
|
snprintf (line, DIM(line), "SETKEYINFO %c/%s",
|
||||||
cache_mode == CACHE_MODE_USER? 'u' :
|
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);
|
keyinfo);
|
||||||
else
|
else
|
||||||
snprintf (line, DIM(line), "SETKEYINFO --clear");
|
snprintf (line, DIM(line), "SETKEYINFO --clear");
|
||||||
@ -1313,10 +1315,12 @@ agent_get_passphrase (ctrl_t ctrl,
|
|||||||
we do not error out in this case. */
|
we do not error out in this case. */
|
||||||
if (keyinfo && (cache_mode == CACHE_MODE_NORMAL
|
if (keyinfo && (cache_mode == CACHE_MODE_NORMAL
|
||||||
|| cache_mode == CACHE_MODE_USER
|
|| 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",
|
snprintf (line, DIM(line), "SETKEYINFO %c/%s",
|
||||||
cache_mode == CACHE_MODE_USER? 'u' :
|
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);
|
keyinfo);
|
||||||
else
|
else
|
||||||
snprintf (line, DIM(line), "SETKEYINFO --clear");
|
snprintf (line, DIM(line), "SETKEYINFO --clear");
|
||||||
@ -1635,7 +1639,8 @@ agent_clear_passphrase (ctrl_t ctrl,
|
|||||||
|
|
||||||
if (! (keyinfo && (cache_mode == CACHE_MODE_NORMAL
|
if (! (keyinfo && (cache_mode == CACHE_MODE_NORMAL
|
||||||
|| cache_mode == CACHE_MODE_USER
|
|| 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);
|
return gpg_error (GPG_ERR_NOT_SUPPORTED);
|
||||||
|
|
||||||
rc = start_pinentry (ctrl);
|
rc = start_pinentry (ctrl);
|
||||||
|
@ -1611,7 +1611,8 @@ static const char hlp_clear_passphrase[] =
|
|||||||
"function returns with OK even when there is no cached passphrase.\n"
|
"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"
|
"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 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
|
static gpg_error_t
|
||||||
cmd_clear_passphrase (assuan_context_t ctx, char *line)
|
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;
|
cache_mode = CACHE_MODE_NORMAL;
|
||||||
else if (has_option (line, "--mode=ssh"))
|
else if (has_option (line, "--mode=ssh"))
|
||||||
cache_mode = CACHE_MODE_SSH;
|
cache_mode = CACHE_MODE_SSH;
|
||||||
|
else if (has_option (line, "--mode=export"))
|
||||||
|
cache_mode = CACHE_MODE_EXPORT;
|
||||||
|
|
||||||
line = skip_options (line);
|
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. */
|
the passphrase so that we can use it to re-encrypt it. */
|
||||||
err = agent_key_from_file (ctrl, cache_nonce,
|
err = agent_key_from_file (ctrl, cache_nonce,
|
||||||
ctrl->server_local->keydesc, grip,
|
ctrl->server_local->keydesc, grip,
|
||||||
&shadow_info, CACHE_MODE_IGNORE, NULL, &s_skey,
|
&shadow_info, CACHE_MODE_EXPORT, NULL, &s_skey,
|
||||||
openpgp ? &passphrase : NULL);
|
openpgp ? &passphrase : NULL);
|
||||||
if (err)
|
if (err)
|
||||||
goto leave;
|
goto leave;
|
||||||
|
@ -49,32 +49,6 @@
|
|||||||
"Secret key packet not found")
|
"Secret key packet not found")
|
||||||
(check-exported-key dump keyid)))
|
(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
|
(for-each-p
|
||||||
"Checking key export"
|
"Checking key export"
|
||||||
(lambda (keyid)
|
(lambda (keyid)
|
||||||
@ -84,17 +58,9 @@
|
|||||||
(pipe:gpg '(--list-packets)))
|
(pipe:gpg '(--list-packets)))
|
||||||
(tr:call-with-content check-exported-public-key keyid))
|
(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:do
|
||||||
(tr:pipe-do
|
(tr:pipe-do
|
||||||
(pipe:gpg `(--export-secret-keys ,keyid))
|
(pipe:gpg `(--export-secret-keys ,keyid))
|
||||||
(pipe:gpg '(--list-packets)))
|
(pipe:gpg '(--list-packets)))
|
||||||
(tr:call-with-content check-exported-private-key keyid))
|
(tr:call-with-content check-exported-private-key keyid)))
|
||||||
|
'("D74C5F22" "C40FDECF" "ECABF51D"))
|
||||||
(assert-passphrases-consumed))
|
|
||||||
'("D74C5F22" "C40FDECF" "ECABF51D")))
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user