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
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
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
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
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
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
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
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
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
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
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
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))
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
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
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)
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(
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
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
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
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
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)
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
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
def _configure_context_common(context: ssl.SSLContext, config: confuse.ConfigView): if config["ciphers"].exists(): context.set_ciphers(config["ciphers"].as_str())