source: titan/mediathek/localhoster/lib/python2.7/ssl.py @ 40114

Last change on this file since 40114 was 40094, checked in by obi, 5 years ago

tithek add yoztube-dl support

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