mirror of
git://git.gnupg.org/gnupg.git
synced 2025-06-12 18:11:03 +02:00
agent: Call TKDaemon READKEY command.
Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
This commit is contained in:
parent
08ef809c5e
commit
d0855b1204
@ -748,8 +748,8 @@ int agent_tkd_pksign (ctrl_t ctrl,
|
|||||||
const char *keygrip,
|
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 *id,
|
int agent_tkd_readkey (ctrl_t ctrl, const char *keygrip,
|
||||||
unsigned char **r_buf, char **r_keyref);
|
unsigned char **r_buf, size_t *r_buflen);
|
||||||
|
|
||||||
/*-- learncard.c --*/
|
/*-- learncard.c --*/
|
||||||
int agent_handle_learn (ctrl_t ctrl, int send, void *assuan_context, int force);
|
int agent_handle_learn (ctrl_t ctrl, int send, void *assuan_context, int force);
|
||||||
|
@ -128,6 +128,52 @@ pin_cb (ctrl_t ctrl, const char *prompt, char **passphrase)
|
|||||||
hexgrip, CACHE_MODE_USER, NULL);
|
hexgrip, CACHE_MODE_USER, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Read a key with KEYGRIP and return it in a malloced buffer pointed
|
||||||
|
* to by R_BUF as a valid S-expression. If R_BUFLEN is not NULL the
|
||||||
|
* length is stored there. */
|
||||||
|
int
|
||||||
|
agent_tkd_readkey (ctrl_t ctrl, const char *keygrip,
|
||||||
|
unsigned char **r_buf, size_t *r_buflen)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
char line[ASSUAN_LINELENGTH];
|
||||||
|
membuf_t data;
|
||||||
|
size_t buflen;
|
||||||
|
|
||||||
|
*r_buf = NULL;
|
||||||
|
if (r_buflen)
|
||||||
|
*r_buflen = 0;
|
||||||
|
|
||||||
|
rc = start_tkd (ctrl);
|
||||||
|
if (rc)
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
init_membuf (&data, 1024);
|
||||||
|
snprintf (line, DIM(line), "READKEY %s", keygrip);
|
||||||
|
rc = assuan_transact (daemon_ctx (ctrl), line,
|
||||||
|
put_membuf_cb, &data,
|
||||||
|
NULL, NULL, NULL, NULL);
|
||||||
|
if (rc)
|
||||||
|
{
|
||||||
|
xfree (get_membuf (&data, &buflen));
|
||||||
|
return unlock_tkd (ctrl, rc);
|
||||||
|
}
|
||||||
|
*r_buf = get_membuf (&data, &buflen);
|
||||||
|
if (!*r_buf)
|
||||||
|
return unlock_tkd (ctrl, gpg_error (GPG_ERR_ENOMEM));
|
||||||
|
|
||||||
|
if (!gcry_sexp_canon_len (*r_buf, buflen, NULL, NULL))
|
||||||
|
{
|
||||||
|
xfree (*r_buf); *r_buf = NULL;
|
||||||
|
return unlock_tkd (ctrl, gpg_error (GPG_ERR_INV_VALUE));
|
||||||
|
}
|
||||||
|
if (r_buflen)
|
||||||
|
*r_buflen = buflen;
|
||||||
|
|
||||||
|
return unlock_tkd (ctrl, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
agent_tkd_pksign (ctrl_t ctrl, const char *keygrip,
|
agent_tkd_pksign (ctrl_t ctrl, const char *keygrip,
|
||||||
const unsigned char *digest, size_t digestlen,
|
const unsigned char *digest, size_t digestlen,
|
||||||
@ -154,7 +200,7 @@ agent_tkd_pksign (ctrl_t ctrl, const char *keygrip,
|
|||||||
inqparm.extralen = digestlen;
|
inqparm.extralen = digestlen;
|
||||||
inqparm.pin = NULL;
|
inqparm.pin = NULL;
|
||||||
|
|
||||||
snprintf(line, sizeof(line), "PKSIGN");
|
snprintf (line, sizeof(line), "PKSIGN %s", keygrip);
|
||||||
|
|
||||||
rc = assuan_transact (daemon_ctx (ctrl), line,
|
rc = assuan_transact (daemon_ctx (ctrl), line,
|
||||||
put_membuf_cb, &data,
|
put_membuf_cb, &data,
|
||||||
|
@ -1303,6 +1303,7 @@ cmd_keyattr (assuan_context_t ctx, char *line)
|
|||||||
static const char hlp_readkey[] =
|
static const char hlp_readkey[] =
|
||||||
"READKEY [--no-data] [--format=ssh] <hexstring_with_keygrip>\n"
|
"READKEY [--no-data] [--format=ssh] <hexstring_with_keygrip>\n"
|
||||||
" --card <keyid>\n"
|
" --card <keyid>\n"
|
||||||
|
" --token <hexstring_with_keygrip>\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Return the public key for the given keygrip or keyid.\n"
|
"Return the public key for the given keygrip or keyid.\n"
|
||||||
"With --card, private key file with card information will be created.";
|
"With --card, private key file with card information will be created.";
|
||||||
@ -1315,13 +1316,14 @@ cmd_readkey (assuan_context_t ctx, char *line)
|
|||||||
gcry_sexp_t s_pkey = NULL;
|
gcry_sexp_t s_pkey = NULL;
|
||||||
unsigned char *pkbuf = NULL;
|
unsigned char *pkbuf = NULL;
|
||||||
size_t pkbuflen;
|
size_t pkbuflen;
|
||||||
int opt_card, opt_no_data, opt_format_ssh;
|
int opt_card, opt_token, opt_no_data, opt_format_ssh;
|
||||||
|
|
||||||
if (ctrl->restricted)
|
if (ctrl->restricted)
|
||||||
return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
|
return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
|
||||||
|
|
||||||
opt_no_data = has_option (line, "--no-data");
|
opt_no_data = has_option (line, "--no-data");
|
||||||
opt_card = has_option (line, "--card");
|
opt_card = has_option (line, "--card");
|
||||||
|
opt_token = has_option (line, "--token");
|
||||||
opt_format_ssh = has_option (line, "--format=ssh");
|
opt_format_ssh = has_option (line, "--format=ssh");
|
||||||
|
|
||||||
line = skip_options (line);
|
line = skip_options (line);
|
||||||
@ -1373,6 +1375,34 @@ cmd_readkey (assuan_context_t ctx, char *line)
|
|||||||
xfree (serialno);
|
xfree (serialno);
|
||||||
xfree (keyidbuf);
|
xfree (keyidbuf);
|
||||||
}
|
}
|
||||||
|
else if (opt_token)
|
||||||
|
{
|
||||||
|
const char *keygrip = line;
|
||||||
|
|
||||||
|
rc = agent_tkd_readkey (ctrl, keygrip, &pkbuf, &pkbuflen);
|
||||||
|
if (rc)
|
||||||
|
goto leave;
|
||||||
|
rc = gcry_sexp_sscan (&s_pkey, NULL, (char*)pkbuf, pkbuflen);
|
||||||
|
if (rc)
|
||||||
|
goto leave;
|
||||||
|
|
||||||
|
if (!gcry_pk_get_keygrip (s_pkey, grip))
|
||||||
|
{
|
||||||
|
rc = gcry_pk_testkey (s_pkey);
|
||||||
|
if (rc == 0)
|
||||||
|
rc = gpg_error (GPG_ERR_INTERNAL);
|
||||||
|
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (agent_key_available (grip))
|
||||||
|
{
|
||||||
|
/* (Shadow)-key is not available in our key storage. */
|
||||||
|
rc = agent_write_shadow_key (grip, NULL, NULL, pkbuf, 0);
|
||||||
|
if (rc)
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
rc = parse_keygrip (ctx, line, grip);
|
rc = parse_keygrip (ctx, line, grip);
|
||||||
|
@ -1821,16 +1821,22 @@ agent_write_shadow_key (const unsigned char *grip,
|
|||||||
unsigned char *shdkey;
|
unsigned char *shdkey;
|
||||||
size_t len;
|
size_t len;
|
||||||
|
|
||||||
/* Just in case some caller did not parse the stuff correctly, skip
|
if (serialno == NULL && keyid == NULL)
|
||||||
* leading spaces. */
|
/* It's a token, identified by the keygrip. */
|
||||||
while (spacep (serialno))
|
shadow_info = NULL;
|
||||||
serialno++;
|
else
|
||||||
while (spacep (keyid))
|
{
|
||||||
keyid++;
|
/* Just in case some caller did not parse the stuff correctly, skip
|
||||||
|
* leading spaces. */
|
||||||
|
while (spacep (serialno))
|
||||||
|
serialno++;
|
||||||
|
while (spacep (keyid))
|
||||||
|
keyid++;
|
||||||
|
|
||||||
shadow_info = make_shadow_info (serialno, keyid);
|
shadow_info = make_shadow_info (serialno, keyid);
|
||||||
if (!shadow_info)
|
if (!shadow_info)
|
||||||
return gpg_error_from_syserror ();
|
return gpg_error_from_syserror ();
|
||||||
|
}
|
||||||
|
|
||||||
err = agent_shadow_key (pkbuf, shadow_info, &shdkey);
|
err = agent_shadow_key (pkbuf, shadow_info, &shdkey);
|
||||||
xfree (shadow_info);
|
xfree (shadow_info);
|
||||||
|
@ -342,9 +342,11 @@ to keys stored on a token:
|
|||||||
(comment whatever)
|
(comment whatever)
|
||||||
)
|
)
|
||||||
|
|
||||||
The currently used protocols are "t1-v1" (token info version 1) and
|
The currently used protocols are "t1-v1" (token info version 1),
|
||||||
"tpm2-v1" (TPM format key information). The second list with the
|
"tpm2-v1" (TPM format key information), and "tkd-v1" (token daemon
|
||||||
information has this layout for "t1-v1":
|
info version 1).
|
||||||
|
|
||||||
|
The second list with the information has this layout for "t1-v1":
|
||||||
|
|
||||||
(card_serial_number id_string_of_key fixed_pin_length)
|
(card_serial_number id_string_of_key fixed_pin_length)
|
||||||
|
|
||||||
@ -353,13 +355,15 @@ the PIN; a value of 0 indicates that this information is not
|
|||||||
available. The rationale for this field is that some pinpad equipped
|
available. The rationale for this field is that some pinpad equipped
|
||||||
readers don't allow passing a variable length PIN.
|
readers don't allow passing a variable length PIN.
|
||||||
|
|
||||||
This is the (info) layout for "tpm2-v1":
|
For "tpm2-v1", the layout of the (info) is:
|
||||||
|
|
||||||
(parent tpm_private_string tpm_public_string)
|
(parent tpm_private_string tpm_public_string)
|
||||||
|
|
||||||
Although this precise format is encapsulated inside the tpm2daemon
|
Although this precise format is encapsulated inside the tpm2daemon
|
||||||
itself and nothing in gpg ever uses this.
|
itself and nothing in gpg ever uses this.
|
||||||
|
|
||||||
|
For "tkd-v1", the layout of the (info) part is nothing.
|
||||||
|
|
||||||
More items may be added to the list.
|
More items may be added to the list.
|
||||||
|
|
||||||
** OpenPGP Private Key Transfer Format
|
** OpenPGP Private Key Transfer Format
|
||||||
|
@ -1545,10 +1545,15 @@ agent_shadow_key_type (const unsigned char *pubkey,
|
|||||||
int depth = 0;
|
int depth = 0;
|
||||||
char *p;
|
char *p;
|
||||||
size_t pubkey_len = gcry_sexp_canon_len (pubkey, 0, NULL,NULL);
|
size_t pubkey_len = gcry_sexp_canon_len (pubkey, 0, NULL,NULL);
|
||||||
size_t shadow_info_len = gcry_sexp_canon_len (shadow_info, 0, NULL,NULL);
|
size_t shadow_info_len;
|
||||||
|
|
||||||
if (!pubkey_len || !shadow_info_len)
|
if (!pubkey_len)
|
||||||
return gpg_error (GPG_ERR_INV_VALUE);
|
return gpg_error (GPG_ERR_INV_VALUE);
|
||||||
|
if (shadow_info)
|
||||||
|
shadow_info_len = gcry_sexp_canon_len (shadow_info, 0, NULL,NULL);
|
||||||
|
else
|
||||||
|
shadow_info_len = 0;
|
||||||
|
|
||||||
s = pubkey;
|
s = pubkey;
|
||||||
if (*s != '(')
|
if (*s != '(')
|
||||||
return gpg_error (GPG_ERR_INV_SEXP);
|
return gpg_error (GPG_ERR_INV_SEXP);
|
||||||
@ -1604,7 +1609,8 @@ agent_shadow_key_type (const unsigned char *pubkey,
|
|||||||
memcpy (p, pubkey+14, point - (pubkey+14));
|
memcpy (p, pubkey+14, point - (pubkey+14));
|
||||||
p += point - (pubkey+14);
|
p += point - (pubkey+14);
|
||||||
p += sprintf (p, "(8:shadowed%d:%s", (int)strlen(type), type);
|
p += sprintf (p, "(8:shadowed%d:%s", (int)strlen(type), type);
|
||||||
memcpy (p, shadow_info, shadow_info_len);
|
if (shadow_info_len)
|
||||||
|
memcpy (p, shadow_info, shadow_info_len);
|
||||||
p += shadow_info_len;
|
p += shadow_info_len;
|
||||||
*p++ = ')';
|
*p++ = ')';
|
||||||
memcpy (p, point, pubkey_len - (point - pubkey));
|
memcpy (p, point, pubkey_len - (point - pubkey));
|
||||||
@ -1618,7 +1624,10 @@ agent_shadow_key (const unsigned char *pubkey,
|
|||||||
const unsigned char *shadow_info,
|
const unsigned char *shadow_info,
|
||||||
unsigned char **result)
|
unsigned char **result)
|
||||||
{
|
{
|
||||||
return agent_shadow_key_type (pubkey, shadow_info, "t1-v1", result);
|
if (shadow_info)
|
||||||
|
return agent_shadow_key_type (pubkey, shadow_info, "t1-v1", result);
|
||||||
|
else
|
||||||
|
return agent_shadow_key_type (pubkey, NULL, "tkd-v1", result);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Parse a canonical encoded shadowed key and return a pointer to the
|
/* Parse a canonical encoded shadowed key and return a pointer to the
|
||||||
|
Loading…
x
Reference in New Issue
Block a user