I'm trying to create a secure connection to aws.amazon.com and I'm getting an ssl SSLV3_ALERT_HANDSHAKE_FAILURE error. This makes no sense to me, as there does not appear to be anything wrong on the server side at AWS. The same code works fine connecting to other sites.
As is unfortunately common, the error itself doesn't provide any details about the root cause of the issue.
Here's the code I'm using to reproduce this:
import socket, ssl, sys
address = (
sys.argv[1],
int(sys.argv[2]) if len(sys.argv) > 2 else 443
)
print("Python %s" % sys.version)
print("OpenSSL %s" % ssl.OPENSSL_VERSION)
print("Address %s:%d" % address)
print("-" * 80)
test_socket = socket.socket()
test_socket.connect(address)
test_ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
test_ssl_context.check_hostname = False
test_ssl_context.load_default_certs()
wrapped_test_socket = test_ssl_context.wrap_socket(test_socket)
print("No exceptions!")
This code works fine connecting to example.com:
Anonymous@machine:~ $ python test_ssl.py example.com
Python 3.11.2 (main, Sep 14 2024, 03:00:30) [GCC 12.2.0]
OpenSSL OpenSSL 3.0.15 3 Sep 2024
Address example.com:443
--------------------------------------------------------------------------------
No exceptions!
I've tested this with different versions of Python and Operating System, with the latest OpenSSL (3.0.15) and I'm consistently getting an SSLV3_ALERT_HANDSHAKE_FAILURE for aws.amazon.com:
C:\dev\mSSL>python test_ssl.py aws.amazon.com
Python 3.13.0 (tags/v3.13.0:60403a5, Oct 7 2024, 09:38:07) [MSC v.1941 64 bit (AMD64)]
OpenSSL OpenSSL 3.0.15 3 Sep 2024
Address aws.amazon.com:443
--------------------------------------------------------------------------------
Traceback (most recent call last):
File "C:\dev\mSSL\test_ssl.py", line 17, in <module>
wrapped_test_socket = test_ssl_context.wrap_socket(test_socket)
File "ssl.py", line 455, in wrap_socket
File "ssl.py", line 1076, in _create
File "ssl.py", line 1372, in do_handshake
ssl.SSLError: [SSL: SSLV3_ALERT_HANDSHAKE_FAILURE] sslv3 alert handshake failure (_ssl.c:1020)
Anonymous@machine:~ $ python test_ssl.py aws.amazon.com
Python 3.11.2 (main, Sep 14 2024, 03:00:30) [GCC 12.2.0]
OpenSSL OpenSSL 3.0.15 3 Sep 2024
Address aws.amazon.com:443
--------------------------------------------------------------------------------
Traceback (most recent call last):
File "/home/Anonymous/test_ssl.py", line 17, in <module>
wrapped_test_socket = test_ssl_context.wrap_socket(test_socket)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.11/ssl.py", line 517, in wrap_socket
return self.sslsocket_class._create(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.11/ssl.py", line 1108, in _create
self.do_handshake()
File "/usr/lib/python3.11/ssl.py", line 1379, in do_handshake
self._sslobj.do_handshake()
ssl.SSLError: [SSL: SSLV3_ALERT_HANDSHAKE_FAILURE] sslv3 alert handshake failure (_ssl.c:992)
Does anybody know what is causing this issue and how I can avoid it?
You must use the server_hostname
argument to SSLContext.wrap_socket()
.
From the docs:
On client connections, the optional parameter server_hostname specifies the hostname of the service which we are connecting to. This allows a single server to host multiple SSL-based services with distinct certificates, quite similarly to HTTP virtual hosts.
aws.amazon.com
requires the SNI extension from clients, which is provided through the server_hostname
argument.
So,
wrapped_test_socket = test_ssl_context.wrap_socket(test_socket, server_hostname=address[0])
should work.