mirror of
https://github.com/aljazceru/python-teos.git
synced 2025-12-17 14:14:22 +01:00
Modifies behaviour towards a failed EncryptedBlob decrpytion
The decryption for the `EncryptedBlob` using AES-GCM-128 (the only cipher available atm) raises an `InvalidTag` exception. This was not properly captured by the watcher making it crash. This behavior was already discovered during the `EncryptedBlob` unit testing and left to be fixed in the `Watcher` unit testing. However, making the EncryptedBlob raise such an exception may not be a good practice, since other ciphers may run into different exceptions. Therefore, the `EncryptedBlob` has been modified to return None upon facing a decryption issue, the `BlockProcessor` will detect that and return a None justice_txm and justice_txid. Upon receiving a None `justice_txid` the `Watcher` will delete the appointment without notifiying the `Responder`.
This commit is contained in:
@@ -74,15 +74,17 @@ class BlockProcessor:
|
|||||||
# ToDo: #20-test-tx-decrypting-edge-cases
|
# ToDo: #20-test-tx-decrypting-edge-cases
|
||||||
justice_rawtx = appointments[uuid].encrypted_blob.decrypt(dispute_txid)
|
justice_rawtx = appointments[uuid].encrypted_blob.decrypt(dispute_txid)
|
||||||
justice_txid = bitcoin_cli.decoderawtransaction(justice_rawtx).get('txid')
|
justice_txid = bitcoin_cli.decoderawtransaction(justice_rawtx).get('txid')
|
||||||
matches.append((locator, uuid, dispute_txid, justice_txid, justice_rawtx))
|
|
||||||
|
|
||||||
logger.info("Match found for locator.", locator=locator, uuid=uuid, justice_txid=justice_txid)
|
logger.info("Match found for locator.", locator=locator, uuid=uuid, justice_txid=justice_txid)
|
||||||
|
|
||||||
except JSONRPCException as e:
|
except JSONRPCException as e:
|
||||||
# Tx decode failed returns error code -22, maybe we should be more strict here. Leaving it simple
|
# Tx decode failed returns error code -22, maybe we should be more strict here. Leaving it simple
|
||||||
# for the POC
|
# for the POC
|
||||||
|
justice_txid = None
|
||||||
|
justice_rawtx = None
|
||||||
logger.error("Can't build transaction from decoded data.", error=e.error)
|
logger.error("Can't build transaction from decoded data.", error=e.error)
|
||||||
|
|
||||||
|
matches.append((locator, uuid, dispute_txid, justice_txid, justice_rawtx))
|
||||||
|
|
||||||
return matches
|
return matches
|
||||||
|
|
||||||
# DISCUSS: This method comes from the Responder and seems like it could go back there.
|
# DISCUSS: This method comes from the Responder and seems like it could go back there.
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
from hashlib import sha256
|
from hashlib import sha256
|
||||||
from binascii import unhexlify, hexlify
|
from binascii import unhexlify, hexlify
|
||||||
|
from cryptography.exceptions import InvalidTag
|
||||||
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
|
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
|
||||||
|
|
||||||
from pisa.logger import Logger
|
from pisa.logger import Logger
|
||||||
|
|
||||||
logger = Logger("Watcher")
|
logger = Logger("Watcher")
|
||||||
@@ -33,7 +35,12 @@ class EncryptedBlob:
|
|||||||
# Decrypt
|
# Decrypt
|
||||||
aesgcm = AESGCM(sk)
|
aesgcm = AESGCM(sk)
|
||||||
data = unhexlify(self.data.encode())
|
data = unhexlify(self.data.encode())
|
||||||
raw_tx = aesgcm.decrypt(nonce=nonce, data=data, associated_data=None)
|
|
||||||
hex_raw_tx = hexlify(raw_tx).decode('utf8')
|
try:
|
||||||
|
raw_tx = aesgcm.decrypt(nonce=nonce, data=data, associated_data=None)
|
||||||
|
hex_raw_tx = hexlify(raw_tx).decode('utf8')
|
||||||
|
|
||||||
|
except InvalidTag:
|
||||||
|
hex_raw_tx = None
|
||||||
|
|
||||||
return hex_raw_tx
|
return hex_raw_tx
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ class Watcher:
|
|||||||
if self.asleep:
|
if self.asleep:
|
||||||
self.asleep = False
|
self.asleep = False
|
||||||
self.block_queue = Queue()
|
self.block_queue = Queue()
|
||||||
zmq_thread = Thread(target=self.do_subscribe, args=[self.block_queue])
|
zmq_thread = Thread(target=self.do_subscribe)
|
||||||
watcher = Thread(target=self.do_watch)
|
watcher = Thread(target=self.do_watch)
|
||||||
zmq_thread.start()
|
zmq_thread.start()
|
||||||
watcher.start()
|
watcher.start()
|
||||||
@@ -67,9 +67,9 @@ class Watcher:
|
|||||||
|
|
||||||
return appointment_added
|
return appointment_added
|
||||||
|
|
||||||
def do_subscribe(self, block_queue):
|
def do_subscribe(self):
|
||||||
self.zmq_subscriber = ZMQHandler(parent="Watcher")
|
self.zmq_subscriber = ZMQHandler(parent="Watcher")
|
||||||
self.zmq_subscriber.handle(block_queue)
|
self.zmq_subscriber.handle(self.block_queue)
|
||||||
|
|
||||||
def do_watch(self):
|
def do_watch(self):
|
||||||
while len(self.appointments) > 0:
|
while len(self.appointments) > 0:
|
||||||
@@ -92,11 +92,13 @@ class Watcher:
|
|||||||
matches = BlockProcessor.get_matches(potential_matches, self.locator_uuid_map, self.appointments)
|
matches = BlockProcessor.get_matches(potential_matches, self.locator_uuid_map, self.appointments)
|
||||||
|
|
||||||
for locator, uuid, dispute_txid, justice_txid, justice_rawtx in matches:
|
for locator, uuid, dispute_txid, justice_txid, justice_rawtx in matches:
|
||||||
logger.info("Notifying responder and deleting appointment.",
|
# Errors decrypting the Blob will result in a None justice_txid
|
||||||
justice_txid=justice_txid, locator=locator, uuid=uuid)
|
if justice_txid is not None:
|
||||||
|
logger.info("Notifying responder and deleting appointment.", justice_txid=justice_txid,
|
||||||
|
locator=locator, uuid=uuid)
|
||||||
|
|
||||||
self.responder.add_response(uuid, dispute_txid, justice_txid, justice_rawtx,
|
self.responder.add_response(uuid, dispute_txid, justice_txid, justice_rawtx,
|
||||||
self.appointments[uuid].end_time)
|
self.appointments[uuid].end_time)
|
||||||
|
|
||||||
# Delete the appointment
|
# Delete the appointment
|
||||||
self.appointments.pop(uuid)
|
self.appointments.pop(uuid)
|
||||||
|
|||||||
@@ -19,13 +19,10 @@ def test_decrypt():
|
|||||||
encrypted_data = urandom(64).hex()
|
encrypted_data = urandom(64).hex()
|
||||||
encrypted_blob = EncryptedBlob(encrypted_data)
|
encrypted_blob = EncryptedBlob(encrypted_data)
|
||||||
|
|
||||||
# Trying to decrypt random data (in AES_GCM-128) should result in an InvalidTag exception
|
# Trying to decrypt random data (in AES_GCM-128) should result in an InvalidTag exception. Our decrypt function
|
||||||
try:
|
# returns None
|
||||||
encrypted_blob.decrypt(key)
|
hex_tx = encrypted_blob.decrypt(key)
|
||||||
assert False, "Able to decrypt random data with random key"
|
assert hex_tx is None
|
||||||
|
|
||||||
except InvalidTag:
|
|
||||||
assert True
|
|
||||||
|
|
||||||
# Valid data should run with no InvalidTag and verify
|
# Valid data should run with no InvalidTag and verify
|
||||||
data = "6097cdf52309b1b2124efeed36bd34f46dc1c25ad23ac86f28380f746254f777"
|
data = "6097cdf52309b1b2124efeed36bd34f46dc1c25ad23ac86f28380f746254f777"
|
||||||
|
|||||||
Reference in New Issue
Block a user