mirror of
https://github.com/markqvist/Reticulum.git
synced 2024-12-25 07:29:35 -05:00
Separate Ed25519 signature keys on links
This commit is contained in:
parent
11fe8b64f8
commit
94813d95b1
51
RNS/Link.py
51
RNS/Link.py
@ -30,14 +30,15 @@ class Link:
|
||||
|
||||
:param destination: A :ref:`RNS.Destination<api-destination>` instance which to establish a link to.
|
||||
:param owner: Internal use by :ref:`RNS.Transport<api-Transport>`, ignore this argument.
|
||||
:param peer_pub_bytes: Internal use by :ref:`RNS.Transport<api-Transport>`, ignore this argument.
|
||||
:param peer_pub_bytes: Internal use, ignore this argument.
|
||||
:param peer_sig_pub_bytes: Internal use, ignore this argument.
|
||||
"""
|
||||
CURVE = "Curve25519"
|
||||
"""
|
||||
The curve used for Elliptic Curve DH key exchanges
|
||||
"""
|
||||
|
||||
ECPUBSIZE = 32
|
||||
ECPUBSIZE = 32+32
|
||||
BLOCKSIZE = 16
|
||||
KEYSIZE = 32
|
||||
|
||||
@ -77,7 +78,7 @@ class Link:
|
||||
def validate_request(owner, data, packet):
|
||||
if len(data) == (Link.ECPUBSIZE):
|
||||
try:
|
||||
link = Link(owner = owner, peer_pub_bytes = data[:Link.ECPUBSIZE])
|
||||
link = Link(owner = owner, peer_pub_bytes=data[:Link.ECPUBSIZE//2], peer_sig_pub_bytes=data[Link.ECPUBSIZE//2:Link.ECPUBSIZE])
|
||||
link.set_link_id(packet)
|
||||
link.destination = packet.destination
|
||||
RNS.log("Validating link request "+RNS.prettyhexrep(link.link_id), RNS.LOG_VERBOSE)
|
||||
@ -107,7 +108,7 @@ class Link:
|
||||
return None
|
||||
|
||||
|
||||
def __init__(self, destination=None, owner=None, peer_pub_bytes = None):
|
||||
def __init__(self, destination=None, owner=None, peer_pub_bytes = None, peer_sig_pub_bytes = None):
|
||||
if destination != None and destination.type != RNS.Destination.SINGLE:
|
||||
raise TypeError("Links can only be established to the \"single\" destination type")
|
||||
self.rtt = None
|
||||
@ -140,28 +141,28 @@ class Link:
|
||||
self.fernet = None
|
||||
|
||||
self.prv = X25519PrivateKey.generate()
|
||||
self.sig_prv = Ed25519PrivateKey.from_private_bytes(
|
||||
self.prv.private_bytes(
|
||||
encoding=serialization.Encoding.Raw,
|
||||
format=serialization.PrivateFormat.Raw,
|
||||
encryption_algorithm=serialization.NoEncryption()
|
||||
)
|
||||
)
|
||||
|
||||
self.sig_prv = Ed25519PrivateKey.generate()
|
||||
|
||||
self.pub = self.prv.public_key()
|
||||
self.pub_bytes = self.pub.public_bytes(
|
||||
encoding=serialization.Encoding.Raw,
|
||||
format=serialization.PublicFormat.Raw
|
||||
)
|
||||
|
||||
self.sig_pub = self.sig_prv.public_key()
|
||||
self.sig_pub_bytes = self.sig_pub.public_bytes(
|
||||
encoding=serialization.Encoding.Raw,
|
||||
format=serialization.PublicFormat.Raw
|
||||
)
|
||||
|
||||
if peer_pub_bytes == None:
|
||||
self.peer_pub = None
|
||||
self.peer_pub_bytes = None
|
||||
else:
|
||||
self.load_peer(peer_pub_bytes)
|
||||
self.load_peer(peer_pub_bytes, peer_sig_pub_bytes)
|
||||
|
||||
if (self.initiator):
|
||||
self.request_data = self.pub_bytes
|
||||
self.request_data = self.pub_bytes+self.sig_pub_bytes
|
||||
self.packet = RNS.Packet(destination, self.request_data, packet_type=RNS.Packet.LINKREQUEST)
|
||||
self.packet.pack()
|
||||
self.set_link_id(self.packet)
|
||||
@ -173,11 +174,11 @@ class Link:
|
||||
RNS.log("Link request "+RNS.prettyhexrep(self.link_id)+" sent to "+str(self.destination), RNS.LOG_VERBOSE)
|
||||
|
||||
|
||||
def load_peer(self, peer_pub_bytes):
|
||||
def load_peer(self, peer_pub_bytes, peer_sig_pub_bytes):
|
||||
self.peer_pub_bytes = peer_pub_bytes
|
||||
self.peer_pub = X25519PublicKey.from_public_bytes(self.peer_pub_bytes)
|
||||
|
||||
self.peer_sig_pub_bytes = peer_pub_bytes
|
||||
self.peer_sig_pub_bytes = peer_sig_pub_bytes
|
||||
self.peer_sig_pub = Ed25519PublicKey.from_public_bytes(self.peer_sig_pub_bytes)
|
||||
|
||||
if not hasattr(self.peer_pub, "curve"):
|
||||
@ -198,10 +199,10 @@ class Link:
|
||||
).derive(self.shared_key)
|
||||
|
||||
def prove(self):
|
||||
signed_data = self.link_id+self.pub_bytes
|
||||
signed_data = self.link_id+self.pub_bytes+self.sig_pub_bytes
|
||||
signature = self.owner.identity.sign(signed_data)
|
||||
|
||||
proof_data = self.pub_bytes+signature
|
||||
proof_data = self.pub_bytes+self.sig_pub_bytes+signature
|
||||
proof = RNS.Packet(self, proof_data, packet_type=RNS.Packet.PROOF, context=RNS.Packet.LRPROOF)
|
||||
proof.send()
|
||||
self.had_outbound()
|
||||
@ -220,13 +221,14 @@ class Link:
|
||||
self.had_outbound()
|
||||
|
||||
def validate_proof(self, packet):
|
||||
if self.initiator:
|
||||
peer_pub_bytes = packet.data[:Link.ECPUBSIZE]
|
||||
signed_data = self.link_id+peer_pub_bytes
|
||||
if self.initiator and len(packet.data) == Link.ECPUBSIZE+RNS.Identity.KEYSIZE//8:
|
||||
peer_pub_bytes = packet.data[:Link.ECPUBSIZE//2]
|
||||
peer_sig_pub_bytes = packet.data[Link.ECPUBSIZE//2:Link.ECPUBSIZE]
|
||||
signed_data = self.link_id+peer_pub_bytes+peer_sig_pub_bytes
|
||||
signature = packet.data[Link.ECPUBSIZE:RNS.Identity.KEYSIZE//8+Link.ECPUBSIZE]
|
||||
|
||||
if self.destination.identity.validate(signature, signed_data):
|
||||
self.load_peer(peer_pub_bytes)
|
||||
self.load_peer(peer_pub_bytes, peer_sig_pub_bytes)
|
||||
self.handshake()
|
||||
self.rtt = time.time() - self.request_time
|
||||
self.attached_interface = packet.receiving_interface
|
||||
@ -244,10 +246,7 @@ class Link:
|
||||
thread.setDaemon(True)
|
||||
thread.start()
|
||||
else:
|
||||
RNS.log("Invalid link proof signature received by "+str(self), RNS.LOG_VERBOSE)
|
||||
# TODO: should we really do this, or just wait
|
||||
# for a valid one? Needs analysis.
|
||||
self.teardown()
|
||||
RNS.log("Invalid link proof signature received by "+str(self)+". Ignoring.", RNS.LOG_DEBUG)
|
||||
|
||||
|
||||
def rtt_packet(self, packet):
|
||||
|
Loading…
Reference in New Issue
Block a user