From: Jakub Zelenka Date: Fri, 15 May 2026 11:00:38 +0000 (+0200) Subject: Add apps test for external PSK callbacks X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=ab6f5e915b6869ea5d15df14976a1499031b9366;p=thirdparty%2Fopenssl.git Add apps test for external PSK callbacks Reviewed-by: Neil Horman Reviewed-by: Tomas Mraz MergeDate: Thu Jun 11 15:52:36 2026 (Merged from https://github.com/openssl/openssl/pull/31190) --- diff --git a/test/recipes/70-test_tlspskext.t b/test/recipes/70-test_tlspskext.t new file mode 100644 index 00000000000..980aab2cb47 --- /dev/null +++ b/test/recipes/70-test_tlspskext.t @@ -0,0 +1,148 @@ +#! /usr/bin/env perl +# Copyright 2025 The OpenSSL Project Authors. All Rights Reserved. +# +# Licensed under the Apache License 2.0 (the "License"). You may not use +# this file except in compliance with the License. You can obtain a copy +# in the file LICENSE in the source distribution or at +# https://www.openssl.org/source/license.html + +use strict; +use OpenSSL::Test qw/:DEFAULT cmdstr srctop_file bldtop_dir/; +use OpenSSL::Test::Utils; +use TLSProxy::Proxy; +use TLSProxy::Message; +use Cwd qw(abs_path); + +my $test_name = "test_tlpskext"; +setup($test_name); + +plan skip_all => "TLSProxy isn't usable on $^O" + if $^O =~ /^(VMS)$/; +plan skip_all => "$test_name needs the sock feature enabled" + if disabled("sock"); +plan skip_all => "No TLS protocols are supported by this OpenSSL build" + if alldisabled(available_protocols("tls")); +plan skip_all => "$test_name needs the module feature enabled" + if disabled("module"); + +$ENV{OPENSSL_MODULES} = abs_path(bldtop_dir("test")); + +my $psk = "0102030405060708090a0b0c0d0e0f10"; + +my $proxy = TLSProxy::Proxy->new( + undef, + cmdstr(app(["openssl"]), display => 1), + srctop_file("apps", "server.pem"), + (!$ENV{HARNESS_ACTIVE} || $ENV{HARNESS_VERBOSE}), + have_IPv6() +); + +$proxy->start() or plan skip_all => "Unable to start up Proxy for tests"; + +my $tls13_disabled = disabled("tls1_3") || (disabled("ec") && disabled("dh")); +my $tls12_disabled = disabled("tls1_2"); +plan skip_all => "$test_name needs TLSv1.2 or TLSv1.3 enabled" + if $tls13_disabled && $tls12_disabled; +plan tests => 6; + +my $psk_ext_in_ch = 0; +my $psk_ext_in_sh = 0; + +SKIP: { + skip "TLS 1.3 disabled", 4 + if disabled("tls1_3") || (disabled("ec") && disabled("dh")); + + my $flags = "-tls1_3 -no_rx_cert_comp"; + + # psk_use_session_cb (client) / psk_find_session_cb (server). + $proxy->clear(); + $proxy->clientflags("-psk $psk $flags"); + $proxy->serverflags("-psk $psk $flags"); + $proxy->filter(undef); + $proxy->start(); + ok(TLSProxy::Message->success(), "TLS 1.3 PSK connection"); + + $proxy->clear(); + $proxy->clientflags("-psk $psk $flags"); + $proxy->serverflags("-psk $psk $flags"); + $psk_ext_in_ch = 0; + $proxy->filter(\&check_psk_in_ch); + $proxy->start(); + ok($psk_ext_in_ch, "PSK extension present in TLS 1.3 ClientHello"); + + # psk_find_session_cb returns *sess = NULL on mismatch; falls back to cert. + $proxy->clear(); + $proxy->clientflags("-psk $psk -psk_identity other_id $flags"); + $proxy->serverflags("-psk $psk $flags"); + $proxy->filter(undef); + $proxy->start(); + ok(TLSProxy::Message->success(), + "TLS 1.3 PSK identity mismatch falls back to certificate auth"); + + $proxy->clear(); + $proxy->clientflags("-psk $psk -psk_identity other_id $flags"); + $proxy->serverflags("-psk $psk $flags"); + $psk_ext_in_sh = 0; + $proxy->filter(\&check_psk_in_sh); + $proxy->start(); + ok(!$psk_ext_in_sh, + "No PSK in ServerHello when TLS 1.3 identity mismatches"); +} + +SKIP: { + skip "TLS 1.2 disabled", 2 if disabled("tls1_2"); + + # PSK-AES128-CBC-SHA is required here: TLSProxy's record layer only handles + # CBC correctly (it strips IV + padding + MAC as fixed offset bytes). + # GCM ciphers use a different wire layout and confuse the decryption stub, + # making close_notify detection fail even on a successful connection. + my $psk_cipher = "PSK-AES128-CBC-SHA:\@SECLEVEL=0"; + my $flags = "-tls1_2 -no_rx_cert_comp"; + + # psk_client_cb (client) / psk_server_cb (server). + $proxy->clear(); + $proxy->ciphers($psk_cipher); + $proxy->cipherc($psk_cipher); + $proxy->clientflags("-psk $psk $flags"); + $proxy->serverflags("-psk $psk $flags"); + $proxy->filter(undef); + $proxy->start(); + ok(TLSProxy::Message->success(), "TLS 1.2 PSK connection"); + + # psk_server_cb accepts regardless of identity and only logs a warning. + $proxy->clear(); + $proxy->ciphers($psk_cipher); + $proxy->cipherc($psk_cipher); + $proxy->clientflags("-psk $psk -psk_identity other_id $flags"); + $proxy->serverflags("-psk $psk $flags"); + $proxy->filter(undef); + $proxy->start(); + ok(TLSProxy::Message->success(), + "TLS 1.2 PSK identity mismatch succeeds with warning"); +} + +sub check_psk_in_ch +{ + my $proxy = shift; + + return if $proxy->flight != 0; + + foreach my $message (@{$proxy->message_list}) { + next unless $message->mt == TLSProxy::Message::MT_CLIENT_HELLO; + $psk_ext_in_ch = 1 + if defined ${$message->extension_data}{TLSProxy::Message::EXT_PSK}; + } +} + +sub check_psk_in_sh +{ + my $proxy = shift; + + return if $proxy->flight != 1; + + foreach my $message (@{$proxy->message_list}) { + next unless $message->mt == TLSProxy::Message::MT_SERVER_HELLO; + $psk_ext_in_sh = 1 + if defined ${$message->extension_data}{TLSProxy::Message::EXT_PSK}; + } +}