Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:Ledest:erlang:23
erlang
1023-ssl-Make-sure-refresh-of-trusted-certs-rep...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 1023-ssl-Make-sure-refresh-of-trusted-certs-repopulates-c.patch of Package erlang
From d06aafba3b546157f9a4893d837e74bb69b6728c Mon Sep 17 00:00:00 2001 From: Ingela Anderton Andin <ingela@erlang.org> Date: Sat, 18 Jun 2022 11:40:01 +0200 Subject: [PATCH] ssl: Make sure refresh of trusted certs repopulates cache --- lib/ssl/src/ssl_certificate.erl | 16 +- lib/ssl/src/ssl_manager.erl | 14 +- lib/ssl/src/ssl_pkix_db.erl | 66 +++++-- lib/ssl/test/ssl_pem_cache_SUITE.erl | 248 +++++++++++++-------------- 4 files changed, 181 insertions(+), 163 deletions(-) diff --git a/lib/ssl/src/ssl_certificate.erl b/lib/ssl/src/ssl_certificate.erl index fdc5ed1636..2e2b43f564 100644 --- a/lib/ssl/src/ssl_certificate.erl +++ b/lib/ssl/src/ssl_certificate.erl @@ -448,7 +448,7 @@ find_alternative_root([Cert | _], CertDbHandle, CertDbRef, InvalidatedList) -> end. find_issuer(#cert{der=DerCert, otp=OtpCert}, CertDbHandle, CertsDbRef, ListDb, InvalidatedList) -> - IsIssuerFun = + IsIssuerFun = fun({_Key, #cert{otp=ErlCertCandidate}}, Acc) -> case public_key:pkix_is_issuer(OtpCert, ErlCertCandidate) of true -> @@ -468,12 +468,15 @@ find_issuer(#cert{der=DerCert, otp=OtpCert}, CertDbHandle, CertsDbRef, ListDb, I end, Result = case is_reference(CertsDbRef) of - true -> - do_find_issuer(IsIssuerFun, CertDbHandle, ListDb); - false -> + true when ListDb == [] -> + CertEntryList = ssl_pkix_db:select_certentries_by_ref(CertsDbRef, CertDbHandle), + do_find_issuer(IsIssuerFun, CertDbHandle, CertEntryList); + false when ListDb == [] -> {extracted, CertsData} = CertsDbRef, - DB = [Entry || {decoded, Entry} <- CertsData], - do_find_issuer(IsIssuerFun, CertDbHandle, DB) + CertEntryList = [Entry || {decoded, Entry} <- CertsData], + do_find_issuer(IsIssuerFun, CertDbHandle, CertEntryList); + _ -> + do_find_issuer(IsIssuerFun, CertDbHandle, ListDb) end, case Result of issuer_not_found -> @@ -482,6 +485,7 @@ find_issuer(#cert{der=DerCert, otp=OtpCert}, CertDbHandle, CertsDbRef, ListDb, I Result end. + do_find_issuer(IssuerFun, CertDbHandle, CertDb) -> try foldl_db(IssuerFun, CertDbHandle, CertDb) diff --git a/lib/ssl/src/ssl_manager.erl b/lib/ssl/src/ssl_manager.erl index e115fe394c..f4c6dbfc96 100644 --- a/lib/ssl/src/ssl_manager.erl +++ b/lib/ssl/src/ssl_manager.erl @@ -276,23 +276,23 @@ init([ManagerName, PemCacheName, Opts]) -> %% Description: Handling call messages %%-------------------------------------------------------------------- handle_call({{connection_init, <<>>, Role, {CRLCb, UserCRLDb}}, _Pid}, _From, - #state{certificate_db = [CertDb, FileRefDb, PemChace | _] = Db} = State) -> + #state{certificate_db = [CertDb, FileRefDb, PemCache | _] = Db} = State) -> Ref = make_ref(), {reply, {ok, #{cert_db_ref => Ref, cert_db_handle => CertDb, fileref_db_handle => FileRefDb, - pem_cache => PemChace, + pem_cache => PemCache, session_cache => session_cache(Role, State), crl_db_info => {CRLCb, crl_db_info(Db, UserCRLDb)}}}, State}; handle_call({{connection_init, Trustedcerts, Role, {CRLCb, UserCRLDb}}, Pid}, _From, - #state{certificate_db = [CertDb, FileRefDb, PemChace | _] = Db} = State) -> + #state{certificate_db = [CertDb, FileRefDb, PemCache | _] = Db} = State) -> case add_trusted_certs(Pid, Trustedcerts, Db) of {ok, Ref} -> {reply, {ok, #{cert_db_ref => Ref, cert_db_handle => CertDb, fileref_db_handle => FileRefDb, - pem_cache => PemChace, + pem_cache => PemCache, session_cache => session_cache(Role, State), crl_db_info => {CRLCb, crl_db_info(Db, UserCRLDb)}}}, State}; {error, _} = Error -> @@ -312,10 +312,12 @@ handle_call({{register_session, Host, Port, Session},_}, _, State0) -> State = client_register_session(Host, Port, Session, State0), {reply, ok, State}; handle_call({refresh_trusted_db, _}, _, #state{certificate_db = Db} = State) -> - ssl_pkix_db:refresh_trusted_certs(Db), + PemCache = get(ssl_pem_cache), + ssl_pkix_db:refresh_trusted_certs(Db, PemCache), {reply, ok, State}; handle_call({{refresh_trusted_db, File}, _}, _, #state{certificate_db = Db} = State) -> - ssl_pkix_db:refresh_trusted_certs(File, Db), + PemCache = get(ssl_pem_cache), + ssl_pkix_db:refresh_trusted_certs(File, Db, PemCache), {reply, ok, State}. %%-------------------------------------------------------------------- diff --git a/lib/ssl/src/ssl_pkix_db.erl b/lib/ssl/src/ssl_pkix_db.erl index dbdae5307c..6da1503b8d 100644 --- a/lib/ssl/src/ssl_pkix_db.erl +++ b/lib/ssl/src/ssl_pkix_db.erl @@ -31,11 +31,11 @@ -export([create/1, create_pem_cache/1, add_crls/3, remove_crls/2, remove/1, add_trusted_certs/3, - refresh_trusted_certs/1, refresh_trusted_certs/2, + refresh_trusted_certs/3, extract_trusted_certs/1, remove_trusted_certs/2, insert/3, remove/2, clear/1, db_size/1, - ref_count/3, lookup_trusted_cert/4, foldl/3, select_cert_by_issuer/2, + ref_count/3, lookup_trusted_cert/4, foldl/3, select_certentries_by_ref/2, decode_pem_file/1, lookup/2]). %%==================================================================== @@ -146,18 +146,18 @@ add_trusted_certs(_Pid, File, [ _, {RefDb, FileMapDb} | _] = Db) -> new_trusted_cert_entry(File, Db) end. -refresh_trusted_certs(File, [CertsDb, {_, FileMapDb} | _]) -> +refresh_trusted_certs(File, [CertsDb, {_, FileMapDb} | _], PemCache) -> case lookup(File, FileMapDb) of [Ref] -> - {ok, Content} = decode_pem_file(File), - remove_trusted_certs(Ref, CertsDb), - add_certs_from_pem(Content, Ref, CertsDb); + Certs = ssl_certificate:file_to_certificats(File, PemCache), + KeyList = select_certentries_by_ref(Ref,CertsDb), + update_certs(Ref, Certs, KeyList, CertsDb); undefined -> ok end. -refresh_trusted_certs([_, {_, FileMapDb} | _] = Db) -> +refresh_trusted_certs([_, {_, FileMapDb} | _] = Db, PemCache) -> Refresh = fun({File, _}, Acc) -> - refresh_trusted_certs(File, Db), + refresh_trusted_certs(File, Db, PemCache), Acc end, foldl(Refresh, refresh, FileMapDb). @@ -243,9 +243,13 @@ lookup(Key, Db) -> foldl(Fun, Acc0, Cache) -> ets:foldl(Fun, Acc0, Cache). - -select_cert_by_issuer(Cache, Issuer) -> - ets:select(Cache, [{{{'_','_', Issuer},{'_', '$1'}},[],['$$']}]). +%%-------------------------------------------------------------------- +-spec select_certentries_by_ref(reference(), db_handle()) -> term(). +%% +%% Description: Select certs entries originating from same source +%%-------------------------------------------------------------------- +select_certentries_by_ref(Ref, Cache) -> + ets:select(Cache, [{{{Ref,'_', '_'}, '_'},[],['$_']}]). %%-------------------------------------------------------------------- -spec ref_count(term(), db_handle(), integer()) -> integer(). @@ -297,40 +301,40 @@ remove_certs(Ref, CertsDb) -> ok. add_certs_from_der(DerList, Ref, CertsDb) -> - Add = fun(Cert) -> add_certs(Cert, Ref, CertsDb) end, + Add = fun(Cert) -> add_cert(Cert, Ref, CertsDb) end, [Add(Cert) || Cert <- DerList], ok. certs_from_der(DerList) -> Ref = make_ref(), [Decoded || Cert <- DerList, - Decoded <- [decode_certs(Ref, Cert)], + Decoded <- [decode_cert(Ref, Cert)], Decoded =/= undefined]. add_certs_from_pem(PemEntries, Ref, CertsDb) -> - Add = fun(Cert) -> add_certs(Cert, Ref, CertsDb) end, + Add = fun(Cert) -> add_cert(Cert, Ref, CertsDb) end, [Add(Cert) || {'Certificate', Cert, not_encrypted} <- PemEntries], ok. -add_certs(Cert, Ref, CertsDb) -> +add_cert(Cert, Ref, CertsDb) -> try - {decoded, {Key, Val}} = decode_certs(Ref, Cert), + {decoded, {Key, Val}} = decode_cert(Ref, Cert), insert(Key, Val, CertsDb) catch error:_ -> ok end. -decode_certs(Ref, #cert{otp=ErlCert} = Cert) -> +decode_cert(Ref, #cert{otp=ErlCert} = Cert) -> TBSCertificate = ErlCert#'OTPCertificate'.tbsCertificate, SerialNumber = TBSCertificate#'OTPTBSCertificate'.serialNumber, Issuer = public_key:pkix_normalize_name( TBSCertificate#'OTPTBSCertificate'.issuer), {decoded, {{Ref, SerialNumber, Issuer}, Cert}}; -decode_certs(Ref, Der) -> +decode_cert(Ref, Der) -> try public_key:pkix_decode_cert(Der, otp) of ErlCert -> - decode_certs(Ref, #cert{der=Der, otp=ErlCert}) + decode_cert(Ref, #cert{der=Der, otp=ErlCert}) catch error:_ -> ?LOG_NOTICE("SSL WARNING: Ignoring a CA cert as " "it could not be correctly decoded.~n"), @@ -378,3 +382,27 @@ crl_issuer(DerCRL) -> TBSCRL = CRL#'CertificateList'.tbsCertList, TBSCRL#'TBSCertList'.issuer. +update_certs(Ref, CertList, KeyList, CertsDb) -> + {Insert, Delete} = insert_delete_lists(Ref, CertList, CertsDb, [], KeyList), + insert_cert_entries(Insert, CertsDb), + remove_cert_entries(Delete, CertsDb). + +insert_delete_lists(_, [], _, Insert, Delete) -> + {Insert, Delete}; +insert_delete_lists(Ref, [Cert | Rest], CertsDb, Insert, Delete) -> + case decode_cert(Ref, Cert) of + {decoded, {Key, Value} = Entry} -> + case lookup(Key, CertsDb) of + [Value] -> %% Entry already exists and is unchanged + insert_delete_lists(Ref, Rest, CertsDb, Insert, lists:keydelete(Key, 1, Delete)); + _ -> + insert_delete_lists(Ref, Rest, CertsDb, [Entry | Insert], lists:keydelete(Key, 1, Delete)) + end; + undefined -> + insert_delete_lists(Ref, Rest, CertsDb, Insert, Delete) + end. + +insert_cert_entries(EntryList, CertsDb) -> + ets:insert(CertsDb, EntryList). +remove_cert_entries(EntryList, CertsDb) -> + lists:foreach(fun({Key, Value}) -> remove(Key, Value, CertsDb) end, EntryList). diff --git a/lib/ssl/test/ssl_pem_cache_SUITE.erl b/lib/ssl/test/ssl_pem_cache_SUITE.erl index bb68b3f7b8..6647bab898 100644 --- a/lib/ssl/test/ssl_pem_cache_SUITE.erl +++ b/lib/ssl/test/ssl_pem_cache_SUITE.erl @@ -68,7 +68,6 @@ check_cert/3 ]). - -define(CLEANUP_INTERVAL, 5000). -define(BIG_CLEANUP_INTERVAL, 600000). -define(SLEEP_AMOUNT, 1000). @@ -115,18 +114,23 @@ end_per_group(_GroupName, Config) -> init_per_testcase(pem_certfile_keyfile_periodical_cleanup = Case, Config) -> adjust_pem_periodical_cleanup_interval(Case, Config, ?CLEANUP_INTERVAL), + ssl:clear_pem_cache(), Config; init_per_testcase(pem_cacertfile_periodical_cleanup = Case, Config) -> adjust_pem_periodical_cleanup_interval(Case, Config, ?CLEANUP_INTERVAL), + ssl:clear_pem_cache(), Config; init_per_testcase(new_root_pem_periodical_cleanup = Case, Config) -> adjust_pem_periodical_cleanup_interval(Case, Config, ?CLEANUP_INTERVAL), + ssl:clear_pem_cache(), Config; init_per_testcase(new_root_pem_manual_cleanup = Case, Config) -> + ssl:clear_pem_cache(), adjust_pem_periodical_cleanup_interval(Case, Config, ?BIG_CLEANUP_INTERVAL), Config; init_per_testcase(_Case, Config) -> ssl_test_lib:clean_start(), + ssl:clear_pem_cache(), ct:timetrap({seconds, 20}), Config. @@ -146,19 +150,18 @@ end_per_testcase(_TestCase, Config) -> %% Test Cases -------------------------------------------------------- %%-------------------------------------------------------------------- pem_certfile_keyfile_periodical_cleanup() -> - [{doc, "Test pem cache invalidate mechanism using mtime attribute " + [{doc, "Test PEM cache invalidate mechanism using mtime attribute " "adjustment - certfile and keyfile."}]. %% 1. establish TLS connection %% 2. mtime adjusted for certfile, keyfile for server %% 3. during cleanup: -%% 1. 2 files removed from PemCache -%% 2. tables unchanged (Cert, CaFileRef, CaRefCnt) -%% 4. after TLS disconnect PemCache size is 4, rest of tables are empty +%% 1. 2 files removed from PEM Cache +%% 2. Ca trust store and its references mapping tables are not affected +%% 4. After TLS disconnect only the PEM cache is populated pem_certfile_keyfile_periodical_cleanup(Config) when is_list(Config) -> Expected = #{init => [0, 0, 0, 0], connected => [6, 6, 2, 2], cleaned => [4, 6, 2, 2], disconnected => [4, 0, 0, 0]}, - pem_periodical_cleanup(Config, [certfile, keyfile], Expected), - ok. + pem_periodical_cleanup(Config, [certfile, keyfile], Expected, false). pem_cacertfile_periodical_cleanup() -> [{doc, "Test pem cache invalidate mechanism using mtime attribute " @@ -166,88 +169,77 @@ pem_cacertfile_periodical_cleanup() -> %% 1. establish TLS connection %% 2. mtime adjusted for cacertfile for server %% 3. during cleanup: -%% 1. 1 file removed from PemCache -%% 2. tables unchanged (Cert, CaFileRef, CaRefCnt) -%% 4. after TLS disconnect PemCache size is 5, rest of tables are empty +%% 1. 1 file removed from PEM Cache +%% 2. The file will however be reentered as it is a CA file that is +%% referenced +%% 4. After TLS disconnect only the PEM cache is populated pem_cacertfile_periodical_cleanup(Config) when is_list(Config) -> Expected = #{init => [0, 0, 0, 0], connected => [6, 6, 2, 2], - cleaned => [5, 6, 2, 2], disconnected => [5, 0, 0, 0]}, - pem_periodical_cleanup(Config, [cacertfile], Expected), - ok. + cleaned => [6, 6, 2, 2], disconnected => [6, 0, 0, 0]}, + pem_periodical_cleanup(Config, [cacertfile], Expected, true). pem_manual_cleanup() -> [{doc,"Test that internal reference table is cleaned properly even when " " the PEM cache is cleared" }]. %% 1. establish 1st TLS connection -%% 2. check CaRefCnt content - expecting summed ref counters value of 2 -%% 3. store content of all tables for future checks -%% 4. ssl:clear_pem_cache() -%% 5. verify that PemCache table is now empty -%% 6. verify Cert, CaFileRef, CaRefCnt were unchanged -%% 7. establish 2nd TLS connection -%% 8. check CaRefCnt content - expecting summed ref counters value of 4 -%% 9. verify that PemCache table size is 4 (cafileoption is ignored? not loaded -%% to PemCache because CaFileRef contains entry for path; probably previously -%% cached CA certs are used) -%% 10. verify that Cert and CaFileRef table content is the same as after 1st connection -%% 11. PemCache contains files specified with certfile and keyfile - their -%% content should be the same as for 1st TLS connection -%% 12. Upon disconnecting summed ref counters are reduced to 2 and 0 -%% 13. When that value becomes 0 (after terminating both connection) CaFileRef, -%% Cert, CaRefCnt tables are cleared +%% 2. The server and client process will now have a reference to its CA file +%% 3. ssl:clear_pem_cache() will empty the PEM cache but as we have +%% references to the CAfiles they will be read back, and possible updated +%% in the CA store. (Will not happen in this test). +%% 4. establish 2nd TLS connection +%% 5. Now there will be two server and two client processes in total 4 references +%% 6. The same files are used for both connections so the total amount of file is +%% still 6. +%% 7. Upon disconnecting summed ref counters are reduced to 2 and 0 +%% When there is no reference to a CA file (the entries for its CA certs) +%% will be removed from the CA store. All files will still be cached. +%% 10. Clear the PEM cache and check that it is empty. pem_manual_cleanup(Config) when is_list(Config) -> + %% Initialy all tables are empty. First size will be nubmer of + %% files (PEM cache), second size will be number of CA certs (CA store), + %% third and forth number of CA files (used for reference counting and mapping + %% from filename to ref key) [0, 0, 0, 0] = get_table_sizes(), + {Server, Client} = basic_verify_test_no_close(Config), - 2 = get_total_counter(), + 2 = get_total_number_of_references(), + %% 6 files (cacerts,cert,key x 2), 6 CA certs in 2 different CA files [6, 6, 2, 2] = get_table_sizes(), - [{pem_cache, PemCacheData0}, {cert, CertData0}, {ca_ref_cnt, CaRefCntData0}, - {ca_file_ref, CaFileRefData0}] = get_tables(), - ssl:clear_pem_cache(), - _ = sys:get_status(whereis(ssl_manager)), - [0, 6, 2, 2] = get_table_sizes(), - check_tables([{pem_cache, []}, {cert, CertData0}, - {ca_ref_cnt, CaRefCntData0}, {ca_file_ref, CaFileRefData0}]), + ssl:clear_pem_cache(), + [2, 6, 2, 2] = get_table_sizes(), %% Pemcache cleared and used CAs read back + {Server1, Client1} = basic_verify_test_no_close(Config), - 4 = get_total_counter(), - [4, 6, 2, 2] = get_table_sizes(), - [{pem_cache, PemCacheData2}, _, {ca_ref_cnt, CaRefCntData2}, _] = get_tables(), - check_tables([{pem_cache, PemCacheData2}, {cert, CertData0}, - {ca_ref_cnt, CaRefCntData2}, {ca_file_ref, CaFileRefData0}]), - [true = lists:member(Row, PemCacheData0) || Row <- PemCacheData2], + %% Total 4 processes reference a CA file + 4 = get_total_number_of_references(), + %% New connection causes keys end entity certs and keys to be cached again + [6, 6, 2, 2] = get_table_sizes(), [ssl_test_lib:close(A) || A <- [Server, Client]], - ct:sleep(2 * ?SLEEP_AMOUNT), - - _ = sys:get_status(whereis(ssl_manager)), - 2 = get_total_counter(), - - [4, 6, 2, 2] = get_table_sizes(), - check_tables([{pem_cache, PemCacheData2}, {cert, CertData0}, - {ca_ref_cnt, CaRefCntData0}, {ca_file_ref, CaFileRefData0}]), + [6, 6, 2, 2] = get_table_sizes(), %% All CA files are still referenced + %% Total 2 processes reference a CA file + 2 = get_total_number_of_references(), [ssl_test_lib:close(A) || A <- [Server1, Client1]], - ct:sleep(2 * ?SLEEP_AMOUNT), + %% No processes reference a CA file + 0 = get_total_number_of_references(), + %% All files are still cached + [6, 0, 0, 0] = get_table_sizes(), - _ = sys:get_status(whereis(ssl_manager)), - 0 = get_total_counter(), - [4, 0, 0, 0] = get_table_sizes(), - check_tables([{pem_cache, PemCacheData2}, {cert, []}, - {ca_ref_cnt, []}, {ca_file_ref, []}]), - ok. + ssl:clear_pem_cache(), + [0, 0, 0, 0] = get_table_sizes(). invalid_insert() -> [{doc, "Test that insert of invalid pem does not cause empty cache entry"}]. %% 1. attempt to establish TLS connection with client passing invalid path in %% cacertfile option -%% 2. verify PemCache table is populated with options passed by server -%% 3. verify Cert, CaFileRef, CaRefCnt tables are empty -%% 4. connection is not established -%% 5. error happens during handshake, when client tries to open file passed in -%% cacertfile option +%% 2. verify PEM Cache table is populated with options passed by server +%% 3. connection is not established as error happens during handshake, +%% when client tries to open file passed in cacertfile option +%% 4. verify Cert, CaFileRef tables are empty and the reference count is zero invalid_insert(Config) when is_list(Config) -> process_flag(trap_exit, true), - [0, 0, 0, 0] = get_table_sizes(), + [0, 0, 0, 0] = get_table_sizes(), %% Initialy all tables are empty ClientOpts = proplists:get_value(client_rsa_verify_opts, Config), ServerOpts = proplists:get_value(server_rsa_verify_opts, Config), {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config), @@ -262,10 +254,9 @@ invalid_insert(Config) when is_list(Config) -> ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port}, {host, Hostname}, {from, self()}, {options, BadClientOpts}]), - [3, 0, 0, 0] = get_table_sizes(), - ssl_test_lib:close(Server), - ct:sleep(?SLEEP_AMOUNT), - [3, 0, 0, 0] = get_table_sizes(). + [3, 0, 0, 0] = get_table_sizes(), %% Server options are cached and bad client options ignored + 0 = get_total_number_of_references(), + [3, 0, 0, 0] = get_table_sizes(). %% Cache is still valid new_root_pem_manual_cleanup() -> [{doc, "Test that changed PEM-files on disk followed by ssl:clear_pem_cache()" @@ -302,21 +293,21 @@ new_root_pem_manual_cleanup() -> %% is terminated) new_root_pem_manual_cleanup(Config) when is_list(Config) -> Expected = #{init => [0, 0, 0, 0], connected1 => [6, 6, 2, 2], - cleaned => [0, 6, 2, 2], connected2 => [4, 6, 2, 2], - disconnected1 => [4, 6, 2, 2], disconnected2 => [4,0,0,0]}, + cleaned => [2, 6, 2, 2], connected2 => [6, 6, 2, 2], + disconnected1 => [6, 6, 2, 2], disconnected2 => [6,0,0,0]}, new_root_pem_helper(Config, manual, Expected, fun identity/1), %% verify also same key sequence for initial and overwritten certs PEM files new_root_pem_helper(Config, manual, Expected, fun identity/1, 5). new_root_pem_periodical_cleanup() -> [{doc, "Test that changed PEM-files on disk followed by periodical cleanup" - " invalidates trusted CA cache as well as ordinary PEM cache. " + " invalidates trusted CA store as well as ordinary PEM cache. " "This test case recreates a PEM file, resulting with its actual content change."}]. %% see new_root_pem_manual_cleanup for specification new_root_pem_periodical_cleanup(Config) when is_list(Config) -> ExpectedStats = #{init => [0, 0, 0, 0], connected1 => [6, 6, 2, 2], - cleaned => [0, 6, 2, 2], connected2 => [4, 6, 2, 2], - disconnected1 => [4, 6, 2, 2], disconnected2 => [4,0,0,0]}, + cleaned => [2, 6, 2, 2], connected2 => [6, 6, 2, 2], + disconnected1 => [6, 6, 2, 2], disconnected2 => [6,0,0,0]}, new_root_pem_helper(Config, periodical, ExpectedStats, fun identity/1), %% verify also same key sequence for initial and overwritten certs PEM files new_root_pem_helper(Config, periodical, ExpectedStats, fun identity/1, 5). @@ -427,13 +418,11 @@ get_table_sizes() -> {Label, Db} <- get_table_refs()], [Size || {_, _, Size} <- DbSizes]. -get_total_counter() -> +get_total_number_of_references() -> CaFileRef = proplists:get_value(ca_ref_cnt, get_table_refs()), - CountReferencedFiles = fun({_, -1}, Acc) -> - Acc; - ({_, N}, Acc) -> - N + Acc - end, + CountReferencedFiles = fun({Ref, _}, Acc) -> + ets:update_counter(CaFileRef,Ref,0) + Acc + end, ets:foldl(CountReferencedFiles, 0, CaFileRef). get_table_refs() -> @@ -536,26 +525,21 @@ new_root_pem_helper(Config, CleanMode, [{pem_cache, PemCacheData1}, {cert, CertData1}, {ca_ref_cnt, CaRefCntData1}, {ca_file_ref, _}] = get_tables(), - case CleanMode of - no_cleanup -> - check_tables([{pem_cache, PemCacheData0}, - {cert, CertData0}, - {ca_ref_cnt, CaRefCntData0}, - {ca_file_ref, CaFileRefData0}]), - {Client1, Server1} = - make_connection_check_cert(ServerRootCert0, ClientNode, ClientConf, - ServerNode, ServerConf, Hostname, ServerCAFile0); - _ -> - check_tables([{pem_cache, []}, - {ca_ref_cnt, CaRefCntData0}, - {ca_file_ref, CaFileRefData0}]), - false = (CertData1 == CertData0), - {Client1, Server1} = - make_connection_check_cert(ServerRootCert, ClientNode, ClientConf, - ServerNode, ServerConf, Hostname, ServerCAFile) - end, - - 4 = get_total_counter(), + {Client1, Server1} = case CleanMode of + no_cleanup -> + check_tables([{pem_cache, PemCacheData0}, + {cert, CertData0}, + {ca_ref_cnt, CaRefCntData0}, + {ca_file_ref, CaFileRefData0}]), + make_connection_check_cert(ServerRootCert0, ClientNode, ClientConf, + ServerNode, ServerConf, Hostname, ServerCAFile0); + _ -> + false = (CertData1 == CertData0), + make_connection_check_cert(ServerRootCert, ClientNode, ClientConf, + ServerNode, ServerConf, Hostname, ServerCAFile) + end, + + 4 = get_total_number_of_references(), Connected2 = get_table_sizes(), [{pem_cache, PemCacheData2}, {cert, CertData2}, {ca_ref_cnt, CaRefCntData2}, {ca_file_ref, _}] = get_tables(), @@ -571,7 +555,7 @@ new_root_pem_helper(Config, CleanMode, true = (CaRefCntData2 /= CaRefCntData1), [ssl_test_lib:close(A) || A <- [Client1, Server1]], - 2 = get_total_counter(), + 2 = get_total_number_of_references(), Disconnected1 = get_table_sizes(), case CleanMode of @@ -583,7 +567,7 @@ new_root_pem_helper(Config, CleanMode, check_tables([{cert, CertData1}, {ca_ref_cnt, CaRefCntData0}, {ca_file_ref, CaFileRefData0}]), [ssl_test_lib:close(A) || A <- [Client0, Server0]], - 0 = get_total_counter(), + 0 = get_total_number_of_references(), Disconnected2 = get_table_sizes(), case CleanMode of no_cleanup -> @@ -617,13 +601,13 @@ alternative_path_helper(Config, GetAlternative, CACertFilePath1 = filename:join([Cwd, CACertFilename]), {ok, _} = file:copy(CACertFilePath0, CACertFilePath1), - 0 = get_total_counter(), + 0 = get_total_number_of_references(), Init = get_table_sizes(), %% connect with full path {Server0, Client0} = basic_verify_test_no_close( replace_cacertfile(Config, CACertFilePath1)), - 2 = get_total_counter(), + 2 = get_total_number_of_references(), Connected1 = get_table_sizes(), TestAlternative = fun(ExpectedTotalCounter, ExpectedSizes, CertPath) -> @@ -634,7 +618,7 @@ alternative_path_helper(Config, GetAlternative, %% connect with filename only {Server, Client} = basic_verify_test_no_close( replace_cacertfile(Config, Alternative)), - ExpectedTotalCounter = get_total_counter(), + ExpectedTotalCounter = get_total_number_of_references(), ExpectedSizes = get_table_sizes(), [Server, Client] end @@ -663,7 +647,7 @@ alternative_path_helper(Config, GetAlternative, ProcessesCreated], ct:sleep(?SLEEP_AMOUNT), _ = sys:get_status(whereis(ssl_manager)), - 0 = get_total_counter(), + 0 = get_total_number_of_references(), Disconnected = get_table_sizes(), ok; {skip, Reason} -> @@ -705,7 +689,7 @@ create_initial_config(Config) -> intermediates => [[{key, ?KEY(2)}]], peer => [{key, ?KEY(3)}]}}), ClientBase = filename:join(PrivDir, "client_test"), - ServerBase = filename:join(PrivDir, "server_test"), + ServerBase = filename:join(PrivDir, "server_test"), PemConfig = x509_test:gen_pem_config_files(DerConfig, ClientBase, ServerBase), ClientConf = proplists:get_value(client_config, PemConfig), ServerConf = proplists:get_value(server_config, PemConfig), @@ -739,7 +723,7 @@ overwrite_files_with_new_configuration(ServerRootCert0, ClientBase, pem_periodical_cleanup(Config, FileIds, #{init := Init, connected := Connected, - cleaned := Cleaned, disconnected := Disconnected} = _ExpectedStats)-> + cleaned := Cleaned, disconnected := Disconnected} = _ExpectedStats, IsSame)-> %% ExpectedStats map passed to function contains expected sizes of tables %% holding various cert, cacert, keyfile data. %% Init - represents initial state @@ -754,20 +738,9 @@ pem_periodical_cleanup(Config, FileIds, ct:sleep(4 * ?SLEEP_AMOUNT), Init = get_table_sizes(), - ClientOpts = proplists:get_value(client_rsa_verify_opts, Config), ServerOpts = proplists:get_value(server_rsa_verify_opts, Config), - {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config), - Server = - ssl_test_lib:start_server([{node, ServerNode}, {port, 0}, - {from, self()}, - {mfa, {ssl_test_lib, no_result, []}}, - {options, ServerOpts}]), - Port = ssl_test_lib:inet_port(Server), - Client = - ssl_test_lib:start_client([{node, ClientNode}, - {port, Port}, {host, Hostname}, - {mfa, {ssl_test_lib, no_result, []}}, - {from, self()}, {options, ClientOpts}]), + + {Server, Client} = basic_verify_test_no_close(Config), Connected = get_table_sizes(), [{pem_cache, PemCacheData0}, {cert, CertData0}, {ca_ref_cnt, CaRefCntData0}, @@ -786,21 +759,32 @@ pem_periodical_cleanup(Config, FileIds, Memory = [MakeLookingYounger(F) || F <- FileIds], ct:sleep(round(1.5 * ?CLEANUP_INTERVAL)), + _ = sys:get_status(whereis(ssl_manager)), + Result = + try + Cleaned = get_table_sizes(), + [{pem_cache, PemCacheData1}, _, _, _] = get_tables(), + IsSame = PemCacheData1 == PemCacheData0, + check_tables([{pem_cache, PemCacheData1}, {cert, CertData0}, {ca_ref_cnt, CaRefCntData0}, + {ca_file_ref, CaFileRefData0}]), + [true = lists:member(Row, PemCacheData0) || Row <- PemCacheData1], + + [ssl_test_lib:close(A) || A <- [Server, Client]], + Disconnected = get_table_sizes(), + ok + catch _:Reason -> + Reason + end, - Cleaned = get_table_sizes(), - [{pem_cache, PemCacheData1}, _, _, _] = get_tables(), - false = PemCacheData1 == PemCacheData0, - check_tables([{pem_cache, PemCacheData1}, {cert, CertData0}, {ca_ref_cnt, CaRefCntData0}, - {ca_file_ref, CaFileRefData0}]), - [true = lists:member(Row, PemCacheData0) || Row <- PemCacheData1], - - [ssl_test_lib:close(A) || A <- [Server, Client]], - ct:sleep(?SLEEP_AMOUNT), - - Disconnected = get_table_sizes(), %% restore original mtime attributes [ok = file:write_file_info(C, F#file_info{mtime = OT}) || - {C, F, OT} <- Memory]. + {C, F, OT} <- Memory], + case Result of + ok -> + ok; + _ -> + ct:fail(Result) + end. later()-> DateTime = calendar:now_to_local_time(os:timestamp()), -- 2.35.3
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor