From 6c8c78d01ab449ba30a1f93d967f155482702c35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Gr=C3=BCnbichler?= Date: Tue, 26 Mar 2024 09:15:02 +0100 Subject: [PATCH] fix validation of self-signed cert chains MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The interface here is a bit weird - if the verify callback returns 1 for a certificate higher up in the chain, this will propagate to the next invocation of the callback for the next certificate, even if openssl on its own would not trust the certificate. By re-ordering the checks and keeping track of the fact that we returned 1 despite openssl failing its own validation, the validation logic should now cover all combinations of certificate count and self-signed/system trust status. Signed-off-by: Fabian Grünbichler --- src/PVE/APIClient/LWP.pm | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/PVE/APIClient/LWP.pm b/src/PVE/APIClient/LWP.pm index 722b35a..f753109 100755 --- a/src/PVE/APIClient/LWP.pm +++ b/src/PVE/APIClient/LWP.pm @@ -415,11 +415,18 @@ sub new { $ssl_opts->{'SSL_verify_callback'} = sub { my ($openssl_valid, undef, undef, undef, $cert, $depth) = @_; - # we don't care about intermediate or root certificates - return 1 if $depth != 0; - return 1 if $trust_openssl && $openssl_valid; + # Openssl encountered validation error, only allow validation to + # pass if fingerprint is verified + $trust_openssl = 0; + + # We don't care about intermediate or root certificates if we don't + # trust openssl's validation result + return 1 if $depth != 0; + + # We've reached the leaf certificate and the chain didn't pass + # openssl's validation - let's verify the fingerprint! return verify_cert_callback($fingerprints, $cert, $verify_fingerprint_cb); } }