]> git.proxmox.com Git - pve-apiclient.git/commitdiff
cert verification: trust openssl result if hostnames are verified
authorThomas Lamprecht <t.lamprecht@proxmox.com>
Thu, 3 Dec 2020 15:00:00 +0000 (16:00 +0100)
committerThomas Lamprecht <t.lamprecht@proxmox.com>
Thu, 3 Dec 2020 15:06:33 +0000 (16:06 +0100)
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 <t.lamprecht@proxmox.com>
PVE/APIClient/LWP.pm

index b16be3fc25217a115fc2fe65953d171c66133534..998c15de8b6d9412722c2a58f736fdc77cb874b3 100755 (executable)
@@ -303,6 +303,10 @@ sub new {
     my $ssl_default_opts = { verify_hostname => 0 };
     my $ssl_opts = $param{ssl_opts} || $ssl_default_opts;
 
     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},
     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 $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;
 
 
            # 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);
        }
     }
            return verify_cert_callback($fingerprints, $cert, $verify_fingerprint_cb);
        }
     }