File 4522-ssl-Handle-signature_algorithms_cert-extension-in-TL.patch of Package erlang

From b8339871af85c426e20fc73be3df208821d54c46 Mon Sep 17 00:00:00 2001
From: Ingela Anderton Andin <ingela@erlang.org>
Date: Fri, 13 Aug 2021 09:23:01 +0200
Subject: [PATCH 2/4] ssl: Handle signature_algorithms_cert extension in
 TLS-1.2

---
 lib/ssl/doc/src/ssl.xml                  | 53 ++++++++++++++++--------
 lib/ssl/doc/src/standards_compliance.xml |  4 +-
 lib/ssl/src/ssl_handshake.erl            | 25 ++++++-----
 lib/ssl/test/ssl_cert_SUITE.erl          | 34 +++++++++------
 lib/ssl/test/tls_1_3_version_SUITE.erl   |  2 +-
 5 files changed, 73 insertions(+), 45 deletions(-)

diff --git a/lib/ssl/doc/src/ssl.xml b/lib/ssl/doc/src/ssl.xml
index 807d292c63..2bda3c538c 100644
--- a/lib/ssl/doc/src/ssl.xml
+++ b/lib/ssl/doc/src/ssl.xml
@@ -494,26 +494,43 @@ version.
 
     <datatype>
       <name name="sign_schemes"/>
+
       <desc>
-	  <p>
-	    In addition to the signature_algorithms extension from TLS 1.2,
-	    <url href="http://www.ietf.org/rfc/rfc8446.txt#section-4.2.3">TLS 1.3
-	    (RFC 5246 Section 4.2.3)</url>adds the signature_algorithms_cert extension
-	    which enables having special requirements on the signatures used in the
-	    certificates that differs from the requirements on digital signatures as a whole.
-	    If this is not required this extension is not needed.
-	  </p>
-	  <p>
-	    The client will send a signature_algorithms_cert extension (ClientHello),
-	    if TLS version 1.3 or later is used, and the signature_algs_cert option is
-	    explicitly specified. By default, only the signature_algs extension is sent.
-	  </p>
-	  <p>
-	    The signature schemes shall be ordered according to the client's preference
-	    (favorite choice first).
-	  </p>
+	<p>Explicitly list acceptable signature schemes (algorithms),
+	in prefered ordered, for certificates, overrides the
+	algorithms supplied in  <seetype
+	marker="#signature_algs"><c>signature_algs</c></seetype> option for
+	certificates.</p>
+
+	<p>
+	  In addition to the <c>signature_algorithms</c> extension from TLS
+	  1.2, <url
+	  href="http://www.ietf.org/rfc/rfc8446.txt#section-4.2.3">TLS
+	  1.3 (RFC 5246 Section 4.2.3)</url> adds the
+	  <c>signature_algorithms_cert</c> extension which enables having
+	  special requirements on the signatures used in the
+	  certificates that differs from the requirements on digital
+	  signatures as a whole.  If this is not required this
+	  extension is not need.
+	</p>
+
+	<p>
+	  The client will send a <c>signature_algorithms_cert</c> extension
+	  (in the client hello message), if TLS version 1.2
+	  (back-ported to TLS 1.2 in @OTP-16590@) or later is used, and
+	  the signature_algs_cert option is explicitly specified. By
+	  default, only the <seetype
+	  marker="#signature_algs">signature_algs</seetype> extension
+	  is sent. </p>
+
+	  <note> <p> Note that supported signature schemes for TLS-1.2
+	  are <seetype
+	  marker="#sign_scheme_legacy">sign_scheme_legacy()</seetype>
+	  and <seetype
+	  marker="#rsassa_pss_scheme">rsassa_pss_scheme()</seetype>
+	  </p></note>
       </desc>
-     </datatype>
+    </datatype>
 
      <datatype>
        <name name="supported_groups"/>
diff --git a/lib/ssl/doc/src/standards_compliance.xml b/lib/ssl/doc/src/standards_compliance.xml
index 0fe67b8734..856fb65bc6 100644
--- a/lib/ssl/doc/src/standards_compliance.xml
+++ b/lib/ssl/doc/src/standards_compliance.xml
@@ -166,7 +166,7 @@
 	</cell>
         <cell align="left" valign="middle"></cell>
 	<cell align="left" valign="middle"><em>C</em></cell>
-	<cell align="left" valign="middle"><em>22</em></cell>
+	<cell align="left" valign="middle"><em>@OTP-16590@</em></cell>
       </row>
       <row>
         <cell align="left" valign="middle"></cell>
@@ -190,7 +190,7 @@
         <cell align="left" valign="middle"></cell>
         <cell align="left" valign="middle">signature_algorithms_cert extension</cell>
 	<cell align="left" valign="middle"><em>C</em></cell>
-	<cell align="left" valign="middle"><em>22</em></cell>
+	<cell align="left" valign="middle"><em>@OTP-16590@</em></cell>
       </row>
 
       <row>
