From bcc89a6df24c79690436340f65c7ab13c65c2c45 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 5 Mar 2019 12:08:27 +0100 Subject: [PATCH] agent: Minor change to the KEYTOCARD command. * agent/command.c (cmd_keytocard): Make timestamp optional. Use modern parser function. * agent/call-scd.c (agent_card_writekey): Rename an arg and for clarity return gpg_error_t instead of int. * agent/divert-scd.c (divert_writekey): Ditto. Signed-off-by: Werner Koch --- agent/agent.h | 17 +++++----- agent/call-scd.c | 23 ++++++++------ agent/command.c | 78 +++++++++++++++++----------------------------- agent/divert-scd.c | 9 +++--- 4 files changed, 56 insertions(+), 71 deletions(-) diff --git a/agent/agent.h b/agent/agent.h index ee5a31eef..3a29dc817 100644 --- a/agent/agent.h +++ b/agent/agent.h @@ -548,8 +548,9 @@ int divert_pkdecrypt (ctrl_t ctrl, const char *desc_text, char **r_buf, size_t *r_len, int *r_padding); int divert_generic_cmd (ctrl_t ctrl, const char *cmdline, void *assuan_context); -int divert_writekey (ctrl_t ctrl, int force, const char *serialno, - const char *id, const char *keydata, size_t keydatalen); +gpg_error_t divert_writekey (ctrl_t ctrl, int force, const char *serialno, + const char *keyref, + const char *keydata, size_t keydatalen); /*-- call-scd.c --*/ @@ -586,12 +587,12 @@ int agent_card_pkdecrypt (ctrl_t ctrl, int agent_card_readcert (ctrl_t ctrl, const char *id, char **r_buf, size_t *r_buflen); 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 *, - const char *, char*, size_t), - void *getpin_cb_arg); +gpg_error_t agent_card_writekey (ctrl_t ctrl, int force, const char *serialno, + const char *keyref, + const char *keydata, size_t keydatalen, + 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, diff --git a/agent/call-scd.c b/agent/call-scd.c index d0d4794a4..1189bd477 100644 --- a/agent/call-scd.c +++ b/agent/call-scd.c @@ -1075,23 +1075,26 @@ inq_writekey_parms (void *opaque, const char *line) } -int +/* Call scd to write a key to a card under the id KEYREF. */ +gpg_error_t agent_card_writekey (ctrl_t ctrl, int force, const char *serialno, - const char *id, const char *keydata, size_t keydatalen, + const char *keyref, + const char *keydata, size_t keydatalen, int (*getpin_cb)(void *, const char *, const char *, char*, size_t), void *getpin_cb_arg) { - int rc; + gpg_error_t err; char line[ASSUAN_LINELENGTH]; struct inq_needpin_parm_s parms; (void)serialno; - rc = start_scd (ctrl); - if (rc) - return rc; - snprintf (line, DIM(line), "WRITEKEY %s%s", force ? "--force " : "", id); + err = start_scd (ctrl); + if (err) + return err; + + snprintf (line, DIM(line), "WRITEKEY %s%s", force ? "--force " : "", keyref); parms.ctx = ctrl->scd_local->ctx; parms.getpin_cb = getpin_cb; parms.getpin_cb_arg = getpin_cb_arg; @@ -1100,9 +1103,9 @@ agent_card_writekey (ctrl_t ctrl, int force, const char *serialno, parms.keydata = keydata; parms.keydatalen = keydatalen; - rc = assuan_transact (ctrl->scd_local->ctx, line, NULL, NULL, - inq_writekey_parms, &parms, NULL, NULL); - return unlock_scd (ctrl, rc); + err = assuan_transact (ctrl->scd_local->ctx, line, NULL, NULL, + inq_writekey_parms, &parms, NULL, NULL); + return unlock_scd (ctrl, err); } diff --git a/agent/command.c b/agent/command.c index 332d20ff4..62b701467 100644 --- a/agent/command.c +++ b/agent/command.c @@ -2484,19 +2484,23 @@ cmd_delete_key (assuan_context_t ctx, char *line) #endif static const char hlp_keytocard[] = - "KEYTOCARD [--force] \n" - "\n"; + "KEYTOCARD [--force] []\n" + "\n" + "TIMESTAMP is required for OpenPGP and defaults to the Epoch." + ; static gpg_error_t cmd_keytocard (assuan_context_t ctx, char *line) { ctrl_t ctrl = assuan_get_pointer (ctx); int force; gpg_error_t err = 0; + char *argv[5]; + int argc; unsigned char grip[20]; + const char *serialno, *timestamp_str, *keyref; gcry_sexp_t s_skey = NULL; unsigned char *keydata; size_t keydatalen; - const char *serialno, *timestamp_str, *id; unsigned char *shadow_info = NULL; time_t timestamp; @@ -2506,7 +2510,14 @@ cmd_keytocard (assuan_context_t ctx, char *line) force = has_option (line, "--force"); line = skip_options (line); - err = parse_keygrip (ctx, line, grip); + argc = split_fields (line, argv, DIM (argv)); + if (argc < 3) + { + err = gpg_error (GPG_ERR_MISSING_VALUE); + goto leave; + } + + err = parse_keygrip (ctx, argv[0], grip); if (err) goto leave; @@ -2516,39 +2527,9 @@ cmd_keytocard (assuan_context_t ctx, char *line) goto leave; } - /* Fixme: Replace the parsing code by split_fields(). */ - line += 40; - while (*line && (*line == ' ' || *line == '\t')) - line++; - serialno = line; - while (*line && (*line != ' ' && *line != '\t')) - line++; - if (!*line) - { - err = gpg_error (GPG_ERR_MISSING_VALUE); - goto leave; - } - *line = '\0'; - line++; - while (*line && (*line == ' ' || *line == '\t')) - line++; - id = line; - while (*line && (*line != ' ' && *line != '\t')) - line++; - if (!*line) - { - err = gpg_error (GPG_ERR_MISSING_VALUE); - goto leave; - } - *line = '\0'; - line++; - while (*line && (*line == ' ' || *line == '\t')) - line++; - timestamp_str = line; - while (*line && (*line != ' ' && *line != '\t')) - line++; - if (*line) - *line = '\0'; + serialno = argv[1]; + keyref = argv[2]; + timestamp_str = argc > 3? argv[3] : "19700101T000000"; if ((timestamp = isotime2epoch (timestamp_str)) == (time_t)(-1)) { @@ -2560,38 +2541,37 @@ cmd_keytocard (assuan_context_t ctx, char *line) &shadow_info, CACHE_MODE_IGNORE, NULL, &s_skey, NULL); if (err) - { - xfree (shadow_info); - goto leave; - } + goto leave; if (shadow_info) { - /* Key is on a smartcard already. */ - xfree (shadow_info); - gcry_sexp_release (s_skey); + /* Key is already on a smartcard - we can't extract it. */ err = gpg_error (GPG_ERR_UNUSABLE_SECKEY); goto leave; } - keydatalen = gcry_sexp_sprint (s_skey, GCRYSEXP_FMT_CANON, NULL, 0); + /* Note: We can't use make_canon_sexp because we need to allocate a + * few extra bytes for our hack below. */ + keydatalen = gcry_sexp_sprint (s_skey, GCRYSEXP_FMT_CANON, NULL, 0); keydata = xtrymalloc_secure (keydatalen + 30); if (keydata == NULL) { err = gpg_error_from_syserror (); - gcry_sexp_release (s_skey); goto leave; } - gcry_sexp_sprint (s_skey, GCRYSEXP_FMT_CANON, keydata, keydatalen); gcry_sexp_release (s_skey); + s_skey = NULL; keydatalen--; /* Decrement for last '\0'. */ - /* Add timestamp "created-at" in the private key */ + /* Hack to insert the timestamp "created-at" into the private key. */ snprintf (keydata+keydatalen-1, 30, KEYTOCARD_TIMESTAMP_FORMAT, timestamp); keydatalen += 10 + 19 - 1; - err = divert_writekey (ctrl, force, serialno, id, keydata, keydatalen); + + err = divert_writekey (ctrl, force, serialno, keyref, keydata, keydatalen); xfree (keydata); leave: + gcry_sexp_release (s_skey); + xfree (shadow_info); return leave_cmd (ctx, err); } diff --git a/agent/divert-scd.c b/agent/divert-scd.c index 02fe5295a..e89c74a19 100644 --- a/agent/divert-scd.c +++ b/agent/divert-scd.c @@ -597,12 +597,13 @@ divert_pkdecrypt (ctrl_t ctrl, const char *desc_text, return rc; } -int + +gpg_error_t divert_writekey (ctrl_t ctrl, int force, const char *serialno, - const char *id, const char *keydata, size_t keydatalen) + const char *keyref, const char *keydata, size_t keydatalen) { - return agent_card_writekey (ctrl, force, serialno, id, keydata, keydatalen, - getpin_cb, ctrl); + return agent_card_writekey (ctrl, force, serialno, keyref, + keydata, keydatalen, getpin_cb, ctrl); } int