2022-01-05 10:00:35 +05:30
|
|
|
/*
|
2023-07-09 23:37:40 +02:00
|
|
|
* SPDX-FileCopyrightText: 2018-2024 Espressif Systems (Shanghai) CO LTD
|
2022-01-05 10:00:35 +05:30
|
|
|
*
|
|
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
|
|
*/
|
2019-09-29 18:04:34 +08:00
|
|
|
#include <string.h>
|
2022-11-08 16:30:32 +05:30
|
|
|
#include <stdbool.h>
|
2023-07-09 23:37:40 +02:00
|
|
|
#include <sys/param.h>
|
|
|
|
|
|
|
|
#include "esp_check.h"
|
2019-09-29 18:04:34 +08:00
|
|
|
#include "esp_crt_bundle.h"
|
|
|
|
#include "esp_log.h"
|
|
|
|
|
2023-07-09 23:37:40 +02:00
|
|
|
#include "mbedtls/pk.h"
|
|
|
|
#include "mbedtls/oid.h"
|
|
|
|
#include "mbedtls/asn1.h"
|
|
|
|
|
|
|
|
/*
|
|
|
|
Format of certificate bundle:
|
|
|
|
First, n uint32 "offset" entries, each describing the start of one certificate's data in terms of
|
|
|
|
bytes from the beginning of the bundle. This offset list is immediately followed by the 1st...n-th
|
|
|
|
certificate data. Hence, the first offset entry, i.e. the uint32 at the very start of the bundle,
|
|
|
|
is equal to the size of the offset list in bytes and therefore the # of certificates in the bundle
|
|
|
|
is [first offset]/sizeof(uint32_t)
|
|
|
|
[offset of 1st certificate](u32)
|
|
|
|
[offset of 2nd certificate](u32)
|
|
|
|
...
|
|
|
|
[offset of n-th certificate](u32)
|
|
|
|
[1st certificate](variable)
|
|
|
|
...
|
|
|
|
[n-th certificate](variable)
|
|
|
|
|
|
|
|
Structure of each certificate:
|
|
|
|
[length of CN](u16)
|
|
|
|
[length of key](u16)
|
|
|
|
[CN](variable)
|
|
|
|
[key](variable)
|
|
|
|
|
|
|
|
The offset list is used for fast random access to any certificate by index.
|
|
|
|
For verification, a certificate is looked up by its CN via binary search; for this reason,
|
|
|
|
the offset list *must* be sorted by CN (ascending) and the first certificate must be the
|
|
|
|
one with the least CN in the bundle, so that the first offset in the list still refers to the
|
|
|
|
first certificate after the list (see above).
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define CRT_NAME_LEN_OFFSET 0 //<! offset of certificate name length value
|
|
|
|
#define CRT_KEY_LEN_OFFSET (CRT_NAME_LEN_OFFSET + sizeof(uint16_t)) //<! offset of certificate key length value
|
|
|
|
#define CRT_NAME_OFFSET (CRT_KEY_LEN_OFFSET + sizeof(uint16_t)) //<! certificate name data starts here
|
|
|
|
|
|
|
|
#define CRT_HEADER_SIZE CRT_NAME_OFFSET //<! size of certificate header
|
2019-09-29 18:04:34 +08:00
|
|
|
|
|
|
|
static const char *TAG = "esp-x509-crt-bundle";
|
|
|
|
|
|
|
|
/* a dummy certificate so that
|
|
|
|
* cacert_ptr passes non-NULL check during handshake */
|
2024-10-10 12:34:32 +05:30
|
|
|
static const mbedtls_x509_crt s_dummy_crt;
|
2019-09-29 18:04:34 +08:00
|
|
|
|
|
|
|
extern const uint8_t x509_crt_imported_bundle_bin_start[] asm("_binary_x509_crt_bundle_start");
|
|
|
|
extern const uint8_t x509_crt_imported_bundle_bin_end[] asm("_binary_x509_crt_bundle_end");
|
|
|
|
|
2023-07-09 23:37:40 +02:00
|
|
|
typedef const uint8_t* bundle_t;
|
|
|
|
typedef const uint8_t* cert_t;
|
2019-09-29 18:04:34 +08:00
|
|
|
|
2023-07-09 23:37:40 +02:00
|
|
|
static bundle_t s_crt_bundle;
|
2019-09-29 18:04:34 +08:00
|
|
|
|
2023-07-09 23:37:40 +02:00
|
|
|
// Read a 16-bit value stored in little-endian format from the given address
|
2024-06-28 11:15:40 +05:30
|
|
|
static uint16_t get16_le(const uint8_t* ptr)
|
|
|
|
{
|
2023-07-09 23:37:40 +02:00
|
|
|
#if defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
|
|
|
|
return *((const uint16_t*)ptr);
|
|
|
|
#else
|
|
|
|
return (((uint16_t)ptr[1]) << 8) | ptr[0];
|
|
|
|
#endif
|
|
|
|
}
|
2019-09-29 18:04:34 +08:00
|
|
|
|
2024-06-28 11:15:40 +05:30
|
|
|
static uint16_t esp_crt_get_name_len(const cert_t cert)
|
|
|
|
{
|
2023-07-09 23:37:40 +02:00
|
|
|
return get16_le(cert + CRT_NAME_LEN_OFFSET);
|
|
|
|
}
|
2019-09-29 18:04:34 +08:00
|
|
|
|
2024-06-28 11:15:40 +05:30
|
|
|
static const uint8_t* esp_crt_get_name(const cert_t cert)
|
|
|
|
{
|
2023-07-09 23:37:40 +02:00
|
|
|
return cert + CRT_NAME_OFFSET;
|
|
|
|
}
|
|
|
|
|
2024-06-28 11:15:40 +05:30
|
|
|
static uint16_t esp_crt_get_key_len(const cert_t cert)
|
|
|
|
{
|
2023-07-09 23:37:40 +02:00
|
|
|
return get16_le(cert + CRT_KEY_LEN_OFFSET);
|
|
|
|
}
|
|
|
|
|
2024-06-28 11:15:40 +05:30
|
|
|
static const uint8_t* esp_crt_get_key(const cert_t cert)
|
|
|
|
{
|
2023-07-09 23:37:40 +02:00
|
|
|
return esp_crt_get_name(cert) + esp_crt_get_name_len(cert);
|
|
|
|
}
|
|
|
|
|
2024-06-28 11:15:40 +05:30
|
|
|
static uint16_t esp_crt_get_len(const cert_t cert)
|
|
|
|
{
|
2023-07-09 23:37:40 +02:00
|
|
|
return CRT_HEADER_SIZE + esp_crt_get_name_len(cert) + esp_crt_get_key_len(cert);
|
|
|
|
}
|
|
|
|
|
2024-06-28 11:15:40 +05:30
|
|
|
static uint32_t esp_crt_get_cert_offset(const bundle_t bundle, const uint32_t index)
|
|
|
|
{
|
2023-07-09 23:37:40 +02:00
|
|
|
return ((const uint32_t*)bundle)[index];
|
|
|
|
}
|
|
|
|
|
2024-06-28 11:15:40 +05:30
|
|
|
static uint32_t esp_crt_get_certcount(const bundle_t bundle)
|
|
|
|
{
|
2023-07-09 23:37:40 +02:00
|
|
|
// Offset of 1st certificate == end of offset list == size of offset list == # of certs * sizeof(uint32_t)
|
|
|
|
return esp_crt_get_cert_offset(bundle, 0) / sizeof(uint32_t);
|
|
|
|
}
|
2019-09-29 18:04:34 +08:00
|
|
|
|
2023-07-09 23:37:40 +02:00
|
|
|
/**
|
|
|
|
* @brief Get the certificate at the given index within a bundle.
|
|
|
|
*
|
|
|
|
* @param bundle pointer to the \c bundle_t
|
|
|
|
* @param index of the certificate; must be less than \c esp_crt_get_certcount(...) !
|
|
|
|
* @return pointer to the certificate
|
|
|
|
*/
|
2024-06-28 11:15:40 +05:30
|
|
|
static cert_t esp_crt_get_cert(const bundle_t bundle, const uint32_t index)
|
|
|
|
{
|
2023-07-09 23:37:40 +02:00
|
|
|
return bundle + esp_crt_get_cert_offset(bundle, index);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int esp_crt_check_signature(const mbedtls_x509_crt* child, const uint8_t* pub_key_buf, const size_t pub_key_len)
|
2019-09-29 18:04:34 +08:00
|
|
|
{
|
2020-03-26 10:53:50 +08:00
|
|
|
int ret = 0;
|
2023-07-09 23:37:40 +02:00
|
|
|
mbedtls_pk_context pubkey;
|
2019-09-29 18:04:34 +08:00
|
|
|
const mbedtls_md_info_t *md_info;
|
|
|
|
|
2023-07-09 23:37:40 +02:00
|
|
|
mbedtls_pk_init(&pubkey);
|
2019-09-29 18:04:34 +08:00
|
|
|
|
2024-06-28 11:15:40 +05:30
|
|
|
if (unlikely((ret = mbedtls_pk_parse_public_key(&pubkey, pub_key_buf, pub_key_len)) != 0)) {
|
2023-07-09 23:37:40 +02:00
|
|
|
ESP_LOGE(TAG, "PK parse failed with error 0x%x", -ret);
|
2020-03-26 10:53:50 +08:00
|
|
|
goto cleanup;
|
2019-09-29 18:04:34 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Fast check to avoid expensive computations when not necessary
|
2024-06-28 11:15:40 +05:30
|
|
|
if (unlikely(!mbedtls_pk_can_do(&pubkey, child->MBEDTLS_PRIVATE(sig_pk)))) {
|
2023-07-09 23:37:40 +02:00
|
|
|
ESP_LOGE(TAG, "Unsuitable public key");
|
|
|
|
ret = MBEDTLS_ERR_PK_TYPE_MISMATCH;
|
2020-03-26 10:53:50 +08:00
|
|
|
goto cleanup;
|
2019-09-29 18:04:34 +08:00
|
|
|
}
|
|
|
|
|
2021-08-09 15:28:36 +05:30
|
|
|
md_info = mbedtls_md_info_from_type(child->MBEDTLS_PRIVATE(sig_md));
|
2023-07-09 23:37:40 +02:00
|
|
|
|
2024-06-28 11:15:40 +05:30
|
|
|
if (unlikely(md_info == NULL)) {
|
2023-07-09 23:37:40 +02:00
|
|
|
ESP_LOGE(TAG, "Unknown message digest");
|
|
|
|
ret = MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE;
|
2020-03-26 10:53:50 +08:00
|
|
|
goto cleanup;
|
2019-09-29 18:04:34 +08:00
|
|
|
}
|
|
|
|
|
2023-07-09 23:37:40 +02:00
|
|
|
unsigned char hash[MBEDTLS_MD_MAX_SIZE];
|
|
|
|
const unsigned char md_size = mbedtls_md_get_size(md_info);
|
2019-09-29 18:04:34 +08:00
|
|
|
|
2023-07-09 23:37:40 +02:00
|
|
|
if ((ret = mbedtls_md(md_info, child->tbs.p, child->tbs.len, hash)) != 0) {
|
|
|
|
ESP_LOGE(TAG, "MD failed with error 0x%x", -ret);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2024-06-28 11:15:40 +05:30
|
|
|
if (unlikely((ret = mbedtls_pk_verify_ext(child->MBEDTLS_PRIVATE(sig_pk), child->MBEDTLS_PRIVATE(sig_opts), &pubkey,
|
|
|
|
child->MBEDTLS_PRIVATE(sig_md), hash, md_size,
|
|
|
|
child->MBEDTLS_PRIVATE(sig).p, child->MBEDTLS_PRIVATE(sig).len)) != 0)) {
|
2023-07-09 23:37:40 +02:00
|
|
|
ESP_LOGE(TAG, "PK verify failed with error 0x%x", -ret);
|
2020-03-26 10:53:50 +08:00
|
|
|
goto cleanup;
|
2019-09-29 18:04:34 +08:00
|
|
|
}
|
2020-03-26 10:53:50 +08:00
|
|
|
|
2023-07-09 23:37:40 +02:00
|
|
|
cleanup:
|
|
|
|
mbedtls_pk_free(&pubkey);
|
2020-03-26 10:53:50 +08:00
|
|
|
return ret;
|
2019-09-29 18:04:34 +08:00
|
|
|
}
|
|
|
|
|
2023-07-09 23:37:40 +02:00
|
|
|
static cert_t esp_crt_find_cert(const unsigned char* const issuer, const size_t issuer_len)
|
|
|
|
{
|
2024-06-28 11:15:40 +05:30
|
|
|
if (unlikely(issuer == NULL || issuer_len == 0)) {
|
2023-07-09 23:37:40 +02:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
int start = 0;
|
2024-06-28 11:15:40 +05:30
|
|
|
int end = esp_crt_get_certcount(s_crt_bundle) - 1;
|
2023-07-09 23:37:40 +02:00
|
|
|
int middle = (start + end) / 2;
|
|
|
|
|
|
|
|
cert_t cert = NULL;
|
|
|
|
size_t cert_name_len = 0;
|
|
|
|
|
|
|
|
/* Look for the certificate using binary search on subject name */
|
|
|
|
while (start <= end) {
|
|
|
|
cert = esp_crt_get_cert(s_crt_bundle, middle);
|
|
|
|
cert_name_len = esp_crt_get_name_len(cert);
|
|
|
|
|
|
|
|
// Issuers are in DER encoding, with lengths encoded in the content; if valid DER, differing lengths
|
|
|
|
// are reflected in differing content.
|
|
|
|
// Still, we won't try to memcmp beyond the given length:
|
2024-06-28 11:15:40 +05:30
|
|
|
int cmp_res = memcmp(issuer, esp_crt_get_name(cert), MIN(issuer_len, cert_name_len));
|
2023-07-09 23:37:40 +02:00
|
|
|
|
2024-06-28 11:15:40 +05:30
|
|
|
if (unlikely(cmp_res == 0)) {
|
2023-07-09 23:37:40 +02:00
|
|
|
return cert;
|
|
|
|
} else if (cmp_res < 0) {
|
|
|
|
end = middle - 1;
|
|
|
|
} else {
|
|
|
|
start = middle + 1;
|
|
|
|
}
|
|
|
|
middle = (start + end) / 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2019-09-29 18:04:34 +08:00
|
|
|
|
|
|
|
/* This callback is called for every certificate in the chain. If the chain
|
|
|
|
* is proper each intermediate certificate is validated through its parent
|
|
|
|
* in the x509_crt_verify_chain() function. So this callback should
|
|
|
|
* only verify the first untrusted link in the chain is signed by the
|
|
|
|
* root certificate in the trusted bundle
|
|
|
|
*/
|
2023-07-09 23:37:40 +02:00
|
|
|
int esp_crt_verify_callback(void *buf, mbedtls_x509_crt* const crt, const int depth, uint32_t* const flags)
|
2019-09-29 18:04:34 +08:00
|
|
|
{
|
2023-07-09 23:37:40 +02:00
|
|
|
const mbedtls_x509_crt* const child = crt;
|
2019-09-29 18:04:34 +08:00
|
|
|
|
2020-11-26 15:22:41 +08:00
|
|
|
/* It's OK for a trusted cert to have a weak signature hash alg.
|
|
|
|
as we already trust this certificate */
|
|
|
|
uint32_t flags_filtered = *flags & ~(MBEDTLS_X509_BADCERT_BAD_MD);
|
|
|
|
|
|
|
|
if (flags_filtered != MBEDTLS_X509_BADCERT_NOT_TRUSTED) {
|
2019-09-29 18:04:34 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2024-06-28 11:15:40 +05:30
|
|
|
|
|
|
|
if (unlikely(s_crt_bundle == NULL)) {
|
2019-09-29 18:04:34 +08:00
|
|
|
ESP_LOGE(TAG, "No certificates in bundle");
|
|
|
|
return MBEDTLS_ERR_X509_FATAL_ERROR;
|
|
|
|
}
|
|
|
|
|
2023-07-09 23:37:40 +02:00
|
|
|
ESP_LOGD(TAG, "%" PRIu16 " certificates in bundle", (uint16_t)esp_crt_get_certcount(s_crt_bundle));
|
2019-09-29 18:04:34 +08:00
|
|
|
|
2023-07-09 23:37:40 +02:00
|
|
|
cert_t cert = esp_crt_find_cert(child->issuer_raw.p, child->issuer_raw.len);
|
2019-09-29 18:04:34 +08:00
|
|
|
|
2024-06-28 11:15:40 +05:30
|
|
|
if (likely(cert != NULL)) {
|
2019-09-29 18:04:34 +08:00
|
|
|
|
2023-07-09 23:37:40 +02:00
|
|
|
const int ret = esp_crt_check_signature(child, esp_crt_get_key(cert), esp_crt_get_key_len(cert));
|
2019-09-29 18:04:34 +08:00
|
|
|
|
2024-06-28 11:15:40 +05:30
|
|
|
if (likely(ret == 0)) {
|
2023-07-09 23:37:40 +02:00
|
|
|
ESP_LOGI(TAG, "Certificate validated");
|
|
|
|
*flags = 0;
|
|
|
|
return 0;
|
2019-09-29 18:04:34 +08:00
|
|
|
} else {
|
2023-07-09 23:37:40 +02:00
|
|
|
ESP_LOGE(TAG, "Certificate matched but signature verification failed");
|
|
|
|
#if (CONFIG_LOG_DEFAULT_LEVEL_DEBUG || CONFIG_LOG_DEFAULT_LEVEL_VERBOSE)
|
|
|
|
char *cert_name = malloc((esp_crt_get_name_len(cert) + 1) * sizeof(char));
|
|
|
|
if (cert_name) {
|
|
|
|
memcpy(cert_name, esp_crt_get_name(cert), esp_crt_get_name_len(cert));
|
|
|
|
cert_name[esp_crt_get_name_len(cert)] = '\0';
|
|
|
|
ESP_LOGE(TAG, "Certificate matched with %s but signature verification failed", cert_name);
|
|
|
|
free(cert_name);
|
|
|
|
}
|
|
|
|
#endif
|
2019-09-29 18:04:34 +08:00
|
|
|
}
|
|
|
|
|
2023-07-09 23:37:40 +02:00
|
|
|
} else {
|
|
|
|
ESP_LOGI(TAG, "No matching trusted root certificate found");
|
2019-09-29 18:04:34 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
ESP_LOGE(TAG, "Failed to verify certificate");
|
2023-07-09 23:37:40 +02:00
|
|
|
return MBEDTLS_ERR_X509_CERT_VERIFY_FAILED;
|
2019-09-29 18:04:34 +08:00
|
|
|
}
|
|
|
|
|
2023-07-09 23:37:40 +02:00
|
|
|
/**
|
|
|
|
* @brief Perform some consistency checks on the user-provided bundle data to try and make sure
|
|
|
|
* it actually is a certificate bundle.
|
|
|
|
*
|
|
|
|
* @param x509_bundle pointer to the bundle data
|
|
|
|
* @param bundle_size size of bundle data
|
|
|
|
* @return true the given bundle data is consistent
|
|
|
|
* @return false the given bundle data is invalid
|
2019-09-29 18:04:34 +08:00
|
|
|
*/
|
2023-07-09 23:37:40 +02:00
|
|
|
static bool esp_crt_check_bundle(const uint8_t* const x509_bundle, const size_t bundle_size)
|
2019-09-29 18:04:34 +08:00
|
|
|
{
|
2024-06-28 11:15:40 +05:30
|
|
|
if (unlikely(x509_bundle == NULL || bundle_size <= (sizeof(uint32_t) + CRT_HEADER_SIZE))) {
|
2023-07-09 23:37:40 +02:00
|
|
|
// Bundle is too small for even one offset and one certificate
|
|
|
|
return false;
|
2022-03-30 09:27:46 +05:30
|
|
|
}
|
2019-09-29 18:04:34 +08:00
|
|
|
|
2023-07-09 23:37:40 +02:00
|
|
|
// Pointer to the first offset entry
|
|
|
|
const uint32_t* offsets = (const uint32_t*)x509_bundle;
|
|
|
|
|
2024-06-28 11:15:40 +05:30
|
|
|
if (unlikely(offsets[0] == 0 || (offsets[0] % sizeof(uint32_t)) != 0)) {
|
2023-07-09 23:37:40 +02:00
|
|
|
// First offset is invalid.
|
|
|
|
// The first certificate must start after N uint32_t offset values.
|
|
|
|
return false;
|
2022-03-30 09:27:46 +05:30
|
|
|
}
|
|
|
|
|
2024-06-28 11:15:40 +05:30
|
|
|
if (unlikely(offsets[0] >= bundle_size)) {
|
2023-07-09 23:37:40 +02:00
|
|
|
// First cert starts beyond end of bundle
|
|
|
|
return false;
|
2019-09-29 18:04:34 +08:00
|
|
|
}
|
|
|
|
|
2023-07-09 23:37:40 +02:00
|
|
|
const uint32_t num_certs = esp_crt_get_certcount(x509_bundle);
|
2019-09-29 18:04:34 +08:00
|
|
|
|
2024-06-28 11:15:40 +05:30
|
|
|
if (unlikely(num_certs > CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_MAX_CERTS)) {
|
2023-07-09 23:37:40 +02:00
|
|
|
ESP_LOGE(TAG, "Cert bundle certificates exceed max allowed certificates");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check all offsets for consistency with certificate data
|
2024-06-28 11:15:40 +05:30
|
|
|
for (uint32_t i = 0; i < num_certs - 1; ++i) {
|
2023-07-09 23:37:40 +02:00
|
|
|
const uint32_t off = offsets[i];
|
|
|
|
cert_t cert = x509_bundle + off;
|
|
|
|
// The next offset in the list must point to right after the current cert
|
|
|
|
const uint32_t expected_next_offset = off + esp_crt_get_len(cert);
|
|
|
|
|
2024-06-28 11:15:40 +05:30
|
|
|
if (unlikely(offsets[i + 1] != expected_next_offset || expected_next_offset >= bundle_size)) {
|
2023-07-09 23:37:40 +02:00
|
|
|
return false;
|
2022-03-30 09:27:46 +05:30
|
|
|
}
|
2019-09-29 18:04:34 +08:00
|
|
|
}
|
|
|
|
|
2023-07-09 23:37:40 +02:00
|
|
|
// All checks passed.
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
the bundle generated by the python utility is already presorted by subject name
|
|
|
|
*/
|
|
|
|
static esp_err_t esp_crt_bundle_init(const uint8_t* const x509_bundle, const size_t bundle_size)
|
|
|
|
{
|
2024-06-28 11:15:40 +05:30
|
|
|
if (likely(esp_crt_check_bundle(x509_bundle, bundle_size))) {
|
2023-07-09 23:37:40 +02:00
|
|
|
s_crt_bundle = x509_bundle;
|
|
|
|
return ESP_OK;
|
|
|
|
} else {
|
2022-03-30 09:27:46 +05:30
|
|
|
return ESP_ERR_INVALID_ARG;
|
|
|
|
}
|
2019-09-29 18:04:34 +08:00
|
|
|
}
|
|
|
|
|
2020-03-11 15:48:34 +05:30
|
|
|
esp_err_t esp_crt_bundle_attach(void *conf)
|
2019-09-29 18:04:34 +08:00
|
|
|
{
|
|
|
|
esp_err_t ret = ESP_OK;
|
|
|
|
// If no bundle has been set by the user then use the bundle embedded in the binary
|
2023-07-09 23:37:40 +02:00
|
|
|
if (s_crt_bundle == NULL) {
|
2022-03-30 09:27:46 +05:30
|
|
|
ret = esp_crt_bundle_init(x509_crt_imported_bundle_bin_start, x509_crt_imported_bundle_bin_end - x509_crt_imported_bundle_bin_start);
|
2019-09-29 18:04:34 +08:00
|
|
|
}
|
|
|
|
|
2024-06-28 11:15:40 +05:30
|
|
|
if (unlikely(ret != ESP_OK)) {
|
2019-09-29 18:04:34 +08:00
|
|
|
ESP_LOGE(TAG, "Failed to attach bundle");
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (conf) {
|
|
|
|
/* point to a dummy certificate
|
|
|
|
* This is only required so that the
|
|
|
|
* cacert_ptr passes non-NULL check during handshake
|
|
|
|
*/
|
2020-05-21 14:48:17 +08:00
|
|
|
mbedtls_ssl_config *ssl_conf = (mbedtls_ssl_config *)conf;
|
2023-07-09 23:37:40 +02:00
|
|
|
mbedtls_ssl_conf_ca_chain(ssl_conf, (mbedtls_x509_crt*)&s_dummy_crt, NULL);
|
2020-05-21 14:48:17 +08:00
|
|
|
mbedtls_ssl_conf_verify(ssl_conf, esp_crt_verify_callback, NULL);
|
2019-09-29 18:04:34 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
void esp_crt_bundle_detach(mbedtls_ssl_config *conf)
|
|
|
|
{
|
2023-07-09 23:37:40 +02:00
|
|
|
s_crt_bundle = NULL;
|
2019-09-29 18:04:34 +08:00
|
|
|
if (conf) {
|
|
|
|
mbedtls_ssl_conf_verify(conf, NULL, NULL);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-03-30 09:27:46 +05:30
|
|
|
esp_err_t esp_crt_bundle_set(const uint8_t *x509_bundle, size_t bundle_size)
|
2019-09-29 18:04:34 +08:00
|
|
|
{
|
2022-03-30 09:27:46 +05:30
|
|
|
return esp_crt_bundle_init(x509_bundle, bundle_size);
|
2019-09-29 18:04:34 +08:00
|
|
|
}
|
2024-10-10 12:34:32 +05:30
|
|
|
|
|
|
|
bool esp_crt_bundle_in_use(const mbedtls_x509_crt* ca_chain)
|
|
|
|
{
|
|
|
|
return ((ca_chain == &s_dummy_crt) ? true : false);
|
|
|
|
}
|