diff --git a/components/esp_http_client/esp_http_client.c b/components/esp_http_client/esp_http_client.c index 8363638196..5f1154cccf 100644 --- a/components/esp_http_client/esp_http_client.c +++ b/components/esp_http_client/esp_http_client.c @@ -608,7 +608,13 @@ esp_http_client_handle_t esp_http_client_init(const esp_http_client_config_t *co goto error; } - if (config->use_global_ca_store == true) { + if (config->crt_bundle_attach != NULL) { +#ifdef CONFIG_MBEDTLS_CERTIFICATE_BUNDLE + esp_transport_ssl_crt_bundle_attach(ssl, config->crt_bundle_attach); +#else //CONFIG_MBEDTLS_CERTIFICATE_BUNDLE + ESP_LOGE(TAG, "use_crt_bundle configured but not enabled in menuconfig: Please enable MBEDTLS_CERTIFICATE_BUNDLE option"); +#endif + } else if (config->use_global_ca_store == true) { esp_transport_ssl_enable_global_ca_store(ssl); } else if (config->cert_pem) { if (!config->cert_len) { diff --git a/components/esp_http_client/include/esp_http_client.h b/components/esp_http_client/include/esp_http_client.h index ee19f70cd7..249eb217ba 100644 --- a/components/esp_http_client/include/esp_http_client.h +++ b/components/esp_http_client/include/esp_http_client.h @@ -135,6 +135,8 @@ typedef struct { bool is_async; /*!< Set asynchronous mode, only supported with HTTPS for now */ bool use_global_ca_store; /*!< Use a global ca_store for all the connections in which this bool is set. */ bool skip_cert_common_name_check; /*!< Skip any validation of server certificate CN field */ + esp_err_t (*crt_bundle_attach)(void *conf); /*!< Function pointer to esp_crt_bundle_attach. Enables the use of certification + bundle for server verification, must be enabled in menuconfig */ bool keep_alive_enable; /*!< Enable keep-alive timeout */ int keep_alive_idle; /*!< Keep-alive idle time. Default is 5 (second) */ int keep_alive_interval; /*!< Keep-alive interval time. Default is 5 (second) */ diff --git a/components/tcp_transport/include/esp_transport_ssl.h b/components/tcp_transport/include/esp_transport_ssl.h index d23a725c23..b31e5b4495 100644 --- a/components/tcp_transport/include/esp_transport_ssl.h +++ b/components/tcp_transport/include/esp_transport_ssl.h @@ -52,6 +52,16 @@ void esp_transport_ssl_set_cert_data(esp_transport_handle_t t, const char *data, */ void esp_transport_ssl_set_cert_data_der(esp_transport_handle_t t, const char *data, int len); +/** + * @brief Enable the use of certification bundle for server verfication for + * an SSL connection. + * It must be first enabled in menuconfig. + * + * @param t ssl transport + * @param[in] crt_bundle_attach Function pointer to esp_crt_bundle_attach + */ +void esp_transport_ssl_crt_bundle_attach(esp_transport_handle_t t, esp_err_t ((*crt_bundle_attach)(void *conf))); + /** * @brief Enable global CA store for SSL connection * @@ -141,14 +151,12 @@ void esp_transport_ssl_skip_common_name_check(esp_transport_handle_t t); */ void esp_transport_ssl_use_secure_element(esp_transport_handle_t t); - /** * @brief Set the ds_data handle in ssl context.(used for the digital signature operation) * * @param t ssl transport * ds_data the handle for ds data params */ - void esp_transport_ssl_set_ds_data(esp_transport_handle_t t, void *ds_data); /** diff --git a/components/tcp_transport/transport_ssl.c b/components/tcp_transport/transport_ssl.c index a1a678404a..e359b390b8 100644 --- a/components/tcp_transport/transport_ssl.c +++ b/components/tcp_transport/transport_ssl.c @@ -329,6 +329,12 @@ void esp_transport_ssl_use_secure_element(esp_transport_handle_t t) ssl->cfg.use_secure_element = true; } +void esp_transport_ssl_crt_bundle_attach(esp_transport_handle_t t, esp_err_t ((*crt_bundle_attach)(void *conf))) +{ + GET_SSL_FROM_TRANSPORT_OR_RETURN(ssl, t); + ssl->cfg.crt_bundle_attach = crt_bundle_attach; +} + static int ssl_get_socket(esp_transport_handle_t t) { transport_esp_tls_t *ssl = ssl_get_context_data(t); diff --git a/examples/protocols/esp_http_client/main/CMakeLists.txt b/examples/protocols/esp_http_client/main/CMakeLists.txt index 2cb6a74b8a..12347781a6 100644 --- a/examples/protocols/esp_http_client/main/CMakeLists.txt +++ b/examples/protocols/esp_http_client/main/CMakeLists.txt @@ -3,4 +3,5 @@ # (If this was a component, we would set COMPONENT_EMBED_TXTFILES here.) idf_component_register(SRCS "esp_http_client_example.c" INCLUDE_DIRS "." - EMBED_TXTFILES howsmyssl_com_root_cert.pem) + EMBED_TXTFILES howsmyssl_com_root_cert.pem + postman_root_cert.pem) diff --git a/examples/protocols/esp_http_client/main/component.mk b/examples/protocols/esp_http_client/main/component.mk index cb97ca08ee..c1f04b76bc 100644 --- a/examples/protocols/esp_http_client/main/component.mk +++ b/examples/protocols/esp_http_client/main/component.mk @@ -5,4 +5,4 @@ # embed files from the "certs" directory as binary data symbols # in the app -COMPONENT_EMBED_TXTFILES := howsmyssl_com_root_cert.pem +COMPONENT_EMBED_TXTFILES := howsmyssl_com_root_cert.pem postman_root_cert.pem diff --git a/examples/protocols/esp_http_client/main/esp_http_client_example.c b/examples/protocols/esp_http_client/main/esp_http_client_example.c index 7dd2b93df6..d4e573b2ca 100644 --- a/examples/protocols/esp_http_client/main/esp_http_client_example.c +++ b/examples/protocols/esp_http_client/main/esp_http_client_example.c @@ -18,6 +18,7 @@ #include "esp_netif.h" #include "protocol_examples_common.h" #include "esp_tls.h" +#include "esp_crt_bundle.h" #include "esp_http_client.h" @@ -38,6 +39,10 @@ static const char *TAG = "HTTP_CLIENT"; extern const char howsmyssl_com_root_cert_pem_start[] asm("_binary_howsmyssl_com_root_cert_pem_start"); extern const char howsmyssl_com_root_cert_pem_end[] asm("_binary_howsmyssl_com_root_cert_pem_end"); +extern const char postman_root_cert_pem_start[] asm("_binary_postman_root_cert_pem_start"); +extern const char postman_root_cert_pem_end[] asm("_binary_postman_root_cert_pem_end"); + + esp_err_t _http_event_handler(esp_http_client_event_t *evt) { static char *output_buffer; // Buffer to store response of http request from event handler @@ -367,7 +372,7 @@ static void https_with_url(void) esp_http_client_config_t config = { .url = "https://www.howsmyssl.com", .event_handler = _http_event_handler, - .cert_pem = howsmyssl_com_root_cert_pem_start, + .crt_bundle_attach = esp_crt_bundle_attach, }; esp_http_client_handle_t client = esp_http_client_init(&config); esp_err_t err = esp_http_client_perform(client); @@ -521,6 +526,7 @@ static void https_async(void) esp_http_client_config_t config = { .url = "https://postman-echo.com/post", .event_handler = _http_event_handler, + .cert_pem = postman_root_cert_pem_start, .is_async = true, .timeout_ms = 5000, }; diff --git a/examples/protocols/esp_http_client/main/postman_root_cert.pem b/examples/protocols/esp_http_client/main/postman_root_cert.pem new file mode 100644 index 0000000000..a6f3e92af5 --- /dev/null +++ b/examples/protocols/esp_http_client/main/postman_root_cert.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsF +ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6 +b24gUm9vdCBDQSAxMB4XDTE1MDUyNjAwMDAwMFoXDTM4MDExNzAwMDAwMFowOTEL +MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv +b3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALJ4gHHKeNXj +ca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgHFzZM +9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qw +IFAGbHrQgLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6 +VOujw5H5SNz/0egwLX0tdHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L +93FcXmn/6pUCyziKrlA4b9v7LWIbxcceVOF34GfID5yHI9Y/QCB/IIDEgEw+OyQm +jgSubJrIqg0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC +AYYwHQYDVR0OBBYEFIQYzIU07LwMlJQuCFmcx7IQTgoIMA0GCSqGSIb3DQEBCwUA +A4IBAQCY8jdaQZChGsV2USggNiMOruYou6r4lK5IpDB/G/wkjUu0yKGX9rbxenDI +U5PMCCjjmCXPI6T53iHTfIUJrU6adTrCC2qJeHZERxhlbI1Bjjt/msv0tadQ1wUs +N+gDS63pYaACbvXy8MWy7Vu33PqUXHeeE6V/Uq2V8viTO96LXFvKWlJbYK8U90vv +o/ufQJVtMVT8QtPHRh8jrdkPSHCa2XV4cdFyQzR1bldZwgJcJmApzyMZFo6IQ6XU +5MsI+yMRQ+hDKXJioaldXgjUkK642M4UwtBV8ob2xJNDd2ZhwLnoQdeXeGADbkpy +rqXRfboQnoZsG4q5WTP468SQvvG5 +-----END CERTIFICATE-----