1%% 2%% %CopyrightBegin% 3%% 4%% Copyright Ericsson AB 2008-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%% 22-module(ssl_test_lib). 23 24-behaviour(ct_suite). 25 26-include_lib("common_test/include/ct.hrl"). 27-include_lib("public_key/include/public_key.hrl"). 28-include_lib("ssl/src/tls_handshake_1_3.hrl"). 29 30-export([clean_start/0, 31 clean_start/1, 32 clean_env/0, 33 init_per_group/2, 34 init_per_group_openssl/2, 35 end_per_group/2, 36 ct_log_supported_protocol_versions/1, 37 ssl_options/2, 38 run_where/1, 39 run_where/2, 40 inet_port/1, 41 default_tls_version/1, 42 check_sane_openssl_renegotiate/2, 43 check_openssl_npn_support/1, 44 start_server/1, 45 start_server/2, 46 start_client/1, 47 start_client/2, 48 start_server/3, 49 start_client/3, 50 start_client/4, 51 start_upgrade_server/1, 52 start_upgrade_server_error/1, 53 start_upgrade_client/1, 54 start_client_error/1, 55 start_server_error/1, 56 start_server_transport_abuse_socket/1, 57 start_server_transport_control/1, 58 start_server_with_raw_key/3, 59 start_openssl_client/2, 60 run_server/1, 61 run_server/3, 62 run_server_error/1, 63 ecc_test/6, 64 ecc_test_error/5, 65 transport_accept_abuse/1, 66 transport_switch_control/1, 67 init_openssl_server/3, 68 init_openssl_client/1, 69 run_client_init/1, 70 run_upgrade_server/1, 71 run_upgrade_client/1, 72 run_upgrade_server_error/1, 73 run_client_error/1, 74 send_recv_result_active/3, 75 wait_for_result/2, 76 wait_for_result/4, 77 wait_for_openssl_server/2, 78 send_recv_result/1, 79 send_recv_result_active/1, 80 send_recv_result_active/2, 81 send_recv_result_active_once/1, 82 active_recv/2, 83 active_recv_loop/3, 84 active_once_recv/2, 85 recv_disregard/2, 86 active_disregard/2, 87 active_once_disregard/2, 88 send/2, 89 close/1, 90 close/2, 91 check_active_receive/2, 92 check_client_alert/2, 93 check_client_alert/3, 94 check_server_alert/2, 95 check_server_alert/3, 96 check_tickets/1, 97 check_ecc/3, 98 check_key_exchange_send_active/2, 99 verify_active_session_resumption/2, 100 verify_active_session_resumption/3, 101 verify_active_session_resumption/4, 102 verify_active_session_resumption/5, 103 verify_server_early_data/3, 104 verify_session_ticket_extension/2, 105 update_session_ticket_extension/2, 106 check_sane_openssl_version/1, 107 check_ok/1, 108 check_result/4, 109 check_result/2, 110 gen_check_result/4, 111 basic_alert/4, 112 session_id/1, 113 update_keys/2, 114 sanity_check/2, 115 oscp_responder/6, 116 supported_eccs/1, 117 no_result/1, 118 receive_tickets/1, 119 set_protocol_versions/1, 120 user_lookup/3, 121 digest/0, 122 accepters/1, 123 client_msg/2, 124 server_msg/2, 125 hardcode_rsa_key/1, 126 bigger_buffers/0, 127 stop/2, 128 working_openssl_client/0 129 ]). 130 131-export([basic_test/3, 132 erlang_ssl_receive_and_assert_negotiated_protocol/3, 133 cipher_result/2, 134 assert_mfl/2, 135 trigger_renegotiate/4, 136 trigger_renegotiate/2, 137 session_info_result/1, 138 reuse_session/3, 139 test_ciphers/3, 140 test_cipher/2, 141 openssl_ciphers/0, 142 openssl_support_rsa_kex/0 143 ]). 144 145-export([tls_version/1, 146 is_protocol_version/1, 147 is_dtls_version/1, 148 protocol_version/1, 149 protocol_version/2, 150 protocol_options/2, 151 public_key/1, 152 state/1, 153 new_config/2, 154 node_to_hostip/2 155 ]). 156 157-export([make_rsa_cert/1, 158 make_dsa_cert/1, 159 make_ecdsa_cert/1, 160 make_ecdh_rsa_cert/1, 161 make_rsa_ecdsa_cert/2, 162 make_rsa_cert_chains/3, 163 make_dsa_cert_chains/3, 164 make_ecc_cert_chains/3, 165 make_cert_chains_der/2, 166 make_cert_chains_pem/4, 167 make_ec_cert_chains/4, 168 make_ec_cert_chains/5, 169 make_rsa_1024_cert/1, 170 make_rsa_pss_pem/4, 171 gen_conf/4, 172 make_mix_cert/1, 173 default_cert_chain_conf/0, 174 cert_options/1, 175 rsa_non_signed_suites/1, 176 ecdh_dh_anonymous_suites/1, 177 ecdsa_suites/1, 178 der_to_pem/2, 179 pem_to_der/1, 180 appropriate_sha/1, 181 format_certs/1, 182 format_cert/1 183 ]). 184 185-export([maybe_force_ipv4/1, 186 openssl_sane_dtls/0, 187 kill_openssl/0, 188 openssl_allows_server_renegotiate/1, 189 openssl_dtls_maxfraglen_support/0, 190 openssl_maxfraglen_support/0, 191 is_sane_oppenssl_pss/1, 192 consume_port_exit/1, 193 is_sane_oppenssl_client/0, 194 openssl_sane_dtls_session_reuse/0, 195 sufficient_crypto_support/1, 196 openssl_sane_dtls_alpn/0, 197 openssl_ecdsa_suites/0, 198 openssl_dsa_suites/0, 199 enough_openssl_crl_support/1, 200 openssl_ocsp_support/0, 201 openssl_allows_client_renegotiate/1, 202 version_flag/1, 203 portable_cmd/2, 204 portable_open_port/2, 205 close_port/1, 206 verify_early_data/1 207 ]). 208 209-record(sslsocket, { fd = nil, pid = nil}). 210-define(SLEEP, 1000). 211-define(DEFAULT_CURVE, secp256r1). 212-define(PRINT_DEPTH, 100). 213 214%%==================================================================== 215%% API 216%%==================================================================== 217start_client(erlang, Options, Config) -> 218 start_client(Options, Config); 219start_client(openssl, Options, Config) -> 220 start_openssl_client(Options, Config); 221start_client(Type, _Args, _Config) -> 222 {error, unsupported_client_type, Type}. 223 224start_server(erlang, Options, Config) -> 225 start_server(Options, Config); 226start_server(openssl, Options, Config) -> 227 start_openssl_server(openssl, Options, Config); 228start_server(openssl_ocsp, Options, Config) -> 229 start_openssl_server(openssl_ocsp, Options, Config); 230start_server(openssl_ocsp_revoked, Options, Config) -> 231 start_openssl_server(openssl_ocsp_revoked, Options, Config); 232start_server(Type, _Args, _Config) -> 233 {error, unsupported_server_type, Type}. 234 235 236%% Test 237send_recv_result_active(Peer1, Peer2, Data) -> 238 ok = send(Peer1, Data), 239 Data = check_active_receive(Peer2, Data), 240 ok = send(Peer2, Data), 241 Data = check_active_receive(Peer1, Data). 242 243 244%% Options 245get_server_opts(Config) -> 246 get_server_opts(openssl, Config). 247 %% DSOpts = proplists:get_value(server_ecdsa_opts, Config), 248 %% SOpts = proplists:get_value(server_opts, Config, DSOpts), 249 %% ssl_test_lib:ssl_options(SOpts, Config). 250%% 251get_server_opts(openssl, Config) -> 252 DSOpts = proplists:get_value(server_ecdsa_opts, Config), 253 SOpts = proplists:get_value(server_opts, Config, DSOpts), 254 ssl_options(SOpts, Config); 255get_server_opts(openssl_ocsp, Config) -> 256 PrivDir = proplists:get_value(priv_dir, Config), 257 Cert = filename:join(PrivDir, "a.server/cert.pem"), 258 Key = filename:join(PrivDir, "a.server/key.pem"), 259 CACerts = filename:join(PrivDir, "a.server/cacerts.pem"), 260 SOpts = [{reuseaddr, true}, 261 {cacertfile, CACerts}, 262 {certfile, Cert}, 263 {keyfile, Key}], 264 ssl_options(SOpts, Config); 265get_server_opts(openssl_ocsp_revoked, Config) -> 266 PrivDir = proplists:get_value(priv_dir, Config), 267 Cert = filename:join(PrivDir, "revoked/cert.pem"), 268 Key = filename:join(PrivDir, "revoked/key.pem"), 269 CACerts = filename:join(PrivDir, "revoked/cacerts.pem"), 270 SOpts = [{reuseaddr, true}, 271 {cacertfile, CACerts}, 272 {certfile, Cert}, 273 {keyfile, Key}], 274 ssl_options(SOpts, Config). 275 276 277get_client_opts(Config) -> 278 DCOpts = proplists:get_value(client_ecdsa_opts, Config), 279 COpts = proplists:get_value(client_opts, Config, DCOpts), 280 ssl_options(COpts, Config). 281 282%% Default callback functions 283init_per_group(GroupName, Config0) -> 284 case is_protocol_version(GroupName) andalso sufficient_crypto_support(GroupName) of 285 true -> 286 Config = clean_protocol_version(Config0), 287 [{version, GroupName}|init_protocol_version(GroupName, Config)]; 288 _ -> 289 case sufficient_crypto_support(GroupName) of 290 true -> 291 ssl:start(), 292 Config0; 293 false -> 294 {skip, "Missing crypto support"} 295 end 296 end. 297 298working_openssl_client() -> 299 case portable_cmd("openssl", ["version"]) of 300 %% Theses versions of OpenSSL has a client that 301 %% can not handle hello extensions. And will 302 %% fail with bad packet length if they are present 303 %% in ServerHello 304 "OpenSSL 0.9.8h" ++ _ -> 305 false; 306 "OpenSSL 0.9.8k" ++ _ -> 307 false; 308 _ -> 309 true 310 end. 311 312init_per_group_openssl(GroupName, Config0) -> 313 case is_tls_version(GroupName) andalso sufficient_crypto_support(GroupName) of 314 true -> 315 Config = clean_protocol_version(Config0), 316 case openssl_tls_version_support(GroupName, Config) 317 of 318 true -> 319 [{version, GroupName}|init_protocol_version(GroupName, Config)]; 320 false -> 321 {skip, "Missing openssl support"} 322 end; 323 _ -> 324 case sufficient_crypto_support(GroupName) of 325 true -> 326 ssl:start(), 327 Config0; 328 false -> 329 {skip, "Missing crypto support"} 330 end 331 end. 332 333end_per_group(GroupName, Config) -> 334 case is_tls_version(GroupName) of 335 true -> 336 clean_protocol_version(Config); 337 false -> 338 Config 339 end. 340 341openssl_ocsp_support() -> 342 case portable_cmd("openssl", ["version"]) of 343 "OpenSSL 1.1.1" ++ _Rest -> 344 true; 345 _ -> 346 false 347 end. 348 349openssl_ciphers() -> 350 Str = portable_cmd("openssl", ["ciphers"]), 351 Ciphers = string:split(string:strip(Str, right, $\n), ":", all), 352 case portable_cmd("openssl", ["version"]) of 353 "LibreSSL 3." ++ _ -> 354 Ciphers -- ["DES-CBC3-SHA","AES128-SHA", "AES256-SHA", "RC4-SHA", "RC4-MD5"]; 355 _ -> 356 Ciphers 357 end. 358 359openssl_support_rsa_kex() -> 360 case portable_cmd("openssl", ["version"]) of 361 "OpenSSL 1.1.1" ++ _Rest -> 362 false; 363 _ -> 364 true 365 end. 366 367%%==================================================================== 368%% Internal functions 369%%==================================================================== 370 371%% For now always run locally 372run_where(_) -> 373 ClientNode = node(), 374 ServerNode = node(), 375 Host = rpc:call(ServerNode, net_adm, localhost, []), 376 {ClientNode, ServerNode, Host}. 377 378run_where(_, ipv6) -> 379 ClientNode = node(), 380 ServerNode = node(), 381 Host = rpc:call(ServerNode, net_adm, localhost, []), 382 {ClientNode, ServerNode, Host}. 383 384node_to_hostip(Node, Role) -> 385 [_ , Host] = string:tokens(atom_to_list(Node), "@"), 386 {ok, Address} = inet:getaddr(Host, inet), 387 %% Convert client addresses in 127.0.0.0/24 subnet to the atom 'localhost'. 388 %% This is a workaround for testcase problems caused by the fact that 389 %% inet:peername/1 and inet:getaddr/2 return different addresses when 390 %% running on localhost. 391 normalize_loopback(Address, Role). 392 393normalize_loopback({127,_,_,_}, client) -> 394 localhost; 395normalize_loopback(Address, _) -> 396 Address. 397 398 399start_server(Args0, Config) -> 400 {_, ServerNode, _} = run_where(Config), 401 ServerOpts = get_server_opts(Config), 402 Node = proplists:get_value(node, Args0, ServerNode), 403 Port = proplists:get_value(port, Args0, 0), 404 Args = [{from, self()}, 405 {node, Node}, 406 {port, Port}, 407 {options, ServerOpts} | Args0], 408 start_server(Args). 409%% 410start_server(Args) -> 411 Node = proplists:get_value(node, Args), 412 Result = spawn_link(Node, ?MODULE, run_server, [Args]), 413 receive 414 {listen, up} -> 415 Result; 416 {error, Error} -> 417 Error 418 end. 419 420run_server(Opts) -> 421 Port = proplists:get_value(port, Opts), 422 Options = proplists:get_value(options, Opts), 423 Pid = proplists:get_value(from, Opts), 424 Transport = proplists:get_value(transport, Opts, ssl), 425 ct:log("~p:~p~nssl:listen(~p, ~p)~n", [?MODULE,?LINE, Port, format_options(Options)]), 426 %% {ok, ListenSocket} = Transport:listen(Port, Options), 427 case Transport:listen(Port, Options) of 428 {ok, ListenSocket} -> 429 Pid ! {listen, up}, 430 send_selected_port(Pid, Port, ListenSocket), 431 run_server(ListenSocket, Opts); 432 Error -> 433 Pid ! Error 434 end. 435 436run_server(ListenSocket, Opts) -> 437 Accepters = proplists:get_value(accepters, Opts, 1), 438 run_server(ListenSocket, Opts, Accepters). 439 440run_server(ListenSocket, Opts, 1) -> 441 do_run_server(ListenSocket, connect(ListenSocket, Opts), Opts); 442run_server(ListenSocket, Opts, N) -> 443 Pid = proplists:get_value(from, Opts), 444 Server = spawn(?MODULE, run_server, [ListenSocket, Opts, 1]), 445 Pid ! {accepter, N, Server}, 446 run_server(ListenSocket, Opts, N-1). 447 448do_run_server(_, {error, _} = Result, Opts) -> 449 ct:log("Server error result ~p~n", [Result]), 450 Pid = proplists:get_value(from, Opts), 451 Pid ! {self(), Result}; 452do_run_server(_, ok = Result, Opts) -> 453 ct:log("Server cancel result ~p~n", [Result]), 454 Pid = proplists:get_value(from, Opts), 455 Pid ! {self(), Result}; 456do_run_server(ListenSocket, AcceptSocket, Opts) -> 457 Pid = proplists:get_value(from, Opts), 458 Transport = proplists:get_value(transport, Opts, ssl), 459 MFA = proplists:get_value(mfa, Opts), 460 case server_apply_mfa(AcceptSocket, MFA) of 461 no_result_msg -> 462 ok; 463 Msg -> 464 ct:log("~p:~p~nServer Msg: ~p ~n", [?MODULE,?LINE, Msg]), 465 Pid ! {self(), Msg} 466 end, 467 do_run_server_core(ListenSocket, AcceptSocket, Opts, Transport, Pid). 468 469server_apply_mfa(_, undefined) -> 470 no_result_msg; 471server_apply_mfa(AcceptSocket, {Module, Function, Args}) -> 472 ct:log("~p:~p~nServer: apply(~p,~p,~p)~n", 473 [?MODULE,?LINE, Module, Function, [AcceptSocket | Args]]), 474 apply(Module, Function, [AcceptSocket | Args]). 475 476client_apply_mfa(_, undefined) -> 477 no_result_msg; 478client_apply_mfa(AcceptSocket, {Module, Function, Args}) -> 479 ct:log("~p:~p~nClient: apply(~p,~p,~p)~n", 480 [?MODULE,?LINE, Module, Function, [AcceptSocket | Args]]), 481 apply(Module, Function, [AcceptSocket | Args]). 482 483 484do_run_server_core(ListenSocket, AcceptSocket, Opts, Transport, Pid) -> 485 receive 486 {data, Data} -> 487 ct:log("[server] Send: ~p~n", [Data]), 488 case Transport:send(AcceptSocket, Data) of 489 ok -> 490 Pid ! {self(), ok}; 491 {error, Reason} -> 492 Pid ! {self(), Reason} 493 end, 494 do_run_server_core(ListenSocket, AcceptSocket, Opts, Transport, Pid); 495 {active_receive, Data} -> 496 case active_recv(AcceptSocket, length(Data)) of 497 ReceivedData -> 498 ct:log("[server] Received: ~p~n", [Data]), 499 Pid ! {self(), ReceivedData} 500 end, 501 do_run_server_core(ListenSocket, AcceptSocket, Opts, Transport, Pid); 502 {update_keys, Type} -> 503 case ssl:update_keys(AcceptSocket, Type) of 504 ok -> 505 ct:log("[server] Update keys: ~p", [Type]), 506 Pid ! {self(), ok}; 507 {error, Reason} -> 508 ct:log("[server] Update keys failed: ~p", [Type]), 509 Pid ! {self(), Reason} 510 end, 511 do_run_server_core(ListenSocket, AcceptSocket, Opts, Transport, Pid); 512 get_socket -> 513 Pid ! {self(), {socket, AcceptSocket}}, 514 do_run_server_core(ListenSocket, AcceptSocket, Opts, Transport, Pid); 515 listen -> 516 run_server(ListenSocket, Opts); 517 {listen, MFA} -> 518 run_server(ListenSocket, [MFA | proplists:delete(mfa, Opts)]); 519 close -> 520 ct:log("~p:~p~nServer closing ~p ~n", [?MODULE,?LINE, self()]), 521 Result = Transport:close(AcceptSocket), 522 Result1 = Transport:close(ListenSocket), 523 ct:log("~p:~p~nResult ~p : ~p ~n", [?MODULE,?LINE, Result, Result1]) 524 end. 525 526%%% To enable to test with s_client -reconnect 527connect(#sslsocket{} = ListenSocket, Opts) -> 528 Node = proplists:get_value(node, Opts), 529 ReconnectTimes = proplists:get_value(reconnect_times, Opts, 0), 530 Timeout = proplists:get_value(timeout, Opts, infinity), 531 SslOpts = proplists:get_value(ssl_extra_opts, Opts, []), 532 ContOpts = proplists:get_value(continue_options, Opts, []), 533 AcceptSocket = connect(ListenSocket, Node, 1 + ReconnectTimes, dummy, Timeout, SslOpts, ContOpts), 534 case ReconnectTimes of 535 0 -> 536 AcceptSocket; 537 _ -> 538 remove_close_msg(ReconnectTimes), 539 AcceptSocket 540 end; 541connect(ListenSocket, _Opts) -> 542 ct:log("~p:~p~ngen_tcp:accept(~p)~n", [?MODULE,?LINE, ListenSocket]), 543 {ok, AcceptSocket} = gen_tcp:accept(ListenSocket), 544 AcceptSocket. 545 546connect(_, _, 0, AcceptSocket, _, _, _) -> 547 AcceptSocket; 548connect(ListenSocket, Node, _N, _, Timeout, SslOpts, cancel) -> 549 ct:log("ssl:transport_accept(~P)~n", [ListenSocket, ?PRINT_DEPTH]), 550 {ok, AcceptSocket} = ssl:transport_accept(ListenSocket), 551 ct:log("~p:~p~nssl:handshake(~p,~p,~p)~n", [?MODULE,?LINE, AcceptSocket, format_options(SslOpts),Timeout]), 552 553 case ssl:handshake(AcceptSocket, SslOpts, Timeout) of 554 {ok, Socket0, Ext} -> 555 ct:log("Ext ~p:~n", [Ext]), 556 ct:log("~p:~p~nssl:handshake_cancel(~p)~n", [?MODULE,?LINE, Socket0]), 557 ssl:handshake_cancel(Socket0); 558 Result -> 559 ct:log("~p:~p~nssl:handshake@~p ret ~p",[?MODULE,?LINE, Node,Result]), 560 Result 561 end; 562connect(ListenSocket, Node, N, _, Timeout, SslOpts, [_|_] =ContOpts0) -> 563 ct:log("ssl:transport_accept(~P)~n", [ListenSocket, ?PRINT_DEPTH]), 564 {ok, AcceptSocket} = ssl:transport_accept(ListenSocket), 565 ct:log("~p:~p~nssl:handshake(~p,~p,~p)~n", [?MODULE,?LINE, AcceptSocket, SslOpts,Timeout]), 566 567 case ssl:handshake(AcceptSocket, SslOpts, Timeout) of 568 {ok, Socket0, Ext} -> 569 [_|_] = maps:get(sni, Ext), 570 ct:log("Ext ~p:~n", [Ext]), 571 ContOpts = case lists:keytake(want_ext, 1, ContOpts0) of 572 {value, {_, WantExt}, ContOpts1} -> 573 if is_pid(WantExt) -> 574 WantExt ! {self(), {ext, Ext}}; 575 true -> 576 ignore 577 end, 578 ContOpts1; 579 _ -> 580 ContOpts0 581 end, 582 ct:log("~p:~p~nssl:handshake_continue(~p,~p,~p)~n", [?MODULE,?LINE, Socket0, ContOpts,Timeout]), 583 case ssl:handshake_continue(Socket0, ContOpts, Timeout) of 584 {ok, Socket} -> 585 connect(ListenSocket, Node, N-1, Socket, Timeout, SslOpts, ContOpts0); 586 Error -> 587 ct:log("~p:~p~nssl:handshake_continue@~p ret ~p",[?MODULE,?LINE, Node,Error]), 588 Error 589 end; 590 Result -> 591 ct:log("~p:~p~nssl:handshake@~p ret ~p",[?MODULE,?LINE, Node,Result]), 592 Result 593 end; 594connect(ListenSocket, Node, N, _, Timeout, [], ContOpts) -> 595 ct:log("ssl:transport_accept(~P)~n", [ListenSocket, ?PRINT_DEPTH]), 596 {ok, AcceptSocket} = ssl:transport_accept(ListenSocket), 597 ct:log("~p:~p~nssl:ssl_accept(~p, ~p)~n", [?MODULE,?LINE, AcceptSocket, Timeout]), 598 599 case ssl:handshake(AcceptSocket, Timeout) of 600 {ok, Socket} -> 601 connect(ListenSocket, Node, N-1, Socket, Timeout, [], ContOpts); 602 Result -> 603 ct:log("~p:~p~nssl:handshake@~p ret ~p",[?MODULE,?LINE, Node,Result]), 604 Result 605 end; 606connect(ListenSocket, _Node, _, _, Timeout, Opts, _) -> 607 ct:log("ssl:transport_accept(~P)~n", [ListenSocket, ?PRINT_DEPTH]), 608 {ok, AcceptSocket} = ssl:transport_accept(ListenSocket), 609 ct:log("ssl:handshake(~p,~p, ~p)~n", [AcceptSocket, Opts, Timeout]), 610 ssl:handshake(AcceptSocket, Opts, Timeout), 611 AcceptSocket. 612 613 614start_server_transport_abuse_socket(Args) -> 615 Node = proplists:get_value(node, Args), 616 Result = spawn_link(Node, ?MODULE, transport_accept_abuse, [Args]), 617 receive 618 {listen, up} -> 619 Result 620 end. 621 622start_server_transport_control(Args) -> 623 Node = proplists:get_value(node, Args), 624 Result = spawn_link(Node, ?MODULE, transport_switch_control, [Args]), 625 receive 626 {listen, up} -> 627 Result 628 end. 629 630transport_accept_abuse(Opts) -> 631 Port = proplists:get_value(port, Opts), 632 Options = proplists:get_value(options, Opts), 633 Pid = proplists:get_value(from, Opts), 634 Transport = proplists:get_value(transport, Opts, ssl), 635 ct:log("~p:~p~nssl:listen(~p, ~p)~n", [?MODULE,?LINE, Port, Options]), 636 {ok, ListenSocket} = Transport:listen(Port, Options), 637 Pid ! {listen, up}, 638 send_selected_port(Pid, Port, ListenSocket), 639 {ok, AcceptSocket} = ssl:transport_accept(ListenSocket), 640 {error, _} = ssl:connection_information(AcceptSocket), 641 _ = ssl:handshake(AcceptSocket, infinity), 642 Pid ! {self(), ok}. 643 644transport_switch_control(Opts) -> 645 Port = proplists:get_value(port, Opts), 646 Options = proplists:get_value(options, Opts), 647 Pid = proplists:get_value(from, Opts), 648 Transport = proplists:get_value(transport, Opts, ssl), 649 ct:log("~p:~p~nssl:listen(~p, ~p)~n", [?MODULE,?LINE, Port, Options]), 650 {ok, ListenSocket} = Transport:listen(Port, Options), 651 Pid ! {listen, up}, 652 send_selected_port(Pid, Port, ListenSocket), 653 {ok, AcceptSocket} = ssl:transport_accept(ListenSocket), 654 ok = ssl:controlling_process(AcceptSocket, self()), 655 Pid ! {self(), ok}. 656 657 658remove_close_msg(0) -> 659 ok; 660remove_close_msg(ReconnectTimes) -> 661 receive 662 {ssl_closed, _} -> 663 remove_close_msg(ReconnectTimes -1) 664 end. 665 666 667start_openssl_server(Mode, Args0, Config) -> 668 {_, ServerNode, _} = run_where(Config), 669 ServerOpts = get_server_opts(Mode, Config), 670 Node = proplists:get_value(node, Args0, ServerNode), 671 Port = proplists:get_value(port, Args0, 0), 672 ResponderPort = proplists:get_value(responder_port, Config, 0), 673 PrivDir = proplists:get_value(priv_dir, Config), 674 Args = [{from, self()}, {port, Port}] ++ ServerOpts ++ Args0 ++ [{priv_dir, PrivDir}], 675 Result = spawn_link(Node, ?MODULE, init_openssl_server, 676 [Mode, ResponderPort,lists:delete(return_port, Args)]), 677 receive 678 {started, OpenSSLPort} -> 679 case lists:member(return_port, Args) of 680 true -> {Result, OpenSSLPort}; 681 false -> Result 682 end; 683 {start_failed, Reason} -> 684 {start_failed, Reason} 685 end. 686 687init_openssl_server(openssl, _, Options) -> 688 DefaultVersions = default_tls_version(Options), 689 [Version | _] = proplists:get_value(versions, Options, DefaultVersions), 690 Port = inet_port(node()), 691 Pid = proplists:get_value(from, Options), 692 693 Exe = "openssl", 694 Ciphers = proplists:get_value(ciphers, Options, default_ciphers(Version)), 695 Groups0 = proplists:get_value(groups, Options), 696 EarlyData = proplists:get_value(early_data, Options, undefined), 697 PrivDir = proplists:get_value(priv_dir, Options), 698 CertArgs = openssl_cert_options(Options, server), 699 AlpnArgs = openssl_alpn_options(proplists:get_value(alpn, Options, undefined)), 700 NpnArgs = openssl_npn_options(proplists:get_value(np, Options, undefined)), 701 Debug = openssl_debug_options(PrivDir), 702 703 Args0 = case Groups0 of 704 undefined -> 705 ["s_server", "-accept", integer_to_list(Port), cipher_flag(Version), 706 ciphers(Ciphers, Version), 707 version_flag(Version)] ++ AlpnArgs ++ NpnArgs ++ CertArgs ++ Debug; 708 Group -> 709 ["s_server", "-accept", integer_to_list(Port), cipher_flag(Version), 710 ciphers(Ciphers, Version), "-groups", Group, 711 version_flag(Version)] ++ AlpnArgs ++ NpnArgs ++ CertArgs ++ Debug 712 end, 713 Args1 = case EarlyData of 714 undefined -> 715 Args0; 716 MaxSize -> 717 Args0 ++ ["-early_data", "-no_anti_replay", "-max_early_data", 718 integer_to_list(MaxSize)] 719 end, 720 Args = maybe_force_ipv4(Args1), 721 SslPort = portable_open_port(Exe, Args), 722 wait_for_openssl_server(Port, proplists:get_value(protocol, Options, tls)), 723 Pid ! {started, SslPort}, 724 Pid ! {self(), {port, Port}}, 725 openssl_server_loop(Pid, SslPort, Args); 726 727init_openssl_server(Mode, ResponderPort, Options) when Mode == openssl_ocsp orelse 728 Mode == openssl_ocsp_revoked -> 729 DefaultVersions = default_tls_version(Options), 730 [Version | _] = proplists:get_value(versions, Options, DefaultVersions), 731 Port = inet_port(node()), 732 Pid = proplists:get_value(from, Options), 733 GroupName = proplists:get_value(group, Options), 734 735 Exe = "openssl", 736 Ciphers = proplists:get_value(ciphers, Options, ssl:cipher_suites(default,Version)), 737 CertArgs = openssl_cert_options(Options, server), 738 Exe = "openssl", 739 740 Args = ["s_server", "-accept", integer_to_list(Port), cipher_flag(Version), 741 ciphers(Ciphers, Version), 742 "-status_verbose", 743 "-status_url", 744 "http://127.0.0.1:" ++ erlang:integer_to_list(ResponderPort), 745 version_flag(Version)] ++ CertArgs ++ ["-msg", "-debug"] 746 ++ openssl_dtls_opt(GroupName), 747 748 SslPort = portable_open_port(Exe, Args), 749 wait_for_openssl_server(Port, proplists:get_value(protocol, Options, tls)), 750 Pid ! {started, Port}, 751 Pid ! {self(), {port, Port}}, 752 openssl_server_loop(Pid, SslPort, Args). 753 754oscp_responder(Port, Index, CACerts, Cert, Key, Starter) -> 755 Args = ["ocsp", "-index", Index, "-CA", CACerts, "-rsigner", Cert, 756 "-rkey", Key, "-port", erlang:integer_to_list(Port)], 757 Responder = portable_open_port("openssl", Args), 758 wait_for_openssl_server(Port, tls), 759 760 openssl_server_loop(Starter, Responder, []). 761 762 763openssl_dtls_opt('dtlsv1.2') -> 764 ["-dtls"]; 765openssl_dtls_opt(_Other) -> 766 []. 767 768openssl_server_loop(Pid, SslPort, Args) -> 769 receive 770 {data, Data} -> 771 case port_command(SslPort, Data, [nosuspend]) of 772 true -> 773 ct:log("(~p) [openssl server] Send data: ~p~n", 774 [self(), Data]), 775 Pid ! {self(), ok}; 776 _Else -> 777 ct:log("(~p) [openssl server] Send failed, data: ~p~n", 778 [self(), Data]), 779 Pid ! {self(), {error, port_command_failed}} 780 end, 781 openssl_server_loop(Pid, SslPort, Args); 782 {active_receive, Data} -> 783 case active_recv(SslPort, length(Data)) of 784 ReceivedData -> 785 ct:log("(~p) [openssl server] Received: ~p~n", [self(), Data]), 786 Pid ! {self(), ReceivedData} 787 end, 788 openssl_server_loop(Pid, SslPort, Args); 789 {update_keys, Type} -> 790 case Type of 791 write -> 792 ct:log("[openssl server] Update keys: ~p", [Type]), 793 true = port_command(SslPort, "k", [nosuspend]), 794 Pid ! {self(), ok}; 795 read_write -> 796 ct:log("[openssl server] Update keys: ~p", [Type]), 797 true = port_command(SslPort, "K", [nosuspend]), 798 Pid ! {self(), ok} 799 end, 800 openssl_server_loop(Pid, SslPort, Args); 801 close -> 802 ct:log("~p:~p~n[openssl server] Server closing~n", [?MODULE,?LINE]), 803 catch port_close(SslPort); 804 {ssl_closed, _Socket} -> 805 %% TODO 806 ok 807 end. 808 809start_openssl_client(Args0, Config) -> 810 {ClientNode, _, Hostname} = run_where(Config), 811 ClientOpts = get_client_opts(Config), 812 DefaultVersions = default_tls_version(ClientOpts), 813 [Version | _] = proplists:get_value(versions, ClientOpts, DefaultVersions), 814 Node = proplists:get_value(node, Args0, ClientNode), 815 Args = [{from, self()}, 816 {host, Hostname}, 817 {options, ClientOpts} | Args0], 818 819 Result = spawn_link(Node, ?MODULE, init_openssl_client, [[{version, Version} | lists:delete(return_port, Args)]]), 820 receive 821 {connected, OpenSSLPort} -> 822 case lists:member(return_port, Args) of 823 true -> {Result, OpenSSLPort}; 824 false -> Result 825 end; 826 {connect_failed, Reason} -> 827 {connect_failed, Reason} 828 end. 829 830init_openssl_client(Options) -> 831 Version = proplists:get_value(version, Options), 832 Port = proplists:get_value(port, Options), 833 Pid = proplists:get_value(from, Options), 834 SslPort = start_client(openssl, Port, Options, [{version, Version}]), 835 openssl_client_loop(Pid, SslPort, []). 836 837 838openssl_client_loop(Pid, SslPort, Args) -> 839 Pid ! {connected, SslPort}, 840 openssl_client_loop_core(Pid, SslPort, Args). 841 842openssl_client_loop_core(Pid, SslPort, Args) -> 843 receive 844 {data, Data} -> 845 case port_command(SslPort, Data, [nosuspend]) of 846 true -> 847 ct:log("(~p) [openssl client] Send data: ~p~n", 848 [self(), Data]), 849 Pid ! {self(), ok}; 850 _Else -> 851 ct:log("(~p) [openssl client] Send failed, data: ~p~n", 852 [self(), Data]), 853 Pid ! {self(), {error, port_command_failed}} 854 end, 855 openssl_client_loop_core(Pid, SslPort, Args); 856 {active_receive, Data} -> 857 case active_recv(SslPort, length(Data)) of 858 ReceivedData -> 859 ct:log("(~p) [openssl client] Received: ~p~n (forward to PID=~p)~n", 860 [self(), Data, Pid]), 861 Pid ! {self(), ReceivedData} 862 end, 863 openssl_client_loop_core(Pid, SslPort, Args); 864 {update_keys, Type} -> 865 case Type of 866 write -> 867 ct:log("[openssl client] Update keys: ~p", [Type]), 868 true = port_command(SslPort, "k", [nosuspend]), 869 Pid ! {self(), ok}; 870 read_write -> 871 ct:log("[openssl client] Update keys: ~p", [Type]), 872 true = port_command(SslPort, "K", [nosuspend]), 873 Pid ! {self(), ok} 874 end, 875 openssl_client_loop_core(Pid, SslPort, Args); 876 close -> 877 ct:log("~p:~p~nClient closing~n", [?MODULE,?LINE]), 878 catch port_close(SslPort); 879 {ssl_closed, _Socket} -> 880 %% TODO 881 ok 882 end. 883 884start_client(Args0, Config) -> 885 {_, ServerNode, Hostname} = run_where(Config), 886 ClientOpts = get_client_opts(Config), 887 ClientOpts1 = proplists:get_value(options, Args0, []), 888 Node = proplists:get_value(node, Args0, ServerNode), 889 Args1 = proplists:delete(options, Args0), 890 Args = [{from, self()}, 891 {host, Hostname}, 892 {node, Node}, 893 {options, ClientOpts ++ ClientOpts1} | Args1], 894 start_client(Args). 895%% 896start_client(Args) -> 897 Node = proplists:get_value(node, Args), 898 Result = spawn_link(Node, ?MODULE, run_client_init, [lists:delete(return_socket, Args)]), 899 receive 900 {connected, Socket} -> 901 case lists:member(return_socket, Args) of 902 true -> {Result, Socket}; 903 false -> Result 904 end; 905 {connect_failed, Reason} -> 906 {connect_failed, Reason} 907 end. 908 909run_client_init(Opts) -> 910 put(retries, 0), 911 run_client(Opts). 912 913run_client(Opts) -> 914 Node = proplists:get_value(node, Opts), 915 Host = proplists:get_value(host, Opts), 916 Port = proplists:get_value(port, Opts), 917 Pid = proplists:get_value(from, Opts), 918 Transport = proplists:get_value(transport, Opts, ssl), 919 Options = proplists:get_value(options, Opts), 920 ContOpts = proplists:get_value(continue_options, Opts, []), 921 ct:log("~p:~p~n~p:connect(~p, ~p)@~p~n", [?MODULE,?LINE, Transport, Host, Port, Node]), 922 ct:log("SSLOpts: ~p", [format_options(Options)]), 923 case ContOpts of 924 [] -> 925 client_loop(Node, Host, Port, Pid, Transport, Options, Opts); 926 _ -> 927 client_cont_loop(Node, Host, Port, Pid, Transport, Options, ContOpts, Opts) 928 end. 929 930client_loop(_Node, Host, Port, Pid, Transport, Options, Opts) -> 931 case Transport:connect(Host, Port, Options) of 932 {ok, Socket} -> 933 Pid ! {connected, Socket}, 934 ct:log("~p:~p~nClient: connected~n", [?MODULE,?LINE]), 935 %% In special cases we want to know the client port, it will 936 %% be indicated by sending {port, 0} in options list! 937 send_selected_port(Pid, proplists:get_value(port, Options), Socket), 938 MFA = proplists:get_value(mfa, Opts), 939 case client_apply_mfa(Socket, MFA) of 940 no_result_msg -> 941 ok; 942 Msg -> 943 ct:log("~p:~p~nClient Msg: ~p ~n", [?MODULE,?LINE, Msg]), 944 Pid ! {self(), Msg} 945 end, 946 client_loop_core(Socket, Pid, Transport); 947 {error, econnrefused = Reason} -> 948 case proplists:get_value(return_error, Opts, undefined) of 949 econnrefused -> 950 Pid ! {connect_failed, Reason}; 951 _ -> 952 case get(retries) of 953 N when N < 5 -> 954 ct:log("~p:~p~neconnrefused retries=~p sleep ~p",[?MODULE,?LINE, N,?SLEEP]), 955 put(retries, N+1), 956 ct:sleep(?SLEEP), 957 run_client(Opts); 958 _ -> 959 ct:log("~p:~p~nClient faild several times: connection failed: ~p ~n", [?MODULE,?LINE, Reason]), 960 Pid ! {self(), {error, Reason}} 961 end 962 end; 963 {error, econnreset = Reason} -> 964 case get(retries) of 965 N when N < 5 -> 966 ct:log("~p:~p~neconnreset retries=~p sleep ~p",[?MODULE,?LINE, N,?SLEEP]), 967 put(retries, N+1), 968 ct:sleep(?SLEEP), 969 run_client(Opts); 970 _ -> 971 ct:log("~p:~p~nClient faild several times: connection failed: ~p ~n", [?MODULE,?LINE, Reason]), 972 Pid ! {self(), {error, Reason}} 973 end; 974 {error, Reason} -> 975 ct:log("~p:~p~nClient: connection failed: ~p ~n", [?MODULE,?LINE, Reason]), 976 Pid ! {connect_failed, Reason} 977 end. 978 979client_loop_core(Socket, Pid, Transport) -> 980 receive 981 {data, Data} -> 982 ct:log("[client] Send: ~p~n", [Data]), 983 case Transport:send(Socket, Data) of 984 ok -> 985 Pid ! {self(), ok}; 986 {error, Reason} -> 987 Pid ! {self(), Reason} 988 end, 989 client_loop_core(Socket, Pid, Transport); 990 {active_receive, Data} -> 991 case active_recv(Socket, length(Data)) of 992 ReceivedData -> 993 ct:log("[client] Received: ~p~n", [Data]), 994 Pid ! {self(), ReceivedData} 995 end, 996 client_loop_core(Socket, Pid, Transport); 997 {update_keys, Type} -> 998 case ssl:update_keys(Socket, Type) of 999 ok -> 1000 ct:log("[client] Update keys: ~p", [Type]), 1001 Pid ! {self(), ok}; 1002 {error, Reason} -> 1003 ct:log("[client] Update keys failed: ~p", [Type]), 1004 Pid ! {self(), Reason} 1005 end, 1006 client_loop_core(Socket, Pid, Transport); 1007 get_socket -> 1008 Pid ! {self(), {socket, Socket}}, 1009 client_loop_core(Socket, Pid, Transport); 1010 close -> 1011 ct:log("~p:~p~nClient closing~n", [?MODULE,?LINE]), 1012 Transport:close(Socket); 1013 {ssl_closed, Socket} -> 1014 ok; 1015 {gen_tcp, closed} -> 1016 ok 1017 end. 1018 1019client_cont_loop(_Node, Host, Port, Pid, Transport, Options, cancel, _Opts) -> 1020 case Transport:connect(Host, Port, Options) of 1021 {ok, Socket, _} -> 1022 Result = Transport:handshake_cancel(Socket), 1023 ct:log("~p:~p~nClient: Cancel: ~p ~n", [?MODULE,?LINE, Result]), 1024 Pid ! {connect_failed, Result}; 1025 {error, Reason} -> 1026 ct:log("~p:~p~nClient: connection failed: ~p ~n", [?MODULE,?LINE, Reason]), 1027 Pid ! {connect_failed, Reason} 1028 end; 1029 1030client_cont_loop(_Node, Host, Port, Pid, Transport, Options, ContOpts0, Opts) -> 1031 case Transport:connect(Host, Port, Options) of 1032 {ok, Socket0, Ext} -> 1033 ContOpts = case lists:keytake(want_ext, 1, ContOpts0) of 1034 {value, {_, WantExt}, ContOpts1} -> 1035 if is_pid(WantExt) -> 1036 WantExt ! {self(), {ext, Ext}}; 1037 true -> 1038 ignore 1039 end, 1040 ContOpts1; 1041 _ -> 1042 ContOpts0 1043 end, 1044 ct:log("~p:~p~nClient: handshake_continue(~p, ~p, infinity) ~n", [?MODULE, ?LINE, Socket0, ContOpts]), 1045 case Transport:handshake_continue(Socket0, ContOpts) of 1046 {ok, Socket} -> 1047 Pid ! {connected, Socket}, 1048 {Module, Function, Args} = proplists:get_value(mfa, Opts), 1049 ct:log("~p:~p~nClient: apply(~p,~p,~p)~n", 1050 [?MODULE,?LINE, Module, Function, [Socket | Args]]), 1051 case apply(Module, Function, [Socket | Args]) of 1052 no_result_msg -> 1053 ok; 1054 Msg -> 1055 ct:log("~p:~p~nClient Msg: ~p ~n", [?MODULE,?LINE, Msg]), 1056 Pid ! {self(), Msg} 1057 end 1058 end; 1059 {error, Reason} -> 1060 ct:log("~p:~p~nClient: connection failed: ~p ~n", [?MODULE,?LINE, Reason]), 1061 Pid ! {connect_failed, Reason} 1062 end. 1063 1064close(Pid) -> 1065 ct:log("~p:~p~nClose ~p ~n", [?MODULE,?LINE, Pid]), 1066 Monitor = erlang:monitor(process, Pid), 1067 Pid ! close, 1068 receive 1069 {'DOWN', Monitor, process, Pid, Reason} -> 1070 erlang:demonitor(Monitor), 1071 ct:log("~p:~p~nPid: ~p down due to:~p ~n", [?MODULE,?LINE, Pid, Reason]) 1072 1073 end. 1074 1075close(Pid, Timeout) -> 1076 ct:log("~p:~p~n Close ~p ~n", [?MODULE,?LINE, Pid]), 1077 Monitor = erlang:monitor(process, Pid), 1078 Pid ! close, 1079 receive 1080 {'DOWN', Monitor, process, Pid, Reason} -> 1081 erlang:demonitor(Monitor), 1082 ct:log("~p:~p~nPid: ~p down due to:~p ~n", [?MODULE,?LINE, Pid, Reason]) 1083 after 1084 Timeout -> 1085 exit(Pid, kill) 1086 end. 1087 1088check_result(Server, ServerMsg, Client, ClientMsg) -> 1089 {ClientIP, ClientPort} = get_ip_port(ServerMsg), 1090 receive 1091 {Server, ServerMsg} -> 1092 check_result(Client, ClientMsg); 1093 %% Workaround to accept local addresses (127.0.0.0/24) 1094 {Server, {ok, {{127,_,_,_}, ClientPort}}} when ClientIP =:= localhost -> 1095 check_result(Client, ClientMsg); 1096 {Client, ClientMsg} -> 1097 check_result(Server, ServerMsg); 1098 {Port, {data,Debug}} when is_port(Port) -> 1099 ct:log("~p:~p~n Openssl ~s~n",[?MODULE,?LINE, Debug]), 1100 check_result(Server, ServerMsg, Client, ClientMsg); 1101 {Port,closed} when is_port(Port) -> 1102 ct:log("~p:~p~n Openssl port closed ~n",[?MODULE,?LINE]), 1103 check_result(Server, ServerMsg, Client, ClientMsg); 1104 {'EXIT', epipe} -> 1105 ct:log("~p:~p~n Openssl port died ~n",[?MODULE,?LINE]), 1106 check_result(Server, ServerMsg, Client, ClientMsg); 1107 Unexpected -> 1108 Reason = {{expected, {Client, ClientMsg}}, 1109 {expected, {Server, ServerMsg}}, {got, Unexpected}}, 1110 ct:fail(Reason) 1111 end. 1112 1113check_result(Pid, Msg) -> 1114 {ClientIP, ClientPort} = get_ip_port(Msg), 1115 receive 1116 {Pid, Msg} -> 1117 ok; 1118 %% Workaround to accept local addresses (127.0.0.0/24) 1119 {Pid, {ok, {{127,_,_,_}, ClientPort}}} when ClientIP =:= localhost -> 1120 ok; 1121 {Port, {data,Debug}} when is_port(Port) -> 1122 ct:log("~p:~p~n Openssl ~s~n",[?MODULE,?LINE, Debug]), 1123 check_result(Pid,Msg); 1124 {Port,closed} when is_port(Port)-> 1125 ct:log("~p:~p Openssl port closed ~n",[?MODULE,?LINE]), 1126 check_result(Pid, Msg); 1127 Unexpected -> 1128 Reason = {{expected, {Pid, Msg}}, 1129 {got, Unexpected}}, 1130 ct:fail(Reason) 1131 end. 1132 1133 1134get_ip_port({ok,{ClientIP, ClientPort}}) -> 1135 {ClientIP, ClientPort}; 1136get_ip_port(_) -> 1137 {undefined, undefined}. 1138 1139 1140check_server_alert(Pid, Alert) -> 1141 receive 1142 {Pid, {error, {tls_alert, {Alert, STxt}}}} -> 1143 check_server_txt(STxt), 1144 ok; 1145 {Pid, {error, {tls_alert, {OtherAlert, STxt}}}} -> 1146 ct:fail("Unexpected alert during negative test: ~p - ~p", [OtherAlert, STxt]); 1147 {Pid, {error, closed}} -> 1148 ok; 1149 {Pid, {ok, _}} -> 1150 ct:fail("Successful connection during negative test.") 1151 end. 1152 1153check_server_alert(Server, Client, Alert) -> 1154 receive 1155 {Server, {error, {tls_alert, {Alert, STxt}}}} -> 1156 check_server_txt(STxt), 1157 check_client_alert(Client, Alert); 1158 {Server, {ok, _}} -> 1159 ct:fail("Successful connection during negative test.") 1160 end. 1161 1162check_client_alert(Pid, Alert) -> 1163 receive 1164 {Pid, {error, {tls_alert, {Alert, CTxt}}}} -> 1165 check_client_txt(CTxt), 1166 ok; 1167 {Pid, {error, {tls_alert, {OtherAlert, CTxt}}}} -> 1168 ct:fail("Unexpected alert during negative test: ~p - ~p", [OtherAlert, CTxt]); 1169 {Pid, {ssl_error, _, {tls_alert, {Alert, CTxt}}}} -> 1170 check_client_txt(CTxt), 1171 ok; 1172 {Pid, {ssl_error, _, {tls_alert, {OtherAlert, CTxt}}}} -> 1173 ct:fail("Unexpected alert during negative test: ~p - ~p", [OtherAlert, CTxt]); 1174 {Pid, {error, closed}} -> 1175 ok; 1176 {Pid, {ok, _}} -> 1177 ct:fail("Successful connection during negative test.") 1178 end. 1179check_client_alert(Server, Client, Alert) -> 1180 receive 1181 {Client, {error, {tls_alert, {Alert, CTxt}}}} -> 1182 check_client_txt(CTxt), 1183 check_server_alert(Server, Alert); 1184 {Client, {ssl_error, _, {tls_alert, {Alert, CTxt}}}} -> 1185 check_client_txt(CTxt), 1186 ok; 1187 {Client, {error, closed}} -> 1188 ok; 1189 {Client, {ok, _}} -> 1190 ct:fail("Successful connection during negative test.") 1191 end. 1192check_server_txt("TLS server" ++ _) -> 1193 ok; 1194check_server_txt("DTLS server" ++ _) -> 1195 ok; 1196check_server_txt(Txt) -> 1197 ct:fail({expected_server, {got, Txt}}). 1198 1199check_client_txt("TLS client" ++ _) -> 1200 ok; 1201check_client_txt("DTLS client" ++ _) -> 1202 ok; 1203check_client_txt(Txt) -> 1204 ct:fail({expected_server, {got, Txt}}). 1205 1206wait_for_result(Server, ServerMsg, Client, ClientMsg) -> 1207 receive 1208 {Server, ServerMsg} -> 1209 receive 1210 {Client, ClientMsg} -> 1211 ok 1212 %% Unexpected -> 1213 %% Unexpected 1214 end; 1215 {Client, ClientMsg} -> 1216 receive 1217 {Server, ServerMsg} -> 1218 ok 1219 %% Unexpected -> 1220 %% Unexpected 1221 end; 1222 {Port, {data,Debug}} when is_port(Port) -> 1223 ct:log("~p:~p~nopenssl ~s~n",[?MODULE,?LINE, Debug]), 1224 wait_for_result(Server, ServerMsg, Client, ClientMsg) 1225 %% Unexpected -> 1226 %% Unexpected 1227 end. 1228 1229check_ok([]) -> 1230 ok; 1231check_ok(Pids) -> 1232 receive 1233 {Pid, ok} -> 1234 check_ok(lists:delete(Pid, Pids)); 1235 Other -> 1236 ct:fail({expected, {"pid()", ok}, got, Other}) 1237 end. 1238 1239wait_for_result(Pid, Msg) -> 1240 receive 1241 {Pid, Msg} -> 1242 ok; 1243 {Port, {data,Debug}} when is_port(Port) -> 1244 ct:log("~p:~p~nopenssl ~s~n",[?MODULE,?LINE, Debug]), 1245 wait_for_result(Pid,Msg) 1246 %% Unexpected -> 1247 %% Unexpected 1248 end. 1249 1250format_options([{cacerts, Certs}|R]) -> 1251 [{cacerts, format_certs(Certs)} | format_options(R)]; 1252format_options([{cert, Certs}|R]) -> 1253 [{cert, format_certs(Certs)} | format_options(R)]; 1254format_options([{key, Key}|R]) -> 1255 [{key, lists:flatten(io_lib:format("~W",[Key, ?PRINT_DEPTH]))} | format_options(R)]; 1256format_options([Opt|R]) -> 1257 [Opt | format_options(R)]; 1258format_options([]) -> 1259 []. 1260 1261format_certs(Certs) when is_list(Certs) -> 1262 [lists:flatten(format_cert(C)) || C <- Certs]; 1263format_certs(Cert) when is_binary(Cert) -> 1264 lists:flatten(format_cert(Cert)). 1265 1266format_cert(BinCert) when is_binary(BinCert) -> 1267 OtpCert = #'OTPCertificate'{tbsCertificate = Cert} = public_key:pkix_decode_cert(BinCert, otp), 1268 #'OTPTBSCertificate'{subject = Subject, serialNumber = Nr, issuer = Issuer} = Cert, 1269 case public_key:pkix_is_self_signed(OtpCert) of 1270 true -> 1271 io_lib:format("~.3w: ~s -> selfsigned", [Nr, format_subject(Subject)]); 1272 false -> 1273 case public_key:pkix_issuer_id(OtpCert, other) of 1274 {ok, {IsNr, Issuer0}} -> 1275 io_lib:format("~.3w:~s -> ~.3w:~s", [Nr, format_subject(Subject), IsNr, format_subject(Issuer0)]); 1276 {error, _} -> 1277 io_lib:format("~.3w:~s -> :~s", [Nr, format_subject(Subject), format_subject(Issuer)]) 1278 end 1279 end. 1280 1281format_subject({rdnSequence, Seq}) -> 1282 format_subject(Seq); 1283format_subject([[{'AttributeTypeAndValue', ?'id-at-commonName', {_, String}}]|_]) -> 1284 String; 1285format_subject([_|R]) -> 1286 format_subject(R). 1287 1288cert_options(Config) -> 1289 ClientCaCertFile = filename:join([proplists:get_value(priv_dir, Config), 1290 "client", "cacerts.pem"]), 1291 ClientCertFile = filename:join([proplists:get_value(priv_dir, Config), 1292 "client", "cert.pem"]), 1293 ClientCertFileDigitalSignatureOnly = filename:join([proplists:get_value(priv_dir, Config), 1294 "client", "digital_signature_only_cert.pem"]), 1295 ServerCaCertFile = filename:join([proplists:get_value(priv_dir, Config), 1296 "server", "cacerts.pem"]), 1297 ServerCertFile = filename:join([proplists:get_value(priv_dir, Config), 1298 "server", "cert.pem"]), 1299 ServerKeyFile = filename:join([proplists:get_value(priv_dir, Config), 1300 "server", "key.pem"]), 1301 ClientKeyFile = filename:join([proplists:get_value(priv_dir, Config), 1302 "client", "key.pem"]), 1303 ServerKeyCertFile = filename:join([proplists:get_value(priv_dir, Config), 1304 "server", "keycert.pem"]), 1305 ClientKeyCertFile = filename:join([proplists:get_value(priv_dir, Config), 1306 "client", "keycert.pem"]), 1307 1308 BadCaCertFile = filename:join([proplists:get_value(priv_dir, Config), 1309 "badcacert.pem"]), 1310 BadCertFile = filename:join([proplists:get_value(priv_dir, Config), 1311 "badcert.pem"]), 1312 BadKeyFile = filename:join([proplists:get_value(priv_dir, Config), 1313 "badkey.pem"]), 1314 1315 [{client_opts, [{cacertfile, ClientCaCertFile}, 1316 {certfile, ClientCertFile}, 1317 {keyfile, ClientKeyFile}]}, 1318 {client_verification_opts, [{cacertfile, ServerCaCertFile}, 1319 {certfile, ClientCertFile}, 1320 {keyfile, ClientKeyFile}, 1321 {verify, verify_peer}]}, 1322 {client_verification_opts_digital_signature_only, [{cacertfile, ServerCaCertFile}, 1323 {certfile, ClientCertFileDigitalSignatureOnly}, 1324 {keyfile, ClientKeyFile}, 1325 {ssl_imp, new}]}, 1326 {server_opts, [{ssl_imp, new},{reuseaddr, true}, {cacertfile, ServerCaCertFile}, 1327 {certfile, ServerCertFile}, {keyfile, ServerKeyFile}]}, 1328 {server_verification_opts, [{ssl_imp, new},{reuseaddr, true}, 1329 {cacertfile, ClientCaCertFile}, 1330 {certfile, ServerCertFile}, {keyfile, ServerKeyFile}]}, 1331 {client_kc_opts, [{certfile, ClientKeyCertFile}, {ssl_imp, new}]}, 1332 {server_kc_opts, [{ssl_imp, new},{reuseaddr, true}, 1333 {certfile, ServerKeyCertFile}]}, 1334 {client_bad_ca, [{cacertfile, BadCaCertFile}, 1335 {certfile, ClientCertFile}, 1336 {keyfile, ClientKeyFile}, 1337 {ssl_imp, new}]}, 1338 {client_bad_cert, [{cacertfile, ClientCaCertFile}, 1339 {certfile, BadCertFile}, 1340 {keyfile, ClientKeyFile}, 1341 {ssl_imp, new}]}, 1342 {server_bad_ca, [{ssl_imp, new},{cacertfile, BadCaCertFile}, 1343 {certfile, ServerCertFile}, 1344 {keyfile, ServerKeyFile}]}, 1345 {server_bad_cert, [{ssl_imp, new},{cacertfile, ServerCaCertFile}, 1346 {certfile, BadCertFile}, {keyfile, ServerKeyFile}]}, 1347 {server_bad_key, [{ssl_imp, new},{cacertfile, ServerCaCertFile}, 1348 {certfile, ServerCertFile}, {keyfile, BadKeyFile}]} 1349 | Config]. 1350 1351make_dsa_cert(Config) -> 1352 CryptoSupport = crypto:supports(), 1353 case proplists:get_bool(dss, proplists:get_value(public_keys, CryptoSupport)) of 1354 true -> 1355 ClientChain = proplists:get_value(client_chain, Config, default_cert_chain_conf()), 1356 ServerChain = proplists:get_value(server_chain, Config, default_cert_chain_conf()), 1357 CertChainConf = gen_conf(dsa, dsa, ClientChain, ServerChain), 1358 ClientFileBase = filename:join([proplists:get_value(priv_dir, Config), "dsa"]), 1359 ServerFileBase = filename:join([proplists:get_value(priv_dir, Config), "dsa"]), 1360 GenCertData = public_key:pkix_test_data(CertChainConf), 1361 [{server_config, ServerConf}, 1362 {client_config, ClientConf}] = 1363 x509_test:gen_pem_config_files(GenCertData, ClientFileBase, ServerFileBase), 1364 1365 [{server_dsa_opts, ServerConf}, 1366 {server_dsa_verify_opts, [{verify, verify_peer} | ServerConf]}, 1367 {client_dsa_opts, ClientConf} 1368 | Config]; 1369 false -> 1370 Config 1371 end. 1372 1373 1374make_cert_chains_der(Alg, UserConf) -> 1375 ClientChain = proplists:get_value(client_chain, UserConf, default_cert_chain_conf()), 1376 ServerChain = proplists:get_value(server_chain, UserConf, default_cert_chain_conf()), 1377 CertChainConf = gen_conf(Alg, Alg, ClientChain, ServerChain), 1378 public_key:pkix_test_data(CertChainConf). 1379 1380make_cert_chains_pem(Alg, UserConf, Config, Suffix) -> 1381 ClientChain = proplists:get_value(client_chain, UserConf, default_cert_chain_conf()), 1382 ServerChain = proplists:get_value(server_chain, UserConf, default_cert_chain_conf()), 1383 CertChainConf = gen_conf(Alg, Alg, ClientChain, ServerChain), 1384 ClientFileBase = filename:join([proplists:get_value(priv_dir, Config), atom_to_list(Alg) ++ Suffix]), 1385 ServerFileBase = filename:join([proplists:get_value(priv_dir, Config), atom_to_list(Alg) ++ Suffix]), 1386 GenCertData = public_key:pkix_test_data(CertChainConf), 1387 Conf = x509_test:gen_pem_config_files(GenCertData, ClientFileBase, ServerFileBase), 1388 CConf = proplists:get_value(client_config, Conf), 1389 SConf = proplists:get_value(server_config, Conf), 1390 #{server_config => SConf, 1391 client_config => CConf}. 1392 1393make_rsa_cert_chains(UserConf, Config, Suffix) -> 1394 ClientChain = proplists:get_value(client_chain, UserConf, default_cert_chain_conf()), 1395 ServerChain = proplists:get_value(server_chain, UserConf, default_cert_chain_conf()), 1396 CertChainConf = gen_conf(rsa, rsa, ClientChain, ServerChain), 1397 ClientFileBase = filename:join([proplists:get_value(priv_dir, Config), "rsa" ++ Suffix]), 1398 ServerFileBase = filename:join([proplists:get_value(priv_dir, Config), "rsa" ++ Suffix]), 1399 GenCertData = public_key:pkix_test_data(CertChainConf), 1400 [{server_config, ServerConf}, 1401 {client_config, ClientConf}] = 1402 x509_test:gen_pem_config_files(GenCertData, ClientFileBase, ServerFileBase), 1403 {[{verify, verify_peer} | ClientConf], 1404 [{reuseaddr, true}, {verify, verify_peer} | ServerConf] 1405 }. 1406 1407make_ecc_cert_chains(UserConf, Config, Suffix) -> 1408 ClientChain = proplists:get_value(client_chain, UserConf, default_cert_chain_conf()), 1409 ServerChain = proplists:get_value(server_chain, UserConf, default_cert_chain_conf()), 1410 CertChainConf = gen_conf(ecdsa, ecdsa, ClientChain, ServerChain), 1411 ClientFileBase = filename:join([proplists:get_value(priv_dir, Config), "ecdsa" ++ Suffix]), 1412 ServerFileBase = filename:join([proplists:get_value(priv_dir, Config), "ecdsa" ++ Suffix]), 1413 GenCertData = public_key:pkix_test_data(CertChainConf), 1414 [{server_config, ServerConf}, 1415 {client_config, ClientConf}] = 1416 x509_test:gen_pem_config_files(GenCertData, ClientFileBase, ServerFileBase), 1417 {[{verify, verify_peer} | ClientConf], 1418 [{reuseaddr, true}, {verify, verify_peer} | ServerConf] 1419 }. 1420 1421 1422make_dsa_cert_chains(UserConf, Config, Suffix) -> 1423 CryptoSupport = crypto:supports(), 1424 case proplists:get_bool(dss, proplists:get_value(public_keys, CryptoSupport)) of 1425 true -> 1426 ClientChain = proplists:get_value(client_chain, UserConf, default_cert_chain_conf()), 1427 ServerChain = proplists:get_value(server_chain, UserConf, default_cert_chain_conf()), 1428 CertChainConf = gen_conf(dsa, dsa, ClientChain, ServerChain), 1429 ClientFileBase = filename:join([proplists:get_value(priv_dir, Config), "dsa" ++ Suffix]), 1430 ServerFileBase = filename:join([proplists:get_value(priv_dir, Config), "dsa" ++ Suffix]), 1431 GenCertData = public_key:pkix_test_data(CertChainConf), 1432 [{server_config, ServerConf}, 1433 {client_config, ClientConf}] = 1434 x509_test:gen_pem_config_files(GenCertData, ClientFileBase, ServerFileBase), 1435 {[{verify, verify_peer} | ClientConf], 1436 [{reuseaddr, true}, {verify, verify_peer} | ServerConf]}; 1437 false -> 1438 Config 1439 end. 1440 1441make_ec_cert_chains(UserConf, ClientChainType, ServerChainType, Config) -> 1442 make_ec_cert_chains(UserConf, ClientChainType, ServerChainType, Config, ?DEFAULT_CURVE). 1443%% 1444make_ec_cert_chains(UserConf, ClientChainType, ServerChainType, Config, Curve) -> 1445 ClientChain = proplists:get_value(client_chain, UserConf, default_cert_chain_conf()), 1446 ServerChain = proplists:get_value(server_chain, UserConf, default_cert_chain_conf()), 1447 CertChainConf = gen_conf(ClientChainType, ServerChainType, ClientChain, ServerChain, Curve), 1448 ClientFileBase = filename:join([proplists:get_value(priv_dir, Config), atom_to_list(ClientChainType)]), 1449 ServerFileBase = filename:join([proplists:get_value(priv_dir, Config), atom_to_list(ServerChainType)]), 1450 GenCertData = public_key:pkix_test_data(CertChainConf), 1451 [{server_config, ServerConf}, 1452 {client_config, ClientConf}] = 1453 x509_test:gen_pem_config_files(GenCertData, ClientFileBase, ServerFileBase), 1454 {[{verify, verify_peer} | ClientConf], 1455 [{reuseaddr, true}, {verify, verify_peer} | ServerConf] 1456 }. 1457 1458default_cert_chain_conf() -> 1459 %% Use only default options 1460 [[],[],[]]. 1461 1462make_rsa_pss_pem(Alg, _UserConf, Config, Suffix) -> 1463 DefClientConf = chain_spec(client, Alg, []), 1464 DefServerConf = chain_spec(server, Alg, []), 1465 CertChainConf = new_format([{client_chain, DefClientConf}, {server_chain, DefServerConf}]), 1466 ClientFileBase = filename:join([proplists:get_value(priv_dir, Config), atom_to_list(Alg) ++ Suffix]), 1467 ServerFileBase = filename:join([proplists:get_value(priv_dir, Config), atom_to_list(Alg) ++ Suffix]), 1468 GenCertData = public_key:pkix_test_data(CertChainConf), 1469 Conf = x509_test:gen_pem_config_files(GenCertData, ClientFileBase, ServerFileBase), 1470 CConf = proplists:get_value(client_config, Conf), 1471 SConf = proplists:get_value(server_config, Conf), 1472 #{server_config => SConf, 1473 client_config => CConf}. 1474 1475gen_conf(ClientChainType, ServerChainType, UserClient, UserServer) -> 1476 gen_conf(ClientChainType, ServerChainType, UserClient, UserServer, ?DEFAULT_CURVE). 1477%% 1478gen_conf(mix, mix, UserClient, UserServer, _) -> 1479 ClientTag = conf_tag("client"), 1480 ServerTag = conf_tag("server"), 1481 1482 DefaultClient = default_cert_chain_conf(), 1483 DefaultServer = default_cert_chain_conf(), 1484 1485 ClientConf = merge_chain_spec(UserClient, DefaultClient, []), 1486 ServerConf = merge_chain_spec(UserServer, DefaultServer, []), 1487 1488 new_format([{ClientTag, ClientConf}, {ServerTag, ServerConf}]); 1489gen_conf(ClientChainType, ServerChainType, UserClient, UserServer, Curve) -> 1490 ClientTag = conf_tag("client"), 1491 ServerTag = conf_tag("server"), 1492 1493 DefaultClient = chain_spec(client, ClientChainType, Curve), 1494 DefaultServer = chain_spec(server, ServerChainType, Curve), 1495 1496 ClientConf = merge_chain_spec(UserClient, DefaultClient, []), 1497 ServerConf = merge_chain_spec(UserServer, DefaultServer, []), 1498 1499 new_format([{ClientTag, ClientConf}, {ServerTag, ServerConf}]). 1500 1501new_format(Conf) -> 1502 CConf = proplists:get_value(client_chain, Conf), 1503 SConf = proplists:get_value(server_chain, Conf), 1504 #{server_chain => proplist_to_map(SConf), 1505 client_chain => proplist_to_map(CConf)}. 1506 1507proplist_to_map([Head | Rest]) -> 1508 [Last | Tail] = lists:reverse(Rest), 1509 #{root => Head, 1510 intermediates => lists:reverse(Tail), 1511 peer => Last}. 1512 1513conf_tag(Role) -> 1514 list_to_atom(Role ++ "_chain"). 1515 1516chain_spec(_Role, ecdh_rsa, Curve) -> 1517 Digest = {digest, appropriate_sha(crypto:supports())}, 1518 CurveOid = pubkey_cert_records:namedCurves(Curve), 1519 [[Digest, {key, {namedCurve, CurveOid}}], 1520 [Digest, {key, hardcode_rsa_key(1)}], 1521 [Digest, {key, {namedCurve, CurveOid}}]]; 1522 1523chain_spec(_Role, ecdhe_ecdsa, Curve) -> 1524 Digest = {digest, appropriate_sha(crypto:supports())}, 1525 CurveOid = pubkey_cert_records:namedCurves(Curve), 1526 [[Digest, {key, {namedCurve, CurveOid}}], 1527 [Digest, {key, {namedCurve, CurveOid}}], 1528 [Digest, {key, {namedCurve, CurveOid}}]]; 1529 1530chain_spec(_Role, ecdh_ecdsa, Curve) -> 1531 Digest = {digest, appropriate_sha(crypto:supports())}, 1532 CurveOid = pubkey_cert_records:namedCurves(Curve), 1533 [[Digest, {key, {namedCurve, CurveOid}}], 1534 [Digest, {key, {namedCurve, CurveOid}}], 1535 [Digest, {key, {namedCurve, CurveOid}}]]; 1536chain_spec(_Role, ecdhe_rsa, _) -> 1537 Digest = {digest, appropriate_sha(crypto:supports())}, 1538 [[Digest, {key, hardcode_rsa_key(1)}], 1539 [Digest, {key, hardcode_rsa_key(2)}], 1540 [Digest, {key, hardcode_rsa_key(3)}]]; 1541chain_spec(_Role, ecdsa, Curve) -> 1542 Digest = {digest, appropriate_sha(crypto:supports())}, 1543 CurveOid = pubkey_cert_records:namedCurves(Curve), 1544 [[Digest, {key, {namedCurve, CurveOid}}], 1545 [Digest, {key, {namedCurve, CurveOid}}], 1546 [Digest, {key, {namedCurve, CurveOid}}]]; 1547chain_spec(_Role, rsa, _) -> 1548 Digest = {digest, appropriate_sha(crypto:supports())}, 1549 [[Digest, {key, hardcode_rsa_key(1)}], 1550 [Digest, {key, hardcode_rsa_key(2)}], 1551 [Digest, {key, hardcode_rsa_key(3)}]]; 1552chain_spec(_Role, 'rsa-1024', _) -> 1553 Digest = {digest, appropriate_sha(crypto:supports())}, 1554 [[Digest, {key, hardcode_rsa_1024_key(1)}], 1555 [Digest, {key, hardcode_rsa_1024_key(2)}], 1556 [Digest, {key, hardcode_rsa_1024_key(3)}]]; 1557chain_spec(client, rsa_pss_rsae, _) -> 1558 Digest = {digest, sha256}, 1559 [[Digest, {rsa_padding, rsa_pss_rsae}, {key, hardcode_rsa_key(1)}], 1560 [Digest, {rsa_padding, rsa_pss_rsae}, {key, hardcode_rsa_key(2)}], 1561 [Digest, {rsa_padding, rsa_pss_rsae}, {key, hardcode_rsa_key(3)}]]; 1562chain_spec(server, rsa_pss_rsae, _) -> 1563 Digest = {digest, sha256}, 1564 [[Digest, {rsa_padding, rsa_pss_rsae}, {key, hardcode_rsa_key(4)}], 1565 [Digest, {rsa_padding, rsa_pss_rsae}, {key, hardcode_rsa_key(5)}], 1566 [Digest, {rsa_padding, rsa_pss_rsae}, {key, hardcode_rsa_key(6)}]]; 1567chain_spec(client, rsa_pss_pss, _) -> 1568 Digest = {digest, sha256}, 1569 [[Digest, {rsa_padding, rsa_pss_pss}, {key, {hardcode_rsa_key(1), pss_params(sha256)}}], 1570 [Digest, {rsa_padding, rsa_pss_pss}, {key, {hardcode_rsa_key(2), pss_params(sha256)}}], 1571 [Digest, {rsa_padding, rsa_pss_pss}, {key, {hardcode_rsa_key(3), pss_params(sha256)}}]]; 1572chain_spec(server, rsa_pss_pss, _) -> 1573 Digest = {digest, sha256}, 1574 [[Digest, {rsa_padding, rsa_pss_pss}, {key, {hardcode_rsa_key(4), pss_params(sha256)}}], 1575 [Digest, {rsa_padding, rsa_pss_pss}, {key, {hardcode_rsa_key(5), pss_params(sha256)}}], 1576 [Digest, {rsa_padding, rsa_pss_pss}, {key, {hardcode_rsa_key(6), pss_params(sha256)}}]]; 1577chain_spec(_Role, dsa, _) -> 1578 Digest = {digest, appropriate_sha(crypto:supports())}, 1579 [[Digest, {key, hardcode_dsa_key(1)}], 1580 [Digest, {key, hardcode_dsa_key(2)}], 1581 [Digest, {key, hardcode_dsa_key(3)}]]. 1582 1583merge_chain_spec([], [], Acc)-> 1584 lists:reverse(Acc); 1585merge_chain_spec([User| UserRest], [Default | DefaultRest], Acc) -> 1586 Merge = merge_spec(User, Default, confs(), []), 1587 merge_chain_spec(UserRest, DefaultRest, [Merge | Acc]). 1588 1589confs() -> 1590 [key, digest, validity, extensions]. 1591 1592merge_spec(_, _, [], Acc) -> 1593 Acc; 1594merge_spec(User, Default, [Conf | Rest], Acc) -> 1595 case proplists:get_value(Conf, User, undefined) of 1596 undefined -> 1597 case proplists:get_value(Conf, Default, undefined) of 1598 undefined -> 1599 merge_spec(User, Default, Rest, Acc); 1600 Value -> 1601 merge_spec(User, Default, Rest, [{Conf, Value} | Acc]) 1602 end; 1603 Value -> 1604 merge_spec(User, Default, Rest, [{Conf, Value} | Acc]) 1605 end. 1606 1607make_mix_cert(Config) -> 1608 Ext = x509_test:extensions([{key_usage, [digitalSignature]}]), 1609 Digest = {digest, appropriate_sha(crypto:supports())}, 1610 CurveOid = pubkey_cert_records:namedCurves(?DEFAULT_CURVE), 1611 Mix = proplists:get_value(mix, Config, peer_ecc), 1612 ClientChainType =ServerChainType = mix, 1613 {ClientChain, ServerChain} = mix(Mix, Digest, CurveOid, Ext), 1614 CertChainConf = gen_conf(ClientChainType, ServerChainType, ClientChain, ServerChain), 1615 ClientFileBase = filename:join([proplists:get_value(priv_dir, Config), "mix" ++ atom_to_list(Mix)]), 1616 ServerFileBase = filename:join([proplists:get_value(priv_dir, Config), "mix" ++ atom_to_list(Mix)]), 1617 GenCertData = public_key:pkix_test_data(CertChainConf), 1618 [{server_config, ServerConf}, 1619 {client_config, ClientConf}] = 1620 x509_test:gen_pem_config_files(GenCertData, ClientFileBase, ServerFileBase), 1621 {[{verify, verify_peer} | ClientConf], 1622 [{reuseaddr, true}, {verify, verify_peer} | ServerConf] 1623 }. 1624 1625mix(peer_ecc, Digest, CurveOid, Ext) -> 1626 ClientChain = [[Digest, {key, {namedCurve, CurveOid}}], 1627 [Digest, {key, hardcode_rsa_key(1)}], 1628 [Digest, {key, {namedCurve, CurveOid}}, {extensions, Ext}] 1629 ], 1630 ServerChain = [[Digest, {key, {namedCurve, CurveOid}}], 1631 [Digest, {key, hardcode_rsa_key(2)}], 1632 [Digest, {key, {namedCurve, CurveOid}},{extensions, Ext}] 1633 ], 1634 {ClientChain, ServerChain}; 1635 1636mix(peer_rsa, Digest, CurveOid, Ext) -> 1637 ClientChain = [[Digest, {key, {namedCurve, CurveOid}}], 1638 [Digest, {key, {namedCurve, CurveOid}}], 1639 [Digest, {key, hardcode_rsa_key(1)}, {extensions, Ext}] 1640 ], 1641 ServerChain = [[Digest, {key, {namedCurve, CurveOid}}], 1642 [Digest, {key, {namedCurve, CurveOid}}], 1643 [Digest, {key, hardcode_rsa_key(2)},{extensions, Ext}] 1644 ], 1645 {ClientChain, ServerChain}. 1646 1647make_ecdsa_cert(Config) -> 1648 CryptoSupport = crypto:supports(), 1649 case proplists:get_bool(ecdsa, proplists:get_value(public_keys, CryptoSupport)) of 1650 true -> 1651 ClientFileBase = filename:join([proplists:get_value(priv_dir, Config), "ecdsa"]), 1652 ServerFileBase = filename:join([proplists:get_value(priv_dir, Config), "ecdsa"]), 1653 ClientChain = proplists:get_value(client_chain, Config, default_cert_chain_conf()), 1654 ServerChain = proplists:get_value(server_chain, Config, default_cert_chain_conf()), 1655 CertChainConf = gen_conf(ecdsa, ecdsa, ClientChain, ServerChain), 1656 GenCertData = public_key:pkix_test_data(CertChainConf), 1657 [{server_config, ServerConf}, 1658 {client_config, ClientConf}] = 1659 x509_test:gen_pem_config_files(GenCertData, ClientFileBase, ServerFileBase), 1660 [{server_ecdsa_opts, [{ssl_imp, new},{reuseaddr, true} | ServerConf]}, 1661 1662 {server_ecdsa_verify_opts, [{ssl_imp, new}, {reuseaddr, true}, 1663 {verify, verify_peer} | ServerConf]}, 1664 {client_ecdsa_opts, ClientConf} 1665 | Config]; 1666 false -> 1667 Config 1668 end. 1669make_rsa_cert(Config) -> 1670 CryptoSupport = crypto:supports(), 1671 case proplists:get_bool(rsa, proplists:get_value(public_keys, CryptoSupport)) of 1672 true -> 1673 ClientFileBase = filename:join([proplists:get_value(priv_dir, Config), "rsa"]), 1674 ServerFileBase = filename:join([proplists:get_value(priv_dir, Config), "rsa"]), 1675 ClientChain = proplists:get_value(client_chain, Config, default_cert_chain_conf()), 1676 ServerChain = proplists:get_value(server_chain, Config, default_cert_chain_conf()), 1677 CertChainConf = gen_conf(rsa, rsa, ClientChain, ServerChain), 1678 GenCertData = public_key:pkix_test_data(CertChainConf), 1679 [{server_config, ServerConf}, 1680 {client_config, ClientConf}] = 1681 x509_test:gen_pem_config_files(GenCertData, ClientFileBase, ServerFileBase), 1682 [{server_rsa_opts, [{reuseaddr, true} | ServerConf]}, 1683 1684 {server_rsa_verify_opts, [{reuseaddr, true}, 1685 {verify, verify_peer} | ServerConf]}, 1686 {client_rsa_opts, ClientConf}, 1687 {client_rsa_verify_opts, [{verify, verify_peer} |ClientConf]} 1688 | Config]; 1689 false -> 1690 Config 1691 end. 1692 1693make_rsa_1024_cert(Config) -> 1694 CryptoSupport = crypto:supports(), 1695 case proplists:get_bool(rsa, proplists:get_value(public_keys, CryptoSupport)) of 1696 true -> 1697 ClientFileBase = filename:join([proplists:get_value(priv_dir, Config), "rsa-1024"]), 1698 ServerFileBase = filename:join([proplists:get_value(priv_dir, Config), "rsa-1024"]), 1699 ClientChain = proplists:get_value(client_chain, Config, default_cert_chain_conf()), 1700 ServerChain = proplists:get_value(server_chain, Config, default_cert_chain_conf()), 1701 CertChainConf = gen_conf('rsa-1024', 'rsa-1024', ClientChain, ServerChain), 1702 GenCertData = public_key:pkix_test_data(CertChainConf), 1703 [{server_config, ServerConf}, 1704 {client_config, ClientConf}] = 1705 x509_test:gen_pem_config_files(GenCertData, ClientFileBase, ServerFileBase), 1706 [{server_rsa_1024_opts, [{ssl_imp, new},{reuseaddr, true} | ServerConf]}, 1707 1708 {server_rsa_1024_verify_opts, [{ssl_imp, new}, {reuseaddr, true}, 1709 {verify, verify_peer} | ServerConf]}, 1710 {client_rsa_1024_opts, ClientConf}, 1711 {client_rsa_1024_verify_opts, [{verify, verify_peer} |ClientConf]} 1712 | Config]; 1713 false -> 1714 Config 1715 end. 1716 1717appropriate_sha(CryptoSupport) -> 1718 Hashes = proplists:get_value(hashs, CryptoSupport), 1719 case portable_cmd("openssl", ["version"]) of 1720 "OpenSSL 0.9.8" ++ _ -> 1721 sha; 1722 _ -> 1723 case lists:member(sha256, Hashes) of 1724 true -> 1725 sha256; 1726 false -> 1727 sha 1728 end 1729 end. 1730 1731%% RFC 4492, Sect. 2.3. ECDH_RSA 1732%% 1733%% This key exchange algorithm is the same as ECDH_ECDSA except that the 1734%% server's certificate MUST be signed with RSA rather than ECDSA. 1735make_ecdh_rsa_cert(Config) -> 1736 CryptoSupport = crypto:supports(), 1737 case proplists:get_bool(ecdh, proplists:get_value(public_keys, CryptoSupport)) of 1738 true -> 1739 ClientFileBase = filename:join([proplists:get_value(priv_dir, Config), "ecdh_rsa"]), 1740 ServerFileBase = filename:join([proplists:get_value(priv_dir, Config), "ecdh_rsa"]), 1741 ClientChain = proplists:get_value(client_chain, Config, default_cert_chain_conf()), 1742 ServerChain = proplists:get_value(server_chain, Config, default_cert_chain_conf()), 1743 CertChainConf = gen_conf(ecdh_rsa, ecdh_rsa, ClientChain, ServerChain), 1744 GenCertData = public_key:pkix_test_data(CertChainConf), 1745 [{server_config, ServerConf}, 1746 {client_config, ClientConf}] = 1747 x509_test:gen_pem_config_files(GenCertData, ClientFileBase, ServerFileBase), 1748 1749 [{server_ecdh_rsa_opts, [{ssl_imp, new},{reuseaddr, true} | ServerConf]}, 1750 1751 {server_ecdh_rsa_verify_opts, [{ssl_imp, new},{reuseaddr, true}, 1752 {verify, verify_peer} | ServerConf]}, 1753 1754 {client_ecdh_rsa_opts, ClientConf} 1755 1756 | Config]; 1757 _ -> 1758 Config 1759 end. 1760 1761make_rsa_ecdsa_cert(Config, Curve) -> 1762 CryptoSupport = crypto:supports(), 1763 case proplists:get_bool(ecdh, proplists:get_value(public_keys, CryptoSupport)) of 1764 true -> 1765 ClientFileBase = filename:join([proplists:get_value(priv_dir, Config), 1766 "rsa_ecdsa_" ++ atom_to_list(Curve)]), 1767 ServerFileBase = filename:join([proplists:get_value(priv_dir, Config), 1768 "rsa_ecdsa_" ++ atom_to_list(Curve)]), 1769 ClientChain = proplists:get_value(client_chain, Config, default_cert_chain_conf()), 1770 ServerChain = proplists:get_value(server_chain, Config, default_cert_chain_conf()), 1771 CertChainConf = gen_conf(ecdh_rsa, ecdh_rsa, ClientChain, ServerChain, Curve), 1772 GenCertData = public_key:pkix_test_data(CertChainConf), 1773 [{server_config, ServerConf}, 1774 {client_config, ClientConf}] = 1775 x509_test:gen_pem_config_files(GenCertData, ClientFileBase, ServerFileBase), 1776 1777 [{server_rsa_ecdsa_opts, [{ssl_imp, new},{reuseaddr, true} | ServerConf]}, 1778 {server_rsa_ecdsa_verify_opts, [{ssl_imp, new},{reuseaddr, true}, 1779 {verify, verify_peer} | ServerConf]}, 1780 {client_rsa_ecdsa_opts, ClientConf} | Config]; 1781 _ -> 1782 Config 1783 end. 1784 1785 1786start_upgrade_server(Args) -> 1787 Node = proplists:get_value(node, Args), 1788 Result = spawn_link(Node, ?MODULE, run_upgrade_server, [Args]), 1789 receive 1790 {listen, up} -> 1791 Result 1792 end. 1793 1794run_upgrade_server(Opts) -> 1795 Port = proplists:get_value(port, Opts), 1796 TimeOut = proplists:get_value(timeout, Opts, infinity), 1797 TcpOptions = proplists:get_value(tcp_options, Opts), 1798 SslOptions = proplists:get_value(ssl_options, Opts), 1799 Pid = proplists:get_value(from, Opts), 1800 1801 ct:log("~p:~p~ngen_tcp:listen(~p, ~p)~n", [?MODULE,?LINE, Port, TcpOptions]), 1802 {ok, ListenSocket} = gen_tcp:listen(Port, TcpOptions), 1803 Pid ! {listen, up}, 1804 send_selected_port(Pid, Port, ListenSocket), 1805 ct:log("~p:~p~ngen_tcp:accept(~p)~n", [?MODULE,?LINE, ListenSocket]), 1806 {ok, AcceptSocket} = gen_tcp:accept(ListenSocket), 1807 1808 try 1809 {ok, SslAcceptSocket} = case TimeOut of 1810 infinity -> 1811 ct:log("~p:~p~nssl:handshake(~p, ~p)~n", 1812 [?MODULE,?LINE, AcceptSocket, SslOptions]), 1813 ssl:handshake(AcceptSocket, SslOptions); 1814 _ -> 1815 ct:log("~p:~p~nssl:handshake(~p, ~p, ~p)~n", 1816 [?MODULE,?LINE, AcceptSocket, SslOptions, TimeOut]), 1817 ssl:handshake(AcceptSocket, SslOptions, TimeOut) 1818 end, 1819 {Module, Function, Args} = proplists:get_value(mfa, Opts), 1820 Msg = apply(Module, Function, [SslAcceptSocket | Args]), 1821 ct:log("~p:~p~nUpgrade Server Msg: ~p ~n", [?MODULE,?LINE, Msg]), 1822 Pid ! {self(), Msg}, 1823 receive 1824 close -> 1825 ct:log("~p:~p~nUpgrade Server closing~n", [?MODULE,?LINE]), 1826 ssl:close(SslAcceptSocket) 1827 end 1828 catch error:{badmatch, Error} -> 1829 Pid ! {self(), Error} 1830 end. 1831 1832start_upgrade_client(Args) -> 1833 Node = proplists:get_value(node, Args), 1834 spawn_link(Node, ?MODULE, run_upgrade_client, [Args]). 1835 1836run_upgrade_client(Opts) -> 1837 Host = proplists:get_value(host, Opts), 1838 Port = proplists:get_value(port, Opts), 1839 Pid = proplists:get_value(from, Opts), 1840 TcpOptions = proplists:get_value(tcp_options, Opts), 1841 SslOptions = proplists:get_value(ssl_options, Opts), 1842 1843 ct:log("~p:~p~ngen_tcp:connect(~p, ~p, ~p)~n", 1844 [?MODULE,?LINE, Host, Port, TcpOptions]), 1845 {ok, Socket} = gen_tcp:connect(Host, Port, TcpOptions), 1846 1847 send_selected_port(Pid, Port, Socket), 1848 1849 ct:log("~p:~p~nssl:connect(~p, ~p)~n", [?MODULE,?LINE, Socket, SslOptions]), 1850 {ok, SslSocket} = ssl:connect(Socket, SslOptions), 1851 1852 {Module, Function, Args} = proplists:get_value(mfa, Opts), 1853 ct:log("~p:~p~napply(~p, ~p, ~p)~n", 1854 [?MODULE,?LINE, Module, Function, [SslSocket | Args]]), 1855 Msg = apply(Module, Function, [SslSocket | Args]), 1856 ct:log("~p:~p~nUpgrade Client Msg: ~p ~n", [?MODULE,?LINE, Msg]), 1857 Pid ! {self(), Msg}, 1858 receive 1859 close -> 1860 ct:log("~p:~p~nUpgrade Client closing~n", [?MODULE,?LINE]), 1861 ssl:close(SslSocket) 1862 end. 1863 1864start_upgrade_server_error(Args) -> 1865 Node = proplists:get_value(node, Args), 1866 Result = spawn_link(Node,?MODULE, run_upgrade_server_error, [Args]), 1867 receive 1868 {listen, up} -> 1869 Result 1870 end. 1871 1872run_upgrade_server_error(Opts) -> 1873 Port = proplists:get_value(port, Opts), 1874 TimeOut = proplists:get_value(timeout, Opts, infinity), 1875 TcpOptions = proplists:get_value(tcp_options, Opts), 1876 SslOptions = proplists:get_value(ssl_options, Opts), 1877 Pid = proplists:get_value(from, Opts), 1878 1879 ct:log("~p:~p~ngen_tcp:listen(~p, ~p)~n", [?MODULE,?LINE, Port, TcpOptions]), 1880 {ok, ListenSocket} = gen_tcp:listen(Port, TcpOptions), 1881 Pid ! {listen, up}, 1882 send_selected_port(Pid, Port, ListenSocket), 1883 ct:log("~p:~p~ngen_tcp:accept(~p)~n", [?MODULE,?LINE, ListenSocket]), 1884 {ok, AcceptSocket} = gen_tcp:accept(ListenSocket), 1885 Error = case TimeOut of 1886 infinity -> 1887 ct:log("~p:~p~nssl:handshake(~p, ~p)~n", 1888 [?MODULE,?LINE, AcceptSocket, SslOptions]), 1889 ssl:handshake(AcceptSocket, SslOptions); 1890 _ -> 1891 ct:log("~p:~p~nssl:ssl_handshake(~p, ~p, ~p)~n", 1892 [?MODULE,?LINE, AcceptSocket, SslOptions, TimeOut]), 1893 ssl:handshake(AcceptSocket, SslOptions, TimeOut) 1894 end, 1895 Pid ! {self(), Error}. 1896 1897start_server_error(Args) -> 1898 Result = spawn_link(?MODULE, run_server_error, [Args]), 1899 receive 1900 {listen, up} -> 1901 Result 1902 end. 1903 1904run_server_error(Opts) -> 1905 Port = proplists:get_value(port, Opts), 1906 Options = proplists:get_value(options, Opts), 1907 Pid = proplists:get_value(from, Opts), 1908 Transport = proplists:get_value(transport, Opts, ssl), 1909 ct:log("~p:~p~nssl:listen(~p, ~p)~n", [?MODULE,?LINE, Port, Options]), 1910 case Transport:listen(Port, Options) of 1911 {ok, #sslsocket{} = ListenSocket} -> 1912 %% To make sure error_client will 1913 %% get {error, closed} and not {error, connection_refused} 1914 Pid ! {listen, up}, 1915 send_selected_port(Pid, Port, ListenSocket), 1916 ct:log("~p:~p~nssl:transport_accept(~p)~n", [?MODULE,?LINE, ListenSocket]), 1917 case Transport:transport_accept(ListenSocket) of 1918 {error, _} = Error -> 1919 Pid ! {self(), Error}; 1920 {ok, AcceptSocket} -> 1921 ct:log("~p:~p~nssl:ssl_accept(~p)~n", [?MODULE,?LINE, AcceptSocket]), 1922 Error = ssl:handshake(AcceptSocket), 1923 Pid ! {self(), Error} 1924 end; 1925 {ok, ListenSocket} -> 1926 Pid ! {listen, up}, 1927 send_selected_port(Pid, Port, ListenSocket), 1928 ct:log("~p:~p~n~p:accept(~p)~n", [?MODULE,?LINE, Transport, ListenSocket]), 1929 case Transport:accept(ListenSocket) of 1930 {error, _} = Error -> 1931 Pid ! {self(), Error} 1932 end; 1933 Error -> 1934 %% Not really true but as this is an error test 1935 %% this is what we want. 1936 Pid ! {listen, up}, 1937 Pid ! {self(), Error} 1938 end. 1939 1940start_client_error(Args) -> 1941 Node = proplists:get_value(node, Args), 1942 spawn_link(Node, ?MODULE, run_client_error, [Args]). 1943 1944run_client_error(Opts) -> 1945 Host = proplists:get_value(host, Opts), 1946 Port = proplists:get_value(port, Opts), 1947 Pid = proplists:get_value(from, Opts), 1948 Transport = proplists:get_value(transport, Opts, ssl), 1949 Options = proplists:get_value(options, Opts), 1950 ct:log("~p:~p~nssl:connect(~p, ~p, ~p)~n", [?MODULE,?LINE, Host, Port, Options]), 1951 Error = Transport:connect(Host, Port, Options), 1952 case Error of 1953 {error, _} -> 1954 Pid ! {self(), Error}; 1955 {ok, _Socket} -> 1956 receive 1957 {ssl_error, _, {tls_alert, _}} = SslError -> 1958 Pid ! {self(), SslError} 1959 end; 1960 {ok, Socket, _Ext} -> 1961 ContOpts = proplists:get_value(continue_options, Opts, []), 1962 Result = Transport:handshake_continue(Socket, ContOpts), 1963 Pid ! {self(), Result} 1964 end. 1965 1966accepters(N) -> 1967 accepters([], N). 1968 1969accepters(Acc, 0) -> 1970 Acc; 1971accepters(Acc, N) -> 1972 receive 1973 {accepter, _, Server} -> 1974 accepters([Server| Acc], N-1) 1975 end. 1976 1977 1978basic_test(COpts, SOpts, Config) -> 1979 SType = proplists:get_value(server_type, Config, erlang), 1980 CType = proplists:get_value(client_type, Config, erlang), 1981 {Server, Port} = start_server(SType, COpts, SOpts, Config), 1982 Client = start_client(CType, Port, COpts, Config), 1983 gen_check_result(Server, SType, Client, CType), 1984 stop(Server, Client). 1985 1986basic_alert(ClientOpts, ServerOpts, Config, Alert) -> 1987 SType = proplists:get_value(server_type, Config), 1988 CType = proplists:get_value(client_type, Config), 1989 run_basic_alert(SType, CType, ClientOpts, ServerOpts, Config, Alert). 1990 1991run_basic_alert(erlang, erlang, ClientOpts, ServerOpts, Config, Alert) -> 1992 {ClientNode, ServerNode, Hostname} = run_where(Config), 1993 1994 Server = start_server_error([{node, ServerNode}, {port, 0}, 1995 {from, self()}, 1996 {mfa, {ssl_test_lib, no_result, []}}, 1997 {options, ServerOpts}]), 1998 1999 Port = inet_port(Server), 2000 2001 Client = start_client_error([{node, ClientNode}, {port, Port}, 2002 {host, Hostname}, 2003 {from, self()}, 2004 {mfa, {ssl_test_lib, no_result, []}}, 2005 {options, ClientOpts}]), 2006 2007 check_server_alert(Server, Client, Alert); 2008run_basic_alert(openssl = SType, erlang, ClientOpts, ServerOpts, Config, Alert) -> 2009 {ClientNode, _, Hostname} = run_where(Config), 2010 {_Server, Port} = start_server(SType, ClientOpts, ServerOpts, Config), 2011 wait_for_openssl_server(Port, proplists:get_value(protocol, Config)), 2012 Client = start_client_error([{node, ClientNode}, {port, Port}, 2013 {host, Hostname}, 2014 {from, self()}, 2015 {mfa, {ssl_test_lib, no_result, []}}, 2016 {options, ClientOpts}]), 2017 2018 check_client_alert(Client, Alert); 2019run_basic_alert(erlang, openssl = CType, ClientOpts, ServerOpts, Config, Alert) -> 2020 {_, ServerNode, Hostname} = run_where(Config), 2021 Server = start_server_error([{node, ServerNode}, {port, 0}, 2022 {host, Hostname}, 2023 {from, self()}, 2024 {mfa, {ssl_test_lib, no_result, []}}, 2025 {options, ServerOpts}]), 2026 Port = inet_port(Server), 2027 start_client(CType, Port, ClientOpts, Config), 2028 2029 check_server_alert(Server, Alert). 2030 2031 2032ecc_test(Expect, COpts, SOpts, CECCOpts, SECCOpts, Config) -> 2033 {Server, Port} = start_server_ecc(erlang, SOpts, Expect, SECCOpts, Config), 2034 Client = start_client_ecc(erlang, Port, COpts, Expect, CECCOpts, Config), 2035 check_result(Server, ok, Client, ok), 2036 stop(Server, Client). 2037 2038ecc_test_error(COpts, SOpts, CECCOpts, SECCOpts, Config) -> 2039 {Server, Port} = start_server_ecc_error(erlang, SOpts, SECCOpts, Config), 2040 Client = start_client_ecc_error(erlang, Port, COpts, CECCOpts, Config), 2041 check_server_alert(Server, Client, insufficient_security). 2042 2043start_client(openssl, Port, ClientOpts, Config) -> 2044 Version = protocol_version(Config), 2045 Exe = "openssl", 2046 Ciphers = proplists:get_value(ciphers, ClientOpts, ssl:cipher_suites(default,Version)), 2047 Groups0 = proplists:get_value(groups, ClientOpts), 2048 CertArgs = openssl_cert_options(ClientOpts, client), 2049 AlpnArgs = openssl_alpn_options(proplists:get_value(alpn, ClientOpts, undefined)), 2050 NpnArgs = openssl_npn_options(proplists:get_value(np, ClientOpts, undefined)), 2051 Reconnect = openssl_reconect_option(proplists:get_value(reconnect, ClientOpts, false)), 2052 MaxFragLen = openssl_maxfag_option(proplists:get_value(maxfrag, ClientOpts, false)), 2053 SessionArgs = proplists:get_value(session_args, ClientOpts, []), 2054 HostName = proplists:get_value(hostname, ClientOpts, net_adm:localhost()), 2055 Debug = openssl_debug_options(), 2056 2057 Exe = "openssl", 2058 Args0 = case Groups0 of 2059 undefined -> 2060 ["s_client", 2061 "-verify", "2", 2062 "-connect", hostname_format(HostName) ++ ":" ++ integer_to_list(Port), cipher_flag(Version), 2063 ciphers(Ciphers, Version), 2064 version_flag(Version)] 2065 ++ CertArgs ++ AlpnArgs ++ NpnArgs ++ Reconnect ++ MaxFragLen ++ SessionArgs 2066 ++ Debug; 2067 Group -> 2068 ["s_client", 2069 "-verify", "2", 2070 "-connect", hostname_format(HostName) ++ ":" ++ integer_to_list(Port), cipher_flag(Version), 2071 ciphers(Ciphers, Version), "-groups", Group, 2072 version_flag(Version)] 2073 ++ CertArgs ++ AlpnArgs ++ NpnArgs ++ Reconnect ++ MaxFragLen ++ SessionArgs 2074 ++ Debug 2075 end, 2076 Args = maybe_force_ipv4(Args0), 2077 OpenSslPort = portable_open_port(Exe, Args), 2078 true = port_command(OpenSslPort, "Hello world"), 2079 OpenSslPort; 2080 2081start_client(erlang, Port, ClientOpts, Config) -> 2082 {ClientNode, _, Hostname} = run_where(Config), 2083 KeyEx = proplists:get_value(check_keyex, Config, false), 2084 start_client([{node, ClientNode}, {port, Port}, 2085 {host, Hostname}, 2086 {from, self()}, 2087 {mfa, {ssl_test_lib, check_key_exchange_send_active, [KeyEx]}}, 2088 {options, ClientOpts}]). 2089 2090%% Workaround for running tests on machines where openssl 2091%% s_client would use an IPv6 address with localhost. As 2092%% this test suite and the ssl application is not prepared 2093%% for that we have to force s_client to use IPv4 if 2094%% OpenSSL supports IPv6. 2095maybe_force_ipv4(Args0) -> 2096 case is_ipv6_supported() of 2097 true -> 2098 Args0 ++ ["-4"]; 2099 false -> 2100 Args0 2101 end. 2102 2103start_client_ecc(erlang, Port, ClientOpts, Expect, ECCOpts, Config) -> 2104 {ClientNode, _, Hostname} = run_where(Config), 2105 ssl_test_lib:start_client([{node, ClientNode}, {port, Port}, 2106 {host, Hostname}, 2107 {from, self()}, 2108 {mfa, {?MODULE, check_ecc, [client, Expect]}}, 2109 {options, 2110 ECCOpts ++ 2111 [{verify, verify_peer} | ClientOpts]}]). 2112 2113start_client_ecc_error(erlang, Port, ClientOpts, ECCOpts, Config) -> 2114 {ClientNode, _, Hostname} = run_where(Config), 2115 ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port}, 2116 {host, Hostname}, 2117 {from, self()}, 2118 {options, 2119 ECCOpts ++ 2120 [{verify, verify_peer} | ClientOpts]}]). 2121 2122 2123start_server(openssl, ClientOpts, ServerOpts, Config) -> 2124 Port = inet_port(node()), 2125 Version = protocol_version(Config), 2126 Exe = "openssl", 2127 CertArgs = openssl_cert_options(ServerOpts, server), 2128 Ciphers = proplists:get_value(ciphers, ClientOpts, ssl:cipher_suites(default,Version)), 2129 Groups0 = proplists:get_value(groups, ServerOpts), 2130 SigAlgs = proplists:get_value(openssl_sigalgs, Config, undefined), 2131 SessionArgs = proplists:get_value(session_args, Config, []), 2132 Debug = openssl_debug_options(), 2133 2134 Args = case Groups0 of 2135 undefined -> 2136 ["s_server", "-accept", integer_to_list(Port), cipher_flag(Version), 2137 ciphers(Ciphers, Version), 2138 version_flag(Version)] ++ sig_algs(SigAlgs) ++ CertArgs ++ SessionArgs ++ Debug; 2139 Group -> 2140 ["s_server", "-accept", integer_to_list(Port), cipher_flag(Version), 2141 ciphers(Ciphers, Version), "-groups", Group, 2142 version_flag(Version)] ++ sig_algs(SigAlgs) ++ CertArgs ++ SessionArgs ++ Debug 2143 end, 2144 OpenSslPort = portable_open_port(Exe, Args), 2145 true = port_command(OpenSslPort, "Hello world"), 2146 {OpenSslPort, Port}; 2147start_server(erlang, _, ServerOpts, Config) -> 2148 {_, ServerNode, _} = run_where(Config), 2149 KeyEx = proplists:get_value(check_keyex, Config, false), 2150 Server = start_server([{node, ServerNode}, {port, 0}, 2151 {from, self()}, 2152 {mfa, {ssl_test_lib, 2153 check_key_exchange_send_active, 2154 [KeyEx]}}, 2155 {options, [{verify, verify_peer} | ServerOpts]}]), 2156 {Server, inet_port(Server)}. 2157 2158sig_algs(undefined) -> 2159 []; 2160sig_algs(SigAlgs) -> 2161 ["-sigalgs " ++ SigAlgs]. 2162 2163cipher_flag('tlsv1.3') -> 2164 "-ciphersuites"; 2165cipher_flag(_) -> 2166 "-cipher". 2167 2168ciphers([#{}| _] = Ciphers, Version) -> 2169 Strs = [ssl_cipher_format:suite_map_to_openssl_str(Cipher) || Cipher <- Ciphers], 2170 ciphers_concat(Version, Strs, ""); 2171ciphers(Ciphers, Version) -> 2172 ciphers_concat(Version, Ciphers, ""). 2173 2174ciphers_concat(_, [], [":" | Acc]) -> 2175 lists:append(lists:reverse(Acc)); 2176ciphers_concat('tlsv1.3' = Version, [Head| Tail], Acc) -> 2177 case Head of 2178 "TLS" ++ _ -> 2179 ciphers_concat(Version, Tail, [":", Head | Acc]); 2180 _ -> 2181 ciphers_concat(Version, Tail, Acc) 2182 end; 2183ciphers_concat(Version, [Head| Tail], Acc) -> 2184 ciphers_concat(Version, Tail, [":", Head | Acc]). 2185 2186openssl_alpn_options(undefined) -> 2187 []; 2188openssl_alpn_options(Alpn) -> 2189 ["-alpn", Alpn]. 2190 2191openssl_npn_options(undefined) -> 2192 []; 2193openssl_npn_options(Npn) -> 2194 ["-nextprotoneg", Npn]. 2195 2196openssl_reconect_option(false) -> 2197 []; 2198openssl_reconect_option(true) -> 2199 ["-reconnect"]. 2200openssl_maxfag_option(false) -> 2201 []; 2202openssl_maxfag_option(Int) -> 2203 ["-maxfraglen", integer_to_list(Int)]. 2204 2205openssl_debug_options() -> 2206 ["-msg", "-debug"]. 2207%% 2208openssl_debug_options(PrivDir) -> 2209 case is_keylogfile_supported() of 2210 true -> 2211 ["-msg", "-debug","-keylogfile", PrivDir ++ "keylog"]; 2212 false -> 2213 ["-msg", "-debug"] 2214 end. 2215 2216is_keylogfile_supported() -> 2217 [{_,_, Bin}] = crypto:info_lib(), 2218 case binary_to_list(Bin) of 2219 "OpenSSL 1.1.1" ++ _ -> 2220 true; 2221 _ -> 2222 false 2223 end. 2224 2225start_server_with_raw_key(erlang, ServerOpts, Config) -> 2226 {_, ServerNode, _} = run_where(Config), 2227 Server = start_server([{node, ServerNode}, {port, 0}, 2228 {from, self()}, 2229 {mfa, {ssl_test_lib, 2230 send_recv_result_active, 2231 []}}, 2232 {options, 2233 [{verify, verify_peer} | ServerOpts]}]), 2234 {Server, inet_port(Server)}. 2235 2236start_server_ecc(erlang, ServerOpts, Expect, ECCOpts, Config) -> 2237 {_, ServerNode, _} = run_where(Config), 2238 Server = start_server([{node, ServerNode}, {port, 0}, 2239 {from, self()}, 2240 {mfa, {?MODULE, check_ecc, [server, Expect]}}, 2241 {options, 2242 ECCOpts ++ 2243 [{verify, verify_peer} | ServerOpts]}]), 2244 {Server, inet_port(Server)}. 2245 2246start_server_ecc_error(erlang, ServerOpts, ECCOpts, Config) -> 2247 {_, ServerNode, _} = run_where(Config), 2248 Server = start_server_error([{node, ServerNode}, {port, 0}, 2249 {from, self()}, 2250 {options, 2251 ECCOpts ++ 2252 [{verify, verify_peer} | ServerOpts]}]), 2253 {Server, inet_port(Server)}. 2254 2255gen_check_result(Server, erlang, Client, erlang) -> 2256 check_result(Server, ok, Client, ok); 2257gen_check_result(Server, erlang, _, _) -> 2258 check_result(Server, ok); 2259gen_check_result(_, _, Client, erlang) -> 2260 check_result(Client, ok); 2261gen_check_result(_,openssl, _, openssl) -> 2262 ok. 2263 2264stop(Port1, Port2) when is_port(Port1), is_port(Port2) -> 2265 close_port(Port1), 2266 close_port(Port2); 2267stop(Port, Pid) when is_port(Port) -> 2268 close_port(Port), 2269 close(Pid); 2270stop(Pid, Port) when is_port(Port) -> 2271 close_port(Port), 2272 close(Pid); 2273stop(Client, Server) -> 2274 close(Server), 2275 close(Client). 2276 2277 2278openssl_cert_options(Opts, Role) -> 2279 Cert = proplists:get_value(certfile, Opts, undefined), 2280 Key = proplists:get_value(keyfile, Opts, undefined), 2281 CA = proplists:get_value(cacertfile, Opts, undefined), 2282 case CA of 2283 undefined -> 2284 case cert_option("-cert", Cert) ++ cert_option("-key", Key) of 2285 [] when Role == server -> 2286 ["-nocert"]; 2287 Other -> 2288 Other 2289 end; 2290 _ -> 2291 cert_option("-cert", Cert) ++ cert_option("-CAfile", CA) 2292 ++ cert_option("-cert_chain", CA) ++ 2293 cert_option("-key", Key) ++ openssl_verify(Opts) ++ ["2"] 2294 end. 2295 2296openssl_verify(Opts) -> 2297 case proplists:get_value(fail_if_no_peer_cert, Opts, undefined) of 2298 true -> 2299 ["-Verify"]; 2300 _ -> 2301 ["-verify"] 2302 end. 2303 2304cert_option(_, undefined) -> 2305 []; 2306cert_option("-cert_chain", Value) -> 2307 case portable_cmd("openssl", ["version"]) of 2308 "OpenSSL 1.1.1" ++ _ -> 2309 ["-cert_chain", Value]; 2310 _ -> 2311 "" 2312 end; 2313cert_option(Opt, Value) -> 2314 [Opt, Value]. 2315 2316supported_eccs(Opts) -> 2317 ToCheck = proplists:get_value(eccs, Opts, []), 2318 Supported = ssl:eccs(), 2319 lists:all(fun(Curve) -> lists:member(Curve, Supported) end, ToCheck). 2320 2321check_ecc(SSL, Role, Expect) -> 2322 {ok, Data} = ssl:connection_information(SSL), 2323 case lists:keyfind(ecc, 1, Data) of 2324 {ecc, {named_curve, Expect}} -> ok; 2325 Other -> {error, Role, Expect, Other} 2326 end. 2327 2328inet_port(Pid) when is_pid(Pid)-> 2329 receive 2330 {Pid, {port, Port}} -> 2331 Port 2332 end; 2333 2334inet_port(Node) -> 2335 {Port, Socket} = do_inet_port(Node), 2336 rpc:call(Node, gen_tcp, close, [Socket]), 2337 Port. 2338 2339do_inet_port(Node) -> 2340 {ok, Socket} = rpc:call(Node, gen_tcp, listen, [0, [{reuseaddr, true}]]), 2341 {ok, Port} = rpc:call(Node, inet, port, [Socket]), 2342 {Port, Socket}. 2343 2344no_result(_) -> 2345 no_result_msg. 2346 2347trigger_renegotiate(Socket, [ErlData, N]) -> 2348 {ok, [{session_id, Id}]} = ssl:connection_information(Socket, [session_id]), 2349 trigger_renegotiate(Socket, ErlData, N, Id). 2350 2351trigger_renegotiate(Socket, _, 0, Id) -> 2352 ct:sleep(1000), 2353 case ssl:connection_information(Socket, [session_id]) of 2354 {ok, [{session_id, Id}]} -> 2355 fail_session_not_renegotiated; 2356 %% Tests that uses this function will not reuse 2357 %% sessions so if we get a new session id the 2358 %% renegotiation has succeeded. 2359 {ok, [{session_id, _}]} -> 2360 ok; 2361 {error, closed} -> 2362 fail_session_fatal_alert_during_renegotiation; 2363 {error, timeout} -> 2364 fail_timeout 2365 end; 2366 2367trigger_renegotiate(Socket, ErlData, N, Id) -> 2368 ssl:send(Socket, ErlData), 2369 trigger_renegotiate(Socket, ErlData, N-1, Id). 2370 2371 2372send_selected_port(Pid, 0, #sslsocket{} = Socket) -> 2373 {ok, {_, NewPort}} = ssl:sockname(Socket), 2374 Pid ! {self(), {port, NewPort}}; 2375send_selected_port(Pid, 0, Socket) -> 2376 {ok, {_, NewPort}} = inet:sockname(Socket), 2377 Pid ! {self(), {port, NewPort}}; 2378send_selected_port(_,_,_) -> 2379 ok. 2380 2381 2382available_suites(Version) -> 2383 [ssl_cipher_format:suite_bin_to_map(Suite) || 2384 Suite <- ssl_cipher:filter_suites(ssl_cipher:suites(Version))]. 2385 2386 2387rsa_non_signed_suites(Version) -> 2388 lists:filter(fun({rsa, _, _}) -> 2389 false; 2390 (_) -> 2391 true 2392 end, 2393 available_suites(Version)). 2394 2395ecdsa_suites(Version) -> 2396 lists:filter(fun({ecdhe_ecdsa, _, _}) -> 2397 true; 2398 (_) -> 2399 false 2400 end, 2401 available_suites(Version)). 2402 2403openssl_dsa_suites() -> 2404 Ciphers = ssl:cipher_suites(openssl), 2405 lists:filter(fun(Str) -> string_regex_filter(Str, "DSS") 2406 end, Ciphers). 2407 2408openssl_ecdsa_suites() -> 2409 Ciphers = ssl:cipher_suites(openssl), 2410 lists:filter(fun(Str) -> string_regex_filter(Str, "ECDHE-ECDSA") 2411 end, Ciphers). 2412 2413 2414openssl_filter(FilterStr) -> 2415 Ciphers = string:tokens(portable_cmd("openssl", ["ciphers"]), ":"), 2416 lists:filter(fun(Str) -> string_regex_filter(Str, FilterStr) 2417 end, Ciphers). 2418 2419 2420string_regex_filter(Str, Search) when is_list(Str) -> 2421 case re:run(Str, Search, []) of 2422 nomatch -> 2423 false; 2424 _ -> 2425 true 2426 end; 2427string_regex_filter(_Str, _Search) -> 2428 false. 2429 2430ecdh_dh_anonymous_suites(Version) -> 2431 ssl:filter_cipher_suites([ssl_cipher_format:suite_bin_to_map(S) || S <- ssl_cipher:anonymous_suites(Version)], 2432 [{key_exchange, 2433 fun(dh_anon) -> 2434 true; 2435 (ecdh_anon) -> 2436 true; 2437 (_) -> 2438 false 2439 end}]). 2440 2441pem_to_der(File) -> 2442 {ok, PemBin} = file:read_file(File), 2443 public_key:pem_decode(PemBin). 2444 2445der_to_pem(File, Entries) -> 2446 PemBin = public_key:pem_encode(Entries), 2447 file:write_file(File, PemBin). 2448 2449cipher_result(Socket, Result) -> 2450 {ok, Info} = ssl:connection_information(Socket), 2451 Result = {ok, {proplists:get_value(protocol, Info), proplists:get_value(selected_cipher_suite, Info)}}, 2452 ct:log("~p:~p~nSuccessfull connect: ~p~n", [?MODULE,?LINE, Result]), 2453 %% Importante to send two packets here 2454 %% to properly test "cipher state" handling 2455 Hello = "Hello\n", 2456 World = " world\n", 2457 ssl:send(Socket, Hello), 2458 ct:sleep(500), 2459 ssl:send(Socket, World), 2460 Expected = Hello ++ World, 2461 Expected = active_recv(Socket, length(Expected)), 2462 ok. 2463 2464session_info_result(Socket) -> 2465 {ok, Info} = ssl:connection_information(Socket, [session_id, cipher_suite]), 2466 Info. 2467 2468public_key(#'PrivateKeyInfo'{privateKeyAlgorithm = 2469 #'PrivateKeyInfo_privateKeyAlgorithm'{algorithm = ?rsaEncryption}, 2470 privateKey = Key}) -> 2471 public_key:der_decode('RSAPrivateKey', iolist_to_binary(Key)); 2472 2473public_key(#'PrivateKeyInfo'{privateKeyAlgorithm = 2474 #'PrivateKeyInfo_privateKeyAlgorithm'{algorithm = ?'id-dsa'}, 2475 privateKey = Key}) -> 2476 public_key:der_decode('DSAPrivateKey', iolist_to_binary(Key)); 2477public_key(Key) -> 2478 Key. 2479 2480state([{data,[{"State", {_StateName, StateData}}]} | _]) -> %% gen_statem 2481 StateData; 2482state([{data,[{"State", State}]} | _]) -> %% gen_server 2483 State; 2484state([{data,[{"StateData", State}]} | _]) -> %% gen_fsm 2485 State; 2486state([_ | Rest]) -> 2487 state(Rest). 2488 2489is_protocol_version(Ver) -> 2490 is_tls_version(Ver) orelse 2491 is_dtls_version(Ver). 2492 2493is_tls_version('tlsv1.3') -> 2494 true; 2495is_tls_version('tlsv1.2') -> 2496 true; 2497is_tls_version('tlsv1.1') -> 2498 true; 2499is_tls_version('tlsv1') -> 2500 true; 2501is_tls_version(_) -> 2502 false. 2503 2504is_dtls_version('dtlsv1.2') -> 2505 true; 2506is_dtls_version('dtlsv1') -> 2507 true; 2508is_dtls_version(_) -> 2509 false. 2510 2511openssl_tls_version_support(Version, Config0) -> 2512 %% Check if version is supported 2513 Config = make_rsa_cert(Config0), 2514 ServerOpts = proplists:get_value(server_rsa_opts, Config), 2515 Port = inet_port(node()), 2516 CaCertFile = proplists:get_value(cacertfile, ServerOpts), 2517 CertFile = proplists:get_value(certfile, ServerOpts), 2518 KeyFile = proplists:get_value(keyfile, ServerOpts), 2519 Exe = "openssl", 2520 Args0 = ["s_server", "-accept", 2521 integer_to_list(Port), "-CAfile", CaCertFile, 2522 "-cert", CertFile,"-key", KeyFile], 2523 Args = maybe_force_ipv4(Args0), 2524 OpensslPort = portable_open_port(Exe, Args), 2525 2526 try wait_for_openssl_server(Port, tls) of 2527 ok -> 2528 case ssl:connect("localhost", Port, [{versions, [Version]}]) of 2529 {ok, Socket} -> 2530 ssl:close(Socket), 2531 close_port(OpensslPort), 2532 true; 2533 {error, {tls_alert, {protocol_version, _}}} -> 2534 ct:pal("Openssl does not support ~p", [Version]), 2535 close_port(OpensslPort), 2536 false; 2537 {error, {tls_alert, Alert}} -> 2538 ct:pal("Openssl returned alert ~p", [Alert]), 2539 close_port(OpensslPort), 2540 false 2541 end 2542 catch 2543 _:_ -> 2544 ct:pal("Openssl does not support ~p", [Version]), 2545 close_port(OpensslPort), 2546 false 2547 end. 2548 2549init_protocol_version(Version, Config) 2550 when Version == 'dtlsv1.2'; Version == 'dtlsv1' -> 2551 ssl:stop(), 2552 application:load(ssl), 2553 application:set_env(ssl, dtls_protocol_version, [Version]), 2554 ssl:start(), 2555 NewConfig = proplists:delete(protocol_opts, proplists:delete(protocol, Config)), 2556 [{protocol, dtls}, {protocol_opts, [{protocol, dtls}]} | NewConfig]; 2557 2558init_protocol_version(Version, Config) -> 2559 ssl:stop(), 2560 application:load(ssl), 2561 application:set_env(ssl, protocol_version, [Version]), 2562 ssl:start(), 2563 NewConfig = proplists:delete(protocol_opts, proplists:delete(protocol, Config)), 2564 [{protocol, tls} | NewConfig]. 2565 2566clean_protocol_version(Config) -> 2567 proplists:delete(version, proplists:delete(protocol_opts, proplists:delete(protocol, Config))). 2568 2569sufficient_crypto_support(Version) 2570 when Version == 'tlsv1.3' -> 2571 CryptoSupport = crypto:supports(), 2572 lists:member(rsa_pkcs1_pss_padding, proplists:get_value(rsa_opts, CryptoSupport)) andalso 2573 lists:member(x448, proplists:get_value(curves, CryptoSupport)); 2574sufficient_crypto_support(Version) 2575 when Version == 'tlsv1.2'; Version == 'dtlsv1.2' -> 2576 CryptoSupport = crypto:supports(), 2577 proplists:get_bool(sha256, proplists:get_value(hashs, CryptoSupport)); 2578sufficient_crypto_support(cipher_ec) -> 2579 CryptoSupport = crypto:supports(), 2580 proplists:get_bool(ecdh, proplists:get_value(public_keys, CryptoSupport)); 2581sufficient_crypto_support(_) -> 2582 true. 2583 2584check_key_exchange_send_active(Socket, false) -> 2585 send_recv_result_active(Socket); 2586check_key_exchange_send_active(Socket, KeyEx) -> 2587 {ok, Info} = 2588 ssl:connection_information(Socket, [cipher_suite, protocol]), 2589 Suite = proplists:get_value(cipher_suite, Info), 2590 Version = proplists:get_value(protocol, Info), 2591 true = check_key_exchange(Suite, KeyEx, Version), 2592 send_recv_result_active(Socket). 2593 2594check_key_exchange({KeyEx,_, _}, KeyEx, _) -> 2595 ct:pal("Kex: ~p", [KeyEx]), 2596 true; 2597check_key_exchange({KeyEx,_,_,_}, KeyEx, _) -> 2598 ct:pal("Kex: ~p", [KeyEx]), 2599 true; 2600check_key_exchange(KeyEx1, KeyEx2, Version) -> 2601 ct:pal("Kex: ~p ~p", [KeyEx1, KeyEx2]), 2602 case Version of 2603 'tlsv1.2' -> 2604 v_1_2_check(element(1, KeyEx1), KeyEx2); 2605 'dtlsv1.2' -> 2606 v_1_2_check(element(1, KeyEx1), KeyEx2); 2607 _ -> 2608 ct:pal("Negotiated ~p Expected ~p", [KeyEx1, KeyEx2]), 2609 false 2610 end. 2611 2612v_1_2_check(ecdh_ecdsa, ecdh_rsa) -> 2613 true; 2614v_1_2_check(ecdh_rsa, ecdh_ecdsa) -> 2615 true; 2616v_1_2_check(_, _) -> 2617 false. 2618 2619send_recv_result(Socket) -> 2620 Data = "Hello world", 2621 ssl:send(Socket, Data), 2622 {ok, Data} = ssl:recv(Socket, length(Data)), 2623 ok. 2624 2625send_recv_result_active(Socket) -> 2626 Data = "Hello world", 2627 ssl:send(Socket, Data), 2628 Data = active_recv(Socket, length(Data)), 2629 ok. 2630 2631send_recv_result_active(Socket, Data) -> 2632 ssl:send(Socket, Data), 2633 Data = active_recv(Socket, length(Data)), 2634 ok. 2635 2636send(Pid, Data) -> 2637 Pid ! {data, Data}, 2638 receive 2639 {Pid, ok} -> 2640 ok; 2641 {Pid, Reason} -> 2642 {error, Reason} 2643 end. 2644 2645check_active_receive(Pid, Data) -> 2646 Pid ! {active_receive, Data}, 2647 check_active_receive_loop(Pid, Data). 2648 2649check_active_receive_loop(Pid, Data) -> 2650 receive 2651 {Pid, Data} -> 2652 ct:log("(~p) Received: ~p~n (from ~p)~n", [self(), Data, Pid]), 2653 Data; 2654 {Pid, Data2} -> 2655 ct:log("(~p) Received unexpected message: ~p~n (from ~p)~n", 2656 [self(), Data2, Pid]), 2657 check_active_receive_loop(Pid, Data) 2658 end. 2659 2660update_keys(Pid, Type) -> 2661 Pid ! {update_keys, Type}, 2662 receive 2663 {Pid, ok} -> 2664 ok; 2665 {Pid, Reason} -> 2666 {error, Reason} 2667 end. 2668 2669send_recv_result_active_once(Socket) -> 2670 Data = "Hello world", 2671 ssl:send(Socket, Data), 2672 active_once_recv_list(Socket, length(Data)). 2673 2674%% This function can verify the following functionalities in clients: 2675%% - session resumption, sending/receiving application data, receiving session tickets 2676%% - verifying if client early data is accepted/rejected 2677verify_active_session_resumption(Socket, SessionResumption) -> 2678 verify_active_session_resumption(Socket, SessionResumption, wait_reply, no_tickets, no_early_data). 2679%% 2680verify_active_session_resumption(Socket, SessionResumption, WaitReply) -> 2681 verify_active_session_resumption(Socket, SessionResumption, WaitReply, no_tickets, no_early_data). 2682%% 2683verify_active_session_resumption(Socket, SessionResumption, WaitReply, TicketOption) -> 2684 verify_active_session_resumption(Socket, SessionResumption, WaitReply, TicketOption, no_early_data). 2685%% 2686verify_active_session_resumption(Socket, SessionResumption, WaitForReply, TicketOption, EarlyData) -> 2687 case ssl:connection_information(Socket, [session_resumption]) of 2688 {ok, [{session_resumption, SessionResumption}]} -> 2689 Msg = boolean_to_log_msg(SessionResumption), 2690 ct:log("~p:~p~nSession resumption verified! (expected ~p, got ~p)!", 2691 [?MODULE, ?LINE, Msg, Msg]); 2692 {ok, [{session_resumption, Got0}]} -> 2693 Expected = boolean_to_log_msg(SessionResumption), 2694 Got = boolean_to_log_msg(Got0), 2695 ct:fail("~p:~p~nFailed to verify session resumption! (expected ~p, got ~p)", 2696 [?MODULE, ?LINE, Expected, Got]); 2697 {error, Reason} -> 2698 ct:fail("~p:~p~nFailed to verify session resumption! Reason: ~p", 2699 [?MODULE, ?LINE, Reason]) 2700 end, 2701 2702 Data = "Hello world", 2703 ssl:send(Socket, Data), 2704 case WaitForReply of 2705 wait_reply -> 2706 Data = active_recv(Socket, length(Data)); 2707 no_reply -> 2708 ok; 2709 Else1 -> 2710 ct:fail("~p:~p~nFaulty parameter: ~p", [?MODULE, ?LINE, Else1]) 2711 end, 2712 Tickets = 2713 case TicketOption of 2714 {tickets, N} -> 2715 receive_tickets(N); 2716 no_tickets -> 2717 ok; 2718 Else2 -> 2719 ct:fail("~p:~p~nFaulty parameter: ~p", [?MODULE, ?LINE, Else2]) 2720 end, 2721 case EarlyData of 2722 {verify_early_data, Atom} -> 2723 case verify_early_data(Atom) of 2724 ok -> 2725 Tickets; 2726 Else -> 2727 ct:fail("~p:~p~nFailed to verify early_data! (expected ~p, got ~p)", 2728 [?MODULE, ?LINE, Atom, Else]) 2729 end; 2730 no_early_data -> 2731 Tickets; 2732 Else3 -> 2733 ct:fail("~p:~p~nFaulty parameter: ~p", [?MODULE, ?LINE, Else3]) 2734 end. 2735 2736verify_server_early_data(Socket, WaitForReply, EarlyData) -> 2737 case ssl:connection_information(Socket, [session_resumption]) of 2738 {ok, [{session_resumption, true}]} -> 2739 Msg = boolean_to_log_msg(true), 2740 ct:log("~p:~p~nSession resumption verified! (expected ~p, got ~p)!", 2741 [?MODULE, ?LINE, Msg, Msg]); 2742 {ok, [{session_resumption, Got0}]} -> 2743 Expected = boolean_to_log_msg(true), 2744 Got = boolean_to_log_msg(Got0), 2745 ct:fail("~p:~p~nFailed to verify session resumption! (expected ~p, got ~p)", 2746 [?MODULE, ?LINE, Expected, Got]); 2747 {error, Reason} -> 2748 ct:fail("~p:~p~nFailed to verify session resumption! Reason: ~p", 2749 [?MODULE, ?LINE, Reason]) 2750 end, 2751 Data = "Hello world", 2752 ssl:send(Socket, Data), 2753 Reply = 2754 case EarlyData of 2755 no_early_data -> 2756 Data; 2757 _ -> 2758 binary_to_list(EarlyData) ++ Data 2759 end, 2760 ct:log("Expected Reply: ~p~n", [Reply]), 2761 case WaitForReply of 2762 wait_reply -> 2763 Reply = active_recv(Socket, length(Reply)); 2764 no_reply -> 2765 ok; 2766 Else1 -> 2767 ct:fail("~p:~p~nFaulty parameter: ~p", [?MODULE, ?LINE, Else1]) 2768 end, 2769 ok. 2770 2771verify_session_ticket_extension([Ticket0|_], MaxEarlyDataSize) -> 2772 #{ticket := #new_session_ticket{ 2773 extensions = #{early_data := 2774 #early_data_indication_nst{ 2775 indication = Size}}}} = Ticket0, 2776 case Size of 2777 MaxEarlyDataSize -> 2778 ct:log("~p:~p~nmax_early_data_size verified! (expected ~p, got ~p)!", 2779 [?MODULE, ?LINE, MaxEarlyDataSize, Size]); 2780 Else -> 2781 ct:log("~p:~p~nFailed to verify max_early_data_size! (expected ~p, got ~p)!", 2782 [?MODULE, ?LINE, MaxEarlyDataSize, Else]) 2783 end. 2784 2785update_session_ticket_extension([Ticket|_], MaxEarlyDataSize) -> 2786 #{ticket := #new_session_ticket{ 2787 extensions = #{early_data := 2788 #early_data_indication_nst{ 2789 indication = Size}}}} = Ticket, 2790 ct:log("~p:~p~nOverwrite max_early_data_size (from ~p to ~p)!", 2791 [?MODULE, ?LINE, Size, MaxEarlyDataSize]), 2792 #{ticket := #new_session_ticket{ 2793 extensions = #{early_data := Extensions0}} = NST0} = Ticket, 2794 Extensions = #{early_data => #early_data_indication_nst{ 2795 indication = MaxEarlyDataSize}}, 2796 NST = NST0#new_session_ticket{extensions = Extensions}, 2797 [Ticket#{ticket => NST}]. 2798 2799boolean_to_log_msg(true) -> 2800 "OK"; 2801boolean_to_log_msg(false) -> 2802 "FAIL". 2803 2804receive_tickets(N) -> 2805 receive_tickets(N, []). 2806%% 2807receive_tickets(0, Acc) -> 2808 Acc; 2809receive_tickets(N, Acc) -> 2810 receive 2811 {ssl, session_ticket, Ticket} -> 2812 receive_tickets(N - 1, [Ticket|Acc]) 2813 end. 2814 2815check_tickets(Client) -> 2816 receive 2817 {Client, Tickets} -> 2818 Tickets 2819 after 2820 5000 -> 2821 ct:fail("~p:~p~nNo tickets received!", [?MODULE, ?LINE]) 2822 end. 2823 2824active_recv_loop(Pid, SslPort, Data) -> 2825 case active_recv(SslPort, length(Data)) of 2826 Data -> 2827 ct:log("(~p) [openssl server] Received: ~p~n (forward to PID=~p)~n", 2828 [self(), Data, Pid]), 2829 Pid ! {self(), Data}; 2830 Unexpected -> 2831 ct:log("(~p) [openssl server] Received unexpected: ~p~n (dropping message)~n", [self(), Unexpected]), 2832 active_recv_loop(Pid, SslPort, Data) 2833 end. 2834 2835active_recv(Socket, N) -> 2836 active_recv(Socket, N, []). 2837 2838active_recv(_Socket, 0, Acc) -> 2839 Acc; 2840active_recv(_Socket, N, Acc) when N < 0 -> 2841 {_, T} = lists:split(0 - N, Acc), 2842 T; 2843active_recv(Socket, N, Acc) -> 2844 receive 2845 %% Filter {ssl, Socket, {early_data, Atom}} messages 2846 {ssl, Socket, Bytes} when not is_tuple(Bytes) -> 2847 active_recv(Socket, N-data_length(Bytes), Acc ++ Bytes); 2848 {Socket, {data, Bytes0}} -> 2849 Bytes = filter_openssl_debug_data(Bytes0), 2850 active_recv(Socket, N-data_length(Bytes), Acc ++ Bytes) 2851 end. 2852 2853 2854data_length(Bytes) when is_list(Bytes) -> 2855 length(Bytes); 2856data_length(Bytes) when is_binary(Bytes)-> 2857 size(Bytes). 2858 2859filter_openssl_debug_data(Bytes) -> 2860 re:replace(Bytes, 2861 "(read.*\n|write to.*\n|[\\dabcdefABCDEF]{4,4} -.*\n|>>> .*\n|<<< .*\n| \\d\\d.*\n|KEYUPDATE\n|.*Read BLOCK\n)*", 2862 "", [global,{return, list}]). 2863 2864active_once_recv(_Socket, 0) -> 2865 ok; 2866active_once_recv(Socket, N) -> 2867 receive 2868 {ssl, Socket, Bytes} -> 2869 ssl:setopts(Socket, [{active, once}]), 2870 active_once_recv(Socket, N-byte_size(Bytes)) 2871 end. 2872 2873active_once_recv_list(_Socket, 0) -> 2874 ok; 2875active_once_recv_list(Socket, N) -> 2876 receive 2877 {ssl, Socket, Bytes} -> 2878 ssl:setopts(Socket, [{active, once}]), 2879 active_once_recv_list(Socket, N-length(Bytes)) 2880 end. 2881recv_disregard(_Socket, 0) -> 2882 ok; 2883recv_disregard(Socket, N) -> 2884 {ok, Bytes} = ssl:recv(Socket, 0), 2885 recv_disregard(Socket, N-byte_size(Bytes)). 2886 2887active_disregard(_Socket, 0) -> 2888 ok; 2889active_disregard(Socket, N) -> 2890 receive 2891 {ssl, Socket, Bytes} -> 2892 active_disregard(Socket, N-byte_size(Bytes)) 2893 end. 2894active_once_disregard(_Socket, 0) -> 2895 ok; 2896active_once_disregard(Socket, N) -> 2897 receive 2898 {ssl, Socket, Bytes} -> 2899 ssl:setopts(Socket, [{active, once}]), 2900 active_once_disregard(Socket, N-byte_size(Bytes)) 2901 end. 2902 2903is_ipv6_supported() -> 2904 case portable_cmd("openssl", ["version"]) of 2905 "OpenSSL 0.9.8" ++ _ -> % Does not support IPv6 2906 false; 2907 "OpenSSL 1.0" ++ _ -> % Does not support IPv6 2908 false; 2909 "LibreSSL 3" ++ _-> 2910 false; 2911 _ -> 2912 true 2913 end. 2914 2915 2916is_sane_oppenssl_client() -> 2917 [{_,_, Bin}] = crypto:info_lib(), 2918 case binary_to_list(Bin) of 2919 "OpenSSL 0.9" ++ _ -> 2920 false; 2921 _ -> 2922 true 2923 end. 2924 2925is_sane_oppenssl_pss(rsa_pss_pss) -> 2926 case portable_cmd("openssl",["version"]) of 2927 "OpenSSL 1.1.1" ++ Rest -> 2928 hd(Rest) >= $c; 2929 _ -> 2930 false 2931 end; 2932is_sane_oppenssl_pss(rsa_pss_rsae) -> 2933 case portable_cmd("openssl",["version"]) of 2934 "OpenSSL 1.1.1" ++ _ -> 2935 true; 2936 _ -> 2937 false 2938 end. 2939 2940is_fips(openssl) -> 2941 VersionStr = portable_cmd("openssl",["version"]), 2942 case re:split(VersionStr, "fips") of 2943 [_] -> 2944 false; 2945 _ -> 2946 true 2947 end; 2948is_fips(crypto) -> 2949 [{_,_, Bin}] = crypto:info_lib(), 2950 case re:split(Bin, <<"fips">>) of 2951 [_] -> 2952 false; 2953 _ -> 2954 true 2955 end; 2956is_fips(_) -> 2957 false. 2958 2959%% Acctual support is tested elsewhere, this is to exclude some LibreSSL and OpenSSL versions 2960openssl_sane_dtls() -> 2961 case portable_cmd("openssl", ["version"]) of 2962 "OpenSSL 0." ++ _ -> 2963 false; 2964 "OpenSSL 1.0.1s-freebsd" ++ _ -> 2965 false; 2966 "OpenSSL 1.0.2k-freebsd" ++ _ -> 2967 false; 2968 "OpenSSL 1.0.2" ++ _ -> 2969 false; 2970 "OpenSSL 1.0.0" ++ _ -> 2971 false; 2972 "OpenSSL" ++ _ -> 2973 true; 2974 "LibreSSL 2.7" ++ _ -> 2975 true; 2976 _ -> 2977 false 2978 end. 2979 2980check_sane_openssl_version(Version) -> 2981 case supports_ssl_tls_version(Version) of 2982 true -> 2983 case {Version, portable_cmd("openssl",["version"])} of 2984 {'dtlsv1', "OpenSSL 0" ++ _} -> 2985 false; 2986 {'dtlsv1.2', "OpenSSL 0" ++ _} -> 2987 false; 2988 {'dtlsv1.2', "OpenSSL 1.0.2" ++ _} -> 2989 false; 2990 {'dtlsv1', "OpenSSL 1.0.0" ++ _} -> 2991 false; 2992 {'dtlsv1', _} -> 2993 not is_fips(openssl); 2994 {'dtlsv1.2', _} -> 2995 not is_fips(openssl); 2996 {_, "OpenSSL 1.0.2" ++ _} -> 2997 true; 2998 {_, "OpenSSL 1.0.1" ++ _} -> 2999 true; 3000 {'tlsv1.2', "OpenSSL 1.0.0" ++ _} -> 3001 false; 3002 {'tlsv1.1', "OpenSSL 1.0.0" ++ _} -> 3003 false; 3004 {'tlsv1.2', "OpenSSL 0" ++ _} -> 3005 false; 3006 {'tlsv1.1', "OpenSSL 0" ++ _} -> 3007 false; 3008 {'tlsv1', "OpenSSL 0" ++ _} -> 3009 false; 3010 {_, _} -> 3011 true 3012 end; 3013 false -> 3014 false 3015 end. 3016check_sane_openssl_renegotiate(Config, Version) when Version == 'tlsv1'; 3017 Version == 'tlsv1.1'; 3018 Version == 'tlsv1.2' -> 3019 case portable_cmd("openssl", ["version"]) of 3020 "OpenSSL 1.0.1c" ++ _ -> 3021 {skip, "Known renegotiation bug in OpenSSL"}; 3022 "OpenSSL 1.0.1b" ++ _ -> 3023 {skip, "Known renegotiation bug in OpenSSL"}; 3024 "OpenSSL 1.0.1a" ++ _ -> 3025 {skip, "Known renegotiation bug in OpenSSL"}; 3026 "OpenSSL 1.0.1 " ++ _ -> 3027 {skip, "Known renegotiation bug in OpenSSL"}; 3028 "LibreSSL 3.0.2" ++ _ -> 3029 {skip, "Known renegotiation bug in LibreSSL"}; 3030 "LibreSSL 3.1" ++ _ -> 3031 {skip, "Known renegotiation bug in LibreSSL"}; 3032 _ -> 3033 check_sane_openssl_renegotiate(Config) 3034 end; 3035check_sane_openssl_renegotiate(Config, _) -> 3036 check_sane_openssl_renegotiate(Config). 3037 3038check_sane_openssl_renegotiate(Config) -> 3039 case portable_cmd("openssl", ["version"]) of 3040 "OpenSSL 1.0.0" ++ _ -> 3041 {skip, "Known renegotiation bug in OpenSSL"}; 3042 "OpenSSL 0.9.8" ++ _ -> 3043 {skip, "Known renegotiation bug in OpenSSL"}; 3044 "OpenSSL 0.9.7" ++ _ -> 3045 {skip, "Known renegotiation bug in OpenSSL"}; 3046 "LibreSSL 2." ++ _ -> 3047 {skip, "Known renegotiation bug in LibreSSL"}; 3048 "LibreSSL 3." ++ _ -> 3049 {skip, "Known renegotiation bug in LibreSSL"}; 3050 _ -> 3051 Config 3052 end. 3053 3054openssl_allows_client_renegotiate(Config) -> 3055 case portable_cmd("openssl", ["version"]) of 3056 "OpenSSL 1.1" ++ _ -> 3057 {skip, "OpenSSL does not allow client renegotiation"}; 3058 "LibreSSL" ++ _ -> 3059 {skip, "LibreSSL does not allow client renegotiation"}; 3060 _ -> 3061 Config 3062 end. 3063 3064openssl_allows_server_renegotiate(Config) -> 3065 case portable_cmd("openssl", ["version"]) of 3066 "LibreSSL 3.1" ++ _ -> 3067 {skip, "LibreSSL 3.1 does not allow server renegotiation"}; 3068 _ -> 3069 Config 3070 end. 3071 3072 3073enough_openssl_crl_support("OpenSSL 0." ++ _) -> false; 3074enough_openssl_crl_support(_) -> true. 3075 3076wait_for_openssl_server(Port, tls) -> 3077 do_wait_for_openssl_tls_server(Port, 10); 3078wait_for_openssl_server(_Port, dtls) -> 3079 ok. %% No need to wait for DTLS over UDP server 3080 %% client will retransmitt until it is up. 3081 3082do_wait_for_openssl_tls_server(_, 0) -> 3083 exit(failed_to_connect_to_openssl); 3084do_wait_for_openssl_tls_server(Port, N) -> 3085 case gen_tcp:connect("localhost", Port, []) of 3086 {ok, S} -> 3087 gen_tcp:close(S), 3088 ok; 3089 _ -> 3090 ct:sleep(?SLEEP), 3091 do_wait_for_openssl_tls_server(Port, N-1) 3092 end. 3093 3094version_flag(tlsv1) -> 3095 "-tls1"; 3096version_flag('tlsv1.1') -> 3097 "-tls1_1"; 3098version_flag('tlsv1.2') -> 3099 "-tls1_2"; 3100version_flag('tlsv1.3') -> 3101 "-tls1_3"; 3102version_flag(sslv3) -> 3103 "-ssl3"; 3104version_flag(sslv2) -> 3105 "-ssl2"; 3106version_flag('dtlsv1.2') -> 3107 "-dtls1_2"; 3108version_flag('dtlsv1') -> 3109 "-dtls1". 3110 3111-define(OPENSSL_QUIT, "Q\n"). 3112close_port(Port) -> 3113 catch port_command(Port, ?OPENSSL_QUIT), 3114 close_loop(Port, 500, false). 3115 3116close_loop(Port, Time, SentClose) -> 3117 receive 3118 {Port, {data,Debug}} when is_port(Port) -> 3119 ct:log("openssl ~s~n",[Debug]), 3120 close_loop(Port, Time, SentClose); 3121 {ssl,_,Msg} -> 3122 ct:log("ssl Msg ~s~n",[Msg]), 3123 close_loop(Port, Time, SentClose); 3124 {Port, closed} -> 3125 ct:log("Port Closed~n",[]), 3126 ok; 3127 {'EXIT', Port, Reason} -> 3128 ct:log("Port Closed ~p~n",[Reason]), 3129 ok; 3130 Msg -> 3131 ct:log("Port Msg ~p~n",[Msg]), 3132 close_loop(Port, Time, SentClose) 3133 after Time -> 3134 case SentClose of 3135 false -> 3136 ct:log("Closing port ~n",[]), 3137 catch erlang:port_close(Port), 3138 close_loop(Port, Time, true); 3139 true -> 3140 ct:log("Timeout~n",[]) 3141 end 3142 end. 3143 3144portable_open_port("openssl" = Exe, Args0) -> 3145 IsWindows = case os:type() of 3146 {win32, _} -> true; 3147 _ -> false 3148 end, 3149 case IsWindows andalso os:getenv("WSLENV") of 3150 false -> 3151 AbsPath = os:find_executable(Exe), 3152 ct:pal("open_port({spawn_executable, ~p}, [{args, ~p}, stderr_to_stdout]).", 3153 [AbsPath, Args0]), 3154 open_port({spawn_executable, AbsPath}, 3155 [{args, Args0}, stderr_to_stdout]); 3156 _ -> 3157 %% I can't get the new windows version of openssl.exe to be stable 3158 %% certain server tests are failing for no reason. 3159 %% This is using "linux" openssl via wslenv 3160 3161 Translate = fun([_Drive|":/" ++ _ ]= Path) -> 3162 string:trim(os:cmd("wsl wslpath -u " ++ Path)); 3163 (Arg) -> 3164 Arg 3165 end, 3166 Args1 = [Translate(Arg) || Arg <- Args0], 3167 Args = ["/C","wsl","openssl"| Args1] ++ ["2>&1"], 3168 Cmd = os:find_executable("cmd"), 3169 ct:pal("open_port({spawn_executable, ~p}, [{args, ~p}, stderr_to_stdout]).", [Cmd,Args]), 3170 open_port({spawn_executable, Cmd}, 3171 [{args, Args}, stderr_to_stdout, hide]) 3172 end; 3173portable_open_port(Exe, Args) -> 3174 AbsPath = os:find_executable(Exe), 3175 ct:pal("open_port({spawn_executable, ~p}, [{args, ~p}, stderr_to_stdout]).", [AbsPath, Args]), 3176 open_port({spawn_executable, AbsPath}, 3177 [{args, Args}, stderr_to_stdout]). 3178 3179portable_cmd(Exe, Args) -> 3180 Port = portable_open_port(Exe, Args), 3181 receive 3182 {Port, {data, Data}} -> 3183 catch erlang:port_close(Port), 3184 Data 3185 end. 3186 3187supports_ssl_tls_version(Version) when Version == sslv2; 3188 Version == sslv3 -> 3189 3190 case ubuntu_legacy_support() of 3191 true -> 3192 case portable_cmd("openssl", ["version"]) of 3193 "OpenSSL 1.0.1" ++ _ -> 3194 Version =/= sslv2; 3195 "OpenSSL 1" ++ _ -> 3196 false; 3197 %% Appears to be broken 3198 "OpenSSL 0.9.8.o" ++ _ -> 3199 false; 3200 _ -> 3201 VersionFlag = version_flag(Version), 3202 Exe = "openssl", 3203 Args = ["s_client", VersionFlag], 3204 [{trap_exit, Trap}] = process_info(self(), [trap_exit]), 3205 process_flag(trap_exit, true), 3206 Port = portable_open_port(Exe, Args), 3207 Bool = do_supports_ssl_tls_version(Port, ""), 3208 consume_port_exit(Port), 3209 process_flag(trap_exit, Trap), 3210 Bool 3211 end; 3212 false -> 3213 false 3214 end; 3215supports_ssl_tls_version(Version) -> 3216 VersionFlag = version_flag(Version), 3217 Exe = "openssl", 3218 Args = ["s_client", VersionFlag], 3219 Port = portable_open_port(Exe, Args), 3220 do_supports_ssl_tls_version(Port, ""). 3221 3222do_supports_ssl_tls_version(Port, Acc) -> 3223 receive 3224 {Port, {data, Data}} -> 3225 case Acc ++ Data of 3226 "unknown option" ++ _ -> 3227 false; 3228 "s_client: Option unknown" ++ _-> 3229 false; 3230 Info when length(Info) >= 24 -> 3231 ct:pal("~p", [Info]), 3232 true; 3233 _ -> 3234 do_supports_ssl_tls_version(Port, Acc ++ Data) 3235 end 3236 after 1000 -> 3237 true 3238 end. 3239 3240ubuntu_legacy_support() -> 3241 case os:type() of 3242 {unix, linux} -> 3243 Issue = os:cmd("more /etc/issue"), 3244 case re:run(Issue, "Ubuntu 1[6-9]+", [global]) of 3245 nomatch -> 3246 true; 3247 _ -> 3248 false 3249 end; 3250 _ -> 3251 true 3252 end. 3253 3254ssl_options(Option, Config) when is_atom(Option) -> 3255 ProtocolOpts = proplists:get_value(protocol_opts, Config, []), 3256 Opts = proplists:get_value(Option, Config, []), 3257 Opts ++ ProtocolOpts; 3258ssl_options(Options, Config) -> 3259 ProtocolOpts = proplists:get_value(protocol_opts, Config, []), 3260 Options ++ ProtocolOpts. 3261 3262protocol_version(Config) -> 3263 case proplists:get_value(version, Config, undefined) of 3264 undefined -> 3265 protocol_version(Config, atom); 3266 Version -> 3267 Version 3268 end. 3269protocol_version(Config, tuple) -> 3270 case proplists:get_value(protocol, Config) of 3271 dtls -> 3272 dtls_record:highest_protocol_version(dtls_record:supported_protocol_versions()); 3273 _ -> 3274 tls_record:highest_protocol_version(tls_record:supported_protocol_versions()) 3275 end; 3276 3277protocol_version(Config, atom) -> 3278 case proplists:get_value(protocol, Config) of 3279 dtls -> 3280 dtls_record:protocol_version(protocol_version(Config, tuple)); 3281 _ -> 3282 tls_record:protocol_version(protocol_version(Config, tuple)) 3283 end. 3284 3285protocol_options(Config, Options) -> 3286 Protocol = proplists:get_value(protocol, Config, tls), 3287 {Protocol, Opts} = lists:keyfind(Protocol, 1, Options), 3288 Opts. 3289 3290ct_log_supported_protocol_versions(Config) -> 3291 case proplists:get_value(protocol, Config) of 3292 dtls -> 3293 ct:log("DTLS version ~p~n ", [dtls_record:supported_protocol_versions()]); 3294 _ -> 3295 ct:log("TLS/SSL version ~p~n ", [tls_record:supported_protocol_versions()]) 3296 end. 3297 3298clean_env() -> 3299 application:unset_env(ssl, protocol_version), 3300 application:unset_env(ssl, dtls_protocol_version), 3301 application:unset_env(ssl, session_lifetime), 3302 application:unset_env(ssl, session_cb), 3303 application:unset_env(ssl, session_cb_init_args), 3304 application:unset_env(ssl, session_cache_client_max), 3305 application:unset_env(ssl, session_cache_server_max), 3306 application:unset_env(ssl, ssl_pem_cache_clean), 3307 application:unset_env(ssl, bypass_pem_cache), 3308 application:unset_env(ssl, alert_timeout), 3309 application:unset_env(ssl, internal_active_n). 3310%% 3311clean_env(keep_version) -> 3312 application:unset_env(ssl, session_lifetime), 3313 application:unset_env(ssl, session_cb), 3314 application:unset_env(ssl, session_cb_init_args), 3315 application:unset_env(ssl, session_cache_client_max), 3316 application:unset_env(ssl, session_cache_server_max), 3317 application:unset_env(ssl, ssl_pem_cache_clean), 3318 application:unset_env(ssl, bypass_pem_cache), 3319 application:unset_env(ssl, alert_timeout), 3320 application:unset_env(ssl, internal_active_n). 3321 3322clean_start() -> 3323 ssl:stop(), 3324 application:load(ssl), 3325 clean_env(), 3326 ssl:start(). 3327%% 3328clean_start(keep_version) -> 3329 ssl:stop(), 3330 application:load(ssl), 3331 clean_env(keep_version), 3332 ssl:start(). 3333 3334 3335tls_version('dtlsv1' = Atom) -> 3336 dtls_v1:corresponding_tls_version(dtls_record:protocol_version(Atom)); 3337tls_version('dtlsv1.2' = Atom) -> 3338 dtls_v1:corresponding_tls_version(dtls_record:protocol_version(Atom)); 3339tls_version(Atom) -> 3340 tls_record:protocol_version(Atom). 3341 3342consume_port_exit(OpenSSLPort) -> 3343 receive 3344 {'EXIT', OpenSSLPort, _} -> 3345 ok 3346 end. 3347 3348hardcode_rsa_key(1) -> 3349 #'RSAPrivateKey'{ 3350 version = 'two-prime', 3351 modulus = 23995666614853919027835084074500048897452890537492185072956789802729257783422306095699263934587064480357348855732149402060270996295002843755712064937715826848741191927820899197493902093529581182351132392364214171173881547273475904587683433713767834856230531387991145055273426806331200574039205571401702219159773947658558490957010003143162250693492642996408861265758000254664396313741422909188635443907373976005987612936763564996605457102336549804831742940035613780926178523017685712710473543251580072875247250504243621640157403744718833162626193206685233710319205099867303242759099560438381385658382486042995679707669, 3352 publicExponent = 17, 3353 privateExponent = 11292078406990079542510627799764728892919007311761028269626724613049062486316379339152594792746853873109340637991599718616598115903530750002688030558925094987642913848386305504703012749896273497577003478759630198199473669305165131570674557041773098755873191241407597673069847908861741446606684974777271632545629600685952292605647052193819136445675100211504432575554351515262198132231537860917084269870590492135731720141577986787033006338680118008484613510063003323516659048210893001173583018220214626635609151105287049126443102976056146630518124476470236027123782297108342869049542023328584384300970694412006494684657, 3354 prime1 = 169371138592582642967021557955633494538845517070305333860805485424261447791289944610138334410987654265476540480228705481960508520379619587635662291973699651583489223555422528867090299996446070521801757353675026048850480903160224210802452555900007597342687137394192939372218903554801584969667104937092080815197, 3355 prime2 = 141675062317286527042995673340952251894209529891636708844197799307963834958115010129693036021381525952081167155681637592199810112261679449166276939178032066869788822014115556349519329537177920752776047051833616197615329017439297361972726138285974555338480581117881706656603857310337984049152655480389797687577, 3356 exponent1 = 119556097830058336212015217380447172615655659108450823901745048534772786676204666783627059584226579481512852103690850928442711896738555003036938088452023283470698275450886490965004917644550167427154181661417665446247398284583687678213495921811770068712485038160606780733330990744565824684470897602653233516609, 3357 exponent2 = 41669135975672507953822256864985956439473391144599032012999352737636422046504414744027363535700448809435637398729893409470532385959317485048904982111185902020526124121798693043976273393287623750816484427009887116945685005129205106462566511260580751570141347387612266663707016855981760014456663376585234613993, 3358 coefficient = 76837684977089699359024365285678488693966186052769523357232308621548155587515525857011429902602352279058920284048929101483304120686557782043616693940283344235057989514310975192908256494992960578961614059245280827077951132083993754797053182279229469590276271658395444955906108899267024101096069475145863928441, 3359 otherPrimeInfos = asn1_NOVALUE}; 3360 3361hardcode_rsa_key(2) -> 3362 #'RSAPrivateKey'{ 3363 version = 'two-prime', 3364 modulus = 21343679768589700771839799834197557895311746244621307033143551583788179817796325695589283169969489517156931770973490560582341832744966317712674900833543896521418422508485833901274928542544381247956820115082240721897193055368570146764204557110415281995205343662628196075590438954399631753508888358737971039058298703003743872818150364935790613286541190842600031570570099801682794056444451081563070538409720109449780410837763602317050353477918147758267825417201591905091231778937606362076129350476690460157227101296599527319242747999737801698427160817755293383890373574621116766934110792127739174475029121017282777887777, 3365 publicExponent = 17, 3366 privateExponent = 18832658619343853622211588088997845201745658451136447382185486691577805721584993260814073385267196632785528033211903435807948675951440868570007265441362261636545666919252206383477878125774454042314841278013741813438699754736973658909592256273895837054592950290554290654932740253882028017801960316533503857992358685308186680144968293076156011747178275038098868263178095174694099811498968993700538293188879611375604635940554394589807673542938082281934965292051746326331046224291377703201248790910007232374006151098976879987912446997911775904329728563222485791845480864283470332826504617837402078265424772379987120023773, 3367 prime1 = 146807662748886761089048448970170315054939768171908279335181627815919052012991509112344782731265837727551849787333310044397991034789843793140419387740928103541736452627413492093463231242466386868459637115999163097726153692593711599245170083315894262154838974616739452594203727376460632750934355508361223110419, 3368 prime2 = 145385325050081892763917667176962991350872697916072592966410309213561884732628046256782356731057378829876640317801978404203665761131810712267778698468684631707642938779964806354584156202882543264893826268426566901882487709510744074274965029453915224310656287149777603803201831202222853023280023478269485417083, 3369 exponent1 = 51814469205489445090252393754177758254684624060673510353593515699736136004585238510239335081623236845018299924941168250963996835808180162284853901555621683602965806809675350150634081614988136541809283687999704622726877773856604093851236499993845033701707873394143336209718962603456693912094478414715725803677, 3370 exponent2 = 51312467664734785681382706062457526359131540440966797517556579722433606376221663384746714140373192528191755406283051201483646739222992016094510128871300458249756331334105225772206172777487956446433115153562317730076172132768497908567634716277852432109643395464627389577600646306666889302334125933506877206029, 3371 coefficient = 30504662229874176232343608562807118278893368758027179776313787938167236952567905398252901545019583024374163153775359371298239336609182249464886717948407152570850677549297935773605431024166978281486607154204888016179709037883348099374995148481968169438302456074511782717758301581202874062062542434218011141540, 3372 otherPrimeInfos = asn1_NOVALUE}; 3373hardcode_rsa_key(3) -> 3374 #'RSAPrivateKey'{ 3375 version = 'two-prime', 3376 modulus = 25089040456112869869472694987833070928503703615633809313972554887193090845137746668197820419383804666271752525807484521370419854590682661809972833718476098189250708650325307850184923546875260207894844301992963978994451844985784504212035958130279304082438876764367292331581532569155681984449177635856426023931875082020262146075451989132180409962870105455517050416234175675478291534563995772675388370042873175344937421148321291640477650173765084699931690748536036544188863178325887393475703801759010864779559318631816411493486934507417755306337476945299570726975433250753415110141783026008347194577506976486290259135429, 3377 publicExponent = 17, 3378 privateExponent = 8854955455098659953931539407470495621824836570223697404931489960185796768872145882893348383311931058684147950284994536954265831032005645344696294253579799360912014817761873358888796545955974191021709753644575521998041827642041589721895044045980930852625485916835514940558187965584358347452650930302268008446431977397918214293502821599497633970075862760001650736520566952260001423171553461362588848929781360590057040212831994258783694027013289053834376791974167294527043946669963760259975273650548116897900664646809242902841107022557239712438496384819445301703021164043324282687280801738470244471443835900160721870265, 3379 prime1 = 171641816401041100605063917111691927706183918906535463031548413586331728772311589438043965564336865070070922328258143588739626712299625805650832695450270566547004154065267940032684307994238248203186986569945677705100224518137694769557564475390859269797990555863306972197736879644001860925483629009305104925823, 3380 prime2 =146170909759497809922264016492088453282310383272504533061020897155289106805616042710009332510822455269704884883705830985184223718261139908416790475825625309815234508695722132706422885088219618698987115562577878897003573425367881351537506046253616435685549396767356003663417208105346307649599145759863108910523, 3381 exponent1 = 60579464612132153154728441333538327425711971378777222246428851853999433684345266860486105493295364142377972586444050678378691780811632637288529186629507258781295583787741625893888579292084087601124818789392592131211843947578009918667375697196773859928702549128225990187436545756706539150170692591519448797349, 3382 exponent2 = 137572620950115585809189662580789132500998007785886619351549079675566218169991569609420548245479957900898715184664311515467504676010484619686391036071176762179044243478326713135456833024206699951987873470661533079532774988581535389682358631768109586527575902839864474036157372334443583670210960715165278974609, 3383 coefficient = 15068630434698373319269196003209754243798959461311186548759287649485250508074064775263867418602372588394608558985183294561315208336731894947137343239541687540387209051236354318837334154993136528453613256169847839789803932725339395739618592522865156272771578671216082079933457043120923342632744996962853951612, 3384 otherPrimeInfos = asn1_NOVALUE}; 3385hardcode_rsa_key(4) -> 3386 #'RSAPrivateKey'{ 3387 version ='two-prime', 3388 modulus = 28617237755030755643854803617273584643843067580642149032833640135949799721163782522787597288521902619948688786051081993247908700824196122780349730169173433743054172191054872553484065655968335396052034378669869864779940355219732200954630251223541048434478476115391643898092650304645086338265930608997389611376417609043761464100338332976874588396803891301015812818307951159858145399281035705713082131199940309445719678087542976246147777388465712394062188801177717719764254900022006288880246925156931391594131839991579403409541227225173269459173129377291869028712271737734702830877034334838181789916127814298794576266389, 3389 publicExponent = 17, 3390 privateExponent = 26933870828264240605980991639786903194205240075898493207372837775011576208154148256741268036255908348187001210401018346586267012540419880263858569570986761169933338532757527109161473558558433313931326474042230460969355628442100895016122589386862163232450330461545076609969553227901257730132640573174013751883368376011370428995523268034111482031427024082719896108094847702954695363285832195666458915142143884210891427766607838346722974883433132513540317964796373298134261669479023445911856492129270184781873446960437310543998533283339488055776892320162032014809906169940882070478200435536171854883284366514852906334641, 3391 prime1 = 177342190816702392178883147766999616783253285436834252111702533617098994535049411784501174309695427674025956656849179054202187436663487378682303508229883753383891163725167367039879190685255046547908384208614573353917213168937832054054779266431207529839577747601879940934691505396807977946728204814969824442867, 3392 prime2 = 161367340863680900415977542864139121629424927689088951345472941851682581254789586032968359551717004797621579428672968948552429138154521719743297455351687337112710712475376510559020211584326773715482918387500187602625572442687231345855402020688502483137168684570635690059254866684191216155909970061793538842967, 3393 exponent1 = 62591361464718491357252875682470452982324688977706206627659717747211409835899792394529826226951327414362102349476180842659595565881230839534930649963488383547255704844176717778780890830090016428673547367746320007264898765507470136725216211681602657590439205035957626212244060728285168687080542875871702744541, 3394 exponent2 = 28476589564178982426348978152495139111074987239250991413906989738532220221433456358759122273832412611344984605059935696803369847909621479954699550944415412431654831613301737157474154985469430655673456186029444871051571607533040825739188591886206320553618003159523945304574388238386685203984112363845918619347, 3395 coefficient = 34340318160575773065401929915821192439103777558577109939078671096408836197675640654693301707202885840826672396546056002756167635035389371579540325327619480512374920136684787633921441576901246290213545161954865184290700344352088099063404416346968182170720521708773285279884132629954461545103181082503707725012, 3396 otherPrimeInfos = asn1_NOVALUE}; 3397 3398hardcode_rsa_key(5) -> 3399 #'RSAPrivateKey'{ 3400 version= 'two-prime', 3401 modulus = 26363170152814518327068346871197765236382539835597898797762992537312221863402655353436079974302838986536256364057947538018476963115004626096654613827403121905035011992899481598437933532388248462251770039307078647864188314916665766359828262009578648593031111569685489178543405615478739906285223620987558499488359880003693226535420421293716164794046859453204135383236667988765227190694994861629971618548127529849059769249520775574008363789050621665120207265361610436965088511042779948238320901918522125988916609088415989475825860046571847719492980547438560049874493788767083330042728150253120940100665370844282489982633, 3402 publicExponent = 17, 3403 privateExponent = 10855423004100095781734025182257903332628104638187370093196526338893267826106975733767797636477639582691399679317978398007608161282648963686857782164224814902073240232370374775827384395689278778574258251479385325591136364965685903795223402003944149420659869469870495544106108194608892902588033255700759382142132115013969680562678811046675523365751498355532768935784747314021422035957153013494814430893022253205880275287307995039363642554998244274484818208792520243113824379110193356010059999642946040953102866271737127640405568982049887176990990501963784502429481034227543991366980671390566584211881030995602076468001, 3404 prime1 =163564135568104310461344551909369650951960301778977149705601170951529791054750122905880591964737953456660497440730575925978769763154927541340839715938951226089095007207042122512586007411328664679011914120351043948122025612160733403945093961374276707993674792189646478659304624413958625254578122842556295400709, 3405 prime2 = 161179405627326572739107057023381254841260287988433675196680483761672455172873134522398837271764104320975746111042211695289319249471386600030523328069395763313848583139553961129874895374324504709512019736703349829576024049432816885712623938437949550266365056310544300920756181033500610331519029869549723159637, 3406 exponent1 = 115457036871603042678596154288966812436677860079277988027483179495197499568058910286503947269226790675289762899339230065396778656344654735064122152427494983121714122734382674714766593466820233891067233496718383963380253373289929461608301619793607087995535147427985749641862087821617853120878674947686796753441, 3407 exponent2 = 142217122612346975946270932667689342506994371754500301644129838613240401623123353990351915239791856753802128921507833848784693455415929352968108818884760967629866396887841730408713142977345151214275311532385308673155315337734838428569962298621720191411498579097539089047726042088382891468987379296661520434973, 3408 coefficient = 40624877259097915043489529504071755460170951428490878553842519165800720914888257733191322215286203357356050737713125202129282154441426952501134581314792133018830748896123382106683994268028624341502298766844710276939303555637478596035491641473828661569958212421472263269629366559343208764012473880251174832392, 3409 otherPrimeInfos = asn1_NOVALUE}; 3410hardcode_rsa_key(6) -> 3411 #'RSAPrivateKey'{ 3412 version = 'two-prime', 3413 modulus = 22748888494866396715768692484866595111939200209856056370972713870125588774286266397044592487895293134537316190976192161177144143633669641697309689280475257429554879273045671863645233402796222694405634510241820106743648116753479926387434021380537483429927516962909367257212902212159798399531316965145618774905828756510318897899298783143203190245236381440043169622358239226123652592179006905016804587837199618842875361941208299410035232803124113612082221121192550063791073372276763648926636149384299189072950588522522800393261949880796214514243704858378436010975184294077063518776479282353562934591448646412389762167039, 3414 publicExponent = 17, 3415 privateExponent = 6690849557313646092873144848490175032923294179369428344403739373566349639495960705013115437616262686628622409110644753287395336362844012263914614494257428655751435080307550548130951000822418439531068973600535325512837681398082331290421770994275730420566916753796872722709677121223470117509210872101652580854566448661533030419787125312956120661097410038933324613372774190658239039998357548275441758790939430824924502690997433186652165055694361752689819209062683281242276039100201318203707142383491769671330743466041394101421674581185260900666085723130684175548215193875544802254923825103844262661010117443222587769713, 3416 prime1 = 164748737139489923768181260808494855987398781964531448608652166632780898215212977127034263859971474195908846263894581556691971503119888726148555271179103885786024920582830105413607436718060544856016793981261118694063993837665813285582095833772675610567592660039821387740255651489996976698808018635344299728063, 3417 prime2 = 138082323967104548254375818343885141517788525705334488282154811252858957969378263753268344088034079842223206527922445018725900110643394926788280539200323021781309918753249061620424428562366627334409266756720941754364262467100514166396917565961434203543659974860389803369482625510495464845206228470088664021953, 3418 exponent1 = 19382204369351755737433089506881747763223386113474288071606137250915399790025056132592266336467232258342217207517009594904937823896457497193947678962247515974826461245038835931012639613889475865413740468383661022831058098548919210068481862796785365949128548239978986792971253116470232552800943368864035262125, 3419 exponent2 = 48734937870742781736838524121371226418043009072470995864289933383361985165662916618800592031070851709019955245149098241903258862580021738866451955011878713569874088971734962924855680669070574353320917678842685325069739694270769705787147376221682660074232932303666989424523279591939575827719845342384234360689, 3420 coefficient = 81173034184183681160439870161505779100040258708276674532866007896310418779840630960490793104541748007902477778658270784073595697910785917474138815202903114440800310078464142273778315781957021015333260021813037604142367434117205299831740956310682461174553260184078272196958146289378701001596552915990080834227, 3421 otherPrimeInfos = asn1_NOVALUE}. 3422 3423hardcode_rsa_1024_key(1) -> 3424 #'RSAPrivateKey'{version = 'two-prime', 3425 modulus = 152618920709346576506952607098028299458615405194120516804067302859774798720862572082626851690572130284910454988859007980367926204341637028795420927026111160369130942718840998292351565050537705794496742217762844103737634290634532232714374862322877076125650783658974242305324207239909234718160759907957502819181, 3426 publicExponent = 17, 3427 privateExponent = 89775835711380339121736827704722529093303179525953245178863119329279293365213277695662853935630664873476738228740592929628191884906845311056129957074183020957315463095429495020547731127789657232144654051871515007759243605000909583210051114028049068215595185959728886310943042856399988846590947179831354428913, 3428 prime1 = 13018105310773689694711101111767176661493882304979760063552973933059514785910240943852845097923711145970844208861778343060919395218474310542285865516544653, 3429 prime2 = 11723589344682921162046319310366118627005968525349821205037572987102618200031016344115630095736447992996683226273798377973464634035204645607416378683745377, 3430 exponent1 = 7657709006337464526300647712804221565584636649988094155031161137093832227006024084619320645837477144688731887565751966506423173657926065024874038539143913, 3431 exponent2 = 11033966442054514034867124056815170472476205670917478781211833399625993600029191853285298913634303993408643036492986708680907890856663195865803650525878001, 3432 coefficient = 7357357483264399363785138527396251818499941660605442417644885251395376792981387533016821796011101917057636813775613592220898054882923958484000235934554630, 3433 otherPrimeInfos = asn1_NOVALUE}; 3434hardcode_rsa_1024_key(2) -> 3435 #'RSAPrivateKey'{version = 'two-prime', 3436 modulus = 132417984874904377472239436563253515498607309816574784497785056464473431603604973287322746340055062696030016903830406088140534281534301418467490242269156926775506208514027213826501153438861284871625076651352798208559277520683414148048437439635357639033850360133068980157555507518934285770383924814915583919331, 3437 publicExponent = 17, 3438 privateExponent = 116839398419033274240211267555811925439947626308742456909810343939241263179651447018225952652989761202379426679850358313065177307236148310412491390237491385620149263549211570156731410125598364338974865883306073709062002620705336269289633237348474049621806833904576124689232282666798030505410189805859996211233, 3439 prime1 = 12354286715326546399270830019697416039683060665495490476376955068446562229853736822465010796530936501225722243114286822522048306078247961653481711526701259, 3440 prime2 = 10718383661165041035044708868932433765604392896488115438294667272770655136522450030638962957185192634722652306257889603065114923772949624056219896061512009, 3441 exponent1 = 5087059235722695576170341772816583075163613215204025490272863851713290329939773985720886798571562088740003276576471044567902243679278572445551292981582871, 3442 exponent2 = 6304931565391200608849828746430843391531995821463597316643921925159208903836735312140566445403054491013324886034052707685361719866440955327188174153830593, 3443 coefficient = 6764088858264512915296172980190092445938774052616013205418164952211827027745702759906572599388571087295432259160097016323193144471211837074613329649320009, 3444 otherPrimeInfos = asn1_NOVALUE}; 3445hardcode_rsa_1024_key(3) -> 3446 #'RSAPrivateKey'{version = 'two-prime', 3447 modulus = 132603582566987335579015215397416921308461253540735107996254563101087328483405996961761145905021132317760270172654141110354018131670337351296871719192630978670273323069438897632586026697023844069174787494970866246368200405578784055149230641370998125414763230872277095376893138420738507940599560410343688278361, 3448 publicExponent = 17, 3449 privateExponent = 124803371827752786427308438021098278878551768038338925172945471153964544454970350081657549087078712769656724868380368103862605300395611624749996912181299722918452562565562892031863847812293655197586374503957768862684015202213024002730410420619423541154205461118764880018581745374583581669240937327152309672753, 3450 prime1 = 12202483472094988277172439292742673588688995751099198683383744575043357099902468606144011463115716181768777309695574163698153032647393450605174909802187971, 3451 prime2 = 10866934003248540047676291395653788246732743513485317053446021859209870346149779563425451397497222238159656279714782986335807210805023580459325334557063091, 3452 exponent1 = 3588965727086761257991893909630198114320292867970352553936395463248046205853667237101179842092857700520228620498698283440633244896292191354463208765349403, 3453 exponent2 = 4474619883690575313749061162916265748654659093788071727889538412615828966061673937881068222498856215712799644588440053197097086802068533130310431876437743, 3454 coefficient = 6440880395775803235356940314241907933534073137546236980469653455119937607298142560546736915150573386382326185901566797818281064505978928392351326571984856, 3455 otherPrimeInfos = asn1_NOVALUE}. 3456 3457 3458hardcode_dsa_key(1) -> 3459 {'DSAPrivateKey',0, 3460 99438313664986922963487511141216248076486724382260996073922424025828494981416579966171753999204426907349400798052572573634137057487829150578821328280864500098312146772602202702021153757550650696224643730869835650674962433068943942837519621267815961566259265204876799778977478160416743037274938277357237615491, 3461 1454908511695148818053325447108751926908854531909, 3462 20302424198893709525243209250470907105157816851043773596964076323184805650258390738340248469444700378962907756890306095615785481696522324901068493502141775433048117442554163252381401915027666416630898618301033737438756165023568220631119672502120011809327566543827706483229480417066316015458225612363927682579, 3463 48598545580251057979126570873881530215432219542526130654707948736559463436274835406081281466091739849794036308281564299754438126857606949027748889019480936572605967021944405048011118039171039273602705998112739400664375208228641666852589396502386172780433510070337359132965412405544709871654840859752776060358, 3464 1457508827177594730669011716588605181448418352823}; 3465hardcode_dsa_key(2) -> 3466 #'DSAPrivateKey'{ 3467 version = 0, 3468 p = 145447354557382582722944332987784622105075065624518040072393858097520305927329240484963764783346271194321683798321743658303478090647837211867389721684646254999291098347011037298359107547264573476540026676832159205689428125157386525591130716464335426605521884822982379206842523670736739023467072341958074788151, 3469 q = 742801637799670234315651916144768554943688916729, 3470 g = 79727684678125120155622004643594683941478642656111969487719464672433839064387954070113655822700268007902716505761008423792735229036965034283173483862273639257533568978482104785033927768441235063983341565088899599358397638308472931049309161811156189887217888328371767967629005149630676763492409067382020352505, 3471 y = 35853727034965131665219275925554159789667905059030049940938124723126925435403746979702929280654735557166864135215989313820464108440192507913554896358611966877432546584986661291483639036057475682547385322659469460385785257933737832719745145778223672383438466035853830832837226950912832515496378486927322864228, 3472 x = 801315110178350279541885862867982846569980443911}; 3473hardcode_dsa_key(3) -> 3474 #'DSAPrivateKey'{ 3475 version = 0, 3476 p = 99438313664986922963487511141216248076486724382260996073922424025828494981416579966171753999204426907349400798052572573634137057487829150578821328280864500098312146772602202702021153757550650696224643730869835650674962433068943942837519621267815961566259265204876799778977478160416743037274938277357237615491, 3477 q = 1454908511695148818053325447108751926908854531909, 3478 g = 20302424198893709525243209250470907105157816851043773596964076323184805650258390738340248469444700378962907756890306095615785481696522324901068493502141775433048117442554163252381401915027666416630898618301033737438756165023568220631119672502120011809327566543827706483229480417066316015458225612363927682579, 3479 y = 48598545580251057979126570873881530215432219542526130654707948736559463436274835406081281466091739849794036308281564299754438126857606949027748889019480936572605967021944405048011118039171039273602705998112739400664375208228641666852589396502386172780433510070337359132965412405544709871654840859752776060358, 3480 x = 1457508827177594730669011716588605181448418352823}. 3481 3482 3483client_msg(Client, ClientMsg) -> 3484 receive 3485 {Client, ClientMsg} -> 3486 ok; 3487 {Client, {error,closed}} -> 3488 ct:log("client got close"), 3489 ok; 3490 {Client, {error, Reason}} -> 3491 ct:log("client got econnaborted: ~p", [Reason]), 3492 ok; 3493 Unexpected -> 3494 ct:fail(Unexpected) 3495 end. 3496server_msg(Server, ServerMsg) -> 3497 receive 3498 {Server, ServerMsg} -> 3499 ok; 3500 {Server, {error,closed}} -> 3501 ct:log("server got close"), 3502 ok; 3503 {Server, {error, Reason}} -> 3504 ct:log("server got econnaborted: ~p", [Reason]), 3505 ok; 3506 Unexpected -> 3507 ct:fail(Unexpected) 3508 end. 3509 3510session_id(Socket) -> 3511 {ok, [{session_id, ID}]} = ssl:connection_information(Socket, [session_id]), 3512 ID. 3513 3514reuse_session(ClientOpts, ServerOpts, Config) -> 3515 {ClientNode, ServerNode, Hostname} = run_where(Config), 3516 3517 Server0 = 3518 start_server([{node, ServerNode}, {port, 0}, 3519 {from, self()}, 3520 {mfa, {ssl_test_lib, no_result, []}}, 3521 {tcp_options, [{active, false}]}, 3522 {options, ServerOpts}]), 3523 Port0 = inet_port(Server0), 3524 3525 Client0 = start_client([{node, ClientNode}, 3526 {port, Port0}, {host, Hostname}, 3527 {mfa, {ssl_test_lib, session_id, []}}, 3528 {from, self()}, {options, [{reuse_sessions, save} | ClientOpts]}]), 3529 Server0 ! listen, 3530 3531 Client1 = start_client([{node, ClientNode}, 3532 {port, Port0}, {host, Hostname}, 3533 {mfa, {ssl_test_lib, session_id, []}}, 3534 {from, self()}, {options, ClientOpts}]), 3535 3536 SID = receive 3537 {Client0, Id0} -> 3538 Id0 3539 end, 3540 3541 receive 3542 {Client1, SID} -> 3543 ok 3544 after ?SLEEP -> 3545 ct:fail(session_not_reused) 3546 end, 3547 3548 Server0 ! listen, 3549 3550 Client2 = 3551 start_client([{node, ClientNode}, 3552 {port, Port0}, {host, Hostname}, 3553 {mfa, {ssl_test_lib, session_id, []}}, 3554 {from, self()}, {options, [{reuse_sessions, false} 3555 | ClientOpts]}]), 3556 receive 3557 {Client2, SID} -> 3558 ct:fail(session_reused_when_session_reuse_disabled_by_client); 3559 {Client2, _} -> 3560 ok 3561 end, 3562 3563 close(Server0), 3564 close(Client0), 3565 close(Client1), 3566 close(Client2), 3567 3568 Server1 = 3569 start_server([{node, ServerNode}, {port, 0}, 3570 {from, self()}, 3571 {mfa, {ssl_test_lib, no_result, []}}, 3572 {tcp_options, [{active, false}]}, 3573 {options, [{reuse_sessions, false} | ServerOpts]}]), 3574 Port1 = inet_port(Server1), 3575 3576 Client3 = start_client([{node, ClientNode}, 3577 {port, Port1}, {host, Hostname}, 3578 {mfa, {ssl_test_lib, session_id, []}}, 3579 {from, self()}, {options, [{reuse_sessions, save} | ClientOpts]}]), 3580 SID1 = receive 3581 {Client3, Id3} -> 3582 Id3 3583 end, 3584 3585 Server1 ! listen, 3586 3587 Client4 = 3588 start_client([{node, ClientNode}, 3589 {port, Port1}, {host, Hostname}, 3590 {mfa, {ssl_test_lib, session_id, []}}, 3591 {from, self()}, {options, ClientOpts}]), 3592 3593 receive 3594 {Client4, SID1} -> 3595 ct:fail(session_reused_when_session_reuse_disabled_by_server); 3596 {Client4, _} -> 3597 ok 3598 end, 3599 3600 close(Server1), 3601 close(Client3), 3602 close(Client4). 3603 3604user_lookup(psk, _Identity, UserState) -> 3605 {ok, UserState}; 3606user_lookup(srp, Username, _UserState) -> 3607 Salt = ssl_cipher:random_bytes(16), 3608 UserPassHash = crypto:hash(sha, [Salt, crypto:hash(sha, [Username, <<$:>>, <<"secret">>])]), 3609 {ok, {srp_1024, Salt, UserPassHash}}. 3610 3611test_cipher(TestCase, Config) -> 3612 [{name, Group} |_] = proplists:get_value(tc_group_properties, Config), 3613 list_to_atom(re:replace(atom_to_list(TestCase), atom_to_list(Group) ++ "_", "", [{return, list}])). 3614 3615digest() -> 3616 case application:get_env(ssl, protocol_version, application:get_env(ssl, dtls_protocol_version)) of 3617 Ver when Ver == 'tlsv1.2'; 3618 Ver == 'dtlsv1.2' -> 3619 {digest, sha256}; 3620 _ -> 3621 {digest, sha1} 3622 end. 3623 3624kill_openssl() -> 3625 case os:type() of 3626 {win32, _} -> 3627 case os:getenv("WSLENV") of 3628 false -> os:cmd("cmd.exe /C \"taskkill /IM openssl.exe /F\""); 3629 _ -> os:cmd("wsl pkill openssl") 3630 end; 3631 _ -> 3632 os:cmd("pkill openssl") 3633 end. 3634 3635hostname_format(Hostname) -> 3636 case lists:member($., Hostname) of 3637 true -> 3638 Hostname; 3639 false -> 3640 "localhost" 3641 end. 3642 3643erlang_ssl_receive_and_assert_negotiated_protocol(Socket, Protocol, Data) -> 3644 case ssl:negotiated_protocol(Socket) of 3645 {ok, Protocol} -> 3646 active_recv(Socket, length(Data)); 3647 Result -> 3648 {error, {{expected, Protocol}, {got, Result}}} 3649 end. 3650 3651check_openssl_npn_support(Config) -> 3652 HelpText = portable_cmd("openssl", ["s_client --help"]), 3653 case string:str(HelpText, "nextprotoneg") of 3654 0 -> 3655 {skip, "Openssl not compiled with nextprotoneg support"}; 3656 _ -> 3657 Config 3658 end. 3659 3660new_config(PrivDir, ServerOpts0) -> 3661 CaCertFile = proplists:get_value(cacertfile, ServerOpts0), 3662 CertFile = proplists:get_value(certfile, ServerOpts0), 3663 KeyFile = proplists:get_value(keyfile, ServerOpts0), 3664 NewCaCertFile = filename:join(PrivDir, "new_ca.pem"), 3665 NewCertFile = filename:join(PrivDir, "new_cert.pem"), 3666 NewKeyFile = filename:join(PrivDir, "new_key.pem"), 3667 file:copy(CaCertFile, NewCaCertFile), 3668 file:copy(CertFile, NewCertFile), 3669 file:copy(KeyFile, NewKeyFile), 3670 ServerOpts1 = proplists:delete(cacertfile, ServerOpts0), 3671 ServerOpts2 = proplists:delete(certfile, ServerOpts1), 3672 ServerOpts = proplists:delete(keyfile, ServerOpts2), 3673 3674 {ok, PEM} = file:read_file(NewCaCertFile), 3675 ct:log("CA file content: ~p~n", [public_key:pem_decode(PEM)]), 3676 3677 [{cacertfile, NewCaCertFile}, {certfile, NewCertFile}, 3678 {keyfile, NewKeyFile} | ServerOpts]. 3679 3680 3681openssl_sane_dtls_alpn() -> 3682 case portable_cmd("openssl", ["version"]) of 3683 "OpenSSL 1.1.0g" ++ _ -> 3684 false; 3685 "OpenSSL 1.1.1 " ++ _ -> 3686 false; 3687 "OpenSSL 1.1.1a" ++ _ -> 3688 false; 3689 "OpenSSL 1.1.1d FIPS" ++ _ -> 3690 false; 3691 "OpenSSL 1.1.1d-freebsd" ++ _ -> 3692 false; 3693 _-> 3694 openssl_sane_dtls() 3695 end. 3696 3697openssl_sane_dtls_session_reuse() -> 3698 case portable_cmd("openssl", ["version"]) of 3699 "OpenSSL 1.1.1 " ++ _ -> 3700 false; 3701 "OpenSSL 1.1.1a" ++ _ -> 3702 false; 3703 _-> 3704 openssl_sane_dtls() 3705 end. 3706 3707set_protocol_versions(Version) when Version == 'tlsv1'; 3708 Version == 'tlsv1.1'; 3709 Version == 'tlsv1.2'; 3710 Version == 'tlsv1.3'-> 3711 set_protocol_versions(protocol_version, [Version]); 3712set_protocol_versions(Version) when Version == 'dtlsv1'; 3713 Version == 'dtlsv1.2' -> 3714 set_protocol_versions(dtls_protocol_version, [Version]). 3715 3716set_protocol_versions(_, undefined) -> 3717 ok; 3718set_protocol_versions(AppVar, Value) -> 3719 application:set_env(ssl, AppVar, Value). 3720 3721pss_params(sha256) -> 3722 #'RSASSA-PSS-params'{ 3723 hashAlgorithm = #'HashAlgorithm'{algorithm = ?'id-sha256'}, 3724 maskGenAlgorithm = #'MaskGenAlgorithm'{algorithm = ?'id-mgf1', 3725 parameters = #'HashAlgorithm'{algorithm = ?'id-sha256'} 3726 }, 3727 saltLength = 32, 3728 trailerField = 1}. 3729 3730test_ciphers(Kex, Cipher, Version) -> 3731 ssl:filter_cipher_suites( 3732 ssl:cipher_suites(all, Version) ++ ssl:cipher_suites(anonymous, Version), 3733 [{key_exchange, 3734 fun(K) when K == Kex -> true; 3735 (_) -> false 3736 end}, 3737 {cipher, 3738 fun(C) when C == Cipher -> true; 3739 (_) -> false 3740 end}]). 3741 3742sanity_check(ErlangPeer, OpenSSLPort) -> 3743 Data = "OpenSSL to Erlang", 3744 port_command(OpenSSLPort, Data, [nosuspend]), 3745 Data = check_active_receive(ErlangPeer, Data). 3746 3747default_tls_version(Config) -> 3748 case proplists:get_value(protocol, Config, tls) of 3749 tls -> 3750 {ok, Versions} = application:get_env(ssl, protocol_version), 3751 Versions; 3752 dtls -> 3753 {ok, Versions} = application:get_env(ssl, dtls_protocol_version), 3754 Versions 3755 end. 3756 3757openssl_maxfraglen_support() -> 3758 case portable_cmd("openssl", ["version"]) of 3759 %% Max fragmentation support introduced in OpenSSL 1.1.1 3760 "OpenSSL 0" ++ _ -> 3761 false; 3762 "OpenSSL 1.0" ++ _ -> 3763 false; 3764 "OpenSSL 1.1.0" ++ _ -> 3765 false; 3766 "OpenSSL 1.1.1" ++ _ -> 3767 true; 3768 "OpenSSL" ++ _ -> 3769 true; 3770 _ -> 3771 false 3772 end. 3773 3774openssl_dtls_maxfraglen_support() -> 3775 case portable_cmd("openssl", ["version"]) of 3776 "OpenSSL 0" ++ _ -> 3777 false; 3778 "OpenSSL 1.0" ++ _ -> 3779 false; 3780 "OpenSSL 1.1.0" ++ _ -> 3781 false; 3782 "OpenSSL 1.1.1" ++ _ -> 3783 false; 3784 "OpenSSL 1.1" ++ _ -> 3785 false; 3786 "OpenSSL" ++ _ -> 3787 true; 3788 _ -> 3789 false 3790 end. 3791 3792assert_mfl(Socket, undefined) -> 3793 InfoMFL = ssl:connection_information(Socket, [max_fragment_length]), 3794 ct:log("Connection MFL ~p, Expecting: [] ~n", [InfoMFL]), 3795 {ok, []} = InfoMFL; 3796assert_mfl(Socket, MFL) -> 3797 InfoMFL = ssl:connection_information(Socket, [max_fragment_length]), 3798 ct:log("Connection MFL ~p, Expecting: ~p ~n", [InfoMFL, MFL]), 3799 {ok, [{max_fragment_length, ConnMFL}]} = InfoMFL, 3800 ConnMFL = MFL. 3801-define(BIG_BUF, 10000000). 3802%% Workaround data delivery issues on solaris | openbsd when kernel buffers are small 3803bigger_buffers() -> 3804 case os:type() of 3805 {unix,sunos} -> 3806 [{buffer, ?BIG_BUF}, {recbuf, ?BIG_BUF},{sndbuf, ?BIG_BUF}]; 3807 {unix,openbsd} -> 3808 [{buffer, ?BIG_BUF}, {recbuf, ?BIG_BUF},{sndbuf, ?BIG_BUF}]; 3809 _ -> 3810 [] 3811 end. 3812 3813default_ciphers(Version) -> 3814 OpenSSLCiphers = openssl_ciphers(), 3815 Ciphers = 3816 case portable_cmd("openssl", ["version"]) of 3817 "OpenSSL 0.9" ++ _ -> 3818 ssl:cipher_suites(all,Version); 3819 _ -> 3820 ssl:cipher_suites(default, Version) 3821 end, 3822 [Cipher || Cipher <- Ciphers, lists:member(ssl:suite_to_openssl_str(Cipher), OpenSSLCiphers)]. 3823 3824verify_early_data(Atom) -> 3825 receive 3826 {ssl, _Socket, {early_data, Atom}} -> 3827 ok; 3828 {ssl, _Socket, {early_data, Other}} -> 3829 Other 3830 end. 3831 3832