Sitelet https://github.com/python-kasa/python-kasa/issues/1736
Skip to content

SslAesTransport CIPHERS list excludes ECDHE, causing SSLV3_ALERT_HANDSHAKE_FAILURE on cameras with updated firmware (Tapo C220) #1736

Description

@giannisigalotti

SslAesTransport._create_ssl_context() in kasa/transports/sslaestransport.py restricts the TLS cipher list to a fixed set of non-ECDHE (static RSA key exchange, no forward secrecy) ciphers:

CIPHERS = ":".join([
    "AES256-GCM-SHA384",
    "AES256-SHA256",
    "AES128-GCM-SHA256",
    "AES128-SHA256",
    "AES256-SHA",
])

Recent Tapo camera firmware versions (confirmed on two separate Tapo C220 units, firmware version 1.5.4) appear to have dropped support for these legacy non-PFS ciphers, while still fully supporting modern ECDHE cipher suites. This causes every fresh pairing attempt from Home Assistant / python-kasa to fail with SSLV3_ALERT_HANDSHAKE_FAILURE, since none of the ciphers in the fixed whitelist are accepted by the device anymore.

Diagnosis

Tested directly against the camera (192.168.1.119:443) from inside the same container/environment running the integration:

Default OpenSSL cipher list (includes ECDHE):
openssl s_client -connect 192.168.1.119:443

→ Handshake succeeds: TLSv1.2, ECDHE-RSA-AES128-GCM-SHA256, camera responds HTTP/1.1 200 OK.

Exact cipher list used by SslAesTransport (no ECDHE):
openssl s_client -connect 192.168.1.119:443 -cipher 'AES256-GCM-SHA384:AES256-SHA256:AES128-GCM-SHA256:AES128-SHA256:AES256-SHA'

→ Fails immediately: SSL alert number 40 (handshake_failure), matching exactly the error seen in HA/kasa logs.

This confirms the camera rejects the whitelist in CIPHERS, but happily negotiates ECDHE-based ciphers.

Reproduction steps
Factory reset a Tapo C220 (or C210/C230) currently on the latest firmware (confirmed on 1.5.4).
Pair it fresh via the Tapo app, enable Third-Party Compatibility and set up a camera account.
Try adding it to Home Assistant via the TP-Link Smart Home integration.
Setup fails with:
Device connection error: <ip>: Cannot connect to host <ip>:443 ssl:<ssl.SSLContext object> [[SSL: SSLV3_ALERT_HANDSHAKE_FAILURE] ssl/tls alert handshake failure]
Notably, a camera that was already paired and working before the firmware update continues to work fine after an in-place update — the issue only appears on a fresh handshake/pairing after the firmware update.

Suggested fix

Extend CIPHERS to include ECDHE suites (e.g. ECDHE-RSA-AES128-GCM-SHA256, ECDHE-RSA-AES256-GCM-SHA384), or fall back to the default OpenSSL cipher list if the current fixed set fails to negotiate. This should preserve compatibility with older cameras (which reportedly only support the legacy list) while restoring compatibility with newer firmware that has dropped non-PFS ciphers.

Environment
python-kasa version: (installed via Home Assistant Core) python-kasa 0.10.2.
Home Assistant Core/OS version: 2026.7.4
Device: TP-Link Tapo C220, firmware 1.5.4
OpenSSL: 3.5.7 (confirmed identical across two separate HAOS installations, ruling out a client-side OpenSSL/SECLEVEL issue)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions