mirror of
https://github.com/esphome/esphome.git
synced 2024-11-26 08:55:22 +01:00
Add support X.509 client certificates for MQTT. (#5778)
Co-authored-by: h2zero <powellperalata@gmail.com> Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
This commit is contained in:
parent
b606e976e1
commit
e731a2ffaa
5 changed files with 29 additions and 0 deletions
|
@ -10,6 +10,8 @@ from esphome.const import (
|
||||||
CONF_BIRTH_MESSAGE,
|
CONF_BIRTH_MESSAGE,
|
||||||
CONF_BROKER,
|
CONF_BROKER,
|
||||||
CONF_CERTIFICATE_AUTHORITY,
|
CONF_CERTIFICATE_AUTHORITY,
|
||||||
|
CONF_CLIENT_CERTIFICATE,
|
||||||
|
CONF_CLIENT_CERTIFICATE_KEY,
|
||||||
CONF_CLIENT_ID,
|
CONF_CLIENT_ID,
|
||||||
CONF_COMMAND_TOPIC,
|
CONF_COMMAND_TOPIC,
|
||||||
CONF_COMMAND_RETAIN,
|
CONF_COMMAND_RETAIN,
|
||||||
|
@ -199,6 +201,12 @@ CONFIG_SCHEMA = cv.All(
|
||||||
cv.Optional(CONF_CERTIFICATE_AUTHORITY): cv.All(
|
cv.Optional(CONF_CERTIFICATE_AUTHORITY): cv.All(
|
||||||
cv.string, cv.only_with_esp_idf
|
cv.string, cv.only_with_esp_idf
|
||||||
),
|
),
|
||||||
|
cv.Inclusive(CONF_CLIENT_CERTIFICATE, "cert-key-pair"): cv.All(
|
||||||
|
cv.string, cv.only_on_esp32
|
||||||
|
),
|
||||||
|
cv.Inclusive(CONF_CLIENT_CERTIFICATE_KEY, "cert-key-pair"): cv.All(
|
||||||
|
cv.string, cv.only_on_esp32
|
||||||
|
),
|
||||||
cv.SplitDefault(CONF_SKIP_CERT_CN_CHECK, esp32_idf=False): cv.All(
|
cv.SplitDefault(CONF_SKIP_CERT_CN_CHECK, esp32_idf=False): cv.All(
|
||||||
cv.boolean, cv.only_with_esp_idf
|
cv.boolean, cv.only_with_esp_idf
|
||||||
),
|
),
|
||||||
|
@ -378,6 +386,9 @@ async def to_code(config):
|
||||||
if CONF_CERTIFICATE_AUTHORITY in config:
|
if CONF_CERTIFICATE_AUTHORITY in config:
|
||||||
cg.add(var.set_ca_certificate(config[CONF_CERTIFICATE_AUTHORITY]))
|
cg.add(var.set_ca_certificate(config[CONF_CERTIFICATE_AUTHORITY]))
|
||||||
cg.add(var.set_skip_cert_cn_check(config[CONF_SKIP_CERT_CN_CHECK]))
|
cg.add(var.set_skip_cert_cn_check(config[CONF_SKIP_CERT_CN_CHECK]))
|
||||||
|
if CONF_CLIENT_CERTIFICATE in config:
|
||||||
|
cg.add(var.set_cl_certificate(config[CONF_CLIENT_CERTIFICATE]))
|
||||||
|
cg.add(var.set_cl_key(config[CONF_CLIENT_CERTIFICATE_KEY]))
|
||||||
|
|
||||||
# prevent error -0x428e
|
# prevent error -0x428e
|
||||||
# See https://github.com/espressif/esp-idf/issues/139
|
# See https://github.com/espressif/esp-idf/issues/139
|
||||||
|
|
|
@ -45,6 +45,11 @@ bool MQTTBackendESP32::initialize_() {
|
||||||
mqtt_cfg_.cert_pem = ca_certificate_.value().c_str();
|
mqtt_cfg_.cert_pem = ca_certificate_.value().c_str();
|
||||||
mqtt_cfg_.skip_cert_common_name_check = skip_cert_cn_check_;
|
mqtt_cfg_.skip_cert_common_name_check = skip_cert_cn_check_;
|
||||||
mqtt_cfg_.transport = MQTT_TRANSPORT_OVER_SSL;
|
mqtt_cfg_.transport = MQTT_TRANSPORT_OVER_SSL;
|
||||||
|
|
||||||
|
if (this->cl_certificate_.has_value() && this->cl_key_.has_value()) {
|
||||||
|
mqtt_cfg_.client_cert_pem = this->cl_certificate_.value().c_str();
|
||||||
|
mqtt_cfg_.client_key_pem = this->cl_key_.value().c_str();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
mqtt_cfg_.transport = MQTT_TRANSPORT_OVER_TCP;
|
mqtt_cfg_.transport = MQTT_TRANSPORT_OVER_TCP;
|
||||||
}
|
}
|
||||||
|
@ -79,6 +84,11 @@ bool MQTTBackendESP32::initialize_() {
|
||||||
mqtt_cfg_.broker.verification.certificate = ca_certificate_.value().c_str();
|
mqtt_cfg_.broker.verification.certificate = ca_certificate_.value().c_str();
|
||||||
mqtt_cfg_.broker.verification.skip_cert_common_name_check = skip_cert_cn_check_;
|
mqtt_cfg_.broker.verification.skip_cert_common_name_check = skip_cert_cn_check_;
|
||||||
mqtt_cfg_.broker.address.transport = MQTT_TRANSPORT_OVER_SSL;
|
mqtt_cfg_.broker.address.transport = MQTT_TRANSPORT_OVER_SSL;
|
||||||
|
|
||||||
|
if (this->cl_certificate_.has_value() && this->cl_key_.has_value()) {
|
||||||
|
mqtt_cfg_.credentials.authentication.certificate = this->cl_certificate_.value().c_str();
|
||||||
|
mqtt_cfg_.credentials.authentication.key = this->cl_key_.value().c_str();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
mqtt_cfg_.broker.address.transport = MQTT_TRANSPORT_OVER_TCP;
|
mqtt_cfg_.broker.address.transport = MQTT_TRANSPORT_OVER_TCP;
|
||||||
}
|
}
|
||||||
|
|
|
@ -124,6 +124,8 @@ class MQTTBackendESP32 final : public MQTTBackend {
|
||||||
void loop() final;
|
void loop() final;
|
||||||
|
|
||||||
void set_ca_certificate(const std::string &cert) { ca_certificate_ = cert; }
|
void set_ca_certificate(const std::string &cert) { ca_certificate_ = cert; }
|
||||||
|
void set_cl_certificate(const std::string &cert) { cl_certificate_ = cert; }
|
||||||
|
void set_cl_key(const std::string &key) { cl_key_ = key; }
|
||||||
void set_skip_cert_cn_check(bool skip_check) { skip_cert_cn_check_ = skip_check; }
|
void set_skip_cert_cn_check(bool skip_check) { skip_cert_cn_check_ = skip_check; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -154,6 +156,8 @@ class MQTTBackendESP32 final : public MQTTBackend {
|
||||||
uint16_t keep_alive_;
|
uint16_t keep_alive_;
|
||||||
bool clean_session_;
|
bool clean_session_;
|
||||||
optional<std::string> ca_certificate_;
|
optional<std::string> ca_certificate_;
|
||||||
|
optional<std::string> cl_certificate_;
|
||||||
|
optional<std::string> cl_key_;
|
||||||
bool skip_cert_cn_check_{false};
|
bool skip_cert_cn_check_{false};
|
||||||
|
|
||||||
// callbacks
|
// callbacks
|
||||||
|
|
|
@ -146,6 +146,8 @@ class MQTTClientComponent : public Component {
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_ESP32
|
#ifdef USE_ESP32
|
||||||
void set_ca_certificate(const char *cert) { this->mqtt_backend_.set_ca_certificate(cert); }
|
void set_ca_certificate(const char *cert) { this->mqtt_backend_.set_ca_certificate(cert); }
|
||||||
|
void set_cl_certificate(const char *cert) { this->mqtt_backend_.set_cl_certificate(cert); }
|
||||||
|
void set_cl_key(const char *key) { this->mqtt_backend_.set_cl_key(key); }
|
||||||
void set_skip_cert_cn_check(bool skip_check) { this->mqtt_backend_.set_skip_cert_cn_check(skip_check); }
|
void set_skip_cert_cn_check(bool skip_check) { this->mqtt_backend_.set_skip_cert_cn_check(skip_check); }
|
||||||
#endif
|
#endif
|
||||||
const Availability &get_availability();
|
const Availability &get_availability();
|
||||||
|
|
|
@ -112,6 +112,8 @@ CONF_CHANNELS = "channels"
|
||||||
CONF_CHARACTERISTIC_UUID = "characteristic_uuid"
|
CONF_CHARACTERISTIC_UUID = "characteristic_uuid"
|
||||||
CONF_CHIPSET = "chipset"
|
CONF_CHIPSET = "chipset"
|
||||||
CONF_CLEAR_IMPEDANCE = "clear_impedance"
|
CONF_CLEAR_IMPEDANCE = "clear_impedance"
|
||||||
|
CONF_CLIENT_CERTIFICATE = "client_certificate"
|
||||||
|
CONF_CLIENT_CERTIFICATE_KEY = "client_certificate_key"
|
||||||
CONF_CLIENT_ID = "client_id"
|
CONF_CLIENT_ID = "client_id"
|
||||||
CONF_CLK_PIN = "clk_pin"
|
CONF_CLK_PIN = "clk_pin"
|
||||||
CONF_CLOCK_PIN = "clock_pin"
|
CONF_CLOCK_PIN = "clock_pin"
|
||||||
|
|
Loading…
Reference in a new issue