E (3515) esp-tls-mbedtls: mbedtls_ssl_handshake returned -0x2700
E (3516) esp-tls: Failed to open new connection
E (3516) TRANSPORT_BASE: Failed to open a new connection
E (3521) HTTP_CLIENT: Connection failed, sock < 0
E (3524) esp_https_ota: Failed to open HTTP connection: ESP_ERR_HTTP_CONNECT
Googling didn’t find any good clues.
I’ve decoded the certificate and it looks good. I’ve placed that info at the end. One major difference is that I used LetsEncrypt for the latter certificate.
Thanks in advance for any pointers.
Hi @mzincalli, and welcome to the LE community forum
[I've moved your post to a separate topic because it really has little to do with that other topic]
The certificate is not the likeliest problem here.
If I had to guess (which I do, since you haven't provided a real functional FQDN) I would have to say that your client lacks TLSv1.2 support.
Being that the failing URL doesn't support TLSv1.0.
I was under the assumption that since my server domain matches the one in this certificate, that the HTTPS access would succeed.
My, probably incorrect, notion is that when I pass in this certificate, I am basically saying that I trust anything signed from this server, and there is no need for any code on my side to go up the trust chain and try to get to the root CA. If there is malicious actor trying to impersonate that server, then they would have to be able to generate encrypted traffic that I could decrypt with the public key in the cert, which would be unlikely since they don't have the private key that was used to generate the cert that I have.
I know I probably should brush up on SSL, but I knew some of the basic ideas. I'm going to try to figure out where I am wrong.
Where things get more complicated are actually after I get this to work. I expected this to work, as I explained above, but what is unworkable is a certificate that is only valid for 90 days. Since this code is embedded into an IoT device, I'd like it to stay functional for longer than 90 days. And that is where I would need to have a root certificate with a longer validity. However, I first have to overcome this issue.
I think that behavior probably varies between TLS client libraries. Some might accept an end-entity (leaf) certificate as a root, meaning "trust this end-entity certificate only." But it's a bit of an incorrect concept, like using a hammer where a wrench is called for. Most client libraries want a list of root certificates. And as you point out, that's important because end-entity certificates expire after 90 days, while root certificates stick around a long time[1].
Can you link to the docs for esp_http_client_config_t, and specifically its cert_pem field?
[1]: Not even root certificates live forever! You should make sure you're thinking about how to deliver root certificate updates to your devices. And don't trust just one root certificate - CAs change roots, go out of business, etc. You should trust a variety of root certificates for flexibility.
One of the reason I brought this up here is that I can easily use the amazon's cert for communication with AWS, but when I try to communicate with my own server, which uses the LE cert, I am having issues. I've also tried the cert provided by this:
My solution for changing certificates is to provide updates for the device, at least annually. Of course there are users who don't/won't do that, so I may have to have a way to work around that too.
So, are you saying that I need a bundle? I have some memory constraints to worry about and I also don't need "90 % coverage according to market share statistics" of all websites; I only want my own server to be covered. How do I do that/what certs do I need to bundle?
Let me be clear:
do you think that the certificate I have, like the one I get from the openssl CLI above, should work, and the problem is how I am providing that to mbedtls?
or, I need a whole new set of certs (maybe including the one from openssl), because I am lacking enough of the chain of certs?
There are two sets of certificates you should be thinking about:
The set of end-entity certificates and intermediate certificates served by optimized.realyze.com (the chain)
The set of root certificates you pass to mbedTLS on your devices (the bundle)
(1) looks fine, with a caveat I'll explain below. I think the problem is (2). So yes, you need a bundle of root certificates. It's true that you don't need coverage of all websites, but you do need a backup plan in case Let's Encrypt is hit by a meteor tomorrow and ceases to exist. The most straightforward backup plan is to trust the roots from the Mozilla program, and keep that list up to date. Try that first; if you run into memory constraints you might choose to select a smaller group of roots, but this gets very tricky very fast. There are instructions on how to generate such a bundle on the documentation page I linked.
Here's the caveat for (1): The chain served by optimized.realyze.comincludes our cross-sign from the expired DST Root CA X3. That's normal and good and expected. However, some older TLS libraries have issues with it. I think mbedTLS isn't one of them but I'm not sure. This really gets into the nitty-gritty of PKI stuff, and I suspect it isn't your problem, so don't worry about it for now. Just make sure you're running the very latest version of mbedTLS.
Yes, in this case the memory I was referring to is Flash. And I have to preserve it so that there is enough room leftover to allow for over-the-air updates, etc. The total flash size is 4MB in my case, and the firmware size right now is over 1900KB.