aboutsummaryrefslogtreecommitdiffstats
path: root/lib/ssl
diff options
context:
space:
mode:
authorPéter Dimitrov <[email protected]>2019-06-14 15:53:47 +0200
committerPéter Dimitrov <[email protected]>2019-06-14 15:53:47 +0200
commitdca65c70badd3b33903a0535ef2366eecc3e12dc (patch)
tree6989f3cd54aacc6fc37c42b8169735b574398091 /lib/ssl
parentb4fb2e5669acb02697d9a9ab168eb0fbff6f370c (diff)
downloadotp-dca65c70badd3b33903a0535ef2366eecc3e12dc.tar.gz
otp-dca65c70badd3b33903a0535ef2366eecc3e12dc.tar.bz2
otp-dca65c70badd3b33903a0535ef2366eecc3e12dc.zip
ssl: Improve handling of signature algorithms
TLS 1.2 ClientHello caused handshake failure in the TLS 1.2 server if the signature_algorithms_cert extension contained legacy algorithms. Update TLS 1.2 server to properly handle legacy signature algorithms in the signature_algorithms_cert extension. Update TLS 1.3 client so that it can send legacy algorithms in its signature_algorithms_cert extension.
Diffstat (limited to 'lib/ssl')
-rw-r--r--lib/ssl/src/ssl_cipher.erl10
-rw-r--r--lib/ssl/src/ssl_handshake.erl5
-rw-r--r--lib/ssl/src/tls_v1.erl22
3 files changed, 30 insertions, 7 deletions
diff --git a/lib/ssl/src/ssl_cipher.erl b/lib/ssl/src/ssl_cipher.erl
index 21db887bb5..4da50d2af8 100644
--- a/lib/ssl/src/ssl_cipher.erl
+++ b/lib/ssl/src/ssl_cipher.erl
@@ -923,6 +923,12 @@ signature_scheme(rsa_pss_pss_sha384) -> ?RSA_PSS_PSS_SHA384;
signature_scheme(rsa_pss_pss_sha512) -> ?RSA_PSS_PSS_SHA512;
signature_scheme(rsa_pkcs1_sha1) -> ?RSA_PKCS1_SHA1;
signature_scheme(ecdsa_sha1) -> ?ECDSA_SHA1;
+%% Handling legacy signature algorithms
+signature_scheme({Hash0, Sign0}) ->
+ Hash = hash_algorithm(Hash0),
+ Sign = sign_algorithm(Sign0),
+ <<?UINT16(SigAlg)>> = <<?BYTE(Hash),?BYTE(Sign)>>,
+ SigAlg;
signature_scheme(?RSA_PKCS1_SHA256) -> rsa_pkcs1_sha256;
signature_scheme(?RSA_PKCS1_SHA384) -> rsa_pkcs1_sha384;
signature_scheme(?RSA_PKCS1_SHA512) -> rsa_pkcs1_sha512;
@@ -962,7 +968,9 @@ scheme_to_components(rsa_pss_pss_sha256) -> {sha256, rsa_pss_pss, undefined};
scheme_to_components(rsa_pss_pss_sha384) -> {sha384, rsa_pss_pss, undefined};
scheme_to_components(rsa_pss_pss_sha512) -> {sha512, rsa_pss_pss, undefined};
scheme_to_components(rsa_pkcs1_sha1) -> {sha1, rsa_pkcs1, undefined};
-scheme_to_components(ecdsa_sha1) -> {sha1, ecdsa, undefined}.
+scheme_to_components(ecdsa_sha1) -> {sha1, ecdsa, undefined};
+%% Handling legacy signature algorithms
+scheme_to_components({Hash,Sign}) -> {Hash, Sign, undefined}.
%% TODO: Add support for EC and RSA-SSA signatures
diff --git a/lib/ssl/src/ssl_handshake.erl b/lib/ssl/src/ssl_handshake.erl
index f68d3e9b26..3d2abb714f 100644
--- a/lib/ssl/src/ssl_handshake.erl
+++ b/lib/ssl/src/ssl_handshake.erl
@@ -1186,10 +1186,7 @@ signature_algs_ext(undefined) ->
signature_algs_ext(SignatureSchemes0) ->
%% The SSL option signature_algs contains both hash-sign algorithms (tuples) and
%% signature schemes (atoms) if TLS 1.3 is configured.
- %% Filter out all hash-sign tuples when creating the signature_algs extension.
- %% (TLS 1.3 specific record type)
- SignatureSchemes = lists:filter(fun is_atom/1, SignatureSchemes0),
- #signature_algorithms{signature_scheme_list = SignatureSchemes}.
+ #signature_algorithms{signature_scheme_list = SignatureSchemes0}.
signature_algs_cert(undefined) ->
undefined;
diff --git a/lib/ssl/src/tls_v1.erl b/lib/ssl/src/tls_v1.erl
index 27cd5765e5..f7c8c770ae 100644
--- a/lib/ssl/src/tls_v1.erl
+++ b/lib/ssl/src/tls_v1.erl
@@ -606,8 +606,26 @@ signature_schemes(Version, SignatureSchemes) when is_tuple(Version)
Acc
end;
%% Special clause for filtering out the legacy hash-sign tuples.
- (_ , Acc) ->
- Acc
+ ({Hash, dsa = Sign} = Alg, Acc) ->
+ case proplists:get_bool(dss, PubKeys)
+ andalso proplists:get_bool(Hash, Hashes)
+ andalso is_pair(Hash, Sign, Hashes)
+ of
+ true ->
+ [Alg | Acc];
+ false ->
+ Acc
+ end;
+ ({Hash, Sign} = Alg, Acc) ->
+ case proplists:get_bool(Sign, PubKeys)
+ andalso proplists:get_bool(Hash, Hashes)
+ andalso is_pair(Hash, Sign, Hashes)
+ of
+ true ->
+ [Alg | Acc];
+ false ->
+ Acc
+ end
end,
Supported = lists:foldl(Fun, [], SignatureSchemes),
lists:reverse(Supported);