diff options
author | Werner Koch <wk@gnupg.org> | 2013-04-12 00:16:24 +0200 |
---|---|---|
committer | Werner Koch <wk@gnupg.org> | 2013-04-12 18:18:11 +0200 |
commit | af8a79aea80217a0c85a592db1fa001792a6bf0f (patch) | |
tree | 70a1d95d59c391a9e03f2816f72c68f78923662e /cipher/pubkey.c | |
parent | 1f3cfad66456dd6f2e48f20b8eb0c51343449a1c (diff) | |
download | libgcrypt-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.c | 50 |
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 |