[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#975870: marked as done (buster-pu: package lacme/0.5-1+deb10u1)



Your message dated Sat, 05 Dec 2020 11:02:00 +0000
with message-id <b70f86aac27195271a9b5212c7acc936da6ff100.camel@adam-barratt.org.uk>
and subject line Closing bugs for updates in 10.7 point release
has caused the Debian Bug report #975870,
regarding buster-pu: package lacme/0.5-1+deb10u1
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact owner@bugs.debian.org
immediately.)


-- 
975870: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=975870
Debian Bug Tracking System
Contact owner@bugs.debian.org with problems
--- Begin Message ---
Package: release.debian.org
Severity: normal
Tags: buster
User: release.debian.org@packages.debian.org
Usertags: pu

Dear release team,

[ Reason ]

#975862: Two upcoming changes in the Let's Encrypt chain of trust
severely impact lacme and will break all issuance once they're rolled
out in December / January.

 1. The current issuer CA, namely “Let's Encrypt Authority X3”, which
    expires on 2021-03-17, will be phased out in December and
    progressively replaced with “Let's Encrypt Authority R3”.
    https://community.letsencrypt.org/t/beginning-issuance-from-r3/139018
 2. The current trust root, namely “IdenTrust DST Root CA X3”, which
    expires on 2021-09-30, will be replaced with ”ISRG Root X1” on
    January 11 next year.
    https://letsencrypt.org/2020/11/06/own-two-feet.html

[ Impact ]
Once Let's Encrypt roll out their change users won't be able to request /
renew certificates.

[ Tests ]
Tested against the Let's Encrypt staging API, with and without chain, as
well as manual certificate renewal in production.  The new root and
intermediate certificates have not been tested yet though, as Let's
Encrypt hasn't not rolled out the change yet (but will before Debian
10.8 is released).

[ Risks ]
The code is rather simple, instead of manually assembling the chain
using the leaf cert and CAfile we preserve the the chain received (per
RFC8555 7.4.2, unfortunately published after the Buster freeze) and only
use CAfile for trust validation before deploying the certificate.

The only alternative I could think of is to simply change the default
CAfile to https://letsencrypt.org/certs/lets-encrypt-r3.txt once Let's
Encrypt have finalized the transition.  But that means we'd have two
months or so during which certificate requests and renewals would fail.

[ Checklist ]
  [x] *all* changes are documented in the d/changelog
  [x] I reviewed all changes and I approve them
  [x] attach debdiff against the package in stable
  [x] the issue is verified as fixed in unstable

[ Changes ]

Unfortunately the fix isn't simply uploading a new package with the new
certificates, as Let's Encrypt will roll the changes progressively and
thus cause a period of up to two months were all certificate issuance /
renewal using lacme would fail.

Instead, the change is two fold:

 * Use the CA chain provided by the ACME v2 endpoint instead of bundling
   our own and hardcoding a possibly obsolete intermediate certificate
 
 * The CAfile option (now only used for verification, not for building
   the chain) points to bundle containing all currently active Let's
   Encrypt certificates (incl. the previous default).  This extends the
   scope of validation function and allows the issuer to smoothly
   transition between intermediate CAs.

[ Other info ]

0.2-1 from oldstable is affected too, however that version doesn't
support ACME v2 which is required for the smooth transition.

I attach the debdiff against 0.5-1+deb10u1 as well as the output of
`diff -ru` to emphasize the code/documentation change an not the
certificate rotation.

Cheers,
-- 
Guilhem.
diffstat for lacme-0.5 lacme-0.5

 changelog                                                               |   23 
 lacme.install                                                           |    3 
 patches/0003-Use-upstream-certicate-chain-instead-of-an-hardcoded.patch |  479 ++++++++++
 patches/series                                                          |    1 
 4 files changed, 505 insertions(+), 1 deletion(-)

diff -Nru lacme-0.5/debian/changelog lacme-0.5/debian/changelog
--- lacme-0.5/debian/changelog	2019-08-22 00:14:42.000000000 +0200
+++ lacme-0.5/debian/changelog	2020-11-26 01:14:50.000000000 +0100
@@ -1,3 +1,26 @@
+lacme (0.5-1+deb10u2) buster; urgency=medium
+
+  * Use upstream certificate 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
+  * Additional current/planned CA certificates can be found under
+    /usr/local/share/lacme:
+      - lets-encrypt-e[12].pem
+      - lets-encrypt-r[34]-cross-signed.pem
+      - lets-encrypt-r[34].pem
+      - letsencryptauthorityx[34].pem
+    See https://letsencrypt.org/certificates/
+  * Moreover 'CAfile' now defaults to /usr/share/lacme/ca-certificates.crt
+    which is a concatenation of all known active CA certificates (which
+    includes the previous default).
+    Closes: #975862.
+
+ -- Guilhem Moulin <guilhem@debian.org>  Thu, 26 Nov 2020 01:14:50 +0100
+
 lacme (0.5-1+deb10u1) buster; urgency=medium
 
   * Link to RFC 8555 <https://tools.ietf.org/html/rfc8555> instead of the
