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