Skip to content

Commit

Permalink
Issue #28025: Convert all ssl module constants to IntEnum and IntFlags.
Browse files Browse the repository at this point in the history
  • Loading branch information
tiran committed Sep 9, 2016
1 parent 308c7c4 commit 328067c
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 19 deletions.
51 changes: 51 additions & 0 deletions Doc/library/ssl.rst
Original file line number Diff line number Diff line change
Expand Up @@ -515,6 +515,10 @@ Certificate handling
Constants
^^^^^^^^^

All constants are now :class:`enum.IntEnum` or :class:`enum.IntFlag` collections.

.. versionadded:: 3.6

.. data:: CERT_NONE

Possible value for :attr:`SSLContext.verify_mode`, or the ``cert_reqs``
Expand Down Expand Up @@ -548,6 +552,12 @@ Constants
be passed, either to :meth:`SSLContext.load_verify_locations` or as a
value of the ``ca_certs`` parameter to :func:`wrap_socket`.

.. class:: VerifyMode

:class:`enum.IntEnum` collection of CERT_* constants.

.. versionadded:: 3.6

.. data:: VERIFY_DEFAULT

Possible value for :attr:`SSLContext.verify_flags`. In this mode, certificate
Expand Down Expand Up @@ -588,6 +598,12 @@ Constants

.. versionadded:: 3.4.4

.. class:: VerifyFlags

:class:`enum.IntFlag` collection of VERIFY_* constants.

.. versionadded:: 3.6

.. data:: PROTOCOL_TLS

Selects the highest protocol version that both the client and server support.
Expand Down Expand Up @@ -757,6 +773,12 @@ Constants

.. versionadded:: 3.3

.. class:: Options

:class:`enum.IntFlag` collection of OP_* constants.

.. versionadded:: 3.6

.. data:: HAS_ALPN

Whether the OpenSSL library has built-in support for the *Application-Layer
Expand Down Expand Up @@ -839,6 +861,12 @@ Constants

.. versionadded:: 3.4

.. class:: AlertDescription

:class:`enum.IntEnum` collection of ALERT_DESCRIPTION_* constants.

.. versionadded:: 3.6

.. data:: Purpose.SERVER_AUTH

Option for :func:`create_default_context` and
Expand All @@ -857,6 +885,12 @@ Constants

.. versionadded:: 3.4

.. class:: SSLErrorNumber

:class:`enum.IntEnum` collection of SSL_ERROR_* constants.

.. versionadded:: 3.6


SSL Sockets
-----------
Expand Down Expand Up @@ -1540,6 +1574,12 @@ to speed up repeated connections from the same clients.
to set options, not to clear them. Attempting to clear an option
(by resetting the corresponding bits) will raise a ``ValueError``.

.. versionchanged:: 3.6
:attr:`SSLContext.options` returns :class:`Options` flags:

>>> ssl.create_default_context().options
<Options.OP_ALL|OP_NO_SSLv3|OP_NO_SSLv2|OP_NO_COMPRESSION: 2197947391>

.. attribute:: SSLContext.protocol

The protocol version chosen when constructing the context. This attribute
Expand All @@ -1554,12 +1594,23 @@ to speed up repeated connections from the same clients.

.. versionadded:: 3.4

.. versionchanged:: 3.6
:attr:`SSLContext.verify_flags` returns :class:`VerifyFlags` flags:

>>> ssl.create_default_context().verify_flags
<VerifyFlags.VERIFY_X509_TRUSTED_FIRST: 32768>

.. attribute:: SSLContext.verify_mode

Whether to try to verify other peers' certificates and how to behave
if verification fails. This attribute must be one of
:data:`CERT_NONE`, :data:`CERT_OPTIONAL` or :data:`CERT_REQUIRED`.

.. versionchanged:: 3.6
:attr:`SSLContext.verify_mode` returns :class:`VerifyMode` enum:

>>> ssl.create_default_context().verify_mode
<VerifyMode.CERT_REQUIRED: 2>

.. index:: single: certificates

Expand Down
80 changes: 61 additions & 19 deletions Lib/ssl.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@
import sys
import os
from collections import namedtuple
from enum import Enum as _Enum, IntEnum as _IntEnum
from enum import Enum as _Enum, IntEnum as _IntEnum, IntFlag as _IntFlag

import _ssl # if we can't import it, let the error propagate

Expand All @@ -104,7 +104,6 @@
SSLError, SSLZeroReturnError, SSLWantReadError, SSLWantWriteError,
SSLSyscallError, SSLEOFError,
)
from _ssl import CERT_NONE, CERT_OPTIONAL, CERT_REQUIRED
from _ssl import txt2obj as _txt2obj, nid2obj as _nid2obj
from _ssl import RAND_status, RAND_add, RAND_bytes, RAND_pseudo_bytes
try:
Expand All @@ -113,32 +112,47 @@
# LibreSSL does not provide RAND_egd
pass

def _import_symbols(prefix):
for n in dir(_ssl):
if n.startswith(prefix):
globals()[n] = getattr(_ssl, n)

_import_symbols('OP_')
_import_symbols('ALERT_DESCRIPTION_')
_import_symbols('SSL_ERROR_')
_import_symbols('VERIFY_')

from _ssl import HAS_SNI, HAS_ECDH, HAS_NPN, HAS_ALPN

from _ssl import _OPENSSL_API_VERSION


_IntEnum._convert(
'_SSLMethod', __name__,
lambda name: name.startswith('PROTOCOL_') and name != 'PROTOCOL_SSLv23',
source=_ssl)

_IntFlag._convert(
'Options', __name__,
lambda name: name.startswith('OP_'),
source=_ssl)

_IntEnum._convert(
'_SSLMethod', __name__,
lambda name: name.startswith('PROTOCOL_') and name != 'PROTOCOL_SSLv23',
source=_ssl)
'AlertDescription', __name__,
lambda name: name.startswith('ALERT_DESCRIPTION_'),
source=_ssl)

_IntEnum._convert(
'SSLErrorNumber', __name__,
lambda name: name.startswith('SSL_ERROR_'),
source=_ssl)

_IntFlag._convert(
'VerifyFlags', __name__,
lambda name: name.startswith('VERIFY_'),
source=_ssl)

_IntEnum._convert(
'VerifyMode', __name__,
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()}

try:
_SSLv2_IF_EXISTS = PROTOCOL_SSLv2
except NameError:
_SSLv2_IF_EXISTS = None
_SSLv2_IF_EXISTS = getattr(_SSLMethod, 'PROTOCOL_SSLv2', None)


if sys.platform == "win32":
from _ssl import enum_certificates, enum_crls
Expand Down Expand Up @@ -434,6 +448,34 @@ def load_default_certs(self, purpose=Purpose.SERVER_AUTH):
self._load_windows_store_certs(storename, purpose)
self.set_default_verify_paths()

@property
def options(self):
return Options(super().options)

@options.setter
def options(self, value):
super(SSLContext, SSLContext).options.__set__(self, value)

@property
def verify_flags(self):
return VerifyFlags(super().verify_flags)

@verify_flags.setter
def verify_flags(self, value):
super(SSLContext, SSLContext).verify_flags.__set__(self, value)

@property
def verify_mode(self):
value = super().verify_mode
try:
return VerifyMode(value)
except ValueError:
return value

@verify_mode.setter
def verify_mode(self, value):
super(SSLContext, SSLContext).verify_mode.__set__(self, value)


def create_default_context(purpose=Purpose.SERVER_AUTH, *, cafile=None,
capath=None, cadata=None):
Expand Down
3 changes: 3 additions & 0 deletions Misc/NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,9 @@ Core and Builtins
Library
-------

- Issue #28025: Convert all ssl module constants to IntEnum and IntFlags.
SSLContext properties now return flags and enums.

- Issue #433028: Added support of modifier spans in regular expressions.

- Issue #24594: Validates persist parameter when opening MSI database
Expand Down

0 comments on commit 328067c

Please sign in to comment.