diff options
author | Christian Heimes <christian@python.org> | 2018-01-27 15:51:38 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-01-27 15:51:38 +0100 |
commit | 61d478c71c5341cdc54e6bfb4ace4252852fd972 (patch) | |
tree | 5ad17242b4c341df03664ee5cde87cdb80b0ee50 /Lib/ssl.py | |
parent | 746cc75541f31278864a10b995e7d009bd2ff053 (diff) | |
download | cpython-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.py | 29 |
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.""" |