diff -Nru lacme-0.5/debian/lacme.install lacme-0.5/debian/lacme.install
--- lacme-0.5/debian/lacme.install	2019-08-22 00:14:42.000000000 +0200
+++ lacme-0.5/debian/lacme.install	2020-11-26 01:14:50.000000000 +0100
@@ -1,4 +1,5 @@
-certs/lets-encrypt-x[1-4]-cross-signed.pem /usr/share/lacme
+certs/*.pem                                /usr/share/lacme
+/usr/share/lacme/ca-certificates.crt
 client webserver                           /usr/lib/lacme
 config/lacme-certs.conf config/lacme.conf  /etc/lacme
 lacme                                      /usr/sbin
diff -Nru lacme-0.5/debian/patches/0003-Use-upstream-certicate-chain-instead-of-an-hardcoded.patch lacme-0.5/debian/patches/0003-Use-upstream-certicate-chain-instead-of-an-hardcoded.patch
--- lacme-0.5/debian/patches/0003-Use-upstream-certicate-chain-instead-of-an-hardcoded.patch	1970-01-01 01:00:00.000000000 +0100
+++ lacme-0.5/debian/patches/0003-Use-upstream-certicate-chain-instead-of-an-hardcoded.patch	2020-11-26 01:14:50.000000000 +0100
@@ -0,0 +1,479 @@
+From d3c9435c4f43167b9d5c9315044f50b8878a2881 Mon Sep 17 00:00:00 2001
+From: Guilhem Moulin <guilhem@fripost.org>
+Date: Thu, 26 Nov 2020 01:10:38 +0100
+Subject: Use upstream certificate 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).
+---
+ Makefile                               |  9 ++++++-
+ certs/lets-encrypt-e1.pem              | 17 +++++++++++++
+ certs/lets-encrypt-e2.pem              | 17 +++++++++++++
+ certs/lets-encrypt-r3-cross-signed.pem | 26 +++++++++++++++++++
+ certs/lets-encrypt-r3.pem              | 30 ++++++++++++++++++++++
+ certs/lets-encrypt-r4-cross-signed.pem | 26 +++++++++++++++++++
+ certs/lets-encrypt-r4.pem              | 30 ++++++++++++++++++++++
+ certs/letsencryptauthorityx3.pem       | 32 +++++++++++++++++++++++
+ certs/letsencryptauthorityx4.pem       | 32 +++++++++++++++++++++++
+ client                                 | 15 +----------
+ config/lacme-certs.conf                | 11 ++++----
+ lacme                                  | 35 ++++++++++++++++----------
+ lacme.md                               | 13 ++++------
+ 13 files changed, 251 insertions(+), 42 deletions(-)
+ create mode 100644 certs/lets-encrypt-e1.pem
+ create mode 100644 certs/lets-encrypt-e2.pem
+ create mode 100644 certs/lets-encrypt-r3-cross-signed.pem
+ create mode 100644 certs/lets-encrypt-r3.pem
+ create mode 100644 certs/lets-encrypt-r4-cross-signed.pem
+ create mode 100644 certs/lets-encrypt-r4.pem
+ create mode 100644 certs/letsencryptauthorityx3.pem
+ create mode 100644 certs/letsencryptauthorityx4.pem
+
+diff --git a/Makefile b/Makefile
+index 5d421bf..99ce749 100644
+--- a/Makefile
++++ b/Makefile
+@@ -37,7 +37,14 @@ install: ${MANPAGES}
+ 	install -m0644 -t $(DESTDIR)/etc/lacme config/*.conf
+ 	install -m0644 -t $(DESTDIR)/etc/lacme snippets/*.conf
+ 	install -d $(DESTDIR)/usr/share/lacme
+-	install -m0644 -t $(DESTDIR)/usr/share/lacme certs/lets-encrypt-x[1-4]-cross-signed.pem
++	install -m0644 -t $(DESTDIR)/usr/share/lacme certs/*
++	# used for validation, see https://letsencrypt.org/certificates/
++	cat certs/letsencryptauthorityx[34].pem \
++        certs/lets-encrypt-x[34]-cross-signed.pem \
++        certs/lets-encrypt-r[34].pem \
++        certs/lets-encrypt-r[34]-cross-signed.pem \
++        certs/lets-encrypt-e[12].pem \
++		>$(DESTDIR)/usr/share/lacme/ca-certificates.crt
+ 	install -d $(DESTDIR)/usr/lib/lacme
+ 	install -m0755 -t $(DESTDIR)/usr/lib/lacme client webserver
+ 	install -d $(DESTDIR)/usr/share/man/man1
+diff --git a/certs/lets-encrypt-e1.pem b/certs/lets-encrypt-e1.pem
+new file mode 100644
+index 0000000..2a19d41
+--- /dev/null
++++ b/certs/lets-encrypt-e1.pem
+@@ -0,0 +1,17 @@
++-----BEGIN CERTIFICATE-----
++MIICxjCCAk2gAwIBAgIRALO93/inhFu86QOgQTWzSkUwCgYIKoZIzj0EAwMwTzEL
++MAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2VhcmNo
++IEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDIwHhcNMjAwOTA0MDAwMDAwWhcN
++MjUwOTE1MTYwMDAwWjAyMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNTGV0J3MgRW5j
++cnlwdDELMAkGA1UEAxMCRTEwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQkXC2iKv0c
++S6Zdl3MnMayyoGli72XoprDwrEuf/xwLcA/TmC9N/A8AmzfwdAVXMpcuBe8qQyWj
+++240JxP2T35p0wKZXuskR5LBJJvmsSGPwSSB/GjMH2m6WPUZIvd0xhajggEIMIIB
++BDAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMB
++MBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFFrz7Sv8NsI3eblSMOpUb89V
++yy6sMB8GA1UdIwQYMBaAFHxClq7eS0g7+pL4nozPbYupcjeVMDIGCCsGAQUFBwEB
++BCYwJDAiBggrBgEFBQcwAoYWaHR0cDovL3gyLmkubGVuY3Iub3JnLzAnBgNVHR8E
++IDAeMBygGqAYhhZodHRwOi8veDIuYy5sZW5jci5vcmcvMCIGA1UdIAQbMBkwCAYG
++Z4EMAQIBMA0GCysGAQQBgt8TAQEBMAoGCCqGSM49BAMDA2cAMGQCMHt01VITjWH+
++Dbo/AwCd89eYhNlXLr3pD5xcSAQh8suzYHKOl9YST8pE9kLJ03uGqQIwWrGxtO3q
++YJkgsTgDyj2gJrjubi1K9sZmHzOa25JK1fUpE8ZwYii6I4zPPS/Lgul/
++-----END CERTIFICATE-----
+diff --git a/certs/lets-encrypt-e2.pem b/certs/lets-encrypt-e2.pem
+new file mode 100644
+index 0000000..0fd9f40
+--- /dev/null
++++ b/certs/lets-encrypt-e2.pem
+@@ -0,0 +1,17 @@
++-----BEGIN CERTIFICATE-----
++MIICxjCCAkygAwIBAgIQTtI99q9+x/mwxHJv+VEqdzAKBggqhkjOPQQDAzBPMQsw
++CQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJuZXQgU2VjdXJpdHkgUmVzZWFyY2gg
++R3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBYMjAeFw0yMDA5MDQwMDAwMDBaFw0y
++NTA5MTUxNjAwMDBaMDIxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNy
++eXB0MQswCQYDVQQDEwJFMjB2MBAGByqGSM49AgEGBSuBBAAiA2IABCOaLO3lixmN
++YVWex+ZVYOiTLgi0SgNWtU4hufk50VU4Zp/LbBVDxCsnsI7vuf4xp4Cu+ETNggGE
++yBqJ3j8iUwe5Yt/qfSrRf1/D5R58duaJ+IvLRXeASRqEL+VkDXrW3qOCAQgwggEE
++MA4GA1UdDwEB/wQEAwIBhjAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEw
++EgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUbZkq9U0C6+MRwWC6km+NPS7x
++6kQwHwYDVR0jBBgwFoAUfEKWrt5LSDv6kviejM9ti6lyN5UwMgYIKwYBBQUHAQEE
++JjAkMCIGCCsGAQUFBzAChhZodHRwOi8veDIuaS5sZW5jci5vcmcvMCcGA1UdHwQg
++MB4wHKAaoBiGFmh0dHA6Ly94Mi5jLmxlbmNyLm9yZy8wIgYDVR0gBBswGTAIBgZn
++gQwBAgEwDQYLKwYBBAGC3xMBAQEwCgYIKoZIzj0EAwMDaAAwZQIxAPJCN9qpyDmZ
++tX8K3m8UYQvK51BrXclM6WfrdeZlUBKyhTXUmFAtJw4X6A0x9mQFPAIwJa/No+KQ
++UAM1u34E36neL/Zba7ombkIOchSgx1iVxzqtFWGddgoG+tppRPWhuhhn
++-----END CERTIFICATE-----
+diff --git a/certs/lets-encrypt-r3-cross-signed.pem b/certs/lets-encrypt-r3-cross-signed.pem
+new file mode 100644
+index 0000000..1d82449
+--- /dev/null
++++ b/certs/lets-encrypt-r3-cross-signed.pem
+@@ -0,0 +1,26 @@
++-----BEGIN CERTIFICATE-----
++MIIEZTCCA02gAwIBAgIQQAF1BIMUpMghjISpDBbN3zANBgkqhkiG9w0BAQsFADA/
++MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT
++DkRTVCBSb290IENBIFgzMB4XDTIwMTAwNzE5MjE0MFoXDTIxMDkyOTE5MjE0MFow
++MjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUxldCdzIEVuY3J5cHQxCzAJBgNVBAMT
++AlIzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuwIVKMz2oJTTDxLs
++jVWSw/iC8ZmmekKIp10mqrUrucVMsa+Oa/l1yKPXD0eUFFU1V4yeqKI5GfWCPEKp
++Tm71O8Mu243AsFzzWTjn7c9p8FoLG77AlCQlh/o3cbMT5xys4Zvv2+Q7RVJFlqnB
++U840yFLuta7tj95gcOKlVKu2bQ6XpUA0ayvTvGbrZjR8+muLj1cpmfgwF126cm/7
++gcWt0oZYPRfH5wm78Sv3htzB2nFd1EbjzK0lwYi8YGd1ZrPxGPeiXOZT/zqItkel
++/xMY6pgJdz+dU/nPAeX1pnAXFK9jpP+Zs5Od3FOnBv5IhR2haa4ldbsTzFID9e1R
++oYvbFQIDAQABo4IBaDCCAWQwEgYDVR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8E
++BAMCAYYwSwYIKwYBBQUHAQEEPzA9MDsGCCsGAQUFBzAChi9odHRwOi8vYXBwcy5p
++ZGVudHJ1c3QuY29tL3Jvb3RzL2RzdHJvb3RjYXgzLnA3YzAfBgNVHSMEGDAWgBTE
++p7Gkeyxx+tvhS5B1/8QVYIWJEDBUBgNVHSAETTBLMAgGBmeBDAECATA/BgsrBgEE
++AYLfEwEBATAwMC4GCCsGAQUFBwIBFiJodHRwOi8vY3BzLnJvb3QteDEubGV0c2Vu
++Y3J5cHQub3JnMDwGA1UdHwQ1MDMwMaAvoC2GK2h0dHA6Ly9jcmwuaWRlbnRydXN0
++LmNvbS9EU1RST09UQ0FYM0NSTC5jcmwwHQYDVR0OBBYEFBQusxe3WFbLrlAJQOYf
++r52LFMLGMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjANBgkqhkiG9w0B
++AQsFAAOCAQEA2UzgyfWEiDcx27sT4rP8i2tiEmxYt0l+PAK3qB8oYevO4C5z70kH
++ejWEHx2taPDY/laBL21/WKZuNTYQHHPD5b1tXgHXbnL7KqC401dk5VvCadTQsvd8
++S8MXjohyc9z9/G2948kLjmE6Flh9dDYrVYA9x2O+hEPGOaEOa1eePynBgPayvUfL
++qjBstzLhWVQLGAkXXmNs+5ZnPBxzDJOLxhF2JIbeQAcH5H0tZrUlo5ZYyOqA7s9p
++O5b85o3AM/OJ+CktFBQtfvBhcJVd9wvlwPsk+uyOy2HI7mNxKKgsBTt375teA2Tw
++UdHkhVNcsAKX1H7GNNLOEADksd86wuoXvg==
++-----END CERTIFICATE-----
+diff --git a/certs/lets-encrypt-r3.pem b/certs/lets-encrypt-r3.pem
+new file mode 100644
+index 0000000..43b222a
+--- /dev/null
++++ b/certs/lets-encrypt-r3.pem
+@@ -0,0 +1,30 @@
++-----BEGIN CERTIFICATE-----
++MIIFFjCCAv6gAwIBAgIRAJErCErPDBinU/bWLiWnX1owDQYJKoZIhvcNAQELBQAw
++TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
++cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMjAwOTA0MDAwMDAw
++WhcNMjUwOTE1MTYwMDAwWjAyMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNTGV0J3Mg
++RW5jcnlwdDELMAkGA1UEAxMCUjMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
++AoIBAQC7AhUozPaglNMPEuyNVZLD+ILxmaZ6QoinXSaqtSu5xUyxr45r+XXIo9cP
++R5QUVTVXjJ6oojkZ9YI8QqlObvU7wy7bjcCwXPNZOOftz2nwWgsbvsCUJCWH+jdx
++sxPnHKzhm+/b5DtFUkWWqcFTzjTIUu61ru2P3mBw4qVUq7ZtDpelQDRrK9O8Zutm
++NHz6a4uPVymZ+DAXXbpyb/uBxa3Shlg9F8fnCbvxK/eG3MHacV3URuPMrSXBiLxg
++Z3Vms/EY96Jc5lP/Ooi2R6X/ExjqmAl3P51T+c8B5fWmcBcUr2Ok/5mzk53cU6cG
++/kiFHaFpriV1uxPMUgP17VGhi9sVAgMBAAGjggEIMIIBBDAOBgNVHQ8BAf8EBAMC
++AYYwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMBMBIGA1UdEwEB/wQIMAYB
++Af8CAQAwHQYDVR0OBBYEFBQusxe3WFbLrlAJQOYfr52LFMLGMB8GA1UdIwQYMBaA
++FHm0WeZ7tuXkAXOACIjIGlj26ZtuMDIGCCsGAQUFBwEBBCYwJDAiBggrBgEFBQcw
++AoYWaHR0cDovL3gxLmkubGVuY3Iub3JnLzAnBgNVHR8EIDAeMBygGqAYhhZodHRw
++Oi8veDEuYy5sZW5jci5vcmcvMCIGA1UdIAQbMBkwCAYGZ4EMAQIBMA0GCysGAQQB
++gt8TAQEBMA0GCSqGSIb3DQEBCwUAA4ICAQCFyk5HPqP3hUSFvNVneLKYY611TR6W
++PTNlclQtgaDqw+34IL9fzLdwALduO/ZelN7kIJ+m74uyA+eitRY8kc607TkC53wl
++ikfmZW4/RvTZ8M6UK+5UzhK8jCdLuMGYL6KvzXGRSgi3yLgjewQtCPkIVz6D2QQz
++CkcheAmCJ8MqyJu5zlzyZMjAvnnAT45tRAxekrsu94sQ4egdRCnbWSDtY7kh+BIm
++lJNXoB1lBMEKIq4QDUOXoRgffuDghje1WrG9ML+Hbisq/yFOGwXD9RiX8F6sw6W4
++avAuvDszue5L3sz85K+EC4Y/wFVDNvZo4TYXao6Z0f+lQKc0t8DQYzk1OXVu8rp2
++yJMC6alLbBfODALZvYH7n7do1AZls4I9d1P4jnkDrQoxB3UqQ9hVl3LEKQ73xF1O
++yK5GhDDX8oVfGKF5u+decIsH4YaTw7mP3GFxJSqv3+0lUFJoi5Lc5da149p90Ids
++hCExroL1+7mryIkXPeFM5TgO9r0rvZaBFOvV2z0gp35Z0+L4WPlbuEjN/lxPFin+
++HlUjr8gRsI3qfJOQFy/9rKIJR0Y/8Omwt/8oTWgy1mdeHmmjk7j1nYsvC9JSQ6Zv
++MldlTTKB3zhThV1+XWYp6rjd5JW1zbVWEkLNxE7GJThEUG3szgBVGP7pSWTUTsqX
++nLRbwHOoq7hHwg==
++-----END CERTIFICATE-----
+diff --git a/certs/lets-encrypt-r4-cross-signed.pem b/certs/lets-encrypt-r4-cross-signed.pem
+new file mode 100644
+index 0000000..f0ed3cd
+--- /dev/null
++++ b/certs/lets-encrypt-r4-cross-signed.pem
+@@ -0,0 +1,26 @@
++-----BEGIN CERTIFICATE-----
++MIIEZTCCA02gAwIBAgIQQAF1BIMlO+Rkt3exI9CKgjANBgkqhkiG9w0BAQsFADA/
++MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT
++DkRTVCBSb290IENBIFgzMB4XDTIwMTAwNzE5MjE0NVoXDTIxMDkyOTE5MjE0NVow
++MjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUxldCdzIEVuY3J5cHQxCzAJBgNVBAMT
++AlI0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsyjcdynT55G+87cK
++AMf78lULJSJjUzav6Qgg3w2vKD7NxqtXtp2kJRml0jJtSaYIuccvoZuTxSBAa4Qx
++IKKOMGAlYO/ZGok/H2lxstrqP3NBxJBvZv19nljYd8/NWXVEyaEKe58/Gw46Zm+2
++dc+Ly6+dwHDF/9KCCq9dzeLonIWUpOYANeh+TjmBxyGJYHfqHZbyi4N7R8RtMsBS
++fiMeRbVx7qPvF8IDqZOJ3fWf27rx2uB+l4dxgR4aglbkPnwYogjlFl+o+qjgSFFN
++GBSgDKPltsqztVUSa3LHWn87jPnn2dGOEk0zMwMq8RPhQjzCLllgLm3gB0czZd/S
++Z8pNhQIDAQABo4IBaDCCAWQwEgYDVR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8E
++BAMCAYYwSwYIKwYBBQUHAQEEPzA9MDsGCCsGAQUFBzAChi9odHRwOi8vYXBwcy5p
++ZGVudHJ1c3QuY29tL3Jvb3RzL2RzdHJvb3RjYXgzLnA3YzAfBgNVHSMEGDAWgBTE
++p7Gkeyxx+tvhS5B1/8QVYIWJEDBUBgNVHSAETTBLMAgGBmeBDAECATA/BgsrBgEE
++AYLfEwEBATAwMC4GCCsGAQUFBwIBFiJodHRwOi8vY3BzLnJvb3QteDEubGV0c2Vu
++Y3J5cHQub3JnMDwGA1UdHwQ1MDMwMaAvoC2GK2h0dHA6Ly9jcmwuaWRlbnRydXN0
++LmNvbS9EU1RST09UQ0FYM0NSTC5jcmwwHQYDVR0OBBYEFDadPuCxQPYnLHy/jZ0x
++ivZUpkYmMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjANBgkqhkiG9w0B
++AQsFAAOCAQEAN4CpgPmK2C5pq/RdV9gEdWcvPnPfT9ToucrAMTcn//wyWBWF2wG4
++hvPBQxxuqPECZsi4nLQ45VJpyC1NDd0GqGQIMqNdC4N4TLDtd7Yhy8v5JsfEMUbb
++6xW4sKeeeKy3afOkel60Xg1/7ndSmppiHqdh+TdJML1hptRgdxGiB8LMpHuW/oM8
++akfyt4TkBhA8+Wu8MM6dlJyJ7nHBVnEUFQ4Ni+GzNC/pQSL2+Y9Mq4HHIk2ZFy0W
++B8KsVwdeNrERPL+LjhhLde1Et0aL9nlv4CqwXHML2LPgk38j/WllbQ/8HRd2VpB+
++JW6Z8JNhcnuBwATHMCeJVCFapoZsPfQQ6Q==
++-----END CERTIFICATE-----
+diff --git a/certs/lets-encrypt-r4.pem b/certs/lets-encrypt-r4.pem
+new file mode 100644
+index 0000000..578b3bd
+--- /dev/null
++++ b/certs/lets-encrypt-r4.pem
+@@ -0,0 +1,30 @@
++-----BEGIN CERTIFICATE-----
++MIIFFjCCAv6gAwIBAgIRAIp5IlCr5SxSbO7Pf8lC3WIwDQYJKoZIhvcNAQELBQAw
++TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
++cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMjAwOTA0MDAwMDAw
++WhcNMjUwOTE1MTYwMDAwWjAyMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNTGV0J3Mg
++RW5jcnlwdDELMAkGA1UEAxMCUjQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
++AoIBAQCzKNx3KdPnkb7ztwoAx/vyVQslImNTNq/pCCDfDa8oPs3Gq1e2naQlGaXS
++Mm1Jpgi5xy+hm5PFIEBrhDEgoo4wYCVg79kaiT8faXGy2uo/c0HEkG9m/X2eWNh3
++z81ZdUTJoQp7nz8bDjpmb7Z1z4vLr53AcMX/0oIKr13N4uichZSk5gA16H5OOYHH
++IYlgd+odlvKLg3tHxG0ywFJ+Ix5FtXHuo+8XwgOpk4nd9Z/buvHa4H6Xh3GBHhqC
++VuQ+fBiiCOUWX6j6qOBIUU0YFKAMo+W2yrO1VRJrcsdafzuM+efZ0Y4STTMzAyrx
++E+FCPMIuWWAubeAHRzNl39Jnyk2FAgMBAAGjggEIMIIBBDAOBgNVHQ8BAf8EBAMC
++AYYwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMBMBIGA1UdEwEB/wQIMAYB
++Af8CAQAwHQYDVR0OBBYEFDadPuCxQPYnLHy/jZ0xivZUpkYmMB8GA1UdIwQYMBaA
++FHm0WeZ7tuXkAXOACIjIGlj26ZtuMDIGCCsGAQUFBwEBBCYwJDAiBggrBgEFBQcw
++AoYWaHR0cDovL3gxLmkubGVuY3Iub3JnLzAnBgNVHR8EIDAeMBygGqAYhhZodHRw
++Oi8veDEuYy5sZW5jci5vcmcvMCIGA1UdIAQbMBkwCAYGZ4EMAQIBMA0GCysGAQQB
++gt8TAQEBMA0GCSqGSIb3DQEBCwUAA4ICAQCJbu5CalWO+H+Az0lmIG14DXmlYHQE
++k26umjuCyioWs2icOlZznPTcZvbfq02YPHGTCu3ctggVDULJ+fwOxKekzIqeyLNk
++p8dyFwSAr23DYBIVeXDpxHhShvv0MLJzqqDFBTHYe1X5X2Y7oogy+UDJxV2N24/g
++Z8lxG4Vr2/VEfUOrw4Tosl5Z+1uzOdvTyBcxD/E5rGgTLczmulctHy3IMTmdTFr0
++FnU0/HMQoquWQuODhFqzMqNcsdbjANUBwOEQrKI8Sy6+b84kHP7PtO+S4Ik8R2k7
++ZeMlE1JmxBi/PZU860YlwT8/qOYToCHVyDjhv8qutbf2QnUl3SV86th2I1QQE14s
++0y7CdAHcHkw3sAEeYGkwCA74MO+VFtnYbf9B2JBOhyyWb5087rGzitu5MTAW41X9
++DwTeXEg+a24tAeht+Y1MionHUwa4j7FB/trN3Fnb/r90+4P66ZETVIEcjseUSMHO
++w6yqv10/H/dw/8r2EDUincBBX3o9DL3SadqragkKy96HtMiLcqMMGAPm0gti1b6f
++bnvOdr0mrIVIKX5nzOeGZORaYLoSD4C8qvFT7U+Um6DMo36cVDNsPmkF575/s3C2
++CxGiCPQqVxPgfNSh+2CPd2Xv04lNeuw6gG89DlOhHuoFKRlmPnom+gwqhz3ZXMfz
++TfmvjrBokzCICA==
++-----END CERTIFICATE-----
+diff --git a/certs/letsencryptauthorityx3.pem b/certs/letsencryptauthorityx3.pem
+new file mode 100644
+index 0000000..4e82cb5
+--- /dev/null
++++ b/certs/letsencryptauthorityx3.pem
+@@ -0,0 +1,32 @@
++-----BEGIN CERTIFICATE-----
++MIIFjTCCA3WgAwIBAgIRANOxciY0IzLc9AUoUSrsnGowDQYJKoZIhvcNAQELBQAw
++TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
++cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTYxMDA2MTU0MzU1
++WhcNMjExMDA2MTU0MzU1WjBKMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNTGV0J3Mg
++RW5jcnlwdDEjMCEGA1UEAxMaTGV0J3MgRW5jcnlwdCBBdXRob3JpdHkgWDMwggEi
++MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCc0wzwWuUuR7dyXTeDs2hjMOrX
++NSYZJeG9vjXxcJIvt7hLQQWrqZ41CFjssSrEaIcLo+N15Obzp2JxunmBYB/XkZqf
++89B4Z3HIaQ6Vkc/+5pnpYDxIzH7KTXcSJJ1HG1rrueweNwAcnKx7pwXqzkrrvUHl
++Npi5y/1tPJZo3yMqQpAMhnRnyH+lmrhSYRQTP2XpgofL2/oOVvaGifOFP5eGr7Dc
++Gu9rDZUWfcQroGWymQQ2dYBrrErzG5BJeC+ilk8qICUpBMZ0wNAxzY8xOJUWuqgz
++uEPxsR/DMH+ieTETPS02+OP88jNquTkxxa/EjQ0dZBYzqvqEKbbUC8DYfcOTAgMB
++AAGjggFnMIIBYzAOBgNVHQ8BAf8EBAMCAYYwEgYDVR0TAQH/BAgwBgEB/wIBADBU
++BgNVHSAETTBLMAgGBmeBDAECATA/BgsrBgEEAYLfEwEBATAwMC4GCCsGAQUFBwIB
++FiJodHRwOi8vY3BzLnJvb3QteDEubGV0c2VuY3J5cHQub3JnMB0GA1UdDgQWBBSo
++SmpjBH3duubRObemRWXv86jsoTAzBgNVHR8ELDAqMCigJqAkhiJodHRwOi8vY3Js
++LnJvb3QteDEubGV0c2VuY3J5cHQub3JnMHIGCCsGAQUFBwEBBGYwZDAwBggrBgEF
++BQcwAYYkaHR0cDovL29jc3Aucm9vdC14MS5sZXRzZW5jcnlwdC5vcmcvMDAGCCsG
++AQUFBzAChiRodHRwOi8vY2VydC5yb290LXgxLmxldHNlbmNyeXB0Lm9yZy8wHwYD
++VR0jBBgwFoAUebRZ5nu25eQBc4AIiMgaWPbpm24wDQYJKoZIhvcNAQELBQADggIB
++ABnPdSA0LTqmRf/Q1eaM2jLonG4bQdEnqOJQ8nCqxOeTRrToEKtwT++36gTSlBGx
++A/5dut82jJQ2jxN8RI8L9QFXrWi4xXnA2EqA10yjHiR6H9cj6MFiOnb5In1eWsRM
++UM2v3e9tNsCAgBukPHAg1lQh07rvFKm/Bz9BCjaxorALINUfZ9DD64j2igLIxle2
++DPxW8dI/F2loHMjXZjqG8RkqZUdoxtID5+90FgsGIfkMpqgRS05f4zPbCEHqCXl1
++eO5HyELTgcVlLXXQDgAWnRzut1hFJeczY1tjQQno6f6s+nMydLN26WuU4s3UYvOu
++OsUxRlJu7TSRHqDC3lSE5XggVkzdaPkuKGQbGpny+01/47hfXXNB7HntWNZ6N2Vw
++p7G6OfY+YQrZwIaQmhrIqJZuigsrbe3W+gdn5ykE9+Ky0VgVUsfxo52mwFYs1JKY
++2PGDuWx8M6DlS6qQkvHaRUo0FMd8TsSlbF0/v965qGFKhSDeQoMpYnwcmQilRh/0
++ayLThlHLN81gSkJjVrPI0Y8xCVPB4twb1PFUd2fPM3sA1tJ83sZ5v8vgFv2yofKR
++PB0t6JzUA81mSqM3kxl5e+IZwhYAyO0OTg3/fs8HqGTNKd9BqoUwSRBzp06JMg5b
++rUCGwbCUDI0mxadJ3Bz4WxR6fyNpBK2yAinWEsikxqEt
++-----END CERTIFICATE-----
+diff --git a/certs/letsencryptauthorityx4.pem b/certs/letsencryptauthorityx4.pem
+new file mode 100644
+index 0000000..34064da
+--- /dev/null
++++ b/certs/letsencryptauthorityx4.pem
+@@ -0,0 +1,32 @@
++-----BEGIN CERTIFICATE-----
++MIIFjTCCA3WgAwIBAgIRAJObmZ6kjhYNW0JZtD0gE9owDQYJKoZIhvcNAQELBQAw
++TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
++cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTYxMDA2MTU0NDM0
++WhcNMjExMDA2MTU0NDM0WjBKMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNTGV0J3Mg
++RW5jcnlwdDEjMCEGA1UEAxMaTGV0J3MgRW5jcnlwdCBBdXRob3JpdHkgWDQwggEi
++MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDhJHRCe7eRMdlz/ziq2M5EXLc5
++CtxErg29RbmXN2evvVBPX9MQVGv3QdqOY+ZtW8DoQKmMQfzRA4n/YmEJYNYHBXia
++kL0aZD5P3M93L4lry2evQU3FjQDAa/6NhNy18pUxqOj2kKBDSpN0XLM+Q2lLiSJH
++dFE+mWTDzSQB+YQvKHcXIqfdw2wITGYvN3TFb5OOsEY3FmHRUJjIsA9PWFN8rPba
++LZZhUK1D3AqmT561Urmcju9O30azMdwg/GnCoyB1Puw4GzZOZmbS3/VmpJMve6YO
++lD5gPUpLHG+6tE0cPJFYbi9NxNpw2+0BOXbASefpNbUUBpDB5ZLiEP1rubSFAgMB
++AAGjggFnMIIBYzAOBgNVHQ8BAf8EBAMCAYYwEgYDVR0TAQH/BAgwBgEB/wIBADBU
++BgNVHSAETTBLMAgGBmeBDAECATA/BgsrBgEEAYLfEwEBATAwMC4GCCsGAQUFBwIB
++FiJodHRwOi8vY3BzLnJvb3QteDEubGV0c2VuY3J5cHQub3JnMB0GA1UdDgQWBBTF
++satOTLHNZDCTfsGEmQWr5gPiJTAzBgNVHR8ELDAqMCigJqAkhiJodHRwOi8vY3Js
++LnJvb3QteDEubGV0c2VuY3J5cHQub3JnMHIGCCsGAQUFBwEBBGYwZDAwBggrBgEF
++BQcwAYYkaHR0cDovL29jc3Aucm9vdC14MS5sZXRzZW5jcnlwdC5vcmcvMDAGCCsG
++AQUFBzAChiRodHRwOi8vY2VydC5yb290LXgxLmxldHNlbmNyeXB0Lm9yZy8wHwYD
++VR0jBBgwFoAUebRZ5nu25eQBc4AIiMgaWPbpm24wDQYJKoZIhvcNAQELBQADggIB
++AF4tI1yGjZgld9lP01+zftU3aSV0un0d2GKUMO7GxvwTLWAKQz/eT+u3J4+GvpD+
++BMfopIxkJcDCzMChjjZtZZwJpIY7BatVrO6OkEmaRNITtbZ/hCwNkUnbk3C7EG3O
++GJZlo9b2wzA8v9WBsPzHpTvLfOr+dS57LLPZBhp3ArHaLbdk33lIONRPt9sseDEk
++mdHnVmGmBRf4+J0Wy67mddOvz5rHH8uzY94raOayf20gzzcmqmot4hPXtDG4Y49M
++oFMMT2kcWck3EOTAH6QiGWkGJ7cxMfSL3S0niA6wgFJtfETETOZu8AVDgENgCJ3D
++S0bz/dhVKvs3WRkaKuuR/W0nnC2VDdaFj4+CRF8LGtn/8ERaH48TktH5BDyDVcF9
++zfJ75Scxcy23jAL2N6w3n/t3nnqoXt9Im4FprDr+mP1g2Z6Lf2YA0jE3kZalgZ6l
++NHu4CmvJYoOTSJw9X2qlGl1K+B4U327rG1tRxgjM76pN6lIS02PMECoyKJigpOSB
++u4V8+LVaUMezCJH9Qf4EKeZTHddQ1t96zvNd2s9ewSKx/DblXbKsBDzIdHJ+qi6+
++F9DIVM5/ICdtDdulOO+dr/BXB+pBZ3uVxjRANvJKKpdxkePyluITSNZHbanWRN07
++gMvwBWOL060i4VrL9er1sBQrRjU9iNpZQGTnLVAxQVFu
++-----END CERTIFICATE-----
+diff --git a/client b/client
+index 838b184..52aab3d 100755
+--- a/client
++++ b/client
+@@ -338,20 +338,7 @@ elsif ($COMMAND eq 'newOrder') {
+         die "Timeout exceeded while waiting for certificate\n" if $timeout > 0 and $i >= $timeout;
+         sleep $retry_after;
+     }
+-
+-    # 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: $!";
+-        exec qw/openssl x509 -outform PEM/ or die;
+-    }
+-    $rd->close() or die "Can't close: $!";
+-    $wd->print( $r->decoded_content() );
+-    $wd->close() or die "Can't close: $!";
+-
+-    waitpid $pid => 0;
+-    die $? if $? > 0;
++    print $r->decoded_content();
+ }
+ 
+ 
+diff --git a/config/lacme-certs.conf b/config/lacme-certs.conf
+index 97d588a..7a9ba29 100644
+--- a/config/lacme-certs.conf
++++ b/config/lacme-certs.conf
+@@ -20,8 +20,8 @@
+ #
+ #certificate = /etc/nginx/ssl/srv.pem
+ 
+-# Where to store the issued certificate, concatenated with the content
+-# of the file specified specified with the CAfile option (in PEM format).
++# Where to store the issued certificate along with its chain of trust
++# (in PEM format).
+ #
+ #certificate-chain = /etc/nginx/ssl/srv.chain.pem
+ 
+@@ -30,11 +30,10 @@
+ #
+ #min-days = 21
+ 
+-# Path to the issuer's certificate.  This is used for certificate-chain
+-# and to verify the validity of each issued certificate.  Specifying an
+-# empty value skip certificate validation.
++# Path to trusted issuer certificates, used for validating each issued
++# certificate.  Specifying an empty value skips certificate validation.
+ #
+-#CAfile = /usr/share/lacme/lets-encrypt-x3-cross-signed.pem
++#CAfile = /usr/share/lacme/ca-certificates.crt
+ 
+ # Subject field of the Certificate Signing Request.  This option is
+ # required.
+diff --git a/lacme b/lacme
+index 3e5347d..8f03d38 100755
+--- a/lacme
++++ b/lacme
+@@ -609,12 +609,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);
+@@ -624,12 +622,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: $!";
+     };
+@@ -767,7 +776,7 @@ elsif ($COMMAND eq 'newOrder' or $COMMAND eq 'new-cert') {
+         };
+ 
+         # verify certificate validity against the CA
+-        $conf->{CAfile} //= '/usr/share/lacme/lets-encrypt-x3-cross-signed.pem';
++        $conf->{CAfile} //= '/usr/share/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";
+@@ -778,11 +787,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}) {
+diff --git a/lacme.md b/lacme.md
+index 2d70c49..28d1a53 100644
+--- a/lacme.md
++++ b/lacme.md
+@@ -327,9 +327,8 @@ Valid options are:
+ 
+ *certificate-chain*
+ 
+-:   Where to store the issued certificate, concatenated with the content
+-    of the file specified specified with the *CAfile* option (in PEM
+-    format).
++:   Where to store the issued certificate along with its chain of trust
++    (in PEM format).
+     At least one of *certificate* or *certificate-chain* is required.
+ 
+ *certificate-key*
+@@ -351,11 +350,9 @@ Valid options are:
+ 
+ *CAfile*
+ 
+-:   Path to the issuer's certificate.  This is used for
+-    *certificate-chain* and to verify the validity of each issued
+-    certificate.
+-    Specifying an empty value skip certificate validation.
+-    Default: `/usr/share/lacme/lets-encrypt-x3-cross-signed.pem`.
++:   Path to trusted issuer certificates, used for validating each issued
++    certificate.  Specifying an empty values skips certificate validation.
++    Default: `/usr/share/lacme/ca-certificates.crt`.
+ 
+ *hash*
+ 
+-- 
+2.29.2
+
diff -Nru lacme-0.5/debian/patches/series lacme-0.5/debian/patches/series
--- lacme-0.5/debian/patches/series	2019-08-22 00:14:42.000000000 +0200
+++ lacme-0.5/debian/patches/series	2020-11-26 01:14:50.000000000 +0100
@@ -1,2 +1,3 @@
 0001-Mention-the-Debian-BTS-in-the-manpages.patch
 0002-Issue-GET-and-POST-as-GET-requests.patch
+0003-Use-upstream-certicate-chain-instead-of-an-hardcoded.patch
Only in b/lacme-0.5/certs: letsencryptauthorityx3.pem
Only in b/lacme-0.5/certs: letsencryptauthorityx4.pem
Only in b/lacme-0.5/certs: lets-encrypt-e1.pem
Only in b/lacme-0.5/certs: lets-encrypt-e2.pem
Only in b/lacme-0.5/certs: lets-encrypt-r3-cross-signed.pem
Only in b/lacme-0.5/certs: lets-encrypt-r3.pem
Only in b/lacme-0.5/certs: lets-encrypt-r4-cross-signed.pem
Only in b/lacme-0.5/certs: lets-encrypt-r4.pem
diff -ru a/lacme-0.5/client b/lacme-0.5/client
--- a/lacme-0.5/client	2020-11-26 02:31:10.000000000 +0100
+++ b/lacme-0.5/client	2020-11-26 02:31:22.000000000 +0100
@@ -338,20 +338,7 @@
         die "Timeout exceeded while waiting for certificate\n" if $timeout > 0 and $i >= $timeout;
         sleep $retry_after;
     }
-
-    # 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: $!";
-        exec qw/openssl x509 -outform PEM/ or die;
-    }
-    $rd->close() or die "Can't close: $!";
-    $wd->print( $r->decoded_content() );
-    $wd->close() or die "Can't close: $!";
-
-    waitpid $pid => 0;
-    die $? if $? > 0;
+    print $r->decoded_content();
 }
 
 
diff -ru a/lacme-0.5/config/lacme-certs.conf b/lacme-0.5/config/lacme-certs.conf
--- a/lacme-0.5/config/lacme-certs.conf	2018-05-09 14:09:18.000000000 +0200
+++ b/lacme-0.5/config/lacme-certs.conf	2020-11-26 02:31:22.000000000 +0100
@@ -20,8 +20,8 @@
 #
 #certificate = /etc/nginx/ssl/srv.pem
 
-# Where to store the issued certificate, concatenated with the content
-# of the file specified specified with the CAfile option (in PEM format).
+# Where to store the issued certificate along with its chain of trust
+# (in PEM format).
 #
 #certificate-chain = /etc/nginx/ssl/srv.chain.pem
 
@@ -30,11 +30,10 @@
 #
 #min-days = 21
 
-# Path to the issuer's certificate.  This is used for certificate-chain
-# and to verify the validity of each issued certificate.  Specifying an
-# empty value skip certificate validation.
+# Path to trusted issuer certificates, used for validating each issued
+# certificate.  Specifying an empty value skips certificate validation.
 #
-#CAfile = /usr/share/lacme/lets-encrypt-x3-cross-signed.pem
+#CAfile = /usr/share/lacme/ca-certificates.crt
 
 # Subject field of the Certificate Signing Request.  This option is
 # required.
diff -ru a/lacme-0.5/debian/changelog b/lacme-0.5/debian/changelog
--- a/lacme-0.5/debian/changelog	2019-08-22 00:14:42.000000000 +0200
+++ b/lacme-0.5/debian/changelog	2020-11-26 01:14:50.000000000 +0100
@@ -1,3 +1,26 @@
+lacme (0.5-1+deb10u2) buster; urgency=medium
+
+  * Use upstream certificate 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
+  * Additional current/planned CA certificates can be found under
+    /usr/local/share/lacme:
+      - lets-encrypt-e[12].pem
+      - lets-encrypt-r[34]-cross-signed.pem
+      - lets-encrypt-r[34].pem
+      - letsencryptauthorityx[34].pem
+    See https://letsencrypt.org/certificates/
+  * Moreover 'CAfile' now defaults to /usr/share/lacme/ca-certificates.crt
+    which is a concatenation of all known active CA certificates (which
+    includes the previous default).
+    Closes: #975862.
+
+ -- Guilhem Moulin <guilhem@debian.org>  Thu, 26 Nov 2020 01:14:50 +0100
+
 lacme (0.5-1+deb10u1) buster; urgency=medium
 
   * Link to RFC 8555 <https://tools.ietf.org/html/rfc8555> instead of the
diff -ru a/lacme-0.5/debian/lacme.install b/lacme-0.5/debian/lacme.install
--- a/lacme-0.5/debian/lacme.install	2019-08-22 00:14:42.000000000 +0200
+++ b/lacme-0.5/debian/lacme.install	2020-11-26 01:14:50.000000000 +0100
@@ -1,4 +1,5 @@
-certs/lets-encrypt-x[1-4]-cross-signed.pem /usr/share/lacme
+certs/*.pem                                /usr/share/lacme
+/usr/share/lacme/ca-certificates.crt
 client webserver                           /usr/lib/lacme
 config/lacme-certs.conf config/lacme.conf  /etc/lacme
 lacme                                      /usr/sbin
Only in b/lacme-0.5/debian/patches: 0003-Use-upstream-certicate-chain-instead-of-an-hardcoded.patch
diff -ru a/lacme-0.5/debian/patches/series b/lacme-0.5/debian/patches/series
--- a/lacme-0.5/debian/patches/series	2019-08-22 00:14:42.000000000 +0200
+++ b/lacme-0.5/debian/patches/series	2020-11-26 01:14:50.000000000 +0100
@@ -1,2 +1,3 @@
 0001-Mention-the-Debian-BTS-in-the-manpages.patch
 0002-Issue-GET-and-POST-as-GET-requests.patch
+0003-Use-upstream-certicate-chain-instead-of-an-hardcoded.patch
diff -ru a/lacme-0.5/lacme b/lacme-0.5/lacme
--- a/lacme-0.5/lacme	2018-05-09 14:09:18.000000000 +0200
+++ b/lacme-0.5/lacme	2020-11-26 02:31:22.000000000 +0100
@@ -609,12 +609,10 @@
 
 
 #############################################################################
-# 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);
@@ -624,12 +622,23 @@
     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: $!";
     };
@@ -767,7 +776,7 @@
         };
 
         # verify certificate validity against the CA
-        $conf->{CAfile} //= '/usr/share/lacme/lets-encrypt-x3-cross-signed.pem';
+        $conf->{CAfile} //= '/usr/share/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";
@@ -778,11 +787,11 @@
         # 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}) {
diff -ru a/lacme-0.5/lacme.md b/lacme-0.5/lacme.md
--- a/lacme-0.5/lacme.md	2020-11-26 02:31:10.000000000 +0100
+++ b/lacme-0.5/lacme.md	2020-11-26 02:31:22.000000000 +0100
@@ -327,9 +327,8 @@
 
 *certificate-chain*
 
-:   Where to store the issued certificate, concatenated with the content
-    of the file specified specified with the *CAfile* option (in PEM
-    format).
+:   Where to store the issued certificate along with its chain of trust
+    (in PEM format).
     At least one of *certificate* or *certificate-chain* is required.
 
 *certificate-key*
@@ -351,11 +350,9 @@
 
 *CAfile*
 
-:   Path to the issuer's certificate.  This is used for
-    *certificate-chain* and to verify the validity of each issued
-    certificate.
-    Specifying an empty value skip certificate validation.
-    Default: `/usr/share/lacme/lets-encrypt-x3-cross-signed.pem`.
+:   Path to trusted issuer certificates, used for validating each issued
+    certificate.  Specifying an empty values skips certificate validation.
+    Default: `/usr/share/lacme/ca-certificates.crt`.
 
 *hash*
 
diff -ru a/lacme-0.5/Makefile b/lacme-0.5/Makefile
--- a/lacme-0.5/Makefile	2018-05-09 14:09:18.000000000 +0200
+++ b/lacme-0.5/Makefile	2020-11-26 02:31:22.000000000 +0100
@@ -37,7 +37,14 @@
 	install -m0644 -t $(DESTDIR)/etc/lacme config/*.conf
 	install -m0644 -t $(DESTDIR)/etc/lacme snippets/*.conf
 	install -d $(DESTDIR)/usr/share/lacme
-	install -m0644 -t $(DESTDIR)/usr/share/lacme certs/lets-encrypt-x[1-4]-cross-signed.pem
+	install -m0644 -t $(DESTDIR)/usr/share/lacme certs/*
+	# used for validation, see https://letsencrypt.org/certificates/
+	cat certs/letsencryptauthorityx[34].pem \
+        certs/lets-encrypt-x[34]-cross-signed.pem \
+        certs/lets-encrypt-r[34].pem \
+        certs/lets-encrypt-r[34]-cross-signed.pem \
+        certs/lets-encrypt-e[12].pem \
+		>$(DESTDIR)/usr/share/lacme/ca-certificates.crt
 	install -d $(DESTDIR)/usr/lib/lacme
 	install -m0755 -t $(DESTDIR)/usr/lib/lacme client webserver
 	install -d $(DESTDIR)/usr/share/man/man1
Only in b/lacme-0.5/.pc: 0003-Use-upstream-certicate-chain-instead-of-an-hardcoded.patch
diff -ru a/lacme-0.5/.pc/applied-patches b/lacme-0.5/.pc/applied-patches
--- a/lacme-0.5/.pc/applied-patches	2020-11-26 02:31:10.067084330 +0100
+++ b/lacme-0.5/.pc/applied-patches	2020-11-26 02:31:22.598929829 +0100
@@ -1,2 +1,3 @@
 0001-Mention-the-Debian-BTS-in-the-manpages.patch
 0002-Issue-GET-and-POST-as-GET-requests.patch
+0003-Use-upstream-certicate-chain-instead-of-an-hardcoded.patch

Attachment: signature.asc
Description: PGP signature


--- End Message ---
--- Begin Message ---
Package: release.debian.org
Version: 10.7

Hi,

Each of the updates referenced by these bugs was included in this
morning's buster 10.7 point release.

Regards,

Adam

--- End Message ---

Reply to: