Christian Heimes added the comment:

PoC implementation:

from enum import Enum
import ssl

OP_NO_TLSv1_3 = getattr(ssl, 'OP_NO_TLSv1_3', 0)

OP_NO_FLAGS = [
    ssl.OP_NO_SSLv2,
    ssl.OP_NO_SSLv3,
    ssl.OP_NO_TLSv1,
    ssl.OP_NO_TLSv1_1,
    ssl.OP_NO_TLSv1_2,
    OP_NO_TLSv1_3
]

OP_NO_MASK = sum(OP_NO_FLAGS)


class TLSVersions(Enum):
    SSLv2 = 'SSL 2.0', 0x0200, 0
    SSLv3 = 'SSL 3.0', 0x0300, 1
    TLSv1 = 'TLS 1.0', 0x0301, 2
    TLSv1_1 = 'TLS 1.1', 0x0302, 3
    TLSv1_2 = 'TLS 1.2', 0x0303, 4

    if OP_NO_TLSv1_3:
        TLSv1_3 = 'TLS 1.3', 0x0304, 5
        MAX = TLSv1_3
    else:
        MAX = TLSv1_2

    MIN = TLSv1

    def __init__(self, prettyname, wireprotocol, offset):
        self.prettyname = prettyname
        self.wireprotocol = wireprotocol
        self.noflag = OP_NO_FLAGS[offset]
        self.minflag = sum(OP_NO_FLAGS[:offset])
        self.maxflag = sum(OP_NO_FLAGS[offset+1:])

    def __repr__(self):
        return ("<{0.__class__.__name__}.{0.name} "
                "({0.prettyname}, 0x{0.wireprotocol:x})>").format(self)

    __str__ = __repr__


class SSLContext(ssl.SSLContext):
    def set_version(self, minver=TLSVersions.MIN, maxver=TLSVersions.MAX):
        options = self.options & ~OP_NO_MASK
        self.options = options | minver.minflag | maxver.maxflag


if __name__ == '__main__':
    for name, member in TLSVersions.__members__.items():
        print(name, member)

    ctx = SSLContext(ssl.PROTOCOL_SSLv23)
    print(ctx.options)
    ctx.set_version(minver=TLSVersions.SSLv3, maxver=TLSVersions.TLSv1_1)
    print(ctx.options)

----------
versions: +Python 3.7 -Python 3.6

_______________________________________
Python tracker <rep...@bugs.python.org>
<http://bugs.python.org/issue27876>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to