agent: Minor change to the KEYTOCARD command.
authorWerner Koch <wk@gnupg.org>
Tue, 5 Mar 2019 11:08:27 +0000 (12:08 +0100)
committerWerner Koch <wk@gnupg.org>
Tue, 5 Mar 2019 11:08:27 +0000 (12:08 +0100)
* 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 <wk@gnupg.org>
agent/agent.h
agent/call-scd.c
agent/command.c
agent/divert-scd.c

index ee5a31e..3a29dc8 100644 (file)
@@ -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,
index d0d4794..1189bd4 100644 (file)
@@ -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);
 }
 
 
index 332d20f..62b7014 100644 (file)
@@ -2484,19 +2484,23 @@ cmd_delete_key (assuan_context_t ctx, char *line)
 #endif
 
 static const char hlp_keytocard[] =
-  "KEYTOCARD [--force] <hexstring_with_keygrip> <serialno> <id> <timestamp>\n"
-  "\n";
+  "KEYTOCARD [--force] <hexgrip> <serialno> <keyref> [<timestamp>]\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);
 }
 
index 02fe529..e89c74a 100644 (file)
@@ -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