diff options
author | Andreas Schultz <[email protected]> | 2012-08-16 11:23:33 +0200 |
---|---|---|
committer | Ingela Anderton Andin <[email protected]> | 2012-08-22 14:00:46 +0200 |
commit | be66663142da66e013ad65c4ebe429d9391312b0 (patch) | |
tree | 7cc5a5b93c34f23ce5c309d22202f185a504255a /lib/ssl/src | |
parent | 191931c58ebc9f18efb2422d296b4a246119ab83 (diff) | |
download | otp-be66663142da66e013ad65c4ebe429d9391312b0.tar.gz otp-be66663142da66e013ad65c4ebe429d9391312b0.tar.bz2 otp-be66663142da66e013ad65c4ebe429d9391312b0.zip |
ssl: TLS 1.2: fix hash and signature handling
with TLS 1.2 the hash and signature on a certify message can
differ from the defaults. So we have to make sure to always
use the hash and signature algorithm indicated in the
handshake message
Diffstat (limited to 'lib/ssl/src')
-rw-r--r-- | lib/ssl/src/ssl_connection.erl | 9 | ||||
-rw-r--r-- | lib/ssl/src/ssl_handshake.erl | 2 | ||||
-rw-r--r-- | lib/ssl/src/ssl_tls1.erl | 6 |
3 files changed, 11 insertions, 6 deletions
diff --git a/lib/ssl/src/ssl_connection.erl b/lib/ssl/src/ssl_connection.erl index c09e07018d..fc2488952d 100644 --- a/lib/ssl/src/ssl_connection.erl +++ b/lib/ssl/src/ssl_connection.erl @@ -640,14 +640,18 @@ cipher(#hello_request{}, State0) -> {Record, State} = next_record(State0), next_state(cipher, hello, Record, State); -cipher(#certificate_verify{signature = Signature}, +cipher(#certificate_verify{signature = Signature, hashsign_algorithm = CertHashSign}, #state{role = server, public_key_info = PublicKeyInfo, negotiated_version = Version, session = #session{master_secret = MasterSecret}, - hashsign_algorithm = HashSign, + hashsign_algorithm = ConnectionHashSign, tls_handshake_history = Handshake } = State0) -> + HashSign = case CertHashSign of + {_, _} -> CertHashSign; + _ -> ConnectionHashSign + end, case ssl_handshake:certificate_verify(Signature, PublicKeyInfo, Version, HashSign, MasterSecret, Handshake) of valid -> @@ -1253,6 +1257,7 @@ verify_client_cert(#state{client_certificate_requested = true, role = client, hashsign_algorithm = HashSign, tls_handshake_history = Handshake0} = State) -> + %%TODO: for TLS 1.2 we can choose a different/stronger HashSign combination for this. case ssl_handshake:client_certificate_verify(OwnCert, MasterSecret, Version, HashSign, PrivateKey, Handshake0) of #certificate_verify{} = Verified -> diff --git a/lib/ssl/src/ssl_handshake.erl b/lib/ssl/src/ssl_handshake.erl index 9d251054c9..497f778bc2 100644 --- a/lib/ssl/src/ssl_handshake.erl +++ b/lib/ssl/src/ssl_handshake.erl @@ -927,7 +927,7 @@ dec_hs({Major, Minor}, ?CERTIFICATE_VERIFY,<<HashSign:2/binary, ?UINT16(SignLen) when Major == 3, Minor >= 3 -> #certificate_verify{hashsign_algorithm = hashsign_dec(HashSign), signature = Signature}; dec_hs(_Version, ?CERTIFICATE_VERIFY,<<?UINT16(SignLen), Signature:SignLen/binary>>)-> - #certificate_verify{hashsign_algorithm = {unknown, unknown}, signature = Signature}; + #certificate_verify{signature = Signature}; dec_hs(_Version, ?CLIENT_KEY_EXCHANGE, PKEPMS) -> #client_key_exchange{exchange_keys = PKEPMS}; dec_hs(_Version, ?FINISHED, VerifyData) -> diff --git a/lib/ssl/src/ssl_tls1.erl b/lib/ssl/src/ssl_tls1.erl index 91b321bcd9..1daf9640ab 100644 --- a/lib/ssl/src/ssl_tls1.erl +++ b/lib/ssl/src/ssl_tls1.erl @@ -80,11 +80,11 @@ certificate_verify(md5sha, _Version, Handshake) -> SHA = crypto:sha(Handshake), <<MD5/binary, SHA/binary>>; -certificate_verify(sha, _Version, Handshake) -> - crypto:sha(Handshake). +certificate_verify(HashAlgo, _Version, Handshake) -> + Hash = crypto:hash(HashAlgo, Handshake). -spec setup_keys(integer(), integer(), binary(), binary(), binary(), integer(), - integer(), integer()) -> {binary(), binary(), binary(), + integer(), integer()) -> {binary(), binary(), binary(), binary(), binary(), binary()}. setup_keys(Version, _PrfAlgo, MasterSecret, ServerRandom, ClientRandom, HashSize, |