From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by lists.proxmox.com (Postfix) with ESMTPS id B2FA573A2C for ; Fri, 8 Oct 2021 10:52:42 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id B0B4D23FC2 for ; Fri, 8 Oct 2021 10:52:42 +0200 (CEST) Received: from proxmox-new.maurer-it.com (proxmox-new.maurer-it.com [94.136.29.106]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by firstgate.proxmox.com (Proxmox) with ESMTPS id EE70C23FFC for ; Fri, 8 Oct 2021 10:52:41 +0200 (CEST) Received: from proxmox-new.maurer-it.com (localhost.localdomain [127.0.0.1]) by proxmox-new.maurer-it.com (Proxmox) with ESMTP id C38584595F for ; Fri, 8 Oct 2021 10:52:41 +0200 (CEST) Date: Fri, 8 Oct 2021 10:52:40 +0200 From: Stoiko Ivanov To: Fabian =?UTF-8?B?R3LDvG5iaWNobGVy?= Cc: Proxmox VE development discussion Message-ID: <20211008105240.73c22613@rosa.proxmox.com> In-Reply-To: <20211008081821.3499530-1-f.gruenbichler@proxmox.com> References: <20211008081821.3499530-1-f.gruenbichler@proxmox.com> X-Mailer: Claws Mail 3.17.8 (GTK+ 2.24.33; x86_64-pc-linux-gnu) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable X-SPAM-LEVEL: Spam detection results: 0 AWL 0.379 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record URIBL_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to URIBL was blocked. See http://wiki.apache.org/spamassassin/DnsBlocklists#dnsbl-block for more information. [acme.pm] Subject: Re: [pve-devel] [PATCH v2 proxmox-acme] support downloading alternate chains X-BeenThere: pve-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox VE development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 08 Oct 2021 08:52:42 -0000 Tested again against LE production endpoint - LGTM :) Thanks! Reviewed-By: Stoiko Ivanov Tested-By: Stoiko Ivanov On Fri, 8 Oct 2021 10:18:21 +0200 Fabian Gr=C3=BCnbichler wrote: > the current default chains end with an expired root certificate for > maximum compatibility with old Android versions. this breaks some other > older clients (openssl, gnutls) which don't expect chains to contain any > expired certificates, even if they are 'above' the trust anchor. >=20 > by setting $root, it is possible to specify which root the ACME provided > certificate chain should end with, downloading alternate chains as > necessary. >=20 > Signed-off-by: Fabian Gr=C3=BCnbichler > --- >=20 > Notes: > v2:=20 > - only check issuer > - also check default chain > - add 'i' to RE check >=20 > only tested with pebble >=20 > src/PVE/ACME.pm | 35 ++++++++++++++++++++++++++++++++++- > 1 file changed, 34 insertions(+), 1 deletion(-) >=20 > diff --git a/src/PVE/ACME.pm b/src/PVE/ACME.pm > index 265482d..57578d7 100644 > --- a/src/PVE/ACME.pm > +++ b/src/PVE/ACME.pm > @@ -442,17 +442,50 @@ sub deactivate_authorization { > =20 > # Get certificate > # GET-as-POST to order's certificate URL > +# if $root is specified, attempts to find a matching (alternate) chain > # Expects a '200 OK' reply > # returns certificate chain in PEM format > sub get_certificate { > - my ($self, $order) =3D @_; > + my ($self, $order, $root) =3D @_; > =20 > $self->fatal("no certificate URL available (yet?)", $order) > if !$order->{certificate}; > =20 > + my $check_root =3D sub { > + my ($chain) =3D @_; > + > + my @certs =3D PVE::Certificate::split_pem($chain); > + my $root_pem =3D $certs[-1]; > + > + my ($file, $fh) =3D PVE::Tools::tempfile_contents($root_pem); > + my $info =3D PVE::Certificate::get_certificate_info($file); > + > + return defined($info->{issuer}) && $info->{issuer} =3D~ m/\Q$root\E/i; > + }; > + > my $r =3D $self->do(POST =3D> $order->{certificate}, ''); > my $return =3D eval { > + # default chain > my $res =3D __get_result($r, 200, 1); > + if ($root && !$check_root->($res)) { > + # alternate chains if requested and default didn't match > + $res =3D undef; > + my @links =3D $r->header('link'); > + for my $link (@links) { > + if ($link =3D~ /^<(.*)>;rel=3D"alternate"$/) { > + my $url =3D $1; > + my $chain =3D eval { __get_result($self->do(POST =3D> $url, ''), 2= 00, 1); }; > + die "failed to retrieve alternate chain from '$url' - $@\n" if $@; > + if ($check_root->($chain)) { > + $res =3D $chain; > + last; > + } > + } > + } > + die "no matching alternate chain for '$root' returned by server\n" > + if !defined($res); > + } > + > if ($res =3D~ /^(-----BEGIN CERTIFICATE-----)(.+)(-----END CERTIFICATE-= ----)$/s) { # untaint > return $1 . $2 . $3; > }