Add --verify (display/check key-verifier). Not entirely usable yet.
To be useful, both sides must add -v. If the sender uses -v but the receiver doesn't, the receiver won't show the verification string, so the sender can't compare it to anything (and must either abort the transfer or accept it blindly). Maybe the receiver should show the verification string unconditionally. Maybe the sender should indicate (in unprotected plaintext, along with the PAKE message) whether the receiver should show it or not.
This commit is contained in:
parent
ed1809d521
commit
fae14ebe6a
|
@ -175,6 +175,8 @@ class Initiator(Common):
|
|||
self.wait = 0.5*SECOND
|
||||
self.timeout = 3*MINUTE
|
||||
self.side = "initiator"
|
||||
self.key = None
|
||||
self.verifier = None
|
||||
|
||||
def get_code(self, code_length=2):
|
||||
self.channel_id = self._allocate() # allocate channel
|
||||
|
@ -185,9 +187,18 @@ class Initiator(Common):
|
|||
self._post_pake()
|
||||
return self.code
|
||||
|
||||
def _wait_for_key(self):
|
||||
if not self.key:
|
||||
key = self._get_pake([])
|
||||
self.key = key
|
||||
self.verifier = self.derive_key(self.appid+b":Verifier")
|
||||
|
||||
def get_verifier(self):
|
||||
self._wait_for_key()
|
||||
return self.verifier
|
||||
|
||||
def get_data(self, outbound_data):
|
||||
key = self._get_pake([])
|
||||
self.key = key
|
||||
self._wait_for_key()
|
||||
try:
|
||||
outbound_key = self.derive_key(b"sender")
|
||||
outbound_encrypted = self._encrypt_data(outbound_key, outbound_data)
|
||||
|
@ -216,6 +227,8 @@ class Receiver(Common):
|
|||
self.side = "receiver"
|
||||
self.code = None
|
||||
self.channel_id = None
|
||||
self.key = None
|
||||
self.verifier = None
|
||||
|
||||
def list_channels(self):
|
||||
r = requests.get(self.relay + "list")
|
||||
|
@ -237,12 +250,21 @@ class Receiver(Common):
|
|||
idA=self.appid+":Initiator",
|
||||
idB=self.appid+":Receiver")
|
||||
|
||||
def _wait_for_key(self):
|
||||
if not self.key:
|
||||
other_msgs = self._post_pake()
|
||||
key = self._get_pake(other_msgs)
|
||||
self.key = key
|
||||
self.verifier = self.derive_key(self.appid+b":Verifier")
|
||||
|
||||
def get_verifier(self):
|
||||
self._wait_for_key()
|
||||
return self.verifier
|
||||
|
||||
def get_data(self, outbound_data):
|
||||
assert self.code is not None
|
||||
assert self.channel_id is not None
|
||||
other_msgs = self._post_pake()
|
||||
key = self._get_pake(other_msgs)
|
||||
self.key = key
|
||||
self._wait_for_key()
|
||||
|
||||
try:
|
||||
outbound_key = self.derive_key(b"receiver")
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
from __future__ import print_function
|
||||
import sys, os, json
|
||||
import sys, os, json, binascii
|
||||
from wormhole.blocking.transcribe import Receiver, WrongPasswordError
|
||||
from wormhole.blocking.transit import TransitReceiver, TransitError
|
||||
from .progress import start_progress, update_progress, finish_progress
|
||||
|
@ -17,6 +17,10 @@ def receive_file(args):
|
|||
args.code_length)
|
||||
r.set_code(code)
|
||||
|
||||
if args.verify:
|
||||
verifier = binascii.hexlify(r.get_verifier())
|
||||
print("Verifier %s." % verifier)
|
||||
|
||||
mydata = json.dumps({
|
||||
"transit": {
|
||||
"direct_connection_hints": transit_receiver.get_direct_hints(),
|
||||
|
@ -30,6 +34,10 @@ def receive_file(args):
|
|||
return 1
|
||||
#print("their data: %r" % (data,))
|
||||
|
||||
if "error" in data:
|
||||
print("ERROR: " + data["error"], file=sys.stderr)
|
||||
return 1
|
||||
|
||||
file_data = data["file"]
|
||||
filename = os.path.basename(file_data["filename"]) # unicode
|
||||
filesize = file_data["filesize"]
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
from __future__ import print_function
|
||||
import sys, json
|
||||
import sys, json, binascii
|
||||
from wormhole.blocking.transcribe import Receiver, WrongPasswordError
|
||||
|
||||
APPID = "lothar.com/wormhole/text-xfer"
|
||||
|
@ -12,6 +12,11 @@ def receive_text(args):
|
|||
code = r.input_code("Enter receive-text wormhole code: ",
|
||||
args.code_length)
|
||||
r.set_code(code)
|
||||
|
||||
if args.verify:
|
||||
verifier = binascii.hexlify(r.get_verifier())
|
||||
print("Verifier %s." % verifier)
|
||||
|
||||
data = json.dumps({"message": "ok"}).encode("utf-8")
|
||||
try:
|
||||
them_bytes = r.get_data(data)
|
||||
|
@ -19,4 +24,7 @@ def receive_text(args):
|
|||
print("ERROR: " + e.explain(), file=sys.stderr)
|
||||
return 1
|
||||
them_d = json.loads(them_bytes.decode("utf-8"))
|
||||
if "error" in them_d:
|
||||
print("ERROR: " + them_d["error"], file=sys.stderr)
|
||||
return 1
|
||||
print(them_d["message"])
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
from __future__ import print_function
|
||||
import os, sys, json
|
||||
import os, sys, json, binascii
|
||||
from wormhole.blocking.transcribe import Initiator, WrongPasswordError
|
||||
from wormhole.blocking.transit import TransitSender
|
||||
from .progress import start_progress, update_progress, finish_progress
|
||||
|
@ -18,6 +18,20 @@ def send_file(args):
|
|||
print("Wormhole code is '%s'" % code)
|
||||
print()
|
||||
|
||||
if args.verify:
|
||||
verifier = binascii.hexlify(i.get_verifier())
|
||||
while True:
|
||||
ok = raw_input("Verifier %s. ok? (yes/no): " % verifier)
|
||||
if ok.lower() == "yes":
|
||||
break
|
||||
if ok.lower() == "no":
|
||||
print("verification rejected, abandoning transfer",
|
||||
file=sys.stderr)
|
||||
reject_data = json.dumps({"error": "verification rejected",
|
||||
}).encode("utf-8")
|
||||
i.get_data(reject_data)
|
||||
return 1
|
||||
|
||||
filesize = os.stat(filename).st_size
|
||||
data = json.dumps({
|
||||
"file": {
|
||||
|
|
|
@ -1,19 +1,34 @@
|
|||
from __future__ import print_function
|
||||
import sys, json
|
||||
import sys, json, binascii
|
||||
from wormhole.blocking.transcribe import Initiator, WrongPasswordError
|
||||
|
||||
APPID = "lothar.com/wormhole/text-xfer"
|
||||
|
||||
def send_text(args):
|
||||
# we're sending
|
||||
message = args.text
|
||||
data = json.dumps({"message": message,
|
||||
}).encode("utf-8")
|
||||
i = Initiator(APPID, args.relay_url)
|
||||
code = i.get_code(args.code_length)
|
||||
print("On the other computer, please run: wormhole receive-text")
|
||||
print("Wormhole code is: %s" % code)
|
||||
print("")
|
||||
|
||||
if args.verify:
|
||||
verifier = binascii.hexlify(i.get_verifier())
|
||||
while True:
|
||||
ok = raw_input("Verifier %s. ok? (yes/no): " % verifier)
|
||||
if ok.lower() == "yes":
|
||||
break
|
||||
if ok.lower() == "no":
|
||||
print("verification rejected, abandoning transfer",
|
||||
file=sys.stderr)
|
||||
reject_data = json.dumps({"error": "verification rejected",
|
||||
}).encode("utf-8")
|
||||
i.get_data(reject_data)
|
||||
return 1
|
||||
|
||||
message = args.text
|
||||
data = json.dumps({"message": message,
|
||||
}).encode("utf-8")
|
||||
try:
|
||||
them_bytes = i.get_data(data)
|
||||
except WrongPasswordError as e:
|
||||
|
|
|
@ -20,6 +20,8 @@ g.add_argument("--transit-helper", default=public_relay.TRANSIT_RELAY,
|
|||
metavar="tcp:HOST:PORT", help="transit relay to use")
|
||||
g.add_argument("-c", "--code-length", type=int, default=2,
|
||||
metavar="WORDS", help="length of code (in bytes/words)")
|
||||
g.add_argument("-v", "--verify", action="store_true",
|
||||
help="display (and wait for acceptance of) verification string")
|
||||
subparsers = parser.add_subparsers(title="subcommands",
|
||||
dest="subcommand")
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user