示例#1
0
def create_urllib3_context(ssl_version=None, cert_reqs=None,
                           options=None, ciphers=None):
    """All arguments have the same meaning as ``ssl_wrap_socket``.

    By default, this function does a lot of the same work that
    ``ssl.create_default_context`` does on Python 3.4+. It:

    - Disables SSLv2, SSLv3, and compression
    - Sets a restricted set of server ciphers

    If you wish to enable SSLv3, you can do::

        from pip._vendor.urllib3.util import ssl_
        context = ssl_.create_urllib3_context()
        context.options &= ~ssl_.OP_NO_SSLv3

    You can do the same to enable compression (substituting ``COMPRESSION``
    for ``SSLv3`` in the last line above).

    :param ssl_version:
        The desired protocol version to use. This will default to
        PROTOCOL_SSLv23 which will negotiate the highest protocol that both
        the server and your installation of OpenSSL support.
    :param cert_reqs:
        Whether to require the certificate verification. This defaults to
        ``ssl.CERT_REQUIRED``.
    :param options:
        Specific OpenSSL options. These default to ``ssl.OP_NO_SSLv2``,
        ``ssl.OP_NO_SSLv3``, ``ssl.OP_NO_COMPRESSION``.
    :param ciphers:
        Which cipher suites to allow the server to select.
    :returns:
        Constructed SSLContext object with specified options
    :rtype: SSLContext
    """
    context = SSLContext(ssl_version or ssl.PROTOCOL_SSLv23)

    context.set_ciphers(ciphers or DEFAULT_CIPHERS)

    # Setting the default here, as we may have no ssl module on import
    cert_reqs = ssl.CERT_REQUIRED if cert_reqs is None else cert_reqs

    if options is None:
        options = 0
        # SSLv2 is easily broken and is considered harmful and dangerous
        options |= OP_NO_SSLv2
        # SSLv3 has several problems and is now dangerous
        options |= OP_NO_SSLv3
        # Disable compression to prevent CRIME attacks for OpenSSL 1.0+
        # (issue #309)
        options |= OP_NO_COMPRESSION

    context.options |= options

    context.verify_mode = cert_reqs
    if getattr(context, 'check_hostname', None) is not None:  # Platform-specific: Python 3.2
        # We do our own verification, including fingerprints and alternative
        # hostnames. So disable it here
        context.check_hostname = False
    return context
示例#2
0
def wrap(client, _socket):
    """ Wrap socket in SSL wrapper. """
    if client.init_kwargs.get('use_ssl', None):
        keyfile = client.init_kwargs.get('ssl_keyfile', None)
        certfile = client.init_kwargs.get('ssl_certfile', None)

        if keyfile and not certfile:
            raise ValueError("certfile must be specified")

        password = client.init_kwargs.get('ssl_keyfile_password', None)
        ssl_version = client.init_kwargs.get('ssl_version',
                                             SSL_DEFAULT_VERSION)
        ciphers = client.init_kwargs.get('ssl_ciphers', SSL_DEFAULT_CIPHERS)
        cert_reqs = client.init_kwargs.get('ssl_cert_reqs', ssl.CERT_NONE)
        ca_certs = client.init_kwargs.get('ssl_ca_certfile', None)

        context = SSLContext(ssl_version)
        context.verify_mode = cert_reqs

        if ca_certs:
            context.load_verify_locations(ca_certs)
        if certfile:
            context.load_cert_chain(certfile, keyfile, password)
        if ciphers:
            context.set_ciphers(ciphers)

        _socket = context.wrap_socket(sock=_socket)

    return _socket
示例#3
0
    async def wrap_connection(self,
                              packet: bytes,
                              up: AbstractAioSocket,
                              down: AbstractAioSocket,
                              loop: AbstractEventLoop) -> \
            Tuple[AbstractAioSocket, AbstractAioSocket]:
        print("Wrapping connection...")
        # TODO: What to do, if sni returns 'None'?
        sni = get_sni_from_handshake(packet)

        print("Wrapping Server")
        new_down: AbstractAioSocket = AioTlsSocket(
            down,
            _create_unverified_context(PROTOCOL_SSLv23),
            server_hostname=sni,
            loop=loop)
        await new_down.handshake()

        certificate_file = self.certificate_manager.get_certificate(sni)
        ctx = SSLContext(PROTOCOL_SSLv23)
        ctx.set_ciphers(self.ciphers)
        ctx.load_cert_chain(
            certificate_file, certificate_file,
            self.certificate_manager.get_certificate_password())
        print("Wrapping Client")
        new_up = AioTlsSocket(up, ctx, True, loop=loop)
        new_up.push_data(packet)
        await new_up.handshake()
        print("Done")

        return new_up, new_down
示例#4
0
    def ssl_wrap_socket(sock, keyfile=None, certfile=None, cert_reqs=None,
                        ca_certs=None, server_hostname=None,
                        ssl_version=None, ciphers=None):
        """
        All arguments except `server_hostname` have the same meaning as for
        :func:`ssl.wrap_socket`

        :param server_hostname:
            Hostname of the expected certificate
        """
        context = SSLContext(ssl_version)
        context.verify_mode = cert_reqs

        # Disable TLS compression to migitate CRIME attack (issue #309)
        OP_NO_COMPRESSION = 0x20000
        context.options |= OP_NO_COMPRESSION

        if ca_certs:
            try:
                context.load_verify_locations(ca_certs)
            # Py32 raises IOError
            # Py33 raises FileNotFoundError
            except Exception as e:  # Reraise as SSLError
                raise SSLError(e)
        if certfile:
            # FIXME: This block needs a test.
            context.load_cert_chain(certfile, keyfile)
        if ciphers:
            context.set_ciphers(ciphers)
        if HAS_SNI:  # Platform-specific: OpenSSL with enabled SNI
            return context.wrap_socket(sock, server_hostname=server_hostname)
        return context.wrap_socket(sock)
