summaryrefslogtreecommitdiff
path: root/cipher
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2013-10-08 17:59:50 +0200
committerWerner Koch <wk@gnupg.org>2013-10-08 17:59:50 +0200
commit3816e46ce211e63adf46dbc775510aa137572248 (patch)
tree7a4e51d84d2e0f83803f5865b58c8135f4a1ca5e /cipher
parentf79d3e13d3229115c47cbe5007647cb44105fe3f (diff)
downloadlibgcrypt-3816e46ce211e63adf46dbc775510aa137572248.tar.gz
pubkey: Move sexp parsing for gcry_pk_getkey to the modules.
* 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>
Diffstat (limited to 'cipher')
-rw-r--r--cipher/Makefile.am2
-rw-r--r--cipher/dsa.c160
-rw-r--r--cipher/ecc.c42
-rw-r--r--cipher/elgamal.c28
-rw-r--r--cipher/pubkey-internal.h12
-rw-r--r--cipher/pubkey-util.c127
-rw-r--r--cipher/pubkey.c58
-rw-r--r--cipher/rsa.c17
8 files changed, 264 insertions, 182 deletions
diff --git a/cipher/Makefile.am b/cipher/Makefile.am
index cce12c2e..a2b2c8af 100644
--- a/cipher/Makefile.am
+++ b/cipher/Makefile.am
@@ -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 \
diff --git a/cipher/dsa.c b/cipher/dsa.c
index 394800df..136d64f4 100644
--- a/cipher/dsa.c
+++ b/cipher/dsa.c
@@ -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 ())
diff --git a/cipher/ecc.c b/cipher/ecc.c
index a7fb90f1..eed96eb8 100644
--- a/cipher/ecc.c
+++ b/cipher/ecc.c
@@ -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. */
diff --git a/cipher/elgamal.c b/cipher/elgamal.c
index f51f9079..3c8741a0 100644
--- a/cipher/elgamal.c
+++ b/cipher/elgamal.c
@@ -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)
diff --git a/cipher/pubkey-internal.h b/cipher/pubkey-internal.h
index a33ccfe6..0b20c7dc 100644
--- a/cipher/pubkey-internal.h
+++ b/cipher/pubkey-internal.h
@@ -20,7 +20,15 @@
#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
index 00000000..ef0ef441
--- /dev/null
+++ b/cipher/pubkey-util.c
@@ -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;
+}
diff --git a/cipher/pubkey.c b/cipher/pubkey.c
index 50ce6382..305f53a4 100644
--- a/cipher/pubkey.c
+++ b/cipher/pubkey.c
@@ -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);
}
diff --git a/cipher/rsa.c b/cipher/rsa.c
index 53b9d895..55f39e48 100644
--- a/cipher/rsa.c
+++ b/cipher/rsa.c
@@ -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)