aboutsummaryrefslogtreecommitdiffstats
path: root/lib/ssl
diff options
context:
space:
mode:
authorRory Byrne <[email protected]>2010-04-05 16:23:36 +0100
committerRory Byrne <[email protected]>2010-04-05 17:57:38 +0100
commit16dafd19b34d1b458cf68857f65c7d3c77d6f291 (patch)
treeef5ac78d384207a5d3164fb5a5cc2bb2a720cc88 /lib/ssl
parentc75443977b2957c8f0d35b0765c5a8b8859315f2 (diff)
downloadotp-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.erl3
-rw-r--r--lib/ssl/test/ssl_basic_SUITE.erl64
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) ->