aboutsummaryrefslogtreecommitdiffstats
path: root/lib/ssl/src
diff options
context:
space:
mode:
authorAndreas Schultz <[email protected]>2012-08-16 11:23:33 +0200
committerIngela Anderton Andin <[email protected]>2012-08-22 14:00:46 +0200
commitbe66663142da66e013ad65c4ebe429d9391312b0 (patch)
tree7cc5a5b93c34f23ce5c309d22202f185a504255a /lib/ssl/src
parent191931c58ebc9f18efb2422d296b4a246119ab83 (diff)
downloadotp-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.erl9
-rw-r--r--lib/ssl/src/ssl_handshake.erl2
-rw-r--r--lib/ssl/src/ssl_tls1.erl6
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,