diff --git a/lib/ssl/src/ssl_handshake.erl b/lib/ssl/src/ssl_handshake.erl
index dd226c3c56..f7dc641fb3 100644
--- a/lib/ssl/src/ssl_handshake.erl
+++ b/lib/ssl/src/ssl_handshake.erl
@@ -1181,18 +1181,22 @@ add_common_extensions({3,4},
                       _CipherSuites,
                       #{eccs := SupportedECCs,
                         supported_groups := Groups,
-                        signature_algs := SignatureSchemes}) ->
+                        signature_algs := SignatureSchemes,
+                        signature_algs_cert := SignatureCertSchemes}) ->
     {EcPointFormats, _} =
         client_ecc_extensions(SupportedECCs),
     HelloExtensions#{ec_point_formats => EcPointFormats,
                      elliptic_curves => Groups,
-                     signature_algs => signature_algs_ext(SignatureSchemes)};
+                     signature_algs => signature_algs_ext(SignatureSchemes),
+                     signature_algs_cert =>
+                         signature_algs_cert(SignatureCertSchemes)};
 
 add_common_extensions(Version,
                       HelloExtensions,
                       CipherSuites,
                       #{eccs := SupportedECCs,
-                        signature_algs := SupportedHashSigns}) ->
+                        signature_algs := SupportedHashSigns,
+                        signature_algs_cert := SignatureCertSchemes}) ->
 
     {EcPointFormats, EllipticCurves} =
         case advertises_ec_ciphers(
@@ -1205,20 +1209,18 @@ add_common_extensions(Version,
         end,
     HelloExtensions#{ec_point_formats => EcPointFormats,
                      elliptic_curves => EllipticCurves,
-                     signature_algs => available_signature_algs(SupportedHashSigns, Version)}.
-
+                     signature_algs => available_signature_algs(SupportedHashSigns, Version),
+                     signature_algs_cert =>
+                         signature_algs_cert(SignatureCertSchemes)}.
 
 maybe_add_tls13_extensions({3,4},
                            HelloExtensions0,
-                           #{signature_algs_cert := SignatureSchemes,
-                                        versions := SupportedVersions},
+                           #{versions := SupportedVersions},
                            KeyShare,
                            TicketData) ->
     HelloExtensions1 =
         HelloExtensions0#{client_hello_versions =>
-                              #client_hello_versions{versions = SupportedVersions},
-                          signature_algs_cert =>
-                              signature_algs_cert(SignatureSchemes)},
+                              #client_hello_versions{versions = SupportedVersions}},
     HelloExtensions = maybe_add_key_share(HelloExtensions1, KeyShare),
     maybe_add_pre_shared_key(HelloExtensions, TicketData);
 maybe_add_tls13_extensions(_, HelloExtensions, _, _, _) ->
@@ -3750,6 +3752,7 @@ path_validation(TrustedCert, Path, ServerName, Role, CertDbHandle, CertDbRef, CR
                   crl_check := CrlCheck,
                   log_level := Level,
                   signature_algs := SignAlgos,
+                  signature_algs_cert := SignAlgosCert,
                   depth := Depth}, 
                 #{cert_ext := CertExt,
                   ocsp_responder_certs := OcspResponderCerts,
@@ -3762,7 +3765,7 @@ path_validation(TrustedCert, Path, ServerName, Role, CertDbHandle, CertDbRef, CR
                                               customize_hostname_check =>
                                                   CustomizeHostnameCheck,
                                               signature_algs => SignAlgos,
-                                              signature_algs_cert => undefined,
+                                              signature_algs_cert => SignAlgosCert,
                                               version => Version,
                                               crl_check => CrlCheck,
                                               crl_db => CRLDbHandle,
diff --git a/lib/ssl/test/ssl_cert_SUITE.erl b/lib/ssl/test/ssl_cert_SUITE.erl
index 2550fce21b..42c44e4855 100644
--- a/lib/ssl/test/ssl_cert_SUITE.erl
+++ b/lib/ssl/test/ssl_cert_SUITE.erl
@@ -151,7 +151,7 @@ groups() ->
      {dsa, [], all_version_tests()},
      {rsa_1_3, [], all_version_tests() ++ rsa_tests() ++
           tls_1_3_tests() ++ tls_1_3_rsa_tests() ++ [basic_rsa_1024]},
-     {rsa_pss_rsae, [], all_version_tests()},
+     {rsa_pss_rsae, [], all_version_tests() ++ tls_1_2_rsa_tests()},
      {rsa_pss_rsae_1_3, [], all_version_tests() ++ rsa_tests() ++ tls_1_3_tests() ++ tls_1_3_rsa_tests()},
      {rsa_pss_pss, [], all_version_tests()},
      {rsa_pss_pss_1_3, [], all_version_tests() ++ rsa_tests() ++ tls_1_3_tests() ++ tls_1_3_rsa_tests()},
@@ -209,6 +209,12 @@ tls_1_3_rsa_tests() ->
       unsupported_sign_algo_cert_client_auth
      ].
 
