Home | History | Annotate | Line # | Download | only in recipes
      1  1.1  christos #! /usr/bin/env perl
      2  1.1  christos # Copyright 2017-2024 The OpenSSL Project Authors. All Rights Reserved.
      3  1.1  christos #
      4  1.1  christos # Licensed under the Apache License 2.0 (the "License").  You may not use
      5  1.1  christos # this file except in compliance with the License.  You can obtain a copy
      6  1.1  christos # in the file LICENSE in the source distribution or at
      7  1.1  christos # https://www.openssl.org/source/license.html
      8  1.1  christos 
      9  1.1  christos use strict;
     10  1.1  christos use OpenSSL::Test qw/:DEFAULT cmdstr srctop_file srctop_dir bldtop_dir/;
     11  1.1  christos use OpenSSL::Test::Utils;
     12  1.1  christos use File::Temp qw(tempfile);
     13  1.1  christos use TLSProxy::Proxy;
     14  1.1  christos use checkhandshake qw(checkhandshake @handmessages @extensions);
     15  1.1  christos 
     16  1.1  christos my $test_name = "test_tls13kexmodes";
     17  1.1  christos setup($test_name);
     18  1.1  christos 
     19  1.1  christos plan skip_all => "TLSProxy isn't usable on $^O"
     20  1.1  christos     if $^O =~ /^(VMS)$/;
     21  1.1  christos 
     22  1.1  christos plan skip_all => "$test_name needs the dynamic engine feature enabled"
     23  1.1  christos     if disabled("engine") || disabled("dynamic-engine");
     24  1.1  christos 
     25  1.1  christos plan skip_all => "$test_name needs the sock feature enabled"
     26  1.1  christos     if disabled("sock");
     27  1.1  christos 
     28  1.1  christos plan skip_all => "$test_name needs TLSv1.3 enabled"
     29  1.1  christos     if disabled("tls1_3") || (disabled("ec") && disabled("dh"));
     30  1.1  christos 
     31  1.1  christos plan skip_all => "$test_name needs EC enabled"
     32  1.1  christos     if disabled("ec");
     33  1.1  christos 
     34  1.1  christos @handmessages = (
     35  1.1  christos     [TLSProxy::Message::MT_CLIENT_HELLO,
     36  1.1  christos         checkhandshake::ALL_HANDSHAKES],
     37  1.1  christos     [TLSProxy::Message::MT_SERVER_HELLO,
     38  1.1  christos         checkhandshake::HRR_HANDSHAKE | checkhandshake::HRR_RESUME_HANDSHAKE],
     39  1.1  christos     [TLSProxy::Message::MT_CLIENT_HELLO,
     40  1.1  christos         checkhandshake::HRR_HANDSHAKE | checkhandshake::HRR_RESUME_HANDSHAKE],
     41  1.1  christos     [TLSProxy::Message::MT_SERVER_HELLO,
     42  1.1  christos         checkhandshake::ALL_HANDSHAKES],
     43  1.1  christos     [TLSProxy::Message::MT_ENCRYPTED_EXTENSIONS,
     44  1.1  christos         checkhandshake::ALL_HANDSHAKES],
     45  1.1  christos     [TLSProxy::Message::MT_CERTIFICATE_REQUEST,
     46  1.1  christos         checkhandshake::CLIENT_AUTH_HANDSHAKE],
     47  1.1  christos     [TLSProxy::Message::MT_CERTIFICATE,
     48  1.1  christos         checkhandshake::ALL_HANDSHAKES & ~(checkhandshake::RESUME_HANDSHAKE | checkhandshake::HRR_RESUME_HANDSHAKE)],
     49  1.1  christos     [TLSProxy::Message::MT_CERTIFICATE_VERIFY,
     50  1.1  christos         checkhandshake::ALL_HANDSHAKES & ~(checkhandshake::RESUME_HANDSHAKE | checkhandshake::HRR_RESUME_HANDSHAKE)],
     51  1.1  christos     [TLSProxy::Message::MT_FINISHED,
     52  1.1  christos         checkhandshake::ALL_HANDSHAKES],
     53  1.1  christos     [TLSProxy::Message::MT_CERTIFICATE,
     54  1.1  christos         checkhandshake::CLIENT_AUTH_HANDSHAKE],
     55  1.1  christos     [TLSProxy::Message::MT_CERTIFICATE_VERIFY,
     56  1.1  christos         checkhandshake::CLIENT_AUTH_HANDSHAKE],
     57  1.1  christos     [TLSProxy::Message::MT_FINISHED,
     58  1.1  christos         checkhandshake::ALL_HANDSHAKES],
     59  1.1  christos     [0, 0]
     60  1.1  christos );
     61  1.1  christos 
     62  1.1  christos @extensions = (
     63  1.1  christos     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SERVER_NAME,
     64  1.1  christos         TLSProxy::Message::CLIENT,
     65  1.1  christos         checkhandshake::SERVER_NAME_CLI_EXTENSION],
     66  1.1  christos     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_STATUS_REQUEST,
     67  1.1  christos         TLSProxy::Message::CLIENT,
     68  1.1  christos         checkhandshake::STATUS_REQUEST_CLI_EXTENSION],
     69  1.1  christos     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SUPPORTED_GROUPS,
     70  1.1  christos         TLSProxy::Message::CLIENT,
     71  1.1  christos         checkhandshake::DEFAULT_EXTENSIONS],
     72  1.1  christos     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_EC_POINT_FORMATS,
     73  1.1  christos         TLSProxy::Message::CLIENT,
     74  1.1  christos         checkhandshake::DEFAULT_EXTENSIONS],
     75  1.1  christos     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SIG_ALGS,
     76  1.1  christos         TLSProxy::Message::CLIENT,
     77  1.1  christos         checkhandshake::DEFAULT_EXTENSIONS],
     78  1.1  christos     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_ALPN,
     79  1.1  christos         TLSProxy::Message::CLIENT,
     80  1.1  christos         checkhandshake::ALPN_CLI_EXTENSION],
     81  1.1  christos     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SCT,
     82  1.1  christos         TLSProxy::Message::CLIENT,
     83  1.1  christos         checkhandshake::SCT_CLI_EXTENSION],
     84  1.1  christos     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_ENCRYPT_THEN_MAC,
     85  1.1  christos         TLSProxy::Message::CLIENT,
     86  1.1  christos         checkhandshake::DEFAULT_EXTENSIONS],
     87  1.1  christos     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_EXTENDED_MASTER_SECRET,
     88  1.1  christos         TLSProxy::Message::CLIENT,
     89  1.1  christos         checkhandshake::DEFAULT_EXTENSIONS],
     90  1.1  christos     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SESSION_TICKET,
     91  1.1  christos         TLSProxy::Message::CLIENT,
     92  1.1  christos         checkhandshake::DEFAULT_EXTENSIONS],
     93  1.1  christos     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_KEY_SHARE,
     94  1.1  christos         TLSProxy::Message::CLIENT,
     95  1.1  christos         checkhandshake::DEFAULT_EXTENSIONS],
     96  1.1  christos     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SUPPORTED_VERSIONS,
     97  1.1  christos         TLSProxy::Message::CLIENT,
     98  1.1  christos         checkhandshake::DEFAULT_EXTENSIONS],
     99  1.1  christos     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_PSK_KEX_MODES,
    100  1.1  christos         TLSProxy::Message::CLIENT,
    101  1.1  christos         checkhandshake::PSK_KEX_MODES_EXTENSION],
    102  1.1  christos     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_PSK,
    103  1.1  christos         TLSProxy::Message::CLIENT,
    104  1.1  christos         checkhandshake::PSK_CLI_EXTENSION],
    105  1.1  christos     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_RENEGOTIATE,
    106  1.1  christos         TLSProxy::Message::CLIENT,
    107  1.1  christos         checkhandshake::DEFAULT_EXTENSIONS],
    108  1.1  christos 
    109  1.1  christos     [TLSProxy::Message::MT_SERVER_HELLO, TLSProxy::Message::EXT_SUPPORTED_VERSIONS,
    110  1.1  christos         TLSProxy::Message::SERVER,
    111  1.1  christos         checkhandshake::DEFAULT_EXTENSIONS],
    112  1.1  christos     [TLSProxy::Message::MT_SERVER_HELLO, TLSProxy::Message::EXT_KEY_SHARE,
    113  1.1  christos         TLSProxy::Message::SERVER,
    114  1.1  christos         checkhandshake::KEY_SHARE_HRR_EXTENSION],
    115  1.1  christos 
    116  1.1  christos     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SERVER_NAME,
    117  1.1  christos         TLSProxy::Message::CLIENT,
    118  1.1  christos         checkhandshake::SERVER_NAME_CLI_EXTENSION],
    119  1.1  christos     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_STATUS_REQUEST,
    120  1.1  christos         TLSProxy::Message::CLIENT,
    121  1.1  christos         checkhandshake::STATUS_REQUEST_CLI_EXTENSION],
    122  1.1  christos     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SUPPORTED_GROUPS,
    123  1.1  christos         TLSProxy::Message::CLIENT,
    124  1.1  christos         checkhandshake::DEFAULT_EXTENSIONS],
    125  1.1  christos     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_EC_POINT_FORMATS,
    126  1.1  christos         TLSProxy::Message::CLIENT,
    127  1.1  christos         checkhandshake::DEFAULT_EXTENSIONS],
    128  1.1  christos     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SIG_ALGS,
    129  1.1  christos         TLSProxy::Message::CLIENT,
    130  1.1  christos         checkhandshake::DEFAULT_EXTENSIONS],
    131  1.1  christos     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_ALPN,
    132  1.1  christos         TLSProxy::Message::CLIENT,
    133  1.1  christos         checkhandshake::ALPN_CLI_EXTENSION],
    134  1.1  christos     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SCT,
    135  1.1  christos         TLSProxy::Message::CLIENT,
    136  1.1  christos         checkhandshake::SCT_CLI_EXTENSION],
    137  1.1  christos     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_ENCRYPT_THEN_MAC,
    138  1.1  christos         TLSProxy::Message::CLIENT,
    139  1.1  christos         checkhandshake::DEFAULT_EXTENSIONS],
    140  1.1  christos     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_EXTENDED_MASTER_SECRET,
    141  1.1  christos         TLSProxy::Message::CLIENT,
    142  1.1  christos         checkhandshake::DEFAULT_EXTENSIONS],
    143  1.1  christos     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SESSION_TICKET,
    144  1.1  christos         TLSProxy::Message::CLIENT,
    145  1.1  christos         checkhandshake::DEFAULT_EXTENSIONS],
    146  1.1  christos     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_KEY_SHARE,
    147  1.1  christos         TLSProxy::Message::CLIENT,
    148  1.1  christos         checkhandshake::DEFAULT_EXTENSIONS],
    149  1.1  christos     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SUPPORTED_VERSIONS,
    150  1.1  christos         TLSProxy::Message::CLIENT,
    151  1.1  christos         checkhandshake::DEFAULT_EXTENSIONS],
    152  1.1  christos     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_PSK_KEX_MODES,
    153  1.1  christos         TLSProxy::Message::CLIENT,
    154  1.1  christos         checkhandshake::PSK_KEX_MODES_EXTENSION],
    155  1.1  christos     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_PSK,
    156  1.1  christos         TLSProxy::Message::CLIENT,
    157  1.1  christos         checkhandshake::PSK_CLI_EXTENSION],
    158  1.1  christos     [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_RENEGOTIATE,
    159  1.1  christos         TLSProxy::Message::CLIENT,
    160  1.1  christos         checkhandshake::DEFAULT_EXTENSIONS],
    161  1.1  christos 
    162  1.1  christos     [TLSProxy::Message::MT_SERVER_HELLO, TLSProxy::Message::EXT_SUPPORTED_VERSIONS,
    163  1.1  christos         TLSProxy::Message::SERVER,
    164  1.1  christos         checkhandshake::DEFAULT_EXTENSIONS],
    165  1.1  christos     [TLSProxy::Message::MT_SERVER_HELLO, TLSProxy::Message::EXT_KEY_SHARE,
    166  1.1  christos         TLSProxy::Message::SERVER,
    167  1.1  christos         checkhandshake::KEY_SHARE_SRV_EXTENSION],
    168  1.1  christos     [TLSProxy::Message::MT_SERVER_HELLO, TLSProxy::Message::EXT_PSK,
    169  1.1  christos         TLSProxy::Message::SERVER,
    170  1.1  christos         checkhandshake::PSK_SRV_EXTENSION],
    171  1.1  christos 
    172  1.1  christos     [TLSProxy::Message::MT_CERTIFICATE, TLSProxy::Message::EXT_STATUS_REQUEST,
    173  1.1  christos         TLSProxy::Message::SERVER,
    174  1.1  christos         checkhandshake::STATUS_REQUEST_SRV_EXTENSION],
    175  1.1  christos     [0,0,0,0]
    176  1.1  christos );
    177  1.1  christos 
    178  1.1  christos use constant {
    179  1.1  christos     DELETE_EXTENSION => 0,
    180  1.1  christos     EMPTY_EXTENSION => 1,
    181  1.1  christos     NON_DHE_KEX_MODE_ONLY => 2,
    182  1.1  christos     DHE_KEX_MODE_ONLY => 3,
    183  1.1  christos     UNKNOWN_KEX_MODES => 4,
    184  1.1  christos     BOTH_KEX_MODES => 5
    185  1.1  christos };
    186  1.1  christos 
    187  1.1  christos my $proxy = TLSProxy::Proxy->new(
    188  1.1  christos     undef,
    189  1.1  christos     cmdstr(app(["openssl"]), display => 1),
    190  1.1  christos     srctop_file("apps", "server.pem"),
    191  1.1  christos     (!$ENV{HARNESS_ACTIVE} || $ENV{HARNESS_VERBOSE})
    192  1.1  christos );
    193  1.1  christos 
    194  1.1  christos #Test 1: First get a session
    195  1.1  christos (undef, my $session) = tempfile();
    196  1.1  christos $proxy->cipherc("DEFAULT:\@SECLEVEL=2");
    197  1.1  christos $proxy->clientflags("-no_rx_cert_comp -sess_out ".$session);
    198  1.1  christos $proxy->serverflags("-no_rx_cert_comp -servername localhost");
    199  1.1  christos $proxy->sessionfile($session);
    200  1.1  christos $proxy->start() or plan skip_all => "Unable to start up Proxy for tests";
    201  1.1  christos plan tests => 13;
    202  1.1  christos ok(TLSProxy::Message->success(), "Initial connection");
    203  1.1  christos 
    204  1.1  christos #Test 2: Attempt a resume with no kex modes extension. Should fail (server
    205  1.1  christos #        MUST abort handshake with pre_shared key and no psk_kex_modes)
    206  1.1  christos $proxy->clear();
    207  1.1  christos $proxy->cipherc("DEFAULT:\@SECLEVEL=2");
    208  1.1  christos $proxy->clientflags("-no_rx_cert_comp -sess_in ".$session);
    209  1.1  christos my $testtype = DELETE_EXTENSION;
    210  1.1  christos $proxy->filter(\&modify_kex_modes_filter);
    211  1.1  christos $proxy->start();
    212  1.1  christos ok(TLSProxy::Message->fail(), "Resume with no kex modes");
    213  1.1  christos 
    214  1.1  christos #Test 3: Attempt a resume with empty kex modes extension. Should fail (empty
    215  1.1  christos #        extension is invalid)
    216  1.1  christos $proxy->clear();
    217  1.1  christos $proxy->cipherc("DEFAULT:\@SECLEVEL=2");
    218  1.1  christos $proxy->clientflags("-no_rx_cert_comp -sess_in ".$session);
    219  1.1  christos $testtype = EMPTY_EXTENSION;
    220  1.1  christos $proxy->start();
    221  1.1  christos ok(TLSProxy::Message->fail(), "Resume with empty kex modes");
    222  1.1  christos 
    223  1.1  christos #Test 4: Attempt a resume with non-dhe kex mode only. Should resume without a
    224  1.1  christos #        key_share
    225  1.1  christos $proxy->clear();
    226  1.1  christos $proxy->cipherc("DEFAULT:\@SECLEVEL=2");
    227  1.1  christos $proxy->clientflags("-no_rx_cert_comp -allow_no_dhe_kex -sess_in ".$session);
    228  1.1  christos $proxy->serverflags("-no_rx_cert_comp -allow_no_dhe_kex");
    229  1.1  christos $testtype = NON_DHE_KEX_MODE_ONLY;
    230  1.1  christos $proxy->start();
    231  1.1  christos checkhandshake($proxy, checkhandshake::RESUME_HANDSHAKE,
    232  1.1  christos                checkhandshake::DEFAULT_EXTENSIONS
    233  1.1  christos                | checkhandshake::PSK_KEX_MODES_EXTENSION
    234  1.1  christos                | checkhandshake::PSK_CLI_EXTENSION
    235  1.1  christos                | checkhandshake::PSK_SRV_EXTENSION,
    236  1.1  christos                "Resume with non-dhe kex mode");
    237  1.1  christos 
    238  1.1  christos #Test 5: Attempt a resume with dhe kex mode only. Should resume with a key_share
    239  1.1  christos $proxy->clear();
    240  1.1  christos $proxy->cipherc("DEFAULT:\@SECLEVEL=2");
    241  1.1  christos $proxy->clientflags("-no_rx_cert_comp -sess_in ".$session);
    242  1.1  christos $testtype = DHE_KEX_MODE_ONLY;
    243  1.1  christos $proxy->start();
    244  1.1  christos checkhandshake($proxy, checkhandshake::RESUME_HANDSHAKE,
    245  1.1  christos                checkhandshake::DEFAULT_EXTENSIONS
    246  1.1  christos                | checkhandshake::PSK_KEX_MODES_EXTENSION
    247  1.1  christos                | checkhandshake::KEY_SHARE_SRV_EXTENSION
    248  1.1  christos                | checkhandshake::PSK_CLI_EXTENSION
    249  1.1  christos                | checkhandshake::PSK_SRV_EXTENSION,
    250  1.1  christos                "Resume with non-dhe kex mode");
    251  1.1  christos 
    252  1.1  christos #Test 6: Attempt a resume with only unrecognised kex modes. Should not resume
    253  1.1  christos #        but rather fall back to full handshake
    254  1.1  christos $proxy->clear();
    255  1.1  christos $proxy->cipherc("DEFAULT:\@SECLEVEL=2");
    256  1.1  christos $proxy->clientflags("-no_rx_cert_comp -sess_in ".$session);
    257  1.1  christos $testtype = UNKNOWN_KEX_MODES;
    258  1.1  christos $proxy->start();
    259  1.1  christos checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE,
    260  1.1  christos                checkhandshake::DEFAULT_EXTENSIONS
    261  1.1  christos                | checkhandshake::PSK_KEX_MODES_EXTENSION
    262  1.1  christos                | checkhandshake::KEY_SHARE_SRV_EXTENSION
    263  1.1  christos                | checkhandshake::PSK_CLI_EXTENSION,
    264  1.1  christos                "Resume with unrecognized kex mode");
    265  1.1  christos 
    266  1.1  christos #Test 7: Attempt a resume with both, non-dhe and dhe kex mode. Should resume with
    267  1.1  christos #        a key_share, even though non-dhe is allowed, but not explicitly preferred.
    268  1.1  christos $proxy->clear();
    269  1.1  christos $proxy->cipherc("DEFAULT:\@SECLEVEL=2");
    270  1.1  christos $proxy->clientflags("-no_rx_cert_comp -allow_no_dhe_kex -sess_in ".$session);
    271  1.1  christos $proxy->serverflags("-allow_no_dhe_kex");
    272  1.1  christos $testtype = BOTH_KEX_MODES;
    273  1.1  christos $proxy->start();
    274  1.1  christos checkhandshake($proxy, checkhandshake::RESUME_HANDSHAKE,
    275  1.1  christos                checkhandshake::DEFAULT_EXTENSIONS
    276  1.1  christos                | checkhandshake::PSK_KEX_MODES_EXTENSION
    277  1.1  christos                | checkhandshake::KEY_SHARE_SRV_EXTENSION
    278  1.1  christos                | checkhandshake::PSK_CLI_EXTENSION
    279  1.1  christos                | checkhandshake::PSK_SRV_EXTENSION,
    280  1.1  christos                "Resume with both kex modes");
    281  1.1  christos 
    282  1.1  christos #Test 8: Attempt a resume with both, non-dhe and dhe kex mode, but with server-side
    283  1.1  christos #        preference for non-dhe. Should resume without a key_share.
    284  1.1  christos $proxy->clear();
    285  1.1  christos $proxy->cipherc("DEFAULT:\@SECLEVEL=2");
    286  1.1  christos $proxy->clientflags("-no_rx_cert_comp -allow_no_dhe_kex -sess_in ".$session);
    287  1.1  christos $proxy->serverflags("-allow_no_dhe_kex -prefer_no_dhe_kex");
    288  1.1  christos $testtype = BOTH_KEX_MODES;
    289  1.1  christos $proxy->start();
    290  1.1  christos checkhandshake($proxy, checkhandshake::RESUME_HANDSHAKE,
    291  1.1  christos                checkhandshake::DEFAULT_EXTENSIONS
    292  1.1  christos                | checkhandshake::PSK_KEX_MODES_EXTENSION
    293  1.1  christos                | checkhandshake::PSK_CLI_EXTENSION
    294  1.1  christos                | checkhandshake::PSK_SRV_EXTENSION,
    295  1.1  christos                "Resume with both kex modes, preference for non-dhe");
    296  1.1  christos 
    297  1.1  christos #Test 9: Attempt a resume with both, non-dhe and dhe kex mode, with server-side
    298  1.1  christos #        preference for non-dhe, but non-dhe not allowed. Should resume with a key_share.
    299  1.1  christos $proxy->clear();
    300  1.1  christos $proxy->cipherc("DEFAULT:\@SECLEVEL=2");
    301  1.1  christos $proxy->clientflags("-no_rx_cert_comp -allow_no_dhe_kex -sess_in ".$session);
    302  1.1  christos $proxy->serverflags("-prefer_no_dhe_kex");
    303  1.1  christos $testtype = BOTH_KEX_MODES;
    304  1.1  christos $proxy->start();
    305  1.1  christos checkhandshake($proxy, checkhandshake::RESUME_HANDSHAKE,
    306  1.1  christos                checkhandshake::DEFAULT_EXTENSIONS
    307  1.1  christos                | checkhandshake::PSK_KEX_MODES_EXTENSION
    308  1.1  christos                | checkhandshake::KEY_SHARE_SRV_EXTENSION
    309  1.1  christos                | checkhandshake::PSK_CLI_EXTENSION
    310  1.1  christos                | checkhandshake::PSK_SRV_EXTENSION,
    311  1.1  christos                "Resume with both kex modes, preference for but disabled non-dhe");
    312  1.1  christos 
    313  1.1  christos #Test 10: Attempt a resume with both non-dhe and dhe kex mode, but unacceptable
    314  1.1  christos #        initial key_share. Should resume with a key_share following an HRR
    315  1.1  christos $proxy->clear();
    316  1.1  christos $proxy->cipherc("DEFAULT:\@SECLEVEL=2");
    317  1.1  christos $proxy->clientflags("-no_rx_cert_comp -sess_in ".$session);
    318  1.1  christos $proxy->serverflags("-no_rx_cert_comp -curves P-384");
    319  1.1  christos $testtype = BOTH_KEX_MODES;
    320  1.1  christos $proxy->start();
    321  1.1  christos checkhandshake($proxy, checkhandshake::HRR_RESUME_HANDSHAKE,
    322  1.1  christos                checkhandshake::DEFAULT_EXTENSIONS
    323  1.1  christos                | checkhandshake::PSK_KEX_MODES_EXTENSION
    324  1.1  christos                | checkhandshake::KEY_SHARE_SRV_EXTENSION
    325  1.1  christos                | checkhandshake::KEY_SHARE_HRR_EXTENSION
    326  1.1  christos                | checkhandshake::PSK_CLI_EXTENSION
    327  1.1  christos                | checkhandshake::PSK_SRV_EXTENSION,
    328  1.1  christos                "Resume with both kex modes and HRR");
    329  1.1  christos 
    330  1.1  christos #Test 11: Attempt a resume with dhe kex mode only and an unacceptable initial
    331  1.1  christos #        key_share. Should resume with a key_share following an HRR
    332  1.1  christos $proxy->clear();
    333  1.1  christos $proxy->cipherc("DEFAULT:\@SECLEVEL=2");
    334  1.1  christos $proxy->clientflags("-no_rx_cert_comp -sess_in ".$session);
    335  1.1  christos $proxy->serverflags("-no_rx_cert_comp -curves P-384");
    336  1.1  christos $testtype = DHE_KEX_MODE_ONLY;
    337  1.1  christos $proxy->start();
    338  1.1  christos checkhandshake($proxy, checkhandshake::HRR_RESUME_HANDSHAKE,
    339  1.1  christos                checkhandshake::DEFAULT_EXTENSIONS
    340  1.1  christos                | checkhandshake::PSK_KEX_MODES_EXTENSION
    341  1.1  christos                | checkhandshake::KEY_SHARE_SRV_EXTENSION
    342  1.1  christos                | checkhandshake::KEY_SHARE_HRR_EXTENSION
    343  1.1  christos                | checkhandshake::PSK_CLI_EXTENSION
    344  1.1  christos                | checkhandshake::PSK_SRV_EXTENSION,
    345  1.1  christos                "Resume with dhe kex mode and HRR");
    346  1.1  christos 
    347  1.1  christos #Test 12: Attempt a resume with both non-dhe and dhe kex mode, unacceptable
    348  1.1  christos #         initial key_share and no overlapping groups. Should resume without a
    349  1.1  christos #         key_share
    350  1.1  christos $proxy->clear();
    351  1.1  christos $proxy->cipherc("DEFAULT:\@SECLEVEL=2");
    352  1.1  christos $proxy->clientflags("-no_rx_cert_comp -allow_no_dhe_kex -curves P-384 -sess_in ".$session);
    353  1.1  christos $proxy->serverflags("-no_rx_cert_comp -allow_no_dhe_kex -curves P-256");
    354  1.1  christos $testtype = BOTH_KEX_MODES;
    355  1.1  christos $proxy->start();
    356  1.1  christos checkhandshake($proxy, checkhandshake::RESUME_HANDSHAKE,
    357  1.1  christos                checkhandshake::DEFAULT_EXTENSIONS
    358  1.1  christos                | checkhandshake::PSK_KEX_MODES_EXTENSION
    359  1.1  christos                | checkhandshake::PSK_CLI_EXTENSION
    360  1.1  christos                | checkhandshake::PSK_SRV_EXTENSION,
    361  1.1  christos                "Resume with both kex modes, no overlapping groups");
    362  1.1  christos 
    363  1.1  christos #Test 13: Attempt a resume with dhe kex mode only, unacceptable
    364  1.1  christos #         initial key_share and no overlapping groups. Should fail
    365  1.1  christos $proxy->clear();
    366  1.1  christos $proxy->cipherc("DEFAULT:\@SECLEVEL=2");
    367  1.1  christos $proxy->clientflags("-no_rx_cert_comp -curves P-384 -sess_in ".$session);
    368  1.1  christos $proxy->serverflags("-no_rx_cert_comp -curves P-256");
    369  1.1  christos $testtype = DHE_KEX_MODE_ONLY;
    370  1.1  christos $proxy->start();
    371  1.1  christos ok(TLSProxy::Message->fail(), "Resume with dhe kex mode, no overlapping groups");
    372  1.1  christos 
    373  1.1  christos unlink $session;
    374  1.1  christos 
    375  1.1  christos sub modify_kex_modes_filter
    376  1.1  christos {
    377  1.1  christos     my $proxy = shift;
    378  1.1  christos 
    379  1.1  christos     # We're only interested in the initial ClientHello
    380  1.1  christos     return if ($proxy->flight != 0);
    381  1.1  christos 
    382  1.1  christos     foreach my $message (@{$proxy->message_list}) {
    383  1.1  christos         if ($message->mt == TLSProxy::Message::MT_CLIENT_HELLO) {
    384  1.1  christos             my $ext;
    385  1.1  christos 
    386  1.1  christos             if ($testtype == EMPTY_EXTENSION) {
    387  1.1  christos                 $ext = pack "C",
    388  1.1  christos                     0x00;       #List length
    389  1.1  christos             } elsif ($testtype == NON_DHE_KEX_MODE_ONLY) {
    390  1.1  christos                 $ext = pack "C2",
    391  1.1  christos                     0x01,       #List length
    392  1.1  christos                     0x00;       #psk_ke
    393  1.1  christos             } elsif ($testtype == DHE_KEX_MODE_ONLY) {
    394  1.1  christos                 $ext = pack "C2",
    395  1.1  christos                     0x01,       #List length
    396  1.1  christos                     0x01;       #psk_dhe_ke
    397  1.1  christos             } elsif ($testtype == UNKNOWN_KEX_MODES) {
    398  1.1  christos                 $ext = pack "C3",
    399  1.1  christos                     0x02,       #List length
    400  1.1  christos                     0xfe,       #unknown
    401  1.1  christos                     0xff;       #unknown
    402  1.1  christos             } elsif ($testtype == BOTH_KEX_MODES) {
    403  1.1  christos                 #We deliberately list psk_ke first...should still use psk_dhe_ke, except if the server is configured otherwise.
    404  1.1  christos                 $ext = pack "C3",
    405  1.1  christos                     0x02,       #List length
    406  1.1  christos                     0x00,       #psk_ke
    407  1.1  christos                     0x01;       #psk_dhe_ke
    408  1.1  christos             }
    409  1.1  christos 
    410  1.1  christos             if ($testtype == DELETE_EXTENSION) {
    411  1.1  christos                 $message->delete_extension(
    412  1.1  christos                     TLSProxy::Message::EXT_PSK_KEX_MODES);
    413  1.1  christos             } else {
    414  1.1  christos                 $message->set_extension(
    415  1.1  christos                     TLSProxy::Message::EXT_PSK_KEX_MODES, $ext);
    416  1.1  christos             }
    417  1.1  christos 
    418  1.1  christos             $message->repack();
    419  1.1  christos         }
    420  1.1  christos     }
    421  1.1  christos }
    422