def create_ssl_context(ssl_params):
    if not ssl_params.get('use_ssl'):
        return None

    keyfile = ssl_params.get('ssl_keyfile', None)
    certfile = ssl_params.get('ssl_certfile', None)

    if keyfile and not certfile:
        raise ValueError("certfile must be specified")

    password = ssl_params.get('ssl_keyfile_password', None)
    ssl_version = ssl_params.get('ssl_version', SSL_DEFAULT_VERSION)
    ciphers = ssl_params.get('ssl_ciphers', SSL_DEFAULT_CIPHERS)
    cert_reqs = ssl_params.get('ssl_cert_reqs', ssl.CERT_NONE)
    ca_certs = ssl_params.get('ssl_ca_certfile', None)

    context = SSLContext(ssl_version)
    context.verify_mode = cert_reqs

    if ca_certs:
        context.load_verify_locations(ca_certs)
    if certfile:
        context.load_cert_chain(certfile, keyfile, password)
    if ciphers:
        context.set_ciphers(ciphers)

    return context
示例#6
0
文件: ssl_.py 项目: Ddoudou/test
def create_urllib3_context(ssl_version=None, cert_reqs=None,
                           options=None, ciphers=None):
    """All arguments have the same meaning as ``ssl_wrap_socket``.

    By default, this function does a lot of the same work that
    ``ssl.create_default_context`` does on Python 3.4+. It:

    - Disables SSLv2, SSLv3, and compression
    - Sets a restricted set of server ciphers

    If you wish to enable SSLv3, you can do::

        from urllib3.util import ssl_
        context = ssl_.create_urllib3_context()
        context.options &= ~ssl_.OP_NO_SSLv3

    You can do the same to enable compression (substituting ``COMPRESSION``
    for ``SSLv3`` in the last line above).

    :param ssl_version:
        The desired protocol version to use. This will default to
        PROTOCOL_SSLv23 which will negotiate the highest protocol that both
        the server and your installation of OpenSSL support.
    :param cert_reqs:
        Whether to require the certificate verification. This defaults to
        ``ssl.CERT_REQUIRED``.
    :param options:
        Specific OpenSSL options. These default to ``ssl.OP_NO_SSLv2``,
        ``ssl.OP_NO_SSLv3``, ``ssl.OP_NO_COMPRESSION``.
    :param ciphers:
        Which cipher suites to allow the server to select.
    :returns:
        Constructed SSLContext object with specified options
    :rtype: SSLContext
    """
    context = SSLContext(ssl_version or ssl.PROTOCOL_SSLv23)

    context.set_ciphers(ciphers or DEFAULT_CIPHERS)

    # Setting the default here, as we may have no ssl module on import
    cert_reqs = ssl.CERT_REQUIRED if cert_reqs is None else cert_reqs

    if options is None:
        options = 0
        # SSLv2 is easily broken and is considered harmful and dangerous
        options |= OP_NO_SSLv2
        # SSLv3 has several problems and is now dangerous
        options |= OP_NO_SSLv3
        # Disable compression to prevent CRIME attacks for OpenSSL 1.0+
        # (issue #309)
        options |= OP_NO_COMPRESSION

    context.options |= options

    context.verify_mode = cert_reqs
    if getattr(context, 'check_hostname', None) is not None:  # Platform-specific: Python 3.2
        # We do our own verification, including fingerprints and alternative
        # hostnames. So disable it here
        context.check_hostname = False
    return context
示例#7
0
def sslContext(trustStore: str, keyStore: str) -> SSLContext:
    sslContext = SSLContext(PROTOCOL_TLSv1_2)
    sslContext.verify_mode = CERT_REQUIRED
    storePath = "../../certificates/"
    sslContext.load_verify_locations(storePath + trustStore)
    sslContext.load_cert_chain(storePath + keyStore, password="******")
    sslContext.set_ciphers("AES128-SHA")
    return sslContext
示例#8
0
def sslContext(trustStore: str, keyStore: str) -> SSLContext:
    sslContext = SSLContext(PROTOCOL_TLSv1_2)
    sslContext.verify_mode = CERT_REQUIRED
    storePath = "../../certificates/"
    sslContext.load_verify_locations(storePath + trustStore)
    sslContext.load_cert_chain(storePath + keyStore, password="******")
    sslContext.set_ciphers("AES128-SHA")
    return sslContext
示例#9
0
def getSSLContext(capath, crtpath, keypath, keypass=None):
    ctx = SSLContext(PROTOCOL_TLSv1_2)
    ctx.set_ciphers('HIGH:!SSLv3:!TLSv1:!aNULL:@STRENGTH')
    # client certificate is required
    ctx.verify_mode = CERT_REQUIRED
    ctx.options |= OP_NO_COMPRESSION
    ctx.load_verify_locations(capath)
    ctx.load_cert_chain(crtpath, keypath, password=keypass)
    return ctx
示例#10
0
 def clean_cipher_suite(self):
     """ Verify cipher suite format """
     value = self.cleaned_data['cipher_suite']
     """ Test cipher with ssl library """
     c = SSLContext(PROTOCOL_SSLv23)  # FIXME : Associate with selected protocol
     try:
         c.set_ciphers(value)
     except SSLError:
         self.add_error('cipher_suite', "Invalid cipher suite")
     return value
示例#11
0
 def _create_ssl_context(self) -> Optional[SSLContext]:
     ssl_context = None
     if self.cfg.is_ssl:
         ssl_context = SSLContext(self.cfg.ssl_version)
         ssl_context.load_cert_chain(self.cfg.certfile, self.cfg.keyfile)
         if self.cfg.ca_certs:
             ssl_context.load_verify_locations(self.cfg.ca_certs)
         if self.cfg.ciphers:
             ssl_context.set_ciphers(self.cfg.ciphers)
         ssl_context.set_alpn_protocols(['h2', 'http/1.1'])
     return ssl_context
示例#12
0
文件: ssl_.py 项目: connoryang/1v1dec
def create_urllib3_context(ssl_version = None, cert_reqs = None, options = None, ciphers = None):
    context = SSLContext(ssl_version or ssl.PROTOCOL_SSLv23)
    cert_reqs = ssl.CERT_REQUIRED if cert_reqs is None else cert_reqs
    if options is None:
        options = 0
        options |= OP_NO_SSLv2
        options |= OP_NO_SSLv3
        options |= OP_NO_COMPRESSION
    context.options |= options
    if getattr(context, 'supports_set_ciphers', True):
        context.set_ciphers(ciphers or DEFAULT_CIPHERS)
    context.verify_mode = cert_reqs
    if getattr(context, 'check_hostname', None) is not None:
        context.check_hostname = False
    return context
