mirror of
https://github.com/markqvist/Reticulum.git
synced 2025-07-25 07:45:27 -04:00
Implemented compatibility handling for AES-256 migration
This commit is contained in:
parent
5dc8cdc6dc
commit
d7791c60e2
4 changed files with 64 additions and 26 deletions
|
@ -37,6 +37,8 @@ from RNS.Cryptography import AES
|
|||
from RNS.Cryptography.AES import AES_128_CBC
|
||||
from RNS.Cryptography.AES import AES_256_CBC
|
||||
|
||||
# import RNS # TODO: Remove
|
||||
|
||||
class Token():
|
||||
"""
|
||||
This class provides a slightly modified implementation of the Fernet spec
|
||||
|
@ -64,11 +66,23 @@ class Token():
|
|||
self._signing_key = key[:16]
|
||||
self._encryption_key = key[16:]
|
||||
|
||||
####################################################################
|
||||
self.mode_legacy = AES_128_CBC # TODO: Remove after migration
|
||||
self._signing_key_128 = key[:16] # TODO: Remove after migration
|
||||
self._encryption_key_128 = key[16:] # TODO: Remove after migration
|
||||
####################################################################
|
||||
|
||||
elif len(key) == 64:
|
||||
self.mode = AES_256_CBC
|
||||
self._signing_key = key[:32]
|
||||
self._encryption_key = key[32:]
|
||||
|
||||
####################################################################
|
||||
self.mode_legacy = AES_128_CBC # TODO: Remove after migration
|
||||
self._signing_key_128 = key[:16] # TODO: Remove after migration
|
||||
self._encryption_key_128 = key[16:32] # TODO: Remove after migration
|
||||
####################################################################
|
||||
|
||||
else: raise ValueError("Token key must be 128 or 256 bits, not "+str(len(key)*8))
|
||||
|
||||
else: raise TypeError(f"Invalid token mode: {mode}")
|
||||
|
@ -79,16 +93,17 @@ class Token():
|
|||
else:
|
||||
received_hmac = token[-32:]
|
||||
expected_hmac = HMAC.new(self._signing_key, token[:-32]).digest()
|
||||
expected_hmac_128 = HMAC.new(self._signing_key_128, token[:-32]).digest() # TODO: Remove after migration
|
||||
|
||||
if received_hmac == expected_hmac: return True
|
||||
# TODO: Reset after migration
|
||||
# if received_hmac == expected_hmac: return True
|
||||
if received_hmac == expected_hmac or received_hmac == expected_hmac_128: return True
|
||||
else: return False
|
||||
|
||||
|
||||
def encrypt(self, data = None):
|
||||
iv = os.urandom(16)
|
||||
current_time = int(time.time())
|
||||
|
||||
if not isinstance(data, bytes): raise TypeError("Token plaintext input must be bytes")
|
||||
iv = os.urandom(16)
|
||||
|
||||
ciphertext = self.mode.encrypt(
|
||||
plaintext = PKCS7.pad(data),
|
||||
|
@ -108,12 +123,31 @@ class Token():
|
|||
ciphertext = token[16:-32]
|
||||
|
||||
try:
|
||||
try:
|
||||
# RNS.log(f"Trying decryption with {self.mode}", RNS.LOG_DEBUG) # TODO: Remove
|
||||
plaintext = PKCS7.unpad(
|
||||
self.mode.decrypt(
|
||||
ciphertext = ciphertext,
|
||||
key = self._encryption_key,
|
||||
iv = iv))
|
||||
|
||||
# RNS.log(f"Decrypted packet with {self.mode}", RNS.LOG_DEBUG) # TODO: Remove
|
||||
return plaintext
|
||||
|
||||
except Exception as e: raise ValueError("Could not decrypt token")
|
||||
# TODO: Remove after migration ############################
|
||||
except Exception as e:
|
||||
# RNS.log(f"{self.mode} decryption failed", RNS.LOG_DEBUG) # TODO: Remove
|
||||
# RNS.log(f"Trying decryption with {self.mode_legacy}", RNS.LOG_DEBUG) # TODO: Remove
|
||||
plaintext = PKCS7.unpad(
|
||||
self.mode_legacy.decrypt(
|
||||
ciphertext = ciphertext,
|
||||
key = self._encryption_key_128,
|
||||
iv = iv))
|
||||
|
||||
# RNS.log(f"Decrypted packet with {self.mode_legacy}", RNS.LOG_DEBUG) # TODO: Remove
|
||||
return plaintext
|
||||
###########################################################
|
||||
|
||||
except Exception as e:
|
||||
RNS.trace_exception(e) # TODO: Remove after migration
|
||||
raise ValueError("Could not decrypt token")
|
|
@ -418,7 +418,8 @@ class Destination:
|
|||
else:
|
||||
plaintext = self.decrypt(packet.data)
|
||||
packet.ratchet_id = self.latest_ratchet_id
|
||||
if plaintext != None:
|
||||
if plaintext == None: return False
|
||||
else:
|
||||
if packet.packet_type == RNS.Packet.DATA:
|
||||
if self.callbacks.packet != None:
|
||||
try:
|
||||
|
@ -426,6 +427,8 @@ class Destination:
|
|||
except Exception as e:
|
||||
RNS.log("Error while executing receive callback from "+str(self)+". The contained exception was: "+str(e), RNS.LOG_ERROR)
|
||||
|
||||
return True
|
||||
|
||||
def incoming_link_request(self, data, packet):
|
||||
if self.accept_link_requests:
|
||||
link = RNS.Link.validate_request(self, data, packet)
|
||||
|
|
|
@ -544,6 +544,8 @@ class Identity:
|
|||
RNS.log("The contained exception was: "+str(e))
|
||||
|
||||
def __init__(self,create_keys=True):
|
||||
self.derived_key_length = 64
|
||||
|
||||
# Initialize keys to none
|
||||
self.prv = None
|
||||
self.prv_bytes = None
|
||||
|
@ -677,7 +679,7 @@ class Identity:
|
|||
shared_key = ephemeral_key.exchange(target_public_key)
|
||||
|
||||
derived_key = RNS.Cryptography.hkdf(
|
||||
length=32,
|
||||
length=self.derived_key_length,
|
||||
derive_from=shared_key,
|
||||
salt=self.get_salt(),
|
||||
context=self.get_context(),
|
||||
|
@ -715,7 +717,7 @@ class Identity:
|
|||
ratchet_id = Identity._get_ratchet_id(ratchet_prv.public_key().public_bytes())
|
||||
shared_key = ratchet_prv.exchange(peer_pub)
|
||||
derived_key = RNS.Cryptography.hkdf(
|
||||
length=32,
|
||||
length=self.derived_key_length,
|
||||
derive_from=shared_key,
|
||||
salt=self.get_salt(),
|
||||
context=self.get_context(),
|
||||
|
@ -740,7 +742,7 @@ class Identity:
|
|||
if plaintext == None:
|
||||
shared_key = self.prv.exchange(peer_pub)
|
||||
derived_key = RNS.Cryptography.hkdf(
|
||||
length=32,
|
||||
length=self.derived_key_length,
|
||||
derive_from=shared_key,
|
||||
salt=self.get_salt(),
|
||||
context=self.get_context(),
|
||||
|
|
|
@ -1879,8 +1879,7 @@ class Transport:
|
|||
for destination in Transport.destinations:
|
||||
if destination.hash == packet.destination_hash and destination.type == packet.destination_type:
|
||||
packet.destination = destination
|
||||
destination.receive(packet)
|
||||
|
||||
if destination.receive(packet):
|
||||
if destination.proof_strategy == RNS.Destination.PROVE_ALL:
|
||||
packet.prove()
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue