Skip to content

Commit 6331c71

Browse files
author
root
committed
Added TLS 1.3 support to the Python driver
1 parent 959c0d7 commit 6331c71

File tree

1 file changed

+62
-0
lines changed

1 file changed

+62
-0
lines changed

vertica_python/vertica/connection.py

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -596,6 +596,68 @@ def balance_load(self, raw_socket: socket.socket) -> socket.socket:
596596
self._logger.warning(no_load_balancing)
597597

598598
return raw_socket
599+
def enable_ssl(self, raw_socket, ssl_options):
600+
# Send SSL request and read server response
601+
self._logger.debug('=> %s', messages.SslRequest())
602+
raw_socket.sendall(messages.SslRequest().get_message())
603+
response = raw_socket.recv(1)
604+
self._logger.debug('<= SslResponse: %s', response)
605+
606+
if response == b'S':
607+
self._logger.info('Enabling SSL')
608+
try:
609+
server_host = self.address_list.peek_host()
610+
if server_host is None: # This should not happen
611+
msg = 'Cannot get the connected server host while enabling SSL'
612+
self._logger.error(msg)
613+
raise errors.ConnectionError(msg)
614+
615+
if isinstance(ssl_options, ssl.SSLContext):
616+
context = ssl_options
617+
else:
618+
context = ssl.create_default_context()
619+
620+
# Load user-provided certificates if available
621+
cafile = self.options.get('tls_cafile')
622+
certfile = self.options.get('tls_certfile')
623+
keyfile = self.options.get('tls_keyfile')
624+
625+
if cafile:
626+
self._logger.info(f'Loading CA file: {cafile}')
627+
context.load_verify_locations(cafile)
628+
if certfile and keyfile:
629+
self._logger.info(f'Loading client cert: {certfile} and key: {keyfile}')
630+
context.load_cert_chain(certfile=certfile, keyfile=keyfile)
631+
else:
632+
self._logger.warning('Client certificate/key not provided; connection may fail if server requires mutual TLS.')
633+
634+
# Allow automatic negotiation between TLS 1.2 and 1.3
635+
context.minimum_version = ssl.TLSVersion.TLSv1_2
636+
context.maximum_version = ssl.TLSVersion.TLSv1_3
637+
638+
# Enable ALPN for Vertica protocol negotiation
639+
try:
640+
context.set_alpn_protocols(['http/1.1', 'vertica', 'postgresql'])
641+
except NotImplementedError:
642+
self._logger.warning("ALPN not supported on this system; skipping.")
643+
644+
# Disable hostname verification for testing (not for production)
645+
context.check_hostname = True
646+
context.verify_mode = ssl.CERT_REQUIRED
647+
648+
raw_socket = context.wrap_socket(raw_socket, server_hostname=server_host)
649+
650+
except ssl.CertificateError as e:
651+
raise_from(errors.ConnectionError(str(e)), e)
652+
except ssl.SSLError as e:
653+
raise_from(errors.ConnectionError(str(e)), e)
654+
else:
655+
err_msg = "SSL requested but not supported by server"
656+
self._logger.error(err_msg)
657+
raise errors.SSLNotSupported(err_msg)
658+
659+
return raw_socket
660+
599661

600662
def enable_ssl(self,
601663
raw_socket: socket.socket,

0 commit comments

Comments
 (0)