Open noahwilliamsson opened 5 years ago
Thanks a lot for reporting this... I'll ask the team to generate a new pem file that I can include in the next release.
@jirikrepl @Xykon If you fix the certificate chain issue on pybytes-staging.pycom.io
you can drop Let's Encrypt's issuer certificate (the first cert in _pybytes_ca.py
) that is still included in f1e26760b236ea35a6d994a35076f91501b761bb (pybytes-master
branch), leaving only the root CA certificate from IdentTrust.
Since it appears this server is using Nginx, what you need to do is to append the above mention certificate in the file pointed out by the Nginx directive ssl_certificate and then make Nginx reload its configuration (usually sudo systemctl reload nginx
).
Hi @noahwilliamsomm good catch ! A PR that do exactly what you have explained is on the go on an upstream repository. Will be merged on by build pipeline.
Hey @Xykon, in commit 978c9bbd835112c1a0f200f69d448dabebe9f846 you appear to have committed an expired Let's Encrypt leaf certificate (for
pybytes-staging.pycom.io
) in the file https://github.com/pycom/pycom-micropython-sigfox/blob/release-candidate/esp32/frozen/Pybytes/_pybytes_ca.py.For reference, here's an excerpt of leaf certificate in question:
(if you're on Linux or a Mac, you can use
openssl x509 -noout -text -in <certificate-file.pem>
to show the above text from a certificate file in PEM format)While I haven't looked at the implementation for this specific case, the way things typically work is that you include one or more root CA (certificate authority) certificates in the the device or the computer. These certificates serve as a trust anchor on the device.
So let's say that a Pycom device would want to establish a TLS connection to
https://pybytes.pycom.io
(or some other protocol protected with TLS). This server would then present a certificate chain consisting of:pybytes.pycom.io
)After verifying that the leaf certificate has not expired and is also valid for the domain the device intended to connect to, the Pycom device would go over each certificate presented by the server and verify that it was issued (signed) by the next certificate in the chain (using public key signature checks) . To verify the last certificate in the chain the device needs a local copy of the issuing (signing) certificate -- this is what need to be present in the device's trust store (= a list of trusted CA certificate a.k.a. the trust anchor).
On most operating systems and (some) browsers, the trust store contains a list of over hundred vetted CA certificates, mostly from commercial CAs and government organizations, but also from Let's Encrypt.
Naturally it's not feasible to include a large list of root CAs on a device with small amounts of storage but if you only intend to use certificates from Let's Encrypt on your servers you can get away with keeping just one or two root CA certificates in the device's trust store:
DST Root CA X3
(the last certificate inesp32/frozen/Pybytes/_pybytes_ca.py
; also available asTrustID X3
from https://www.identrust.com/support/downloads)ISRG Root X1
(Let's Encrypt's own root certificate -- see https://letsencrypt.org/certificates/)Of those above, the most important certificate for now is the
DST Root CA X3
one, which has signed the intermediate certificate that Let's Encrypt uses to issue most of their leaf certificates from. For best/future compatibility you should also include their own root certificate, theISRG Root X1
. The way you do this is to simple concatenate these two files and place them in_pybytes_ca.py
. Unlike a server certificate chain, the order is not important here.You can read more about Let's Encrypt's CA certificates on https://letsencrypt.org/certificates/.
All of this of course assumes that your servers are setup correctly and serve up not only the leaf certificate, but also any intermediate certificates that leads up to a root certificate present on the connecting device.
The web server at
https://pybytes.pycom.io
is correctly setup and serves up both a leaf certificate valid forpybytes.pycom.io
(among other domains) as well as the issuing (signing) certificateCN=Let's Encrypt Authority X3
(which in turn was signed by a root CA present in most operating systems' trust stores).The web server at
https://pybytes-staging.pycom.io
is however misconfigured and lacks the intermediate certificateCN=Let's Encrypt Authority X3
. If you update the certificate chain and include the missing intermediate certificate, you could drop the two first certificates (expired leaf + intermediate cert) inesp32/frozen/Pybytes/_pybytes_ca.py
, and optionally consider adding theISRG Root X1
certificate. Then things should work as expected.(if your TLS stack supports it, you might want to consider encoding your certificates in the binary DER format as opposed to the text-friendly PEM format: header+base64 encoded cert+footer).
Use the excellent https://www.ssllabs.com service and verify that it no longer reports
Chain issues: incomplete
for https://www.ssllabs.com/ssltest/analyze.html?d=pybytes-staging.pycom.io once you've updated the web server(s) responsible forpybytes-staging.pycom.io
.Alternative, if you're on a Linux/Mac and have a local copy of the
DST Root X3
in a file nameddst_x3.pem
, you can use theopenssl
utility like this:The last line should read
Verify return code: 0 (ok)
if the server's certificate chain could be verified sucessfully. If it's broken, the last line will say something likeVerify return code: 21 (unable to verify the first certificate)
.HTH.