diff options
author | Ingela Anderton Andin <ingela@erlang.org> | 2012-06-28 16:02:27 +0200 |
---|---|---|
committer | Ingela Anderton Andin <ingela@erlang.org> | 2012-08-22 14:00:44 +0200 |
commit | 7682bd59933f20cba5c32df96a58f252924478a9 (patch) | |
tree | 7a4f1fadbb0f6b6197fece51ec844c590cabf5fe | |
parent | aa9a388f9498028f7288fc2f61264cf13bec7278 (diff) | |
download | otp-7682bd59933f20cba5c32df96a58f252924478a9.tar.gz otp-7682bd59933f20cba5c32df96a58f252924478a9.tar.bz2 otp-7682bd59933f20cba5c32df96a58f252924478a9.zip |
ssl: Fix PRF logic
-rw-r--r-- | lib/ssl/src/ssl_cipher.erl | 68 | ||||
-rw-r--r-- | lib/ssl/src/ssl_connection.erl | 42 | ||||
-rw-r--r-- | lib/ssl/src/ssl_handshake.erl | 79 | ||||
-rw-r--r-- | lib/ssl/src/ssl_handshake.hrl | 6 | ||||
-rw-r--r-- | lib/ssl/src/ssl_record.erl | 6 | ||||
-rw-r--r-- | lib/ssl/src/ssl_record.hrl | 5 | ||||
-rw-r--r-- | lib/ssl/src/ssl_ssl3.erl | 30 | ||||
-rw-r--r-- | lib/ssl/src/ssl_tls1.erl | 10 |
8 files changed, 139 insertions, 107 deletions
diff --git a/lib/ssl/src/ssl_cipher.erl b/lib/ssl/src/ssl_cipher.erl index b58c496bfa..9e1fbe20f4 100644 --- a/lib/ssl/src/ssl_cipher.erl +++ b/lib/ssl/src/ssl_cipher.erl @@ -28,10 +28,11 @@ -include("ssl_internal.hrl"). -include("ssl_record.hrl"). -include("ssl_cipher.hrl"). +-include("ssl_handshake.hrl"). -include("ssl_alert.hrl"). -include_lib("public_key/include/public_key.hrl"). --export([security_parameters/2, suite_definition/1, +-export([security_parameters/3, suite_definition/1, decipher/5, cipher/5, suite/1, suites/1, anonymous_suites/0, openssl_suite/1, openssl_suite_name/1, filter/2]). @@ -39,14 +40,14 @@ -compile(inline). %%-------------------------------------------------------------------- --spec security_parameters(cipher_suite(), #security_parameters{}) -> +-spec security_parameters(tls_version(), cipher_suite(), #security_parameters{}) -> #security_parameters{}. %% %% Description: Returns a security parameters record where the %% cipher values has been updated according to <CipherSuite> %%------------------------------------------------------------------- -security_parameters(CipherSuite, SecParams) -> - { _, Cipher, Hash, PrfHash} = suite_definition(CipherSuite), +security_parameters(Version, CipherSuite, SecParams) -> + { _, Cipher, Hash, PrfHashAlg} = suite_definition(CipherSuite), SecParams#security_parameters{ cipher_suite = CipherSuite, bulk_cipher_algorithm = bulk_cipher_algorithm(Cipher), @@ -55,8 +56,8 @@ security_parameters(CipherSuite, SecParams) -> expanded_key_material_length = expanded_key_material(Cipher), key_material_length = key_material(Cipher), iv_size = iv_size(Cipher), - mac_algorithm = mac_algorithm(Hash), - prf_algorithm = prf_algorithm(PrfHash), + mac_algorithm = hash_algorithm(Hash), + prf_algorithm = prf_algorithm(PrfHashAlg, Version), hash_size = hash_size(Hash)}. %%-------------------------------------------------------------------- @@ -590,29 +591,36 @@ block_size(Cipher) when Cipher == aes_128_cbc; Cipher == aes_256_cbc -> 16. -mac_algorithm(null) -> - ?NULL; -mac_algorithm(md5) -> - ?MD5; -mac_algorithm(sha) -> - ?SHA; -mac_algorithm(sha256) -> - ?SHA256; -mac_algorithm(sha384) -> - ?SHA384. - -prf_algorithm(default_prf) -> +prf_algorithm(default_prf, {3, N}) when N >= 3 -> ?SHA256; -prf_algorithm(null) -> - ?NULL; -prf_algorithm(md5) -> - ?MD5; -prf_algorithm(sha) -> - ?SHA; -prf_algorithm(sha256) -> - ?SHA256; -prf_algorithm(sha384) -> - ?SHA384. +prf_algorithm(default_prf, {3, _}) -> + ?MD5SHA; +prf_algorithm(Algo, _) -> + hash_algorithm(Algo). + +hash_algorithm(null) -> ?NULL; +hash_algorithm(md5) -> ?MD5; +hash_algorithm(sha) -> ?SHA; %% Only sha always refers to "SHA-1" +hash_algorithm(sha224) -> ?SHA224; +hash_algorithm(sha256) -> ?SHA256; +hash_algorithm(sha384) -> ?SHA384; +hash_algorithm(sha512) -> ?SHA512; +hash_algorithm(?NULL) -> null; +hash_algorithm(?MD5) -> md5; +hash_algorithm(?SHA) -> sha; +%%hash_algorithm(?SHA224) -> sha224; +hash_algorithm(?SHA256) -> sha256; +hash_algorithm(?SHA384) -> sha384; +hash_algorithm(?SHA512) -> sha512. + +sign_algorithm(anon) -> ?ANON; +sign_algorithm(rsa) -> ?RSA; +sign_algorithm(dsa) -> ?DSA; +sign_algorithm(ecdsa) -> ?ECDSA; +sign_algorithm(?ANON) -> anon; +sign_algorithm(?RSA) -> rsa; +sign_algorithm(?DSA) -> dsa; +sign_algorithm(?ECDSA) -> ecdsa. hash_size(null) -> 0; @@ -621,9 +629,7 @@ hash_size(md5) -> hash_size(sha) -> 20; hash_size(sha256) -> - 32; -hash_size(sha384) -> - 48. + 32. %% RFC 5246: 6.2.3.2. CBC Block Cipher %% diff --git a/lib/ssl/src/ssl_connection.erl b/lib/ssl/src/ssl_connection.erl index 002565bc79..0d3efae5f4 100644 --- a/lib/ssl/src/ssl_connection.erl +++ b/lib/ssl/src/ssl_connection.erl @@ -435,9 +435,8 @@ abbreviated(#finished{verify_data = Data} = Finished, session = #session{master_secret = MasterSecret}, connection_states = ConnectionStates0} = State) -> -%%CHECKME: the connection state prf logic is pure guess work! case ssl_handshake:verify_connection(Version, Finished, client, - get_current_connection_state_prf(ConnectionStates0, read), + get_current_connection_state_prf(ConnectionStates0, write), MasterSecret, Handshake) of verified -> ConnectionStates = ssl_record:set_client_verify_data(current_both, Data, ConnectionStates0), @@ -453,7 +452,6 @@ abbreviated(#finished{verify_data = Data} = Finished, session = #session{master_secret = MasterSecret}, negotiated_version = Version, connection_states = ConnectionStates0} = State) -> -%%CHECKME: the connection state prf logic is pure guess work! case ssl_handshake:verify_connection(Version, Finished, server, get_pending_connection_state_prf(ConnectionStates0, write), MasterSecret, Handshake0) of @@ -2414,3 +2412,41 @@ get_current_connection_state_prf(CStates, Direction) -> get_pending_connection_state_prf(CStates, Direction) -> CS = ssl_record:pending_connection_state(CStates, Direction), CS#connection_state.security_parameters#security_parameters.prf_algorithm. + +connection_hash_algo({HashAlgo, _}, _State) -> + HashAlgo; +connection_hash_algo(_, #state{hashsign_algorithm = {HashAlgo, _}}) -> + HashAlgo. + +%% RFC 5246, Sect. 7.4.1.4.1. Signature Algorithms +%% If the client does not send the signature_algorithms extension, the +%% server MUST do the following: +%% +%% - If the negotiated key exchange algorithm is one of (RSA, DHE_RSA, +%% DH_RSA, RSA_PSK, ECDH_RSA, ECDHE_RSA), behave as if client had +%% sent the value {sha1,rsa}. +%% +%% - If the negotiated key exchange algorithm is one of (DHE_DSS, +%% DH_DSS), behave as if the client had sent the value {sha1,dsa}. +%% +%% - If the negotiated key exchange algorithm is one of (ECDH_ECDSA, +%% ECDHE_ECDSA), behave as if the client had sent value {sha1,ecdsa}. + +default_hashsign(_Version = {Major, Minor}, KeyExchange) + when Major == 3 andalso Minor >= 3 andalso + (KeyExchange == rsa orelse + KeyExchange == dhe_rsa orelse + KeyExchange == dh_rsa) -> + {sha, rsa}; +default_hashsign(_Version, KeyExchange) + when KeyExchange == rsa; + KeyExchange == dhe_rsa; + KeyExchange == dh_rsa -> + {md5sha, rsa}; +default_hashsign(_Version, KeyExchange) + when KeyExchange == dhe_dss; + KeyExchange == dh_dss -> + {sha, dsa}; +default_hashsign(_Version, KeyExchange) + when KeyExchange == dh_anon -> + {null, anon}. diff --git a/lib/ssl/src/ssl_handshake.erl b/lib/ssl/src/ssl_handshake.erl index 1b83293730..7dba77560c 100644 --- a/lib/ssl/src/ssl_handshake.erl +++ b/lib/ssl/src/ssl_handshake.erl @@ -131,7 +131,7 @@ hello(#server_hello{cipher_suite = CipherSuite, server_version = Version, Renegotiation, SecureRenegotation, []) of {ok, ConnectionStates1} -> ConnectionStates = - hello_pending_connection_states(client, CipherSuite, Random, + hello_pending_connection_states(client, Version, CipherSuite, Random, Compression, ConnectionStates1), {Version, SessionId, ConnectionStates}; #alert{} = Alert -> @@ -164,6 +164,7 @@ hello(#client_hello{client_version = ClientVersion, random = Random, {ok, ConnectionStates1} -> ConnectionStates = hello_pending_connection_states(server, + Version, CipherSuite, Random, Compression, @@ -286,10 +287,13 @@ client_certificate_verify(OwnCert, MasterSecret, Version, %% %% Description: Checks that the certificate_verify message is valid. %%-------------------------------------------------------------------- -certificate_verify(Signature, {?'rsaEncryption'= Algorithm, PublicKey, _}, Version, - MasterSecret, {_, Handshake}) -> - Hashes = calc_certificate_verify(Version, MasterSecret, - Algorithm, Handshake), +certificate_verify_rsa(Hashes, sha, Signature, PublicKey, {Major, Minor}) + when Major == 3, Minor >= 3 -> + public_key:verify({digest, Hashes}, sha, Signature, PublicKey); +certificate_verify_rsa(Hashes, HashAlgo, Signature, PublicKey, {Major, Minor}) + when Major == 3, Minor >= 3 -> + public_key:verify({digest, Hashes}, HashAlgo, Signature, PublicKey); +certificate_verify_rsa(Hashes, _HashAlgo, Signature, PublicKey, _Version) -> case public_key:decrypt_public(Signature, PublicKey, [{rsa_pad, rsa_pkcs1_padding}]) of Hashes -> @@ -527,8 +531,7 @@ decrypt_premaster_secret(Secret, RSAPrivateKey) -> end. %%-------------------------------------------------------------------- --spec server_key_exchange_hash(rsa | dhe_rsa| dhe_dss | dh_anon, binary()) -> binary(). - +-spec server_key_exchange_hash(md5sha1 | md5 | sha | sha256 | sha384 | sha512, binary()) -> binary(). %% %% Description: Calculate server key exchange hash %%-------------------------------------------------------------------- @@ -551,7 +554,7 @@ prf({3,0}, _, _, _, _) -> {error, undefined}; prf({3,1}, Secret, Label, Seed, WantedLength) -> {ok, ssl_tls1:prf(?MD5SHA, Secret, Label, Seed, WantedLength)}; -prf({3,N}, Secret, Label, Seed, WantedLength) -> +prf({3,_N}, Secret, Label, Seed, WantedLength) -> {ok, ssl_tls1:prf(?SHA256, Secret, Label, Seed, WantedLength)}. %%-------------------------------------------------------------------- @@ -719,7 +722,7 @@ handle_renegotiation_info(ConnectionStates, SecureRenegotation) -> %% hello messages %% NOTE : Role is the role of the receiver of the hello message %% currently being processed. -hello_pending_connection_states(Role, CipherSuite, Random, Compression, +hello_pending_connection_states(Role, Version, CipherSuite, Random, Compression, ConnectionStates) -> ReadState = ssl_record:pending_connection_state(ConnectionStates, read), @@ -727,30 +730,30 @@ hello_pending_connection_states(Role, CipherSuite, Random, Compression, ssl_record:pending_connection_state(ConnectionStates, write), NewReadSecParams = - hello_security_parameters(Role, ReadState, CipherSuite, + hello_security_parameters(Role, Version, ReadState, CipherSuite, Random, Compression), NewWriteSecParams = - hello_security_parameters(Role, WriteState, CipherSuite, + hello_security_parameters(Role, Version, WriteState, CipherSuite, Random, Compression), ssl_record:update_security_params(NewReadSecParams, NewWriteSecParams, ConnectionStates). -hello_security_parameters(client, ConnectionState, CipherSuite, Random, +hello_security_parameters(client, Version, ConnectionState, CipherSuite, Random, Compression) -> SecParams = ConnectionState#connection_state.security_parameters, - NewSecParams = ssl_cipher:security_parameters(CipherSuite, SecParams), + NewSecParams = ssl_cipher:security_parameters(Version, CipherSuite, SecParams), NewSecParams#security_parameters{ server_random = Random, compression_algorithm = Compression }; -hello_security_parameters(server, ConnectionState, CipherSuite, Random, +hello_security_parameters(server, Version, ConnectionState, CipherSuite, Random, Compression) -> SecParams = ConnectionState#connection_state.security_parameters, - NewSecParams = ssl_cipher:security_parameters(CipherSuite, SecParams), + NewSecParams = ssl_cipher:security_parameters(Version, CipherSuite, SecParams), NewSecParams#security_parameters{ client_random = Random, compression_algorithm = Compression @@ -1093,6 +1096,17 @@ certificate_types({KeyExchange, _, _, _}) certificate_types(_) -> <<?BYTE(?RSA_SIGN)>>. +hashsign_dec(<<?BYTE(HashAlgo), ?BYTE(SignAlgo)>>) -> + {ssl_cipher:hash_algorithm(HashAlgo), ssl_cipher:sign_algorithm(SignAlgo)}. + +hashsign_enc(HashAlgo, SignAlgo) -> + Hash = ssl_cipher:hash_algorithm(HashAlgo), + Sign = ssl_cipher:sign_algorithm(SignAlgo), + <<?BYTE(Hash), ?BYTE(Sign)>>. + +hashsign_algorithms(_) -> + hashsign_enc(sha, rsa). + certificate_authorities(CertDbHandle, CertDbRef) -> Authorities = certificate_authorities_from_db(CertDbHandle, CertDbRef), Enc = fun(#'OTPCertificate'{tbsCertificate=TBSCert}) -> @@ -1114,7 +1128,12 @@ certificate_authorities_from_db(CertDbHandle, CertDbRef) -> end, ssl_certificate_db:foldl(ConnectionCerts, [], CertDbHandle). -digitally_signed(Hash, #'RSAPrivateKey'{} = Key) -> + +digitally_signed({3, Minor}, Hash, HashAlgo, Key) when Minor >= 3 -> + public_key:sign({digest, Hash}, HashAlgo, Key); +digitally_signed(_Version, Hash, _HashAlgo, #'DSAPrivateKey'{} = Key) -> + public_key:sign({digest, Hash}, sha, Key); +digitally_signed(_Version, Hash, _HashAlgo, #'RSAPrivateKey'{} = Key) -> public_key:encrypt_private(Hash, Key, [{rsa_pad, rsa_pkcs1_padding}]); digitally_signed(Hash, #'DSAPrivateKey'{} = Key) -> @@ -1123,45 +1142,27 @@ digitally_signed(Hash, #'DSAPrivateKey'{} = Key) -> calc_master_secret({3,0}, _PrfAlgo, PremasterSecret, ClientRandom, ServerRandom) -> ssl_ssl3:master_secret(PremasterSecret, ClientRandom, ServerRandom); -calc_master_secret({3,N}, _PrfAlgo, PremasterSecret, ClientRandom, ServerRandom) - when N == 1; N == 2 -> - ssl_tls1:master_secret(?MD5SHA, PremasterSecret, ClientRandom, ServerRandom); - -calc_master_secret({3,N}, PrfAlgo, PremasterSecret, ClientRandom, ServerRandom) - when N == 3 -> - %% only from TLS 1.2 onwards the selection of a PrfAlgo is supported +calc_master_secret({3,_}, PrfAlgo, PremasterSecret, ClientRandom, ServerRandom) -> ssl_tls1:master_secret(PrfAlgo, PremasterSecret, ClientRandom, ServerRandom). setup_keys({3,0}, _PrfAlgo, MasterSecret, ServerRandom, ClientRandom, HashSize, KML, EKML, IVS) -> - ssl_ssl3:setup_keys(MasterSecret, ServerRandom, + ssl_ssl3:setup_keys(MasterSecret, ServerRandom, ClientRandom, HashSize, KML, EKML, IVS); -setup_keys({3,N}, _PrfAlgo, MasterSecret, - ServerRandom, ClientRandom, HashSize, KML, _EKML, IVS) - when N == 1; N == 2 -> - ssl_tls1:setup_keys(N, ?MD5SHA, MasterSecret, ServerRandom, ClientRandom, HashSize, - KML, IVS); - setup_keys({3,N}, PrfAlgo, MasterSecret, - ServerRandom, ClientRandom, HashSize, KML, _EKML, IVS) - when N == 3 -> + ServerRandom, ClientRandom, HashSize, KML, _EKML, IVS) -> ssl_tls1:setup_keys(N, PrfAlgo, MasterSecret, ServerRandom, ClientRandom, HashSize, KML, IVS). calc_finished({3, 0}, Role, _PrfAlgo, MasterSecret, Handshake) -> ssl_ssl3:finished(Role, MasterSecret, lists:reverse(Handshake)); -calc_finished({3, N}, Role, _PrfAlgo, MasterSecret, Handshake) - when N == 1; N == 2 -> - ssl_tls1:finished(Role, N, ?MD5SHA, MasterSecret, lists:reverse(Handshake)); -calc_finished({3, N}, Role, PrfAlgo, MasterSecret, Handshake) - when N == 3 -> +calc_finished({3, N}, Role, PrfAlgo, MasterSecret, Handshake) -> ssl_tls1:finished(Role, N, PrfAlgo, MasterSecret, lists:reverse(Handshake)). calc_certificate_verify({3, 0}, HashAlgo, MasterSecret, Handshake) -> ssl_ssl3:certificate_verify(HashAlgo, MasterSecret, lists:reverse(Handshake)); -calc_certificate_verify({3, N}, HashAlgo, _MasterSecret, Handshake) - when N == 1; N == 2 -> +calc_certificate_verify({3, N}, HashAlgo, _MasterSecret, Handshake) -> ssl_tls1:certificate_verify(HashAlgo, N, lists:reverse(Handshake)). key_exchange_alg(rsa) -> diff --git a/lib/ssl/src/ssl_handshake.hrl b/lib/ssl/src/ssl_handshake.hrl index 8510def2fd..20e498ea2e 100644 --- a/lib/ssl/src/ssl_handshake.hrl +++ b/lib/ssl/src/ssl_handshake.hrl @@ -33,6 +33,12 @@ -type public_key_info() :: {algo_oid(), #'RSAPublicKey'{} | integer() , public_key_params()}. -type tls_handshake_history() :: {[binary()], [binary()]}. +%% Signature algorithms +-define(ANON, 0). +-define(RSA, 1). +-define(DSA, 2). +-define(ECDSA, 3). + -record(session, { session_id, peer_certificate, diff --git a/lib/ssl/src/ssl_record.erl b/lib/ssl/src/ssl_record.erl index f9ccaea0e3..676c191c17 100644 --- a/lib/ssl/src/ssl_record.erl +++ b/lib/ssl/src/ssl_record.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2007-2011. All Rights Reserved. +%% Copyright Ericsson AB 2007-2012. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -561,14 +561,14 @@ highest_protocol_version() -> initial_connection_state(ConnectionEnd) -> #connection_state{security_parameters = - initial_security_params(ConnectionEnd), + initial_security_params(ConnectionEnd), sequence_number = 0 }. initial_security_params(ConnectionEnd) -> SecParams = #security_parameters{connection_end = ConnectionEnd, compression_algorithm = ?NULL}, - ssl_cipher:security_parameters(?TLS_NULL_WITH_NULL_NULL, + ssl_cipher:security_parameters(highest_protocol_version(), ?TLS_NULL_WITH_NULL_NULL, SecParams). empty_connection_state(ConnectionEnd) -> diff --git a/lib/ssl/src/ssl_record.hrl b/lib/ssl/src/ssl_record.hrl index cb1008c2be..f73da92a52 100644 --- a/lib/ssl/src/ssl_record.hrl +++ b/lib/ssl/src/ssl_record.hrl @@ -98,11 +98,12 @@ %-define(TRUE, 0). %% Already defined by ssl_internal.hrl %-define(FALSE, 1). %% Already defined by ssl_internal.hrl -%% MACAlgorithm +%% MAC and PRF Algorithms %-define(NULL, 0). %% Already defined by ssl_internal.hrl -define(MD5, 1). -define(SHA, 2). --define(MD5SHA, 3). +-define(MD5SHA, 4711). %% Not defined in protocol used to represent old prf +-define(SHA224, 3). -define(SHA256, 4). -define(SHA384, 5). -define(SHA512, 6). diff --git a/lib/ssl/src/ssl_ssl3.erl b/lib/ssl/src/ssl_ssl3.erl index 11bc663e77..bb368fe5d0 100644 --- a/lib/ssl/src/ssl_ssl3.erl +++ b/lib/ssl/src/ssl_ssl3.erl @@ -74,7 +74,7 @@ finished(Role, MasterSecret, Handshake) -> SHA = handshake_hash(?SHA, MasterSecret, Sender, Handshake), <<MD5/binary, SHA/binary>>. --spec certificate_verify(OID::tuple(), binary(), [binary()]) -> binary(). +-spec certificate_verify(md5sha | sha, binary(), [binary()]) -> binary(). certificate_verify(?'rsaEncryption', MasterSecret, Handshake) -> %% md5_hash @@ -88,7 +88,7 @@ certificate_verify(?'rsaEncryption', MasterSecret, Handshake) -> SHA = handshake_hash(?SHA, MasterSecret, undefined, Handshake), <<MD5/binary, SHA/binary>>; -certificate_verify(?'id-dsa', MasterSecret, Handshake) -> +certificate_verify(sha, MasterSecret, Handshake) -> %% sha_hash %% SHA(master_secret + pad_2 + %% SHA(handshake_messages + master_secret + pad_1)); @@ -153,26 +153,17 @@ suites() -> %%% Internal functions %%-------------------------------------------------------------------- -hash(?MD5, Data) -> +hash(?MD5, Data) -> crypto:md5(Data); -hash(?SHA, Data) -> - crypto:sha(Data); -hash(?SHA256, Data) -> - crypto:sha256(Data); -hash(?SHA384, Data) -> - crypto:sha384(Data). +hash(?SHA, Data) -> + crypto:sha(Data). %%pad_1(?NULL) -> %% ""; pad_1(?MD5) -> <<"666666666666666666666666666666666666666666666666">>; pad_1(?SHA) -> - <<"6666666666666666666666666666666666666666">>; -pad_1(?SHA256) -> - <<"66666666666666666666666666666666">>; -pad_1(?SHA384) -> - <<"666666666666666666666666666666666666666666666666">>. - + <<"6666666666666666666666666666666666666666">>. %%pad_2(?NULL) -> %% ""; pad_2(?MD5) -> @@ -180,14 +171,7 @@ pad_2(?MD5) -> "\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\">>; pad_2(?SHA) -> <<"\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\" - "\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\">>; -pad_2(?SHA256) -> - <<"\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\" - "\\\\\\\\\\\\\\\\\\\\\\\\">>; -pad_2(?SHA384) -> - <<"\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\" - "\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\" - "\\\\\\\\\\\\\\\\">>. + "\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\">>. mac_hash(?NULL, _Secret, _Data) -> <<>>; diff --git a/lib/ssl/src/ssl_tls1.erl b/lib/ssl/src/ssl_tls1.erl index d56b8ee07f..e6e55048a4 100644 --- a/lib/ssl/src/ssl_tls1.erl +++ b/lib/ssl/src/ssl_tls1.erl @@ -28,7 +28,7 @@ -include("ssl_internal.hrl"). -include("ssl_record.hrl"). --export([master_secret/4, finished/5, certificate_verify/3, mac_hash/7, +-export([master_secret/4, finished/5, certificate_verify/2, mac_hash/7, setup_keys/8, suites/1, prf/5]). %%==================================================================== @@ -73,14 +73,14 @@ finished(Role, Version, PrfAlgo, MasterSecret, Handshake) Hash = crypto:hash(mac_algo(PrfAlgo), Handshake), prf(PrfAlgo, MasterSecret, finished_label(Role), Hash, 12). --spec certificate_verify(OID::tuple(), [binary()]) -> binary(). +-spec certificate_verify(md5sha | sha, integer(), [binary()]) -> binary(). certificate_verify(?'rsaEncryption', Handshake) -> MD5 = crypto:md5(Handshake), SHA = crypto:sha(Handshake), <<MD5/binary, SHA/binary>>; -certificate_verify(?'id-dsa', Handshake) -> +certificate_verify(sha, _Version, Handshake) -> crypto:sha(Handshake). -spec setup_keys(integer(), integer(), binary(), binary(), binary(), integer(), @@ -233,7 +233,6 @@ hmac_hash(?SHA512, Key, Value) -> mac_algo(?MD5) -> md5; mac_algo(?SHA) -> sha; -mac_algo(?MD5SHA) -> sha256; %% RFC 5246 defines minimum hash for TLS 1.2 mac_algo(?SHA256) -> sha256; mac_algo(?SHA384) -> sha384; mac_algo(?SHA512) -> sha512. @@ -287,8 +286,7 @@ split_secret(BinSecret) -> <<_:Div/binary, Secret2:EvenLength/binary>> = BinSecret, {Secret1, Secret2}. -prf(MAC, Secret, Label, Seed, WantedLength) - when MAC == ?MD5SHA -> +prf(?MD5SHA, Secret, Label, Seed, WantedLength) -> %% PRF(secret, label, seed) = P_MD5(S1, label + seed) XOR %% P_SHA-1(S2, label + seed); {S1, S2} = split_secret(Secret), |