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