I intend to connect to the remote host example.com over TLS but I have to connect through a proxy IP address with DNS name example-proxy.com.
I don't have control over the SSL certificate and I cannot ask the admin at example.com to add example-proxy.com to its certificate's SAN.
Using example-prxoy.com would cause OpenSSL to error out because the host name does not match the name in the certificate. How can I split the host parameter into two: (1) domain name for the network connection and (2) domain name for the certificate verification.
I don't have the resources to modify the OpenSSL library but I can make changes to the Python libraries. According to this doc, I could have modified the match_hostname method to implement this feature but it is no longer available as of Python 3.7+.
Asks
Just give a different hostname for TCP connection and TLS handshake, i.e. set server_hostname
in wrap_socket
. To modify the example from the official documentation for this:
import socket
import ssl
tls_hostname = 'www.example.com'
context = ssl.create_default_context()
with socket.create_connection(('127.0.0.1',8443)) as sock:
with context.wrap_socket(sock, server_hostname=tls_hostname) as ssock:
print(ssock.version())
This will connect to ('127.0.0.1',8443)
but do the TLS handshake with www.example.com
.
Note that this will use tls_hostname
for both SNI extension in the TLS handshake and for validating the certificate. But this seems to be what you need based on your question anyway: connect to IP:port but do TLS handshake and validation with a specific hostname.