summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNIIBE Yutaka <gniibe@fsij.org>2022-07-07 12:13:08 +0900
committerNIIBE Yutaka <gniibe@fsij.org>2022-07-07 12:13:08 +0900
commitb2a64ed4f34abbd3871336503bec5ffeb3ad547b (patch)
tree23fbf2c35906a33d803c32661a9480bd46e5f168
parent37b812f5e2a3c80d4bc104512248a07268f3c98b (diff)
downloadlibgcrypt-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.c94
-rw-r--r--tests/t-ecdsa.c5
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));