1from __future__
import absolute_import
7from binascii
import hexlify, unhexlify
8from hashlib
import md5, sha1, sha256
10from ..exceptions
import (
11 InsecurePlatformWarning,
12 ProxySchemeUnsupported,
16from ..packages
import six
17from .url
import BRACELESS_IPV6_ADDRZ_RE, IPV4_RE
23IS_SECURETRANSPORT =
False
24ALPN_PROTOCOLS = [
"http/1.1"]
27HASHFUNC_MAP = {32: md5, 40: sha1, 64: sha256}
32 Compare two digests of equal length in constant time.
34 The digests must be of type str/bytes.
35 Returns True if the digests match, and False otherwise.
39 result |= left ^ right
43_const_compare_digest =
getattr(hmac,
"compare_digest", _const_compare_digest_backport)
47 from ssl
import CERT_REQUIRED, wrap_socket
52 from ssl
import HAS_SNI
57 from .ssltransport
import SSLTransport
63 from ssl
import PROTOCOL_TLS
65 PROTOCOL_SSLv23 = PROTOCOL_TLS
68 from ssl
import PROTOCOL_SSLv23
as PROTOCOL_TLS
70 PROTOCOL_SSLv23 = PROTOCOL_TLS
72 PROTOCOL_SSLv23 = PROTOCOL_TLS = 2
75 from ssl
import PROTOCOL_TLS_CLIENT
77 PROTOCOL_TLS_CLIENT = PROTOCOL_TLS
81 from ssl
import OP_NO_COMPRESSION, OP_NO_SSLv2, OP_NO_SSLv3
83 OP_NO_SSLv2, OP_NO_SSLv3 = 0x1000000, 0x2000000
84 OP_NO_COMPRESSION = 0x20000
88 from ssl
import OP_NO_TICKET
110DEFAULT_CIPHERS =
":".join(
130 from ssl
import SSLContext
152 if capath
is not None:
153 raise SSLError(
"CA directories not supported in older Pythons")
155 if cadata
is not None:
156 raise SSLError(
"CA data not supported in older Pythons")
161 def wrap_socket(self, socket, server_hostname=None, server_side=False):
163 "A true SSLContext object is not available. This prevents "
164 "urllib3 from configuring SSL appropriately and may cause "
165 "certain SSL connections to fail. You can upgrade to a newer "
166 "version of Python to solve this. For more information, see "
167 "https://urllib3.readthedocs.io/en/1.26.x/advanced-usage.html"
169 InsecurePlatformWarning,
177 "server_side": server_side,
179 return wrap_socket(socket, ciphers=self.
ciphers, **kwargs)
182def assert_fingerprint(cert, fingerprint):
184 Checks if given fingerprint matches the supplied certificate.
187 Certificate as bytes object.
189 Fingerprint as string of hexdigits, can be interspersed by colons.
193 digest_length =
len(fingerprint)
196 raise SSLError(
"Fingerprint of invalid length: {0}".format(fingerprint))
201 cert_digest =
hashfunc(cert).digest()
205 'Fingerprints did not match. Expected "{0}", got "{1}".'.format(
206 fingerprint, hexlify(cert_digest)
211def resolve_cert_reqs(candidate):
213 Resolves the argument to a numeric constant, which can be passed to
214 the wrap_socket function/method from the ssl module.
215 Defaults to :data:`ssl.CERT_REQUIRED`.
216 If given a string it is assumed to be the name of the constant in the
217 :mod:`ssl` module or its abbreviation.
218 (So you can specify `REQUIRED` instead of `CERT_REQUIRED`.
219 If it's neither `None` nor a string we assume it is already the numeric
220 constant which can directly be passed to wrap_socket.
222 if candidate
is None:
226 res =
getattr(ssl, candidate,
None)
228 res =
getattr(ssl,
"CERT_" + candidate)
234def resolve_ssl_version(candidate):
236 like resolve_cert_reqs
238 if candidate
is None:
242 res =
getattr(ssl, candidate,
None)
244 res =
getattr(ssl,
"PROTOCOL_" + candidate)
250def create_urllib3_context(
251 ssl_version=None, cert_reqs=None, options=None, ciphers=None
253 """All arguments have the same meaning as ``ssl_wrap_socket``.
255 By default, this function does a lot of the same work that
256 ``ssl.create_default_context`` does on Python 3.4+. It:
258 - Disables SSLv2, SSLv3, and compression
259 - Sets a restricted set of server ciphers
261 If you wish to enable SSLv3, you can do::
263 from pip._vendor.urllib3.util import ssl_
264 context = ssl_.create_urllib3_context()
265 context.options &= ~ssl_.OP_NO_SSLv3
267 You can do the same to enable compression (substituting ``COMPRESSION``
268 for ``SSLv3`` in the last line above).
271 The desired protocol version to use. This will default to
272 PROTOCOL_SSLv23 which will negotiate the highest protocol that both
273 the server and your installation of OpenSSL support.
275 Whether to require the certificate verification. This defaults to
276 ``ssl.CERT_REQUIRED``.
278 Specific OpenSSL options. These default to ``ssl.OP_NO_SSLv2``,
279 ``ssl.OP_NO_SSLv3``, ``ssl.OP_NO_COMPRESSION``, and ``ssl.OP_NO_TICKET``.
281 Which cipher suites to allow the server to select.
283 Constructed SSLContext object with specified options
287 if not ssl_version
or ssl_version == PROTOCOL_TLS:
288 ssl_version = PROTOCOL_TLS_CLIENT
300 options |= OP_NO_SSLv2
302 options |= OP_NO_SSLv3
305 options |= OP_NO_COMPRESSION
310 options |= OP_NO_TICKET
321 context,
"post_handshake_auth",
None
327 getattr(context,
"check_hostname",
None)
is not None
347 if hasattr(context,
"keylog_filename"):
361 server_hostname=None,
371 All arguments except for server_hostname, ssl_context, and ca_cert_dir have
372 the same meaning as they do when using :func:`ssl.wrap_socket`.
374 :param server_hostname:
375 When SNI is supported, the expected hostname of the certificate
377 A pre-made :class:`SSLContext` object. If none is provided, one will
378 be created using :func:`create_urllib3_context`.
380 A string of ciphers we wish the client to support.
382 A directory containing CA certificates in multiple separate files, as
383 supported by OpenSSL's -CApath flag or the capath argument to
384 SSLContext.load_verify_locations().
386 Optional password if the keyfile is encrypted.
388 Optional string containing CA certificates in PEM format suitable for
389 passing as the cadata parameter to SSLContext.load_verify_locations()
391 Use SSLTransport to wrap the existing socket.
393 context = ssl_context
398 context = create_urllib3_context(ssl_version, cert_reqs, ciphers=ciphers)
400 if ca_certs
or ca_cert_dir
or ca_cert_data:
403 except (IOError, OSError)
as e:
406 elif ssl_context
is None and hasattr(context,
"load_default_certs"):
414 raise SSLError(
"Client private key is encrypted, password is required")
417 if key_password
is None:
423 if hasattr(context,
"set_alpn_protocols"):
425 except NotImplementedError:
430 use_sni_hostname = server_hostname
and not is_ipaddress(server_hostname)
432 send_sni = (use_sni_hostname
and HAS_SNI)
or (
433 IS_SECURETRANSPORT
and server_hostname
436 if not HAS_SNI
and use_sni_hostname:
438 "An HTTPS request has been made, but the SNI (Server Name "
439 "Indication) extension to TLS is not available on this platform. "
440 "This may cause the server to present an incorrect TLS "
441 "certificate, which can cause validation failures. You can upgrade to "
442 "a newer version of Python to solve this. For more information, see "
443 "https://urllib3.readthedocs.io/en/1.26.x/advanced-usage.html"
450 sock, context, tls_in_tls, server_hostname=server_hostname
457def is_ipaddress(hostname):
458 """Detects whether the hostname given is an IPv4 or IPv6 address.
459 Also detects IPv6 addresses with Zone IDs.
461 :param str hostname: Hostname to examine.
462 :return: True if the hostname is an IP address, False otherwise.
471 """Detects if a key file is encrypted or not."""
472 with open(key_file,
"r")
as f:
475 if "ENCRYPTED" in line:
486 "TLS in TLS requires support for the 'ssl' module"
load_cert_chain(self, certfile, keyfile)
load_verify_locations(self, cafile=None, capath=None, cadata=None)
set_ciphers(self, cipher_suite)
__init__(self, protocol_version)
_const_compare_digest_backport(a, b)
_is_key_file_encrypted(key_file)
_ssl_wrap_socket_impl(sock, ssl_context, tls_in_tls, server_hostname=None)