示例#13
0
文件: _ssl.py 项目: 10sr/hue
def create_thriftpy_context(server_side=False, ciphers=None):
    """Backport create_default_context for older python versions.

    The SSLContext has some default security options, you can disable them
    manually, for example::

        from thriftpy.transport import _ssl
        context = _ssl.create_thriftpy_context()
        context.options &= ~_ssl.OP_NO_SSLv3

    You can do the same to enable compression.
    """
    if MODERN_SSL:
        if server_side:
            context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
        else:
            context = ssl.create_default_context(ssl.Purpose.SERVER_AUTH)

        if ciphers:
            context.set_ciphers(ciphers)

    else:
        context = SSLContext(ssl.PROTOCOL_SSLv23)
        context.options |= OP_NO_SSLv2
        context.options |= OP_NO_SSLv3
        context.options |= OP_NO_COMPRESSION

        # server/client default options
        if server_side:
            context.options |= OP_CIPHER_SERVER_PREFERENCE
            context.options |= OP_SINGLE_DH_USE
            context.options |= OP_SINGLE_ECDH_USE
        else:
            context.verify_mode = ssl.CERT_REQUIRED
            # context.check_hostname = True
            warnings.warn(
                "ssl check hostname support disabled, upgrade your python",
                InsecurePlatformWarning)

        # Platform-specific: Python 2.6
        if getattr(context, 'supports_set_ciphers', True):
            if ciphers:
                context.set_ciphers(ciphers)
        else:
            warnings.warn("ssl ciphers support disabled, upgrade your python",
                          InsecurePlatformWarning)

    return context
示例#14
0
def create_thriftpy_context(server_side=False, ciphers=None):
    """Backport create_default_context for older python versions.

    The SSLContext has some default security options, you can disable them
    manually, for example::

        from thriftpy.transport import _ssl
        context = _ssl.create_thriftpy_context()
        context.options &= ~_ssl.OP_NO_SSLv3

    You can do the same to enable compression.
    """
    if MODERN_SSL:
        if server_side:
            context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
        else:
            context = ssl.create_default_context(ssl.Purpose.SERVER_AUTH)

        if ciphers:
            context.set_ciphers(ciphers)

    else:
        context = SSLContext(ssl.PROTOCOL_SSLv23)
        context.options |= OP_NO_SSLv2
        context.options |= OP_NO_SSLv3
        context.options |= OP_NO_COMPRESSION

        # server/client default options
        if server_side:
            context.options |= OP_CIPHER_SERVER_PREFERENCE
            context.options |= OP_SINGLE_DH_USE
            context.options |= OP_SINGLE_ECDH_USE
        else:
            context.verify_mode = ssl.CERT_REQUIRED
            # context.check_hostname = True
            warnings.warn(
                "ssl check hostname support disabled, upgrade your python",
                InsecurePlatformWarning)

        # Platform-specific: Python 2.6
        if getattr(context, 'supports_set_ciphers', True):
            if ciphers:
                context.set_ciphers(ciphers)
        else:
            warnings.warn("ssl ciphers support disabled, upgrade your python",
                          InsecurePlatformWarning)

    return context
示例#15
0
 def _config_ssl_context(config):
     if config.get_ssl_context() is not None:
         return
     if config.get_service_url().scheme == 'https':
         try:
             if config.get_ssl_protocol() is None:
                 ctx = create_default_context()
             else:
                 ctx = SSLContext(config.get_ssl_protocol())
             if config.get_ssl_cipher_suites() is not None:
                 ctx.set_ciphers(config.get_ssl_cipher_suites())
             if config.get_ssl_ca_certs() is not None:
                 ctx.load_verify_locations(config.get_ssl_ca_certs())
             config.set_ssl_context(ctx)
         except (SSLError, ValueError) as err:
             raise IllegalArgumentException(str(err))
示例#16
0
    def __get_ssl_context(cls, sslca=None):
        """Make an SSLConext for this Python version using public or sslca
        """
        if ((version_info[0] == 2 and (version_info[1] >= 7 and version_info[2] >= 5)) or
                (version_info[0] == 3 and version_info[1] >= 4)):
            logger.debug('SSL method for 2.7.5+ / 3.4+')
            # pylint: disable=no-name-in-module,import-outside-toplevel
            from ssl import SSLContext, PROTOCOL_TLSv1_2, CERT_REQUIRED, OP_NO_COMPRESSION
            ctx = SSLContext(PROTOCOL_TLSv1_2)
            ctx.set_ciphers('HIGH:!SSLv3:!TLSv1:!aNULL:@STRENGTH')
            # see CRIME security exploit
            ctx.options |= OP_NO_COMPRESSION
            # the following options are used to verify the identity of the broker
            if sslca:
                ctx.load_verify_locations(sslca)
                ctx.verify_mode = CERT_REQUIRED
                ctx.check_hostname = False
            else:
                # Verify public certifcates if sslca is None (default)
                from ssl import Purpose  # pylint: disable=no-name-in-module,import-outside-toplevel
                ctx.load_default_certs(purpose=Purpose.SERVER_AUTH)
                ctx.verify_mode = CERT_REQUIRED
                ctx.check_hostname = True

        elif version_info[0] == 3 and version_info[1] < 4:
            logger.debug('Using SSL method for 3.2+, < 3.4')
            # pylint: disable=no-name-in-module,import-outside-toplevel
            from ssl import SSLContext, CERT_REQUIRED, PROTOCOL_SSLv23, OP_NO_SSLv2, OP_NO_SSLv3, OP_NO_TLSv1
            ctx = SSLContext(PROTOCOL_SSLv23)
            ctx.options |= (OP_NO_SSLv2 | OP_NO_SSLv3 | OP_NO_TLSv1)
            ctx.set_ciphers('HIGH:!SSLv3:!TLSv1:!aNULL:@STRENGTH')
            # the following options are used to verify the identity of the broker
            if sslca:
                ctx.load_verify_locations(sslca)
                ctx.verify_mode = CERT_REQUIRED
            else:
                # Verify public certifcates if sslca is None (default)
                ctx.set_default_verify_paths()
                ctx.verify_mode = CERT_REQUIRED

        else:
            raise Exception("Unsupported Python version %s" % '.'.join(str(item) for item in version_info[:3]))

        return ctx
