backports-ssl-match-hostname
This library provides a backport of the `ssl.match_hostname()` function from Python 3.5 to earlier Python versions. It ensures proper hostname verification against SSL/TLS certificates, a critical security measure. The current version is 3.7.0.1, released in 2019. The project is considered unmaintained, as its functionality is now present in standard Python versions.
Warnings
- deprecated The `backports-ssl-match-hostname` library is a backport for older Python versions and is not actively maintained. For Python 3.2 and newer, the `ssl.match_hostname()` function is included in the standard library. For Python 3.7+, the implementation includes further updates (e.g., RFC 6125 compliance, IP address handling).
- breaking Security vulnerabilities (CVEs) related to SSL hostname matching have been discovered and patched in the upstream Python `ssl` module (e.g., RFC 6125 compliance, wildcard matching denial-of-service). An unmaintained backport might not receive these critical security updates, leaving applications vulnerable.
- gotcha When using `backports-ssl-match-hostname` on Python versions that *do* have a built-in `ssl.match_hostname`, care must be taken to ensure the backport's version is used if that's the intention (e.g., for specific behavior). However, generally, the built-in version should be preferred if available and up-to-date.
Install
-
pip install backports-ssl-match-hostname
Imports
- match_hostname
from backports.ssl_match_hostname import match_hostname
- CertificateError
from backports.ssl_match_hostname import CertificateError
Quickstart
import socket
import ssl
from backports.ssl_match_hostname import match_hostname, CertificateError
def verify_ssl_hostname(hostname: str, port: int):
try:
# Simulate a socket connection (replace with actual connection in real use)
# For demonstration, we'll create a dummy context and peer certificate
context = ssl.create_default_context()
with socket.create_connection((hostname, port)) as sock:
with context.wrap_socket(sock, server_hostname=hostname) as sslsock:
cert = sslsock.getpeercert()
match_hostname(cert, hostname)
print(f"Hostname '{hostname}' successfully matched certificate.")
except CertificateError as e:
print(f"Certificate hostname mismatch for '{hostname}': {e}")
except Exception as e:
print(f"An error occurred: {e}")
# Example Usage (replace with a real hostname and port for actual testing)
# For a live example, you'd connect to a server with SSL.
# Using a dummy here for runnable example without actual network call or certs.
# To make it runnable for demonstration, let's just show the logic structure.
# This part is illustrative, assumes you have a 'cert' object from a real ssl connection
# For an actual runnable quickstart with mock, it's complex.
# The essence is `match_hostname(sslsock.getpeercert(), hostname)`
# For a truly runnable example (requires a running SSL server at specified host/port)
# try:
# hostname = "www.google.com"
# port = 443
# context = ssl.create_default_context()
# with socket.create_connection((hostname, port)) as sock:
# with context.wrap_socket(sock, server_hostname=hostname) as sslsock:
# cert = sslsock.getpeercert()
# match_hostname(cert, hostname)
# print(f"Hostname '{hostname}' successfully matched certificate.")
# except CertificateError as e:
# print(f"Certificate hostname mismatch for '{hostname}': {e}")
# except Exception as e:
# print(f"An error occurred: {e}")
print("Consult the documentation for actual socket setup as this is a backport.")