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
This commit is contained in:
Peter Šurda 2017-01-14 13:22:46 +01:00
parent cc4c07025b
commit fa2f87743e
Signed by: PeterSurda
GPG Key ID: 0C5F50C0B5F37D87
2 changed files with 6 additions and 3 deletions

View File

@ -294,16 +294,17 @@ class receiveDataThread(threading.Thread):
protocol.haveSSL(not self.initiatedConnection)): protocol.haveSSL(not self.initiatedConnection)):
logger.debug("Initialising TLS") logger.debug("Initialising TLS")
if sys.version_info >= (2,7,9): 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_ciphers("AECDH-AES256-SHA")
context.set_ecdh_curve("secp256k1") context.set_ecdh_curve("secp256k1")
context.check_hostname = False context.check_hostname = False
context.verify_mode = ssl.CERT_NONE context.verify_mode = ssl.CERT_NONE
# also exclude TLSv1 and TLSv1.1 in the future # 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) self.sslSock = context.wrap_socket(self.sock, server_side = not self.initiatedConnection, do_handshake_on_connect=False)
else: 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.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: while True:
try: try:
self.sslSock.do_handshake() self.sslSock.do_handshake()
@ -316,7 +317,7 @@ class receiveDataThread(threading.Thread):
logger.debug("Waiting for SSL socket handhake write") logger.debug("Waiting for SSL socket handhake write")
select.select([], [self.sslSock], [], 10) select.select([], [self.sslSock], [], 10)
except: 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')) self.sendDataThreadQueue.put((0, 'shutdown','tls handshake fail'))
return return
# Command the corresponding sendDataThread to set its own connectionIsOrWasFullyEstablished variable to True also # Command the corresponding sendDataThread to set its own connectionIsOrWasFullyEstablished variable to True also

View File

@ -185,6 +185,8 @@ class sendDataThread(threading.Thread):
self.services, self.sslSock = data self.services, self.sslSock = data
else: else:
logger.error('sendDataThread ID: ' + str(id(self)) + ' ignoring command ' + command + ' because the thread is not in stream' + str(deststream)) 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: try:
self.sock.shutdown(socket.SHUT_RDWR) self.sock.shutdown(socket.SHUT_RDWR)