diff options
Diffstat (limited to 'src/ct_helper.erl')
-rw-r--r-- | src/ct_helper.erl | 76 |
1 files changed, 59 insertions, 17 deletions
diff --git a/src/ct_helper.erl b/src/ct_helper.erl index ff6c3d7..3723095 100644 --- a/src/ct_helper.erl +++ b/src/ct_helper.erl @@ -24,11 +24,13 @@ -export([get_parent_pid/1]). -export([get_remote_pid_tcp/1]). -export([get_remote_pid_tls/1]). +-export([get_remote_pid_tls_state/1]). -export([ignore/3]). -export([is_process_down/1]). -export([is_process_down/2]). -export([make_certs/0]). -export([make_certs_in_ets/0]). +-export([make_certs_in_dir/1]). -export([name/0]). -export([start/1]). @@ -127,14 +129,26 @@ get_parent_pid(Pid) -> get_remote_pid_tcp(Socket) when is_port(Socket) -> get_remote_pid_tcp(inet:sockname(Socket)); get_remote_pid_tcp(SockName) -> + get_remote_pid_tcp(SockName, 5). + +get_remote_pid_tcp(SockName, 0) -> + AllPorts = [{P, erlang:port_info(P), (catch inet:peername(P))} || P <- erlang:ports()], + error({missing_or_duplicate_ports, SockName, AllPorts}); +get_remote_pid_tcp(SockName, Attempts) -> AllPorts = [{P, erlang:port_info(P)} || P <- erlang:ports()], - [Pid] = [ + Result = [ proplists:get_value(connected, I) || {P, I} <- AllPorts, I =/= undefined, proplists:get_value(name, I) =:= "tcp_inet", inet:peername(P) =:= SockName], - Pid. + case Result of + [Pid] -> + Pid; + _ -> + timer:sleep(10), + get_remote_pid_tcp(SockName, Attempts - 1) + end. %% @doc Find the pid of the remote end of a TLS socket. %% @@ -144,27 +158,28 @@ get_remote_pid_tls(Socket) -> %% This gives us the pid of the sslsocket process. %% We must introspect this process in order to retrieve the connection pid. TLSPid = get_remote_pid_tcp(ssl:sockname(Socket)), - get_tls_state(TLSPid). + get_remote_pid_tls_state(TLSPid). -ifdef(OTP_RELEASE). -if(?OTP_RELEASE >= 22). -get_tls_state(TLSPid) -> - {_, #state{connection_env=#connection_env{user_application={_, UserPid}}}} = sys:get_state(TLSPid), +get_remote_pid_tls_state(TLSPid) -> + {_, #state{connection_env=ConnEnv}} = sys:get_state(TLSPid), + {_, UserPid} = element(2, ConnEnv), %% #connection_env.user_application UserPid. -else. %% This is defined in ssl_record.hrl starting from OTP-21.3. -ifdef(KNOWN_RECORD_TYPE). -get_tls_state(TLSPid) -> +get_remote_pid_tls_state(TLSPid) -> {_, #state{connection_env=#connection_env{user_application={_, UserPid}}}} = sys:get_state(TLSPid), UserPid. -else. -get_tls_state(TLSPid) -> +get_remote_pid_tls_state(TLSPid) -> {_, #state{user_application={_, UserPid}}} = sys:get_state(TLSPid), UserPid. -endif. -endif. -else. -get_tls_state(TLSPid) -> +get_remote_pid_tls_state(TLSPid) -> {_, #state{user_application={_, UserPid}}} = sys:get_state(TLSPid), UserPid. -endif. @@ -194,11 +209,40 @@ is_process_down(Pid, Timeout) -> %% @doc Create a set of certificates. -spec make_certs() - -> {CaCert::der_encoded(), Cert::der_encoded(), Key::key()}. + -> {[CaCert::der_encoded()], Cert::der_encoded(), Key::key()}. make_certs() -> - CaInfo = {CaCert, _} = erl_make_certs:make_cert([]), - {Cert, {Asn1Type, Der, _}} = erl_make_certs:make_cert([{issuer, CaInfo}]), - {CaCert, Cert, {Asn1Type, Der}}. + Opts = public_key:pkix_test_data(#{ + root => [{digest, sha256}, {key, {rsa, 2048, 17}}], + peer => [{digest, sha256}, {key, {rsa, 2048, 17}}, {extensions, [ + #'Extension'{ + extnID = ?'id-ce-subjectAltName', + extnValue = [{dNSName, "localhost"}], + critical = true + } + ]}] + }), + { + proplists:get_value(cacerts, Opts), + proplists:get_value(cert, Opts), + proplists:get_value(key, Opts) + }. + +%% @doc Create a set of certificates and store them in a directory. + +make_certs_in_dir(Dir) -> + {CaCerts, Cert, Key} = make_certs(), + CertFile = filename:join(Dir, "cert.pem"), + CaCertsFile = filename:join(Dir, "cacerts.pem"), + KeyFile = filename:join(Dir, "key.pem"), + CertPem = public_key:pem_encode([{'Certificate', Cert, not_encrypted}]), + CaCertsPem = public_key:pem_encode( + [{'Certificate', CaCert, not_encrypted} || CaCert <- CaCerts]), + {KeyAsn1Type, KeyDer} = Key, + KeyPem = public_key:pem_encode([{KeyAsn1Type, KeyDer, not_encrypted}]), + ok = file:write_file(CertFile, CertPem), + ok = file:write_file(CaCertsFile, CaCertsPem), + ok = file:write_file(KeyFile, KeyPem), + {CaCertsFile, CertFile, KeyFile}. %% @doc Create a set of certificates and store them in an ets table. %% @@ -210,7 +254,7 @@ make_certs() -> %% They have no effect otherwise. make_certs_in_ets() -> - {CaCert, Cert, Key} = make_certs(), + {CaCerts, Cert, Key} = make_certs(), VerifyFun = fun (_, {bad_cert, _}, UserState) -> {valid, UserState}; @@ -224,12 +268,10 @@ make_certs_in_ets() -> {valid, UserState} end, CertOpts = [ - {cert, Cert}, {key, Key}, {cacerts, [CaCert]}, + {cert, Cert}, {key, Key}, {cacerts, CaCerts}, {verify, verify_peer}, {verify_fun, {VerifyFun, []}}, %% We stick to TLS 1.2 because our certificates are not - %% secure enough for use with TLS 1.3. This can be resolved - %% when we no longer depend on erl_make_certs for generating - %% them. + %% secure enough for use with TLS 1.3. {versions, ['tlsv1.2']} ], Pid = spawn(fun() -> receive shutdown -> ok after infinity -> ok end end), |