diff options
author | orivej <orivej@yandex-team.ru> | 2022-02-10 16:44:49 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:44:49 +0300 |
commit | 718c552901d703c502ccbefdfc3c9028d608b947 (patch) | |
tree | 46534a98bbefcd7b1f3faa5b52c138ab27db75b7 /contrib/restricted/aws/s2n/tls/extensions | |
parent | e9656aae26e0358d5378e5b63dcac5c8dbe0e4d0 (diff) | |
download | ydb-718c552901d703c502ccbefdfc3c9028d608b947.tar.gz |
Restoring authorship annotation for <orivej@yandex-team.ru>. Commit 1 of 2.
Diffstat (limited to 'contrib/restricted/aws/s2n/tls/extensions')
64 files changed, 4790 insertions, 4790 deletions
diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_alpn.c b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_alpn.c index e66b7c0478..7ad2946880 100644 --- a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_alpn.c +++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_alpn.c @@ -1,129 +1,129 @@ -/* - * 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 <sys/param.h> -#include <stdint.h> - -#include "tls/extensions/s2n_client_alpn.h" - -#include "tls/extensions/s2n_extension_type.h" -#include "tls/s2n_tls.h" -#include "tls/s2n_tls_parameters.h" - -#include "utils/s2n_safety.h" - -static bool s2n_client_alpn_should_send(struct s2n_connection *conn); -static int s2n_client_alpn_send(struct s2n_connection *conn, struct s2n_stuffer *out); -static int s2n_client_alpn_recv(struct s2n_connection *conn, struct s2n_stuffer *extension); - -const s2n_extension_type s2n_client_alpn_extension = { - .iana_value = TLS_EXTENSION_ALPN, - .is_response = false, - .send = s2n_client_alpn_send, - .recv = s2n_client_alpn_recv, - .should_send = s2n_client_alpn_should_send, - .if_missing = s2n_extension_noop_if_missing, -}; - -static bool s2n_client_alpn_should_send(struct s2n_connection *conn) -{ - struct s2n_blob *client_app_protocols; - - return s2n_connection_get_protocol_preferences(conn, &client_app_protocols) == S2N_SUCCESS - && client_app_protocols->size != 0 && client_app_protocols->data != NULL; -} - -static int s2n_client_alpn_send(struct s2n_connection *conn, struct s2n_stuffer *out) -{ - struct s2n_blob *client_app_protocols; - GUARD(s2n_connection_get_protocol_preferences(conn, &client_app_protocols)); - notnull_check(client_app_protocols); - - GUARD(s2n_stuffer_write_uint16(out, client_app_protocols->size)); - GUARD(s2n_stuffer_write(out, client_app_protocols)); - - return S2N_SUCCESS; -} - -static int s2n_client_alpn_recv(struct s2n_connection *conn, struct s2n_stuffer *extension) -{ - uint16_t size_of_all; - struct s2n_stuffer client_protos = {0}; - struct s2n_stuffer server_protos = {0}; - - struct s2n_blob *server_app_protocols; - GUARD(s2n_connection_get_protocol_preferences(conn, &server_app_protocols)); - - if (!server_app_protocols->size) { - /* No protocols configured, nothing to do */ - return S2N_SUCCESS; - } - - GUARD(s2n_stuffer_read_uint16(extension, &size_of_all)); - if (size_of_all > s2n_stuffer_data_available(extension) || size_of_all < 3) { - /* Malformed length, ignore the extension */ - return S2N_SUCCESS; - } - - struct s2n_blob client_app_protocols = { 0 }; - client_app_protocols.size = size_of_all; - client_app_protocols.data = s2n_stuffer_raw_read(extension, size_of_all); - notnull_check(client_app_protocols.data); - - /* Find a matching protocol */ - GUARD(s2n_stuffer_init(&client_protos, &client_app_protocols)); - GUARD(s2n_stuffer_write(&client_protos, &client_app_protocols)); - GUARD(s2n_stuffer_init(&server_protos, server_app_protocols)); - GUARD(s2n_stuffer_write(&server_protos, server_app_protocols)); - - while (s2n_stuffer_data_available(&server_protos)) { - uint8_t length; - uint8_t server_protocol[255]; - GUARD(s2n_stuffer_read_uint8(&server_protos, &length)); - GUARD(s2n_stuffer_read_bytes(&server_protos, server_protocol, length)); - - while (s2n_stuffer_data_available(&client_protos)) { - uint8_t client_length; - GUARD(s2n_stuffer_read_uint8(&client_protos, &client_length)); - S2N_ERROR_IF(client_length > s2n_stuffer_data_available(&client_protos), S2N_ERR_BAD_MESSAGE); - if (client_length != length) { - GUARD(s2n_stuffer_skip_read(&client_protos, client_length)); - } else { - uint8_t client_protocol[255]; - GUARD(s2n_stuffer_read_bytes(&client_protos, client_protocol, client_length)); - if (memcmp(client_protocol, server_protocol, client_length) == 0) { - memcpy_check(conn->application_protocol, client_protocol, client_length); - conn->application_protocol[client_length] = '\0'; - return S2N_SUCCESS; - } - } - } - - GUARD(s2n_stuffer_reread(&client_protos)); - } - return S2N_SUCCESS; -} - -/* Old-style extension functions -- remove after extensions refactor is complete */ - -int s2n_extensions_client_alpn_send(struct s2n_connection *conn, struct s2n_stuffer *out) -{ - return s2n_extension_send(&s2n_client_alpn_extension, conn, out); -} - -int s2n_recv_client_alpn(struct s2n_connection *conn, struct s2n_stuffer *extension) -{ - return s2n_extension_recv(&s2n_client_alpn_extension, conn, extension); -} +/* + * 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 <sys/param.h> +#include <stdint.h> + +#include "tls/extensions/s2n_client_alpn.h" + +#include "tls/extensions/s2n_extension_type.h" +#include "tls/s2n_tls.h" +#include "tls/s2n_tls_parameters.h" + +#include "utils/s2n_safety.h" + +static bool s2n_client_alpn_should_send(struct s2n_connection *conn); +static int s2n_client_alpn_send(struct s2n_connection *conn, struct s2n_stuffer *out); +static int s2n_client_alpn_recv(struct s2n_connection *conn, struct s2n_stuffer *extension); + +const s2n_extension_type s2n_client_alpn_extension = { + .iana_value = TLS_EXTENSION_ALPN, + .is_response = false, + .send = s2n_client_alpn_send, + .recv = s2n_client_alpn_recv, + .should_send = s2n_client_alpn_should_send, + .if_missing = s2n_extension_noop_if_missing, +}; + +static bool s2n_client_alpn_should_send(struct s2n_connection *conn) +{ + struct s2n_blob *client_app_protocols; + + return s2n_connection_get_protocol_preferences(conn, &client_app_protocols) == S2N_SUCCESS + && client_app_protocols->size != 0 && client_app_protocols->data != NULL; +} + +static int s2n_client_alpn_send(struct s2n_connection *conn, struct s2n_stuffer *out) +{ + struct s2n_blob *client_app_protocols; + GUARD(s2n_connection_get_protocol_preferences(conn, &client_app_protocols)); + notnull_check(client_app_protocols); + + GUARD(s2n_stuffer_write_uint16(out, client_app_protocols->size)); + GUARD(s2n_stuffer_write(out, client_app_protocols)); + + return S2N_SUCCESS; +} + +static int s2n_client_alpn_recv(struct s2n_connection *conn, struct s2n_stuffer *extension) +{ + uint16_t size_of_all; + struct s2n_stuffer client_protos = {0}; + struct s2n_stuffer server_protos = {0}; + + struct s2n_blob *server_app_protocols; + GUARD(s2n_connection_get_protocol_preferences(conn, &server_app_protocols)); + + if (!server_app_protocols->size) { + /* No protocols configured, nothing to do */ + return S2N_SUCCESS; + } + + GUARD(s2n_stuffer_read_uint16(extension, &size_of_all)); + if (size_of_all > s2n_stuffer_data_available(extension) || size_of_all < 3) { + /* Malformed length, ignore the extension */ + return S2N_SUCCESS; + } + + struct s2n_blob client_app_protocols = { 0 }; + client_app_protocols.size = size_of_all; + client_app_protocols.data = s2n_stuffer_raw_read(extension, size_of_all); + notnull_check(client_app_protocols.data); + + /* Find a matching protocol */ + GUARD(s2n_stuffer_init(&client_protos, &client_app_protocols)); + GUARD(s2n_stuffer_write(&client_protos, &client_app_protocols)); + GUARD(s2n_stuffer_init(&server_protos, server_app_protocols)); + GUARD(s2n_stuffer_write(&server_protos, server_app_protocols)); + + while (s2n_stuffer_data_available(&server_protos)) { + uint8_t length; + uint8_t server_protocol[255]; + GUARD(s2n_stuffer_read_uint8(&server_protos, &length)); + GUARD(s2n_stuffer_read_bytes(&server_protos, server_protocol, length)); + + while (s2n_stuffer_data_available(&client_protos)) { + uint8_t client_length; + GUARD(s2n_stuffer_read_uint8(&client_protos, &client_length)); + S2N_ERROR_IF(client_length > s2n_stuffer_data_available(&client_protos), S2N_ERR_BAD_MESSAGE); + if (client_length != length) { + GUARD(s2n_stuffer_skip_read(&client_protos, client_length)); + } else { + uint8_t client_protocol[255]; + GUARD(s2n_stuffer_read_bytes(&client_protos, client_protocol, client_length)); + if (memcmp(client_protocol, server_protocol, client_length) == 0) { + memcpy_check(conn->application_protocol, client_protocol, client_length); + conn->application_protocol[client_length] = '\0'; + return S2N_SUCCESS; + } + } + } + + GUARD(s2n_stuffer_reread(&client_protos)); + } + return S2N_SUCCESS; +} + +/* Old-style extension functions -- remove after extensions refactor is complete */ + +int s2n_extensions_client_alpn_send(struct s2n_connection *conn, struct s2n_stuffer *out) +{ + return s2n_extension_send(&s2n_client_alpn_extension, conn, out); +} + +int s2n_recv_client_alpn(struct s2n_connection *conn, struct s2n_stuffer *extension) +{ + return s2n_extension_recv(&s2n_client_alpn_extension, conn, extension); +} diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_alpn.h b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_alpn.h index 177ca5daea..d25bbb027b 100644 --- a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_alpn.h +++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_alpn.h @@ -1,27 +1,27 @@ -/* - * 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. - */ - -#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_alpn_extension; - -/* Old-style extension functions -- remove after extensions refactor is complete */ - -extern int s2n_extensions_client_alpn_send(struct s2n_connection *conn, struct s2n_stuffer *out); -extern int s2n_recv_client_alpn(struct s2n_connection *conn, struct s2n_stuffer *extension); +/* + * 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. + */ + +#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_alpn_extension; + +/* Old-style extension functions -- remove after extensions refactor is complete */ + +extern int s2n_extensions_client_alpn_send(struct s2n_connection *conn, struct s2n_stuffer *out); +extern int s2n_recv_client_alpn(struct s2n_connection *conn, struct s2n_stuffer *extension); diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_key_share.c b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_key_share.c index 97797cc054..1e3ea069f2 100644 --- a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_key_share.c +++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_key_share.c @@ -1,521 +1,521 @@ -/* - * 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_client_key_share.h" -#include "tls/extensions/s2n_key_share.h" -#include "tls/s2n_security_policies.h" -#include "tls/s2n_kem_preferences.h" - -#include "error/s2n_errno.h" -#include "stuffer/s2n_stuffer.h" -#include "utils/s2n_safety.h" -#include "tls/s2n_tls13.h" -#include "crypto/s2n_fips.h" - -#define S2N_IS_KEY_SHARE_LIST_EMPTY(preferred_key_shares) (preferred_key_shares & 1) -#define S2N_IS_KEY_SHARE_REQUESTED(preferred_key_shares, i) ((preferred_key_shares >> (i + 1)) & 1) -/** - * Specified in https://tools.ietf.org/html/rfc8446#section-4.2.8 - * "The "key_share" extension contains the endpoint's cryptographic parameters." - * - * Structure: - * Extension type (2 bytes) - * Extension data size (2 bytes) - * Client shares size (2 bytes) - * Client shares: - * Named group (2 bytes) - * Key share size (2 bytes) - * Key share (variable size) - * - * This extension only modifies the connection's client ecc_evp_params. It does - * not make any decisions about which set of params to use. - * - * The server will NOT alert when processing a client extension that violates the RFC. - * So the server will accept: - * - Multiple key shares for the same named group. The server will accept the first - * key share for the group and ignore any duplicates. - * - Key shares for named groups not in the client's supported_groups extension. - **/ - -static int s2n_client_key_share_send(struct s2n_connection *conn, struct s2n_stuffer *out); -static int s2n_client_key_share_recv(struct s2n_connection *conn, struct s2n_stuffer *extension); - -const s2n_extension_type s2n_client_key_share_extension = { - .iana_value = TLS_EXTENSION_KEY_SHARE, - .is_response = false, - .send = s2n_client_key_share_send, - .recv = s2n_client_key_share_recv, - .should_send = s2n_extension_send_if_tls13_connection, - .if_missing = s2n_extension_noop_if_missing, -}; - -static int s2n_generate_preferred_ecc_key_shares(struct s2n_connection *conn, struct s2n_stuffer *out) -{ - notnull_check(conn); - uint8_t preferred_key_shares = conn->preferred_key_shares; - struct s2n_ecc_evp_params *ecc_evp_params = NULL; - - const struct s2n_ecc_preferences *ecc_pref = NULL; - GUARD(s2n_connection_get_ecc_preferences(conn, &ecc_pref)); - notnull_check(ecc_pref); - - /* If lsb is set, skip keyshare generation for all curve */ - if (S2N_IS_KEY_SHARE_LIST_EMPTY(preferred_key_shares)) { - return S2N_SUCCESS; - } - - for (size_t i = 0; i < ecc_pref->count; i++) { - /* If a bit in the bitmap (minus the lsb) is set, generate keyshare for the corresponding curve */ - if (S2N_IS_KEY_SHARE_REQUESTED(preferred_key_shares, i)) { - ecc_evp_params = &conn->secure.client_ecc_evp_params[i]; - ecc_evp_params->negotiated_curve = ecc_pref->ecc_curves[i]; - GUARD(s2n_ecdhe_parameters_send(ecc_evp_params, out)); - } - } - - return S2N_SUCCESS; -} - -static int s2n_generate_default_ecc_key_share(struct s2n_connection *conn, struct s2n_stuffer *out) -{ - notnull_check(conn); - const struct s2n_ecc_preferences *ecc_pref = NULL; - GUARD(s2n_connection_get_ecc_preferences(conn, &ecc_pref)); - notnull_check(ecc_pref); - - struct s2n_ecc_evp_params *ecc_evp_params = NULL; - ecc_evp_params = &conn->secure.client_ecc_evp_params[0]; - ecc_evp_params->negotiated_curve = ecc_pref->ecc_curves[0]; - GUARD(s2n_ecdhe_parameters_send(ecc_evp_params, out)); - - return S2N_SUCCESS; -} - -static int s2n_generate_pq_hybrid_key_share(struct s2n_stuffer *out, struct s2n_kem_group_params *kem_group_params) { - notnull_check(out); - notnull_check(kem_group_params); - - /* This function should never be called when in FIPS mode */ - ENSURE_POSIX(s2n_is_in_fips_mode() == false, S2N_ERR_PQ_KEMS_DISALLOWED_IN_FIPS); - - const struct s2n_kem_group *kem_group = kem_group_params->kem_group; - notnull_check(kem_group); - - /* The structure of the PQ share is: - * IANA ID (2 bytes) - * || total share size (2 bytes) - * || size of ECC key share (2 bytes) - * || ECC key share (variable bytes) - * || size of PQ key share (2 bytes) - * || PQ key share (variable bytes) */ - GUARD(s2n_stuffer_write_uint16(out, kem_group->iana_id)); - - struct s2n_stuffer_reservation total_share_size = {0}; - GUARD(s2n_stuffer_reserve_uint16(out, &total_share_size)); - - struct s2n_ecc_evp_params *ecc_params = &kem_group_params->ecc_params; - ecc_params->negotiated_curve = kem_group->curve; - GUARD(s2n_stuffer_write_uint16(out, ecc_params->negotiated_curve->share_size)); - GUARD(s2n_ecc_evp_generate_ephemeral_key(ecc_params)); - GUARD(s2n_ecc_evp_write_params_point(ecc_params, out)); - - struct s2n_kem_params *kem_params = &kem_group_params->kem_params; - kem_params->kem = kem_group->kem; - GUARD(s2n_kem_send_public_key(out, kem_params)); - - GUARD(s2n_stuffer_write_vector_size(&total_share_size)); - - return S2N_SUCCESS; -} - -static int s2n_generate_default_pq_hybrid_key_share(struct s2n_connection *conn, struct s2n_stuffer *out) { - notnull_check(conn); - notnull_check(out); - - /* Client should skip sending PQ groups/key shares if in FIPS mode */ - if (s2n_is_in_fips_mode()) { - return S2N_SUCCESS; - } - - const struct s2n_kem_preferences *kem_pref = NULL; - GUARD(s2n_connection_get_kem_preferences(conn, &kem_pref)); - notnull_check(kem_pref); - - if (kem_pref->tls13_kem_group_count == 0) { - return S2N_SUCCESS; - } - - /* We only send a single PQ key share - the highest preferred one */ - struct s2n_kem_group_params *kem_group_params = &conn->secure.client_kem_group_params[0]; - kem_group_params->kem_group = kem_pref->tls13_kem_groups[0]; - - GUARD(s2n_generate_pq_hybrid_key_share(out, kem_group_params)); - - return S2N_SUCCESS; -} - -static int s2n_wipe_all_client_keyshares(struct s2n_connection *conn) { - notnull_check(conn); - - const struct s2n_ecc_preferences *ecc_pref = NULL; - GUARD(s2n_connection_get_ecc_preferences(conn, &ecc_pref)); - notnull_check(ecc_pref); - - const struct s2n_kem_preferences *kem_pref = NULL; - GUARD(s2n_connection_get_kem_preferences(conn, &kem_pref)); - notnull_check(kem_pref); - - for (size_t i = 0; i < ecc_pref->count; i++) { - GUARD(s2n_ecc_evp_params_free(&conn->secure.client_ecc_evp_params[i])); - conn->secure.client_ecc_evp_params[i].negotiated_curve = NULL; - } - - for (size_t i = 0; i < kem_pref->tls13_kem_group_count; i++) { - GUARD(s2n_kem_group_free(&conn->secure.client_kem_group_params[i])); - conn->secure.client_kem_group_params[i].kem_group = NULL; - conn->secure.client_kem_group_params[i].kem_params.kem = NULL; - conn->secure.client_kem_group_params[i].ecc_params.negotiated_curve = NULL; - } - - return S2N_SUCCESS; -} - -static int s2n_send_hrr_ecc_keyshare(struct s2n_connection *conn, struct s2n_stuffer *out) -{ - notnull_check(conn); - const struct s2n_ecc_named_curve *server_negotiated_curve = NULL; - struct s2n_ecc_evp_params *ecc_evp_params = NULL; - - const struct s2n_ecc_preferences *ecc_pref = NULL; - GUARD(s2n_connection_get_ecc_preferences(conn, &ecc_pref)); - notnull_check(ecc_pref); - - server_negotiated_curve = conn->secure.server_ecc_evp_params.negotiated_curve; - ENSURE_POSIX(server_negotiated_curve != NULL, S2N_ERR_BAD_KEY_SHARE); - ENSURE_POSIX(s2n_ecc_preferences_includes_curve(ecc_pref, server_negotiated_curve->iana_id), - S2N_ERR_INVALID_HELLO_RETRY); - - for (size_t i = 0; i < ecc_pref->count; i++) { - if (ecc_pref->ecc_curves[i]->iana_id == server_negotiated_curve->iana_id) { - ecc_evp_params = &conn->secure.client_ecc_evp_params[i]; - ENSURE_POSIX(ecc_evp_params->evp_pkey == NULL, S2N_ERR_INVALID_HELLO_RETRY); - } - } - - /* None of the previously generated keyshares were selected for negotiation, so wipe them */ - GUARD(s2n_wipe_all_client_keyshares(conn)); - /* Generate the keyshare for the server negotiated curve */ - ecc_evp_params->negotiated_curve = server_negotiated_curve; - GUARD(s2n_ecdhe_parameters_send(ecc_evp_params, out)); - - return S2N_SUCCESS; -} - -static int s2n_send_hrr_pq_hybrid_keyshare(struct s2n_connection *conn, struct s2n_stuffer *out) { - notnull_check(conn); - notnull_check(out); - - /* If in FIPS mode, the client should not have sent any PQ IDs - * in the supported_groups list of the initial ClientHello */ - ENSURE_POSIX(s2n_is_in_fips_mode() == false, S2N_ERR_PQ_KEMS_DISALLOWED_IN_FIPS); - - const struct s2n_kem_preferences *kem_pref = NULL; - GUARD(s2n_connection_get_kem_preferences(conn, &kem_pref)); - notnull_check(kem_pref); - - const struct s2n_kem_group *server_negotiated_kem_group = conn->secure.server_kem_group_params.kem_group; - ENSURE_POSIX(server_negotiated_kem_group != NULL, S2N_ERR_INVALID_HELLO_RETRY); - ENSURE_POSIX(s2n_kem_preferences_includes_tls13_kem_group(kem_pref, server_negotiated_kem_group->iana_id), - S2N_ERR_INVALID_HELLO_RETRY); - struct s2n_kem_group_params *kem_group_params = NULL; - - for (size_t i = 0; i < kem_pref->tls13_kem_group_count; i++) { - if (kem_pref->tls13_kem_groups[i]->iana_id == server_negotiated_kem_group->iana_id) { - kem_group_params = &conn->secure.client_kem_group_params[i]; - ENSURE_POSIX(kem_group_params->kem_group == NULL, S2N_ERR_INVALID_HELLO_RETRY); - ENSURE_POSIX(kem_group_params->ecc_params.evp_pkey == NULL, S2N_ERR_INVALID_HELLO_RETRY); - ENSURE_POSIX(kem_group_params->kem_params.private_key.data == NULL, S2N_ERR_INVALID_HELLO_RETRY); - } - } - - /* None of the previously generated keyshares were selected for negotiation, so wipe them */ - GUARD(s2n_wipe_all_client_keyshares(conn)); - /* Generate the keyshare for the server negotiated KEM group */ - kem_group_params->kem_group = server_negotiated_kem_group; - GUARD(s2n_generate_pq_hybrid_key_share(out, kem_group_params)); - - return S2N_SUCCESS; -} - -/* From https://tools.ietf.org/html/rfc8446#section-4.1.2 - * If a "key_share" extension was supplied in the HelloRetryRequest, - * replace the list of shares with a list containing a single - * KeyShareEntry from the indicated group.*/ -static int s2n_send_hrr_keyshare(struct s2n_connection *conn, struct s2n_stuffer *out) { - notnull_check(conn); - notnull_check(out); - - if (conn->secure.server_kem_group_params.kem_group != NULL) { - GUARD(s2n_send_hrr_pq_hybrid_keyshare(conn, out)); - } else { - GUARD(s2n_send_hrr_ecc_keyshare(conn, out)); - } - - return S2N_SUCCESS; -} - -static int s2n_ecdhe_supported_curves_send(struct s2n_connection *conn, struct s2n_stuffer *out) -{ - if (!conn->preferred_key_shares) { - GUARD(s2n_generate_default_ecc_key_share(conn, out)); - return S2N_SUCCESS; - } - - GUARD(s2n_generate_preferred_ecc_key_shares(conn, out)); - return S2N_SUCCESS; -} - -static int s2n_client_key_share_send(struct s2n_connection *conn, struct s2n_stuffer *out) -{ - struct s2n_stuffer_reservation shares_size = {0}; - GUARD(s2n_stuffer_reserve_uint16(out, &shares_size)); - - if (s2n_is_hello_retry_handshake(conn)) { - GUARD(s2n_send_hrr_keyshare(conn, out)); - } else { - GUARD(s2n_generate_default_pq_hybrid_key_share(conn, out)); - GUARD(s2n_ecdhe_supported_curves_send(conn, out)); - } - - GUARD(s2n_stuffer_write_vector_size(&shares_size)); - - return S2N_SUCCESS; -} - -static int s2n_client_key_share_parse_ecc(struct s2n_stuffer *key_share, const struct s2n_ecc_named_curve *curve, - struct s2n_ecc_evp_params *ecc_params) { - notnull_check(key_share); - notnull_check(curve); - notnull_check(ecc_params); - - struct s2n_blob point_blob = { 0 }; - GUARD(s2n_ecc_evp_read_params_point(key_share, curve->share_size, &point_blob)); - - /* Ignore curves with points we can't parse */ - ecc_params->negotiated_curve = curve; - if (s2n_ecc_evp_parse_params_point(&point_blob, ecc_params) != S2N_SUCCESS) { - ecc_params->negotiated_curve = NULL; - GUARD(s2n_ecc_evp_params_free(ecc_params)); - } - - return S2N_SUCCESS; -} - -static int s2n_client_key_share_recv_ecc(struct s2n_connection *conn, struct s2n_stuffer *key_share, - uint16_t curve_iana_id, bool *match) { - notnull_check(conn); - notnull_check(key_share); - notnull_check(match); - - const struct s2n_ecc_preferences *ecc_pref = NULL; - GUARD(s2n_connection_get_ecc_preferences(conn, &ecc_pref)); - notnull_check(ecc_pref); - - const struct s2n_ecc_named_curve *curve = NULL; - struct s2n_ecc_evp_params *client_ecc_params = NULL; - for (size_t i = 0; i < ecc_pref->count; i++) { - if (curve_iana_id == ecc_pref->ecc_curves[i]->iana_id) { - curve = ecc_pref->ecc_curves[i]; - client_ecc_params = &conn->secure.client_ecc_evp_params[i]; - break; - } - } - - /* Ignore unsupported curves */ - if (!curve || !client_ecc_params) { - return S2N_SUCCESS; - } - - /* Ignore curves that we've already received material for */ - if (client_ecc_params->negotiated_curve) { - return S2N_SUCCESS; - } - - /* Ignore curves with unexpected share sizes */ - if (key_share->blob.size != curve->share_size) { - return S2N_SUCCESS; - } - - GUARD(s2n_client_key_share_parse_ecc(key_share, curve, client_ecc_params)); - /* negotiated_curve will be non-NULL if the key share was parsed successfully */ - if (client_ecc_params->negotiated_curve) { - *match = true; - } - - return S2N_SUCCESS; -} - -static int s2n_client_key_share_recv_pq_hybrid(struct s2n_connection *conn, struct s2n_stuffer *key_share, - uint16_t kem_group_iana_id, bool *match) { - notnull_check(conn); - notnull_check(key_share); - notnull_check(match); - - const struct s2n_kem_preferences *kem_pref = NULL; - GUARD(s2n_connection_get_kem_preferences(conn, &kem_pref)); - notnull_check(kem_pref); - - ENSURE_POSIX(s2n_is_in_fips_mode() == false, S2N_ERR_PQ_KEMS_DISALLOWED_IN_FIPS); - - const struct s2n_kem_group *kem_group = NULL; - struct s2n_kem_group_params *client_kem_group_params = NULL; - for (size_t i = 0; i < kem_pref->tls13_kem_group_count; i++) { - if (kem_group_iana_id == kem_pref->tls13_kem_groups[i]->iana_id) { - kem_group = kem_pref->tls13_kem_groups[i]; - client_kem_group_params = &conn->secure.client_kem_group_params[i]; - break; - } - } - - /* Ignore unsupported KEM groups */ - if (!kem_group || !client_kem_group_params) { - return S2N_SUCCESS; - } - - /* Ignore KEM groups that we've already received material for */ - if (client_kem_group_params->kem_group) { - return S2N_SUCCESS; - } - - /* Ignore KEM groups with unexpected overall total share sizes */ - if (key_share->blob.size != kem_group->client_share_size) { - return S2N_SUCCESS; - } - - uint16_t ec_share_size = 0; - GUARD(s2n_stuffer_read_uint16(key_share, &ec_share_size)); - /* Ignore KEM groups with unexpected ECC share sizes */ - if (ec_share_size != kem_group->curve->share_size) { - return S2N_SUCCESS; - } - - GUARD(s2n_client_key_share_parse_ecc(key_share, kem_group->curve, &client_kem_group_params->ecc_params)); - /* If we were unable to parse the EC portion of the share, negotiated_curve - * will be NULL, and we should ignore the entire key share. */ - if (!client_kem_group_params->ecc_params.negotiated_curve) { - return S2N_SUCCESS; - } - - /* Note: the PQ share size is validated in s2n_kem_recv_public_key() */ - /* Ignore groups with PQ public keys we can't parse */ - client_kem_group_params->kem_params.kem = kem_group->kem; - if (s2n_kem_recv_public_key(key_share, &client_kem_group_params->kem_params) != S2N_SUCCESS) { - client_kem_group_params->kem_group = NULL; - client_kem_group_params->kem_params.kem = NULL; - client_kem_group_params->ecc_params.negotiated_curve = NULL; - /* s2n_kem_group_free() will free both the ECC and KEM params */ - GUARD(s2n_kem_group_free(client_kem_group_params)); - return S2N_SUCCESS; - } - - client_kem_group_params->kem_group = kem_group; - *match = true; - return S2N_SUCCESS; -} - -static int s2n_client_key_share_recv(struct s2n_connection *conn, struct s2n_stuffer *extension) { - notnull_check(conn); - notnull_check(extension); - - if (s2n_connection_get_protocol_version(conn) < S2N_TLS13) { - return S2N_SUCCESS; - } - - const struct s2n_ecc_preferences *ecc_pref = NULL; - GUARD(s2n_connection_get_ecc_preferences(conn, &ecc_pref)); - notnull_check(ecc_pref); - - const struct s2n_kem_preferences *kem_pref = NULL; - GUARD(s2n_connection_get_kem_preferences(conn, &kem_pref)); - notnull_check(kem_pref); - - uint16_t key_shares_size; - GUARD(s2n_stuffer_read_uint16(extension, &key_shares_size)); - ENSURE_POSIX(s2n_stuffer_data_available(extension) >= key_shares_size, S2N_ERR_BAD_MESSAGE); - - uint16_t named_group, share_size; - bool match_found = false; - /* bytes_processed is declared as a uint32_t to avoid integer overflow in later calculations */ - uint32_t bytes_processed = 0; - - while (bytes_processed < key_shares_size) { - GUARD(s2n_stuffer_read_uint16(extension, &named_group)); - GUARD(s2n_stuffer_read_uint16(extension, &share_size)); - - ENSURE_POSIX(s2n_stuffer_data_available(extension) >= share_size, S2N_ERR_BAD_MESSAGE); - bytes_processed += share_size + S2N_SIZE_OF_NAMED_GROUP + S2N_SIZE_OF_KEY_SHARE_SIZE; - - struct s2n_blob key_share_blob = { .size = share_size, .data = s2n_stuffer_raw_read(extension, share_size) }; - notnull_check(key_share_blob.data); - struct s2n_stuffer key_share = { 0 }; - GUARD(s2n_stuffer_init(&key_share, &key_share_blob)); - GUARD(s2n_stuffer_skip_write(&key_share, share_size)); - - /* Try to parse the share as ECC, then as PQ/hybrid; will ignore - * shares for unrecognized groups. */ - GUARD(s2n_client_key_share_recv_ecc(conn, &key_share, named_group, &match_found)); - if (!s2n_is_in_fips_mode()) { - GUARD(s2n_client_key_share_recv_pq_hybrid(conn, &key_share, named_group, &match_found)); - } - } - - /* If there were no matching key shares, then we received an empty key share extension - * or we didn't match a key share with a supported group. We should send a retry. */ - if (!match_found) { - GUARD(s2n_set_hello_retry_required(conn)); - } - - return S2N_SUCCESS; -} - -/* Old-style extension functions -- remove after extensions refactor is complete */ - -uint32_t s2n_extensions_client_key_share_size(struct s2n_connection *conn) -{ - notnull_check(conn); - - const struct s2n_ecc_preferences *ecc_pref = NULL; - GUARD(s2n_connection_get_ecc_preferences(conn, &ecc_pref)); - notnull_check(ecc_pref); - - uint32_t s2n_client_key_share_extension_size = S2N_SIZE_OF_EXTENSION_TYPE - + S2N_SIZE_OF_EXTENSION_DATA_SIZE - + S2N_SIZE_OF_CLIENT_SHARES_SIZE; - - s2n_client_key_share_extension_size += S2N_SIZE_OF_KEY_SHARE_SIZE + S2N_SIZE_OF_NAMED_GROUP; - s2n_client_key_share_extension_size += ecc_pref->ecc_curves[0]->share_size; - - return s2n_client_key_share_extension_size; -} - -int s2n_extensions_client_key_share_send(struct s2n_connection *conn, struct s2n_stuffer *out) -{ - return s2n_extension_send(&s2n_client_key_share_extension, conn, out); -} - -int s2n_extensions_client_key_share_recv(struct s2n_connection *conn, struct s2n_stuffer *extension) -{ - return s2n_extension_recv(&s2n_client_key_share_extension, conn, extension); -} +/* + * 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_client_key_share.h" +#include "tls/extensions/s2n_key_share.h" +#include "tls/s2n_security_policies.h" +#include "tls/s2n_kem_preferences.h" + +#include "error/s2n_errno.h" +#include "stuffer/s2n_stuffer.h" +#include "utils/s2n_safety.h" +#include "tls/s2n_tls13.h" +#include "crypto/s2n_fips.h" + +#define S2N_IS_KEY_SHARE_LIST_EMPTY(preferred_key_shares) (preferred_key_shares & 1) +#define S2N_IS_KEY_SHARE_REQUESTED(preferred_key_shares, i) ((preferred_key_shares >> (i + 1)) & 1) +/** + * Specified in https://tools.ietf.org/html/rfc8446#section-4.2.8 + * "The "key_share" extension contains the endpoint's cryptographic parameters." + * + * Structure: + * Extension type (2 bytes) + * Extension data size (2 bytes) + * Client shares size (2 bytes) + * Client shares: + * Named group (2 bytes) + * Key share size (2 bytes) + * Key share (variable size) + * + * This extension only modifies the connection's client ecc_evp_params. It does + * not make any decisions about which set of params to use. + * + * The server will NOT alert when processing a client extension that violates the RFC. + * So the server will accept: + * - Multiple key shares for the same named group. The server will accept the first + * key share for the group and ignore any duplicates. + * - Key shares for named groups not in the client's supported_groups extension. + **/ + +static int s2n_client_key_share_send(struct s2n_connection *conn, struct s2n_stuffer *out); +static int s2n_client_key_share_recv(struct s2n_connection *conn, struct s2n_stuffer *extension); + +const s2n_extension_type s2n_client_key_share_extension = { + .iana_value = TLS_EXTENSION_KEY_SHARE, + .is_response = false, + .send = s2n_client_key_share_send, + .recv = s2n_client_key_share_recv, + .should_send = s2n_extension_send_if_tls13_connection, + .if_missing = s2n_extension_noop_if_missing, +}; + +static int s2n_generate_preferred_ecc_key_shares(struct s2n_connection *conn, struct s2n_stuffer *out) +{ + notnull_check(conn); + uint8_t preferred_key_shares = conn->preferred_key_shares; + struct s2n_ecc_evp_params *ecc_evp_params = NULL; + + const struct s2n_ecc_preferences *ecc_pref = NULL; + GUARD(s2n_connection_get_ecc_preferences(conn, &ecc_pref)); + notnull_check(ecc_pref); + + /* If lsb is set, skip keyshare generation for all curve */ + if (S2N_IS_KEY_SHARE_LIST_EMPTY(preferred_key_shares)) { + return S2N_SUCCESS; + } + + for (size_t i = 0; i < ecc_pref->count; i++) { + /* If a bit in the bitmap (minus the lsb) is set, generate keyshare for the corresponding curve */ + if (S2N_IS_KEY_SHARE_REQUESTED(preferred_key_shares, i)) { + ecc_evp_params = &conn->secure.client_ecc_evp_params[i]; + ecc_evp_params->negotiated_curve = ecc_pref->ecc_curves[i]; + GUARD(s2n_ecdhe_parameters_send(ecc_evp_params, out)); + } + } + + return S2N_SUCCESS; +} + +static int s2n_generate_default_ecc_key_share(struct s2n_connection *conn, struct s2n_stuffer *out) +{ + notnull_check(conn); + const struct s2n_ecc_preferences *ecc_pref = NULL; + GUARD(s2n_connection_get_ecc_preferences(conn, &ecc_pref)); + notnull_check(ecc_pref); + + struct s2n_ecc_evp_params *ecc_evp_params = NULL; + ecc_evp_params = &conn->secure.client_ecc_evp_params[0]; + ecc_evp_params->negotiated_curve = ecc_pref->ecc_curves[0]; + GUARD(s2n_ecdhe_parameters_send(ecc_evp_params, out)); + + return S2N_SUCCESS; +} + +static int s2n_generate_pq_hybrid_key_share(struct s2n_stuffer *out, struct s2n_kem_group_params *kem_group_params) { + notnull_check(out); + notnull_check(kem_group_params); + + /* This function should never be called when in FIPS mode */ + ENSURE_POSIX(s2n_is_in_fips_mode() == false, S2N_ERR_PQ_KEMS_DISALLOWED_IN_FIPS); + + const struct s2n_kem_group *kem_group = kem_group_params->kem_group; + notnull_check(kem_group); + + /* The structure of the PQ share is: + * IANA ID (2 bytes) + * || total share size (2 bytes) + * || size of ECC key share (2 bytes) + * || ECC key share (variable bytes) + * || size of PQ key share (2 bytes) + * || PQ key share (variable bytes) */ + GUARD(s2n_stuffer_write_uint16(out, kem_group->iana_id)); + + struct s2n_stuffer_reservation total_share_size = {0}; + GUARD(s2n_stuffer_reserve_uint16(out, &total_share_size)); + + struct s2n_ecc_evp_params *ecc_params = &kem_group_params->ecc_params; + ecc_params->negotiated_curve = kem_group->curve; + GUARD(s2n_stuffer_write_uint16(out, ecc_params->negotiated_curve->share_size)); + GUARD(s2n_ecc_evp_generate_ephemeral_key(ecc_params)); + GUARD(s2n_ecc_evp_write_params_point(ecc_params, out)); + + struct s2n_kem_params *kem_params = &kem_group_params->kem_params; + kem_params->kem = kem_group->kem; + GUARD(s2n_kem_send_public_key(out, kem_params)); + + GUARD(s2n_stuffer_write_vector_size(&total_share_size)); + + return S2N_SUCCESS; +} + +static int s2n_generate_default_pq_hybrid_key_share(struct s2n_connection *conn, struct s2n_stuffer *out) { + notnull_check(conn); + notnull_check(out); + + /* Client should skip sending PQ groups/key shares if in FIPS mode */ + if (s2n_is_in_fips_mode()) { + return S2N_SUCCESS; + } + + const struct s2n_kem_preferences *kem_pref = NULL; + GUARD(s2n_connection_get_kem_preferences(conn, &kem_pref)); + notnull_check(kem_pref); + + if (kem_pref->tls13_kem_group_count == 0) { + return S2N_SUCCESS; + } + + /* We only send a single PQ key share - the highest preferred one */ + struct s2n_kem_group_params *kem_group_params = &conn->secure.client_kem_group_params[0]; + kem_group_params->kem_group = kem_pref->tls13_kem_groups[0]; + + GUARD(s2n_generate_pq_hybrid_key_share(out, kem_group_params)); + + return S2N_SUCCESS; +} + +static int s2n_wipe_all_client_keyshares(struct s2n_connection *conn) { + notnull_check(conn); + + const struct s2n_ecc_preferences *ecc_pref = NULL; + GUARD(s2n_connection_get_ecc_preferences(conn, &ecc_pref)); + notnull_check(ecc_pref); + + const struct s2n_kem_preferences *kem_pref = NULL; + GUARD(s2n_connection_get_kem_preferences(conn, &kem_pref)); + notnull_check(kem_pref); + + for (size_t i = 0; i < ecc_pref->count; i++) { + GUARD(s2n_ecc_evp_params_free(&conn->secure.client_ecc_evp_params[i])); + conn->secure.client_ecc_evp_params[i].negotiated_curve = NULL; + } + + for (size_t i = 0; i < kem_pref->tls13_kem_group_count; i++) { + GUARD(s2n_kem_group_free(&conn->secure.client_kem_group_params[i])); + conn->secure.client_kem_group_params[i].kem_group = NULL; + conn->secure.client_kem_group_params[i].kem_params.kem = NULL; + conn->secure.client_kem_group_params[i].ecc_params.negotiated_curve = NULL; + } + + return S2N_SUCCESS; +} + +static int s2n_send_hrr_ecc_keyshare(struct s2n_connection *conn, struct s2n_stuffer *out) +{ + notnull_check(conn); + const struct s2n_ecc_named_curve *server_negotiated_curve = NULL; + struct s2n_ecc_evp_params *ecc_evp_params = NULL; + + const struct s2n_ecc_preferences *ecc_pref = NULL; + GUARD(s2n_connection_get_ecc_preferences(conn, &ecc_pref)); + notnull_check(ecc_pref); + + server_negotiated_curve = conn->secure.server_ecc_evp_params.negotiated_curve; + ENSURE_POSIX(server_negotiated_curve != NULL, S2N_ERR_BAD_KEY_SHARE); + ENSURE_POSIX(s2n_ecc_preferences_includes_curve(ecc_pref, server_negotiated_curve->iana_id), + S2N_ERR_INVALID_HELLO_RETRY); + + for (size_t i = 0; i < ecc_pref->count; i++) { + if (ecc_pref->ecc_curves[i]->iana_id == server_negotiated_curve->iana_id) { + ecc_evp_params = &conn->secure.client_ecc_evp_params[i]; + ENSURE_POSIX(ecc_evp_params->evp_pkey == NULL, S2N_ERR_INVALID_HELLO_RETRY); + } + } + + /* None of the previously generated keyshares were selected for negotiation, so wipe them */ + GUARD(s2n_wipe_all_client_keyshares(conn)); + /* Generate the keyshare for the server negotiated curve */ + ecc_evp_params->negotiated_curve = server_negotiated_curve; + GUARD(s2n_ecdhe_parameters_send(ecc_evp_params, out)); + + return S2N_SUCCESS; +} + +static int s2n_send_hrr_pq_hybrid_keyshare(struct s2n_connection *conn, struct s2n_stuffer *out) { + notnull_check(conn); + notnull_check(out); + + /* If in FIPS mode, the client should not have sent any PQ IDs + * in the supported_groups list of the initial ClientHello */ + ENSURE_POSIX(s2n_is_in_fips_mode() == false, S2N_ERR_PQ_KEMS_DISALLOWED_IN_FIPS); + + const struct s2n_kem_preferences *kem_pref = NULL; + GUARD(s2n_connection_get_kem_preferences(conn, &kem_pref)); + notnull_check(kem_pref); + + const struct s2n_kem_group *server_negotiated_kem_group = conn->secure.server_kem_group_params.kem_group; + ENSURE_POSIX(server_negotiated_kem_group != NULL, S2N_ERR_INVALID_HELLO_RETRY); + ENSURE_POSIX(s2n_kem_preferences_includes_tls13_kem_group(kem_pref, server_negotiated_kem_group->iana_id), + S2N_ERR_INVALID_HELLO_RETRY); + struct s2n_kem_group_params *kem_group_params = NULL; + + for (size_t i = 0; i < kem_pref->tls13_kem_group_count; i++) { + if (kem_pref->tls13_kem_groups[i]->iana_id == server_negotiated_kem_group->iana_id) { + kem_group_params = &conn->secure.client_kem_group_params[i]; + ENSURE_POSIX(kem_group_params->kem_group == NULL, S2N_ERR_INVALID_HELLO_RETRY); + ENSURE_POSIX(kem_group_params->ecc_params.evp_pkey == NULL, S2N_ERR_INVALID_HELLO_RETRY); + ENSURE_POSIX(kem_group_params->kem_params.private_key.data == NULL, S2N_ERR_INVALID_HELLO_RETRY); + } + } + + /* None of the previously generated keyshares were selected for negotiation, so wipe them */ + GUARD(s2n_wipe_all_client_keyshares(conn)); + /* Generate the keyshare for the server negotiated KEM group */ + kem_group_params->kem_group = server_negotiated_kem_group; + GUARD(s2n_generate_pq_hybrid_key_share(out, kem_group_params)); + + return S2N_SUCCESS; +} + +/* From https://tools.ietf.org/html/rfc8446#section-4.1.2 + * If a "key_share" extension was supplied in the HelloRetryRequest, + * replace the list of shares with a list containing a single + * KeyShareEntry from the indicated group.*/ +static int s2n_send_hrr_keyshare(struct s2n_connection *conn, struct s2n_stuffer *out) { + notnull_check(conn); + notnull_check(out); + + if (conn->secure.server_kem_group_params.kem_group != NULL) { + GUARD(s2n_send_hrr_pq_hybrid_keyshare(conn, out)); + } else { + GUARD(s2n_send_hrr_ecc_keyshare(conn, out)); + } + + return S2N_SUCCESS; +} + +static int s2n_ecdhe_supported_curves_send(struct s2n_connection *conn, struct s2n_stuffer *out) +{ + if (!conn->preferred_key_shares) { + GUARD(s2n_generate_default_ecc_key_share(conn, out)); + return S2N_SUCCESS; + } + + GUARD(s2n_generate_preferred_ecc_key_shares(conn, out)); + return S2N_SUCCESS; +} + +static int s2n_client_key_share_send(struct s2n_connection *conn, struct s2n_stuffer *out) +{ + struct s2n_stuffer_reservation shares_size = {0}; + GUARD(s2n_stuffer_reserve_uint16(out, &shares_size)); + + if (s2n_is_hello_retry_handshake(conn)) { + GUARD(s2n_send_hrr_keyshare(conn, out)); + } else { + GUARD(s2n_generate_default_pq_hybrid_key_share(conn, out)); + GUARD(s2n_ecdhe_supported_curves_send(conn, out)); + } + + GUARD(s2n_stuffer_write_vector_size(&shares_size)); + + return S2N_SUCCESS; +} + +static int s2n_client_key_share_parse_ecc(struct s2n_stuffer *key_share, const struct s2n_ecc_named_curve *curve, + struct s2n_ecc_evp_params *ecc_params) { + notnull_check(key_share); + notnull_check(curve); + notnull_check(ecc_params); + + struct s2n_blob point_blob = { 0 }; + GUARD(s2n_ecc_evp_read_params_point(key_share, curve->share_size, &point_blob)); + + /* Ignore curves with points we can't parse */ + ecc_params->negotiated_curve = curve; + if (s2n_ecc_evp_parse_params_point(&point_blob, ecc_params) != S2N_SUCCESS) { + ecc_params->negotiated_curve = NULL; + GUARD(s2n_ecc_evp_params_free(ecc_params)); + } + + return S2N_SUCCESS; +} + +static int s2n_client_key_share_recv_ecc(struct s2n_connection *conn, struct s2n_stuffer *key_share, + uint16_t curve_iana_id, bool *match) { + notnull_check(conn); + notnull_check(key_share); + notnull_check(match); + + const struct s2n_ecc_preferences *ecc_pref = NULL; + GUARD(s2n_connection_get_ecc_preferences(conn, &ecc_pref)); + notnull_check(ecc_pref); + + const struct s2n_ecc_named_curve *curve = NULL; + struct s2n_ecc_evp_params *client_ecc_params = NULL; + for (size_t i = 0; i < ecc_pref->count; i++) { + if (curve_iana_id == ecc_pref->ecc_curves[i]->iana_id) { + curve = ecc_pref->ecc_curves[i]; + client_ecc_params = &conn->secure.client_ecc_evp_params[i]; + break; + } + } + + /* Ignore unsupported curves */ + if (!curve || !client_ecc_params) { + return S2N_SUCCESS; + } + + /* Ignore curves that we've already received material for */ + if (client_ecc_params->negotiated_curve) { + return S2N_SUCCESS; + } + + /* Ignore curves with unexpected share sizes */ + if (key_share->blob.size != curve->share_size) { + return S2N_SUCCESS; + } + + GUARD(s2n_client_key_share_parse_ecc(key_share, curve, client_ecc_params)); + /* negotiated_curve will be non-NULL if the key share was parsed successfully */ + if (client_ecc_params->negotiated_curve) { + *match = true; + } + + return S2N_SUCCESS; +} + +static int s2n_client_key_share_recv_pq_hybrid(struct s2n_connection *conn, struct s2n_stuffer *key_share, + uint16_t kem_group_iana_id, bool *match) { + notnull_check(conn); + notnull_check(key_share); + notnull_check(match); + + const struct s2n_kem_preferences *kem_pref = NULL; + GUARD(s2n_connection_get_kem_preferences(conn, &kem_pref)); + notnull_check(kem_pref); + + ENSURE_POSIX(s2n_is_in_fips_mode() == false, S2N_ERR_PQ_KEMS_DISALLOWED_IN_FIPS); + + const struct s2n_kem_group *kem_group = NULL; + struct s2n_kem_group_params *client_kem_group_params = NULL; + for (size_t i = 0; i < kem_pref->tls13_kem_group_count; i++) { + if (kem_group_iana_id == kem_pref->tls13_kem_groups[i]->iana_id) { + kem_group = kem_pref->tls13_kem_groups[i]; + client_kem_group_params = &conn->secure.client_kem_group_params[i]; + break; + } + } + + /* Ignore unsupported KEM groups */ + if (!kem_group || !client_kem_group_params) { + return S2N_SUCCESS; + } + + /* Ignore KEM groups that we've already received material for */ + if (client_kem_group_params->kem_group) { + return S2N_SUCCESS; + } + + /* Ignore KEM groups with unexpected overall total share sizes */ + if (key_share->blob.size != kem_group->client_share_size) { + return S2N_SUCCESS; + } + + uint16_t ec_share_size = 0; + GUARD(s2n_stuffer_read_uint16(key_share, &ec_share_size)); + /* Ignore KEM groups with unexpected ECC share sizes */ + if (ec_share_size != kem_group->curve->share_size) { + return S2N_SUCCESS; + } + + GUARD(s2n_client_key_share_parse_ecc(key_share, kem_group->curve, &client_kem_group_params->ecc_params)); + /* If we were unable to parse the EC portion of the share, negotiated_curve + * will be NULL, and we should ignore the entire key share. */ + if (!client_kem_group_params->ecc_params.negotiated_curve) { + return S2N_SUCCESS; + } + + /* Note: the PQ share size is validated in s2n_kem_recv_public_key() */ + /* Ignore groups with PQ public keys we can't parse */ + client_kem_group_params->kem_params.kem = kem_group->kem; + if (s2n_kem_recv_public_key(key_share, &client_kem_group_params->kem_params) != S2N_SUCCESS) { + client_kem_group_params->kem_group = NULL; + client_kem_group_params->kem_params.kem = NULL; + client_kem_group_params->ecc_params.negotiated_curve = NULL; + /* s2n_kem_group_free() will free both the ECC and KEM params */ + GUARD(s2n_kem_group_free(client_kem_group_params)); + return S2N_SUCCESS; + } + + client_kem_group_params->kem_group = kem_group; + *match = true; + return S2N_SUCCESS; +} + +static int s2n_client_key_share_recv(struct s2n_connection *conn, struct s2n_stuffer *extension) { + notnull_check(conn); + notnull_check(extension); + + if (s2n_connection_get_protocol_version(conn) < S2N_TLS13) { + return S2N_SUCCESS; + } + + const struct s2n_ecc_preferences *ecc_pref = NULL; + GUARD(s2n_connection_get_ecc_preferences(conn, &ecc_pref)); + notnull_check(ecc_pref); + + const struct s2n_kem_preferences *kem_pref = NULL; + GUARD(s2n_connection_get_kem_preferences(conn, &kem_pref)); + notnull_check(kem_pref); + + uint16_t key_shares_size; + GUARD(s2n_stuffer_read_uint16(extension, &key_shares_size)); + ENSURE_POSIX(s2n_stuffer_data_available(extension) >= key_shares_size, S2N_ERR_BAD_MESSAGE); + + uint16_t named_group, share_size; + bool match_found = false; + /* bytes_processed is declared as a uint32_t to avoid integer overflow in later calculations */ + uint32_t bytes_processed = 0; + + while (bytes_processed < key_shares_size) { + GUARD(s2n_stuffer_read_uint16(extension, &named_group)); + GUARD(s2n_stuffer_read_uint16(extension, &share_size)); + + ENSURE_POSIX(s2n_stuffer_data_available(extension) >= share_size, S2N_ERR_BAD_MESSAGE); + bytes_processed += share_size + S2N_SIZE_OF_NAMED_GROUP + S2N_SIZE_OF_KEY_SHARE_SIZE; + + struct s2n_blob key_share_blob = { .size = share_size, .data = s2n_stuffer_raw_read(extension, share_size) }; + notnull_check(key_share_blob.data); + struct s2n_stuffer key_share = { 0 }; + GUARD(s2n_stuffer_init(&key_share, &key_share_blob)); + GUARD(s2n_stuffer_skip_write(&key_share, share_size)); + + /* Try to parse the share as ECC, then as PQ/hybrid; will ignore + * shares for unrecognized groups. */ + GUARD(s2n_client_key_share_recv_ecc(conn, &key_share, named_group, &match_found)); + if (!s2n_is_in_fips_mode()) { + GUARD(s2n_client_key_share_recv_pq_hybrid(conn, &key_share, named_group, &match_found)); + } + } + + /* If there were no matching key shares, then we received an empty key share extension + * or we didn't match a key share with a supported group. We should send a retry. */ + if (!match_found) { + GUARD(s2n_set_hello_retry_required(conn)); + } + + return S2N_SUCCESS; +} + +/* Old-style extension functions -- remove after extensions refactor is complete */ + +uint32_t s2n_extensions_client_key_share_size(struct s2n_connection *conn) +{ + notnull_check(conn); + + const struct s2n_ecc_preferences *ecc_pref = NULL; + GUARD(s2n_connection_get_ecc_preferences(conn, &ecc_pref)); + notnull_check(ecc_pref); + + uint32_t s2n_client_key_share_extension_size = S2N_SIZE_OF_EXTENSION_TYPE + + S2N_SIZE_OF_EXTENSION_DATA_SIZE + + S2N_SIZE_OF_CLIENT_SHARES_SIZE; + + s2n_client_key_share_extension_size += S2N_SIZE_OF_KEY_SHARE_SIZE + S2N_SIZE_OF_NAMED_GROUP; + s2n_client_key_share_extension_size += ecc_pref->ecc_curves[0]->share_size; + + return s2n_client_key_share_extension_size; +} + +int s2n_extensions_client_key_share_send(struct s2n_connection *conn, struct s2n_stuffer *out) +{ + return s2n_extension_send(&s2n_client_key_share_extension, conn, out); +} + +int s2n_extensions_client_key_share_recv(struct s2n_connection *conn, struct s2n_stuffer *extension) +{ + return s2n_extension_recv(&s2n_client_key_share_extension, conn, extension); +} diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_key_share.h b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_key_share.h index 9977625680..365bc2ecf1 100644 --- a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_key_share.h +++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_key_share.h @@ -1,27 +1,27 @@ -/* - * 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. - */ - -#pragma once - -#include "tls/s2n_connection.h" -#include "stuffer/s2n_stuffer.h" - -extern const s2n_extension_type s2n_client_key_share_extension; - -/* Old-style extension functions -- remove after extensions refactor is complete */ -extern int s2n_extensions_client_key_share_recv(struct s2n_connection *conn, struct s2n_stuffer *extension); -extern uint32_t s2n_extensions_client_key_share_size(struct s2n_connection *conn); -extern int s2n_extensions_client_key_share_send(struct s2n_connection *conn, struct s2n_stuffer *out); - +/* + * 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. + */ + +#pragma once + +#include "tls/s2n_connection.h" +#include "stuffer/s2n_stuffer.h" + +extern const s2n_extension_type s2n_client_key_share_extension; + +/* Old-style extension functions -- remove after extensions refactor is complete */ +extern int s2n_extensions_client_key_share_recv(struct s2n_connection *conn, struct s2n_stuffer *extension); +extern uint32_t s2n_extensions_client_key_share_size(struct s2n_connection *conn); +extern int s2n_extensions_client_key_share_send(struct s2n_connection *conn, struct s2n_stuffer *out); + diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_max_frag_len.c b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_max_frag_len.c index 880193a1a1..6f419250db 100644 --- a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_max_frag_len.c +++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_max_frag_len.c @@ -1,75 +1,75 @@ -/* - * 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 <sys/param.h> -#include <stdint.h> - -#include "tls/extensions/s2n_client_max_frag_len.h" -#include "tls/s2n_tls.h" -#include "tls/s2n_tls_parameters.h" - -#include "utils/s2n_safety.h" - -static bool s2n_client_max_frag_len_should_send(struct s2n_connection *conn); -static int s2n_client_max_frag_len_send(struct s2n_connection *conn, struct s2n_stuffer *out); -static int s2n_client_max_frag_len_recv(struct s2n_connection *conn, struct s2n_stuffer *extension); - -const s2n_extension_type s2n_client_max_frag_len_extension = { - .iana_value = TLS_EXTENSION_MAX_FRAG_LEN, - .is_response = false, - .send = s2n_client_max_frag_len_send, - .recv = s2n_client_max_frag_len_recv, - .should_send = s2n_client_max_frag_len_should_send, - .if_missing = s2n_extension_noop_if_missing, -}; - -static bool s2n_client_max_frag_len_should_send(struct s2n_connection *conn) -{ - return conn->config->mfl_code != S2N_TLS_MAX_FRAG_LEN_EXT_NONE; -} - -static int s2n_client_max_frag_len_send(struct s2n_connection *conn, struct s2n_stuffer *out) -{ - return s2n_stuffer_write_uint8(out, conn->config->mfl_code); -} - -static int s2n_client_max_frag_len_recv(struct s2n_connection *conn, struct s2n_stuffer *extension) -{ - if (!conn->config->accept_mfl) { - return S2N_SUCCESS; - } - - uint8_t mfl_code; - GUARD(s2n_stuffer_read_uint8(extension, &mfl_code)); - if (mfl_code > S2N_TLS_MAX_FRAG_LEN_4096 || mfl_code_to_length[mfl_code] > S2N_TLS_MAXIMUM_FRAGMENT_LENGTH) { - return S2N_SUCCESS; - } - - conn->mfl_code = mfl_code; - conn->max_outgoing_fragment_length = mfl_code_to_length[mfl_code]; - return S2N_SUCCESS; -} - -/* Old-style extension functions -- remove after extensions refactor is complete */ - -int s2n_extensions_client_max_frag_len_send(struct s2n_connection *conn, struct s2n_stuffer *out) -{ - return s2n_extension_send(&s2n_client_max_frag_len_extension, conn, out); -} - -int s2n_recv_client_max_frag_len(struct s2n_connection *conn, struct s2n_stuffer *extension) -{ - return s2n_extension_recv(&s2n_client_max_frag_len_extension, conn, extension); -} +/* + * 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 <sys/param.h> +#include <stdint.h> + +#include "tls/extensions/s2n_client_max_frag_len.h" +#include "tls/s2n_tls.h" +#include "tls/s2n_tls_parameters.h" + +#include "utils/s2n_safety.h" + +static bool s2n_client_max_frag_len_should_send(struct s2n_connection *conn); +static int s2n_client_max_frag_len_send(struct s2n_connection *conn, struct s2n_stuffer *out); +static int s2n_client_max_frag_len_recv(struct s2n_connection *conn, struct s2n_stuffer *extension); + +const s2n_extension_type s2n_client_max_frag_len_extension = { + .iana_value = TLS_EXTENSION_MAX_FRAG_LEN, + .is_response = false, + .send = s2n_client_max_frag_len_send, + .recv = s2n_client_max_frag_len_recv, + .should_send = s2n_client_max_frag_len_should_send, + .if_missing = s2n_extension_noop_if_missing, +}; + +static bool s2n_client_max_frag_len_should_send(struct s2n_connection *conn) +{ + return conn->config->mfl_code != S2N_TLS_MAX_FRAG_LEN_EXT_NONE; +} + +static int s2n_client_max_frag_len_send(struct s2n_connection *conn, struct s2n_stuffer *out) +{ + return s2n_stuffer_write_uint8(out, conn->config->mfl_code); +} + +static int s2n_client_max_frag_len_recv(struct s2n_connection *conn, struct s2n_stuffer *extension) +{ + if (!conn->config->accept_mfl) { + return S2N_SUCCESS; + } + + uint8_t mfl_code; + GUARD(s2n_stuffer_read_uint8(extension, &mfl_code)); + if (mfl_code > S2N_TLS_MAX_FRAG_LEN_4096 || mfl_code_to_length[mfl_code] > S2N_TLS_MAXIMUM_FRAGMENT_LENGTH) { + return S2N_SUCCESS; + } + + conn->mfl_code = mfl_code; + conn->max_outgoing_fragment_length = mfl_code_to_length[mfl_code]; + return S2N_SUCCESS; +} + +/* Old-style extension functions -- remove after extensions refactor is complete */ + +int s2n_extensions_client_max_frag_len_send(struct s2n_connection *conn, struct s2n_stuffer *out) +{ + return s2n_extension_send(&s2n_client_max_frag_len_extension, conn, out); +} + +int s2n_recv_client_max_frag_len(struct s2n_connection *conn, struct s2n_stuffer *extension) +{ + return s2n_extension_recv(&s2n_client_max_frag_len_extension, conn, extension); +} diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_max_frag_len.h b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_max_frag_len.h index 49bb3be845..cb822a5410 100644 --- a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_max_frag_len.h +++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_max_frag_len.h @@ -1,26 +1,26 @@ -/* - * 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. - */ - -#pragma once - -#include "tls/s2n_connection.h" -#include "stuffer/s2n_stuffer.h" - -extern const s2n_extension_type s2n_client_max_frag_len_extension; - -/* Old-style extension functions -- remove after extensions refactor is complete */ - -extern int s2n_extensions_client_max_frag_len_send(struct s2n_connection *conn, struct s2n_stuffer *out); -extern int s2n_recv_client_max_frag_len(struct s2n_connection *conn, struct s2n_stuffer *extension); +/* + * 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. + */ + +#pragma once + +#include "tls/s2n_connection.h" +#include "stuffer/s2n_stuffer.h" + +extern const s2n_extension_type s2n_client_max_frag_len_extension; + +/* Old-style extension functions -- remove after extensions refactor is complete */ + +extern int s2n_extensions_client_max_frag_len_send(struct s2n_connection *conn, struct s2n_stuffer *out); +extern int s2n_recv_client_max_frag_len(struct s2n_connection *conn, struct s2n_stuffer *extension); diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_pq_kem.c b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_pq_kem.c index 450e293299..b553cdf6ca 100644 --- a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_pq_kem.c +++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_pq_kem.c @@ -1,89 +1,89 @@ -/* - * 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 <stdint.h> -#include <sys/param.h> - -#include "tls/extensions/s2n_client_pq_kem.h" -#include "tls/s2n_kem.h" -#include "tls/s2n_security_policies.h" -#include "tls/s2n_tls.h" -#include "tls/s2n_tls_parameters.h" - -#include "utils/s2n_safety.h" - -static bool s2n_client_pq_kem_should_send(struct s2n_connection *conn); -static int s2n_client_pq_kem_send(struct s2n_connection *conn, struct s2n_stuffer *out); -static int s2n_client_pq_kem_recv(struct s2n_connection *conn, struct s2n_stuffer *extension); - -const s2n_extension_type s2n_client_pq_kem_extension = { - .iana_value = TLS_EXTENSION_PQ_KEM_PARAMETERS, - .is_response = false, - .send = s2n_client_pq_kem_send, - .recv = s2n_client_pq_kem_recv, - .should_send = s2n_client_pq_kem_should_send, - .if_missing = s2n_extension_noop_if_missing, -}; - -static bool s2n_client_pq_kem_should_send(struct s2n_connection *conn) -{ - const struct s2n_security_policy *security_policy; - return s2n_connection_get_security_policy(conn, &security_policy) == S2N_SUCCESS - && s2n_pq_kem_is_extension_required(security_policy); -} - -static int s2n_client_pq_kem_send(struct s2n_connection *conn, struct s2n_stuffer *out) -{ - const struct s2n_kem_preferences *kem_preferences = NULL; - GUARD(s2n_connection_get_kem_preferences(conn, &kem_preferences)); - notnull_check(kem_preferences); - - GUARD(s2n_stuffer_write_uint16(out, kem_preferences->kem_count * sizeof(kem_extension_size))); - for (int i = 0; i < kem_preferences->kem_count; i++) { - GUARD(s2n_stuffer_write_uint16(out, kem_preferences->kems[i]->kem_extension_id)); - } - - return S2N_SUCCESS; -} - -static int s2n_client_pq_kem_recv(struct s2n_connection *conn, struct s2n_stuffer *extension) -{ - uint16_t size_of_all; - struct s2n_blob *proposed_kems = &conn->secure.client_pq_kem_extension; - - GUARD(s2n_stuffer_read_uint16(extension, &size_of_all)); - if (size_of_all > s2n_stuffer_data_available(extension) || size_of_all % sizeof(kem_extension_size)) { - /* Malformed length, ignore the extension */ - return S2N_SUCCESS; - } - - proposed_kems->size = size_of_all; - proposed_kems->data = s2n_stuffer_raw_read(extension, proposed_kems->size); - notnull_check(proposed_kems->data); - - return S2N_SUCCESS; -} - -/* Old-style extension functions -- remove after extensions refactor is complete */ - -int s2n_extensions_client_pq_kem_send(struct s2n_connection *conn, struct s2n_stuffer *out, uint16_t pq_kem_list_size) -{ - return s2n_extension_send(&s2n_client_pq_kem_extension, conn, out); -} - -int s2n_recv_pq_kem_extension(struct s2n_connection *conn, struct s2n_stuffer *extension) -{ - return s2n_extension_recv(&s2n_client_pq_kem_extension, conn, extension); -} +/* + * 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 <stdint.h> +#include <sys/param.h> + +#include "tls/extensions/s2n_client_pq_kem.h" +#include "tls/s2n_kem.h" +#include "tls/s2n_security_policies.h" +#include "tls/s2n_tls.h" +#include "tls/s2n_tls_parameters.h" + +#include "utils/s2n_safety.h" + +static bool s2n_client_pq_kem_should_send(struct s2n_connection *conn); +static int s2n_client_pq_kem_send(struct s2n_connection *conn, struct s2n_stuffer *out); +static int s2n_client_pq_kem_recv(struct s2n_connection *conn, struct s2n_stuffer *extension); + +const s2n_extension_type s2n_client_pq_kem_extension = { + .iana_value = TLS_EXTENSION_PQ_KEM_PARAMETERS, + .is_response = false, + .send = s2n_client_pq_kem_send, + .recv = s2n_client_pq_kem_recv, + .should_send = s2n_client_pq_kem_should_send, + .if_missing = s2n_extension_noop_if_missing, +}; + +static bool s2n_client_pq_kem_should_send(struct s2n_connection *conn) +{ + const struct s2n_security_policy *security_policy; + return s2n_connection_get_security_policy(conn, &security_policy) == S2N_SUCCESS + && s2n_pq_kem_is_extension_required(security_policy); +} + +static int s2n_client_pq_kem_send(struct s2n_connection *conn, struct s2n_stuffer *out) +{ + const struct s2n_kem_preferences *kem_preferences = NULL; + GUARD(s2n_connection_get_kem_preferences(conn, &kem_preferences)); + notnull_check(kem_preferences); + + GUARD(s2n_stuffer_write_uint16(out, kem_preferences->kem_count * sizeof(kem_extension_size))); + for (int i = 0; i < kem_preferences->kem_count; i++) { + GUARD(s2n_stuffer_write_uint16(out, kem_preferences->kems[i]->kem_extension_id)); + } + + return S2N_SUCCESS; +} + +static int s2n_client_pq_kem_recv(struct s2n_connection *conn, struct s2n_stuffer *extension) +{ + uint16_t size_of_all; + struct s2n_blob *proposed_kems = &conn->secure.client_pq_kem_extension; + + GUARD(s2n_stuffer_read_uint16(extension, &size_of_all)); + if (size_of_all > s2n_stuffer_data_available(extension) || size_of_all % sizeof(kem_extension_size)) { + /* Malformed length, ignore the extension */ + return S2N_SUCCESS; + } + + proposed_kems->size = size_of_all; + proposed_kems->data = s2n_stuffer_raw_read(extension, proposed_kems->size); + notnull_check(proposed_kems->data); + + return S2N_SUCCESS; +} + +/* Old-style extension functions -- remove after extensions refactor is complete */ + +int s2n_extensions_client_pq_kem_send(struct s2n_connection *conn, struct s2n_stuffer *out, uint16_t pq_kem_list_size) +{ + return s2n_extension_send(&s2n_client_pq_kem_extension, conn, out); +} + +int s2n_recv_pq_kem_extension(struct s2n_connection *conn, struct s2n_stuffer *extension) +{ + return s2n_extension_recv(&s2n_client_pq_kem_extension, conn, extension); +} diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_pq_kem.h b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_pq_kem.h index 91934773f3..bc7dd6868e 100644 --- a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_pq_kem.h +++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_pq_kem.h @@ -1,27 +1,27 @@ -/* - * 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. - */ - -#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_pq_kem_extension; - -/* Old-style extension functions -- remove after extensions refactor is complete */ - -extern int s2n_extensions_client_pq_kem_send(struct s2n_connection *conn, struct s2n_stuffer *out, uint16_t pq_kem_list_size); -extern int s2n_recv_pq_kem_extension(struct s2n_connection *conn, struct s2n_stuffer *extension); +/* + * 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. + */ + +#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_pq_kem_extension; + +/* Old-style extension functions -- remove after extensions refactor is complete */ + +extern int s2n_extensions_client_pq_kem_send(struct s2n_connection *conn, struct s2n_stuffer *out, uint16_t pq_kem_list_size); +extern int s2n_recv_pq_kem_extension(struct s2n_connection *conn, struct s2n_stuffer *extension); diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_psk.c b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_psk.c index 6e058d4392..0d8cecefab 100644 --- a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_psk.c +++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_psk.c @@ -1,271 +1,271 @@ -/* - * 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 <sys/param.h> -#include <stdint.h> - -#include "crypto/s2n_hash.h" -#include "tls/s2n_tls.h" -#include "tls/s2n_tls_parameters.h" - -#include "utils/s2n_safety.h" - -#define SIZE_OF_BINDER_SIZE sizeof(uint8_t) -#define SIZE_OF_BINDER_LIST_SIZE sizeof(uint16_t) - -static bool s2n_client_psk_should_send(struct s2n_connection *conn); -static int s2n_client_psk_send(struct s2n_connection *conn, struct s2n_stuffer *out); -static int s2n_client_psk_recv(struct s2n_connection *conn, struct s2n_stuffer *extension); - -const s2n_extension_type s2n_client_psk_extension = { - .iana_value = TLS_EXTENSION_PRE_SHARED_KEY, - .is_response = false, - .send = s2n_client_psk_send, - .recv = s2n_client_psk_recv, - .should_send = s2n_client_psk_should_send, - .if_missing = s2n_extension_noop_if_missing, -}; - -static bool s2n_client_psk_should_send(struct s2n_connection *conn) -{ - return conn && s2n_connection_get_protocol_version(conn) >= S2N_TLS13 - && conn->psk_params.psk_list.len; -} - -static int s2n_client_psk_send(struct s2n_connection *conn, struct s2n_stuffer *out) -{ - notnull_check(conn); - - struct s2n_psk_parameters *psk_params = &conn->psk_params; - struct s2n_array *psk_list = &psk_params->psk_list; - - struct s2n_stuffer_reservation identity_list_size; - GUARD(s2n_stuffer_reserve_uint16(out, &identity_list_size)); - - uint16_t binder_list_size = SIZE_OF_BINDER_LIST_SIZE; - - for (size_t i = 0; i < psk_list->len; i++) { - struct s2n_psk *psk = NULL; - GUARD_AS_POSIX(s2n_array_get(psk_list, i, (void**) &psk)); - notnull_check(psk); - - /* Write the identity */ - GUARD(s2n_stuffer_write_uint16(out, psk->identity.size)); - GUARD(s2n_stuffer_write(out, &psk->identity)); - GUARD(s2n_stuffer_write_uint32(out, 0)); - - /* Calculate binder size */ - uint8_t hash_size = 0; - GUARD(s2n_hash_digest_size(psk->hash_alg, &hash_size)); - binder_list_size += hash_size + SIZE_OF_BINDER_SIZE; - } - - GUARD(s2n_stuffer_write_vector_size(&identity_list_size)); - - /* Calculating the binders requires a complete ClientHello, and at this point - * the extension size, extension list size, and message size are all blank. - * - * We'll write placeholder data to ensure the extension and extension list sizes - * are calculated correctly, then rewrite the binders with real data later. */ - psk_params->binder_list_size = binder_list_size; - GUARD(s2n_stuffer_skip_write(out, binder_list_size)); - - return S2N_SUCCESS; -} - -/* Match a PSK identity received from the client against the server's known PSK identities. - * - * While both the client's offered identities and whether a match was found are public, we should make an attempt - * to keep the server's known identities a secret. We will make comparisons to the server's identities constant - * time (to hide partial matches) and not end the search early when a match is found (to hide the ordering). - * - * Keeping these comparisons constant time is not high priority. There's no known attack using these timings, - * and an attacker could probably guess the server's known identities just by observing the public identities - * sent by clients. - */ -static S2N_RESULT s2n_match_psk_identity(struct s2n_array *known_psks, const struct s2n_blob *wire_identity, - struct s2n_psk **match) -{ - ENSURE_REF(match); - ENSURE_REF(wire_identity); - ENSURE_REF(known_psks); - - *match = NULL; - - for (size_t i = 0; i < known_psks->len; i++) { - struct s2n_psk *psk = NULL; - GUARD_RESULT(s2n_array_get(known_psks, i, (void**)&psk)); - ENSURE_REF(psk); - - ENSURE_REF(psk->identity.data); - ENSURE_REF(wire_identity->data); - - uint32_t compare_size = MIN(wire_identity->size, psk->identity.size); - if (s2n_constant_time_equals(psk->identity.data, wire_identity->data, compare_size) - & (psk->identity.size == wire_identity->size) & (!*match)) { - *match = psk; - } - } - return S2N_RESULT_OK; -} - -static S2N_RESULT s2n_client_psk_recv_identity_list(struct s2n_connection *conn, struct s2n_stuffer *wire_identities_in) -{ - ENSURE_REF(conn); - ENSURE_REF(wire_identities_in); - - uint8_t wire_index = 0; - while (s2n_stuffer_data_available(wire_identities_in) > 0) { - uint16_t identity_size = 0; - GUARD_AS_RESULT(s2n_stuffer_read_uint16(wire_identities_in, &identity_size)); - - uint8_t *identity_data; - ENSURE_REF(identity_data = s2n_stuffer_raw_read(wire_identities_in, identity_size)); - - struct s2n_blob identity = { 0 }; - GUARD_AS_RESULT(s2n_blob_init(&identity, identity_data, identity_size)); - - /* TODO: Validate obfuscated_ticket_age when using session tickets: - * https://github.com/awslabs/s2n/issues/2417 - * - * "For identities established externally, an obfuscated_ticket_age of 0 SHOULD be - * used, and servers MUST ignore the value." - */ - uint32_t obfuscated_ticket_age = 0; - GUARD_AS_RESULT(s2n_stuffer_read_uint32(wire_identities_in, &obfuscated_ticket_age)); - - /* TODO: Implement the callback to choose a PSK: https://github.com/awslabs/s2n/issues/2397 - * - * When we don't have a callback configured to choose a PSK, we should fall back to accepting - * the first PSK identity that also exists in our list of supported PSKs. */ - GUARD_RESULT(s2n_match_psk_identity(&conn->psk_params.psk_list, &identity, &conn->psk_params.chosen_psk)); - - if (conn->psk_params.chosen_psk) { - conn->psk_params.chosen_psk_wire_index = wire_index; - return S2N_RESULT_OK; - } - - wire_index++; - } - return S2N_RESULT_OK; -} - -static S2N_RESULT s2n_client_psk_recv_binder_list(struct s2n_connection *conn, struct s2n_blob *partial_client_hello, - struct s2n_stuffer *wire_binders_in) -{ - ENSURE_REF(conn); - ENSURE_REF(wire_binders_in); - - uint8_t wire_index = 0; - while (s2n_stuffer_data_available(wire_binders_in) > 0) { - uint8_t wire_binder_size = 0; - GUARD_AS_RESULT(s2n_stuffer_read_uint8(wire_binders_in, &wire_binder_size)); - - uint8_t *wire_binder_data; - ENSURE_REF(wire_binder_data = s2n_stuffer_raw_read(wire_binders_in, wire_binder_size)); - - struct s2n_blob wire_binder = { 0 }; - GUARD_AS_RESULT(s2n_blob_init(&wire_binder, wire_binder_data, wire_binder_size)); - - if (wire_index == conn->psk_params.chosen_psk_wire_index) { - GUARD_AS_RESULT(s2n_psk_verify_binder(conn, conn->psk_params.chosen_psk, - partial_client_hello, &wire_binder)); - return S2N_RESULT_OK; - } - wire_index++; - } - BAIL(S2N_ERR_BAD_MESSAGE); -} - -static S2N_RESULT s2n_client_psk_recv_identities(struct s2n_connection *conn, struct s2n_stuffer *extension) -{ - ENSURE_REF(conn); - - uint16_t identity_list_size = 0; - GUARD_AS_RESULT(s2n_stuffer_read_uint16(extension, &identity_list_size)); - - uint8_t *identity_list_data; - ENSURE_REF(identity_list_data = s2n_stuffer_raw_read(extension, identity_list_size)); - - struct s2n_blob identity_list_blob = { 0 }; - GUARD_AS_RESULT(s2n_blob_init(&identity_list_blob, identity_list_data, identity_list_size)); - - struct s2n_stuffer identity_list = { 0 }; - GUARD_AS_RESULT(s2n_stuffer_init(&identity_list, &identity_list_blob)); - GUARD_AS_RESULT(s2n_stuffer_skip_write(&identity_list, identity_list_blob.size)); - - return s2n_client_psk_recv_identity_list(conn, &identity_list); -} - -static S2N_RESULT s2n_client_psk_recv_binders(struct s2n_connection *conn, struct s2n_stuffer *extension) -{ - ENSURE_REF(conn); - - uint16_t binder_list_size = 0; - GUARD_AS_RESULT(s2n_stuffer_read_uint16(extension, &binder_list_size)); - - uint8_t *binder_list_data; - ENSURE_REF(binder_list_data = s2n_stuffer_raw_read(extension, binder_list_size)); - - struct s2n_blob binder_list_blob = { 0 }; - GUARD_AS_RESULT(s2n_blob_init(&binder_list_blob, binder_list_data, binder_list_size)); - - struct s2n_stuffer binder_list = { 0 }; - GUARD_AS_RESULT(s2n_stuffer_init(&binder_list, &binder_list_blob)); - GUARD_AS_RESULT(s2n_stuffer_skip_write(&binder_list, binder_list_blob.size)); - - /* Record the ClientHello message up to but not including the binder list. - * This is required to calculate the binder for the chosen PSK. */ - struct s2n_blob partial_client_hello = { 0 }; - const struct s2n_stuffer *client_hello = &conn->handshake.io; - uint32_t binders_size = binder_list_blob.size + SIZE_OF_BINDER_LIST_SIZE; - ENSURE_GTE(client_hello->write_cursor, binders_size); - uint16_t partial_client_hello_size = client_hello->write_cursor - binders_size; - GUARD_AS_RESULT(s2n_blob_slice(&client_hello->blob, &partial_client_hello, 0, partial_client_hello_size)); - - return s2n_client_psk_recv_binder_list(conn, &partial_client_hello, &binder_list); -} - -int s2n_client_psk_recv(struct s2n_connection *conn, struct s2n_stuffer *extension) -{ - notnull_check(conn); - - if (s2n_connection_get_protocol_version(conn) < S2N_TLS13) { - return S2N_SUCCESS; - } - - if (s2n_result_is_error(s2n_client_psk_recv_identities(conn, extension))) { - /* https://tools.ietf.org/html/rfc8446#section-4.2.11: - * "If no acceptable PSKs are found, the server SHOULD perform a non-PSK - * handshake if possible." - */ - conn->psk_params.chosen_psk = NULL; - } - - if (conn->psk_params.chosen_psk) { - /* https://tools.ietf.org/html/rfc8446#section-4.2.11: - * "Prior to accepting PSK key establishment, the server MUST validate - * the corresponding binder value. If this value is not present or does - * not validate, the server MUST abort the handshake." - */ - GUARD_AS_POSIX(s2n_client_psk_recv_binders(conn, extension)); - } - - /* At this point, we have either chosen a PSK or fallen back to a full handshake. - * Wipe any PSKs not chosen. */ - GUARD_AS_POSIX(s2n_psk_parameters_free_unused_psks(&conn->psk_params)); - - return S2N_SUCCESS; -} +/* + * 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 <sys/param.h> +#include <stdint.h> + +#include "crypto/s2n_hash.h" +#include "tls/s2n_tls.h" +#include "tls/s2n_tls_parameters.h" + +#include "utils/s2n_safety.h" + +#define SIZE_OF_BINDER_SIZE sizeof(uint8_t) +#define SIZE_OF_BINDER_LIST_SIZE sizeof(uint16_t) + +static bool s2n_client_psk_should_send(struct s2n_connection *conn); +static int s2n_client_psk_send(struct s2n_connection *conn, struct s2n_stuffer *out); +static int s2n_client_psk_recv(struct s2n_connection *conn, struct s2n_stuffer *extension); + +const s2n_extension_type s2n_client_psk_extension = { + .iana_value = TLS_EXTENSION_PRE_SHARED_KEY, + .is_response = false, + .send = s2n_client_psk_send, + .recv = s2n_client_psk_recv, + .should_send = s2n_client_psk_should_send, + .if_missing = s2n_extension_noop_if_missing, +}; + +static bool s2n_client_psk_should_send(struct s2n_connection *conn) +{ + return conn && s2n_connection_get_protocol_version(conn) >= S2N_TLS13 + && conn->psk_params.psk_list.len; +} + +static int s2n_client_psk_send(struct s2n_connection *conn, struct s2n_stuffer *out) +{ + notnull_check(conn); + + struct s2n_psk_parameters *psk_params = &conn->psk_params; + struct s2n_array *psk_list = &psk_params->psk_list; + + struct s2n_stuffer_reservation identity_list_size; + GUARD(s2n_stuffer_reserve_uint16(out, &identity_list_size)); + + uint16_t binder_list_size = SIZE_OF_BINDER_LIST_SIZE; + + for (size_t i = 0; i < psk_list->len; i++) { + struct s2n_psk *psk = NULL; + GUARD_AS_POSIX(s2n_array_get(psk_list, i, (void**) &psk)); + notnull_check(psk); + + /* Write the identity */ + GUARD(s2n_stuffer_write_uint16(out, psk->identity.size)); + GUARD(s2n_stuffer_write(out, &psk->identity)); + GUARD(s2n_stuffer_write_uint32(out, 0)); + + /* Calculate binder size */ + uint8_t hash_size = 0; + GUARD(s2n_hash_digest_size(psk->hash_alg, &hash_size)); + binder_list_size += hash_size + SIZE_OF_BINDER_SIZE; + } + + GUARD(s2n_stuffer_write_vector_size(&identity_list_size)); + + /* Calculating the binders requires a complete ClientHello, and at this point + * the extension size, extension list size, and message size are all blank. + * + * We'll write placeholder data to ensure the extension and extension list sizes + * are calculated correctly, then rewrite the binders with real data later. */ + psk_params->binder_list_size = binder_list_size; + GUARD(s2n_stuffer_skip_write(out, binder_list_size)); + + return S2N_SUCCESS; +} + +/* Match a PSK identity received from the client against the server's known PSK identities. + * + * While both the client's offered identities and whether a match was found are public, we should make an attempt + * to keep the server's known identities a secret. We will make comparisons to the server's identities constant + * time (to hide partial matches) and not end the search early when a match is found (to hide the ordering). + * + * Keeping these comparisons constant time is not high priority. There's no known attack using these timings, + * and an attacker could probably guess the server's known identities just by observing the public identities + * sent by clients. + */ +static S2N_RESULT s2n_match_psk_identity(struct s2n_array *known_psks, const struct s2n_blob *wire_identity, + struct s2n_psk **match) +{ + ENSURE_REF(match); + ENSURE_REF(wire_identity); + ENSURE_REF(known_psks); + + *match = NULL; + + for (size_t i = 0; i < known_psks->len; i++) { + struct s2n_psk *psk = NULL; + GUARD_RESULT(s2n_array_get(known_psks, i, (void**)&psk)); + ENSURE_REF(psk); + + ENSURE_REF(psk->identity.data); + ENSURE_REF(wire_identity->data); + + uint32_t compare_size = MIN(wire_identity->size, psk->identity.size); + if (s2n_constant_time_equals(psk->identity.data, wire_identity->data, compare_size) + & (psk->identity.size == wire_identity->size) & (!*match)) { + *match = psk; + } + } + return S2N_RESULT_OK; +} + +static S2N_RESULT s2n_client_psk_recv_identity_list(struct s2n_connection *conn, struct s2n_stuffer *wire_identities_in) +{ + ENSURE_REF(conn); + ENSURE_REF(wire_identities_in); + + uint8_t wire_index = 0; + while (s2n_stuffer_data_available(wire_identities_in) > 0) { + uint16_t identity_size = 0; + GUARD_AS_RESULT(s2n_stuffer_read_uint16(wire_identities_in, &identity_size)); + + uint8_t *identity_data; + ENSURE_REF(identity_data = s2n_stuffer_raw_read(wire_identities_in, identity_size)); + + struct s2n_blob identity = { 0 }; + GUARD_AS_RESULT(s2n_blob_init(&identity, identity_data, identity_size)); + + /* TODO: Validate obfuscated_ticket_age when using session tickets: + * https://github.com/awslabs/s2n/issues/2417 + * + * "For identities established externally, an obfuscated_ticket_age of 0 SHOULD be + * used, and servers MUST ignore the value." + */ + uint32_t obfuscated_ticket_age = 0; + GUARD_AS_RESULT(s2n_stuffer_read_uint32(wire_identities_in, &obfuscated_ticket_age)); + + /* TODO: Implement the callback to choose a PSK: https://github.com/awslabs/s2n/issues/2397 + * + * When we don't have a callback configured to choose a PSK, we should fall back to accepting + * the first PSK identity that also exists in our list of supported PSKs. */ + GUARD_RESULT(s2n_match_psk_identity(&conn->psk_params.psk_list, &identity, &conn->psk_params.chosen_psk)); + + if (conn->psk_params.chosen_psk) { + conn->psk_params.chosen_psk_wire_index = wire_index; + return S2N_RESULT_OK; + } + + wire_index++; + } + return S2N_RESULT_OK; +} + +static S2N_RESULT s2n_client_psk_recv_binder_list(struct s2n_connection *conn, struct s2n_blob *partial_client_hello, + struct s2n_stuffer *wire_binders_in) +{ + ENSURE_REF(conn); + ENSURE_REF(wire_binders_in); + + uint8_t wire_index = 0; + while (s2n_stuffer_data_available(wire_binders_in) > 0) { + uint8_t wire_binder_size = 0; + GUARD_AS_RESULT(s2n_stuffer_read_uint8(wire_binders_in, &wire_binder_size)); + + uint8_t *wire_binder_data; + ENSURE_REF(wire_binder_data = s2n_stuffer_raw_read(wire_binders_in, wire_binder_size)); + + struct s2n_blob wire_binder = { 0 }; + GUARD_AS_RESULT(s2n_blob_init(&wire_binder, wire_binder_data, wire_binder_size)); + + if (wire_index == conn->psk_params.chosen_psk_wire_index) { + GUARD_AS_RESULT(s2n_psk_verify_binder(conn, conn->psk_params.chosen_psk, + partial_client_hello, &wire_binder)); + return S2N_RESULT_OK; + } + wire_index++; + } + BAIL(S2N_ERR_BAD_MESSAGE); +} + +static S2N_RESULT s2n_client_psk_recv_identities(struct s2n_connection *conn, struct s2n_stuffer *extension) +{ + ENSURE_REF(conn); + + uint16_t identity_list_size = 0; + GUARD_AS_RESULT(s2n_stuffer_read_uint16(extension, &identity_list_size)); + + uint8_t *identity_list_data; + ENSURE_REF(identity_list_data = s2n_stuffer_raw_read(extension, identity_list_size)); + + struct s2n_blob identity_list_blob = { 0 }; + GUARD_AS_RESULT(s2n_blob_init(&identity_list_blob, identity_list_data, identity_list_size)); + + struct s2n_stuffer identity_list = { 0 }; + GUARD_AS_RESULT(s2n_stuffer_init(&identity_list, &identity_list_blob)); + GUARD_AS_RESULT(s2n_stuffer_skip_write(&identity_list, identity_list_blob.size)); + + return s2n_client_psk_recv_identity_list(conn, &identity_list); +} + +static S2N_RESULT s2n_client_psk_recv_binders(struct s2n_connection *conn, struct s2n_stuffer *extension) +{ + ENSURE_REF(conn); + + uint16_t binder_list_size = 0; + GUARD_AS_RESULT(s2n_stuffer_read_uint16(extension, &binder_list_size)); + + uint8_t *binder_list_data; + ENSURE_REF(binder_list_data = s2n_stuffer_raw_read(extension, binder_list_size)); + + struct s2n_blob binder_list_blob = { 0 }; + GUARD_AS_RESULT(s2n_blob_init(&binder_list_blob, binder_list_data, binder_list_size)); + + struct s2n_stuffer binder_list = { 0 }; + GUARD_AS_RESULT(s2n_stuffer_init(&binder_list, &binder_list_blob)); + GUARD_AS_RESULT(s2n_stuffer_skip_write(&binder_list, binder_list_blob.size)); + + /* Record the ClientHello message up to but not including the binder list. + * This is required to calculate the binder for the chosen PSK. */ + struct s2n_blob partial_client_hello = { 0 }; + const struct s2n_stuffer *client_hello = &conn->handshake.io; + uint32_t binders_size = binder_list_blob.size + SIZE_OF_BINDER_LIST_SIZE; + ENSURE_GTE(client_hello->write_cursor, binders_size); + uint16_t partial_client_hello_size = client_hello->write_cursor - binders_size; + GUARD_AS_RESULT(s2n_blob_slice(&client_hello->blob, &partial_client_hello, 0, partial_client_hello_size)); + + return s2n_client_psk_recv_binder_list(conn, &partial_client_hello, &binder_list); +} + +int s2n_client_psk_recv(struct s2n_connection *conn, struct s2n_stuffer *extension) +{ + notnull_check(conn); + + if (s2n_connection_get_protocol_version(conn) < S2N_TLS13) { + return S2N_SUCCESS; + } + + if (s2n_result_is_error(s2n_client_psk_recv_identities(conn, extension))) { + /* https://tools.ietf.org/html/rfc8446#section-4.2.11: + * "If no acceptable PSKs are found, the server SHOULD perform a non-PSK + * handshake if possible." + */ + conn->psk_params.chosen_psk = NULL; + } + + if (conn->psk_params.chosen_psk) { + /* https://tools.ietf.org/html/rfc8446#section-4.2.11: + * "Prior to accepting PSK key establishment, the server MUST validate + * the corresponding binder value. If this value is not present or does + * not validate, the server MUST abort the handshake." + */ + GUARD_AS_POSIX(s2n_client_psk_recv_binders(conn, extension)); + } + + /* At this point, we have either chosen a PSK or fallen back to a full handshake. + * Wipe any PSKs not chosen. */ + GUARD_AS_POSIX(s2n_psk_parameters_free_unused_psks(&conn->psk_params)); + + return S2N_SUCCESS; +} diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_psk.h b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_psk.h index a317ace2bc..0e12137676 100644 --- a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_psk.h +++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_psk.h @@ -1,22 +1,22 @@ -/* - * 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. - */ - -#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_psk_extension; +/* + * 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. + */ + +#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_psk_extension; diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_renegotiation_info.c b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_renegotiation_info.c index 3a012f47d1..502b84b624 100644 --- a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_renegotiation_info.c +++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_renegotiation_info.c @@ -1,51 +1,51 @@ -/* - * 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 <sys/param.h> -#include <stdint.h> - -#include "tls/extensions/s2n_client_renegotiation_info.h" -#include "tls/s2n_tls.h" - -#include "utils/s2n_safety.h" - -static int s2n_client_renegotiation_recv(struct s2n_connection *conn, struct s2n_stuffer *extension); - -const s2n_extension_type s2n_client_renegotiation_info_extension = { - .iana_value = TLS_EXTENSION_RENEGOTIATION_INFO, - .is_response = false, - .send = s2n_extension_send_unimplemented, - .recv = s2n_client_renegotiation_recv, - .should_send = s2n_extension_never_send, - .if_missing = s2n_extension_noop_if_missing, -}; - -static int s2n_client_renegotiation_recv(struct s2n_connection *conn, struct s2n_stuffer *extension) -{ - /* RFC5746 Section 3.2: The renegotiated_connection field is of zero length for the initial handshake. */ - uint8_t renegotiated_connection_len; - GUARD(s2n_stuffer_read_uint8(extension, &renegotiated_connection_len)); - S2N_ERROR_IF(s2n_stuffer_data_available(extension) || renegotiated_connection_len, S2N_ERR_NON_EMPTY_RENEGOTIATION_INFO); - - conn->secure_renegotiation = 1; - return S2N_SUCCESS; -} - -/* Old-style extension functions -- remove after extensions refactor is complete */ - -int s2n_recv_client_renegotiation_info(struct s2n_connection *conn, struct s2n_stuffer *extension) -{ - return s2n_extension_recv(&s2n_client_renegotiation_info_extension, conn, extension); -} +/* + * 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 <sys/param.h> +#include <stdint.h> + +#include "tls/extensions/s2n_client_renegotiation_info.h" +#include "tls/s2n_tls.h" + +#include "utils/s2n_safety.h" + +static int s2n_client_renegotiation_recv(struct s2n_connection *conn, struct s2n_stuffer *extension); + +const s2n_extension_type s2n_client_renegotiation_info_extension = { + .iana_value = TLS_EXTENSION_RENEGOTIATION_INFO, + .is_response = false, + .send = s2n_extension_send_unimplemented, + .recv = s2n_client_renegotiation_recv, + .should_send = s2n_extension_never_send, + .if_missing = s2n_extension_noop_if_missing, +}; + +static int s2n_client_renegotiation_recv(struct s2n_connection *conn, struct s2n_stuffer *extension) +{ + /* RFC5746 Section 3.2: The renegotiated_connection field is of zero length for the initial handshake. */ + uint8_t renegotiated_connection_len; + GUARD(s2n_stuffer_read_uint8(extension, &renegotiated_connection_len)); + S2N_ERROR_IF(s2n_stuffer_data_available(extension) || renegotiated_connection_len, S2N_ERR_NON_EMPTY_RENEGOTIATION_INFO); + + conn->secure_renegotiation = 1; + return S2N_SUCCESS; +} + +/* Old-style extension functions -- remove after extensions refactor is complete */ + +int s2n_recv_client_renegotiation_info(struct s2n_connection *conn, struct s2n_stuffer *extension) +{ + return s2n_extension_recv(&s2n_client_renegotiation_info_extension, conn, extension); +} diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_renegotiation_info.h b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_renegotiation_info.h index dbc98ddf80..d1e37e9677 100644 --- a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_renegotiation_info.h +++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_renegotiation_info.h @@ -1,25 +1,25 @@ -/* - * 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. - */ - -#pragma once - -#include "tls/s2n_connection.h" -#include "stuffer/s2n_stuffer.h" - -extern const s2n_extension_type s2n_client_renegotiation_info_extension; - -/* Old-style extension functions -- remove after extensions refactor is complete */ - -int s2n_recv_client_renegotiation_info(struct s2n_connection *conn, struct s2n_stuffer *extension); +/* + * 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. + */ + +#pragma once + +#include "tls/s2n_connection.h" +#include "stuffer/s2n_stuffer.h" + +extern const s2n_extension_type s2n_client_renegotiation_info_extension; + +/* Old-style extension functions -- remove after extensions refactor is complete */ + +int s2n_recv_client_renegotiation_info(struct s2n_connection *conn, struct s2n_stuffer *extension); diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_sct_list.c b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_sct_list.c index d3f699c8c3..ecf86b2647 100644 --- a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_sct_list.c +++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_sct_list.c @@ -1,59 +1,59 @@ -/* - * 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 <sys/param.h> -#include <stdint.h> - -#include "tls/extensions/s2n_client_sct_list.h" -#include "tls/s2n_tls.h" -#include "tls/s2n_tls_parameters.h" - -#include "utils/s2n_safety.h" - -static bool s2n_client_sct_list_should_send(struct s2n_connection *conn); -static int s2n_client_sct_list_recv(struct s2n_connection *conn, struct s2n_stuffer *extension); - -const s2n_extension_type s2n_client_sct_list_extension = { - .iana_value = TLS_EXTENSION_SCT_LIST, - .is_response = false, - .send = s2n_extension_send_noop, - .recv = s2n_client_sct_list_recv, - .should_send = s2n_client_sct_list_should_send, - .if_missing = s2n_extension_noop_if_missing, -}; - -static bool s2n_client_sct_list_should_send(struct s2n_connection *conn) -{ - return conn->config->ct_type != S2N_CT_SUPPORT_NONE; -} - -static int s2n_client_sct_list_recv(struct s2n_connection *conn, struct s2n_stuffer *out) -{ - conn->ct_level_requested = S2N_CT_SUPPORT_REQUEST; - /* Skip reading the extension, per RFC6962 (3.1.1) it SHOULD be empty anyway */ - return S2N_SUCCESS; -} - -/* Old-style extension functions -- remove after extensions refactor is complete */ - -int s2n_extensions_client_sct_list_send(struct s2n_connection *conn, struct s2n_stuffer *out) -{ - return s2n_extension_send(&s2n_client_sct_list_extension, conn, out); -} - -int s2n_recv_client_sct_list(struct s2n_connection *conn, struct s2n_stuffer *extension) -{ - return s2n_extension_recv(&s2n_client_sct_list_extension, conn, extension); -} +/* + * 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 <sys/param.h> +#include <stdint.h> + +#include "tls/extensions/s2n_client_sct_list.h" +#include "tls/s2n_tls.h" +#include "tls/s2n_tls_parameters.h" + +#include "utils/s2n_safety.h" + +static bool s2n_client_sct_list_should_send(struct s2n_connection *conn); +static int s2n_client_sct_list_recv(struct s2n_connection *conn, struct s2n_stuffer *extension); + +const s2n_extension_type s2n_client_sct_list_extension = { + .iana_value = TLS_EXTENSION_SCT_LIST, + .is_response = false, + .send = s2n_extension_send_noop, + .recv = s2n_client_sct_list_recv, + .should_send = s2n_client_sct_list_should_send, + .if_missing = s2n_extension_noop_if_missing, +}; + +static bool s2n_client_sct_list_should_send(struct s2n_connection *conn) +{ + return conn->config->ct_type != S2N_CT_SUPPORT_NONE; +} + +static int s2n_client_sct_list_recv(struct s2n_connection *conn, struct s2n_stuffer *out) +{ + conn->ct_level_requested = S2N_CT_SUPPORT_REQUEST; + /* Skip reading the extension, per RFC6962 (3.1.1) it SHOULD be empty anyway */ + return S2N_SUCCESS; +} + +/* Old-style extension functions -- remove after extensions refactor is complete */ + +int s2n_extensions_client_sct_list_send(struct s2n_connection *conn, struct s2n_stuffer *out) +{ + return s2n_extension_send(&s2n_client_sct_list_extension, conn, out); +} + +int s2n_recv_client_sct_list(struct s2n_connection *conn, struct s2n_stuffer *extension) +{ + return s2n_extension_recv(&s2n_client_sct_list_extension, conn, extension); +} diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_sct_list.h b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_sct_list.h index 2f03d9baff..9d7a75e7cb 100644 --- a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_sct_list.h +++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_sct_list.h @@ -1,26 +1,26 @@ -/* - * 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. - */ - -#pragma once - -#include "tls/s2n_connection.h" -#include "stuffer/s2n_stuffer.h" - -extern const s2n_extension_type s2n_client_sct_list_extension; - -/* Old-style extension functions -- remove after extensions refactor is complete */ - -extern int s2n_extensions_client_sct_list_send(struct s2n_connection *conn, struct s2n_stuffer *out); -extern int s2n_recv_client_sct_list(struct s2n_connection *conn, struct s2n_stuffer *extension); +/* + * 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. + */ + +#pragma once + +#include "tls/s2n_connection.h" +#include "stuffer/s2n_stuffer.h" + +extern const s2n_extension_type s2n_client_sct_list_extension; + +/* Old-style extension functions -- remove after extensions refactor is complete */ + +extern int s2n_extensions_client_sct_list_send(struct s2n_connection *conn, struct s2n_stuffer *out); +extern int s2n_recv_client_sct_list(struct s2n_connection *conn, struct s2n_stuffer *extension); diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_server_name.c b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_server_name.c index 904976e4cc..c9eaca23a9 100644 --- a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_server_name.c +++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_server_name.c @@ -1,110 +1,110 @@ -/* - * 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 <sys/param.h> -#include <stdint.h> - -#include "tls/extensions/s2n_client_server_name.h" -#include "tls/s2n_tls.h" -#include "tls/s2n_tls_parameters.h" - -#include "utils/s2n_safety.h" - -#define S2N_NAME_TYPE_HOST_NAME 0 - -static bool s2n_client_server_name_should_send(struct s2n_connection *conn); -static int s2n_client_server_name_send(struct s2n_connection *conn, struct s2n_stuffer *out); -static int s2n_client_server_name_recv(struct s2n_connection *conn, struct s2n_stuffer *extension); - -const s2n_extension_type s2n_client_server_name_extension = { - .iana_value = TLS_EXTENSION_SERVER_NAME, - .is_response = false, - .send = s2n_client_server_name_send, - .recv = s2n_client_server_name_recv, - .should_send = s2n_client_server_name_should_send, - .if_missing = s2n_extension_noop_if_missing, -}; - -static bool s2n_client_server_name_should_send(struct s2n_connection *conn) -{ - return conn && strlen(conn->server_name) > 0; -} - -static int s2n_client_server_name_send(struct s2n_connection *conn, struct s2n_stuffer *out) -{ - struct s2n_stuffer_reservation server_name_list_size = {0}; - GUARD(s2n_stuffer_reserve_uint16(out, &server_name_list_size)); - - /* NameType, as described by RFC6066. - * host_name is currently the only possible NameType defined. */ - GUARD(s2n_stuffer_write_uint8(out, S2N_NAME_TYPE_HOST_NAME)); - - GUARD(s2n_stuffer_write_uint16(out, strlen(conn->server_name))); - GUARD(s2n_stuffer_write_bytes(out, (const uint8_t *) conn->server_name, strlen(conn->server_name))); - - GUARD(s2n_stuffer_write_vector_size(&server_name_list_size)); - return S2N_SUCCESS; -} - -static int s2n_client_server_name_check(struct s2n_connection *conn, struct s2n_stuffer *extension, uint16_t *server_name_len) -{ - notnull_check(conn); - - uint16_t size_of_all; - GUARD(s2n_stuffer_read_uint16(extension, &size_of_all)); - lte_check(size_of_all, s2n_stuffer_data_available(extension)); - - uint8_t server_name_type; - GUARD(s2n_stuffer_read_uint8(extension, &server_name_type)); - eq_check(server_name_type, S2N_NAME_TYPE_HOST_NAME); - - GUARD(s2n_stuffer_read_uint16(extension, server_name_len)); - lt_check(*server_name_len, sizeof(conn->server_name)); - lte_check(*server_name_len, s2n_stuffer_data_available(extension)); - - return S2N_SUCCESS; -} - -static int s2n_client_server_name_recv(struct s2n_connection *conn, struct s2n_stuffer *extension) -{ - notnull_check(conn); - - /* Exit early if we've already parsed the server name */ - if (conn->server_name[0]) { - return S2N_SUCCESS; - } - - /* Ignore if malformed. We just won't use the server name. */ - uint16_t server_name_len; - if (s2n_client_server_name_check(conn, extension, &server_name_len) != S2N_SUCCESS) { - return S2N_SUCCESS; - } - - uint8_t *server_name; - notnull_check(server_name = s2n_stuffer_raw_read(extension, server_name_len)); - memcpy_check(conn->server_name, server_name, server_name_len); - - return S2N_SUCCESS; -} - -int s2n_extensions_client_server_name_send(struct s2n_connection *conn, struct s2n_stuffer *out) -{ - return s2n_extension_send(&s2n_client_server_name_extension, conn, out); -} - -int s2n_parse_client_hello_server_name(struct s2n_connection *conn, struct s2n_stuffer *extension) -{ - return s2n_extension_recv(&s2n_client_server_name_extension, conn, extension); -} +/* + * 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 <sys/param.h> +#include <stdint.h> + +#include "tls/extensions/s2n_client_server_name.h" +#include "tls/s2n_tls.h" +#include "tls/s2n_tls_parameters.h" + +#include "utils/s2n_safety.h" + +#define S2N_NAME_TYPE_HOST_NAME 0 + +static bool s2n_client_server_name_should_send(struct s2n_connection *conn); +static int s2n_client_server_name_send(struct s2n_connection *conn, struct s2n_stuffer *out); +static int s2n_client_server_name_recv(struct s2n_connection *conn, struct s2n_stuffer *extension); + +const s2n_extension_type s2n_client_server_name_extension = { + .iana_value = TLS_EXTENSION_SERVER_NAME, + .is_response = false, + .send = s2n_client_server_name_send, + .recv = s2n_client_server_name_recv, + .should_send = s2n_client_server_name_should_send, + .if_missing = s2n_extension_noop_if_missing, +}; + +static bool s2n_client_server_name_should_send(struct s2n_connection *conn) +{ + return conn && strlen(conn->server_name) > 0; +} + +static int s2n_client_server_name_send(struct s2n_connection *conn, struct s2n_stuffer *out) +{ + struct s2n_stuffer_reservation server_name_list_size = {0}; + GUARD(s2n_stuffer_reserve_uint16(out, &server_name_list_size)); + + /* NameType, as described by RFC6066. + * host_name is currently the only possible NameType defined. */ + GUARD(s2n_stuffer_write_uint8(out, S2N_NAME_TYPE_HOST_NAME)); + + GUARD(s2n_stuffer_write_uint16(out, strlen(conn->server_name))); + GUARD(s2n_stuffer_write_bytes(out, (const uint8_t *) conn->server_name, strlen(conn->server_name))); + + GUARD(s2n_stuffer_write_vector_size(&server_name_list_size)); + return S2N_SUCCESS; +} + +static int s2n_client_server_name_check(struct s2n_connection *conn, struct s2n_stuffer *extension, uint16_t *server_name_len) +{ + notnull_check(conn); + + uint16_t size_of_all; + GUARD(s2n_stuffer_read_uint16(extension, &size_of_all)); + lte_check(size_of_all, s2n_stuffer_data_available(extension)); + + uint8_t server_name_type; + GUARD(s2n_stuffer_read_uint8(extension, &server_name_type)); + eq_check(server_name_type, S2N_NAME_TYPE_HOST_NAME); + + GUARD(s2n_stuffer_read_uint16(extension, server_name_len)); + lt_check(*server_name_len, sizeof(conn->server_name)); + lte_check(*server_name_len, s2n_stuffer_data_available(extension)); + + return S2N_SUCCESS; +} + +static int s2n_client_server_name_recv(struct s2n_connection *conn, struct s2n_stuffer *extension) +{ + notnull_check(conn); + + /* Exit early if we've already parsed the server name */ + if (conn->server_name[0]) { + return S2N_SUCCESS; + } + + /* Ignore if malformed. We just won't use the server name. */ + uint16_t server_name_len; + if (s2n_client_server_name_check(conn, extension, &server_name_len) != S2N_SUCCESS) { + return S2N_SUCCESS; + } + + uint8_t *server_name; + notnull_check(server_name = s2n_stuffer_raw_read(extension, server_name_len)); + memcpy_check(conn->server_name, server_name, server_name_len); + + return S2N_SUCCESS; +} + +int s2n_extensions_client_server_name_send(struct s2n_connection *conn, struct s2n_stuffer *out) +{ + return s2n_extension_send(&s2n_client_server_name_extension, conn, out); +} + +int s2n_parse_client_hello_server_name(struct s2n_connection *conn, struct s2n_stuffer *extension) +{ + return s2n_extension_recv(&s2n_client_server_name_extension, conn, extension); +} diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_server_name.h b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_server_name.h index a6dde369dc..a6c2f2250a 100644 --- a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_server_name.h +++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_server_name.h @@ -1,26 +1,26 @@ -/* - * 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. - */ - -#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_server_name_extension; - -/* Old-style extension functions -- remove after extensions refactor is complete */ -extern int s2n_extensions_client_server_name_send(struct s2n_connection *conn, struct s2n_stuffer *out); -extern int s2n_parse_client_hello_server_name(struct s2n_connection *conn, struct s2n_stuffer *extension); +/* + * 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. + */ + +#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_server_name_extension; + +/* Old-style extension functions -- remove after extensions refactor is complete */ +extern int s2n_extensions_client_server_name_send(struct s2n_connection *conn, struct s2n_stuffer *out); +extern int s2n_parse_client_hello_server_name(struct s2n_connection *conn, struct s2n_stuffer *extension); diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_session_ticket.c b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_session_ticket.c index 96ef1b7308..3628f7be9a 100644 --- a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_session_ticket.c +++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_session_ticket.c @@ -1,82 +1,82 @@ -/* - * 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 <sys/param.h> -#include <stdint.h> - -#include "tls/extensions/s2n_client_session_ticket.h" -#include "tls/s2n_tls.h" -#include "tls/s2n_tls_parameters.h" -#include "tls/s2n_resume.h" - -#include "utils/s2n_safety.h" - -static bool s2n_client_session_ticket_should_send(struct s2n_connection *conn); -static int s2n_client_session_ticket_send(struct s2n_connection *conn, struct s2n_stuffer *out); -static int s2n_client_session_ticket_recv(struct s2n_connection *conn, struct s2n_stuffer *extension); - -const s2n_extension_type s2n_client_session_ticket_extension = { - .iana_value = TLS_EXTENSION_SESSION_TICKET, - .is_response = false, - .send = s2n_client_session_ticket_send, - .recv = s2n_client_session_ticket_recv, - .should_send = s2n_client_session_ticket_should_send, - .if_missing = s2n_extension_noop_if_missing, -}; - -static bool s2n_client_session_ticket_should_send(struct s2n_connection *conn) -{ - return conn->config->use_tickets; -} - -static int s2n_client_session_ticket_send(struct s2n_connection *conn, struct s2n_stuffer *out) -{ - GUARD(s2n_stuffer_write(out, &conn->client_ticket)); - return S2N_SUCCESS; -} - -static int s2n_client_session_ticket_recv(struct s2n_connection *conn, struct s2n_stuffer *extension) -{ - if (conn->config->use_tickets != 1) { - /* Ignore the extension. */ - return S2N_SUCCESS; - } - - /* s2n server does not support session ticket with CLIENT_AUTH enabled */ - if (s2n_connection_is_client_auth_enabled(conn) > 0) { - return S2N_SUCCESS; - } - - if (s2n_stuffer_data_available(extension) == S2N_TICKET_SIZE_IN_BYTES) { - conn->session_ticket_status = S2N_DECRYPT_TICKET; - GUARD(s2n_stuffer_copy(extension, &conn->client_ticket_to_decrypt, S2N_TICKET_SIZE_IN_BYTES)); - } else if (s2n_config_is_encrypt_decrypt_key_available(conn->config) == 1) { - conn->session_ticket_status = S2N_NEW_TICKET; - } - - return S2N_SUCCESS; -} - -/* Old-style extension functions -- remove after extensions refactor is complete */ - -int s2n_extensions_client_session_ticket_send(struct s2n_connection *conn, struct s2n_stuffer *out) -{ - return s2n_extension_send(&s2n_client_session_ticket_extension, conn, out); -} - -int s2n_recv_client_session_ticket_ext(struct s2n_connection *conn, struct s2n_stuffer *extension) -{ - return s2n_extension_recv(&s2n_client_session_ticket_extension, conn, extension); -} +/* + * 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 <sys/param.h> +#include <stdint.h> + +#include "tls/extensions/s2n_client_session_ticket.h" +#include "tls/s2n_tls.h" +#include "tls/s2n_tls_parameters.h" +#include "tls/s2n_resume.h" + +#include "utils/s2n_safety.h" + +static bool s2n_client_session_ticket_should_send(struct s2n_connection *conn); +static int s2n_client_session_ticket_send(struct s2n_connection *conn, struct s2n_stuffer *out); +static int s2n_client_session_ticket_recv(struct s2n_connection *conn, struct s2n_stuffer *extension); + +const s2n_extension_type s2n_client_session_ticket_extension = { + .iana_value = TLS_EXTENSION_SESSION_TICKET, + .is_response = false, + .send = s2n_client_session_ticket_send, + .recv = s2n_client_session_ticket_recv, + .should_send = s2n_client_session_ticket_should_send, + .if_missing = s2n_extension_noop_if_missing, +}; + +static bool s2n_client_session_ticket_should_send(struct s2n_connection *conn) +{ + return conn->config->use_tickets; +} + +static int s2n_client_session_ticket_send(struct s2n_connection *conn, struct s2n_stuffer *out) +{ + GUARD(s2n_stuffer_write(out, &conn->client_ticket)); + return S2N_SUCCESS; +} + +static int s2n_client_session_ticket_recv(struct s2n_connection *conn, struct s2n_stuffer *extension) +{ + if (conn->config->use_tickets != 1) { + /* Ignore the extension. */ + return S2N_SUCCESS; + } + + /* s2n server does not support session ticket with CLIENT_AUTH enabled */ + if (s2n_connection_is_client_auth_enabled(conn) > 0) { + return S2N_SUCCESS; + } + + if (s2n_stuffer_data_available(extension) == S2N_TICKET_SIZE_IN_BYTES) { + conn->session_ticket_status = S2N_DECRYPT_TICKET; + GUARD(s2n_stuffer_copy(extension, &conn->client_ticket_to_decrypt, S2N_TICKET_SIZE_IN_BYTES)); + } else if (s2n_config_is_encrypt_decrypt_key_available(conn->config) == 1) { + conn->session_ticket_status = S2N_NEW_TICKET; + } + + return S2N_SUCCESS; +} + +/* Old-style extension functions -- remove after extensions refactor is complete */ + +int s2n_extensions_client_session_ticket_send(struct s2n_connection *conn, struct s2n_stuffer *out) +{ + return s2n_extension_send(&s2n_client_session_ticket_extension, conn, out); +} + +int s2n_recv_client_session_ticket_ext(struct s2n_connection *conn, struct s2n_stuffer *extension) +{ + return s2n_extension_recv(&s2n_client_session_ticket_extension, conn, extension); +} diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_session_ticket.h b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_session_ticket.h index 4b3b045dcd..e0cdd7225c 100644 --- a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_session_ticket.h +++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_session_ticket.h @@ -1,25 +1,25 @@ -/* - * 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. - */ - -#pragma once - -#include "tls/s2n_connection.h" -#include "stuffer/s2n_stuffer.h" - -extern const s2n_extension_type s2n_client_session_ticket_extension; - -/* Old-style extension functions -- remove after extensions refactor is complete */ -extern int s2n_extensions_client_session_ticket_send(struct s2n_connection *conn, struct s2n_stuffer *out); -extern int s2n_recv_client_session_ticket_ext(struct s2n_connection *conn, struct s2n_stuffer *extension); +/* + * 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. + */ + +#pragma once + +#include "tls/s2n_connection.h" +#include "stuffer/s2n_stuffer.h" + +extern const s2n_extension_type s2n_client_session_ticket_extension; + +/* Old-style extension functions -- remove after extensions refactor is complete */ +extern int s2n_extensions_client_session_ticket_send(struct s2n_connection *conn, struct s2n_stuffer *out); +extern int s2n_recv_client_session_ticket_ext(struct s2n_connection *conn, struct s2n_stuffer *extension); diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_signature_algorithms.c b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_signature_algorithms.c index 9986a2cad1..6d6124a261 100644 --- a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_signature_algorithms.c +++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_signature_algorithms.c @@ -1,64 +1,64 @@ -/* - * 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 <sys/param.h> -#include <stdint.h> - -#include "tls/extensions/s2n_client_signature_algorithms.h" -#include "tls/s2n_tls.h" -#include "tls/s2n_tls_parameters.h" -#include "tls/s2n_signature_algorithms.h" - -#include "utils/s2n_safety.h" - -static bool s2n_client_signature_algorithms_should_send(struct s2n_connection *conn); -static int s2n_client_signature_algorithms_recv(struct s2n_connection *conn, struct s2n_stuffer *extension); - -const s2n_extension_type s2n_client_signature_algorithms_extension = { - .iana_value = TLS_EXTENSION_SIGNATURE_ALGORITHMS, - .is_response = false, - .send = s2n_send_supported_sig_scheme_list, - .recv = s2n_client_signature_algorithms_recv, - .should_send = s2n_client_signature_algorithms_should_send, - .if_missing = s2n_extension_noop_if_missing, -}; - -static bool s2n_client_signature_algorithms_should_send(struct s2n_connection *conn) -{ - return s2n_connection_get_protocol_version(conn) >= S2N_TLS12; -} - -static int s2n_client_signature_algorithms_recv(struct s2n_connection *conn, struct s2n_stuffer *extension) -{ - return s2n_recv_supported_sig_scheme_list(extension, &conn->handshake_params.client_sig_hash_algs); -} - -/* Old-style extension functions -- remove after extensions refactor is complete */ - -int s2n_extensions_client_signature_algorithms_send(struct s2n_connection *conn, struct s2n_stuffer *out) -{ - return s2n_extension_send(&s2n_client_signature_algorithms_extension, conn, out); -} - -int s2n_extensions_client_signature_algorithms_recv(struct s2n_connection *conn, struct s2n_stuffer *extension) -{ - return s2n_extension_recv(&s2n_client_signature_algorithms_extension, conn, extension); -} - -int s2n_extensions_client_signature_algorithms_size(struct s2n_connection *conn) -{ - /* extra 6 = 2 from extension type, 2 from extension size, 2 from list length */ - return s2n_supported_sig_scheme_list_size(conn) + 6; -} +/* + * 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 <sys/param.h> +#include <stdint.h> + +#include "tls/extensions/s2n_client_signature_algorithms.h" +#include "tls/s2n_tls.h" +#include "tls/s2n_tls_parameters.h" +#include "tls/s2n_signature_algorithms.h" + +#include "utils/s2n_safety.h" + +static bool s2n_client_signature_algorithms_should_send(struct s2n_connection *conn); +static int s2n_client_signature_algorithms_recv(struct s2n_connection *conn, struct s2n_stuffer *extension); + +const s2n_extension_type s2n_client_signature_algorithms_extension = { + .iana_value = TLS_EXTENSION_SIGNATURE_ALGORITHMS, + .is_response = false, + .send = s2n_send_supported_sig_scheme_list, + .recv = s2n_client_signature_algorithms_recv, + .should_send = s2n_client_signature_algorithms_should_send, + .if_missing = s2n_extension_noop_if_missing, +}; + +static bool s2n_client_signature_algorithms_should_send(struct s2n_connection *conn) +{ + return s2n_connection_get_protocol_version(conn) >= S2N_TLS12; +} + +static int s2n_client_signature_algorithms_recv(struct s2n_connection *conn, struct s2n_stuffer *extension) +{ + return s2n_recv_supported_sig_scheme_list(extension, &conn->handshake_params.client_sig_hash_algs); +} + +/* Old-style extension functions -- remove after extensions refactor is complete */ + +int s2n_extensions_client_signature_algorithms_send(struct s2n_connection *conn, struct s2n_stuffer *out) +{ + return s2n_extension_send(&s2n_client_signature_algorithms_extension, conn, out); +} + +int s2n_extensions_client_signature_algorithms_recv(struct s2n_connection *conn, struct s2n_stuffer *extension) +{ + return s2n_extension_recv(&s2n_client_signature_algorithms_extension, conn, extension); +} + +int s2n_extensions_client_signature_algorithms_size(struct s2n_connection *conn) +{ + /* extra 6 = 2 from extension type, 2 from extension size, 2 from list length */ + return s2n_supported_sig_scheme_list_size(conn) + 6; +} diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_signature_algorithms.h b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_signature_algorithms.h index 0832d40460..817594f6f7 100644 --- a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_signature_algorithms.h +++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_signature_algorithms.h @@ -1,27 +1,27 @@ -/* - * 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. - */ - -#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_signature_algorithms_extension; - -/* Old-style extension functions -- remove after extensions refactor is complete */ -int s2n_extensions_client_signature_algorithms_send(struct s2n_connection *conn, struct s2n_stuffer *out); -int s2n_extensions_client_signature_algorithms_recv(struct s2n_connection *conn, struct s2n_stuffer *extension); -int s2n_extensions_client_signature_algorithms_size(struct s2n_connection *conn); +/* + * 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. + */ + +#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_signature_algorithms_extension; + +/* Old-style extension functions -- remove after extensions refactor is complete */ +int s2n_extensions_client_signature_algorithms_send(struct s2n_connection *conn, struct s2n_stuffer *out); +int s2n_extensions_client_signature_algorithms_recv(struct s2n_connection *conn, struct s2n_stuffer *extension); +int s2n_extensions_client_signature_algorithms_size(struct s2n_connection *conn); diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_status_request.c b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_status_request.c index e5144fba8b..62e3df4aa8 100644 --- a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_status_request.c +++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_status_request.c @@ -1,91 +1,91 @@ -/* - * 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 <sys/param.h> -#include <stdint.h> - -#include "tls/extensions/s2n_client_status_request.h" -#include "tls/s2n_tls.h" -#include "tls/s2n_tls_parameters.h" - -#include "utils/s2n_safety.h" - -static bool s2n_client_status_request_should_send(struct s2n_connection *conn); -static int s2n_client_status_request_send(struct s2n_connection *conn, struct s2n_stuffer *out); -static int s2n_client_status_request_recv(struct s2n_connection *conn, struct s2n_stuffer *extension); - -const s2n_extension_type s2n_client_status_request_extension = { - .iana_value = TLS_EXTENSION_STATUS_REQUEST, - .is_response = false, - .send = s2n_client_status_request_send, - .recv = s2n_client_status_request_recv, - .should_send = s2n_client_status_request_should_send, - .if_missing = s2n_extension_noop_if_missing, -}; - -static bool s2n_client_status_request_should_send(struct s2n_connection *conn) -{ - return conn->config->status_request_type != S2N_STATUS_REQUEST_NONE; -} - -static int s2n_client_status_request_send(struct s2n_connection *conn, struct s2n_stuffer *out) -{ - GUARD(s2n_stuffer_write_uint8(out, (uint8_t) conn->config->status_request_type)); - - /* responder_id_list - * - * From https://tools.ietf.org/html/rfc6066#section-8: - * A zero-length "responder_id_list" sequence has the special meaning that the responders are implicitly - * known to the server, e.g., by prior arrangement */ - GUARD(s2n_stuffer_write_uint16(out, 0)); - - /* request_extensions - * - * From https://tools.ietf.org/html/rfc6066#section-8: - * A zero-length "request_extensions" value means that there are no extensions. */ - GUARD(s2n_stuffer_write_uint16(out, 0)); - - return S2N_SUCCESS; -} - -static int s2n_client_status_request_recv(struct s2n_connection *conn, struct s2n_stuffer *extension) -{ - if (s2n_stuffer_data_available(extension) < 5) { - /* Malformed length, ignore the extension */ - return S2N_SUCCESS; - } - - uint8_t type; - GUARD(s2n_stuffer_read_uint8(extension, &type)); - if (type != (uint8_t) S2N_STATUS_REQUEST_OCSP) { - /* We only support OCSP (type 1), ignore the extension */ - return S2N_SUCCESS; - } - - conn->status_type = (s2n_status_request_type) type; - return S2N_SUCCESS; -} - -/* Old-style extension functions -- remove after extensions refactor is complete */ - -int s2n_extensions_client_status_request_send(struct s2n_connection *conn, struct s2n_stuffer *out) -{ - return s2n_extension_send(&s2n_client_status_request_extension, conn, out); -} - -int s2n_recv_client_status_request(struct s2n_connection *conn, struct s2n_stuffer *extension) -{ - return s2n_extension_recv(&s2n_client_status_request_extension, conn, extension); -} +/* + * 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 <sys/param.h> +#include <stdint.h> + +#include "tls/extensions/s2n_client_status_request.h" +#include "tls/s2n_tls.h" +#include "tls/s2n_tls_parameters.h" + +#include "utils/s2n_safety.h" + +static bool s2n_client_status_request_should_send(struct s2n_connection *conn); +static int s2n_client_status_request_send(struct s2n_connection *conn, struct s2n_stuffer *out); +static int s2n_client_status_request_recv(struct s2n_connection *conn, struct s2n_stuffer *extension); + +const s2n_extension_type s2n_client_status_request_extension = { + .iana_value = TLS_EXTENSION_STATUS_REQUEST, + .is_response = false, + .send = s2n_client_status_request_send, + .recv = s2n_client_status_request_recv, + .should_send = s2n_client_status_request_should_send, + .if_missing = s2n_extension_noop_if_missing, +}; + +static bool s2n_client_status_request_should_send(struct s2n_connection *conn) +{ + return conn->config->status_request_type != S2N_STATUS_REQUEST_NONE; +} + +static int s2n_client_status_request_send(struct s2n_connection *conn, struct s2n_stuffer *out) +{ + GUARD(s2n_stuffer_write_uint8(out, (uint8_t) conn->config->status_request_type)); + + /* responder_id_list + * + * From https://tools.ietf.org/html/rfc6066#section-8: + * A zero-length "responder_id_list" sequence has the special meaning that the responders are implicitly + * known to the server, e.g., by prior arrangement */ + GUARD(s2n_stuffer_write_uint16(out, 0)); + + /* request_extensions + * + * From https://tools.ietf.org/html/rfc6066#section-8: + * A zero-length "request_extensions" value means that there are no extensions. */ + GUARD(s2n_stuffer_write_uint16(out, 0)); + + return S2N_SUCCESS; +} + +static int s2n_client_status_request_recv(struct s2n_connection *conn, struct s2n_stuffer *extension) +{ + if (s2n_stuffer_data_available(extension) < 5) { + /* Malformed length, ignore the extension */ + return S2N_SUCCESS; + } + + uint8_t type; + GUARD(s2n_stuffer_read_uint8(extension, &type)); + if (type != (uint8_t) S2N_STATUS_REQUEST_OCSP) { + /* We only support OCSP (type 1), ignore the extension */ + return S2N_SUCCESS; + } + + conn->status_type = (s2n_status_request_type) type; + return S2N_SUCCESS; +} + +/* Old-style extension functions -- remove after extensions refactor is complete */ + +int s2n_extensions_client_status_request_send(struct s2n_connection *conn, struct s2n_stuffer *out) +{ + return s2n_extension_send(&s2n_client_status_request_extension, conn, out); +} + +int s2n_recv_client_status_request(struct s2n_connection *conn, struct s2n_stuffer *extension) +{ + return s2n_extension_recv(&s2n_client_status_request_extension, conn, extension); +} diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_status_request.h b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_status_request.h index b3862755fc..f1274143da 100644 --- a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_status_request.h +++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_status_request.h @@ -1,26 +1,26 @@ -/* - * 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. - */ - -#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_status_request_extension; - -/* Old-style extension functions -- remove after extensions refactor is complete */ -extern int s2n_extensions_client_status_request_send(struct s2n_connection *conn, struct s2n_stuffer *out); -extern int s2n_recv_client_status_request(struct s2n_connection *conn, struct s2n_stuffer *extension); +/* + * 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. + */ + +#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_status_request_extension; + +/* Old-style extension functions -- remove after extensions refactor is complete */ +extern int s2n_extensions_client_status_request_send(struct s2n_connection *conn, struct s2n_stuffer *out); +extern int s2n_recv_client_status_request(struct s2n_connection *conn, struct s2n_stuffer *extension); diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_supported_groups.c b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_supported_groups.c index 9c1bf71092..d01017e244 100644 --- a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_supported_groups.c +++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_supported_groups.c @@ -1,201 +1,201 @@ -/* - * 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 <sys/param.h> -#include <stdint.h> - -#include "tls/extensions/s2n_client_supported_groups.h" -#include "tls/extensions/s2n_ec_point_format.h" - -#include "tls/s2n_tls.h" -#include "tls/s2n_tls_parameters.h" -#include "tls/s2n_security_policies.h" - -#include "utils/s2n_safety.h" -#include "crypto/s2n_fips.h" -#include "tls/s2n_tls13.h" - -static int s2n_client_supported_groups_send(struct s2n_connection *conn, struct s2n_stuffer *out); -static int s2n_client_supported_groups_recv(struct s2n_connection *conn, struct s2n_stuffer *extension); - -const s2n_extension_type s2n_client_supported_groups_extension = { - .iana_value = TLS_EXTENSION_SUPPORTED_GROUPS, - .is_response = false, - .send = s2n_client_supported_groups_send, - .recv = s2n_client_supported_groups_recv, - .should_send = s2n_extension_should_send_if_ecc_enabled, - .if_missing = s2n_extension_noop_if_missing, -}; - -bool s2n_extension_should_send_if_ecc_enabled(struct s2n_connection *conn) -{ - const struct s2n_security_policy *security_policy; - return s2n_connection_get_security_policy(conn, &security_policy) == S2N_SUCCESS - && s2n_ecc_is_extension_required(security_policy); -} - -static int s2n_client_supported_groups_send(struct s2n_connection *conn, struct s2n_stuffer *out) -{ - notnull_check(conn); - - const struct s2n_ecc_preferences *ecc_pref = NULL; - GUARD(s2n_connection_get_ecc_preferences(conn, &ecc_pref)); - notnull_check(ecc_pref); - - const struct s2n_kem_preferences *kem_pref = NULL; - GUARD(s2n_connection_get_kem_preferences(conn, &kem_pref)); - notnull_check(kem_pref); - - /* Group list len */ - struct s2n_stuffer_reservation group_list_len = { 0 }; - GUARD(s2n_stuffer_reserve_uint16(out, &group_list_len)); - - /* Send KEM groups list first */ - if (s2n_connection_get_protocol_version(conn) >= S2N_TLS13 && !s2n_is_in_fips_mode()) { - for (size_t i = 0; i < kem_pref->tls13_kem_group_count; i++) { - GUARD(s2n_stuffer_write_uint16(out, kem_pref->tls13_kem_groups[i]->iana_id)); - } - } - - /* Then send curve list */ - for (size_t i = 0; i < ecc_pref->count; i++) { - GUARD(s2n_stuffer_write_uint16(out, ecc_pref->ecc_curves[i]->iana_id)); - } - - GUARD(s2n_stuffer_write_vector_size(&group_list_len)); - - return S2N_SUCCESS; -} - -/* Populates the appropriate index of either the mutually_supported_curves or - * mutually_supported_kem_groups array based on the received IANA ID. Will - * ignore unrecognized IANA IDs (and return success). */ -static int s2n_client_supported_groups_recv_iana_id(struct s2n_connection *conn, uint16_t iana_id) { - notnull_check(conn); - - const struct s2n_ecc_preferences *ecc_pref = NULL; - GUARD(s2n_connection_get_ecc_preferences(conn, &ecc_pref)); - notnull_check(ecc_pref); - - for (size_t i = 0; i < ecc_pref->count; i++) { - const struct s2n_ecc_named_curve *supported_curve = ecc_pref->ecc_curves[i]; - if (iana_id == supported_curve->iana_id) { - conn->secure.mutually_supported_curves[i] = supported_curve; - return S2N_SUCCESS; - } - } - - /* Return early if in FIPS mode, or if TLS 1.3 is disabled, so as to ignore PQ IDs */ - if (s2n_is_in_fips_mode() || s2n_connection_get_protocol_version(conn) < S2N_TLS13) { - return S2N_SUCCESS; - } - - const struct s2n_kem_preferences *kem_pref = NULL; - GUARD(s2n_connection_get_kem_preferences(conn, &kem_pref)); - notnull_check(kem_pref); - - for (size_t i = 0; i < kem_pref->tls13_kem_group_count; i++) { - const struct s2n_kem_group *supported_kem_group = kem_pref->tls13_kem_groups[i]; - if (iana_id == supported_kem_group->iana_id) { - conn->secure.mutually_supported_kem_groups[i] = supported_kem_group; - return S2N_SUCCESS; - } - } - - return S2N_SUCCESS; -} - -static int s2n_choose_supported_group(struct s2n_connection *conn) { - notnull_check(conn); - - const struct s2n_ecc_preferences *ecc_pref = NULL; - GUARD(s2n_connection_get_ecc_preferences(conn, &ecc_pref)); - notnull_check(ecc_pref); - - const struct s2n_kem_preferences *kem_pref = NULL; - GUARD(s2n_connection_get_kem_preferences(conn, &kem_pref)); - notnull_check(kem_pref); - - /* Ensure that only the intended group will be non-NULL (if no group is chosen, everything - * should be NULL). */ - conn->secure.server_kem_group_params.kem_group = NULL; - conn->secure.server_kem_group_params.ecc_params.negotiated_curve = NULL; - conn->secure.server_kem_group_params.kem_params.kem = NULL; - conn->secure.server_ecc_evp_params.negotiated_curve = NULL; - - /* Prefer to negotiate hybrid PQ over ECC. If in FIPS mode, we will never choose a - * PQ group because the mutually_supported_kem_groups array will not have been - * populated with anything. */ - for (size_t i = 0; i < kem_pref->tls13_kem_group_count; i++) { - const struct s2n_kem_group *candidate_kem_group = conn->secure.mutually_supported_kem_groups[i]; - if (candidate_kem_group != NULL) { - conn->secure.server_kem_group_params.kem_group = candidate_kem_group; - conn->secure.server_kem_group_params.ecc_params.negotiated_curve = candidate_kem_group->curve; - conn->secure.server_kem_group_params.kem_params.kem = candidate_kem_group->kem; - return S2N_SUCCESS; - } - } - - for (size_t i = 0; i < ecc_pref->count; i++) { - const struct s2n_ecc_named_curve *candidate_curve = conn->secure.mutually_supported_curves[i]; - if (candidate_curve != NULL) { - conn->secure.server_ecc_evp_params.negotiated_curve = candidate_curve; - return S2N_SUCCESS; - } - } - - return S2N_SUCCESS; -} - -static int s2n_client_supported_groups_recv(struct s2n_connection *conn, struct s2n_stuffer *extension) { - notnull_check(conn); - notnull_check(extension); - - uint16_t size_of_all; - GUARD(s2n_stuffer_read_uint16(extension, &size_of_all)); - if (size_of_all > s2n_stuffer_data_available(extension) || (size_of_all % sizeof(uint16_t))) { - /* Malformed length, ignore the extension */ - return S2N_SUCCESS; - } - - for (size_t i = 0; i < (size_of_all / sizeof(uint16_t)); i++) { - uint16_t iana_id; - GUARD(s2n_stuffer_read_uint16(extension, &iana_id)); - GUARD(s2n_client_supported_groups_recv_iana_id(conn, iana_id)); - } - - GUARD(s2n_choose_supported_group(conn)); - - return S2N_SUCCESS; -} - -/* Old-style extension functions -- remove after extensions refactor is complete */ - -int s2n_extensions_client_supported_groups_send(struct s2n_connection *conn, struct s2n_stuffer *out) -{ - GUARD(s2n_extension_send(&s2n_client_supported_groups_extension, conn, out)); - - /* The original send method also sent ec point formats. To avoid breaking - * anything, I'm going to let it continue writing point formats. - */ - GUARD(s2n_extension_send(&s2n_client_ec_point_format_extension, conn, out)); - - return S2N_SUCCESS; -} - -int s2n_recv_client_supported_groups(struct s2n_connection *conn, struct s2n_stuffer *extension) -{ - return s2n_extension_recv(&s2n_client_supported_groups_extension, conn, extension); -} +/* + * 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 <sys/param.h> +#include <stdint.h> + +#include "tls/extensions/s2n_client_supported_groups.h" +#include "tls/extensions/s2n_ec_point_format.h" + +#include "tls/s2n_tls.h" +#include "tls/s2n_tls_parameters.h" +#include "tls/s2n_security_policies.h" + +#include "utils/s2n_safety.h" +#include "crypto/s2n_fips.h" +#include "tls/s2n_tls13.h" + +static int s2n_client_supported_groups_send(struct s2n_connection *conn, struct s2n_stuffer *out); +static int s2n_client_supported_groups_recv(struct s2n_connection *conn, struct s2n_stuffer *extension); + +const s2n_extension_type s2n_client_supported_groups_extension = { + .iana_value = TLS_EXTENSION_SUPPORTED_GROUPS, + .is_response = false, + .send = s2n_client_supported_groups_send, + .recv = s2n_client_supported_groups_recv, + .should_send = s2n_extension_should_send_if_ecc_enabled, + .if_missing = s2n_extension_noop_if_missing, +}; + +bool s2n_extension_should_send_if_ecc_enabled(struct s2n_connection *conn) +{ + const struct s2n_security_policy *security_policy; + return s2n_connection_get_security_policy(conn, &security_policy) == S2N_SUCCESS + && s2n_ecc_is_extension_required(security_policy); +} + +static int s2n_client_supported_groups_send(struct s2n_connection *conn, struct s2n_stuffer *out) +{ + notnull_check(conn); + + const struct s2n_ecc_preferences *ecc_pref = NULL; + GUARD(s2n_connection_get_ecc_preferences(conn, &ecc_pref)); + notnull_check(ecc_pref); + + const struct s2n_kem_preferences *kem_pref = NULL; + GUARD(s2n_connection_get_kem_preferences(conn, &kem_pref)); + notnull_check(kem_pref); + + /* Group list len */ + struct s2n_stuffer_reservation group_list_len = { 0 }; + GUARD(s2n_stuffer_reserve_uint16(out, &group_list_len)); + + /* Send KEM groups list first */ + if (s2n_connection_get_protocol_version(conn) >= S2N_TLS13 && !s2n_is_in_fips_mode()) { + for (size_t i = 0; i < kem_pref->tls13_kem_group_count; i++) { + GUARD(s2n_stuffer_write_uint16(out, kem_pref->tls13_kem_groups[i]->iana_id)); + } + } + + /* Then send curve list */ + for (size_t i = 0; i < ecc_pref->count; i++) { + GUARD(s2n_stuffer_write_uint16(out, ecc_pref->ecc_curves[i]->iana_id)); + } + + GUARD(s2n_stuffer_write_vector_size(&group_list_len)); + + return S2N_SUCCESS; +} + +/* Populates the appropriate index of either the mutually_supported_curves or + * mutually_supported_kem_groups array based on the received IANA ID. Will + * ignore unrecognized IANA IDs (and return success). */ +static int s2n_client_supported_groups_recv_iana_id(struct s2n_connection *conn, uint16_t iana_id) { + notnull_check(conn); + + const struct s2n_ecc_preferences *ecc_pref = NULL; + GUARD(s2n_connection_get_ecc_preferences(conn, &ecc_pref)); + notnull_check(ecc_pref); + + for (size_t i = 0; i < ecc_pref->count; i++) { + const struct s2n_ecc_named_curve *supported_curve = ecc_pref->ecc_curves[i]; + if (iana_id == supported_curve->iana_id) { + conn->secure.mutually_supported_curves[i] = supported_curve; + return S2N_SUCCESS; + } + } + + /* Return early if in FIPS mode, or if TLS 1.3 is disabled, so as to ignore PQ IDs */ + if (s2n_is_in_fips_mode() || s2n_connection_get_protocol_version(conn) < S2N_TLS13) { + return S2N_SUCCESS; + } + + const struct s2n_kem_preferences *kem_pref = NULL; + GUARD(s2n_connection_get_kem_preferences(conn, &kem_pref)); + notnull_check(kem_pref); + + for (size_t i = 0; i < kem_pref->tls13_kem_group_count; i++) { + const struct s2n_kem_group *supported_kem_group = kem_pref->tls13_kem_groups[i]; + if (iana_id == supported_kem_group->iana_id) { + conn->secure.mutually_supported_kem_groups[i] = supported_kem_group; + return S2N_SUCCESS; + } + } + + return S2N_SUCCESS; +} + +static int s2n_choose_supported_group(struct s2n_connection *conn) { + notnull_check(conn); + + const struct s2n_ecc_preferences *ecc_pref = NULL; + GUARD(s2n_connection_get_ecc_preferences(conn, &ecc_pref)); + notnull_check(ecc_pref); + + const struct s2n_kem_preferences *kem_pref = NULL; + GUARD(s2n_connection_get_kem_preferences(conn, &kem_pref)); + notnull_check(kem_pref); + + /* Ensure that only the intended group will be non-NULL (if no group is chosen, everything + * should be NULL). */ + conn->secure.server_kem_group_params.kem_group = NULL; + conn->secure.server_kem_group_params.ecc_params.negotiated_curve = NULL; + conn->secure.server_kem_group_params.kem_params.kem = NULL; + conn->secure.server_ecc_evp_params.negotiated_curve = NULL; + + /* Prefer to negotiate hybrid PQ over ECC. If in FIPS mode, we will never choose a + * PQ group because the mutually_supported_kem_groups array will not have been + * populated with anything. */ + for (size_t i = 0; i < kem_pref->tls13_kem_group_count; i++) { + const struct s2n_kem_group *candidate_kem_group = conn->secure.mutually_supported_kem_groups[i]; + if (candidate_kem_group != NULL) { + conn->secure.server_kem_group_params.kem_group = candidate_kem_group; + conn->secure.server_kem_group_params.ecc_params.negotiated_curve = candidate_kem_group->curve; + conn->secure.server_kem_group_params.kem_params.kem = candidate_kem_group->kem; + return S2N_SUCCESS; + } + } + + for (size_t i = 0; i < ecc_pref->count; i++) { + const struct s2n_ecc_named_curve *candidate_curve = conn->secure.mutually_supported_curves[i]; + if (candidate_curve != NULL) { + conn->secure.server_ecc_evp_params.negotiated_curve = candidate_curve; + return S2N_SUCCESS; + } + } + + return S2N_SUCCESS; +} + +static int s2n_client_supported_groups_recv(struct s2n_connection *conn, struct s2n_stuffer *extension) { + notnull_check(conn); + notnull_check(extension); + + uint16_t size_of_all; + GUARD(s2n_stuffer_read_uint16(extension, &size_of_all)); + if (size_of_all > s2n_stuffer_data_available(extension) || (size_of_all % sizeof(uint16_t))) { + /* Malformed length, ignore the extension */ + return S2N_SUCCESS; + } + + for (size_t i = 0; i < (size_of_all / sizeof(uint16_t)); i++) { + uint16_t iana_id; + GUARD(s2n_stuffer_read_uint16(extension, &iana_id)); + GUARD(s2n_client_supported_groups_recv_iana_id(conn, iana_id)); + } + + GUARD(s2n_choose_supported_group(conn)); + + return S2N_SUCCESS; +} + +/* Old-style extension functions -- remove after extensions refactor is complete */ + +int s2n_extensions_client_supported_groups_send(struct s2n_connection *conn, struct s2n_stuffer *out) +{ + GUARD(s2n_extension_send(&s2n_client_supported_groups_extension, conn, out)); + + /* The original send method also sent ec point formats. To avoid breaking + * anything, I'm going to let it continue writing point formats. + */ + GUARD(s2n_extension_send(&s2n_client_ec_point_format_extension, conn, out)); + + return S2N_SUCCESS; +} + +int s2n_recv_client_supported_groups(struct s2n_connection *conn, struct s2n_stuffer *extension) +{ + return s2n_extension_recv(&s2n_client_supported_groups_extension, conn, extension); +} diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_supported_groups.h b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_supported_groups.h index e5b798543e..d1590938b8 100644 --- a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_supported_groups.h +++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_supported_groups.h @@ -1,27 +1,27 @@ -/* - * 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. - */ - -#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_supported_groups_extension; -bool s2n_extension_should_send_if_ecc_enabled(struct s2n_connection *conn); - -/* Old-style extension functions -- remove after extensions refactor is complete */ -int s2n_extensions_client_supported_groups_send(struct s2n_connection *conn, struct s2n_stuffer *out); -int s2n_recv_client_supported_groups(struct s2n_connection *conn, struct s2n_stuffer *extension); +/* + * 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. + */ + +#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_supported_groups_extension; +bool s2n_extension_should_send_if_ecc_enabled(struct s2n_connection *conn); + +/* Old-style extension functions -- remove after extensions refactor is complete */ +int s2n_extensions_client_supported_groups_send(struct s2n_connection *conn, struct s2n_stuffer *out); +int s2n_recv_client_supported_groups(struct s2n_connection *conn, struct s2n_stuffer *extension); diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_supported_versions.c b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_supported_versions.c index d0ec8cb329..3b686e12f6 100644 --- a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_supported_versions.c +++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_supported_versions.c @@ -1,153 +1,153 @@ -/* - * 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 <sys/param.h> -#include <stdint.h> - -#include "tls/extensions/s2n_client_supported_versions.h" -#include "tls/extensions/s2n_supported_versions.h" -#include "tls/s2n_alerts.h" -#include "tls/s2n_cipher_preferences.h" -#include "tls/s2n_tls.h" -#include "tls/s2n_tls_parameters.h" - -#include "utils/s2n_safety.h" - -/** - * Specified in https://tools.ietf.org/html/rfc8446#section-4.2.1 - * - * "The "supported_versions" extension is used by the client to indicate - * which versions of TLS it supports and by the server to indicate which - * version it is using. The extension contains a list of supported - * versions in preference order, with the most preferred version first." - * - * Structure: - * Extension type (2 bytes) - * Extension size (2 bytes) - * Version list length (1 byte) - * Version list (number of versions * 2 bytes) - * - * Note: We assume in these functions that the supported version numbers - * are consecutive. This is true because S2N does not support SSLv2, and - * is already an assumption made in the old client hello version handling. - **/ - -static int s2n_client_supported_versions_send(struct s2n_connection *conn, struct s2n_stuffer *out); -static int s2n_client_supported_versions_recv(struct s2n_connection *conn, struct s2n_stuffer *in); - -const s2n_extension_type s2n_client_supported_versions_extension = { - .iana_value = TLS_EXTENSION_SUPPORTED_VERSIONS, - .is_response = false, - .send = s2n_client_supported_versions_send, - .recv = s2n_client_supported_versions_recv, - .should_send = s2n_extension_send_if_tls13_connection, - .if_missing = s2n_extension_noop_if_missing, -}; - -static int s2n_client_supported_versions_send(struct s2n_connection *conn, struct s2n_stuffer *out) -{ - uint8_t highest_supported_version = conn->client_protocol_version; - uint8_t minimum_supported_version; - GUARD(s2n_connection_get_minimum_supported_version(conn, &minimum_supported_version)); - - uint8_t version_list_length = highest_supported_version - minimum_supported_version + 1; - GUARD(s2n_stuffer_write_uint8(out, version_list_length * S2N_TLS_PROTOCOL_VERSION_LEN)); - - for (uint8_t i = highest_supported_version; i >= minimum_supported_version; i--) { - GUARD(s2n_stuffer_write_uint8(out, i / 10)); - GUARD(s2n_stuffer_write_uint8(out, i % 10)); - } - - return S2N_SUCCESS; -} - -static int s2n_extensions_client_supported_versions_process(struct s2n_connection *conn, struct s2n_stuffer *extension) { - uint8_t highest_supported_version = conn->server_protocol_version; - uint8_t minimum_supported_version; - GUARD(s2n_connection_get_minimum_supported_version(conn, &minimum_supported_version)); - - uint8_t size_of_version_list; - GUARD(s2n_stuffer_read_uint8(extension, &size_of_version_list)); - S2N_ERROR_IF(size_of_version_list != s2n_stuffer_data_available(extension), S2N_ERR_BAD_MESSAGE); - S2N_ERROR_IF(size_of_version_list % S2N_TLS_PROTOCOL_VERSION_LEN != 0, S2N_ERR_BAD_MESSAGE); - - conn->client_protocol_version = s2n_unknown_protocol_version; - conn->actual_protocol_version = s2n_unknown_protocol_version; - - for (int i = 0; i < size_of_version_list; i += S2N_TLS_PROTOCOL_VERSION_LEN) { - uint8_t client_version_parts[S2N_TLS_PROTOCOL_VERSION_LEN]; - GUARD(s2n_stuffer_read_bytes(extension, client_version_parts, S2N_TLS_PROTOCOL_VERSION_LEN)); - - /* If the client version is outside of our supported versions, then ignore the value. - * S2N does not support SSLv2 except for upgrading connections. Since this extension is - * a TLS1.3 extension, we will skip any SSLv2 values. */ - if (client_version_parts[0] != 3 || client_version_parts[1] > 4) { - continue; - } - - uint16_t client_version = (client_version_parts[0] * 10) + client_version_parts[1]; - - conn->client_protocol_version = MAX(client_version, conn->client_protocol_version); - - if (client_version > highest_supported_version) { - continue; - } - - if (client_version < minimum_supported_version) { - continue; - } - - /* We ignore the client's preferred order and instead choose - * the highest version that both client and server support. */ - conn->actual_protocol_version = MAX(client_version, conn->actual_protocol_version); - } - - S2N_ERROR_IF(conn->actual_protocol_version == s2n_unknown_protocol_version, S2N_ERR_UNKNOWN_PROTOCOL_VERSION); - - return S2N_SUCCESS; -} - -static int s2n_client_supported_versions_recv(struct s2n_connection *conn, struct s2n_stuffer *in) -{ - if (s2n_connection_get_protocol_version(conn) < S2N_TLS13) { - return S2N_SUCCESS; - } - - if (s2n_extensions_client_supported_versions_process(conn, in) < 0) { - s2n_queue_reader_unsupported_protocol_version_alert(conn); - S2N_ERROR(S2N_ERR_BAD_MESSAGE); - } - return S2N_SUCCESS; -} - -/* Old-style extension functions -- remove after extensions refactor is complete */ - -int s2n_extensions_client_supported_versions_size(struct s2n_connection *conn) { - uint8_t minimum_supported_version; - GUARD(s2n_connection_get_minimum_supported_version(conn, &minimum_supported_version)); - uint8_t highest_supported_version = conn->client_protocol_version; - - uint8_t version_list_length = highest_supported_version - minimum_supported_version + 1; - - return version_list_length * S2N_TLS_PROTOCOL_VERSION_LEN + 5; -} - -int s2n_extensions_client_supported_versions_recv(struct s2n_connection *conn, struct s2n_stuffer *extension) { - return s2n_extension_recv(&s2n_client_supported_versions_extension, conn, extension); -} - -int s2n_extensions_client_supported_versions_send(struct s2n_connection *conn, struct s2n_stuffer *out) { - return s2n_extension_send(&s2n_client_supported_versions_extension, conn, out); -} +/* + * 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 <sys/param.h> +#include <stdint.h> + +#include "tls/extensions/s2n_client_supported_versions.h" +#include "tls/extensions/s2n_supported_versions.h" +#include "tls/s2n_alerts.h" +#include "tls/s2n_cipher_preferences.h" +#include "tls/s2n_tls.h" +#include "tls/s2n_tls_parameters.h" + +#include "utils/s2n_safety.h" + +/** + * Specified in https://tools.ietf.org/html/rfc8446#section-4.2.1 + * + * "The "supported_versions" extension is used by the client to indicate + * which versions of TLS it supports and by the server to indicate which + * version it is using. The extension contains a list of supported + * versions in preference order, with the most preferred version first." + * + * Structure: + * Extension type (2 bytes) + * Extension size (2 bytes) + * Version list length (1 byte) + * Version list (number of versions * 2 bytes) + * + * Note: We assume in these functions that the supported version numbers + * are consecutive. This is true because S2N does not support SSLv2, and + * is already an assumption made in the old client hello version handling. + **/ + +static int s2n_client_supported_versions_send(struct s2n_connection *conn, struct s2n_stuffer *out); +static int s2n_client_supported_versions_recv(struct s2n_connection *conn, struct s2n_stuffer *in); + +const s2n_extension_type s2n_client_supported_versions_extension = { + .iana_value = TLS_EXTENSION_SUPPORTED_VERSIONS, + .is_response = false, + .send = s2n_client_supported_versions_send, + .recv = s2n_client_supported_versions_recv, + .should_send = s2n_extension_send_if_tls13_connection, + .if_missing = s2n_extension_noop_if_missing, +}; + +static int s2n_client_supported_versions_send(struct s2n_connection *conn, struct s2n_stuffer *out) +{ + uint8_t highest_supported_version = conn->client_protocol_version; + uint8_t minimum_supported_version; + GUARD(s2n_connection_get_minimum_supported_version(conn, &minimum_supported_version)); + + uint8_t version_list_length = highest_supported_version - minimum_supported_version + 1; + GUARD(s2n_stuffer_write_uint8(out, version_list_length * S2N_TLS_PROTOCOL_VERSION_LEN)); + + for (uint8_t i = highest_supported_version; i >= minimum_supported_version; i--) { + GUARD(s2n_stuffer_write_uint8(out, i / 10)); + GUARD(s2n_stuffer_write_uint8(out, i % 10)); + } + + return S2N_SUCCESS; +} + +static int s2n_extensions_client_supported_versions_process(struct s2n_connection *conn, struct s2n_stuffer *extension) { + uint8_t highest_supported_version = conn->server_protocol_version; + uint8_t minimum_supported_version; + GUARD(s2n_connection_get_minimum_supported_version(conn, &minimum_supported_version)); + + uint8_t size_of_version_list; + GUARD(s2n_stuffer_read_uint8(extension, &size_of_version_list)); + S2N_ERROR_IF(size_of_version_list != s2n_stuffer_data_available(extension), S2N_ERR_BAD_MESSAGE); + S2N_ERROR_IF(size_of_version_list % S2N_TLS_PROTOCOL_VERSION_LEN != 0, S2N_ERR_BAD_MESSAGE); + + conn->client_protocol_version = s2n_unknown_protocol_version; + conn->actual_protocol_version = s2n_unknown_protocol_version; + + for (int i = 0; i < size_of_version_list; i += S2N_TLS_PROTOCOL_VERSION_LEN) { + uint8_t client_version_parts[S2N_TLS_PROTOCOL_VERSION_LEN]; + GUARD(s2n_stuffer_read_bytes(extension, client_version_parts, S2N_TLS_PROTOCOL_VERSION_LEN)); + + /* If the client version is outside of our supported versions, then ignore the value. + * S2N does not support SSLv2 except for upgrading connections. Since this extension is + * a TLS1.3 extension, we will skip any SSLv2 values. */ + if (client_version_parts[0] != 3 || client_version_parts[1] > 4) { + continue; + } + + uint16_t client_version = (client_version_parts[0] * 10) + client_version_parts[1]; + + conn->client_protocol_version = MAX(client_version, conn->client_protocol_version); + + if (client_version > highest_supported_version) { + continue; + } + + if (client_version < minimum_supported_version) { + continue; + } + + /* We ignore the client's preferred order and instead choose + * the highest version that both client and server support. */ + conn->actual_protocol_version = MAX(client_version, conn->actual_protocol_version); + } + + S2N_ERROR_IF(conn->actual_protocol_version == s2n_unknown_protocol_version, S2N_ERR_UNKNOWN_PROTOCOL_VERSION); + + return S2N_SUCCESS; +} + +static int s2n_client_supported_versions_recv(struct s2n_connection *conn, struct s2n_stuffer *in) +{ + if (s2n_connection_get_protocol_version(conn) < S2N_TLS13) { + return S2N_SUCCESS; + } + + if (s2n_extensions_client_supported_versions_process(conn, in) < 0) { + s2n_queue_reader_unsupported_protocol_version_alert(conn); + S2N_ERROR(S2N_ERR_BAD_MESSAGE); + } + return S2N_SUCCESS; +} + +/* Old-style extension functions -- remove after extensions refactor is complete */ + +int s2n_extensions_client_supported_versions_size(struct s2n_connection *conn) { + uint8_t minimum_supported_version; + GUARD(s2n_connection_get_minimum_supported_version(conn, &minimum_supported_version)); + uint8_t highest_supported_version = conn->client_protocol_version; + + uint8_t version_list_length = highest_supported_version - minimum_supported_version + 1; + + return version_list_length * S2N_TLS_PROTOCOL_VERSION_LEN + 5; +} + +int s2n_extensions_client_supported_versions_recv(struct s2n_connection *conn, struct s2n_stuffer *extension) { + return s2n_extension_recv(&s2n_client_supported_versions_extension, conn, extension); +} + +int s2n_extensions_client_supported_versions_send(struct s2n_connection *conn, struct s2n_stuffer *out) { + return s2n_extension_send(&s2n_client_supported_versions_extension, conn, out); +} diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_supported_versions.h b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_supported_versions.h index b9deabe628..c3657953c9 100644 --- a/contrib/restricted/aws/s2n/tls/extensions/s2n_client_supported_versions.h +++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_client_supported_versions.h @@ -1,26 +1,26 @@ -/* - * 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. - */ - -#pragma once - -#include "tls/s2n_connection.h" -#include "stuffer/s2n_stuffer.h" - -extern const s2n_extension_type s2n_client_supported_versions_extension; - -/* Old-style extension functions -- remove after extensions refactor is complete */ -extern int s2n_extensions_client_supported_versions_recv(struct s2n_connection *conn, struct s2n_stuffer *extension); -extern int s2n_extensions_client_supported_versions_size(struct s2n_connection *conn); -extern int s2n_extensions_client_supported_versions_send(struct s2n_connection *conn, struct s2n_stuffer *out); +/* + * 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. + */ + +#pragma once + +#include "tls/s2n_connection.h" +#include "stuffer/s2n_stuffer.h" + +extern const s2n_extension_type s2n_client_supported_versions_extension; + +/* Old-style extension functions -- remove after extensions refactor is complete */ +extern int s2n_extensions_client_supported_versions_recv(struct s2n_connection *conn, struct s2n_stuffer *extension); +extern int s2n_extensions_client_supported_versions_size(struct s2n_connection *conn); +extern int s2n_extensions_client_supported_versions_send(struct s2n_connection *conn, struct s2n_stuffer *out); diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_cookie.c b/contrib/restricted/aws/s2n/tls/extensions/s2n_cookie.c index 7e8885bc0b..add1f64269 100644 --- a/contrib/restricted/aws/s2n/tls/extensions/s2n_cookie.c +++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_cookie.c @@ -1,103 +1,103 @@ -/* - * 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, - .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, - .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 s2n_extension_send_if_tls13_connection(conn) - && conn && s2n_stuffer_data_available(&conn->cookie_stuffer) > 0; -} - -static int s2n_cookie_send(struct s2n_connection *conn, struct s2n_stuffer *out) -{ - notnull_check(conn); - uint16_t cookie_size = s2n_stuffer_data_available(&conn->cookie_stuffer); - GUARD(s2n_stuffer_write_uint16(out, cookie_size)); - 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) -{ - notnull_check(conn); - if (s2n_connection_get_protocol_version(conn) < S2N_TLS13) { - return S2N_SUCCESS; - } - - uint16_t cookie_len; - GUARD(s2n_stuffer_read_uint16(extension, &cookie_len)); - ENSURE_POSIX(s2n_stuffer_data_available(extension) == cookie_len, S2N_ERR_BAD_MESSAGE); - - GUARD(s2n_stuffer_wipe(&conn->cookie_stuffer)); - GUARD(s2n_stuffer_resize(&conn->cookie_stuffer, cookie_len)); - 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) -{ - 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); -} +/* + * 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, + .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, + .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 s2n_extension_send_if_tls13_connection(conn) + && conn && s2n_stuffer_data_available(&conn->cookie_stuffer) > 0; +} + +static int s2n_cookie_send(struct s2n_connection *conn, struct s2n_stuffer *out) +{ + notnull_check(conn); + uint16_t cookie_size = s2n_stuffer_data_available(&conn->cookie_stuffer); + GUARD(s2n_stuffer_write_uint16(out, cookie_size)); + 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) +{ + notnull_check(conn); + if (s2n_connection_get_protocol_version(conn) < S2N_TLS13) { + return S2N_SUCCESS; + } + + uint16_t cookie_len; + GUARD(s2n_stuffer_read_uint16(extension, &cookie_len)); + ENSURE_POSIX(s2n_stuffer_data_available(extension) == cookie_len, S2N_ERR_BAD_MESSAGE); + + GUARD(s2n_stuffer_wipe(&conn->cookie_stuffer)); + GUARD(s2n_stuffer_resize(&conn->cookie_stuffer, cookie_len)); + 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) +{ + 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..115226d9d4 100644 --- a/contrib/restricted/aws/s2n/tls/extensions/s2n_cookie.h +++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_cookie.h @@ -1,29 +1,29 @@ -/* - * 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. - */ - - -#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); +/* + * 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. + */ + + +#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); diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_ec_point_format.c b/contrib/restricted/aws/s2n/tls/extensions/s2n_ec_point_format.c index cb720581a6..ac6a162efb 100644 --- a/contrib/restricted/aws/s2n/tls/extensions/s2n_ec_point_format.c +++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_ec_point_format.c @@ -1,91 +1,91 @@ -/* - * 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 <sys/param.h> -#include <stdint.h> - -#include "tls/extensions/s2n_client_supported_groups.h" -#include "tls/extensions/s2n_ec_point_format.h" -#include "tls/s2n_tls.h" - -#include "utils/s2n_safety.h" - -static int s2n_ec_point_format_send(struct s2n_connection *conn, struct s2n_stuffer *out); -static int s2n_ec_point_format_recv(struct s2n_connection *conn, struct s2n_stuffer *extension); - -const s2n_extension_type s2n_client_ec_point_format_extension = { - .iana_value = TLS_EXTENSION_EC_POINT_FORMATS, - .is_response = false, - .send = s2n_ec_point_format_send, - .recv = s2n_ec_point_format_recv, - .should_send = s2n_extension_should_send_if_ecc_enabled, - .if_missing = s2n_extension_noop_if_missing, -}; - -static bool s2n_server_ec_point_format_should_send(struct s2n_connection *conn); - -const s2n_extension_type s2n_server_ec_point_format_extension = { - .iana_value = TLS_EXTENSION_EC_POINT_FORMATS, - .is_response = true, - .send = s2n_ec_point_format_send, - .recv = s2n_extension_recv_noop, - .should_send = s2n_server_ec_point_format_should_send, - .if_missing = s2n_extension_noop_if_missing, -}; - -static bool s2n_server_ec_point_format_should_send(struct s2n_connection *conn) -{ - return conn && conn->secure.cipher_suite - && s2n_kex_includes(conn->secure.cipher_suite->key_exchange_alg, &s2n_ecdhe); -} - -static int s2n_ec_point_format_send(struct s2n_connection *conn, struct s2n_stuffer *out) -{ - /* Point format list len. We only support one. */ - GUARD(s2n_stuffer_write_uint8(out, 1)); - - /* Only allow uncompressed format */ - GUARD(s2n_stuffer_write_uint8(out, TLS_EC_POINT_FORMAT_UNCOMPRESSED)); - - return S2N_SUCCESS; -} - -static int s2n_ec_point_format_recv(struct s2n_connection *conn, struct s2n_stuffer *extension) -{ - /** - * Only uncompressed points are supported by the server and the client must include it in - * the extension. Just skip the extension. - */ - conn->ec_point_formats = 1; - return S2N_SUCCESS; -} - -/* Old-style extension functions -- remove after extensions refactor is complete */ - -int s2n_server_ecc_point_format_extension_size(struct s2n_connection *conn) -{ - if (s2n_server_ec_point_format_extension.should_send(conn) && s2n_server_can_send_ec_point_formats(conn)) { - return sizeof(uint16_t) /* extension type */ - + sizeof(uint16_t) /* extension size */ - + sizeof(uint8_t) /* point list size */ - + sizeof(uint8_t); /* point */ - } - return 0; -} - -int s2n_recv_client_ec_point_formats(struct s2n_connection *conn, struct s2n_stuffer *extension) -{ - return s2n_extension_recv(&s2n_client_ec_point_format_extension, conn, extension); -} +/* + * 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 <sys/param.h> +#include <stdint.h> + +#include "tls/extensions/s2n_client_supported_groups.h" +#include "tls/extensions/s2n_ec_point_format.h" +#include "tls/s2n_tls.h" + +#include "utils/s2n_safety.h" + +static int s2n_ec_point_format_send(struct s2n_connection *conn, struct s2n_stuffer *out); +static int s2n_ec_point_format_recv(struct s2n_connection *conn, struct s2n_stuffer *extension); + +const s2n_extension_type s2n_client_ec_point_format_extension = { + .iana_value = TLS_EXTENSION_EC_POINT_FORMATS, + .is_response = false, + .send = s2n_ec_point_format_send, + .recv = s2n_ec_point_format_recv, + .should_send = s2n_extension_should_send_if_ecc_enabled, + .if_missing = s2n_extension_noop_if_missing, +}; + +static bool s2n_server_ec_point_format_should_send(struct s2n_connection *conn); + +const s2n_extension_type s2n_server_ec_point_format_extension = { + .iana_value = TLS_EXTENSION_EC_POINT_FORMATS, + .is_response = true, + .send = s2n_ec_point_format_send, + .recv = s2n_extension_recv_noop, + .should_send = s2n_server_ec_point_format_should_send, + .if_missing = s2n_extension_noop_if_missing, +}; + +static bool s2n_server_ec_point_format_should_send(struct s2n_connection *conn) +{ + return conn && conn->secure.cipher_suite + && s2n_kex_includes(conn->secure.cipher_suite->key_exchange_alg, &s2n_ecdhe); +} + +static int s2n_ec_point_format_send(struct s2n_connection *conn, struct s2n_stuffer *out) +{ + /* Point format list len. We only support one. */ + GUARD(s2n_stuffer_write_uint8(out, 1)); + + /* Only allow uncompressed format */ + GUARD(s2n_stuffer_write_uint8(out, TLS_EC_POINT_FORMAT_UNCOMPRESSED)); + + return S2N_SUCCESS; +} + +static int s2n_ec_point_format_recv(struct s2n_connection *conn, struct s2n_stuffer *extension) +{ + /** + * Only uncompressed points are supported by the server and the client must include it in + * the extension. Just skip the extension. + */ + conn->ec_point_formats = 1; + return S2N_SUCCESS; +} + +/* Old-style extension functions -- remove after extensions refactor is complete */ + +int s2n_server_ecc_point_format_extension_size(struct s2n_connection *conn) +{ + if (s2n_server_ec_point_format_extension.should_send(conn) && s2n_server_can_send_ec_point_formats(conn)) { + return sizeof(uint16_t) /* extension type */ + + sizeof(uint16_t) /* extension size */ + + sizeof(uint8_t) /* point list size */ + + sizeof(uint8_t); /* point */ + } + return 0; +} + +int s2n_recv_client_ec_point_formats(struct s2n_connection *conn, struct s2n_stuffer *extension) +{ + return s2n_extension_recv(&s2n_client_ec_point_format_extension, conn, extension); +} diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_ec_point_format.h b/contrib/restricted/aws/s2n/tls/extensions/s2n_ec_point_format.h index 4e7cf3065d..ac01ad7672 100644 --- a/contrib/restricted/aws/s2n/tls/extensions/s2n_ec_point_format.h +++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_ec_point_format.h @@ -1,29 +1,29 @@ -/* - * 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. - */ - -#pragma once - -#include "tls/extensions/s2n_extension_type.h" -#include "tls/s2n_connection.h" -#include "stuffer/s2n_stuffer.h" - -#define TLS_EC_POINT_FORMAT_UNCOMPRESSED 0 - -extern const s2n_extension_type s2n_client_ec_point_format_extension; -extern const s2n_extension_type s2n_server_ec_point_format_extension; - -/* Old-style extension functions -- remove after extensions refactor is complete */ -int s2n_server_ecc_point_format_extension_size(struct s2n_connection *conn); -int s2n_recv_client_ec_point_formats(struct s2n_connection *conn, struct s2n_stuffer *extension); +/* + * 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. + */ + +#pragma once + +#include "tls/extensions/s2n_extension_type.h" +#include "tls/s2n_connection.h" +#include "stuffer/s2n_stuffer.h" + +#define TLS_EC_POINT_FORMAT_UNCOMPRESSED 0 + +extern const s2n_extension_type s2n_client_ec_point_format_extension; +extern const s2n_extension_type s2n_server_ec_point_format_extension; + +/* Old-style extension functions -- remove after extensions refactor is complete */ +int s2n_server_ecc_point_format_extension_size(struct s2n_connection *conn); +int s2n_recv_client_ec_point_formats(struct s2n_connection *conn, struct s2n_stuffer *extension); diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_extension_list.c b/contrib/restricted/aws/s2n/tls/extensions/s2n_extension_list.c index 81c9e9bf5a..11c840d66a 100644 --- a/contrib/restricted/aws/s2n/tls/extensions/s2n_extension_list.c +++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_extension_list.c @@ -1,184 +1,184 @@ -/* - * 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 "s2n_extension_list.h" -#include "s2n_extension_type.h" -#include "s2n_extension_type_lists.h" - -#include <s2n.h> - -#include "error/s2n_errno.h" -#include "utils/s2n_safety.h" - -#define s2n_parsed_extension_is_empty(parsed_extension) ((parsed_extension)->extension.data == NULL) - -static const s2n_parsed_extension empty_parsed_extensions[S2N_PARSED_EXTENSIONS_COUNT] = { 0 }; - -int s2n_extension_list_send(s2n_extension_list_id list_type, struct s2n_connection *conn, struct s2n_stuffer *out) -{ - s2n_extension_type_list *extension_type_list; - GUARD(s2n_extension_type_list_get(list_type, &extension_type_list)); - - struct s2n_stuffer_reservation total_extensions_size = {0}; - GUARD(s2n_stuffer_reserve_uint16(out, &total_extensions_size)); - - for (int i = 0; i < extension_type_list->count; i++) { - GUARD(s2n_extension_send(extension_type_list->extension_types[i], conn, out)); - } - - GUARD(s2n_stuffer_write_vector_size(&total_extensions_size)); - return S2N_SUCCESS; -} - -int s2n_extension_list_recv(s2n_extension_list_id list_type, struct s2n_connection *conn, struct s2n_stuffer *in) -{ - s2n_parsed_extensions_list parsed_extension_list = { 0 }; - GUARD(s2n_extension_list_parse(in, &parsed_extension_list)); - GUARD(s2n_extension_list_process(list_type, conn, &parsed_extension_list)); - return S2N_SUCCESS; -} - -static int s2n_extension_process_impl(const s2n_extension_type *extension_type, s2n_extension_type_id extension_id, - struct s2n_connection *conn, s2n_parsed_extension *parsed_extensions) -{ - notnull_check(extension_type); - notnull_check(parsed_extensions); - - if (s2n_parsed_extension_is_empty(&parsed_extensions[extension_id])) { - GUARD(s2n_extension_is_missing(extension_type, conn)); - return S2N_SUCCESS; - } - - ENSURE_POSIX(parsed_extensions[extension_id].extension_type == extension_type->iana_value, - S2N_ERR_INVALID_PARSED_EXTENSIONS); - - struct s2n_stuffer extension_stuffer; - GUARD(s2n_stuffer_init(&extension_stuffer, &parsed_extensions[extension_id].extension)); - GUARD(s2n_stuffer_skip_write(&extension_stuffer, parsed_extensions[extension_id].extension.size)); - - GUARD(s2n_extension_recv(extension_type, conn, &extension_stuffer)); - - return S2N_SUCCESS; -} - -int s2n_extension_process(const s2n_extension_type *extension_type, struct s2n_connection *conn, - s2n_parsed_extensions_list *parsed_extension_list) -{ - notnull_check(parsed_extension_list); - notnull_check(extension_type); - - s2n_extension_type_id extension_id; - GUARD(s2n_extension_supported_iana_value_to_id(extension_type->iana_value, &extension_id)); - - int result = s2n_extension_process_impl(extension_type, extension_id, conn, parsed_extension_list->parsed_extensions); - - /* Wipe parsed_extension. - * We can check for unprocessed extensions later by checking for non-blank parsed_extensions. */ - parsed_extension_list->parsed_extensions[extension_id] = empty_parsed_extensions[0]; - - return result; -} - -int s2n_extension_list_process(s2n_extension_list_id list_type, struct s2n_connection *conn, - s2n_parsed_extensions_list *parsed_extension_list) -{ - notnull_check(parsed_extension_list); - - s2n_extension_type_list *extension_type_list; - GUARD(s2n_extension_type_list_get(list_type, &extension_type_list)); - - for (int i = 0; i < extension_type_list->count; i++) { - GUARD(s2n_extension_process(extension_type_list->extension_types[i], - conn, parsed_extension_list)); - } - - /* If parsed_extension_list.parsed_extensions is not completely wiped at this point, - * then we have received an extension not allowed on this message type. - * - * According to the RFC, we should alert and close the connection. - * From https://tools.ietf.org/html/rfc8446#section-4.2: - * If an implementation receives an extension which it recognizes and which is not - * specified for the message in which it appears, it MUST abort the handshake with an - * "illegal_parameter" alert. - * - * However, to be more tolerant of non-compliant peers, we will just ignore and not - * process the illegal extensions, treating them as if they are unsupported. - */ - - return S2N_SUCCESS; -} - -static int s2n_extension_parse(struct s2n_stuffer *in, s2n_parsed_extension *parsed_extensions) -{ - notnull_check(parsed_extensions); - - uint16_t extension_type; - ENSURE_POSIX(s2n_stuffer_read_uint16(in, &extension_type) == S2N_SUCCESS, - S2N_ERR_BAD_MESSAGE); - - uint16_t extension_size; - ENSURE_POSIX(s2n_stuffer_read_uint16(in, &extension_size) == S2N_SUCCESS, - S2N_ERR_BAD_MESSAGE); - - uint8_t *extension_data = s2n_stuffer_raw_read(in, extension_size); - ENSURE_POSIX(extension_data != NULL, S2N_ERR_BAD_MESSAGE); - - s2n_extension_type_id extension_id; - if (s2n_extension_supported_iana_value_to_id(extension_type, &extension_id) != S2N_SUCCESS) { - /* Ignore unknown extensions */ - return S2N_SUCCESS; - } - - s2n_parsed_extension *parsed_extension = &parsed_extensions[extension_id]; - - /* Error if extension is a duplicate */ - ENSURE_POSIX(s2n_parsed_extension_is_empty(parsed_extension), - S2N_ERR_DUPLICATE_EXTENSION); - - /* Fill in parsed extension */ - parsed_extension->extension_type = extension_type; - GUARD(s2n_blob_init(&parsed_extension->extension, extension_data, extension_size)); - - return S2N_SUCCESS; -} - -int s2n_extension_list_parse(struct s2n_stuffer *in, s2n_parsed_extensions_list *parsed_extension_list) -{ - notnull_check(in); - notnull_check(parsed_extension_list); - - memset_check((s2n_parsed_extension*) parsed_extension_list->parsed_extensions, - 0, sizeof(parsed_extension_list->parsed_extensions)); - - uint16_t total_extensions_size; - if (s2n_stuffer_read_uint16(in, &total_extensions_size) != S2N_SUCCESS) { - total_extensions_size = 0; - } - - uint8_t *extensions_data = s2n_stuffer_raw_read(in, total_extensions_size); - ENSURE_POSIX(extensions_data != NULL, S2N_ERR_BAD_MESSAGE); - - GUARD(s2n_blob_init(&parsed_extension_list->raw, extensions_data, total_extensions_size)); - - struct s2n_stuffer extensions_stuffer; - GUARD(s2n_stuffer_init(&extensions_stuffer, &parsed_extension_list->raw)); - GUARD(s2n_stuffer_skip_write(&extensions_stuffer, total_extensions_size)); - - while (s2n_stuffer_data_available(&extensions_stuffer)) { - GUARD(s2n_extension_parse(&extensions_stuffer, parsed_extension_list->parsed_extensions)); - } - - return S2N_SUCCESS; -} +/* + * 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 "s2n_extension_list.h" +#include "s2n_extension_type.h" +#include "s2n_extension_type_lists.h" + +#include <s2n.h> + +#include "error/s2n_errno.h" +#include "utils/s2n_safety.h" + +#define s2n_parsed_extension_is_empty(parsed_extension) ((parsed_extension)->extension.data == NULL) + +static const s2n_parsed_extension empty_parsed_extensions[S2N_PARSED_EXTENSIONS_COUNT] = { 0 }; + +int s2n_extension_list_send(s2n_extension_list_id list_type, struct s2n_connection *conn, struct s2n_stuffer *out) +{ + s2n_extension_type_list *extension_type_list; + GUARD(s2n_extension_type_list_get(list_type, &extension_type_list)); + + struct s2n_stuffer_reservation total_extensions_size = {0}; + GUARD(s2n_stuffer_reserve_uint16(out, &total_extensions_size)); + + for (int i = 0; i < extension_type_list->count; i++) { + GUARD(s2n_extension_send(extension_type_list->extension_types[i], conn, out)); + } + + GUARD(s2n_stuffer_write_vector_size(&total_extensions_size)); + return S2N_SUCCESS; +} + +int s2n_extension_list_recv(s2n_extension_list_id list_type, struct s2n_connection *conn, struct s2n_stuffer *in) +{ + s2n_parsed_extensions_list parsed_extension_list = { 0 }; + GUARD(s2n_extension_list_parse(in, &parsed_extension_list)); + GUARD(s2n_extension_list_process(list_type, conn, &parsed_extension_list)); + return S2N_SUCCESS; +} + +static int s2n_extension_process_impl(const s2n_extension_type *extension_type, s2n_extension_type_id extension_id, + struct s2n_connection *conn, s2n_parsed_extension *parsed_extensions) +{ + notnull_check(extension_type); + notnull_check(parsed_extensions); + + if (s2n_parsed_extension_is_empty(&parsed_extensions[extension_id])) { + GUARD(s2n_extension_is_missing(extension_type, conn)); + return S2N_SUCCESS; + } + + ENSURE_POSIX(parsed_extensions[extension_id].extension_type == extension_type->iana_value, + S2N_ERR_INVALID_PARSED_EXTENSIONS); + + struct s2n_stuffer extension_stuffer; + GUARD(s2n_stuffer_init(&extension_stuffer, &parsed_extensions[extension_id].extension)); + GUARD(s2n_stuffer_skip_write(&extension_stuffer, parsed_extensions[extension_id].extension.size)); + + GUARD(s2n_extension_recv(extension_type, conn, &extension_stuffer)); + + return S2N_SUCCESS; +} + +int s2n_extension_process(const s2n_extension_type *extension_type, struct s2n_connection *conn, + s2n_parsed_extensions_list *parsed_extension_list) +{ + notnull_check(parsed_extension_list); + notnull_check(extension_type); + + s2n_extension_type_id extension_id; + GUARD(s2n_extension_supported_iana_value_to_id(extension_type->iana_value, &extension_id)); + + int result = s2n_extension_process_impl(extension_type, extension_id, conn, parsed_extension_list->parsed_extensions); + + /* Wipe parsed_extension. + * We can check for unprocessed extensions later by checking for non-blank parsed_extensions. */ + parsed_extension_list->parsed_extensions[extension_id] = empty_parsed_extensions[0]; + + return result; +} + +int s2n_extension_list_process(s2n_extension_list_id list_type, struct s2n_connection *conn, + s2n_parsed_extensions_list *parsed_extension_list) +{ + notnull_check(parsed_extension_list); + + s2n_extension_type_list *extension_type_list; + GUARD(s2n_extension_type_list_get(list_type, &extension_type_list)); + + for (int i = 0; i < extension_type_list->count; i++) { + GUARD(s2n_extension_process(extension_type_list->extension_types[i], + conn, parsed_extension_list)); + } + + /* If parsed_extension_list.parsed_extensions is not completely wiped at this point, + * then we have received an extension not allowed on this message type. + * + * According to the RFC, we should alert and close the connection. + * From https://tools.ietf.org/html/rfc8446#section-4.2: + * If an implementation receives an extension which it recognizes and which is not + * specified for the message in which it appears, it MUST abort the handshake with an + * "illegal_parameter" alert. + * + * However, to be more tolerant of non-compliant peers, we will just ignore and not + * process the illegal extensions, treating them as if they are unsupported. + */ + + return S2N_SUCCESS; +} + +static int s2n_extension_parse(struct s2n_stuffer *in, s2n_parsed_extension *parsed_extensions) +{ + notnull_check(parsed_extensions); + + uint16_t extension_type; + ENSURE_POSIX(s2n_stuffer_read_uint16(in, &extension_type) == S2N_SUCCESS, + S2N_ERR_BAD_MESSAGE); + + uint16_t extension_size; + ENSURE_POSIX(s2n_stuffer_read_uint16(in, &extension_size) == S2N_SUCCESS, + S2N_ERR_BAD_MESSAGE); + + uint8_t *extension_data = s2n_stuffer_raw_read(in, extension_size); + ENSURE_POSIX(extension_data != NULL, S2N_ERR_BAD_MESSAGE); + + s2n_extension_type_id extension_id; + if (s2n_extension_supported_iana_value_to_id(extension_type, &extension_id) != S2N_SUCCESS) { + /* Ignore unknown extensions */ + return S2N_SUCCESS; + } + + s2n_parsed_extension *parsed_extension = &parsed_extensions[extension_id]; + + /* Error if extension is a duplicate */ + ENSURE_POSIX(s2n_parsed_extension_is_empty(parsed_extension), + S2N_ERR_DUPLICATE_EXTENSION); + + /* Fill in parsed extension */ + parsed_extension->extension_type = extension_type; + GUARD(s2n_blob_init(&parsed_extension->extension, extension_data, extension_size)); + + return S2N_SUCCESS; +} + +int s2n_extension_list_parse(struct s2n_stuffer *in, s2n_parsed_extensions_list *parsed_extension_list) +{ + notnull_check(in); + notnull_check(parsed_extension_list); + + memset_check((s2n_parsed_extension*) parsed_extension_list->parsed_extensions, + 0, sizeof(parsed_extension_list->parsed_extensions)); + + uint16_t total_extensions_size; + if (s2n_stuffer_read_uint16(in, &total_extensions_size) != S2N_SUCCESS) { + total_extensions_size = 0; + } + + uint8_t *extensions_data = s2n_stuffer_raw_read(in, total_extensions_size); + ENSURE_POSIX(extensions_data != NULL, S2N_ERR_BAD_MESSAGE); + + GUARD(s2n_blob_init(&parsed_extension_list->raw, extensions_data, total_extensions_size)); + + struct s2n_stuffer extensions_stuffer; + GUARD(s2n_stuffer_init(&extensions_stuffer, &parsed_extension_list->raw)); + GUARD(s2n_stuffer_skip_write(&extensions_stuffer, total_extensions_size)); + + while (s2n_stuffer_data_available(&extensions_stuffer)) { + GUARD(s2n_extension_parse(&extensions_stuffer, parsed_extension_list->parsed_extensions)); + } + + return S2N_SUCCESS; +} diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_extension_list.h b/contrib/restricted/aws/s2n/tls/extensions/s2n_extension_list.h index 35582e5638..3609587ac4 100644 --- a/contrib/restricted/aws/s2n/tls/extensions/s2n_extension_list.h +++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_extension_list.h @@ -1,51 +1,51 @@ -/* - * 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. - */ - -#pragma once - -#include "stuffer/s2n_stuffer.h" -#include "tls/extensions/s2n_extension_type.h" - -#define S2N_PARSED_EXTENSIONS_COUNT S2N_SUPPORTED_EXTENSIONS_COUNT - -typedef struct { - uint16_t extension_type; - struct s2n_blob extension; -} s2n_parsed_extension; - -typedef struct { - s2n_parsed_extension parsed_extensions[S2N_PARSED_EXTENSIONS_COUNT]; - struct s2n_blob raw; /* Needed by some ClientHello APIs */ -} s2n_parsed_extensions_list; - -typedef enum { - S2N_EXTENSION_LIST_CLIENT_HELLO = 0, - S2N_EXTENSION_LIST_SERVER_HELLO_DEFAULT, - S2N_EXTENSION_LIST_SERVER_HELLO_TLS13, - S2N_EXTENSION_LIST_ENCRYPTED_EXTENSIONS, - S2N_EXTENSION_LIST_CERT_REQ, - S2N_EXTENSION_LIST_CERTIFICATE, - S2N_EXTENSION_LIST_EMPTY, - S2N_EXTENSION_LIST_IDS_COUNT, -} s2n_extension_list_id; - -int s2n_extension_list_send(s2n_extension_list_id list_type, struct s2n_connection *conn, struct s2n_stuffer *out); -int s2n_extension_list_recv(s2n_extension_list_id list_type, struct s2n_connection *conn, struct s2n_stuffer *in); - -int s2n_extension_process(const s2n_extension_type *extension_type, struct s2n_connection *conn, - s2n_parsed_extensions_list *parsed_extension_list); -int s2n_extension_list_process(s2n_extension_list_id list_type, struct s2n_connection *conn, - s2n_parsed_extensions_list *parsed_extension_list); -int s2n_extension_list_parse(struct s2n_stuffer *in, s2n_parsed_extensions_list *parsed_extension_list); +/* + * 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. + */ + +#pragma once + +#include "stuffer/s2n_stuffer.h" +#include "tls/extensions/s2n_extension_type.h" + +#define S2N_PARSED_EXTENSIONS_COUNT S2N_SUPPORTED_EXTENSIONS_COUNT + +typedef struct { + uint16_t extension_type; + struct s2n_blob extension; +} s2n_parsed_extension; + +typedef struct { + s2n_parsed_extension parsed_extensions[S2N_PARSED_EXTENSIONS_COUNT]; + struct s2n_blob raw; /* Needed by some ClientHello APIs */ +} s2n_parsed_extensions_list; + +typedef enum { + S2N_EXTENSION_LIST_CLIENT_HELLO = 0, + S2N_EXTENSION_LIST_SERVER_HELLO_DEFAULT, + S2N_EXTENSION_LIST_SERVER_HELLO_TLS13, + S2N_EXTENSION_LIST_ENCRYPTED_EXTENSIONS, + S2N_EXTENSION_LIST_CERT_REQ, + S2N_EXTENSION_LIST_CERTIFICATE, + S2N_EXTENSION_LIST_EMPTY, + S2N_EXTENSION_LIST_IDS_COUNT, +} s2n_extension_list_id; + +int s2n_extension_list_send(s2n_extension_list_id list_type, struct s2n_connection *conn, struct s2n_stuffer *out); +int s2n_extension_list_recv(s2n_extension_list_id list_type, struct s2n_connection *conn, struct s2n_stuffer *in); + +int s2n_extension_process(const s2n_extension_type *extension_type, struct s2n_connection *conn, + s2n_parsed_extensions_list *parsed_extension_list); +int s2n_extension_list_process(s2n_extension_list_id list_type, struct s2n_connection *conn, + s2n_parsed_extensions_list *parsed_extension_list); +int s2n_extension_list_parse(struct s2n_stuffer *in, s2n_parsed_extensions_list *parsed_extension_list); diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_extension_type.c b/contrib/restricted/aws/s2n/tls/extensions/s2n_extension_type.c index 040c57a16c..a961692f92 100644 --- a/contrib/restricted/aws/s2n/tls/extensions/s2n_extension_type.c +++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_extension_type.c @@ -1,212 +1,212 @@ -/* - * 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 <s2n.h> - -#include "error/s2n_errno.h" -#include "tls/extensions/s2n_extension_type.h" -#include "tls/s2n_connection.h" -#include "tls/s2n_tls13.h" -#include "utils/s2n_bitmap.h" -#include "utils/s2n_safety.h" - -#define TLS_EXTENSION_DATA_LENGTH_BYTES 2 - -/* Because there are 65536 possible extension IANAs, we will only - * put the lowest (and most common) in a lookup table to conserve space. */ -#define S2N_MAX_INDEXED_EXTENSION_IANA 60 - -const s2n_extension_type_id s2n_unsupported_extension = S2N_SUPPORTED_EXTENSIONS_COUNT; -s2n_extension_type_id s2n_extension_ianas_to_ids[S2N_MAX_INDEXED_EXTENSION_IANA]; - -int s2n_extension_type_init() -{ - /* Initialize to s2n_unsupported_extension */ - for (int i = 0; i < S2N_MAX_INDEXED_EXTENSION_IANA; i++) { - s2n_extension_ianas_to_ids[i] = s2n_unsupported_extension; - } - - /* Reverse the mapping */ - for (int i = 0; i < S2N_SUPPORTED_EXTENSIONS_COUNT; i++) { - uint16_t iana_value = s2n_supported_extensions[i]; - if (iana_value < S2N_MAX_INDEXED_EXTENSION_IANA) { - s2n_extension_ianas_to_ids[iana_value] = i; - } - } - - return S2N_SUCCESS; -} - -/* Convert the IANA value (which ranges from 0->65535) to an id with a more - * constrained range. That id can be used for bitfields, array indexes, etc. - * to avoid allocating too much memory. */ -s2n_extension_type_id s2n_extension_iana_value_to_id(const uint16_t iana_value) -{ - /* Check the lookup table */ - if (iana_value < S2N_MAX_INDEXED_EXTENSION_IANA) { - return s2n_extension_ianas_to_ids[iana_value]; - } - - /* Fall back to the full list. We can handle this more - * efficiently later if our extension list gets long. */ - for (int i = 0; i < S2N_SUPPORTED_EXTENSIONS_COUNT; i++) { - if (s2n_supported_extensions[i] == iana_value) { - return i; - } - } - - return s2n_unsupported_extension; -} - -int s2n_extension_supported_iana_value_to_id(const uint16_t iana_value, s2n_extension_type_id *internal_id) -{ - notnull_check(internal_id); - - *internal_id = s2n_extension_iana_value_to_id(iana_value); - S2N_ERROR_IF(*internal_id == s2n_unsupported_extension, S2N_ERR_UNRECOGNIZED_EXTENSION); - return S2N_SUCCESS; -} - -int s2n_extension_send(const s2n_extension_type *extension_type, struct s2n_connection *conn, struct s2n_stuffer *out) -{ - notnull_check(extension_type); - notnull_check(extension_type->should_send); - notnull_check(extension_type->send); - notnull_check(conn); - - s2n_extension_type_id extension_id; - GUARD(s2n_extension_supported_iana_value_to_id(extension_type->iana_value, &extension_id)); - - /* Do not send response if request not received. */ - if (extension_type->is_response && - !S2N_CBIT_TEST(conn->extension_requests_received, extension_id)) { - return S2N_SUCCESS; - } - - /* Check if we need to send. Some extensions are only sent if specific conditions are met. */ - if (!extension_type->should_send(conn)) { - return S2N_SUCCESS; - } - - /* Write extension type */ - GUARD(s2n_stuffer_write_uint16(out, extension_type->iana_value)); - - /* Reserve space for extension size */ - struct s2n_stuffer_reservation extension_size_bytes = {0}; - GUARD(s2n_stuffer_reserve_uint16(out, &extension_size_bytes)); - - /* Write extension data */ - GUARD(extension_type->send(conn, out)); - - /* Record extension size */ - GUARD(s2n_stuffer_write_vector_size(&extension_size_bytes)); - - /* Set request bit flag */ - if (!extension_type->is_response) { - S2N_CBIT_SET(conn->extension_requests_sent, extension_id); - } - - return S2N_SUCCESS; -} - -int s2n_extension_recv(const s2n_extension_type *extension_type, struct s2n_connection *conn, struct s2n_stuffer *in) -{ - notnull_check(extension_type); - notnull_check(extension_type->recv); - notnull_check(conn); - - s2n_extension_type_id extension_id; - GUARD(s2n_extension_supported_iana_value_to_id(extension_type->iana_value, &extension_id)); - - /* Do not accept a response if we did not send a request */ - if(extension_type->is_response && - !S2N_CBIT_TEST(conn->extension_requests_sent, extension_id)) { - S2N_ERROR(S2N_ERR_UNSUPPORTED_EXTENSION); - } - - GUARD(extension_type->recv(conn, in)); - - /* Set request bit flag */ - if (!extension_type->is_response) { - S2N_CBIT_SET(conn->extension_requests_received, extension_id); - } - - return S2N_SUCCESS; -} - -int s2n_extension_is_missing(const s2n_extension_type *extension_type, struct s2n_connection *conn) -{ - notnull_check(extension_type); - notnull_check(extension_type->if_missing); - notnull_check(conn); - - s2n_extension_type_id extension_id; - GUARD(s2n_extension_supported_iana_value_to_id(extension_type->iana_value, &extension_id)); - - /* Do not consider an extension missing if we did not send a request */ - if(extension_type->is_response && - !S2N_CBIT_TEST(conn->extension_requests_sent, extension_id)) { - return S2N_SUCCESS; - } - - GUARD(extension_type->if_missing(conn)); - - return S2N_SUCCESS; -} - -int s2n_extension_send_unimplemented(struct s2n_connection *conn, struct s2n_stuffer *out) -{ - S2N_ERROR(S2N_ERR_UNIMPLEMENTED); -} - -int s2n_extension_recv_unimplemented(struct s2n_connection *conn, struct s2n_stuffer *in) -{ - S2N_ERROR(S2N_ERR_UNIMPLEMENTED); -} - -int s2n_extension_send_noop(struct s2n_connection *conn, struct s2n_stuffer *out) -{ - return S2N_SUCCESS; -} - -int s2n_extension_recv_noop(struct s2n_connection *conn, struct s2n_stuffer *in) -{ - return S2N_SUCCESS; -} - -bool s2n_extension_always_send(struct s2n_connection *conn) -{ - return true; -} - -bool s2n_extension_never_send(struct s2n_connection *conn) -{ - return false; -} - -bool s2n_extension_send_if_tls13_connection(struct s2n_connection *conn) -{ - return s2n_connection_get_protocol_version(conn) >= S2N_TLS13; -} - -int s2n_extension_error_if_missing(struct s2n_connection *conn) -{ - S2N_ERROR(S2N_ERR_MISSING_EXTENSION); -} - -int s2n_extension_noop_if_missing(struct s2n_connection *conn) -{ - return S2N_SUCCESS; -} +/* + * 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 <s2n.h> + +#include "error/s2n_errno.h" +#include "tls/extensions/s2n_extension_type.h" +#include "tls/s2n_connection.h" +#include "tls/s2n_tls13.h" +#include "utils/s2n_bitmap.h" +#include "utils/s2n_safety.h" + +#define TLS_EXTENSION_DATA_LENGTH_BYTES 2 + +/* Because there are 65536 possible extension IANAs, we will only + * put the lowest (and most common) in a lookup table to conserve space. */ +#define S2N_MAX_INDEXED_EXTENSION_IANA 60 + +const s2n_extension_type_id s2n_unsupported_extension = S2N_SUPPORTED_EXTENSIONS_COUNT; +s2n_extension_type_id s2n_extension_ianas_to_ids[S2N_MAX_INDEXED_EXTENSION_IANA]; + +int s2n_extension_type_init() +{ + /* Initialize to s2n_unsupported_extension */ + for (int i = 0; i < S2N_MAX_INDEXED_EXTENSION_IANA; i++) { + s2n_extension_ianas_to_ids[i] = s2n_unsupported_extension; + } + + /* Reverse the mapping */ + for (int i = 0; i < S2N_SUPPORTED_EXTENSIONS_COUNT; i++) { + uint16_t iana_value = s2n_supported_extensions[i]; + if (iana_value < S2N_MAX_INDEXED_EXTENSION_IANA) { + s2n_extension_ianas_to_ids[iana_value] = i; + } + } + + return S2N_SUCCESS; +} + +/* Convert the IANA value (which ranges from 0->65535) to an id with a more + * constrained range. That id can be used for bitfields, array indexes, etc. + * to avoid allocating too much memory. */ +s2n_extension_type_id s2n_extension_iana_value_to_id(const uint16_t iana_value) +{ + /* Check the lookup table */ + if (iana_value < S2N_MAX_INDEXED_EXTENSION_IANA) { + return s2n_extension_ianas_to_ids[iana_value]; + } + + /* Fall back to the full list. We can handle this more + * efficiently later if our extension list gets long. */ + for (int i = 0; i < S2N_SUPPORTED_EXTENSIONS_COUNT; i++) { + if (s2n_supported_extensions[i] == iana_value) { + return i; + } + } + + return s2n_unsupported_extension; +} + +int s2n_extension_supported_iana_value_to_id(const uint16_t iana_value, s2n_extension_type_id *internal_id) +{ + notnull_check(internal_id); + + *internal_id = s2n_extension_iana_value_to_id(iana_value); + S2N_ERROR_IF(*internal_id == s2n_unsupported_extension, S2N_ERR_UNRECOGNIZED_EXTENSION); + return S2N_SUCCESS; +} + +int s2n_extension_send(const s2n_extension_type *extension_type, struct s2n_connection *conn, struct s2n_stuffer *out) +{ + notnull_check(extension_type); + notnull_check(extension_type->should_send); + notnull_check(extension_type->send); + notnull_check(conn); + + s2n_extension_type_id extension_id; + GUARD(s2n_extension_supported_iana_value_to_id(extension_type->iana_value, &extension_id)); + + /* Do not send response if request not received. */ + if (extension_type->is_response && + !S2N_CBIT_TEST(conn->extension_requests_received, extension_id)) { + return S2N_SUCCESS; + } + + /* Check if we need to send. Some extensions are only sent if specific conditions are met. */ + if (!extension_type->should_send(conn)) { + return S2N_SUCCESS; + } + + /* Write extension type */ + GUARD(s2n_stuffer_write_uint16(out, extension_type->iana_value)); + + /* Reserve space for extension size */ + struct s2n_stuffer_reservation extension_size_bytes = {0}; + GUARD(s2n_stuffer_reserve_uint16(out, &extension_size_bytes)); + + /* Write extension data */ + GUARD(extension_type->send(conn, out)); + + /* Record extension size */ + GUARD(s2n_stuffer_write_vector_size(&extension_size_bytes)); + + /* Set request bit flag */ + if (!extension_type->is_response) { + S2N_CBIT_SET(conn->extension_requests_sent, extension_id); + } + + return S2N_SUCCESS; +} + +int s2n_extension_recv(const s2n_extension_type *extension_type, struct s2n_connection *conn, struct s2n_stuffer *in) +{ + notnull_check(extension_type); + notnull_check(extension_type->recv); + notnull_check(conn); + + s2n_extension_type_id extension_id; + GUARD(s2n_extension_supported_iana_value_to_id(extension_type->iana_value, &extension_id)); + + /* Do not accept a response if we did not send a request */ + if(extension_type->is_response && + !S2N_CBIT_TEST(conn->extension_requests_sent, extension_id)) { + S2N_ERROR(S2N_ERR_UNSUPPORTED_EXTENSION); + } + + GUARD(extension_type->recv(conn, in)); + + /* Set request bit flag */ + if (!extension_type->is_response) { + S2N_CBIT_SET(conn->extension_requests_received, extension_id); + } + + return S2N_SUCCESS; +} + +int s2n_extension_is_missing(const s2n_extension_type *extension_type, struct s2n_connection *conn) +{ + notnull_check(extension_type); + notnull_check(extension_type->if_missing); + notnull_check(conn); + + s2n_extension_type_id extension_id; + GUARD(s2n_extension_supported_iana_value_to_id(extension_type->iana_value, &extension_id)); + + /* Do not consider an extension missing if we did not send a request */ + if(extension_type->is_response && + !S2N_CBIT_TEST(conn->extension_requests_sent, extension_id)) { + return S2N_SUCCESS; + } + + GUARD(extension_type->if_missing(conn)); + + return S2N_SUCCESS; +} + +int s2n_extension_send_unimplemented(struct s2n_connection *conn, struct s2n_stuffer *out) +{ + S2N_ERROR(S2N_ERR_UNIMPLEMENTED); +} + +int s2n_extension_recv_unimplemented(struct s2n_connection *conn, struct s2n_stuffer *in) +{ + S2N_ERROR(S2N_ERR_UNIMPLEMENTED); +} + +int s2n_extension_send_noop(struct s2n_connection *conn, struct s2n_stuffer *out) +{ + return S2N_SUCCESS; +} + +int s2n_extension_recv_noop(struct s2n_connection *conn, struct s2n_stuffer *in) +{ + return S2N_SUCCESS; +} + +bool s2n_extension_always_send(struct s2n_connection *conn) +{ + return true; +} + +bool s2n_extension_never_send(struct s2n_connection *conn) +{ + return false; +} + +bool s2n_extension_send_if_tls13_connection(struct s2n_connection *conn) +{ + return s2n_connection_get_protocol_version(conn) >= S2N_TLS13; +} + +int s2n_extension_error_if_missing(struct s2n_connection *conn) +{ + S2N_ERROR(S2N_ERR_MISSING_EXTENSION); +} + +int s2n_extension_noop_if_missing(struct s2n_connection *conn) +{ + return S2N_SUCCESS; +} diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_extension_type.h b/contrib/restricted/aws/s2n/tls/extensions/s2n_extension_type.h index 674c8e63dd..22e01b2005 100644 --- a/contrib/restricted/aws/s2n/tls/extensions/s2n_extension_type.h +++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_extension_type.h @@ -1,99 +1,99 @@ -/* - * 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. - */ - -#pragma once - -#include <stdbool.h> - -#include "stuffer/s2n_stuffer.h" -#include "tls/s2n_tls_parameters.h" - -#define S2N_EXTENSION_TYPE_FIELD_LENGTH 2 -#define S2N_EXTENSION_LENGTH_FIELD_LENGTH 2 - -/* The number of extensions supported by S2N */ -#define S2N_SUPPORTED_EXTENSIONS_COUNT (sizeof(s2n_supported_extensions) / sizeof(s2n_supported_extensions[0])) - -/* The number of bytes needed to assign 1 bit to every supported extension. - * The +1 is necessary to handle any remainder left over when dividing. */ -#define S2N_SUPPORTED_EXTENSIONS_BITFIELD_LEN ((S2N_SUPPORTED_EXTENSIONS_COUNT / sizeof(char)) + 1) - -struct s2n_connection; -typedef struct { - uint16_t iana_value; - unsigned is_response:1; - - int (*send) (struct s2n_connection *conn, struct s2n_stuffer *out); - int (*recv) (struct s2n_connection *conn, struct s2n_stuffer *in); - - /* Returns true or false to indicate whether the extension should be sent */ - bool (*should_send) (struct s2n_connection *conn); - - /* Handler called if an extension is not received */ - int (*if_missing) (struct s2n_connection *conn); -} s2n_extension_type; - -static const uint16_t s2n_supported_extensions[] = { - TLS_EXTENSION_RENEGOTIATION_INFO, - TLS_EXTENSION_PQ_KEM_PARAMETERS, - TLS_EXTENSION_SERVER_NAME, - TLS_EXTENSION_MAX_FRAG_LEN, - TLS_EXTENSION_STATUS_REQUEST, - TLS_EXTENSION_SUPPORTED_GROUPS, - TLS_EXTENSION_EC_POINT_FORMATS, - TLS_EXTENSION_SIGNATURE_ALGORITHMS, - TLS_EXTENSION_ALPN, - TLS_EXTENSION_SCT_LIST, - TLS_EXTENSION_SESSION_TICKET, - TLS_EXTENSION_SUPPORTED_VERSIONS, - TLS_EXTENSION_KEY_SHARE, - TLS_EXTENSION_COOKIE, - TLS_QUIC_TRANSPORT_PARAMETERS, - TLS_EXTENSION_PRE_SHARED_KEY, -}; - -typedef char s2n_extension_bitfield[S2N_SUPPORTED_EXTENSIONS_BITFIELD_LEN]; - -typedef uint8_t s2n_extension_type_id; -extern const s2n_extension_type_id s2n_unsupported_extension; - -int s2n_extension_send(const s2n_extension_type *extension_type, struct s2n_connection *conn, struct s2n_stuffer *out); -int s2n_extension_recv(const s2n_extension_type *extension_type, struct s2n_connection *conn, struct s2n_stuffer *in); -int s2n_extension_is_missing(const s2n_extension_type *extension_type, struct s2n_connection *conn); - -/* Map from TLS IANA value to internal s2n id. - * All possible IANA values is a large space, so using an internal id gives us more - * flexibility when using arrays / bitfields / etc. */ -int s2n_extension_supported_iana_value_to_id(const uint16_t iana_value, s2n_extension_type_id *internal_id); - -/* Initializer */ -int s2n_extension_type_init(); - -/* Common implementations for send */ -int s2n_extension_send_unimplemented(struct s2n_connection *conn, struct s2n_stuffer *out); -int s2n_extension_send_noop(struct s2n_connection *conn, struct s2n_stuffer *out); - -/* Common implementations for recv */ -int s2n_extension_recv_unimplemented(struct s2n_connection *conn, struct s2n_stuffer *in); -int s2n_extension_recv_noop(struct s2n_connection *conn, struct s2n_stuffer *out); - -/* Common implementations for should_send */ -bool s2n_extension_always_send(struct s2n_connection *conn); -bool s2n_extension_never_send(struct s2n_connection *conn); -bool s2n_extension_send_if_tls13_connection(struct s2n_connection *conn); - -/* Common implementations for if_missing */ -int s2n_extension_error_if_missing(struct s2n_connection *conn); -int s2n_extension_noop_if_missing(struct s2n_connection *conn); +/* + * 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. + */ + +#pragma once + +#include <stdbool.h> + +#include "stuffer/s2n_stuffer.h" +#include "tls/s2n_tls_parameters.h" + +#define S2N_EXTENSION_TYPE_FIELD_LENGTH 2 +#define S2N_EXTENSION_LENGTH_FIELD_LENGTH 2 + +/* The number of extensions supported by S2N */ +#define S2N_SUPPORTED_EXTENSIONS_COUNT (sizeof(s2n_supported_extensions) / sizeof(s2n_supported_extensions[0])) + +/* The number of bytes needed to assign 1 bit to every supported extension. + * The +1 is necessary to handle any remainder left over when dividing. */ +#define S2N_SUPPORTED_EXTENSIONS_BITFIELD_LEN ((S2N_SUPPORTED_EXTENSIONS_COUNT / sizeof(char)) + 1) + +struct s2n_connection; +typedef struct { + uint16_t iana_value; + unsigned is_response:1; + + int (*send) (struct s2n_connection *conn, struct s2n_stuffer *out); + int (*recv) (struct s2n_connection *conn, struct s2n_stuffer *in); + + /* Returns true or false to indicate whether the extension should be sent */ + bool (*should_send) (struct s2n_connection *conn); + + /* Handler called if an extension is not received */ + int (*if_missing) (struct s2n_connection *conn); +} s2n_extension_type; + +static const uint16_t s2n_supported_extensions[] = { + TLS_EXTENSION_RENEGOTIATION_INFO, + TLS_EXTENSION_PQ_KEM_PARAMETERS, + TLS_EXTENSION_SERVER_NAME, + TLS_EXTENSION_MAX_FRAG_LEN, + TLS_EXTENSION_STATUS_REQUEST, + TLS_EXTENSION_SUPPORTED_GROUPS, + TLS_EXTENSION_EC_POINT_FORMATS, + TLS_EXTENSION_SIGNATURE_ALGORITHMS, + TLS_EXTENSION_ALPN, + TLS_EXTENSION_SCT_LIST, + TLS_EXTENSION_SESSION_TICKET, + TLS_EXTENSION_SUPPORTED_VERSIONS, + TLS_EXTENSION_KEY_SHARE, + TLS_EXTENSION_COOKIE, + TLS_QUIC_TRANSPORT_PARAMETERS, + TLS_EXTENSION_PRE_SHARED_KEY, +}; + +typedef char s2n_extension_bitfield[S2N_SUPPORTED_EXTENSIONS_BITFIELD_LEN]; + +typedef uint8_t s2n_extension_type_id; +extern const s2n_extension_type_id s2n_unsupported_extension; + +int s2n_extension_send(const s2n_extension_type *extension_type, struct s2n_connection *conn, struct s2n_stuffer *out); +int s2n_extension_recv(const s2n_extension_type *extension_type, struct s2n_connection *conn, struct s2n_stuffer *in); +int s2n_extension_is_missing(const s2n_extension_type *extension_type, struct s2n_connection *conn); + +/* Map from TLS IANA value to internal s2n id. + * All possible IANA values is a large space, so using an internal id gives us more + * flexibility when using arrays / bitfields / etc. */ +int s2n_extension_supported_iana_value_to_id(const uint16_t iana_value, s2n_extension_type_id *internal_id); + +/* Initializer */ +int s2n_extension_type_init(); + +/* Common implementations for send */ +int s2n_extension_send_unimplemented(struct s2n_connection *conn, struct s2n_stuffer *out); +int s2n_extension_send_noop(struct s2n_connection *conn, struct s2n_stuffer *out); + +/* Common implementations for recv */ +int s2n_extension_recv_unimplemented(struct s2n_connection *conn, struct s2n_stuffer *in); +int s2n_extension_recv_noop(struct s2n_connection *conn, struct s2n_stuffer *out); + +/* Common implementations for should_send */ +bool s2n_extension_always_send(struct s2n_connection *conn); +bool s2n_extension_never_send(struct s2n_connection *conn); +bool s2n_extension_send_if_tls13_connection(struct s2n_connection *conn); + +/* Common implementations for if_missing */ +int s2n_extension_error_if_missing(struct s2n_connection *conn); +int s2n_extension_noop_if_missing(struct s2n_connection *conn); 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 ed4c196f59..86e55bbd8a 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 @@ -1,121 +1,121 @@ -/* - * 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 <s2n.h> - -#include "tls/extensions/s2n_extension_type_lists.h" -#include "tls/s2n_connection.h" - -#include "tls/extensions/s2n_cookie.h" -#include "tls/extensions/s2n_client_supported_versions.h" -#include "tls/extensions/s2n_client_signature_algorithms.h" -#include "tls/extensions/s2n_client_max_frag_len.h" -#include "tls/extensions/s2n_client_session_ticket.h" -#include "tls/extensions/s2n_client_server_name.h" -#include "tls/extensions/s2n_client_alpn.h" -#include "tls/extensions/s2n_client_status_request.h" -#include "tls/extensions/s2n_client_key_share.h" -#include "tls/extensions/s2n_client_sct_list.h" -#include "tls/extensions/s2n_client_supported_groups.h" -#include "tls/extensions/s2n_client_pq_kem.h" -#include "tls/extensions/s2n_client_psk.h" -#include "tls/extensions/s2n_client_renegotiation_info.h" -#include "tls/extensions/s2n_ec_point_format.h" -#include "tls/extensions/s2n_quic_transport_params.h" -#include "tls/extensions/s2n_server_certificate_status.h" -#include "tls/extensions/s2n_server_renegotiation_info.h" -#include "tls/extensions/s2n_server_alpn.h" -#include "tls/extensions/s2n_server_status_request.h" -#include "tls/extensions/s2n_server_sct_list.h" -#include "tls/extensions/s2n_server_max_fragment_length.h" -#include "tls/extensions/s2n_server_session_ticket.h" -#include "tls/extensions/s2n_server_server_name.h" -#include "tls/extensions/s2n_server_signature_algorithms.h" -#include "tls/extensions/s2n_server_supported_versions.h" -#include "tls/extensions/s2n_server_key_share.h" - -static const s2n_extension_type *const client_hello_extensions[] = { - &s2n_client_supported_versions_extension, - &s2n_client_key_share_extension, - &s2n_client_signature_algorithms_extension, - &s2n_client_server_name_extension, - &s2n_client_alpn_extension, - &s2n_client_status_request_extension, - &s2n_client_sct_list_extension, - &s2n_client_max_frag_len_extension, - &s2n_client_session_ticket_extension, - &s2n_client_supported_groups_extension, - &s2n_client_ec_point_format_extension, - &s2n_client_pq_kem_extension, - &s2n_client_renegotiation_info_extension, - &s2n_client_cookie_extension, - &s2n_quic_transport_parameters_extension, - &s2n_client_psk_extension /* MUST be last */ -}; - -static const s2n_extension_type *const tls12_server_hello_extensions[] = { - &s2n_server_supported_versions_extension, - &s2n_server_server_name_extension, - &s2n_server_ec_point_format_extension, - &s2n_server_renegotiation_info_extension, - &s2n_server_alpn_extension, - &s2n_server_status_request_extension, - &s2n_server_sct_list_extension, - &s2n_server_max_fragment_length_extension, - &s2n_server_session_ticket_extension, -}; - -static const s2n_extension_type *const tls13_server_hello_extensions[] = { - &s2n_server_supported_versions_extension, - &s2n_server_key_share_extension, - &s2n_server_cookie_extension, -}; - -static const s2n_extension_type *const encrypted_extensions[] = { - &s2n_server_server_name_extension, - &s2n_server_max_fragment_length_extension, - &s2n_server_alpn_extension, - &s2n_quic_transport_parameters_extension, -}; - -static const s2n_extension_type *const cert_req_extensions[] = { - &s2n_server_signature_algorithms_extension, -}; - -static const s2n_extension_type *const certificate_extensions[] = { - &s2n_tls13_server_status_request_extension, - &s2n_server_sct_list_extension, -}; - -#define S2N_EXTENSION_LIST(list) { .extension_types = (list), .count = s2n_array_len(list) } - -static s2n_extension_type_list extension_lists[] = { - [S2N_EXTENSION_LIST_CLIENT_HELLO] = S2N_EXTENSION_LIST(client_hello_extensions), - [S2N_EXTENSION_LIST_SERVER_HELLO_DEFAULT] = S2N_EXTENSION_LIST(tls12_server_hello_extensions), - [S2N_EXTENSION_LIST_SERVER_HELLO_TLS13] = S2N_EXTENSION_LIST(tls13_server_hello_extensions), - [S2N_EXTENSION_LIST_ENCRYPTED_EXTENSIONS] = S2N_EXTENSION_LIST(encrypted_extensions), - [S2N_EXTENSION_LIST_CERT_REQ] = S2N_EXTENSION_LIST(cert_req_extensions), - [S2N_EXTENSION_LIST_CERTIFICATE] = S2N_EXTENSION_LIST(certificate_extensions), - [S2N_EXTENSION_LIST_EMPTY] = { .extension_types = NULL, .count = 0 }, -}; - -int s2n_extension_type_list_get(s2n_extension_list_id list_type, s2n_extension_type_list **extension_list) -{ - notnull_check(extension_list); - lt_check(list_type, s2n_array_len(extension_lists)); - - *extension_list = &extension_lists[list_type]; - return S2N_SUCCESS; -} +/* + * 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 <s2n.h> + +#include "tls/extensions/s2n_extension_type_lists.h" +#include "tls/s2n_connection.h" + +#include "tls/extensions/s2n_cookie.h" +#include "tls/extensions/s2n_client_supported_versions.h" +#include "tls/extensions/s2n_client_signature_algorithms.h" +#include "tls/extensions/s2n_client_max_frag_len.h" +#include "tls/extensions/s2n_client_session_ticket.h" +#include "tls/extensions/s2n_client_server_name.h" +#include "tls/extensions/s2n_client_alpn.h" +#include "tls/extensions/s2n_client_status_request.h" +#include "tls/extensions/s2n_client_key_share.h" +#include "tls/extensions/s2n_client_sct_list.h" +#include "tls/extensions/s2n_client_supported_groups.h" +#include "tls/extensions/s2n_client_pq_kem.h" +#include "tls/extensions/s2n_client_psk.h" +#include "tls/extensions/s2n_client_renegotiation_info.h" +#include "tls/extensions/s2n_ec_point_format.h" +#include "tls/extensions/s2n_quic_transport_params.h" +#include "tls/extensions/s2n_server_certificate_status.h" +#include "tls/extensions/s2n_server_renegotiation_info.h" +#include "tls/extensions/s2n_server_alpn.h" +#include "tls/extensions/s2n_server_status_request.h" +#include "tls/extensions/s2n_server_sct_list.h" +#include "tls/extensions/s2n_server_max_fragment_length.h" +#include "tls/extensions/s2n_server_session_ticket.h" +#include "tls/extensions/s2n_server_server_name.h" +#include "tls/extensions/s2n_server_signature_algorithms.h" +#include "tls/extensions/s2n_server_supported_versions.h" +#include "tls/extensions/s2n_server_key_share.h" + +static const s2n_extension_type *const client_hello_extensions[] = { + &s2n_client_supported_versions_extension, + &s2n_client_key_share_extension, + &s2n_client_signature_algorithms_extension, + &s2n_client_server_name_extension, + &s2n_client_alpn_extension, + &s2n_client_status_request_extension, + &s2n_client_sct_list_extension, + &s2n_client_max_frag_len_extension, + &s2n_client_session_ticket_extension, + &s2n_client_supported_groups_extension, + &s2n_client_ec_point_format_extension, + &s2n_client_pq_kem_extension, + &s2n_client_renegotiation_info_extension, + &s2n_client_cookie_extension, + &s2n_quic_transport_parameters_extension, + &s2n_client_psk_extension /* MUST be last */ +}; + +static const s2n_extension_type *const tls12_server_hello_extensions[] = { + &s2n_server_supported_versions_extension, + &s2n_server_server_name_extension, + &s2n_server_ec_point_format_extension, + &s2n_server_renegotiation_info_extension, + &s2n_server_alpn_extension, + &s2n_server_status_request_extension, + &s2n_server_sct_list_extension, + &s2n_server_max_fragment_length_extension, + &s2n_server_session_ticket_extension, +}; + +static const s2n_extension_type *const tls13_server_hello_extensions[] = { + &s2n_server_supported_versions_extension, + &s2n_server_key_share_extension, + &s2n_server_cookie_extension, +}; + +static const s2n_extension_type *const encrypted_extensions[] = { + &s2n_server_server_name_extension, + &s2n_server_max_fragment_length_extension, + &s2n_server_alpn_extension, + &s2n_quic_transport_parameters_extension, +}; + +static const s2n_extension_type *const cert_req_extensions[] = { + &s2n_server_signature_algorithms_extension, +}; + +static const s2n_extension_type *const certificate_extensions[] = { + &s2n_tls13_server_status_request_extension, + &s2n_server_sct_list_extension, +}; + +#define S2N_EXTENSION_LIST(list) { .extension_types = (list), .count = s2n_array_len(list) } + +static s2n_extension_type_list extension_lists[] = { + [S2N_EXTENSION_LIST_CLIENT_HELLO] = S2N_EXTENSION_LIST(client_hello_extensions), + [S2N_EXTENSION_LIST_SERVER_HELLO_DEFAULT] = S2N_EXTENSION_LIST(tls12_server_hello_extensions), + [S2N_EXTENSION_LIST_SERVER_HELLO_TLS13] = S2N_EXTENSION_LIST(tls13_server_hello_extensions), + [S2N_EXTENSION_LIST_ENCRYPTED_EXTENSIONS] = S2N_EXTENSION_LIST(encrypted_extensions), + [S2N_EXTENSION_LIST_CERT_REQ] = S2N_EXTENSION_LIST(cert_req_extensions), + [S2N_EXTENSION_LIST_CERTIFICATE] = S2N_EXTENSION_LIST(certificate_extensions), + [S2N_EXTENSION_LIST_EMPTY] = { .extension_types = NULL, .count = 0 }, +}; + +int s2n_extension_type_list_get(s2n_extension_list_id list_type, s2n_extension_type_list **extension_list) +{ + notnull_check(extension_list); + lt_check(list_type, s2n_array_len(extension_lists)); + + *extension_list = &extension_lists[list_type]; + return S2N_SUCCESS; +} diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_extension_type_lists.h b/contrib/restricted/aws/s2n/tls/extensions/s2n_extension_type_lists.h index 114f6ae75e..d57cfa2988 100644 --- a/contrib/restricted/aws/s2n/tls/extensions/s2n_extension_type_lists.h +++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_extension_type_lists.h @@ -1,26 +1,26 @@ -/* - * 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. - */ - -#pragma once - -#include "tls/extensions/s2n_extension_list.h" -#include "tls/extensions/s2n_extension_type.h" - -typedef struct { - const s2n_extension_type *const *extension_types; - const uint8_t count; -} s2n_extension_type_list; - -int s2n_extension_type_list_get(s2n_extension_list_id list_type, s2n_extension_type_list **extension_type_list); +/* + * 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. + */ + +#pragma once + +#include "tls/extensions/s2n_extension_list.h" +#include "tls/extensions/s2n_extension_type.h" + +typedef struct { + const s2n_extension_type *const *extension_types; + const uint8_t count; +} s2n_extension_type_list; + +int s2n_extension_type_list_get(s2n_extension_list_id list_type, s2n_extension_type_list **extension_type_list); diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_key_share.c b/contrib/restricted/aws/s2n/tls/extensions/s2n_key_share.c index a91dbfd30b..0b64096b2f 100644 --- a/contrib/restricted/aws/s2n/tls/extensions/s2n_key_share.c +++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_key_share.c @@ -1,33 +1,33 @@ -/* - * 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_key_share.h" -#include "tls/s2n_tls.h" -#include "utils/s2n_safety.h" - -int s2n_ecdhe_parameters_send(struct s2n_ecc_evp_params *ecc_evp_params, struct s2n_stuffer *out) -{ - notnull_check(out); - notnull_check(ecc_evp_params); - notnull_check(ecc_evp_params->negotiated_curve); - - GUARD(s2n_stuffer_write_uint16(out, ecc_evp_params->negotiated_curve->iana_id)); - GUARD(s2n_stuffer_write_uint16(out, ecc_evp_params->negotiated_curve->share_size)); - - GUARD(s2n_ecc_evp_generate_ephemeral_key(ecc_evp_params)); - GUARD(s2n_ecc_evp_write_params_point(ecc_evp_params, out)); - - return 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_key_share.h" +#include "tls/s2n_tls.h" +#include "utils/s2n_safety.h" + +int s2n_ecdhe_parameters_send(struct s2n_ecc_evp_params *ecc_evp_params, struct s2n_stuffer *out) +{ + notnull_check(out); + notnull_check(ecc_evp_params); + notnull_check(ecc_evp_params->negotiated_curve); + + GUARD(s2n_stuffer_write_uint16(out, ecc_evp_params->negotiated_curve->iana_id)); + GUARD(s2n_stuffer_write_uint16(out, ecc_evp_params->negotiated_curve->share_size)); + + GUARD(s2n_ecc_evp_generate_ephemeral_key(ecc_evp_params)); + GUARD(s2n_ecc_evp_write_params_point(ecc_evp_params, out)); + + return 0; +} diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_key_share.h b/contrib/restricted/aws/s2n/tls/extensions/s2n_key_share.h index f621d76b52..a29fdd3806 100644 --- a/contrib/restricted/aws/s2n/tls/extensions/s2n_key_share.h +++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_key_share.h @@ -1,28 +1,28 @@ -/* - * 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. - */ - -#pragma once - -#include "crypto/s2n_ecc_evp.h" -#include "tls/s2n_connection.h" -#include "stuffer/s2n_stuffer.h" - -#define S2N_SIZE_OF_EXTENSION_TYPE 2 -#define S2N_SIZE_OF_EXTENSION_DATA_SIZE 2 -#define S2N_SIZE_OF_CLIENT_SHARES_SIZE 2 -#define S2N_SIZE_OF_NAMED_GROUP 2 -#define S2N_SIZE_OF_KEY_SHARE_SIZE 2 - -extern int s2n_ecdhe_parameters_send(struct s2n_ecc_evp_params *ecc_evp_params, struct s2n_stuffer *out); +/* + * 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. + */ + +#pragma once + +#include "crypto/s2n_ecc_evp.h" +#include "tls/s2n_connection.h" +#include "stuffer/s2n_stuffer.h" + +#define S2N_SIZE_OF_EXTENSION_TYPE 2 +#define S2N_SIZE_OF_EXTENSION_DATA_SIZE 2 +#define S2N_SIZE_OF_CLIENT_SHARES_SIZE 2 +#define S2N_SIZE_OF_NAMED_GROUP 2 +#define S2N_SIZE_OF_KEY_SHARE_SIZE 2 + +extern int s2n_ecdhe_parameters_send(struct s2n_ecc_evp_params *ecc_evp_params, struct s2n_stuffer *out); diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_quic_transport_params.c b/contrib/restricted/aws/s2n/tls/extensions/s2n_quic_transport_params.c index 56f17abc3b..9b6fa1bee3 100644 --- a/contrib/restricted/aws/s2n/tls/extensions/s2n_quic_transport_params.c +++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_quic_transport_params.c @@ -1,77 +1,77 @@ -/* - * 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_quic_transport_params.h" - -#include "tls/s2n_connection.h" -#include "tls/s2n_tls.h" - -#include "stuffer/s2n_stuffer.h" -#include "utils/s2n_safety.h" - -/* - * The quic_transport_params extension is required by the QUIC protocol to - * negotiate additional connection parameters when using S2N. - * - * This extension should not be sent or received unless using S2N with QUIC. - * S2N treats the extension data as opaque bytes and performs no validation. - */ - -static bool s2n_quic_transport_params_should_send(struct s2n_connection *conn) -{ - return conn && conn->config && conn->config->quic_enabled; -} - -static int s2n_quic_transport_params_if_missing(struct s2n_connection *conn) -{ - notnull_check(conn); - notnull_check(conn->config); - ENSURE_POSIX(!conn->config->quic_enabled, S2N_ERR_MISSING_EXTENSION); - return S2N_SUCCESS; -} - -static int s2n_quic_transport_params_send(struct s2n_connection *conn, struct s2n_stuffer *out) -{ - notnull_check(conn); - notnull_check(out); - - if (conn->our_quic_transport_parameters.size) { - GUARD(s2n_stuffer_write(out, &conn->our_quic_transport_parameters)); - } - return S2N_SUCCESS; -} - -static int s2n_quic_transport_params_recv(struct s2n_connection *conn, struct s2n_stuffer *extension) -{ - notnull_check(conn); - notnull_check(extension); - notnull_check(conn->config); - ENSURE_POSIX(conn->config->quic_enabled, S2N_ERR_UNSUPPORTED_EXTENSION); - - if (s2n_stuffer_data_available(extension)) { - GUARD(s2n_alloc(&conn->peer_quic_transport_parameters, s2n_stuffer_data_available(extension))); - GUARD(s2n_stuffer_read(extension, &conn->peer_quic_transport_parameters)); - } - return S2N_SUCCESS; -} - -const s2n_extension_type s2n_quic_transport_parameters_extension = { - .iana_value = TLS_QUIC_TRANSPORT_PARAMETERS, - .is_response = false, - .send = s2n_quic_transport_params_send, - .recv = s2n_quic_transport_params_recv, - .should_send = s2n_quic_transport_params_should_send, - .if_missing = s2n_quic_transport_params_if_missing, -}; +/* + * 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_quic_transport_params.h" + +#include "tls/s2n_connection.h" +#include "tls/s2n_tls.h" + +#include "stuffer/s2n_stuffer.h" +#include "utils/s2n_safety.h" + +/* + * The quic_transport_params extension is required by the QUIC protocol to + * negotiate additional connection parameters when using S2N. + * + * This extension should not be sent or received unless using S2N with QUIC. + * S2N treats the extension data as opaque bytes and performs no validation. + */ + +static bool s2n_quic_transport_params_should_send(struct s2n_connection *conn) +{ + return conn && conn->config && conn->config->quic_enabled; +} + +static int s2n_quic_transport_params_if_missing(struct s2n_connection *conn) +{ + notnull_check(conn); + notnull_check(conn->config); + ENSURE_POSIX(!conn->config->quic_enabled, S2N_ERR_MISSING_EXTENSION); + return S2N_SUCCESS; +} + +static int s2n_quic_transport_params_send(struct s2n_connection *conn, struct s2n_stuffer *out) +{ + notnull_check(conn); + notnull_check(out); + + if (conn->our_quic_transport_parameters.size) { + GUARD(s2n_stuffer_write(out, &conn->our_quic_transport_parameters)); + } + return S2N_SUCCESS; +} + +static int s2n_quic_transport_params_recv(struct s2n_connection *conn, struct s2n_stuffer *extension) +{ + notnull_check(conn); + notnull_check(extension); + notnull_check(conn->config); + ENSURE_POSIX(conn->config->quic_enabled, S2N_ERR_UNSUPPORTED_EXTENSION); + + if (s2n_stuffer_data_available(extension)) { + GUARD(s2n_alloc(&conn->peer_quic_transport_parameters, s2n_stuffer_data_available(extension))); + GUARD(s2n_stuffer_read(extension, &conn->peer_quic_transport_parameters)); + } + return S2N_SUCCESS; +} + +const s2n_extension_type s2n_quic_transport_parameters_extension = { + .iana_value = TLS_QUIC_TRANSPORT_PARAMETERS, + .is_response = false, + .send = s2n_quic_transport_params_send, + .recv = s2n_quic_transport_params_recv, + .should_send = s2n_quic_transport_params_should_send, + .if_missing = s2n_quic_transport_params_if_missing, +}; diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_quic_transport_params.h b/contrib/restricted/aws/s2n/tls/extensions/s2n_quic_transport_params.h index 93369b5478..ed0a73d140 100644 --- a/contrib/restricted/aws/s2n/tls/extensions/s2n_quic_transport_params.h +++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_quic_transport_params.h @@ -1,20 +1,20 @@ -/* - * 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. - */ - -#pragma once - -#include "tls/extensions/s2n_extension_type.h" - -extern const s2n_extension_type s2n_quic_transport_parameters_extension; +/* + * 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. + */ + +#pragma once + +#include "tls/extensions/s2n_extension_type.h" + +extern const s2n_extension_type s2n_quic_transport_parameters_extension; diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_alpn.c b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_alpn.c index a1f5ac17cf..50dbcf11f9 100644 --- a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_alpn.c +++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_alpn.c @@ -1,81 +1,81 @@ -/* - * 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 "stuffer/s2n_stuffer.h" - -#include "utils/s2n_safety.h" - -#include "tls/s2n_connection.h" -#include "tls/s2n_tls.h" - -#include "tls/extensions/s2n_server_alpn.h" - -static bool s2n_alpn_should_send(struct s2n_connection *conn); -static int s2n_alpn_send(struct s2n_connection *conn, struct s2n_stuffer *out); -static int s2n_alpn_recv(struct s2n_connection *conn, struct s2n_stuffer *extension); - -const s2n_extension_type s2n_server_alpn_extension = { - .iana_value = TLS_EXTENSION_ALPN, - .is_response = true, - .send = s2n_alpn_send, - .recv = s2n_alpn_recv, - .should_send = s2n_alpn_should_send, - .if_missing = s2n_extension_noop_if_missing, -}; - -static bool s2n_alpn_should_send(struct s2n_connection *conn) -{ - return conn && strlen(conn->application_protocol) > 0; -} - -static int s2n_alpn_send(struct s2n_connection *conn, struct s2n_stuffer *out) -{ - notnull_check(conn); - const uint8_t application_protocol_len = strlen(conn->application_protocol); - - /* Size of protocol name list */ - GUARD(s2n_stuffer_write_uint16(out, application_protocol_len + sizeof(uint8_t))); - - /* Single entry in protocol name list */ - GUARD(s2n_stuffer_write_uint8(out, application_protocol_len)); - GUARD(s2n_stuffer_write_bytes(out, (uint8_t *) conn->application_protocol, application_protocol_len)); - - return S2N_SUCCESS; -} - -static int s2n_alpn_recv(struct s2n_connection *conn, struct s2n_stuffer *extension) -{ - notnull_check(conn); - - uint16_t size_of_all; - GUARD(s2n_stuffer_read_uint16(extension, &size_of_all)); - if (size_of_all > s2n_stuffer_data_available(extension) || size_of_all < 3) { - /* ignore invalid extension size */ - return S2N_SUCCESS; - } - - uint8_t protocol_len; - GUARD(s2n_stuffer_read_uint8(extension, &protocol_len)); - lt_check(protocol_len, s2n_array_len(conn->application_protocol)); - - uint8_t *protocol = s2n_stuffer_raw_read(extension, protocol_len); - notnull_check(protocol); - - /* copy the first protocol name */ - memcpy_check(conn->application_protocol, protocol, protocol_len); - conn->application_protocol[protocol_len] = '\0'; - - return S2N_SUCCESS; -} +/* + * 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 "stuffer/s2n_stuffer.h" + +#include "utils/s2n_safety.h" + +#include "tls/s2n_connection.h" +#include "tls/s2n_tls.h" + +#include "tls/extensions/s2n_server_alpn.h" + +static bool s2n_alpn_should_send(struct s2n_connection *conn); +static int s2n_alpn_send(struct s2n_connection *conn, struct s2n_stuffer *out); +static int s2n_alpn_recv(struct s2n_connection *conn, struct s2n_stuffer *extension); + +const s2n_extension_type s2n_server_alpn_extension = { + .iana_value = TLS_EXTENSION_ALPN, + .is_response = true, + .send = s2n_alpn_send, + .recv = s2n_alpn_recv, + .should_send = s2n_alpn_should_send, + .if_missing = s2n_extension_noop_if_missing, +}; + +static bool s2n_alpn_should_send(struct s2n_connection *conn) +{ + return conn && strlen(conn->application_protocol) > 0; +} + +static int s2n_alpn_send(struct s2n_connection *conn, struct s2n_stuffer *out) +{ + notnull_check(conn); + const uint8_t application_protocol_len = strlen(conn->application_protocol); + + /* Size of protocol name list */ + GUARD(s2n_stuffer_write_uint16(out, application_protocol_len + sizeof(uint8_t))); + + /* Single entry in protocol name list */ + GUARD(s2n_stuffer_write_uint8(out, application_protocol_len)); + GUARD(s2n_stuffer_write_bytes(out, (uint8_t *) conn->application_protocol, application_protocol_len)); + + return S2N_SUCCESS; +} + +static int s2n_alpn_recv(struct s2n_connection *conn, struct s2n_stuffer *extension) +{ + notnull_check(conn); + + uint16_t size_of_all; + GUARD(s2n_stuffer_read_uint16(extension, &size_of_all)); + if (size_of_all > s2n_stuffer_data_available(extension) || size_of_all < 3) { + /* ignore invalid extension size */ + return S2N_SUCCESS; + } + + uint8_t protocol_len; + GUARD(s2n_stuffer_read_uint8(extension, &protocol_len)); + lt_check(protocol_len, s2n_array_len(conn->application_protocol)); + + uint8_t *protocol = s2n_stuffer_raw_read(extension, protocol_len); + notnull_check(protocol); + + /* copy the first protocol name */ + memcpy_check(conn->application_protocol, protocol, protocol_len); + conn->application_protocol[protocol_len] = '\0'; + + return S2N_SUCCESS; +} diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_alpn.h b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_alpn.h index ccdf3fce9c..5e5564dd54 100644 --- a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_alpn.h +++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_alpn.h @@ -1,20 +1,20 @@ -/* - * 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. - */ - -#pragma once - -#include "tls/extensions/s2n_extension_type.h" - -extern const s2n_extension_type s2n_server_alpn_extension; +/* + * 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. + */ + +#pragma once + +#include "tls/extensions/s2n_extension_type.h" + +extern const s2n_extension_type s2n_server_alpn_extension; diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_certificate_status.c b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_certificate_status.c index 486835689c..a362b446af 100644 --- a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_certificate_status.c +++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_certificate_status.c @@ -1,80 +1,80 @@ -/* - * 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/s2n_config.h" -#include "tls/s2n_connection.h" -#include "tls/s2n_tls.h" -#include "tls/s2n_x509_validator.h" -#include "tls/extensions/s2n_server_certificate_status.h" -#include "utils/s2n_safety.h" - -#define U24_SIZE 3 - -/* In TLS 1.3, a response to a Status Request extension is sent as an extension with - * status request as well as the OCSP response. This contrasts to TLS 1.2 where - * the OCSP response is sent in the Certificate Status handshake message */ - -static bool s2n_tls13_server_status_request_should_send(struct s2n_connection *conn); - -const s2n_extension_type s2n_tls13_server_status_request_extension = { - .iana_value = TLS_EXTENSION_STATUS_REQUEST, - .is_response = true, - .send = s2n_server_certificate_status_send, - .recv = s2n_server_certificate_status_recv, - .should_send = s2n_tls13_server_status_request_should_send, - .if_missing = s2n_extension_noop_if_missing, -}; - -static bool s2n_tls13_server_status_request_should_send(struct s2n_connection *conn) -{ - return s2n_server_can_send_ocsp(conn); -} - -int s2n_server_certificate_status_send(struct s2n_connection *conn, struct s2n_stuffer *out) -{ - notnull_check(conn); - struct s2n_blob *ocsp_status = &conn->handshake_params.our_chain_and_key->ocsp_status; - notnull_check(ocsp_status); - - GUARD(s2n_stuffer_write_uint8(out, (uint8_t) S2N_STATUS_REQUEST_OCSP)); - GUARD(s2n_stuffer_write_uint24(out, ocsp_status->size)); - GUARD(s2n_stuffer_write(out, ocsp_status)); - - return S2N_SUCCESS; -} - -int s2n_server_certificate_status_recv(struct s2n_connection *conn, struct s2n_stuffer *in) -{ - notnull_check(conn); - - uint8_t type; - GUARD(s2n_stuffer_read_uint8(in, &type)); - if (type != S2N_STATUS_REQUEST_OCSP) { - /* We only support OCSP */ - return S2N_SUCCESS; - } - - uint32_t status_size; - GUARD(s2n_stuffer_read_uint24(in, &status_size)); - lte_check(status_size, s2n_stuffer_data_available(in)); - - GUARD(s2n_realloc(&conn->status_response, status_size)); - GUARD(s2n_stuffer_read_bytes(in, conn->status_response.data, status_size)); - - GUARD(s2n_x509_validator_validate_cert_stapled_ocsp_response( - &conn->x509_validator, conn, conn->status_response.data, conn->status_response.size)); - - return S2N_SUCCESS; -} +/* + * 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/s2n_config.h" +#include "tls/s2n_connection.h" +#include "tls/s2n_tls.h" +#include "tls/s2n_x509_validator.h" +#include "tls/extensions/s2n_server_certificate_status.h" +#include "utils/s2n_safety.h" + +#define U24_SIZE 3 + +/* In TLS 1.3, a response to a Status Request extension is sent as an extension with + * status request as well as the OCSP response. This contrasts to TLS 1.2 where + * the OCSP response is sent in the Certificate Status handshake message */ + +static bool s2n_tls13_server_status_request_should_send(struct s2n_connection *conn); + +const s2n_extension_type s2n_tls13_server_status_request_extension = { + .iana_value = TLS_EXTENSION_STATUS_REQUEST, + .is_response = true, + .send = s2n_server_certificate_status_send, + .recv = s2n_server_certificate_status_recv, + .should_send = s2n_tls13_server_status_request_should_send, + .if_missing = s2n_extension_noop_if_missing, +}; + +static bool s2n_tls13_server_status_request_should_send(struct s2n_connection *conn) +{ + return s2n_server_can_send_ocsp(conn); +} + +int s2n_server_certificate_status_send(struct s2n_connection *conn, struct s2n_stuffer *out) +{ + notnull_check(conn); + struct s2n_blob *ocsp_status = &conn->handshake_params.our_chain_and_key->ocsp_status; + notnull_check(ocsp_status); + + GUARD(s2n_stuffer_write_uint8(out, (uint8_t) S2N_STATUS_REQUEST_OCSP)); + GUARD(s2n_stuffer_write_uint24(out, ocsp_status->size)); + GUARD(s2n_stuffer_write(out, ocsp_status)); + + return S2N_SUCCESS; +} + +int s2n_server_certificate_status_recv(struct s2n_connection *conn, struct s2n_stuffer *in) +{ + notnull_check(conn); + + uint8_t type; + GUARD(s2n_stuffer_read_uint8(in, &type)); + if (type != S2N_STATUS_REQUEST_OCSP) { + /* We only support OCSP */ + return S2N_SUCCESS; + } + + uint32_t status_size; + GUARD(s2n_stuffer_read_uint24(in, &status_size)); + lte_check(status_size, s2n_stuffer_data_available(in)); + + GUARD(s2n_realloc(&conn->status_response, status_size)); + GUARD(s2n_stuffer_read_bytes(in, conn->status_response.data, status_size)); + + GUARD(s2n_x509_validator_validate_cert_stapled_ocsp_response( + &conn->x509_validator, conn, conn->status_response.data, conn->status_response.size)); + + return S2N_SUCCESS; +} diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_certificate_status.h b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_certificate_status.h index 0f5ef18742..ad5d1f380f 100644 --- a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_certificate_status.h +++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_certificate_status.h @@ -1,25 +1,25 @@ -/* - * 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. - */ - -#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_tls13_server_status_request_extension; - -int s2n_server_certificate_status_send(struct s2n_connection *conn, struct s2n_stuffer *out); -int s2n_server_certificate_status_recv(struct s2n_connection *conn, struct s2n_stuffer *in); +/* + * 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. + */ + +#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_tls13_server_status_request_extension; + +int s2n_server_certificate_status_send(struct s2n_connection *conn, struct s2n_stuffer *out); +int s2n_server_certificate_status_recv(struct s2n_connection *conn, struct s2n_stuffer *in); diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_key_share.c b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_key_share.c index af112de0f4..5203e7db57 100644 --- a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_key_share.c +++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_key_share.c @@ -1,430 +1,430 @@ -/* - * 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_server_key_share.h" -#include "tls/s2n_security_policies.h" -#include "tls/s2n_tls.h" -#include "tls/s2n_tls13.h" - -#include "utils/s2n_safety.h" - -#include "crypto/s2n_fips.h" - -static int s2n_server_key_share_send(struct s2n_connection *conn, struct s2n_stuffer *out); -static int s2n_server_key_share_recv(struct s2n_connection *conn, struct s2n_stuffer *extension); - -const s2n_extension_type s2n_server_key_share_extension = { - .iana_value = TLS_EXTENSION_KEY_SHARE, - .is_response = false, - .send = s2n_server_key_share_send, - .recv = s2n_server_key_share_recv, - .should_send = s2n_extension_send_if_tls13_connection, - .if_missing = s2n_extension_noop_if_missing, -}; - -static int s2n_server_key_share_generate_pq_hybrid(struct s2n_connection *conn, struct s2n_stuffer *out) { - notnull_check(out); - notnull_check(conn); - - ENSURE_POSIX(s2n_is_in_fips_mode() == false, S2N_ERR_PQ_KEMS_DISALLOWED_IN_FIPS); - - struct s2n_kem_group_params *server_kem_group_params = &conn->secure.server_kem_group_params; - - notnull_check(server_kem_group_params->kem_group); - GUARD(s2n_stuffer_write_uint16(out, server_kem_group_params->kem_group->iana_id)); - - struct s2n_stuffer_reservation total_share_size = { 0 }; - GUARD(s2n_stuffer_reserve_uint16(out, &total_share_size)); - - struct s2n_ecc_evp_params *server_ecc_params = &server_kem_group_params->ecc_params; - notnull_check(server_ecc_params->negotiated_curve); - GUARD(s2n_stuffer_write_uint16(out, server_ecc_params->negotiated_curve->share_size)); - GUARD(s2n_ecc_evp_generate_ephemeral_key(server_ecc_params)); - GUARD(s2n_ecc_evp_write_params_point(server_ecc_params, out)); - - notnull_check(conn->secure.chosen_client_kem_group_params); - struct s2n_kem_params *client_kem_params = &conn->secure.chosen_client_kem_group_params->kem_params; - notnull_check(client_kem_params->public_key.data); - /* s2n_kem_send_ciphertext() will generate the PQ shared secret and use - * the client's public key to encapsulate; the PQ shared secret will be - * stored in client_kem_params, and will be used during the hybrid shared - * secret derivation. */ - GUARD(s2n_kem_send_ciphertext(out, client_kem_params)); - - GUARD(s2n_stuffer_write_vector_size(&total_share_size)); - return S2N_SUCCESS; -} - -/* Check that client has sent a corresponding key share for the server's KEM group */ -int s2n_server_key_share_send_check_pq_hybrid(struct s2n_connection *conn) { - notnull_check(conn); - - ENSURE_POSIX(s2n_is_in_fips_mode() == false, S2N_ERR_PQ_KEMS_DISALLOWED_IN_FIPS); - - notnull_check(conn->secure.server_kem_group_params.kem_group); - notnull_check(conn->secure.server_kem_group_params.kem_params.kem); - notnull_check(conn->secure.server_kem_group_params.ecc_params.negotiated_curve); - - const struct s2n_kem_group *server_kem_group = conn->secure.server_kem_group_params.kem_group; - - const struct s2n_kem_preferences *kem_pref = NULL; - GUARD(s2n_connection_get_kem_preferences(conn, &kem_pref)); - notnull_check(kem_pref); - - ENSURE_POSIX(s2n_kem_preferences_includes_tls13_kem_group(kem_pref, server_kem_group->iana_id), - S2N_ERR_KEM_UNSUPPORTED_PARAMS); - - struct s2n_kem_group_params *client_params = conn->secure.chosen_client_kem_group_params; - notnull_check(client_params); - - ENSURE_POSIX(client_params->kem_group == server_kem_group, S2N_ERR_BAD_KEY_SHARE); - - ENSURE_POSIX(client_params->ecc_params.negotiated_curve == server_kem_group->curve, S2N_ERR_BAD_KEY_SHARE); - ENSURE_POSIX(client_params->ecc_params.evp_pkey != NULL, S2N_ERR_BAD_KEY_SHARE); - - ENSURE_POSIX(client_params->kem_params.kem == server_kem_group->kem, S2N_ERR_BAD_KEY_SHARE); - ENSURE_POSIX(client_params->kem_params.public_key.size == server_kem_group->kem->public_key_length, S2N_ERR_BAD_KEY_SHARE); - ENSURE_POSIX(client_params->kem_params.public_key.data != NULL, S2N_ERR_BAD_KEY_SHARE); - - return S2N_SUCCESS; -} - -/* Check that client has sent a corresponding key share for the server's EC curve */ -int s2n_server_key_share_send_check_ecdhe(struct s2n_connection *conn) { - notnull_check(conn); - - const struct s2n_ecc_preferences *ecc_pref = NULL; - GUARD(s2n_connection_get_ecc_preferences(conn, &ecc_pref)); - notnull_check(ecc_pref); - - const struct s2n_ecc_named_curve *server_curve = conn->secure.server_ecc_evp_params.negotiated_curve; - notnull_check(server_curve); - - struct s2n_ecc_evp_params *client_params = NULL; - for (size_t i = 0; i < ecc_pref->count; i++) { - if (server_curve == ecc_pref->ecc_curves[i]) { - client_params = &conn->secure.client_ecc_evp_params[i]; - break; - } - } - - notnull_check(client_params); - ENSURE_POSIX(client_params->negotiated_curve == server_curve, S2N_ERR_BAD_KEY_SHARE); - ENSURE_POSIX(client_params->evp_pkey != NULL, S2N_ERR_BAD_KEY_SHARE); - - return S2N_SUCCESS; -} - -static int s2n_server_key_share_send(struct s2n_connection *conn, struct s2n_stuffer *out) { - notnull_check(conn); - notnull_check(out); - - const struct s2n_ecc_named_curve *curve = conn->secure.server_ecc_evp_params.negotiated_curve; - const struct s2n_kem_group *kem_group = conn->secure.server_kem_group_params.kem_group; - - /* Boolean XOR: exactly one of {server_curve, server_kem_group} should be non-null. */ - ENSURE_POSIX((curve == NULL) != (kem_group == NULL), S2N_ERR_ECDHE_UNSUPPORTED_CURVE); - - /* Retry requests only require the selected named group, not an actual share. - * https://tools.ietf.org/html/rfc8446#section-4.2.8 */ - if (s2n_is_hello_retry_message(conn)) { - uint16_t named_group_id; - if (curve != NULL) { - named_group_id = curve->iana_id; - } else { - named_group_id = kem_group->iana_id; - } - - GUARD(s2n_stuffer_write_uint16(out, named_group_id)); - return S2N_SUCCESS; - } - - if (curve != NULL) { - GUARD(s2n_server_key_share_send_check_ecdhe(conn)); - GUARD(s2n_ecdhe_parameters_send(&conn->secure.server_ecc_evp_params, out)); - } else { - GUARD(s2n_server_key_share_send_check_pq_hybrid(conn)); - GUARD(s2n_server_key_share_generate_pq_hybrid(conn, out)); - } - - return S2N_SUCCESS; -} - -static int s2n_server_key_share_recv_pq_hybrid(struct s2n_connection *conn, uint16_t named_group_iana, - struct s2n_stuffer *extension) { - notnull_check(conn); - notnull_check(extension); - - /* If in FIPS mode, the client should not have sent any PQ IDs - * in the supported_groups list of the initial ClientHello */ - ENSURE_POSIX(s2n_is_in_fips_mode() == false, S2N_ERR_PQ_KEMS_DISALLOWED_IN_FIPS); - - const struct s2n_kem_preferences *kem_pref = NULL; - GUARD(s2n_connection_get_kem_preferences(conn, &kem_pref)); - notnull_check(kem_pref); - - /* This check should have been done higher up, but including it here as well for extra defense. - * Uses S2N_ERR_ECDHE_UNSUPPORTED_CURVE for backward compatibility. */ - ENSURE_POSIX(s2n_kem_preferences_includes_tls13_kem_group(kem_pref, named_group_iana), S2N_ERR_ECDHE_UNSUPPORTED_CURVE); - - size_t kem_group_index = 0; - for (size_t i = 0; i < kem_pref->tls13_kem_group_count; i++) { - if (named_group_iana == kem_pref->tls13_kem_groups[i]->iana_id) { - kem_group_index = i; - break; - } - } - - struct s2n_kem_group_params *server_kem_group_params = &conn->secure.server_kem_group_params; - server_kem_group_params->kem_group = kem_pref->tls13_kem_groups[kem_group_index]; - server_kem_group_params->kem_params.kem = kem_pref->tls13_kem_groups[kem_group_index]->kem; - server_kem_group_params->ecc_params.negotiated_curve = kem_pref->tls13_kem_groups[kem_group_index]->curve; - - /* If this a HRR, the server will only have sent the named group ID. We assign the - * appropriate KEM group params above, then exit early so that the client can - * generate the correct key share. */ - if (s2n_is_hello_retry_message(conn)) { - return S2N_SUCCESS; - } - - /* Ensure that the server's key share corresponds with a key share previously sent by the client */ - ENSURE_POSIX(conn->secure.client_kem_group_params[kem_group_index].kem_params.private_key.data != NULL, - S2N_ERR_BAD_KEY_SHARE); - ENSURE_POSIX(conn->secure.client_kem_group_params[kem_group_index].ecc_params.evp_pkey != NULL, - S2N_ERR_BAD_KEY_SHARE); - notnull_check(conn->secure.client_kem_group_params[kem_group_index].kem_group); - eq_check(conn->secure.client_kem_group_params[kem_group_index].kem_group->iana_id, named_group_iana); - conn->secure.chosen_client_kem_group_params = &conn->secure.client_kem_group_params[kem_group_index]; - - uint16_t received_total_share_size; - GUARD(s2n_stuffer_read_uint16(extension, &received_total_share_size)); - ENSURE_POSIX(received_total_share_size == server_kem_group_params->kem_group->server_share_size, S2N_ERR_BAD_KEY_SHARE); - ENSURE_POSIX(s2n_stuffer_data_available(extension) == received_total_share_size, S2N_ERR_BAD_KEY_SHARE); - - /* Parse ECC key share */ - uint16_t ecc_share_size; - struct s2n_blob point_blob; - GUARD(s2n_stuffer_read_uint16(extension, &ecc_share_size)); - ENSURE_POSIX(s2n_ecc_evp_read_params_point(extension, ecc_share_size, &point_blob) == S2N_SUCCESS, S2N_ERR_BAD_KEY_SHARE); - ENSURE_POSIX(s2n_ecc_evp_parse_params_point(&point_blob, &server_kem_group_params->ecc_params) == S2N_SUCCESS, S2N_ERR_BAD_KEY_SHARE); - ENSURE_POSIX(server_kem_group_params->ecc_params.evp_pkey != NULL, S2N_ERR_BAD_KEY_SHARE); - - /* Parse the PQ KEM key share */ - ENSURE_POSIX(s2n_kem_recv_ciphertext(extension, &conn->secure.chosen_client_kem_group_params->kem_params) == S2N_SUCCESS, - S2N_ERR_BAD_KEY_SHARE); - - return S2N_SUCCESS; -} - -static int s2n_server_key_share_recv_ecc(struct s2n_connection *conn, uint16_t named_group_iana, - struct s2n_stuffer *extension) { - notnull_check(conn); - notnull_check(extension); - - const struct s2n_ecc_preferences *ecc_pref = NULL; - GUARD(s2n_connection_get_ecc_preferences(conn, &ecc_pref)); - notnull_check(ecc_pref); - - /* This check should have been done higher up, but including it here as well for extra defense. */ - ENSURE_POSIX(s2n_ecc_preferences_includes_curve(ecc_pref, named_group_iana), - S2N_ERR_ECDHE_UNSUPPORTED_CURVE); - - size_t supported_curve_index = 0; - - for (size_t i = 0; i < ecc_pref->count; i++) { - if (named_group_iana == ecc_pref->ecc_curves[i]->iana_id) { - supported_curve_index = i; - break; - } - } - - struct s2n_ecc_evp_params *server_ecc_evp_params = &conn->secure.server_ecc_evp_params; - server_ecc_evp_params->negotiated_curve = ecc_pref->ecc_curves[supported_curve_index]; - - /* If this is a HelloRetryRequest, we won't have a key share. We just have the selected group. - * Set the server negotiated curve and exit early so a proper keyshare can be generated. */ - if (s2n_is_hello_retry_message(conn)) { - return S2N_SUCCESS; - } - - /* Key share not sent by client */ - S2N_ERROR_IF(conn->secure.client_ecc_evp_params[supported_curve_index].evp_pkey == NULL, S2N_ERR_BAD_KEY_SHARE); - - uint16_t share_size; - S2N_ERROR_IF(s2n_stuffer_data_available(extension) < sizeof(share_size), S2N_ERR_BAD_KEY_SHARE); - GUARD(s2n_stuffer_read_uint16(extension, &share_size)); - S2N_ERROR_IF(s2n_stuffer_data_available(extension) < share_size, S2N_ERR_BAD_KEY_SHARE); - - /* Proceed to parse share */ - struct s2n_blob point_blob; - S2N_ERROR_IF(s2n_ecc_evp_read_params_point(extension, share_size, &point_blob) < 0, S2N_ERR_BAD_KEY_SHARE); - S2N_ERROR_IF(s2n_ecc_evp_parse_params_point(&point_blob, server_ecc_evp_params) < 0, S2N_ERR_BAD_KEY_SHARE); - S2N_ERROR_IF(server_ecc_evp_params->evp_pkey == NULL, S2N_ERR_BAD_KEY_SHARE); - - return S2N_SUCCESS; -} - -/* - * From https://tools.ietf.org/html/rfc8446#section-4.2.8 - * - * If using (EC)DHE key establishment, servers offer exactly one - * KeyShareEntry in the ServerHello. This value MUST be in the same - * group as the KeyShareEntry value offered by the client that the - * server has selected for the negotiated key exchange. - */ -static int s2n_server_key_share_recv(struct s2n_connection *conn, struct s2n_stuffer *extension) -{ - if (s2n_connection_get_protocol_version(conn) < S2N_TLS13) { - return S2N_SUCCESS; - } - - notnull_check(conn); - notnull_check(extension); - - uint16_t negotiated_named_group_iana = 0; - S2N_ERROR_IF(s2n_stuffer_data_available(extension) < sizeof(negotiated_named_group_iana), S2N_ERR_BAD_KEY_SHARE); - GUARD(s2n_stuffer_read_uint16(extension, &negotiated_named_group_iana)); - - const struct s2n_kem_preferences *kem_pref = NULL; - GUARD(s2n_connection_get_kem_preferences(conn, &kem_pref)); - notnull_check(kem_pref); - - const struct s2n_ecc_preferences *ecc_pref = NULL; - GUARD(s2n_connection_get_ecc_preferences(conn, &ecc_pref)); - notnull_check(ecc_pref); - - if (s2n_ecc_preferences_includes_curve(ecc_pref, negotiated_named_group_iana)) { - GUARD(s2n_server_key_share_recv_ecc(conn, negotiated_named_group_iana, extension)); - } else if (s2n_kem_preferences_includes_tls13_kem_group(kem_pref, negotiated_named_group_iana)) { - GUARD(s2n_server_key_share_recv_pq_hybrid(conn, negotiated_named_group_iana, extension)); - } else { - S2N_ERROR(S2N_ERR_ECDHE_UNSUPPORTED_CURVE); - } - - return S2N_SUCCESS; -} - -/* Selects highest priority mutually supported key share, or indicates need for HRR */ -int s2n_extensions_server_key_share_select(struct s2n_connection *conn) { - notnull_check(conn); - - const struct s2n_ecc_preferences *ecc_pref = NULL; - GUARD(s2n_connection_get_ecc_preferences(conn, &ecc_pref)); - notnull_check(ecc_pref); - - const struct s2n_kem_preferences *kem_pref = NULL; - GUARD(s2n_connection_get_kem_preferences(conn, &kem_pref)); - notnull_check(kem_pref); - - /* Boolean XOR check. When receiving the supported_groups extension, s2n server - * should (exclusively) set either server_curve or server_kem_group based on the - * set of mutually supported groups. If both server_curve and server_kem_group - * are NULL, it is because client and server do not share any mutually supported - * groups; key negotiation is not possible and the handshake should be aborted - * without sending HRR. (The case of both being non-NULL should never occur, and - * is an error.) */ - const struct s2n_ecc_named_curve *server_curve = conn->secure.server_ecc_evp_params.negotiated_curve; - const struct s2n_kem_group *server_kem_group = conn->secure.server_kem_group_params.kem_group; - ENSURE_POSIX((server_curve == NULL) != (server_kem_group == NULL), S2N_ERR_ECDHE_UNSUPPORTED_CURVE); - - /* To avoid extra round trips, we prefer to negotiate a group for which we have already - * received a key share (even if it is different than the group previously chosen). In - * general, we prefer to negotiate PQ over ECDHE; however, if both client and server - * support PQ, but the client sent only EC key shares, then we will negotiate ECHDE. */ - for (size_t i = 0; i < kem_pref->tls13_kem_group_count; i++) { - if (conn->secure.mutually_supported_kem_groups[i] && conn->secure.client_kem_group_params[i].kem_group) { - notnull_check(conn->secure.client_kem_group_params[i].ecc_params.negotiated_curve); - notnull_check(conn->secure.client_kem_group_params[i].kem_params.kem); - - conn->secure.server_kem_group_params.kem_group = conn->secure.client_kem_group_params[i].kem_group; - conn->secure.server_kem_group_params.ecc_params.negotiated_curve = conn->secure.client_kem_group_params[i].ecc_params.negotiated_curve; - conn->secure.server_kem_group_params.kem_params.kem = conn->secure.client_kem_group_params[i].kem_params.kem; - conn->secure.chosen_client_kem_group_params = &conn->secure.client_kem_group_params[i]; - - conn->secure.server_ecc_evp_params.negotiated_curve = NULL; - return S2N_SUCCESS; - } - } - - for (size_t i = 0; i < ecc_pref->count; i++) { - if (conn->secure.mutually_supported_curves[i] && conn->secure.client_ecc_evp_params[i].negotiated_curve) { - conn->secure.server_ecc_evp_params.negotiated_curve = conn->secure.client_ecc_evp_params[i].negotiated_curve; - - conn->secure.server_kem_group_params.kem_group = NULL; - conn->secure.server_kem_group_params.ecc_params.negotiated_curve = NULL; - conn->secure.server_kem_group_params.kem_params.kem = NULL; - conn->secure.chosen_client_kem_group_params = NULL; - return S2N_SUCCESS; - } - } - - /* Server and client have mutually supported groups, but the client did not send key - * shares for any of them. Send HRR indicating the server's preference. */ - GUARD(s2n_set_hello_retry_required(conn)); - return S2N_SUCCESS; -} - -/* Old-style extension functions -- remove after extensions refactor is complete */ - -/* - * Calculate the data length for Server Key Share extension - * based on negotiated_curve selected in server_ecc_evp_params. - * - * Retry requests have a different key share format, - * https://tools.ietf.org/html/rfc8446#section-4.2.8 - * - * This functions does not error, but s2n_extensions_server_key_share_send() would - */ -int s2n_extensions_server_key_share_send_size(struct s2n_connection *conn) -{ - const struct s2n_ecc_named_curve* curve = conn->secure.server_ecc_evp_params.negotiated_curve; - int key_share_size = S2N_SIZE_OF_EXTENSION_TYPE - + S2N_SIZE_OF_EXTENSION_DATA_SIZE - + S2N_SIZE_OF_NAMED_GROUP; - - /* If this is a KeyShareHelloRetryRequest we don't include the share size */ - if (s2n_is_hello_retry_message(conn)) { - return key_share_size; - } - - if (curve == NULL) { - return 0; - } - - /* If this is a full KeyShareEntry, include the share size */ - key_share_size += (S2N_SIZE_OF_KEY_SHARE_SIZE + curve->share_size); - - return key_share_size; -} - -/* - * Sends Key Share extension in Server Hello. - * - * Expects negotiated_curve to be set and generates a ephemeral key for key sharing - */ -int s2n_extensions_server_key_share_send(struct s2n_connection *conn, struct s2n_stuffer *out) -{ - return s2n_extension_send(&s2n_server_key_share_extension, conn, out); -} - -/* - * Client receives a Server Hello key share. - * - * If the curve is supported, conn->secure.server_ecc_evp_params will be set. - */ -int s2n_extensions_server_key_share_recv(struct s2n_connection *conn, struct s2n_stuffer *extension) -{ - return s2n_extension_recv(&s2n_server_key_share_extension, conn, extension); -} +/* + * 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_server_key_share.h" +#include "tls/s2n_security_policies.h" +#include "tls/s2n_tls.h" +#include "tls/s2n_tls13.h" + +#include "utils/s2n_safety.h" + +#include "crypto/s2n_fips.h" + +static int s2n_server_key_share_send(struct s2n_connection *conn, struct s2n_stuffer *out); +static int s2n_server_key_share_recv(struct s2n_connection *conn, struct s2n_stuffer *extension); + +const s2n_extension_type s2n_server_key_share_extension = { + .iana_value = TLS_EXTENSION_KEY_SHARE, + .is_response = false, + .send = s2n_server_key_share_send, + .recv = s2n_server_key_share_recv, + .should_send = s2n_extension_send_if_tls13_connection, + .if_missing = s2n_extension_noop_if_missing, +}; + +static int s2n_server_key_share_generate_pq_hybrid(struct s2n_connection *conn, struct s2n_stuffer *out) { + notnull_check(out); + notnull_check(conn); + + ENSURE_POSIX(s2n_is_in_fips_mode() == false, S2N_ERR_PQ_KEMS_DISALLOWED_IN_FIPS); + + struct s2n_kem_group_params *server_kem_group_params = &conn->secure.server_kem_group_params; + + notnull_check(server_kem_group_params->kem_group); + GUARD(s2n_stuffer_write_uint16(out, server_kem_group_params->kem_group->iana_id)); + + struct s2n_stuffer_reservation total_share_size = { 0 }; + GUARD(s2n_stuffer_reserve_uint16(out, &total_share_size)); + + struct s2n_ecc_evp_params *server_ecc_params = &server_kem_group_params->ecc_params; + notnull_check(server_ecc_params->negotiated_curve); + GUARD(s2n_stuffer_write_uint16(out, server_ecc_params->negotiated_curve->share_size)); + GUARD(s2n_ecc_evp_generate_ephemeral_key(server_ecc_params)); + GUARD(s2n_ecc_evp_write_params_point(server_ecc_params, out)); + + notnull_check(conn->secure.chosen_client_kem_group_params); + struct s2n_kem_params *client_kem_params = &conn->secure.chosen_client_kem_group_params->kem_params; + notnull_check(client_kem_params->public_key.data); + /* s2n_kem_send_ciphertext() will generate the PQ shared secret and use + * the client's public key to encapsulate; the PQ shared secret will be + * stored in client_kem_params, and will be used during the hybrid shared + * secret derivation. */ + GUARD(s2n_kem_send_ciphertext(out, client_kem_params)); + + GUARD(s2n_stuffer_write_vector_size(&total_share_size)); + return S2N_SUCCESS; +} + +/* Check that client has sent a corresponding key share for the server's KEM group */ +int s2n_server_key_share_send_check_pq_hybrid(struct s2n_connection *conn) { + notnull_check(conn); + + ENSURE_POSIX(s2n_is_in_fips_mode() == false, S2N_ERR_PQ_KEMS_DISALLOWED_IN_FIPS); + + notnull_check(conn->secure.server_kem_group_params.kem_group); + notnull_check(conn->secure.server_kem_group_params.kem_params.kem); + notnull_check(conn->secure.server_kem_group_params.ecc_params.negotiated_curve); + + const struct s2n_kem_group *server_kem_group = conn->secure.server_kem_group_params.kem_group; + + const struct s2n_kem_preferences *kem_pref = NULL; + GUARD(s2n_connection_get_kem_preferences(conn, &kem_pref)); + notnull_check(kem_pref); + + ENSURE_POSIX(s2n_kem_preferences_includes_tls13_kem_group(kem_pref, server_kem_group->iana_id), + S2N_ERR_KEM_UNSUPPORTED_PARAMS); + + struct s2n_kem_group_params *client_params = conn->secure.chosen_client_kem_group_params; + notnull_check(client_params); + + ENSURE_POSIX(client_params->kem_group == server_kem_group, S2N_ERR_BAD_KEY_SHARE); + + ENSURE_POSIX(client_params->ecc_params.negotiated_curve == server_kem_group->curve, S2N_ERR_BAD_KEY_SHARE); + ENSURE_POSIX(client_params->ecc_params.evp_pkey != NULL, S2N_ERR_BAD_KEY_SHARE); + + ENSURE_POSIX(client_params->kem_params.kem == server_kem_group->kem, S2N_ERR_BAD_KEY_SHARE); + ENSURE_POSIX(client_params->kem_params.public_key.size == server_kem_group->kem->public_key_length, S2N_ERR_BAD_KEY_SHARE); + ENSURE_POSIX(client_params->kem_params.public_key.data != NULL, S2N_ERR_BAD_KEY_SHARE); + + return S2N_SUCCESS; +} + +/* Check that client has sent a corresponding key share for the server's EC curve */ +int s2n_server_key_share_send_check_ecdhe(struct s2n_connection *conn) { + notnull_check(conn); + + const struct s2n_ecc_preferences *ecc_pref = NULL; + GUARD(s2n_connection_get_ecc_preferences(conn, &ecc_pref)); + notnull_check(ecc_pref); + + const struct s2n_ecc_named_curve *server_curve = conn->secure.server_ecc_evp_params.negotiated_curve; + notnull_check(server_curve); + + struct s2n_ecc_evp_params *client_params = NULL; + for (size_t i = 0; i < ecc_pref->count; i++) { + if (server_curve == ecc_pref->ecc_curves[i]) { + client_params = &conn->secure.client_ecc_evp_params[i]; + break; + } + } + + notnull_check(client_params); + ENSURE_POSIX(client_params->negotiated_curve == server_curve, S2N_ERR_BAD_KEY_SHARE); + ENSURE_POSIX(client_params->evp_pkey != NULL, S2N_ERR_BAD_KEY_SHARE); + + return S2N_SUCCESS; +} + +static int s2n_server_key_share_send(struct s2n_connection *conn, struct s2n_stuffer *out) { + notnull_check(conn); + notnull_check(out); + + const struct s2n_ecc_named_curve *curve = conn->secure.server_ecc_evp_params.negotiated_curve; + const struct s2n_kem_group *kem_group = conn->secure.server_kem_group_params.kem_group; + + /* Boolean XOR: exactly one of {server_curve, server_kem_group} should be non-null. */ + ENSURE_POSIX((curve == NULL) != (kem_group == NULL), S2N_ERR_ECDHE_UNSUPPORTED_CURVE); + + /* Retry requests only require the selected named group, not an actual share. + * https://tools.ietf.org/html/rfc8446#section-4.2.8 */ + if (s2n_is_hello_retry_message(conn)) { + uint16_t named_group_id; + if (curve != NULL) { + named_group_id = curve->iana_id; + } else { + named_group_id = kem_group->iana_id; + } + + GUARD(s2n_stuffer_write_uint16(out, named_group_id)); + return S2N_SUCCESS; + } + + if (curve != NULL) { + GUARD(s2n_server_key_share_send_check_ecdhe(conn)); + GUARD(s2n_ecdhe_parameters_send(&conn->secure.server_ecc_evp_params, out)); + } else { + GUARD(s2n_server_key_share_send_check_pq_hybrid(conn)); + GUARD(s2n_server_key_share_generate_pq_hybrid(conn, out)); + } + + return S2N_SUCCESS; +} + +static int s2n_server_key_share_recv_pq_hybrid(struct s2n_connection *conn, uint16_t named_group_iana, + struct s2n_stuffer *extension) { + notnull_check(conn); + notnull_check(extension); + + /* If in FIPS mode, the client should not have sent any PQ IDs + * in the supported_groups list of the initial ClientHello */ + ENSURE_POSIX(s2n_is_in_fips_mode() == false, S2N_ERR_PQ_KEMS_DISALLOWED_IN_FIPS); + + const struct s2n_kem_preferences *kem_pref = NULL; + GUARD(s2n_connection_get_kem_preferences(conn, &kem_pref)); + notnull_check(kem_pref); + + /* This check should have been done higher up, but including it here as well for extra defense. + * Uses S2N_ERR_ECDHE_UNSUPPORTED_CURVE for backward compatibility. */ + ENSURE_POSIX(s2n_kem_preferences_includes_tls13_kem_group(kem_pref, named_group_iana), S2N_ERR_ECDHE_UNSUPPORTED_CURVE); + + size_t kem_group_index = 0; + for (size_t i = 0; i < kem_pref->tls13_kem_group_count; i++) { + if (named_group_iana == kem_pref->tls13_kem_groups[i]->iana_id) { + kem_group_index = i; + break; + } + } + + struct s2n_kem_group_params *server_kem_group_params = &conn->secure.server_kem_group_params; + server_kem_group_params->kem_group = kem_pref->tls13_kem_groups[kem_group_index]; + server_kem_group_params->kem_params.kem = kem_pref->tls13_kem_groups[kem_group_index]->kem; + server_kem_group_params->ecc_params.negotiated_curve = kem_pref->tls13_kem_groups[kem_group_index]->curve; + + /* If this a HRR, the server will only have sent the named group ID. We assign the + * appropriate KEM group params above, then exit early so that the client can + * generate the correct key share. */ + if (s2n_is_hello_retry_message(conn)) { + return S2N_SUCCESS; + } + + /* Ensure that the server's key share corresponds with a key share previously sent by the client */ + ENSURE_POSIX(conn->secure.client_kem_group_params[kem_group_index].kem_params.private_key.data != NULL, + S2N_ERR_BAD_KEY_SHARE); + ENSURE_POSIX(conn->secure.client_kem_group_params[kem_group_index].ecc_params.evp_pkey != NULL, + S2N_ERR_BAD_KEY_SHARE); + notnull_check(conn->secure.client_kem_group_params[kem_group_index].kem_group); + eq_check(conn->secure.client_kem_group_params[kem_group_index].kem_group->iana_id, named_group_iana); + conn->secure.chosen_client_kem_group_params = &conn->secure.client_kem_group_params[kem_group_index]; + + uint16_t received_total_share_size; + GUARD(s2n_stuffer_read_uint16(extension, &received_total_share_size)); + ENSURE_POSIX(received_total_share_size == server_kem_group_params->kem_group->server_share_size, S2N_ERR_BAD_KEY_SHARE); + ENSURE_POSIX(s2n_stuffer_data_available(extension) == received_total_share_size, S2N_ERR_BAD_KEY_SHARE); + + /* Parse ECC key share */ + uint16_t ecc_share_size; + struct s2n_blob point_blob; + GUARD(s2n_stuffer_read_uint16(extension, &ecc_share_size)); + ENSURE_POSIX(s2n_ecc_evp_read_params_point(extension, ecc_share_size, &point_blob) == S2N_SUCCESS, S2N_ERR_BAD_KEY_SHARE); + ENSURE_POSIX(s2n_ecc_evp_parse_params_point(&point_blob, &server_kem_group_params->ecc_params) == S2N_SUCCESS, S2N_ERR_BAD_KEY_SHARE); + ENSURE_POSIX(server_kem_group_params->ecc_params.evp_pkey != NULL, S2N_ERR_BAD_KEY_SHARE); + + /* Parse the PQ KEM key share */ + ENSURE_POSIX(s2n_kem_recv_ciphertext(extension, &conn->secure.chosen_client_kem_group_params->kem_params) == S2N_SUCCESS, + S2N_ERR_BAD_KEY_SHARE); + + return S2N_SUCCESS; +} + +static int s2n_server_key_share_recv_ecc(struct s2n_connection *conn, uint16_t named_group_iana, + struct s2n_stuffer *extension) { + notnull_check(conn); + notnull_check(extension); + + const struct s2n_ecc_preferences *ecc_pref = NULL; + GUARD(s2n_connection_get_ecc_preferences(conn, &ecc_pref)); + notnull_check(ecc_pref); + + /* This check should have been done higher up, but including it here as well for extra defense. */ + ENSURE_POSIX(s2n_ecc_preferences_includes_curve(ecc_pref, named_group_iana), + S2N_ERR_ECDHE_UNSUPPORTED_CURVE); + + size_t supported_curve_index = 0; + + for (size_t i = 0; i < ecc_pref->count; i++) { + if (named_group_iana == ecc_pref->ecc_curves[i]->iana_id) { + supported_curve_index = i; + break; + } + } + + struct s2n_ecc_evp_params *server_ecc_evp_params = &conn->secure.server_ecc_evp_params; + server_ecc_evp_params->negotiated_curve = ecc_pref->ecc_curves[supported_curve_index]; + + /* If this is a HelloRetryRequest, we won't have a key share. We just have the selected group. + * Set the server negotiated curve and exit early so a proper keyshare can be generated. */ + if (s2n_is_hello_retry_message(conn)) { + return S2N_SUCCESS; + } + + /* Key share not sent by client */ + S2N_ERROR_IF(conn->secure.client_ecc_evp_params[supported_curve_index].evp_pkey == NULL, S2N_ERR_BAD_KEY_SHARE); + + uint16_t share_size; + S2N_ERROR_IF(s2n_stuffer_data_available(extension) < sizeof(share_size), S2N_ERR_BAD_KEY_SHARE); + GUARD(s2n_stuffer_read_uint16(extension, &share_size)); + S2N_ERROR_IF(s2n_stuffer_data_available(extension) < share_size, S2N_ERR_BAD_KEY_SHARE); + + /* Proceed to parse share */ + struct s2n_blob point_blob; + S2N_ERROR_IF(s2n_ecc_evp_read_params_point(extension, share_size, &point_blob) < 0, S2N_ERR_BAD_KEY_SHARE); + S2N_ERROR_IF(s2n_ecc_evp_parse_params_point(&point_blob, server_ecc_evp_params) < 0, S2N_ERR_BAD_KEY_SHARE); + S2N_ERROR_IF(server_ecc_evp_params->evp_pkey == NULL, S2N_ERR_BAD_KEY_SHARE); + + return S2N_SUCCESS; +} + +/* + * From https://tools.ietf.org/html/rfc8446#section-4.2.8 + * + * If using (EC)DHE key establishment, servers offer exactly one + * KeyShareEntry in the ServerHello. This value MUST be in the same + * group as the KeyShareEntry value offered by the client that the + * server has selected for the negotiated key exchange. + */ +static int s2n_server_key_share_recv(struct s2n_connection *conn, struct s2n_stuffer *extension) +{ + if (s2n_connection_get_protocol_version(conn) < S2N_TLS13) { + return S2N_SUCCESS; + } + + notnull_check(conn); + notnull_check(extension); + + uint16_t negotiated_named_group_iana = 0; + S2N_ERROR_IF(s2n_stuffer_data_available(extension) < sizeof(negotiated_named_group_iana), S2N_ERR_BAD_KEY_SHARE); + GUARD(s2n_stuffer_read_uint16(extension, &negotiated_named_group_iana)); + + const struct s2n_kem_preferences *kem_pref = NULL; + GUARD(s2n_connection_get_kem_preferences(conn, &kem_pref)); + notnull_check(kem_pref); + + const struct s2n_ecc_preferences *ecc_pref = NULL; + GUARD(s2n_connection_get_ecc_preferences(conn, &ecc_pref)); + notnull_check(ecc_pref); + + if (s2n_ecc_preferences_includes_curve(ecc_pref, negotiated_named_group_iana)) { + GUARD(s2n_server_key_share_recv_ecc(conn, negotiated_named_group_iana, extension)); + } else if (s2n_kem_preferences_includes_tls13_kem_group(kem_pref, negotiated_named_group_iana)) { + GUARD(s2n_server_key_share_recv_pq_hybrid(conn, negotiated_named_group_iana, extension)); + } else { + S2N_ERROR(S2N_ERR_ECDHE_UNSUPPORTED_CURVE); + } + + return S2N_SUCCESS; +} + +/* Selects highest priority mutually supported key share, or indicates need for HRR */ +int s2n_extensions_server_key_share_select(struct s2n_connection *conn) { + notnull_check(conn); + + const struct s2n_ecc_preferences *ecc_pref = NULL; + GUARD(s2n_connection_get_ecc_preferences(conn, &ecc_pref)); + notnull_check(ecc_pref); + + const struct s2n_kem_preferences *kem_pref = NULL; + GUARD(s2n_connection_get_kem_preferences(conn, &kem_pref)); + notnull_check(kem_pref); + + /* Boolean XOR check. When receiving the supported_groups extension, s2n server + * should (exclusively) set either server_curve or server_kem_group based on the + * set of mutually supported groups. If both server_curve and server_kem_group + * are NULL, it is because client and server do not share any mutually supported + * groups; key negotiation is not possible and the handshake should be aborted + * without sending HRR. (The case of both being non-NULL should never occur, and + * is an error.) */ + const struct s2n_ecc_named_curve *server_curve = conn->secure.server_ecc_evp_params.negotiated_curve; + const struct s2n_kem_group *server_kem_group = conn->secure.server_kem_group_params.kem_group; + ENSURE_POSIX((server_curve == NULL) != (server_kem_group == NULL), S2N_ERR_ECDHE_UNSUPPORTED_CURVE); + + /* To avoid extra round trips, we prefer to negotiate a group for which we have already + * received a key share (even if it is different than the group previously chosen). In + * general, we prefer to negotiate PQ over ECDHE; however, if both client and server + * support PQ, but the client sent only EC key shares, then we will negotiate ECHDE. */ + for (size_t i = 0; i < kem_pref->tls13_kem_group_count; i++) { + if (conn->secure.mutually_supported_kem_groups[i] && conn->secure.client_kem_group_params[i].kem_group) { + notnull_check(conn->secure.client_kem_group_params[i].ecc_params.negotiated_curve); + notnull_check(conn->secure.client_kem_group_params[i].kem_params.kem); + + conn->secure.server_kem_group_params.kem_group = conn->secure.client_kem_group_params[i].kem_group; + conn->secure.server_kem_group_params.ecc_params.negotiated_curve = conn->secure.client_kem_group_params[i].ecc_params.negotiated_curve; + conn->secure.server_kem_group_params.kem_params.kem = conn->secure.client_kem_group_params[i].kem_params.kem; + conn->secure.chosen_client_kem_group_params = &conn->secure.client_kem_group_params[i]; + + conn->secure.server_ecc_evp_params.negotiated_curve = NULL; + return S2N_SUCCESS; + } + } + + for (size_t i = 0; i < ecc_pref->count; i++) { + if (conn->secure.mutually_supported_curves[i] && conn->secure.client_ecc_evp_params[i].negotiated_curve) { + conn->secure.server_ecc_evp_params.negotiated_curve = conn->secure.client_ecc_evp_params[i].negotiated_curve; + + conn->secure.server_kem_group_params.kem_group = NULL; + conn->secure.server_kem_group_params.ecc_params.negotiated_curve = NULL; + conn->secure.server_kem_group_params.kem_params.kem = NULL; + conn->secure.chosen_client_kem_group_params = NULL; + return S2N_SUCCESS; + } + } + + /* Server and client have mutually supported groups, but the client did not send key + * shares for any of them. Send HRR indicating the server's preference. */ + GUARD(s2n_set_hello_retry_required(conn)); + return S2N_SUCCESS; +} + +/* Old-style extension functions -- remove after extensions refactor is complete */ + +/* + * Calculate the data length for Server Key Share extension + * based on negotiated_curve selected in server_ecc_evp_params. + * + * Retry requests have a different key share format, + * https://tools.ietf.org/html/rfc8446#section-4.2.8 + * + * This functions does not error, but s2n_extensions_server_key_share_send() would + */ +int s2n_extensions_server_key_share_send_size(struct s2n_connection *conn) +{ + const struct s2n_ecc_named_curve* curve = conn->secure.server_ecc_evp_params.negotiated_curve; + int key_share_size = S2N_SIZE_OF_EXTENSION_TYPE + + S2N_SIZE_OF_EXTENSION_DATA_SIZE + + S2N_SIZE_OF_NAMED_GROUP; + + /* If this is a KeyShareHelloRetryRequest we don't include the share size */ + if (s2n_is_hello_retry_message(conn)) { + return key_share_size; + } + + if (curve == NULL) { + return 0; + } + + /* If this is a full KeyShareEntry, include the share size */ + key_share_size += (S2N_SIZE_OF_KEY_SHARE_SIZE + curve->share_size); + + return key_share_size; +} + +/* + * Sends Key Share extension in Server Hello. + * + * Expects negotiated_curve to be set and generates a ephemeral key for key sharing + */ +int s2n_extensions_server_key_share_send(struct s2n_connection *conn, struct s2n_stuffer *out) +{ + return s2n_extension_send(&s2n_server_key_share_extension, conn, out); +} + +/* + * Client receives a Server Hello key share. + * + * If the curve is supported, conn->secure.server_ecc_evp_params will be set. + */ +int s2n_extensions_server_key_share_recv(struct s2n_connection *conn, struct s2n_stuffer *extension) +{ + return s2n_extension_recv(&s2n_server_key_share_extension, conn, extension); +} diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_key_share.h b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_key_share.h index 11a289d1de..afc1589a18 100644 --- a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_key_share.h +++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_key_share.h @@ -1,30 +1,30 @@ -/* - * 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. - */ - -#pragma once - -#include "tls/s2n_connection.h" -#include "stuffer/s2n_stuffer.h" - -#include "tls/extensions/s2n_key_share.h" - -extern const s2n_extension_type s2n_server_key_share_extension; - -extern int s2n_extensions_server_key_share_select(struct s2n_connection *conn); - -/* Old-style extension functions -- remove after extensions refactor is complete */ -extern int s2n_extensions_server_key_share_send_size(struct s2n_connection *conn); -extern int s2n_extensions_server_key_share_send(struct s2n_connection *conn, struct s2n_stuffer *out); -extern int s2n_extensions_server_key_share_recv(struct s2n_connection *conn, struct s2n_stuffer *extension); +/* + * 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. + */ + +#pragma once + +#include "tls/s2n_connection.h" +#include "stuffer/s2n_stuffer.h" + +#include "tls/extensions/s2n_key_share.h" + +extern const s2n_extension_type s2n_server_key_share_extension; + +extern int s2n_extensions_server_key_share_select(struct s2n_connection *conn); + +/* Old-style extension functions -- remove after extensions refactor is complete */ +extern int s2n_extensions_server_key_share_send_size(struct s2n_connection *conn); +extern int s2n_extensions_server_key_share_send(struct s2n_connection *conn, struct s2n_stuffer *out); +extern int s2n_extensions_server_key_share_recv(struct s2n_connection *conn, struct s2n_stuffer *extension); diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_max_fragment_length.c b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_max_fragment_length.c index 69b1530e54..65a0c611dc 100644 --- a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_max_fragment_length.c +++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_max_fragment_length.c @@ -1,61 +1,61 @@ -/* - * 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 "error/s2n_errno.h" - -#include "stuffer/s2n_stuffer.h" - -#include "utils/s2n_safety.h" - -#include "tls/s2n_tls_parameters.h" -#include "tls/s2n_connection.h" - -#include "tls/extensions/s2n_server_max_fragment_length.h" - -static bool s2n_max_fragment_length_should_send(struct s2n_connection *conn); -static int s2n_max_fragment_length_send(struct s2n_connection *conn, struct s2n_stuffer *out); -static int s2n_max_fragment_length_recv(struct s2n_connection *conn, struct s2n_stuffer *extension); - -const s2n_extension_type s2n_server_max_fragment_length_extension = { - .iana_value = TLS_EXTENSION_MAX_FRAG_LEN, - .is_response = true, - .send = s2n_max_fragment_length_send, - .recv = s2n_max_fragment_length_recv, - .should_send = s2n_max_fragment_length_should_send, - .if_missing = s2n_extension_noop_if_missing, -}; - -static bool s2n_max_fragment_length_should_send(struct s2n_connection *conn) -{ - return conn && conn->mfl_code != S2N_TLS_MAX_FRAG_LEN_EXT_NONE; -} - -static int s2n_max_fragment_length_send(struct s2n_connection *conn, struct s2n_stuffer *out) -{ - notnull_check(conn); - GUARD(s2n_stuffer_write_uint8(out, conn->mfl_code)); - return S2N_SUCCESS; -} - -static int s2n_max_fragment_length_recv(struct s2n_connection *conn, struct s2n_stuffer *extension) -{ - notnull_check(conn); - notnull_check(conn->config); - - uint8_t mfl_code; - GUARD(s2n_stuffer_read_uint8(extension, &mfl_code)); - S2N_ERROR_IF(mfl_code != conn->config->mfl_code, S2N_ERR_MAX_FRAG_LEN_MISMATCH); - return S2N_SUCCESS; -} +/* + * 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 "error/s2n_errno.h" + +#include "stuffer/s2n_stuffer.h" + +#include "utils/s2n_safety.h" + +#include "tls/s2n_tls_parameters.h" +#include "tls/s2n_connection.h" + +#include "tls/extensions/s2n_server_max_fragment_length.h" + +static bool s2n_max_fragment_length_should_send(struct s2n_connection *conn); +static int s2n_max_fragment_length_send(struct s2n_connection *conn, struct s2n_stuffer *out); +static int s2n_max_fragment_length_recv(struct s2n_connection *conn, struct s2n_stuffer *extension); + +const s2n_extension_type s2n_server_max_fragment_length_extension = { + .iana_value = TLS_EXTENSION_MAX_FRAG_LEN, + .is_response = true, + .send = s2n_max_fragment_length_send, + .recv = s2n_max_fragment_length_recv, + .should_send = s2n_max_fragment_length_should_send, + .if_missing = s2n_extension_noop_if_missing, +}; + +static bool s2n_max_fragment_length_should_send(struct s2n_connection *conn) +{ + return conn && conn->mfl_code != S2N_TLS_MAX_FRAG_LEN_EXT_NONE; +} + +static int s2n_max_fragment_length_send(struct s2n_connection *conn, struct s2n_stuffer *out) +{ + notnull_check(conn); + GUARD(s2n_stuffer_write_uint8(out, conn->mfl_code)); + return S2N_SUCCESS; +} + +static int s2n_max_fragment_length_recv(struct s2n_connection *conn, struct s2n_stuffer *extension) +{ + notnull_check(conn); + notnull_check(conn->config); + + uint8_t mfl_code; + GUARD(s2n_stuffer_read_uint8(extension, &mfl_code)); + S2N_ERROR_IF(mfl_code != conn->config->mfl_code, S2N_ERR_MAX_FRAG_LEN_MISMATCH); + return S2N_SUCCESS; +} diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_max_fragment_length.h b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_max_fragment_length.h index 8a8ae81ad1..57211c20b8 100644 --- a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_max_fragment_length.h +++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_max_fragment_length.h @@ -1,20 +1,20 @@ -/* - * 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. - */ - -#pragma once - -#include "tls/extensions/s2n_extension_type.h" - -extern const s2n_extension_type s2n_server_max_fragment_length_extension; +/* + * 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. + */ + +#pragma once + +#include "tls/extensions/s2n_extension_type.h" + +extern const s2n_extension_type s2n_server_max_fragment_length_extension; diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_renegotiation_info.c b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_renegotiation_info.c index aac791c43c..f7d4ee7c97 100644 --- a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_renegotiation_info.c +++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_renegotiation_info.c @@ -1,87 +1,87 @@ -/* - * 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 "error/s2n_errno.h" - -#include "stuffer/s2n_stuffer.h" - -#include "utils/s2n_safety.h" - -#include "tls/s2n_tls_parameters.h" -#include "tls/s2n_connection.h" -#include "tls/s2n_tls.h" -#include "tls/extensions/s2n_server_renegotiation_info.h" - -static bool s2n_renegotiation_info_should_send(struct s2n_connection *conn); -static int s2n_renegotiation_info_send(struct s2n_connection *conn, struct s2n_stuffer *out); -static int s2n_renegotiation_info_recv(struct s2n_connection *conn, struct s2n_stuffer *extension); - -const s2n_extension_type s2n_server_renegotiation_info_extension = { - .iana_value = TLS_EXTENSION_RENEGOTIATION_INFO, - .is_response = false, - .send = s2n_renegotiation_info_send, - .recv = s2n_renegotiation_info_recv, - .should_send = s2n_renegotiation_info_should_send, - .if_missing = s2n_extension_noop_if_missing, -}; - -static bool s2n_renegotiation_info_should_send(struct s2n_connection *conn) -{ - return conn && conn->secure_renegotiation && s2n_connection_get_protocol_version(conn) < S2N_TLS13; -} - -static int s2n_renegotiation_info_send(struct s2n_connection *conn, struct s2n_stuffer *out) -{ - /* renegotiated_connection length. Zero since we don't support renegotiation. */ - GUARD(s2n_stuffer_write_uint8(out, 0)); - return S2N_SUCCESS; -} - -static int s2n_renegotiation_info_recv(struct s2n_connection *conn, struct s2n_stuffer *extension) -{ - /* RFC5746 Section 3.4: The client MUST then verify that the length of - * the "renegotiated_connection" field is zero, and if it is not, MUST - * abort the handshake. */ - uint8_t renegotiated_connection_len; - GUARD(s2n_stuffer_read_uint8(extension, &renegotiated_connection_len)); - S2N_ERROR_IF(s2n_stuffer_data_available(extension), S2N_ERR_NON_EMPTY_RENEGOTIATION_INFO); - S2N_ERROR_IF(renegotiated_connection_len, S2N_ERR_NON_EMPTY_RENEGOTIATION_INFO); - - notnull_check(conn); - conn->secure_renegotiation = 1; - return S2N_SUCCESS; -} - -/* Old-style extension functions -- remove after extensions refactor is complete */ - -int s2n_recv_server_renegotiation_info_ext(struct s2n_connection *conn, struct s2n_stuffer *extension) -{ - return s2n_extension_recv(&s2n_server_renegotiation_info_extension, conn, extension); -} - -int s2n_send_server_renegotiation_info_ext(struct s2n_connection *conn, struct s2n_stuffer *out) -{ - return s2n_extension_send(&s2n_server_renegotiation_info_extension, conn, out); -} - -int s2n_server_renegotiation_info_ext_size(struct s2n_connection *conn) -{ - if (s2n_renegotiation_info_should_send(conn)) { - /* 2 for ext type, 2 for extension length, 1 for value of 0 */ - return 5; - } - - return 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 "error/s2n_errno.h" + +#include "stuffer/s2n_stuffer.h" + +#include "utils/s2n_safety.h" + +#include "tls/s2n_tls_parameters.h" +#include "tls/s2n_connection.h" +#include "tls/s2n_tls.h" +#include "tls/extensions/s2n_server_renegotiation_info.h" + +static bool s2n_renegotiation_info_should_send(struct s2n_connection *conn); +static int s2n_renegotiation_info_send(struct s2n_connection *conn, struct s2n_stuffer *out); +static int s2n_renegotiation_info_recv(struct s2n_connection *conn, struct s2n_stuffer *extension); + +const s2n_extension_type s2n_server_renegotiation_info_extension = { + .iana_value = TLS_EXTENSION_RENEGOTIATION_INFO, + .is_response = false, + .send = s2n_renegotiation_info_send, + .recv = s2n_renegotiation_info_recv, + .should_send = s2n_renegotiation_info_should_send, + .if_missing = s2n_extension_noop_if_missing, +}; + +static bool s2n_renegotiation_info_should_send(struct s2n_connection *conn) +{ + return conn && conn->secure_renegotiation && s2n_connection_get_protocol_version(conn) < S2N_TLS13; +} + +static int s2n_renegotiation_info_send(struct s2n_connection *conn, struct s2n_stuffer *out) +{ + /* renegotiated_connection length. Zero since we don't support renegotiation. */ + GUARD(s2n_stuffer_write_uint8(out, 0)); + return S2N_SUCCESS; +} + +static int s2n_renegotiation_info_recv(struct s2n_connection *conn, struct s2n_stuffer *extension) +{ + /* RFC5746 Section 3.4: The client MUST then verify that the length of + * the "renegotiated_connection" field is zero, and if it is not, MUST + * abort the handshake. */ + uint8_t renegotiated_connection_len; + GUARD(s2n_stuffer_read_uint8(extension, &renegotiated_connection_len)); + S2N_ERROR_IF(s2n_stuffer_data_available(extension), S2N_ERR_NON_EMPTY_RENEGOTIATION_INFO); + S2N_ERROR_IF(renegotiated_connection_len, S2N_ERR_NON_EMPTY_RENEGOTIATION_INFO); + + notnull_check(conn); + conn->secure_renegotiation = 1; + return S2N_SUCCESS; +} + +/* Old-style extension functions -- remove after extensions refactor is complete */ + +int s2n_recv_server_renegotiation_info_ext(struct s2n_connection *conn, struct s2n_stuffer *extension) +{ + return s2n_extension_recv(&s2n_server_renegotiation_info_extension, conn, extension); +} + +int s2n_send_server_renegotiation_info_ext(struct s2n_connection *conn, struct s2n_stuffer *out) +{ + return s2n_extension_send(&s2n_server_renegotiation_info_extension, conn, out); +} + +int s2n_server_renegotiation_info_ext_size(struct s2n_connection *conn) +{ + if (s2n_renegotiation_info_should_send(conn)) { + /* 2 for ext type, 2 for extension length, 1 for value of 0 */ + return 5; + } + + return 0; +} diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_renegotiation_info.h b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_renegotiation_info.h index b037b2182a..3fd0f128e9 100644 --- a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_renegotiation_info.h +++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_renegotiation_info.h @@ -1,27 +1,27 @@ -/* - * 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. - */ - -#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_server_renegotiation_info_extension; - -/* Old-style extension functions -- remove after extensions refactor is complete */ -int s2n_recv_server_renegotiation_info_ext(struct s2n_connection *conn, struct s2n_stuffer *extension); -int s2n_send_server_renegotiation_info_ext(struct s2n_connection *conn, struct s2n_stuffer *out); -int s2n_server_renegotiation_info_ext_size(struct s2n_connection *conn); +/* + * 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. + */ + +#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_server_renegotiation_info_extension; + +/* Old-style extension functions -- remove after extensions refactor is complete */ +int s2n_recv_server_renegotiation_info_ext(struct s2n_connection *conn, struct s2n_stuffer *extension); +int s2n_send_server_renegotiation_info_ext(struct s2n_connection *conn, struct s2n_stuffer *out); +int s2n_server_renegotiation_info_ext_size(struct s2n_connection *conn); diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_sct_list.c b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_sct_list.c index 8a8158aecf..88b2cf7837 100644 --- a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_sct_list.c +++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_sct_list.c @@ -1,67 +1,67 @@ -/* - * 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 "stuffer/s2n_stuffer.h" -#include "tls/s2n_connection.h" -#include "tls/s2n_tls.h" -#include "tls/extensions/s2n_server_sct_list.h" - -#include "utils/s2n_safety.h" -#include "utils/s2n_blob.h" - -static bool s2n_server_sct_list_should_send(struct s2n_connection *conn); -static int s2n_server_sct_list_send(struct s2n_connection *conn, struct s2n_stuffer *out); -static int s2n_server_sct_list_recv(struct s2n_connection *conn, struct s2n_stuffer *extension); - -const s2n_extension_type s2n_server_sct_list_extension = { - .iana_value = TLS_EXTENSION_SCT_LIST, - .is_response = true, - .send = s2n_server_sct_list_send, - .recv = s2n_server_sct_list_recv, - .should_send = s2n_server_sct_list_should_send, - .if_missing = s2n_extension_noop_if_missing, -}; - -static bool s2n_server_sct_list_should_send(struct s2n_connection *conn) -{ - return s2n_server_can_send_sct_list(conn); -} - -int s2n_server_sct_list_send(struct s2n_connection *conn, struct s2n_stuffer *out) -{ - notnull_check(conn); - struct s2n_blob *sct_list = &conn->handshake_params.our_chain_and_key->sct_list; - - notnull_check(sct_list); - GUARD(s2n_stuffer_write(out, sct_list)); - - return S2N_SUCCESS; -} - -int s2n_server_sct_list_recv(struct s2n_connection *conn, struct s2n_stuffer *extension) -{ - notnull_check(conn); - - struct s2n_blob sct_list; - size_t data_available = s2n_stuffer_data_available(extension); - GUARD(s2n_blob_init(&sct_list, - s2n_stuffer_raw_read(extension, data_available), - data_available)); - notnull_check(sct_list.data); - - GUARD(s2n_dup(&sct_list, &conn->ct_response)); - - return S2N_SUCCESS; -} +/* + * 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 "stuffer/s2n_stuffer.h" +#include "tls/s2n_connection.h" +#include "tls/s2n_tls.h" +#include "tls/extensions/s2n_server_sct_list.h" + +#include "utils/s2n_safety.h" +#include "utils/s2n_blob.h" + +static bool s2n_server_sct_list_should_send(struct s2n_connection *conn); +static int s2n_server_sct_list_send(struct s2n_connection *conn, struct s2n_stuffer *out); +static int s2n_server_sct_list_recv(struct s2n_connection *conn, struct s2n_stuffer *extension); + +const s2n_extension_type s2n_server_sct_list_extension = { + .iana_value = TLS_EXTENSION_SCT_LIST, + .is_response = true, + .send = s2n_server_sct_list_send, + .recv = s2n_server_sct_list_recv, + .should_send = s2n_server_sct_list_should_send, + .if_missing = s2n_extension_noop_if_missing, +}; + +static bool s2n_server_sct_list_should_send(struct s2n_connection *conn) +{ + return s2n_server_can_send_sct_list(conn); +} + +int s2n_server_sct_list_send(struct s2n_connection *conn, struct s2n_stuffer *out) +{ + notnull_check(conn); + struct s2n_blob *sct_list = &conn->handshake_params.our_chain_and_key->sct_list; + + notnull_check(sct_list); + GUARD(s2n_stuffer_write(out, sct_list)); + + return S2N_SUCCESS; +} + +int s2n_server_sct_list_recv(struct s2n_connection *conn, struct s2n_stuffer *extension) +{ + notnull_check(conn); + + struct s2n_blob sct_list; + size_t data_available = s2n_stuffer_data_available(extension); + GUARD(s2n_blob_init(&sct_list, + s2n_stuffer_raw_read(extension, data_available), + data_available)); + notnull_check(sct_list.data); + + GUARD(s2n_dup(&sct_list, &conn->ct_response)); + + return S2N_SUCCESS; +} diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_sct_list.h b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_sct_list.h index 2632c76238..08dd86fdb8 100644 --- a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_sct_list.h +++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_sct_list.h @@ -1,20 +1,20 @@ -/* - * 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. - */ - -#pragma once - -#include "tls/extensions/s2n_extension_type.h" - -extern const s2n_extension_type s2n_server_sct_list_extension; +/* + * 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. + */ + +#pragma once + +#include "tls/extensions/s2n_extension_type.h" + +extern const s2n_extension_type s2n_server_sct_list_extension; diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_server_name.c b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_server_name.c index 158a9eae6c..22e0b03cd7 100644 --- a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_server_name.c +++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_server_name.c @@ -1,51 +1,51 @@ -/* - * 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 "stuffer/s2n_stuffer.h" - -#include "tls/s2n_connection.h" -#include "tls/extensions/s2n_server_server_name.h" - -static bool s2n_server_name_should_send(struct s2n_connection *conn); -static int s2n_server_name_send(struct s2n_connection *conn, struct s2n_stuffer *out); -static int s2n_server_name_recv(struct s2n_connection *conn, struct s2n_stuffer *extension); - -const s2n_extension_type s2n_server_server_name_extension = { - .iana_value = TLS_EXTENSION_SERVER_NAME, - .is_response = true, - .send = s2n_server_name_send, - .recv = s2n_server_name_recv, - .should_send = s2n_server_name_should_send, - .if_missing = s2n_extension_noop_if_missing, -}; - -static bool s2n_server_name_should_send(struct s2n_connection *conn) -{ - return conn && conn->server_name_used && !s2n_connection_is_session_resumed(conn); -} - -static int s2n_server_name_send(struct s2n_connection *conn, struct s2n_stuffer *out) -{ - /* Write nothing. The extension just needs to exist. */ - return S2N_SUCCESS; -} - -static int s2n_server_name_recv(struct s2n_connection *conn, struct s2n_stuffer *extension) -{ - notnull_check(conn); - /* Read nothing. The extension just needs to exist. */ - conn->server_name_used = 1; - return S2N_SUCCESS; -} +/* + * 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 "stuffer/s2n_stuffer.h" + +#include "tls/s2n_connection.h" +#include "tls/extensions/s2n_server_server_name.h" + +static bool s2n_server_name_should_send(struct s2n_connection *conn); +static int s2n_server_name_send(struct s2n_connection *conn, struct s2n_stuffer *out); +static int s2n_server_name_recv(struct s2n_connection *conn, struct s2n_stuffer *extension); + +const s2n_extension_type s2n_server_server_name_extension = { + .iana_value = TLS_EXTENSION_SERVER_NAME, + .is_response = true, + .send = s2n_server_name_send, + .recv = s2n_server_name_recv, + .should_send = s2n_server_name_should_send, + .if_missing = s2n_extension_noop_if_missing, +}; + +static bool s2n_server_name_should_send(struct s2n_connection *conn) +{ + return conn && conn->server_name_used && !s2n_connection_is_session_resumed(conn); +} + +static int s2n_server_name_send(struct s2n_connection *conn, struct s2n_stuffer *out) +{ + /* Write nothing. The extension just needs to exist. */ + return S2N_SUCCESS; +} + +static int s2n_server_name_recv(struct s2n_connection *conn, struct s2n_stuffer *extension) +{ + notnull_check(conn); + /* Read nothing. The extension just needs to exist. */ + conn->server_name_used = 1; + return S2N_SUCCESS; +} diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_server_name.h b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_server_name.h index 8ed13d3084..2519dfcd18 100644 --- a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_server_name.h +++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_server_name.h @@ -1,20 +1,20 @@ -/* - * 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. - */ - -#pragma once - -#include "tls/extensions/s2n_extension_type.h" - -extern const s2n_extension_type s2n_server_server_name_extension; +/* + * 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. + */ + +#pragma once + +#include "tls/extensions/s2n_extension_type.h" + +extern const s2n_extension_type s2n_server_server_name_extension; diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_session_ticket.c b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_session_ticket.c index 74875f05a6..02a52c6cf7 100644 --- a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_session_ticket.c +++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_session_ticket.c @@ -1,68 +1,68 @@ -/* - * 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 "stuffer/s2n_stuffer.h" - -#include "tls/s2n_tls_parameters.h" -#include "tls/s2n_connection.h" -#include "tls/s2n_tls.h" -#include "tls/extensions/s2n_server_session_ticket.h" - -static bool s2n_session_ticket_should_send(struct s2n_connection *conn); -static int s2n_session_ticket_recv(struct s2n_connection *conn, struct s2n_stuffer *extension); - -const s2n_extension_type s2n_server_session_ticket_extension = { - .iana_value = TLS_EXTENSION_SESSION_TICKET, - .is_response = true, - .send = s2n_extension_send_noop, - .recv = s2n_session_ticket_recv, - .should_send = s2n_session_ticket_should_send, - .if_missing = s2n_extension_noop_if_missing, -}; - -static bool s2n_session_ticket_should_send(struct s2n_connection *conn) -{ - return s2n_server_sending_nst(conn) && s2n_connection_get_protocol_version(conn) < S2N_TLS13; -} - -static int s2n_session_ticket_recv(struct s2n_connection *conn, struct s2n_stuffer *extension) -{ - /* Read nothing. The extension just needs to exist. */ - notnull_check(conn); - conn->session_ticket_status = S2N_NEW_TICKET; - return S2N_SUCCESS; -} - -/* Old-style extension functions -- remove after extensions refactor is complete */ - -int s2n_recv_server_session_ticket_ext(struct s2n_connection *conn, struct s2n_stuffer *extension) -{ - return s2n_extension_recv(&s2n_server_session_ticket_extension, conn, extension); -} - -int s2n_send_server_session_ticket_ext(struct s2n_connection *conn, struct s2n_stuffer *out) -{ - return s2n_extension_send(&s2n_server_session_ticket_extension, conn, out); -} - -int s2n_server_session_ticket_ext_size(struct s2n_connection *conn) -{ - if (s2n_session_ticket_should_send(conn)) { - /* 2 for extension type. 2 for extension length of 0 */ - return 4; - } - - return 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 "stuffer/s2n_stuffer.h" + +#include "tls/s2n_tls_parameters.h" +#include "tls/s2n_connection.h" +#include "tls/s2n_tls.h" +#include "tls/extensions/s2n_server_session_ticket.h" + +static bool s2n_session_ticket_should_send(struct s2n_connection *conn); +static int s2n_session_ticket_recv(struct s2n_connection *conn, struct s2n_stuffer *extension); + +const s2n_extension_type s2n_server_session_ticket_extension = { + .iana_value = TLS_EXTENSION_SESSION_TICKET, + .is_response = true, + .send = s2n_extension_send_noop, + .recv = s2n_session_ticket_recv, + .should_send = s2n_session_ticket_should_send, + .if_missing = s2n_extension_noop_if_missing, +}; + +static bool s2n_session_ticket_should_send(struct s2n_connection *conn) +{ + return s2n_server_sending_nst(conn) && s2n_connection_get_protocol_version(conn) < S2N_TLS13; +} + +static int s2n_session_ticket_recv(struct s2n_connection *conn, struct s2n_stuffer *extension) +{ + /* Read nothing. The extension just needs to exist. */ + notnull_check(conn); + conn->session_ticket_status = S2N_NEW_TICKET; + return S2N_SUCCESS; +} + +/* Old-style extension functions -- remove after extensions refactor is complete */ + +int s2n_recv_server_session_ticket_ext(struct s2n_connection *conn, struct s2n_stuffer *extension) +{ + return s2n_extension_recv(&s2n_server_session_ticket_extension, conn, extension); +} + +int s2n_send_server_session_ticket_ext(struct s2n_connection *conn, struct s2n_stuffer *out) +{ + return s2n_extension_send(&s2n_server_session_ticket_extension, conn, out); +} + +int s2n_server_session_ticket_ext_size(struct s2n_connection *conn) +{ + if (s2n_session_ticket_should_send(conn)) { + /* 2 for extension type. 2 for extension length of 0 */ + return 4; + } + + return 0; +} diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_session_ticket.h b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_session_ticket.h index 2e9ba959cb..0733c02380 100644 --- a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_session_ticket.h +++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_session_ticket.h @@ -1,27 +1,27 @@ -/* - * 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. - */ - -#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_server_session_ticket_extension; - -/* Old-style extension functions -- remove after extensions refactor is complete */ -int s2n_recv_server_session_ticket_ext(struct s2n_connection *conn, struct s2n_stuffer *extension); -int s2n_send_server_session_ticket_ext(struct s2n_connection *conn, struct s2n_stuffer *out); -int s2n_server_session_ticket_ext_size(struct s2n_connection *conn); +/* + * 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. + */ + +#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_server_session_ticket_extension; + +/* Old-style extension functions -- remove after extensions refactor is complete */ +int s2n_recv_server_session_ticket_ext(struct s2n_connection *conn, struct s2n_stuffer *extension); +int s2n_send_server_session_ticket_ext(struct s2n_connection *conn, struct s2n_stuffer *out); +int s2n_server_session_ticket_ext_size(struct s2n_connection *conn); diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_signature_algorithms.c b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_signature_algorithms.c index e7bd8a32cc..a864012dd5 100644 --- a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_signature_algorithms.c +++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_signature_algorithms.c @@ -1,42 +1,42 @@ -/* - * 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 <sys/param.h> -#include <stdint.h> - -#include "tls/extensions/s2n_client_signature_algorithms.h" -#include "tls/s2n_connection.h" -#include "tls/s2n_tls.h" -#include "tls/s2n_tls_parameters.h" -#include "tls/s2n_signature_algorithms.h" - -#include "stuffer/s2n_stuffer.h" -#include "utils/s2n_safety.h" - -static int s2n_signature_algorithms_recv(struct s2n_connection *conn, struct s2n_stuffer *extension); - -const s2n_extension_type s2n_server_signature_algorithms_extension = { - .iana_value = TLS_EXTENSION_SIGNATURE_ALGORITHMS, - .is_response = false, - .send = s2n_send_supported_sig_scheme_list, - .recv = s2n_signature_algorithms_recv, - .should_send = s2n_extension_always_send, - .if_missing = s2n_extension_error_if_missing, -}; - -static int s2n_signature_algorithms_recv(struct s2n_connection *conn, struct s2n_stuffer *extension) -{ - return s2n_recv_supported_sig_scheme_list(extension, &conn->handshake_params.server_sig_hash_algs); -} +/* + * 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 <sys/param.h> +#include <stdint.h> + +#include "tls/extensions/s2n_client_signature_algorithms.h" +#include "tls/s2n_connection.h" +#include "tls/s2n_tls.h" +#include "tls/s2n_tls_parameters.h" +#include "tls/s2n_signature_algorithms.h" + +#include "stuffer/s2n_stuffer.h" +#include "utils/s2n_safety.h" + +static int s2n_signature_algorithms_recv(struct s2n_connection *conn, struct s2n_stuffer *extension); + +const s2n_extension_type s2n_server_signature_algorithms_extension = { + .iana_value = TLS_EXTENSION_SIGNATURE_ALGORITHMS, + .is_response = false, + .send = s2n_send_supported_sig_scheme_list, + .recv = s2n_signature_algorithms_recv, + .should_send = s2n_extension_always_send, + .if_missing = s2n_extension_error_if_missing, +}; + +static int s2n_signature_algorithms_recv(struct s2n_connection *conn, struct s2n_stuffer *extension) +{ + return s2n_recv_supported_sig_scheme_list(extension, &conn->handshake_params.server_sig_hash_algs); +} diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_signature_algorithms.h b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_signature_algorithms.h index 644d71770e..05a6cc2d9d 100644 --- a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_signature_algorithms.h +++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_signature_algorithms.h @@ -1,20 +1,20 @@ -/* - * 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. - */ - -#pragma once - -#include "tls/extensions/s2n_extension_type.h" - -extern const s2n_extension_type s2n_server_signature_algorithms_extension; +/* + * 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. + */ + +#pragma once + +#include "tls/extensions/s2n_extension_type.h" + +extern const s2n_extension_type s2n_server_signature_algorithms_extension; diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_status_request.c b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_status_request.c index 7003bf46ba..463f0898cd 100644 --- a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_status_request.c +++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_status_request.c @@ -1,66 +1,66 @@ -/* - * 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 "stuffer/s2n_stuffer.h" -#include "tls/s2n_connection.h" -#include "tls/s2n_tls.h" -#include "tls/s2n_tls_parameters.h" -#include "tls/extensions/s2n_server_status_request.h" - -static bool s2n_server_status_request_should_send(struct s2n_connection *conn); -static int s2n_server_status_request_recv(struct s2n_connection *conn, struct s2n_stuffer *extension); - -const s2n_extension_type s2n_server_status_request_extension = { - .iana_value = TLS_EXTENSION_STATUS_REQUEST, - .is_response = true, - .send = s2n_extension_send_noop, - .recv = s2n_server_status_request_recv, - .should_send = s2n_server_status_request_should_send, - .if_missing = s2n_extension_noop_if_missing, -}; - -static bool s2n_server_status_request_should_send(struct s2n_connection *conn) -{ - return s2n_server_can_send_ocsp(conn); -} - -int s2n_server_status_request_recv(struct s2n_connection *conn, struct s2n_stuffer *extension) -{ - /* Read nothing. The extension just needs to exist. */ - notnull_check(conn); - conn->status_type = S2N_STATUS_REQUEST_OCSP; - return S2N_SUCCESS; -} - -/* Old-style extension functions -- remove after extensions refactor is complete */ - -int s2n_server_extensions_status_request_send_size(struct s2n_connection *conn) -{ - if (s2n_server_can_send_ocsp(conn)) { - return 2 * sizeof(uint16_t); - } - - return 0; -} - -int s2n_server_extensions_status_request_send(struct s2n_connection *conn, struct s2n_stuffer *out) -{ - return s2n_extension_send(&s2n_server_status_request_extension, conn, out); -} - -int s2n_recv_server_status_request(struct s2n_connection *conn, struct s2n_stuffer *extension) -{ - return s2n_extension_recv(&s2n_server_status_request_extension, conn, extension); -} +/* + * 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 "stuffer/s2n_stuffer.h" +#include "tls/s2n_connection.h" +#include "tls/s2n_tls.h" +#include "tls/s2n_tls_parameters.h" +#include "tls/extensions/s2n_server_status_request.h" + +static bool s2n_server_status_request_should_send(struct s2n_connection *conn); +static int s2n_server_status_request_recv(struct s2n_connection *conn, struct s2n_stuffer *extension); + +const s2n_extension_type s2n_server_status_request_extension = { + .iana_value = TLS_EXTENSION_STATUS_REQUEST, + .is_response = true, + .send = s2n_extension_send_noop, + .recv = s2n_server_status_request_recv, + .should_send = s2n_server_status_request_should_send, + .if_missing = s2n_extension_noop_if_missing, +}; + +static bool s2n_server_status_request_should_send(struct s2n_connection *conn) +{ + return s2n_server_can_send_ocsp(conn); +} + +int s2n_server_status_request_recv(struct s2n_connection *conn, struct s2n_stuffer *extension) +{ + /* Read nothing. The extension just needs to exist. */ + notnull_check(conn); + conn->status_type = S2N_STATUS_REQUEST_OCSP; + return S2N_SUCCESS; +} + +/* Old-style extension functions -- remove after extensions refactor is complete */ + +int s2n_server_extensions_status_request_send_size(struct s2n_connection *conn) +{ + if (s2n_server_can_send_ocsp(conn)) { + return 2 * sizeof(uint16_t); + } + + return 0; +} + +int s2n_server_extensions_status_request_send(struct s2n_connection *conn, struct s2n_stuffer *out) +{ + return s2n_extension_send(&s2n_server_status_request_extension, conn, out); +} + +int s2n_recv_server_status_request(struct s2n_connection *conn, struct s2n_stuffer *extension) +{ + return s2n_extension_recv(&s2n_server_status_request_extension, conn, extension); +} diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_status_request.h b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_status_request.h index b43ff10ca8..cbe695f9b4 100644 --- a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_status_request.h +++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_status_request.h @@ -1,27 +1,27 @@ -/* - * 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. - */ - -#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_server_status_request_extension; - -/* Old-style extension functions -- remove after extensions refactor is complete */ -int s2n_server_extensions_status_request_send_size(struct s2n_connection *conn); -int s2n_server_extensions_status_request_send(struct s2n_connection *conn, struct s2n_stuffer *out); -int s2n_recv_server_status_request(struct s2n_connection *conn, struct s2n_stuffer *extension); +/* + * 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. + */ + +#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_server_status_request_extension; + +/* Old-style extension functions -- remove after extensions refactor is complete */ +int s2n_server_extensions_status_request_send_size(struct s2n_connection *conn); +int s2n_server_extensions_status_request_send(struct s2n_connection *conn, struct s2n_stuffer *out); +int s2n_recv_server_status_request(struct s2n_connection *conn, struct s2n_stuffer *extension); diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_supported_versions.c b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_supported_versions.c index cd0fb015dc..026cec9c21 100644 --- a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_supported_versions.c +++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_supported_versions.c @@ -1,106 +1,106 @@ -/* - * 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 <sys/param.h> -#include <stdint.h> - -#include "tls/extensions/s2n_server_supported_versions.h" -#include "tls/extensions/s2n_supported_versions.h" -#include "tls/s2n_alerts.h" -#include "tls/s2n_cipher_preferences.h" -#include "tls/s2n_tls.h" -#include "tls/s2n_tls_parameters.h" - -#include "utils/s2n_safety.h" - -/** - * Specified in https://tools.ietf.org/html/rfc8446#section-4.2.1 - * - * "A server which negotiates TLS 1.3 MUST respond by sending a - * "supported_versions" extension containing the selected version value - * (0x0304)." - * - * Structure: - * Extension type (2 bytes) - * Extension size (2 bytes) - * Selected Version (2 byte) - **/ - -static int s2n_server_supported_versions_send(struct s2n_connection *conn, struct s2n_stuffer *out); -static int s2n_server_supported_versions_recv(struct s2n_connection *conn, struct s2n_stuffer *in); - -const s2n_extension_type s2n_server_supported_versions_extension = { - .iana_value = TLS_EXTENSION_SUPPORTED_VERSIONS, - .is_response = true, - .send = s2n_server_supported_versions_send, - .recv = s2n_server_supported_versions_recv, - .should_send = s2n_extension_send_if_tls13_connection, - .if_missing = s2n_extension_noop_if_missing, -}; - -static int s2n_server_supported_versions_send(struct s2n_connection *conn, struct s2n_stuffer *out) -{ - GUARD(s2n_stuffer_write_uint8(out, conn->server_protocol_version / 10)); - GUARD(s2n_stuffer_write_uint8(out, conn->server_protocol_version % 10)); - - return S2N_SUCCESS; -} - -static int s2n_extensions_server_supported_versions_process(struct s2n_connection *conn, struct s2n_stuffer *extension) -{ - uint8_t highest_supported_version = conn->client_protocol_version; - uint8_t minimum_supported_version; - GUARD(s2n_connection_get_minimum_supported_version(conn, &minimum_supported_version)); - - uint8_t server_version_parts[S2N_TLS_PROTOCOL_VERSION_LEN]; - GUARD(s2n_stuffer_read_bytes(extension, server_version_parts, S2N_TLS_PROTOCOL_VERSION_LEN)); - - uint16_t server_version = (server_version_parts[0] * 10) + server_version_parts[1]; - - gte_check(server_version, S2N_TLS13); - lte_check(server_version, highest_supported_version); - gte_check(server_version, minimum_supported_version); - - conn->server_protocol_version = server_version; - - return S2N_SUCCESS; -} - -static int s2n_server_supported_versions_recv(struct s2n_connection *conn, struct s2n_stuffer *in) -{ - if (s2n_connection_get_protocol_version(conn) < S2N_TLS13) { - return S2N_SUCCESS; - } - - S2N_ERROR_IF(s2n_extensions_server_supported_versions_process(conn, in) < 0, S2N_ERR_BAD_MESSAGE); - return S2N_SUCCESS; -} - -/* Old-style extension functions -- remove after extensions refactor is complete */ - -int s2n_extensions_server_supported_versions_size(struct s2n_connection *conn) -{ - return 6; -} - -int s2n_extensions_server_supported_versions_recv(struct s2n_connection *conn, struct s2n_stuffer *extension) -{ - return s2n_extension_recv(&s2n_server_supported_versions_extension, conn, extension); -} - -int s2n_extensions_server_supported_versions_send(struct s2n_connection *conn, struct s2n_stuffer *out) -{ - return s2n_extension_send(&s2n_server_supported_versions_extension, conn, out); -} +/* + * 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 <sys/param.h> +#include <stdint.h> + +#include "tls/extensions/s2n_server_supported_versions.h" +#include "tls/extensions/s2n_supported_versions.h" +#include "tls/s2n_alerts.h" +#include "tls/s2n_cipher_preferences.h" +#include "tls/s2n_tls.h" +#include "tls/s2n_tls_parameters.h" + +#include "utils/s2n_safety.h" + +/** + * Specified in https://tools.ietf.org/html/rfc8446#section-4.2.1 + * + * "A server which negotiates TLS 1.3 MUST respond by sending a + * "supported_versions" extension containing the selected version value + * (0x0304)." + * + * Structure: + * Extension type (2 bytes) + * Extension size (2 bytes) + * Selected Version (2 byte) + **/ + +static int s2n_server_supported_versions_send(struct s2n_connection *conn, struct s2n_stuffer *out); +static int s2n_server_supported_versions_recv(struct s2n_connection *conn, struct s2n_stuffer *in); + +const s2n_extension_type s2n_server_supported_versions_extension = { + .iana_value = TLS_EXTENSION_SUPPORTED_VERSIONS, + .is_response = true, + .send = s2n_server_supported_versions_send, + .recv = s2n_server_supported_versions_recv, + .should_send = s2n_extension_send_if_tls13_connection, + .if_missing = s2n_extension_noop_if_missing, +}; + +static int s2n_server_supported_versions_send(struct s2n_connection *conn, struct s2n_stuffer *out) +{ + GUARD(s2n_stuffer_write_uint8(out, conn->server_protocol_version / 10)); + GUARD(s2n_stuffer_write_uint8(out, conn->server_protocol_version % 10)); + + return S2N_SUCCESS; +} + +static int s2n_extensions_server_supported_versions_process(struct s2n_connection *conn, struct s2n_stuffer *extension) +{ + uint8_t highest_supported_version = conn->client_protocol_version; + uint8_t minimum_supported_version; + GUARD(s2n_connection_get_minimum_supported_version(conn, &minimum_supported_version)); + + uint8_t server_version_parts[S2N_TLS_PROTOCOL_VERSION_LEN]; + GUARD(s2n_stuffer_read_bytes(extension, server_version_parts, S2N_TLS_PROTOCOL_VERSION_LEN)); + + uint16_t server_version = (server_version_parts[0] * 10) + server_version_parts[1]; + + gte_check(server_version, S2N_TLS13); + lte_check(server_version, highest_supported_version); + gte_check(server_version, minimum_supported_version); + + conn->server_protocol_version = server_version; + + return S2N_SUCCESS; +} + +static int s2n_server_supported_versions_recv(struct s2n_connection *conn, struct s2n_stuffer *in) +{ + if (s2n_connection_get_protocol_version(conn) < S2N_TLS13) { + return S2N_SUCCESS; + } + + S2N_ERROR_IF(s2n_extensions_server_supported_versions_process(conn, in) < 0, S2N_ERR_BAD_MESSAGE); + return S2N_SUCCESS; +} + +/* Old-style extension functions -- remove after extensions refactor is complete */ + +int s2n_extensions_server_supported_versions_size(struct s2n_connection *conn) +{ + return 6; +} + +int s2n_extensions_server_supported_versions_recv(struct s2n_connection *conn, struct s2n_stuffer *extension) +{ + return s2n_extension_recv(&s2n_server_supported_versions_extension, conn, extension); +} + +int s2n_extensions_server_supported_versions_send(struct s2n_connection *conn, struct s2n_stuffer *out) +{ + return s2n_extension_send(&s2n_server_supported_versions_extension, conn, out); +} diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_supported_versions.h b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_supported_versions.h index c7312be137..4d49a61dea 100644 --- a/contrib/restricted/aws/s2n/tls/extensions/s2n_server_supported_versions.h +++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_server_supported_versions.h @@ -1,27 +1,27 @@ -/* - * 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. - */ - - -#pragma once - -#include "tls/s2n_connection.h" -#include "stuffer/s2n_stuffer.h" - -extern const s2n_extension_type s2n_server_supported_versions_extension; - -/* Old-style extension functions -- remove after extensions refactor is complete */ -int s2n_extensions_server_supported_versions_recv(struct s2n_connection *conn, struct s2n_stuffer *extension); -int s2n_extensions_server_supported_versions_send(struct s2n_connection *conn, struct s2n_stuffer *out); -int s2n_extensions_server_supported_versions_size(struct s2n_connection *conn); +/* + * 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. + */ + + +#pragma once + +#include "tls/s2n_connection.h" +#include "stuffer/s2n_stuffer.h" + +extern const s2n_extension_type s2n_server_supported_versions_extension; + +/* Old-style extension functions -- remove after extensions refactor is complete */ +int s2n_extensions_server_supported_versions_recv(struct s2n_connection *conn, struct s2n_stuffer *extension); +int s2n_extensions_server_supported_versions_send(struct s2n_connection *conn, struct s2n_stuffer *out); +int s2n_extensions_server_supported_versions_size(struct s2n_connection *conn); diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_supported_versions.c b/contrib/restricted/aws/s2n/tls/extensions/s2n_supported_versions.c index d02b3f920d..018fff5b26 100644 --- a/contrib/restricted/aws/s2n/tls/extensions/s2n_supported_versions.c +++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_supported_versions.c @@ -1,31 +1,31 @@ -/* - * 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 <stdint.h> -#include <sys/param.h> - -#include "tls/extensions/s2n_supported_versions.h" -#include "tls/s2n_security_policies.h" - -#include "utils/s2n_safety.h" - -int s2n_connection_get_minimum_supported_version(struct s2n_connection *conn, uint8_t *min_version) -{ - const struct s2n_security_policy *security_policy; - GUARD(s2n_connection_get_security_policy(conn, &security_policy)); - *min_version = security_policy->minimum_protocol_version; - - return 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 <stdint.h> +#include <sys/param.h> + +#include "tls/extensions/s2n_supported_versions.h" +#include "tls/s2n_security_policies.h" + +#include "utils/s2n_safety.h" + +int s2n_connection_get_minimum_supported_version(struct s2n_connection *conn, uint8_t *min_version) +{ + const struct s2n_security_policy *security_policy; + GUARD(s2n_connection_get_security_policy(conn, &security_policy)); + *min_version = security_policy->minimum_protocol_version; + + return 0; +} diff --git a/contrib/restricted/aws/s2n/tls/extensions/s2n_supported_versions.h b/contrib/restricted/aws/s2n/tls/extensions/s2n_supported_versions.h index 613830c347..44e2d17957 100644 --- a/contrib/restricted/aws/s2n/tls/extensions/s2n_supported_versions.h +++ b/contrib/restricted/aws/s2n/tls/extensions/s2n_supported_versions.h @@ -1,21 +1,21 @@ -/* - * 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. - */ - -#pragma once - -#include "tls/s2n_connection.h" -#include "stuffer/s2n_stuffer.h" - -extern int s2n_connection_get_minimum_supported_version(struct s2n_connection *conn, uint8_t *min_version); +/* + * 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. + */ + +#pragma once + +#include "tls/s2n_connection.h" +#include "stuffer/s2n_stuffer.h" + +extern int s2n_connection_get_minimum_supported_version(struct s2n_connection *conn, uint8_t *min_version); |