diff options
author | Werner Koch <[email protected]> | 2020-02-11 19:51:33 +0000 |
---|---|---|
committer | Werner Koch <[email protected]> | 2020-02-11 19:51:33 +0000 |
commit | 9c719c9c1ff34cc06a0fef2bfe29cfd7182753eb (patch) | |
tree | 747fcf6be3254cbf593b92f9492104af3afd7dbf /g10/call-agent.c | |
parent | scd:openpgp: Send a KEY-TIME status with READKEY (diff) | |
download | gnupg-9c719c9c1ff34cc06a0fef2bfe29cfd7182753eb.tar.gz gnupg-9c719c9c1ff34cc06a0fef2bfe29cfd7182753eb.zip |
gpg: Improve key creation direct from the card.
* g10/call-agent.c (readkey_status_cb): New.
(agent_scd_readkey): Add new arg r_keytime and allow NULL for
r_result. Change all callers.
(agent_readkey): Minor code reformatting.
* g10/keygen.c (pCARDKEY): New.
(struct para_data_s): Add u.bool.
(get_parameter_bool): New.
(do_create_from_keygrip): Add arg cardkey and make use of it.
(ask_algo): Add args r_cardkey and r_keytime. Read the keytime of the
selected card key and return it.
(generate_keypair): Store CARDKEY and KEYTIME.
(do_generate_keypair): Pass CARDKEY to do_create_from_keygrip.
(generate_subkeypair): Ditto.
--
This allows to first create keys on the card (e.g. using gpg-card)
even without having any public key for OpenPGP. Then the key
generation option 14 (cardkey) can be used to create a primary OpenPGP
key from the key on the card.
There are still a couple of problems related to the agent which
creates the stub key and may run into problems if creating a second
key from the card. This will be fixed in a future patch.
Signed-off-by: Werner Koch <[email protected]>
Diffstat (limited to 'g10/call-agent.c')
-rw-r--r-- | g10/call-agent.c | 65 |
1 files changed, 53 insertions, 12 deletions
diff --git a/g10/call-agent.c b/g10/call-agent.c index 5a877c38f..5faa2d311 100644 --- a/g10/call-agent.c +++ b/g10/call-agent.c @@ -1,6 +1,7 @@ /* call-agent.c - Divert GPG operations to the agent. * Copyright (C) 2001-2003, 2006-2011, 2013 Free Software Foundation, Inc. * Copyright (C) 2013-2015 Werner Koch + * Copyright (C) 2020 g10 Code GmbH * * This file is part of GnuPG. * @@ -1379,11 +1380,35 @@ agent_scd_readcert (const char *certidstr, } +/* Callback for the agent_scd_readkey fucntion. */ +static gpg_error_t +readkey_status_cb (void *opaque, const char *line) +{ + u32 *keytimep = opaque; + const char *args; + + if ((args = has_leading_keyword (line, "KEY-TIME"))) + { + /* Skip the keyref - READKEY returns just one. */ + while (*args && !spacep (args)) + args++; + while (spacep (args)) + args++; + /* We are at the keytime. */ + *keytimep = strtoul (args, NULL, 10); + } + + return 0; +} + /* This is a variant of agent_readkey which sends a READKEY command * directly Scdaemon. On success a new s-expression is stored at - * R_RESULT. */ + * R_RESULT. If R_KEYTIME is not NULL the key cresation time of an + * OpenPGP card is stored there - if that is not known 0 is stored. + * In the latter case it is allowed to pass NULL for R_RESULT. */ gpg_error_t -agent_scd_readkey (const char *keyrefstr, gcry_sexp_t *r_result) +agent_scd_readkey (const char *keyrefstr, + gcry_sexp_t *r_result, u32 *r_keytime) { gpg_error_t err; char line[ASSUAN_LINELENGTH]; @@ -1391,21 +1416,28 @@ agent_scd_readkey (const char *keyrefstr, gcry_sexp_t *r_result) unsigned char *buf; size_t len, buflen; struct default_inq_parm_s dfltparm; + u32 keytime; memset (&dfltparm, 0, sizeof dfltparm); dfltparm.ctx = agent_ctx; - *r_result = NULL; + if (r_result) + *r_result = NULL; + if (r_keytime) + *r_keytime = 0; err = start_agent (NULL, 1); if (err) return err; init_membuf (&data, 1024); - snprintf (line, DIM(line), "SCD READKEY %s", keyrefstr); + snprintf (line, DIM(line), + "SCD READKEY --info%s -- %s", + r_result? "":"-only", keyrefstr); + keytime = 0; err = assuan_transact (agent_ctx, line, put_membuf_cb, &data, default_inq_cb, &dfltparm, - NULL, NULL); + readkey_status_cb, &keytime); if (err) { xfree (get_membuf (&data, &len)); @@ -1415,9 +1447,14 @@ agent_scd_readkey (const char *keyrefstr, gcry_sexp_t *r_result) if (!buf) return gpg_error_from_syserror (); - err = gcry_sexp_new (r_result, buf, buflen, 0); + if (r_result) + err = gcry_sexp_new (r_result, buf, buflen, 0); + else + err = 0; xfree (buf); + if (!err && r_keytime) + *r_keytime = keytime; return err; } @@ -2250,10 +2287,12 @@ agent_genkey (ctrl_t ctrl, char **cache_nonce_addr, char **passwd_nonce_addr, -/* Call the agent to read the public key part for a given keygrip. If - FROMCARD is true, the key is directly read from the current - smartcard. In this case HEXKEYGRIP should be the keyID - (e.g. OPENPGP.3). */ +/* Call the agent to read the public key part for a given keygrip. + * Values from FROMCARD: + * 0 - Standard + * 1 - The key is read from the current card + * via the agent and a stub file is created. + */ gpg_error_t agent_readkey (ctrl_t ctrl, int fromcard, const char *hexkeygrip, unsigned char **r_pubkey) @@ -2278,8 +2317,10 @@ agent_readkey (ctrl_t ctrl, int fromcard, const char *hexkeygrip, if (err) return err; - snprintf (line, DIM(line), "READKEY %s%s", fromcard? "--card ":"", - hexkeygrip); + if (fromcard) + snprintf (line, DIM(line), "READKEY --card -- %s", hexkeygrip); + else + snprintf (line, DIM(line), "READKEY -- %s", hexkeygrip); init_membuf (&data, 1024); err = assuan_transact (agent_ctx, line, |