gpg: Allow creating keys using an existing ECC key.
authorWerner Koch <wk@gnupg.org>
Wed, 1 Mar 2017 12:36:01 +0000 (13:36 +0100)
committerWerner Koch <wk@gnupg.org>
Wed, 1 Mar 2017 12:36:01 +0000 (13:36 +0100)
* common/sexputil.c (get_pk_algo_from_canon_sexp): Remove arg R_ALGO.
Change to return the algo id.  Reimplement using get_pk_algo_from_key.
* g10/keygen.c (check_keygrip): Adjust for change.
* sm/certreqgen-ui.c (check_keygrip): Ditto.
--

GnuPG-bug-id: 2976
Signed-off-by: Werner Koch <wk@gnupg.org>
common/sexputil.c
common/util.h
g10/keygen.c
sm/certreqgen-ui.c

index 0c5c730..a8dc1a5 100644 (file)
@@ -512,53 +512,6 @@ get_rsa_pk_from_canon_sexp (const unsigned char *keydata, size_t keydatalen,
 }
 
 
-/* Return the algo of a public RSA expressed as an canonical encoded
-   S-expression.  The return value is a statically allocated
-   string.  On error that string is set to NULL. */
-gpg_error_t
-get_pk_algo_from_canon_sexp (const unsigned char *keydata, size_t keydatalen,
-                             const char **r_algo)
-{
-  gpg_error_t err;
-  const unsigned char *buf, *tok;
-  size_t buflen, toklen;
-  int depth;
-
-  *r_algo = NULL;
-
-  buf = keydata;
-  buflen = keydatalen;
-  depth = 0;
-  if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
-    return err;
-  if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
-    return err;
-  if (!tok || toklen != 10 || memcmp ("public-key", tok, toklen))
-    return gpg_error (GPG_ERR_BAD_PUBKEY);
-  if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
-    return err;
-  if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
-    return err;
-  if (!tok)
-    return gpg_error (GPG_ERR_BAD_PUBKEY);
-
-  if (toklen == 3 && !memcmp ("rsa", tok, toklen))
-    *r_algo = "rsa";
-  else if (toklen == 3 && !memcmp ("dsa", tok, toklen))
-    *r_algo = "dsa";
-  else if (toklen == 3 && !memcmp ("elg", tok, toklen))
-    *r_algo = "elg";
-  else if (toklen == 5 && !memcmp ("ecdsa", tok, toklen))
-    *r_algo = "ecdsa";
-  else if (toklen == 5 && !memcmp ("eddsa", tok, toklen))
-    *r_algo = "eddsa";
-  else
-    return gpg_error (GPG_ERR_PUBKEY_ALGO);
-
-  return 0;
-}
-
-
 /* Return the algo of a public KEY of SEXP. */
 int
 get_pk_algo_from_key (gcry_sexp_t key)
@@ -606,3 +559,21 @@ get_pk_algo_from_key (gcry_sexp_t key)
 
   return algo;
 }
+
+
+/* This is a variant of get_pk_algo_from_key but takes an canonical
+ * encoded S-expression as input.  Returns a GCRYPT public key
+ * identiier or 0 on error.  */
+int
+get_pk_algo_from_canon_sexp (const unsigned char *keydata, size_t keydatalen)
+{
+  gcry_sexp_t sexp;
+  int algo;
+
+  if (gcry_sexp_sscan (&sexp, NULL, keydata, keydatalen))
+    return 0;
+
+  algo = get_pk_algo_from_key (sexp);
+  gcry_sexp_release (sexp);
+  return algo;
+}
index 4e871d2..c0aa57a 100644 (file)
@@ -195,10 +195,10 @@ gpg_error_t get_rsa_pk_from_canon_sexp (const unsigned char *keydata,
                                         size_t *r_nlen,
                                         unsigned char const **r_e,
                                         size_t *r_elen);
-gpg_error_t get_pk_algo_from_canon_sexp (const unsigned char *keydata,
-                                         size_t keydatalen,
-                                         const char **r_algo);
+
 int get_pk_algo_from_key (gcry_sexp_t key);
+int get_pk_algo_from_canon_sexp (const unsigned char *keydata,
+                                 size_t keydatalen);
 
 /*-- convert.c --*/
 int hex2bin (const char *string, void *buffer, size_t length);
index 226cabd..24cf93c 100644 (file)
@@ -1839,7 +1839,7 @@ check_keygrip (ctrl_t ctrl, const char *hexgrip)
   gpg_error_t err;
   unsigned char *public;
   size_t publiclen;
-  const char *algostr;
+  int algo;
 
   if (hexgrip[0] == '&')
     hexgrip++;
@@ -1849,26 +1849,10 @@ check_keygrip (ctrl_t ctrl, const char *hexgrip)
     return 0;
   publiclen = gcry_sexp_canon_len (public, 0, NULL, NULL);
 
-  get_pk_algo_from_canon_sexp (public, publiclen, &algostr);
+  algo = get_pk_algo_from_canon_sexp (public, publiclen);
   xfree (public);
 
-  /* FIXME: Mapping of ECC algorithms is probably not correct. */
-  if (!algostr)
-    return 0;
-  else if (!strcmp (algostr, "rsa"))
-    return PUBKEY_ALGO_RSA;
-  else if (!strcmp (algostr, "dsa"))
-    return PUBKEY_ALGO_DSA;
-  else if (!strcmp (algostr, "elg"))
-    return PUBKEY_ALGO_ELGAMAL_E;
-  else if (!strcmp (algostr, "ecc"))
-    return PUBKEY_ALGO_ECDH;
-  else if (!strcmp (algostr, "ecdsa"))
-    return PUBKEY_ALGO_ECDSA;
-  else if (!strcmp (algostr, "eddsa"))
-    return PUBKEY_ALGO_EDDSA;
-  else
-    return 0;
+  return map_pk_gcry_to_openpgp (algo);
 }
 
 
index ece8668..b50d338 100644 (file)
@@ -95,7 +95,7 @@ check_keygrip (ctrl_t ctrl, const char *hexgrip)
   gpg_error_t err;
   ksba_sexp_t public;
   size_t publiclen;
-  const char *algostr;
+  int algo;
 
   if (hexgrip[0] == '&')
     hexgrip++;
@@ -105,21 +105,17 @@ check_keygrip (ctrl_t ctrl, const char *hexgrip)
     return NULL;
   publiclen = gcry_sexp_canon_len (public, 0, NULL, NULL);
 
-  get_pk_algo_from_canon_sexp (public, publiclen, &algostr);
+  algo = get_pk_algo_from_canon_sexp (public, publiclen);
   xfree (public);
 
-  if (!algostr)
-    return NULL;
-  else if (!strcmp (algostr, "rsa"))
-    return "RSA";
-  else if (!strcmp (algostr, "dsa"))
-    return "DSA";
-  else if (!strcmp (algostr, "elg"))
-    return "ELG";
-  else if (!strcmp (algostr, "ecdsa"))
-    return "ECDSA";
-  else
-    return NULL;
+  switch (algo)
+    {
+    case GCRY_PK_RSA:   return "RSA";
+    case GCRY_PK_DSA:   return "DSA";
+    case GCRY_PK_ELG:   return "ELG";
+    case GCRY_PK_EDDSA: return "ECDSA";
+    default: return NULL;
+    }
 }