diff -r 1891ba98ff59 Lib/ssl.py --- a/Lib/ssl.py Thu Oct 02 17:12:20 2014 -0400 +++ b/Lib/ssl.py Fri Oct 03 06:35:35 2014 -0400 @@ -493,9 +493,9 @@ * The ``do_handshake_on_connect`` and ``suppress_ragged_eofs`` machinery. """ - def __init__(self, sslobj): + def __init__(self, sslobj, owner=None): self._sslobj = sslobj - self._sslobj.owner = self + self._sslobj.owner = owner or self @property def context(self): @@ -578,7 +578,7 @@ def unwrap(self): """Start the SSL shutdown handshake.""" - self._sslobj.shutdown() + return self._sslobj.shutdown() def get_channel_binding(self, cb_type="tls-unique"): """Get channel binding data for current connection. Raise ValueError @@ -592,6 +592,11 @@ .format(cb_type)) return self._sslobj.tls_unique_cb() + def version(self): + """Return a string identifying the protocol version used by the + current SSL channel. """ + return self._sslobj.version() + class SSLSocket(socket): """This class implements a subtype of socket.socket that wraps @@ -680,8 +685,9 @@ if connected: # create the SSL object try: - self._sslobj = self._context._wrap_socket(self, server_side, - server_hostname) + sslobj = self._context._wrap_socket(self, server_side, + server_hostname) + self._sslobj = SSLObject(sslobj, owner=self) if do_handshake_on_connect: timeout = self.gettimeout() if timeout == 0.0: @@ -726,11 +732,7 @@ if not self._sslobj: raise ValueError("Read on closed or unwrapped SSL socket.") try: - if buffer is not None: - v = self._sslobj.read(len, buffer) - else: - v = self._sslobj.read(len or 1024) - return v + return self._sslobj.read(len, buffer) except SSLError as x: if x.args[0] == SSL_ERROR_EOF and self.suppress_ragged_eofs: if buffer is not None: @@ -757,7 +759,7 @@ self._checkClosed() self._check_connected() - return self._sslobj.peer_certificate(binary_form) + return self._sslobj.getpeercert(binary_form) def selected_npn_protocol(self): self._checkClosed() @@ -897,7 +899,7 @@ def unwrap(self): if self._sslobj: - s = self._sslobj.shutdown() + s = self._sslobj.unwrap() self._sslobj = None return s else: @@ -918,12 +920,6 @@ finally: self.settimeout(timeout) - if self.context.check_hostname: - if not self.server_hostname: - raise ValueError("check_hostname needs server_hostname " - "argument") - match_hostname(self.getpeercert(), self.server_hostname) - def _real_connect(self, addr, connect_ex): if self.server_side: raise ValueError("can't connect in server-side mode") @@ -931,7 +927,8 @@ # connected at the time of the call. We connect it, then wrap it. if self._connected: raise ValueError("attempt to connect already-connected SSLSocket!") - self._sslobj = self.context._wrap_socket(self, False, self.server_hostname) + sslobj = self.context._wrap_socket(self, False, self.server_hostname) + self._sslobj = SSLObject(sslobj, owner=self) try: if connect_ex: rc = socket.connect_ex(self, addr) @@ -974,15 +971,9 @@ 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() + return self._sslobj.get_channel_binding(cb_type) def version(self): """ diff -r 1891ba98ff59 Lib/test/test_ssl.py --- a/Lib/test/test_ssl.py Thu Oct 02 17:12:20 2014 -0400 +++ b/Lib/test/test_ssl.py Fri Oct 03 06:35:35 2014 -0400 @@ -518,7 +518,11 @@ def test_unknown_channel_binding(self): # should raise ValueError for unknown type s = socket.socket(socket.AF_INET) - with ssl.wrap_socket(s) as ss: + s.bind(('127.0.0.1', 0)) + s.listen() + c = socket.socket(socket.AF_INET) + c.connect(s.getsockname()) + with ssl.wrap_socket(c, do_handshake_on_connect=False) as ss: with self.assertRaises(ValueError): ss.get_channel_binding("unknown-type")