summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2024-01-22 16:52:22 +0100
committerWerner Koch <wk@gnupg.org>2024-01-22 16:52:22 +0100
commitead2982286f8ae94e96c0da09c6ed8c294711a47 (patch)
tree1180aaf93abda4eb22782e3862c9b7b8167a846d
parentagent: Add "ephemeral" Assuan option. (diff)
downloadgnupg2-ead2982286f8ae94e96c0da09c6ed8c294711a47.tar.xz
gnupg2-ead2982286f8ae94e96c0da09c6ed8c294711a47.zip
gpg: Use ephemeral mode for generating card keys.
* g10/call-agent.c (agent_set_ephemeral_mode): New. * g10/keyedit.c (keyedit_menu) <bkuptocard>: Switch to ephemeral mode. * g10/keygen.c (do_generate_keypair): Switch to ephemeral mode for card keys with backup. -- GnuPG-bug-id: 6944
Diffstat (limited to '')
-rw-r--r--g10/call-agent.c39
-rw-r--r--g10/call-agent.h4
-rw-r--r--g10/keyedit.c32
-rw-r--r--g10/keygen.c48
4 files changed, 104 insertions, 19 deletions
diff --git a/g10/call-agent.c b/g10/call-agent.c
index 744c0fcb8..daf12fae7 100644
--- a/g10/call-agent.c
+++ b/g10/call-agent.c
@@ -3243,6 +3243,45 @@ agent_passwd (ctrl_t ctrl, const char *hexkeygrip, const char *desc, int verify,
}
+/* Enable or disable the ephemeral mode. In ephemeral mode keys are
+ * created,searched and used in a per-session key store and not in the
+ * on-disk file. Set ENABLE to 1 to enable this mode, to 0 to disable
+ * this mode and to -1 to only query the current mode. If R_PREVIOUS
+ * is given the previously used state of the ephemeral mode is stored
+ * at that address. */
+gpg_error_t
+agent_set_ephemeral_mode (ctrl_t ctrl, int enable, int *r_previous)
+{
+ gpg_error_t err;
+
+ err = start_agent (ctrl, 0);
+ if (err)
+ goto leave;
+
+ if (r_previous)
+ {
+ err = assuan_transact (agent_ctx, "GETINFO ephemeral",
+ NULL, NULL, NULL, NULL, NULL, NULL);
+ if (!err)
+ *r_previous = 1;
+ else if (gpg_err_code (err) == GPG_ERR_FALSE)
+ *r_previous = 0;
+ else
+ goto leave;
+ }
+
+ /* Skip setting if we are only querying or if the mode is already set. */
+ if (enable == -1 || (r_previous && !!*r_previous == !!enable))
+ err = 0;
+ else
+ err = assuan_transact (agent_ctx,
+ enable? "OPTION ephemeral=1" : "OPTION ephemeral=0",
+ NULL, NULL, NULL, NULL, NULL, NULL);
+ leave:
+ return err;
+}
+
+
/* Return the version reported by gpg-agent. */
gpg_error_t
agent_get_version (ctrl_t ctrl, char **r_version)
diff --git a/g10/call-agent.h b/g10/call-agent.h
index 45af95422..1e72dc03f 100644
--- a/g10/call-agent.h
+++ b/g10/call-agent.h
@@ -247,6 +247,10 @@ gpg_error_t agent_delete_key (ctrl_t ctrl, const char *hexkeygrip,
gpg_error_t agent_passwd (ctrl_t ctrl, const char *hexkeygrip, const char *desc,
int verify,
char **cache_nonce_addr, char **passwd_nonce_addr);
+
+/* Set or get the ephemeral mode. */
+gpg_error_t agent_set_ephemeral_mode (ctrl_t ctrl, int enable, int *r_previous);
+
/* Get the version reported by gpg-agent. */
gpg_error_t agent_get_version (ctrl_t ctrl, char **r_version);
diff --git a/g10/keyedit.c b/g10/keyedit.c
index a12546f71..cae0f7841 100644
--- a/g10/keyedit.c
+++ b/g10/keyedit.c
@@ -1905,6 +1905,7 @@ keyedit_menu (ctrl_t ctrl, const char *username, strlist_t locusr,
PACKET *pkt;
IOBUF a;
struct parse_packet_ctx_s parsectx;
+ int lastmode;
if (!*arg_string)
{
@@ -1959,17 +1960,28 @@ keyedit_menu (ctrl_t ctrl, const char *username, strlist_t locusr,
xfree (fname);
node = new_kbnode (pkt);
- /* Transfer it to gpg-agent which handles secret keys. */
- err = transfer_secret_keys (ctrl, NULL, node, 1, 1, 0);
-
- /* Treat the pkt as a public key. */
- pkt->pkttype = PKT_PUBLIC_KEY;
-
- /* Ask gpg-agent to store the secret key to card. */
- if (card_store_subkey (node, 0, NULL))
+ err = agent_set_ephemeral_mode (ctrl, 1, &lastmode);
+ if (err)
+ log_error ("error switching to ephemeral mode: %s\n",
+ gpg_strerror (err));
+ else
{
- redisplay = 1;
- sec_shadowing = 1;
+ /* Transfer it to gpg-agent which handles secret keys. */
+ err = transfer_secret_keys (ctrl, NULL, node, 1, 1, 0);
+ if (!err)
+ {
+ /* Treat the pkt as a public key. */
+ pkt->pkttype = PKT_PUBLIC_KEY;
+
+ /* Ask gpg-agent to store the secret key to card. */
+ if (card_store_subkey (node, 0, NULL))
+ {
+ redisplay = 1;
+ sec_shadowing = 1;
+ }
+ }
+ if (!lastmode && agent_set_ephemeral_mode (ctrl, 0, NULL))
+ log_error ("error clearing the ephemeral mode\n");
}
release_kbnode (node);
}
diff --git a/g10/keygen.c b/g10/keygen.c
index 886c3b007..b263a47de 100644
--- a/g10/keygen.c
+++ b/g10/keygen.c
@@ -5754,7 +5754,6 @@ do_generate_keypair (ctrl_t ctrl, struct para_data_s *para,
if (!err && get_parameter (para, pSUBKEYTYPE))
{
- const char *cardbackupkey = NULL;
int subkey_algo = get_parameter_algo (ctrl, para, pSUBKEYTYPE, NULL);
key_from_hexgrip = get_parameter_value (para, pSUBKEYGRIP);
@@ -5769,22 +5768,57 @@ do_generate_keypair (ctrl_t ctrl, struct para_data_s *para,
pub_root, subkeytimestamp,
get_parameter_u32 (para, pSUBKEYEXPIRE),
1, &keygen_flags);
- else if (!card
- || (cardbackupkey = get_parameter_value (para, pCARDBACKUPKEY)))
+ else if (get_parameter_value (para, pCARDBACKUPKEY))
{
+ int lastmode;
unsigned int mykeygenflags = KEYGEN_FLAG_NO_PROTECTION;
+ err = agent_set_ephemeral_mode (ctrl, 1, &lastmode);
+ if (err)
+ log_error ("error switching to ephemeral mode: %s\n",
+ gpg_strerror (err));
+ else
+ {
+ err = do_create (subkey_algo,
+ get_parameter_uint (para, pSUBKEYLENGTH),
+ get_parameter_value (para, pSUBKEYCURVE),
+ pub_root,
+ subkeytimestamp,
+ get_parameter_u32 (para, pSUBKEYEXPIRE), 1,
+ &mykeygenflags,
+ get_parameter_passphrase (para),
+ &cache_nonce, NULL,
+ NULL, NULL);
+ /* Get the pointer to the generated public subkey packet. */
+ if (!err)
+ {
+ kbnode_t node;
+
+ for (node = pub_root; node; node = node->next)
+ if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
+ sub_psk = node->pkt->pkt.public_key;
+ log_assert (sub_psk);
+ err = card_store_key_with_backup (ctrl,
+ sub_psk, gnupg_homedir ());
+ }
+
+ /* Reset the ephemeral mode as needed. */
+ if (!lastmode && agent_set_ephemeral_mode (ctrl, 0, NULL))
+ log_error ("error clearing the ephemeral mode\n");
+ }
+ }
+ else if (!card)
+ {
err = do_create (subkey_algo,
get_parameter_uint (para, pSUBKEYLENGTH),
get_parameter_value (para, pSUBKEYCURVE),
pub_root,
subkeytimestamp,
get_parameter_u32 (para, pSUBKEYEXPIRE), 1,
- cardbackupkey? &mykeygenflags : &keygen_flags,
+ &keygen_flags,
get_parameter_passphrase (para),
&cache_nonce, NULL,
NULL, NULL);
- /* Get the pointer to the generated public subkey packet. */
if (!err)
{
kbnode_t node;
@@ -5793,10 +5827,6 @@ do_generate_keypair (ctrl_t ctrl, struct para_data_s *para,
if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
sub_psk = node->pkt->pkt.public_key;
log_assert (sub_psk);
-
- if (cardbackupkey)
- err = card_store_key_with_backup (ctrl,
- sub_psk, gnupg_homedir ());
}
}
else