diff --git a/esphome/components/http_request/__init__.py b/esphome/components/http_request/__init__.py index 9f74fb1023..7347b8ebf7 100644 --- a/esphome/components/http_request/__init__.py +++ b/esphome/components/http_request/__init__.py @@ -126,7 +126,7 @@ CONFIG_SCHEMA = cv.All( ), cv.Optional(CONF_CA_CERTIFICATE_PATH): cv.All( cv.file_, - cv.only_on(PLATFORM_HOST), + cv.Any(cv.only_on(PLATFORM_HOST), cv.only_on_esp32), ), } ).extend(cv.COMPONENT_SCHEMA), @@ -160,7 +160,14 @@ async def to_code(config): cg.add(var.set_verify_ssl(config[CONF_VERIFY_SSL])) if config.get(CONF_VERIFY_SSL): - esp32.add_idf_sdkconfig_option("CONFIG_MBEDTLS_CERTIFICATE_BUNDLE", True) + if ca_cert_path := config.get(CONF_CA_CERTIFICATE_PATH): + with open(ca_cert_path, encoding="utf-8") as f: + ca_cert_content = f.read() + cg.add(var.set_ca_certificate(ca_cert_content)) + else: + esp32.add_idf_sdkconfig_option( + "CONFIG_MBEDTLS_CERTIFICATE_BUNDLE", True + ) esp32.add_idf_sdkconfig_option( "CONFIG_ESP_TLS_INSECURE", diff --git a/esphome/components/http_request/http_request_idf.cpp b/esphome/components/http_request/http_request_idf.cpp index b6fb7f7ea9..680ae6c801 100644 --- a/esphome/components/http_request/http_request_idf.cpp +++ b/esphome/components/http_request/http_request_idf.cpp @@ -27,8 +27,9 @@ void HttpRequestIDF::dump_config() { HttpRequestComponent::dump_config(); ESP_LOGCONFIG(TAG, " Buffer Size RX: %u\n" - " Buffer Size TX: %u", - this->buffer_size_rx_, this->buffer_size_tx_); + " Buffer Size TX: %u\n" + " Custom CA Certificate: %s", + this->buffer_size_rx_, this->buffer_size_tx_, YESNO(this->ca_certificate_ != nullptr)); } esp_err_t HttpRequestIDF::http_event_handler(esp_http_client_event_t *evt) { @@ -88,11 +89,15 @@ std::shared_ptr HttpRequestIDF::perform(const std::string &url, c config.disable_auto_redirect = !this->follow_redirects_; config.max_redirection_count = this->redirect_limit_; config.auth_type = HTTP_AUTH_TYPE_BASIC; -#if CONFIG_MBEDTLS_CERTIFICATE_BUNDLE if (secure && this->verify_ssl_) { - config.crt_bundle_attach = esp_crt_bundle_attach; - } + if (this->ca_certificate_ != nullptr) { + config.cert_pem = this->ca_certificate_; +#if CONFIG_MBEDTLS_CERTIFICATE_BUNDLE + } else { + config.crt_bundle_attach = esp_crt_bundle_attach; #endif + } + } if (this->useragent_ != nullptr) { config.user_agent = this->useragent_; diff --git a/esphome/components/http_request/http_request_idf.h b/esphome/components/http_request/http_request_idf.h index 0fae67f5bc..ad11811a8f 100644 --- a/esphome/components/http_request/http_request_idf.h +++ b/esphome/components/http_request/http_request_idf.h @@ -35,6 +35,7 @@ class HttpRequestIDF : public HttpRequestComponent { void set_buffer_size_rx(uint16_t buffer_size_rx) { this->buffer_size_rx_ = buffer_size_rx; } void set_buffer_size_tx(uint16_t buffer_size_tx) { this->buffer_size_tx_ = buffer_size_tx; } void set_verify_ssl(bool verify_ssl) { this->verify_ssl_ = verify_ssl; } + void set_ca_certificate(const char *ca_certificate) { this->ca_certificate_ = ca_certificate; } protected: std::shared_ptr perform(const std::string &url, const std::string &method, const std::string &body, @@ -44,6 +45,7 @@ class HttpRequestIDF : public HttpRequestComponent { uint16_t buffer_size_rx_{}; uint16_t buffer_size_tx_{}; bool verify_ssl_{true}; + const char *ca_certificate_{nullptr}; /// @brief Monitors the http client events to gather response headers static esp_err_t http_event_handler(esp_http_client_event_t *evt); diff --git a/tests/components/http_request/test-custom-ca.esp32-idf.yaml b/tests/components/http_request/test-custom-ca.esp32-idf.yaml new file mode 100644 index 0000000000..0b1b2f8829 --- /dev/null +++ b/tests/components/http_request/test-custom-ca.esp32-idf.yaml @@ -0,0 +1,7 @@ +substitutions: + verify_ssl: "true" + +http_request: + ca_certificate_path: $component_dir/test_ca.pem + +<<: !include common.yaml diff --git a/tests/components/http_request/test_ca.pem b/tests/components/http_request/test_ca.pem new file mode 100644 index 0000000000..30cbc1a3c4 --- /dev/null +++ b/tests/components/http_request/test_ca.pem @@ -0,0 +1,10 @@ +-----BEGIN CERTIFICATE----- +MIIBkTCB+wIJAKHBfpegPjMCMA0GCSqGSIb3DQEBCwUAMBExDzANBgNVBAMMBnVu +dXNlZDAeFw0yNDAxMDEwMDAwMDBaFw0yNTAxMDEwMDAwMDBaMBExDzANBgNVBAMM +BnVudXNlZDBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQC5mMUB1hOgLmlnXtsvcGMP +XkhAqZaR0dDPW5OS8VEopWLJCX9Y0cvNCqiDI8cnP8pP8XJGU1hGLvA5PJzWnWZz +AgMBAAGjUzBRMB0GA1UdDgQWBBR5oQ9KqFeZOdBuAJrXxEP0dqzPtTAfBgNVHSME +GDAWgBR5oQ9KqFeZOdBuAJrXxEP0dqzPtTAPBgNVHRMBAf8EBTADAQH/MA0GCSqG +SIb3DQEBCwUAA0EAKqZFf6+f8FPDbKyPCpssquojgn7fEXqr/I/yz0R5CowGdMms +H3WH3aKP4lLSHdPTBtfIoJi3gEIZjFxp3S1TWw== +-----END CERTIFICATE-----