bpo-31453: Add setter for min/max protocol version (#5259)

OpenSSL 1.1 has introduced a new API to set the minimum and maximum
supported protocol version. The API is easier to use than the old
OP_NO_TLS1 option flags, too.

Since OpenSSL has no call to set minimum version to highest supported,
the implementation emulate maximum_version = MINIMUM_SUPPORTED and
minimum_version = MAXIMUM_SUPPORTED by figuring out the minumum and
maximum supported version at compile time.

Signed-off-by: Christian Heimes <christian@python.org>
This commit is contained in:
Christian Heimes 2018-02-27 11:54:43 +01:00 committed by GitHub
parent 9d50ab563d
commit 698dde16f6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 474 additions and 30 deletions

View file

@ -112,9 +112,11 @@ except ImportError:
pass
from _ssl import HAS_SNI, HAS_ECDH, HAS_NPN, HAS_ALPN, HAS_TLSv1_3
from _ssl import _DEFAULT_CIPHERS
from _ssl import _OPENSSL_API_VERSION
from _ssl import (
HAS_SNI, HAS_ECDH, HAS_NPN, HAS_ALPN, HAS_SSLv2, HAS_SSLv3, HAS_TLSv1,
HAS_TLSv1_1, HAS_TLSv1_2, HAS_TLSv1_3
)
from _ssl import _DEFAULT_CIPHERS, _OPENSSL_API_VERSION
_IntEnum._convert(
@ -153,6 +155,16 @@ _PROTOCOL_NAMES = {value: name for name, value in _SSLMethod.__members__.items()
_SSLv2_IF_EXISTS = getattr(_SSLMethod, 'PROTOCOL_SSLv2', None)
class TLSVersion(_IntEnum):
MINIMUM_SUPPORTED = _ssl.PROTO_MINIMUM_SUPPORTED
SSLv3 = _ssl.PROTO_SSLv3
TLSv1 = _ssl.PROTO_TLSv1
TLSv1_1 = _ssl.PROTO_TLSv1_1
TLSv1_2 = _ssl.PROTO_TLSv1_2
TLSv1_3 = _ssl.PROTO_TLSv1_3
MAXIMUM_SUPPORTED = _ssl.PROTO_MAXIMUM_SUPPORTED
if sys.platform == "win32":
from _ssl import enum_certificates, enum_crls
@ -467,6 +479,25 @@ class SSLContext(_SSLContext):
self._load_windows_store_certs(storename, purpose)
self.set_default_verify_paths()
if hasattr(_SSLContext, 'minimum_version'):
@property
def minimum_version(self):
return TLSVersion(super().minimum_version)
@minimum_version.setter
def minimum_version(self, value):
if value == TLSVersion.SSLv3:
self.options &= ~Options.OP_NO_SSLv3
super(SSLContext, SSLContext).minimum_version.__set__(self, value)
@property
def maximum_version(self):
return TLSVersion(super().maximum_version)
@maximum_version.setter
def maximum_version(self, value):
super(SSLContext, SSLContext).maximum_version.__set__(self, value)
@property
def options(self):
return Options(super().options)