diff options
author | Rory Byrne <[email protected]> | 2010-04-05 16:23:36 +0100 |
---|---|---|
committer | Rory Byrne <[email protected]> | 2010-04-05 17:57:38 +0100 |
commit | 16dafd19b34d1b458cf68857f65c7d3c77d6f291 (patch) | |
tree | ef5ac78d384207a5d3164fb5a5cc2bb2a720cc88 /lib/ssl | |
parent | c75443977b2957c8f0d35b0765c5a8b8859315f2 (diff) | |
download | otp-16dafd19b34d1b458cf68857f65c7d3c77d6f291.tar.gz otp-16dafd19b34d1b458cf68857f65c7d3c77d6f291.tar.bz2 otp-16dafd19b34d1b458cf68857f65c7d3c77d6f291.zip |
Fix verification of ssl client when fail_if_no_peer_cert
The SSL handshake fails when an ssl server is configured with the
'fail_if_no_peer_cert' option and a valid client sends its certificate
as instructed. On the server-side ssl:ssl_accept/2 will return
{error,esslerrssl}, and it will send an "Unexpected Message" SSL Alert
(type 10) to the client.
Diffstat (limited to 'lib/ssl')
-rw-r--r-- | lib/ssl/src/ssl_connection.erl | 3 | ||||
-rw-r--r-- | lib/ssl/test/ssl_basic_SUITE.erl | 64 |
2 files changed, 64 insertions, 3 deletions
diff --git a/lib/ssl/src/ssl_connection.erl b/lib/ssl/src/ssl_connection.erl index 4ec90600e9..defcfa31bd 100644 --- a/lib/ssl/src/ssl_connection.erl +++ b/lib/ssl/src/ssl_connection.erl @@ -441,7 +441,8 @@ certify(#certificate{} = Cert, Opts#ssl_options.verify, Opts#ssl_options.verify_fun) of {PeerCert, PublicKeyInfo} -> - handle_peer_cert(PeerCert, PublicKeyInfo, State); + State1 = State#state{client_certificate_requested = false}, + handle_peer_cert(PeerCert, PublicKeyInfo, State1); #alert{} = Alert -> handle_own_alert(Alert, Version, certify_certificate, State), {stop, normal, State} diff --git a/lib/ssl/test/ssl_basic_SUITE.erl b/lib/ssl/test/ssl_basic_SUITE.erl index 41624cf087..30a721b0b5 100644 --- a/lib/ssl/test/ssl_basic_SUITE.erl +++ b/lib/ssl/test/ssl_basic_SUITE.erl @@ -159,8 +159,9 @@ all(suite) -> server_verify_peer_passive, server_verify_peer_active, server_verify_peer_active_once, server_verify_none_passive, server_verify_none_active, - server_verify_none_active_once, - server_verify_no_cacerts, client_verify_none_passive, + server_verify_none_active_once, server_verify_no_cacerts, + server_require_peer_cert_ok, server_require_peer_cert_fail, + 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, @@ -1832,7 +1833,66 @@ server_verify_no_cacerts(Config) when is_list(Config) -> | ServerOpts]}]), ssl_test_lib:check_result(Server, {error, {eoptions, {cacertfile, ""}}}). + +%%-------------------------------------------------------------------- + +server_require_peer_cert_ok(doc) -> + ["Test server option fail_if_no_peer_cert when peer sends cert"]; + +server_require_peer_cert_ok(suite) -> + []; + +server_require_peer_cert_ok(Config) when is_list(Config) -> + ServerOpts = [{verify, verify_peer}, {fail_if_no_peer_cert, true} + | ?config(server_verification_opts, Config)], + ClientOpts = ?config(client_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} | 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, []}}, + {options, [{active, false} | ClientOpts]}]), + + ssl_test_lib:check_result(Server, ok, Client, ok), + ssl_test_lib:close(Server), + ssl_test_lib:close(Client). + +%%-------------------------------------------------------------------- + +server_require_peer_cert_fail(doc) -> + ["Test server option fail_if_no_peer_cert when peer doesn't send cert"]; + +server_require_peer_cert_fail(suite) -> + []; + +server_require_peer_cert_fail(Config) when is_list(Config) -> + ServerOpts = [{verify, verify_peer}, {fail_if_no_peer_cert, true} + | ?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}, + {from, self()}, + {mfa, {?MODULE, send_recv_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]}]), + ssl_test_lib:check_result(Server, {error, esslaccept}, + Client, {error, esslconnect}), + ssl_test_lib:close(Server), + ssl_test_lib:close(Client). + %%-------------------------------------------------------------------- client_verify_none_passive(doc) -> |