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