示例#17
0
    def __get_ssl_context(cls, sslca=None):
        """Make an SSLConext for this Python version using public or sslca
        """
        if ((version_info[0] == 2 and (version_info[1] >= 7 and version_info[2] >= 9)) or
                (version_info[0] == 3 and version_info[1] >= 4)):
            logger.debug('SSL method for 2.7.9+ / 3.4+')
            # pylint: disable=no-name-in-module
            from ssl import SSLContext, PROTOCOL_TLSv1_2, CERT_REQUIRED, OP_NO_COMPRESSION
            ctx = SSLContext(PROTOCOL_TLSv1_2)
            ctx.set_ciphers('HIGH:!SSLv3:!TLSv1:!aNULL:@STRENGTH')
            # see CRIME security exploit
            ctx.options |= OP_NO_COMPRESSION
            # the following options are used to verify the identity of the broker
            if sslca:
                ctx.load_verify_locations(sslca)
                ctx.verify_mode = CERT_REQUIRED
                ctx.check_hostname = False
            else:
                # Verify public certifcates if sslca is None (default)
                from ssl import Purpose  # pylint: disable=no-name-in-module
                ctx.load_default_certs(purpose=Purpose.SERVER_AUTH)
                ctx.verify_mode = CERT_REQUIRED
                ctx.check_hostname = True

        elif version_info[0] == 3 and version_info[1] < 4:
            logger.debug('Using SSL method for 3.2+, < 3.4')
            # pylint: disable=no-name-in-module
            from ssl import SSLContext, CERT_REQUIRED, PROTOCOL_SSLv23, OP_NO_SSLv2, OP_NO_SSLv3, OP_NO_TLSv1
            ctx = SSLContext(PROTOCOL_SSLv23)
            ctx.options |= (OP_NO_SSLv2 | OP_NO_SSLv3 | OP_NO_TLSv1)
            ctx.set_ciphers('HIGH:!SSLv3:!TLSv1:!aNULL:@STRENGTH')
            # the following options are used to verify the identity of the broker
            if sslca:
                ctx.load_verify_locations(sslca)
                ctx.verify_mode = CERT_REQUIRED
            else:
                # Verify public certifcates if sslca is None (default)
                ctx.set_default_verify_paths()
                ctx.verify_mode = CERT_REQUIRED

        else:
            raise Exception("Unsupported Python version %s" % '.'.join(str(item) for item in version_info[:3]))

        return ctx
示例#18
0
    def _make_call(self, message):
        """All network interaction is isolated here for stubbing out."""
        request = Request('https://%s:%s/' % (self.host, self.port))
        headers = {
            'Content-Type': 'text/xml',
            'X-Username': self.username,
            'X-Signature': message.sign(self.private_key),
        }
        [request.add_header(k, v) for k, v in headers.items()]

        timeout = message.timeout or self.default_timeout
        log.debug('Making XCP call with timeout = %s', timeout)

        ctx = SSLContext()
        ctx.set_ciphers('DEFAULT:!DH')
        xml = urlopen(request, message.get_content(), timeout,
                      context=ctx).read()

        return OPSMessage(xml=xml)
示例#19
0
from ssl import SSLContext, PROTOCOL_TLS, CERT_REQUIRED, Purpose

