diff options
author | Werner Koch <wk@gnupg.org> | 2019-04-03 15:30:10 +0200 |
---|---|---|
committer | Werner Koch <wk@gnupg.org> | 2019-04-03 15:30:10 +0200 |
commit | ec6a6779236a89d4784a6bb7de0def9cc0f9e8a4 (patch) | |
tree | 69e7cc27c2e651f5b76dc20b97d90632d050897a /g10/skclist.c | |
parent | scd: New standard attributes $ENCRKEYID and $SIGNKEYID. (diff) | |
download | gnupg2-ec6a6779236a89d4784a6bb7de0def9cc0f9e8a4.tar.xz gnupg2-ec6a6779236a89d4784a6bb7de0def9cc0f9e8a4.zip |
gpg: Allow decryption using PIV cards.
* g10/call-agent.c (struct getattr_one_parm_s): New.
(getattr_one_status_cb): New.
(agent_scd_getattr_one): New.
* g10/pubkey-enc.c (get_it): Allow the standard leading zero byte from
pkcs#1.
* g10/skclist.c (enum_secret_keys): Handle non-OpenPGP cards.
Signed-off-by: Werner Koch <wk@gnupg.org>
Diffstat (limited to 'g10/skclist.c')
-rw-r--r-- | g10/skclist.c | 61 |
1 files changed, 53 insertions, 8 deletions
diff --git a/g10/skclist.c b/g10/skclist.c index ebbaba254..b4f83ea1a 100644 --- a/g10/skclist.c +++ b/g10/skclist.c @@ -340,6 +340,10 @@ enum_secret_keys (ctrl_t ctrl, void **context, PKT_public_key *sk) SK_LIST results; } *c = *context; +#if MAX_FINGERPRINT_LEN < KEYGRIP_LEN +# error buffer too short for this configuration +#endif + if (!c) { /* Make a new context. */ @@ -430,17 +434,58 @@ enum_secret_keys (ctrl_t ctrl, void **context, PKT_public_key *sk) xfree (serialno); c->info.fpr2len = 0; err = agent_scd_getattr ("KEY-FPR", &c->info); + if (!err) + { + if (c->info.fpr2len) + { + c->fpr2[0] = '0'; + c->fpr2[1] = 'x'; + bin2hex (c->info.fpr2, sizeof c->info.fpr2, + c->fpr2 + 2); + name = c->fpr2; + } + } + else if (gpg_err_code (err) == GPG_ERR_INV_NAME) + { + /* KEY-FPR not supported by the card - get + * the key using the keygrip. */ + char *keyref; + strlist_t kplist, sl; + const char *s; + int i; + + err = agent_scd_getattr_one ("$ENCRKEYID", &keyref); + if (!err) + { + err = agent_scd_keypairinfo (ctrl, &kplist); + if (!err) + { + for (sl = kplist; sl; sl = sl->next) + if ((s = strchr (sl->d, ' ')) + && !strcmp (s+1, keyref)) + break; + if (sl) + { + c->fpr2[0] = '&'; + for (i=1, s=sl->d; + (*s && *s != ' ' + && i < sizeof c->fpr2 - 3); + s++, i++) + c->fpr2[i] = *s; + c->fpr2[i] = 0; + name = c->fpr2; + } + else /* Restore error. */ + err = gpg_error (GPG_ERR_INV_NAME); + free_strlist (kplist); + } + } + xfree (keyref); + } if (err) - log_error ("error retrieving key fingerprint from card: %s\n", + log_error ("error retrieving key from card: %s\n", gpg_strerror (err)); - if (c->info.fpr2len) - { - c->fpr2[0] = '0'; - c->fpr2[1] = 'x'; - bin2hex (c->info.fpr2, sizeof c->info.fpr2,c->fpr2+2); - name = c->fpr2; - } c->sl = c->sl->next; } else |