diff options
author | Gustav Simonsson <[email protected]> | 2012-03-26 15:50:31 +0200 |
---|---|---|
committer | Gustav Simonsson <[email protected]> | 2012-03-26 15:51:03 +0200 |
commit | c1f3ffc3df15422bb60a24eb6417069feec9352f (patch) | |
tree | 4f7f95d95f33d6680ef09e5708b4db5bae7659dd /lib/ssl/src/ssl_connection.erl | |
parent | 49bd93a2bc608f84bc1bb849ee98e0677e34dd43 (diff) | |
parent | 89ae746305215c5dd077441ba796ff37b03fdaa3 (diff) | |
download | otp-c1f3ffc3df15422bb60a24eb6417069feec9352f.tar.gz otp-c1f3ffc3df15422bb60a24eb6417069feec9352f.tar.bz2 otp-c1f3ffc3df15422bb60a24eb6417069feec9352f.zip |
Merge branch 'as/ssl-tls-prf-function' into maint
* as/ssl-tls-prf-function:
Some protocols (e.g. EAP-PEAP, EAP-TLS, EAP-TTLS)
that use TLS as transport layer need to generate
additional application specific key material
One way to generate such material is to use the
TLS PRF and key material from the TLS session itself
OTP-10024
Diffstat (limited to 'lib/ssl/src/ssl_connection.erl')
-rw-r--r-- | lib/ssl/src/ssl_connection.erl | 39 |
1 files changed, 38 insertions, 1 deletions
diff --git a/lib/ssl/src/ssl_connection.erl b/lib/ssl/src/ssl_connection.erl index 28dd0c85d0..59133dccf0 100644 --- a/lib/ssl/src/ssl_connection.erl +++ b/lib/ssl/src/ssl_connection.erl @@ -40,7 +40,8 @@ -export([send/2, recv/3, connect/7, ssl_accept/6, handshake/2, socket_control/3, close/1, shutdown/2, new_user/2, get_opts/2, set_opts/2, info/1, session_info/1, - peer_certificate/1, sockname/1, peername/1, renegotiation/1]). + peer_certificate/1, sockname/1, peername/1, renegotiation/1, + prf/5]). %% Called by ssl_connection_sup -export([start_link/7]). @@ -273,6 +274,16 @@ peer_certificate(ConnectionPid) -> renegotiation(ConnectionPid) -> sync_send_all_state_event(ConnectionPid, renegotiate). +%%-------------------------------------------------------------------- +-spec prf(pid(), binary() | 'master_secret', binary(), + binary() | ssl:prf_secret(), non_neg_integer()) -> + {ok, binary()} | {error, reason()} | {'EXIT', term()}. +%% +%% Description: use a ssl sessions TLS PRF to generate key material +%%-------------------------------------------------------------------- +prf(ConnectionPid, Secret, Label, Seed, WantedLength) -> + sync_send_all_state_event(ConnectionPid, {prf, Secret, Label, Seed, WantedLength}). + %%==================================================================== %% ssl_connection_sup API %%==================================================================== @@ -868,6 +879,32 @@ handle_sync_event(renegotiate, From, connection, State) -> handle_sync_event(renegotiate, _, StateName, State) -> {reply, {error, already_renegotiating}, StateName, State, get_timeout(State)}; +handle_sync_event({prf, Secret, Label, Seed, WantedLength}, _, StateName, + #state{connection_states = ConnectionStates, + negotiated_version = Version} = State) -> + ConnectionState = + ssl_record:current_connection_state(ConnectionStates, read), + SecParams = ConnectionState#connection_state.security_parameters, + #security_parameters{master_secret = MasterSecret, + client_random = ClientRandom, + server_random = ServerRandom} = SecParams, + Reply = try + SecretToUse = case Secret of + _ when is_binary(Secret) -> Secret; + master_secret -> MasterSecret + end, + SeedToUse = lists:reverse( + lists:foldl(fun(X, Acc) when is_binary(X) -> [X|Acc]; + (client_random, Acc) -> [ClientRandom|Acc]; + (server_random, Acc) -> [ServerRandom|Acc] + end, [], Seed)), + ssl_handshake:prf(Version, SecretToUse, Label, SeedToUse, WantedLength) + catch + exit:_ -> {error, badarg}; + error:Reason -> {error, Reason} + end, + {reply, Reply, StateName, State, get_timeout(State)}; + handle_sync_event(info, _, StateName, #state{negotiated_version = Version, session = #session{cipher_suite = Suite}} = State) -> |