From 1ada8decb2076b5bdee513d8dbfd81ff1cbd1dc3 Mon Sep 17 00:00:00 2001 From: tb <> Date: Wed, 4 Jun 2025 10:28:00 +0000 Subject: libtls: add basic regress for ALPN This currently only tests the behavior for successful protocol negotiations since the test expects all handshakes to complete. --- src/regress/lib/libtls/tls/tlstest.c | 139 ++++++++++++++++++++++++++++++++++- 1 file changed, 138 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/regress/lib/libtls/tls/tlstest.c b/src/regress/lib/libtls/tls/tlstest.c index b675c798b4..d52156128d 100644 --- a/src/regress/lib/libtls/tls/tlstest.c +++ b/src/regress/lib/libtls/tls/tlstest.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tlstest.c,v 1.16 2024/08/02 15:02:22 tb Exp $ */ +/* $OpenBSD: tlstest.c,v 1.17 2025/06/04 10:28:00 tb Exp $ */ /* * Copyright (c) 2017 Joel Sing * @@ -531,6 +531,142 @@ do_tls_version_tests(void) return failure; } +static int +test_tls_alpn(const char *client_alpn, const char *server_alpn, + const char *selected) +{ + struct tls_config *client_cfg, *server_cfg; + struct tls *client, *server, *server_cctx; + const char *got_server, *got_client; + int failed = 1; + + if ((client = tls_client()) == NULL) + errx(1, "failed to create tls client"); + if ((client_cfg = tls_config_new()) == NULL) + errx(1, "failed to create tls client config"); + tls_config_insecure_noverifyname(client_cfg); + if (tls_config_set_alpn(client_cfg, client_alpn) == -1) + errx(1, "failed to set alpn: %s", tls_config_error(client_cfg)); + if (tls_config_set_ca_file(client_cfg, cafile) == -1) + errx(1, "failed to set ca: %s", tls_config_error(client_cfg)); + + if ((server = tls_server()) == NULL) + errx(1, "failed to create tls server"); + if ((server_cfg = tls_config_new()) == NULL) + errx(1, "failed to create tls server config"); + if (tls_config_set_alpn(server_cfg, server_alpn) == -1) + errx(1, "failed to set alpn: %s", tls_config_error(server_cfg)); + if (tls_config_set_keypair_file(server_cfg, certfile, keyfile) == -1) + errx(1, "failed to set keypair: %s", + tls_config_error(server_cfg)); + + if (tls_configure(client, client_cfg) == -1) + errx(1, "failed to configure client: %s", tls_error(client)); + tls_reset(server); + if (tls_configure(server, server_cfg) == -1) + errx(1, "failed to configure server: %s", tls_error(server)); + + tls_config_free(client_cfg); + tls_config_free(server_cfg); + + circular_init(); + + if (tls_accept_cbs(server, &server_cctx, server_read, server_write, + NULL) == -1) + errx(1, "failed to accept: %s", tls_error(server)); + + if (tls_connect_cbs(client, client_read, client_write, NULL, + "test") == -1) + errx(1, "failed to connect: %s", tls_error(client)); + + if (do_client_server_test("alpn", client, server_cctx) != 0) + goto fail; + + got_server = tls_conn_alpn_selected(server_cctx); + got_client = tls_conn_alpn_selected(client); + + if (got_server == NULL || got_client == NULL) { + printf("FAIL: expected ALPN for server and client, got " + "server: %p, client %p\n", got_server, got_client); + goto fail; + } + + if (strcmp(got_server, got_client) != 0) { + printf("FAIL: ALPN mismatch: server %s, client %s\n", + got_server, got_client); + goto fail; + } + + if (strcmp(selected, got_server) != 0) { + printf("FAIL: ALPN mismatch: want %s, got %s\n", + selected, got_server); + goto fail; + } + + failed = 0; + + fail: + tls_free(client); + tls_free(server); + tls_free(server_cctx); + + return (failed); +} + +static const struct test_alpn { + const char *client; + const char *server; + const char *selected; +} tls_test_alpn[] = { + { + .client = "http/2,http/1.1", + .server = "http/1.1", + .selected = "http/1.1", + }, + { + .client = "http/2,http/1.1", + .server = "http/2,http/1.1", + .selected = "http/2", + }, + { + .client = "http/1.1,http/2", + .server = "http/2,http/1.1", + .selected = "http/2", + }, + { + .client = "http/2,http/1.1", + .server = "http/1.1,http/2", + .selected = "http/1.1", + }, + { + .client = "http/1.1", + .server = "http/2,http/1.1", + .selected = "http/1.1", + }, +}; + +#define N_TLS_ALPN_TESTS (sizeof(tls_test_alpn) / sizeof(tls_test_alpn[0])) + +static int +do_tls_alpn_tests(void) +{ + const struct test_alpn *ta; + int failure = 0; + size_t i; + + printf("== TLS alpn tests ==\n"); + + for (i = 0; i < N_TLS_ALPN_TESTS; i++) { + ta = &tls_test_alpn[i]; + printf("INFO: alpn test %zu - client alpn '%s' " + "and server alpn '%s'\n", i, ta->client, ta->server); + failure |= test_tls_alpn(ta->client, ta->server, ta->selected); + printf("\n"); + } + + return failure; +} + int main(int argc, char **argv) { @@ -549,6 +685,7 @@ main(int argc, char **argv) failure |= do_tls_tests(); failure |= do_tls_ordering_tests(); failure |= do_tls_version_tests(); + failure |= do_tls_alpn_tests(); return (failure); } -- cgit v1.2.3-55-g6feb