1#! /usr/bin/env perl 2# Copyright 2015-2021 The OpenSSL Project Authors. All Rights Reserved. 3# 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 8 9use strict; 10use OpenSSL::Test qw/:DEFAULT cmdstr srctop_file srctop_dir bldtop_dir/; 11use OpenSSL::Test::Utils; 12use File::Temp qw(tempfile); 13use TLSProxy::Proxy; 14use checkhandshake qw(checkhandshake @handmessages @extensions); 15 16my $test_name = "test_sslmessages"; 17setup($test_name); 18 19plan skip_all => "TLSProxy isn't usable on $^O" 20 if $^O =~ /^(VMS)$/; 21 22plan skip_all => "$test_name needs the dynamic engine feature enabled" 23 if disabled("engine") || disabled("dynamic-engine"); 24 25plan skip_all => "$test_name needs the sock feature enabled" 26 if disabled("sock"); 27 28plan skip_all => "$test_name needs TLS enabled" 29 if alldisabled(available_protocols("tls")) 30 || (!disabled("tls1_3") && disabled("tls1_2")); 31 32my $proxy = TLSProxy::Proxy->new( 33 undef, 34 cmdstr(app(["openssl"]), display => 1), 35 srctop_file("apps", "server.pem"), 36 (!$ENV{HARNESS_ACTIVE} || $ENV{HARNESS_VERBOSE}) 37); 38 39@handmessages = ( 40 [TLSProxy::Message::MT_CLIENT_HELLO, 41 checkhandshake::ALL_HANDSHAKES], 42 [TLSProxy::Message::MT_SERVER_HELLO, 43 checkhandshake::ALL_HANDSHAKES], 44 [TLSProxy::Message::MT_CERTIFICATE, 45 checkhandshake::ALL_HANDSHAKES 46 & ~checkhandshake::RESUME_HANDSHAKE], 47 (disabled("ec") ? () : 48 [TLSProxy::Message::MT_SERVER_KEY_EXCHANGE, 49 checkhandshake::EC_HANDSHAKE]), 50 [TLSProxy::Message::MT_CERTIFICATE_STATUS, 51 checkhandshake::OCSP_HANDSHAKE], 52 #ServerKeyExchange handshakes not currently supported by TLSProxy 53 [TLSProxy::Message::MT_CERTIFICATE_REQUEST, 54 checkhandshake::CLIENT_AUTH_HANDSHAKE], 55 [TLSProxy::Message::MT_SERVER_HELLO_DONE, 56 checkhandshake::ALL_HANDSHAKES 57 & ~checkhandshake::RESUME_HANDSHAKE], 58 [TLSProxy::Message::MT_CERTIFICATE, 59 checkhandshake::CLIENT_AUTH_HANDSHAKE], 60 [TLSProxy::Message::MT_CLIENT_KEY_EXCHANGE, 61 checkhandshake::ALL_HANDSHAKES 62 & ~checkhandshake::RESUME_HANDSHAKE], 63 [TLSProxy::Message::MT_CERTIFICATE_VERIFY, 64 checkhandshake::CLIENT_AUTH_HANDSHAKE], 65 [TLSProxy::Message::MT_NEXT_PROTO, 66 checkhandshake::NPN_HANDSHAKE], 67 [TLSProxy::Message::MT_FINISHED, 68 checkhandshake::ALL_HANDSHAKES], 69 [TLSProxy::Message::MT_NEW_SESSION_TICKET, 70 checkhandshake::ALL_HANDSHAKES 71 & ~checkhandshake::RESUME_HANDSHAKE], 72 [TLSProxy::Message::MT_FINISHED, 73 checkhandshake::ALL_HANDSHAKES], 74 [TLSProxy::Message::MT_CLIENT_HELLO, 75 checkhandshake::RENEG_HANDSHAKE], 76 [TLSProxy::Message::MT_SERVER_HELLO, 77 checkhandshake::RENEG_HANDSHAKE], 78 [TLSProxy::Message::MT_CERTIFICATE, 79 checkhandshake::RENEG_HANDSHAKE], 80 [TLSProxy::Message::MT_SERVER_HELLO_DONE, 81 checkhandshake::RENEG_HANDSHAKE], 82 [TLSProxy::Message::MT_CLIENT_KEY_EXCHANGE, 83 checkhandshake::RENEG_HANDSHAKE], 84 [TLSProxy::Message::MT_FINISHED, 85 checkhandshake::RENEG_HANDSHAKE], 86 [TLSProxy::Message::MT_NEW_SESSION_TICKET, 87 checkhandshake::RENEG_HANDSHAKE], 88 [TLSProxy::Message::MT_FINISHED, 89 checkhandshake::RENEG_HANDSHAKE], 90 [0, 0] 91); 92 93@extensions = ( 94 [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SERVER_NAME, 95 TLSProxy::Message::CLIENT, 96 checkhandshake::SERVER_NAME_CLI_EXTENSION], 97 [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_STATUS_REQUEST, 98 TLSProxy::Message::CLIENT, 99 checkhandshake::STATUS_REQUEST_CLI_EXTENSION], 100 (disabled("ec") ? () : 101 [TLSProxy::Message::MT_CLIENT_HELLO, 102 TLSProxy::Message::EXT_SUPPORTED_GROUPS, 103 TLSProxy::Message::CLIENT, 104 checkhandshake::DEFAULT_EXTENSIONS]), 105 (disabled("ec") ? () : 106 [TLSProxy::Message::MT_CLIENT_HELLO, 107 TLSProxy::Message::EXT_EC_POINT_FORMATS, 108 TLSProxy::Message::CLIENT, 109 checkhandshake::DEFAULT_EXTENSIONS]), 110 (disabled("tls1_2") ? () : 111 [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SIG_ALGS, 112 TLSProxy::Message::CLIENT, 113 checkhandshake::DEFAULT_EXTENSIONS]), 114 [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_ALPN, 115 TLSProxy::Message::CLIENT, 116 checkhandshake::ALPN_CLI_EXTENSION], 117 [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SCT, 118 TLSProxy::Message::CLIENT, 119 checkhandshake::SCT_CLI_EXTENSION], 120 [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_ENCRYPT_THEN_MAC, 121 TLSProxy::Message::CLIENT, 122 checkhandshake::DEFAULT_EXTENSIONS], 123 [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_EXTENDED_MASTER_SECRET, 124 TLSProxy::Message::CLIENT, 125 checkhandshake::DEFAULT_EXTENSIONS], 126 [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SESSION_TICKET, 127 TLSProxy::Message::CLIENT, 128 checkhandshake::DEFAULT_EXTENSIONS], 129 [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_RENEGOTIATE, 130 TLSProxy::Message::CLIENT, 131 checkhandshake::RENEGOTIATE_CLI_EXTENSION], 132 [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_NPN, 133 TLSProxy::Message::CLIENT, 134 checkhandshake::NPN_CLI_EXTENSION], 135 [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SRP, 136 TLSProxy::Message::CLIENT, 137 checkhandshake::SRP_CLI_EXTENSION], 138 139 [TLSProxy::Message::MT_SERVER_HELLO, TLSProxy::Message::EXT_RENEGOTIATE, 140 TLSProxy::Message::SERVER, 141 checkhandshake::DEFAULT_EXTENSIONS], 142 [TLSProxy::Message::MT_SERVER_HELLO, TLSProxy::Message::EXT_ENCRYPT_THEN_MAC, 143 TLSProxy::Message::SERVER, 144 checkhandshake::DEFAULT_EXTENSIONS], 145 [TLSProxy::Message::MT_SERVER_HELLO, TLSProxy::Message::EXT_EXTENDED_MASTER_SECRET, 146 TLSProxy::Message::SERVER, 147 checkhandshake::DEFAULT_EXTENSIONS], 148 [TLSProxy::Message::MT_SERVER_HELLO, TLSProxy::Message::EXT_SESSION_TICKET, 149 TLSProxy::Message::SERVER, 150 checkhandshake::SESSION_TICKET_SRV_EXTENSION], 151 [TLSProxy::Message::MT_SERVER_HELLO, TLSProxy::Message::EXT_SERVER_NAME, 152 TLSProxy::Message::SERVER, 153 checkhandshake::SERVER_NAME_SRV_EXTENSION], 154 [TLSProxy::Message::MT_SERVER_HELLO, TLSProxy::Message::EXT_STATUS_REQUEST, 155 TLSProxy::Message::SERVER, 156 checkhandshake::STATUS_REQUEST_SRV_EXTENSION], 157 [TLSProxy::Message::MT_SERVER_HELLO, TLSProxy::Message::EXT_ALPN, 158 TLSProxy::Message::SERVER, 159 checkhandshake::ALPN_SRV_EXTENSION], 160 [TLSProxy::Message::MT_SERVER_HELLO, TLSProxy::Message::EXT_SCT, 161 TLSProxy::Message::SERVER, 162 checkhandshake::SCT_SRV_EXTENSION], 163 [TLSProxy::Message::MT_SERVER_HELLO, TLSProxy::Message::EXT_NPN, 164 TLSProxy::Message::SERVER, 165 checkhandshake::NPN_SRV_EXTENSION], 166 [TLSProxy::Message::MT_SERVER_HELLO, TLSProxy::Message::EXT_EC_POINT_FORMATS, 167 TLSProxy::Message::SERVER, 168 checkhandshake::EC_POINT_FORMAT_SRV_EXTENSION], 169 [0,0,0,0] 170); 171 172#Test 1: Check we get all the right messages for a default handshake 173(undef, my $session) = tempfile(); 174$proxy->serverconnects(2); 175$proxy->clientflags("-no_tls1_3 -sess_out ".$session); 176$proxy->start() or plan skip_all => "Unable to start up Proxy for tests"; 177plan tests => 21; 178checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE, 179 checkhandshake::DEFAULT_EXTENSIONS, 180 "Default handshake test"); 181 182#Test 2: Resumption handshake 183$proxy->clearClient(); 184$proxy->clientflags("-no_tls1_3 -sess_in ".$session); 185$proxy->clientstart(); 186checkhandshake($proxy, checkhandshake::RESUME_HANDSHAKE, 187 checkhandshake::DEFAULT_EXTENSIONS 188 & ~checkhandshake::SESSION_TICKET_SRV_EXTENSION, 189 "Resumption handshake test"); 190unlink $session; 191 192SKIP: { 193 skip "No OCSP support in this OpenSSL build", 3 194 if disabled("ocsp"); 195 196 #Test 3: A status_request handshake (client request only) 197 $proxy->clear(); 198 $proxy->clientflags("-no_tls1_3 -status"); 199 $proxy->start(); 200 checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE, 201 checkhandshake::DEFAULT_EXTENSIONS 202 | checkhandshake::STATUS_REQUEST_CLI_EXTENSION, 203 "status_request handshake test (client)"); 204 205 #Test 4: A status_request handshake (server support only) 206 $proxy->clear(); 207 $proxy->clientflags("-no_tls1_3"); 208 $proxy->serverflags("-status_file " 209 .srctop_file("test", "recipes", "ocsp-response.der")); 210 $proxy->start(); 211 checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE, 212 checkhandshake::DEFAULT_EXTENSIONS, 213 "status_request handshake test (server)"); 214 215 #Test 5: A status_request handshake (client and server) 216 $proxy->clear(); 217 $proxy->clientflags("-no_tls1_3 -status"); 218 $proxy->serverflags("-status_file " 219 .srctop_file("test", "recipes", "ocsp-response.der")); 220 $proxy->start(); 221 checkhandshake($proxy, checkhandshake::OCSP_HANDSHAKE, 222 checkhandshake::DEFAULT_EXTENSIONS 223 | checkhandshake::STATUS_REQUEST_CLI_EXTENSION 224 | checkhandshake::STATUS_REQUEST_SRV_EXTENSION, 225 "status_request handshake test"); 226} 227 228#Test 6: A client auth handshake 229$proxy->clear(); 230$proxy->clientflags("-no_tls1_3 -cert ".srctop_file("apps", "server.pem")); 231$proxy->serverflags("-Verify 5"); 232$proxy->start(); 233checkhandshake($proxy, checkhandshake::CLIENT_AUTH_HANDSHAKE, 234 checkhandshake::DEFAULT_EXTENSIONS, 235 "Client auth handshake test"); 236 237#Test 7: A handshake with a renegotiation 238$proxy->clear(); 239$proxy->clientflags("-no_tls1_3"); 240$proxy->serverflags("-client_renegotiation"); 241$proxy->reneg(1); 242$proxy->start(); 243checkhandshake($proxy, checkhandshake::RENEG_HANDSHAKE, 244 checkhandshake::DEFAULT_EXTENSIONS, 245 "Renegotiation handshake test"); 246 247#Test 8: Server name handshake (no client request) 248$proxy->clear(); 249$proxy->clientflags("-no_tls1_3 -noservername"); 250$proxy->start(); 251checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE, 252 checkhandshake::DEFAULT_EXTENSIONS 253 & ~checkhandshake::SERVER_NAME_CLI_EXTENSION, 254 "Server name handshake test (client)"); 255 256#Test 9: Server name handshake (server support only) 257$proxy->clear(); 258$proxy->clientflags("-no_tls1_3 -noservername"); 259$proxy->serverflags("-servername testhost"); 260$proxy->start(); 261checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE, 262 checkhandshake::DEFAULT_EXTENSIONS 263 & ~checkhandshake::SERVER_NAME_CLI_EXTENSION, 264 "Server name handshake test (server)"); 265 266#Test 10: Server name handshake (client and server) 267$proxy->clear(); 268$proxy->clientflags("-no_tls1_3 -servername testhost"); 269$proxy->serverflags("-servername testhost"); 270$proxy->start(); 271checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE, 272 checkhandshake::DEFAULT_EXTENSIONS 273 | checkhandshake::SERVER_NAME_SRV_EXTENSION, 274 "Server name handshake test"); 275 276#Test 11: ALPN handshake (client request only) 277$proxy->clear(); 278$proxy->clientflags("-no_tls1_3 -alpn test"); 279$proxy->start(); 280checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE, 281 checkhandshake::DEFAULT_EXTENSIONS 282 | checkhandshake::ALPN_CLI_EXTENSION, 283 "ALPN handshake test (client)"); 284 285#Test 12: ALPN handshake (server support only) 286$proxy->clear(); 287$proxy->clientflags("-no_tls1_3"); 288$proxy->serverflags("-alpn test"); 289$proxy->start(); 290checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE, 291 checkhandshake::DEFAULT_EXTENSIONS, 292 "ALPN handshake test (server)"); 293 294#Test 13: ALPN handshake (client and server) 295$proxy->clear(); 296$proxy->clientflags("-no_tls1_3 -alpn test"); 297$proxy->serverflags("-alpn test"); 298$proxy->start(); 299checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE, 300 checkhandshake::DEFAULT_EXTENSIONS 301 | checkhandshake::ALPN_CLI_EXTENSION 302 | checkhandshake::ALPN_SRV_EXTENSION, 303 "ALPN handshake test"); 304 305SKIP: { 306 skip "No CT, EC or OCSP support in this OpenSSL build", 1 307 if disabled("ct") || disabled("ec") || disabled("ocsp"); 308 309 #Test 14: SCT handshake (client request only) 310 $proxy->clear(); 311 #Note: -ct also sends status_request 312 $proxy->clientflags("-no_tls1_3 -ct"); 313 $proxy->serverflags("-status_file " 314 .srctop_file("test", "recipes", "ocsp-response.der")); 315 $proxy->start(); 316 checkhandshake($proxy, checkhandshake::OCSP_HANDSHAKE, 317 checkhandshake::DEFAULT_EXTENSIONS 318 | checkhandshake::SCT_CLI_EXTENSION 319 | checkhandshake::STATUS_REQUEST_CLI_EXTENSION 320 | checkhandshake::STATUS_REQUEST_SRV_EXTENSION, 321 "SCT handshake test (client)"); 322} 323 324SKIP: { 325 skip "No OCSP support in this OpenSSL build", 1 326 if disabled("ocsp"); 327 328 #Test 15: SCT handshake (server support only) 329 $proxy->clear(); 330 #Note: -ct also sends status_request 331 $proxy->clientflags("-no_tls1_3"); 332 $proxy->serverflags("-status_file " 333 .srctop_file("test", "recipes", "ocsp-response.der")); 334 $proxy->start(); 335 checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE, 336 checkhandshake::DEFAULT_EXTENSIONS, 337 "SCT handshake test (server)"); 338} 339 340SKIP: { 341 skip "No CT, EC or OCSP support in this OpenSSL build", 1 342 if disabled("ct") || disabled("ec") || disabled("ocsp"); 343 344 #Test 16: SCT handshake (client and server) 345 #There is no built-in server side support for this so we are actually also 346 #testing custom extensions here 347 $proxy->clear(); 348 #Note: -ct also sends status_request 349 $proxy->clientflags("-no_tls1_3 -ct"); 350 $proxy->serverflags("-status_file " 351 .srctop_file("test", "recipes", "ocsp-response.der") 352 ." -serverinfo ".srctop_file("test", "serverinfo.pem")); 353 $proxy->start(); 354 checkhandshake($proxy, checkhandshake::OCSP_HANDSHAKE, 355 checkhandshake::DEFAULT_EXTENSIONS 356 | checkhandshake::SCT_CLI_EXTENSION 357 | checkhandshake::SCT_SRV_EXTENSION 358 | checkhandshake::STATUS_REQUEST_CLI_EXTENSION 359 | checkhandshake::STATUS_REQUEST_SRV_EXTENSION, 360 "SCT handshake test"); 361} 362 363 364SKIP: { 365 skip "No NPN support in this OpenSSL build", 3 366 if disabled("nextprotoneg"); 367 368 #Test 17: NPN handshake (client request only) 369 $proxy->clear(); 370 $proxy->clientflags("-no_tls1_3 -nextprotoneg test"); 371 $proxy->start(); 372 checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE, 373 checkhandshake::DEFAULT_EXTENSIONS 374 | checkhandshake::NPN_CLI_EXTENSION, 375 "NPN handshake test (client)"); 376 377 #Test 18: NPN handshake (server support only) 378 $proxy->clear(); 379 $proxy->clientflags("-no_tls1_3"); 380 $proxy->serverflags("-nextprotoneg test"); 381 $proxy->start(); 382 checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE, 383 checkhandshake::DEFAULT_EXTENSIONS, 384 "NPN handshake test (server)"); 385 386 #Test 19: NPN handshake (client and server) 387 $proxy->clear(); 388 $proxy->clientflags("-no_tls1_3 -nextprotoneg test"); 389 $proxy->serverflags("-nextprotoneg test"); 390 $proxy->start(); 391 checkhandshake($proxy, checkhandshake::NPN_HANDSHAKE, 392 checkhandshake::DEFAULT_EXTENSIONS 393 | checkhandshake::NPN_CLI_EXTENSION 394 | checkhandshake::NPN_SRV_EXTENSION, 395 "NPN handshake test"); 396} 397 398SKIP: { 399 skip "No SRP support in this OpenSSL build", 1 400 if disabled("srp"); 401 402 #Test 20: SRP extension 403 #Note: We are not actually going to perform an SRP handshake (TLSProxy 404 #does not support it). However it is sufficient for us to check that the 405 #SRP extension gets added on the client side. There is no SRP extension 406 #generated on the server side anyway. 407 $proxy->clear(); 408 $proxy->clientflags("-no_tls1_3 -srpuser user -srppass pass:pass"); 409 $proxy->start(); 410 checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE, 411 checkhandshake::DEFAULT_EXTENSIONS 412 | checkhandshake::SRP_CLI_EXTENSION, 413 "SRP extension test"); 414} 415 416#Test 21: EC handshake 417SKIP: { 418 skip "No EC support in this OpenSSL build", 1 if disabled("ec"); 419 $proxy->clear(); 420 $proxy->clientflags("-no_tls1_3"); 421 $proxy->serverflags("-no_tls1_3"); 422 $proxy->ciphers("ECDHE-RSA-AES128-SHA"); 423 $proxy->start(); 424 checkhandshake($proxy, checkhandshake::EC_HANDSHAKE, 425 checkhandshake::DEFAULT_EXTENSIONS 426 | checkhandshake::EC_POINT_FORMAT_SRV_EXTENSION, 427 "EC handshake test"); 428} 429