diff --git a/agent/agent.h b/agent/agent.h index 5ab710f1d..90a6d0d3f 100644 --- a/agent/agent.h +++ b/agent/agent.h @@ -670,8 +670,7 @@ gpg_error_t divert_writekey (ctrl_t ctrl, int force, const char *serialno, const char *keydata, size_t keydatalen); /*-- divert-tkd.c --*/ int divert_tkd_pksign (ctrl_t ctrl, - const unsigned char *grip, - const unsigned char *digest, size_t digestlen, int algo, + const unsigned char *digest, size_t digestlen, unsigned char **r_sig, size_t *r_siglen); /*-- call-daemon.c --*/ @@ -745,7 +744,6 @@ gpg_error_t agent_card_keyinfo (ctrl_t ctrl, const char *keygrip, /*-- call-tkd.c --*/ int agent_tkd_pksign (ctrl_t ctrl, - const char *keygrip, const unsigned char *indata, size_t indatalen, unsigned char **r_buf, size_t *r_buflen); int agent_tkd_readkey (ctrl_t ctrl, const char *keygrip, diff --git a/agent/call-tkd.c b/agent/call-tkd.c index cbcfcd0dd..44857ba89 100644 --- a/agent/call-tkd.c +++ b/agent/call-tkd.c @@ -90,17 +90,6 @@ inq_needpin (void *opaque, const char *line) return rc; } -static gpg_error_t -inq_keydata (void *opaque, const char *line) -{ - struct inq_parm_s *parm = opaque; - - if (has_leading_keyword (line, "KEYDATA")) - return assuan_send_data (parm->ctx, parm->keydata, parm->keydatalen); - else - return inq_needpin (opaque, line); -} - static gpg_error_t inq_extra (void *opaque, const char *line) { @@ -109,7 +98,7 @@ inq_extra (void *opaque, const char *line) if (has_leading_keyword (line, "EXTRA")) return assuan_send_data (parm->ctx, parm->extra, parm->extralen); else - return inq_keydata (opaque, line); + return inq_needpin (opaque, line); } static gpg_error_t @@ -121,11 +110,11 @@ pin_cb (ctrl_t ctrl, const char *prompt, char **passphrase) *passphrase = agent_get_cache (ctrl, hexgrip, CACHE_MODE_USER); if (*passphrase) return 0; - return agent_get_passphrase(ctrl, passphrase, - _("Please enter your passphrase, so that the " - "secret key can be unlocked for this session"), - prompt, NULL, 0, - hexgrip, CACHE_MODE_USER, NULL); + return agent_get_passphrase (ctrl, passphrase, + _("Please enter your passphrase, so that the " + "secret key can be unlocked for this session"), + prompt, NULL, 0, + hexgrip, CACHE_MODE_USER, NULL); } /* Read a key with KEYGRIP and return it in a malloced buffer pointed @@ -139,6 +128,7 @@ agent_tkd_readkey (ctrl_t ctrl, const char *keygrip, char line[ASSUAN_LINELENGTH]; membuf_t data; size_t buflen; + struct inq_parm_s inqparm; *r_buf = NULL; if (r_buflen) @@ -149,10 +139,17 @@ agent_tkd_readkey (ctrl_t ctrl, const char *keygrip, return rc; init_membuf (&data, 1024); + + inqparm.ctx = daemon_ctx (ctrl); + inqparm.getpin_cb = pin_cb; + inqparm.ctrl = ctrl; + inqparm.pin = NULL; + snprintf (line, DIM(line), "READKEY %s", keygrip); rc = assuan_transact (daemon_ctx (ctrl), line, put_membuf_cb, &data, - NULL, NULL, NULL, NULL); + inq_needpin, &inqparm, + NULL, NULL); if (rc) { xfree (get_membuf (&data, &buflen)); @@ -174,9 +171,27 @@ agent_tkd_readkey (ctrl_t ctrl, const char *keygrip, } +/* Helper returning a command option to describe the used hash + algorithm. See scd/command.c:cmd_pksign. */ +static const char * +hash_algo_option (int algo) +{ + switch (algo) + { + case GCRY_MD_MD5 : return "--hash=md5"; + case GCRY_MD_RMD160: return "--hash=rmd160"; + case GCRY_MD_SHA1 : return "--hash=sha1"; + case GCRY_MD_SHA224: return "--hash=sha224"; + case GCRY_MD_SHA256: return "--hash=sha256"; + case GCRY_MD_SHA384: return "--hash=sha384"; + case GCRY_MD_SHA512: return "--hash=sha512"; + default: return ""; + } +} + + int -agent_tkd_pksign (ctrl_t ctrl, const char *keygrip, - const unsigned char *digest, size_t digestlen, +agent_tkd_pksign (ctrl_t ctrl, const unsigned char *digest, size_t digestlen, unsigned char **r_sig, size_t *r_siglen) { int rc; @@ -194,13 +209,13 @@ agent_tkd_pksign (ctrl_t ctrl, const char *keygrip, inqparm.ctx = daemon_ctx (ctrl); inqparm.getpin_cb = pin_cb; inqparm.ctrl = ctrl; - // inqparm.keydata = shadow_info; - // inqparm.keydatalen = gcry_sexp_canon_len (shadow_info, 0, NULL, NULL); inqparm.extra = digest; inqparm.extralen = digestlen; inqparm.pin = NULL; - snprintf (line, sizeof(line), "PKSIGN %s", keygrip); + bin2hex (ctrl->keygrip, KEYGRIP_LEN, hexgrip); + snprintf (line, sizeof(line), "PKSIGN %s %s", + hash_algo_option (ctrl->digest.algo), hexgrip); rc = assuan_transact (daemon_ctx (ctrl), line, put_membuf_cb, &data, diff --git a/agent/divert-tkd.c b/agent/divert-tkd.c index b5e07bdf2..c61bef240 100644 --- a/agent/divert-tkd.c +++ b/agent/divert-tkd.c @@ -32,10 +32,8 @@ #include "../common/sexp-parse.h" int -divert_tkd_pksign (ctrl_t ctrl, const unsigned char *grip, - const unsigned char *digest, size_t digestlen, int algo, +divert_tkd_pksign (ctrl_t ctrl, const unsigned char *digest, size_t digestlen, unsigned char **r_sig, size_t *r_siglen) { - (void)algo; - return agent_tkd_pksign(ctrl, grip, digest, digestlen, r_sig, r_siglen); + return agent_tkd_pksign (ctrl, digest, digestlen, r_sig, r_siglen); } diff --git a/agent/findkey.c b/agent/findkey.c index 27881f380..14db330ed 100644 --- a/agent/findkey.c +++ b/agent/findkey.c @@ -1329,24 +1329,36 @@ agent_key_from_file (ctrl_t ctrl, const char *cache_nonce, err = agent_get_shadow_info_type (buf, &s, &shadow_type); if (!err) { - n = gcry_sexp_canon_len (s, 0, NULL,NULL); - log_assert (n); - *shadow_info = xtrymalloc (n); - if (!*shadow_info) + if (!s) { - err = out_of_core (); - goto shadow_error; + *shadow_info = xstrdup ("tkd"); + if (!*shadow_info) + { + err = out_of_core (); + goto shadow_error; + } } else { - memcpy (*shadow_info, s, n); - /* - * When it's a key on card (not on tpm2), maks sure - * it's available. - */ - if (strcmp (shadow_type, "t1-v1") == 0 && !grip) - err = prompt_for_card (ctrl, ctrl->keygrip, - keymeta, *shadow_info); + n = gcry_sexp_canon_len (s, 0, NULL,NULL); + log_assert (n); + *shadow_info = xtrymalloc (n); + if (!*shadow_info) + { + err = out_of_core (); + goto shadow_error; + } + else + { + memcpy (*shadow_info, s, n); + /* + * When it's a key on card (not on tpm2), make sure + * it's available. + */ + if (strcmp (shadow_type, "t1-v1") == 0 && !grip) + err = prompt_for_card (ctrl, ctrl->keygrip, + keymeta, *shadow_info); + } } } else diff --git a/agent/pksign.c b/agent/pksign.c index dfed0e398..1ee278aac 100644 --- a/agent/pksign.c +++ b/agent/pksign.c @@ -392,7 +392,9 @@ agent_pksign_do (ctrl_t ctrl, const char *cache_nonce, } { - if (agent_is_tpm2_key (s_skey)) + if (!strcmp (shadow_info, "tkd")) + err = divert_tkd_pksign (ctrl, data, datalen, &buf, &len); + else if (agent_is_tpm2_key (s_skey)) err = divert_tpm2_pksign (ctrl, data, datalen, ctrl->digest.algo, diff --git a/agent/protect.c b/agent/protect.c index b92b015df..3e08f9a93 100644 --- a/agent/protect.c +++ b/agent/protect.c @@ -1697,6 +1697,11 @@ agent_get_shadow_info_type (const unsigned char *shadowkey, if (shadow_info) *shadow_info = s; } + else if (smatch(&s, n, "tkd-v1")) + { + if (shadow_info) + *shadow_info = NULL; + } else return gpg_error (GPG_ERR_UNSUPPORTED_PROTOCOL); s = saved_s;