Skip to content

Commit

Permalink
test for protocol getters on server with a received supported version…
Browse files Browse the repository at this point in the history
…s extension
  • Loading branch information
goatgoose committed Oct 16, 2023
1 parent 08d3d78 commit 9f63693
Showing 1 changed file with 178 additions and 0 deletions.
178 changes: 178 additions & 0 deletions tests/unit/s2n_protocol_version_getter_test.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
/*
* 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 "api/s2n.h"
#include "s2n_test.h"
#include "testlib/s2n_testlib.h"
#include "tls/s2n_tls.h"

#define S2N_TEST_MAX_SUPPORTED_VERSIONS 10
#define S2N_TEST_SUPPORTED_VERSIONS_EXTENSION_SIZE (1 + (S2N_TEST_MAX_SUPPORTED_VERSIONS * 2))

struct s2n_override_extension_ctx {
struct s2n_blob extension_blob;
int invoked_count;
};

static int s2n_override_supported_versions_cb(struct s2n_connection *conn, void *ctx)
{
EXPECT_NOT_NULL(conn);
EXPECT_NOT_NULL(ctx);

struct s2n_override_extension_ctx *context = (struct s2n_override_extension_ctx *) ctx;
context->invoked_count += 1;

struct s2n_client_hello *client_hello = s2n_connection_get_client_hello(conn);
EXPECT_NOT_NULL(client_hello);

s2n_extension_type_id supported_versions_id = 0;
EXPECT_SUCCESS(s2n_extension_supported_iana_value_to_id(S2N_EXTENSION_SUPPORTED_VERSIONS, &supported_versions_id));

s2n_parsed_extension *supported_versions_extension = &client_hello->extensions.parsed_extensions[supported_versions_id];
supported_versions_extension->extension_type = S2N_EXTENSION_SUPPORTED_VERSIONS;
supported_versions_extension->extension = context->extension_blob;

return S2N_SUCCESS;
}

int main(int argc, char **argv)
{
BEGIN_TEST();

DEFER_CLEANUP(struct s2n_cert_chain_and_key *chain_and_key = NULL, s2n_cert_chain_and_key_ptr_free);
EXPECT_SUCCESS(s2n_test_cert_chain_and_key_new(&chain_and_key,
S2N_DEFAULT_TEST_CERT_CHAIN, S2N_DEFAULT_TEST_PRIVATE_KEY));

/* Safety */
{
EXPECT_FAILURE_WITH_ERRNO(s2n_connection_get_client_protocol_version(NULL), S2N_ERR_NULL);
EXPECT_FAILURE_WITH_ERRNO(s2n_connection_get_client_hello_version(NULL), S2N_ERR_NULL);
EXPECT_FAILURE_WITH_ERRNO(s2n_connection_get_server_protocol_version(NULL), S2N_ERR_NULL);
EXPECT_FAILURE_WITH_ERRNO(s2n_connection_get_actual_protocol_version(NULL), S2N_ERR_NULL);
}

