diff options
author | Daiki Ueno <ueno@gnu.org> | 2020-03-18 10:07:42 +0000 |
---|---|---|
committer | Daiki Ueno <ueno@gnu.org> | 2020-03-18 10:07:42 +0000 |
commit | ea2a81e5bd115826d2ecd0b0ecc634c95b285a48 (patch) | |
tree | ca2977176c5b61f0cbd756efe32d38a9b89976f4 | |
parent | a4e6a5626c1aafaf68735b462943b2c87f77c1bf (diff) | |
parent | e671633cf32616401b3cdb04e4285f5dc37fbc65 (diff) | |
download | gnutls-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.h | 6 | ||||
-rw-r--r-- | lib/algorithms/sign.c | 30 | ||||
-rw-r--r-- | lib/x509/verify.c | 4 | ||||
-rw-r--r-- | tests/sign-is-secure.c | 2 | ||||
-rw-r--r-- | tests/test-chains.h | 17 |
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} }; |