Author: Amaury Forgeot d'Arc <[email protected]>
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
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit