summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaiki Ueno <ueno@gnu.org>2020-03-18 10:07:42 +0000
committerDaiki Ueno <ueno@gnu.org>2020-03-18 10:07:42 +0000
commitea2a81e5bd115826d2ecd0b0ecc634c95b285a48 (patch)
treeca2977176c5b61f0cbd756efe32d38a9b89976f4
parenta4e6a5626c1aafaf68735b462943b2c87f77c1bf (diff)
parente671633cf32616401b3cdb04e4285f5dc37fbc65 (diff)
downloadgnutls-ea2a81e5bd115826d2ecd0b0ecc634c95b285a48.tar.gz
Merge branch 'tmp-ed448-fixes' into 'master'
ed448: fix certificate signature verification See merge request gnutls/gnutls!1213
-rw-r--r--lib/algorithms.h6
-rw-r--r--lib/algorithms/sign.c30
-rw-r--r--lib/x509/verify.c4
-rw-r--r--tests/sign-is-secure.c2
-rw-r--r--tests/test-chains.h17
5 files changed, 55 insertions, 4 deletions
diff --git a/lib/algorithms.h b/lib/algorithms.h
index c68a266cc9..9cdb3abf7a 100644
--- a/lib/algorithms.h
+++ b/lib/algorithms.h
@@ -367,6 +367,10 @@ struct gnutls_sign_entry_st {
for values to use in aid struct. */
const sign_algorithm_st aid;
hash_security_level_t slevel; /* contains values of hash_security_level_t */
+
+ /* 0 if it matches the predefined hash output size, otherwise
+ * it is truncated or expanded (with XOF) */
+ unsigned hash_output_size;
};
typedef struct gnutls_sign_entry_st gnutls_sign_entry_st;
@@ -521,4 +525,6 @@ static inline int _sig_is_ecdsa(gnutls_sign_algorithm_t sig)
bool _gnutls_pk_are_compat(gnutls_pk_algorithm_t pk1, gnutls_pk_algorithm_t pk2);
+unsigned _gnutls_sign_get_hash_strength(gnutls_sign_algorithm_t sign);
+
#endif /* GNUTLS_LIB_ALGORITHMS_H */
diff --git a/lib/algorithms/sign.c b/lib/algorithms/sign.c
index 9c95e388ae..0d8d1a89c9 100644
--- a/lib/algorithms/sign.c
+++ b/lib/algorithms/sign.c
@@ -134,7 +134,8 @@ gnutls_sign_entry_st sign_algorithms[] = {
.pk = GNUTLS_PK_EDDSA_ED448,
.hash = GNUTLS_DIG_SHAKE_256,
.flags = GNUTLS_SIGN_FLAG_TLS13_OK,
- .aid = {{8, 8}, SIG_SEM_DEFAULT}},
+ .aid = {{8, 8}, SIG_SEM_DEFAULT},
+ .hash_output_size = 114},
/* ECDSA */
/* The following three signature algorithms
@@ -785,3 +786,30 @@ _gnutls13_sign_get_compatible_with_privkey(gnutls_privkey_t privkey)
return NULL;
}
+
+unsigned
+_gnutls_sign_get_hash_strength(gnutls_sign_algorithm_t sign)
+{
+ const gnutls_sign_entry_st *se = _gnutls_sign_to_entry(sign);
+ const mac_entry_st *me;
+ unsigned hash_output_size;
+
+ if (unlikely(se == NULL))
+ return 0;
+
+ me = mac_to_entry(se->hash);
+ if (unlikely(me == NULL))
+ return 0;
+
+ if (se->hash_output_size > 0)
+ hash_output_size = se->hash_output_size;
+ else
+ hash_output_size = _gnutls_mac_get_algo_len(me);
+
+ if (me->id == GNUTLS_MAC_SHAKE_128)
+ return MIN(hash_output_size*8/2, 128);
+ else if (me->id == GNUTLS_MAC_SHAKE_256)
+ return MIN(hash_output_size*8/2, 256);
+
+ return hash_output_size*8/2;
+}
diff --git a/lib/x509/verify.c b/lib/x509/verify.c
index d381b4ee87..d202670198 100644
--- a/lib/x509/verify.c
+++ b/lib/x509/verify.c
@@ -421,9 +421,9 @@ unsigned _gnutls_is_broken_sig_allowed(const gnutls_sign_entry_st *se, unsigned
_gnutls_debug_log(#level": certificate's signature hash is unknown\n"); \
return gnutls_assert_val(0); \
} \
- if (entry->output_size*8/2 < sym_bits) { \
+ if (_gnutls_sign_get_hash_strength(sigalg) < sym_bits) { \
_gnutls_cert_log("cert", crt); \
- _gnutls_debug_log(#level": certificate's signature hash strength is unacceptable (is %u bits, needed %u)\n", entry->output_size*8/2, sym_bits); \
+ _gnutls_debug_log(#level": certificate's signature hash strength is unacceptable (is %u bits, needed %u)\n", _gnutls_sign_get_hash_strength(sigalg), sym_bits); \
return gnutls_assert_val(0); \
} \
sp = gnutls_pk_bits_to_sec_param(pkalg, bits); \
diff --git a/tests/sign-is-secure.c b/tests/sign-is-secure.c
index 729e5024b3..5f987e08b4 100644
--- a/tests/sign-is-secure.c
+++ b/tests/sign-is-secure.c
@@ -86,7 +86,7 @@ void doit(void)
CHECK_INSECURE_SIG(GNUTLS_SIGN_RSA_MD5);
CHECK_INSECURE_SIG(GNUTLS_SIGN_RSA_MD2);
- for (i=1;i<GNUTLS_SIGN_MAX;i++) {
+ for (i=1;i<=GNUTLS_SIGN_MAX;i++) {
#ifndef ALLOW_SHA1
if (i==GNUTLS_SIGN_RSA_SHA1||i==GNUTLS_SIGN_DSA_SHA1||i==GNUTLS_SIGN_ECDSA_SHA1)
continue;
diff --git a/tests/test-chains.h b/tests/test-chains.h
index fe118717d4..dd19e6a815 100644
--- a/tests/test-chains.h
+++ b/tests/test-chains.h
@@ -3995,6 +3995,21 @@ static const char *rsa_512[] = {
NULL
};
+static const char *ed448[] = {
+ "-----BEGIN CERTIFICATE-----\n"
+ "MIIBhDCCAQSgAwIBAgIUIWKQV5hisum31Z2Fw+PeZ80wqnkwBQYDK2VxMBkxFzAV\n"
+ "BgNVBAMTDkdudVRMUyB0ZXN0IENBMCAXDTIwMDMxNjA5MTY1M1oYDzk5OTkxMjMx\n"
+ "MjM1OTU5WjAZMRcwFQYDVQQDEw5HbnVUTFMgdGVzdCBDQTBDMAUGAytlcQM6AFsM\n"
+ "fQUL5TonNaVrBB7H4UtwnVlolZatMXceHZiWnzMKXOZXlIabi0nTGkvSFu9ed6JJ\n"
+ "L7EWarjRAKNDMEEwDwYDVR0TAQH/BAUwAwEB/zAPBgNVHQ8BAf8EBQMDBwQAMB0G\n"
+ "A1UdDgQWBBRMwtFQ9T9Ndw63UP2QGAuIFoYb6TAFBgMrZXEDcwB8hbYLw7KMlb3a\n"
+ "Q2YAXiugWt2WcAMtvKgqzjXzUt2jilaDA72d3MCAWQQsMmQfRNSthDIao5CksoDk\n"
+ "Xc8qFzckmdBiF7W+UNT3OMisE9yIxF4iA1Sxsji3C0WDUq2jen5Uv9E99H+r47L8\n"
+ "U955wKxWJAA=\n"
+ "-----END CERTIFICATE-----\n",
+ NULL
+};
+
#if defined __clang__ || __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wunused-variable"
@@ -4161,6 +4176,8 @@ static struct
#endif
{ "rsa-512 - not ok (due to profile)", rsa_512, &rsa_512[0], GNUTLS_PROFILE_TO_VFLAGS(GNUTLS_PROFILE_MEDIUM),
GNUTLS_CERT_INSECURE_ALGORITHM | GNUTLS_CERT_INVALID, NULL, 1576759855, 1},
+ { "ed448 - ok", ed448, &ed448[0], GNUTLS_PROFILE_TO_VFLAGS(GNUTLS_PROFILE_ULTRA),
+ 0, NULL, 1584352960, 1},
{ NULL, NULL, NULL, 0, 0}
};