From a1298cc2a5d5eb3586efaaf4bad25e17eedf4295 Mon Sep 17 00:00:00 2001 From: Thomas Lamprecht Date: Thu, 3 Dec 2020 16:00:00 +0100 Subject: [PATCH] cert verification: trust openssl result if hostnames are verified If we verified that the hostname matches the cert we can also trust the openssl verification result. We get the openssl result as first parameter[0]. [0]: https://metacpan.org/pod/IO::Socket::SSL#SSL_verify_callback Signed-off-by: Thomas Lamprecht --- PVE/APIClient/LWP.pm | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/PVE/APIClient/LWP.pm b/PVE/APIClient/LWP.pm index b16be3f..998c15d 100755 --- a/PVE/APIClient/LWP.pm +++ b/PVE/APIClient/LWP.pm @@ -303,6 +303,10 @@ sub new { my $ssl_default_opts = { verify_hostname => 0 }; my $ssl_opts = $param{ssl_opts} || $ssl_default_opts; + # we can only really trust openssl result if it also verifies the hostname, + # else it's easy to intercept (MITM using valid Lets Encrypt) + my $trust_openssl = $ssl_opts->{verify_hostname} ? 1 : 0; + my $self = { username => $param{username}, password => $param{password}, @@ -326,11 +330,13 @@ sub new { my $fingerprints = $self->{fingerprint}; # avoid passing $self, that's a RC cycle! my $verify_fingerprint_cb = $param{verify_fingerprint_cb}; $ssl_opts->{'SSL_verify_callback'} = sub { - my (undef, undef, undef, undef, $cert, $depth) = @_; + 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; + return verify_cert_callback($fingerprints, $cert, $verify_fingerprint_cb); } }