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/call-agent.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/call-agent.c')
-rw-r--r-- | g10/call-agent.c | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/g10/call-agent.c b/g10/call-agent.c index 3b4882b53..f603d491a 100644 --- a/g10/call-agent.c +++ b/g10/call-agent.c @@ -948,6 +948,86 @@ agent_keytocard (const char *hexgrip, int keyno, int force, +/* Object used with the agent_scd_getattr_one. */ +struct getattr_one_parm_s { + const char *keyword; /* Keyword to look for. */ + char *data; /* Malloced and unescaped data. */ + gpg_error_t err; /* Error code or 0 on success. */ +}; + + +/* Callback for agent_scd_getattr_one. */ +static gpg_error_t +getattr_one_status_cb (void *opaque, const char *line) +{ + struct getattr_one_parm_s *parm = opaque; + const char *s; + + if (parm->data) + return 0; /* We want only the first occurrence. */ + + if ((s=has_leading_keyword (line, parm->keyword))) + { + parm->data = percent_plus_unescape (s, 0xff); + if (!parm->data) + parm->err = gpg_error_from_syserror (); + } + + return 0; +} + + +/* Simplified version of agent_scd_getattr. This function returns + * only the first occurance of the attribute NAME and stores it at + * R_VALUE. A nul in the result is silennly replaced by 0xff. On + * error NULL is stored at R_VALUE. */ +gpg_error_t +agent_scd_getattr_one (const char *name, char **r_value) +{ + gpg_error_t err; + char line[ASSUAN_LINELENGTH]; + struct default_inq_parm_s inqparm; + struct getattr_one_parm_s parm; + + *r_value = NULL; + + if (!*name) + return gpg_error (GPG_ERR_INV_VALUE); + + memset (&inqparm, 0, sizeof inqparm); + inqparm.ctx = agent_ctx; + + memset (&parm, 0, sizeof parm); + parm.keyword = name; + + /* We assume that NAME does not need escaping. */ + if (12 + strlen (name) > DIM(line)-1) + return gpg_error (GPG_ERR_TOO_LARGE); + stpcpy (stpcpy (line, "SCD GETATTR "), name); + + err = start_agent (NULL, 1); + if (err) + return err; + + err = assuan_transact (agent_ctx, line, + NULL, NULL, + default_inq_cb, &inqparm, + getattr_one_status_cb, &parm); + if (!err && parm.err) + err = parm.err; + else if (!err && !parm.data) + err = gpg_error (GPG_ERR_NO_DATA); + + if (!err) + *r_value = parm.data; + else + xfree (parm.data); + + return err; +} + + + /* Call the agent to retrieve a data object. This function returns * the data in the same structure as used by the learn command. It is * allowed to update such a structure using this command. |