|
44 | 44 | #define COMPRESSION_METHODS 0x00, 0x01, 0x02, 0x03, 0x04
|
45 | 45 | #define COMPRESSION_METHODS_LEN 0x05
|
46 | 46 |
|
| 47 | +#define CIPHER_SUITES_MAX_LENGTH (UINT16_MAX - 2) |
| 48 | +#define NUM_OF_CIPHER_SUITES_TO_DROP 150 |
| 49 | +#define MAXIMUM_NUM_OF_CIPHER_SUITES (CIPHER_SUITES_MAX_LENGTH / S2N_TLS_CIPHER_SUITE_LEN) |
| 50 | +/* Drop 150 cipher suites from max, so that the total handshake message length won't exceed 64KB */ |
| 51 | +#define REDUCED_CIPHER_SUITE_COUNT (MAXIMUM_NUM_OF_CIPHER_SUITES - NUM_OF_CIPHER_SUITES_TO_DROP) |
| 52 | +/* Reducing cipher suites by 150 creates approximately 300 bytes margin below maximum handshake length */ |
| 53 | +#define ESTMATIED_MAX_HANDSHAKE_LENGTH_MARGIN (NUM_OF_CIPHER_SUITES_TO_DROP * S2N_TLS_CIPHER_SUITE_LEN) |
| 54 | + |
47 | 55 | int s2n_parse_client_hello(struct s2n_connection *conn);
|
48 | 56 | S2N_RESULT s2n_client_hello_get_raw_extension(uint16_t extension_iana,
|
49 | 57 | struct s2n_blob *raw_extensions, struct s2n_blob *extension);
|
@@ -1953,6 +1961,138 @@ int main(int argc, char **argv)
|
1953 | 1961 | };
|
1954 | 1962 | };
|
1955 | 1963 |
|
| 1964 | + /* Test: Client Hello is slightly less than 64KB */ |
| 1965 | + { |
| 1966 | + DEFER_CLEANUP(struct s2n_config *client_config = s2n_config_new(), s2n_config_ptr_free); |
| 1967 | + EXPECT_NOT_NULL(client_config); |
| 1968 | + |
| 1969 | + DEFER_CLEANUP(struct s2n_config *server_config = s2n_config_new(), s2n_config_ptr_free); |
| 1970 | + EXPECT_NOT_NULL(server_config); |
| 1971 | + |
| 1972 | + EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key_to_store(server_config, chain_and_key)); |
| 1973 | + |
| 1974 | + struct s2n_cipher_suite *test_cipher_suites[REDUCED_CIPHER_SUITE_COUNT] = { 0 }; |
| 1975 | + |
| 1976 | + for (int i = 0; i < REDUCED_CIPHER_SUITE_COUNT; i++) { |
| 1977 | + test_cipher_suites[i] = &s2n_rsa_with_aes_128_gcm_sha256; |
| 1978 | + } |
| 1979 | + |
| 1980 | + const struct s2n_cipher_preferences test_cipher_suites_preferences = { |
| 1981 | + .count = s2n_array_len(test_cipher_suites), |
| 1982 | + .suites = test_cipher_suites, |
| 1983 | + }; |
| 1984 | + |
| 1985 | + struct s2n_security_policy test_security_policy = { |
| 1986 | + .minimum_protocol_version = S2N_TLS12, |
| 1987 | + .cipher_preferences = &test_cipher_suites_preferences, |
| 1988 | + .kem_preferences = &kem_preferences_null, |
| 1989 | + .signature_preferences = &s2n_signature_preferences_20240501, |
| 1990 | + .ecc_preferences = &s2n_ecc_preferences_20240501, |
| 1991 | + .rules = { |
| 1992 | + [S2N_PERFECT_FORWARD_SECRECY] = true, |
| 1993 | + }, |
| 1994 | + }; |
| 1995 | + |
| 1996 | + EXPECT_SUCCESS(s2n_config_disable_x509_verification(client_config)); |
| 1997 | + |
| 1998 | + DEFER_CLEANUP(struct s2n_connection *client = s2n_connection_new(S2N_CLIENT), |
| 1999 | + s2n_connection_ptr_free); |
| 2000 | + EXPECT_NOT_NULL(client); |
| 2001 | + EXPECT_SUCCESS(s2n_connection_set_config(client, client_config)); |
| 2002 | + EXPECT_SUCCESS(s2n_connection_set_blinding(client, S2N_SELF_SERVICE_BLINDING)); |
| 2003 | + client->security_policy_override = &test_security_policy; |
| 2004 | + |
| 2005 | + DEFER_CLEANUP(struct s2n_connection *server = s2n_connection_new(S2N_SERVER), |
| 2006 | + s2n_connection_ptr_free); |
| 2007 | + EXPECT_NOT_NULL(server); |
| 2008 | + EXPECT_SUCCESS(s2n_connection_set_config(server, server_config)); |
| 2009 | + EXPECT_SUCCESS(s2n_connection_set_blinding(server, S2N_SELF_SERVICE_BLINDING)); |
| 2010 | + server->security_policy_override = &test_security_policy; |
| 2011 | + |
| 2012 | + DEFER_CLEANUP(struct s2n_test_io_stuffer_pair io_pair = { 0 }, s2n_io_stuffer_pair_free); |
| 2013 | + EXPECT_OK(s2n_io_stuffer_pair_init(&io_pair)); |
| 2014 | + EXPECT_OK(s2n_connections_set_io_stuffer_pair(client, server, &io_pair)); |
| 2015 | + |
| 2016 | + EXPECT_OK(s2n_negotiate_test_server_and_client_until_message(server, client, SERVER_HELLO)); |
| 2017 | + |
| 2018 | + /* handshake.io shouldn't be tainted after sending and receiving large client hello */ |
| 2019 | + EXPECT_TRUE(client->handshake.io.tainted == 0); |
| 2020 | + EXPECT_TRUE(server->handshake.io.tainted == 0); |
| 2021 | + |
| 2022 | + struct s2n_client_hello *client_hello = s2n_connection_get_client_hello(server); |
| 2023 | + EXPECT_NOT_NULL(client_hello); |
| 2024 | + uint32_t handshake_max_len_margin = S2N_MAXIMUM_HANDSHAKE_MESSAGE_LENGTH - s2n_client_hello_get_raw_message_length(client_hello); |
| 2025 | + /* Size of Client Hello is less than 300 bytes from the maximum handshake length */ |
| 2026 | + EXPECT_TRUE(handshake_max_len_margin < ESTMATIED_MAX_HANDSHAKE_LENGTH_MARGIN); |
| 2027 | + } |
| 2028 | + |
| 2029 | + /* Test: Client Hello is larger than 64KB */ |
| 2030 | + { |
| 2031 | + DEFER_CLEANUP(struct s2n_config *client_config = s2n_config_new(), s2n_config_ptr_free); |
| 2032 | + EXPECT_NOT_NULL(client_config); |
| 2033 | + |
| 2034 | + DEFER_CLEANUP(struct s2n_config *server_config = s2n_config_new(), s2n_config_ptr_free); |
| 2035 | + EXPECT_NOT_NULL(server_config); |
| 2036 | + |
| 2037 | + EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key_to_store(server_config, chain_and_key)); |
| 2038 | + |
| 2039 | + struct s2n_cipher_suite *test_cipher_suites[MAXIMUM_NUM_OF_CIPHER_SUITES] = { 0 }; |
| 2040 | + |
| 2041 | + for (int i = 0; i < MAXIMUM_NUM_OF_CIPHER_SUITES; i++) { |
| 2042 | + test_cipher_suites[i] = &s2n_rsa_with_aes_128_gcm_sha256; |
| 2043 | + } |
| 2044 | + |
| 2045 | + /* We append the maximun number of cipher suites, so that the Client Hello size grows beyond 64KB */ |
| 2046 | + const struct s2n_cipher_preferences test_cipher_suites_preferences = { |
| 2047 | + .count = s2n_array_len(test_cipher_suites), |
| 2048 | + .suites = test_cipher_suites, |
| 2049 | + }; |
| 2050 | + |
| 2051 | + struct s2n_security_policy test_security_policy = { |
| 2052 | + .minimum_protocol_version = S2N_TLS12, |
| 2053 | + .cipher_preferences = &test_cipher_suites_preferences, |
| 2054 | + .kem_preferences = &kem_preferences_null, |
| 2055 | + .signature_preferences = &s2n_signature_preferences_20240501, |
| 2056 | + .ecc_preferences = &s2n_ecc_preferences_20240501, |
| 2057 | + .rules = { |
| 2058 | + [S2N_PERFECT_FORWARD_SECRECY] = true, |
| 2059 | + }, |
| 2060 | + }; |
| 2061 | + |
| 2062 | + EXPECT_SUCCESS(s2n_config_disable_x509_verification(client_config)); |
| 2063 | + |
| 2064 | + DEFER_CLEANUP(struct s2n_connection *client = s2n_connection_new(S2N_CLIENT), |
| 2065 | + s2n_connection_ptr_free); |
| 2066 | + EXPECT_NOT_NULL(client); |
| 2067 | + EXPECT_SUCCESS(s2n_connection_set_config(client, client_config)); |
| 2068 | + EXPECT_SUCCESS(s2n_connection_set_blinding(client, S2N_SELF_SERVICE_BLINDING)); |
| 2069 | + client->security_policy_override = &test_security_policy; |
| 2070 | + |
| 2071 | + DEFER_CLEANUP(struct s2n_connection *server = s2n_connection_new(S2N_SERVER), |
| 2072 | + s2n_connection_ptr_free); |
| 2073 | + EXPECT_NOT_NULL(server); |
| 2074 | + EXPECT_SUCCESS(s2n_connection_set_config(server, server_config)); |
| 2075 | + EXPECT_SUCCESS(s2n_connection_set_blinding(server, S2N_SELF_SERVICE_BLINDING)); |
| 2076 | + server->security_policy_override = &test_security_policy; |
| 2077 | + |
| 2078 | + DEFER_CLEANUP(struct s2n_test_io_stuffer_pair io_pair = { 0 }, s2n_io_stuffer_pair_free); |
| 2079 | + EXPECT_OK(s2n_io_stuffer_pair_init(&io_pair)); |
| 2080 | + EXPECT_OK(s2n_connections_set_io_stuffer_pair(client, server, &io_pair)); |
| 2081 | + |
| 2082 | + s2n_blocked_status blocked = S2N_NOT_BLOCKED; |
| 2083 | + |
| 2084 | + /* Write Client Hello into io_pair.server_in */ |
| 2085 | + s2n_negotiate(client, &blocked); |
| 2086 | + |
| 2087 | + /* The size of Client Hello exceeds S2N_MAXIMUM_HANDSHAKE_MESSAGE_LENGTH */ |
| 2088 | + EXPECT_TRUE(io_pair.server_in.write_cursor > S2N_MAXIMUM_HANDSHAKE_MESSAGE_LENGTH); |
| 2089 | + EXPECT_ERROR_WITH_ERRNO(s2n_negotiate_test_server_and_client_until_message(server, client, SERVER_HELLO), S2N_ERR_BAD_MESSAGE); |
| 2090 | + |
| 2091 | + /* handshake.io shouldn't be tainted after sending and receiving large client hello */ |
| 2092 | + EXPECT_TRUE(client->handshake.io.tainted == 0); |
| 2093 | + EXPECT_TRUE(server->handshake.io.tainted == 0); |
| 2094 | + } |
| 2095 | + |
1956 | 2096 | EXPECT_SUCCESS(s2n_cert_chain_and_key_free(chain_and_key));
|
1957 | 2097 | EXPECT_SUCCESS(s2n_cert_chain_and_key_free(ecdsa_chain_and_key));
|
1958 | 2098 | END_TEST();
|
|
0 commit comments