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