diff options
Diffstat (limited to 'lib/ssl/test/ssl_basic_SUITE.erl')
-rw-r--r-- | lib/ssl/test/ssl_basic_SUITE.erl | 602 |
1 files changed, 354 insertions, 248 deletions
diff --git a/lib/ssl/test/ssl_basic_SUITE.erl b/lib/ssl/test/ssl_basic_SUITE.erl index 7ccd5b617c..7f33efd7e1 100644 --- a/lib/ssl/test/ssl_basic_SUITE.erl +++ b/lib/ssl/test/ssl_basic_SUITE.erl @@ -26,12 +26,14 @@ -include("test_server.hrl"). -include("test_server_line.hrl"). +-include_lib("public_key/include/public_key.hrl"). -define('24H_in_sec', 86400). -define(TIMEOUT, 60000). -define(EXPIRE, 10). -define(SLEEP, 500). + -behaviour(ssl_session_cache_api). %% For the session cache tests @@ -151,7 +153,7 @@ all(doc) -> all(suite) -> [app, connection_info, controlling_process, controller_dies, peercert, connect_dist, - peername, sockname, socket_options, valid_ssl_options, versions, cipher_suites, + peername, sockname, socket_options, misc_ssl_options, versions, cipher_suites, upgrade, upgrade_with_timeout, tcp_connect, ipv6, ekeyfile, ecertfile, ecacertfile, eoptions, shutdown, shutdown_write, shutdown_both, shutdown_error, ciphers, @@ -161,12 +163,16 @@ all(suite) -> server_verify_none_passive, server_verify_none_active, server_verify_none_active_once, server_verify_no_cacerts, server_require_peer_cert_ok, server_require_peer_cert_fail, + server_verify_client_once_passive, + server_verify_client_once_active, + server_verify_client_once_active_once, client_verify_none_passive, client_verify_none_active, client_verify_none_active_once %%, session_cache_process_list, session_cache_process_mnesia ,reuse_session, reuse_session_expired, server_does_not_want_to_reuse_session, client_renegotiate, server_renegotiate, - client_no_wrap_sequence_number, server_no_wrap_sequence_number + client_no_wrap_sequence_number, server_no_wrap_sequence_number, + extended_key_usage, validate_extensions_fun ]. %% Test cases starts here. @@ -311,7 +317,7 @@ controller_dies(Config) when is_list(Config) -> get_close(Client, ?LINE), %% Test that clients die when process disappear - Server ! listen, test_server:sleep(?SLEEP), + Server ! listen, Tester = self(), Connect = fun(Pid) -> {ok, Socket} = ssl:connect(Hostname, Port, @@ -325,7 +331,7 @@ controller_dies(Config) when is_list(Config) -> get_close(Client2, ?LINE), %% Test that clients die when the controlling process have changed - Server ! listen, test_server:sleep(?SLEEP), + Server ! listen, Client3 = spawn_link(fun() -> Connect(Tester) end), Controller = spawn_link(fun() -> receive die_nice -> normal end end), @@ -349,7 +355,7 @@ controller_dies(Config) when is_list(Config) -> get_close(Controller, ?LINE), %% Test that servers die - Server ! listen, test_server:sleep(?SLEEP), + Server ! listen, LastClient = ssl_test_lib:start_client([{node, ClientNode}, {port, Port}, {host, Hostname}, {from, self()}, @@ -488,9 +494,9 @@ peername(Config) when is_list(Config) -> Port = ssl_test_lib:inet_port(Server), Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port}, {host, Hostname}, - {from, self()}, - {mfa, {?MODULE, peername_result, []}}, - {options, [{port, 0} | ClientOpts]}]), + {from, self()}, + {mfa, {?MODULE, peername_result, []}}, + {options, [{port, 0} | ClientOpts]}]), ClientPort = ssl_test_lib:inet_port(Client), ServerIp = ssl_test_lib:node_to_hostip(ServerNode), @@ -530,6 +536,7 @@ sockname(Config) when is_list(Config) -> {from, self()}, {mfa, {?MODULE, sockname_result, []}}, {options, [{port, 0} | ClientOpts]}]), + ClientPort = ssl_test_lib:inet_port(Client), ServerIp = ssl_test_lib:node_to_hostip(ServerNode), ClientIp = ssl_test_lib:node_to_hostip(ClientNode), @@ -606,57 +613,44 @@ socket_options_result(Socket, Options, DefaultValues, NewOptions, NewValues) -> ok. %%-------------------------------------------------------------------- -valid_ssl_options(doc) -> +misc_ssl_options(doc) -> ["Test what happens when we give valid options"]; -valid_ssl_options(suite) -> +misc_ssl_options(suite) -> []; -valid_ssl_options(Config) when is_list(Config) -> - ClientOpts = [{reuseaddr, true} | ?config(client_opts, Config)], - ServerOpts = [{reuseaddr, true} | ?config(server_opts, Config)], +misc_ssl_options(Config) when is_list(Config) -> + ClientOpts = ?config(client_opts, Config), + ServerOpts = ?config(server_opts, Config), {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config), - Port = ssl_test_lib:inet_port(ServerNode), - - StartOk = - fun(Peer, Pid, TestOpt) -> - receive - {Pid, ok} when Peer =:= server -> - ok; - {Pid, {ok, _}} when Peer =:= client -> - ok; - {Pid, Error} -> - test_server:fail({Peer, - {option_being_tested, TestOpt}, - {got, Error}}) - end - end, - - %% The following contains both documented and undocumented options as - %% listed in ssl:handle_options/2. It excludes file options which are - %% tested elsewhere (cacertfile, certfile, keyfile). - TestOpts = [{versions, []}, {verify, verify_none}, {verify_fun, fun(_) -> false end}, - {fail_if_no_peer_cert, false}, {verify_client_once, false}, - {depth, 1}, {key, undefined}, {password, "secret"}, {ciphers, []}, - {reuse_sessions, true}, {reuse_session, fun(_,_,_,_) -> true end}, - {renegotiate_at, 1000000000}, {debug, []}, + + %% Chek that ssl options not tested elsewhere are filtered away e.i. not passed to inet. + TestOpts = [{depth, 1}, + {key, undefined}, + {password, []}, + {reuse_session, fun(_,_,_,_) -> true end}, + {debug, []}, {cb_info, {gen_tcp, tcp, tcp_closed}}], - [begin - Server = - ssl_test_lib:start_server_error([{node, ServerNode}, {port, Port}, - {from, self()}, - {options, [TestOpt | ServerOpts]}]), - Client = - ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port}, - {host, Hostname}, {from, self()}, - {options, [TestOpt | ClientOpts]}]), - StartOk(server, Server, TestOpt), - StartOk(client, Client, TestOpt), - ssl_test_lib:close(Server), - ssl_test_lib:close(Client), - ok - end || TestOpt <- TestOpts], - ok. + + Server = + ssl_test_lib:start_server([{node, ServerNode}, {port, 0}, + {from, self()}, + {mfa, {?MODULE, send_recv_result_active, []}}, + {options, TestOpts ++ ServerOpts}]), + Port = ssl_test_lib:inet_port(Server), + Client = + ssl_test_lib:start_client([{node, ClientNode}, {port, Port}, + {host, Hostname}, + {from, self()}, + {mfa, {?MODULE, send_recv_result_active, []}}, + {options, TestOpts ++ ClientOpts}]), + + test_server:format("Testcase ~p, Client ~p Server ~p ~n", + [self(), Client, Server]), + + ssl_test_lib:check_result(Server, ok, Client, ok), + ssl_test_lib:close(Server), + ssl_test_lib:close(Client). %%-------------------------------------------------------------------- versions(doc) -> @@ -878,9 +872,8 @@ tcp_connect(suite) -> []; tcp_connect(Config) when is_list(Config) -> - ClientOpts = ?config(client_opts, Config), ServerOpts = ?config(server_opts, Config), - {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config), + {_, ServerNode, Hostname} = ssl_test_lib:run_where(Config), TcpOpts = [binary, {reuseaddr, true}], Server = ssl_test_lib:start_upgrade_server([{node, ServerNode}, {port, 0}, @@ -905,7 +898,7 @@ tcp_connect(Config) when is_list(Config) -> ssl_test_lib:close(Server). -dummy(Socket) -> +dummy(_Socket) -> %% Should not happen as the ssl connection will not be established %% due to fatal handshake failiure exit(kill). @@ -960,12 +953,14 @@ ekeyfile(Config) when is_list(Config) -> ClientOpts = ?config(client_opts, Config), BadOpts = ?config(server_bad_key, Config), {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config), - Port = ssl_test_lib:inet_port(ServerNode), - + Server = - ssl_test_lib:start_server_error([{node, ServerNode}, {port, Port}, + ssl_test_lib:start_server_error([{node, ServerNode}, {port, 0}, {from, self()}, {options, BadOpts}]), + + Port = ssl_test_lib:inet_port(Server), + Client = ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port}, {host, Hostname}, @@ -986,19 +981,21 @@ ecertfile(Config) when is_list(Config) -> ClientOpts = ?config(client_opts, Config), ServerBadOpts = ?config(server_bad_cert, Config), {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config), - Port = ssl_test_lib:inet_port(ServerNode), - Server0 = - ssl_test_lib:start_server_error([{node, ServerNode}, {port, Port}, + Server = + ssl_test_lib:start_server_error([{node, ServerNode}, {port, 0}, {from, self()}, {options, ServerBadOpts}]), - Client0 = + + Port = ssl_test_lib:inet_port(Server), + + Client = ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port}, {host, Hostname}, {from, self()}, {options, ClientOpts}]), - ssl_test_lib:check_result(Server0, {error, ecertfile}, Client0, + ssl_test_lib:check_result(Server, {error, ecertfile}, Client, {error, closed}). @@ -1013,15 +1010,18 @@ ecacertfile(Config) when is_list(Config) -> ClientOpts = [{reuseaddr, true}|?config(client_opts, Config)], ServerBadOpts = [{reuseaddr, true}|?config(server_bad_ca, Config)], {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config), - Port = ssl_test_lib:inet_port(ServerNode), Server0 = ssl_test_lib:start_server_error([{node, ServerNode}, - {port, Port}, {from, self()}, + {port, 0}, {from, self()}, {options, ServerBadOpts}]), + + Port0 = ssl_test_lib:inet_port(Server0), + + Client0 = ssl_test_lib:start_client_error([{node, ClientNode}, - {port, Port}, {host, Hostname}, + {port, Port0}, {host, Hostname}, {from, self()}, {options, ClientOpts}]), @@ -1034,11 +1034,14 @@ ecacertfile(Config) when is_list(Config) -> Server1 = ssl_test_lib:start_server_error([{node, ServerNode}, - {port, Port}, {from, self()}, + {port, 0}, {from, self()}, {options, ServerBadOpts1}]), + + Port1 = ssl_test_lib:inet_port(Server1), + Client1 = ssl_test_lib:start_client_error([{node, ClientNode}, - {port, Port}, {host, Hostname}, + {port, Port1}, {host, Hostname}, {from, self()}, {options, ClientOpts}]), @@ -1059,168 +1062,58 @@ eoptions(Config) when is_list(Config) -> ClientOpts = ?config(client_opts, Config), ServerOpts = ?config(server_opts, Config), {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config), - Port = ssl_test_lib:inet_port(ServerNode), - - %% Emulated opts - Server0 = - ssl_test_lib:start_server_error([{node, ServerNode}, {port, Port}, - {from, self()}, - {options, [{active, trice} | ServerOpts]}]), - Client0 = - ssl_test_lib:start_client_error([{node, ClientNode}, - {port, Port}, {host, Hostname}, - {from, self()}, - {options, [{active, trice} | ClientOpts]}]), - ssl_test_lib:check_result(Server0, {error, {eoptions, {active,trice}}}, - Client0, {error, {eoptions, {active,trice}}}), - - Server1 = - ssl_test_lib:start_server_error([{node, ServerNode}, {port, Port}, - {from, self()}, - {options, [{header, a} | ServerOpts]}]), - Client1 = - ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port}, - {host, Hostname}, - {from, self()}, - {options, [{header, a} | ClientOpts]}]), - ssl_test_lib:check_result(Server1, {error, {eoptions, {header, a}}}, - Client1, {error, {eoptions, {header, a}}}), - - Server2 = - ssl_test_lib:start_server_error([{node, ServerNode}, {port, Port}, - {from, self()}, - {options, [{mode, a} | ServerOpts]}]), - Client2 = - ssl_test_lib:start_client_error([{node, ClientNode}, - {port, Port}, {host, Hostname}, - {from, self()}, - {options, [{mode, a} | ClientOpts]}]), - ssl_test_lib:check_result(Server2, {error, {eoptions, {mode, a}}}, - Client2, {error, {eoptions, {mode, a}}}), + Check = fun(Client, Server, {versions, [sslv2, sslv3]} = Option) -> + ssl_test_lib:check_result(Server, + {error, {eoptions, {sslv2, Option}}}, + Client, + {error, {eoptions, {sslv2, Option}}}); + (Client, Server, Option) -> + ssl_test_lib:check_result(Server, + {error, {eoptions, Option}}, + Client, + {error, {eoptions, Option}}) + end, - Server3 = - ssl_test_lib:start_server_error([{node, ServerNode}, {port, Port}, - {from, self()}, - {options, [{packet, 8.0} | ServerOpts]}]), - Client3 = - ssl_test_lib:start_client_error([{node, ClientNode}, - {port, Port}, {host, Hostname}, - {from, self()}, - {options, [{packet, 8.0} | ClientOpts]}]), - ssl_test_lib:check_result(Server3, {error, {eoptions, {packet, 8.0}}}, - Client3, {error, {eoptions, {packet, 8.0}}}), - - %% ssl - Server4 = - ssl_test_lib:start_server_error([{node, ServerNode}, {port, Port}, - {from, self()}, - {options, [{verify, 4} | ServerOpts]}]), - Client4 = - ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port}, - {host, Hostname}, - {from, self()}, - {options, [{verify, 4} | ClientOpts]}]), - ssl_test_lib:check_result(Server4, {error, {eoptions, {verify, 4}}}, - Client4, {error, {eoptions, {verify, 4}}}), - - Server5 = - ssl_test_lib:start_server_error([{node, ServerNode}, {port, Port}, - {from, self()}, - {options, [{depth, four} | ServerOpts]}]), - Client5 = - ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port}, - {host, Hostname}, - {from, self()}, - {options, [{depth, four} | ClientOpts]}]), - ssl_test_lib:check_result(Server5, {error, {eoptions, {depth, four}}}, - Client5, {error, {eoptions, {depth, four}}}), - - Server6 = - ssl_test_lib:start_server_error([{node, ServerNode}, {port, Port}, - {from, self()}, - {options, [{cacertfile, ""} | ServerOpts]}]), - Client6 = - ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port}, - {host, Hostname}, - {from, self()}, - {options, [{cacertfile, ""} | ClientOpts]}]), - ssl_test_lib:check_result(Server6, {error, {eoptions, {cacertfile, ""}}}, - Client6, {error, {eoptions, {cacertfile, ""}}}), - - Server7 = - ssl_test_lib:start_server_error([{node, ServerNode}, {port, Port}, - {from, self()}, - {options, [{certfile, 'cert.pem'} | ServerOpts]}]), - Client7 = - ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port}, - {host, Hostname}, - {from, self()}, - {options, [{certfile, 'cert.pem'} | ClientOpts]}]), - ssl_test_lib:check_result(Server7, - {error, {eoptions, {certfile, 'cert.pem'}}}, - Client7, {error, {eoptions, {certfile, 'cert.pem'}}}), - - Server8 = - ssl_test_lib:start_server_error([{node, ServerNode}, {port, Port}, - {from, self()}, - {options, [{keyfile,'key.pem' } | ServerOpts]}]), - Client8 = - ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port}, - {host, Hostname}, - {from, self()}, {options, [{keyfile, 'key.pem'} - | ClientOpts]}]), - ssl_test_lib:check_result(Server8, - {error, {eoptions, {keyfile, 'key.pem'}}}, - Client8, {error, {eoptions, {keyfile, 'key.pem'}}}), - - Server9 = - ssl_test_lib:start_server_error([{node, ServerNode}, {port, Port}, - {from, self()}, - {options, [{key, 'key.pem' } | ServerOpts]}]), - Client9 = - ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port}, - {host, Hostname}, - {from, self()}, {options, [{key, 'key.pem'} - | ClientOpts]}]), - ssl_test_lib:check_result(Server9, {error, {eoptions, {key, 'key.pem'}}}, - Client9, {error, {eoptions, {key, 'key.pem'}}}), - - Server10 = - ssl_test_lib:start_server_error([{node, ServerNode}, {port, Port}, - {from, self()}, - {options, [{password, foo} | ServerOpts]}]), - Client10 = - ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port}, - {host, Hostname}, - {from, self()}, - {options, [{password, foo} | ClientOpts]}]), - ssl_test_lib:check_result(Server10, {error, {eoptions, {password, foo}}}, - Client10, {error, {eoptions, {password, foo}}}), - %% Misc - Server11 = - ssl_test_lib:start_server_error([{node, ServerNode}, {port, Port}, - {from, self()}, - {options, [{ssl_imp, cool} | ServerOpts]}]), - Client11 = - ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port}, - {host, Hostname}, - {from, self()}, - {options, [{ssl_imp, cool} | ClientOpts]}]), - ssl_test_lib:check_result(Server11, {error, {eoptions, {ssl_imp, cool}}}, - Client11, {error, {eoptions, {ssl_imp, cool}}}), - - Server12 = - ssl_test_lib:start_server_error([{node, ServerNode}, {port, Port}, - {from, self()}, - {options, [{debug, cool} | ServerOpts]}]), - Client12 = - ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port}, - {host, Hostname}, - {from, self()}, - {options, [{debug, cool} | ClientOpts]}]), - ssl_test_lib:check_result(Server12, {error, {eoptions, {debug, cool}}}, - Client12, {error, {eoptions, {debug, cool}}}). + TestOpts = [{versions, [sslv2, sslv3]}, + {ssl_imp, cool}, + {verify, 4}, + {verify_fun, function}, + {fail_if_no_peer_cert, 0}, + {verify_client_once, 1}, + {validate_extensions_fun, function}, + {depth, four}, + {certfile, 'cert.pem'}, + {keyfile,'key.pem' }, + {password, foo}, + {cacertfile, ""}, + {dhfile,'dh.pem' }, + {ciphers, [{foo, bar, sha, ignore}]}, + {reuse_session, foo}, + {reuse_sessions, 0}, + {renegotiate_at, "10"}, + {debug, 1}, + {mode, depech}, + {packet, 8.0}, + {packet_size, "2"}, + {header, a}, + {active, trice}, + {key, 'key.pem' }], + + [begin + Server = + ssl_test_lib:start_server_error([{node, ServerNode}, {port, 0}, + {from, self()}, + {options, [TestOpt | ServerOpts]}]), + %% Will never reach a point where port is used. + Client = + ssl_test_lib:start_client_error([{node, ClientNode}, {port, 0}, + {host, Hostname}, {from, self()}, + {options, [TestOpt | ClientOpts]}]), + Check(Client, Server, TestOpt), + ok + end || TestOpt <- TestOpts], + ok. %%-------------------------------------------------------------------- shutdown(doc) -> @@ -1812,10 +1705,124 @@ server_verify_none_active_once(Config) when is_list(Config) -> ssl_test_lib:check_result(Server, ok, Client, ok), ssl_test_lib:close(Server), ssl_test_lib:close(Client). +%%-------------------------------------------------------------------- + +server_verify_client_once_passive(doc) -> + ["Test server option verify_client_once"]; + +server_verify_client_once_passive(suite) -> + []; + +server_verify_client_once_passive(Config) when is_list(Config) -> + ClientOpts = ?config(client_opts, Config), + ServerOpts = ?config(server_verification_opts, Config), + {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config), + Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0}, + {from, self()}, + {mfa, {?MODULE, send_recv_result, []}}, + {options, [{active, false}, {verify, verify_peer}, + {verify_client_once, true} + | ServerOpts]}]), + Port = ssl_test_lib:inet_port(Server), + Client0 = ssl_test_lib:start_client([{node, ClientNode}, {port, Port}, + {host, Hostname}, + {from, self()}, + {mfa, {?MODULE, send_recv_result, []}}, + {options, [{active, false} | ClientOpts]}]), + + ssl_test_lib:check_result(Server, ok, Client0, ok), + ssl_test_lib:close(Client0), + Server ! listen, + Client1 = ssl_test_lib:start_client([{node, ClientNode}, {port, Port}, + {host, Hostname}, + {from, self()}, + {mfa, {?MODULE, result_ok, []}}, + {options, [{active, false} | ClientOpts]}]), + + ssl_test_lib:check_result(Client1, ok), + ssl_test_lib:close(Server), + ssl_test_lib:close(Client1). + +%%-------------------------------------------------------------------- + +server_verify_client_once_active(doc) -> + ["Test server option verify_client_once"]; + +server_verify_client_once_active(suite) -> + []; +server_verify_client_once_active(Config) when is_list(Config) -> + ClientOpts = ?config(client_opts, Config), + ServerOpts = ?config(server_verification_opts, Config), + {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config), + Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0}, + {from, self()}, + {mfa, {?MODULE, send_recv_result_active, []}}, + {options, [{active, once}, {verify, verify_peer}, + {verify_client_once, true} + | ServerOpts]}]), + Port = ssl_test_lib:inet_port(Server), + Client0 = ssl_test_lib:start_client([{node, ClientNode}, {port, Port}, + {host, Hostname}, + {from, self()}, + {mfa, {?MODULE, send_recv_result_active, []}}, + {options, [{active, true} | ClientOpts]}]), + + ssl_test_lib:check_result(Server, ok, Client0, ok), + ssl_test_lib:close(Client0), + Server ! listen, + Client1 = ssl_test_lib:start_client([{node, ClientNode}, {port, Port}, + {host, Hostname}, + {from, self()}, + {mfa, {?MODULE, result_ok, []}}, + {options, [{active, true} | ClientOpts]}]), + + ssl_test_lib:check_result(Client1, ok), + ssl_test_lib:close(Server), + ssl_test_lib:close(Client1). + %%-------------------------------------------------------------------- +server_verify_client_once_active_once(doc) -> + ["Test server option verify_client_once"]; + +server_verify_client_once_active_once(suite) -> + []; + +server_verify_client_once_active_once(Config) when is_list(Config) -> + ClientOpts = ?config(client_opts, Config), + ServerOpts = ?config(server_verification_opts, Config), + {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config), + Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0}, + {from, self()}, + {mfa, {?MODULE, send_recv_result_active_once, []}}, + {options, [{active, once}, {verify, verify_peer}, + {verify_client_once, true} + | ServerOpts]}]), + Port = ssl_test_lib:inet_port(Server), + Client0 = ssl_test_lib:start_client([{node, ClientNode}, {port, Port}, + {host, Hostname}, + {from, self()}, + {mfa, {?MODULE, send_recv_result_active_once, []}}, + {options, [{active, once} | ClientOpts]}]), + + ssl_test_lib:check_result(Server, ok, Client0, ok), + ssl_test_lib:close(Client0), + Server ! listen, + + Client1 = ssl_test_lib:start_client([{node, ClientNode}, {port, Port}, + {host, Hostname}, + {from, self()}, + {mfa, {?MODULE, result_ok, []}}, + {options, [{active, once} | ClientOpts]}]), + + ssl_test_lib:check_result(Client1, ok), + ssl_test_lib:close(Server), + ssl_test_lib:close(Client1). + +%%-------------------------------------------------------------------- + server_verify_no_cacerts(doc) -> ["Test server must have cacerts if it wants to verify client"]; @@ -1874,17 +1881,19 @@ server_require_peer_cert_fail(Config) when is_list(Config) -> | ?config(server_verification_opts, Config)], BadClientOpts = ?config(client_opts, Config), {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config), - Port = ssl_test_lib:inet_port(ServerNode), - - Server = ssl_test_lib:start_server_error([{node, ServerNode}, {port, Port}, + + Server = ssl_test_lib:start_server_error([{node, ServerNode}, {port, 0}, {from, self()}, - {mfa, {?MODULE, send_recv_result, []}}, + {mfa, {?MODULE, no_result, []}}, {options, [{active, false} | ServerOpts]}]), - Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port}, - {host, Hostname}, - {from, self()}, - {mfa, {?MODULE, send_recv_result, []}}, - {options, [{active, false} | BadClientOpts]}]), + + Port = ssl_test_lib:inet_port(Server), + + Client = ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port}, + {host, Hostname}, + {from, self()}, + {mfa, {?MODULE, no_result, []}}, + {options, [{active, false} | BadClientOpts]}]), ssl_test_lib:check_result(Server, {error, esslaccept}, Client, {error, esslconnect}), @@ -2146,6 +2155,97 @@ server_no_wrap_sequence_number(Config) when is_list(Config) -> ok. %%-------------------------------------------------------------------- +extended_key_usage(doc) -> + ["Test cert that has a critical extended_key_usage extension"]; + +extended_key_usage(suite) -> + []; + +extended_key_usage(Config) when is_list(Config) -> + ClientOpts = ?config(client_opts, Config), + ServerOpts = ?config(server_opts, Config), + PrivDir = ?config(priv_dir, Config), + + CertFile = proplists:get_value(certfile, ServerOpts), + KeyFile = proplists:get_value(keyfile, ServerOpts), + NewCertFile = filename:join(PrivDir, "cert.pem"), + + {ok, [{cert, DerCert, _}]} = public_key:pem_to_der(CertFile), + + {ok, [KeyInfo]} = public_key:pem_to_der(KeyFile), + + {ok, Key} = public_key:decode_private_key(KeyInfo), + + {ok, OTPCert} = public_key:pkix_decode_cert(DerCert, otp), + + ExtKeyUsageExt = {'Extension', ?'id-ce-extKeyUsage', true, [?'id-kp-serverAuth']}, + + OTPTbsCert = OTPCert#'OTPCertificate'.tbsCertificate, + + Extensions = OTPTbsCert#'OTPTBSCertificate'.extensions, + + NewOTPTbsCert = OTPTbsCert#'OTPTBSCertificate'{extensions = [ExtKeyUsageExt |Extensions]}, + + NewDerCert = public_key:sign(NewOTPTbsCert, Key), + + public_key:der_to_pem(NewCertFile, [{cert, NewDerCert}]), + + NewServerOpts = [{certfile, NewCertFile} | proplists:delete(certfile, ServerOpts)], + + {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config), + + Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0}, + {from, self()}, + {mfa, {?MODULE, send_recv_result_active, []}}, + {options, NewServerOpts}]), + Port = ssl_test_lib:inet_port(Server), + Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port}, + {host, Hostname}, + {from, self()}, + {mfa, {?MODULE, send_recv_result_active, []}}, + {options, ClientOpts}]), + + ssl_test_lib:check_result(Server, ok, Client, ok), + + ssl_test_lib:close(Server), + ssl_test_lib:close(Client). + +%%-------------------------------------------------------------------- +validate_extensions_fun(doc) -> + ["Test that it is possible to specify a validate_extensions_fun"]; + +validate_extensions_fun(suite) -> + []; + +validate_extensions_fun(Config) when is_list(Config) -> + ClientOpts = ?config(client_verification_opts, Config), + ServerOpts = ?config(server_verification_opts, Config), + + Fun = fun(Extensions, State, _, AccError) -> + {Extensions, State, AccError} + end, + + {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config), + + Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0}, + {from, self()}, + {mfa, {?MODULE, send_recv_result_active, []}}, + {options, [{validate_extensions_fun, Fun}, + {verify, verify_peer} | ServerOpts]}]), + Port = ssl_test_lib:inet_port(Server), + + Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port}, + {host, Hostname}, + {from, self()}, + {mfa, {?MODULE, send_recv_result_active, []}}, + {options,[{validate_extensions_fun, Fun} | ClientOpts]}]), + + ssl_test_lib:check_result(Server, ok, Client, ok), + + ssl_test_lib:close(Server), + ssl_test_lib:close(Client). + +%%-------------------------------------------------------------------- %%% Internal functions %%-------------------------------------------------------------------- send_recv_result(Socket) -> @@ -2167,20 +2267,26 @@ send_recv_result_active_once(Socket) -> ok end. +result_ok(_Socket) -> + ok. renegotiate(Socket, Data) -> - [{session_id, Id} | _ ] = ssl:session_info(Socket), - ssl:renegotiate(Socket), + test_server:format("Renegotiating ~n", []), + Result = ssl:renegotiate(Socket), + test_server:format("Result ~p~n", [Result]), ssl:send(Socket, Data), - test_server:sleep(1000), - case ssl:session_info(Socket) of - [{session_id, Id} | _ ] -> - fail_session_not_renegotiated; - _ -> - ok + case Result of + ok -> + ok; + %% It is not an error in erlang ssl + %% if peer rejects renegotiation. + %% Connection will stay up + {error, renegotiation_rejected} -> + ok; + Other -> + Other end. - session_cache_process_list(doc) -> ["Test reuse of sessions (short handshake)"]; @@ -2426,7 +2532,7 @@ erlang_ssl_receive(Socket, Data) -> ok; Other -> test_server:fail({unexpected_message, Other}) - after 4000 -> + after ?SLEEP * 3 -> test_server:fail({did_not_get, Data}) end. |