[PATCH v2 1/4] g10: report whether key in agent is passphrase-protected or not
Daniel Kahn Gillmor
dkg at fifthhorseman.net
Fri Jun 10 22:15:33 CEST 2016
* g10/call-agent.c, g10/call-agent.h (agent_get_keyinfo): add
r_cleartext parameter to report whether a key is stored without
passphrase protection.
* g10/gpgv.c, g10/test-stubs.c: augment dummy agent_get_keyinfo to
match new API.
* g10/export.c, g10/keyedit.c, g10/keygen.c, g10/keylist.c,
g10/sign.c: pass NULL to agent_get_keyinfo since we do not yet
need to know whether agent is passphrase-protected.
--
Signed-off-by: Daniel Kahn Gillmor <dkg at fifthhorseman.net>
---
g10/call-agent.c | 61 +++++++++++++++++++++++++++++++++++++++-----------------
g10/call-agent.h | 2 +-
g10/export.c | 2 +-
g10/gpgv.c | 4 +++-
g10/keyedit.c | 4 ++--
g10/keygen.c | 2 +-
g10/keylist.c | 10 +++++-----
g10/sign.c | 2 +-
g10/test-stubs.c | 4 +++-
9 files changed, 60 insertions(+), 31 deletions(-)
diff --git a/g10/call-agent.c b/g10/call-agent.c
index 46dfd57..470fa16 100644
--- a/g10/call-agent.c
+++ b/g10/call-agent.c
@@ -1671,26 +1671,42 @@ agent_probe_any_secret_key (ctrl_t ctrl, kbnode_t keyblock)
+struct keyinfo_data {
+ char *serialno;
+ int cleartext;
+};
+
static gpg_error_t
keyinfo_status_cb (void *opaque, const char *line)
{
- char **serialno = opaque;
+ struct keyinfo_data *data = opaque;
+ int is_smartcard;
const char *s, *s2;
- if ((s = has_leading_keyword (line, "KEYINFO")) && !*serialno)
+ if ((s = has_leading_keyword (line, "KEYINFO")) && data)
{
s = strchr (s, ' ');
- if (s && s[1] == 'T' && s[2] == ' ' && s[3])
+ if (s)
{
- s += 3;
- s2 = strchr (s, ' ');
- if ( s2 > s )
+ is_smartcard = (s[1] == 'T');
+ if ( s[2] == ' ' && s[3] )
{
- *serialno = xtrymalloc ((s2 - s)+1);
- if (*serialno)
+ s += 3;
+ s2 = strchr (s, ' ');
+ if ( s2 > s )
{
- memcpy (*serialno, s, s2 - s);
- (*serialno)[s2 - s] = 0;
+ if (is_smartcard && !data->serialno)
+ {
+ data->serialno = xtrymalloc ((s2 - s)+1);
+ if (data->serialno)
+ {
+ memcpy (data->serialno, s, s2 - s);
+ (data->serialno)[s2 - s] = 0;
+ }
+ }
+ if (s2 = strchr (s2 + 1, ' '), s2) /* skip IDSTR (can IDSTR contain a space?) */
+ if (s2 = strchr (s2 + 1, ' '), s2) /* skip CACHED */
+ data->cleartext = (s2[1] == 'C'); /* 'P' for protected, 'C' for clear */
}
}
}
@@ -1701,13 +1717,18 @@ keyinfo_status_cb (void *opaque, const char *line)
/* Return the serial number for a secret key. If the returned serial
number is NULL, the key is not stored on a smartcard. Caller needs
- to free R_SERIALNO. */
+ to free R_SERIALNO.
+
+ if r_cleartext is not NULL, the referenced int will be set to 1 if
+ the agent's copy of the key is stored in the clear, or 0 otherwise
+*/
gpg_error_t
-agent_get_keyinfo (ctrl_t ctrl, const char *hexkeygrip, char **r_serialno)
+agent_get_keyinfo (ctrl_t ctrl, const char *hexkeygrip,
+ char **r_serialno, int *r_cleartext)
{
gpg_error_t err;
char line[ASSUAN_LINELENGTH];
- char *serialno = NULL;
+ struct keyinfo_data keyinfo = { .serialno = NULL, .cleartext = 0 };
*r_serialno = NULL;
@@ -1722,17 +1743,21 @@ agent_get_keyinfo (ctrl_t ctrl, const char *hexkeygrip, char **r_serialno)
line[DIM(line)-1] = 0;
err = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL,
- keyinfo_status_cb, &serialno);
- if (!err && serialno)
+ keyinfo_status_cb, &keyinfo);
+ if (!err && keyinfo.serialno)
{
/* Sanity check for bad characters. */
- if (strpbrk (serialno, ":\n\r"))
+ if (strpbrk (keyinfo.serialno, ":\n\r"))
err = GPG_ERR_INV_VALUE;
}
if (err)
- xfree (serialno);
+ xfree (keyinfo.serialno);
else
- *r_serialno = serialno;
+ {
+ *r_serialno = keyinfo.serialno;
+ if (r_cleartext)
+ *r_cleartext = keyinfo.cleartext;
+ }
return err;
}
diff --git a/g10/call-agent.h b/g10/call-agent.h
index 4e83388..a5d01e6 100644
--- a/g10/call-agent.h
+++ b/g10/call-agent.h
@@ -153,7 +153,7 @@ gpg_error_t agent_probe_any_secret_key (ctrl_t ctrl, kbnode_t keyblock);
/* Return infos about the secret key with HEXKEYGRIP. */
gpg_error_t agent_get_keyinfo (ctrl_t ctrl, const char *hexkeygrip,
- char **r_serialno);
+ char **r_serialno, int *r_cleartext);
/* Generate a new key. */
gpg_error_t agent_genkey (ctrl_t ctrl,
diff --git a/g10/export.c b/g10/export.c
index aae8d42..d47c27d 100644
--- a/g10/export.c
+++ b/g10/export.c
@@ -1228,7 +1228,7 @@ do_export_stream (ctrl_t ctrl, iobuf_t out, strlist_t users, int secret,
serialno = NULL;
}
else
- err = agent_get_keyinfo (ctrl, hexgrip, &serialno);
+ err = agent_get_keyinfo (ctrl, hexgrip, &serialno, NULL);
if ((!err && serialno)
&& secret == 2 && node->pkt->pkttype == PKT_PUBLIC_KEY)
diff --git a/g10/gpgv.c b/g10/gpgv.c
index 30b4422..2aed10c 100644
--- a/g10/gpgv.c
+++ b/g10/gpgv.c
@@ -603,10 +603,12 @@ agent_probe_any_secret_key (ctrl_t ctrl, kbnode_t keyblock)
}
gpg_error_t
-agent_get_keyinfo (ctrl_t ctrl, const char *hexkeygrip, char **r_serialno)
+agent_get_keyinfo (ctrl_t ctrl, const char *hexkeygrip,
+ char **r_serialno, int *r_cleartext)
{
(void)ctrl;
(void)hexkeygrip;
+ (void)r_cleartext;
*r_serialno = NULL;
return gpg_error (GPG_ERR_NO_SECKEY);
}
diff --git a/g10/keyedit.c b/g10/keyedit.c
index aa62cc1..d05ea5d 100644
--- a/g10/keyedit.c
+++ b/g10/keyedit.c
@@ -1692,7 +1692,7 @@ change_passphrase (ctrl_t ctrl, kbnode_t keyblock)
err = hexkeygrip_from_pk (pk, &hexgrip);
if (err)
goto leave;
- err = agent_get_keyinfo (ctrl, hexgrip, &serialno);
+ err = agent_get_keyinfo (ctrl, hexgrip, &serialno, NULL);
if (!err && serialno)
; /* Key on card. */
else if (gpg_err_code (err) == GPG_ERR_NOT_FOUND)
@@ -3766,7 +3766,7 @@ show_key_with_all_names (ctrl_t ctrl, estream_t fp,
have_seckey = 0;
}
else
- have_seckey = !agent_get_keyinfo (ctrl, hexgrip, &serialno);
+ have_seckey = !agent_get_keyinfo (ctrl, hexgrip, &serialno, NULL);
xfree (hexgrip);
}
diff --git a/g10/keygen.c b/g10/keygen.c
index ad5dfa4..b8e4cb8 100644
--- a/g10/keygen.c
+++ b/g10/keygen.c
@@ -4571,7 +4571,7 @@ generate_subkeypair (ctrl_t ctrl, kbnode_t keyblock, const char *algostr,
err = hexkeygrip_from_pk (pri_psk, &hexgrip);
if (err)
goto leave;
- if (agent_get_keyinfo (NULL, hexgrip, &serialno))
+ if (agent_get_keyinfo (NULL, hexgrip, &serialno, NULL))
{
if (interactive)
tty_printf (_("Secret parts of primary key are not available.\n"));
diff --git a/g10/keylist.c b/g10/keylist.c
index 231f3c0..973a9fb 100644
--- a/g10/keylist.c
+++ b/g10/keylist.c
@@ -247,7 +247,7 @@ print_card_key_info (estream_t fp, kbnode_t keyblock)
log_error ("error computing a keygrip: %s\n", gpg_strerror (rc));
s2k_char = '?';
}
- else if (!agent_get_keyinfo (NULL, hexgrip, &serialno))
+ else if (!agent_get_keyinfo (NULL, hexgrip, &serialno, NULL))
s2k_char = serialno? '>':' ';
else
s2k_char = '#'; /* Key not found. */
@@ -1046,7 +1046,7 @@ list_keyblock_print (ctrl_t ctrl, kbnode_t keyblock, int secret, int fpr,
if (secret)
{
/* Encode some info about the secret key in SECRET. */
- if (!agent_get_keyinfo (NULL, hexgrip, &serialno))
+ if (!agent_get_keyinfo (NULL, hexgrip, &serialno, NULL))
secret = serialno? 3 : 1;
else
secret = 2; /* Key not found. */
@@ -1160,7 +1160,7 @@ list_keyblock_print (ctrl_t ctrl, kbnode_t keyblock, int secret, int fpr,
}
if (secret)
{
- if (!agent_get_keyinfo (NULL, hexgrip, &serialno))
+ if (!agent_get_keyinfo (NULL, hexgrip, &serialno, NULL))
secret = serialno? 3 : 1;
else
secret = '2'; /* Key not found. */
@@ -1354,7 +1354,7 @@ list_keyblock_colon (ctrl_t ctrl, kbnode_t keyblock,
log_error ("error computing a keygrip: %s\n", gpg_strerror (rc));
}
stubkey = 0;
- if ((secret||has_secret) && agent_get_keyinfo (NULL, hexgrip, &serialno))
+ if ((secret||has_secret) && agent_get_keyinfo (NULL, hexgrip, &serialno, NULL))
stubkey = 1; /* Key not found. */
keyid_from_pk (pk, keyid);
@@ -1501,7 +1501,7 @@ list_keyblock_colon (ctrl_t ctrl, kbnode_t keyblock,
}
stubkey = 0;
if ((secret||has_secret)
- && agent_get_keyinfo (NULL, hexgrip, &serialno))
+ && agent_get_keyinfo (NULL, hexgrip, &serialno, NULL))
stubkey = 1; /* Key not found. */
keyid_from_pk (pk2, keyid2);
diff --git a/g10/sign.c b/g10/sign.c
index 364634a..15c18ee 100644
--- a/g10/sign.c
+++ b/g10/sign.c
@@ -346,7 +346,7 @@ openpgp_card_v1_p (PKT_public_key *pk)
}
xfree (pk->serialno);
- agent_get_keyinfo (NULL, hexgrip, &pk->serialno);
+ agent_get_keyinfo (NULL, hexgrip, &pk->serialno, NULL);
xfree (hexgrip);
pk->flags.serialno_valid = 1;
}
diff --git a/g10/test-stubs.c b/g10/test-stubs.c
index cfaa72c..42c91f8 100644
--- a/g10/test-stubs.c
+++ b/g10/test-stubs.c
@@ -415,10 +415,12 @@ agent_probe_any_secret_key (ctrl_t ctrl, kbnode_t keyblock)
}
gpg_error_t
-agent_get_keyinfo (ctrl_t ctrl, const char *hexkeygrip, char **r_serialno)
+agent_get_keyinfo (ctrl_t ctrl, const char *hexkeygrip,
+ char **r_serialno, int *r_cleartext)
{
(void)ctrl;
(void)hexkeygrip;
+ (void)r_cleartext;
*r_serialno = NULL;
return gpg_error (GPG_ERR_NO_SECKEY);
}
--
2.8.1
More information about the Gnupg-devel
mailing list