From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from gate001.proxmox.com (gate001.proxmox.com [45.144.208.40]) by lore.proxmox.com (Postfix) with ESMTPS id ADD891FF129 for ; Thu, 06 Aug 2026 17:02:27 +0200 (CEST) Received: from gate001.proxmox.com (localhost.localdomain [127.0.0.1]) by gate001.proxmox.com (Proxmox) with ESMTP id 2CD892153B; Thu, 06 Aug 2026 17:02:27 +0200 (CEST) Date: Thu, 06 Aug 2026 17:02:19 +0200 From: Fabian =?iso-8859-1?q?Gr=FCnbichler?= Subject: Re: [PATCH pve-common v2 02/16] certificate: add helper to verify that a certificate was signed by a ca To: pdm-devel@lists.proxmox.com, Shannon Sterz References: <20260805131838.254723-2-s.sterz@proxmox.com> <20260805131838.254723-4-s.sterz@proxmox.com> In-Reply-To: <20260805131838.254723-4-s.sterz@proxmox.com> MIME-Version: 1.0 User-Agent: astroid/0.17.0 (https://github.com/astroidmail/astroid) Message-Id: <1786028130.jqm5u0q9cj.astroid@yuna.none> Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Bm-Milter-Handled: 55990f41-d878-4baa-be0a-ee34c49e34d2 X-Bm-Transport-Timestamp: 1786028527829 X-SPAM-LEVEL: Spam detection results: 0 AWL 0.098 Adjusted score from AWL reputation of From: address DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment (newer systems) RCVD_IN_DNSWL_LOW -0.7 Sender listed at https://www.dnswl.org/, low trust SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record Message-ID-Hash: CMWB64QRW4AQ4RKJPN7DI6UAEJCH7QTY X-Message-ID-Hash: CMWB64QRW4AQ4RKJPN7DI6UAEJCH7QTY X-MailFrom: f.gruenbichler@proxmox.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.10 Precedence: list List-Id: Proxmox Datacenter Manager development discussion List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: On August 5, 2026 3:18 pm, Shannon Sterz wrote: > Signed-off-by: Shannon Sterz > --- > src/PVE/Certificate.pm | 46 ++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 46 insertions(+) >=20 > diff --git a/src/PVE/Certificate.pm b/src/PVE/Certificate.pm > index b8415e2..91b3c4d 100644 > --- a/src/PVE/Certificate.pm > +++ b/src/PVE/Certificate.pm > @@ -260,6 +260,52 @@ sub assert_certificate_matches_key { > return 1; > } > =20 > +=3Dhead3 check_certificate_signed_by_ca() > + > +Checks whether the certificate at C<$cert_path> is signed by the CA cert= ificate > +located at C<$ca_path>. > + > +=3Dcut > + > +sub check_certificate_signed_by_ca { > + my ($cert_path, $ca_path) =3D @_; > + my @cleanup; > + > + my $result =3D eval { > + my $ca_cert =3D $read_certificate->($ca_path); > + push @cleanup, sub { Net::SSLeay::X509_free($ca_cert) }; > + > + my $cert =3D $read_certificate->($cert_path); > + push @cleanup, sub { Net::SSLeay::X509_free($cert) }; > + > + my $store =3D Net::SSLeay::X509_STORE_new() > + or ssl_die("Could not create an SSL store to check if ca sig= ned certificate"); > + push @cleanup, sub { Net::SSLeay::X509_STORE_free($store) }; > + > + Net::SSLeay::X509_STORE_add_cert($store, $ca_cert) > + or ssl_die("Could not load ca certificate into context."); > + > + my $ctx =3D Net::SSLeay::X509_STORE_CTX_new() > + or ssl_die("Could not create an SSL context to check if ca s= igned certificate"); > + push @cleanup, sub { Net::SSLeay::X509_STORE_CTX_free($ctx) }; > + > + Net::SSLeay::X509_STORE_CTX_init($ctx, $store, $cert, 0) > + or ssl_die("Could not initialize an SSL context to check if = ca signed certificate"); > + > + Net::SSLeay::X509_verify_cert($ctx); doesn't this check more then implied by the sub's name? e.g., if the certificate is expired, this will return false if we just want to check the signature, we should probably just check the signature? but - as discussed off-list - I think this whole module and parts of PVE::Cluster::Setup are prime candidates for being moved into the proposed proxmox-tls-certificates crate and perlmod-ified. > + }; > + > + my $err =3D $@; > + > + while (my $cleanup_fn =3D pop @cleanup) { > + $cleanup_fn->(); > + } > + > + die $err if $err; > + > + return $result =3D=3D 1; > +} > + > sub get_certificate_info { > my ($cert_path) =3D @_; > =20 > --=20 > 2.47.3 >=20 >=20 >=20 >=20 >=20 >=20