diff options
Diffstat (limited to 'Lib/ssl.py')
-rw-r--r-- | Lib/ssl.py | 73 |
1 files changed, 65 insertions, 8 deletions
@@ -60,10 +60,25 @@ import re import _ssl # if we can't import it, let the error propagate from _ssl import OPENSSL_VERSION_NUMBER, OPENSSL_VERSION_INFO, OPENSSL_VERSION -from _ssl import _SSLContext, SSLError +from _ssl import _SSLContext +from _ssl import ( + SSLError, SSLZeroReturnError, SSLWantReadError, SSLWantWriteError, + SSLSyscallError, SSLEOFError, + ) from _ssl import CERT_NONE, CERT_OPTIONAL, CERT_REQUIRED -from _ssl import OP_ALL, OP_NO_SSLv2, OP_NO_SSLv3, OP_NO_TLSv1 -from _ssl import RAND_status, RAND_egd, RAND_add +from _ssl import ( + OP_ALL, OP_NO_SSLv2, OP_NO_SSLv3, OP_NO_TLSv1, + OP_CIPHER_SERVER_PREFERENCE, OP_SINGLE_DH_USE + ) +try: + from _ssl import OP_NO_COMPRESSION +except ImportError: + pass +try: + from _ssl import OP_SINGLE_ECDH_USE +except ImportError: + pass +from _ssl import RAND_status, RAND_egd, RAND_add, RAND_bytes, RAND_pseudo_bytes from _ssl import ( SSL_ERROR_ZERO_RETURN, SSL_ERROR_WANT_READ, @@ -75,8 +90,9 @@ from _ssl import ( SSL_ERROR_EOF, SSL_ERROR_INVALID_ERROR_CODE, ) -from _ssl import HAS_SNI -from _ssl import PROTOCOL_SSLv3, PROTOCOL_SSLv23, PROTOCOL_TLSv1 +from _ssl import HAS_SNI, HAS_ECDH +from _ssl import (PROTOCOL_SSLv3, PROTOCOL_SSLv23, + PROTOCOL_TLSv1) from _ssl import _OPENSSL_API_VERSION _PROTOCOL_NAMES = { @@ -94,11 +110,16 @@ else: from socket import getnameinfo as _getnameinfo from socket import error as socket_error -from socket import socket, AF_INET, SOCK_STREAM +from socket import socket, AF_INET, SOCK_STREAM, create_connection import base64 # for DER-to-PEM translation import traceback import errno +if _ssl.HAS_TLS_UNIQUE: + CHANNEL_BINDING_TYPES = ['tls-unique'] +else: + CHANNEL_BINDING_TYPES = [] + # Disable weak or insecure ciphers by default # (OpenSSL's default setting is 'DEFAULT:!aNULL:!eNULL') _DEFAULT_CIPHERS = 'DEFAULT:!aNULL:!eNULL:!LOW:!EXPORT:!SSLv2' @@ -326,6 +347,13 @@ class SSLSocket(socket): else: return self._sslobj.cipher() + def compression(self): + self._checkClosed() + if not self._sslobj: + return None + else: + return self._sslobj.compression() + def send(self, data, flags=0): self._checkClosed() if self._sslobj: @@ -358,6 +386,12 @@ class SSLSocket(socket): else: return socket.sendto(self, data, flags_or_addr, addr) + def sendmsg(self, *args, **kwargs): + # Ensure programs don't send data unencrypted if they try to + # use this method. + raise NotImplementedError("sendmsg not allowed on instances of %s" % + self.__class__) + def sendall(self, data, flags=0): self._checkClosed() if self._sslobj: @@ -416,6 +450,14 @@ class SSLSocket(socket): else: return socket.recvfrom_into(self, buffer, nbytes, flags) + def recvmsg(self, *args, **kwargs): + raise NotImplementedError("recvmsg not allowed on instances of %s" % + self.__class__) + + def recvmsg_into(self, *args, **kwargs): + raise NotImplementedError("recvmsg_into not allowed on instances of " + "%s" % self.__class__) + def pending(self): self._checkClosed() if self._sslobj: @@ -502,6 +544,21 @@ class SSLSocket(socket): self.do_handshake_on_connect), addr) + def get_channel_binding(self, cb_type="tls-unique"): + """Get channel binding data for current connection. Raise ValueError + if the requested `cb_type` is not supported. Return bytes of the data + or None if the data is not available (e.g. before the handshake). + """ + if cb_type not in CHANNEL_BINDING_TYPES: + raise ValueError("Unsupported channel binding type") + if cb_type != "tls-unique": + raise NotImplementedError( + "{0} channel binding type not implemented" + .format(cb_type)) + if self._sslobj is None: + return None + return self._sslobj.tls_unique_cb() + def __del__(self): # sys.stderr.write("__del__ on %s\n" % repr(self)) self._real_close() @@ -566,9 +623,9 @@ def get_server_certificate(addr, ssl_version=PROTOCOL_SSLv3, ca_certs=None): cert_reqs = CERT_REQUIRED else: cert_reqs = CERT_NONE - s = wrap_socket(socket(), ssl_version=ssl_version, + s = create_connection(addr) + s = wrap_socket(s, ssl_version=ssl_version, cert_reqs=cert_reqs, ca_certs=ca_certs) - s.connect(addr) dercert = s.getpeercert(True) s.close() return DER_cert_to_PEM_cert(dercert) |