1
0
mirror of git://git.gnupg.org/gnupg.git synced 2024-12-22 10:19:57 +01:00

agent: Fix diverting to TKDaemon.

Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
This commit is contained in:
NIIBE Yutaka 2023-03-17 15:22:52 +09:00
parent d0d728a5b7
commit 2c9e9e9294
No known key found for this signature in database
GPG Key ID: 640114AF89DE6054
6 changed files with 75 additions and 45 deletions

View File

@ -670,8 +670,7 @@ gpg_error_t divert_writekey (ctrl_t ctrl, int force, const char *serialno,
const char *keydata, size_t keydatalen); const char *keydata, size_t keydatalen);
/*-- divert-tkd.c --*/ /*-- divert-tkd.c --*/
int divert_tkd_pksign (ctrl_t ctrl, int divert_tkd_pksign (ctrl_t ctrl,
const unsigned char *grip, const unsigned char *digest, size_t digestlen,
const unsigned char *digest, size_t digestlen, int algo,
unsigned char **r_sig, size_t *r_siglen); unsigned char **r_sig, size_t *r_siglen);
/*-- call-daemon.c --*/ /*-- call-daemon.c --*/
@ -745,7 +744,6 @@ gpg_error_t agent_card_keyinfo (ctrl_t ctrl, const char *keygrip,
/*-- call-tkd.c --*/ /*-- call-tkd.c --*/
int agent_tkd_pksign (ctrl_t ctrl, int agent_tkd_pksign (ctrl_t ctrl,
const char *keygrip,
const unsigned char *indata, size_t indatalen, const unsigned char *indata, size_t indatalen,
unsigned char **r_buf, size_t *r_buflen); unsigned char **r_buf, size_t *r_buflen);
int agent_tkd_readkey (ctrl_t ctrl, const char *keygrip, int agent_tkd_readkey (ctrl_t ctrl, const char *keygrip,

View File

@ -90,17 +90,6 @@ inq_needpin (void *opaque, const char *line)
return rc; 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 static gpg_error_t
inq_extra (void *opaque, const char *line) inq_extra (void *opaque, const char *line)
{ {
@ -109,7 +98,7 @@ inq_extra (void *opaque, const char *line)
if (has_leading_keyword (line, "EXTRA")) if (has_leading_keyword (line, "EXTRA"))
return assuan_send_data (parm->ctx, parm->extra, parm->extralen); return assuan_send_data (parm->ctx, parm->extra, parm->extralen);
else else
return inq_keydata (opaque, line); return inq_needpin (opaque, line);
} }
static gpg_error_t 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); *passphrase = agent_get_cache (ctrl, hexgrip, CACHE_MODE_USER);
if (*passphrase) if (*passphrase)
return 0; return 0;
return agent_get_passphrase(ctrl, passphrase, return agent_get_passphrase (ctrl, passphrase,
_("Please enter your passphrase, so that the " _("Please enter your passphrase, so that the "
"secret key can be unlocked for this session"), "secret key can be unlocked for this session"),
prompt, NULL, 0, prompt, NULL, 0,
hexgrip, CACHE_MODE_USER, NULL); hexgrip, CACHE_MODE_USER, NULL);
} }
/* Read a key with KEYGRIP and return it in a malloced buffer pointed /* 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]; char line[ASSUAN_LINELENGTH];
membuf_t data; membuf_t data;
size_t buflen; size_t buflen;
struct inq_parm_s inqparm;
*r_buf = NULL; *r_buf = NULL;
if (r_buflen) if (r_buflen)
@ -149,10 +139,17 @@ agent_tkd_readkey (ctrl_t ctrl, const char *keygrip,
return rc; return rc;
init_membuf (&data, 1024); 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); snprintf (line, DIM(line), "READKEY %s", keygrip);
rc = assuan_transact (daemon_ctx (ctrl), line, rc = assuan_transact (daemon_ctx (ctrl), line,
put_membuf_cb, &data, put_membuf_cb, &data,
NULL, NULL, NULL, NULL); inq_needpin, &inqparm,
NULL, NULL);
if (rc) if (rc)
{ {
xfree (get_membuf (&data, &buflen)); 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 int
agent_tkd_pksign (ctrl_t ctrl, const char *keygrip, agent_tkd_pksign (ctrl_t ctrl, const unsigned char *digest, size_t digestlen,
const unsigned char *digest, size_t digestlen,
unsigned char **r_sig, size_t *r_siglen) unsigned char **r_sig, size_t *r_siglen)
{ {
int rc; int rc;
@ -194,13 +209,13 @@ agent_tkd_pksign (ctrl_t ctrl, const char *keygrip,
inqparm.ctx = daemon_ctx (ctrl); inqparm.ctx = daemon_ctx (ctrl);
inqparm.getpin_cb = pin_cb; inqparm.getpin_cb = pin_cb;
inqparm.ctrl = ctrl; inqparm.ctrl = ctrl;
// inqparm.keydata = shadow_info;
// inqparm.keydatalen = gcry_sexp_canon_len (shadow_info, 0, NULL, NULL);
inqparm.extra = digest; inqparm.extra = digest;
inqparm.extralen = digestlen; inqparm.extralen = digestlen;
inqparm.pin = NULL; 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, rc = assuan_transact (daemon_ctx (ctrl), line,
put_membuf_cb, &data, put_membuf_cb, &data,

View File

@ -32,10 +32,8 @@
#include "../common/sexp-parse.h" #include "../common/sexp-parse.h"
int int
divert_tkd_pksign (ctrl_t ctrl, const unsigned char *grip, divert_tkd_pksign (ctrl_t ctrl, const unsigned char *digest, size_t digestlen,
const unsigned char *digest, size_t digestlen, int algo,
unsigned char **r_sig, size_t *r_siglen) unsigned char **r_sig, size_t *r_siglen)
{ {
(void)algo; return agent_tkd_pksign (ctrl, digest, digestlen, r_sig, r_siglen);
return agent_tkd_pksign(ctrl, grip, digest, digestlen, r_sig, r_siglen);
} }

View File

@ -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); err = agent_get_shadow_info_type (buf, &s, &shadow_type);
if (!err) if (!err)
{ {
n = gcry_sexp_canon_len (s, 0, NULL,NULL); if (!s)
log_assert (n);
*shadow_info = xtrymalloc (n);
if (!*shadow_info)
{ {
err = out_of_core (); *shadow_info = xstrdup ("tkd");
goto shadow_error; if (!*shadow_info)
{
err = out_of_core ();
goto shadow_error;
}
} }
else else
{ {
memcpy (*shadow_info, s, n); n = gcry_sexp_canon_len (s, 0, NULL,NULL);
/* log_assert (n);
* When it's a key on card (not on tpm2), maks sure *shadow_info = xtrymalloc (n);
* it's available. if (!*shadow_info)
*/ {
if (strcmp (shadow_type, "t1-v1") == 0 && !grip) err = out_of_core ();
err = prompt_for_card (ctrl, ctrl->keygrip, goto shadow_error;
keymeta, *shadow_info); }
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 else

View File

@ -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, err = divert_tpm2_pksign (ctrl,
data, datalen, data, datalen,
ctrl->digest.algo, ctrl->digest.algo,

View File

@ -1697,6 +1697,11 @@ agent_get_shadow_info_type (const unsigned char *shadowkey,
if (shadow_info) if (shadow_info)
*shadow_info = s; *shadow_info = s;
} }
else if (smatch(&s, n, "tkd-v1"))
{
if (shadow_info)
*shadow_info = NULL;
}
else else
return gpg_error (GPG_ERR_UNSUPPORTED_PROTOCOL); return gpg_error (GPG_ERR_UNSUPPORTED_PROTOCOL);
s = saved_s; s = saved_s;