1e1051a39Sopenharmony_ci#! /usr/bin/env perl
2e1051a39Sopenharmony_ci# Copyright 2015-2021 The OpenSSL Project Authors. All Rights Reserved.
3e1051a39Sopenharmony_ci#
4e1051a39Sopenharmony_ci# Licensed under the Apache License 2.0 (the "License").  You may not use
5e1051a39Sopenharmony_ci# this file except in compliance with the License.  You can obtain a copy
6e1051a39Sopenharmony_ci# in the file LICENSE in the source distribution or at
7e1051a39Sopenharmony_ci# https://www.openssl.org/source/license.html
8e1051a39Sopenharmony_ci
9e1051a39Sopenharmony_ciuse strict;
10e1051a39Sopenharmony_ciuse OpenSSL::Test qw/:DEFAULT cmdstr srctop_file bldtop_dir/;
11e1051a39Sopenharmony_ciuse OpenSSL::Test::Utils;
12e1051a39Sopenharmony_ciuse TLSProxy::Proxy;
13e1051a39Sopenharmony_ciuse File::Temp qw(tempfile);
14e1051a39Sopenharmony_ci
15e1051a39Sopenharmony_cimy $test_name = "test_tlsextms";
16e1051a39Sopenharmony_cisetup($test_name);
17e1051a39Sopenharmony_ci
18e1051a39Sopenharmony_ciplan skip_all => "TLSProxy isn't usable on $^O"
19e1051a39Sopenharmony_ci    if $^O =~ /^(VMS)$/;
20e1051a39Sopenharmony_ci
21e1051a39Sopenharmony_ciplan skip_all => "$test_name needs the dynamic engine feature enabled"
22e1051a39Sopenharmony_ci    if disabled("engine") || disabled("dynamic-engine");
23e1051a39Sopenharmony_ci
24e1051a39Sopenharmony_ciplan skip_all => "$test_name needs the sock feature enabled"
25e1051a39Sopenharmony_ci    if disabled("sock");
26e1051a39Sopenharmony_ci
27e1051a39Sopenharmony_ciplan skip_all => "$test_name needs TLSv1.0, TLSv1.1 or TLSv1.2 enabled"
28e1051a39Sopenharmony_ci    if disabled("tls1") && disabled("tls1_1") && disabled("tls1_2");
29e1051a39Sopenharmony_ci
30e1051a39Sopenharmony_ci$ENV{OPENSSL_ia32cap} = '~0x200000200000000';
31e1051a39Sopenharmony_ci
32e1051a39Sopenharmony_cisub checkmessages($$$$$);
33e1051a39Sopenharmony_cisub setrmextms($$);
34e1051a39Sopenharmony_cisub clearall();
35e1051a39Sopenharmony_ci
36e1051a39Sopenharmony_cimy $crmextms = 0;
37e1051a39Sopenharmony_cimy $srmextms = 0;
38e1051a39Sopenharmony_cimy $cextms = 0;
39e1051a39Sopenharmony_cimy $sextms = 0;
40e1051a39Sopenharmony_cimy $fullhand = 0;
41e1051a39Sopenharmony_ci
42e1051a39Sopenharmony_cimy $proxy = TLSProxy::Proxy->new(
43e1051a39Sopenharmony_ci    \&extms_filter,
44e1051a39Sopenharmony_ci    cmdstr(app(["openssl"]), display => 1),
45e1051a39Sopenharmony_ci    srctop_file("apps", "server.pem"),
46e1051a39Sopenharmony_ci    (!$ENV{HARNESS_ACTIVE} || $ENV{HARNESS_VERBOSE})
47e1051a39Sopenharmony_ci);
48e1051a39Sopenharmony_ci
49e1051a39Sopenharmony_ci#Note that EXTMS is only relevant for <TLS1.3
50e1051a39Sopenharmony_ci
51e1051a39Sopenharmony_ci#Test 1: By default server and client should send extended master secret
52e1051a39Sopenharmony_ci# extension.
53e1051a39Sopenharmony_ci#Expected result: ClientHello extension seen; ServerHello extension seen
54e1051a39Sopenharmony_ci#                 Full handshake
55e1051a39Sopenharmony_ci
56e1051a39Sopenharmony_cisetrmextms(0, 0);
57e1051a39Sopenharmony_ci$proxy->clientflags("-no_tls1_3");
58e1051a39Sopenharmony_ci$proxy->start() or plan skip_all => "Unable to start up Proxy for tests";
59e1051a39Sopenharmony_ciplan tests => 10;
60e1051a39Sopenharmony_cicheckmessages(1, "Default extended master secret test", 1, 1, 1);
61e1051a39Sopenharmony_ci
62e1051a39Sopenharmony_ci#Test 2: If client omits extended master secret extension, server should too.
63e1051a39Sopenharmony_ci#Expected result: ClientHello extension not seen; ServerHello extension not seen
64e1051a39Sopenharmony_ci#                 Full handshake
65e1051a39Sopenharmony_ci
66e1051a39Sopenharmony_ciclearall();
67e1051a39Sopenharmony_cisetrmextms(1, 0);
68e1051a39Sopenharmony_ci$proxy->clientflags("-no_tls1_3");
69e1051a39Sopenharmony_ci$proxy->start();
70e1051a39Sopenharmony_cicheckmessages(2, "No client extension extended master secret test", 0, 0, 1);
71e1051a39Sopenharmony_ci
72e1051a39Sopenharmony_ci# Test 3: same as 1 but with session tickets disabled.
73e1051a39Sopenharmony_ci# Expected result: same as test 1.
74e1051a39Sopenharmony_ci
75e1051a39Sopenharmony_ciclearall();
76e1051a39Sopenharmony_ci$proxy->clientflags("-no_ticket -no_tls1_3");
77e1051a39Sopenharmony_cisetrmextms(0, 0);
78e1051a39Sopenharmony_ci$proxy->start();
79e1051a39Sopenharmony_cicheckmessages(3, "No ticket extended master secret test", 1, 1, 1);
80e1051a39Sopenharmony_ci
81e1051a39Sopenharmony_ci# Test 4: same as 2 but with session tickets disabled.
82e1051a39Sopenharmony_ci# Expected result: same as test 2.
83e1051a39Sopenharmony_ci
84e1051a39Sopenharmony_ciclearall();
85e1051a39Sopenharmony_ci$proxy->clientflags("-no_ticket -no_tls1_3");
86e1051a39Sopenharmony_cisetrmextms(1, 0);
87e1051a39Sopenharmony_ci$proxy->start();
88e1051a39Sopenharmony_cicheckmessages(4, "No ticket, no client extension extended master secret test", 0, 0, 1);
89e1051a39Sopenharmony_ci
90e1051a39Sopenharmony_ci#Test 5: Session resumption extended master secret test
91e1051a39Sopenharmony_ci#
92e1051a39Sopenharmony_ci#Expected result: ClientHello extension seen; ServerHello extension seen
93e1051a39Sopenharmony_ci#                 Abbreviated handshake
94e1051a39Sopenharmony_ci
95e1051a39Sopenharmony_ciclearall();
96e1051a39Sopenharmony_cisetrmextms(0, 0);
97e1051a39Sopenharmony_ci(undef, my $session) = tempfile();
98e1051a39Sopenharmony_ci$proxy->serverconnects(2);
99e1051a39Sopenharmony_ci$proxy->clientflags("-no_tls1_3 -sess_out ".$session);
100e1051a39Sopenharmony_ci$proxy->start();
101e1051a39Sopenharmony_ci$proxy->clearClient();
102e1051a39Sopenharmony_ci$proxy->clientflags("-no_tls1_3 -sess_in ".$session);
103e1051a39Sopenharmony_ci$proxy->clientstart();
104e1051a39Sopenharmony_cicheckmessages(5, "Session resumption extended master secret test", 1, 1, 0);
105e1051a39Sopenharmony_ciunlink $session;
106e1051a39Sopenharmony_ci
107e1051a39Sopenharmony_ci#Test 6: Session resumption extended master secret test original session
108e1051a39Sopenharmony_ci# omits extension. Server must not resume session.
109e1051a39Sopenharmony_ci#Expected result: ClientHello extension seen; ServerHello extension seen
110e1051a39Sopenharmony_ci#                 Full handshake
111e1051a39Sopenharmony_ci
112e1051a39Sopenharmony_ciclearall();
113e1051a39Sopenharmony_cisetrmextms(1, 0);
114e1051a39Sopenharmony_ci(undef, $session) = tempfile();
115e1051a39Sopenharmony_ci$proxy->serverconnects(2);
116e1051a39Sopenharmony_ci$proxy->clientflags("-no_tls1_3 -sess_out ".$session);
117e1051a39Sopenharmony_ci$proxy->start();
118e1051a39Sopenharmony_ci$proxy->clearClient();
119e1051a39Sopenharmony_ci$proxy->clientflags("-no_tls1_3 -sess_in ".$session);
120e1051a39Sopenharmony_cisetrmextms(0, 0);
121e1051a39Sopenharmony_ci$proxy->clientstart();
122e1051a39Sopenharmony_cicheckmessages(6, "Session resumption extended master secret test", 1, 1, 1);
123e1051a39Sopenharmony_ciunlink $session;
124e1051a39Sopenharmony_ci
125e1051a39Sopenharmony_ci#Test 7: Session resumption extended master secret test resumed session
126e1051a39Sopenharmony_ci# omits client extension. Server must abort connection.
127e1051a39Sopenharmony_ci#Expected result: aborted connection.
128e1051a39Sopenharmony_ci
129e1051a39Sopenharmony_ciclearall();
130e1051a39Sopenharmony_cisetrmextms(0, 0);
131e1051a39Sopenharmony_ci(undef, $session) = tempfile();
132e1051a39Sopenharmony_ci$proxy->serverconnects(2);
133e1051a39Sopenharmony_ci$proxy->clientflags("-no_tls1_3 -sess_out ".$session);
134e1051a39Sopenharmony_ci$proxy->start();
135e1051a39Sopenharmony_ci$proxy->clearClient();
136e1051a39Sopenharmony_ci$proxy->clientflags("-no_tls1_3 -sess_in ".$session);
137e1051a39Sopenharmony_cisetrmextms(1, 0);
138e1051a39Sopenharmony_ci$proxy->clientstart();
139e1051a39Sopenharmony_ciok(TLSProxy::Message->fail(), "Client inconsistent session resumption");
140e1051a39Sopenharmony_ciunlink $session;
141e1051a39Sopenharmony_ci
142e1051a39Sopenharmony_ci#Test 8: Session resumption extended master secret test resumed session
143e1051a39Sopenharmony_ci# omits server extension. Client must abort connection.
144e1051a39Sopenharmony_ci#Expected result: aborted connection.
145e1051a39Sopenharmony_ci
146e1051a39Sopenharmony_ciclearall();
147e1051a39Sopenharmony_cisetrmextms(0, 0);
148e1051a39Sopenharmony_ci(undef, $session) = tempfile();
149e1051a39Sopenharmony_ci$proxy->serverconnects(2);
150e1051a39Sopenharmony_ci$proxy->clientflags("-no_tls1_3 -sess_out ".$session);
151e1051a39Sopenharmony_ci$proxy->start();
152e1051a39Sopenharmony_ci$proxy->clearClient();
153e1051a39Sopenharmony_ci$proxy->clientflags("-no_tls1_3 -sess_in ".$session);
154e1051a39Sopenharmony_cisetrmextms(0, 1);
155e1051a39Sopenharmony_ci$proxy->clientstart();
156e1051a39Sopenharmony_ciok(TLSProxy::Message->fail(), "Server inconsistent session resumption 1");
157e1051a39Sopenharmony_ciunlink $session;
158e1051a39Sopenharmony_ci
159e1051a39Sopenharmony_ci#Test 9: Session resumption extended master secret test initial session
160e1051a39Sopenharmony_ci# omits server extension. Client must abort connection.
161e1051a39Sopenharmony_ci#Expected result: aborted connection.
162e1051a39Sopenharmony_ci
163e1051a39Sopenharmony_ciclearall();
164e1051a39Sopenharmony_cisetrmextms(0, 1);
165e1051a39Sopenharmony_ci(undef, $session) = tempfile();
166e1051a39Sopenharmony_ci$proxy->serverconnects(2);
167e1051a39Sopenharmony_ci$proxy->clientflags("-no_tls1_3 -sess_out ".$session);
168e1051a39Sopenharmony_ci$proxy->start();
169e1051a39Sopenharmony_ci$proxy->clearClient();
170e1051a39Sopenharmony_ci$proxy->clientflags("-no_tls1_3 -sess_in ".$session);
171e1051a39Sopenharmony_cisetrmextms(0, 0);
172e1051a39Sopenharmony_ci$proxy->clientstart();
173e1051a39Sopenharmony_ciok(TLSProxy::Message->fail(), "Server inconsistent session resumption 2");
174e1051a39Sopenharmony_ciunlink $session;
175e1051a39Sopenharmony_ci
176e1051a39Sopenharmony_ciSKIP: {
177e1051a39Sopenharmony_ci    skip "TLS 1.3 disabled", 1
178e1051a39Sopenharmony_ci        if disabled("tls1_3") || (disabled("ec") && disabled("dh"));
179e1051a39Sopenharmony_ci
180e1051a39Sopenharmony_ci    #Test 10: In TLS1.3 we should not negotiate extended master secret
181e1051a39Sopenharmony_ci    #Expected result: ClientHello extension seen; ServerHello extension not seen
182e1051a39Sopenharmony_ci    #                 TLS1.3 handshake (will appear as abbreviated handshake
183e1051a39Sopenharmony_ci    #                 because of no CKE message)
184e1051a39Sopenharmony_ci    clearall();
185e1051a39Sopenharmony_ci    setrmextms(0, 0);
186e1051a39Sopenharmony_ci    $proxy->start();
187e1051a39Sopenharmony_ci    checkmessages(10, "TLS1.3 extended master secret test", 1, 0, 0);
188e1051a39Sopenharmony_ci}
189e1051a39Sopenharmony_ci
190e1051a39Sopenharmony_ci
191e1051a39Sopenharmony_cisub extms_filter
192e1051a39Sopenharmony_ci{
193e1051a39Sopenharmony_ci    my $proxy = shift;
194e1051a39Sopenharmony_ci
195e1051a39Sopenharmony_ci    foreach my $message (@{$proxy->message_list}) {
196e1051a39Sopenharmony_ci        if ($crmextms && $message->mt == TLSProxy::Message::MT_CLIENT_HELLO) {
197e1051a39Sopenharmony_ci            $message->delete_extension(TLSProxy::Message::EXT_EXTENDED_MASTER_SECRET);
198e1051a39Sopenharmony_ci            $message->repack();
199e1051a39Sopenharmony_ci        }
200e1051a39Sopenharmony_ci        if ($srmextms && $message->mt == TLSProxy::Message::MT_SERVER_HELLO) {
201e1051a39Sopenharmony_ci            $message->delete_extension(TLSProxy::Message::EXT_EXTENDED_MASTER_SECRET);
202e1051a39Sopenharmony_ci            $message->repack();
203e1051a39Sopenharmony_ci        }
204e1051a39Sopenharmony_ci    }
205e1051a39Sopenharmony_ci}
206e1051a39Sopenharmony_ci
207e1051a39Sopenharmony_cisub checkmessages($$$$$)
208e1051a39Sopenharmony_ci{
209e1051a39Sopenharmony_ci    my ($testno, $testname, $testcextms, $testsextms, $testhand) = @_;
210e1051a39Sopenharmony_ci
211e1051a39Sopenharmony_ci    subtest $testname => sub {
212e1051a39Sopenharmony_ci
213e1051a39Sopenharmony_ci    foreach my $message (@{$proxy->message_list}) {
214e1051a39Sopenharmony_ci        if ($message->mt == TLSProxy::Message::MT_CLIENT_HELLO
215e1051a39Sopenharmony_ci            || $message->mt == TLSProxy::Message::MT_SERVER_HELLO) {
216e1051a39Sopenharmony_ci        #Get the extensions data
217e1051a39Sopenharmony_ci        my %extensions = %{$message->extension_data};
218e1051a39Sopenharmony_ci        if (defined
219e1051a39Sopenharmony_ci            $extensions{TLSProxy::Message::EXT_EXTENDED_MASTER_SECRET}) {
220e1051a39Sopenharmony_ci            if ($message->mt == TLSProxy::Message::MT_CLIENT_HELLO) {
221e1051a39Sopenharmony_ci                $cextms = 1;
222e1051a39Sopenharmony_ci            } else {
223e1051a39Sopenharmony_ci                $sextms = 1;
224e1051a39Sopenharmony_ci            }
225e1051a39Sopenharmony_ci        }
226e1051a39Sopenharmony_ci        } elsif ($message->mt == TLSProxy::Message::MT_CLIENT_KEY_EXCHANGE) {
227e1051a39Sopenharmony_ci            #Must be doing a full handshake
228e1051a39Sopenharmony_ci            $fullhand = 1;
229e1051a39Sopenharmony_ci        }
230e1051a39Sopenharmony_ci    }
231e1051a39Sopenharmony_ci
232e1051a39Sopenharmony_ci    plan tests => 4;
233e1051a39Sopenharmony_ci
234e1051a39Sopenharmony_ci    ok(TLSProxy::Message->success, "Handshake");
235e1051a39Sopenharmony_ci
236e1051a39Sopenharmony_ci    ok($testcextms == $cextms,
237e1051a39Sopenharmony_ci       "ClientHello extension extended master secret check");
238e1051a39Sopenharmony_ci    ok($testsextms == $sextms,
239e1051a39Sopenharmony_ci       "ServerHello extension extended master secret check");
240e1051a39Sopenharmony_ci    ok($testhand == $fullhand,
241e1051a39Sopenharmony_ci       "Extended master secret full handshake check");
242e1051a39Sopenharmony_ci
243e1051a39Sopenharmony_ci    }
244e1051a39Sopenharmony_ci}
245e1051a39Sopenharmony_ci
246e1051a39Sopenharmony_cisub setrmextms($$)
247e1051a39Sopenharmony_ci{
248e1051a39Sopenharmony_ci    ($crmextms, $srmextms) = @_;
249e1051a39Sopenharmony_ci}
250e1051a39Sopenharmony_ci
251e1051a39Sopenharmony_cisub clearall()
252e1051a39Sopenharmony_ci{
253e1051a39Sopenharmony_ci    $cextms = 0;
254e1051a39Sopenharmony_ci    $sextms = 0;
255e1051a39Sopenharmony_ci    $fullhand = 0;
256e1051a39Sopenharmony_ci    $proxy->clear();
257e1051a39Sopenharmony_ci}
258