pubkey: Move sexp parsing for gcry_pk_getkey to the modules.
authorWerner Koch <wk@gnupg.org>
Tue, 8 Oct 2013 15:59:50 +0000 (17:59 +0200)
committerWerner Koch <wk@gnupg.org>
Tue, 8 Oct 2013 15:59:50 +0000 (17:59 +0200)
* cipher/pubkey-util.c: New.
(_gcry_pk_util_get_nbits): New.  Based on code from gcry_pk_genkey.
(_gcry_pk_util_get_rsa_use_e): Ditto.
* cipher/pubkey.c (gcry_pk_genkey): Strip most code and pass.
* cipher/rsa.c (rsa_generate): Remove args ALGO, NBITS and EVALUE.
Call new fucntions to get these values.
* cipher/dsa.c (dsa_generate): Remove args ALGO, NBITS and EVALUE.
Call _gcry_pk_util_get_nbits to get nbits.  Always parse genparms.
* cipher/elgamal.c (elg_generate): Ditto.
* cipher/ecc.c (ecc_generate): Ditto.

Signed-off-by: Werner Koch <wk@gnupg.org>
cipher/Makefile.am
cipher/dsa.c
cipher/ecc.c
cipher/elgamal.c
cipher/pubkey-internal.h
cipher/pubkey-util.c [new file with mode: 0644]
cipher/pubkey.c
cipher/rsa.c
src/cipher-proto.h

index cce12c2..a2b2c8a 100644 (file)
@@ -41,7 +41,7 @@ libcipher_la_SOURCES = \
 cipher.c cipher-internal.h \
 cipher-cbc.c cipher-cfb.c cipher-ofb.c cipher-ctr.c cipher-aeswrap.c \
 cipher-selftest.c cipher-selftest.h \
-pubkey.c pubkey-internal.h \
+pubkey.c pubkey-internal.h pubkey-util.c \
 md.c \
 kdf.c kdf-internal.h \
 hmac-tests.c \
index 394800d..136d64f 100644 (file)
@@ -689,10 +689,11 @@ verify (gcry_mpi_t r, gcry_mpi_t s, gcry_mpi_t hash, DSA_public_key *pkey )
  *********************************************/
 
 static gcry_err_code_t
