Open mzealey opened 3 years ago
@mzealey having exact issue on same platform. Sorry for newb question, was trying to do a quick flash, but how would I change to v1_2? thanks in advance
@jemccullough Look for PROTOCOL_TLSv1_1 in sonota.py, change it to PROTOCOL_TLSv1_2.
Hmm. I've got the same issue. Ubuntu 20.04, SSL internal error.
I changed sonota.py to PROTOCOL_TLSv1_2. Definitely got further, but now it hangs with this:
OSError: [Errno 0] Error
Exception in callback None()
handle:
Looks like still an SSL related issue.
Help?
-- Idan
While researching this myself before finding this ticket, I found this oddity from my Sonoff TXUS switch:
TLSv1.2 Record Layer: Handshake Protocol: Client Hello
Content Type: Handshake (22)
Version: TLS 1.0 (0x0301)
Length: 79
Handshake Protocol: Client Hello
Handshake Type: Client Hello (1)
Length: 75
Version: TLS 1.2 (0x0303)
Note the conflicting TLS versions provided in the Client Hello packet:
The default code in SonOTA hardcodes the TLS version to v1.1. This is why switching it to v1.2 works. Though, I'm not sure what's up with the outermost v1.0.
After changing the TLS version to v1.2, I get this error on the SonOTA console:
*** IMPORTANT! ***
** AFTER the first download is COMPLETE, with in a minute or so you should connect to the new SSID "FinalStage" to finish the process.
** ONLY disconnect when the new "FinalStage" SSID is visible as an available WiFi network.
This server should automatically be allocated the IP address: 192.168.4.2.
If you have successfully connected to "FinalStage" and this is not the IP Address you were allocated, please ensure no other device has connected, and reboot your Sonoff.
...SSL Error on 11 ('192.168.13.152', 17295): [SSL: NO_SHARED_CIPHER] no shared cipher (_ssl.c:1007)
...............SSL Error on 11 ('192.168.13.152', 29447): [SSL: NO_SHARED_CIPHER] no shared cipher (_ssl.c:1007)
......SSL Error on 11 ('192.168.13.152', 5280): [SSL: NO_SHARED_CIPHER] no shared cipher (_ssl.c:1007)
......
Ciphers offered by my Sonoff TXUS when connecting to the server on my laptop, as decoded by wireshark:
Cipher Suites Length: 18
Cipher Suites (9 suites)
Cipher Suite: TLS_RSA_WITH_AES_256_CBC_SHA256 (0x003d)
Cipher Suite: TLS_RSA_WITH_AES_256_CBC_SHA (0x0035)
Cipher Suite: TLS_RSA_WITH_AES_128_CBC_SHA256 (0x003c)
Cipher Suite: TLS_RSA_WITH_AES_128_CBC_SHA (0x002f)
Cipher Suite: TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 (0x00b7)
Cipher Suite: TLS_RSA_PSK_WITH_AES_256_CBC_SHA (0x0095)
Cipher Suite: TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 (0x00b6)
Cipher Suite: TLS_RSA_PSK_WITH_AES_128_CBC_SHA (0x0094)
Cipher Suite: TLS_EMPTY_RENEGOTIATION_INFO_SCSV (0x00ff)
Ciphers accepted by Tornado, by way of Python's SSL Context:
>>> pprint([foo['name'] for foo in ssl_ctx.get_ciphers()])
['TLS_AES_256_GCM_SHA384',
'TLS_CHACHA20_POLY1305_SHA256',
'TLS_AES_128_GCM_SHA256',
'ECDHE-ECDSA-AES256-GCM-SHA384',
'ECDHE-RSA-AES256-GCM-SHA384',
'ECDHE-ECDSA-AES128-GCM-SHA256',
'ECDHE-RSA-AES128-GCM-SHA256',
'ECDHE-ECDSA-CHACHA20-POLY1305',
'ECDHE-RSA-CHACHA20-POLY1305',
'ECDHE-ECDSA-AES256-SHA384',
'ECDHE-RSA-AES256-SHA384',
'ECDHE-ECDSA-AES128-SHA256',
'ECDHE-RSA-AES128-SHA256',
'DHE-RSA-AES256-GCM-SHA384',
'DHE-RSA-AES128-GCM-SHA256',
'DHE-RSA-AES256-SHA256',
'DHE-RSA-AES128-SHA256']
>>>
Indeed, no common ciphers.
Documentation for ssl.SSLContext includes the following note:
Changed in version 3.10: The default cipher suites now include only secure AES and ChaCha20 ciphers with forward secrecy and security level 2. RSA and DH keys with less than 2048 bits and ECC keys with less than 224 bits are prohibited. [PROTOCOL_TLS](https://docs.python.org/3/library/ssl.html#ssl.PROTOCOL_TLS), [PROTOCOL_TLS_CLIENT](https://docs.python.org/3/library/ssl.html#ssl.PROTOCOL_TLS_CLIENT), and [PROTOCOL_TLS_SERVER](https://docs.python.org/3/library/ssl.html#ssl.PROTOCOL_TLS_SERVER) use TLS 1.2 as minimum TLS version.
You can add back one of the older ciphers if you build an SSL Context manually and pass it to the HTTPServer constructor instead of a dict of parameters:
Line 664:
ssl_ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
ssl_ctx.load_cert_chain(certfile=resource_path("ssl/server.crt"), keyfile=resource_path("ssl/server.key"))
ssl_ctx.set_ciphers('AES256-SHA256') # aka TLS_RSA_WITH_AES_256_CBC_SHA256
# https://ciphersuite.info/cs/TLS_RSA_WITH_AES_256_CBC_SHA256/
app_ssl = tornado.httpserver.HTTPServer(app, ssl_options=ssl_ctx)
#app_ssl = tornado.httpserver.HTTPServer(app, ssl_options={
# "certfile": resource_path("ssl/server.crt"),
# "keyfile": resource_path("ssl/server.key"),
# "ssl_version": ssl.PROTOCOL_TLSv1_2,
#})
This gets SonOTA to at least respond to the Client Hello with a Server Hello, listing TLS_RSA_WITH_AES_256_CBC_SHA256 as the chosen cipher.
But then the Sonoff TXUS immediately closes the socket with a FIN ACK, with no indication of what it's unhappy about.
Unfortunately, the only other meaningful thing that's included in the Server Hello is the TLS certificate, which strongly suggests it's the TLS cert it's unhappy with. If its actually checking the server TLS cert, then there's very little we can do to spoof that, without having the matching private key.
The TLS 1.1 flag is not working for me and causes errors like
Changing to v1_2 fixes this issue - perhaps modern ubuntu's ssl doesnt have tls 1.1 support or python 3.8 removed this support?