summaryrefslogtreecommitdiff
path: root/lib/ssl/test/ssl_basic_SUITE.erl
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ssl/test/ssl_basic_SUITE.erl')
-rw-r--r--lib/ssl/test/ssl_basic_SUITE.erl388
1 files changed, 374 insertions, 14 deletions
diff --git a/lib/ssl/test/ssl_basic_SUITE.erl b/lib/ssl/test/ssl_basic_SUITE.erl
index fbe2d4f6b0..a5ece4fad8 100644
--- a/lib/ssl/test/ssl_basic_SUITE.erl
+++ b/lib/ssl/test/ssl_basic_SUITE.erl
@@ -22,12 +22,71 @@
-module(ssl_basic_SUITE).
-%% Note: This directive should only be used in test suites.
--compile(export_all).
+-behaviour(ct_suite).
-include_lib("common_test/include/ct.hrl").
+-include_lib("public_key/include/public_key.hrl").
-include_lib("ssl/src/ssl_api.hrl").
+%% Callback functions
+-export([all/0,
+ groups/0,
+ init_per_suite/1,
+ end_per_suite/1,
+ init_per_testcase/2,
+ end_per_testcase/2]).
+
+%% Testcases
+-export([app/0,
+ app/1,
+ appup/0,
+ appup/1,
+ version_option/0,
+ version_option/1,
+ connect_twice/0,
+ connect_twice/1,
+ connect_dist/0,
+ connect_dist/1,
+ defaults/1,
+ fallback/0,
+ fallback/1,
+ cipher_format/0,
+ cipher_format/1,
+ tls_versions_option/0,
+ tls_versions_option/1,
+ eccs/0,
+ eccs/1,
+ cipher_suites/0,
+ cipher_suites/1,
+ old_cipher_suites/0,
+ old_cipher_suites/1,
+ cipher_suites_mix/0,
+ cipher_suites_mix/1,
+ unordered_protocol_versions_server/0,
+ unordered_protocol_versions_server/1,
+ unordered_protocol_versions_client/0,
+ unordered_protocol_versions_client/1,
+ fake_root/0,
+ fake_root/1,
+ fake_root_legacy/0,
+ fake_root_legacy/1,
+ fake_root_no_intermediate/0,
+ fake_root_no_intermediate/1,
+ fake_root_no_intermediate_legacy/0,
+ fake_root_no_intermediate_legacy/1,
+ fake_intermediate_cert/0,
+ fake_intermediate_cert/1
+ ]).
+
+%% Apply export
+-export([tcp_send_recv_result/1,
+ result_ok/1,
+ protocol_info_result/1,
+ version_info_result/1,
+ connect_dist_s/1,
+ connect_dist_c/1,
+ dummy/1
+ ]).
-define(TIMEOUT, 20000).
-define(EXPIRE, 10).
@@ -63,7 +122,12 @@ basic_tests() ->
eccs,
cipher_suites,
old_cipher_suites,
- cipher_suites_mix
+ cipher_suites_mix,
+ fake_root,
+ fake_root_no_intermediate,
+ fake_root_legacy,
+ fake_root_no_intermediate_legacy,
+ fake_intermediate_cert
].
options_tests() ->
@@ -76,7 +140,7 @@ init_per_suite(Config0) ->
try crypto:start() of
ok ->
ssl_test_lib:clean_start(),
- %% make rsa certs using oppenssl
+ %% make rsa certs using openssl
{ok, _} = make_certs:all(proplists:get_value(data_dir, Config0),
proplists:get_value(priv_dir, Config0)),
Config1 = ssl_test_lib:make_dsa_cert(Config0),
@@ -173,7 +237,7 @@ connect_twice(Config) when is_list(Config) ->
ssl_test_lib:close(Client1).
defaults(Config) when is_list(Config)->
Versions = ssl:versions(),
- true = lists:member(sslv3, proplists:get_value(available, Versions)),
+ false = lists:member(sslv3, proplists:get_value(available, Versions)),
false = lists:member(sslv3, proplists:get_value(supported, Versions)),
true = lists:member('tlsv1', proplists:get_value(available, Versions)),
false = lists:member('tlsv1', proplists:get_value(supported, Versions)),
@@ -244,7 +308,7 @@ cipher_suites(Config) when is_list(Config) ->
cipher => 'aes_128_cbc',
mac => sha,
prf => default_prf},
- Version = ssl_test_lib:protocol_version(Config),
+ Version = tls_record:highest_protocol_version([]),
All = [_|_] = ssl:cipher_suites(all, Version),
Default = [_|_] = ssl:cipher_suites(default, Version),
Anonymous = [_|_] = ssl:cipher_suites(anonymous, Version),
@@ -321,7 +385,7 @@ cipher_suites_mix(Config) when is_list(Config) ->
{host, Hostname},
{from, self()},
{mfa, {ssl_test_lib, send_recv_result_active, []}},
- {options, [{ciphers, CipherSuites} | ClientOpts]}]),
+ {options, [{versions, ['tlsv1.2']},{ciphers, CipherSuites} | ClientOpts]}]),
ssl_test_lib:check_result(Server, ok, Client, ok),
ssl_test_lib:close(Server),
@@ -406,7 +470,6 @@ eccs() ->
eccs(Config) when is_list(Config) ->
[_|_] = All = ssl:eccs(),
- [] = ssl:eccs(sslv3),
[_|_] = Tls = ssl:eccs(tlsv1),
[_|_] = Tls1 = ssl:eccs('tlsv1.1'),
[_|_] = Tls2 = ssl:eccs('tlsv1.2'),
@@ -450,14 +513,252 @@ tls_versions_option(Config) when is_list(Config) ->
end,
ssl_test_lib:check_client_alert(ErrClient, protocol_version).
+fake_root() ->
+ [{doc,"Test that we can not use a fake root signed by other key but with correct name and serial number."}].
+fake_root(Config) when is_list(Config) ->
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Ext = x509_test:extensions([{key_usage, [keyCertSign, cRLSign, digitalSignature, keyAgreement]}]),
+ ROOT = #{cert := Cert,
+ key := _Key} = public_key:pkix_test_root_cert("SERVER ROOT CA", [{key, ssl_test_lib:hardcode_rsa_key(6)},
+ {extensions, Ext}]),
+
+ FakeKey = ssl_test_lib:hardcode_rsa_key(1),
+ OTPCert = public_key:pkix_decode_cert(Cert, otp),
+ TBS = OTPCert#'OTPCertificate'.tbsCertificate,
+ FakeCert = public_key:pkix_sign(TBS, FakeKey),
+
+
+ AuthExt = #'AuthorityKeyIdentifier'{authorityCertIssuer = [{directoryName, TBS#'OTPTBSCertificate'.issuer}],
+ authorityCertSerialNumber = TBS#'OTPTBSCertificate'.serialNumber},
+ [AuthKeyExt] = x509_test:extensions([{?'id-ce-authorityKeyIdentifier',
+ AuthExt,
+ false}]),
+
+ #{server_config := ServerConf,
+ client_config := ClientConf} = public_key:pkix_test_data(#{server_chain =>
+ #{root => ROOT,
+ intermediates => [[{key, ssl_test_lib:hardcode_rsa_key(5)},
+ {extensions, [AuthKeyExt]}]],
+ peer => [{key, ssl_test_lib:hardcode_rsa_key(4)}]},
+ client_chain =>
+ #{root => [{key, ssl_test_lib:hardcode_rsa_key(1)}],
+ intermediates => [[{key, ssl_test_lib:hardcode_rsa_key(2)}]],
+ peer => [{key, ssl_test_lib:hardcode_rsa_key(3)}]}}
+ ),
+
+ #{server_config := FakeServerConf} = public_key:pkix_test_data(#{server_chain =>
+ #{root => #{cert => FakeCert, key => FakeKey},
+ intermediates => [[{key, ssl_test_lib:hardcode_rsa_key(2)},
+ {extensions, [AuthKeyExt]}]],
+ peer => [{key, ssl_test_lib:hardcode_rsa_key(3)}]},
+ client_chain =>
+ #{root => [{key, ssl_test_lib:hardcode_rsa_key(1)}],
+ intermediates => [[{key, ssl_test_lib:hardcode_rsa_key(2)}]],
+ peer => [{key, ssl_test_lib:hardcode_rsa_key(3)}]}}
+ ),
+
+
+ test_fake_root(Hostname, ServerNode, ClientNode, ServerConf, ClientConf, FakeCert, FakeServerConf, bad_certificate, bad_certificate).
+
+fake_root_no_intermediate() ->
+ [{doc,"Test that we can not use a fake root signed by other key but with correct name and serial number."}].
+
+fake_root_no_intermediate(Config) when is_list(Config) ->
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Ext = x509_test:extensions([{key_usage, [keyCertSign, cRLSign, digitalSignature, keyAgreement]}]),
+ ROOT = #{cert := Cert,
+ key := _Key} = public_key:pkix_test_root_cert("SERVER ROOT CA", [{key, ssl_test_lib:hardcode_rsa_key(6)},
+ {extensions, Ext}]),
+
+ FakeKey = ssl_test_lib:hardcode_rsa_key(1),
+ OTPCert = public_key:pkix_decode_cert(Cert, otp),
+ TBS = OTPCert#'OTPCertificate'.tbsCertificate,
+ FakeCert = public_key:pkix_sign(TBS, FakeKey),
+
+ AuthExt = #'AuthorityKeyIdentifier'{authorityCertIssuer = [{directoryName, TBS#'OTPTBSCertificate'.issuer}],
+ authorityCertSerialNumber = TBS#'OTPTBSCertificate'.serialNumber},
+ [AuthKeyExt] = x509_test:extensions([{?'id-ce-authorityKeyIdentifier',
+ AuthExt,
+ false}]),
+
+
+ #{server_config := ServerConf,
+ client_config := ClientConf} = public_key:pkix_test_data(#{server_chain =>
+ #{root => ROOT,
+ intermediates => [],
+ peer => [{key, ssl_test_lib:hardcode_rsa_key(4)},
+ {extensions, [AuthKeyExt]}]},
+ client_chain =>
+ #{root => [{key, ssl_test_lib:hardcode_rsa_key(1)}],
+ intermediates => [[{key, ssl_test_lib:hardcode_rsa_key(2)}]],
+ peer => [{key, ssl_test_lib:hardcode_rsa_key(3)}]}}
+ ),
+
+ #{server_config := FakeServerConf} = public_key:pkix_test_data(#{server_chain =>
+ #{root => #{cert => FakeCert, key => FakeKey},
+ intermediates => [],
+ peer => [{key, ssl_test_lib:hardcode_rsa_key(3)},
+ {extensions, [AuthKeyExt]}]},
+ client_chain =>
+ #{root => [{key, ssl_test_lib:hardcode_rsa_key(1)}],
+ intermediates => [[{key, ssl_test_lib:hardcode_rsa_key(2)}]],
+ peer => [{key, ssl_test_lib:hardcode_rsa_key(3)}]}}
+ ),
+ test_fake_root(Hostname, ServerNode, ClientNode, ServerConf, ClientConf, FakeCert, FakeServerConf, bad_certificate, bad_certificate).
+
+fake_root_legacy() ->
+ [{doc,"Test that we can not use a fake root signed by other key but with correct name and serial number."}].
+fake_root_legacy(Config) when is_list(Config) ->
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Ext = x509_test:extensions([{key_usage, [keyCertSign, cRLSign, digitalSignature, keyAgreement]}]),
+ ROOT = #{cert := Cert,
+ key := _Key} = public_key:pkix_test_root_cert("SERVER ROOT CA", [{key, ssl_test_lib:hardcode_rsa_key(6)},
+ {extensions, Ext}]),
+
+ FakeKey = ssl_test_lib:hardcode_rsa_key(1),
+ OTPCert = public_key:pkix_decode_cert(Cert, otp),
+ TBS = OTPCert#'OTPCertificate'.tbsCertificate,
+ FakeCert = public_key:pkix_sign(TBS, FakeKey),
+
+ #{server_config := ServerConf,
+ client_config := ClientConf} = public_key:pkix_test_data(#{server_chain =>
+ #{root => ROOT,
+ intermediates => [[{key, ssl_test_lib:hardcode_rsa_key(5)}]],
+ peer => [{key, ssl_test_lib:hardcode_rsa_key(4)}]},
+ client_chain =>
+ #{root => [{key, ssl_test_lib:hardcode_rsa_key(1)}],
+ intermediates => [[{key, ssl_test_lib:hardcode_rsa_key(2)}]],
+ peer => [{key, ssl_test_lib:hardcode_rsa_key(3)}]}}
+ ),
+
+ #{server_config := FakeServerConf} = public_key:pkix_test_data(#{server_chain =>
+ #{root => #{cert => FakeCert, key => FakeKey},
+ intermediates => [[{key, ssl_test_lib:hardcode_rsa_key(2)}]],
+ peer => [{key, ssl_test_lib:hardcode_rsa_key(3)}]},
+ client_chain =>
+ #{root => [{key, ssl_test_lib:hardcode_rsa_key(1)}],
+ intermediates => [[{key, ssl_test_lib:hardcode_rsa_key(2)}]],
+ peer => [{key, ssl_test_lib:hardcode_rsa_key(3)}]}}
+ ),
+
+
+ test_fake_root(Hostname, ServerNode, ClientNode, ServerConf, ClientConf, FakeCert, FakeServerConf, unknown_ca, unknown_ca).
+
+fake_root_no_intermediate_legacy() ->
+ [{doc,"Test that we can not use a fake root signed by other key but with correct name and serial number."}].
+fake_root_no_intermediate_legacy(Config) when is_list(Config) ->
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Ext = x509_test:extensions([{key_usage, [keyCertSign, cRLSign, digitalSignature, keyAgreement]}]),
+ ROOT = #{cert := Cert,
+ key := _Key} = public_key:pkix_test_root_cert("SERVER ROOT CA", [{key, ssl_test_lib:hardcode_rsa_key(6)},
+ {extensions, Ext}]),
+
+ FakeKey = ssl_test_lib:hardcode_rsa_key(1),
+ OTPCert = public_key:pkix_decode_cert(Cert, otp),
+ TBS = OTPCert#'OTPCertificate'.tbsCertificate,
+ FakeCert = public_key:pkix_sign(TBS, FakeKey),
+
+ #{server_config := ServerConf,
+ client_config := ClientConf} = public_key:pkix_test_data(#{server_chain =>
+ #{root => ROOT,
+ intermediates => [],
+ peer => [{key, ssl_test_lib:hardcode_rsa_key(4)}]},
+ client_chain =>
+ #{root => [{key, ssl_test_lib:hardcode_rsa_key(1)}],
+ intermediates => [[{key, ssl_test_lib:hardcode_rsa_key(2)}]],
+ peer => [{key, ssl_test_lib:hardcode_rsa_key(3)}]}}
+ ),
+
+ #{server_config := FakeServerConf} = public_key:pkix_test_data(#{server_chain =>
+ #{root => #{cert => FakeCert, key => FakeKey},
+ intermediates => [],
+ peer => [{key, ssl_test_lib:hardcode_rsa_key(3)}]},
+ client_chain =>
+ #{root => [{key, ssl_test_lib:hardcode_rsa_key(1)}],
+ intermediates => [[{key, ssl_test_lib:hardcode_rsa_key(2)}]],
+ peer => [{key, ssl_test_lib:hardcode_rsa_key(3)}]}}
+ ),
+ test_fake_root(Hostname, ServerNode, ClientNode, ServerConf, ClientConf, FakeCert, FakeServerConf, unknown_ca, unknown_ca).
+
+fake_intermediate_cert() ->
+ [{doc,"Test that we can not use a fake intermediat cert claiming to be signed by a trusted ROOT but is not."}].
+
+fake_intermediate_cert(Config) when is_list(Config) ->
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Ext = x509_test:extensions([{key_usage, [keyCertSign, cRLSign, digitalSignature, keyAgreement]}]),
+ ROOT = #{cert := Cert,
+ key := _Key} = public_key:pkix_test_root_cert("SERVER ROOT CA", [{key, ssl_test_lib:hardcode_rsa_key(6)},
+ {extensions, Ext}]),
+
+ OtherSROOT = #{cert := OtherSCert,
+ key := OtherSKey} = public_key:pkix_test_root_cert("OTHER SERVER ROOT CA", [{key, ssl_test_lib:hardcode_rsa_key(3)},
+ {extensions, Ext}]),
+ OtherCROOT = #{cert := OtherCCert,
+ key := _OtherCKey} = public_key:pkix_test_root_cert("OTHER Client ROOT CA", [{key, ssl_test_lib:hardcode_rsa_key(1)},
+ {extensions, Ext}]),
+
+ #{client_config := ClientConf} = public_key:pkix_test_data(#{server_chain =>
+ #{root => ROOT,
+ intermediates => [[{key, ssl_test_lib:hardcode_rsa_key(5)}]],
+ peer => [{key, ssl_test_lib:hardcode_rsa_key(4)}]},
+ client_chain =>
+ #{root => [{key, ssl_test_lib:hardcode_rsa_key(1)}],
+ intermediates => [[{key, ssl_test_lib:hardcode_rsa_key(2)}]],
+ peer => [{key, ssl_test_lib:hardcode_rsa_key(3)}]}}
+ ),
+
+ #{server_config := OtherServerConf} = public_key:pkix_test_data(#{server_chain =>
+ #{root => OtherSROOT,
+ intermediates => [[{key, ssl_test_lib:hardcode_rsa_key(2)}]],
+ peer => [{key, ssl_test_lib:hardcode_rsa_key(1)}]},
+ client_chain =>
+ #{root => OtherCROOT,
+ intermediates => [[{key, ssl_test_lib:hardcode_rsa_key(2)}]],
+ peer => [{key, ssl_test_lib:hardcode_rsa_key(3)}]}}
+ ),
+ OTPCert = public_key:pkix_decode_cert(Cert, otp),
+ TBS = OTPCert#'OTPCertificate'.tbsCertificate,
+ TBSExt = TBS#'OTPTBSCertificate'.extensions,
+ AuthExt = #'AuthorityKeyIdentifier'{authorityCertIssuer = [{directoryName, TBS#'OTPTBSCertificate'.issuer}],
+ authorityCertSerialNumber = TBS#'OTPTBSCertificate'.serialNumber},
+ [AuthKeyExt] = x509_test:extensions([{?'id-ce-authorityKeyIdentifier',
+ AuthExt,
+ false}]),
+
+
+ CAs = proplists:get_value(cacerts, OtherServerConf),
+
+ [ICA] = CAs -- [OtherSCert, OtherCCert],
+
+ OTPICACert = public_key:pkix_decode_cert(ICA, otp),
+ ICATBS = OTPICACert#'OTPCertificate'.tbsCertificate,
+
+ FakeICA = public_key:pkix_sign(ICATBS#'OTPTBSCertificate'{extensions = [AuthKeyExt | TBSExt]}, OtherSKey),
+
+ ServerCert = proplists:get_value(cert, OtherServerConf),
+ FakeServer = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {ssl_test_lib, no_result, []}},
+ {options, [{cert, [ServerCert, FakeICA]} |
+ proplists:delete(cert, OtherServerConf)]
+ }]),
+ Port1 = ssl_test_lib:inet_port(FakeServer),
+
+ Client1 = ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port1},
+ {host, Hostname},
+ {from, self()},
+ {options, [{verify, verify_peer} | ClientConf]}]),
+
+ ssl_test_lib:check_client_alert(Client1, bad_certificate).
%%--------------------------------------------------------------------
-%% Internal functions ------------------------------------------------
+%% callback functions ------------------------------------------------
%%--------------------------------------------------------------------
-send_recv_result(Socket) ->
- ssl:send(Socket, "Hello world"),
- {ok,"Hello world"} = ssl:recv(Socket, 11),
- ok.
tcp_send_recv_result(Socket) ->
gen_tcp:send(Socket, "Hello world"),
{ok,"Hello world"} = gen_tcp:recv(Socket, 11),
@@ -489,7 +790,9 @@ dummy(_Socket) ->
%% Should not happen as the ssl connection will not be established
%% due to fatal handshake failiure
exit(kill).
-
+%%--------------------------------------------------------------------
+%% Internal functions ------------------------------------------------
+%%--------------------------------------------------------------------
version_option_test(Config, Version) ->
ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
@@ -526,3 +829,60 @@ remove_supported_versions(Available, Supported) ->
Versions0
end.
+
+test_fake_root(Hostname, ServerNode, ClientNode, ServerConf, ClientConf, FakeCert, FakeServerConf, ResultRootIncluded, ResultRootExcluded) ->
+ RealServer = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {ssl_test_lib, send_recv_result_active, []}},
+ {options, ServerConf}]),
+ Port0 = ssl_test_lib:inet_port(RealServer),
+ Client0 = ssl_test_lib:start_client([{node, ClientNode}, {port, Port0},
+ {host, Hostname},
+ {mfa, {ssl_test_lib, send_recv_result_active, []}},
+ {from, self()},
+ {options, [{verify, verify_peer} | ClientConf]}]),
+
+ ssl_test_lib:check_result(RealServer, ok, Client0, ok),
+
+ ssl_test_lib:close(RealServer),
+ ssl_test_lib:close(Client0),
+
+ %% Fake server sends ROOT cert
+ FakeServer = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {ssl_test_lib, no_result, []}},
+ {options, FakeServerConf}]),
+ Port1 = ssl_test_lib:inet_port(FakeServer),
+
+ Client1 = ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port1},
+ {host, Hostname},
+ {from, self()},
+ {options, [{verify, verify_peer} | ClientConf]}]),
+
+ ssl_test_lib:check_client_alert(Client1, ResultRootIncluded),
+
+
+ %%Fake server does not send ROOT cert
+ CAS0 = proplists:get_value(cacerts, FakeServerConf),
+ CAS1 = CAS0 -- [FakeCert],
+
+ FakeServer1 = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {ssl_test_lib, no_result, []}},
+ {options, [{cacerts, CAS1} | proplists:delete(cacerts, FakeServerConf)]}]),
+
+ Port2 = ssl_test_lib:inet_port(FakeServer1),
+
+ Client2 = ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port2},
+ {host, Hostname},
+ {from, self()},
+ {options, [{verify, verify_peer} | ClientConf]}]),
+
+ ssl_test_lib:check_client_alert(Client2, ResultRootExcluded),
+
+ ssl_test_lib:close(FakeServer1).
+
+
+
+
+