add derive_key(), use it for file-xfer bulk-encryption key

This commit is contained in:
Brian Warner 2015-02-19 17:16:43 -08:00
parent 40e78ca839
commit 12845f191b
3 changed files with 12 additions and 8 deletions

View File

@ -1,6 +1,5 @@
from __future__ import print_function from __future__ import print_function
import sys, os, json import sys, os, json
from binascii import unhexlify
from nacl.secret import SecretBox from nacl.secret import SecretBox
from wormhole.blocking.transcribe import Receiver from wormhole.blocking.transcribe import Receiver
from wormhole.blocking.transit import TransitReceiver from wormhole.blocking.transit import TransitReceiver
@ -23,7 +22,7 @@ data = json.loads(r.get_data().decode("utf-8"))
#print("their data: %r" % (data,)) #print("their data: %r" % (data,))
file_data = data["file"] 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 filename = os.path.basename(file_data["filename"]) # unicode
filesize = file_data["filesize"] filesize = file_data["filesize"]
encrypted_filesize = filesize + SecretBox.NONCE_SIZE+16 encrypted_filesize = filesize + SecretBox.NONCE_SIZE+16

View File

@ -10,7 +10,6 @@ APPID = "lothar.com/wormhole/file-xfer"
# we're sending # we're sending
filename = sys.argv[1] filename = sys.argv[1]
assert os.path.isfile(filename) assert os.path.isfile(filename)
xfer_key = os.urandom(SecretBox.KEY_SIZE)
transit_sender = TransitSender() transit_sender = TransitSender()
transit_key = transit_sender.get_transit_key() transit_key = transit_sender.get_transit_key()
direct_hints = transit_sender.get_direct_hints() direct_hints = transit_sender.get_direct_hints()
@ -19,7 +18,6 @@ relay_hints = transit_sender.get_relay_hints()
filesize = os.stat(filename).st_size filesize = os.stat(filename).st_size
data = json.dumps({ data = json.dumps({
"file": { "file": {
"key": hexlify(xfer_key),
"filename": os.path.basename(filename), "filename": os.path.basename(filename),
"filesize": filesize, "filesize": filesize,
}, },
@ -38,6 +36,7 @@ print("")
them_bytes = i.get_data() them_bytes = i.get_data()
them_d = json.loads(them_bytes.decode("utf-8")) them_d = json.loads(them_bytes.decode("utf-8"))
#print("them: %r" % (them_d,)) #print("them: %r" % (them_d,))
xfer_key = i.derive_key(APPID+"/xfer-key", SecretBox.KEY_SIZE)
box = SecretBox(xfer_key) box = SecretBox(xfer_key)
with open(filename, "rb") as f: with open(filename, "rb") as f:

View File

@ -82,6 +82,10 @@ class Common:
r = requests.post(self.url("deallocate")) r = requests.post(self.url("deallocate"))
r.raise_for_status() 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): class Initiator(Common):
def __init__(self, appid, data, relay=RELAY): def __init__(self, appid, data, relay=RELAY):
self.appid = appid self.appid = appid
@ -104,13 +108,14 @@ class Initiator(Common):
def get_data(self): def get_data(self):
key = self._poll_pake([]) key = self._poll_pake([])
self.key = key
try: 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) outbound_encrypted = self._encrypt_data(outbound_key, self.data)
other_msgs = self._post_data(outbound_encrypted) other_msgs = self._post_data(outbound_encrypted)
inbound_encrypted = self._poll_data(other_msgs) 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) inbound_data = self._decrypt_data(inbound_key, inbound_encrypted)
finally: finally:
self._deallocate() self._deallocate()
@ -155,14 +160,15 @@ class Receiver(Common):
assert self.channel_id is not None assert self.channel_id is not None
other_msgs = self._post_pake() other_msgs = self._post_pake()
key = self._poll_pake(other_msgs) key = self._poll_pake(other_msgs)
self.key = key
try: 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) outbound_encrypted = self._encrypt_data(outbound_key, self.data)
other_msgs = self._post_data(outbound_encrypted) other_msgs = self._post_data(outbound_encrypted)
inbound_encrypted = self._poll_data(other_msgs) 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) inbound_data = self._decrypt_data(inbound_key, inbound_encrypted)
finally: finally:
self._deallocate() self._deallocate()