1#! /usr/bin/env perl 2# Copyright 2015-2024 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::DEFAULT_EXTENSIONS], 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->cipherc("DEFAULT:\@SECLEVEL=2"); 176$proxy->clientflags("-no_tls1_3 -sess_out ".$session); 177$proxy->start() or plan skip_all => "Unable to start up Proxy for tests"; 178plan tests => 21; 179checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE, 180 checkhandshake::DEFAULT_EXTENSIONS, 181 "Default handshake test"); 182 183#Test 2: Resumption handshake 184$proxy->clearClient(); 185$proxy->cipherc("DEFAULT:\@SECLEVEL=2"); 186$proxy->clientflags("-no_tls1_3 -sess_in ".$session); 187$proxy->clientstart(); 188checkhandshake($proxy, checkhandshake::RESUME_HANDSHAKE, 189 checkhandshake::DEFAULT_EXTENSIONS 190 & ~checkhandshake::SESSION_TICKET_SRV_EXTENSION, 191 "Resumption handshake test"); 192unlink $session; 193 194SKIP: { 195 skip "No OCSP support in this OpenSSL build", 3 196 if disabled("ocsp"); 197 198 #Test 3: A status_request handshake (client request only) 199 $proxy->clear(); 200 $proxy->cipherc("DEFAULT:\@SECLEVEL=2"); 201 $proxy->clientflags("-no_tls1_3 -status"); 202 $proxy->start(); 203 checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE, 204 checkhandshake::DEFAULT_EXTENSIONS 205 | checkhandshake::STATUS_REQUEST_CLI_EXTENSION, 206 "status_request handshake test (client)"); 207 208 #Test 4: A status_request handshake (server support only) 209 $proxy->clear(); 210 $proxy->cipherc("DEFAULT:\@SECLEVEL=2"); 211 $proxy->clientflags("-no_tls1_3"); 212 $proxy->serverflags("-status_file " 213 .srctop_file("test", "recipes", "ocsp-response.der")); 214 $proxy->start(); 215 checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE, 216 checkhandshake::DEFAULT_EXTENSIONS, 217 "status_request handshake test (server)"); 218 219 #Test 5: A status_request handshake (client and server) 220 $proxy->clear(); 221 $proxy->cipherc("DEFAULT:\@SECLEVEL=2"); 222 $proxy->clientflags("-no_tls1_3 -status"); 223 $proxy->serverflags("-status_file " 224 .srctop_file("test", "recipes", "ocsp-response.der")); 225 $proxy->start(); 226 checkhandshake($proxy, checkhandshake::OCSP_HANDSHAKE, 227 checkhandshake::DEFAULT_EXTENSIONS 228 | checkhandshake::STATUS_REQUEST_CLI_EXTENSION 229 | checkhandshake::STATUS_REQUEST_SRV_EXTENSION, 230 "status_request handshake test"); 231} 232 233#Test 6: A client auth handshake 234$proxy->clear(); 235$proxy->cipherc("DEFAULT:\@SECLEVEL=2"); 236$proxy->clientflags("-no_tls1_3 -cert ".srctop_file("apps", "server.pem")); 237$proxy->serverflags("-Verify 5"); 238$proxy->start(); 239checkhandshake($proxy, checkhandshake::CLIENT_AUTH_HANDSHAKE, 240 checkhandshake::DEFAULT_EXTENSIONS, 241 "Client auth handshake test"); 242 243#Test 7: A handshake with a renegotiation 244$proxy->clear(); 245$proxy->cipherc("DEFAULT:\@SECLEVEL=2"); 246$proxy->clientflags("-no_tls1_3"); 247$proxy->serverflags("-client_renegotiation"); 248$proxy->reneg(1); 249$proxy->start(); 250checkhandshake($proxy, checkhandshake::RENEG_HANDSHAKE, 251 checkhandshake::DEFAULT_EXTENSIONS, 252 "Renegotiation handshake test"); 253 254#Test 8: Server name handshake (no client request) 255$proxy->clear(); 256$proxy->cipherc("DEFAULT:\@SECLEVEL=2"); 257$proxy->clientflags("-no_tls1_3 -noservername"); 258$proxy->start(); 259checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE, 260 checkhandshake::DEFAULT_EXTENSIONS 261 & ~checkhandshake::SERVER_NAME_CLI_EXTENSION, 262 "Server name handshake test (client)"); 263 264#Test 9: Server name handshake (server support only) 265$proxy->clear(); 266$proxy->cipherc("DEFAULT:\@SECLEVEL=2"); 267$proxy->clientflags("-no_tls1_3 -noservername"); 268$proxy->serverflags("-servername testhost"); 269$proxy->start(); 270checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE, 271 checkhandshake::DEFAULT_EXTENSIONS 272 & ~checkhandshake::SERVER_NAME_CLI_EXTENSION, 273 "Server name handshake test (server)"); 274 275#Test 10: Server name handshake (client and server) 276$proxy->clear(); 277$proxy->cipherc("DEFAULT:\@SECLEVEL=2"); 278$proxy->clientflags("-no_tls1_3 -servername testhost"); 279$proxy->serverflags("-servername testhost"); 280$proxy->start(); 281checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE, 282 checkhandshake::DEFAULT_EXTENSIONS 283 | checkhandshake::SERVER_NAME_SRV_EXTENSION, 284 "Server name handshake test"); 285 286#Test 11: ALPN handshake (client request only) 287$proxy->clear(); 288$proxy->cipherc("DEFAULT:\@SECLEVEL=2"); 289$proxy->clientflags("-no_tls1_3 -alpn test"); 290$proxy->start(); 291checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE, 292 checkhandshake::DEFAULT_EXTENSIONS 293 | checkhandshake::ALPN_CLI_EXTENSION, 294 "ALPN handshake test (client)"); 295 296#Test 12: ALPN handshake (server support only) 297$proxy->clear(); 298$proxy->cipherc("DEFAULT:\@SECLEVEL=2"); 299$proxy->clientflags("-no_tls1_3"); 300$proxy->serverflags("-alpn test"); 301$proxy->start(); 302checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE, 303 checkhandshake::DEFAULT_EXTENSIONS, 304 "ALPN handshake test (server)"); 305 306#Test 13: ALPN handshake (client and server) 307$proxy->clear(); 308$proxy->cipherc("DEFAULT:\@SECLEVEL=2"); 309$proxy->clientflags("-no_tls1_3 -alpn test"); 310$proxy->serverflags("-alpn test"); 311$proxy->start(); 312checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE, 313 checkhandshake::DEFAULT_EXTENSIONS 314 | checkhandshake::ALPN_CLI_EXTENSION 315 | checkhandshake::ALPN_SRV_EXTENSION, 316 "ALPN handshake test"); 317 318SKIP: { 319 skip "No CT, EC or OCSP support in this OpenSSL build", 1 320 if disabled("ct") || disabled("ec") || disabled("ocsp"); 321 322 #Test 14: SCT handshake (client request only) 323 $proxy->clear(); 324 $proxy->cipherc("DEFAULT:\@SECLEVEL=2"); 325 #Note: -ct also sends status_request 326 $proxy->clientflags("-no_tls1_3 -ct"); 327 $proxy->serverflags("-status_file " 328 .srctop_file("test", "recipes", "ocsp-response.der")); 329 $proxy->start(); 330 checkhandshake($proxy, checkhandshake::OCSP_HANDSHAKE, 331 checkhandshake::DEFAULT_EXTENSIONS 332 | checkhandshake::SCT_CLI_EXTENSION 333 | checkhandshake::STATUS_REQUEST_CLI_EXTENSION 334 | checkhandshake::STATUS_REQUEST_SRV_EXTENSION, 335 "SCT handshake test (client)"); 336} 337 338SKIP: { 339 skip "No OCSP support in this OpenSSL build", 1 340 if disabled("ocsp"); 341 342 #Test 15: SCT handshake (server support only) 343 $proxy->clear(); 344 $proxy->cipherc("DEFAULT:\@SECLEVEL=2"); 345 #Note: -ct also sends status_request 346 $proxy->clientflags("-no_tls1_3"); 347 $proxy->serverflags("-status_file " 348 .srctop_file("test", "recipes", "ocsp-response.der")); 349 $proxy->start(); 350 checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE, 351 checkhandshake::DEFAULT_EXTENSIONS, 352 "SCT handshake test (server)"); 353} 354 355SKIP: { 356 skip "No CT, EC or OCSP support in this OpenSSL build", 1 357 if disabled("ct") || disabled("ec") || disabled("ocsp"); 358 359 #Test 16: SCT handshake (client and server) 360 #There is no built-in server side support for this so we are actually also 361 #testing custom extensions here 362 $proxy->clear(); 363 $proxy->cipherc("DEFAULT:\@SECLEVEL=2"); 364 #Note: -ct also sends status_request 365 $proxy->clientflags("-no_tls1_3 -ct"); 366 $proxy->serverflags("-status_file " 367 .srctop_file("test", "recipes", "ocsp-response.der") 368 ." -serverinfo ".srctop_file("test", "serverinfo.pem")); 369 $proxy->start(); 370 checkhandshake($proxy, checkhandshake::OCSP_HANDSHAKE, 371 checkhandshake::DEFAULT_EXTENSIONS 372 | checkhandshake::SCT_CLI_EXTENSION 373 | checkhandshake::SCT_SRV_EXTENSION 374 | checkhandshake::STATUS_REQUEST_CLI_EXTENSION 375 | checkhandshake::STATUS_REQUEST_SRV_EXTENSION, 376 "SCT handshake test"); 377} 378 379 380SKIP: { 381 skip "No NPN support in this OpenSSL build", 3 382 if disabled("nextprotoneg"); 383 384 #Test 17: NPN handshake (client request only) 385 $proxy->clear(); 386 $proxy->cipherc("DEFAULT:\@SECLEVEL=2"); 387 $proxy->clientflags("-no_tls1_3 -nextprotoneg test"); 388 $proxy->start(); 389 checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE, 390 checkhandshake::DEFAULT_EXTENSIONS 391 | checkhandshake::NPN_CLI_EXTENSION, 392 "NPN handshake test (client)"); 393 394 #Test 18: NPN handshake (server support only) 395 $proxy->clear(); 396 $proxy->cipherc("DEFAULT:\@SECLEVEL=2"); 397 $proxy->clientflags("-no_tls1_3"); 398 $proxy->serverflags("-nextprotoneg test"); 399 $proxy->start(); 400 checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE, 401 checkhandshake::DEFAULT_EXTENSIONS, 402 "NPN handshake test (server)"); 403 404 #Test 19: NPN handshake (client and server) 405 $proxy->clear(); 406 $proxy->cipherc("DEFAULT:\@SECLEVEL=2"); 407 $proxy->clientflags("-no_tls1_3 -nextprotoneg test"); 408 $proxy->serverflags("-nextprotoneg test"); 409 $proxy->start(); 410 checkhandshake($proxy, checkhandshake::NPN_HANDSHAKE, 411 checkhandshake::DEFAULT_EXTENSIONS 412 | checkhandshake::NPN_CLI_EXTENSION 413 | checkhandshake::NPN_SRV_EXTENSION, 414 "NPN handshake test"); 415} 416 417SKIP: { 418 skip "No SRP support in this OpenSSL build", 1 419 if disabled("srp"); 420 421 #Test 20: SRP extension 422 #Note: We are not actually going to perform an SRP handshake (TLSProxy 423 #does not support it). However it is sufficient for us to check that the 424 #SRP extension gets added on the client side. There is no SRP extension 425 #generated on the server side anyway. 426 $proxy->clear(); 427 $proxy->cipherc("DEFAULT:\@SECLEVEL=2"); 428 $proxy->clientflags("-no_tls1_3 -srpuser user -srppass pass:pass"); 429 $proxy->start(); 430 checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE, 431 checkhandshake::DEFAULT_EXTENSIONS 432 | checkhandshake::SRP_CLI_EXTENSION, 433 "SRP extension test"); 434} 435 436#Test 21: EC handshake 437SKIP: { 438 skip "No EC support in this OpenSSL build", 1 if disabled("ec"); 439 $proxy->clear(); 440 $proxy->cipherc("DEFAULT:\@SECLEVEL=2"); 441 $proxy->clientflags("-no_tls1_3"); 442 $proxy->serverflags("-no_tls1_3"); 443 $proxy->ciphers("ECDHE-RSA-AES128-SHA"); 444 $proxy->start(); 445 checkhandshake($proxy, checkhandshake::EC_HANDSHAKE, 446 checkhandshake::DEFAULT_EXTENSIONS 447 | checkhandshake::EC_POINT_FORMAT_SRV_EXTENSION, 448 "EC handshake test"); 449} 450