From c2d8bc95fb60c47fb00fae7b12c568a526195541 Mon Sep 17 00:00:00 2001 From: Igor Abdrakhimov Date: Thu, 11 Sep 2025 13:37:30 -0700 Subject: [PATCH 01/15] Add test for minimum TLS version --- .builder/actions/tls_server_setup.py | 48 ++++++++++++++------- tests/CMakeLists.txt | 1 + tests/tls_handler_test.c | 27 +++++++++--- tests/tls_server/tls_server.py | 62 ++++++++++++++++++++++++---- 4 files changed, 112 insertions(+), 26 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 5b751326c..26b05d537 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -231,6 +231,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 08fc2fe5c..c53f5e69f 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, @@ -1623,14 +1642,12 @@ AWS_TEST_CASE( s_tls_client_channel_negotiation_success_ecc384_SCHANNEL_CREDS_fn) # endif -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_ecc384_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_mqtt_connect(allocator, s_aws_ecc384_host_name, 59443, s_raise_tls_version_to_13); + uint32_t server_tls1_3_port = 59443; + return s_verify_good_host_mqtt_connect( + allocator, s_aws_ecc384_host_name, server_tls1_3_port, s_raise_tls_version_to_13); } AWS_TEST_CASE( 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 4a71592d5b9a01ccd711da6979db2cfee40dec16 Mon Sep 17 00:00:00 2001 From: Igor Abdrakhimov Date: Thu, 11 Sep 2025 13:50:52 -0700 Subject: [PATCH 02/15] 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 6d8c797185e8859a48002a83ac81f916f4a32515 Mon Sep 17 00:00:00 2001 From: Igor Abdrakhimov Date: Thu, 11 Sep 2025 14:00:19 -0700 Subject: [PATCH 03/15] 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 c53f5e69f..8c8284d6f 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 9f884027239415ff76bcc3598257af3c9f502847 Mon Sep 17 00:00:00 2001 From: Igor Abdrakhimov Date: Thu, 11 Sep 2025 16:29:38 -0700 Subject: [PATCH 04/15] 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 8c8284d6f..f64d913b7 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, @@ -1659,6 +1639,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 c2266edb1eae7806ddc11c0a69032307fc455597 Mon Sep 17 00:00:00 2001 From: Igor Abdrakhimov Date: Thu, 11 Sep 2025 16:33:08 -0700 Subject: [PATCH 05/15] 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 f64d913b7..4299d3daa 100644 --- a/tests/tls_handler_test.c +++ b/tests/tls_handler_test.c @@ -1581,7 +1581,7 @@ static int s_verify_good_host_mqtt_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 2cb16bd2d5f82f09219f9abac34a3e399d896f31 Mon Sep 17 00:00:00 2001 From: Igor Abdrakhimov Date: Fri, 12 Sep 2025 11:24:39 -0700 Subject: [PATCH 06/15] 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 a855535bd..7fc854298 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 2416377641daeae20aed4e1c949a7406e02da474 Mon Sep 17 00:00:00 2001 From: Igor Abdrakhimov Date: Fri, 12 Sep 2025 11:26:00 -0700 Subject: [PATCH 07/15] wip --- tests/tls_handler_test.c | 146 ++++++++++++++++++++++++++++++++++----- 1 file changed, 129 insertions(+), 17 deletions(-) diff --git a/tests/tls_handler_test.c b/tests/tls_handler_test.c index 4299d3daa..f71764901 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_mqtt_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_mqtt_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_mqtt_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_mqtt_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_mqtt_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) { @@ -1631,8 +1745,7 @@ AWS_STATIC_STRING_FROM_LITERAL(s_aws_ecc384_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; uint32_t server_tls1_3_port = 59443; - return s_verify_good_host_mqtt_connect( - allocator, s_aws_ecc384_host_name, server_tls1_3_port, s_raise_tls_version_to_13); + 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( @@ -1644,8 +1757,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 821d1dfdb043d2c13a31be23add6dff476d4e7de Mon Sep 17 00:00:00 2001 From: Igor Abdrakhimov Date: Fri, 12 Sep 2025 11:32:46 -0700 Subject: [PATCH 08/15] 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 7fc854298..43156d6f0 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 a3b9b40da18fa3461f1519df4f1d4cb499f15476 Mon Sep 17 00:00:00 2001 From: Igor Abdrakhimov Date: Fri, 12 Sep 2025 11:35:01 -0700 Subject: [PATCH 09/15] 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 f71764901..3fe6ebda3 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 aee458503cf682ef194ab20e586c7e52d3ab5c5e Mon Sep 17 00:00:00 2001 From: Igor Abdrakhimov Date: Fri, 12 Sep 2025 13:44:30 -0700 Subject: [PATCH 10/15] 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 3fe6ebda3..cef1ee4a2 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; @@ -1759,7 +1757,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 50ec88ece2f3ba40168f026963a60adb1db6cbd9 Mon Sep 17 00:00:00 2001 From: Igor Abdrakhimov Date: Fri, 12 Sep 2025 13:54:54 -0700 Subject: [PATCH 11/15] 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 cef1ee4a2..d86d86885 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 191284fcfe52fdfd89a91b22de178151911124f0 Mon Sep 17 00:00:00 2001 From: Igor Abdrakhimov Date: Fri, 12 Sep 2025 14:05:49 -0700 Subject: [PATCH 12/15] 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 d86d86885..12b2b38bf 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 3e55b9b597373fdbb025c42d4d2a38f301165317 Mon Sep 17 00:00:00 2001 From: Igor Abdrakhimov Date: Fri, 12 Sep 2025 14:58:23 -0700 Subject: [PATCH 13/15] 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 12b2b38bf..2150199b1 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 ee5918a13276ac6fe490a404096f9464756211f5 Mon Sep 17 00:00:00 2001 From: Igor Abdrakhimov Date: Mon, 15 Sep 2025 15:20:43 -0700 Subject: [PATCH 14/15] 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 43156d6f0..7d3876889 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 45ce94997d94919a3d1e4e60387b0dc66e9e79aa Mon Sep 17 00:00:00 2001 From: Igor Abdrakhimov Date: Tue, 16 Sep 2025 10:52:43 -0700 Subject: [PATCH 15/15] 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,