2 # Copyright 2024 The OpenSSL Project Authors. All Rights Reserved.
4 # Licensed under the Apache License 2.0 (the "License"). You may not use
5 # this file except in compliance with the License. You can obtain a copy
6 # in the file LICENSE in the source distribution or at
7 # https://www.openssl.org/source/license.html
12 use OpenSSL::Test qw/:DEFAULT cmdstr srctop_file bldtop_dir/;
13 use OpenSSL::Test::Utils;
15 use TLSProxy::Message;
17 my $test_name = "test_dtlsrecords";
20 plan skip_all => "TLSProxy isn't usable on $^O"
21 if $^O =~ /^(VMS|MSWin32)$/;
23 plan skip_all => "$test_name needs the dynamic engine feature enabled"
24 if disabled("engine") || disabled("dynamic-engine");
26 plan skip_all => "$test_name needs the sock feature enabled"
29 plan skip_all => "$test_name needs DTLSv1.2 enabled"
30 if disabled("dtls1_2");
32 my $proxy = TLSProxy::Proxy->new_dtls(
34 cmdstr(app(["openssl"]), display => 1),
35 srctop_file("apps", "server.pem"),
36 (!$ENV{HARNESS_ACTIVE} || $ENV{HARNESS_VERBOSE})
41 my $fatal_alert = 0; # set by filters at expected fatal alerts
42 my $inject_recs_num = 0; # used by add_empty_recs_filter
43 my $proxy_start_success = 0;
45 #Test 1: Injecting out of context empty records should succeed
46 my $content_type = TLSProxy::Record::RT_APPLICATION_DATA;
48 $proxy->serverflags("-min_protocol DTLSv1.2 -max_protocol DTLSv1.2");
49 $proxy->clientflags("-max_protocol DTLSv1.2");
50 $proxy->filter(\&add_empty_recs_filter);
51 $proxy_start_success = $proxy->start();
52 ok($proxy_start_success && TLSProxy::Message->success(), "Out of context empty records test");
54 #Test 2: Injecting in context empty records should succeed
56 $content_type = TLSProxy::Record::RT_HANDSHAKE;
58 $proxy->serverflags("-min_protocol DTLSv1.2 -max_protocol DTLSv1.2");
59 $proxy->clientflags("-max_protocol DTLSv1.2");
60 $proxy->filter(\&add_empty_recs_filter);
61 $proxy_start_success = $proxy->start();
62 ok($proxy_start_success && TLSProxy::Message->success(), "In context empty records test");
64 #Unrecognised record type tests
66 #Test 3: Sending an unrecognised record type in DTLSv1.2 should fail
69 $proxy->serverflags("-min_protocol DTLSv1.2 -max_protocol DTLSv1.2");
70 $proxy->clientflags("-max_protocol DTLSv1.2");
71 $proxy->filter(\&add_unknown_record_type);
72 ok($proxy->start() == 0, "Unrecognised record type in DTLS1.2");
75 skip "DTLSv1 disabled", 1 if disabled("dtls1");
77 #Test 4: Sending an unrecognised record type in DTLSv1 should fail
80 $proxy->clientflags("-min_protocol DTLSv1 -max_protocol DTLSv1 -cipher DEFAULT:\@SECLEVEL=0");
81 $proxy->ciphers("AES128-SHA:\@SECLEVEL=0");
82 $proxy->filter(\&add_unknown_record_type);
83 ok($proxy->start() == 0, "Unrecognised record type in DTLSv1");
86 sub add_empty_recs_filter
89 my $records = $proxy->record_list;
91 # We're only interested in the initial ClientHello
92 if ($proxy->flight != 0) {
93 $fatal_alert = 1 if @{$records}[-1]->is_fatal_alert(1) == TLSProxy::Message::AL_DESC_UNEXPECTED_MESSAGE;
97 for (my $i = 0; $i < $inject_recs_num; $i++) {
98 my $record = TLSProxy::Record->new_dtls(
101 TLSProxy::Record::VERS_TLS_1_2,
111 push @{$records}, $record;
115 sub add_unknown_record_type
118 my $records = $proxy->record_list;
121 # We'll change a record after the initial version neg has taken place
122 if ($proxy->flight == 0) {
125 } elsif ($proxy->flight != 1 || $added_record) {
126 $fatal_alert = 1 if @{$records}[-1]->is_fatal_alert(0) == TLSProxy::Message::AL_DESC_UNEXPECTED_MESSAGE;
130 my $record = TLSProxy::Record->new_dtls(
132 TLSProxy::Record::RT_UNKNOWN,
133 @{$records}[-1]->version(),
134 @{$records}[-1]->epoch(),
135 @{$records}[-1]->seq() +1,
144 #Find ServerHello record and insert after that
146 for ($i = 0; ${$proxy->record_list}[$i]->flight() < 1; $i++) {
151 splice @{$proxy->record_list}, $i, 0, $record;