diff options
author | Andreas Schultz <[email protected]> | 2012-04-08 02:39:18 +0200 |
---|---|---|
committer | Ingela Anderton Andin <[email protected]> | 2012-08-22 14:00:44 +0200 |
commit | d848984efd05314abf2de8da6ddd4ee651f0da35 (patch) | |
tree | c56ce48d75c8c8ba74c99af46a59182575202d88 /lib/ssl/src/ssl_tls1.erl | |
parent | 7c9639c785bb6b3047788b6b27ddbafb8f5b0b08 (diff) | |
download | otp-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.erl | 38 |
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), |