ยปCore Development>Code coverage>Lib/ssl.py

Python code coverage for Lib/ssl.py

#countcontent
1n/a# Wrapper module for _ssl, providing some additional facilities
2n/a# implemented in Python. Written by Bill Janssen.
3n/a
4n/a"""This module provides some more Pythonic support for SSL.
5n/a
6n/aObject types:
7n/a
8n/a SSLSocket -- subtype of socket.socket which does SSL over the socket
9n/a
10n/aExceptions:
11n/a
12n/a SSLError -- exception raised for I/O errors
13n/a
14n/aFunctions:
15n/a
16n/a cert_time_to_seconds -- convert time string used for certificate
17n/a notBefore and notAfter functions to integer
18n/a seconds past the Epoch (the time values
19n/a returned from time.time())
20n/a
21n/a fetch_server_certificate (HOST, PORT) -- fetch the certificate provided
22n/a by the server running on HOST at port PORT. No
23n/a validation of the certificate is performed.
24n/a
25n/aInteger constants:
26n/a
27n/aSSL_ERROR_ZERO_RETURN
28n/aSSL_ERROR_WANT_READ
29n/aSSL_ERROR_WANT_WRITE
30n/aSSL_ERROR_WANT_X509_LOOKUP
31n/aSSL_ERROR_SYSCALL
32n/aSSL_ERROR_SSL
33n/aSSL_ERROR_WANT_CONNECT
34n/a
35n/aSSL_ERROR_EOF
36n/aSSL_ERROR_INVALID_ERROR_CODE
37n/a
38n/aThe following group define certificate requirements that one side is
39n/aallowing/requiring from the other side:
40n/a
41n/aCERT_NONE - no certificates from the other side are required (or will
42n/a be looked at if provided)
43n/aCERT_OPTIONAL - certificates are not required, but if provided will be
44n/a validated, and if validation fails, the connection will
45n/a also fail
46n/aCERT_REQUIRED - certificates are required, and will be validated, and
47n/a if validation fails, the connection will also fail
48n/a
49n/aThe following constants identify various SSL protocol variants:
50n/a
51n/aPROTOCOL_SSLv2
52n/aPROTOCOL_SSLv3
53n/aPROTOCOL_SSLv23
54n/aPROTOCOL_TLSv1
55n/aPROTOCOL_TLSv1_1
56n/aPROTOCOL_TLSv1_2
57n/a
58n/aThe following constants identify various SSL alert message descriptions as per
59n/ahttp://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-6
60n/a
61n/aALERT_DESCRIPTION_CLOSE_NOTIFY
62n/aALERT_DESCRIPTION_UNEXPECTED_MESSAGE
63n/aALERT_DESCRIPTION_BAD_RECORD_MAC
64n/aALERT_DESCRIPTION_RECORD_OVERFLOW
65n/aALERT_DESCRIPTION_DECOMPRESSION_FAILURE
66n/aALERT_DESCRIPTION_HANDSHAKE_FAILURE
67n/aALERT_DESCRIPTION_BAD_CERTIFICATE
68n/aALERT_DESCRIPTION_UNSUPPORTED_CERTIFICATE
69n/aALERT_DESCRIPTION_CERTIFICATE_REVOKED
70n/aALERT_DESCRIPTION_CERTIFICATE_EXPIRED
71n/aALERT_DESCRIPTION_CERTIFICATE_UNKNOWN
72n/aALERT_DESCRIPTION_ILLEGAL_PARAMETER
73n/aALERT_DESCRIPTION_UNKNOWN_CA
74n/aALERT_DESCRIPTION_ACCESS_DENIED
75n/aALERT_DESCRIPTION_DECODE_ERROR
76n/aALERT_DESCRIPTION_DECRYPT_ERROR
77n/aALERT_DESCRIPTION_PROTOCOL_VERSION
78n/aALERT_DESCRIPTION_INSUFFICIENT_SECURITY
79n/aALERT_DESCRIPTION_INTERNAL_ERROR
80n/aALERT_DESCRIPTION_USER_CANCELLED
81n/aALERT_DESCRIPTION_NO_RENEGOTIATION
82n/aALERT_DESCRIPTION_UNSUPPORTED_EXTENSION
83n/aALERT_DESCRIPTION_CERTIFICATE_UNOBTAINABLE
84n/aALERT_DESCRIPTION_UNRECOGNIZED_NAME
85n/aALERT_DESCRIPTION_BAD_CERTIFICATE_STATUS_RESPONSE
86n/aALERT_DESCRIPTION_BAD_CERTIFICATE_HASH_VALUE
87n/aALERT_DESCRIPTION_UNKNOWN_PSK_IDENTITY
88n/a"""
89n/a
90n/aimport ipaddress
91n/aimport textwrap
92n/aimport re
93n/aimport sys
94n/aimport os
95n/afrom collections import namedtuple
96n/afrom enum import Enum as _Enum, IntEnum as _IntEnum
97n/a
98n/aimport _ssl # if we can't import it, let the error propagate
99n/a
100n/afrom _ssl import OPENSSL_VERSION_NUMBER, OPENSSL_VERSION_INFO, OPENSSL_VERSION
101n/afrom _ssl import _SSLContext, MemoryBIO
102n/afrom _ssl import (
103n/a SSLError, SSLZeroReturnError, SSLWantReadError, SSLWantWriteError,
104n/a SSLSyscallError, SSLEOFError,
105n/a )
106n/afrom _ssl import CERT_NONE, CERT_OPTIONAL, CERT_REQUIRED
107n/afrom _ssl import txt2obj as _txt2obj, nid2obj as _nid2obj
108n/afrom _ssl import RAND_status, RAND_add, RAND_bytes, RAND_pseudo_bytes
109n/atry:
110n/a from _ssl import RAND_egd
111n/aexcept ImportError:
112n/a # LibreSSL does not provide RAND_egd
113n/a pass
114n/a
115n/adef _import_symbols(prefix):
116n/a for n in dir(_ssl):
117n/a if n.startswith(prefix):
118n/a globals()[n] = getattr(_ssl, n)
119n/a
120n/a_import_symbols('OP_')
121n/a_import_symbols('ALERT_DESCRIPTION_')
122n/a_import_symbols('SSL_ERROR_')
123n/a_import_symbols('VERIFY_')
124n/a
125n/afrom _ssl import HAS_SNI, HAS_ECDH, HAS_NPN, HAS_ALPN
126n/a
127n/afrom _ssl import _OPENSSL_API_VERSION
128n/a
129n/a_IntEnum._convert(
130n/a '_SSLMethod', __name__,
131n/a lambda name: name.startswith('PROTOCOL_'),
132n/a source=_ssl)
133n/a
134n/a_PROTOCOL_NAMES = {value: name for name, value in _SSLMethod.__members__.items()}
135n/a
136n/atry:
137n/a _SSLv2_IF_EXISTS = PROTOCOL_SSLv2
138n/aexcept NameError:
139n/a _SSLv2_IF_EXISTS = None
140n/a
141n/aif sys.platform == "win32":
142n/a from _ssl import enum_certificates, enum_crls
143n/a
144n/afrom socket import socket, AF_INET, SOCK_STREAM, create_connection
145n/afrom socket import SOL_SOCKET, SO_TYPE
146n/aimport base64 # for DER-to-PEM translation
147n/aimport errno
148n/aimport warnings
149n/a
150n/a
151n/asocket_error = OSError # keep that public name in module namespace
152n/a
153n/aif _ssl.HAS_TLS_UNIQUE:
154n/a CHANNEL_BINDING_TYPES = ['tls-unique']
155n/aelse:
156n/a CHANNEL_BINDING_TYPES = []
157n/a
158n/a# Disable weak or insecure ciphers by default
159n/a# (OpenSSL's default setting is 'DEFAULT:!aNULL:!eNULL')
160n/a# Enable a better set of ciphers by default
161n/a# This list has been explicitly chosen to:
162n/a# * Prefer cipher suites that offer perfect forward secrecy (DHE/ECDHE)
163n/a# * Prefer ECDHE over DHE for better performance
164n/a# * Prefer any AES-GCM over any AES-CBC for better performance and security
165n/a# * Then Use HIGH cipher suites as a fallback
166n/a# * Then Use 3DES as fallback which is secure but slow
167n/a# * Disable NULL authentication, NULL encryption, and MD5 MACs for security
168n/a# reasons
169n/a_DEFAULT_CIPHERS = (
170n/a 'ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+HIGH:'
171n/a 'DH+HIGH:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+HIGH:RSA+3DES:!aNULL:'
172n/a '!eNULL:!MD5'
173n/a)
174n/a
175n/a# Restricted and more secure ciphers for the server side
176n/a# This list has been explicitly chosen to:
177n/a# * Prefer cipher suites that offer perfect forward secrecy (DHE/ECDHE)
178n/a# * Prefer ECDHE over DHE for better performance
179n/a# * Prefer any AES-GCM over any AES-CBC for better performance and security
180n/a# * Then Use HIGH cipher suites as a fallback
181n/a# * Then Use 3DES as fallback which is secure but slow
182n/a# * Disable NULL authentication, NULL encryption, MD5 MACs, DSS, and RC4 for
183n/a# security reasons
184n/a_RESTRICTED_SERVER_CIPHERS = (
185n/a 'ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+HIGH:'
186n/a 'DH+HIGH:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+HIGH:RSA+3DES:!aNULL:'
187n/a '!eNULL:!MD5:!DSS:!RC4'
188n/a)
189n/a
190n/a
191n/aclass CertificateError(ValueError):
192n/a pass
193n/a
194n/a
195n/adef _dnsname_match(dn, hostname, max_wildcards=1):
196n/a """Matching according to RFC 6125, section 6.4.3
197n/a
198n/a http://tools.ietf.org/html/rfc6125#section-6.4.3
199n/a """
200n/a pats = []
201n/a if not dn:
202n/a return False
203n/a
204n/a leftmost, *remainder = dn.split(r'.')
205n/a
206n/a wildcards = leftmost.count('*')
207n/a if wildcards > max_wildcards:
208n/a # Issue #17980: avoid denials of service by refusing more
209n/a # than one wildcard per fragment. A survey of established
210n/a # policy among SSL implementations showed it to be a
211n/a # reasonable choice.
212n/a raise CertificateError(
213n/a "too many wildcards in certificate DNS name: " + repr(dn))
214n/a
215n/a # speed up common case w/o wildcards
216n/a if not wildcards:
217n/a return dn.lower() == hostname.lower()
218n/a
219n/a # RFC 6125, section 6.4.3, subitem 1.
220n/a # The client SHOULD NOT attempt to match a presented identifier in which
221n/a # the wildcard character comprises a label other than the left-most label.
222n/a if leftmost == '*':
223n/a # When '*' is a fragment by itself, it matches a non-empty dotless
224n/a # fragment.
225n/a pats.append('[^.]+')
226n/a elif leftmost.startswith('xn--') or hostname.startswith('xn--'):
227n/a # RFC 6125, section 6.4.3, subitem 3.
228n/a # The client SHOULD NOT attempt to match a presented identifier
229n/a # where the wildcard character is embedded within an A-label or
230n/a # U-label of an internationalized domain name.
231n/a pats.append(re.escape(leftmost))
232n/a else:
233n/a # Otherwise, '*' matches any dotless string, e.g. www*
234n/a pats.append(re.escape(leftmost).replace(r'\*', '[^.]*'))
235n/a
236n/a # add the remaining fragments, ignore any wildcards
237n/a for frag in remainder:
238n/a pats.append(re.escape(frag))
239n/a
240n/a pat = re.compile(r'\A' + r'\.'.join(pats) + r'\Z', re.IGNORECASE)
241n/a return pat.match(hostname)
242n/a
243n/a
244n/adef _ipaddress_match(ipname, host_ip):
245n/a """Exact matching of IP addresses.
246n/a
247n/a RFC 6125 explicitly doesn't define an algorithm for this
248n/a (section 1.7.2 - "Out of Scope").
249n/a """
250n/a # OpenSSL may add a trailing newline to a subjectAltName's IP address
251n/a ip = ipaddress.ip_address(ipname.rstrip())
252n/a return ip == host_ip
253n/a
254n/a
255n/adef match_hostname(cert, hostname):
256n/a """Verify that *cert* (in decoded format as returned by
257n/a SSLSocket.getpeercert()) matches the *hostname*. RFC 2818 and RFC 6125
258n/a rules are followed, but IP addresses are not accepted for *hostname*.
259n/a
260n/a CertificateError is raised on failure. On success, the function
261n/a returns nothing.
262n/a """
263n/a if not cert:
264n/a raise ValueError("empty or no certificate, match_hostname needs a "
265n/a "SSL socket or SSL context with either "
266n/a "CERT_OPTIONAL or CERT_REQUIRED")
267n/a try:
268n/a host_ip = ipaddress.ip_address(hostname)
269n/a except ValueError:
270n/a # Not an IP address (common case)
271n/a host_ip = None
272n/a dnsnames = []
273n/a san = cert.get('subjectAltName', ())
274n/a for key, value in san:
275n/a if key == 'DNS':
276n/a if host_ip is None and _dnsname_match(value, hostname):
277n/a return
278n/a dnsnames.append(value)
279n/a elif key == 'IP Address':
280n/a if host_ip is not None and _ipaddress_match(value, host_ip):
281n/a return
282n/a dnsnames.append(value)
283n/a if not dnsnames:
284n/a # The subject is only checked when there is no dNSName entry
285n/a # in subjectAltName
286n/a for sub in cert.get('subject', ()):
287n/a for key, value in sub:
288n/a # XXX according to RFC 2818, the most specific Common Name
289n/a # must be used.
290n/a if key == 'commonName':
291n/a if _dnsname_match(value, hostname):
292n/a return
293n/a dnsnames.append(value)
294n/a if len(dnsnames) > 1:
295n/a raise CertificateError("hostname %r "
296n/a "doesn't match either of %s"
297n/a % (hostname, ', '.join(map(repr, dnsnames))))
298n/a elif len(dnsnames) == 1:
299n/a raise CertificateError("hostname %r "
300n/a "doesn't match %r"
301n/a % (hostname, dnsnames[0]))
302n/a else:
303n/a raise CertificateError("no appropriate commonName or "
304n/a "subjectAltName fields were found")
305n/a
306n/a
307n/aDefaultVerifyPaths = namedtuple("DefaultVerifyPaths",
308n/a "cafile capath openssl_cafile_env openssl_cafile openssl_capath_env "
309n/a "openssl_capath")
310n/a
311n/adef get_default_verify_paths():
312n/a """Return paths to default cafile and capath.
313n/a """
314n/a parts = _ssl.get_default_verify_paths()
315n/a
316n/a # environment vars shadow paths
317n/a cafile = os.environ.get(parts[0], parts[1])
318n/a capath = os.environ.get(parts[2], parts[3])
319n/a
320n/a return DefaultVerifyPaths(cafile if os.path.isfile(cafile) else None,
321n/a capath if os.path.isdir(capath) else None,
322n/a *parts)
323n/a
324n/a
325n/aclass _ASN1Object(namedtuple("_ASN1Object", "nid shortname longname oid")):
326n/a """ASN.1 object identifier lookup
327n/a """
328n/a __slots__ = ()
329n/a
330n/a def __new__(cls, oid):
331n/a return super().__new__(cls, *_txt2obj(oid, name=False))
332n/a
333n/a @classmethod
334n/a def fromnid(cls, nid):
335n/a """Create _ASN1Object from OpenSSL numeric ID
336n/a """
337n/a return super().__new__(cls, *_nid2obj(nid))
338n/a
339n/a @classmethod
340n/a def fromname(cls, name):
341n/a """Create _ASN1Object from short name, long name or OID
342n/a """
343n/a return super().__new__(cls, *_txt2obj(name, name=True))
344n/a
345n/a
346n/aclass Purpose(_ASN1Object, _Enum):
347n/a """SSLContext purpose flags with X509v3 Extended Key Usage objects
348n/a """
349n/a SERVER_AUTH = '1.3.6.1.5.5.7.3.1'
350n/a CLIENT_AUTH = '1.3.6.1.5.5.7.3.2'
351n/a
352n/a
353n/aclass SSLContext(_SSLContext):
354n/a """An SSLContext holds various SSL-related configuration options and
355n/a data, such as certificates and possibly a private key."""
356n/a
357n/a __slots__ = ('protocol', '__weakref__')
358n/a _windows_cert_stores = ("CA", "ROOT")
359n/a
360n/a def __new__(cls, protocol, *args, **kwargs):
361n/a self = _SSLContext.__new__(cls, protocol)
362n/a if protocol != _SSLv2_IF_EXISTS:
363n/a self.set_ciphers(_DEFAULT_CIPHERS)
364n/a return self
365n/a
366n/a def __init__(self, protocol):
367n/a self.protocol = protocol
368n/a
369n/a def wrap_socket(self, sock, server_side=False,
370n/a do_handshake_on_connect=True,
371n/a suppress_ragged_eofs=True,
372n/a server_hostname=None):
373n/a return SSLSocket(sock=sock, server_side=server_side,
374n/a do_handshake_on_connect=do_handshake_on_connect,
375n/a suppress_ragged_eofs=suppress_ragged_eofs,
376n/a server_hostname=server_hostname,
377n/a _context=self)
378n/a
379n/a def wrap_bio(self, incoming, outgoing, server_side=False,
380n/a server_hostname=None):
381n/a sslobj = self._wrap_bio(incoming, outgoing, server_side=server_side,
382n/a server_hostname=server_hostname)
383n/a return SSLObject(sslobj)
384n/a
385n/a def set_npn_protocols(self, npn_protocols):
386n/a protos = bytearray()
387n/a for protocol in npn_protocols:
388n/a b = bytes(protocol, 'ascii')
389n/a if len(b) == 0 or len(b) > 255:
390n/a raise SSLError('NPN protocols must be 1 to 255 in length')
391n/a protos.append(len(b))
392n/a protos.extend(b)
393n/a
394n/a self._set_npn_protocols(protos)
395n/a
396n/a def set_alpn_protocols(self, alpn_protocols):
397n/a protos = bytearray()
398n/a for protocol in alpn_protocols:
399n/a b = bytes(protocol, 'ascii')
400n/a if len(b) == 0 or len(b) > 255:
401n/a raise SSLError('ALPN protocols must be 1 to 255 in length')
402n/a protos.append(len(b))
403n/a protos.extend(b)
404n/a
405n/a self._set_alpn_protocols(protos)
406n/a
407n/a def _load_windows_store_certs(self, storename, purpose):
408n/a certs = bytearray()
409n/a try:
410n/a for cert, encoding, trust in enum_certificates(storename):
411n/a # CA certs are never PKCS#7 encoded
412n/a if encoding == "x509_asn":
413n/a if trust is True or purpose.oid in trust:
414n/a certs.extend(cert)
415n/a except PermissionError:
416n/a warnings.warn("unable to enumerate Windows certificate store")
417n/a if certs:
418n/a self.load_verify_locations(cadata=certs)
419n/a return certs
420n/a
421n/a def load_default_certs(self, purpose=Purpose.SERVER_AUTH):
422n/a if not isinstance(purpose, _ASN1Object):
423n/a raise TypeError(purpose)
424n/a if sys.platform == "win32":
425n/a for storename in self._windows_cert_stores:
426n/a self._load_windows_store_certs(storename, purpose)
427n/a self.set_default_verify_paths()
428n/a
429n/a
430n/adef create_default_context(purpose=Purpose.SERVER_AUTH, *, cafile=None,
431n/a capath=None, cadata=None):
432n/a """Create a SSLContext object with default settings.
433n/a
434n/a NOTE: The protocol and settings may change anytime without prior
435n/a deprecation. The values represent a fair balance between maximum
436n/a compatibility and security.
437n/a """
438n/a if not isinstance(purpose, _ASN1Object):
439n/a raise TypeError(purpose)
440n/a
441n/a context = SSLContext(PROTOCOL_SSLv23)
442n/a
443n/a # SSLv2 considered harmful.
444n/a context.options |= OP_NO_SSLv2
445n/a
446n/a # SSLv3 has problematic security and is only required for really old
447n/a # clients such as IE6 on Windows XP
448n/a context.options |= OP_NO_SSLv3
449n/a
450n/a # disable compression to prevent CRIME attacks (OpenSSL 1.0+)
451n/a context.options |= getattr(_ssl, "OP_NO_COMPRESSION", 0)
452n/a
453n/a if purpose == Purpose.SERVER_AUTH:
454n/a # verify certs and host name in client mode
455n/a context.verify_mode = CERT_REQUIRED
456n/a context.check_hostname = True
457n/a elif purpose == Purpose.CLIENT_AUTH:
458n/a # Prefer the server's ciphers by default so that we get stronger
459n/a # encryption
460n/a context.options |= getattr(_ssl, "OP_CIPHER_SERVER_PREFERENCE", 0)
461n/a
462n/a # Use single use keys in order to improve forward secrecy
463n/a context.options |= getattr(_ssl, "OP_SINGLE_DH_USE", 0)
464n/a context.options |= getattr(_ssl, "OP_SINGLE_ECDH_USE", 0)
465n/a
466n/a # disallow ciphers with known vulnerabilities
467n/a context.set_ciphers(_RESTRICTED_SERVER_CIPHERS)
468n/a
469n/a if cafile or capath or cadata:
470n/a context.load_verify_locations(cafile, capath, cadata)
471n/a elif context.verify_mode != CERT_NONE:
472n/a # no explicit cafile, capath or cadata but the verify mode is
473n/a # CERT_OPTIONAL or CERT_REQUIRED. Let's try to load default system
474n/a # root CA certificates for the given purpose. This may fail silently.
475n/a context.load_default_certs(purpose)
476n/a return context
477n/a
478n/adef _create_unverified_context(protocol=PROTOCOL_SSLv23, *, cert_reqs=None,
479n/a check_hostname=False, purpose=Purpose.SERVER_AUTH,
480n/a certfile=None, keyfile=None,
481n/a cafile=None, capath=None, cadata=None):
482n/a """Create a SSLContext object for Python stdlib modules
483n/a
484n/a All Python stdlib modules shall use this function to create SSLContext
485n/a objects in order to keep common settings in one place. The configuration
486n/a is less restrict than create_default_context()'s to increase backward
487n/a compatibility.
488n/a """
489n/a if not isinstance(purpose, _ASN1Object):
490n/a raise TypeError(purpose)
491n/a
492n/a context = SSLContext(protocol)
493n/a # SSLv2 considered harmful.
494n/a context.options |= OP_NO_SSLv2
495n/a # SSLv3 has problematic security and is only required for really old
496n/a # clients such as IE6 on Windows XP
497n/a context.options |= OP_NO_SSLv3
498n/a
499n/a if cert_reqs is not None:
500n/a context.verify_mode = cert_reqs
501n/a context.check_hostname = check_hostname
502n/a
503n/a if keyfile and not certfile:
504n/a raise ValueError("certfile must be specified")
505n/a if certfile or keyfile:
506n/a context.load_cert_chain(certfile, keyfile)
507n/a
508n/a # load CA root certs
509n/a if cafile or capath or cadata:
510n/a context.load_verify_locations(cafile, capath, cadata)
511n/a elif context.verify_mode != CERT_NONE:
512n/a # no explicit cafile, capath or cadata but the verify mode is
513n/a # CERT_OPTIONAL or CERT_REQUIRED. Let's try to load default system
514n/a # root CA certificates for the given purpose. This may fail silently.
515n/a context.load_default_certs(purpose)
516n/a
517n/a return context
518n/a
519n/a# Used by http.client if no context is explicitly passed.
520n/a_create_default_https_context = create_default_context
521n/a
522n/a
523n/a# Backwards compatibility alias, even though it's not a public name.
524n/a_create_stdlib_context = _create_unverified_context
525n/a
526n/a
527n/aclass SSLObject:
528n/a """This class implements an interface on top of a low-level SSL object as
529n/a implemented by OpenSSL. This object captures the state of an SSL connection
530n/a but does not provide any network IO itself. IO needs to be performed
531n/a through separate "BIO" objects which are OpenSSL's IO abstraction layer.
532n/a
533n/a This class does not have a public constructor. Instances are returned by
534n/a ``SSLContext.wrap_bio``. This class is typically used by framework authors
535n/a that want to implement asynchronous IO for SSL through memory buffers.
536n/a
537n/a When compared to ``SSLSocket``, this object lacks the following features:
538n/a
539n/a * Any form of network IO incluging methods such as ``recv`` and ``send``.
540n/a * The ``do_handshake_on_connect`` and ``suppress_ragged_eofs`` machinery.
541n/a """
542n/a
543n/a def __init__(self, sslobj, owner=None):
544n/a self._sslobj = sslobj
545n/a # Note: _sslobj takes a weak reference to owner
546n/a self._sslobj.owner = owner or self
547n/a
548n/a @property
549n/a def context(self):
550n/a """The SSLContext that is currently in use."""
551n/a return self._sslobj.context
552n/a
553n/a @context.setter
554n/a def context(self, ctx):
555n/a self._sslobj.context = ctx
556n/a
557n/a @property
558n/a def server_side(self):
559n/a """Whether this is a server-side socket."""
560n/a return self._sslobj.server_side
561n/a
562n/a @property
563n/a def server_hostname(self):
564n/a """The currently set server hostname (for SNI), or ``None`` if no
565n/a server hostame is set."""
566n/a return self._sslobj.server_hostname
567n/a
568n/a def read(self, len=1024, buffer=None):
569n/a """Read up to 'len' bytes from the SSL object and return them.
570n/a
571n/a If 'buffer' is provided, read into this buffer and return the number of
572n/a bytes read.
573n/a """
574n/a if buffer is not None:
575n/a v = self._sslobj.read(len, buffer)
576n/a else:
577n/a v = self._sslobj.read(len)
578n/a return v
579n/a
580n/a def write(self, data):
581n/a """Write 'data' to the SSL object and return the number of bytes
582n/a written.
583n/a
584n/a The 'data' argument must support the buffer interface.
585n/a """
586n/a return self._sslobj.write(data)
587n/a
588n/a def getpeercert(self, binary_form=False):
589n/a """Returns a formatted version of the data in the certificate provided
590n/a by the other end of the SSL channel.
591n/a
592n/a Return None if no certificate was provided, {} if a certificate was
593n/a provided, but not validated.
594n/a """
595n/a return self._sslobj.peer_certificate(binary_form)
596n/a
597n/a def selected_npn_protocol(self):
598n/a """Return the currently selected NPN protocol as a string, or ``None``
599n/a if a next protocol was not negotiated or if NPN is not supported by one
600n/a of the peers."""
601n/a if _ssl.HAS_NPN:
602n/a return self._sslobj.selected_npn_protocol()
603n/a
604n/a def selected_alpn_protocol(self):
605n/a """Return the currently selected ALPN protocol as a string, or ``None``
606n/a if a next protocol was not negotiated or if ALPN is not supported by one
607n/a of the peers."""
608n/a if _ssl.HAS_ALPN:
609n/a return self._sslobj.selected_alpn_protocol()
610n/a
611n/a def cipher(self):
612n/a """Return the currently selected cipher as a 3-tuple ``(name,
613n/a ssl_version, secret_bits)``."""
614n/a return self._sslobj.cipher()
615n/a
616n/a def shared_ciphers(self):
617n/a """Return a list of ciphers shared by the client during the handshake or
618n/a None if this is not a valid server connection.
619n/a """
620n/a return self._sslobj.shared_ciphers()
621n/a
622n/a def compression(self):
623n/a """Return the current compression algorithm in use, or ``None`` if
624n/a compression was not negotiated or not supported by one of the peers."""
625n/a return self._sslobj.compression()
626n/a
627n/a def pending(self):
628n/a """Return the number of bytes that can be read immediately."""
629n/a return self._sslobj.pending()
630n/a
631n/a def do_handshake(self):
632n/a """Start the SSL/TLS handshake."""
633n/a self._sslobj.do_handshake()
634n/a if self.context.check_hostname:
635n/a if not self.server_hostname:
636n/a raise ValueError("check_hostname needs server_hostname "
637n/a "argument")
638n/a match_hostname(self.getpeercert(), self.server_hostname)
639n/a
640n/a def unwrap(self):
641n/a """Start the SSL shutdown handshake."""
642n/a return self._sslobj.shutdown()
643n/a
644n/a def get_channel_binding(self, cb_type="tls-unique"):
645n/a """Get channel binding data for current connection. Raise ValueError
646n/a if the requested `cb_type` is not supported. Return bytes of the data
647n/a or None if the data is not available (e.g. before the handshake)."""
648n/a if cb_type not in CHANNEL_BINDING_TYPES:
649n/a raise ValueError("Unsupported channel binding type")
650n/a if cb_type != "tls-unique":
651n/a raise NotImplementedError(
652n/a "{0} channel binding type not implemented"
653n/a .format(cb_type))
654n/a return self._sslobj.tls_unique_cb()
655n/a
656n/a def version(self):
657n/a """Return a string identifying the protocol version used by the
658n/a current SSL channel. """
659n/a return self._sslobj.version()
660n/a
661n/a
662n/aclass SSLSocket(socket):
663n/a """This class implements a subtype of socket.socket that wraps
664n/a the underlying OS socket in an SSL context when necessary, and
665n/a provides read and write methods over that channel."""
666n/a
667n/a def __init__(self, sock=None, keyfile=None, certfile=None,
668n/a server_side=False, cert_reqs=CERT_NONE,
669n/a ssl_version=PROTOCOL_SSLv23, ca_certs=None,
670n/a do_handshake_on_connect=True,
671n/a family=AF_INET, type=SOCK_STREAM, proto=0, fileno=None,
672n/a suppress_ragged_eofs=True, npn_protocols=None, ciphers=None,
673n/a server_hostname=None,
674n/a _context=None):
675n/a
676n/a if _context:
677n/a self._context = _context
678n/a else:
679n/a if server_side and not certfile:
680n/a raise ValueError("certfile must be specified for server-side "
681n/a "operations")
682n/a if keyfile and not certfile:
683n/a raise ValueError("certfile must be specified")
684n/a if certfile and not keyfile:
685n/a keyfile = certfile
686n/a self._context = SSLContext(ssl_version)
687n/a self._context.verify_mode = cert_reqs
688n/a if ca_certs:
689n/a self._context.load_verify_locations(ca_certs)
690n/a if certfile:
691n/a self._context.load_cert_chain(certfile, keyfile)
692n/a if npn_protocols:
693n/a self._context.set_npn_protocols(npn_protocols)
694n/a if ciphers:
695n/a self._context.set_ciphers(ciphers)
696n/a self.keyfile = keyfile
697n/a self.certfile = certfile
698n/a self.cert_reqs = cert_reqs
699n/a self.ssl_version = ssl_version
700n/a self.ca_certs = ca_certs
701n/a self.ciphers = ciphers
702n/a # Can't use sock.type as other flags (such as SOCK_NONBLOCK) get
703n/a # mixed in.
704n/a if sock.getsockopt(SOL_SOCKET, SO_TYPE) != SOCK_STREAM:
705n/a raise NotImplementedError("only stream sockets are supported")
706n/a if server_side and server_hostname:
707n/a raise ValueError("server_hostname can only be specified "
708n/a "in client mode")
709n/a if self._context.check_hostname and not server_hostname:
710n/a raise ValueError("check_hostname requires server_hostname")
711n/a self.server_side = server_side
712n/a self.server_hostname = server_hostname
713n/a self.do_handshake_on_connect = do_handshake_on_connect
714n/a self.suppress_ragged_eofs = suppress_ragged_eofs
715n/a if sock is not None:
716n/a socket.__init__(self,
717n/a family=sock.family,
718n/a type=sock.type,
719n/a proto=sock.proto,
720n/a fileno=sock.fileno())
721n/a self.settimeout(sock.gettimeout())
722n/a sock.detach()
723n/a elif fileno is not None:
724n/a socket.__init__(self, fileno=fileno)
725n/a else:
726n/a socket.__init__(self, family=family, type=type, proto=proto)
727n/a
728n/a # See if we are connected
729n/a try:
730n/a self.getpeername()
731n/a except OSError as e:
732n/a if e.errno != errno.ENOTCONN:
733n/a raise
734n/a connected = False
735n/a else:
736n/a connected = True
737n/a
738n/a self._closed = False
739n/a self._sslobj = None
740n/a self._connected = connected
741n/a if connected:
742n/a # create the SSL object
743n/a try:
744n/a sslobj = self._context._wrap_socket(self, server_side,
745n/a server_hostname)
746n/a self._sslobj = SSLObject(sslobj, owner=self)
747n/a if do_handshake_on_connect:
748n/a timeout = self.gettimeout()
749n/a if timeout == 0.0:
750n/a # non-blocking
751n/a raise ValueError("do_handshake_on_connect should not be specified for non-blocking sockets")
752n/a self.do_handshake()
753n/a
754n/a except (OSError, ValueError):
755n/a self.close()
756n/a raise
757n/a
758n/a @property
759n/a def context(self):
760n/a return self._context
761n/a
762n/a @context.setter
763n/a def context(self, ctx):
764n/a self._context = ctx
765n/a self._sslobj.context = ctx
766n/a
767n/a def dup(self):
768n/a raise NotImplemented("Can't dup() %s instances" %
769n/a self.__class__.__name__)
770n/a
771n/a def _checkClosed(self, msg=None):
772n/a # raise an exception here if you wish to check for spurious closes
773n/a pass
774n/a
775n/a def _check_connected(self):
776n/a if not self._connected:
777n/a # getpeername() will raise ENOTCONN if the socket is really
778n/a # not connected; note that we can be connected even without
779n/a # _connected being set, e.g. if connect() first returned
780n/a # EAGAIN.
781n/a self.getpeername()
782n/a
783n/a def read(self, len=1024, buffer=None):
784n/a """Read up to LEN bytes and return them.
785n/a Return zero-length string on EOF."""
786n/a
787n/a self._checkClosed()
788n/a if not self._sslobj:
789n/a raise ValueError("Read on closed or unwrapped SSL socket.")
790n/a try:
791n/a return self._sslobj.read(len, buffer)
792n/a except SSLError as x:
793n/a if x.args[0] == SSL_ERROR_EOF and self.suppress_ragged_eofs:
794n/a if buffer is not None:
795n/a return 0
796n/a else:
797n/a return b''
798n/a else:
799n/a raise
800n/a
801n/a def write(self, data):
802n/a """Write DATA to the underlying SSL channel. Returns
803n/a number of bytes of DATA actually transmitted."""
804n/a
805n/a self._checkClosed()
806n/a if not self._sslobj:
807n/a raise ValueError("Write on closed or unwrapped SSL socket.")
808n/a return self._sslobj.write(data)
809n/a
810n/a def getpeercert(self, binary_form=False):
811n/a """Returns a formatted version of the data in the
812n/a certificate provided by the other end of the SSL channel.
813n/a Return None if no certificate was provided, {} if a
814n/a certificate was provided, but not validated."""
815n/a
816n/a self._checkClosed()
817n/a self._check_connected()
818n/a return self._sslobj.getpeercert(binary_form)
819n/a
820n/a def selected_npn_protocol(self):
821n/a self._checkClosed()
822n/a if not self._sslobj or not _ssl.HAS_NPN:
823n/a return None
824n/a else:
825n/a return self._sslobj.selected_npn_protocol()
826n/a
827n/a def selected_alpn_protocol(self):
828n/a self._checkClosed()
829n/a if not self._sslobj or not _ssl.HAS_ALPN:
830n/a return None
831n/a else:
832n/a return self._sslobj.selected_alpn_protocol()
833n/a
834n/a def cipher(self):
835n/a self._checkClosed()
836n/a if not self._sslobj:
837n/a return None
838n/a else:
839n/a return self._sslobj.cipher()
840n/a
841n/a def shared_ciphers(self):
842n/a self._checkClosed()
843n/a if not self._sslobj:
844n/a return None
845n/a return self._sslobj.shared_ciphers()
846n/a
847n/a def compression(self):
848n/a self._checkClosed()
849n/a if not self._sslobj:
850n/a return None
851n/a else:
852n/a return self._sslobj.compression()
853n/a
854n/a def send(self, data, flags=0):
855n/a self._checkClosed()
856n/a if self._sslobj:
857n/a if flags != 0:
858n/a raise ValueError(
859n/a "non-zero flags not allowed in calls to send() on %s" %
860n/a self.__class__)
861n/a return self._sslobj.write(data)
862n/a else:
863n/a return socket.send(self, data, flags)
864n/a
865n/a def sendto(self, data, flags_or_addr, addr=None):
866n/a self._checkClosed()
867n/a if self._sslobj:
868n/a raise ValueError("sendto not allowed on instances of %s" %
869n/a self.__class__)
870n/a elif addr is None:
871n/a return socket.sendto(self, data, flags_or_addr)
872n/a else:
873n/a return socket.sendto(self, data, flags_or_addr, addr)
874n/a
875n/a def sendmsg(self, *args, **kwargs):
876n/a # Ensure programs don't send data unencrypted if they try to
877n/a # use this method.
878n/a raise NotImplementedError("sendmsg not allowed on instances of %s" %
879n/a self.__class__)
880n/a
881n/a def sendall(self, data, flags=0):
882n/a self._checkClosed()
883n/a if self._sslobj:
884n/a if flags != 0:
885n/a raise ValueError(
886n/a "non-zero flags not allowed in calls to sendall() on %s" %
887n/a self.__class__)
888n/a amount = len(data)
889n/a count = 0
890n/a while (count < amount):
891n/a v = self.send(data[count:])
892n/a count += v
893n/a else:
894n/a return socket.sendall(self, data, flags)
895n/a
896n/a def sendfile(self, file, offset=0, count=None):
897n/a """Send a file, possibly by using os.sendfile() if this is a
898n/a clear-text socket. Return the total number of bytes sent.
899n/a """
900n/a if self._sslobj is None:
901n/a # os.sendfile() works with plain sockets only
902n/a return super().sendfile(file, offset, count)
903n/a else:
904n/a return self._sendfile_use_send(file, offset, count)
905n/a
906n/a def recv(self, buflen=1024, flags=0):
907n/a self._checkClosed()
908n/a if self._sslobj:
909n/a if flags != 0:
910n/a raise ValueError(
911n/a "non-zero flags not allowed in calls to recv() on %s" %
912n/a self.__class__)
913n/a return self.read(buflen)
914n/a else:
915n/a return socket.recv(self, buflen, flags)
916n/a
917n/a def recv_into(self, buffer, nbytes=None, flags=0):
918n/a self._checkClosed()
919n/a if buffer and (nbytes is None):
920n/a nbytes = len(buffer)
921n/a elif nbytes is None:
922n/a nbytes = 1024
923n/a if self._sslobj:
924n/a if flags != 0:
925n/a raise ValueError(
926n/a "non-zero flags not allowed in calls to recv_into() on %s" %
927n/a self.__class__)
928n/a return self.read(nbytes, buffer)
929n/a else:
930n/a return socket.recv_into(self, buffer, nbytes, flags)
931n/a
932n/a def recvfrom(self, buflen=1024, flags=0):
933n/a self._checkClosed()
934n/a if self._sslobj:
935n/a raise ValueError("recvfrom not allowed on instances of %s" %
936n/a self.__class__)
937n/a else:
938n/a return socket.recvfrom(self, buflen, flags)
939n/a
940n/a def recvfrom_into(self, buffer, nbytes=None, flags=0):
941n/a self._checkClosed()
942n/a if self._sslobj:
943n/a raise ValueError("recvfrom_into not allowed on instances of %s" %
944n/a self.__class__)
945n/a else:
946n/a return socket.recvfrom_into(self, buffer, nbytes, flags)
947n/a
948n/a def recvmsg(self, *args, **kwargs):
949n/a raise NotImplementedError("recvmsg not allowed on instances of %s" %
950n/a self.__class__)
951n/a
952n/a def recvmsg_into(self, *args, **kwargs):
953n/a raise NotImplementedError("recvmsg_into not allowed on instances of "
954n/a "%s" % self.__class__)
955n/a
956n/a def pending(self):
957n/a self._checkClosed()
958n/a if self._sslobj:
959n/a return self._sslobj.pending()
960n/a else:
961n/a return 0
962n/a
963n/a def shutdown(self, how):
964n/a self._checkClosed()
965n/a self._sslobj = None
966n/a socket.shutdown(self, how)
967n/a
968n/a def unwrap(self):
969n/a if self._sslobj:
970n/a s = self._sslobj.unwrap()
971n/a self._sslobj = None
972n/a return s
973n/a else:
974n/a raise ValueError("No SSL wrapper around " + str(self))
975n/a
976n/a def _real_close(self):
977n/a self._sslobj = None
978n/a socket._real_close(self)
979n/a
980n/a def do_handshake(self, block=False):
981n/a """Perform a TLS/SSL handshake."""
982n/a self._check_connected()
983n/a timeout = self.gettimeout()
984n/a try:
985n/a if timeout == 0.0 and block:
986n/a self.settimeout(None)
987n/a self._sslobj.do_handshake()
988n/a finally:
989n/a self.settimeout(timeout)
990n/a
991n/a def _real_connect(self, addr, connect_ex):
992n/a if self.server_side:
993n/a raise ValueError("can't connect in server-side mode")
994n/a # Here we assume that the socket is client-side, and not
995n/a # connected at the time of the call. We connect it, then wrap it.
996n/a if self._connected:
997n/a raise ValueError("attempt to connect already-connected SSLSocket!")
998n/a sslobj = self.context._wrap_socket(self, False, self.server_hostname)
999n/a self._sslobj = SSLObject(sslobj, owner=self)
1000n/a try:
1001n/a if connect_ex:
1002n/a rc = socket.connect_ex(self, addr)
1003n/a else:
1004n/a rc = None
1005n/a socket.connect(self, addr)
1006n/a if not rc:
1007n/a self._connected = True
1008n/a if self.do_handshake_on_connect:
1009n/a self.do_handshake()
1010n/a return rc
1011n/a except (OSError, ValueError):
1012n/a self._sslobj = None
1013n/a raise
1014n/a
1015n/a def connect(self, addr):
1016n/a """Connects to remote ADDR, and then wraps the connection in
1017n/a an SSL channel."""
1018n/a self._real_connect(addr, False)
1019n/a
1020n/a def connect_ex(self, addr):
1021n/a """Connects to remote ADDR, and then wraps the connection in
1022n/a an SSL channel."""
1023n/a return self._real_connect(addr, True)
1024n/a
1025n/a def accept(self):
1026n/a """Accepts a new connection from a remote client, and returns
1027n/a a tuple containing that new connection wrapped with a server-side
1028n/a SSL channel, and the address of the remote client."""
1029n/a
1030n/a newsock, addr = socket.accept(self)
1031n/a newsock = self.context.wrap_socket(newsock,
1032n/a do_handshake_on_connect=self.do_handshake_on_connect,
1033n/a suppress_ragged_eofs=self.suppress_ragged_eofs,
1034n/a server_side=True)
1035n/a return newsock, addr
1036n/a
1037n/a def get_channel_binding(self, cb_type="tls-unique"):
1038n/a """Get channel binding data for current connection. Raise ValueError
1039n/a if the requested `cb_type` is not supported. Return bytes of the data
1040n/a or None if the data is not available (e.g. before the handshake).
1041n/a """
1042n/a if self._sslobj is None:
1043n/a return None
1044n/a return self._sslobj.get_channel_binding(cb_type)
1045n/a
1046n/a def version(self):
1047n/a """
1048n/a Return a string identifying the protocol version used by the
1049n/a current SSL channel, or None if there is no established channel.
1050n/a """
1051n/a if self._sslobj is None:
1052n/a return None
1053n/a return self._sslobj.version()
1054n/a
1055n/a
1056n/adef wrap_socket(sock, keyfile=None, certfile=None,
1057n/a server_side=False, cert_reqs=CERT_NONE,
1058n/a ssl_version=PROTOCOL_SSLv23, ca_certs=None,
1059n/a do_handshake_on_connect=True,
1060n/a suppress_ragged_eofs=True,
1061n/a ciphers=None):
1062n/a
1063n/a return SSLSocket(sock=sock, keyfile=keyfile, certfile=certfile,
1064n/a server_side=server_side, cert_reqs=cert_reqs,
1065n/a ssl_version=ssl_version, ca_certs=ca_certs,
1066n/a do_handshake_on_connect=do_handshake_on_connect,
1067n/a suppress_ragged_eofs=suppress_ragged_eofs,
1068n/a ciphers=ciphers)
1069n/a
1070n/a# some utility functions
1071n/a
1072n/adef cert_time_to_seconds(cert_time):
1073n/a """Return the time in seconds since the Epoch, given the timestring
1074n/a representing the "notBefore" or "notAfter" date from a certificate
1075n/a in ``"%b %d %H:%M:%S %Y %Z"`` strptime format (C locale).
1076n/a
1077n/a "notBefore" or "notAfter" dates must use UTC (RFC 5280).
1078n/a
1079n/a Month is one of: Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
1080n/a UTC should be specified as GMT (see ASN1_TIME_print())
1081n/a """
1082n/a from time import strptime
1083n/a from calendar import timegm
1084n/a
1085n/a months = (
1086n/a "Jan","Feb","Mar","Apr","May","Jun",
1087n/a "Jul","Aug","Sep","Oct","Nov","Dec"
1088n/a )
1089n/a time_format = ' %d %H:%M:%S %Y GMT' # NOTE: no month, fixed GMT
1090n/a try:
1091n/a month_number = months.index(cert_time[:3].title()) + 1
1092n/a except ValueError:
1093n/a raise ValueError('time data %r does not match '
1094n/a 'format "%%b%s"' % (cert_time, time_format))
1095n/a else:
1096n/a # found valid month
1097n/a tt = strptime(cert_time[3:], time_format)
1098n/a # return an integer, the previous mktime()-based implementation
1099n/a # returned a float (fractional seconds are always zero here).
1100n/a return timegm((tt[0], month_number) + tt[2:6])
1101n/a
1102n/aPEM_HEADER = "-----BEGIN CERTIFICATE-----"
1103n/aPEM_FOOTER = "-----END CERTIFICATE-----"
1104n/a
1105n/adef DER_cert_to_PEM_cert(der_cert_bytes):
1106n/a """Takes a certificate in binary DER format and returns the
1107n/a PEM version of it as a string."""
1108n/a
1109n/a f = str(base64.standard_b64encode(der_cert_bytes), 'ASCII', 'strict')
1110n/a return (PEM_HEADER + '\n' +
1111n/a textwrap.fill(f, 64) + '\n' +
1112n/a PEM_FOOTER + '\n')
1113n/a
1114n/adef PEM_cert_to_DER_cert(pem_cert_string):
1115n/a """Takes a certificate in ASCII PEM format and returns the
1116n/a DER-encoded version of it as a byte sequence"""
1117n/a
1118n/a if not pem_cert_string.startswith(PEM_HEADER):
1119n/a raise ValueError("Invalid PEM encoding; must start with %s"
1120n/a % PEM_HEADER)
1121n/a if not pem_cert_string.strip().endswith(PEM_FOOTER):
1122n/a raise ValueError("Invalid PEM encoding; must end with %s"
1123n/a % PEM_FOOTER)
1124n/a d = pem_cert_string.strip()[len(PEM_HEADER):-len(PEM_FOOTER)]
1125n/a return base64.decodebytes(d.encode('ASCII', 'strict'))
1126n/a
1127n/adef get_server_certificate(addr, ssl_version=PROTOCOL_SSLv23, ca_certs=None):
1128n/a """Retrieve the certificate from the server at the specified address,
1129n/a and return it as a PEM-encoded string.
1130n/a If 'ca_certs' is specified, validate the server cert against it.
1131n/a If 'ssl_version' is specified, use it in the connection attempt."""
1132n/a
1133n/a host, port = addr
1134n/a if ca_certs is not None:
1135n/a cert_reqs = CERT_REQUIRED
1136n/a else:
1137n/a cert_reqs = CERT_NONE
1138n/a context = _create_stdlib_context(ssl_version,
1139n/a cert_reqs=cert_reqs,
1140n/a cafile=ca_certs)
1141n/a with create_connection(addr) as sock:
1142n/a with context.wrap_socket(sock) as sslsock:
1143n/a dercert = sslsock.getpeercert(True)
1144n/a return DER_cert_to_PEM_cert(dercert)
1145n/a
1146n/adef get_protocol_name(protocol_code):
1147n/a return _PROTOCOL_NAMES.get(protocol_code, '<unknown>')