if __name__ == '__main__':
    """
    Départ du serveur générique WSGI Flask
    """

    context = None

    if app.config.get('HERMES_CERTIFICAT_TLS') and app.config.get(
            'HERMES_CLE_PRIVEE_TLS'):
        context = SSLContext(PROTOCOL_TLS)

        context.check_hostname = True
        context.set_ciphers(
            "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384"
        )

        context.verify_mode = CERT_REQUIRED
        context.load_cert_chain(app.config.get('HERMES_CERTIFICAT_TLS'),
                                app.config.get('HERMES_CLE_PRIVEE_TLS'))

        context.load_default_certs(Purpose.SERVER_AUTH)

        if app.config.get('HERMES_CERTIFICAT_CA'):
            context.load_verify_locations(
                app.config.get('HERMES_CERTIFICAT_CA'))

    adhoc_request = app.config.get(
        'HERMES_CERTIFICAT_TLS') is False and app.config.get(
            'HERMES_CLE_PRIVEE_TLS') is False and app.config.get(
示例#20
0
def create_urllib3_context(
    ssl_version: Optional[int] = None,
    cert_reqs: Optional[int] = None,
    options: Optional[int] = None,
    ciphers: Optional[str] = None,
) -> "ssl.SSLContext":
    """All arguments have the same meaning as ``ssl_wrap_socket``.

    By default, this function does a lot of the same work that
    ``ssl.create_default_context`` does on Python 3.4+. It:

    - Disables SSLv2, SSLv3, and compression
    - Sets a restricted set of server ciphers

    If you wish to enable SSLv3, you can do::

        from urllib3.util import ssl_
        context = ssl_.create_urllib3_context()
        context.options &= ~ssl_.OP_NO_SSLv3

    You can do the same to enable compression (substituting ``COMPRESSION``
    for ``SSLv3`` in the last line above).

    :param ssl_version:
        The desired protocol version to use. This will default to
        PROTOCOL_SSLv23 which will negotiate the highest protocol that both
        the server and your installation of OpenSSL support.
    :param cert_reqs:
        Whether to require the certificate verification. This defaults to
        ``ssl.CERT_REQUIRED``.
    :param options:
        Specific OpenSSL options. These default to ``ssl.OP_NO_SSLv2``,
        ``ssl.OP_NO_SSLv3``, ``ssl.OP_NO_COMPRESSION``, and ``ssl.OP_NO_TICKET``.
    :param ciphers:
        Which cipher suites to allow the server to select. Defaults to either system configured
        ciphers if OpenSSL 1.1.1+, otherwise uses a secure default set of ciphers.
    :returns:
        Constructed SSLContext object with specified options
    :rtype: SSLContext
    """
    if SSLContext is None:
        raise TypeError(
            "Can't create an SSLContext object without an ssl module")
    context = SSLContext(ssl_version or PROTOCOL_TLS)
    # Unless we're given ciphers defer to either system ciphers in
    # the case of OpenSSL 1.1.1+ or use our own secure default ciphers.
    if ciphers is not None or not USE_DEFAULT_SSLCONTEXT_CIPHERS:
        context.set_ciphers(ciphers or DEFAULT_CIPHERS)

    # Setting the default here, as we may have no ssl module on import
    cert_reqs = ssl.CERT_REQUIRED if cert_reqs is None else cert_reqs

    if options is None:
        options = 0
        # SSLv2 is easily broken and is considered harmful and dangerous
        options |= OP_NO_SSLv2
        # SSLv3 has several problems and is now dangerous
        options |= OP_NO_SSLv3
        # Disable compression to prevent CRIME attacks for OpenSSL 1.0+
        # (issue #309)
        options |= OP_NO_COMPRESSION
        # TLSv1.2 only. Unless set explicitly, do not request tickets.
        # This may save some bandwidth on wire, and although the ticket is encrypted,
        # there is a risk associated with it being on wire,
        # if the server is not rotating its ticketing keys properly.
        options |= OP_NO_TICKET

    context.options |= options

    # Enable post-handshake authentication for TLS 1.3, see GH #1634. PHA is
    # necessary for conditional client cert authentication with TLS 1.3.
    # The attribute is None for OpenSSL <= 1.1.0 or does not exist in older
    # versions of Python.  We only enable on Python 3.7.4+ or if certificate
    # verification is enabled to work around Python issue #37428
    # See: https://bugs.python.org/issue37428
    if (cert_reqs == ssl.CERT_REQUIRED or sys.version_info >=
        (3, 7, 4)) and getattr(context, "post_handshake_auth",
                               None) is not None:
        context.post_handshake_auth = True

    context.verify_mode = cert_reqs
    # We ask for verification here but it may be disabled in HTTPSConnection.connect
    context.check_hostname = cert_reqs == ssl.CERT_REQUIRED
    if hasattr(context, "hostname_checks_common_name"):
        context.hostname_checks_common_name = False

    # Enable logging of TLS session keys via defacto standard environment variable
    # 'SSLKEYLOGFILE', if the feature is available (Python 3.8+). Skip empty values.
    if hasattr(context, "keylog_filename"):
        sslkeylogfile = os.environ.get("SSLKEYLOGFILE")
        if sslkeylogfile:
            context.keylog_filename = sslkeylogfile

    return context
示例#21
0
        the server and your installation of OpenSSL support.
    :param cert_reqs:
        Whether to require the certificate verification. This defaults to
        ``ssl.CERT_REQUIRED``.
    :param options:
        Specific OpenSSL options. These default to ``ssl.OP_NO_SSLv2``,
        ``ssl.OP_NO_SSLv3``, ``ssl.OP_NO_COMPRESSION``.
    :param ciphers:
        Which cipher suites to allow the server to select.
    :returns:
        Constructed SSLContext object with specified options
    :rtype: SSLContext
    """
    context = SSLContext(ssl_version or PROTOCOL_TLS)

    context.set_ciphers(ciphers or DEFAULT_CIPHERS)

    # Setting the default here, as we may have no ssl module on import
    cert_reqs = ssl.CERT_REQUIRED if cert_reqs is None else cert_reqs

    if options is None:
        options = 0
        # SSLv2 is easily broken and is considered harmful and dangerous
        options |= OP_NO_SSLv2
        # SSLv3 has several problems and is now dangerous
        options |= OP_NO_SSLv3
        # Disable compression to prevent CRIME attacks for OpenSSL 1.0+
        # (issue #309)
        options |= OP_NO_COMPRESSION

    context.options |= options
示例#22
0
def create_urllib3_context(
    ssl_version: Optional[int] = None,
    cert_reqs: Optional[int] = None,
    options: Optional[int] = None,
    ciphers: Optional[str] = None,
    ssl_minimum_version: Optional[int] = None,
    ssl_maximum_version: Optional[int] = None,
) -> "ssl.SSLContext":
    """All arguments have the same meaning as ``ssl_wrap_socket``.

    By default, this function does a lot of the same work that
    ``ssl.create_default_context`` does on Python 3.4+. It:

    - Disables SSLv2, SSLv3, and compression
    - Sets a restricted set of server ciphers

    If you wish to enable SSLv3, you can do::

        from urllib3.util import ssl_
        context = ssl_.create_urllib3_context()
        context.options &= ~ssl_.OP_NO_SSLv3

    You can do the same to enable compression (substituting ``COMPRESSION``
    for ``SSLv3`` in the last line above).

    :param ssl_version:
        The desired protocol version to use. This will default to
        PROTOCOL_SSLv23 which will negotiate the highest protocol that both
        the server and your installation of OpenSSL support.

        This parameter is deprecated instead use 'ssl_minimum_version'.
    :param ssl_minimum_version:
        The minimum version of TLS to be used. Use the 'ssl.TLSVersion' enum for specifying the value.
    :param ssl_maximum_version:
        The maximum version of TLS to be used. Use the 'ssl.TLSVersion' enum for specifying the value.
        Not recommended to set to anything other than 'ssl.TLSVersion.MAXIMUM_SUPPORTED' which is the
        default value.
    :param cert_reqs:
        Whether to require the certificate verification. This defaults to
        ``ssl.CERT_REQUIRED``.
    :param options:
        Specific OpenSSL options. These default to ``ssl.OP_NO_SSLv2``,
        ``ssl.OP_NO_SSLv3``, ``ssl.OP_NO_COMPRESSION``, and ``ssl.OP_NO_TICKET``.
    :param ciphers:
        Which cipher suites to allow the server to select. Defaults to either system configured
        ciphers if OpenSSL 1.1.1+, otherwise uses a secure default set of ciphers.
    :returns:
        Constructed SSLContext object with specified options
    :rtype: SSLContext
    """
    if SSLContext is None:
        raise TypeError(
            "Can't create an SSLContext object without an ssl module")

    # This means 'ssl_version' was specified as an exact value.
    if ssl_version not in (None, PROTOCOL_TLS, PROTOCOL_TLS_CLIENT):
        # Disallow setting 'ssl_version' and 'ssl_minimum|maximum_version'
        # to avoid conflicts.
        if ssl_minimum_version is not None or ssl_maximum_version is not None:
            raise ValueError("Can't specify both 'ssl_version' and either "
                             "'ssl_minimum_version' or 'ssl_maximum_version'")

        # 'ssl_version' is deprecated and will be removed in the future.
        else:
            # Use 'ssl_minimum_version' and 'ssl_maximum_version' instead.
            ssl_minimum_version = _SSL_VERSION_TO_TLS_VERSION.get(
                ssl_version, TLSVersion.MINIMUM_SUPPORTED)
            ssl_maximum_version = _SSL_VERSION_TO_TLS_VERSION.get(
                ssl_version, TLSVersion.MAXIMUM_SUPPORTED)

            # This warning message is pushing users to use 'ssl_minimum_version'
            # instead of both min/max. Best practice is to only set the minimum version and
            # keep the maximum version to be it's default value: 'TLSVersion.MAXIMUM_SUPPORTED'
            warnings.warn(
                "'ssl_version' option is deprecated and will be "
                "removed in a future release of urllib3 2.x. Instead "
                "use 'ssl_minimum_version'",
                category=DeprecationWarning,
                stacklevel=2,
            )

    # PROTOCOL_TLS is deprecated in Python 3.10 so we always use PROTOCOL_TLS_CLIENT
    context = SSLContext(PROTOCOL_TLS_CLIENT)

    if ssl_minimum_version is not None:
        context.minimum_version = ssl_minimum_version
    else:  # Python <3.10 defaults to 'MINIMUM_SUPPORTED' so explicitly set TLSv1.2 here
        context.minimum_version = TLSVersion.TLSv1_2

    if ssl_maximum_version is not None:
        context.maximum_version = ssl_maximum_version

    # Unless we're given ciphers defer to either system ciphers in
    # the case of OpenSSL 1.1.1+ or use our own secure default ciphers.
    if ciphers is not None or not USE_DEFAULT_SSLCONTEXT_CIPHERS:
        context.set_ciphers(ciphers or DEFAULT_CIPHERS)

    # Setting the default here, as we may have no ssl module on import
    cert_reqs = ssl.CERT_REQUIRED if cert_reqs is None else cert_reqs

    if options is None:
        options = 0
        # SSLv2 is easily broken and is considered harmful and dangerous
        options |= OP_NO_SSLv2
        # SSLv3 has several problems and is now dangerous
        options |= OP_NO_SSLv3
        # Disable compression to prevent CRIME attacks for OpenSSL 1.0+
        # (issue #309)
        options |= OP_NO_COMPRESSION
        # TLSv1.2 only. Unless set explicitly, do not request tickets.
        # This may save some bandwidth on wire, and although the ticket is encrypted,
        # there is a risk associated with it being on wire,
        # if the server is not rotating its ticketing keys properly.
        options |= OP_NO_TICKET

    context.options |= options

    # Enable post-handshake authentication for TLS 1.3, see GH #1634. PHA is
    # necessary for conditional client cert authentication with TLS 1.3.
    # The attribute is None for OpenSSL <= 1.1.0 or does not exist in older
    # versions of Python.  We only enable on Python 3.7.4+ or if certificate
    # verification is enabled to work around Python issue #37428
    # See: https://bugs.python.org/issue37428
    if (cert_reqs == ssl.CERT_REQUIRED or sys.version_info >=
        (3, 7, 4)) and getattr(context, "post_handshake_auth",
                               None) is not None:
        context.post_handshake_auth = True

    # The order of the below lines setting verify_mode and check_hostname
    # matter due to safe-guards SSLContext has to prevent an SSLContext with
    # check_hostname=True, verify_mode=NONE/OPTIONAL.
    # We always set 'check_hostname=False' for pyOpenSSL so we rely on our own
    # 'ssl.match_hostname()' implementation.
    if cert_reqs == ssl.CERT_REQUIRED and not IS_PYOPENSSL:
        context.verify_mode = cert_reqs
        context.check_hostname = True
    else:
        context.check_hostname = False
        context.verify_mode = cert_reqs

    try:
        context.hostname_checks_common_name = False
    except AttributeError:
        pass

    # Enable logging of TLS session keys via defacto standard environment variable
    # 'SSLKEYLOGFILE', if the feature is available (Python 3.8+). Skip empty values.
    if hasattr(context, "keylog_filename"):
        sslkeylogfile = os.environ.get("SSLKEYLOGFILE")
        if sslkeylogfile:
            context.keylog_filename = sslkeylogfile

    return context
示例#23
0
class SSOForward(object):
    def __init__(self, request, application, authentication):
        self.ssl_context = None
        if application.private_uri_is_ssl():
            self.ssl_context = SSLContext(int(application.ssl_protocol))
            if application.ssl_verify_certificate is True:
                self.ssl_context.verify_mode = CERT_REQUIRED
            else:
                self.ssl_context.verify_mode = CERT_NONE
            if application.ssl_cipher:
                self.ssl_context.set_ciphers(application.ssl_cipher)

        self.sso_client   = SSOClient(application.sso_vulture_agent, request,
                                      [h for h in application.headers_in if h.action in ('set','add')],
                                      application.ssl_client_certificate or None,
                                      self.ssl_context)
        self.application  = application
        self.credentials  = authentication.credentials
        self.backend_id   = authentication.backend_id
        self.oauth2_token = authentication.redis_portal_session.get_oauth2_token(authentication.authenticated_on_backend())
        logger.debug("SSOFORWARD::_init_: Object successfully created")


    def retrieve_sso_profile(self, username, field):
        aes             = AESCipher(str(SECRET_KEY)+str(self.application.id)+str(self.backend_id)+str(username)+str(field))
        encrypted_field = aes.key.hex()
        sso             = SSOProfile.objects.filter(encrypted_name=encrypted_field, login=username).first()
        return sso


    def retrieve_sso_field(self, username, field):
        sso  = self.retrieve_sso_profile(username, field)
        if sso is None:
            raise Exception("SSO profile not found for user {}".format(username))
        data = sso.get_data(sso.encrypted_value, str(self.application.id), str(self.backend_id), str(username), str(field))
        return data


    def stock_sso_field(self, username, field, value):
        try:
            sso_profile = self.retrieve_sso_profile(username, field)
            if not sso_profile:
                raise Exception("Cannot retrieve sso profile")
        except Exception as e:
            logger.debug("Cannot retrieve sso profile '{}' for user '{}' : {}".format(field, username, e))
            try:
                sso_profile = SSOProfile()
                sso_profile.set_data(str(self.application.id), self.application.name, str(self.backend_id), BaseAbstractRepository.search_repository(self.backend_id).repo_name, str(username), str(field), str(value))
                sso_profile.store()
            except Exception as e:
                logger.error("SSOForward::stock_sso_field: Unable to store SSO Profile (field={},username={}) : {}".format(field, username, str(e)))
                logger.exception(e)


    def retrieve_credential(self, request, field_username, field_password, fw_type):
        if self.application.sso_forward_basic_mode == 'learning':
            learning_field_html = {field_username:'******', field_password:'******'}
            fields_to_learn, fields_to_stock, datas = dict(),dict(),dict()
            for field_name,field_html in learning_field_html.items():
                try:
                    field_value = request.POST[field_name]
                    datas[field_name], fields_to_stock[field_name] = field_value,field_value
                except Exception as e:
                    logger.debug("SSOForward{}::retrieve_credentials: Unable to retrieve field '{}' from POST datas : {}".format(fw_type, field_name, str(e)))
                    try:
                        datas[field_name] = self.retrieve_sso_field(self.credentials[0], field_name)
                    except Exception as e:
                        logger.debug("SSOForward{}::retrieve_credentials: Unable to retrieve field '{}' from POST datas : {}".format(fw_type, field_name, str(e)))
                if not datas.get(field_name, None):
                    fields_to_learn[field_name] = field_html

            if fields_to_learn:
                raise CredentialsMissingError("SSOForward{}::retrieve_credentials: Learning field(s) missing : {}".format(fw_type, fields_to_learn), fields_to_learn)

            return datas, fields_to_stock, self.application.get_redirect_uri()
        else:
            return {field_username:self.credentials[0], field_password:self.credentials[1]}, dict(), ""


    def generate_response(self, request, response, asked_url):
        final_response = HttpResponse()

        """ We want to immediately return the result of the SSO Forward POST Request """
        if self.application.sso_forward_return_post:
            matched = None
            if self.application.sso_capture_content_enabled and self.application.sso_capture_content:
                ##TODO: MAKE THE CAPTURE/REPLACE/ADDITIONNAL REQUEST 
                #  ON ALL THE RESPONSE (HEADERS INCLUDED !)
                # response_raw = ""
                # for key,item in response.headers:
                #     response_raw += str(key)+": "+str(item)+"\r\n"
                # response_raw += response.text
                matched = re_search(self.application.sso_capture_content.encode('utf8'), response.content)  # response_raw
            additionnal_response = self.sso_client.advanced_sso_perform(matched, self.application, response)

            """ If it is a Response object - additionnal request was made """
            if isinstance(additionnal_response, Response):
                response = additionnal_response
                final_response_body = response.content
            else:
                """ If not - response body was modified """
                final_response_body = additionnal_response

            final_response = self.sso_client.fill_response(response, final_response,
                                                           self.application.get_redirect_uri())
            if "gzip" in final_response.get('Content-Encoding', ""):
                final_response = create_gzip_response(request, final_response_body)
                final_response = self.sso_client.fill_response(response, final_response, self.application.get_redirect_uri())
            else:
                final_response.content = final_response_body

            final_response.status_code = response.status_code
            final_response['Content-Length'] = len(final_response.content)
            del final_response['transfer-encoding']
            logger.debug("SSOForward::generate_response: sso_forward_return_post activated - final response generated")

        elif response.status_code not in (301,302,303) or not self.application.sso_forward_follow_redirect:
            """ Fill cookies and headers """
            final_response = self.sso_client.fill_response(response, final_response,
                                                           self.application.get_redirect_uri())
            """ simply redirect to the default Application entry point """
            final_response.status_code = 302
            # redirect user to url redirected
            final_response['Location'] = asked_url
            del final_response['Content-Length']
            del final_response['Content-Encoding']
            logger.debug("SSOForward::generate_response: Generated response redirects to '{}'".format(asked_url))

        return final_response
示例#24
0
from socket import socket
from ssl import SSLContext
from ssl import PROTOCOL_SSLv23
from ssl import DER_cert_to_PEM_cert

WEAK_CTX = SSLContext(PROTOCOL_SSLv23)
WEAK_CTX.set_ciphers('ALL:!aNULL:!eNULL')

NORMAL_CTX = SSLContext(PROTOCOL_SSLv23)
NORMAL_CTX.set_ciphers(
    'ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+HIGH:'
    'DH+HIGH:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+HIGH:RSA+3DES:!aNULL:'
    '!eNULL:!MD5'
)
NORMAL_CTX.set_ciphers(
    'DEFAULT:!aNULL:!eNULL:!LOW:!EXPORT:!SSLv3'
)


def getCertificate(addr):
    sock = socket()
    sock.connect(addr)
    isWeakCipher = False
    try:
        sslobj = NORMAL_CTX._wrap_socket(sock._sock, server_side=False)
        sslobj.do_handshake()
    except Exception as ex:
        if hasattr(ex, 'reason') and ex.reason == 'SSLV3_ALERT_HANDSHAKE_FAILURE':
            sock.close()
            sock = socket()
            sock.connect(addr)
示例#25
0
def create_urllib3_context(
    ssl_version=None, cert_reqs=None, options=None, ciphers=None
):
    """All arguments have the same meaning as ``ssl_wrap_socket``.

    By default, this function does a lot of the same work that
    ``ssl.create_default_context`` does on Python 3.4+. It:

    - Disables SSLv2, SSLv3, and compression
    - Sets a restricted set of server ciphers

    If you wish to enable SSLv3, you can do::

        from urllib3.util import ssl_
        context = ssl_.create_urllib3_context()
        context.options &= ~ssl_.OP_NO_SSLv3

    You can do the same to enable compression (substituting ``COMPRESSION``
    for ``SSLv3`` in the last line above).

    :param ssl_version:
        The desired protocol version to use. This will default to
        PROTOCOL_SSLv23 which will negotiate the highest protocol that both
        the server and your installation of OpenSSL support.
    :param cert_reqs:
        Whether to require the certificate verification. This defaults to
        ``ssl.CERT_REQUIRED``.
    :param options:
        Specific OpenSSL options. These default to ``ssl.OP_NO_SSLv2``,
        ``ssl.OP_NO_SSLv3``, ``ssl.OP_NO_COMPRESSION``, and ``ssl.OP_NO_TICKET``.
    :param ciphers:
        Which cipher suites to allow the server to select.
    :returns:
        Constructed SSLContext object with specified options
    :rtype: SSLContext
    """
    # PROTOCOL_TLS is deprecated in Python 3.10
    if not ssl_version or ssl_version == PROTOCOL_TLS:
        ssl_version = PROTOCOL_TLS_CLIENT

    context = SSLContext(ssl_version)

    context.set_ciphers(ciphers or DEFAULT_CIPHERS)

    # Setting the default here, as we may have no ssl module on import
    cert_reqs = ssl.CERT_REQUIRED if cert_reqs is None else cert_reqs

    if options is None:
        options = 0
        # SSLv2 is easily broken and is considered harmful and dangerous
        options |= OP_NO_SSLv2
        # SSLv3 has several problems and is now dangerous
        options |= OP_NO_SSLv3
        # Disable compression to prevent CRIME attacks for OpenSSL 1.0+
        # (issue #309)
        options |= OP_NO_COMPRESSION
        # TLSv1.2 only. Unless set explicitly, do not request tickets.
        # This may save some bandwidth on wire, and although the ticket is encrypted,
        # there is a risk associated with it being on wire,
        # if the server is not rotating its ticketing keys properly.
        options |= OP_NO_TICKET

    context.options |= options

    # Enable post-handshake authentication for TLS 1.3, see GH #1634. PHA is
    # necessary for conditional client cert authentication with TLS 1.3.
    # The attribute is None for OpenSSL <= 1.1.0 or does not exist in older
    # versions of Python.  We only enable on Python 3.7.4+ or if certificate
    # verification is enabled to work around Python issue #37428
    # See: https://bugs.python.org/issue37428
    if (cert_reqs == ssl.CERT_REQUIRED or sys.version_info >= (3, 7, 4)) and getattr(
        context, "post_handshake_auth", None
    ) is not None:
        context.post_handshake_auth = True

    def disable_check_hostname():
        if (
            getattr(context, "check_hostname", None) is not None
        ):  # Platform-specific: Python 3.2
            # We do our own verification, including fingerprints and alternative
            # hostnames. So disable it here
            context.check_hostname = False

    # The order of the below lines setting verify_mode and check_hostname
    # matter due to safe-guards SSLContext has to prevent an SSLContext with
    # check_hostname=True, verify_mode=NONE/OPTIONAL. This is made even more
    # complex because we don't know whether PROTOCOL_TLS_CLIENT will be used
    # or not so we don't know the initial state of the freshly created SSLContext.
    if cert_reqs == ssl.CERT_REQUIRED:
        context.verify_mode = cert_reqs
        disable_check_hostname()
    else:
        disable_check_hostname()
        context.verify_mode = cert_reqs

    # Enable logging of TLS session keys via defacto standard environment variable
    # 'SSLKEYLOGFILE', if the feature is available (Python 3.8+). Skip empty values.
    if hasattr(context, "keylog_filename"):
        sslkeylogfile = os.environ.get("SSLKEYLOGFILE")
        if sslkeylogfile:
            context.keylog_filename = sslkeylogfile

    return context
示例#26
0
def create_urllib3_context(
    ssl_version=None, cert_reqs=None, options=None, ciphers=None
):
    """All arguments have the same meaning as ``ssl_wrap_socket``.

    By default, this function does a lot of the same work that
    ``ssl.create_default_context`` does on Python 3.4+. It:

    - Disables SSLv2, SSLv3, and compression
    - Sets a restricted set of server ciphers

    If you wish to enable SSLv3, you can do::

        from urllib3.util import ssl_
        context = ssl_.create_urllib3_context()
        context.options &= ~ssl_.OP_NO_SSLv3

    You can do the same to enable compression (substituting ``COMPRESSION``
    for ``SSLv3`` in the last line above).

    :param ssl_version:
        The desired protocol version to use. This will default to
        PROTOCOL_SSLv23 which will negotiate the highest protocol that both
        the server and your installation of OpenSSL support.
    :param cert_reqs:
        Whether to require the certificate verification. This defaults to
        ``ssl.CERT_REQUIRED``.
    :param options:
        Specific OpenSSL options. These default to ``ssl.OP_NO_SSLv2``,
        ``ssl.OP_NO_SSLv3``, ``ssl.OP_NO_COMPRESSION``.
    :param ciphers:
        Which cipher suites to allow the server to select.
    :returns:
        Constructed SSLContext object with specified options
    :rtype: SSLContext
    """
    context = SSLContext(ssl_version or PROTOCOL_TLS)

    context.set_ciphers(ciphers or DEFAULT_CIPHERS)

    # Setting the default here, as we may have no ssl module on import
    cert_reqs = ssl.CERT_REQUIRED if cert_reqs is None else cert_reqs

    if options is None:
        options = 0
        # SSLv2 is easily broken and is considered harmful and dangerous
        options |= OP_NO_SSLv2
        # SSLv3 has several problems and is now dangerous
        options |= OP_NO_SSLv3
        # Disable compression to prevent CRIME attacks for OpenSSL 1.0+
        # (issue #309)
        options |= OP_NO_COMPRESSION

    context.options |= options

    # Enable post-handshake authentication for TLS 1.3, see GH #1634. PHA is
    # necessary for conditional client cert authentication with TLS 1.3.
    # The attribute is None for OpenSSL <= 1.1.0 or does not exist in older
    # versions of Python.  We only enable on Python 3.7.4+ or if certificate
    # verification is enabled to work around Python issue #37428
    # See: https://bugs.python.org/issue37428
    if (cert_reqs == ssl.CERT_REQUIRED or sys.version_info >= (3, 7, 4)) and getattr(
        context, "post_handshake_auth", None
    ) is not None:
        context.post_handshake_auth = True

    context.verify_mode = cert_reqs
    if (
        getattr(context, "check_hostname", None) is not None
    ):  # Platform-specific: Python 3.2
        # We do our own verification, including fingerprints and alternative
        # hostnames. So disable it here
        context.check_hostname = False

    # Enable logging of TLS session keys via defacto standard environment variable
    # 'SSLKEYLOGFILE', if the feature is available (Python 3.8+).
    if hasattr(context, "keylog_filename"):
        context.keylog_filename = os.environ.get("SSLKEYLOGFILE")

    return context
示例#27
0
def _configure_context_common(context: ssl.SSLContext,
                              config: confuse.ConfigView):
    if config["ciphers"].exists():
        context.set_ciphers(config["ciphers"].as_str())