summaryrefslogtreecommitdiff
path: root/cipher/pubkey.c
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2013-04-12 00:16:24 +0200
committerWerner Koch <wk@gnupg.org>2013-04-12 18:18:11 +0200
commitaf8a79aea80217a0c85a592db1fa001792a6bf0f (patch)
tree70a1d95d59c391a9e03f2816f72c68f78923662e /cipher/pubkey.c
parent1f3cfad66456dd6f2e48f20b8eb0c51343449a1c (diff)
downloadlibgcrypt-af8a79aea80217a0c85a592db1fa001792a6bf0f.tar.gz
Add hack to allow using an "ecc" key for "ecdsa" or "ecdh".
* cipher/pubkey.c (sexp_to_key): Add optional arg USE. (gcry_pk_encrypt, gcry_pk_decrypt): Call sexp_to_key with usage sign. (gcry_pk_sign, gcry_pk_verify): Call sexp_to_key with usage encrypt. * tests/basic.c (show_sexp): New. (check_pubkey_sign): Print test number and add cases for ecc. (check_pubkey_sign_ecdsa): New. (do_check_one_pubkey): Divert to new function. -- The problem we try to address is that in the mdoule specs both, ECDSA and ECDH have the same alias name "ecc". This patch allows to use for example gcry_pk_verify with a key that has only "ecc" in it. Signed-off-by: Werner Koch <wk@gnupg.org>
Diffstat (limited to 'cipher/pubkey.c')
-rw-r--r--cipher/pubkey.c50
1 files changed, 33 insertions, 17 deletions
diff --git a/cipher/pubkey.c b/cipher/pubkey.c
index 00317b5b..378e0724 100644
--- a/cipher/pubkey.c
+++ b/cipher/pubkey.c
@@ -2002,7 +2002,8 @@ sexp_elements_extract_ecc (gcry_sexp_t key_sexp, const char *element_names,
* The <mpi> are expected to be in GCRYMPI_FMT_USG
*/
static gcry_err_code_t
-sexp_to_key (gcry_sexp_t sexp, int want_private, const char *override_elems,
+sexp_to_key (gcry_sexp_t sexp, int want_private, int use,
+ const char *override_elems,
gcry_mpi_t **retarray, gcry_module_t *retalgo, int *r_is_ecc)
{
gcry_err_code_t err = 0;
@@ -2031,19 +2032,31 @@ sexp_to_key (gcry_sexp_t sexp, int want_private, const char *override_elems,
return GPG_ERR_INV_OBJ; /* Invalid structure of object. */
}
- ath_mutex_lock (&pubkeys_registered_lock);
- module = gcry_pk_lookup_name (name);
- ath_mutex_unlock (&pubkeys_registered_lock);
-
/* Fixme: We should make sure that an ECC key is always named "ecc"
and not "ecdsa". "ecdsa" should be used for the signature
itself. We need a function to test whether an algorithm given
with a key is compatible with an application of the key (signing,
encryption). For RSA this is easy, but ECC is the first
- algorithm which has many flavours. */
- is_ecc = ( !strcmp (name, "ecdsa")
- || !strcmp (name, "ecdh")
- || !strcmp (name, "ecc") );
+ algorithm which has many flavours.
+
+ We use an ugly hack here to decide whether to use ecdsa or ecdh.
+ */
+ if (!strcmp (name, "ecc"))
+ is_ecc = 2;
+ else if (!strcmp (name, "ecdsa") || !strcmp (name, "ecdh"))
+ is_ecc = 1;
+ else
+ is_ecc = 0;
+
+ ath_mutex_lock (&pubkeys_registered_lock);
+ if (is_ecc == 2 && (use & GCRY_PK_USAGE_SIGN))
+ module = gcry_pk_lookup_name ("ecdsa");
+ else if (is_ecc == 2 && (use & GCRY_PK_USAGE_ENCR))
+ module = gcry_pk_lookup_name ("ecdh");
+ else
+ module = gcry_pk_lookup_name (name);
+ ath_mutex_unlock (&pubkeys_registered_lock);
+
gcry_free (name);
if (!module)
@@ -2866,7 +2879,7 @@ gcry_pk_encrypt (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t s_pkey)
REGISTER_DEFAULT_PUBKEYS;
/* Get the key. */
- rc = sexp_to_key (s_pkey, 0, NULL, &pkey, &module, NULL);
+ rc = sexp_to_key (s_pkey, 0, GCRY_PK_USAGE_ENCR, NULL, &pkey, &module, NULL);
if (rc)
goto leave;
@@ -3039,7 +3052,8 @@ gcry_pk_decrypt (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t s_skey)
REGISTER_DEFAULT_PUBKEYS;
- rc = sexp_to_key (s_skey, 1, NULL, &skey, &module_key, NULL);
+ rc = sexp_to_key (s_skey, 1, GCRY_PK_USAGE_ENCR, NULL,
+ &skey, &module_key, NULL);
if (rc)
goto leave;
@@ -3168,7 +3182,8 @@ gcry_pk_sign (gcry_sexp_t *r_sig, gcry_sexp_t s_hash, gcry_sexp_t s_skey)
REGISTER_DEFAULT_PUBKEYS;
- rc = sexp_to_key (s_skey, 1, NULL, &skey, &module, &is_ecc);
+ rc = sexp_to_key (s_skey, 1, GCRY_PK_USAGE_SIGN, NULL,
+ &skey, &module, &is_ecc);
if (rc)
goto leave;
@@ -3302,7 +3317,8 @@ gcry_pk_verify (gcry_sexp_t s_sig, gcry_sexp_t s_hash, gcry_sexp_t s_pkey)
REGISTER_DEFAULT_PUBKEYS;
- rc = sexp_to_key (s_pkey, 0, NULL, &pkey, &module_key, NULL);
+ rc = sexp_to_key (s_pkey, 0, GCRY_PK_USAGE_SIGN, NULL,
+ &pkey, &module_key, NULL);
if (rc)
goto leave;
@@ -3375,7 +3391,7 @@ gcry_pk_testkey (gcry_sexp_t s_key)
REGISTER_DEFAULT_PUBKEYS;
/* Note we currently support only secret key checking. */
- rc = sexp_to_key (s_key, 1, NULL, &key, &module, NULL);
+ rc = sexp_to_key (s_key, 1, 0, NULL, &key, &module, NULL);
if (! rc)
{
rc = pubkey_check_secret_key (module->mod_id, key);
@@ -3708,9 +3724,9 @@ gcry_pk_get_nbits (gcry_sexp_t key)
ECC we would only need to look at P and stop parsing right
away. */
- rc = sexp_to_key (key, 0, NULL, &keyarr, &module, NULL);
+ rc = sexp_to_key (key, 0, 0, NULL, &keyarr, &module, NULL);
if (rc == GPG_ERR_INV_OBJ)
- rc = sexp_to_key (key, 1, NULL, &keyarr, &module, NULL);
+ rc = sexp_to_key (key, 1, 0, NULL, &keyarr, &module, NULL);
if (rc)
return 0; /* Error - 0 is a suitable indication for that. */
@@ -3881,7 +3897,7 @@ gcry_pk_get_curve (gcry_sexp_t key, int iterator, unsigned int *r_nbits)
/* Get the key. We pass the names of the parameters for
override_elems; this allows to call this function without the
actual public key parameter. */
- if (sexp_to_key (key, want_private, "pabgn", &pkey, &module, NULL))
+ if (sexp_to_key (key, want_private, 0, "pabgn", &pkey, &module, NULL))
goto leave;
}
else