aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Kahn Gillmor <[email protected]>2016-06-10 20:15:33 +0000
committerWerner Koch <[email protected]>2016-06-11 09:09:09 +0000
commit00f30cc01c79bbdff5cdc3be795f009f15d3845e (patch)
tree501c18c6aaa3ce352b42736d2bf92da7f8c6d5ef
parentspeedo,w32: Distribute gpg-preset-passphrase. (diff)
downloadgnupg-00f30cc01c79bbdff5cdc3be795f009f15d3845e.tar.gz
gnupg-00f30cc01c79bbdff5cdc3be795f009f15d3845e.zip
g10: report whether key in agent is passphrase-protected or not
* 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 <[email protected]>
-rw-r--r--g10/call-agent.c61
-rw-r--r--g10/call-agent.h2
-rw-r--r--g10/export.c2
-rw-r--r--g10/gpgv.c4
-rw-r--r--g10/keyedit.c4
-rw-r--r--g10/keygen.c2
-rw-r--r--g10/keylist.c10
-rw-r--r--g10/sign.c2
-rw-r--r--g10/test-stubs.c4
9 files changed, 60 insertions, 31 deletions
diff --git a/g10/call-agent.c b/g10/call-agent.c
index 46dfd5779..470fa168c 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 4e83388d2..a5d01e65b 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 aae8d421f..d47c27d23 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 30b44220c..2aed10c2a 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 aa62cc145..d05ea5d01 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 ad5dfa420..b8e4cb832 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 231f3c00e..973a9fb9d 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 364634adc..15c18eeb7 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 cfaa72c02..42c91f869 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);
}