Author: Amaury Forgeot d'Arc <amaur...@gmail.com>
Branch: py3.3
Changeset: r75002:e8613bc29b37
Date: 2014-12-16 19:12 +0100
http://bitbucket.org/pypy/pypy/changeset/e8613bc29b37/

Log:    SSL: implement tls_unique_cb()

diff --git a/pypy/module/_ssl/interp_ssl.py b/pypy/module/_ssl/interp_ssl.py
--- a/pypy/module/_ssl/interp_ssl.py
+++ b/pypy/module/_ssl/interp_ssl.py
@@ -705,6 +705,27 @@
                     return space.wrap(
                         rffi.charpsize2str(out_ptr[0], widen(len_ptr[0])))
 
+    def tls_unique_cb(self, space):
+        """Returns the 'tls-unique' channel binding data, as defined by RFC 
5929.
+        If the TLS handshake is not yet complete, None is returned"""
+
+        # In case of 'tls-unique' it will be 12 bytes for TLS, 36
+        # bytes for older SSL, but let's be safe
+        CB_MAXLEN = 128
+
+        with lltype.scoped_alloc(rffi.CCHARP.TO, CB_MAXLEN) as buf:
+            if (libssl_SSL_session_reused(self.ssl) ^ 
+                (self.socket_side == PY_SSL_CLIENT)):
+                # if session is resumed XOR we are the client
+                length = libssl_SSL_get_finished(self.ssl, buf, CB_MAXLEN)
+            else:
+                # if a new session XOR we are the server
+                length = libssl_SSL_get_peer_finished(self.ssl, buf, CB_MAXLEN)
+            
+            if length > 0:
+                return space.wrapbytes(rffi.charpsize2str(buf, 
intmask(length)))
+
+
 def _decode_certificate(space, certificate, verbose=False):
     w_retval = space.newdict()
 
@@ -916,6 +937,7 @@
     cipher = interp2app(SSLSocket.cipher),
     peer_certificate = interp2app(SSLSocket.peer_certificate),
     selected_npn_protocol = interp2app(SSLSocket.selected_npn_protocol),
+    tls_unique_cb = interp2app(SSLSocket.tls_unique_cb),
 )
 
 
@@ -947,6 +969,7 @@
         libssl_SSL_set_connect_state(ss.ssl)
     else:
         libssl_SSL_set_accept_state(ss.ssl)
+    ss.socket_side = side
 
     ss.w_socket = weakref.ref(w_sock)
     return ss
diff --git a/pypy/module/_ssl/test/test_ssl.py 
b/pypy/module/_ssl/test/test_ssl.py
--- a/pypy/module/_ssl/test/test_ssl.py
+++ b/pypy/module/_ssl/test/test_ssl.py
@@ -190,6 +190,14 @@
         self.s.close()
         del ss; gc.collect()
 
+    def test_tls_unique_cb(self):
+        import ssl, sys, gc
+        ss = ssl.wrap_socket(self.s)
+        ss.do_handshake()
+        assert isinstance(ss.get_channel_binding(), bytes)
+        self.s.close()
+        del ss; gc.collect()
+
 
 class AppTestConnectedSSL_Timeout(AppTestConnectedSSL):
     # Same tests, with a socket timeout
diff --git a/rpython/rlib/ropenssl.py b/rpython/rlib/ropenssl.py
--- a/rpython/rlib/ropenssl.py
+++ b/rpython/rlib/ropenssl.py
@@ -242,6 +242,9 @@
 ssl_external('SSL_get_shutdown', [SSL], rffi.INT)
 ssl_external('SSL_set_read_ahead', [SSL, rffi.INT], lltype.Void)
 ssl_external('SSL_set_tlsext_host_name', [SSL, rffi.CCHARP], rffi.INT, 
macro=True)
+ssl_external('SSL_session_reused', [SSL], rffi.INT, macro=True)
+ssl_external('SSL_get_finished', [SSL, rffi.CCHARP, rffi.SIZE_T], rffi.SIZE_T)
+ssl_external('SSL_get_peer_finished', [SSL, rffi.CCHARP, rffi.SIZE_T], 
rffi.SIZE_T)
 
 ssl_external('SSL_get_peer_certificate', [SSL], X509)
 ssl_external('X509_get_subject_name', [X509], X509_NAME)
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to