diff options
author | arcadia-devtools <arcadia-devtools@yandex-team.ru> | 2022-05-11 14:13:26 +0300 |
---|---|---|
committer | arcadia-devtools <arcadia-devtools@yandex-team.ru> | 2022-05-11 14:13:26 +0300 |
commit | 75902786de9844f219bb757ddcd4c51e02955cec (patch) | |
tree | 0a5ec843e4eda00e22562b3b71f8d17367e1a313 | |
parent | 62f93da087b2fec0f89979fd11ac4d754ca36253 (diff) | |
download | ydb-75902786de9844f219bb757ddcd4c51e02955cec.tar.gz |
intermediate changes
ref:5c95b2714e3588791293c74877179909e25d2950
24 files changed, 399 insertions, 189 deletions
diff --git a/build/rules/autocheck.blacklist b/build/rules/autocheck.blacklist index 1e2699499e..d266a05958 100644 --- a/build/rules/autocheck.blacklist +++ b/build/rules/autocheck.blacklist @@ -1419,3 +1419,4 @@ trunk/arcadia/crm/space/frontend_static crm/space/frontend_static mail/java/furita toolbox/tunneler +samsara/samsara-attachments diff --git a/contrib/restricted/aws/s2n/.yandex_meta/devtools.copyrights.report b/contrib/restricted/aws/s2n/.yandex_meta/devtools.copyrights.report index fb08469f30..2e12fcebe0 100644 --- a/contrib/restricted/aws/s2n/.yandex_meta/devtools.copyrights.report +++ b/contrib/restricted/aws/s2n/.yandex_meta/devtools.copyrights.report @@ -195,6 +195,7 @@ BELONGS ya.make stuffer/s2n_stuffer_text.c [2:2] tls/extensions/s2n_client_alpn.c [2:2] tls/extensions/s2n_client_alpn.h [2:2] + tls/extensions/s2n_client_cookie.c [2:2] tls/extensions/s2n_client_early_data_indication.c [2:2] tls/extensions/s2n_client_ems.c [2:2] tls/extensions/s2n_client_key_share.c [2:2] @@ -221,7 +222,6 @@ BELONGS ya.make tls/extensions/s2n_client_supported_groups.h [2:2] tls/extensions/s2n_client_supported_versions.c [2:2] tls/extensions/s2n_client_supported_versions.h [2:2] - tls/extensions/s2n_cookie.c [2:2] tls/extensions/s2n_cookie.h [2:2] tls/extensions/s2n_early_data_indication.h [2:2] tls/extensions/s2n_ec_point_format.c [2:2] @@ -244,6 +244,7 @@ BELONGS ya.make tls/extensions/s2n_server_alpn.h [2:2] tls/extensions/s2n_server_certificate_status.c [2:2] tls/extensions/s2n_server_certificate_status.h [2:2] + tls/extensions/s2n_server_cookie.c [2:2] tls/extensions/s2n_server_early_data_indication.c [2:2] tls/extensions/s2n_server_ems.c [2:2] tls/extensions/s2n_server_key_share.c [2:2] diff --git a/contrib/restricted/aws/s2n/.yandex_meta/devtools.licenses.report b/contrib/restricted/aws/s2n/.yandex_meta/devtools.licenses.report index 8ac59c754b..77b0c78928 100644 --- a/contrib/restricted/aws/s2n/.yandex_meta/devtools.licenses.report +++ b/contrib/restricted/aws/s2n/.yandex_meta/devtools.licenses.report @@ -352,6 +352,7 @@ BELONGS ya.make stuffer/s2n_stuffer_text.c [4:13] tls/extensions/s2n_client_alpn.c [4:13] tls/extensions/s2n_client_alpn.h [4:13] + tls/extensions/s2n_client_cookie.c [4:13] tls/extensions/s2n_client_early_data_indication.c [4:13] tls/extensions/s2n_client_ems.c [4:13] tls/extensions/s2n_client_key_share.c [4:13] @@ -378,7 +379,6 @@ BELONGS ya.make tls/extensions/s2n_client_supported_groups.h [4:13] tls/extensions/s2n_client_supported_versions.c [4:13] tls/extensions/s2n_client_supported_versions.h [4:13] - tls/extensions/s2n_cookie.c [4:13] tls/extensions/s2n_cookie.h [4:13] tls/extensions/s2n_early_data_indication.h [4:13] tls/extensions/s2n_ec_point_format.c [4:13] @@ -401,6 +401,7 @@ BELONGS ya.make tls/extensions/s2n_server_alpn.h [4:13] tls/extensions/s2n_server_certificate_status.c [4:13] tls/extensions/s2n_server_certificate_status.h [4:13] + tls/extensions/s2n_server_cookie.c [4:13] tls/extensions/s2n_server_early_data_indication.c [4:13] tls/extensions/s2n_server_ems.c [4:13] tls/extensions/s2n_server_key_share.c [4:13] diff --git a/contrib/restricted/aws/s2n/CMakeLists.darwin.txt b/contrib/restricted/aws/s2n/CMakeLists.darwin.txt index bf42b0c84a..13baca35b6 100644 --- a/contrib/restricted/aws/s2n/CMakeLists.darwin.txt +++ b/contrib/restricted/aws/s2n/CMakeLists.darwin.txt @@ -175,6 +175,7 @@ target_sources(restricted-aws-s2n PRIVATE ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/stuffer/s2n_stuffer_pem.c ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/stuffer/s2n_stuffer_text.c ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/extensions/s2n_client_alpn.c + ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/extensions/s2n_client_cookie.c ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/extensions/s2n_client_early_data_indication.c ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/extensions/s2n_client_ems.c ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/extensions/s2n_client_key_share.c @@ -189,7 +190,6 @@ target_sources(restricted-aws-s2n PRIVATE ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/extensions/s2n_client_status_request.c ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/extensions/s2n_client_supported_groups.c ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/extensions/s2n_client_supported_versions.c - ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/extensions/s2n_cookie.c ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/extensions/s2n_ec_point_format.c ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/extensions/s2n_extension_list.c ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/extensions/s2n_extension_type.c @@ -200,6 +200,7 @@ target_sources(restricted-aws-s2n PRIVATE ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/extensions/s2n_quic_transport_params.c ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/extensions/s2n_server_alpn.c ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/extensions/s2n_server_certificate_status.c + ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/extensions/s2n_server_cookie.c ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/extensions/s2n_server_early_data_indication.c ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/extensions/s2n_server_ems.c ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/extensions/s2n_server_key_share.c diff --git a/contrib/restricted/aws/s2n/CMakeLists.linux.txt b/contrib/restricted/aws/s2n/CMakeLists.linux.txt index e66c27d911..02a667dbcb 100644 --- a/contrib/restricted/aws/s2n/CMakeLists.linux.txt +++ b/contrib/restricted/aws/s2n/CMakeLists.linux.txt @@ -178,6 +178,7 @@ target_sources(restricted-aws-s2n PRIVATE ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/stuffer/s2n_stuffer_pem.c ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/stuffer/s2n_stuffer_text.c ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/extensions/s2n_client_alpn.c + ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/extensions/s2n_client_cookie.c ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/extensions/s2n_client_early_data_indication.c ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/extensions/s2n_client_ems.c ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/extensions/s2n_client_key_share.c @@ -192,7 +193,6 @@ target_sources(restricted-aws-s2n PRIVATE ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/extensions/s2n_client_status_request.c ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/extensions/s2n_client_supported_groups.c ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/extensions/s2n_client_supported_versions.c - ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/extensions/s2n_cookie.c ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/extensions/s2n_ec_point_format.c ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/extensions/s2n_extension_list.c ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/extensions/s2n_extension_type.c @@ -203,6 +203,7 @@ target_sources(restricted-aws-s2n PRIVATE ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/extensions/s2n_quic_transport_params.c ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/extensions/s2n_server_alpn.c ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/extensions/s2n_server_certificate_status.c + ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/extensions/s2n_server_cookie.c ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/extensions/s2n_server_early_data_indication.c ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/extensions/s2n_server_ems.c ${CMAKE_SOURCE_DIR}/contrib/restricted/aws/s2n/tls/extensions/s2n_server_key_share.c diff --git a/contrib/restricted/aws/s2n/crypto/s2n_fips.c b/contrib/restricted/aws/s2n/crypto/s2n_fips.c index 8843f4ebd9..2586c4dfee 100644 --- a/contrib/restricted/aws/s2n/crypto/s2n_fips.c +++ b/contrib/restricted/aws/s2n/crypto/s2n_fips.c @@ -31,6 +31,11 @@ int s2n_fips_init(void) * Note: FIPS_mode() does not change the FIPS state of libcrypto. This only returns the current state. Applications * using s2n must call FIPS_mode_set(1) prior to s2n_init. * */ + +#if defined(S2N_INTERN_LIBCRYPTO) && defined(OPENSSL_FIPS) +#error "Interning with OpenSSL fips-validated libcrypto is not currently supported. See https://github.com/aws/s2n-tls/issues/2741" +#endif + #if defined(OPENSSL_FIPS) || defined(OPENSSL_IS_AWSLC) if (FIPS_mode()) { s2n_fips_mode = 1; diff --git a/contrib/restricted/aws/s2n/crypto/s2n_stream_cipher_rc4.c b/contrib/restricted/aws/s2n/crypto/s2n_stream_cipher_rc4.c index 9cc41ff677..9c858ea11b 100644 --- a/contrib/restricted/aws/s2n/crypto/s2n_stream_cipher_rc4.c +++ b/contrib/restricted/aws/s2n/crypto/s2n_stream_cipher_rc4.c @@ -16,6 +16,7 @@ #include <openssl/rc4.h> #include "crypto/s2n_cipher.h" +#include "crypto/s2n_fips.h" #include "crypto/s2n_openssl.h" #include "utils/s2n_safety.h" @@ -23,7 +24,11 @@ static uint8_t s2n_stream_cipher_rc4_available() { - return (EVP_rc4() ? 1 : 0); + if (s2n_is_in_fips_mode()) { + return 0; + } else { + return (EVP_rc4() ? 1 : 0); + } } static int s2n_stream_cipher_rc4_encrypt(struct s2n_session_key *key, struct s2n_blob *in, struct s2n_blob *out) diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_cookie.c b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_cookie.c new file mode 100644 index 0000000000..3143286b5e --- /dev/null +++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_cookie.c @@ -0,0 +1,83 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +#include "tls/extensions/s2n_cookie.h" +#include "tls/s2n_tls.h" +#include "utils/s2n_random.h" + +/* + *= https://tools.ietf.org/rfc/rfc8446#section-4.2.2 + *# When sending the new ClientHello, the client MUST copy + *# the contents of the extension received in the HelloRetryRequest into + *# a "cookie" extension in the new ClientHello. + * + * If the server sent a cookie, send it back. + */ +static bool s2n_client_cookie_should_send(struct s2n_connection *conn) +{ + return conn && conn->cookie.size > 0; +} + +/* + *= https://tools.ietf.org/rfc/rfc8446#section-4.2.2 + *# struct { + *# opaque cookie<1..2^16-1>; + *# } Cookie; + */ +int s2n_cookie_send(struct s2n_connection *conn, struct s2n_stuffer *out) +{ + POSIX_ENSURE_REF(conn); + + POSIX_GUARD(s2n_stuffer_write_uint16(out, conn->cookie.size)); + POSIX_GUARD(s2n_stuffer_write(out, &conn->cookie)); + + return S2N_SUCCESS; +} + +/* + * Our server does not send cookies in production, so + * should never receive a cookie back from the client. + * + * However, we may enable cookies for testing. + * In that case, verify the proper client behavior by + * checking that the cookie sent matches the cookie received. + * This is also why the "if_missing" behavior is an error. + */ +static int s2n_client_cookie_recv(struct s2n_connection *conn, struct s2n_stuffer *extension) +{ + POSIX_ENSURE_REF(conn); + POSIX_ENSURE(s2n_in_unit_test(), S2N_ERR_UNSUPPORTED_EXTENSION); + + uint16_t size = 0; + POSIX_GUARD(s2n_stuffer_read_uint16(extension, &size)); + POSIX_ENSURE(size == conn->cookie.size, S2N_ERR_BAD_MESSAGE); + POSIX_ENSURE(size >= s2n_stuffer_data_available(extension), S2N_ERR_BAD_MESSAGE); + + uint8_t *cookie = s2n_stuffer_raw_read(extension, size); + POSIX_ENSURE_REF(cookie); + POSIX_ENSURE(s2n_constant_time_equals(cookie, conn->cookie.data, size), S2N_ERR_BAD_MESSAGE); + + return S2N_SUCCESS; +} + +const s2n_extension_type s2n_client_cookie_extension = { + .iana_value = TLS_EXTENSION_COOKIE, + .minimum_version = S2N_TLS13, + .is_response = true, + .send = s2n_cookie_send, + .recv = s2n_client_cookie_recv, + .should_send = s2n_client_cookie_should_send, + .if_missing = s2n_extension_error_if_missing, +}; diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_cookie.c b/contrib/restricted/aws/s2n/tls/extensions/s2n_cookie.c deleted file mode 100644 index 18940d7191..0000000000 --- a/contrib/restricted/aws/s2n/tls/extensions/s2n_cookie.c +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://aws.amazon.com/apache2.0 - * - * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ - -#include "tls/extensions/s2n_cookie.h" -#include "tls/s2n_tls.h" - -#define S2N_SIZE_OF_EXTENSION_TYPE 2 -#define S2N_SIZE_OF_EXTENSION_DATA_SIZE 2 -#define S2N_SIZE_OF_COOKIE_DATA_SIZE 2 - -const s2n_extension_type s2n_client_cookie_extension = { - .iana_value = TLS_EXTENSION_COOKIE, - .minimum_version = S2N_TLS13, - .is_response = true, - .send = s2n_extension_send_noop, - .recv = s2n_extension_recv_noop, - .should_send = s2n_extension_never_send, - .if_missing = s2n_extension_noop_if_missing, -}; - -static bool s2n_cookie_should_send(struct s2n_connection *conn); -static int s2n_cookie_send(struct s2n_connection *conn, struct s2n_stuffer *out); -static int s2n_cookie_recv(struct s2n_connection *conn, struct s2n_stuffer *extension); - -const s2n_extension_type s2n_server_cookie_extension = { - .iana_value = TLS_EXTENSION_COOKIE, - .minimum_version = S2N_TLS13, - .is_response = false, - .send = s2n_cookie_send, - .recv = s2n_cookie_recv, - .should_send = s2n_cookie_should_send, - .if_missing = s2n_extension_noop_if_missing, -}; - -static bool s2n_cookie_should_send(struct s2n_connection *conn) -{ - return conn && s2n_stuffer_data_available(&conn->cookie_stuffer) > 0; -} - -static int s2n_cookie_send(struct s2n_connection *conn, struct s2n_stuffer *out) -{ - POSIX_ENSURE_REF(conn); - uint16_t cookie_size = s2n_stuffer_data_available(&conn->cookie_stuffer); - POSIX_GUARD(s2n_stuffer_write_uint16(out, cookie_size)); - POSIX_GUARD(s2n_stuffer_copy(&conn->cookie_stuffer, out, cookie_size)); - return S2N_SUCCESS; -} - -static int s2n_cookie_recv(struct s2n_connection *conn, struct s2n_stuffer *extension) -{ - POSIX_ENSURE_REF(conn); - - uint16_t cookie_len; - POSIX_GUARD(s2n_stuffer_read_uint16(extension, &cookie_len)); - POSIX_ENSURE(s2n_stuffer_data_available(extension) == cookie_len, S2N_ERR_BAD_MESSAGE); - - POSIX_GUARD(s2n_stuffer_wipe(&conn->cookie_stuffer)); - POSIX_GUARD(s2n_stuffer_resize(&conn->cookie_stuffer, cookie_len)); - POSIX_GUARD(s2n_stuffer_copy(extension, &conn->cookie_stuffer, cookie_len)); - return S2N_SUCCESS; -} - -/* Old-style extension functions -- remove after extensions refactor is complete */ - -int s2n_extensions_cookie_size(struct s2n_connection *conn) -{ - POSIX_GUARD(s2n_stuffer_reread(&conn->cookie_stuffer)); - - if (s2n_stuffer_data_available(&conn->cookie_stuffer) == 0) { - return 0; - } - - const int cookie_extension_size = S2N_SIZE_OF_EXTENSION_TYPE - + S2N_SIZE_OF_EXTENSION_DATA_SIZE - + S2N_SIZE_OF_COOKIE_DATA_SIZE - + s2n_stuffer_data_available(&conn->cookie_stuffer); - - return cookie_extension_size; -} - -int s2n_extensions_cookie_recv(struct s2n_connection *conn, struct s2n_stuffer *extension) -{ - return s2n_extension_send(&s2n_server_cookie_extension, conn, extension); -} - -int s2n_extensions_cookie_send(struct s2n_connection *conn, struct s2n_stuffer *out) -{ - return s2n_extension_send(&s2n_server_cookie_extension, conn, out); -} diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_cookie.h b/contrib/restricted/aws/s2n/tls/extensions/s2n_cookie.h index 4a77ba323e..ae844cc7ab 100644 --- a/contrib/restricted/aws/s2n/tls/extensions/s2n_cookie.h +++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_cookie.h @@ -17,13 +17,9 @@ #pragma once #include "tls/extensions/s2n_extension_type.h" -#include "tls/s2n_connection.h" -#include "stuffer/s2n_stuffer.h" extern const s2n_extension_type s2n_client_cookie_extension; extern const s2n_extension_type s2n_server_cookie_extension; -/* Old-style extension functions -- remove after extensions refactor is complete */ -int s2n_extensions_cookie_size(struct s2n_connection *conn); -int s2n_extensions_cookie_send(struct s2n_connection *conn, struct s2n_stuffer *out); -int s2n_extensions_cookie_recv(struct s2n_connection *conn, struct s2n_stuffer *extension); +int s2n_cookie_send(struct s2n_connection *conn, struct s2n_stuffer *out); + diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_extension_type_lists.c b/contrib/restricted/aws/s2n/tls/extensions/s2n_extension_type_lists.c index ba749a4e87..e28e774acc 100644 --- a/contrib/restricted/aws/s2n/tls/extensions/s2n_extension_type_lists.c +++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_extension_type_lists.c @@ -110,7 +110,6 @@ static const s2n_extension_type *const hello_retry_request_extensions[] = { static const s2n_extension_type *const tls13_server_hello_extensions[] = { &s2n_server_supported_versions_extension, &s2n_server_key_share_extension, - &s2n_server_cookie_extension, &s2n_server_psk_extension, /* MUST appear after keyshare extension */ }; diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_psk_key_exchange_modes.c b/contrib/restricted/aws/s2n/tls/extensions/s2n_psk_key_exchange_modes.c index e66a552772..cf0c57ed8d 100644 --- a/contrib/restricted/aws/s2n/tls/extensions/s2n_psk_key_exchange_modes.c +++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_psk_key_exchange_modes.c @@ -37,8 +37,8 @@ const s2n_extension_type s2n_psk_key_exchange_modes_extension = { static bool s2n_psk_key_exchange_modes_should_send(struct s2n_connection *conn) { - /* Only send a psk_key_exchange_modes extension if a psk extension is also being sent */ - return s2n_client_psk_should_send(conn); + /* Only send a psk_key_exchange_modes extension if psks available */ + return conn->psk_params.psk_list.len > 0; } static int s2n_psk_key_exchange_modes_send(struct s2n_connection *conn, struct s2n_stuffer *out) diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_cookie.c b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_cookie.c new file mode 100644 index 0000000000..2be81eb5c2 --- /dev/null +++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_cookie.c @@ -0,0 +1,85 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +#include "tls/extensions/s2n_cookie.h" +#include "tls/s2n_tls.h" +#include "utils/s2n_random.h" + +/* + *= https://tools.ietf.org/rfc/rfc8446#section-4.2.2 + *# Cookies serve two primary purposes: + *# + *# - Allowing the server to force the client to demonstrate + *# reachability at their apparent network address (thus providing a + *# measure of DoS protection). This is primarily useful for + *# non-connection-oriented transports (see [RFC6347] for an example + *# of this). + *# + *# - Allowing the server to offload state to the client, thus allowing + *# it to send a HelloRetryRequest without storing any state. The + *# server can do this by storing the hash of the ClientHello in the + *# HelloRetryRequest cookie (protected with some suitable integrity + *# protection algorithm). + *# + *# When sending a HelloRetryRequest, the server MAY provide a "cookie" + *# extension to the client (this is an exception to the usual rule that + *# the only extensions that may be sent are those that appear in the + *# ClientHello). + * + * So our server does not send cookies in production, + * because it doesn't support DTLS and isn't stateless. + * + * However, we will sometimes send cookies for testing. + */ +static bool s2n_server_cookie_should_send(struct s2n_connection *conn) +{ + return conn && conn->cookie.size > 0 && s2n_in_unit_test(); +} + +/* + *= https://tools.ietf.org/rfc/rfc8446#section-4.2.2 + *# When sending the new ClientHello, the client MUST copy + *# the contents of the extension received in the HelloRetryRequest into + *# a "cookie" extension in the new ClientHello. + * + * Store the server's cookie for later use in the new ClientHello. + */ +static int s2n_server_cookie_recv(struct s2n_connection *conn, struct s2n_stuffer *extension) +{ + POSIX_ENSURE_REF(conn); + + /* This extension should only appear on the hello retry request extension list, + * but verify the retry anyway. + */ + POSIX_ENSURE(s2n_is_hello_retry_handshake(conn), S2N_ERR_UNSUPPORTED_EXTENSION); + + uint16_t size = 0; + POSIX_GUARD(s2n_stuffer_read_uint16(extension, &size)); + POSIX_ENSURE(s2n_stuffer_data_available(extension) >= size, S2N_ERR_BAD_MESSAGE); + + POSIX_GUARD(s2n_realloc(&conn->cookie, size)); + POSIX_GUARD(s2n_stuffer_read(extension, &conn->cookie)); + return S2N_SUCCESS; +} + +const s2n_extension_type s2n_server_cookie_extension = { + .iana_value = TLS_EXTENSION_COOKIE, + .minimum_version = S2N_TLS13, + .is_response = false, + .send = s2n_cookie_send, + .recv = s2n_server_cookie_recv, + .should_send = s2n_server_cookie_should_send, + .if_missing = s2n_extension_noop_if_missing, +}; diff --git a/contrib/restricted/aws/s2n/tls/s2n_client_hello.c b/contrib/restricted/aws/s2n/tls/s2n_client_hello.c index 0bcec3501a..149f4d4b53 100644 --- a/contrib/restricted/aws/s2n/tls/s2n_client_hello.c +++ b/contrib/restricted/aws/s2n/tls/s2n_client_hello.c @@ -87,7 +87,7 @@ static S2N_RESULT s2n_generate_client_session_id(struct s2n_connection *conn) ssize_t s2n_client_hello_get_raw_message_length(struct s2n_client_hello *ch) { POSIX_ENSURE_REF(ch); - return ch->raw_message.blob.size; + return ch->raw_message.size; } ssize_t s2n_client_hello_get_raw_message(struct s2n_client_hello *ch, uint8_t *out, uint32_t max_length) @@ -95,12 +95,8 @@ ssize_t s2n_client_hello_get_raw_message(struct s2n_client_hello *ch, uint8_t *o POSIX_ENSURE_REF(ch); POSIX_ENSURE_REF(out); - uint32_t len = min_size(&ch->raw_message.blob, max_length); - - struct s2n_stuffer *raw_message = &ch->raw_message; - POSIX_GUARD(s2n_stuffer_reread(raw_message)); - POSIX_GUARD(s2n_stuffer_read_bytes(raw_message, out, len)); - + uint32_t len = min_size(&ch->raw_message, max_length); + POSIX_CHECKED_MEMCPY(out, ch->raw_message.data, len); return len; } @@ -161,19 +157,13 @@ int s2n_client_hello_free(struct s2n_client_hello *client_hello) { POSIX_ENSURE_REF(client_hello); - POSIX_GUARD(s2n_stuffer_free(&client_hello->raw_message)); + POSIX_GUARD(s2n_free(&client_hello->raw_message)); /* These point to data in the raw_message stuffer, so we don't need to free them */ client_hello->cipher_suites.data = NULL; client_hello->extensions.raw.data = NULL; - /* clean the CH nonblocking callback flags - * incase we are preparing for CH retry */ - client_hello->callback_async_blocked = 0; - client_hello->callback_async_done = 0; - client_hello->parsed = 0; - return 0; } @@ -187,15 +177,147 @@ int s2n_collect_client_hello(struct s2n_connection *conn, struct s2n_stuffer *so struct s2n_client_hello *ch = &conn->client_hello; - POSIX_GUARD(s2n_stuffer_resize(&ch->raw_message, size)); - POSIX_GUARD(s2n_stuffer_copy(source, &ch->raw_message, size)); + POSIX_GUARD(s2n_realloc(&ch->raw_message, size)); + POSIX_GUARD(s2n_stuffer_read(source, &ch->raw_message)); return 0; } + +static S2N_RESULT s2n_client_hello_verify_for_retry(struct s2n_connection *conn, + struct s2n_client_hello *old_ch, struct s2n_client_hello *new_ch, + uint8_t *previous_client_random) +{ + RESULT_ENSURE_REF(conn); + RESULT_ENSURE_REF(old_ch); + RESULT_ENSURE_REF(new_ch); + RESULT_ENSURE_REF(previous_client_random); + + if (!s2n_is_hello_retry_handshake(conn)) { + return S2N_RESULT_OK; + } + + /* + *= https://tools.ietf.org/rfc/rfc8446#section-4.1.2 + *# The client will also send a + *# ClientHello when the server has responded to its ClientHello with a + *# HelloRetryRequest. In that case, the client MUST send the same + *# ClientHello without modification, except as follows: + * + * All of the exceptions that follow are extensions. + * Ignoring the extensions, the client hellos should match /exactly/. + */ + ssize_t old_msg_len = old_ch->raw_message.size; + /* Also consider the 2-byte size of the extension list */ + ssize_t old_extensions_len = old_ch->extensions.raw.size + sizeof(uint16_t); + RESULT_ENSURE_GT(old_msg_len, old_extensions_len); + size_t verify_len = old_msg_len - old_extensions_len; + RESULT_ENSURE_LTE(verify_len, new_ch->raw_message.size); + RESULT_ENSURE(s2n_constant_time_equals( + old_ch->raw_message.data, + new_ch->raw_message.data, + verify_len + ), S2N_ERR_BAD_MESSAGE); + + /* + * We need to verify the client random separately + * because we erase it from the client hello during parsing. + * Compare the old value to the current value. + */ + RESULT_ENSURE(s2n_constant_time_equals( + previous_client_random, + conn->handshake_params.client_random, + S2N_TLS_RANDOM_DATA_LEN + ), S2N_ERR_BAD_MESSAGE); + + /* + * Now enforce that the extensions also exactly match, + * except for the exceptions described in the RFC. + */ + for (size_t i = 0; i < s2n_array_len(s2n_supported_extensions); i++) { + s2n_parsed_extension *old_extension = &old_ch->extensions.parsed_extensions[i]; + uint32_t old_size = old_extension->extension.size; + s2n_parsed_extension *new_extension = &new_ch->extensions.parsed_extensions[i]; + uint32_t new_size = new_extension->extension.size; + + /* The extension type is only set if the extension is present. + * Look for a non-zero-length extension. + */ + uint16_t extension_type = 0; + if (old_size != 0) { + extension_type = old_extension->extension_type; + } else if (new_size != 0) { + extension_type = new_extension->extension_type; + } else { + continue; + } + + switch(extension_type) { + /* + *= https://tools.ietf.org/rfc/rfc8446#section-4.1.2 + *# - If a "key_share" extension was supplied in the HelloRetryRequest, + *# replacing the list of shares with a list containing a single + *# KeyShareEntry from the indicated group. + */ + case TLS_EXTENSION_KEY_SHARE: + /* Handled when parsing the key share extension */ + break; + /* + *= https://tools.ietf.org/rfc/rfc8446#section-4.1.2 + *# - Removing the "early_data" extension (Section 4.2.10) if one was + *# present. Early data is not permitted after a HelloRetryRequest. + */ + case TLS_EXTENSION_EARLY_DATA: + RESULT_ENSURE(new_size == 0, S2N_ERR_BAD_MESSAGE); + break; + /* + *= https://tools.ietf.org/rfc/rfc8446#section-4.1.2 + *# - Including a "cookie" extension if one was provided in the + *# HelloRetryRequest. + */ + case TLS_EXTENSION_COOKIE: + /* Handled when parsing the cookie extension */ + break; + /* + *= https://tools.ietf.org/rfc/rfc8446#section-4.1.2 + *# - Updating the "pre_shared_key" extension if present by recomputing + *# the "obfuscated_ticket_age" and binder values and (optionally) + *# removing any PSKs which are incompatible with the server's + *# indicated cipher suite. + */ + case TLS_EXTENSION_PRE_SHARED_KEY: + /* Handled when parsing the psk extension */ + break; + /* + * No more exceptions. + * All other extensions must match. + */ + default: + RESULT_ENSURE(old_size == new_size, S2N_ERR_BAD_MESSAGE); + RESULT_ENSURE(s2n_constant_time_equals( + new_extension->extension.data, + old_extension->extension.data, + old_size + ), S2N_ERR_BAD_MESSAGE); + } + } + + return S2N_RESULT_OK; +} + int s2n_parse_client_hello(struct s2n_connection *conn) { POSIX_ENSURE_REF(conn); + + /* If a retry, move the old version of the client hello + * somewhere safe so we can compare it to the new client hello later. + */ + DEFER_CLEANUP(struct s2n_client_hello previous_hello_retry = conn->client_hello, + s2n_client_hello_free); + if (s2n_is_hello_retry_handshake(conn)) { + POSIX_CHECKED_MEMSET(&conn->client_hello, 0, sizeof(struct s2n_client_hello)); + } + POSIX_GUARD(s2n_collect_client_hello(conn, &conn->handshake.io)); if (conn->client_hello_version == S2N_SSLv2) { @@ -205,11 +327,17 @@ int s2n_parse_client_hello(struct s2n_connection *conn) /* Going forward, we parse the collected client hello */ struct s2n_client_hello *client_hello = &conn->client_hello; - struct s2n_stuffer *in = &client_hello->raw_message; + struct s2n_stuffer in_stuffer = { 0 }; + POSIX_GUARD(s2n_stuffer_init(&in_stuffer, &client_hello->raw_message)); + POSIX_GUARD(s2n_stuffer_skip_write(&in_stuffer, client_hello->raw_message.size)); + struct s2n_stuffer *in = &in_stuffer; uint8_t client_protocol_version[S2N_TLS_PROTOCOL_VERSION_LEN]; POSIX_GUARD(s2n_stuffer_read_bytes(in, client_protocol_version, S2N_TLS_PROTOCOL_VERSION_LEN)); + + uint8_t previous_client_random[S2N_TLS_RANDOM_DATA_LEN] = { 0 }; + POSIX_CHECKED_MEMCPY(previous_client_random, conn->handshake_params.client_random, S2N_TLS_RANDOM_DATA_LEN); POSIX_GUARD(s2n_stuffer_erase_and_read_bytes(in, conn->handshake_params.client_random, S2N_TLS_RANDOM_DATA_LEN)); /* Protocol version in the ClientHello is fixed at 0x0303(TLS 1.2) for @@ -256,6 +384,8 @@ int s2n_parse_client_hello(struct s2n_connection *conn) POSIX_GUARD(s2n_extension_list_parse(in, &conn->client_hello.extensions)); + POSIX_GUARD_RESULT(s2n_client_hello_verify_for_retry(conn, + &previous_hello_retry, client_hello, previous_client_random)); return S2N_SUCCESS; } @@ -416,26 +546,22 @@ int s2n_client_hello_send(struct s2n_connection *conn) } struct s2n_stuffer *out = &conn->handshake.io; - struct s2n_stuffer client_random = {0}; uint8_t client_protocol_version[S2N_TLS_PROTOCOL_VERSION_LEN] = {0}; - struct s2n_blob b = {0}; - POSIX_GUARD(s2n_blob_init(&b, conn->handshake_params.client_random, S2N_TLS_RANDOM_DATA_LEN)); - /* Create the client random data */ - POSIX_GUARD(s2n_stuffer_init(&client_random, &b)); - - struct s2n_blob r = {0}; - POSIX_GUARD(s2n_blob_init(&r, s2n_stuffer_raw_write(&client_random, S2N_TLS_RANDOM_DATA_LEN), S2N_TLS_RANDOM_DATA_LEN)); - POSIX_ENSURE_REF(r.data); - POSIX_GUARD_RESULT(s2n_get_public_random_data(&r)); - uint8_t reported_protocol_version = MIN(conn->client_protocol_version, S2N_TLS12); client_protocol_version[0] = reported_protocol_version / 10; client_protocol_version[1] = reported_protocol_version % 10; conn->client_hello_version = reported_protocol_version; - POSIX_GUARD(s2n_stuffer_write_bytes(out, client_protocol_version, S2N_TLS_PROTOCOL_VERSION_LEN)); - POSIX_GUARD(s2n_stuffer_copy(&client_random, out, S2N_TLS_RANDOM_DATA_LEN)); + + struct s2n_blob client_random = { 0 }; + POSIX_GUARD(s2n_blob_init(&client_random, conn->handshake_params.client_random, S2N_TLS_RANDOM_DATA_LEN)); + if (!s2n_is_hello_retry_handshake(conn)) { + /* Only generate the random data for our first client hello. + * If we retry, we'll reuse the value. */ + POSIX_GUARD_RESULT(s2n_get_public_random_data(&client_random)); + } + POSIX_GUARD(s2n_stuffer_write(out, &client_random)); POSIX_GUARD_RESULT(s2n_generate_client_session_id(conn)); POSIX_GUARD(s2n_stuffer_write_uint8(out, conn->session_id_len)); @@ -496,7 +622,10 @@ int s2n_client_hello_send(struct s2n_connection *conn) int s2n_sslv2_client_hello_recv(struct s2n_connection *conn) { struct s2n_client_hello *client_hello = &conn->client_hello; - struct s2n_stuffer *in = &client_hello->raw_message; + struct s2n_stuffer in_stuffer = { 0 }; + POSIX_GUARD(s2n_stuffer_init(&in_stuffer, &client_hello->raw_message)); + POSIX_GUARD(s2n_stuffer_skip_write(&in_stuffer, client_hello->raw_message.size)); + struct s2n_stuffer *in = &in_stuffer; const struct s2n_security_policy *security_policy; POSIX_GUARD(s2n_connection_get_security_policy(conn, &security_policy)); diff --git a/contrib/restricted/aws/s2n/tls/s2n_client_hello.h b/contrib/restricted/aws/s2n/tls/s2n_client_hello.h index d319bbd606..1d6afd95d5 100644 --- a/contrib/restricted/aws/s2n/tls/s2n_client_hello.h +++ b/contrib/restricted/aws/s2n/tls/s2n_client_hello.h @@ -27,7 +27,7 @@ * point to data in the raw_message stuffer */ struct s2n_client_hello { - struct s2n_stuffer raw_message; + struct s2n_blob raw_message; s2n_parsed_extensions_list extensions; struct s2n_blob cipher_suites; diff --git a/contrib/restricted/aws/s2n/tls/s2n_connection.c b/contrib/restricted/aws/s2n/tls/s2n_connection.c index cf6334164f..6aba265cf0 100644 --- a/contrib/restricted/aws/s2n/tls/s2n_connection.c +++ b/contrib/restricted/aws/s2n/tls/s2n_connection.c @@ -140,7 +140,6 @@ struct s2n_connection *s2n_connection_new(s2n_mode mode) PTR_GUARD_POSIX(s2n_stuffer_growable_alloc(&conn->out, 0)); PTR_GUARD_POSIX(s2n_stuffer_growable_alloc(&conn->in, 0)); PTR_GUARD_POSIX(s2n_stuffer_growable_alloc(&conn->handshake.io, 0)); - PTR_GUARD_POSIX(s2n_stuffer_growable_alloc(&conn->client_hello.raw_message, 0)); PTR_GUARD_RESULT(s2n_timer_start(conn->config, &conn->write_timer)); /* NOTE: s2n_connection_wipe MUST be called last in this function. @@ -357,7 +356,7 @@ int s2n_connection_free(struct s2n_connection *conn) s2n_x509_validator_wipe(&conn->x509_validator); POSIX_GUARD(s2n_client_hello_free(&conn->client_hello)); POSIX_GUARD(s2n_free(&conn->application_protocols_overridden)); - POSIX_GUARD(s2n_stuffer_free(&conn->cookie_stuffer)); + POSIX_GUARD(s2n_free(&conn->cookie)); POSIX_GUARD(s2n_free_object((uint8_t **)&conn, sizeof(struct s2n_connection))); return 0; @@ -487,18 +486,18 @@ int s2n_connection_free_handshake(struct s2n_connection *conn) /* Wipe the buffers we are going to free */ POSIX_GUARD(s2n_stuffer_wipe(&conn->handshake.io)); - POSIX_GUARD(s2n_stuffer_wipe(&conn->client_hello.raw_message)); + POSIX_GUARD(s2n_blob_zero(&conn->client_hello.raw_message)); /* Truncate buffers to save memory, we are done with the handshake */ POSIX_GUARD(s2n_stuffer_resize(&conn->handshake.io, 0)); - POSIX_GUARD(s2n_stuffer_resize(&conn->client_hello.raw_message, 0)); + POSIX_GUARD(s2n_free(&conn->client_hello.raw_message)); /* We can free extension data we no longer need */ POSIX_GUARD(s2n_free(&conn->client_ticket)); POSIX_GUARD(s2n_free(&conn->status_response)); POSIX_GUARD(s2n_free(&conn->our_quic_transport_parameters)); POSIX_GUARD(s2n_free(&conn->application_protocols_overridden)); - POSIX_GUARD(s2n_stuffer_free(&conn->cookie_stuffer)); + POSIX_GUARD(s2n_free(&conn->cookie)); return 0; } @@ -519,7 +518,6 @@ int s2n_connection_wipe(struct s2n_connection *conn) struct s2n_stuffer writer_alert_out = {0}; struct s2n_stuffer client_ticket_to_decrypt = {0}; struct s2n_stuffer handshake_io = {0}; - struct s2n_stuffer client_hello_raw_message = {0}; struct s2n_stuffer header_in = {0}; struct s2n_stuffer in = {0}; struct s2n_stuffer out = {0}; @@ -553,7 +551,7 @@ int s2n_connection_wipe(struct s2n_connection *conn) POSIX_GUARD(s2n_stuffer_wipe(&conn->writer_alert_out)); POSIX_GUARD(s2n_stuffer_wipe(&conn->client_ticket_to_decrypt)); POSIX_GUARD(s2n_stuffer_wipe(&conn->handshake.io)); - POSIX_GUARD(s2n_stuffer_wipe(&conn->client_hello.raw_message)); + POSIX_GUARD(s2n_blob_zero(&conn->client_hello.raw_message)); POSIX_GUARD(s2n_stuffer_wipe(&conn->header_in)); POSIX_GUARD(s2n_stuffer_wipe(&conn->in)); POSIX_GUARD(s2n_stuffer_wipe(&conn->out)); @@ -570,15 +568,13 @@ int s2n_connection_wipe(struct s2n_connection *conn) POSIX_GUARD(s2n_free(&conn->peer_quic_transport_parameters)); POSIX_GUARD(s2n_free(&conn->server_early_data_context)); POSIX_GUARD(s2n_free(&conn->tls13_ticket_fields.session_secret)); - /* TODO: Simplify cookie_stuffer implementation. - * https://github.com/aws/s2n-tls/issues/3287 */ - POSIX_GUARD(s2n_stuffer_free(&conn->cookie_stuffer)); + POSIX_GUARD(s2n_free(&conn->cookie)); /* Allocate memory for handling handshakes */ POSIX_GUARD(s2n_stuffer_resize(&conn->handshake.io, S2N_LARGE_RECORD_LENGTH)); /* Truncate the message buffers to save memory, we will dynamically resize it as needed */ - POSIX_GUARD(s2n_stuffer_resize(&conn->client_hello.raw_message, 0)); + POSIX_GUARD(s2n_free(&conn->client_hello.raw_message)); POSIX_GUARD(s2n_stuffer_resize(&conn->in, 0)); POSIX_GUARD(s2n_stuffer_resize(&conn->out, 0)); @@ -600,7 +596,6 @@ int s2n_connection_wipe(struct s2n_connection *conn) POSIX_CHECKED_MEMCPY(&writer_alert_out, &conn->writer_alert_out, sizeof(struct s2n_stuffer)); POSIX_CHECKED_MEMCPY(&client_ticket_to_decrypt, &conn->client_ticket_to_decrypt, sizeof(struct s2n_stuffer)); POSIX_CHECKED_MEMCPY(&handshake_io, &conn->handshake.io, sizeof(struct s2n_stuffer)); - POSIX_CHECKED_MEMCPY(&client_hello_raw_message, &conn->client_hello.raw_message, sizeof(struct s2n_stuffer)); POSIX_CHECKED_MEMCPY(&header_in, &conn->header_in, sizeof(struct s2n_stuffer)); POSIX_CHECKED_MEMCPY(&in, &conn->in, sizeof(struct s2n_stuffer)); POSIX_CHECKED_MEMCPY(&out, &conn->out, sizeof(struct s2n_stuffer)); @@ -620,7 +615,6 @@ int s2n_connection_wipe(struct s2n_connection *conn) POSIX_CHECKED_MEMCPY(&conn->writer_alert_out, &writer_alert_out, sizeof(struct s2n_stuffer)); POSIX_CHECKED_MEMCPY(&conn->client_ticket_to_decrypt, &client_ticket_to_decrypt, sizeof(struct s2n_stuffer)); POSIX_CHECKED_MEMCPY(&conn->handshake.io, &handshake_io, sizeof(struct s2n_stuffer)); - POSIX_CHECKED_MEMCPY(&conn->client_hello.raw_message, &client_hello_raw_message, sizeof(struct s2n_stuffer)); POSIX_CHECKED_MEMCPY(&conn->header_in, &header_in, sizeof(struct s2n_stuffer)); POSIX_CHECKED_MEMCPY(&conn->in, &in, sizeof(struct s2n_stuffer)); POSIX_CHECKED_MEMCPY(&conn->out, &out, sizeof(struct s2n_stuffer)); @@ -659,9 +653,6 @@ int s2n_connection_wipe(struct s2n_connection *conn) /* Initialize remaining values */ conn->blinding = S2N_BUILT_IN_BLINDING; conn->session_ticket_status = S2N_NO_TICKET; - /* Initialize the cookie stuffer with zero length. If a cookie extension - * is received, the stuffer will be resized according to the cookie length */ - POSIX_GUARD(s2n_stuffer_growable_alloc(&conn->cookie_stuffer, 0)); return 0; } diff --git a/contrib/restricted/aws/s2n/tls/s2n_connection.h b/contrib/restricted/aws/s2n/tls/s2n_connection.h index 0332241d63..09e1f19724 100644 --- a/contrib/restricted/aws/s2n/tls/s2n_connection.h +++ b/contrib/restricted/aws/s2n/tls/s2n_connection.h @@ -352,7 +352,7 @@ struct s2n_connection { struct s2n_blob application_protocols_overridden; /* Cookie extension data */ - struct s2n_stuffer cookie_stuffer; + struct s2n_blob cookie; /* Flags to prevent users from calling methods recursively. * This can be an easy mistake to make when implementing callbacks. diff --git a/contrib/restricted/aws/s2n/tls/s2n_handshake_hashes.c b/contrib/restricted/aws/s2n/tls/s2n_handshake_hashes.c index c3c727af81..538c742215 100644 --- a/contrib/restricted/aws/s2n/tls/s2n_handshake_hashes.c +++ b/contrib/restricted/aws/s2n/tls/s2n_handshake_hashes.c @@ -73,7 +73,6 @@ static S2N_RESULT s2n_handshake_hashes_init_hashes(struct s2n_handshake_hashes * */ if (s2n_is_in_fips_mode()) { RESULT_GUARD_POSIX(s2n_hash_allow_md5_for_fips(&hashes->md5)); - RESULT_GUARD_POSIX(s2n_hash_allow_md5_for_fips(&hashes->hash_workspace)); /* Do not check s2n_hash_is_available before initialization. Allow MD5 and * SHA-1 for both fips and non-fips mode. This is required to perform the diff --git a/contrib/restricted/aws/s2n/tls/s2n_prf.c b/contrib/restricted/aws/s2n/tls/s2n_prf.c index 1096eb6c82..161f28eae1 100644 --- a/contrib/restricted/aws/s2n/tls/s2n_prf.c +++ b/contrib/restricted/aws/s2n/tls/s2n_prf.c @@ -44,6 +44,11 @@ static int s2n_sslv3_prf(struct s2n_connection *conn, struct s2n_blob *secret, s POSIX_ENSURE_REF(conn->handshake.hashes); struct s2n_hash_state *workspace = &conn->handshake.hashes->hash_workspace; + /* FIPS specifically allows MD5 for the legacy PRF */ + if (s2n_is_in_fips_mode() && conn->actual_protocol_version < S2N_TLS12) { + POSIX_GUARD(s2n_hash_allow_md5_for_fips(workspace)); + } + uint32_t outputlen = out->size; uint8_t *output = out->data; uint8_t iteration = 1; diff --git a/contrib/restricted/aws/s2n/tls/s2n_psk.c b/contrib/restricted/aws/s2n/tls/s2n_psk.c index 4aacb13d87..7a42ab28dc 100644 --- a/contrib/restricted/aws/s2n/tls/s2n_psk.c +++ b/contrib/restricted/aws/s2n/tls/s2n_psk.c @@ -549,6 +549,12 @@ S2N_RESULT s2n_finish_psk_extension(struct s2n_connection *conn) s2n_stuffer_data_available(client_hello))); RESULT_GUARD(s2n_psk_write_binder_list(conn, &partial_client_hello, client_hello)); + + /* Reset binder list size. + * This is important because the psk extension can be removed during a retry. + */ + conn->psk_params.binder_list_size = 0; + return S2N_RESULT_OK; } diff --git a/contrib/restricted/aws/s2n/tls/s2n_server_hello_retry.c b/contrib/restricted/aws/s2n/tls/s2n_server_hello_retry.c index c305289100..ed80865998 100644 --- a/contrib/restricted/aws/s2n/tls/s2n_server_hello_retry.c +++ b/contrib/restricted/aws/s2n/tls/s2n_server_hello_retry.c @@ -33,22 +33,6 @@ uint8_t hello_retry_req_random[S2N_TLS_RANDOM_DATA_LEN] = { 0xC2, 0xA2, 0x11, 0x16, 0x7A, 0xBB, 0x8C, 0x5E, 0x07, 0x9E, 0x09, 0xE2, 0xC8, 0xA8, 0x33, 0x9C }; -static int s2n_conn_reset_retry_values(struct s2n_connection *conn) -{ - POSIX_ENSURE_REF(conn); - - /* Reset handshake values */ - conn->handshake.client_hello_received = 0; - - /* Reset client hello state */ - POSIX_GUARD(s2n_stuffer_wipe(&conn->client_hello.raw_message)); - POSIX_GUARD(s2n_stuffer_resize(&conn->client_hello.raw_message, 0)); - POSIX_GUARD(s2n_client_hello_free(&conn->client_hello)); - POSIX_GUARD(s2n_stuffer_growable_alloc(&conn->client_hello.raw_message, 0)); - - return 0; -} - int s2n_server_hello_retry_send(struct s2n_connection *conn) { POSIX_ENSURE_REF(conn); @@ -62,7 +46,11 @@ int s2n_server_hello_retry_send(struct s2n_connection *conn) /* Update transcript */ POSIX_GUARD(s2n_server_hello_retry_recreate_transcript(conn)); - POSIX_GUARD(s2n_conn_reset_retry_values(conn)); + + /* Reset handshake values */ + conn->handshake.client_hello_received = 0; + conn->client_hello.parsed = 0; + POSIX_CHECKED_MEMSET((uint8_t*) conn->extension_requests_received, 0, sizeof(s2n_extension_bitfield)); return 0; } @@ -117,5 +105,8 @@ int s2n_server_hello_retry_recv(struct s2n_connection *conn) /* Update transcript hash */ POSIX_GUARD(s2n_server_hello_retry_recreate_transcript(conn)); + /* Reset handshake values */ + POSIX_CHECKED_MEMSET((uint8_t*) conn->extension_requests_sent, 0, sizeof(s2n_extension_bitfield)); + return S2N_SUCCESS; } diff --git a/contrib/restricted/aws/s2n/tls/s2n_server_key_exchange.c b/contrib/restricted/aws/s2n/tls/s2n_server_key_exchange.c index b10b300e57..fc60767bb6 100644 --- a/contrib/restricted/aws/s2n/tls/s2n_server_key_exchange.c +++ b/contrib/restricted/aws/s2n/tls/s2n_server_key_exchange.c @@ -29,6 +29,7 @@ #include "stuffer/s2n_stuffer.h" #include "crypto/s2n_dhe.h" +#include "crypto/s2n_fips.h" #include "utils/s2n_safety.h" #include "utils/s2n_random.h" @@ -58,6 +59,11 @@ int s2n_server_key_recv(struct s2n_connection *conn) POSIX_GUARD(s2n_get_and_validate_negotiated_signature_scheme(conn, in, active_sig_scheme)); } + /* FIPS specifically allows MD5 for <TLS1.2 */ + if (s2n_is_in_fips_mode() && conn->actual_protocol_version < S2N_TLS12) { + POSIX_GUARD(s2n_hash_allow_md5_for_fips(signature_hash)); + } + POSIX_GUARD(s2n_hash_init(signature_hash, active_sig_scheme->hash_alg)); POSIX_GUARD(s2n_hash_update(signature_hash, conn->handshake_params.client_random, S2N_TLS_RANDOM_DATA_LEN)); POSIX_GUARD(s2n_hash_update(signature_hash, conn->handshake_params.server_random, S2N_TLS_RANDOM_DATA_LEN)); @@ -250,6 +256,11 @@ int s2n_server_key_send(struct s2n_connection *conn) POSIX_GUARD(s2n_stuffer_write_uint16(out, conn->handshake_params.conn_sig_scheme.iana_value)); } + /* FIPS specifically allows MD5 for <TLS1.2 */ + if (s2n_is_in_fips_mode() && conn->actual_protocol_version < S2N_TLS12) { + POSIX_GUARD(s2n_hash_allow_md5_for_fips(signature_hash)); + } + /* Add the random data to the hash */ POSIX_GUARD(s2n_hash_init(signature_hash, conn->handshake_params.conn_sig_scheme.hash_alg)); POSIX_GUARD(s2n_hash_update(signature_hash, conn->handshake_params.client_random, S2N_TLS_RANDOM_DATA_LEN)); diff --git a/contrib/restricted/aws/s2n/tls/s2n_signature_algorithms.c b/contrib/restricted/aws/s2n/tls/s2n_signature_algorithms.c index ae367e9670..f7775ccee8 100644 --- a/contrib/restricted/aws/s2n/tls/s2n_signature_algorithms.c +++ b/contrib/restricted/aws/s2n/tls/s2n_signature_algorithms.c @@ -181,18 +181,15 @@ int s2n_choose_default_sig_scheme(struct s2n_connection *conn, struct s2n_signat auth_method = conn->secure.cipher_suite->auth_method; } - /* Default our signature digest algorithms. For TLS 1.2 this default is different and may be - * overridden by the signature_algorithms extension. If the server chooses an ECDHE_ECDSA - * cipher suite, this will be overridden to SHA1. + /* Default our signature digest algorithms. + * For >=TLS 1.2 this default may be overridden by the signature_algorithms extension. */ - *sig_scheme_out = s2n_rsa_pkcs1_md5_sha1; - if (auth_method == S2N_AUTHENTICATION_ECDSA) { *sig_scheme_out = s2n_ecdsa_sha1; } else if (conn->actual_protocol_version >= S2N_TLS12) { *sig_scheme_out = s2n_rsa_pkcs1_sha1; - } else if (s2n_is_in_fips_mode() && signer == S2N_SERVER) { - *sig_scheme_out = s2n_rsa_pkcs1_sha1; + } else { + *sig_scheme_out = s2n_rsa_pkcs1_md5_sha1; } return S2N_SUCCESS; diff --git a/contrib/restricted/aws/s2n/utils/s2n_fork_detection.c b/contrib/restricted/aws/s2n/utils/s2n_fork_detection.c index b148f4bbb3..d9826ad08d 100644 --- a/contrib/restricted/aws/s2n/utils/s2n_fork_detection.c +++ b/contrib/restricted/aws/s2n/utils/s2n_fork_detection.c @@ -20,6 +20,10 @@ typedef struct _opaque_pthread_once_t __darwin_pthread_once_t; typedef __darwin_pthread_once_t pthread_once_t; #define _DARWIN_C_SOURCE +#elif defined(__FreeBSD__) + /* FreeBSD requires POSIX compatibility off for its syscalls (enables __BSD_VISIBLE) + * Without the below line, <sys/mman.h> cannot be imported (it requires __BSD_VISIBLE) */ + #undef _POSIX_C_SOURCE #elif !defined(_GNU_SOURCE) /* Keep in sync with feature probe tests/features/madvise.c */ #define _GNU_SOURCE |