From fa2f87743e8780493922a01d187d07d3fbc32761 Mon Sep 17 00:00:00 2001 From: Peter Surda Date: Sat, 14 Jan 2017 13:22:46 +0100 Subject: [PATCH] SSL handshake fix - SSL handshake would often fail, because verack packet was being sent at the same time as the do_handshake was executed in a different thread. This makes it so that do_handshake waits until verack is done sending. - also minor modifications in SSLContext initialisation --- src/class_receiveDataThread.py | 7 ++++--- src/class_sendDataThread.py | 2 ++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/class_receiveDataThread.py b/src/class_receiveDataThread.py index 5dac4b19..821eedc2 100644 --- a/src/class_receiveDataThread.py +++ b/src/class_receiveDataThread.py @@ -294,16 +294,17 @@ class receiveDataThread(threading.Thread): protocol.haveSSL(not self.initiatedConnection)): logger.debug("Initialising TLS") if sys.version_info >= (2,7,9): - context = ssl.create_default_context(purpose = ssl.Purpose.CLIENT_AUTH if self.initiatedConnection else ssl.Purpose.SERVER_AUTH) + context = ssl.SSLContext(protocol.sslProtocolVersion) context.set_ciphers("AECDH-AES256-SHA") context.set_ecdh_curve("secp256k1") context.check_hostname = False context.verify_mode = ssl.CERT_NONE # also exclude TLSv1 and TLSv1.1 in the future - context.options |= ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3 + context.options = ssl.OP_ALL | ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3 | ssl.OP_SINGLE_ECDH_USE | ssl.OP_CIPHER_SERVER_PREFERENCE self.sslSock = context.wrap_socket(self.sock, server_side = not self.initiatedConnection, do_handshake_on_connect=False) else: self.sslSock = ssl.wrap_socket(self.sock, keyfile = os.path.join(paths.codePath(), 'sslkeys', 'key.pem'), certfile = os.path.join(paths.codePath(), 'sslkeys', 'cert.pem'), server_side = not self.initiatedConnection, ssl_version=protocol.sslProtocolVersion, do_handshake_on_connect=False, ciphers='AECDH-AES256-SHA') + self.sendDataThreadQueue.join() while True: try: self.sslSock.do_handshake() @@ -316,7 +317,7 @@ class receiveDataThread(threading.Thread): logger.debug("Waiting for SSL socket handhake write") select.select([], [self.sslSock], [], 10) except: - logger.debug("SSL socket handhake failed, shutting down connection") + logger.error("SSL socket handhake failed, shutting down connection", exc_info=True) self.sendDataThreadQueue.put((0, 'shutdown','tls handshake fail')) return # Command the corresponding sendDataThread to set its own connectionIsOrWasFullyEstablished variable to True also diff --git a/src/class_sendDataThread.py b/src/class_sendDataThread.py index 2fed7071..e1c03c98 100644 --- a/src/class_sendDataThread.py +++ b/src/class_sendDataThread.py @@ -185,6 +185,8 @@ class sendDataThread(threading.Thread): self.services, self.sslSock = data else: logger.error('sendDataThread ID: ' + str(id(self)) + ' ignoring command ' + command + ' because the thread is not in stream' + str(deststream)) + self.sendDataThreadQueue.task_done() + self.sendDataThreadQueue.task_done() try: self.sock.shutdown(socket.SHUT_RDWR)