aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorAndreas Schultz <[email protected]>2012-06-18 12:07:37 +0200
committerIngela Anderton Andin <[email protected]>2012-08-22 14:00:45 +0200
commit3f10f10404ee85fcf9d8f7915f768b4826eed12a (patch)
tree667e8611989237fe90669e86d179be373f2589f0 /lib
parent0bcbe96a1a68fef87efc43719853edcee2f58720 (diff)
downloadotp-3f10f10404ee85fcf9d8f7915f768b4826eed12a.tar.gz
otp-3f10f10404ee85fcf9d8f7915f768b4826eed12a.tar.bz2
otp-3f10f10404ee85fcf9d8f7915f768b4826eed12a.zip
ssl: Implement TLS 1.2 signature support
Diffstat (limited to 'lib')
-rw-r--r--lib/ssl/src/ssl_handshake.erl43
1 files changed, 41 insertions, 2 deletions
diff --git a/lib/ssl/src/ssl_handshake.erl b/lib/ssl/src/ssl_handshake.erl
index 0d681e9fcb..2957059b74 100644
--- a/lib/ssl/src/ssl_handshake.erl
+++ b/lib/ssl/src/ssl_handshake.erl
@@ -312,10 +312,10 @@ certificate_verify(Signature, {?'rsaEncryption', PublicKey, _}, Version,
certificate_verify(Signature, {?'id-dsa', PublicKey, PublicKeyParams}, Version,
{HashAlgo, _SignAlgo}, MasterSecret, {_, Handshake}) ->
Hashes = calc_certificate_verify(Version, HashAlgo, MasterSecret, Handshake),
- case public_key:verify(Hashes, none, Signature, {PublicKey, PublicKeyParams}) of
+ case public_key:verify({digest, Hashes}, sha, Signature, {PublicKey, PublicKeyParams}) of
true ->
valid;
- false ->
+ false ->
?ALERT_REC(?FATAL, ?BAD_CERTIFICATE)
end.
@@ -890,6 +890,16 @@ dec_hs(_Version, ?SERVER_KEY_EXCHANGE, <<?UINT16(PLen), P:PLen/binary,
#server_key_exchange{params = #server_dh_params{dh_p = P,dh_g = G,
dh_y = Y},
signed_params = <<>>, hashsign = {null, anon}};
+dec_hs({Major, Minor}, ?SERVER_KEY_EXCHANGE, <<?UINT16(PLen), P:PLen/binary,
+ ?UINT16(GLen), G:GLen/binary,
+ ?UINT16(YLen), Y:YLen/binary,
+ ?BYTE(HashAlgo), ?BYTE(SignAlgo),
+ ?UINT16(Len), Sig:Len/binary>>)
+ when Major == 3, Minor >= 3 ->
+ #server_key_exchange{params = #server_dh_params{dh_p = P,dh_g = G,
+ dh_y = Y},
+ signed_params = Sig,
+ hashsign = {ssl_cipher:hash_algorithm(HashAlgo), ssl_cipher:sign_algorithm(SignAlgo)}};
dec_hs(_Version, ?SERVER_KEY_EXCHANGE, <<?UINT16(PLen), P:PLen/binary,
?UINT16(GLen), G:GLen/binary,
?UINT16(YLen), Y:YLen/binary,
@@ -897,6 +907,14 @@ dec_hs(_Version, ?SERVER_KEY_EXCHANGE, <<?UINT16(PLen), P:PLen/binary,
#server_key_exchange{params = #server_dh_params{dh_p = P,dh_g = G,
dh_y = Y},
signed_params = Sig, hashsign = undefined};
+dec_hs({Major, Minor}, ?CERTIFICATE_REQUEST,
+ <<?BYTE(CertTypesLen), CertTypes:CertTypesLen/binary,
+ ?UINT16(HashSignsLen), HashSigns:HashSignsLen/binary,
+ ?UINT16(CertAuthsLen), CertAuths:CertAuthsLen/binary>>)
+ when Major == 3, Minor >= 3 ->
+ #certificate_request{certificate_types = CertTypes,
+ hashsign_algorithms = HashSigns,
+ certificate_authorities = CertAuths};
dec_hs(_Version, ?CERTIFICATE_REQUEST,
<<?BYTE(CertTypesLen), CertTypes:CertTypesLen/binary,
?UINT16(CertAuthsLen), CertAuths:CertAuthsLen/binary>>) ->
@@ -904,6 +922,9 @@ dec_hs(_Version, ?CERTIFICATE_REQUEST,
certificate_authorities = CertAuths};
dec_hs(_Version, ?SERVER_HELLO_DONE, <<>>) ->
#server_hello_done{};
+dec_hs({Major, Minor}, ?CERTIFICATE_VERIFY,<<HashSign:2/binary, ?UINT16(SignLen), Signature:SignLen/binary>>)
+ 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};
dec_hs(_Version, ?CLIENT_KEY_EXCHANGE, PKEPMS) ->
@@ -1027,6 +1048,19 @@ enc_hs(#server_key_exchange{params = #server_dh_params{
Signature/binary>>
};
enc_hs(#certificate_request{certificate_types = CertTypes,
+ hashsign_algorithms = HashSigns,
+ certificate_authorities = CertAuths},
+ {Major, Minor})
+ when Major == 3, Minor >= 3 ->
+ CertTypesLen = byte_size(CertTypes),
+ HashSignsLen = byte_size(HashSigns),
+ CertAuthsLen = byte_size(CertAuths),
+ {?CERTIFICATE_REQUEST,
+ <<?BYTE(CertTypesLen), CertTypes/binary,
+ ?UINT16(HashSignsLen), HashSigns/binary,
+ ?UINT16(CertAuthsLen), CertAuths/binary>>
+ };
+enc_hs(#certificate_request{certificate_types = CertTypes,
certificate_authorities = CertAuths},
_Version) ->
CertTypesLen = byte_size(CertTypes),
@@ -1054,6 +1088,11 @@ enc_cke(#client_diffie_hellman_public{dh_public = DHPublic}, _) ->
Len = byte_size(DHPublic),
<<?UINT16(Len), DHPublic/binary>>.
+enc_sign({HashAlg, SignAlg}, Signature, _Version = {Major, Minor})
+ when Major == 3, Minor >= 3->
+ SignLen = byte_size(Signature),
+ HashSign = hashsign_enc(HashAlg, SignAlg),
+ <<HashSign/binary, ?UINT16(SignLen), Signature/binary>>;
enc_sign(_HashSign, Sign, _Version) ->
SignLen = byte_size(Sign),
<<?UINT16(SignLen), Sign/binary>>.