diff options
author | Werner Koch <wk@gnupg.org> | 2013-10-08 17:59:50 +0200 |
---|---|---|
committer | Werner Koch <wk@gnupg.org> | 2013-10-08 17:59:50 +0200 |
commit | 3816e46ce211e63adf46dbc775510aa137572248 (patch) | |
tree | 7a4e51d84d2e0f83803f5865b58c8135f4a1ca5e /cipher | |
parent | f79d3e13d3229115c47cbe5007647cb44105fe3f (diff) | |
download | libgcrypt-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.am | 2 | ||||
-rw-r--r-- | cipher/dsa.c | 160 | ||||
-rw-r--r-- | cipher/ecc.c | 42 | ||||
-rw-r--r-- | cipher/elgamal.c | 28 | ||||
-rw-r--r-- | cipher/pubkey-internal.h | 12 | ||||
-rw-r--r-- | cipher/pubkey-util.c | 127 | ||||
-rw-r--r-- | cipher/pubkey.c | 58 | ||||
-rw-r--r-- | cipher/rsa.c | 17 |
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) |