[erlang-questions] SSL: Getting master_secret and client_random (or premaster_secret)
Ben Murphy
benmmurphy@REDACTED
Mon Feb 6 18:48:36 CET 2017
We have a hacky way to do this on R19 (Probably only works for our
particular version because these internal records can change). We
hooked ssl:connect using the tracing facility because we couldn't
deploy a code change.
https://gist.github.com/benmmurphy/d2918d3aaea46372501b851814f4ce8a
DumpMS = fun() ->
FindMs = fun(Socket) ->
Pid = element(3, Socket),
Connection = sys:get_state(Pid),
State = element(2, Connection),
Session = element(18, State),
SessionId = element(2, Session),
MasterSecret = element(7, Session),
{SessionId, MasterSecret}
end,
Hex = fun(Id) -> << <<Y>> ||<<X:4>> <= Id, Y <-
integer_to_list(X,16)>> end,
{ok, File} = file:open("/tmp/tls.log", [write, append]),
DebugHandler = fun DebugHandler() ->
receive
{trace, _Pid, return_from, _MFA, {ok, Socket}} ->
try
{SessionId, MasterSecret} = FindMs(Socket),
Bytes = io_lib:format("RSA Session-ID:~s
Master-Key:~s~n", [Hex(SessionId), Hex(MasterSecret)]),
file:write(File, Bytes),
ok
catch C:E ->
ok
end,
DebugHandler();
quit ->
file:close(File),
ok;
_ ->
DebugHandler()
end,
ok
end,
Pid = spawn(DebugHandler),
register(ms_tracer, Pid),
erlang:trace(processes, true, [{tracer, Pid}, call]),
erlang:trace_pattern({ssl, connect, 2}, [{['_', '_'], [],
[{return_trace}]}]),
erlang:trace_pattern({ssl, connect, 3}, [{['_', '_', '_'], [],
[{return_trace}]}]),
erlang:trace_pattern({ssl, connect, 4}, [{['_', '_', '_', '_'],
[], [{return_trace}]}]),
Pid
end.
QuitMS = fun() ->
erlang:trace(all, false, [{tracer, whereis(ms_tracer)}, call]),
ms_tracer ! quit
end.
On Thu, Jan 5, 2017 at 2:20 PM, Roger Lipscombe <roger@REDACTED> wrote:
> We're using ECDHE and DHE ciphers for our SSL connections. This
> provides perfect forward secrecy, which is good, but it makes it
> impossible to decipher packet captures in wireshark, which is
> expected, and also good, almost all of the time.
>
> Sometimes, however, we *do* need to decipher the traffic.
>
> Note that we own both the client (which is embedded) and the server
> (which uses Erlang -- otherwise I wouldn't be asking here -- and
> ranch). We *could* offer a different cipher suite on the server, which
> would disable PFS, but would do it for all connections. I'd prefer
> something a bit more fine-grained.
>
> You can feed a key log to Wireshark, as documented at
> https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/Key_Log_Format,
> and it'll correctly decipher the traffic for that connection.
>
> I'd like to find a way to generate a key log file. This requires
> either (client_random, master_secret) or (encrypted_premaster_secret,
> premaster_secret).
>
> Note that I'm looking at the OTP 17.5 source, because that's what we're using.
>
> It would seem that premaster_secret is not stored past the initial
> negotiation, but the client_random and master_secret values are in the
> #security_parameters record in the #connection_state record in the
> #connection_states record, which is in the #state record of the SSL
> connection pid.
>
> But I can't see any (clean) way to retrieve these values, in order to
> generate a key log suitable for Wireshark.
>
> Is there any clean way to do this in OTP 17.5, or is there a supported
> way to do this in OTP 18.x or 19.x?
>
> Regards,
> Roger.
> _______________________________________________
> erlang-questions mailing list
> erlang-questions@REDACTED
> http://erlang.org/mailman/listinfo/erlang-questions
More information about the erlang-questions
mailing list