diff --git a/agent/agent.h b/agent/agent.h index 2a722fd24..22a4d431b 100644 --- a/agent/agent.h +++ b/agent/agent.h @@ -505,11 +505,11 @@ void agent_reload_trustlist (void); /*-- divert-scd.c --*/ -int divert_pksign (ctrl_t ctrl, +int divert_pksign (ctrl_t ctrl, const char *desc_text, const unsigned char *digest, size_t digestlen, int algo, const unsigned char *shadow_info, unsigned char **r_sig, size_t *r_siglen); -int divert_pkdecrypt (ctrl_t ctrl, +int divert_pkdecrypt (ctrl_t ctrl, const char *desc_text, const unsigned char *cipher, const unsigned char *shadow_info, char **r_buf, size_t *r_len, int *r_padding); @@ -536,15 +536,19 @@ int agent_card_learn (ctrl_t ctrl, int agent_card_serialno (ctrl_t ctrl, char **r_serialno, const char *demand); int agent_card_pksign (ctrl_t ctrl, const char *keyid, - int (*getpin_cb)(void *, const char *, char*, size_t), + int (*getpin_cb)(void *, const char *, + const char *, char*, size_t), void *getpin_cb_arg, + const char *desc_text, int mdalgo, const unsigned char *indata, size_t indatalen, unsigned char **r_buf, size_t *r_buflen); int agent_card_pkdecrypt (ctrl_t ctrl, const char *keyid, - int (*getpin_cb)(void *, const char *, char*,size_t), + int (*getpin_cb)(void *, const char *, + const char *, char*,size_t), void *getpin_cb_arg, + const char *desc_text, const unsigned char *indata, size_t indatalen, char **r_buf, size_t *r_buflen, int *r_padding); int agent_card_readcert (ctrl_t ctrl, @@ -553,12 +557,14 @@ int agent_card_readkey (ctrl_t ctrl, const char *id, unsigned char **r_buf); int agent_card_writekey (ctrl_t ctrl, int force, const char *serialno, const char *id, const char *keydata, size_t keydatalen, - int (*getpin_cb)(void *, const char *, char*, size_t), + int (*getpin_cb)(void *, const char *, + const char *, char*, size_t), void *getpin_cb_arg); gpg_error_t agent_card_getattr (ctrl_t ctrl, const char *name, char **result); gpg_error_t agent_card_cardlist (ctrl_t ctrl, strlist_t *result); int agent_card_scd (ctrl_t ctrl, const char *cmdline, - int (*getpin_cb)(void *, const char *, char*, size_t), + int (*getpin_cb)(void *, const char *, + const char *, char*, size_t), void *getpin_cb_arg, void *assuan_context); diff --git a/agent/call-scd.c b/agent/call-scd.c index 8d46b905d..c86eb741a 100644 --- a/agent/call-scd.c +++ b/agent/call-scd.c @@ -79,14 +79,21 @@ struct learn_parm_s void *sinfo_cb_arg; }; -struct inq_needpin_s + +/* Callback parameter used by inq_getpin and inq_writekey_parms. */ +struct inq_needpin_parm_s { assuan_context_t ctx; - int (*getpin_cb)(void *, const char *, char*, size_t); + int (*getpin_cb)(void *, const char *, const char *, char*, size_t); void *getpin_cb_arg; + const char *getpin_cb_desc; assuan_context_t passthru; /* If not NULL, pass unknown inquiries up to the caller. */ int any_inq_seen; + + /* The next fields are used by inq_writekey_parm. */ + const unsigned char *keydata; + size_t keydatalen; }; @@ -714,7 +721,7 @@ agent_card_serialno (ctrl_t ctrl, char **r_serialno, const char *demand) static gpg_error_t inq_needpin (void *opaque, const char *line) { - struct inq_needpin_s *parm = opaque; + struct inq_needpin_parm_s *parm = opaque; const char *s; char *pin; size_t pinlen; @@ -729,18 +736,21 @@ inq_needpin (void *opaque, const char *line) if (!pin) return out_of_core (); - rc = parm->getpin_cb (parm->getpin_cb_arg, line, pin, pinlen); + rc = parm->getpin_cb (parm->getpin_cb_arg, parm->getpin_cb_desc, + line, pin, pinlen); if (!rc) rc = assuan_send_data (parm->ctx, pin, pinlen); xfree (pin); } else if ((s = has_leading_keyword (line, "POPUPPINPADPROMPT"))) { - rc = parm->getpin_cb (parm->getpin_cb_arg, s, NULL, 1); + rc = parm->getpin_cb (parm->getpin_cb_arg, parm->getpin_cb_desc, + s, NULL, 1); } else if ((s = has_leading_keyword (line, "DISMISSPINPADPROMPT"))) { - rc = parm->getpin_cb (parm->getpin_cb_arg, "", NULL, 0); + rc = parm->getpin_cb (parm->getpin_cb_arg, parm->getpin_cb_desc, + "", NULL, 0); } else if (parm->passthru) { @@ -824,13 +834,17 @@ cancel_inquire (ctrl_t ctrl, gpg_error_t rc) return rc; } + /* Create a signature using the current card. MDALGO is either 0 or - gives the digest algorithm. */ + * gives the digest algorithm. DESC_TEXT is an additional parameter + * passed to GETPIN_CB. */ int agent_card_pksign (ctrl_t ctrl, const char *keyid, - int (*getpin_cb)(void *, const char *, char*, size_t), + int (*getpin_cb)(void *, const char *, + const char *, char*, size_t), void *getpin_cb_arg, + const char *desc_text, int mdalgo, const unsigned char *indata, size_t indatalen, unsigned char **r_buf, size_t *r_buflen) @@ -838,7 +852,7 @@ agent_card_pksign (ctrl_t ctrl, int rc; char line[ASSUAN_LINELENGTH]; membuf_t data; - struct inq_needpin_s inqparm; + struct inq_needpin_parm_s inqparm; *r_buf = NULL; rc = start_scd (ctrl); @@ -859,8 +873,12 @@ agent_card_pksign (ctrl_t ctrl, inqparm.ctx = ctrl->scd_local->ctx; inqparm.getpin_cb = getpin_cb; inqparm.getpin_cb_arg = getpin_cb_arg; + inqparm.getpin_cb_desc = desc_text; inqparm.passthru = 0; inqparm.any_inq_seen = 0; + inqparm.keydata = NULL; + inqparm.keydatalen = 0; + if (ctrl->use_auth_call) snprintf (line, sizeof line, "PKAUTH %s", keyid); else @@ -906,21 +924,24 @@ padding_info_cb (void *opaque, const char *line) /* Decipher INDATA using the current card. Note that the returned - value is not an s-expression but the raw data as returned by - scdaemon. The padding information is stored at R_PADDING with -1 - for not known. */ + * value is not an s-expression but the raw data as returned by + * scdaemon. The padding information is stored at R_PADDING with -1 + * for not known. DESC_TEXT is an additional parameter passed to + * GETPIN_CB. */ int agent_card_pkdecrypt (ctrl_t ctrl, const char *keyid, - int (*getpin_cb)(void *, const char *, char*, size_t), + int (*getpin_cb)(void *, const char *, + const char *, char*, size_t), void *getpin_cb_arg, + const char *desc_text, const unsigned char *indata, size_t indatalen, char **r_buf, size_t *r_buflen, int *r_padding) { int rc, i; char *p, line[ASSUAN_LINELENGTH]; membuf_t data; - struct inq_needpin_s inqparm; + struct inq_needpin_parm_s inqparm; size_t len; *r_buf = NULL; @@ -951,8 +972,11 @@ agent_card_pkdecrypt (ctrl_t ctrl, inqparm.ctx = ctrl->scd_local->ctx; inqparm.getpin_cb = getpin_cb; inqparm.getpin_cb_arg = getpin_cb_arg; + inqparm.getpin_cb_desc = desc_text; inqparm.passthru = 0; inqparm.any_inq_seen = 0; + inqparm.keydata = NULL; + inqparm.keydatalen = 0; snprintf (line, DIM(line), "PKDECRYPT %s", keyid); rc = assuan_transact (ctrl->scd_local->ctx, line, put_membuf_cb, &data, @@ -1051,24 +1075,12 @@ agent_card_readkey (ctrl_t ctrl, const char *id, unsigned char **r_buf) } -struct writekey_parm_s -{ - assuan_context_t ctx; - int (*getpin_cb)(void *, const char *, char*, size_t); - void *getpin_cb_arg; - assuan_context_t passthru; - int any_inq_seen; - /**/ - const unsigned char *keydata; - size_t keydatalen; -}; - /* Handle a KEYDATA inquiry. Note, we only send the data, assuan_transact takes care of flushing and writing the end */ static gpg_error_t inq_writekey_parms (void *opaque, const char *line) { - struct writekey_parm_s *parm = opaque; + struct inq_needpin_parm_s *parm = opaque; if (has_leading_keyword (line, "KEYDATA")) return assuan_send_data (parm->ctx, parm->keydata, parm->keydatalen); @@ -1080,12 +1092,13 @@ inq_writekey_parms (void *opaque, const char *line) int agent_card_writekey (ctrl_t ctrl, int force, const char *serialno, const char *id, const char *keydata, size_t keydatalen, - int (*getpin_cb)(void *, const char *, char*, size_t), + int (*getpin_cb)(void *, const char *, + const char *, char*, size_t), void *getpin_cb_arg) { int rc; char line[ASSUAN_LINELENGTH]; - struct writekey_parm_s parms; + struct inq_needpin_parm_s parms; (void)serialno; rc = start_scd (ctrl); @@ -1096,6 +1109,7 @@ agent_card_writekey (ctrl_t ctrl, int force, const char *serialno, parms.ctx = ctrl->scd_local->ctx; parms.getpin_cb = getpin_cb; parms.getpin_cb_arg = getpin_cb_arg; + parms.getpin_cb_desc= NULL; parms.passthru = 0; parms.any_inq_seen = 0; parms.keydata = keydata; @@ -1108,6 +1122,8 @@ agent_card_writekey (ctrl_t ctrl, int force, const char *serialno, rc = cancel_inquire (ctrl, rc); return unlock_scd (ctrl, rc); } + + /* Type used with the card_getattr_cb. */ struct card_getattr_parm_s { @@ -1190,6 +1206,8 @@ agent_card_getattr (ctrl_t ctrl, const char *name, char **result) return unlock_scd (ctrl, err); } + + struct card_cardlist_parm_s { int error; @@ -1258,6 +1276,8 @@ agent_card_cardlist (ctrl_t ctrl, strlist_t *result) return unlock_scd (ctrl, err); } + + static gpg_error_t pass_status_thru (void *opaque, const char *line) @@ -1307,11 +1327,12 @@ pass_data_thru (void *opaque, const void *buffer, size_t length) inquiry is handled inside gpg-agent. */ int agent_card_scd (ctrl_t ctrl, const char *cmdline, - int (*getpin_cb)(void *, const char *, char*, size_t), + int (*getpin_cb)(void *, const char *, + const char *, char*, size_t), void *getpin_cb_arg, void *assuan_context) { int rc; - struct inq_needpin_s inqparm; + struct inq_needpin_parm_s inqparm; int saveflag; rc = start_scd (ctrl); @@ -1321,8 +1342,12 @@ agent_card_scd (ctrl_t ctrl, const char *cmdline, inqparm.ctx = ctrl->scd_local->ctx; inqparm.getpin_cb = getpin_cb; inqparm.getpin_cb_arg = getpin_cb_arg; + inqparm.getpin_cb_desc = NULL; inqparm.passthru = assuan_context; inqparm.any_inq_seen = 0; + inqparm.keydata = NULL; + inqparm.keydatalen = 0; + saveflag = assuan_get_flag (ctrl->scd_local->ctx, ASSUAN_CONVEY_COMMENTS); assuan_set_flag (ctrl->scd_local->ctx, ASSUAN_CONVEY_COMMENTS, 1); rc = assuan_transact (ctrl->scd_local->ctx, cmdline, diff --git a/agent/divert-scd.c b/agent/divert-scd.c index c23c67335..5ffb7ea54 100644 --- a/agent/divert-scd.c +++ b/agent/divert-scd.c @@ -163,6 +163,9 @@ encode_md_for_card (const unsigned char *digest, size_t digestlen, int algo, string with the passphrase, the buffer may optionally be padded with arbitrary characters. + If DESC_TEXT is not NULL it can be used as further informtion shown + atop of the INFO message. + INFO gets displayed as part of a generic string. However if the first character of INFO is a vertical bar all up to the next verical bar are considered flags and only everything after the @@ -185,7 +188,8 @@ encode_md_for_card (const unsigned char *digest, size_t digestlen, int algo, are considered. */ static int -getpin_cb (void *opaque, const char *info, char *buf, size_t maxbuf) +getpin_cb (void *opaque, const char *desc_text, const char *info, + char *buf, size_t maxbuf) { struct pin_entry_info_s *pi; int rc; @@ -337,9 +341,13 @@ getpin_cb (void *opaque, const char *info, char *buf, size_t maxbuf) - +/* This function is used when a sign operation has been diverted to a + * smartcard. DESC_TEXT is the original text for a prompt has send by + * gpg to gpg-agent. + * + * FIXME: Explain the other args. */ int -divert_pksign (ctrl_t ctrl, +divert_pksign (ctrl_t ctrl, const char *desc_text, const unsigned char *digest, size_t digestlen, int algo, const unsigned char *shadow_info, unsigned char **r_sig, size_t *r_siglen) @@ -357,7 +365,7 @@ divert_pksign (ctrl_t ctrl, { int save = ctrl->use_auth_call; ctrl->use_auth_call = 1; - rc = agent_card_pksign (ctrl, kid, getpin_cb, ctrl, + rc = agent_card_pksign (ctrl, kid, getpin_cb, ctrl, desc_text, algo, digest, digestlen, &sigval, &siglen); ctrl->use_auth_call = save; } @@ -369,7 +377,7 @@ divert_pksign (ctrl_t ctrl, rc = encode_md_for_card (digest, digestlen, algo, &data, &ndata); if (!rc) { - rc = agent_card_pksign (ctrl, kid, getpin_cb, ctrl, + rc = agent_card_pksign (ctrl, kid, getpin_cb, ctrl, desc_text, algo, data, ndata, &sigval, &siglen); xfree (data); } @@ -392,7 +400,7 @@ divert_pksign (ctrl_t ctrl, allocated buffer in R_BUF. The padding information is stored at R_PADDING with -1 for not known. */ int -divert_pkdecrypt (ctrl_t ctrl, +divert_pkdecrypt (ctrl_t ctrl, const char *desc_text, const unsigned char *cipher, const unsigned char *shadow_info, char **r_buf, size_t *r_len, int *r_padding) @@ -471,7 +479,7 @@ divert_pkdecrypt (ctrl_t ctrl, if (rc) return rc; - rc = agent_card_pkdecrypt (ctrl, kid, getpin_cb, ctrl, + rc = agent_card_pkdecrypt (ctrl, kid, getpin_cb, ctrl, desc_text, ciphertext, ciphertextlen, &plaintext, &plaintextlen, r_padding); if (!rc) diff --git a/agent/pkdecrypt.c b/agent/pkdecrypt.c index 3d0f5aac6..f1023b433 100644 --- a/agent/pkdecrypt.c +++ b/agent/pkdecrypt.c @@ -86,7 +86,7 @@ agent_pkdecrypt (ctrl_t ctrl, const char *desc_text, goto leave; } - rc = divert_pkdecrypt (ctrl, ciphertext, shadow_info, + rc = divert_pkdecrypt (ctrl, desc_text, ciphertext, shadow_info, &buf, &len, r_padding); if (rc) { diff --git a/agent/pksign.c b/agent/pksign.c index b34760818..4a5daedb0 100644 --- a/agent/pksign.c +++ b/agent/pksign.c @@ -346,7 +346,7 @@ agent_pksign_do (ctrl_t ctrl, const char *cache_nonce, is_ECDSA = 1; } - rc = divert_pksign (ctrl, + rc = divert_pksign (ctrl, desc_text, data, datalen, ctrl->digest.algo, shadow_info, &buf, &len);