# ESP x509 Certificate Bundle

[中文]

## Overview

The ESP x509 Certificate Bundle API provides an easy way to include a bundle of custom x509 root certificates for TLS server verification.

The bundle comes with the complete list of root certificates from Mozilla's NSS root certificate store. Using the gen_crt_bundle.py python utility, the certificates' subject name and public key are stored in a file and embedded in the ESP32-C5 binary.

When generating the bundle you may choose between:

> - The full root certificate bundle from Mozilla, containing more than 130 certificates. The current bundle was updated Tue Dec 2 04:12:02 2025 GMT.

> - A pre-selected filter list of the name of the most commonly used root certificates, reducing the amount of certificates to around 38 while still having around 93% absolute usage coverage and 99% market share coverage according to SSL certificate authorities statistics.

In addition, it is possible to specify a path to a certificate file or a directory containing certificates which then will be added to the generated bundle.

Note

Trusting all root certificates means the list will have to be updated if any of the certificates are retracted. This includes removing them from `cacrt_all.pem`.

## Configuration

Most configuration is done through menuconfig. CMake generates the bundle according to the configuration and embed it.

> - CONFIG_MBEDTLS_CERTIFICATE_BUNDLE: automatically build and attach the bundle.

> - CONFIG_MBEDTLS_DEFAULT_CERTIFICATE_BUNDLE: decide which certificates to include from the complete root certificate list.

> - CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE_PATH: specify the path of any additional certificates to embed in the bundle.

To enable the bundle when using ESP-TLS simply pass the function pointer to the bundle attach function:

    esp_tls_cfg_t cfg = {
         .crt_bundle_attach = esp_crt_bundle_attach,
    };

This is done to avoid embedding the certificate bundle unless activated by the user.

If using mbedTLS directly then the bundle may be activated by directly calling the attach function during the setup process:

    mbedtls_ssl_config conf;
    mbedtls_ssl_config_init(&conf);

    esp_crt_bundle_attach(&conf);

## Generating the List of Root Certificates

The list of root certificates comes from Mozilla's NSS root certificate store, which can be found here

The list can be downloaded and created by running the script `mk-ca-bundle.pl` that is distributed as a part of curl.

Another alternative would be to download the finished list directly from the curl website: CA certificates extracted from Mozilla

The common certificates bundle were made by selecting the authorities with a market share of more than 1% from w3tech's SSL Survey.

These authorities were then used to pick the names of the certificates for the filter list, `cmn_crt_authorities.csv`, from this list provided by Mozilla.

## Updating the Certificate Bundle

The bundle is embedded into the app and can be updated along with the app by an OTA update. If you want to include a more up-to-date bundle than the bundle currently included in ESP-IDF, then the certificate list can be downloaded from Mozilla as described in Generating the List of Root Certificates.

## Periodic Sync

The bundle is kept updated by periodic sync with the Mozilla's NSS root certificate store. The deprecated certs from the upstream bundle are added to deprecated list (for compatibility reasons) in ESP-IDF minor or patch release. If required, the deprecated certs can be added to the default bundle by enabling CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEPRECATED_LIST. The deprecated certs shall be removed (reset) on the next major ESP-IDF release.

## Cross-Signed Certificate Support

### Overview

When the configuration option CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_CROSS_SIGNED_VERIFY is enabled, the ESP x509 Certificate Bundle API adds support for verifying certificate chains that include cross-signed root certificates.

This feature allows the verification process to dynamically select candidate Certificate Authorities (CAs) from the bundle, even when the certificate chain contains cross-signed roots, improving interoperability with a wider range of server certificates.

With this functionality enabled, certificate verification is performed in a manner equivalent to the default mbedTLS behavior, ensuring compatibility and robust validation for cross-signed chains.

Note

Enabling cross-signed certificate support increases run-time heap utilization by approximately 700 bytes, but reduces the flash footprint as the bundle size is reduced.

Key Points:

- The bundle can act as a dynamic CA store, providing candidate root certificates during the handshake.

- The verification callback uses the issuer information from the certificate chain to locate and provide matching root certificates from the bundle.

- This is especially useful for environments where cross-signing is common, such as during root CA transitions.

### Usage

No additional application changes are required beyond enabling CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_CROSS_SIGNED_VERIFY in your project configuration. The bundle will automatically provide candidate CAs during the TLS handshake.

Note

If CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_CROSS_SIGNED_VERIFY is enabled, it internally uses `MBEDTLS_X509_TRUSTED_CERT_CALLBACK`. In this case, users should not provide their own trusted certificate callback, as the certificate bundle will manage this automatically.

## Application Examples

- protocols/https_x509_bundle demonstrates how to use ESP-TLS to establish a secure socket connection using the certificate bundle with two custom certificates added for verification.

- protocols/https_request demonstrates an HTTPS example that uses ESP-TLS and the default bundle.

- protocols/https_mbedtls demonstrates an HTTPS example that uses Mbed TLS and the default bundle.

## API Reference

### Header File

- components/mbedtls/esp_crt_bundle/include/esp_crt_bundle.h

- This header file can be included with:

  >     #include "esp_crt_bundle.h"

- This header file is a part of the API provided by the `mbedtls` component. To declare that your component depends on `mbedtls`, add the following to your CMakeLists.txt:

  >     REQUIRES mbedtls

  > or

  >     PRIV_REQUIRES mbedtls

### Functions

esp_err_t esp_crt_bundle_attach(void *conf)

  Attach and enable use of a bundle for certificate verification.

  Attach and enable use of a bundle for certificate verification through a verification callback. If no specific bundle has been set through esp_crt_bundle_set() it will default to the bundle defined in menuconfig and embedded in the binary.

  Parameters:

    conf -- [in] The config struct for the SSL connection.

  Returns:

    - ESP_OK if adding certificates was successful.

    - Other if an error occurred or an action must be taken by the calling process.

void esp_crt_bundle_detach(mbedtls_ssl_config *conf)

  Disable and dealloc the certification bundle.

  Removes the certificate verification callback and deallocates used resources

  Parameters:

    conf -- [in] The config struct for the SSL connection.

esp_err_t esp_crt_bundle_set(const uint8_t *x509_bundle, size_t bundle_size)

  Set the default certificate bundle used for verification.

  Overrides the default certificate bundle only in case of successful initialization. In most use cases the bundle should be set through menuconfig. The bundle needs to be sorted by subject name since binary search is used to find certificates.

  Parameters:

    - x509_bundle -- [in] A pointer to the certificate bundle.

    - bundle_size -- [in] Size of the certificate bundle in bytes.

  Returns:

    - ESP_OK if adding certificates was successful.

    - Other if an error occurred or an action must be taken by the calling process.

bool esp_crt_bundle_in_use(const mbedtls_x509_crt *ca_chain)

  Check if the given CA certificate chain is the default "dummy" certificate chain attached by the esp_crt_bundle.

  Parameters:

    ca_chain -- A pointer to the CA chain.

  Returns:

    true if the ca_chain is the dummy CA chain attached by esp_crt_bundle

  Returns:

    false otherwise

Was this page helpful?

- Thank you! We received your feedback.
- If you have any comments, fill in Espressif Documentation Feedback Form.

- We value your feedback.
- Let us know how we can improve this page by filling in Espressif Documentation Feedback Form.