From 281766c5e6604a2d6c7885a4769bd67838f99d37 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Tue, 25 Aug 2020 13:54:08 +0200 Subject: [PATCH] tls-crypto: Filter TLS cipher suites by min/max version There is no point proposing legacy (or future) cipher suites depending on the proposed TLS versions. It was actually possible to negotiate and use cipher suites only defined for TLS 1.2 with earlier TLS versions. --- src/libtls/tests/suites/test_socket.c | 20 ++-- src/libtls/tls_crypto.c | 136 ++++++++++++++------------ src/libtls/tls_crypto.h | 4 +- 3 files changed, 88 insertions(+), 72 deletions(-) diff --git a/src/libtls/tests/suites/test_socket.c b/src/libtls/tests/suites/test_socket.c index af7eaefd38..a637096cda 100644 --- a/src/libtls/tests/suites/test_socket.c +++ b/src/libtls/tests/suites/test_socket.c @@ -426,8 +426,7 @@ static void test_tls(tls_version_t version, uint16_t port, bool cauth, u_int i) start_echo_server(config); - count = tls_crypto_get_supported_suites(TRUE, &suites); - + count = tls_crypto_get_supported_suites(TRUE, version, &suites); ck_assert(i < count); snprintf(suite, sizeof(suite), "%N", tls_cipher_suite_names, suites[i]); lib->settings->set_str(lib->settings, "%s.tls.suites", suite, lib->ns); @@ -482,40 +481,41 @@ Suite *socket_suite_create() { Suite *s; TCase *tc; - int count; - count = tls_crypto_get_supported_suites(TRUE, NULL); +#define add_tls_test(func, version) \ + tcase_add_loop_test(tc, func, 0, \ + tls_crypto_get_supported_suites(TRUE, version, NULL)); s = suite_create("socket"); tc = tcase_create("TLS 1.2/anon"); tcase_add_checked_fixture(tc, setup_creds, teardown_creds); - tcase_add_loop_test(tc, test_tls12, 0, count); + add_tls_test(test_tls12, TLS_1_2); suite_add_tcase(s, tc); tc = tcase_create("TLS 1.2/mutl"); tcase_add_checked_fixture(tc, setup_creds, teardown_creds); - tcase_add_loop_test(tc, test_tls12_mutual, 0, count); + add_tls_test(test_tls12_mutual, TLS_1_2); suite_add_tcase(s, tc); tc = tcase_create("TLS 1.1/anon"); tcase_add_checked_fixture(tc, setup_creds, teardown_creds); - tcase_add_loop_test(tc, test_tls11, 0, count); + add_tls_test(test_tls11, TLS_1_1); suite_add_tcase(s, tc); tc = tcase_create("TLS 1.1/mutl"); tcase_add_checked_fixture(tc, setup_creds, teardown_creds); - tcase_add_loop_test(tc, test_tls11_mutual, 0, count); + add_tls_test(test_tls11_mutual, TLS_1_1); suite_add_tcase(s, tc); tc = tcase_create("TLS 1.0/anon"); tcase_add_checked_fixture(tc, setup_creds, teardown_creds); - tcase_add_loop_test(tc, test_tls10, 0, count); + add_tls_test(test_tls10, TLS_1_0); suite_add_tcase(s, tc); tc = tcase_create("TLS 1.0/mutl"); tcase_add_checked_fixture(tc, setup_creds, teardown_creds); - tcase_add_loop_test(tc, test_tls10_mutual, 0, count); + add_tls_test(test_tls10_mutual, TLS_1_0); suite_add_tcase(s, tc); return s; diff --git a/src/libtls/tls_crypto.c b/src/libtls/tls_crypto.c index 311299bea0..0d296b521f 100644 --- a/src/libtls/tls_crypto.c +++ b/src/libtls/tls_crypto.c @@ -470,7 +470,8 @@ typedef struct { integrity_algorithm_t mac; encryption_algorithm_t encr; size_t encr_size; - tls_version_t tls_version; + tls_version_t min_version; + tls_version_t max_version; } suite_algs_t; /** @@ -483,278 +484,278 @@ static suite_algs_t suite_algs[] = { KEY_ANY, MODP_NONE, HASH_SHA256, PRF_UNDEFINED, AUTH_HMAC_SHA2_256_256, ENCR_AES_GCM_ICV16, 16, - TLS_1_3, + TLS_1_3, TLS_1_3, }, { TLS_AES_256_GCM_SHA384, KEY_ANY, MODP_NONE, HASH_SHA384, PRF_UNDEFINED, AUTH_HMAC_SHA2_384_384, ENCR_AES_GCM_ICV16, 32, - TLS_1_3, + TLS_1_3, TLS_1_3, }, { TLS_CHACHA20_POLY1305_SHA256, KEY_ANY, MODP_NONE, HASH_SHA256, PRF_UNDEFINED, AUTH_HMAC_SHA2_256_256, ENCR_CHACHA20_POLY1305, 32, - TLS_1_3, + TLS_1_3, TLS_1_3, }, { TLS_AES_128_CCM_SHA256, - KEY_ANY, MODP_NONE, - HASH_SHA256, PRF_UNDEFINED, - AUTH_HMAC_SHA2_256_256, ENCR_AES_CCM_ICV16, 16, - TLS_1_3, + KEY_ANY, MODP_NONE, + HASH_SHA256, PRF_UNDEFINED, + AUTH_HMAC_SHA2_256_256, ENCR_AES_CCM_ICV16, 16, + TLS_1_3, TLS_1_3, }, { TLS_AES_128_CCM_8_SHA256, - KEY_ANY, MODP_NONE, - HASH_SHA256, PRF_UNDEFINED, - AUTH_HMAC_SHA2_256_256, ENCR_AES_CCM_ICV8, 16, - TLS_1_3, + KEY_ANY, MODP_NONE, + HASH_SHA256, PRF_UNDEFINED, + AUTH_HMAC_SHA2_256_256, ENCR_AES_CCM_ICV8, 16, + TLS_1_3, TLS_1_3, }, /* Legacy TLS cipher suites */ { TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, KEY_ECDSA, ECP_256_BIT, HASH_SHA256, PRF_HMAC_SHA2_256, AUTH_HMAC_SHA1_160, ENCR_AES_CBC, 16, - TLS_1_2, + TLS_1_0, TLS_1_2, }, { TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, KEY_ECDSA, ECP_256_BIT, HASH_SHA256, PRF_HMAC_SHA2_256, AUTH_HMAC_SHA2_256_256, ENCR_AES_CBC, 16, - TLS_1_2, + TLS_1_2, TLS_1_2, }, { TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, KEY_ECDSA, ECP_384_BIT, HASH_SHA256, PRF_HMAC_SHA2_256, AUTH_HMAC_SHA1_160, ENCR_AES_CBC, 32, - TLS_1_2, + TLS_1_0, TLS_1_2, }, { TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, KEY_ECDSA, ECP_384_BIT, HASH_SHA384, PRF_HMAC_SHA2_384, AUTH_HMAC_SHA2_384_384, ENCR_AES_CBC, 32, - TLS_1_2, + TLS_1_2, TLS_1_2, }, { TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, KEY_ECDSA, ECP_256_BIT, HASH_SHA256, PRF_HMAC_SHA2_256, AUTH_UNDEFINED, ENCR_AES_GCM_ICV16, 16, - TLS_1_2, + TLS_1_2, TLS_1_2, }, { TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, KEY_ECDSA, ECP_384_BIT, HASH_SHA384, PRF_HMAC_SHA2_384, AUTH_UNDEFINED, ENCR_AES_GCM_ICV16, 32, - TLS_1_2, + TLS_1_2, TLS_1_2, }, { TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, KEY_RSA, ECP_256_BIT, HASH_SHA256, PRF_HMAC_SHA2_256, AUTH_HMAC_SHA1_160, ENCR_AES_CBC, 16, - TLS_1_2, + TLS_1_0, TLS_1_2, }, { TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, KEY_RSA, ECP_256_BIT, HASH_SHA256, PRF_HMAC_SHA2_256, AUTH_HMAC_SHA2_256_256, ENCR_AES_CBC, 16, - TLS_1_2, + TLS_1_2, TLS_1_2, }, { TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, KEY_RSA, ECP_384_BIT, HASH_SHA256, PRF_HMAC_SHA2_256, AUTH_HMAC_SHA1_160, ENCR_AES_CBC, 32, - TLS_1_2, + TLS_1_0, TLS_1_2, }, { TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, KEY_RSA, ECP_384_BIT, HASH_SHA384, PRF_HMAC_SHA2_384, AUTH_HMAC_SHA2_384_384, ENCR_AES_CBC, 32, - TLS_1_2, + TLS_1_2, TLS_1_2, }, { TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, KEY_RSA, ECP_256_BIT, HASH_SHA256, PRF_HMAC_SHA2_256, AUTH_UNDEFINED, ENCR_AES_GCM_ICV16, 16, - TLS_1_2, + TLS_1_2, TLS_1_2, }, { TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, KEY_RSA, ECP_384_BIT, HASH_SHA384, PRF_HMAC_SHA2_384, AUTH_UNDEFINED, ENCR_AES_GCM_ICV16, 32, - TLS_1_2, + TLS_1_2, TLS_1_2, }, { TLS_DHE_RSA_WITH_AES_128_CBC_SHA, KEY_RSA, MODP_2048_BIT, HASH_SHA256,PRF_HMAC_SHA2_256, AUTH_HMAC_SHA1_160, ENCR_AES_CBC, 16, - TLS_1_2, + SSL_3_0, TLS_1_2, }, { TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, KEY_RSA, MODP_3072_BIT, HASH_SHA256, PRF_HMAC_SHA2_256, AUTH_HMAC_SHA2_256_256, ENCR_AES_CBC, 16, - TLS_1_2, + TLS_1_2, TLS_1_2, }, { TLS_DHE_RSA_WITH_AES_256_CBC_SHA, KEY_RSA, MODP_3072_BIT, HASH_SHA256, PRF_HMAC_SHA2_256, AUTH_HMAC_SHA1_160, ENCR_AES_CBC, 32, - TLS_1_2, + SSL_3_0, TLS_1_2, }, { TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, KEY_RSA, MODP_4096_BIT, HASH_SHA256, PRF_HMAC_SHA2_256, AUTH_HMAC_SHA2_256_256, ENCR_AES_CBC, 32, - TLS_1_2, + TLS_1_2, TLS_1_2, }, { TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, KEY_RSA, MODP_3072_BIT, HASH_SHA256, PRF_HMAC_SHA2_256, AUTH_UNDEFINED, ENCR_AES_GCM_ICV16, 16, - TLS_1_2, + TLS_1_2, TLS_1_2, }, { TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, KEY_RSA, MODP_4096_BIT, HASH_SHA384, PRF_HMAC_SHA2_384, AUTH_UNDEFINED, ENCR_AES_GCM_ICV16, 32, - TLS_1_2, + TLS_1_2, TLS_1_2, }, { TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA, KEY_RSA, MODP_2048_BIT, HASH_SHA256, PRF_HMAC_SHA2_256, AUTH_HMAC_SHA1_160, ENCR_CAMELLIA_CBC, 16, - TLS_1_2, + SSL_3_0, TLS_1_2, }, { TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256, KEY_RSA, MODP_3072_BIT, HASH_SHA256, PRF_HMAC_SHA2_256, AUTH_HMAC_SHA2_256_256, ENCR_CAMELLIA_CBC, 16, - TLS_1_2, + TLS_1_2, TLS_1_2, }, { TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA, KEY_RSA, MODP_3072_BIT, HASH_SHA256, PRF_HMAC_SHA2_256, AUTH_HMAC_SHA1_160, ENCR_CAMELLIA_CBC, 32, - TLS_1_2, + SSL_3_0, TLS_1_2, }, { TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256, KEY_RSA, MODP_4096_BIT, HASH_SHA256, PRF_HMAC_SHA2_256, AUTH_HMAC_SHA2_256_256, ENCR_CAMELLIA_CBC, 32, - TLS_1_2, + TLS_1_2, TLS_1_2, }, { TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, KEY_RSA, MODP_2048_BIT, HASH_SHA256, PRF_HMAC_SHA2_256, AUTH_HMAC_SHA1_160, ENCR_3DES, 0, - TLS_1_2, + SSL_3_0, TLS_1_2, }, { TLS_RSA_WITH_AES_128_CBC_SHA, KEY_RSA, MODP_NONE, HASH_SHA256, PRF_HMAC_SHA2_256, AUTH_HMAC_SHA1_160, ENCR_AES_CBC, 16, - TLS_1_2, + SSL_3_0, TLS_1_2, }, { TLS_RSA_WITH_AES_128_CBC_SHA256, KEY_RSA, MODP_NONE, HASH_SHA256, PRF_HMAC_SHA2_256, AUTH_HMAC_SHA2_256_256, ENCR_AES_CBC, 16, - TLS_1_2, + TLS_1_2, TLS_1_2, }, { TLS_RSA_WITH_AES_256_CBC_SHA, KEY_RSA, MODP_NONE, HASH_SHA256, PRF_HMAC_SHA2_256, AUTH_HMAC_SHA1_160, ENCR_AES_CBC, 32, - TLS_1_2, + SSL_3_0, TLS_1_2, }, { TLS_RSA_WITH_AES_256_CBC_SHA256, KEY_RSA, MODP_NONE, HASH_SHA256, PRF_HMAC_SHA2_256, AUTH_HMAC_SHA2_256_256, ENCR_AES_CBC, 32, - TLS_1_2, + TLS_1_2, TLS_1_2, }, { TLS_RSA_WITH_AES_128_GCM_SHA256, KEY_RSA, MODP_NONE, HASH_SHA256, PRF_HMAC_SHA2_256, AUTH_UNDEFINED, ENCR_AES_GCM_ICV16, 16, - TLS_1_2, + TLS_1_2, TLS_1_2, }, { TLS_RSA_WITH_AES_256_GCM_SHA384, KEY_RSA, MODP_NONE, HASH_SHA384, PRF_HMAC_SHA2_384, AUTH_UNDEFINED, ENCR_AES_GCM_ICV16, 32, - TLS_1_2, + TLS_1_2, TLS_1_2, }, { TLS_RSA_WITH_CAMELLIA_128_CBC_SHA, KEY_RSA, MODP_NONE, HASH_SHA256, PRF_HMAC_SHA2_256, AUTH_HMAC_SHA1_160, ENCR_CAMELLIA_CBC, 16, - TLS_1_2, + SSL_3_0, TLS_1_2, }, { TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256, KEY_RSA, MODP_NONE, HASH_SHA256, PRF_HMAC_SHA2_256, AUTH_HMAC_SHA2_256_256, ENCR_CAMELLIA_CBC, 16, - TLS_1_2, + TLS_1_2, TLS_1_2, }, { TLS_RSA_WITH_CAMELLIA_256_CBC_SHA, KEY_RSA, MODP_NONE, HASH_SHA256, PRF_HMAC_SHA2_256, AUTH_HMAC_SHA1_160, ENCR_CAMELLIA_CBC, 32, - TLS_1_2, + SSL_3_0, TLS_1_2, }, { TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256, KEY_RSA, MODP_NONE, HASH_SHA256, PRF_HMAC_SHA2_256, AUTH_HMAC_SHA2_256_256, ENCR_CAMELLIA_CBC, 32, - TLS_1_2, + TLS_1_2, TLS_1_2, }, { TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, KEY_ECDSA, ECP_256_BIT, HASH_SHA256, PRF_HMAC_SHA2_256, AUTH_HMAC_SHA1_160, ENCR_3DES, 0, - TLS_1_2, + TLS_1_0, TLS_1_2, }, { TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, KEY_RSA, ECP_256_BIT, HASH_SHA256, PRF_HMAC_SHA2_256, AUTH_HMAC_SHA1_160, ENCR_3DES, 0, - TLS_1_2, + TLS_1_0, TLS_1_2, }, { TLS_RSA_WITH_3DES_EDE_CBC_SHA, KEY_RSA, MODP_NONE, HASH_SHA256, PRF_HMAC_SHA2_256, AUTH_HMAC_SHA1_160, ENCR_3DES, 0, - TLS_1_2, + SSL_3_0, TLS_1_2, }, { TLS_ECDHE_ECDSA_WITH_NULL_SHA, KEY_ECDSA, ECP_256_BIT, HASH_SHA256, PRF_HMAC_SHA2_256, AUTH_HMAC_SHA1_160, ENCR_NULL, 0, - TLS_1_2, + TLS_1_0, TLS_1_2, }, { TLS_ECDHE_RSA_WITH_NULL_SHA, KEY_ECDSA, ECP_256_BIT, HASH_SHA256, PRF_HMAC_SHA2_256, AUTH_HMAC_SHA1_160, ENCR_NULL, 0, - TLS_1_2, + TLS_1_0, TLS_1_2, }, { TLS_RSA_WITH_NULL_SHA, KEY_RSA, MODP_NONE, HASH_SHA256, PRF_HMAC_SHA2_256, AUTH_HMAC_SHA1_160, ENCR_NULL, 0, - TLS_1_2, + SSL_3_0, TLS_1_2, }, { TLS_RSA_WITH_NULL_SHA256, KEY_RSA, MODP_NONE, HASH_SHA256, PRF_HMAC_SHA2_256, AUTH_HMAC_SHA2_256_256, ENCR_NULL, 0, - TLS_1_2, + TLS_1_2, TLS_1_2, }, { TLS_RSA_WITH_NULL_MD5, KEY_RSA, MODP_NONE, HASH_SHA256, PRF_HMAC_SHA2_256, AUTH_HMAC_MD5_128, ENCR_NULL, 0, - TLS_1_2, + SSL_2_0, TLS_1_2, }, }; @@ -1133,12 +1134,20 @@ static void build_cipher_suite_list(private_tls_crypto_t *this, bool require_encryption) { suite_algs_t suites[countof(suite_algs)]; - int count = countof(suite_algs), i; + tls_version_t min_version, max_version; + int count = 0, i; - /* copy all suites */ - for (i = 0; i < count; i++) + min_version = this->tls->get_version_min(this->tls); + max_version = this->tls->get_version_max(this->tls); + + /* copy all suites appropriate for the current min/max versions */ + for (i = 0; i < countof(suite_algs); i++) { - suites[i] = suite_algs[i]; + if (suite_algs[i].min_version <= max_version && + suite_algs[i].max_version >= min_version) + { + suites[count++] = suite_algs[i]; + } } if (require_encryption) @@ -2334,15 +2343,20 @@ tls_crypto_t *tls_crypto_create(tls_t *tls, tls_cache_t *cache) /** * See header. */ -int tls_crypto_get_supported_suites(bool null, tls_cipher_suite_t **out) +int tls_crypto_get_supported_suites(bool null, tls_version_t version, + tls_cipher_suite_t **out) { suite_algs_t suites[countof(suite_algs)]; - int count = countof(suite_algs), i; + int count = 0, i; /* initialize copy of suite list */ - for (i = 0; i < count; i++) + for (i = 0; i < countof(suite_algs); i++) { - suites[i] = suite_algs[i]; + if (suite_algs[i].min_version <= version && + suite_algs[i].max_version >= version) + { + suites[count++] = suite_algs[i]; + } } filter_unsupported_suites(suites, &count); diff --git a/src/libtls/tls_crypto.h b/src/libtls/tls_crypto.h index a1390e3495..0451906565 100644 --- a/src/libtls/tls_crypto.h +++ b/src/libtls/tls_crypto.h @@ -615,9 +615,11 @@ tls_crypto_t *tls_crypto_create(tls_t *tls, tls_cache_t *cache); * Get a list of all supported TLS cipher suites. * * @param null include supported NULL encryption suites + * @param version TLS version * @param suites pointer to allocated suites array, to free(), or NULL * @return number of suites supported */ -int tls_crypto_get_supported_suites(bool null, tls_cipher_suite_t **suites); +int tls_crypto_get_supported_suites(bool null, tls_version_t version, + tls_cipher_suite_t **suites); #endif /** TLS_CRYPTO_H_ @}*/ -- 2.47.2