mirror of
https://github.com/esphome/esphome.git
synced 2026-08-31 10:06:03 +00:00
Keep TLS for components that re-include esp-tls and gate the sdkconfig escape hatch on value
This commit is contained in:
@@ -2333,13 +2333,23 @@ async def _reconcile_certificate_bundle_sdkconfig() -> None:
|
||||
set_idf_sdkconfig_default("CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_CMN", True)
|
||||
|
||||
|
||||
# User sdkconfig_options that mean "keep TLS on"; each becomes a request_tls().
|
||||
# User sdkconfig_options that mean "keep TLS on" when set to y.
|
||||
_MBEDTLS_TLS_ON_OPTIONS = (
|
||||
"CONFIG_MBEDTLS_TLS_ENABLED",
|
||||
"CONFIG_MBEDTLS_TLS_SERVER_AND_CLIENT",
|
||||
"CONFIG_MBEDTLS_TLS_SERVER_ONLY",
|
||||
"CONFIG_MBEDTLS_TLS_CLIENT_ONLY",
|
||||
)
|
||||
# Any user option under these prefixes only makes sense with TLS compiled in.
|
||||
_TLS_OPTION_PREFIXES = ("CONFIG_ESP_TLS_", "CONFIG_MBEDTLS_SSL_", "CONFIG_ESP_HTTPS_")
|
||||
|
||||
|
||||
def _user_sdkconfig_wants_tls(options: dict[str, Any]) -> bool:
|
||||
return any(
|
||||
(name in _MBEDTLS_TLS_ON_OPTIONS and value == "y")
|
||||
or name.startswith(_TLS_OPTION_PREFIXES)
|
||||
for name, value in options.items()
|
||||
)
|
||||
|
||||
|
||||
@coroutine_with_priority(CoroPriority.FINAL)
|
||||
@@ -2352,8 +2362,14 @@ async def _reconcile_mbedtls_sdkconfig() -> None:
|
||||
"""
|
||||
data = _mbedtls_sdkconfig()
|
||||
idf6 = idf_version() >= cv.Version(6, 0, 0)
|
||||
# A component that re-includes esp-tls on its own (external components
|
||||
# predating request_tls()) wants TLS just as much as a request_tls() call.
|
||||
tls_required = (
|
||||
data.tls_required
|
||||
or "esp-tls" not in CORE.data[KEY_ESP32][KEY_EXCLUDE_COMPONENTS]
|
||||
)
|
||||
|
||||
if not CORE.using_arduino and not data.tls_required:
|
||||
if not CORE.using_arduino and not tls_required:
|
||||
# IDF 6 made CONFIG_MBEDTLS_TLS_ENABLED a normal bool; on IDF 5 it has
|
||||
# no prompt and is only reachable through the "None" TLS role choice.
|
||||
if idf6:
|
||||
@@ -2363,7 +2379,8 @@ async def _reconcile_mbedtls_sdkconfig() -> None:
|
||||
# Enterprise WiFi selects TLS back on; wifi writes this itself, but
|
||||
# esp_wifi can also be in the build without a wifi: block (openthread).
|
||||
set_idf_sdkconfig_default("CONFIG_ESP_WIFI_ENTERPRISE_SUPPORT", False)
|
||||
# WiFi, Bluetooth and secure boot re-select ECP through Kconfig.
|
||||
# WiFi (ESP_WIFI_MBEDTLS_CRYPTO), Bluetooth and signed apps
|
||||
# (SECURE_SIGNED_APPS) select ECP back on through Kconfig.
|
||||
if not data.ecp_required:
|
||||
set_idf_sdkconfig_default("CONFIG_MBEDTLS_ECP_C", False)
|
||||
set_idf_sdkconfig_default("CONFIG_MBEDTLS_PEM_WRITE_C", False)
|
||||
@@ -3089,11 +3106,7 @@ async def to_code(config):
|
||||
# so it still gets the CMN variant pinned.
|
||||
if conf[CONF_SDKCONFIG_OPTIONS].get("CONFIG_MBEDTLS_CERTIFICATE_BUNDLE") == "y":
|
||||
require_certificate_bundle()
|
||||
# A TLS role or esp-tls option in sdkconfig_options means the user relies on TLS.
|
||||
elif any(
|
||||
name in _MBEDTLS_TLS_ON_OPTIONS or name.startswith("CONFIG_ESP_TLS_")
|
||||
for name in conf[CONF_SDKCONFIG_OPTIONS]
|
||||
):
|
||||
if _user_sdkconfig_wants_tls(conf[CONF_SDKCONFIG_OPTIONS]):
|
||||
request_tls()
|
||||
|
||||
# Components from YAML are added in a separate coroutine with FINAL priority
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
esphome:
|
||||
name: test
|
||||
|
||||
esp32:
|
||||
board: esp32dev
|
||||
framework:
|
||||
type: esp-idf
|
||||
sdkconfig_options:
|
||||
CONFIG_MBEDTLS_TLS_ENABLED: n
|
||||
@@ -433,7 +433,7 @@ _IDF6 = cv.Version(6, 0, 0)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("framework", "idf", "data", "preset", "expected"),
|
||||
("framework", "idf", "data", "preset", "expected", "excluded"),
|
||||
[
|
||||
pytest.param(
|
||||
PlatformFramework.ESP32_IDF,
|
||||
@@ -441,8 +441,19 @@ _IDF6 = cv.Version(6, 0, 0)
|
||||
MbedtlsSdkconfigData(),
|
||||
{},
|
||||
{**_TLS_OFF_IDF5, **_PEER_CERT_PKCS7_OFF},
|
||||
{"esp-tls"},
|
||||
id="idf5_no_tls_user",
|
||||
),
|
||||
pytest.param(
|
||||
# An external component that only re-included esp-tls keeps TLS.
|
||||
PlatformFramework.ESP32_IDF,
|
||||
_IDF5,
|
||||
MbedtlsSdkconfigData(),
|
||||
{},
|
||||
_PEER_CERT_PKCS7_OFF,
|
||||
set(),
|
||||
id="idf_esp_tls_reincluded",
|
||||
),
|
||||
pytest.param(
|
||||
PlatformFramework.ESP32_IDF,
|
||||
_IDF6,
|
||||
@@ -454,6 +465,7 @@ _IDF6 = cv.Version(6, 0, 0)
|
||||
"CONFIG_MBEDTLS_SHA384_C": False,
|
||||
"CONFIG_MBEDTLS_SHA512_C": False,
|
||||
},
|
||||
{"esp-tls"},
|
||||
id="idf6_drops_sha512",
|
||||
),
|
||||
pytest.param(
|
||||
@@ -462,6 +474,7 @@ _IDF6 = cv.Version(6, 0, 0)
|
||||
MbedtlsSdkconfigData(sha512_required=True),
|
||||
{},
|
||||
{**_TLS_OFF_IDF6, **_PEER_CERT_PKCS7_OFF},
|
||||
{"esp-tls"},
|
||||
id="idf6_sha512_required",
|
||||
),
|
||||
pytest.param(
|
||||
@@ -470,6 +483,7 @@ _IDF6 = cv.Version(6, 0, 0)
|
||||
MbedtlsSdkconfigData(tls_required=True),
|
||||
{},
|
||||
_PEER_CERT_PKCS7_OFF,
|
||||
{"esp-tls"},
|
||||
id="idf_tls_requested",
|
||||
),
|
||||
pytest.param(
|
||||
@@ -485,6 +499,7 @@ _IDF6 = cv.Version(6, 0, 0)
|
||||
"CONFIG_MBEDTLS_X509_CSR_PARSE_C": False,
|
||||
**_PEER_CERT_PKCS7_OFF,
|
||||
},
|
||||
{"esp-tls"},
|
||||
id="idf_ecp_without_tls",
|
||||
),
|
||||
pytest.param(
|
||||
@@ -497,6 +512,7 @@ _IDF6 = cv.Version(6, 0, 0)
|
||||
"CONFIG_MBEDTLS_ECP_C": RawSdkconfigValue("y"),
|
||||
**_PEER_CERT_PKCS7_OFF,
|
||||
},
|
||||
{"esp-tls"},
|
||||
id="idf_user_ecp_wins",
|
||||
),
|
||||
pytest.param(
|
||||
@@ -509,6 +525,7 @@ _IDF6 = cv.Version(6, 0, 0)
|
||||
"CONFIG_MBEDTLS_SSL_KEEP_PEER_CERTIFICATE": True,
|
||||
"CONFIG_MBEDTLS_PKCS7_C": True,
|
||||
},
|
||||
{"esp-tls"},
|
||||
id="idf_peer_cert_pkcs7_required",
|
||||
),
|
||||
pytest.param(
|
||||
@@ -517,6 +534,7 @@ _IDF6 = cv.Version(6, 0, 0)
|
||||
MbedtlsSdkconfigData(disable_peer_cert=False, disable_pkcs7=False),
|
||||
{},
|
||||
_TLS_OFF_IDF5,
|
||||
{"esp-tls"},
|
||||
id="idf_advanced_disables_off",
|
||||
),
|
||||
pytest.param(
|
||||
@@ -525,6 +543,7 @@ _IDF6 = cv.Version(6, 0, 0)
|
||||
MbedtlsSdkconfigData(),
|
||||
{},
|
||||
_PEER_CERT_PKCS7_OFF,
|
||||
{"esp-tls"},
|
||||
id="arduino_keeps_tls",
|
||||
),
|
||||
],
|
||||
@@ -536,6 +555,7 @@ def test_reconcile_mbedtls_sdkconfig(
|
||||
data: MbedtlsSdkconfigData,
|
||||
preset: dict[str, Any],
|
||||
expected: dict[str, Any],
|
||||
excluded: set[str],
|
||||
) -> None:
|
||||
"""The FINAL-priority reconciler turns TLS off only when nothing requested it;
|
||||
user sdkconfig_options always win."""
|
||||
@@ -544,6 +564,7 @@ def test_reconcile_mbedtls_sdkconfig(
|
||||
KEY_IDF_VERSION: idf,
|
||||
KEY_SDKCONFIG_OPTIONS: dict(preset),
|
||||
KEY_MBEDTLS_SDKCONFIG: data,
|
||||
KEY_EXCLUDE_COMPONENTS: excluded,
|
||||
}
|
||||
|
||||
asyncio.run(_reconcile_mbedtls_sdkconfig())
|
||||
@@ -571,6 +592,12 @@ def test_reconcile_mbedtls_sdkconfig(
|
||||
),
|
||||
pytest.param("tls_sdkconfig_esp_tls.yaml", False, False, id="raw_esp_tls"),
|
||||
pytest.param("tls_sdkconfig_tls_role.yaml", False, False, id="raw_tls_role"),
|
||||
# A role option set to n is not a request.
|
||||
pytest.param(
|
||||
"tls_sdkconfig_tls_enabled_n.yaml", True, True, id="raw_tls_enabled_n"
|
||||
),
|
||||
# SECURE_SIGNED_APPS selects ECP back on in Kconfig; ESPHome still writes the default.
|
||||
pytest.param("signed_ota_ecdsa256_c6.yaml", True, True, id="signed_ota_ecdsa"),
|
||||
],
|
||||
)
|
||||
def test_tls_disabled_sdkconfig(
|
||||
|
||||
Reference in New Issue
Block a user