File 1330-public_key-Add-check-for-duplicate-certificates.patch of Package erlang

From 5ece05987cb5c8ca95d3d5b610f99f37584805fc Mon Sep 17 00:00:00 2001
From: Ingela Anderton Andin <ingela@erlang.org>
Date: Wed, 16 Aug 2023 15:02:48 +0200
Subject: [PATCH] public_key: Add check for duplicate certificates

Closes #6394
---
 lib/public_key/src/public_key.erl        | 23 +++++++++++++++++++++--
 lib/public_key/test/public_key_SUITE.erl |  6 +++++-
 2 files changed, 26 insertions(+), 3 deletions(-)

diff --git a/lib/public_key/src/public_key.erl b/lib/public_key/src/public_key.erl
index 8c3805c219..33b404089a 100644
--- a/lib/public_key/src/public_key.erl
+++ b/lib/public_key/src/public_key.erl
@@ -1161,7 +1161,12 @@ pkix_path_validation(#'OTPCertificate'{} = TrustedCert, CertChain, Options)
                                                                 MaxPathDefault, 
                                                                 [{verify_fun, {VerifyFun, UserState1}} | 
                                                                  proplists:delete(verify_fun, Options)]),
-            path_validation(CertChain, ValidationState)
+            case exists_duplicate_cert(CertChain) of
+                true ->
+                    {error, {bad_cert, duplicate_cert_in_path}};
+                false ->
+                    path_validation(CertChain, ValidationState)
+            end
     catch
         throw:{bad_cert, _} = Result ->
             {error, Result}
@@ -1553,6 +1558,20 @@ do_pem_entry_decode({Asn1Type,_, _} = PemEntry, Password) ->
     Der = pubkey_pem:decipher(PemEntry, Password),
     der_decode(Asn1Type, Der).
 
+%% The only way a path with duplicates could be somehow wrongly
+%% passed is if the certs are located together and also are
+%% self-signed. This is what we need to possible protect against. We
+%% only check for togetherness here as it helps with the case not
+%% otherwise caught. It can result in a different error message for
+%% cases already failing before but that is not important, the
+%% important thing is that it will be rejected.
+exists_duplicate_cert([]) ->
+    false;
+exists_duplicate_cert([Cert, Cert | _]) ->
+    true;
+exists_duplicate_cert([_ | Rest]) ->
+    exists_duplicate_cert(Rest).
+
 path_validation([], #path_validation_state{working_public_key_algorithm
 					   = Algorithm,
 					   working_public_key =
diff --git a/lib/public_key/test/public_key_SUITE.erl b/lib/public_key/test/public_key_SUITE.erl
index 1a779e03bd..c5fef5b885 100644
--- a/lib/public_key/test/public_key_SUITE.erl
+++ b/lib/public_key/test/public_key_SUITE.erl
@@ -836,8 +836,12 @@ pkix_path_validation(Config) when is_list(Config) ->
     
     {error, {bad_cert,invalid_issuer}} = 
 	public_key:pkix_path_validation(Trusted, [Cert2], []),
-    
+   
     {ok, _} = public_key:pkix_path_validation(Trusted, [Cert1, Cert2], []),    
+
+    {error, {bad_cert, duplicate_cert_in_path}} =
+	public_key:pkix_path_validation(Trusted, [Cert1, Cert1, Cert2], []),
+
     {error, issuer_not_found} = public_key:pkix_issuer_id(Cert2, other),
 
     CertK3 = {Cert3,_}  = erl_make_certs:make_cert([{issuer, CertK1}, 
-- 
2.35.3

openSUSE Build Service is sponsored by