diff options
author | NIIBE Yutaka <gniibe@fsij.org> | 2022-07-07 12:13:08 +0900 |
---|---|---|
committer | NIIBE Yutaka <gniibe@fsij.org> | 2022-07-07 12:13:08 +0900 |
commit | b2a64ed4f34abbd3871336503bec5ffeb3ad547b (patch) | |
tree | 23fbf2c35906a33d803c32661a9480bd46e5f168 | |
parent | 37b812f5e2a3c80d4bc104512248a07268f3c98b (diff) | |
download | libgcrypt-b2a64ed4f34abbd3871336503bec5ffeb3ad547b.tar.gz |
cipher: Fix gcry_pk_hash_verify for explicit hash.
* cipher/pubkey.c (_gcry_pk_verify_md): Implement support of explicit
hash.
* tests/t-ecdsa.c (one_test_sexp): Use explicit hash.
--
GnuPG-bug-id: 6066
Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
-rw-r--r-- | cipher/pubkey.c | 94 | ||||
-rw-r--r-- | tests/t-ecdsa.c | 5 |
2 files changed, 79 insertions, 20 deletions
diff --git a/cipher/pubkey.c b/cipher/pubkey.c index 8deeced6..2341c868 100644 --- a/cipher/pubkey.c +++ b/cipher/pubkey.c @@ -464,7 +464,7 @@ _gcry_pk_sign_md (gcry_sexp_t *r_sig, const char *tmpl, gcry_md_hd_t hd_orig, const unsigned char *digest; gcry_error_t err; gcry_md_hd_t hd; - char *s; + const char *s; char *hash_name; *r_sig = NULL; @@ -479,7 +479,7 @@ _gcry_pk_sign_md (gcry_sexp_t *r_sig, const char *tmpl, gcry_md_hd_t hd_orig, hash_name = NULL; else { - char *p; + const char *p; for (p = s; *p && *p != ' '; p++) ; @@ -638,28 +638,83 @@ _gcry_pk_verify_md (gcry_sexp_t s_sig, const char *tmpl, gcry_md_hd_t hd_orig, const unsigned char *digest; gcry_error_t err; gcry_md_hd_t hd; + const char *s; + char *hash_name; + + /* Check if it has fixed hash name or %s */ + s = strstr (tmpl, "(hash "); + if (s == NULL) + return GPG_ERR_DIGEST_ALGO; + + s += 6; + if (!strncmp (s, "%s", 2)) + hash_name = NULL; + else + { + const char *p; + + for (p = s; *p && *p != ' '; p++) + ; + + hash_name = xtrymalloc (p - s + 1); + if (!hash_name) + return gpg_error_from_syserror (); + memcpy (hash_name, s, p - s); + hash_name[p - s] = 0; + } err = _gcry_md_copy (&hd, hd_orig); if (err) - return gpg_err_code (err); + { + xfree (hash_name); + return gpg_err_code (err); + } + + if (hash_name) + { + algo = _gcry_md_map_name (hash_name); + if (algo == 0 + || (fips_mode () && algo == GCRY_MD_SHA1)) + { + xfree (hash_name); + _gcry_md_close (hd); + return GPG_ERR_DIGEST_ALGO; + } - algo = _gcry_md_get_algo (hd); + digest = _gcry_md_read (hd, algo); + } + else + { + algo = _gcry_md_get_algo (hd); - if (fips_mode () && algo == GCRY_MD_SHA1) - return GPG_ERR_DIGEST_ALGO; + if (fips_mode () && algo == GCRY_MD_SHA1) + { + _gcry_md_close (hd); + return GPG_ERR_DIGEST_ALGO; + } + + digest = _gcry_md_read (hd, 0); + } - digest = _gcry_md_read (hd, 0); if (!digest) { + xfree (hash_name); _gcry_md_close (hd); return GPG_ERR_DIGEST_ALGO; } if (!ctx) - rc = _gcry_sexp_build (&s_hash, NULL, tmpl, - _gcry_md_algo_name (algo), - (int) _gcry_md_get_algo_dlen (algo), - digest); + { + if (hash_name) + rc = _gcry_sexp_build (&s_hash, NULL, tmpl, + (int) _gcry_md_get_algo_dlen (algo), + digest); + else + rc = _gcry_sexp_build (&s_hash, NULL, tmpl, + _gcry_md_algo_name (algo), + (int) _gcry_md_get_algo_dlen (algo), + digest); + } else { const unsigned char *p; @@ -672,13 +727,20 @@ _gcry_pk_verify_md (gcry_sexp_t s_sig, const char *tmpl, gcry_md_hd_t hd_orig, return rc; } - rc = _gcry_sexp_build (&s_hash, NULL, tmpl, - _gcry_md_algo_name (algo), - (int) _gcry_md_get_algo_dlen (algo), - digest, - (int) len, p); + if (hash_name) + rc = _gcry_sexp_build (&s_hash, NULL, tmpl, + (int) _gcry_md_get_algo_dlen (algo), + digest, + (int) len, p); + else + rc = _gcry_sexp_build (&s_hash, NULL, tmpl, + _gcry_md_algo_name (algo), + (int) _gcry_md_get_algo_dlen (algo), + digest, + (int) len, p); } + xfree (hash_name); _gcry_md_close (hd); if (rc) return rc; diff --git a/tests/t-ecdsa.c b/tests/t-ecdsa.c index 725fcb4f..d36d217b 100644 --- a/tests/t-ecdsa.c +++ b/tests/t-ecdsa.c @@ -487,10 +487,7 @@ one_test_sexp (const char *curvename, const char *sha_alg, fail ("gcry_pk_hash_verify failed for test: %s", gpg_strerror (err)); - /* TODO Verifying with data_tmpl2 crashes because gcry_pk_hash_verify() - * does not support specifying the hash algorithm explicitly. See - * https://dev.gnupg.org/T6066, which tracks this problem. */ - err = gcry_pk_hash_verify (s_sig2, data_tmpl, s_pk, hd, ctx); + err = gcry_pk_hash_verify (s_sig2, data_tmpl2, s_pk, hd, ctx); if (err) fail ("gcry_pk_hash_verify with explicit hash algorithm %s failed: %s", gcry_md_algo_name (md_algo), gpg_strerror (err)); |