Skip to content

Commit 1efa3ea

Browse files
committed
ssl: For TLS-1.2 cert signature must be compatible with cipher suite
In TLS-1.3 this is negotiated separtly
1 parent c247270 commit 1efa3ea

File tree

1 file changed

+33
-13
lines changed

1 file changed

+33
-13
lines changed

lib/ssl/src/ssl_handshake.erl

Lines changed: 33 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1146,38 +1146,58 @@ server_select_cert_key_pair_and_params(CipherSuites, [#{private_key := NoKey, ce
11461146
CipherSuite0 = select_cipher_suite(CipherSuites, Suites, HonorCipherOrder),
11471147
CurveAndSuite = cert_curve(undefined, ECCCurve0, CipherSuite0),
11481148
{NoCerts, NoKey, CurveAndSuite};
1149-
server_select_cert_key_pair_and_params(CipherSuites, [#{private_key := Key, certs := [Cert | _] = Certs}], HashSigns, ECCCurve0,
1149+
server_select_cert_key_pair_and_params(CipherSuites0, [#{private_key := Key, certs := [Cert | _] = Certs}], HashSigns, ECCCurve0,
11501150
#{ciphers := UserSuites, honor_cipher_order := HonorCipherOrder}, Version) ->
11511151
Suites = available_suites(Cert, UserSuites, Version, HashSigns, ECCCurve0),
1152+
CipherSuites = [ Suite || Suite <- CipherSuites0,
1153+
is_acceptable_cert(Suite, Cert, HashSigns, ssl:tls_version(Version))],
11521154
CipherSuite0 = select_cipher_suite(CipherSuites, Suites, HonorCipherOrder),
11531155
CurveAndSuite = cert_curve(Cert, ECCCurve0, CipherSuite0),
11541156
{Certs, Key, CurveAndSuite};
1155-
server_select_cert_key_pair_and_params(CipherSuites, [#{private_key := Key, certs := [Cert | _] = Certs} | Rest], HashSigns, ECCCurve0,
1157+
server_select_cert_key_pair_and_params(CipherSuites0, [#{private_key := Key, certs := [Cert | _] = Certs} | Rest], HashSigns, ECCCurve0,
11561158
#{ciphers := UserSuites, honor_cipher_order := HonorCipherOrder} = Opts, Version) ->
11571159
Suites = available_suites(Cert, UserSuites, Version, HashSigns, ECCCurve0),
1160+
CipherSuites = [ Suite || Suite <- CipherSuites0, is_acceptable_cert(Suite, Cert, HashSigns, ssl:tls_version(Version))],
11581161
case select_cipher_suite(CipherSuites, Suites, HonorCipherOrder) of
11591162
no_suite ->
1160-
server_select_cert_key_pair_and_params(CipherSuites, Rest, HashSigns, ECCCurve0, Opts, Version);
1163+
server_select_cert_key_pair_and_params(CipherSuites0, Rest, HashSigns, ECCCurve0, Opts, Version);
11611164
CipherSuite0 ->
1162-
case is_acceptable_cert(Cert, HashSigns, ssl:tls_version(Version)) of
1163-
true ->
1164-
CurveAndSuite = cert_curve(Cert, ECCCurve0, CipherSuite0),
1165-
{Certs, Key, CurveAndSuite};
1166-
false ->
1167-
server_select_cert_key_pair_and_params(CipherSuites, Rest, HashSigns, ECCCurve0, Opts, Version)
1168-
end
1165+
CurveAndSuite = cert_curve(Cert, ECCCurve0, CipherSuite0),
1166+
{Certs, Key, CurveAndSuite}
11691167
end.
11701168

1171-
is_acceptable_cert(Cert, HashSigns, Version)
1169+
is_acceptable_cert(CipherSuite, Cert, HashSigns, Version)
11721170
when ?TLS_1_X(Version),
11731171
?TLS_GTE(Version, ?TLS_1_2) ->
11741172
{SignAlgo0, Param, _, _, _} = get_cert_params(Cert),
11751173
SignAlgo = sign_algo(SignAlgo0, Param),
1176-
is_acceptable_hash_sign(SignAlgo, HashSigns);
1177-
is_acceptable_cert(_,_,_) ->
1174+
is_acceptable_hash_sign(SignAlgo, acceptable_hash_signs(CipherSuite, HashSigns));
1175+
is_acceptable_cert(_, _,_,_) ->
11781176
%% Not negotiable pre TLS-1.2. So if cert is available for version it is acceptable
11791177
true.
11801178

1179+
acceptable_hash_signs(CipherSuite, HashSigns) ->
1180+
#{key_exchange := Kex} = ssl_cipher_format:suite_bin_to_map(CipherSuite),
1181+
Filter = fun({_, rsa}) when Kex == ecdh_rsa;
1182+
Kex == ecdhe_rsa;
1183+
Kex == dhe_rsa;
1184+
Kex == srp_rsa;
1185+
Kex == rsa_psk;
1186+
Kex == rsa ->
1187+
true;
1188+
({_, ecdsa}) when Kex == ecdh_ecdsa;
1189+
Kex == ecdhe_ecdsa ->
1190+
true;
1191+
({_, dsa}) when Kex == dhe_dss;
1192+
Kex == srp_dss ->
1193+
true;
1194+
(_) when Kex == any ->
1195+
true;
1196+
(_) ->
1197+
false
1198+
end,
1199+
[HS || HS <- HashSigns, Filter(HS)].
1200+
11811201
premaster_secret(OtherPublicDhKey, MyPrivateKey, #'DHParameter'{} = Params) ->
11821202
try
11831203
public_key:compute_key(OtherPublicDhKey, MyPrivateKey, Params)

0 commit comments

Comments
 (0)