summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2023-05-26 11:59:46 +0200
committerWerner Koch <wk@gnupg.org>2023-05-26 11:59:46 +0200
commit13013ec1c0d308b5d22f176f3850840cbbf21f05 (patch)
treec4758ca5e39b1f5ab3d82917cad82ffee0e43f7d
parentcommon: New function nve_set (diff)
downloadgnupg2-13013ec1c0d308b5d22f176f3850840cbbf21f05.tar.xz
gnupg2-13013ec1c0d308b5d22f176f3850840cbbf21f05.zip
agent: Create and use Token entries to track the display s/n.
* agent/findkey.c (agent_write_private_key): Add arg dispserialno and update the token. (agent_write_shadow_key): Add arg dispserialno and adjust all callers. -- GnuPG-bug-id: 6135 Note that this has been forward ported from 2.2
-rw-r--r--agent/agent.h13
-rw-r--r--agent/command-ssh.c9
-rw-r--r--agent/command.c15
-rw-r--r--agent/cvt-openpgp.c4
-rw-r--r--agent/divert-tpm2.c2
-rw-r--r--agent/findkey.c61
-rw-r--r--agent/genkey.c3
-rw-r--r--agent/learncard.c10
-rw-r--r--agent/pksign.c9
-rw-r--r--agent/protect-tool.c5
10 files changed, 102 insertions, 29 deletions
diff --git a/agent/agent.h b/agent/agent.h
index 4e7452eee..531fad210 100644
--- a/agent/agent.h
+++ b/agent/agent.h
@@ -452,10 +452,12 @@ void start_command_handler_ssh (ctrl_t, gnupg_fd_t);
/*-- findkey.c --*/
gpg_error_t agent_modify_description (const char *in, const char *comment,
const gcry_sexp_t key, char **result);
-int agent_write_private_key (const unsigned char *grip,
- const void *buffer, size_t length, int force,
- const char *serialno, const char *keyref,
- time_t timestamp);
+gpg_error_t agent_write_private_key (const unsigned char *grip,
+ const void *buffer, size_t length,
+ int force,
+ const char *serialno, const char *keyref,
+ const char *dispserialno,
+ time_t timestamp);
gpg_error_t agent_key_from_file (ctrl_t ctrl,
const char *cache_nonce,
const char *desc_text,
@@ -587,7 +589,8 @@ gpg_error_t s2k_hash_passphrase (const char *passphrase, int hashalgo,
unsigned char *key, size_t keylen);
gpg_error_t agent_write_shadow_key (const unsigned char *grip,
const char *serialno, const char *keyid,
- const unsigned char *pkbuf, int force);
+ const unsigned char *pkbuf, int force,
+ const char *dispserialno);
/*-- trustlist.c --*/
diff --git a/agent/command-ssh.c b/agent/command-ssh.c
index 51111a60d..ca3993321 100644
--- a/agent/command-ssh.c
+++ b/agent/command-ssh.c
@@ -2432,9 +2432,14 @@ card_key_available (ctrl_t ctrl, const struct card_key_info_s *keyinfo,
hex2bin (keyinfo->keygrip, grip, sizeof (grip));
if ( agent_key_available (grip) )
{
+ char *dispserialno;
+
/* (Shadow)-key is not available in our key storage. */
+ agent_card_getattr (ctrl, "$DISPSERIALNO", &dispserialno,
+ keyinfo->keygrip);
err = agent_write_shadow_key (grip, keyinfo->serialno,
- keyinfo->idstr, pkbuf, 0);
+ keyinfo->idstr, pkbuf, 0, dispserialno);
+ xfree (dispserialno);
if (err)
{
xfree (pkbuf);
@@ -3282,7 +3287,7 @@ ssh_identity_register (ctrl_t ctrl, ssh_key_type_spec_t *spec,
/* Store this key to our key storage. We do not store a creation
* timestamp because we simply do not know. */
err = agent_write_private_key (key_grip_raw, buffer, buffer_n, 0,
- NULL, NULL, 0);
+ NULL, NULL, NULL, 0);
if (err)
goto out;
diff --git a/agent/command.c b/agent/command.c
index dd7cb5e57..b7a71cbe5 100644
--- a/agent/command.c
+++ b/agent/command.c
@@ -1359,7 +1359,14 @@ cmd_readkey (assuan_context_t ctx, char *line)
if (agent_key_available (grip))
{
/* (Shadow)-key is not available in our key storage. */
- rc = agent_write_shadow_key (grip, serialno, keyid, pkbuf, 0);
+ char *dispserialno;
+ char hexgrip[40+1];
+
+ bin2hex (grip, 20, hexgrip);
+ agent_card_getattr (ctrl, "$DISPSERIALNO", &dispserialno, hexgrip);
+ rc = agent_write_shadow_key (grip, serialno, keyid, pkbuf, 0,
+ dispserialno);
+ xfree (dispserialno);
if (rc)
goto leave;
}
@@ -2916,11 +2923,11 @@ cmd_import_key (assuan_context_t ctx, char *line)
ctrl->s2k_count);
if (!err)
err = agent_write_private_key (grip, finalkey, finalkeylen, force,
- NULL, NULL, opt_timestamp);
+ NULL, NULL, NULL, opt_timestamp);
}
else
- err = agent_write_private_key (grip, key, realkeylen, force, NULL, NULL,
- opt_timestamp);
+ err = agent_write_private_key (grip, key, realkeylen, force,
+ NULL, NULL, NULL, opt_timestamp);
leave:
gcry_sexp_release (openpgp_sexp);
diff --git a/agent/cvt-openpgp.c b/agent/cvt-openpgp.c
index 9bb815ff8..6aad35bff 100644
--- a/agent/cvt-openpgp.c
+++ b/agent/cvt-openpgp.c
@@ -1148,7 +1148,7 @@ convert_from_openpgp_native (ctrl_t ctrl,
&protectedkey, &protectedkeylen,
ctrl->s2k_count))
agent_write_private_key (grip, protectedkey, protectedkeylen, 1,
- NULL, NULL, 0);
+ NULL, NULL, NULL, 0);
xfree (protectedkey);
}
else
@@ -1157,7 +1157,7 @@ convert_from_openpgp_native (ctrl_t ctrl,
agent_write_private_key (grip,
*r_key,
gcry_sexp_canon_len (*r_key, 0, NULL,NULL),
- 1, NULL, NULL, 0);
+ 1, NULL, NULL, NULL, 0);
}
}
diff --git a/agent/divert-tpm2.c b/agent/divert-tpm2.c
index 4cae66218..b2f884f93 100644
--- a/agent/divert-tpm2.c
+++ b/agent/divert-tpm2.c
@@ -50,7 +50,7 @@ agent_write_tpm2_shadow_key (ctrl_t ctrl, const unsigned char *grip,
len = gcry_sexp_canon_len (shdkey, 0, NULL, NULL);
err = agent_write_private_key (grip, shdkey, len, 1 /*force*/,
- NULL, NULL, 0);
+ NULL, NULL, NULL, 0);
xfree (shdkey);
if (err)
log_error ("error writing key: %s\n", gpg_strerror (err));
diff --git a/agent/findkey.c b/agent/findkey.c
index 098d5224f..a9cb96a0c 100644
--- a/agent/findkey.c
+++ b/agent/findkey.c
@@ -84,12 +84,13 @@ linefeed_to_percent0A (const char *string)
* storage. With FORCE passed as true an existing key with the given
* GRIP will get overwritten. If SERIALNO and KEYREF are given a
* Token line is added to the key if the extended format is used. If
- * TIMESTAMP is not zero and the key doies not yet exists it will be
+ * TIMESTAMP is not zero and the key does not yet exists it will be
* recorded as creation date. */
-int
+gpg_error_t
agent_write_private_key (const unsigned char *grip,
const void *buffer, size_t length, int force,
const char *serialno, const char *keyref,
+ const char *dispserialno,
time_t timestamp)
{
gpg_error_t err;
@@ -100,7 +101,10 @@ agent_write_private_key (const unsigned char *grip,
nvc_t pk = NULL;
gcry_sexp_t key = NULL;
int remove = 0;
+ char *token0 = NULL;
char *token = NULL;
+ char *dispserialno_buffer = NULL;
+ char **tokenfields = NULL;
bin2hex (grip, 20, hexgrip);
strcpy (hexgrip+40, ".key");
@@ -225,19 +229,34 @@ agent_write_private_key (const unsigned char *grip,
{
nve_t item;
const char *s;
+ size_t token0len;
+
+ if (dispserialno)
+ {
+ /* Escape the DISPSERIALNO. */
+ dispserialno_buffer = percent_plus_escape (dispserialno);
+ if (!dispserialno_buffer)
+ {
+ err = gpg_error_from_syserror ();
+ goto leave;
+ }
+ dispserialno = dispserialno_buffer;
+ }
- token = strconcat (serialno, " ", keyref, NULL);
- if (!token)
+ token0 = strconcat (serialno, " ", keyref, NULL);
+ if (token0)
+ token = strconcat (token0, " - ", dispserialno? dispserialno:"-", NULL);
+ if (!token0 || !token)
{
err = gpg_error_from_syserror ();
goto leave;
}
- /* fixme: the strcmp should compare only the first two strings. */
+ token0len = strlen (token0);
for (item = nvc_lookup (pk, "Token:");
item;
item = nve_next_value (item, "Token:"))
- if ((s = nve_value (item)) && !strcmp (s, token))
+ if ((s = nve_value (item)) && !strncmp (s, token0, token0len))
break;
if (!item)
{
@@ -248,6 +267,23 @@ agent_write_private_key (const unsigned char *grip,
if (err)
goto leave;
}
+ else
+ {
+ /* Token exists: Update the display s/n. It may have
+ * changed due to changes in a newer software version. */
+ if (s && (tokenfields = strtokenize (s, " \t\n"))
+ && tokenfields[0] && tokenfields[1] && tokenfields[2]
+ && tokenfields[3]
+ && !strcmp (tokenfields[3], dispserialno))
+ ; /* No need to update Token entry. */
+ else
+ {
+ err = nve_set (item, token);
+ if (err)
+ goto leave;
+ }
+ }
+
}
/* If a timestamp has been supplied and the key is new, write a
@@ -300,12 +336,15 @@ agent_write_private_key (const unsigned char *grip,
leave:
es_fclose (fp);
- if (remove)
+ if (remove && fname)
gnupg_remove (fname);
xfree (fname);
+ xfree (token);
+ xfree (token0);
+ xfree (dispserialno_buffer);
+ xfree (tokenfields);
gcry_sexp_release (key);
nvc_release (pk);
- xfree (token);
return err;
}
@@ -1794,7 +1833,8 @@ agent_delete_key (ctrl_t ctrl, const char *desc_text,
gpg_error_t
agent_write_shadow_key (const unsigned char *grip,
const char *serialno, const char *keyid,
- const unsigned char *pkbuf, int force)
+ const unsigned char *pkbuf, int force,
+ const char *dispserialno)
{
gpg_error_t err;
unsigned char *shadow_info;
@@ -1821,7 +1861,8 @@ agent_write_shadow_key (const unsigned char *grip,
}
len = gcry_sexp_canon_len (shdkey, 0, NULL, NULL);
- err = agent_write_private_key (grip, shdkey, len, force, serialno, keyid, 0);
+ err = agent_write_private_key (grip, shdkey, len, force,
+ serialno, keyid, dispserialno, 0);
xfree (shdkey);
if (err)
log_error ("error writing key: %s\n", gpg_strerror (err));
diff --git a/agent/genkey.c b/agent/genkey.c
index 7660443ca..741c05f4f 100644
--- a/agent/genkey.c
+++ b/agent/genkey.c
@@ -67,7 +67,8 @@ store_key (gcry_sexp_t private, const char *passphrase, int force,
buf = p;
}
- rc = agent_write_private_key (grip, buf, len, force, NULL, NULL, timestamp);
+ rc = agent_write_private_key (grip, buf, len, force,
+ NULL, NULL, NULL, timestamp);
xfree (buf);
return rc;
}
diff --git a/agent/learncard.c b/agent/learncard.c
index 678ff9b96..8d80b809d 100644
--- a/agent/learncard.c
+++ b/agent/learncard.c
@@ -408,7 +408,15 @@ agent_handle_learn (ctrl_t ctrl, int send, void *assuan_context, int force)
goto leave;
}
- rc = agent_write_shadow_key (grip, serialno, item->id, pubkey, force);
+ {
+ char *dispserialno;
+
+ agent_card_getattr (ctrl, "$DISPSERIALNO", &dispserialno,
+ item->hexgrip);
+ rc = agent_write_shadow_key (grip, serialno, item->id, pubkey, force,
+ dispserialno);
+ xfree (dispserialno);
+ }
xfree (pubkey);
if (rc)
goto leave;
diff --git a/agent/pksign.c b/agent/pksign.c
index dfed0e398..a7b5c579f 100644
--- a/agent/pksign.c
+++ b/agent/pksign.c
@@ -372,8 +372,15 @@ agent_pksign_do (ctrl_t ctrl, const char *cache_nonce,
}
if (keyref)
- agent_write_shadow_key (ctrl->keygrip, serialno, keyref, pkbuf, 0);
+ {
+ char *dispserialno;
+ agent_card_getattr (ctrl, "$DISPSERIALNO", &dispserialno,
+ hexgrip);
+ agent_write_shadow_key (ctrl->keygrip, serialno, keyref, pkbuf,
+ 0, dispserialno);
+ xfree (dispserialno);
+ }
algo = get_pk_algo_from_key (s_pkey);
xfree (serialno);
diff --git a/agent/protect-tool.c b/agent/protect-tool.c
index 87cf36814..17f6fd559 100644
--- a/agent/protect-tool.c
+++ b/agent/protect-tool.c
@@ -813,11 +813,11 @@ agent_askpin (ctrl_t ctrl,
/* Replacement for the function in findkey.c. Here we write the key
* to stdout. */
-int
+gpg_error_t
agent_write_private_key (const unsigned char *grip,
const void *buffer, size_t length, int force,
const char *serialno, const char *keyref,
- time_t timestamp)
+ const char *dispserialno, time_t timestamp)
{
char hexgrip[40+4+1];
char *p;
@@ -826,6 +826,7 @@ agent_write_private_key (const unsigned char *grip,
(void)serialno;
(void)keyref;
(void)timestamp;
+ (void)dispserialno;
bin2hex (grip, 20, hexgrip);
strcpy (hexgrip+40, ".key");