mirror of
git://git.gnupg.org/gnupg.git
synced 2025-07-02 22:46:30 +02:00
agent: Add "ephemeral" Assuan option.
* agent/agent.h (struct ephemeral_private_key_s): New. (struct server_control_s): Add ephemeral_mode and ephemeral_keys. (GENKEY_FLAG_NO_PROTECTION, GENKEY_FLAG_PRESET): New. * agent/genkey.c (clear_ephemeral_keys): New. (store_key): Add arg ctrl and implement ephemeral_mode. Change all callers. (agent_genkey): Replace args no_protection and preset by a generic new flags arg. * agent/findkey.c (wipe_and_fclose): New. (agent_write_private_key): Add arg ctrl and implement ephemeral_mode. Change all callers. (agent_update_private_key): Ditto (read_key_file): Ditto. (agent_key_available): Ditto. * agent/command-ssh.c (card_key_available): Do not update display s/n in ephemeral mode. This is however enver triggred. * agent/gpg-agent.c (agent_deinit_default_ctrl): Cleanup ephemeral keys. * agent/command.c (cmd_genkey): Use the new flags instead of separate vars. (cmd_readkey): Create a shadow key only in non-ephemeral_mode. (cmd_getinfo): Add sub-command "ephemeral". (option_handler): Add option "ephemeral". -- The idea here that a session can be switched in an ephemeral mode which does not store or read keys from disk but keeps them local to the session. GnuPG-bug-id: 6944
This commit is contained in:
parent
18320d692c
commit
434a641d40
11 changed files with 496 additions and 206 deletions
|
@ -251,6 +251,9 @@ reset_notify (assuan_context_t ctx, char *line)
|
|||
|
||||
clear_nonce_cache (ctrl);
|
||||
|
||||
/* Note that a RESET does not clear the ephemeral store becuase
|
||||
* clients are used to issue a RESET on a connection. */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -643,15 +646,15 @@ static const char hlp_havekey[] =
|
|||
static gpg_error_t
|
||||
cmd_havekey (assuan_context_t ctx, char *line)
|
||||
{
|
||||
ctrl_t ctrl;
|
||||
ctrl_t ctrl = assuan_get_pointer (ctx);
|
||||
gpg_error_t err;
|
||||
unsigned char grip[20];
|
||||
char *p;
|
||||
int list_mode = 0; /* Less than 0 for no limit. */
|
||||
int info_mode = 0;
|
||||
int counter;
|
||||
char *dirname;
|
||||
gnupg_dir_t dir;
|
||||
char *dirname = NULL;
|
||||
gnupg_dir_t dir = NULL;
|
||||
gnupg_dirent_t dir_entry;
|
||||
char hexgrip[41];
|
||||
struct card_key_info_s *keyinfo_on_cards, *l;
|
||||
|
@ -668,14 +671,11 @@ cmd_havekey (assuan_context_t ctx, char *line)
|
|||
|
||||
line = skip_options (line);
|
||||
|
||||
|
||||
if (info_mode)
|
||||
{
|
||||
int keytype;
|
||||
const char *infostring;
|
||||
|
||||
ctrl = assuan_get_pointer (ctx);
|
||||
|
||||
err = parse_keygrip (ctx, line, grip);
|
||||
if (err)
|
||||
goto leave;
|
||||
|
@ -706,7 +706,7 @@ cmd_havekey (assuan_context_t ctx, char *line)
|
|||
if (err)
|
||||
return err;
|
||||
|
||||
if (!agent_key_available (grip))
|
||||
if (!agent_key_available (ctrl, grip))
|
||||
return 0; /* Found. */
|
||||
|
||||
while (*line && *line != ' ' && *line != '\t')
|
||||
|
@ -724,7 +724,6 @@ cmd_havekey (assuan_context_t ctx, char *line)
|
|||
/* List mode. */
|
||||
dir = NULL;
|
||||
dirname = NULL;
|
||||
ctrl = assuan_get_pointer (ctx);
|
||||
|
||||
if (ctrl->restricted)
|
||||
{
|
||||
|
@ -1117,26 +1116,27 @@ cmd_genkey (assuan_context_t ctx, char *line)
|
|||
{
|
||||
ctrl_t ctrl = assuan_get_pointer (ctx);
|
||||
int rc;
|
||||
int no_protection;
|
||||
unsigned char *value = NULL;
|
||||
size_t valuelen;
|
||||
unsigned char *newpasswd = NULL;
|
||||
membuf_t outbuf;
|
||||
char *cache_nonce = NULL;
|
||||
char *passwd_nonce = NULL;
|
||||
int opt_preset;
|
||||
int opt_inq_passwd;
|
||||
size_t n;
|
||||
char *p, *pend;
|
||||
const char *s;
|
||||
time_t opt_timestamp;
|
||||
int c;
|
||||
unsigned int flags = 0;
|
||||
|
||||
if (ctrl->restricted)
|
||||
return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
|
||||
|
||||
no_protection = has_option (line, "--no-protection");
|
||||
opt_preset = has_option (line, "--preset");
|
||||
if (has_option (line, "--no-protection"))
|
||||
flags |= GENKEY_FLAG_NO_PROTECTION;
|
||||
if (has_option (line, "--preset"))
|
||||
flags |= GENKEY_FLAG_PRESET;
|
||||
opt_inq_passwd = has_option (line, "--inq-passwd");
|
||||
passwd_nonce = option_value (line, "--passwd-nonce");
|
||||
if (passwd_nonce)
|
||||
|
@ -1191,7 +1191,7 @@ cmd_genkey (assuan_context_t ctx, char *line)
|
|||
|
||||
/* If requested, ask for the password to be used for the key. If
|
||||
this is not used the regular Pinentry mechanism is used. */
|
||||
if (opt_inq_passwd && !no_protection)
|
||||
if (opt_inq_passwd && !(flags & GENKEY_FLAG_NO_PROTECTION))
|
||||
{
|
||||
/* (N is used as a dummy) */
|
||||
assuan_begin_confidential (ctx);
|
||||
|
@ -1204,16 +1204,17 @@ cmd_genkey (assuan_context_t ctx, char *line)
|
|||
/* Empty password given - switch to no-protection mode. */
|
||||
xfree (newpasswd);
|
||||
newpasswd = NULL;
|
||||
no_protection = 1;
|
||||
flags |= GENKEY_FLAG_NO_PROTECTION;
|
||||
}
|
||||
|
||||
}
|
||||
else if (passwd_nonce)
|
||||
newpasswd = agent_get_cache (ctrl, passwd_nonce, CACHE_MODE_NONCE);
|
||||
|
||||
rc = agent_genkey (ctrl, cache_nonce, opt_timestamp,
|
||||
(char*)value, valuelen, no_protection,
|
||||
newpasswd, opt_preset, &outbuf);
|
||||
|
||||
rc = agent_genkey (ctrl, flags, cache_nonce, opt_timestamp,
|
||||
(char*)value, valuelen,
|
||||
newpasswd, &outbuf);
|
||||
|
||||
leave:
|
||||
if (newpasswd)
|
||||
|
@ -1317,7 +1318,7 @@ cmd_keyattr (assuan_context_t ctx, char *line)
|
|||
if (!err)
|
||||
err = nvc_set_private_key (keymeta, s_key);
|
||||
if (!err)
|
||||
err = agent_update_private_key (grip, keymeta);
|
||||
err = agent_update_private_key (ctrl, grip, keymeta);
|
||||
}
|
||||
|
||||
nvc_release (keymeta);
|
||||
|
@ -1327,6 +1328,8 @@ cmd_keyattr (assuan_context_t ctx, char *line)
|
|||
leave:
|
||||
return leave_cmd (ctx, err);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static const char hlp_readkey[] =
|
||||
"READKEY [--no-data] [--format=ssh] <hexstring_with_keygrip>\n"
|
||||
|
@ -1390,7 +1393,7 @@ cmd_readkey (assuan_context_t ctx, char *line)
|
|||
goto leave;
|
||||
}
|
||||
|
||||
if (agent_key_available (grip))
|
||||
if (!ctrl->ephemeral_mode && agent_key_available (ctrl, grip))
|
||||
{
|
||||
/* (Shadow)-key is not available in our key storage. */
|
||||
char *dispserialno;
|
||||
|
@ -1398,7 +1401,7 @@ cmd_readkey (assuan_context_t ctx, char *line)
|
|||
|
||||
bin2hex (grip, 20, hexgrip);
|
||||
agent_card_getattr (ctrl, "$DISPSERIALNO", &dispserialno, hexgrip);
|
||||
rc = agent_write_shadow_key (grip, serialno, keyid, pkbuf, 0,
|
||||
rc = agent_write_shadow_key (ctrl, grip, serialno, keyid, pkbuf, 0,
|
||||
dispserialno);
|
||||
xfree (dispserialno);
|
||||
if (rc)
|
||||
|
@ -2934,7 +2937,7 @@ cmd_import_key (assuan_context_t ctx, char *line)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (!force && !agent_key_available (grip))
|
||||
if (!force && !agent_key_available (ctrl, grip))
|
||||
err = gpg_error (GPG_ERR_EEXIST);
|
||||
else
|
||||
{
|
||||
|
@ -2956,11 +2959,11 @@ cmd_import_key (assuan_context_t ctx, char *line)
|
|||
err = agent_protect (key, passphrase, &finalkey, &finalkeylen,
|
||||
ctrl->s2k_count);
|
||||
if (!err)
|
||||
err = agent_write_private_key (grip, finalkey, finalkeylen, force,
|
||||
err = agent_write_private_key (ctrl, grip, finalkey, finalkeylen, force,
|
||||
NULL, NULL, NULL, opt_timestamp);
|
||||
}
|
||||
else
|
||||
err = agent_write_private_key (grip, key, realkeylen, force,
|
||||
err = agent_write_private_key (ctrl, grip, key, realkeylen, force,
|
||||
NULL, NULL, NULL, opt_timestamp);
|
||||
|
||||
leave:
|
||||
|
@ -2979,7 +2982,8 @@ cmd_import_key (assuan_context_t ctx, char *line)
|
|||
|
||||
|
||||
static const char hlp_export_key[] =
|
||||
"EXPORT_KEY [--cache-nonce=<nonce>] [--openpgp|--mode1003] <hexkeygrip>\n"
|
||||
"EXPORT_KEY [--cache-nonce=<nonce>] \\\n"
|
||||
" [--openpgp|--mode1003] <hexkeygrip>\n"
|
||||
"\n"
|
||||
"Export a secret key from the key store. The key will be encrypted\n"
|
||||
"using the current session's key wrapping key (cf. command KEYWRAP_KEY)\n"
|
||||
|
@ -2987,8 +2991,8 @@ static const char hlp_export_key[] =
|
|||
"prior to using this command. The function takes the keygrip as argument.\n"
|
||||
"\n"
|
||||
"If --openpgp is used, the secret key material will be exported in RFC 4880\n"
|
||||
"compatible passphrase-protected form. If --mode1003 is use the secret key\n"
|
||||
"is exported as s-expression as storred locally. Without those options,\n"
|
||||
"compatible passphrase-protected form. In --mode1003 the secret key\n"
|
||||
"is exported as s-expression as stored locally. Without those options,\n"
|
||||
"the secret key material will be exported in the clear (after prompting\n"
|
||||
"the user to unlock it, if needed).\n";
|
||||
static gpg_error_t
|
||||
|
@ -3045,7 +3049,7 @@ cmd_export_key (assuan_context_t ctx, char *line)
|
|||
if (err)
|
||||
goto leave;
|
||||
|
||||
if (agent_key_available (grip))
|
||||
if (agent_key_available (ctrl, grip))
|
||||
{
|
||||
err = gpg_error (GPG_ERR_NO_SECKEY);
|
||||
goto leave;
|
||||
|
@ -3257,9 +3261,9 @@ cmd_keytocard (assuan_context_t ctx, char *line)
|
|||
if (err)
|
||||
goto leave;
|
||||
|
||||
if (agent_key_available (grip))
|
||||
if (agent_key_available (ctrl, grip))
|
||||
{
|
||||
err =gpg_error (GPG_ERR_NO_SECKEY);
|
||||
err = gpg_error (GPG_ERR_NO_SECKEY);
|
||||
goto leave;
|
||||
}
|
||||
|
||||
|
@ -3577,7 +3581,7 @@ cmd_keytotpm (assuan_context_t ctx, char *line)
|
|||
if (err)
|
||||
goto leave;
|
||||
|
||||
if (agent_key_available (grip))
|
||||
if (agent_key_available (ctrl, grip))
|
||||
{
|
||||
err =gpg_error (GPG_ERR_NO_SECKEY);
|
||||
goto leave;
|
||||
|
@ -3869,6 +3873,7 @@ static const char hlp_getinfo[] =
|
|||
" getenv NAME - Return value of envvar NAME.\n"
|
||||
" connections - Return number of active connections.\n"
|
||||
" jent_active - Returns OK if Libgcrypt's JENT is active.\n"
|
||||
" ephemeral - Returns OK if the connection is in ephemeral mode.\n"
|
||||
" restricted - Returns OK if the connection is in restricted mode.\n"
|
||||
" cmd_has_option CMD OPT\n"
|
||||
" - Returns OK if command CMD has option OPT.\n";
|
||||
|
@ -3922,6 +3927,10 @@ cmd_getinfo (assuan_context_t ctx, char *line)
|
|||
snprintf (numbuf, sizeof numbuf, "%lu", get_standard_s2k_count ());
|
||||
rc = assuan_send_data (ctx, numbuf, strlen (numbuf));
|
||||
}
|
||||
else if (!strcmp (line, "ephemeral"))
|
||||
{
|
||||
rc = ctrl->ephemeral_mode? 0 : gpg_error (GPG_ERR_FALSE);
|
||||
}
|
||||
else if (!strcmp (line, "restricted"))
|
||||
{
|
||||
rc = ctrl->restricted? 0 : gpg_error (GPG_ERR_FALSE);
|
||||
|
@ -4078,6 +4087,10 @@ option_handler (assuan_context_t ctx, const char *key, const char *value)
|
|||
ctrl->server_local->allow_fully_canceled =
|
||||
gnupg_compare_version (value, "2.1.0");
|
||||
}
|
||||
else if (!strcmp (key, "ephemeral"))
|
||||
{
|
||||
ctrl->ephemeral_mode = *value? atoi (value) : 0;
|
||||
}
|
||||
else if (ctrl->restricted)
|
||||
{
|
||||
err = gpg_error (GPG_ERR_FORBIDDEN);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue