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