diff options
author | Ingela Anderton Andin <ingela@erlang.org> | 2021-03-31 15:47:46 +0200 |
---|---|---|
committer | Ingela Anderton Andin <ingela@erlang.org> | 2021-04-02 15:22:50 +0200 |
commit | 691d66b814fb7f3ac3791f34cb69f8e2e0b93de6 (patch) | |
tree | 774c6fef35980ca9aa63b93413871d06642534cf /lib/ssl/test | |
parent | c3784253e168e4f7acf301015e5461eacf884e4e (diff) | |
download | erlang-691d66b814fb7f3ac3791f34cb69f8e2e0b93de6.tar.gz |
ssl: Make sure incomplete chain is a prefix of the new chain candidate
When trying to reconstruct an incomplete chain we must not
use a constructed chain that is a shorter incomplete chain than
the original chain. This might happen if we have a chain that we
will not be able to reconstruct and hence verify. Even though this
is not a problem from a verification point (will fail with unknown_ca anyway)
it could cause different behavior for a verify_fun.
Closes #4682
Diffstat (limited to 'lib/ssl/test')
-rw-r--r-- | lib/ssl/test/ssl_basic_SUITE.erl | 75 |
1 files changed, 73 insertions, 2 deletions
diff --git a/lib/ssl/test/ssl_basic_SUITE.erl b/lib/ssl/test/ssl_basic_SUITE.erl index a5ece4fad8..ce0a2d0902 100644 --- a/lib/ssl/test/ssl_basic_SUITE.erl +++ b/lib/ssl/test/ssl_basic_SUITE.erl @@ -75,7 +75,9 @@ fake_root_no_intermediate_legacy/0, fake_root_no_intermediate_legacy/1, fake_intermediate_cert/0, - fake_intermediate_cert/1 + fake_intermediate_cert/1, + incompleat_chain_length/0, + incompleat_chain_length/1 ]). %% Apply export @@ -127,7 +129,8 @@ basic_tests() -> fake_root_no_intermediate, fake_root_legacy, fake_root_no_intermediate_legacy, - fake_intermediate_cert + fake_intermediate_cert, + incompleat_chain_length ]. options_tests() -> @@ -756,6 +759,74 @@ fake_intermediate_cert(Config) when is_list(Config) -> ssl_test_lib:check_client_alert(Client1, bad_certificate). +incompleat_chain_length() -> + [{doc,"Test that attempts to reconstruct incomplete chains does not make shorter incomplete chains"}]. +incompleat_chain_length(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 = public_key:pkix_test_root_cert("SERVER ROOT CA", [{key, ssl_test_lib:hardcode_rsa_key(6)}, + {extensions, Ext}]), + + OtherROOT = public_key:pkix_test_root_cert("OTHER SERVER ROOT CA", [{key, ssl_test_lib:hardcode_rsa_key(3)}, + {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 := ServerConf} = public_key:pkix_test_data(#{server_chain => + #{root => OtherROOT, + intermediates => [[{key, ssl_test_lib:hardcode_rsa_key(2)}], + [{key, ssl_test_lib:hardcode_rsa_key(3)}] + ], + peer => [{key, ssl_test_lib:hardcode_rsa_key(1)}]}, + 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)}]}} + ), + + + VerifyFun = {fun(_,{bad_cert, unknown_ca}, UserState) -> + %% accept this error to provoke the + %% building of an shorter incomplete chain + %% than the one recived + {valid, UserState}; + (_,{extension, _} = Extension, #{ext := N} = UserState) -> + ct:pal("~p", [Extension]), + {unknown, UserState#{ext => N +1}}; + (_, valid, #{intermediates := N} = UserState) -> + {valid, UserState#{intermediates => N +1}}; + (_, valid_peer, #{intermediates := 2, + ext := 1} = UserState) -> + {valid, UserState}; + (_, valid_peer, UserState) -> + ct:pal("~p", [UserState]), + {error, {bad_cert, too_short_path}} + end, #{intermediates => 0, + ext => 0}}, + + Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0}, + {from, self()}, + {mfa, {ssl_test_lib, send_recv_result_active, []}}, + {options, ServerConf} + ]), + Port = ssl_test_lib:inet_port(Server), + + Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port}, + {host, Hostname}, + {from, self()}, + {mfa, {ssl_test_lib, send_recv_result_active, []}}, + {options, [{verify, verify_peer}, {verify_fun, VerifyFun} | ClientConf]}]), + ssl_test_lib:check_result(Client, ok, Server, ok). + %%-------------------------------------------------------------------- %% callback functions ------------------------------------------------ %%-------------------------------------------------------------------- |