File 4002-ssl-public_key-Adjust-handling-of-extended-key-usage.patch of Package erlang

From 4c8c99b74bd84cc4460c50be982c22607d456e0b Mon Sep 17 00:00:00 2001
From: Ingela Anderton Andin <ingela@erlang.org>
Date: Tue, 29 Aug 2023 08:26:28 +0200
Subject: [PATCH 2/2] ssl, public_key: Adjust handling of extended key usage
 certificate extension

This extension is in general found in end entity certificates, but can apper
in CA certificates. See RFC 5280.

ssl application will validate id-kp-serverAuth and id-kp-clientAuth
in end entity certificates.
---
 lib/public_key/src/pubkey_cert.erl | 11 ++-------
 lib/ssl/src/ssl_certificate.erl    | 24 +++++++++----------
 lib/ssl/src/ssl_handshake.erl      |  4 +++-
 lib/ssl/src/tls_handshake_1_3.erl  | 38 ++++++++++++++++--------------
 4 files changed, 37 insertions(+), 40 deletions(-)

diff --git a/lib/ssl/src/ssl_certificate.erl b/lib/ssl/src/ssl_certificate.erl
index cb1ddbfa05..78dccd6a5c 100644
--- a/lib/ssl/src/ssl_certificate.erl
+++ b/lib/ssl/src/ssl_certificate.erl
@@ -73,7 +73,6 @@
          file_to_certificats/2,
          file_to_crls/2,
          validate/3,
-         is_valid_extkey_usage/2,
          is_valid_key_usage/2,
          select_extension/2,
          extensions_list/1,
@@ -204,7 +203,8 @@ file_to_crls(File, DbHandle) ->
 %%--------------------------------------------------------------------
 validate(_,{extension, #'Extension'{extnID = ?'id-ce-extKeyUsage',
                                     critical = Critical,
-				    extnValue = KeyUse}}, #{pathlen := 1} = UserState) ->
+				    extnValue = KeyUse}}, #{path_len := 1} = UserState) ->
+    %% If extension in peer, check for TLS server/client usage
     case is_valid_extkey_usage(KeyUse, Critical, UserState) of
 	true ->
 	    {valid, UserState};
