diff --git a/bin/receive_file.py b/bin/receive_file.py index 466f66d..b5256fe 100644 --- a/bin/receive_file.py +++ b/bin/receive_file.py @@ -1,6 +1,5 @@ from __future__ import print_function import sys, os, json -from binascii import unhexlify from nacl.secret import SecretBox from wormhole.blocking.transcribe import Receiver from wormhole.blocking.transit import TransitReceiver @@ -23,7 +22,7 @@ data = json.loads(r.get_data().decode("utf-8")) #print("their data: %r" % (data,)) file_data = data["file"] -xfer_key = unhexlify(file_data["key"].encode("ascii")) +xfer_key = r.derive_key(APPID+"/xfer-key", SecretBox.KEY_SIZE) filename = os.path.basename(file_data["filename"]) # unicode filesize = file_data["filesize"] encrypted_filesize = filesize + SecretBox.NONCE_SIZE+16 diff --git a/bin/send_file.py b/bin/send_file.py index a98132d..2e15f52 100644 --- a/bin/send_file.py +++ b/bin/send_file.py @@ -10,7 +10,6 @@ APPID = "lothar.com/wormhole/file-xfer" # we're sending filename = sys.argv[1] assert os.path.isfile(filename) -xfer_key = os.urandom(SecretBox.KEY_SIZE) transit_sender = TransitSender() transit_key = transit_sender.get_transit_key() direct_hints = transit_sender.get_direct_hints() @@ -19,7 +18,6 @@ relay_hints = transit_sender.get_relay_hints() filesize = os.stat(filename).st_size data = json.dumps({ "file": { - "key": hexlify(xfer_key), "filename": os.path.basename(filename), "filesize": filesize, }, @@ -38,6 +36,7 @@ print("") them_bytes = i.get_data() them_d = json.loads(them_bytes.decode("utf-8")) #print("them: %r" % (them_d,)) +xfer_key = i.derive_key(APPID+"/xfer-key", SecretBox.KEY_SIZE) box = SecretBox(xfer_key) with open(filename, "rb") as f: diff --git a/src/wormhole/blocking/transcribe.py b/src/wormhole/blocking/transcribe.py index aa019a3..20efdba 100644 --- a/src/wormhole/blocking/transcribe.py +++ b/src/wormhole/blocking/transcribe.py @@ -82,6 +82,10 @@ class Common: r = requests.post(self.url("deallocate")) r.raise_for_status() + def derive_key(self, purpose, length=SecretBox.KEY_SIZE): + assert type(purpose) == type(b"") + return HKDF(self.key, length, CTXinfo=purpose) + class Initiator(Common): def __init__(self, appid, data, relay=RELAY): self.appid = appid @@ -104,13 +108,14 @@ class Initiator(Common): def get_data(self): key = self._poll_pake([]) + self.key = key try: - outbound_key = HKDF(key, SecretBox.KEY_SIZE, CTXinfo=b"sender") + outbound_key = self.derive_key(b"sender") outbound_encrypted = self._encrypt_data(outbound_key, self.data) other_msgs = self._post_data(outbound_encrypted) inbound_encrypted = self._poll_data(other_msgs) - inbound_key = HKDF(key, SecretBox.KEY_SIZE, CTXinfo=b"receiver") + inbound_key = self.derive_key(b"receiver") inbound_data = self._decrypt_data(inbound_key, inbound_encrypted) finally: self._deallocate() @@ -155,14 +160,15 @@ class Receiver(Common): assert self.channel_id is not None other_msgs = self._post_pake() key = self._poll_pake(other_msgs) + self.key = key try: - outbound_key = HKDF(key, SecretBox.KEY_SIZE, CTXinfo=b"receiver") + outbound_key = self.derive_key(b"receiver") outbound_encrypted = self._encrypt_data(outbound_key, self.data) other_msgs = self._post_data(outbound_encrypted) inbound_encrypted = self._poll_data(other_msgs) - inbound_key = HKDF(key, SecretBox.KEY_SIZE, CTXinfo=b"sender") + inbound_key = self.derive_key(b"sender") inbound_data = self._decrypt_data(inbound_key, inbound_encrypted) finally: self._deallocate()