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