1#! /usr/bin/env perl
2# Copyright 2016-2021 The OpenSSL Project Authors. All Rights Reserved.
3#
4# Licensed under the OpenSSL license (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
8
9use strict;
10use OpenSSL::Test qw/:DEFAULT cmdstr srctop_file bldtop_dir/;
11use OpenSSL::Test::Utils;
12use TLSProxy::Proxy;
13
14my $test_name = "test_renegotiation";
15setup($test_name);
16
17plan skip_all => "TLSProxy isn't usable on $^O"
18    if $^O =~ /^(VMS)$/;
19
20plan skip_all => "$test_name needs the dynamic engine feature enabled"
21    if disabled("engine") || disabled("dynamic-engine");
22
23plan skip_all => "$test_name needs the sock feature enabled"
24    if disabled("sock");
25
26plan skip_all => "$test_name needs TLS <= 1.2 enabled"
27    if alldisabled(("ssl3", "tls1", "tls1_1", "tls1_2"));
28
29$ENV{OPENSSL_ia32cap} = '~0x200000200000000';
30my $proxy = TLSProxy::Proxy->new(
31    undef,
32    cmdstr(app(["openssl"]), display => 1),
33    srctop_file("apps", "server.pem"),
34    (!$ENV{HARNESS_ACTIVE} || $ENV{HARNESS_VERBOSE})
35);
36
37#Test 1: A basic renegotiation test
38$proxy->clientflags("-no_tls1_3");
39$proxy->reneg(1);
40$proxy->start() or plan skip_all => "Unable to start up Proxy for tests";
41plan tests => 4;
42ok(TLSProxy::Message->success(), "Basic renegotiation");
43
44#Test 2: Client does not send the Reneg SCSV. Reneg should fail
45$proxy->clear();
46$proxy->filter(\&reneg_filter);
47$proxy->clientflags("-no_tls1_3");
48$proxy->reneg(1);
49$proxy->start();
50ok(TLSProxy::Message->fail(), "No client SCSV");
51
52SKIP: {
53    skip "TLSv1.2 or TLSv1.1 disabled", 1
54        if disabled("tls1_2") || disabled("tls1_1");
55    #Test 3: Check that the ClientHello version remains the same in the reneg
56    #        handshake
57    $proxy->clear();
58    $proxy->filter(undef);
59    $proxy->clientflags("-no_tls1_3");
60    $proxy->serverflags("-no_tls1_3 -no_tls1_2");
61    $proxy->reneg(1);
62    $proxy->start();
63    my $chversion;
64    my $chmatch = 0;
65    foreach my $message (@{$proxy->message_list}) {
66        if ($message->mt == TLSProxy::Message::MT_CLIENT_HELLO) {
67            if (!defined $chversion) {
68                $chversion = $message->client_version;
69            } else {
70                if ($chversion == $message->client_version) {
71                    $chmatch = 1;
72                }
73            }
74        }
75    }
76    ok(TLSProxy::Message->success() && $chmatch,
77       "Check ClientHello version is the same");
78}
79
80SKIP: {
81    skip "TLSv1.2 disabled", 1
82        if disabled("tls1_2");
83
84    #Test 4: Test for CVE-2021-3449. client_sig_algs instead of sig_algs in
85    #        resumption ClientHello
86    $proxy->clear();
87    $proxy->filter(\&sigalgs_filter);
88    $proxy->clientflags("-tls1_2");
89    $proxy->reneg(1);
90    $proxy->start();
91    ok(TLSProxy::Message->fail(), "client_sig_algs instead of sig_algs");
92}
93
94sub reneg_filter
95{
96    my $proxy = shift;
97
98    # We're only interested in the initial ClientHello message
99    if ($proxy->flight != 0) {
100        return;
101    }
102
103    foreach my $message (@{$proxy->message_list}) {
104        if ($message->mt == TLSProxy::Message::MT_CLIENT_HELLO) {
105            #Remove any SCSV ciphersuites - just leave AES128-SHA (0x002f)
106            my @ciphersuite = (0x002f);
107            $message->ciphersuites(\@ciphersuite);
108            $message->ciphersuite_len(2);
109            $message->repack();
110        }
111    }
112}
113
114sub sigalgs_filter
115{
116    my $proxy = shift;
117    my $cnt = 0;
118
119    # We're only interested in the second ClientHello message
120    foreach my $message (@{$proxy->message_list}) {
121        if ($message->mt == TLSProxy::Message::MT_CLIENT_HELLO) {
122            next if ($cnt++ == 0);
123
124            my $sigs = pack "C10", 0x00, 0x08,
125                            # rsa_pkcs_sha{256,384,512,1}
126                            0x04, 0x01,  0x05, 0x01,  0x06, 0x01,  0x02, 0x01;
127            $message->set_extension(TLSProxy::Message::EXT_SIG_ALGS_CERT, $sigs);
128            $message->delete_extension(TLSProxy::Message::EXT_SIG_ALGS);
129            $message->repack();
130        }
131    }
132}
133