aboutsummaryrefslogtreecommitdiffstats
path: root/lib/ssl/src/ssl_tls1.erl
diff options
context:
space:
mode:
authorAndreas Schultz <[email protected]>2012-04-08 02:39:18 +0200
committerIngela Anderton Andin <[email protected]>2012-08-22 14:00:44 +0200
commitd848984efd05314abf2de8da6ddd4ee651f0da35 (patch)
treec56ce48d75c8c8ba74c99af46a59182575202d88 /lib/ssl/src/ssl_tls1.erl
parent7c9639c785bb6b3047788b6b27ddbafb8f5b0b08 (diff)
downloadotp-d848984efd05314abf2de8da6ddd4ee651f0da35.tar.gz
otp-d848984efd05314abf2de8da6ddd4ee651f0da35.tar.bz2
otp-d848984efd05314abf2de8da6ddd4ee651f0da35.zip
ssl: make PRF function selectable
TLS 1.2 allows to negotiate the used PRF, additional the default PRF uses a different hash. This change make the PRF selectable and hardwires the PRF for TLS < 1.2
Diffstat (limited to 'lib/ssl/src/ssl_tls1.erl')
-rw-r--r--lib/ssl/src/ssl_tls1.erl38
1 files changed, 21 insertions, 17 deletions
diff --git a/lib/ssl/src/ssl_tls1.erl b/lib/ssl/src/ssl_tls1.erl
index d64a8f815d..dc3d9774c2 100644
--- a/lib/ssl/src/ssl_tls1.erl
+++ b/lib/ssl/src/ssl_tls1.erl
@@ -28,25 +28,27 @@
-include("ssl_internal.hrl").
-include("ssl_record.hrl").
--export([master_secret/3, finished/3, certificate_verify/2, mac_hash/7,
- setup_keys/6, suites/0, prf/4]).
+-export([master_secret/4, finished/5, certificate_verify/3, mac_hash/7,
+ setup_keys/8, suites/0, prf/5]).
%%====================================================================
%% Internal application API
%%====================================================================
--spec master_secret(binary(), binary(), binary()) -> binary().
+-spec master_secret(integer(), binary(), binary(), binary()) -> binary().
-master_secret(PreMasterSecret, ClientRandom, ServerRandom) ->
- %% RFC 2246 & 4346 - 8.1 %% master_secret = PRF(pre_master_secret,
- %% "master secret", ClientHello.random +
- %% ServerHello.random)[0..47];
- prf(PreMasterSecret, <<"master secret">>,
+master_secret(PrfAlgo, PreMasterSecret, ClientRandom, ServerRandom) ->
+ %% RFC 2246 & 4346 && RFC 5246 - 8.1 %% master_secret = PRF(pre_master_secret,
+ %% "master secret", ClientHello.random +
+ %% ServerHello.random)[0..47];
+
+ prf(PrfAlgo, PreMasterSecret, <<"master secret">>,
[ClientRandom, ServerRandom], 48).
--spec finished(client | server, binary(), [binary()]) -> binary().
+-spec finished(client | server, integer(), integer(), binary(), [binary()]) -> binary().
-finished(Role, MasterSecret, Handshake) ->
+finished(Role, Version, PrfAlgo, MasterSecret, Handshake)
+ when Version == 1; Version == 2; PrfAlgo == ?MD5SHA ->
%% RFC 2246 & 4346 - 7.4.9. Finished
%% struct {
%% opaque verify_data[12];
@@ -57,7 +59,7 @@ finished(Role, MasterSecret, Handshake) ->
%% SHA-1(handshake_messages)) [0..11];
MD5 = crypto:md5(Handshake),
SHA = crypto:sha(Handshake),
- prf(MasterSecret, finished_label(Role), [MD5, SHA], 12).
+ prf(?MD5SHA, MasterSecret, finished_label(Role), [MD5, SHA], 12);
-spec certificate_verify(OID::tuple(), [binary()]) -> binary().
@@ -69,12 +71,13 @@ certificate_verify(?'rsaEncryption', Handshake) ->
certificate_verify(?'id-dsa', Handshake) ->
crypto:sha(Handshake).
--spec setup_keys(binary(), binary(), binary(), integer(),
+-spec setup_keys(integer(), integer(), binary(), binary(), binary(), integer(),
integer(), integer()) -> {binary(), binary(), binary(),
binary(), binary(), binary()}.
-setup_keys(MasterSecret, ServerRandom, ClientRandom, HashSize,
- KeyMatLen, IVSize) ->
+setup_keys(Version, _PrfAlgo, MasterSecret, ServerRandom, ClientRandom, HashSize,
+ KeyMatLen, IVSize)
+ when Version == 1 ->
%% RFC 2246 - 6.3. Key calculation
%% key_block = PRF(SecurityParameters.master_secret,
%% "key expansion",
@@ -88,7 +91,7 @@ setup_keys(MasterSecret, ServerRandom, ClientRandom, HashSize,
%% client_write_IV[SecurityParameters.IV_size]
%% server_write_IV[SecurityParameters.IV_size]
WantedLength = 2 * (HashSize + KeyMatLen + IVSize),
- KeyBlock = prf(MasterSecret, "key expansion",
+ KeyBlock = prf(?MD5SHA, MasterSecret, "key expansion",
[ServerRandom, ClientRandom], WantedLength),
<<ClientWriteMacSecret:HashSize/binary,
ServerWriteMacSecret:HashSize/binary,
@@ -182,7 +185,7 @@ p_hash(_Secret, _Seed, WantedLength, _Method, _N, [Last | Acc])
when WantedLength =< 0 ->
Keep = byte_size(Last) + WantedLength,
<<B:Keep/binary, _/binary>> = Last,
- lists:reverse(Acc, [B]);
+ list_to_binary(lists:reverse(Acc, [B]));
p_hash(Secret, Seed, WantedLength, Method, N, Acc) ->
N1 = N+1,
Bin = hmac_hash(Method, Secret, [a(N1, Secret, Seed, Method), Seed]),
@@ -214,7 +217,8 @@ split_secret(BinSecret) ->
<<_:Div/binary, Secret2:EvenLength/binary>> = BinSecret,
{Secret1, Secret2}.
-prf(Secret, Label, Seed, WantedLength) ->
+prf(MAC, Secret, Label, Seed, WantedLength)
+ when MAC == ?MD5SHA ->
%% PRF(secret, label, seed) = P_MD5(S1, label + seed) XOR
%% P_SHA-1(S2, label + seed);
{S1, S2} = split_secret(Secret),