1%% 2%% %CopyrightBegin% 3%% 4%% Copyright Ericsson AB 2007-2020. All Rights Reserved. 5%% 6%% Licensed under the Apache License, Version 2.0 (the "License"); 7%% you may not use this file except in compliance with the License. 8%% You may obtain a copy of the License at 9%% 10%% http://www.apache.org/licenses/LICENSE-2.0 11%% 12%% Unless required by applicable law or agreed to in writing, software 13%% distributed under the License is distributed on an "AS IS" BASIS, 14%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15%% See the License for the specific language governing permissions and 16%% limitations under the License. 17%% 18%% %CopyrightEnd% 19%% 20 21-module(openssl_session_ticket_SUITE). 22 23%% Callback functions 24-export([all/0, 25 groups/0, 26 init_per_suite/1, 27 end_per_suite/1, 28 init_per_group/2, 29 end_per_group/2, 30 init_per_testcase/2, 31 end_per_testcase/2]). 32 33%% Testcases 34-export([openssl_server_basic/0, 35 openssl_server_basic/1, 36 openssl_server_hrr/0, 37 openssl_server_hrr/1, 38 openssl_server_hrr_multiple_tickets/0, 39 openssl_server_hrr_multiple_tickets/1, 40 openssl_client_basic/0, 41 openssl_client_basic/1, 42 openssl_client_hrr/0, 43 openssl_client_hrr/1]). 44 45-include("tls_handshake.hrl"). 46 47-include_lib("common_test/include/ct.hrl"). 48 49-define(SLEEP, 500). 50 51%%-------------------------------------------------------------------- 52%% Common Test interface functions ----------------------------------- 53%%-------------------------------------------------------------------- 54all() -> 55 [ 56 {group, 'tlsv1.3'} 57 ]. 58 59groups() -> 60 [{'tlsv1.3', [], [{group, stateful}, 61 {group, stateless}, 62 {group, openssl_server}]}, 63 {openssl_server, [], [openssl_server_basic, 64 openssl_server_hrr, 65 openssl_server_hrr_multiple_tickets 66 ]}, 67 {stateful, [], session_tests()}, 68 {stateless, [], session_tests()}]. 69 70session_tests() -> 71 [openssl_client_basic, 72 openssl_client_hrr]. 73 74init_per_suite(Config0) -> 75 catch crypto:stop(), 76 try crypto:start() of 77 ok -> 78 ssl_test_lib:clean_start(), 79 ssl_test_lib:make_rsa_cert(Config0) 80 catch _:_ -> 81 {skip, "Crypto did not start"} 82 end. 83 84end_per_suite(_Config) -> 85 ssl:stop(), 86 application:stop(crypto). 87 88init_per_group(stateful, Config) -> 89 [{server_ticket_mode, stateful} | proplists:delete(server_ticket_mode, Config)]; 90init_per_group(stateless, Config) -> 91 [{server_ticket_mode, stateless} | proplists:delete(server_ticket_mode, Config)]; 92init_per_group(GroupName, Config) -> 93 ssl_test_lib:init_per_group_openssl(GroupName, Config). 94 95end_per_group(GroupName, Config) -> 96 ssl_test_lib:end_per_group(GroupName, Config). 97 98init_per_testcase(_TestCase, Config) -> 99 ssl:stop(), 100 application:load(ssl), 101 ssl:start(), 102 ct:timetrap({seconds, 15}), 103 Config. 104 105end_per_testcase(_TestCase, Config) -> 106 Config. 107 108%%-------------------------------------------------------------------- 109%% Test Cases -------------------------------------------------------- 110%%-------------------------------------------------------------------- 111 112openssl_server_basic() -> 113 [{doc,"Test session resumption with session tickets (erlang client - openssl server)"}]. 114openssl_server_basic(Config) when is_list(Config) -> 115 process_flag(trap_exit, true), 116 ClientOpts0 = ssl_test_lib:ssl_options(client_rsa_verify_opts, Config), 117 ServerOpts = ssl_test_lib:ssl_options(server_rsa_verify_opts, Config), 118 {ClientNode, _, Hostname} = ssl_test_lib:run_where(Config), 119 120 Version = 'tlsv1.3', 121 Port = ssl_test_lib:inet_port(node()), 122 CertFile = proplists:get_value(certfile, ServerOpts), 123 CACertFile = proplists:get_value(cacertfile, ServerOpts), 124 KeyFile = proplists:get_value(keyfile, ServerOpts), 125 126 %% Configure session tickets 127 ClientOpts = [{session_tickets, auto}, {log_level, debug}, 128 {versions, ['tlsv1.2','tlsv1.3']}|ClientOpts0], 129 130 Exe = "openssl", 131 Args = ["s_server", "-accept", integer_to_list(Port), ssl_test_lib:version_flag(Version), 132 "-cert", CertFile,"-key", KeyFile, "-CAfile", CACertFile, "-msg", "-debug"], 133 134 OpensslPort = ssl_test_lib:portable_open_port(Exe, Args), 135 136 ssl_test_lib:wait_for_openssl_server(Port, proplists:get_value(protocol, Config)), 137 138 %% Store ticket from first connection 139 Client0 = ssl_test_lib:start_client([{node, ClientNode}, 140 {port, Port}, {host, Hostname}, 141 {mfa, {ssl_test_lib, 142 verify_active_session_resumption, 143 [false, no_reply]}}, 144 {from, self()}, {options, ClientOpts}]), 145 %% Wait for session ticket 146 ct:sleep(100), 147 148 %% Close previous connection as s_server can only handle one at a time 149 ssl_test_lib:close(Client0), 150 151 %% Use ticket 152 Client1 = ssl_test_lib:start_client([{node, ClientNode}, 153 {port, Port}, {host, Hostname}, 154 {mfa, {ssl_test_lib, 155 verify_active_session_resumption, 156 [true, no_reply]}}, 157 {from, self()}, 158 {options, ClientOpts}]), 159 process_flag(trap_exit, false), 160 161 %% Clean close down! Server needs to be closed first !! 162 ssl_test_lib:close_port(OpensslPort), 163 ssl_test_lib:close(Client1). 164 165openssl_client_basic() -> 166 [{doc,"Test session resumption with session tickets (openssl client - erlang server)"}]. 167openssl_client_basic(Config) when is_list(Config) -> 168 ServerOpts0 = ssl_test_lib:ssl_options(server_rsa_verify_opts, Config), 169 {_, ServerNode, Hostname} = ssl_test_lib:run_where(Config), 170 TicketFile0 = filename:join([proplists:get_value(priv_dir, Config), "session_ticket0"]), 171 TicketFile1 = filename:join([proplists:get_value(priv_dir, Config), "session_ticket1"]), 172 ServerTicketMode = proplists:get_value(server_ticket_mode, Config), 173 174 Data = "Hello world", 175 176 %% Configure session tickets 177 ServerOpts = [{session_tickets, ServerTicketMode}, {log_level, debug}, 178 {versions, ['tlsv1.2','tlsv1.3']}|ServerOpts0], 179 180 Server0 = 181 ssl_test_lib:start_server([{node, ServerNode}, {port, 0}, 182 {from, self()}, 183 {mfa, {ssl_test_lib, 184 verify_active_session_resumption, 185 [false]}}, 186 {options, ServerOpts}]), 187 188 Version = 'tlsv1.3', 189 Port0 = ssl_test_lib:inet_port(Server0), 190 191 Exe = "openssl", 192 Args0 = ["s_client", "-connect", ssl_test_lib:hostname_format(Hostname) 193 ++ ":" ++ integer_to_list(Port0), 194 ssl_test_lib:version_flag(Version), 195 "-sess_out", TicketFile0], 196 197 OpenSslPort0 = ssl_test_lib:portable_open_port(Exe, Args0), 198 199 true = port_command(OpenSslPort0, Data), 200 201 ssl_test_lib:check_result(Server0, ok), 202 203 Server0 ! {listen, {mfa, {ssl_test_lib, 204 verify_active_session_resumption, 205 [true]}}}, 206 207 %% Wait for session ticket 208 ct:sleep(100), 209 210 Args1 = ["s_client", "-connect", ssl_test_lib:hostname_format(Hostname) 211 ++ ":" ++ integer_to_list(Port0), 212 ssl_test_lib:version_flag(Version), 213 "-sess_in", TicketFile0, 214 "-sess_out", TicketFile1], 215 216 OpenSslPort1 = ssl_test_lib:portable_open_port(Exe, Args1), 217 218 true = port_command(OpenSslPort1, Data), 219 220 ssl_test_lib:check_result(Server0, ok), 221 222 %% Clean close down! Server needs to be closed first !! 223 ssl_test_lib:close(Server0), 224 ssl_test_lib:close_port(OpenSslPort0), 225 ssl_test_lib:close_port(OpenSslPort1). 226 227openssl_server_hrr() -> 228 [{doc,"Test session resumption with session tickets and hello_retry_request (erlang client - openssl server)"}]. 229openssl_server_hrr(Config) when is_list(Config) -> 230 process_flag(trap_exit, true), 231 ClientOpts0 = ssl_test_lib:ssl_options(client_rsa_verify_opts, Config), 232 ServerOpts = ssl_test_lib:ssl_options(server_rsa_verify_opts, Config), 233 {ClientNode, _, Hostname} = ssl_test_lib:run_where(Config), 234 235 Version = 'tlsv1.3', 236 Port = ssl_test_lib:inet_port(node()), 237 CertFile = proplists:get_value(certfile, ServerOpts), 238 CACertFile = proplists:get_value(cacertfile, ServerOpts), 239 KeyFile = proplists:get_value(keyfile, ServerOpts), 240 241 %% Configure session tickets 242 ClientOpts = [{session_tickets, auto}, {log_level, debug}, 243 {versions, ['tlsv1.2','tlsv1.3']}, 244 {supported_groups,[secp256r1, x25519]}|ClientOpts0], 245 246 Exe = "openssl", 247 Args = ["s_server", "-accept", integer_to_list(Port), ssl_test_lib:version_flag(Version), 248 "-cert", CertFile, 249 "-key", KeyFile, 250 "-CAfile", CACertFile, 251 "-groups", "X448:X25519", 252 "-msg", "-debug"], 253 254 OpensslPort = ssl_test_lib:portable_open_port(Exe, Args), 255 256 ssl_test_lib:wait_for_openssl_server(Port, proplists:get_value(protocol, Config)), 257 258 %% Store ticket from first connection 259 Client0 = ssl_test_lib:start_client([{node, ClientNode}, 260 {port, Port}, {host, Hostname}, 261 {mfa, {ssl_test_lib, 262 verify_active_session_resumption, 263 [false, no_reply]}}, 264 {from, self()}, {options, ClientOpts}]), 265 %% Wait for session ticket 266 ct:sleep(100), 267 268 %% Close previous connection as s_server can only handle one at a time 269 ssl_test_lib:close(Client0), 270 271 %% Use ticket 272 Client1 = ssl_test_lib:start_client([{node, ClientNode}, 273 {port, Port}, {host, Hostname}, 274 {mfa, {ssl_test_lib, 275 verify_active_session_resumption, 276 [true, no_reply]}}, 277 {from, self()}, 278 {options, ClientOpts}]), 279 process_flag(trap_exit, false), 280 281 %% Clean close down! Server needs to be closed first !! 282 ssl_test_lib:close_port(OpensslPort), 283 ssl_test_lib:close(Client1). 284 285openssl_client_hrr() -> 286 [{doc,"Test session resumption with session tickets and hello_retry_request (openssl client - erlang server)"}]. 287openssl_client_hrr(Config) when is_list(Config) -> 288 ServerOpts0 = ssl_test_lib:ssl_options(server_rsa_verify_opts, Config), 289 {_, ServerNode, Hostname} = ssl_test_lib:run_where(Config), 290 TicketFile0 = filename:join([proplists:get_value(priv_dir, Config), "session_ticket0"]), 291 TicketFile1 = filename:join([proplists:get_value(priv_dir, Config), "session_ticket1"]), 292 ServerTicketMode = proplists:get_value(server_ticket_mode, Config), 293 294 Data = "Hello world", 295 296 %% Configure session tickets 297 ServerOpts = [{session_tickets, ServerTicketMode}, {log_level, debug}, 298 {versions, ['tlsv1.2','tlsv1.3']}, 299 {supported_groups,[x448, x25519]}|ServerOpts0], 300 301 Server0 = 302 ssl_test_lib:start_server([{node, ServerNode}, {port, 0}, 303 {from, self()}, 304 {mfa, {ssl_test_lib, 305 verify_active_session_resumption, 306 [false]}}, 307 {options, ServerOpts}]), 308 309 Version = 'tlsv1.3', 310 Port0 = ssl_test_lib:inet_port(Server0), 311 312 Exe = "openssl", 313 Args0 = ["s_client", "-connect", ssl_test_lib:hostname_format(Hostname) 314 ++ ":" ++ integer_to_list(Port0), 315 ssl_test_lib:version_flag(Version), 316 "-groups", "P-256:X25519", 317 "-sess_out", TicketFile0], 318 319 OpenSslPort0 = ssl_test_lib:portable_open_port(Exe, Args0), 320 321 true = port_command(OpenSslPort0, Data), 322 323 ssl_test_lib:check_result(Server0, ok), 324 325 Server0 ! {listen, {mfa, {ssl_test_lib, 326 verify_active_session_resumption, 327 [true]}}}, 328 329 %% Wait for session ticket 330 ct:sleep(100), 331 332 Args1 = ["s_client", "-connect", ssl_test_lib:hostname_format(Hostname) 333 ++ ":" ++ integer_to_list(Port0), 334 ssl_test_lib:version_flag(Version), 335 "-groups", "P-256:X25519", 336 "-sess_in", TicketFile0, 337 "-sess_out", TicketFile1], 338 339 OpenSslPort1 = ssl_test_lib:portable_open_port(Exe, Args1), 340 341 true = port_command(OpenSslPort1, Data), 342 343 ssl_test_lib:check_result(Server0, ok), 344 345 %% Clean close down! Server needs to be closed first !! 346 ssl_test_lib:close(Server0), 347 ssl_test_lib:close_port(OpenSslPort0), 348 ssl_test_lib:close_port(OpenSslPort1). 349 350openssl_server_hrr_multiple_tickets() -> 351 [{doc,"Test session resumption with multiple session tickets and hello_retry_request (erlang client - openssl server)"}]. 352openssl_server_hrr_multiple_tickets(Config) when is_list(Config) -> 353 process_flag(trap_exit, true), 354 ClientOpts0 = ssl_test_lib:ssl_options(client_rsa_verify_opts, Config), 355 ServerOpts = ssl_test_lib:ssl_options(server_rsa_verify_opts, Config), 356 {ClientNode, _, Hostname} = ssl_test_lib:run_where(Config), 357 358 Version = 'tlsv1.3', 359 Port = ssl_test_lib:inet_port(node()), 360 CertFile = proplists:get_value(certfile, ServerOpts), 361 CACertFile = proplists:get_value(cacertfile, ServerOpts), 362 KeyFile = proplists:get_value(keyfile, ServerOpts), 363 364 %% Configure session tickets 365 ClientOpts = [{session_tickets, manual}, {log_level, debug}, 366 {versions, ['tlsv1.2','tlsv1.3']}, 367 {supported_groups,[secp256r1, x25519]}|ClientOpts0], 368 369 Exe = "openssl", 370 Args = ["s_server", "-accept", integer_to_list(Port), ssl_test_lib:version_flag(Version), 371 "-cert", CertFile, 372 "-key", KeyFile, 373 "-CAfile", CACertFile, 374 "-groups", "X448:X25519", 375 "-msg", "-debug"], 376 377 OpensslPort = ssl_test_lib:portable_open_port(Exe, Args), 378 379 ssl_test_lib:wait_for_openssl_server(Port, proplists:get_value(protocol, Config)), 380 381 %% Store ticket from first connection 382 Client0 = ssl_test_lib:start_client([{node, ClientNode}, 383 {port, Port}, {host, Hostname}, 384 {mfa, {ssl_test_lib, 385 verify_active_session_resumption, 386 [false, no_reply, {tickets, 2}]}}, 387 {from, self()}, {options, ClientOpts}]), 388 389 Tickets0 = ssl_test_lib:check_tickets(Client0), 390 391 ct:pal("Received tickets: ~p~n", [Tickets0]), 392 393 %% Close previous connection as s_server can only handle one at a time 394 ssl_test_lib:close(Client0), 395 396 %% Use tickets 397 Client1 = ssl_test_lib:start_client([{node, ClientNode}, 398 {port, Port}, {host, Hostname}, 399 {mfa, {ssl_test_lib, 400 verify_active_session_resumption, 401 [true, no_reply, no_tickets]}}, 402 {from, self()}, 403 {options, [{use_ticket, Tickets0}|ClientOpts]}]), 404 405 process_flag(trap_exit, false), 406 407 %% Clean close down! Server needs to be closed first !! 408 ssl_test_lib:close_port(OpensslPort), 409 ssl_test_lib:close(Client1). 410