From d8e31eb6d01a6a472b293564be65a657e2197490 Mon Sep 17 00:00:00 2001 From: Hanno Date: Sun, 9 Jul 2023 23:37:40 +0200 Subject: [PATCH 1/4] feat(mbedtls/esp_crt_bundle): Reduced RAM & stack use of cert bundle Closes https://github.com/espressif/esp-idf/pull/13204 Signed-off-by: harshal.patil --- components/mbedtls/CMakeLists.txt | 2 +- .../mbedtls/esp_crt_bundle/esp_crt_bundle.c | 357 ++++++++++++------ .../mbedtls/esp_crt_bundle/gen_crt_bundle.py | 37 +- .../test_gen_crt_bundle/baltimore_crt_bundle | Bin 392 -> 394 bytes .../test_gen_crt_bundle/entrust_crt_bundle | Bin 479 -> 481 bytes .../test_apps/main/crts/server_cert_bundle | Bin 400 -> 402 bytes 6 files changed, 264 insertions(+), 132 deletions(-) diff --git a/components/mbedtls/CMakeLists.txt b/components/mbedtls/CMakeLists.txt index 93cb165b43..94033218ce 100644 --- a/components/mbedtls/CMakeLists.txt +++ b/components/mbedtls/CMakeLists.txt @@ -61,7 +61,7 @@ if(CONFIG_MBEDTLS_CERTIFICATE_BUNDLE) list(APPEND crt_paths ${custom_bundle_path}) endif() - list(APPEND args --input ${crt_paths} -q) + list(APPEND args --input ${crt_paths} -q --max-certs "${CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_MAX_CERTS}") get_filename_component(crt_bundle ${bundle_name} diff --git a/components/mbedtls/esp_crt_bundle/esp_crt_bundle.c b/components/mbedtls/esp_crt_bundle/esp_crt_bundle.c index 2da3850087..ef2e85542f 100644 --- a/components/mbedtls/esp_crt_bundle/esp_crt_bundle.c +++ b/components/mbedtls/esp_crt_bundle/esp_crt_bundle.c @@ -1,15 +1,54 @@ /* - * SPDX-FileCopyrightText: 2018-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2018-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #include #include +#include + +#include "esp_check.h" #include "esp_crt_bundle.h" #include "esp_log.h" -#define BUNDLE_HEADER_OFFSET 2 -#define CRT_HEADER_OFFSET 4 +#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 //MBEDTLS_PRIVATE(sig_pk))) { - ESP_LOGE(TAG, "Simple compare failed"); - ret = -1; + if ( unlikely( !mbedtls_pk_can_do( &pubkey, child->MBEDTLS_PRIVATE(sig_pk)) ) ) { + ESP_LOGE(TAG, "Unsuitable public key"); + ret = MBEDTLS_ERR_PK_TYPE_MISMATCH; goto cleanup; } md_info = mbedtls_md_info_from_type(child->MBEDTLS_PRIVATE(sig_md)); - if ( (ret = mbedtls_md( md_info, child->tbs.p, child->tbs.len, hash )) != 0 ) { - ESP_LOGE(TAG, "Internal mbedTLS error %X", ret); + + if( unlikely( md_info == NULL) ) { + ESP_LOGE(TAG, "Unknown message digest"); + ret = MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE; goto cleanup; } - if ( (ret = mbedtls_pk_verify_ext( child->MBEDTLS_PRIVATE(sig_pk), child->MBEDTLS_PRIVATE(sig_opts), &parent.pk, - child->MBEDTLS_PRIVATE(sig_md), hash, mbedtls_md_get_size( md_info ), - child->MBEDTLS_PRIVATE(sig).p, child->MBEDTLS_PRIVATE(sig).len )) != 0 ) { + unsigned char hash[MBEDTLS_MD_MAX_SIZE]; + const unsigned char md_size = mbedtls_md_get_size(md_info); - ESP_LOGE(TAG, "PK verify failed with error %X", ret); + 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; } + + 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 ) ) { + ESP_LOGE(TAG, "PK verify failed with error 0x%x", -ret); + goto cleanup; + } + cleanup: - mbedtls_x509_crt_free(&parent); - + mbedtls_pk_free(&pubkey); return ret; } +static cert_t esp_crt_find_cert(const unsigned char* const issuer, const size_t issuer_len) +{ + if (unlikely( issuer == NULL || issuer_len == 0 )) { + return NULL; + } + + int start = 0; + int end = esp_crt_get_certcount(s_crt_bundle)-1; + 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: + int cmp_res = memcmp(issuer, esp_crt_get_name(cert), MIN(issuer_len, cert_name_len) ); + + if ( unlikely( cmp_res == 0 ) ) { + return cert; + } else if (cmp_res < 0) { + end = middle - 1; + } else { + start = middle + 1; + } + middle = (start + end) / 2; + } + + return NULL; +} + /* This callback is called for every certificate in the chain. If the chain * is proper each intermediate certificate is validated through its parent @@ -81,9 +204,9 @@ cleanup: * only verify the first untrusted link in the chain is signed by the * root certificate in the trusted bundle */ -int esp_crt_verify_callback(void *buf, mbedtls_x509_crt *crt, int depth, uint32_t *flags) +int esp_crt_verify_callback(void *buf, mbedtls_x509_crt* const crt, const int depth, uint32_t* const flags) { - mbedtls_x509_crt *child = crt; + const mbedtls_x509_crt* const child = crt; /* It's OK for a trusted cert to have a weak signature hash alg. as we already trust this certificate */ @@ -93,121 +216,119 @@ int esp_crt_verify_callback(void *buf, mbedtls_x509_crt *crt, int depth, uint32_ return 0; } - - if (s_crt_bundle.crts == NULL) { + if( unlikely( s_crt_bundle == NULL ) ) { ESP_LOGE(TAG, "No certificates in bundle"); return MBEDTLS_ERR_X509_FATAL_ERROR; } - ESP_LOGD(TAG, "%d certificates in bundle", s_crt_bundle.num_certs); + ESP_LOGD(TAG, "%" PRIu16 " certificates in bundle", (uint16_t)esp_crt_get_certcount(s_crt_bundle)); - size_t name_len = 0; - const uint8_t *crt_name; + cert_t cert = esp_crt_find_cert(child->issuer_raw.p, child->issuer_raw.len); - bool crt_found = false; - int start = 0; - int end = s_crt_bundle.num_certs - 1; - int middle = (end - start) / 2; + if ( likely( cert != NULL ) ) { - /* Look for the certificate using binary search on subject name */ - while (start <= end) { - name_len = s_crt_bundle.crts[middle][0] << 8 | s_crt_bundle.crts[middle][1]; - crt_name = s_crt_bundle.crts[middle] + CRT_HEADER_OFFSET; + const int ret = esp_crt_check_signature(child, esp_crt_get_key(cert), esp_crt_get_key_len(cert)); - int cmp_res = memcmp(child->issuer_raw.p, crt_name, name_len ); - if (cmp_res == 0) { - crt_found = true; - break; - } else if (cmp_res < 0) { - end = middle - 1; + if ( likely( ret == 0 ) ) { + ESP_LOGI(TAG, "Certificate validated"); + *flags = 0; + return 0; } else { - start = middle + 1; + 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 } - middle = (start + end) / 2; - } - int ret = MBEDTLS_ERR_X509_FATAL_ERROR; - if (crt_found) { - size_t key_len = s_crt_bundle.crts[middle][2] << 8 | s_crt_bundle.crts[middle][3]; - ret = esp_crt_check_signature(child, s_crt_bundle.crts[middle] + CRT_HEADER_OFFSET + name_len, key_len); - } - - if (ret == 0) { - ESP_LOGI(TAG, "Certificate validated"); - *flags = 0; - return 0; + } else { + ESP_LOGI(TAG, "No matching trusted root certificate found"); } ESP_LOGE(TAG, "Failed to verify certificate"); - return MBEDTLS_ERR_X509_FATAL_ERROR; + return MBEDTLS_ERR_X509_CERT_VERIFY_FAILED; } +/** + * @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 + */ +static bool esp_crt_check_bundle(const uint8_t* const x509_bundle, const size_t bundle_size) +{ + if (unlikely( x509_bundle == NULL || bundle_size <= (sizeof(uint32_t) + CRT_HEADER_SIZE)) ) { + // Bundle is too small for even one offset and one certificate + return false; + } -/* Initialize the bundle into an array so we can do binary search for certs, + // Pointer to the first offset entry + const uint32_t* offsets = (const uint32_t*)x509_bundle; + + if(unlikely( offsets[0] == 0 || (offsets[0] % sizeof(uint32_t)) != 0) ) { + // First offset is invalid. + // The first certificate must start after N uint32_t offset values. + return false; + } + + if(unlikely( offsets[0] >= bundle_size )) { + // First cert starts beyond end of bundle + return false; + } + + const uint32_t num_certs = esp_crt_get_certcount(x509_bundle); + + if(unlikely( num_certs > CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_MAX_CERTS )) { + ESP_LOGE(TAG, "Cert bundle certificates exceed max allowed certificates"); + return false; + } + + // Check all offsets for consistency with certificate data + for (uint32_t i = 0; i < num_certs-1; ++i ) { + 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); + + if( unlikely( offsets[i+1] != expected_next_offset || expected_next_offset >= bundle_size ) ) { + return false; + } + } + + // 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 *x509_bundle, size_t bundle_size) +static esp_err_t esp_crt_bundle_init(const uint8_t* const x509_bundle, const size_t bundle_size) { - if (bundle_size < BUNDLE_HEADER_OFFSET + CRT_HEADER_OFFSET) { - ESP_LOGE(TAG, "Invalid certificate bundle"); + if ( likely( esp_crt_check_bundle(x509_bundle, bundle_size) ) ) { + s_crt_bundle = x509_bundle; + return ESP_OK; + } else { return ESP_ERR_INVALID_ARG; } - - uint16_t num_certs = (x509_bundle[0] << 8) | x509_bundle[1]; - if (num_certs > CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_MAX_CERTS) { - ESP_LOGE(TAG, "No. of certs in the certificate bundle = %d exceeds\n" - "Max allowed certificates in the certificate bundle = %d\n" - "Please update the menuconfig option with appropriate value", num_certs, CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_MAX_CERTS); - return ESP_ERR_INVALID_ARG; - } - - const uint8_t **crts = calloc(num_certs, sizeof(x509_bundle)); - if (crts == NULL) { - ESP_LOGE(TAG, "Unable to allocate memory for bundle"); - return ESP_ERR_NO_MEM; - } - - const uint8_t *cur_crt; - /* This is the maximum region that is allowed to access */ - const uint8_t *bundle_end = x509_bundle + bundle_size; - cur_crt = x509_bundle + BUNDLE_HEADER_OFFSET; - - for (int i = 0; i < num_certs; i++) { - crts[i] = cur_crt; - if (cur_crt + CRT_HEADER_OFFSET > bundle_end) { - ESP_LOGE(TAG, "Invalid certificate bundle"); - free(crts); - return ESP_ERR_INVALID_ARG; - } - size_t name_len = cur_crt[0] << 8 | cur_crt[1]; - size_t key_len = cur_crt[2] << 8 | cur_crt[3]; - cur_crt = cur_crt + CRT_HEADER_OFFSET + name_len + key_len; - } - - if (cur_crt > bundle_end) { - ESP_LOGE(TAG, "Invalid certificate bundle"); - free(crts); - return ESP_ERR_INVALID_ARG; - } - - /* The previous crt bundle is only updated when initialization of the - * current crt_bundle is successful */ - /* Free previous crt_bundle */ - free(s_crt_bundle.crts); - s_crt_bundle.num_certs = num_certs; - s_crt_bundle.crts = crts; - return ESP_OK; } esp_err_t esp_crt_bundle_attach(void *conf) { esp_err_t ret = ESP_OK; // If no bundle has been set by the user then use the bundle embedded in the binary - if (s_crt_bundle.crts == NULL) { + if (s_crt_bundle == NULL) { ret = esp_crt_bundle_init(x509_crt_imported_bundle_bin_start, x509_crt_imported_bundle_bin_end - x509_crt_imported_bundle_bin_start); } - if (ret != ESP_OK) { + if ( unlikely(ret != ESP_OK) ) { ESP_LOGE(TAG, "Failed to attach bundle"); return ret; } @@ -218,8 +339,7 @@ esp_err_t esp_crt_bundle_attach(void *conf) * cacert_ptr passes non-NULL check during handshake */ mbedtls_ssl_config *ssl_conf = (mbedtls_ssl_config *)conf; - mbedtls_x509_crt_init(&s_dummy_crt); - mbedtls_ssl_conf_ca_chain(ssl_conf, &s_dummy_crt, NULL); + mbedtls_ssl_conf_ca_chain(ssl_conf, (mbedtls_x509_crt*)&s_dummy_crt, NULL); mbedtls_ssl_conf_verify(ssl_conf, esp_crt_verify_callback, NULL); } @@ -228,8 +348,7 @@ esp_err_t esp_crt_bundle_attach(void *conf) void esp_crt_bundle_detach(mbedtls_ssl_config *conf) { - free(s_crt_bundle.crts); - s_crt_bundle.crts = NULL; + s_crt_bundle = NULL; if (conf) { mbedtls_ssl_conf_verify(conf, NULL, NULL); } diff --git a/components/mbedtls/esp_crt_bundle/gen_crt_bundle.py b/components/mbedtls/esp_crt_bundle/gen_crt_bundle.py index 0211514a46..2e5bca544b 100755 --- a/components/mbedtls/esp_crt_bundle/gen_crt_bundle.py +++ b/components/mbedtls/esp_crt_bundle/gen_crt_bundle.py @@ -8,18 +8,16 @@ # The bundle will have the format: number of certificates; crt 1 subject name length; crt 1 public key length; # crt 1 subject name; crt 1 public key; crt 2... # -# SPDX-FileCopyrightText: 2018-2022 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2018-2024 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: Apache-2.0 - -from __future__ import with_statement - import argparse import csv import os import re import struct import sys -from io import open + +DEFAULT_CERT_BUNDLE_MAX_CERTS = 200 try: from cryptography import x509 @@ -54,9 +52,6 @@ class CertificateBundle: self.certificates = [] self.compressed_crts = [] - if os.path.isfile(ca_bundle_bin_file): - os.remove(ca_bundle_bin_file) - def add_from_path(self, crts_path): found = False @@ -116,11 +111,21 @@ class CertificateBundle: self.certificates.append(x509.load_der_x509_certificate(crt_str, default_backend())) status('Successfully added 1 certificate') - def create_bundle(self): + def create_bundle(self, max_certs=DEFAULT_CERT_BUNDLE_MAX_CERTS): + if max_certs < len(self.certificates): + critical(f'No. of certs in the certificate bundle = {len(self.certificates)} exceeds\n \ + Max allowed certificates in the certificate bundle = {max_certs} \ + Please update the menuconfig option with appropriate value') + raise ValueError + # Sort certificates in order to do binary search when looking up certificates self.certificates = sorted(self.certificates, key=lambda cert: cert.subject.public_bytes(default_backend())) - bundle = struct.pack('>H', len(self.certificates)) + # List of offsets in bytes from the start of the bundle to each certificate inside + offsets = [] + len_offsets = 4 * len(self.certificates) # final size of the offsets list + + bundle = b'' for crt in self.certificates: """ Read the public key as DER format """ @@ -132,12 +137,18 @@ class CertificateBundle: name_len = len(sub_name_der) key_len = len(pub_key_der) - len_data = struct.pack('>HH', name_len, key_len) + len_data = struct.pack('Vgx$? diff --git a/components/mbedtls/test_apps/main/crts/server_cert_bundle b/components/mbedtls/test_apps/main/crts/server_cert_bundle index 0b7f09aa06da459957cb5c4df81df1876b9597b8..5a0a2f139f52aa4576798324076a533e2a8457a2 100644 GIT binary patch delta 17 YcmbQhJc*fug@J(~g+YyRBU=|E02>tp0ssI2 delta 15 WcmbQlJb{^wfsrAFQEekf7b5@{_X7U_ From b097eb12b38894f34ca2a05ea2d07bbada2f840a Mon Sep 17 00:00:00 2001 From: "harshal.patil" Date: Fri, 28 Jun 2024 11:15:40 +0530 Subject: [PATCH 2/4] ci(mbedtls/esp_crt_bundle): Format esp_crt_bundle.c using astyle --- .../mbedtls/esp_crt_bundle/esp_crt_bundle.c | 70 +++++++++++-------- 1 file changed, 40 insertions(+), 30 deletions(-) diff --git a/components/mbedtls/esp_crt_bundle/esp_crt_bundle.c b/components/mbedtls/esp_crt_bundle/esp_crt_bundle.c index ef2e85542f..dc75d0cff4 100644 --- a/components/mbedtls/esp_crt_bundle/esp_crt_bundle.c +++ b/components/mbedtls/esp_crt_bundle/esp_crt_bundle.c @@ -65,7 +65,8 @@ typedef const uint8_t* cert_t; static bundle_t s_crt_bundle; // Read a 16-bit value stored in little-endian format from the given address -static uint16_t get16_le (const uint8_t* ptr) { +static uint16_t get16_le(const uint8_t* ptr) +{ #if defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) return *((const uint16_t*)ptr); #else @@ -73,31 +74,38 @@ static uint16_t get16_le (const uint8_t* ptr) { #endif } -static uint16_t esp_crt_get_name_len(const cert_t cert) { +static uint16_t esp_crt_get_name_len(const cert_t cert) +{ return get16_le(cert + CRT_NAME_LEN_OFFSET); } -static const uint8_t* esp_crt_get_name(const cert_t cert) { +static const uint8_t* esp_crt_get_name(const cert_t cert) +{ return cert + CRT_NAME_OFFSET; } -static uint16_t esp_crt_get_key_len(const cert_t cert) { +static uint16_t esp_crt_get_key_len(const cert_t cert) +{ return get16_le(cert + CRT_KEY_LEN_OFFSET); } -static const uint8_t* esp_crt_get_key(const cert_t cert) { +static const uint8_t* esp_crt_get_key(const cert_t cert) +{ return esp_crt_get_name(cert) + esp_crt_get_name_len(cert); } -static uint16_t esp_crt_get_len(const cert_t cert) { +static uint16_t esp_crt_get_len(const cert_t cert) +{ return CRT_HEADER_SIZE + esp_crt_get_name_len(cert) + esp_crt_get_key_len(cert); } -static uint32_t esp_crt_get_cert_offset(const bundle_t bundle, const uint32_t index) { +static uint32_t esp_crt_get_cert_offset(const bundle_t bundle, const uint32_t index) +{ return ((const uint32_t*)bundle)[index]; } -static uint32_t esp_crt_get_certcount(const bundle_t bundle) { +static uint32_t esp_crt_get_certcount(const bundle_t bundle) +{ // 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); } @@ -109,7 +117,8 @@ static uint32_t esp_crt_get_certcount(const bundle_t bundle) { * @param index of the certificate; must be less than \c esp_crt_get_certcount(...) ! * @return pointer to the certificate */ -static cert_t esp_crt_get_cert(const bundle_t bundle, const uint32_t index) { +static cert_t esp_crt_get_cert(const bundle_t bundle, const uint32_t index) +{ return bundle + esp_crt_get_cert_offset(bundle, index); } @@ -121,13 +130,13 @@ static int esp_crt_check_signature(const mbedtls_x509_crt* child, const uint8_t* mbedtls_pk_init(&pubkey); - if ( unlikely( (ret = mbedtls_pk_parse_public_key(&pubkey, pub_key_buf, pub_key_len)) != 0 ) ) { + if (unlikely((ret = mbedtls_pk_parse_public_key(&pubkey, pub_key_buf, pub_key_len)) != 0)) { ESP_LOGE(TAG, "PK parse failed with error 0x%x", -ret); goto cleanup; } // Fast check to avoid expensive computations when not necessary - if ( unlikely( !mbedtls_pk_can_do( &pubkey, child->MBEDTLS_PRIVATE(sig_pk)) ) ) { + if (unlikely(!mbedtls_pk_can_do(&pubkey, child->MBEDTLS_PRIVATE(sig_pk)))) { ESP_LOGE(TAG, "Unsuitable public key"); ret = MBEDTLS_ERR_PK_TYPE_MISMATCH; goto cleanup; @@ -135,7 +144,7 @@ static int esp_crt_check_signature(const mbedtls_x509_crt* child, const uint8_t* md_info = mbedtls_md_info_from_type(child->MBEDTLS_PRIVATE(sig_md)); - if( unlikely( md_info == NULL) ) { + if (unlikely(md_info == NULL)) { ESP_LOGE(TAG, "Unknown message digest"); ret = MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE; goto cleanup; @@ -149,9 +158,9 @@ static int esp_crt_check_signature(const mbedtls_x509_crt* child, const uint8_t* goto cleanup; } - 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 ) ) { + 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)) { ESP_LOGE(TAG, "PK verify failed with error 0x%x", -ret); goto cleanup; } @@ -163,12 +172,12 @@ cleanup: static cert_t esp_crt_find_cert(const unsigned char* const issuer, const size_t issuer_len) { - if (unlikely( issuer == NULL || issuer_len == 0 )) { + if (unlikely(issuer == NULL || issuer_len == 0)) { return NULL; } int start = 0; - int end = esp_crt_get_certcount(s_crt_bundle)-1; + int end = esp_crt_get_certcount(s_crt_bundle) - 1; int middle = (start + end) / 2; cert_t cert = NULL; @@ -182,9 +191,9 @@ static cert_t esp_crt_find_cert(const unsigned char* const issuer, const size_t // 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: - int cmp_res = memcmp(issuer, esp_crt_get_name(cert), MIN(issuer_len, cert_name_len) ); + int cmp_res = memcmp(issuer, esp_crt_get_name(cert), MIN(issuer_len, cert_name_len)); - if ( unlikely( cmp_res == 0 ) ) { + if (unlikely(cmp_res == 0)) { return cert; } else if (cmp_res < 0) { end = middle - 1; @@ -216,7 +225,8 @@ int esp_crt_verify_callback(void *buf, mbedtls_x509_crt* const crt, const int de return 0; } - if( unlikely( s_crt_bundle == NULL ) ) { + + if (unlikely(s_crt_bundle == NULL)) { ESP_LOGE(TAG, "No certificates in bundle"); return MBEDTLS_ERR_X509_FATAL_ERROR; } @@ -225,11 +235,11 @@ int esp_crt_verify_callback(void *buf, mbedtls_x509_crt* const crt, const int de cert_t cert = esp_crt_find_cert(child->issuer_raw.p, child->issuer_raw.len); - if ( likely( cert != NULL ) ) { + if (likely(cert != NULL)) { const int ret = esp_crt_check_signature(child, esp_crt_get_key(cert), esp_crt_get_key_len(cert)); - if ( likely( ret == 0 ) ) { + if (likely(ret == 0)) { ESP_LOGI(TAG, "Certificate validated"); *flags = 0; return 0; @@ -265,7 +275,7 @@ int esp_crt_verify_callback(void *buf, mbedtls_x509_crt* const crt, const int de */ static bool esp_crt_check_bundle(const uint8_t* const x509_bundle, const size_t bundle_size) { - if (unlikely( x509_bundle == NULL || bundle_size <= (sizeof(uint32_t) + CRT_HEADER_SIZE)) ) { + if (unlikely(x509_bundle == NULL || bundle_size <= (sizeof(uint32_t) + CRT_HEADER_SIZE))) { // Bundle is too small for even one offset and one certificate return false; } @@ -273,32 +283,32 @@ static bool esp_crt_check_bundle(const uint8_t* const x509_bundle, const size_t // Pointer to the first offset entry const uint32_t* offsets = (const uint32_t*)x509_bundle; - if(unlikely( offsets[0] == 0 || (offsets[0] % sizeof(uint32_t)) != 0) ) { + if (unlikely(offsets[0] == 0 || (offsets[0] % sizeof(uint32_t)) != 0)) { // First offset is invalid. // The first certificate must start after N uint32_t offset values. return false; } - if(unlikely( offsets[0] >= bundle_size )) { + if (unlikely(offsets[0] >= bundle_size)) { // First cert starts beyond end of bundle return false; } const uint32_t num_certs = esp_crt_get_certcount(x509_bundle); - if(unlikely( num_certs > CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_MAX_CERTS )) { + if (unlikely(num_certs > CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_MAX_CERTS)) { ESP_LOGE(TAG, "Cert bundle certificates exceed max allowed certificates"); return false; } // Check all offsets for consistency with certificate data - for (uint32_t i = 0; i < num_certs-1; ++i ) { + for (uint32_t i = 0; i < num_certs - 1; ++i) { 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); - if( unlikely( offsets[i+1] != expected_next_offset || expected_next_offset >= bundle_size ) ) { + if (unlikely(offsets[i + 1] != expected_next_offset || expected_next_offset >= bundle_size)) { return false; } } @@ -312,7 +322,7 @@ static bool esp_crt_check_bundle(const uint8_t* const x509_bundle, const size_t */ static esp_err_t esp_crt_bundle_init(const uint8_t* const x509_bundle, const size_t bundle_size) { - if ( likely( esp_crt_check_bundle(x509_bundle, bundle_size) ) ) { + if (likely(esp_crt_check_bundle(x509_bundle, bundle_size))) { s_crt_bundle = x509_bundle; return ESP_OK; } else { @@ -328,7 +338,7 @@ esp_err_t esp_crt_bundle_attach(void *conf) ret = esp_crt_bundle_init(x509_crt_imported_bundle_bin_start, x509_crt_imported_bundle_bin_end - x509_crt_imported_bundle_bin_start); } - if ( unlikely(ret != ESP_OK) ) { + if (unlikely(ret != ESP_OK)) { ESP_LOGE(TAG, "Failed to attach bundle"); return ret; } From 20fff296e4eb65389b4468442b6a514d9b5716f3 Mon Sep 17 00:00:00 2001 From: "harshal.patil" Date: Mon, 15 Jul 2024 20:14:31 +0530 Subject: [PATCH 3/4] test(mbedtls): Update custom cert bundle init API - bound checking testcase - Support the newer cert bundle format in the test --- .../test_apps/main/test_esp_crt_bundle.c | 139 +++++++++++++----- 1 file changed, 99 insertions(+), 40 deletions(-) diff --git a/components/mbedtls/test_apps/main/test_esp_crt_bundle.c b/components/mbedtls/test_apps/main/test_esp_crt_bundle.c index 777af0425b..4b4ae1f927 100644 --- a/components/mbedtls/test_apps/main/test_esp_crt_bundle.c +++ b/components/mbedtls/test_apps/main/test_esp_crt_bundle.c @@ -6,8 +6,9 @@ * * SPDX-License-Identifier: Apache-2.0 * - * SPDX-FileContributor: 2019-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileContributor: 2019-2024 Espressif Systems (Shanghai) CO LTD */ +#include #include "esp_err.h" #include "esp_log.h" @@ -41,6 +42,7 @@ extern const uint8_t server_cert_chain_pem_end[] asm("_binary_server_cert_chai extern const uint8_t server_pk_start[] asm("_binary_prvtkey_pem_start"); extern const uint8_t server_pk_end[] asm("_binary_prvtkey_pem_end"); +// `server_cert_bundle_corrupt` is created by generating the cert bundle using `server_root.pem` extern const uint8_t server_cert_bundle_start[] asm("_binary_server_cert_bundle_start"); extern const uint8_t server_cert_bundle_end[] asm("_binary_server_cert_bundle_end"); @@ -272,7 +274,7 @@ void client_task(void *pvParameters) goto exit; } - /* Test with default crt bundle that doesnt contain the ca crt */ + /* Test with default crt bundle that does not contain the ca crt */ ESP_LOGI(TAG, "Connecting to %s:%s...", SERVER_ADDRESS, SERVER_PORT); if ((ret = mbedtls_net_connect(&client.client_fd, SERVER_ADDRESS, SERVER_PORT, MBEDTLS_NET_PROTO_TCP)) != 0) { ESP_LOGE(TAG, "mbedtls_net_connect returned -%x", -ret); @@ -300,7 +302,7 @@ void client_task(void *pvParameters) } else { ESP_LOGE(TAG, "Certificate verification failed!"); } - TEST_ASSERT(res == ESP_CRT_VALIDATE_FAIL); + TEST_ASSERT_EQUAL(ESP_CRT_VALIDATE_FAIL, res); // Reset session before new connection mbedtls_ssl_close_notify(&client.ssl); @@ -338,7 +340,7 @@ void client_task(void *pvParameters) } else { ESP_LOGE(TAG, "Certificate verification failed!"); } - TEST_ASSERT(res == ESP_CRT_VALIDATE_OK); + TEST_ASSERT_EQUAL(ESP_CRT_VALIDATE_OK, res); // Reset session before new connection mbedtls_ssl_close_notify(&client.ssl); @@ -406,7 +408,7 @@ TEST_CASE("custom certificate bundle - weak hash", "[mbedtls]") mbedtls_x509_crt_init( &crt ); mbedtls_x509_crt_parse(&crt, bad_md_crt_pem_start, bad_md_crt_pem_end - bad_md_crt_pem_start); - TEST_ASSERT(mbedtls_x509_crt_verify(&crt, NULL, NULL, NULL, &flags, esp_crt_verify_callback, NULL) == 0); + TEST_ASSERT_EQUAL(0, mbedtls_x509_crt_verify(&crt, NULL, NULL, NULL, &flags, esp_crt_verify_callback, NULL)); mbedtls_x509_crt_free(&crt); @@ -426,62 +428,119 @@ TEST_CASE("custom certificate bundle - wrong signature", "[mbedtls]") /* esp32.com cert chain where 1 byte in the signature is changed */ printf("Testing certificate with wrong signature\n"); mbedtls_x509_crt_parse(&crt, wrong_sig_crt_pem_start, wrong_sig_crt_pem_end - wrong_sig_crt_pem_start); - TEST_ASSERT(mbedtls_x509_crt_verify(&crt, NULL, NULL, NULL, &flags, esp_crt_verify_callback, NULL) != 0); + TEST_ASSERT_NOT_EQUAL(0, mbedtls_x509_crt_verify(&crt, NULL, NULL, NULL, &flags, esp_crt_verify_callback, NULL)); mbedtls_x509_crt_free(&crt); mbedtls_x509_crt_init( &crt ); /* the correct esp32.com cert chain*/ printf("Testing certificate with correct signature\n"); mbedtls_x509_crt_parse(&crt, correct_sig_crt_pem_start, correct_sig_crt_pem_end - correct_sig_crt_pem_start); - TEST_ASSERT(mbedtls_x509_crt_verify(&crt, NULL, NULL, NULL, &flags, esp_crt_verify_callback, NULL) == 0); + TEST_ASSERT_EQUAL(0, mbedtls_x509_crt_verify(&crt, NULL, NULL, NULL, &flags, esp_crt_verify_callback, NULL)); mbedtls_x509_crt_free(&crt); esp_crt_bundle_detach(NULL); } -TEST_CASE("custom certificate bundle init API - bound checking", "[mbedtls]") +TEST_CASE("custom certificate bundle init API - bound checking - NULL certificate bundle", "[mbedtls]") { - - uint8_t test_bundle[256] = {0}; esp_err_t esp_ret; + + /* The API should fail when NULL is passed as the bundle */ + esp_ret = esp_crt_bundle_set(NULL, 0); + TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_ret); +} + +TEST_CASE("custom certificate bundle init API - bound checking - Invalid size of certificate bundle", "[mbedtls]") +{ + uint8_t test_bundle[1024] = {0}; + esp_err_t esp_ret; + /* The API should fail with bundle size given as 1 */ esp_ret = esp_crt_bundle_set(test_bundle, 1); - TEST_ASSERT( esp_ret == ESP_ERR_INVALID_ARG); + TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_ret); +} + +TEST_CASE("custom certificate bundle init API - bound checking - Invalid first certificate offset", "[mbedtls]") +{ + uint8_t test_bundle[1024] = {0}; + esp_err_t esp_ret; + + /* Check that the esp_crt_bundle_set API will not accept + * the first offset to be invalid */ + + /* The first certificate must start after N uint32_t offset values, + * thus, it cannot start from the 0th position */ + test_bundle[0] = 0; + esp_ret = esp_crt_bundle_set(test_bundle, sizeof(test_bundle)); + TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_ret); + + /* The first certificate must start after N uint32_t offset values, thus, + * the offset from where the it would start should be divisible by sizeof(uint32_t) */ + test_bundle[0] = 1; + esp_ret = esp_crt_bundle_set(test_bundle, sizeof(test_bundle)); + TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_ret); + + /* Check that the esp_crt_bundle_set API will not accept a bundle + * which in which the first cert starts beyond end of bundle*/ + uint8_t *dummy_test_bundle = test_bundle + sizeof(uint32_t); + + esp_ret = esp_crt_bundle_set(dummy_test_bundle, sizeof(test_bundle)); + TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_ret); +} + +TEST_CASE("custom certificate bundle init API - bound checking - Certificates count overflow", "[mbedtls]") +{ + uint8_t test_bundle[1024] = {0}; + esp_err_t esp_ret; + + memset(test_bundle, 0, sizeof(test_bundle)); /* Check that the esp_crt_bundle_set API will not accept a bundle * which has more no. of certs than configured in * CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_MAX_CERTS */ - - uint8_t rand; - esp_fill_random(&rand, 1); - test_bundle[0] = rand; - - /* Make sure that the number of certs will always be greater than - * CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_MAX_CERTS */ - test_bundle[1] = rand + CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_MAX_CERTS; + *((uint32_t*) test_bundle) = ((CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_MAX_CERTS + 1) * sizeof(uint32_t)); esp_ret = esp_crt_bundle_set(test_bundle, sizeof(test_bundle)); - TEST_ASSERT( esp_ret == ESP_ERR_INVALID_ARG); - - /* The API should fail with bundle_size < BUNDLE_HEADER_OFFSET (2) + CRT_HEADER_OFFSET (4) */ - test_bundle[0] = 0; - test_bundle[1] = 1; /* set num_certs = 1 */ - esp_ret = esp_crt_bundle_set(test_bundle, 5); - TEST_ASSERT(esp_ret == ESP_ERR_INVALID_ARG); - - /* Cert number is greater than actual certs present, The API should fail */ - /* Actual No. of certs present in bundle = 1, setting num_certs to 5 */ - test_bundle[1] = 5; /* num_certs */ - test_bundle[3] = 5; /* cert_1_name_len */ - test_bundle[5] = 10; /* cert_1_pub_key_len */ - /* Actual bundle size becomes BUNDLE_HEADER_OFFSET (2) + CRT_HEADER_OFFSET (4) + cert_1_name_len(5) + cert_1_pub_key_len(10) - * i.e. 21 bytes */ - esp_ret = esp_crt_bundle_set(test_bundle, 21); - TEST_ASSERT(esp_ret == ESP_ERR_INVALID_ARG); - - /* The API should fail if bundle_size < BUNDLE_HEADER_OFFSET (2) + CRT_HEADER_OFFSET (4) + cert_1_name_len(5) + cert_1_pub_key_len(10) */ - esp_ret = esp_crt_bundle_set(test_bundle, 20); - TEST_ASSERT(esp_ret == ESP_ERR_INVALID_ARG); + TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_ret); esp_crt_bundle_detach(NULL); } + +TEST_CASE("custom certificate bundle init API - bound checking - Incorrect certificate offset", "[mbedtls]") +{ + uint8_t test_bundle[1024] = {0}; + esp_err_t esp_ret; + + memset(test_bundle, 0, sizeof(test_bundle)); + + /* Check that the esp_crt_bundle_set API will not accept a bundle where + all offsets are not consistent with certificate data */ + + /* + | offset 1 | offset 2 | Cert 1 name len | Cert 1 key len | Cert 1 name | Cert 1 key | Cert 2 name len | ..... | + | ----- offsets ----- | + | ---------------------- Certificate 1 ---------------------- | + | ---- Certificate 2 ---- | + */ + + *((uint32_t*) &test_bundle[0]) = (2 * sizeof(uint32_t)); + *((uint16_t*) &test_bundle[8]) = 2; // Cert 1 name len + *((uint16_t*) &test_bundle[10]) = 4; // Cert 1 key len + + /* Correct offset of certificate 2 should be + = 2 * sizeof(uint32_t) (Offsets of 2 certs) + 2 * sizeof(uint16_t) (Cert name and len) + 2 (Cert 1 name len) + 4 (Cert 1 key len); + = 18 + */ + *((uint32_t*) &test_bundle[4]) = 16; // Incorrect certificate 2 offset + + esp_ret = esp_crt_bundle_set(test_bundle, sizeof(test_bundle)); + TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_ret); + + /* Check that the esp_crt_bundle_set API will not accept a bundle where + all offsets are not consistency with certificate data and the certificate + offsets exceeds the bundle size */ + *((uint32_t*) &test_bundle[4]) = sizeof(test_bundle) + 1; // Offset exceeds the test_bundle size + + esp_ret = esp_crt_bundle_set(test_bundle, sizeof(test_bundle)); + TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_ret); +} From 0702fb82b0021e4812f4715febcddfbf3f534785 Mon Sep 17 00:00:00 2001 From: "harshal.patil" Date: Mon, 15 Jul 2024 17:42:20 +0530 Subject: [PATCH 4/4] ci(examples/protocols): Add more testing connections in the x509 bundle example - This adds a test to try connecting to the domains that use the most common certificate authorities with the default full cert bundle --- .../main/https_x509_bundle_example_main.c | 13 +++++++ .../pytest_https_x509_bundle.py | 36 ++++++++++--------- .../sdkconfig.ci.default_crt_bundle | 10 ++++++ 3 files changed, 42 insertions(+), 17 deletions(-) create mode 100644 examples/protocols/https_x509_bundle/sdkconfig.ci.default_crt_bundle diff --git a/examples/protocols/https_x509_bundle/main/https_x509_bundle_example_main.c b/examples/protocols/https_x509_bundle/main/https_x509_bundle_example_main.c index 966aa8173e..33e3040cf9 100644 --- a/examples/protocols/https_x509_bundle/main/https_x509_bundle_example_main.c +++ b/examples/protocols/https_x509_bundle/main/https_x509_bundle_example_main.c @@ -43,11 +43,24 @@ #include "esp_tls.h" #include "esp_crt_bundle.h" +#if CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL +#define MAX_URLS 9 +#else #define MAX_URLS 2 +#endif static const char *web_urls[MAX_URLS] = { "https://www.howsmyssl.com/a/check", "https://espressif.com", +#if CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL + "https://letsencrypt.org", + "https://www.identrust.com", + "https://www.globalsign.com", + "https://www.sectigo.com", + "https://www.digicert.com", + "https://www.godaddy.com", + "https://rainmaker.espressif.com", // Amazon +#endif }; static const char *TAG = "example"; diff --git a/examples/protocols/https_x509_bundle/pytest_https_x509_bundle.py b/examples/protocols/https_x509_bundle/pytest_https_x509_bundle.py index 12ef0d1f1d..2e6aa59810 100644 --- a/examples/protocols/https_x509_bundle/pytest_https_x509_bundle.py +++ b/examples/protocols/https_x509_bundle/pytest_https_x509_bundle.py @@ -1,10 +1,9 @@ -# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: Unlicense OR CC0-1.0 import logging import os import pytest -from common_test_methods import get_env_config_variable from pytest_embedded import Dut @@ -21,17 +20,11 @@ def test_examples_protocol_https_x509_bundle(dut: Dut) -> None: binary_file = os.path.join(dut.app.binary_path, 'https_x509_bundle.bin') bin_size = os.path.getsize(binary_file) logging.info('https_x509_bundle_bin_size : {}KB'.format(bin_size // 1024)) - # Connect to AP - if dut.app.sdkconfig.get('EXAMPLE_WIFI_SSID_PWD_FROM_STDIN') is True: - dut.expect('Please input ssid password:') - env_name = 'wifi_ap' - ap_ssid = get_env_config_variable(env_name, 'ap_ssid') - ap_password = get_env_config_variable(env_name, 'ap_password') - dut.write(f'{ap_ssid} {ap_password}') dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)[^\d]', timeout=30) # start test num_URLS = int(dut.expect(r'Connecting to (\d+) URLs', timeout=30)[1].decode()) - dut.expect(r'Connection established to ([\s\S]*)', timeout=30) + for _ in range(num_URLS): + dut.expect(r'Connection established to ([\s\S]*)', timeout=30) dut.expect('Completed {} connections'.format(num_URLS), timeout=60) @@ -44,15 +37,24 @@ def test_examples_protocol_https_x509_bundle_dynamic_buffer(dut: Dut) -> None: binary_file = os.path.join(dut.app.binary_path, 'https_x509_bundle.bin') bin_size = os.path.getsize(binary_file) logging.info('https_x509_bundle_bin_size : {}KB'.format(bin_size // 1024)) - # Connect to AP - if dut.app.sdkconfig.get('EXAMPLE_WIFI_SSID_PWD_FROM_STDIN') is True: - dut.expect('Please input ssid password:') - env_name = 'wifi_ap' - ap_ssid = get_env_config_variable(env_name, 'ap_ssid') - ap_password = get_env_config_variable(env_name, 'ap_password') - dut.write(f'{ap_ssid} {ap_password}') dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)[^\d]', timeout=30) # start test num_URLS = int(dut.expect(r'Connecting to (\d+) URLs', timeout=30)[1].decode()) dut.expect(r'Connection established to ([\s\S]*)', timeout=30) dut.expect('Completed {} connections'.format(num_URLS), timeout=60) + + +@pytest.mark.esp32 +@pytest.mark.ethernet +@pytest.mark.parametrize('config', ['default_crt_bundle',], indirect=True) +def test_examples_protocol_https_x509_bundle_default_crt_bundle_stress_test(dut: Dut) -> None: + # check and log bin size + binary_file = os.path.join(dut.app.binary_path, 'https_x509_bundle.bin') + bin_size = os.path.getsize(binary_file) + logging.info('https_x509_bundle_bin_size : {}KB'.format(bin_size // 1024)) + dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)[^\d]', timeout=30) + # start test + num_URLS = int(dut.expect(r'Connecting to (\d+) URLs', timeout=30)[1].decode()) + for _ in range(num_URLS): + dut.expect(r'Connection established to ([\s\S]*)', timeout=30) + dut.expect('Completed {} connections'.format(num_URLS), timeout=60) diff --git a/examples/protocols/https_x509_bundle/sdkconfig.ci.default_crt_bundle b/examples/protocols/https_x509_bundle/sdkconfig.ci.default_crt_bundle new file mode 100644 index 0000000000..3f3ad687e4 --- /dev/null +++ b/examples/protocols/https_x509_bundle/sdkconfig.ci.default_crt_bundle @@ -0,0 +1,10 @@ +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL=y + +CONFIG_EXAMPLE_CONNECT_ETHERNET=y +CONFIG_EXAMPLE_CONNECT_WIFI=n +CONFIG_EXAMPLE_USE_INTERNAL_ETHERNET=y +CONFIG_EXAMPLE_ETH_PHY_IP101=y +CONFIG_EXAMPLE_ETH_MDC_GPIO=23 +CONFIG_EXAMPLE_ETH_MDIO_GPIO=18 +CONFIG_EXAMPLE_ETH_PHY_RST_GPIO=5 +CONFIG_EXAMPLE_ETH_PHY_ADDR=1