summaryrefslogtreecommitdiff
path: root/Lib/ssl.py
diff options
context:
space:
mode:
authorChristian Heimes <christian@python.org>2018-01-27 15:51:38 +0100
committerGitHub <noreply@github.com>2018-01-27 15:51:38 +0100
commit61d478c71c5341cdc54e6bfb4ace4252852fd972 (patch)
tree5ad17242b4c341df03664ee5cde87cdb80b0ee50 /Lib/ssl.py
parent746cc75541f31278864a10b995e7d009bd2ff053 (diff)
downloadcpython-git-61d478c71c5341cdc54e6bfb4ace4252852fd972.tar.gz
bpo-31399: Let OpenSSL verify hostname and IP address (#3462)
bpo-31399: Let OpenSSL verify hostname and IP The ssl module now uses OpenSSL's X509_VERIFY_PARAM_set1_host() and X509_VERIFY_PARAM_set1_ip() API to verify hostname and IP addresses. * Remove match_hostname calls * Check for libssl with set1_host, libssl must provide X509_VERIFY_PARAM_set1_host() * Add documentation for OpenSSL 1.0.2 requirement * Don't support OpenSSL special mode with a leading dot, e.g. ".example.org" matches "www.example.org". It's not standard conform. * Add hostname_checks_common_name Signed-off-by: Christian Heimes <christian@python.org>
Diffstat (limited to 'Lib/ssl.py')
-rw-r--r--Lib/ssl.py29
1 files changed, 20 insertions, 9 deletions
diff --git a/Lib/ssl.py b/Lib/ssl.py
index 7c4cccf4c0..5f972e1d3d 100644
--- a/Lib/ssl.py
+++ b/Lib/ssl.py
@@ -148,7 +148,6 @@ _IntEnum._convert(
lambda name: name.startswith('CERT_'),
source=_ssl)
-
PROTOCOL_SSLv23 = _SSLMethod.PROTOCOL_SSLv23 = _SSLMethod.PROTOCOL_TLS
_PROTOCOL_NAMES = {value: name for name, value in _SSLMethod.__members__.items()}
@@ -172,6 +171,8 @@ if _ssl.HAS_TLS_UNIQUE:
else:
CHANNEL_BINDING_TYPES = []
+HAS_NEVER_CHECK_COMMON_NAME = hasattr(_ssl, 'HOSTFLAG_NEVER_CHECK_SUBJECT')
+
# Disable weak or insecure ciphers by default
# (OpenSSL's default setting is 'DEFAULT:!aNULL:!eNULL')
@@ -216,9 +217,7 @@ _RESTRICTED_SERVER_CIPHERS = (
'!aNULL:!eNULL:!MD5:!DSS:!RC4:!3DES'
)
-
-class CertificateError(ValueError):
- pass
+CertificateError = SSLCertVerificationError
def _dnsname_match(dn, hostname):
@@ -473,6 +472,23 @@ class SSLContext(_SSLContext):
def options(self, value):
super(SSLContext, SSLContext).options.__set__(self, value)
+ if hasattr(_ssl, 'HOSTFLAG_NEVER_CHECK_SUBJECT'):
+ @property
+ def hostname_checks_common_name(self):
+ ncs = self._host_flags & _ssl.HOSTFLAG_NEVER_CHECK_SUBJECT
+ return ncs != _ssl.HOSTFLAG_NEVER_CHECK_SUBJECT
+
+ @hostname_checks_common_name.setter
+ def hostname_checks_common_name(self, value):
+ if value:
+ self._host_flags &= ~_ssl.HOSTFLAG_NEVER_CHECK_SUBJECT
+ else:
+ self._host_flags |= _ssl.HOSTFLAG_NEVER_CHECK_SUBJECT
+ else:
+ @property
+ def hostname_checks_common_name(self):
+ return True
+
@property
def verify_flags(self):
return VerifyFlags(super().verify_flags)
@@ -699,11 +715,6 @@ class SSLObject:
def do_handshake(self):
"""Start the SSL/TLS handshake."""
self._sslobj.do_handshake()
- if self.context.check_hostname:
- if not self.server_hostname:
- raise ValueError("check_hostname needs server_hostname "
- "argument")
- match_hostname(self.getpeercert(), self.server_hostname)
def unwrap(self):
"""Start the SSL shutdown handshake."""