From 7f7aaf102c80ed3b1e28e005ceb7979ac2f8b476 Mon Sep 17 00:00:00 2001 From: Igor Abdrakhimov Date: Thu, 11 Sep 2025 13:37:30 -0700 Subject: [PATCH 01/32] Add test for minimum TLS version --- .builder/actions/tls_server_setup.py | 48 ++++++++++++++------- tests/CMakeLists.txt | 1 + tests/tls_handler_test.c | 19 +++++++++ tests/tls_server/tls_server.py | 62 ++++++++++++++++++++++++---- 4 files changed, 109 insertions(+), 21 deletions(-) diff --git a/.builder/actions/tls_server_setup.py b/.builder/actions/tls_server_setup.py index 4b296f710..a0746ae25 100644 --- a/.builder/actions/tls_server_setup.py +++ b/.builder/actions/tls_server_setup.py @@ -1,14 +1,13 @@ """ -Setup local TLS server for tests +Setup local TLS servers for tests """ import Builder -import os +from pathlib import Path import sys import subprocess import atexit -import time class TlsServerSetup(Builder.Action): @@ -18,6 +17,17 @@ class TlsServerSetup(Builder.Action): This action should be run in the 'pre_build_steps' or 'build_steps' stage. """ + @staticmethod + def cleanup_tls_server(tls_server_process): + tls_server_process.terminate() + out, err = tls_server_process.communicate() + print("TLS server stdout:") + for line in out.splitlines(): + print(f" = {line.decode('utf-8')}") + print("TLS server stderr:") + for line in err.splitlines(): + print(f" = {line.decode('utf-8')}") + def run(self, env): if not env.project.needs_tests(env): print("Skipping TLS server setup because tests disabled for project") @@ -25,19 +35,29 @@ def run(self, env): self.env = env - base_dir = os.path.dirname(os.path.realpath(__file__)) - dir = os.path.join(base_dir, "..", "..", "tests", "tls_server") + root_dir = Path(__file__).resolve().parent / '..' / '..' + tls_server_dir = root_dir / 'tests' / 'tls_server' + resource_dir = root_dir / 'tests' / 'resources' - print("Running openssl TLS server") + print("Running TLS servers") python_path = sys.executable - p = subprocess.Popen([python_path, "tls_server.py", - ], cwd=dir, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + + tls12_server_process = subprocess.Popen( + [python_path, tls_server_dir / 'tls_server.py', '--port', '58443', '--resource-dir', resource_dir, + '--min-tls', '1.2', + '--max-tls', '1.2'], + stdout=subprocess.PIPE, stderr=subprocess.PIPE) + + tls13_server_process = subprocess.Popen( + [python_path, tls_server_dir / 'tls_server.py', '--port', '59443', '--resource-dir', resource_dir, + '--min-tls', '1.3', + '--max-tls', '1.3'], + stdout=subprocess.PIPE, stderr=subprocess.PIPE) @atexit.register - def close_tls_server(): - print("Terminating openssl TLS server") - p.terminate() - out, err = p.communicate() - print("TLS server stdout:\n{}".format(out)) - print("TLS server stderr:\n{}".format(err)) + def close_tls_servers(): + print('Terminating TLS 1.2 server') + TlsServerSetup.cleanup_tls_server(tls12_server_process) + print('Terminating TLS 1.3 server') + TlsServerSetup.cleanup_tls_server(tls13_server_process) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index b12c0bea4..5447534b4 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -233,6 +233,7 @@ if(NOT BYO_CRYPTO) add_net_test_case(tls_client_channel_negotiation_error_broken_crypto_dh480) add_net_test_case(tls_client_channel_negotiation_error_broken_crypto_dh512) add_net_test_case(tls_client_channel_negotiation_error_broken_crypto_null) + add_net_test_case(tls_client_channel_negotiation_error_tls1_3_to_tls1_2_server) # Badssl - Legacy crypto suite, includes both negative and positive tests, with override checks where appropriate # Our current baseline/default is platform-specific, whereas badssl expects a baseline of 1.2 diff --git a/tests/tls_handler_test.c b/tests/tls_handler_test.c index 21b33b183..a30020081 100644 --- a/tests/tls_handler_test.c +++ b/tests/tls_handler_test.c @@ -1225,6 +1225,10 @@ static void s_raise_tls_version_to_12(struct aws_tls_ctx_options *options) { aws_tls_ctx_options_set_minimum_tls_version(options, AWS_IO_TLSv1_2); } +static void s_raise_tls_version_to_13(struct aws_tls_ctx_options *options) { + aws_tls_ctx_options_set_minimum_tls_version(options, AWS_IO_TLSv1_3); +} + static int s_tls_client_channel_negotiation_error_override_legacy_crypto_tls11_fn( struct aws_allocator *allocator, void *ctx) { @@ -1334,6 +1338,21 @@ AWS_TEST_CASE( tls_client_channel_negotiation_error_socket_closed, s_tls_client_channel_negotiation_error_socket_closed_fn); +AWS_STATIC_STRING_FROM_LITERAL(s_aws_local_tls_server_host_name, "127.0.0.1"); + +static int s_tls_client_channel_negotiation_error_tls1_3_to_tls1_2_server_fn( + struct aws_allocator *allocator, + void *ctx) { + (void)ctx; + uint32_t server_tls1_2_port = 58443; + return s_verify_negotiation_fails( + allocator, s_aws_local_tls_server_host_name, server_tls1_2_port, &s_raise_tls_version_to_13); +} + +AWS_TEST_CASE( + tls_client_channel_negotiation_error_tls1_3_to_tls1_2_server, + s_tls_client_channel_negotiation_error_tls1_3_to_tls1_2_server_fn) + static int s_verify_good_host( struct aws_allocator *allocator, const struct aws_string *host_name, diff --git a/tests/tls_server/tls_server.py b/tests/tls_server/tls_server.py index 49b9f188e..405f7509e 100644 --- a/tests/tls_server/tls_server.py +++ b/tests/tls_server/tls_server.py @@ -1,23 +1,71 @@ # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. # SPDX-License-Identifier: Apache-2.0. +import argparse +import pathlib +import signal import socket import ssl +import sys + + +def parse_tls(tls_str): + if tls_str == '1.1': + return ssl.TLSVersion.TLSv1_1 + elif tls_str == '1.2': + return ssl.TLSVersion.TLSv1_2 + elif tls_str == '1.3': + return ssl.TLSVersion.TLSv1_3 + raise ValueError('Unknown TLS version') + + +print(f"Starting TLS server") + +parser = argparse.ArgumentParser( + description="TLS test server", + formatter_class=argparse.ArgumentDefaultsHelpFormatter, +) + +optional = parser.add_argument_group("optional arguments") + +optional.add_argument("--host", dest="host", default="127.0.0.1", help="Listening host") +optional.add_argument("--port", type=int, dest="port", default=59443, help="Listening port") +optional.add_argument("--min-tls", choices=['1.1', '1.2', '1.3'], dest="min_tls", default='1.2', + help="Minimum acceptable TLS version") +optional.add_argument("--max-tls", choices=['1.1', '1.2', '1.3'], dest="max_tls", default='1.3', + help="Maximum acceptable TLS version") +optional.add_argument("--resource-dir", type=pathlib.Path, dest="resource_dir", default='./tests/resources/', + help="Path to keys and certificates") + +args = parser.parse_args() context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) -context.minimum_version = ssl.TLSVersion.TLSv1_3 -context.maximum_version = ssl.TLSVersion.TLSv1_3 -context.load_cert_chain('../resources/tls13_server.pem.crt', '../resources/tls13_server.key') -context.load_verify_locations('../resources/tls13_device_root_ca.pem.crt') +context.minimum_version = parse_tls(args.min_tls) +context.maximum_version = parse_tls(args.max_tls) +context.load_cert_chain(args.resource_dir / 'tls13_server.pem.crt', args.resource_dir / 'tls13_server.key') +context.load_verify_locations(args.resource_dir / 'tls13_device_root_ca.pem.crt') context.verify_mode = ssl.CERT_REQUIRED + +def signal_handler(signum, frame): + sys.stdout.flush() + sys.exit(0) + + +signal.signal(signal.SIGTERM, signal_handler) + +print(f"Running TLS server on {args.host}:{args.port}") +print(f"Minimum TLS version: {context.minimum_version.name}") +print(f"Maximum TLS version: {context.maximum_version.name}") + with socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0) as sock: - sock.bind(('127.0.0.1', 59443)) + sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + sock.bind((args.host, args.port)) sock.listen(1) with context.wrap_socket(sock, server_side=True) as ssock: while True: try: conn, addr = ssock.accept() - print("accepted new connection: {}".format(addr)) + print("Accepted new connection: {}".format(addr)) except Exception as e: - print("accept failed: {}".format(e)) + print(f"Accept failed: {e}") From 52d29dee593ddff067b95c4a036c35c3c0531804 Mon Sep 17 00:00:00 2001 From: Igor Abdrakhimov Date: Thu, 11 Sep 2025 13:50:52 -0700 Subject: [PATCH 02/32] Run TLS servers on all targets --- builder.json | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/builder.json b/builder.json index 7dd9cec51..8b10a84bc 100644 --- a/builder.json +++ b/builder.json @@ -13,14 +13,11 @@ { "name": "aws-c-mqtt" }, { "name": "aws-c-event-stream" } ], + "pre_build_steps": ["tls-server-setup"], "targets": { "linux": { "_comment": "set up SoftHSM2 for PKCS#11 tests (see: ./builder/actions/pkcs11_test_setup.py)", "+pre_build_steps": ["pkcs11-test-setup"] - }, - "windows": { - "+pre_build_steps": ["tls-server-setup"] - } }, "build_env": { From f40f257618a1359c15ace3589e1430c7926253d4 Mon Sep 17 00:00:00 2001 From: Igor Abdrakhimov Date: Thu, 11 Sep 2025 14:00:19 -0700 Subject: [PATCH 03/32] Set verify peers to false --- tests/tls_handler_test.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tests/tls_handler_test.c b/tests/tls_handler_test.c index a30020081..4dca913f1 100644 --- a/tests/tls_handler_test.c +++ b/tests/tls_handler_test.c @@ -1338,6 +1338,11 @@ AWS_TEST_CASE( tls_client_channel_negotiation_error_socket_closed, s_tls_client_channel_negotiation_error_socket_closed_fn); +static void s_raise_tls_version_to_13_and_verify_false(struct aws_tls_ctx_options *options) { + aws_tls_ctx_options_set_verify_peer(options, false); + aws_tls_ctx_options_set_minimum_tls_version(options, AWS_IO_TLSv1_3); +} + AWS_STATIC_STRING_FROM_LITERAL(s_aws_local_tls_server_host_name, "127.0.0.1"); static int s_tls_client_channel_negotiation_error_tls1_3_to_tls1_2_server_fn( @@ -1346,7 +1351,7 @@ static int s_tls_client_channel_negotiation_error_tls1_3_to_tls1_2_server_fn( (void)ctx; uint32_t server_tls1_2_port = 58443; return s_verify_negotiation_fails( - allocator, s_aws_local_tls_server_host_name, server_tls1_2_port, &s_raise_tls_version_to_13); + allocator, s_aws_local_tls_server_host_name, server_tls1_2_port, &s_raise_tls_version_to_13_and_verify_false); } AWS_TEST_CASE( From c43e90b63642e3b4b6a4b77cf374063e6cc87b40 Mon Sep 17 00:00:00 2001 From: Igor Abdrakhimov Date: Thu, 11 Sep 2025 16:29:38 -0700 Subject: [PATCH 04/32] Verify the issue --- tests/tls_handler_test.c | 33 +++++++++++++-------------------- 1 file changed, 13 insertions(+), 20 deletions(-) diff --git a/tests/tls_handler_test.c b/tests/tls_handler_test.c index 4dca913f1..022ac0a97 100644 --- a/tests/tls_handler_test.c +++ b/tests/tls_handler_test.c @@ -1338,26 +1338,6 @@ AWS_TEST_CASE( tls_client_channel_negotiation_error_socket_closed, s_tls_client_channel_negotiation_error_socket_closed_fn); -static void s_raise_tls_version_to_13_and_verify_false(struct aws_tls_ctx_options *options) { - aws_tls_ctx_options_set_verify_peer(options, false); - aws_tls_ctx_options_set_minimum_tls_version(options, AWS_IO_TLSv1_3); -} - -AWS_STATIC_STRING_FROM_LITERAL(s_aws_local_tls_server_host_name, "127.0.0.1"); - -static int s_tls_client_channel_negotiation_error_tls1_3_to_tls1_2_server_fn( - struct aws_allocator *allocator, - void *ctx) { - (void)ctx; - uint32_t server_tls1_2_port = 58443; - return s_verify_negotiation_fails( - allocator, s_aws_local_tls_server_host_name, server_tls1_2_port, &s_raise_tls_version_to_13_and_verify_false); -} - -AWS_TEST_CASE( - tls_client_channel_negotiation_error_tls1_3_to_tls1_2_server, - s_tls_client_channel_negotiation_error_tls1_3_to_tls1_2_server_fn) - static int s_verify_good_host( struct aws_allocator *allocator, const struct aws_string *host_name, @@ -1661,6 +1641,19 @@ AWS_TEST_CASE( tls_client_channel_negotiation_success_mtls_tls1_3, s_tls_client_channel_negotiation_success_mtls_tls1_3_fn) +static int s_tls_client_channel_negotiation_error_tls1_3_to_tls1_2_server_fn( + struct aws_allocator *allocator, + void *ctx) { + (void)ctx; + uint32_t server_tls1_2_port = 58443; + return s_verify_good_host_mqtt_connect( + allocator, s_aws_ecc384_host_name, server_tls1_2_port, s_raise_tls_version_to_13); +} + +AWS_TEST_CASE( + tls_client_channel_negotiation_error_tls1_3_to_tls1_2_server, + s_tls_client_channel_negotiation_error_tls1_3_to_tls1_2_server_fn) + AWS_STATIC_STRING_FROM_LITERAL(s3_host_name, "s3.amazonaws.com"); static void s_disable_verify_peer(struct aws_tls_ctx_options *options) { From 45dcfd0b0dfead73b250d47b16c1bf306713e576 Mon Sep 17 00:00:00 2001 From: Igor Abdrakhimov Date: Thu, 11 Sep 2025 16:33:08 -0700 Subject: [PATCH 05/32] Fail test intentionally --- tests/tls_handler_test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/tls_handler_test.c b/tests/tls_handler_test.c index 022ac0a97..a4fa219ae 100644 --- a/tests/tls_handler_test.c +++ b/tests/tls_handler_test.c @@ -1581,7 +1581,7 @@ static int s_verify_good_host_mtls_connect( aws_client_bootstrap_release(client_bootstrap); ASSERT_SUCCESS(s_tls_common_tester_clean_up(&c_tester)); - return AWS_OP_SUCCESS; + return AWS_OP_ERR; } static int s_tls_client_channel_negotiation_success_fn(struct aws_allocator *allocator, void *ctx) { From 6574413262ca137182954c76ef599314d0a8c162 Mon Sep 17 00:00:00 2001 From: Igor Abdrakhimov Date: Fri, 12 Sep 2025 11:24:39 -0700 Subject: [PATCH 06/32] Update crt-builder --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6291905f2..ec42bb549 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -6,7 +6,7 @@ on: - 'main' env: - BUILDER_VERSION: v0.9.72 + BUILDER_VERSION: v0.9.86 BUILDER_SOURCE: releases BUILDER_HOST: https://d19elf31gohf1l.cloudfront.net PACKAGE_NAME: aws-c-io From 825ea5a25c0d4fb628bccaa378d053d1c6f00ae0 Mon Sep 17 00:00:00 2001 From: Igor Abdrakhimov Date: Fri, 12 Sep 2025 11:26:00 -0700 Subject: [PATCH 07/32] wip --- tests/tls_handler_test.c | 146 ++++++++++++++++++++++++++++++++++----- 1 file changed, 130 insertions(+), 16 deletions(-) diff --git a/tests/tls_handler_test.c b/tests/tls_handler_test.c index a4fa219ae..1d136cf11 100644 --- a/tests/tls_handler_test.c +++ b/tests/tls_handler_test.c @@ -1448,7 +1448,7 @@ static int s_verify_good_host( return AWS_OP_SUCCESS; } -static int s_verify_good_host_mtls_connect( +static int s_verify_good_host_connect( struct aws_allocator *allocator, const struct aws_string *host_name, uint32_t port, @@ -1498,7 +1498,6 @@ static int s_verify_good_host_mtls_connect( /* tls13_server_root_ca.pem.crt is self-signed, so peer verification fails without additional OS configuration. */ aws_tls_ctx_options_set_verify_peer(&tls_options, false); - aws_tls_ctx_options_set_alpn_list(&tls_options, "x-amzn-mqtt-ca"); if (override_tls_options_fn) { (*override_tls_options_fn)(&tls_options); @@ -1515,7 +1514,6 @@ static int s_verify_good_host_mtls_connect( struct aws_byte_cursor host_name_cur = aws_byte_cursor_from_string(host_name); aws_tls_connection_options_set_server_name(&tls_client_conn_options, allocator, &host_name_cur); - aws_tls_connection_options_set_alpn_list(&tls_client_conn_options, allocator, "x-amzn-mqtt-ca"); struct aws_socket_options options; AWS_ZERO_STRUCT(options); @@ -1553,16 +1551,8 @@ static int s_verify_good_host_mtls_connect( ASSERT_SUCCESS(aws_mutex_unlock(&c_tester.mutex)); ASSERT_FALSE(outgoing_args.error_invoked); - struct aws_byte_buf expected_protocol = aws_byte_buf_from_c_str("x-amzn-mqtt-ca"); - /* check ALPN and SNI was properly negotiated */ - if (aws_tls_is_alpn_available() && tls_options.verify_peer) { - ASSERT_BIN_ARRAYS_EQUALS( - expected_protocol.buffer, - expected_protocol.len, - outgoing_args.negotiated_protocol.buffer, - outgoing_args.negotiated_protocol.len); - } + /* check SNI was properly negotiated */ ASSERT_BIN_ARRAYS_EQUALS( host_name->bytes, host_name->len, outgoing_args.server_name.buffer, outgoing_args.server_name.len); @@ -1581,7 +1571,131 @@ static int s_verify_good_host_mtls_connect( aws_client_bootstrap_release(client_bootstrap); ASSERT_SUCCESS(s_tls_common_tester_clean_up(&c_tester)); - return AWS_OP_ERR; + return AWS_OP_SUCCESS; +} + +static int s_verify_negotiation_fails_connect( + struct aws_allocator *allocator, + const struct aws_string *host_name, + uint32_t port, + void (*override_tls_options_fn)(struct aws_tls_ctx_options *)) { + + struct aws_byte_buf cert_buf = {0}; + struct aws_byte_buf key_buf = {0}; + struct aws_byte_buf ca_buf = {0}; + + ASSERT_SUCCESS(aws_byte_buf_init_from_file(&cert_buf, allocator, "tls13_device.pem.crt")); + ASSERT_SUCCESS(aws_byte_buf_init_from_file(&key_buf, allocator, "tls13_device.key")); + ASSERT_SUCCESS(aws_byte_buf_init_from_file(&ca_buf, allocator, "tls13_server_root_ca.pem.crt")); + + struct aws_byte_cursor cert_cur = aws_byte_cursor_from_buf(&cert_buf); + struct aws_byte_cursor key_cur = aws_byte_cursor_from_buf(&key_buf); + struct aws_byte_cursor ca_cur = aws_byte_cursor_from_buf(&ca_buf); + + aws_io_library_init(allocator); + + ASSERT_SUCCESS(s_tls_common_tester_init(allocator, &c_tester)); + + uint8_t outgoing_received_message[128] = {0}; + + struct tls_test_rw_args outgoing_rw_args; + ASSERT_SUCCESS(s_tls_rw_args_init( + &outgoing_rw_args, + &c_tester, + aws_byte_buf_from_empty_array(outgoing_received_message, sizeof(outgoing_received_message)))); + + struct tls_test_args outgoing_args = { + .mutex = &c_tester.mutex, + .allocator = allocator, + .condition_variable = &c_tester.condition_variable, + .error_invoked = 0, + .rw_handler = NULL, + .server = false, + .tls_levels_negotiated = 0, + .desired_tls_levels = 1, + .shutdown_finished = false, + }; + + struct aws_tls_ctx_options tls_options = {0}; + AWS_ZERO_STRUCT(tls_options); + + AWS_FATAL_ASSERT( + AWS_OP_SUCCESS == aws_tls_ctx_options_init_client_mtls(&tls_options, allocator, &cert_cur, &key_cur)); + + /* tls13_server_root_ca.pem.crt is self-signed, so peer verification fails without additional OS configuration. */ + aws_tls_ctx_options_set_verify_peer(&tls_options, false); + + if (override_tls_options_fn) { + (*override_tls_options_fn)(&tls_options); + } + + struct aws_tls_ctx *tls_context = aws_tls_client_ctx_new(allocator, &tls_options); + ASSERT_NOT_NULL(tls_context); + + struct aws_tls_connection_options tls_client_conn_options; + aws_tls_connection_options_init_from_ctx(&tls_client_conn_options, tls_context); + aws_tls_connection_options_set_callbacks(&tls_client_conn_options, s_tls_on_negotiated, NULL, NULL, &outgoing_args); + + aws_tls_ctx_options_override_default_trust_store(&tls_options, &ca_cur); + + struct aws_byte_cursor host_name_cur = aws_byte_cursor_from_string(host_name); + aws_tls_connection_options_set_server_name(&tls_client_conn_options, allocator, &host_name_cur); + + struct aws_socket_options options; + AWS_ZERO_STRUCT(options); + options.connect_timeout_ms = 10000; + options.type = AWS_SOCKET_STREAM; + options.domain = AWS_SOCKET_IPV4; + + struct aws_client_bootstrap_options bootstrap_options = { + .event_loop_group = c_tester.el_group, + .host_resolver = c_tester.resolver, + }; + struct aws_client_bootstrap *client_bootstrap = aws_client_bootstrap_new(allocator, &bootstrap_options); + ASSERT_NOT_NULL(client_bootstrap); + + struct aws_socket_channel_bootstrap_options channel_options; + AWS_ZERO_STRUCT(channel_options); + channel_options.bootstrap = client_bootstrap; + channel_options.host_name = aws_string_c_str(host_name); + channel_options.port = port; + channel_options.socket_options = &options; + channel_options.tls_options = &tls_client_conn_options; + channel_options.setup_callback = s_tls_handler_test_client_setup_callback; + channel_options.shutdown_callback = s_tls_handler_test_client_shutdown_callback; + channel_options.user_data = &outgoing_args; + + ASSERT_SUCCESS(aws_client_bootstrap_new_socket_channel(&channel_options)); + + /* put this here to verify ownership semantics are correct. This should NOT cause a segfault. If it does, ya + * done messed up. */ + aws_tls_connection_options_clean_up(&tls_client_conn_options); + + ASSERT_SUCCESS(aws_mutex_lock(&c_tester.mutex)); + ASSERT_SUCCESS(aws_condition_variable_wait_pred( + &c_tester.condition_variable, &c_tester.mutex, s_tls_channel_setup_predicate, &outgoing_args)); + ASSERT_SUCCESS(aws_mutex_unlock(&c_tester.mutex)); + + ASSERT_TRUE(outgoing_args.error_invoked); + + ASSERT_SUCCESS(aws_mutex_lock(&c_tester.mutex)); + aws_channel_shutdown(outgoing_args.channel, AWS_OP_SUCCESS); + ASSERT_SUCCESS(aws_condition_variable_wait_pred( + &c_tester.condition_variable, &c_tester.mutex, s_tls_channel_shutdown_predicate, &outgoing_args)); + ASSERT_SUCCESS(aws_mutex_unlock(&c_tester.mutex)); + + ASSERT_TRUE(aws_error_code_is_tls(outgoing_args.last_error_code)); + + /* cleanups */ + aws_byte_buf_clean_up(&cert_buf); + aws_byte_buf_clean_up(&key_buf); + aws_byte_buf_clean_up(&ca_buf); + aws_tls_ctx_release(tls_context); + aws_tls_ctx_options_clean_up(&tls_options); + aws_client_bootstrap_release(client_bootstrap); + ASSERT_SUCCESS(s_tls_common_tester_clean_up(&c_tester)); + + return AWS_OP_SUCCESS; } static int s_tls_client_channel_negotiation_success_fn(struct aws_allocator *allocator, void *ctx) { @@ -1634,7 +1748,8 @@ static void s_raise_tls_version_to_13(struct aws_tls_ctx_options *options) { AWS_STATIC_STRING_FROM_LITERAL(s_aws_mtls_host_name, "127.0.0.1"); static int s_tls_client_channel_negotiation_success_mtls_tls1_3_fn(struct aws_allocator *allocator, void *ctx) { (void)ctx; - return s_verify_good_host_mtls_connect(allocator, s_aws_mtls_host_name, 59443, s_raise_tls_version_to_13); + uint32_t server_tls1_3_port = 59443; + return s_verify_good_host_connect(allocator, s_aws_ecc384_host_name, server_tls1_3_port, s_raise_tls_version_to_13); } AWS_TEST_CASE( @@ -1646,8 +1761,7 @@ static int s_tls_client_channel_negotiation_error_tls1_3_to_tls1_2_server_fn( void *ctx) { (void)ctx; uint32_t server_tls1_2_port = 58443; - return s_verify_good_host_mqtt_connect( - allocator, s_aws_ecc384_host_name, server_tls1_2_port, s_raise_tls_version_to_13); + return s_verify_good_host_connect(allocator, s_aws_ecc384_host_name, server_tls1_2_port, s_raise_tls_version_to_13); } AWS_TEST_CASE( From d9a21de62f00013644c6d5318d0f201c25d7f225 Mon Sep 17 00:00:00 2001 From: Igor Abdrakhimov Date: Fri, 12 Sep 2025 11:32:46 -0700 Subject: [PATCH 08/32] Set crt-builder version to v0.9.85 --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ec42bb549..dc551c150 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -6,7 +6,7 @@ on: - 'main' env: - BUILDER_VERSION: v0.9.86 + BUILDER_VERSION: v0.9.85 BUILDER_SOURCE: releases BUILDER_HOST: https://d19elf31gohf1l.cloudfront.net PACKAGE_NAME: aws-c-io From f1934b94c3d1ae82b74f9b96e2790f230d0e5e85 Mon Sep 17 00:00:00 2001 From: Igor Abdrakhimov Date: Fri, 12 Sep 2025 11:35:01 -0700 Subject: [PATCH 09/32] Comment unused function --- tests/tls_handler_test.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/tls_handler_test.c b/tests/tls_handler_test.c index 1d136cf11..a9a5992b7 100644 --- a/tests/tls_handler_test.c +++ b/tests/tls_handler_test.c @@ -1574,6 +1574,7 @@ static int s_verify_good_host_connect( return AWS_OP_SUCCESS; } +#if 0 static int s_verify_negotiation_fails_connect( struct aws_allocator *allocator, const struct aws_string *host_name, @@ -1697,6 +1698,7 @@ static int s_verify_negotiation_fails_connect( return AWS_OP_SUCCESS; } +#endif static int s_tls_client_channel_negotiation_success_fn(struct aws_allocator *allocator, void *ctx) { (void)ctx; From d20f423859595a6c63529f4be030e38b562bee61 Mon Sep 17 00:00:00 2001 From: Igor Abdrakhimov Date: Fri, 12 Sep 2025 13:44:30 -0700 Subject: [PATCH 10/32] Use failing function --- tests/tls_handler_test.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tests/tls_handler_test.c b/tests/tls_handler_test.c index a9a5992b7..b2b7f995c 100644 --- a/tests/tls_handler_test.c +++ b/tests/tls_handler_test.c @@ -1574,7 +1574,6 @@ static int s_verify_good_host_connect( return AWS_OP_SUCCESS; } -#if 0 static int s_verify_negotiation_fails_connect( struct aws_allocator *allocator, const struct aws_string *host_name, @@ -1698,7 +1697,6 @@ static int s_verify_negotiation_fails_connect( return AWS_OP_SUCCESS; } -#endif static int s_tls_client_channel_negotiation_success_fn(struct aws_allocator *allocator, void *ctx) { (void)ctx; @@ -1763,7 +1761,8 @@ static int s_tls_client_channel_negotiation_error_tls1_3_to_tls1_2_server_fn( void *ctx) { (void)ctx; uint32_t server_tls1_2_port = 58443; - return s_verify_good_host_connect(allocator, s_aws_ecc384_host_name, server_tls1_2_port, s_raise_tls_version_to_13); + return s_verify_negotiation_fails_connect( + allocator, s_aws_ecc384_host_name, server_tls1_2_port, s_raise_tls_version_to_13); } AWS_TEST_CASE( From ac646c574189bf1caeb010d337112f93a542074c Mon Sep 17 00:00:00 2001 From: Igor Abdrakhimov Date: Fri, 12 Sep 2025 13:54:54 -0700 Subject: [PATCH 11/32] Remove setup part from failing test --- tests/tls_handler_test.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/tests/tls_handler_test.c b/tests/tls_handler_test.c index b2b7f995c..670c38fc4 100644 --- a/tests/tls_handler_test.c +++ b/tests/tls_handler_test.c @@ -1671,11 +1671,6 @@ static int s_verify_negotiation_fails_connect( * done messed up. */ aws_tls_connection_options_clean_up(&tls_client_conn_options); - ASSERT_SUCCESS(aws_mutex_lock(&c_tester.mutex)); - ASSERT_SUCCESS(aws_condition_variable_wait_pred( - &c_tester.condition_variable, &c_tester.mutex, s_tls_channel_setup_predicate, &outgoing_args)); - ASSERT_SUCCESS(aws_mutex_unlock(&c_tester.mutex)); - ASSERT_TRUE(outgoing_args.error_invoked); ASSERT_SUCCESS(aws_mutex_lock(&c_tester.mutex)); From f6956cfbdfe452949f77f1f3297e7acca0341d9f Mon Sep 17 00:00:00 2001 From: Igor Abdrakhimov Date: Fri, 12 Sep 2025 14:05:49 -0700 Subject: [PATCH 12/32] Check error code after failure happened, duh --- tests/tls_handler_test.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tests/tls_handler_test.c b/tests/tls_handler_test.c index 670c38fc4..925d49350 100644 --- a/tests/tls_handler_test.c +++ b/tests/tls_handler_test.c @@ -1671,14 +1671,13 @@ static int s_verify_negotiation_fails_connect( * done messed up. */ aws_tls_connection_options_clean_up(&tls_client_conn_options); - ASSERT_TRUE(outgoing_args.error_invoked); - ASSERT_SUCCESS(aws_mutex_lock(&c_tester.mutex)); - aws_channel_shutdown(outgoing_args.channel, AWS_OP_SUCCESS); ASSERT_SUCCESS(aws_condition_variable_wait_pred( &c_tester.condition_variable, &c_tester.mutex, s_tls_channel_shutdown_predicate, &outgoing_args)); ASSERT_SUCCESS(aws_mutex_unlock(&c_tester.mutex)); + ASSERT_TRUE(outgoing_args.error_invoked); + ASSERT_TRUE(aws_error_code_is_tls(outgoing_args.last_error_code)); /* cleanups */ From e28d1a85adfef8d7811e0cbc67838aed96983b49 Mon Sep 17 00:00:00 2001 From: Igor Abdrakhimov Date: Fri, 12 Sep 2025 14:58:23 -0700 Subject: [PATCH 13/32] Set expect_error field --- tests/tls_handler_test.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/tls_handler_test.c b/tests/tls_handler_test.c index 925d49350..fd29b2c40 100644 --- a/tests/tls_handler_test.c +++ b/tests/tls_handler_test.c @@ -1609,6 +1609,7 @@ static int s_verify_negotiation_fails_connect( .allocator = allocator, .condition_variable = &c_tester.condition_variable, .error_invoked = 0, + .expects_error = true, .rw_handler = NULL, .server = false, .tls_levels_negotiated = 0, From 009a54563fb2f12f0282e3aa33154ebfbaf09a31 Mon Sep 17 00:00:00 2001 From: Igor Abdrakhimov Date: Mon, 15 Sep 2025 15:20:43 -0700 Subject: [PATCH 14/32] Try out latest crt builder --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index dc551c150..66b3b1649 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -6,8 +6,8 @@ on: - 'main' env: - BUILDER_VERSION: v0.9.85 - BUILDER_SOURCE: releases + BUILDER_VERSION: ubuntu-update + BUILDER_SOURCE: channels BUILDER_HOST: https://d19elf31gohf1l.cloudfront.net PACKAGE_NAME: aws-c-io LINUX_BASE_IMAGE: ubuntu-18-x64 From 4161eeb55c446217324bb6b43ff74882464560ef Mon Sep 17 00:00:00 2001 From: Igor Abdrakhimov Date: Tue, 16 Sep 2025 10:52:43 -0700 Subject: [PATCH 15/32] Use python version set by builder --- .builder/actions/tls_server_setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.builder/actions/tls_server_setup.py b/.builder/actions/tls_server_setup.py index a0746ae25..d0a5a6eda 100644 --- a/.builder/actions/tls_server_setup.py +++ b/.builder/actions/tls_server_setup.py @@ -41,7 +41,7 @@ def run(self, env): print("Running TLS servers") - python_path = sys.executable + python_path = env.config['variables']['python'] tls12_server_process = subprocess.Popen( [python_path, tls_server_dir / 'tls_server.py', '--port', '58443', '--resource-dir', resource_dir, From 1e71d03290be14696f4352b22578a0e3687ec515 Mon Sep 17 00:00:00 2001 From: Igor Abdrakhimov Date: Thu, 25 Sep 2025 10:25:39 -0700 Subject: [PATCH 16/32] Remove unused import --- .builder/actions/tls_server_setup.py | 1 - 1 file changed, 1 deletion(-) diff --git a/.builder/actions/tls_server_setup.py b/.builder/actions/tls_server_setup.py index d0a5a6eda..cc244221a 100644 --- a/.builder/actions/tls_server_setup.py +++ b/.builder/actions/tls_server_setup.py @@ -5,7 +5,6 @@ import Builder from pathlib import Path -import sys import subprocess import atexit From e3f31f83ebca26e3b81ea968533f2dcfac790fa6 Mon Sep 17 00:00:00 2001 From: Igor Abdrakhimov Date: Mon, 1 Dec 2025 14:02:41 -0800 Subject: [PATCH 17/32] Use crt-builder v0.9.88 --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 66b3b1649..0e614d160 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -6,8 +6,8 @@ on: - 'main' env: - BUILDER_VERSION: ubuntu-update - BUILDER_SOURCE: channels + BUILDER_VERSION: v0.9.88 + BUILDER_SOURCE: releases BUILDER_HOST: https://d19elf31gohf1l.cloudfront.net PACKAGE_NAME: aws-c-io LINUX_BASE_IMAGE: ubuntu-18-x64 From a5a8318eed57b973c079667d604e588ae2771603 Mon Sep 17 00:00:00 2001 From: Igor Abdrakhimov Date: Mon, 1 Dec 2025 15:05:41 -0800 Subject: [PATCH 18/32] Downgrade crt-builder --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0e614d160..6291905f2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -6,7 +6,7 @@ on: - 'main' env: - BUILDER_VERSION: v0.9.88 + BUILDER_VERSION: v0.9.72 BUILDER_SOURCE: releases BUILDER_HOST: https://d19elf31gohf1l.cloudfront.net PACKAGE_NAME: aws-c-io From 69058ace36ac90b584789e5b5a299e9d5802f35c Mon Sep 17 00:00:00 2001 From: Igor Abdrakhimov Date: Mon, 1 Dec 2025 15:11:40 -0800 Subject: [PATCH 19/32] Disable test on apple platforms --- tests/CMakeLists.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 5447534b4..51b86f849 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -233,7 +233,10 @@ if(NOT BYO_CRYPTO) add_net_test_case(tls_client_channel_negotiation_error_broken_crypto_dh480) add_net_test_case(tls_client_channel_negotiation_error_broken_crypto_dh512) add_net_test_case(tls_client_channel_negotiation_error_broken_crypto_null) - add_net_test_case(tls_client_channel_negotiation_error_tls1_3_to_tls1_2_server) + if (NOT APPLE) + # Currently, this test doesn't work. It will be enabled when dispatch queue is used on macOS. + add_net_test_case(tls_client_channel_negotiation_error_tls1_3_to_tls1_2_server) + endif() # Badssl - Legacy crypto suite, includes both negative and positive tests, with override checks where appropriate # Our current baseline/default is platform-specific, whereas badssl expects a baseline of 1.2 From 1aa4f296f205592de5a2d88c93423fe4da6492ce Mon Sep 17 00:00:00 2001 From: Igor Abdrakhimov Date: Mon, 1 Dec 2025 15:17:42 -0800 Subject: [PATCH 20/32] Enable mtls tests on macos --- builder.json | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/builder.json b/builder.json index 8b10a84bc..3a276d793 100644 --- a/builder.json +++ b/builder.json @@ -18,6 +18,12 @@ "linux": { "_comment": "set up SoftHSM2 for PKCS#11 tests (see: ./builder/actions/pkcs11_test_setup.py)", "+pre_build_steps": ["pkcs11-test-setup"] + }, + "windows": { + "+pre_build_steps": ["tls-server-setup"] + }, + "macos": { + "+pre_build_steps": ["tls-server-setup"] } }, "build_env": { From 1828b3cc88a8314610b8ab564ecae31b0aa1a022 Mon Sep 17 00:00:00 2001 From: Igor Abdrakhimov Date: Mon, 1 Dec 2025 15:46:56 -0800 Subject: [PATCH 21/32] fixup --- builder.json | 1 - 1 file changed, 1 deletion(-) diff --git a/builder.json b/builder.json index 3a276d793..fc2fc3247 100644 --- a/builder.json +++ b/builder.json @@ -13,7 +13,6 @@ { "name": "aws-c-mqtt" }, { "name": "aws-c-event-stream" } ], - "pre_build_steps": ["tls-server-setup"], "targets": { "linux": { "_comment": "set up SoftHSM2 for PKCS#11 tests (see: ./builder/actions/pkcs11_test_setup.py)", From 11333ac10d2b5ecab07c884020bbf2ac6e86ed8d Mon Sep 17 00:00:00 2001 From: Igor Abdrakhimov Date: Mon, 1 Dec 2025 15:59:04 -0800 Subject: [PATCH 22/32] Run mtls on windows only --- tests/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 51b86f849..b937629bc 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -233,8 +233,8 @@ if(NOT BYO_CRYPTO) add_net_test_case(tls_client_channel_negotiation_error_broken_crypto_dh480) add_net_test_case(tls_client_channel_negotiation_error_broken_crypto_dh512) add_net_test_case(tls_client_channel_negotiation_error_broken_crypto_null) - if (NOT APPLE) - # Currently, this test doesn't work. It will be enabled when dispatch queue is used on macOS. + if (WIN32) + # Currently, this test doesn't work on macOS. It will be enabled when migration to dispatch queue is done. add_net_test_case(tls_client_channel_negotiation_error_tls1_3_to_tls1_2_server) endif() From a5ef8e4bc16dc782d787987cf3bed290aac368bf Mon Sep 17 00:00:00 2001 From: Igor Abdrakhimov Date: Mon, 1 Dec 2025 16:29:43 -0800 Subject: [PATCH 23/32] Add mtls 1.2 test --- tests/CMakeLists.txt | 8 ++++++-- tests/tls_handler_test.c | 34 ++++++++++++++++++++++------------ 2 files changed, 28 insertions(+), 14 deletions(-) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index b937629bc..662d4dc97 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -111,6 +111,10 @@ if(NOT APPLE) add_net_test_case(cleanup_before_connect_or_timeout_doesnt_explode) endif() +if (WIN32 OR APPLE) + add_net_test_case(tls_client_channel_negotiation_success_mtls_tls12) +endif() + if(WIN32) string(REPLACE "." ";" BUILD_VERSION ${CMAKE_HOST_SYSTEM_VERSION}) list(GET BUILD_VERSION 2 BUILD_V) @@ -118,7 +122,7 @@ if(WIN32) if(${BUILD_V} GREATER_EQUAL 20348) message("Building for version 20348 or higher: supporting TLS1.3") - add_net_test_case(tls_client_channel_negotiation_success_mtls_tls1_3) + add_net_test_case(tls_client_channel_negotiation_success_mtls_tls13) endif() add_test_case(local_socket_pipe_connected_race) add_test_case(tls_client_channel_negotiation_success_ecc384_deprecated) @@ -235,7 +239,7 @@ if(NOT BYO_CRYPTO) add_net_test_case(tls_client_channel_negotiation_error_broken_crypto_null) if (WIN32) # Currently, this test doesn't work on macOS. It will be enabled when migration to dispatch queue is done. - add_net_test_case(tls_client_channel_negotiation_error_tls1_3_to_tls1_2_server) + add_net_test_case(tls_client_channel_negotiation_error_tls13_to_tls12_server) endif() # Badssl - Legacy crypto suite, includes both negative and positive tests, with override checks where appropriate diff --git a/tests/tls_handler_test.c b/tests/tls_handler_test.c index fd29b2c40..1dc90a0b1 100644 --- a/tests/tls_handler_test.c +++ b/tests/tls_handler_test.c @@ -1740,29 +1740,39 @@ static void s_raise_tls_version_to_13(struct aws_tls_ctx_options *options) { aws_tls_ctx_options_set_minimum_tls_version(options, AWS_IO_TLSv1_3); } -AWS_STATIC_STRING_FROM_LITERAL(s_aws_mtls_host_name, "127.0.0.1"); -static int s_tls_client_channel_negotiation_success_mtls_tls1_3_fn(struct aws_allocator *allocator, void *ctx) { +AWS_STATIC_STRING_FROM_LITERAL(s_aws_local_tls_server_host_name, "127.0.0.1"); + +static int s_tls_client_channel_negotiation_success_mtls_tls12_fn(struct aws_allocator *allocator, void *ctx) { (void)ctx; - uint32_t server_tls1_3_port = 59443; - return s_verify_good_host_connect(allocator, s_aws_ecc384_host_name, server_tls1_3_port, s_raise_tls_version_to_13); + uint32_t server_tls12_port = 58443; + return s_verify_good_host_connect(allocator, s_aws_local_tls_server_host_name, server_tls12_port, NULL); } -AWS_TEST_CASE( - tls_client_channel_negotiation_success_mtls_tls1_3, - s_tls_client_channel_negotiation_success_mtls_tls1_3_fn) +AWS_TEST_CASE(tls_client_channel_negotiation_success_mtls_tls12, s_tls_client_channel_negotiation_success_mtls_tls12_fn) + +static int s_tls_client_channel_negotiation_success_mtls_tls13_fn(struct aws_allocator *allocator, void *ctx) { + (void)ctx; + uint32_t server_tls13_port = 59443; + return s_verify_good_host_connect( + allocator, s_aws_local_tls_server_host_name, server_tls13_port, s_raise_tls_version_to_13); +} + +AWS_TEST_CASE(tls_client_channel_negotiation_success_mtls_tls13, s_tls_client_channel_negotiation_success_mtls_tls13_fn) -static int s_tls_client_channel_negotiation_error_tls1_3_to_tls1_2_server_fn( +/* In this test, a client sets minimum TLS to 1.3 and then tries to connect to a server supporting TLS 1.2 only. + * The TLS connection should fail. */ +static int s_tls_client_channel_negotiation_error_tls13_to_tls12_server_fn( struct aws_allocator *allocator, void *ctx) { (void)ctx; - uint32_t server_tls1_2_port = 58443; + uint32_t server_tls12_port = 58443; return s_verify_negotiation_fails_connect( - allocator, s_aws_ecc384_host_name, server_tls1_2_port, s_raise_tls_version_to_13); + allocator, s_aws_local_tls_server_host_name, server_tls12_port, s_raise_tls_version_to_13); } AWS_TEST_CASE( - tls_client_channel_negotiation_error_tls1_3_to_tls1_2_server, - s_tls_client_channel_negotiation_error_tls1_3_to_tls1_2_server_fn) + tls_client_channel_negotiation_error_tls13_to_tls12_server, + s_tls_client_channel_negotiation_error_tls13_to_tls12_server_fn) AWS_STATIC_STRING_FROM_LITERAL(s3_host_name, "s3.amazonaws.com"); From fb0ecb409cfb235950379e8ba3f24b482ac6d9ae Mon Sep 17 00:00:00 2001 From: Igor Abdrakhimov Date: Mon, 1 Dec 2025 16:30:29 -0800 Subject: [PATCH 24/32] lint --- tests/tls_handler_test.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/tls_handler_test.c b/tests/tls_handler_test.c index 1dc90a0b1..b1788ca9a 100644 --- a/tests/tls_handler_test.c +++ b/tests/tls_handler_test.c @@ -1761,9 +1761,7 @@ AWS_TEST_CASE(tls_client_channel_negotiation_success_mtls_tls13, s_tls_client_ch /* In this test, a client sets minimum TLS to 1.3 and then tries to connect to a server supporting TLS 1.2 only. * The TLS connection should fail. */ -static int s_tls_client_channel_negotiation_error_tls13_to_tls12_server_fn( - struct aws_allocator *allocator, - void *ctx) { +static int s_tls_client_channel_negotiation_error_tls13_to_tls12_server_fn(struct aws_allocator *allocator, void *ctx) { (void)ctx; uint32_t server_tls12_port = 58443; return s_verify_negotiation_fails_connect( From e7981d3314c263d8d279bdc46fe8534c1bb5e053 Mon Sep 17 00:00:00 2001 From: Igor Abdrakhimov Date: Tue, 2 Dec 2025 09:29:18 -0800 Subject: [PATCH 25/32] cleanup --- tests/tls_handler_test.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tests/tls_handler_test.c b/tests/tls_handler_test.c index b1788ca9a..b5c3e14c1 100644 --- a/tests/tls_handler_test.c +++ b/tests/tls_handler_test.c @@ -1736,10 +1736,6 @@ AWS_TEST_CASE( s_tls_client_channel_negotiation_success_ecc384_SCHANNEL_CREDS_fn) # endif /* _WIN32 */ -static void s_raise_tls_version_to_13(struct aws_tls_ctx_options *options) { - aws_tls_ctx_options_set_minimum_tls_version(options, AWS_IO_TLSv1_3); -} - AWS_STATIC_STRING_FROM_LITERAL(s_aws_local_tls_server_host_name, "127.0.0.1"); static int s_tls_client_channel_negotiation_success_mtls_tls12_fn(struct aws_allocator *allocator, void *ctx) { From b3bbc7eeae3b846a596e0e569dba4cb9f78b139c Mon Sep 17 00:00:00 2001 From: Igor Abdrakhimov Date: Tue, 2 Dec 2025 09:30:17 -0800 Subject: [PATCH 26/32] Fix naming --- tests/tls_handler_test.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/tls_handler_test.c b/tests/tls_handler_test.c index b5c3e14c1..f4a98c9b7 100644 --- a/tests/tls_handler_test.c +++ b/tests/tls_handler_test.c @@ -1448,7 +1448,7 @@ static int s_verify_good_host( return AWS_OP_SUCCESS; } -static int s_verify_good_host_connect( +static int s_verify_mtls_good_host_connect( struct aws_allocator *allocator, const struct aws_string *host_name, uint32_t port, @@ -1741,7 +1741,7 @@ AWS_STATIC_STRING_FROM_LITERAL(s_aws_local_tls_server_host_name, "127.0.0.1"); static int s_tls_client_channel_negotiation_success_mtls_tls12_fn(struct aws_allocator *allocator, void *ctx) { (void)ctx; uint32_t server_tls12_port = 58443; - return s_verify_good_host_connect(allocator, s_aws_local_tls_server_host_name, server_tls12_port, NULL); + return s_verify_mtls_good_host_connect(allocator, s_aws_local_tls_server_host_name, server_tls12_port, NULL); } AWS_TEST_CASE(tls_client_channel_negotiation_success_mtls_tls12, s_tls_client_channel_negotiation_success_mtls_tls12_fn) @@ -1749,7 +1749,7 @@ AWS_TEST_CASE(tls_client_channel_negotiation_success_mtls_tls12, s_tls_client_ch static int s_tls_client_channel_negotiation_success_mtls_tls13_fn(struct aws_allocator *allocator, void *ctx) { (void)ctx; uint32_t server_tls13_port = 59443; - return s_verify_good_host_connect( + return s_verify_mtls_good_host_connect( allocator, s_aws_local_tls_server_host_name, server_tls13_port, s_raise_tls_version_to_13); } From eee0dd0383c23e4d174d213e37c5030e9f80c576 Mon Sep 17 00:00:00 2001 From: Igor Abdrakhimov Date: Tue, 2 Dec 2025 09:33:57 -0800 Subject: [PATCH 27/32] Enable tls13 tests on macos --- tests/CMakeLists.txt | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 662d4dc97..d7afcb9c6 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -111,11 +111,14 @@ if(NOT APPLE) add_net_test_case(cleanup_before_connect_or_timeout_doesnt_explode) endif() -if (WIN32 OR APPLE) +if (APPLE) add_net_test_case(tls_client_channel_negotiation_success_mtls_tls12) + add_net_test_case(tls_client_channel_negotiation_success_mtls_tls13) endif() if(WIN32) + add_net_test_case(tls_client_channel_negotiation_success_mtls_tls12) + string(REPLACE "." ";" BUILD_VERSION ${CMAKE_HOST_SYSTEM_VERSION}) list(GET BUILD_VERSION 2 BUILD_V) message("Windows Version " ${CMAKE_HOST_SYSTEM_VERSION} ", build " ${BUILD_V}) @@ -237,7 +240,7 @@ if(NOT BYO_CRYPTO) add_net_test_case(tls_client_channel_negotiation_error_broken_crypto_dh480) add_net_test_case(tls_client_channel_negotiation_error_broken_crypto_dh512) add_net_test_case(tls_client_channel_negotiation_error_broken_crypto_null) - if (WIN32) + if (WIN32 OR APPLE) # Currently, this test doesn't work on macOS. It will be enabled when migration to dispatch queue is done. add_net_test_case(tls_client_channel_negotiation_error_tls13_to_tls12_server) endif() From d17779ac1d48a97adbc392eeef8320dd94c2c6fb Mon Sep 17 00:00:00 2001 From: Igor Abdrakhimov Date: Tue, 2 Dec 2025 12:05:39 -0800 Subject: [PATCH 28/32] Define local tls servers ports --- tests/tls_handler_test.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/tests/tls_handler_test.c b/tests/tls_handler_test.c index f4a98c9b7..096fba185 100644 --- a/tests/tls_handler_test.c +++ b/tests/tls_handler_test.c @@ -31,6 +31,9 @@ * higher chance of actually testing something. */ # define BADSSL_TIMEOUT_MS 10000 +# define AWS_TEST_LOCAL_TLS12_PORT 58443 +# define AWS_TEST_LOCAL_TLS13_PORT 59443 + bool s_is_badssl_being_flaky(const struct aws_string *host_name, int error_code) { if (strstr(aws_string_c_str(host_name), "badssl.com") != NULL) { if (error_code == AWS_IO_SOCKET_TIMEOUT || error_code == AWS_IO_TLS_NEGOTIATION_TIMEOUT) { @@ -1740,17 +1743,16 @@ AWS_STATIC_STRING_FROM_LITERAL(s_aws_local_tls_server_host_name, "127.0.0.1"); static int s_tls_client_channel_negotiation_success_mtls_tls12_fn(struct aws_allocator *allocator, void *ctx) { (void)ctx; - uint32_t server_tls12_port = 58443; - return s_verify_mtls_good_host_connect(allocator, s_aws_local_tls_server_host_name, server_tls12_port, NULL); + return s_verify_mtls_good_host_connect( + allocator, s_aws_local_tls_server_host_name, AWS_TEST_LOCAL_TLS12_PORT, NULL); } AWS_TEST_CASE(tls_client_channel_negotiation_success_mtls_tls12, s_tls_client_channel_negotiation_success_mtls_tls12_fn) static int s_tls_client_channel_negotiation_success_mtls_tls13_fn(struct aws_allocator *allocator, void *ctx) { (void)ctx; - uint32_t server_tls13_port = 59443; return s_verify_mtls_good_host_connect( - allocator, s_aws_local_tls_server_host_name, server_tls13_port, s_raise_tls_version_to_13); + allocator, s_aws_local_tls_server_host_name, AWS_TEST_LOCAL_TLS13_PORT, s_raise_tls_version_to_13); } AWS_TEST_CASE(tls_client_channel_negotiation_success_mtls_tls13, s_tls_client_channel_negotiation_success_mtls_tls13_fn) @@ -1759,9 +1761,8 @@ AWS_TEST_CASE(tls_client_channel_negotiation_success_mtls_tls13, s_tls_client_ch * The TLS connection should fail. */ static int s_tls_client_channel_negotiation_error_tls13_to_tls12_server_fn(struct aws_allocator *allocator, void *ctx) { (void)ctx; - uint32_t server_tls12_port = 58443; return s_verify_negotiation_fails_connect( - allocator, s_aws_local_tls_server_host_name, server_tls12_port, s_raise_tls_version_to_13); + allocator, s_aws_local_tls_server_host_name, AWS_TEST_LOCAL_TLS12_PORT, s_raise_tls_version_to_13); } AWS_TEST_CASE( From 64a73d1c38edfd4b0836bb10ea9c6743fca62d13 Mon Sep 17 00:00:00 2001 From: Igor Abdrakhimov Date: Tue, 2 Dec 2025 12:09:27 -0800 Subject: [PATCH 29/32] Remove outdated comment --- tests/CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index d7afcb9c6..67d955f90 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -241,7 +241,6 @@ if(NOT BYO_CRYPTO) add_net_test_case(tls_client_channel_negotiation_error_broken_crypto_dh512) add_net_test_case(tls_client_channel_negotiation_error_broken_crypto_null) if (WIN32 OR APPLE) - # Currently, this test doesn't work on macOS. It will be enabled when migration to dispatch queue is done. add_net_test_case(tls_client_channel_negotiation_error_tls13_to_tls12_server) endif() From 34cea5429200a814c0a502163a6e9194e8d5634f Mon Sep 17 00:00:00 2001 From: Igor Abdrakhimov Date: Tue, 2 Dec 2025 12:10:41 -0800 Subject: [PATCH 30/32] Fix naming --- tests/tls_handler_test.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/tls_handler_test.c b/tests/tls_handler_test.c index 096fba185..6f878d05a 100644 --- a/tests/tls_handler_test.c +++ b/tests/tls_handler_test.c @@ -1451,7 +1451,7 @@ static int s_verify_good_host( return AWS_OP_SUCCESS; } -static int s_verify_mtls_good_host_connect( +static int s_verify_good_host_mtls_connect( struct aws_allocator *allocator, const struct aws_string *host_name, uint32_t port, @@ -1743,7 +1743,7 @@ AWS_STATIC_STRING_FROM_LITERAL(s_aws_local_tls_server_host_name, "127.0.0.1"); static int s_tls_client_channel_negotiation_success_mtls_tls12_fn(struct aws_allocator *allocator, void *ctx) { (void)ctx; - return s_verify_mtls_good_host_connect( + return s_verify_good_host_mtls_connect( allocator, s_aws_local_tls_server_host_name, AWS_TEST_LOCAL_TLS12_PORT, NULL); } @@ -1751,7 +1751,7 @@ AWS_TEST_CASE(tls_client_channel_negotiation_success_mtls_tls12, s_tls_client_ch static int s_tls_client_channel_negotiation_success_mtls_tls13_fn(struct aws_allocator *allocator, void *ctx) { (void)ctx; - return s_verify_mtls_good_host_connect( + return s_verify_good_host_mtls_connect( allocator, s_aws_local_tls_server_host_name, AWS_TEST_LOCAL_TLS13_PORT, s_raise_tls_version_to_13); } From 42c42a723af134bac0b63acc8896d451ef461dde Mon Sep 17 00:00:00 2001 From: Igor Abdrakhimov Date: Tue, 2 Dec 2025 12:14:45 -0800 Subject: [PATCH 31/32] Fix creds naming --- .../{tls13_device.key => mtls_device.key} | 0 ...{tls13_device.pem.crt => mtls_device.pem.crt} | 0 ...evice_root_ca.key => mtls_device_root_ca.key} | 0 ...ot_ca.pem.crt => mtls_device_root_ca.pem.crt} | 0 .../{tls13_server.key => mtls_server.key} | 0 ...{tls13_server.pem.crt => mtls_server.pem.crt} | 0 ...erver_root_ca.key => mtls_server_root_ca.key} | 0 ...ot_ca.pem.crt => mtls_server_root_ca.pem.crt} | 0 tests/tls_handler_test.c | 16 ++++++++-------- 9 files changed, 8 insertions(+), 8 deletions(-) rename tests/resources/{tls13_device.key => mtls_device.key} (100%) rename tests/resources/{tls13_device.pem.crt => mtls_device.pem.crt} (100%) rename tests/resources/{tls13_device_root_ca.key => mtls_device_root_ca.key} (100%) rename tests/resources/{tls13_device_root_ca.pem.crt => mtls_device_root_ca.pem.crt} (100%) rename tests/resources/{tls13_server.key => mtls_server.key} (100%) rename tests/resources/{tls13_server.pem.crt => mtls_server.pem.crt} (100%) rename tests/resources/{tls13_server_root_ca.key => mtls_server_root_ca.key} (100%) rename tests/resources/{tls13_server_root_ca.pem.crt => mtls_server_root_ca.pem.crt} (100%) diff --git a/tests/resources/tls13_device.key b/tests/resources/mtls_device.key similarity index 100% rename from tests/resources/tls13_device.key rename to tests/resources/mtls_device.key diff --git a/tests/resources/tls13_device.pem.crt b/tests/resources/mtls_device.pem.crt similarity index 100% rename from tests/resources/tls13_device.pem.crt rename to tests/resources/mtls_device.pem.crt diff --git a/tests/resources/tls13_device_root_ca.key b/tests/resources/mtls_device_root_ca.key similarity index 100% rename from tests/resources/tls13_device_root_ca.key rename to tests/resources/mtls_device_root_ca.key diff --git a/tests/resources/tls13_device_root_ca.pem.crt b/tests/resources/mtls_device_root_ca.pem.crt similarity index 100% rename from tests/resources/tls13_device_root_ca.pem.crt rename to tests/resources/mtls_device_root_ca.pem.crt diff --git a/tests/resources/tls13_server.key b/tests/resources/mtls_server.key similarity index 100% rename from tests/resources/tls13_server.key rename to tests/resources/mtls_server.key diff --git a/tests/resources/tls13_server.pem.crt b/tests/resources/mtls_server.pem.crt similarity index 100% rename from tests/resources/tls13_server.pem.crt rename to tests/resources/mtls_server.pem.crt diff --git a/tests/resources/tls13_server_root_ca.key b/tests/resources/mtls_server_root_ca.key similarity index 100% rename from tests/resources/tls13_server_root_ca.key rename to tests/resources/mtls_server_root_ca.key diff --git a/tests/resources/tls13_server_root_ca.pem.crt b/tests/resources/mtls_server_root_ca.pem.crt similarity index 100% rename from tests/resources/tls13_server_root_ca.pem.crt rename to tests/resources/mtls_server_root_ca.pem.crt diff --git a/tests/tls_handler_test.c b/tests/tls_handler_test.c index 6f878d05a..c2238dbae 100644 --- a/tests/tls_handler_test.c +++ b/tests/tls_handler_test.c @@ -1461,9 +1461,9 @@ static int s_verify_good_host_mtls_connect( struct aws_byte_buf key_buf = {0}; struct aws_byte_buf ca_buf = {0}; - ASSERT_SUCCESS(aws_byte_buf_init_from_file(&cert_buf, allocator, "tls13_device.pem.crt")); - ASSERT_SUCCESS(aws_byte_buf_init_from_file(&key_buf, allocator, "tls13_device.key")); - ASSERT_SUCCESS(aws_byte_buf_init_from_file(&ca_buf, allocator, "tls13_server_root_ca.pem.crt")); + ASSERT_SUCCESS(aws_byte_buf_init_from_file(&cert_buf, allocator, "mtls_device.pem.crt")); + ASSERT_SUCCESS(aws_byte_buf_init_from_file(&key_buf, allocator, "mtls_device.key")); + ASSERT_SUCCESS(aws_byte_buf_init_from_file(&ca_buf, allocator, "mtls_server_root_ca.pem.crt")); struct aws_byte_cursor cert_cur = aws_byte_cursor_from_buf(&cert_buf); struct aws_byte_cursor key_cur = aws_byte_cursor_from_buf(&key_buf); @@ -1499,7 +1499,7 @@ static int s_verify_good_host_mtls_connect( AWS_FATAL_ASSERT( AWS_OP_SUCCESS == aws_tls_ctx_options_init_client_mtls(&tls_options, allocator, &cert_cur, &key_cur)); - /* tls13_server_root_ca.pem.crt is self-signed, so peer verification fails without additional OS configuration. */ + /* mtls_server_root_ca.pem.crt is self-signed, so peer verification fails without additional OS configuration. */ aws_tls_ctx_options_set_verify_peer(&tls_options, false); if (override_tls_options_fn) { @@ -1587,9 +1587,9 @@ static int s_verify_negotiation_fails_connect( struct aws_byte_buf key_buf = {0}; struct aws_byte_buf ca_buf = {0}; - ASSERT_SUCCESS(aws_byte_buf_init_from_file(&cert_buf, allocator, "tls13_device.pem.crt")); - ASSERT_SUCCESS(aws_byte_buf_init_from_file(&key_buf, allocator, "tls13_device.key")); - ASSERT_SUCCESS(aws_byte_buf_init_from_file(&ca_buf, allocator, "tls13_server_root_ca.pem.crt")); + ASSERT_SUCCESS(aws_byte_buf_init_from_file(&cert_buf, allocator, "mtls_device.pem.crt")); + ASSERT_SUCCESS(aws_byte_buf_init_from_file(&key_buf, allocator, "mtls_device.key")); + ASSERT_SUCCESS(aws_byte_buf_init_from_file(&ca_buf, allocator, "mtls_server_root_ca.pem.crt")); struct aws_byte_cursor cert_cur = aws_byte_cursor_from_buf(&cert_buf); struct aws_byte_cursor key_cur = aws_byte_cursor_from_buf(&key_buf); @@ -1626,7 +1626,7 @@ static int s_verify_negotiation_fails_connect( AWS_FATAL_ASSERT( AWS_OP_SUCCESS == aws_tls_ctx_options_init_client_mtls(&tls_options, allocator, &cert_cur, &key_cur)); - /* tls13_server_root_ca.pem.crt is self-signed, so peer verification fails without additional OS configuration. */ + /* mtls_server_root_ca.pem.crt is self-signed, so peer verification fails without additional OS configuration. */ aws_tls_ctx_options_set_verify_peer(&tls_options, false); if (override_tls_options_fn) { From 2dde5e0a9fdab350fd54f0320849783be12bf833 Mon Sep 17 00:00:00 2001 From: Igor Abdrakhimov Date: Tue, 2 Dec 2025 12:31:46 -0800 Subject: [PATCH 32/32] cleanup --- tests/tls_handler_test.c | 30 +----------------------------- tests/tls_server/tls_server.py | 4 ++-- 2 files changed, 3 insertions(+), 31 deletions(-) diff --git a/tests/tls_handler_test.c b/tests/tls_handler_test.c index c2238dbae..43ac8ae85 100644 --- a/tests/tls_handler_test.c +++ b/tests/tls_handler_test.c @@ -1583,30 +1583,8 @@ static int s_verify_negotiation_fails_connect( uint32_t port, void (*override_tls_options_fn)(struct aws_tls_ctx_options *)) { - struct aws_byte_buf cert_buf = {0}; - struct aws_byte_buf key_buf = {0}; - struct aws_byte_buf ca_buf = {0}; - - ASSERT_SUCCESS(aws_byte_buf_init_from_file(&cert_buf, allocator, "mtls_device.pem.crt")); - ASSERT_SUCCESS(aws_byte_buf_init_from_file(&key_buf, allocator, "mtls_device.key")); - ASSERT_SUCCESS(aws_byte_buf_init_from_file(&ca_buf, allocator, "mtls_server_root_ca.pem.crt")); - - struct aws_byte_cursor cert_cur = aws_byte_cursor_from_buf(&cert_buf); - struct aws_byte_cursor key_cur = aws_byte_cursor_from_buf(&key_buf); - struct aws_byte_cursor ca_cur = aws_byte_cursor_from_buf(&ca_buf); - - aws_io_library_init(allocator); - ASSERT_SUCCESS(s_tls_common_tester_init(allocator, &c_tester)); - uint8_t outgoing_received_message[128] = {0}; - - struct tls_test_rw_args outgoing_rw_args; - ASSERT_SUCCESS(s_tls_rw_args_init( - &outgoing_rw_args, - &c_tester, - aws_byte_buf_from_empty_array(outgoing_received_message, sizeof(outgoing_received_message)))); - struct tls_test_args outgoing_args = { .mutex = &c_tester.mutex, .allocator = allocator, @@ -1623,8 +1601,7 @@ static int s_verify_negotiation_fails_connect( struct aws_tls_ctx_options tls_options = {0}; AWS_ZERO_STRUCT(tls_options); - AWS_FATAL_ASSERT( - AWS_OP_SUCCESS == aws_tls_ctx_options_init_client_mtls(&tls_options, allocator, &cert_cur, &key_cur)); + aws_tls_ctx_options_init_default_client(&tls_options, allocator); /* mtls_server_root_ca.pem.crt is self-signed, so peer verification fails without additional OS configuration. */ aws_tls_ctx_options_set_verify_peer(&tls_options, false); @@ -1640,8 +1617,6 @@ static int s_verify_negotiation_fails_connect( aws_tls_connection_options_init_from_ctx(&tls_client_conn_options, tls_context); aws_tls_connection_options_set_callbacks(&tls_client_conn_options, s_tls_on_negotiated, NULL, NULL, &outgoing_args); - aws_tls_ctx_options_override_default_trust_store(&tls_options, &ca_cur); - struct aws_byte_cursor host_name_cur = aws_byte_cursor_from_string(host_name); aws_tls_connection_options_set_server_name(&tls_client_conn_options, allocator, &host_name_cur); @@ -1685,9 +1660,6 @@ static int s_verify_negotiation_fails_connect( ASSERT_TRUE(aws_error_code_is_tls(outgoing_args.last_error_code)); /* cleanups */ - aws_byte_buf_clean_up(&cert_buf); - aws_byte_buf_clean_up(&key_buf); - aws_byte_buf_clean_up(&ca_buf); aws_tls_ctx_release(tls_context); aws_tls_ctx_options_clean_up(&tls_options); aws_client_bootstrap_release(client_bootstrap); diff --git a/tests/tls_server/tls_server.py b/tests/tls_server/tls_server.py index 405f7509e..f09a58688 100644 --- a/tests/tls_server/tls_server.py +++ b/tests/tls_server/tls_server.py @@ -42,8 +42,8 @@ def parse_tls(tls_str): context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) context.minimum_version = parse_tls(args.min_tls) context.maximum_version = parse_tls(args.max_tls) -context.load_cert_chain(args.resource_dir / 'tls13_server.pem.crt', args.resource_dir / 'tls13_server.key') -context.load_verify_locations(args.resource_dir / 'tls13_device_root_ca.pem.crt') +context.load_cert_chain(args.resource_dir / 'mtls_server.pem.crt', args.resource_dir / 'mtls_server.key') +context.load_verify_locations(args.resource_dir / 'mtls_device_root_ca.pem.crt') context.verify_mode = ssl.CERT_REQUIRED