/* Test protocol version getters on the server when a supported versions extension is received */
for (uint8_t server_version = S2N_TLS12; server_version <= S2N_TLS13; server_version++) {
for (uint8_t client_hello_version = S2N_SSLv3; client_hello_version <= S2N_TLS13; client_hello_version++) {
for (uint8_t client_supported_version = S2N_SSLv3; client_supported_version <= S2N_TLS13; client_supported_version++) {
DEFER_CLEANUP(struct s2n_config *config = s2n_config_new(), s2n_config_ptr_free);
EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key_to_store(config, chain_and_key));

if (server_version == S2N_TLS12) {
EXPECT_SUCCESS(s2n_config_set_cipher_preferences(config, "test_all_tls12"));
} else {
if (!s2n_is_tls13_fully_supported()) {
continue;
}
EXPECT_SUCCESS(s2n_config_set_cipher_preferences(config, "test_all"));
}

uint8_t supported_versions_data[3] = { 0 };
struct s2n_blob supported_versions_blob = { 0 };
EXPECT_SUCCESS(s2n_blob_init(&supported_versions_blob, supported_versions_data, s2n_array_len(supported_versions_data)));
struct s2n_stuffer supported_versions_stuffer = { 0 };
EXPECT_SUCCESS(s2n_stuffer_init(&supported_versions_stuffer, &supported_versions_blob));

/* Write length byte */
EXPECT_SUCCESS(s2n_stuffer_write_uint8(&supported_versions_stuffer, 2));
/* Write supported version */
POSIX_GUARD(s2n_stuffer_write_uint8(&supported_versions_stuffer, client_supported_version / 10));
POSIX_GUARD(s2n_stuffer_write_uint8(&supported_versions_stuffer, client_supported_version % 10));

/* The override_supported_versions client hello callback is used to overwrite the
* supported versions extension before the extension is processed.
*/
struct s2n_override_extension_ctx context = {
.extension_blob = supported_versions_blob
};
EXPECT_SUCCESS(s2n_config_set_client_hello_cb(config, s2n_override_supported_versions_cb, &context));

DEFER_CLEANUP(struct s2n_connection *client = s2n_connection_new(S2N_CLIENT),
s2n_connection_ptr_free);
EXPECT_NOT_NULL(client);
EXPECT_SUCCESS(s2n_connection_set_config(client, config));

DEFER_CLEANUP(struct s2n_connection *server = s2n_connection_new(S2N_SERVER),
s2n_connection_ptr_free);
EXPECT_NOT_NULL(server);
EXPECT_SUCCESS(s2n_connection_set_config(server, config));

struct s2n_stuffer *hello_stuffer = &client->handshake.io;
EXPECT_SUCCESS(s2n_client_hello_send(client));

/* Overwrite the client hello version according to the test case. */
uint8_t protocol_version[S2N_TLS_PROTOCOL_VERSION_LEN] = { 0 };
protocol_version[0] = client_hello_version / 10;
protocol_version[1] = client_hello_version % 10;

EXPECT_SUCCESS(s2n_stuffer_rewrite(hello_stuffer));
EXPECT_SUCCESS(s2n_stuffer_write_bytes(hello_stuffer, protocol_version, S2N_TLS_PROTOCOL_VERSION_LEN));
EXPECT_SUCCESS(s2n_stuffer_write(&server->handshake.io, &hello_stuffer->blob));

EXPECT_SUCCESS(s2n_client_hello_recv(server));

EXPECT_EQUAL(s2n_connection_get_server_protocol_version(server), server_version);

/* The reported client protocol version should always match the version specified
* in the supported versions extension, even for TLS 1.2 servers which don't
* process the extension for version selection.
*/
EXPECT_EQUAL(s2n_connection_get_client_protocol_version(server), client_supported_version);

/* Clients indicate support for TLS 1.3 in the supported versions extension, not
* the client hello version. A client hello version above TLS 1.2 is never reported.
*/
EXPECT_EQUAL(s2n_connection_get_client_hello_version(server), MIN(client_hello_version, S2N_TLS12));

uint8_t actual_protocol_version = s2n_connection_get_actual_protocol_version(server);
if (server_version < S2N_TLS13) {
/* For backwards compatibility, TLS 1.2 servers always use the client hello
* version to determine the client's supported version, even if a supported
* versions extension was received.
*/
EXPECT_EQUAL(actual_protocol_version, MIN(server_version, client_hello_version));
} else {
/* TLS 1.3 servers always use the version in the supported versions extension,
* regardless of the client hello version.
*/
EXPECT_EQUAL(actual_protocol_version, MIN(server_version, client_supported_version));
}
}
}
}

/* Test protocol version getters on the server when no supported versions extension is received */
for (uint8_t server_version = S2N_TLS12; server_version <= S2N_TLS13; server_version++) {
for (uint8_t client_hello_version = S2N_SSLv3; client_hello_version <= S2N_TLS13; client_hello_version++) {

}
}

/* Test protocol version getters on the client */
for (uint8_t server_version = S2N_SSLv3; server_version <= S2N_TLS13; server_version++) {

}

/* Test get_client_protocol_version fallback behavior on TLS 1.2 servers */
{
/* Report client hello version if a supported version extension wasn't received */

/* Report client hello version if the supported version extension is malformed */

/* Report client hello version if an invalid supported version was received */
}

END_TEST();
}

0 comments on commit 9f63693

Please sign in to comment.