@@ -217,14 +217,14 @@ validate(Issuer, {bad_cert, cert_expired}, #{issuer := Issuer}) ->
     {fail, {bad_cert, root_cert_expired}};
 validate(_, {bad_cert, _} = Reason, _) ->
     {fail, Reason};
-validate(Cert, valid, #{pathlen := N} = UserState) ->
+validate(Cert, valid, #{path_len := N} = UserState) ->
     case verify_sign(Cert, UserState) of
         true ->
             case maps:get(cert_ext, UserState, undefined) of
                 undefined ->
-                    {valid, UserState#{pathlen => N-1}};
+                    {valid, UserState#{path_len => N-1}};
                 _ ->
-                    verify_cert_extensions(Cert, UserState#{pathlen => N -1})
+                    verify_cert_extensions(Cert, UserState#{path_len => N-1})
             end;
         false ->
             {fail, {bad_cert, invalid_signature}}
@@ -495,19 +495,19 @@ do_find_issuer(IssuerFun, CertDbHandle, CertDb) ->
 	    Return
     end.
 
-is_valid_extkey_usage(KeyUse, true, #{role := Role, pathlen := 1}) when is_list(KeyUse) ->
-    is_valid_key_usage(ext_keysage(Role), KeyUse);
-is_valid_key_usage(KeyUse, true, #{role := Role, pathlen := 1}) ->
-    is_valid_key_usage(ext_keysage(Role), [KeyUse]);
-is_valid_key_usage(_, false, _) ->
+is_valid_extkey_usage(KeyUse, true, #{role := Role}) when is_list(KeyUse) ->
+    is_valid_key_usage(KeyUse, ext_keysage(Role));
+is_valid_extkey_usage(KeyUse, true, #{role := Role}) ->
+    is_valid_key_usage([KeyUse], ext_keysage(Role));
+is_valid_extkey_usage(_, false, _) ->
     false.
 
 ext_keysage(client) ->
     %% Client wants to verify server
-    ?'id-kp-serverAuth'.
+    ?'id-kp-serverAuth';
 ext_keysage(server) ->
     %% Server wants to verify client
-    ?'id-kp-serverAuth'.
+    ?'id-kp-clientAuth'.
 
 verify_cert_signer(BinCert, SignerTBSCert) ->
     PublicKey = public_key(SignerTBSCert#'OTPTBSCertificate'.subjectPublicKeyInfo),
diff --git a/lib/ssl/src/ssl_handshake.erl b/lib/ssl/src/ssl_handshake.erl
index 56a1ca81b9..04601dfbf2 100644
--- a/lib/ssl/src/ssl_handshake.erl
+++ b/lib/ssl/src/ssl_handshake.erl
@@ -3879,7 +3879,9 @@ path_validation(TrustedCert, Path, ServerName, Role, CertDbHandle, CertDbRef, CR
                                               cert_ext => CertExt,
                                               issuer => TrustedCert,
                                               ocsp_responder_certs => OcspResponderCerts,
-                                              ocsp_state => OcspState},
+                                              ocsp_state => OcspState,
+                                              path_len => length(Path)
+                                             },
                                  Path, Level),
     Options = [{max_path_length, Depth},
                {verify_fun, ValidationFunAndState}],
diff --git a/lib/ssl/src/tls_handshake_1_3.erl b/lib/ssl/src/tls_handshake_1_3.erl
index 750a79887f..34690ef9dd 100644
--- a/lib/ssl/src/tls_handshake_1_3.erl
+++ b/lib/ssl/src/tls_handshake_1_3.erl
@@ -2943,24 +2943,26 @@ path_validation(TrustedCert, Path, ServerName, Role, CertDbHandle, CertDbRef, CR
                 #{cert_ext := CertExt,
                   ocsp_responder_certs := OcspResponderCerts,
                   ocsp_state := OcspState}) ->
-    ValidationFunAndState = 
-        ssl_handshake:validation_fun_and_state(VerifyFun, #{role => Role,
-                                                            certdb => CertDbHandle,
-                                                            certdb_ref => CertDbRef,
-                                                            server_name => ServerName,
-                                                            customize_hostname_check =>
-                                                                CustomizeHostnameCheck,
-                                                            crl_check => CrlCheck,
-                                                            crl_db => CRLDbHandle,
-                                                            signature_algs => filter_tls13_algs(SignAlgos),
-                                                            signature_algs_cert => 
-                                                                filter_tls13_algs(SignAlgosCert),
-                                                            version => Version,
-                                                            issuer => TrustedCert,
-                                                            cert_ext => CertExt,
-                                                            ocsp_responder_certs => OcspResponderCerts,
-                                                            ocsp_state => OcspState
-                                                           }, 
+    ValidationFunAndState =
+        ssl_handshake:validation_fun_and_state(VerifyFun,
+                                               #{role => Role,
+                                                 certdb => CertDbHandle,
+                                                 certdb_ref => CertDbRef,
+                                                 server_name => ServerName,
+                                                 customize_hostname_check =>
+                                                     CustomizeHostnameCheck,
+                                                 crl_check => CrlCheck,
+                                                 crl_db => CRLDbHandle,
+                                                 signature_algs => filter_tls13_algs(SignAlgos),
+                                                 signature_algs_cert =>
+                                                     filter_tls13_algs(SignAlgosCert),
+                                                 version => Version,
+                                                 issuer => TrustedCert,
+                                                 cert_ext => CertExt,
+                                                 ocsp_responder_certs => OcspResponderCerts,
+                                                 ocsp_state => OcspState,
+                                                 path_len => length(Path)
+                                                },
                                                Path, LogLevel),
     Options = [{max_path_length, Depth},
                {verify_fun, ValidationFunAndState}],
-- 
2.35.3

openSUSE Build Service is sponsored by