From 51369e3955cdc5bf3f1ba0f6e2d7c4d73406c111 Mon Sep 17 00:00:00 2001 From: Guilhem Moulin Date: Wed, 25 Nov 2020 19:58:13 +0100 Subject: Use upstream certicate chain instead of an hardcoded one. This is a breaking change. The certificate indicated by 'CAfile' is no longer used as is in 'certificate-chain' (along with the leaf cert). The chain returned by the ACME v2 endpoint is used instead. This allows for more flexbility with respect to key/CA rotation, cf. https://letsencrypt.org/2020/11/06/own-two-feet.html and https://community.letsencrypt.org/t/beginning-issuance-from-r3/139018 Moreover 'CAfile' now defaults to @@datadir@@/lacme/ca-certificates.crt which is a concatenation of all known active CA certificates (which includes the previous default). --- lacme | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) (limited to 'lacme') diff --git a/lacme b/lacme index 1ca4a38..07ebb45 100755 --- a/lacme +++ b/lacme @@ -584,12 +584,10 @@ sub spawn($@) { ############################################################################# -# Install the certificate +# Install the certificate (optionally excluding the chain of trust) # sub install_cert($$;$) { - my $filename = shift; - my $x509 = shift; - my @chain = grep !/\A\s*\z/, @_; # ignore empty CAfile + my ($filename, $chain, $leafonly) = @_; my ($dirname, $basename) = $filename =~ /\A(.*)\/([^\/]+)\z/ ? ($1, $2) : ('.', $filename); @@ -599,12 +597,23 @@ sub install_cert($$;$) { eval { my $umask = umask() // die "umask: $!"; chmod(0644 &~ $umask, $fh) or die "chmod: $!"; - $fh->print($x509) or die "Can't print: $!"; - foreach (@chain) { # append the chain - open my $fh2, '<', $_ or die "Can't open $_: $!"; - my $ca = do { local $/ = undef; $fh2->getline() }; - $fh2->close() or die "Can't close: $!"; - $fh->print($ca) or die "Can't print: $!"; + if ($leafonly) { + # keep only the leaf certificate + pipe my $rd, my $wd or die "Can't pipe: $!"; + my $pid = fork // die "Can't fork: $!"; + unless ($pid) { + open STDIN, '<&', $rd or die "Can't dup: $!"; + open STDOUT, '>&', $fh or die "Can't dup: $!"; + exec qw/openssl x509 -outform PEM/ or die; + } + $rd->close() or die "Can't close: $!"; + $wd->print($chain); + $wd->close() or die "Can't close: $!"; + + waitpid $pid => 0; + die $? if $? > 0; + } else { + $fh->print($chain) or die "Can't print: $!"; } $fh->close() or die "Can't close: $!"; }; @@ -743,7 +752,7 @@ elsif ($COMMAND eq 'newOrder' or $COMMAND eq 'new-cert') { }; # verify certificate validity against the CA - $conf->{CAfile} //= '@@datadir@@/lacme/lets-encrypt-x3-cross-signed.pem'; + $conf->{CAfile} //= '@@datadir@@/lacme/ca-certificates.crt'; if ($conf->{CAfile} ne '' and spawn({in => $x509}, 'openssl', 'verify', '-CAfile', $conf->{CAfile}, qw/-purpose sslserver -x509_strict/)) { print STDERR "[$s] Error: Received invalid X.509 certificate from ACME server!\n"; @@ -754,11 +763,11 @@ elsif ($COMMAND eq 'newOrder' or $COMMAND eq 'new-cert') { # install certificate if (defined $conf->{'certificate'}) { print STDERR "Installing X.509 certificate $conf->{'certificate'}\n"; - install_cert($conf->{'certificate'}, $x509); + install_cert($conf->{'certificate'}, $x509, 1); } if (defined $conf->{'certificate-chain'}) { print STDERR "Installing X.509 certificate chain $conf->{'certificate-chain'}\n"; - install_cert($conf->{'certificate-chain'}, $x509, $conf->{CAfile}); + install_cert($conf->{'certificate-chain'}, $x509); } if (defined $conf->{chown}) { -- cgit v1.2.3