Page 1 of 1

How can I use a PEM that expires in 12 months in an embedded product?

Posted: Tue Oct 15, 2024 8:27 am
by Martin Brennan
I apologise in advance if this is a dumb question. I feel like I must be missing something.

The HTTP_CLIENT example program
https://github.com/espressif/esp-idf/tr ... ttp_client
Uses a PEM file to make an HTTPS request.

I read that I can generate a PEM file using a script like this (substitute websocket.org with the appropriate domain)
echo "" | openssl s_client -showcerts -connect websocket.org:443 | sed -n "1,/Root/d; /BEGIN/,/END/p" | openssl x509 -outform PEM >websocket_org.pem

However when I do that and inspect the PEM file I see that it has an expiry date - that varies from site to site but is typically 12 months.

What happens after the expiry date? Does it stop working?

I feel I must be missing something because this mechanism is presumably used for secure OTA upgrades. If the PEM for your server expires then you can no longer upgrade the product.

This problem is doubly annoying because I do not actually need a secure connection - it works fine if I compile with ESP_TLS_INSECURE and ESP_TLS_SKIP_SERVER_VERIFY - but if these are not set then I must supply a cert_pem in the HTTP_CLIENT config. And that implies it will expire.

Martin

Re: How can I use a PEM that expires in 12 months in an embedded product?

Posted: Tue Oct 15, 2024 10:21 am
by MicroController
Martin Brennan wrote:
Tue Oct 15, 2024 8:27 am
If the PEM for your server expires then you can no longer upgrade the product.
This issue is solved by having the server certificate signed by a trusted, secure long-term key/certificate and deploy only this long-term public key on the ESP. You can do the signing yourself, or use a third party ("Certificate Authority", CA), like https://letsencrypt.org/, for the signing, then deploy their root certificate in the ESP. The latter approach is supported via the IDF's "certificate bundle".

Re: How can I use a PEM that expires in 12 months in an embedded product?

Posted: Tue Oct 15, 2024 11:41 am
by boarchuz
And even if the certificate does expire, the ESP32 won't know or care because, in most configurations, it doesn't have a reliable source for the current time (eg. NTP, GPS).

Even then, you would need to enable the relevant option in mbedTLS if you actually want this behaviour.

Re: How can I use a PEM that expires in 12 months in an embedded product?

Posted: Tue Oct 15, 2024 11:55 am
by MicroController
Ok, I think I may have misinterpreted your post a little. Do you operate the webserver or is it provided by a third party? I.e. do you need to manage the server's keys/certificates or is it done 'automatically' for you?

But: The root certificate should actually be pretty long-lived. Maybe manually inspect root certificate in the certificate chain to check if you may have extracted the wrong one.

Re: How can I use a PEM that expires in 12 months in an embedded product?

Posted: Tue Oct 15, 2024 12:02 pm
by MicroController
boarchuz wrote:
Tue Oct 15, 2024 11:41 am
And even if the certificate does expire, the ESP32 won't know or care because,
Except that every web hoster will replace any certificate before it expires, i.e. even if the ESP would be fine with an expired cert, the server will start using a different one every, say, 11 months.

Re: How can I use a PEM that expires in 12 months in an embedded product?

Posted: Wed Oct 16, 2024 7:40 am
by Martin Brennan
Thank you MicroController and boarchuz

Let me give you some background.

My company uses Shopify to host our website and ecommerce and we also use their server for downloads to upgrade older non ESP products.

I just created a pem file for my domain using the script mentioned previously
I then inspected the pem file with "openssl x509 -in <pemfile> -text -noout"
And it shows an expiry of 2027. That's one server.

The product I have in mind also uses a third party API and the pem files I get for their domain typically expire in less than 12 months.
The third party enforces https but does not check for certificates. That's a second server.

I confess I do not properly understand the chain of trust mechanism - but it seems like the reliance of http_client on a single ephemeral pem - in the cert_pem field means that it can only ever work temporarily.

boarchuz mentioned certificate bundle - and that seems similar to my understanding of browser operation - and a better approach.

So my next question is - can http-client make use of a certificate bundle?

The example mentioned on the ESP X509 page

https://github.com/espressif/esp-idf/tr ... ps_mbedtls

appears to show the construction of an HTTP request that uses the certificate bundle to verify the server.

Do you think it is possible therefore to use this approach to bypass http_client?
And having said that it looks like it might be possible to use this example to make the request (over https) but skip verification completely. Any thoughts?

Thanks again

Martin

Re: How can I use a PEM that expires in 12 months in an embedded product?

Posted: Wed Oct 16, 2024 12:36 pm
by MicroController
Martin Brennan wrote:
Wed Oct 16, 2024 7:40 am
So my next question is - can http-client make use of a certificate bundle?
Yes.
See https://docs.espressif.com/projects/esp ... ps-request and https://github.com/espressif/esp-idf/bl ... ple.c#L420 .

Re: How can I use a PEM that expires in 12 months in an embedded product?

Posted: Wed Oct 16, 2024 12:47 pm
by Martin Brennan
Thank you that looks promising I will try it over the next couple of days - Martin

Re: How can I use a PEM that expires in 12 months in an embedded product?

Posted: Thu Oct 17, 2024 1:51 pm
by Martin Brennan
Hi MicroController
I can confirm that using

.crt_bundle_attach = esp_crt_bundle_attach,

in the http_client config allows it to access all the https urls in my project.
So thank you for your help.

I would point out that without some digging I still don't know the expiry date in the certificate authorities behind the urls.

This has implications for OTA. It seems like the only way to guarantee an upgrade service over https is to self certify with very long expiry.

A more pragmatic solution seems to be to use http not https for OTA. I think man in the middle attacks may be a legitimate concern for some applications but its only a hypothetical risk for many products.

Martin

Re: How can I use a PEM that expires in 12 months in an embedded product?

Posted: Thu Oct 17, 2024 1:58 pm
by MicroController
You could also (OTA) update the certificate bundle together with or separate from the application every now and then.