-dsa_generate (int algo, unsigned int nbits, unsigned long evalue,
-              const gcry_sexp_t genparms, gcry_sexp_t *r_skey)
+dsa_generate (const gcry_sexp_t genparms, gcry_sexp_t *r_skey)
 {
   gpg_err_code_t rc;
+  unsigned int nbits;
+  gcry_sexp_t domainsexp;
   DSA_secret_key sk;
   gcry_sexp_t l1;
   unsigned int qbits = 0;
@@ -705,102 +706,97 @@ dsa_generate (int algo, unsigned int nbits, unsigned long evalue,
   dsa_domain_t domain;
   gcry_mpi_t *factors = NULL;
 
-  (void)algo;    /* No need to check it.  */
-  (void)evalue;  /* Not required for DSA. */
-
   memset (&sk, 0, sizeof sk);
   memset (&domain, 0, sizeof domain);
 
-  if (genparms)
+  rc = _gcry_pk_util_get_nbits (genparms, &nbits);
+  if (rc)
+    return rc;
+
+  /* Parse the optional qbits element.  */
+  l1 = gcry_sexp_find_token (genparms, "qbits", 0);
+  if (l1)
     {
-      gcry_sexp_t domainsexp;
+      char buf[50];
+      const char *s;
+      size_t n;
 
-      /* Parse the optional qbits element.  */
-      l1 = gcry_sexp_find_token (genparms, "qbits", 0);
-      if (l1)
+      s = gcry_sexp_nth_data (l1, 1, &n);
+      if (!s || n >= DIM (buf) - 1 )
         {
-          char buf[50];
-          const char *s;
-          size_t n;
-
-          s = gcry_sexp_nth_data (l1, 1, &n);
-          if (!s || n >= DIM (buf) - 1 )
-            {
-              gcry_sexp_release (l1);
-              return GPG_ERR_INV_OBJ; /* No value or value too large.  */
-            }
-          memcpy (buf, s, n);
-          buf[n] = 0;
-          qbits = (unsigned int)strtoul (buf, NULL, 0);
           gcry_sexp_release (l1);
+          return GPG_ERR_INV_OBJ; /* No value or value too large.  */
         }
+      memcpy (buf, s, n);
+      buf[n] = 0;
+      qbits = (unsigned int)strtoul (buf, NULL, 0);
+      gcry_sexp_release (l1);
+    }
 
-      /* Parse the optional transient-key flag.  */
-      l1 = gcry_sexp_find_token (genparms, "transient-key", 0);
-      if (l1)
-        {
-          transient_key = 1;
-          gcry_sexp_release (l1);
-        }
+  /* Parse the optional transient-key flag.  */
+  l1 = gcry_sexp_find_token (genparms, "transient-key", 0);
+  if (l1)
+    {
+      transient_key = 1;
+      gcry_sexp_release (l1);
+    }
 
-      /* Get the optional derive parameters.  */
-      deriveparms = gcry_sexp_find_token (genparms, "derive-parms", 0);
+  /* Get the optional derive parameters.  */
+  deriveparms = gcry_sexp_find_token (genparms, "derive-parms", 0);
 
-      /* Parse the optional "use-fips186" flags.  */
-      l1 = gcry_sexp_find_token (genparms, "use-fips186", 0);
-      if (l1)
-        {
-          use_fips186 = 1;
-          gcry_sexp_release (l1);
-        }
-      l1 = gcry_sexp_find_token (genparms, "use-fips186-2", 0);
-      if (l1)
-        {
-          use_fips186_2 = 1;
-          gcry_sexp_release (l1);
-        }
+  /* Parse the optional "use-fips186" flags.  */
+  l1 = gcry_sexp_find_token (genparms, "use-fips186", 0);
+  if (l1)
+    {
+      use_fips186 = 1;
+      gcry_sexp_release (l1);
+    }
+  l1 = gcry_sexp_find_token (genparms, "use-fips186-2", 0);
+  if (l1)
+    {
+      use_fips186_2 = 1;
+      gcry_sexp_release (l1);
+    }
 
-      /* Check whether domain parameters are given.  */
-      domainsexp = gcry_sexp_find_token (genparms, "domain", 0);
-      if (domainsexp)
+  /* Check whether domain parameters are given.  */
+  domainsexp = gcry_sexp_find_token (genparms, "domain", 0);
+  if (domainsexp)
+    {
+      /* DERIVEPARMS can't be used together with domain parameters.
+         NBITS abnd QBITS may not be specified because there values
+         are derived from the domain parameters.  */
+      if (deriveparms || qbits || nbits)
         {
-          /* DERIVEPARMS can't be used together with domain
-             parameters.  NBITS abnd QBITS may not be specified
-             because there values are derived from the domain
-             parameters.  */
-          if (deriveparms || qbits || nbits)
-            {
-              gcry_sexp_release (domainsexp);
-              gcry_sexp_release (deriveparms);
-              return GPG_ERR_INV_VALUE;
-            }
-
-          /* Put all domain parameters into the domain object.  */
-          l1 = gcry_sexp_find_token (domainsexp, "p", 0);
-          domain.p = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
-          gcry_sexp_release (l1);
-          l1 = gcry_sexp_find_token (domainsexp, "q", 0);
-          domain.q = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
-          gcry_sexp_release (l1);
-          l1 = gcry_sexp_find_token (domainsexp, "g", 0);
-          domain.g = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
-          gcry_sexp_release (l1);
           gcry_sexp_release (domainsexp);
+          gcry_sexp_release (deriveparms);
+          return GPG_ERR_INV_VALUE;
+        }
 
-          /* Check that all domain parameters are available.  */
-          if (!domain.p || !domain.q || !domain.g)
-            {
-              gcry_mpi_release (domain.p);
-              gcry_mpi_release (domain.q);
-              gcry_mpi_release (domain.g);
-              gcry_sexp_release (deriveparms);
-              return GPG_ERR_MISSING_VALUE;
-            }
-
-          /* Get NBITS and QBITS from the domain parameters.  */
-          nbits = mpi_get_nbits (domain.p);
-          qbits = mpi_get_nbits (domain.q);
+      /* Put all domain parameters into the domain object.  */
+      l1 = gcry_sexp_find_token (domainsexp, "p", 0);
+      domain.p = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
+      gcry_sexp_release (l1);
+      l1 = gcry_sexp_find_token (domainsexp, "q", 0);
+      domain.q = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
+      gcry_sexp_release (l1);
+      l1 = gcry_sexp_find_token (domainsexp, "g", 0);
+      domain.g = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
+      gcry_sexp_release (l1);
+      gcry_sexp_release (domainsexp);
+
+      /* Check that all domain parameters are available.  */
+      if (!domain.p || !domain.q || !domain.g)
+        {
+          gcry_mpi_release (domain.p);
+          gcry_mpi_release (domain.q);
+          gcry_mpi_release (domain.g);
+          gcry_sexp_release (deriveparms);
+          return GPG_ERR_MISSING_VALUE;
         }
+
+      /* Get NBITS and QBITS from the domain parameters.  */
+      nbits = mpi_get_nbits (domain.p);
+      qbits = mpi_get_nbits (domain.q);
     }
 
   if (deriveparms || use_fips186 || use_fips186_2 || fips_mode ())
index a7fb90f..eed96eb 100644 (file)
@@ -1226,10 +1226,10 @@ verify_eddsa (gcry_mpi_t input, ECC_public_key *pkey,
  *********************************************/
 
 static gcry_err_code_t
-ecc_generate (int algo, unsigned int nbits, unsigned long evalue,
-              const gcry_sexp_t genparms, gcry_sexp_t *r_skey)
+ecc_generate (const gcry_sexp_t genparms, gcry_sexp_t *r_skey)
 {
   gpg_err_code_t rc;
+  unsigned int nbits;
   elliptic_curve_t E;
   ECC_secret_key sk;
   gcry_mpi_t x = NULL;
@@ -1244,31 +1244,29 @@ ecc_generate (int algo, unsigned int nbits, unsigned long evalue,
   gcry_mpi_t public = NULL;
   gcry_mpi_t secret = NULL;
 
-  (void)algo;
-  (void)evalue;
-
   memset (&E, 0, sizeof E);
   memset (&sk, 0, sizeof sk);
 
-  if (genparms)
+  rc = _gcry_pk_util_get_nbits (genparms, &nbits);
+  if (rc)
+    return rc;
+
+  /* Parse the optional "curve" parameter. */
+  l1 = gcry_sexp_find_token (genparms, "curve", 0);
+  if (l1)
     {
-      /* Parse the optional "curve" parameter. */
-      l1 = gcry_sexp_find_token (genparms, "curve", 0);
-      if (l1)
-        {
-          curve_name = _gcry_sexp_nth_string (l1, 1);
-          gcry_sexp_release (l1);
-          if (!curve_name)
-            return GPG_ERR_INV_OBJ; /* No curve name or value too large. */
-        }
+      curve_name = _gcry_sexp_nth_string (l1, 1);
+      gcry_sexp_release (l1);
+      if (!curve_name)
+        return GPG_ERR_INV_OBJ; /* No curve name or value too large. */
+    }
 
-      /* Parse the optional transient-key flag.  */
-      l1 = gcry_sexp_find_token (genparms, "transient-key", 0);
-      if (l1)
-        {
-          transient_key = 1;
-          gcry_sexp_release (l1);
-        }
+  /* Parse the optional transient-key flag.  */
+  l1 = gcry_sexp_find_token (genparms, "transient-key", 0);
+  if (l1)
+    {
+      transient_key = 1;
+      gcry_sexp_release (l1);
     }
 
   /* NBITS is required if no curve name has been given.  */
index f51f907..3c8741a 100644 (file)
@@ -616,32 +616,30 @@ verify(gcry_mpi_t a, gcry_mpi_t b, gcry_mpi_t input, ELG_public_key *pkey )
  *********************************************/
 
 static gpg_err_code_t
-elg_generate (int algo, unsigned int nbits, unsigned long evalue,
-              const gcry_sexp_t genparms, gcry_sexp_t *r_skey)
+elg_generate (const gcry_sexp_t genparms, gcry_sexp_t *r_skey)
 {
   gpg_err_code_t rc;
+  unsigned int nbits;
   ELG_secret_key sk;
   gcry_mpi_t xvalue = NULL;
   gcry_sexp_t l1;
   gcry_mpi_t *factors = NULL;
   gcry_sexp_t misc_info = NULL;
 
-  (void)algo;
-  (void)evalue;
-
   memset (&sk, 0, sizeof sk);
 
-  if (genparms)
+  rc = _gcry_pk_util_get_nbits (genparms, &nbits);
+  if (rc)
+    return rc;
+
+  /* Parse the optional xvalue element. */
+  l1 = gcry_sexp_find_token (genparms, "xvalue", 0);
+  if (l1)
     {
-      /* Parse the optional xvalue element. */
-      l1 = gcry_sexp_find_token (genparms, "xvalue", 0);
-      if (l1)
-        {
-          xvalue = gcry_sexp_nth_mpi (l1, 1, 0);
-          gcry_sexp_release (l1);
-          if (!xvalue)
-            return GPG_ERR_BAD_MPI;
-        }
+      xvalue = gcry_sexp_nth_mpi (l1, 1, 0);
+      gcry_sexp_release (l1);
+      if (!xvalue)
+        return GPG_ERR_BAD_MPI;
     }
 
   if (xvalue)
index a33ccfe..0b20c7d 100644 (file)
 #ifndef GCRY_PUBKEY_INTERNAL_H
 #define GCRY_PUBKEY_INTERNAL_H
 
-/*-- rsa-common.h --*/
+/*-- pubkey-util.c --*/
+gpg_err_code_t _gcry_pk_util_get_nbits (gcry_sexp_t list,
+                                        unsigned int *r_nbits);
+gpg_err_code_t _gcry_pk_util_get_rsa_use_e (gcry_sexp_t list,
+                                            unsigned long *r_e);
+
+
+
+/*-- rsa-common.c --*/
 gpg_err_code_t
 _gcry_rsa_pkcs1_encode_for_enc (gcry_mpi_t *r_result, unsigned int nbits,
                                 const unsigned char *value, size_t valuelen,
@@ -53,7 +61,7 @@ _gcry_rsa_pss_verify (gcry_mpi_t value, gcry_mpi_t encoded,
 
 
 
-/*-- dsa-common.h --*/
+/*-- dsa-common.c --*/
 gcry_mpi_t _gcry_dsa_gen_k (gcry_mpi_t q, int security_level);
 gpg_err_code_t _gcry_dsa_gen_rfc6979_k (gcry_mpi_t *r_k,
                                         gcry_mpi_t dsa_q, gcry_mpi_t dsa_x,
diff --git a/cipher/pubkey-util.c b/cipher/pubkey-util.c
new file mode 100644 (file)
index 0000000..ef0ef44
--- /dev/null
@@ -0,0 +1,127 @@
+/* pubkey-util.c - Supporting functions for all pubkey modules.
+ * Copyright (C) 1998, 1999, 2000, 2002, 2003, 2005,
+ *               2007, 2008, 2011 Free Software Foundation, Inc.
+ * Copyright (C) 2013  g10 Code GmbH
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "g10lib.h"
+#include "mpi.h"
+#include "cipher.h"
+#include "pubkey-internal.h"
+
+
+
+
+/* Get the "nbits" parameter from an s-expression of the format:
+ *
+ *   (algo
+ *     (parameter_name_1 ....)
+ *      ....
+ *     (parameter_name_n ....))
+ *
+ * Example:
+ *
+ *   (rsa
+ *     (nbits 4:2048))
+ *
+ * On success the value for nbits is stored at R_NBITS.  If no nbits
+ * parameter is found, the function returns success and stores 0 at
+ * R_NBITS.  For parsing errors the function returns an error code and
+ * stores 0 at R_NBITS.
+ */
+gpg_err_code_t
+_gcry_pk_util_get_nbits (gcry_sexp_t list, unsigned int *r_nbits)
+{
+  char buf[50];
+  const char *s;
+  size_t n;
+
+  *r_nbits = 0;
+
+  list = gcry_sexp_find_token (list, "nbits", 0);
+  if (!list)
+    return 0; /* No NBITS found.  */
+
+  s = gcry_sexp_nth_data (list, 1, &n);
+  if (!s || n >= DIM (buf) - 1 )
+    {
+      /* NBITS given without a cdr.  */
+      gcry_sexp_release (list);
+      return GPG_ERR_INV_OBJ;
+    }
+  memcpy (buf, s, n);
+  buf[n] = 0;
+  *r_nbits = (unsigned int)strtoul (buf, NULL, 0);
+  gcry_sexp_release (list);
+  return 0;
+}
+
+
+/* Get the optional "rsa-use-e" parameter from an s-expression of the
+ * format:
+ *
+ *   (algo
+ *     (parameter_name_1 ....)
+ *      ....
+ *     (parameter_name_n ....))
+ *
+ * Example:
+ *
+ *   (rsa
+ *     (nbits 4:2048)
+ *     (rsa-use-e 2:41))
+ *
+ * On success the value for nbits is stored at R_E.  If no rsa-use-e
+ * parameter is found, the function returns success and stores 65537 at
+ * R_E.  For parsing errors the function returns an error code and
+ * stores 0 at R_E.
+ */
+gpg_err_code_t
+_gcry_pk_util_get_rsa_use_e (gcry_sexp_t list, unsigned long *r_e)
+{
+  char buf[50];
+  const char *s;
+  size_t n;
+
+  *r_e = 0;
+
+  list = gcry_sexp_find_token (list, "rsa-use-e", 0);
+  if (!list)
+    {
+      *r_e = 65537; /* Not given, use the value generated by old versions. */
+      return 0;
+    }
+
+  s = gcry_sexp_nth_data (list, 1, &n);
+  if (!s || n >= DIM (buf) - 1 )
+    {
+      /* No value or value too large.  */
+      gcry_sexp_release (list);
+      return GPG_ERR_INV_OBJ;
+    }
+  memcpy (buf, s, n);
+  buf[n] = 0;
+  *r_e = strtoul (buf, NULL, 0);
+  gcry_sexp_release (list);
+  return 0;
+}
index 50ce638..305f53a 100644 (file)
@@ -1862,12 +1862,8 @@ gcry_pk_genkey (gcry_sexp_t *r_key, gcry_sexp_t s_parms)
   gcry_pk_spec_t *spec = NULL;
   gcry_sexp_t list = NULL;
   gcry_sexp_t l2 = NULL;
-  gcry_sexp_t l3 = NULL;
   char *name = NULL;
-  size_t n;
-  gcry_err_code_t rc = GPG_ERR_NO_ERROR;
-  unsigned int nbits = 0;
-  unsigned long use_e = 0;
+  gcry_err_code_t rc;
 
   *r_key = NULL;
 
@@ -1904,63 +1900,15 @@ gcry_pk_genkey (gcry_sexp_t *r_key, gcry_sexp_t s_parms)
       goto leave;
     }
 
-  /* Handle the optional rsa-use-e element.  Actually this belong into
-     the algorithm module but we have this parameter in the public
-     module API, so we need to parse it right here.  */
-  l2 = gcry_sexp_find_token (list, "rsa-use-e", 0);
-  if (l2)
-    {
-      char buf[50];
-      const char *s;
-
-      s = gcry_sexp_nth_data (l2, 1, &n);
-      if ( !s || n >= DIM (buf) - 1 )
-        {
-          rc = GPG_ERR_INV_OBJ; /* No value or value too large.  */
-          goto leave;
-        }
-      memcpy (buf, s, n);
-      buf[n] = 0;
-      use_e = strtoul (buf, NULL, 0);
-      gcry_sexp_release (l2);
-      l2 = NULL;
-    }
-  else
-    use_e = 65537; /* Not given, use the value generated by old versions. */
-
-
-  /* Get the "nbits" parameter.  */
-  l2 = gcry_sexp_find_token (list, "nbits", 0);
-  if (l2)
-    {
-      char buf[50];
-      const char *s;
-
-      s = gcry_sexp_nth_data (l2, 1, &n);
-      if (!s || n >= DIM (buf) - 1 )
-        {
-          rc = GPG_ERR_INV_OBJ; /* NBITS given without a cdr.  */
-          goto leave;
-        }
-      memcpy (buf, s, n);
-      buf[n] = 0;
-      nbits = (unsigned int)strtoul (buf, NULL, 0);
-      gcry_sexp_release (l2); l2 = NULL;
-    }
-  else
-    nbits = 0;
-
   if (spec->generate)
-    rc = spec->generate (spec->algo, nbits, use_e, list, r_key);
+    rc = spec->generate (list, r_key);
   else
     rc = GPG_ERR_NOT_IMPLEMENTED;
 
  leave:
-  gcry_sexp_release (list); list = NULL;
+  gcry_sexp_release (list);
   gcry_free (name);
-  gcry_sexp_release (l3);
   gcry_sexp_release (l2);
-  gcry_sexp_release (list);
 
   return gcry_error (rc);
 }
index 53b9d89..55f39e4 100644 (file)
@@ -743,21 +743,28 @@ secret (gcry_mpi_t output, gcry_mpi_t input, RSA_secret_key *skey )
  *********************************************/
 
 static gcry_err_code_t
-rsa_generate (int algo, unsigned int nbits, unsigned long evalue,
-              const gcry_sexp_t genparms, gcry_sexp_t *r_skey)
+rsa_generate (const gcry_sexp_t genparms, gcry_sexp_t *r_skey)
 {
-  RSA_secret_key sk;
   gpg_err_code_t ec;
+  unsigned int nbits;
+  unsigned long evalue;
+  RSA_secret_key sk;
   gcry_sexp_t deriveparms;
   int transient_key = 0;
   int use_x931 = 0;
   gcry_sexp_t l1;
   gcry_sexp_t swap_info = NULL;
 
-  (void)algo;
-
   memset (&sk, 0, sizeof sk);
 
+  ec = _gcry_pk_util_get_nbits (genparms, &nbits);
+  if (ec)
+    return ec;
+
+  ec = _gcry_pk_util_get_rsa_use_e (genparms, &evalue);
+  if (ec)
+    return ec;
+
   deriveparms = (genparms?
                  gcry_sexp_find_token (genparms, "derive-parms", 0) : NULL);
   if (!deriveparms)
index f4b9959..1011161 100644 (file)
@@ -50,10 +50,7 @@ typedef gpg_err_code_t (*selftest_func_t)
  */
 
 /* Type for the pk_generate function.  */
-typedef gcry_err_code_t (*gcry_pk_generate_t) (int algo,
-                                               unsigned int nbits,
-                                               unsigned long evalue,
-                                               gcry_sexp_t genparms,
+typedef gcry_err_code_t (*gcry_pk_generate_t) (gcry_sexp_t genparms,
                                                gcry_sexp_t *r_skey);
 
 /* Type for the pk_check_secret_key function.  */