pyopenssl
pyopenssl copied to clipboard
Error in do_handshake()
Please look into https://github.com/SecureAuthCorp/impacket/issues/866 and https://github.com/SecureAuthCorp/impacket/issues/856. I think that problem is not in impacket, but in pyOpenSSL.
For example, if you run following code (require installed impacket) you get [('SSL routines', 'state_machine', 'internal error')]:
import impacket.tds
from OpenSSL import SSL
ms_sql = impacket.tds.MSSQL('10.10.10.27', 1433)
ms_sql.connect()
ms_sql.preLogin()
ctx = SSL.Context(SSL.TLSv1_METHOD)
ctx.set_cipher_list('RC4, AES256') (you get warning here)
tls = SSL.Connection(ctx, None)
tls.set_connect_state()
tls.do_handshake() (here you get error)
Actually, it is not working even without impacket and without warning :-) For example, this code does not work:
from OpenSSL import SSL
ctx = SSL.Context(SSL.TLSv1_METHOD)
ctx.set_cipher_list('RC4, AES256'.encode())
tls = SSL.Connection(ctx, None)
tls.set_connect_state()
tls.do_handshake()
I can hit a similar issue with this:
import socket
import OpenSSL
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(100)
ctx = OpenSSL.SSL.Context( OpenSSL.SSL.TLSv1_2_METHOD)
def print_chain(context, hostname, port):
print('Connecting to {0}'.format(hostname))
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock = OpenSSL.SSL.Connection(context=context, socket=sock)
sock.settimeout(5)
sock.connect((hostname, port))
sock.setblocking(1)
sock.do_handshake()
for cert in sock.get_peer_cert_chain():
print(' s:{0}'.format(cert.get_subject()))
print(' i:{0}'.format(cert.get_issuer()))
sock.shutdown()
sock.close()
Servers that are checking ServerName error while servers that don't work fine. For example, things that use Go's autocert will fail with the above script. (thanks to @jrick for tracking that bit down!)
I have confirmed this happens on:
| OS | Library |
|---|---|
| OpenBSD-current | LibreSSL 3.2.1 |
| macOS 11.0 Big Sur | LibreSSL 2.8.3 |
| NixOS 20.3.2625 | OpenSSL 1.1.1g 21 Apr 2020 |
In my example issue happens on last Ubuntu, OpenSSL 1.1.1g 21 Apr 2020, and Python 3.8 (on Python 3.7 there is no issue).
Turns out my issue looked very much like this one, and my test script was not quite exercising the full issue.
Currently on LibreSSL (on OpenBSD-current as of 2020-07-01ish) TLS 1.3 does not support the info callback. This caused the same result as seen in the script I posted earlier. In the example script if one sets sock.set_tlsext_host_name(hostname.encode()) it will work as expected.
I was mistaken in my assumption that sock.set_tlsext_host_name(hostname.encode()) should happen by default.
I'm sorry we've been slow to triage this. Can someone please provide a complete and self-contained example for reproducing this?