+tls_1_2_rsa_tests() ->
+     [
+      unsupported_sign_algo_client_auth,
+      unsupported_sign_algo_cert_client_auth
+     ].
+
 all_version_tests() ->
     [
      no_auth,
@@ -1129,33 +1135,35 @@ custom_groups(Config) ->
 %% of CertificateRequest does not contain the algorithm of the client certificate).
 %% ssl client sends an empty certificate.
 unsupported_sign_algo_cert_client_auth() ->
-     [{doc,"TLS 1.3: Test client authentication with unsupported signature_algorithm_cert"}].
+     [{doc,"TLS 1.3 (backported to TLS-1.2) : Test client authentication with unsupported signature_algorithm_cert"}].
 
 unsupported_sign_algo_cert_client_auth(Config) ->
-    ClientOpts0 = ssl_test_lib:ssl_options(client_cert_opts, Config),
+    ClientOpts = ssl_test_lib:ssl_options(client_cert_opts, Config),
     ServerOpts0 = ssl_test_lib:ssl_options(server_cert_opts, Config),
-    ServerOpts = [{versions, ['tlsv1.2','tlsv1.3']},
-                  {verify, verify_peer},
+    ServerOpts = [{verify, verify_peer},
                   {signature_algs, [rsa_pkcs1_sha256, rsa_pkcs1_sha384, rsa_pss_rsae_sha256, rsa_pss_pss_sha256]},
                   %% Skip rsa_pkcs1_sha256!
                   {signature_algs_cert, [rsa_pkcs1_sha384, rsa_pkcs1_sha512]},
                   {fail_if_no_peer_cert, true}|ServerOpts0],
-    ClientOpts = [{versions, ['tlsv1.2','tlsv1.3']}|ClientOpts0],
-    ssl_test_lib:basic_alert(ClientOpts, ServerOpts, Config, certificate_required).
+    Version = proplists:get_value(version, Config),
+    case Version of
+        'tlsv1.3' ->
+            ssl_test_lib:basic_alert(ClientOpts, ServerOpts, Config, certificate_required);
+        _  ->
+            ssl_test_lib:basic_alert(ClientOpts, ServerOpts, Config, insufficient_security)
+    end.
 
 %%--------------------------------------------------------------------
 unsupported_sign_algo_client_auth() ->
-     [{doc,"TLS 1.3: Test client authentication with unsupported signature_algorithm"}].
+     [{doc,"TLS 1.3 (backported to TLS-1.2): Test client authentication with unsupported signature_algorithm"}].
 
 unsupported_sign_algo_client_auth(Config) ->
     ClientOpts0 = ssl_test_lib:ssl_options(client_cert_opts, Config),
     ServerOpts0 = ssl_test_lib:ssl_options(server_cert_opts, Config),
-    ServerOpts = [{versions, ['tlsv1.2','tlsv1.3']},
-                  {verify, verify_peer},
-                  %% Skip rsa_pkcs1_sha256!
-                  {signature_algs, [rsa_pkcs1_sha384, rsa_pkcs1_sha512]},
+    ClientOpts = [{signature_algs, [rsa_pkcs1_sha256, rsa_pss_rsae_sha256]} | ClientOpts0],
+    ServerOpts = [{verify, verify_peer},
+                  {signature_algs, [ecdsa_sha1, rsa_pss_pss_sha256]},
                   {fail_if_no_peer_cert, true}|ServerOpts0],
-    ClientOpts = [{versions, ['tlsv1.2','tlsv1.3']}|ClientOpts0],
     ssl_test_lib:basic_alert(ClientOpts, ServerOpts, Config, insufficient_security).
 %%--------------------------------------------------------------------
 hello_retry_client_auth() ->
diff --git a/lib/ssl/test/tls_1_3_version_SUITE.erl b/lib/ssl/test/tls_1_3_version_SUITE.erl
index 03fcb9afe5..6e0334a16f 100644
--- a/lib/ssl/test/tls_1_3_version_SUITE.erl
+++ b/lib/ssl/test/tls_1_3_version_SUITE.erl
@@ -146,7 +146,7 @@ tls13_client_tls12_server(Config) when is_list(Config) ->
     
 tls13_client_with_ext_tls12_server() ->
      [{doc,"Test basic connection between TLS 1.2 server and TLS 1.3 client when " 
-       "client has TLS 1.3 specsific extensions"}].
+       "client has TLS 1.3 specific extensions"}].
 
 tls13_client_with_ext_tls12_server(Config) ->
     ClientOpts0 = ssl_test_lib:ssl_options(client_cert_opts, Config),
-- 
2.31.1

openSUSE Build Service is sponsored by