g10,scd: Fix ECC keygen.
authorNIIBE Yutaka <gniibe@fsij.org>
Fri, 21 Oct 2016 12:37:04 +0000 (21:37 +0900)
committerNIIBE Yutaka <gniibe@fsij.org>
Fri, 21 Oct 2016 12:37:04 +0000 (21:37 +0900)
* g10/keygen.c (generate_keypair): For card key generation, fill
parameters by KEY-ATTR.

* scd/app-openpgp.c (ecc_read_pubkey): OID should be freed at last,
after its reference by OIDBUF is finished.
(ecc_writekey): Likewise.
--

Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
g10/call-agent.c
g10/keygen.c
scd/app-openpgp.c

index c1ad8dd..e7af001 100644 (file)
@@ -994,9 +994,11 @@ scd_genkey_cb (void *opaque, const char *line)
   return 0;
 }
 
-/* Send a GENKEY command to the SCdaemon.  If CREATETIME is not 0, it
-  will be passed to SCDAEMON so that the key is created with this
-  timestamp.  On success, creation time  is stored back to CREATETIME.  */
+/* Send a GENKEY command to the SCdaemon.  If *CREATETIME is not 0,
+  the value will be passed to SCDAEMON with --timestamp option so that
+  the key is created with this.  Otherwise, timestamp was generated by
+  SCDEAMON.  On success, creation time is stored back to
+  CREATETIME.  */
 int
 agent_scd_genkey (int keyno, int force, u32 *createtime)
 {
index 64e0d43..a59435d 100644 (file)
@@ -3756,17 +3756,26 @@ generate_keypair (ctrl_t ctrl, int full, const char *fname,
   if (card_serialno)
     {
 #ifdef ENABLE_CARD_SUPPORT
+      gpg_error_t err;
+      struct agent_card_info_s info;
+
+      memset (&info, 0, sizeof (info));
+      err = agent_scd_getattr ("KEY-ATTR", &info);
+      if (err)
+        {
+          log_error (_("error getting current key info: %s\n"), gpg_strerror (err));
+          return;
+        }
+
       r = xcalloc (1, sizeof *r + strlen (card_serialno) );
       r->key = pSERIALNO;
       strcpy( r->u.value, card_serialno);
       r->next = para;
       para = r;
 
-      algo = PUBKEY_ALGO_RSA;
-
       r = xcalloc (1, sizeof *r + 20 );
       r->key = pKEYTYPE;
-      sprintf( r->u.value, "%d", algo );
+      sprintf( r->u.value, "%d", info.key_attr[0].algo );
       r->next = para;
       para = r;
       r = xcalloc (1, sizeof *r + 20 );
@@ -3774,10 +3783,28 @@ generate_keypair (ctrl_t ctrl, int full, const char *fname,
       strcpy (r->u.value, "sign");
       r->next = para;
       para = r;
+      if (info.key_attr[0].algo == PUBKEY_ALGO_RSA)
+        {
+          r = xcalloc (1, sizeof *r + 20 );
+          r->key = pKEYLENGTH;
+          sprintf( r->u.value, "%u", info.key_attr[0].nbits);
+          r->next = para;
+          para = r;
+        }
+      else if (info.key_attr[0].algo == PUBKEY_ALGO_ECDSA
+               || info.key_attr[0].algo == PUBKEY_ALGO_EDDSA
+               || info.key_attr[0].algo == PUBKEY_ALGO_ECDH)
+        {
+          r = xcalloc (1, sizeof *r + strlen (info.key_attr[0].curve));
+          r->key = pKEYCURVE;
+          strcpy (r->u.value, info.key_attr[0].curve);
+          r->next = para;
+          para = r;
+        }
 
       r = xcalloc (1, sizeof *r + 20 );
       r->key = pSUBKEYTYPE;
-      sprintf( r->u.value, "%d", algo );
+      sprintf( r->u.value, "%d", info.key_attr[1].algo );
       r->next = para;
       para = r;
       r = xcalloc (1, sizeof *r + 20 );
@@ -3785,10 +3812,28 @@ generate_keypair (ctrl_t ctrl, int full, const char *fname,
       strcpy (r->u.value, "encrypt");
       r->next = para;
       para = r;
+      if (info.key_attr[1].algo == PUBKEY_ALGO_RSA)
+        {
+          r = xcalloc (1, sizeof *r + 20 );
+          r->key = pSUBKEYLENGTH;
+          sprintf( r->u.value, "%u", info.key_attr[1].nbits);
+          r->next = para;
+          para = r;
+        }
+      else if (info.key_attr[1].algo == PUBKEY_ALGO_ECDSA
+               || info.key_attr[1].algo == PUBKEY_ALGO_EDDSA
+               || info.key_attr[1].algo == PUBKEY_ALGO_ECDH)
+        {
+          r = xcalloc (1, sizeof *r + strlen (info.key_attr[1].curve));
+          r->key = pSUBKEYCURVE;
+          strcpy (r->u.value, info.key_attr[1].curve);
+          r->next = para;
+          para = r;
+        }
 
       r = xcalloc (1, sizeof *r + 20 );
       r->key = pAUTHKEYTYPE;
-      sprintf( r->u.value, "%d", algo );
+      sprintf( r->u.value, "%d", info.key_attr[2].algo );
       r->next = para;
       para = r;
 
@@ -4873,6 +4918,7 @@ gen_card_key (int keyno, int is_primary, kbnode_t pub_root,
   unsigned char *public;
   gcry_sexp_t s_key;
 
+  memset (&info, 0, sizeof (info));
   err = agent_scd_getattr ("KEY-ATTR", &info);
   if (err)
     {
@@ -4931,8 +4977,8 @@ gen_card_key (int keyno, int is_primary, kbnode_t pub_root,
   if (algo == PUBKEY_ALGO_RSA)
     err = key_from_sexp (pk->pkey, s_key, "public-key", "ne");
   else if (algo == PUBKEY_ALGO_ECDSA
-          || algo == PUBKEY_ALGO_EDDSA
-          || algo == PUBKEY_ALGO_ECDH )
+           || algo == PUBKEY_ALGO_EDDSA
+           || algo == PUBKEY_ALGO_ECDH )
     err = ecckey_from_sexp (pk->pkey, s_key, algo);
   else
     err = gpg_error (GPG_ERR_PUBKEY_ALGO);
index f909c6f..e6a7698 100644 (file)
@@ -1312,10 +1312,10 @@ ecc_read_pubkey (app_t app, ctrl_t ctrl, u32 created_at, int keyno,
                  const unsigned char *data, size_t datalen, gcry_sexp_t *r_sexp)
 {
   gpg_error_t err;
-  unsigned char *qbuf;
+  unsigned char *qbuf = NULL;
   const unsigned char *ecc_q;
   size_t ecc_q_len;
-  gcry_mpi_t oid;
+  gcry_mpi_t oid = NULL;
   int n;
   const unsigned char *oidbuf;
   size_t oid_len;
@@ -1338,15 +1338,16 @@ ecc_read_pubkey (app_t app, ctrl_t ctrl, u32 created_at, int keyno,
   if (!oidbuf)
     {
       err = gpg_error_from_syserror ();
-      gcry_mpi_release (oid);
-      return err;
+      goto leave;
     }
-  gcry_mpi_release (oid);
   oid_len = (n+7)/8;
 
   qbuf = xtrymalloc (ecc_q_len + 1);
   if (!qbuf)
-    return gpg_error_from_syserror ();
+    {
+      err = gpg_error_from_syserror ();
+      goto leave;
+    }
 
   if ((app->app_local->keyattr[keyno].ecc.flags & ECC_FLAG_DJB_TWEAK))
     {               /* Prepend 0x40 prefix.  */
@@ -1359,7 +1360,7 @@ ecc_read_pubkey (app_t app, ctrl_t ctrl, u32 created_at, int keyno,
 
   if (ctrl)
     {
-      send_key_data (ctrl, "q", ecc_q, ecc_q_len);
+      send_key_data (ctrl, "q", qbuf, ecc_q_len);
       send_key_data (ctrl, "curve", oidbuf, oid_len);
     }
 
@@ -1399,6 +1400,7 @@ ecc_read_pubkey (app_t app, ctrl_t ctrl, u32 created_at, int keyno,
   curve = openpgp_oid_to_curve (app->app_local->keyattr[keyno].ecc.oid, 1);
   err = gcry_sexp_build (r_sexp, NULL, format, curve, (int)ecc_q_len, qbuf);
  leave:
+  gcry_mpi_release (oid);
   xfree (qbuf);
   return err;
 }
@@ -3344,8 +3346,8 @@ ecc_writekey (app_t app, gpg_error_t (*pincb)(void*, const char *, char **),
   const char *oidstr = NULL;
   int flag_djb_tweak = 0;
   int algo;
-  gcry_mpi_t oid;
-  const unsigned char *oidbuf = NULL;
+  gcry_mpi_t oid = NULL;
+  const unsigned char *oidbuf;
   unsigned int n;
   size_t oid_len;
   unsigned char fprbuf[20];
@@ -3498,10 +3500,8 @@ ecc_writekey (app_t app, gpg_error_t (*pincb)(void*, const char *, char **),
   if (!oidbuf)
     {
       err = gpg_error_from_syserror ();
-      gcry_mpi_release (oid);
       goto leave;
     }
-  gcry_mpi_release (oid);
   oid_len = (n+7)/8;
 
   if (app->app_local->keyattr[keyno].key_type != KEY_TYPE_ECC
@@ -3583,6 +3583,7 @@ ecc_writekey (app_t app, gpg_error_t (*pincb)(void*, const char *, char **),
                    ecc_q, ecc_q_len, "\x03\x01\x08\x07", (size_t)4);
 
  leave:
+  gcry_mpi_release (oid);
   return err;
 }