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.wait = 0.5*SECOND
|
||||||
self.timeout = 3*MINUTE
|
self.timeout = 3*MINUTE
|
||||||
self.side = "initiator"
|
self.side = "initiator"
|
||||||
|
self.key = None
|
||||||
|
self.verifier = None
|
||||||
|
|
||||||
def get_code(self, code_length=2):
|
def get_code(self, code_length=2):
|
||||||
self.channel_id = self._allocate() # allocate channel
|
self.channel_id = self._allocate() # allocate channel
|
||||||
|
@ -185,9 +187,18 @@ class Initiator(Common):
|
||||||
self._post_pake()
|
self._post_pake()
|
||||||
return self.code
|
return self.code
|
||||||
|
|
||||||
def get_data(self, outbound_data):
|
def _wait_for_key(self):
|
||||||
|
if not self.key:
|
||||||
key = self._get_pake([])
|
key = self._get_pake([])
|
||||||
self.key = key
|
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):
|
||||||
|
self._wait_for_key()
|
||||||
try:
|
try:
|
||||||
outbound_key = self.derive_key(b"sender")
|
outbound_key = self.derive_key(b"sender")
|
||||||
outbound_encrypted = self._encrypt_data(outbound_key, outbound_data)
|
outbound_encrypted = self._encrypt_data(outbound_key, outbound_data)
|
||||||
|
@ -216,6 +227,8 @@ class Receiver(Common):
|
||||||
self.side = "receiver"
|
self.side = "receiver"
|
||||||
self.code = None
|
self.code = None
|
||||||
self.channel_id = None
|
self.channel_id = None
|
||||||
|
self.key = None
|
||||||
|
self.verifier = None
|
||||||
|
|
||||||
def list_channels(self):
|
def list_channels(self):
|
||||||
r = requests.get(self.relay + "list")
|
r = requests.get(self.relay + "list")
|
||||||
|
@ -237,12 +250,21 @@ class Receiver(Common):
|
||||||
idA=self.appid+":Initiator",
|
idA=self.appid+":Initiator",
|
||||||
idB=self.appid+":Receiver")
|
idB=self.appid+":Receiver")
|
||||||
|
|
||||||
def get_data(self, outbound_data):
|
def _wait_for_key(self):
|
||||||
assert self.code is not None
|
if not self.key:
|
||||||
assert self.channel_id is not None
|
|
||||||
other_msgs = self._post_pake()
|
other_msgs = self._post_pake()
|
||||||
key = self._get_pake(other_msgs)
|
key = self._get_pake(other_msgs)
|
||||||
self.key = key
|
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
|
||||||
|
self._wait_for_key()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
outbound_key = self.derive_key(b"receiver")
|
outbound_key = self.derive_key(b"receiver")
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
import sys, os, json
|
import sys, os, json, binascii
|
||||||
from wormhole.blocking.transcribe import Receiver, WrongPasswordError
|
from wormhole.blocking.transcribe import Receiver, WrongPasswordError
|
||||||
from wormhole.blocking.transit import TransitReceiver, TransitError
|
from wormhole.blocking.transit import TransitReceiver, TransitError
|
||||||
from .progress import start_progress, update_progress, finish_progress
|
from .progress import start_progress, update_progress, finish_progress
|
||||||
|
@ -17,6 +17,10 @@ def receive_file(args):
|
||||||
args.code_length)
|
args.code_length)
|
||||||
r.set_code(code)
|
r.set_code(code)
|
||||||
|
|
||||||
|
if args.verify:
|
||||||
|
verifier = binascii.hexlify(r.get_verifier())
|
||||||
|
print("Verifier %s." % verifier)
|
||||||
|
|
||||||
mydata = json.dumps({
|
mydata = json.dumps({
|
||||||
"transit": {
|
"transit": {
|
||||||
"direct_connection_hints": transit_receiver.get_direct_hints(),
|
"direct_connection_hints": transit_receiver.get_direct_hints(),
|
||||||
|
@ -30,6 +34,10 @@ def receive_file(args):
|
||||||
return 1
|
return 1
|
||||||
#print("their data: %r" % (data,))
|
#print("their data: %r" % (data,))
|
||||||
|
|
||||||
|
if "error" in data:
|
||||||
|
print("ERROR: " + data["error"], file=sys.stderr)
|
||||||
|
return 1
|
||||||
|
|
||||||
file_data = data["file"]
|
file_data = data["file"]
|
||||||
filename = os.path.basename(file_data["filename"]) # unicode
|
filename = os.path.basename(file_data["filename"]) # unicode
|
||||||
filesize = file_data["filesize"]
|
filesize = file_data["filesize"]
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
import sys, json
|
import sys, json, binascii
|
||||||
from wormhole.blocking.transcribe import Receiver, WrongPasswordError
|
from wormhole.blocking.transcribe import Receiver, WrongPasswordError
|
||||||
|
|
||||||
APPID = "lothar.com/wormhole/text-xfer"
|
APPID = "lothar.com/wormhole/text-xfer"
|
||||||
|
@ -12,6 +12,11 @@ def receive_text(args):
|
||||||
code = r.input_code("Enter receive-text wormhole code: ",
|
code = r.input_code("Enter receive-text wormhole code: ",
|
||||||
args.code_length)
|
args.code_length)
|
||||||
r.set_code(code)
|
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")
|
data = json.dumps({"message": "ok"}).encode("utf-8")
|
||||||
try:
|
try:
|
||||||
them_bytes = r.get_data(data)
|
them_bytes = r.get_data(data)
|
||||||
|
@ -19,4 +24,7 @@ def receive_text(args):
|
||||||
print("ERROR: " + e.explain(), file=sys.stderr)
|
print("ERROR: " + e.explain(), file=sys.stderr)
|
||||||
return 1
|
return 1
|
||||||
them_d = json.loads(them_bytes.decode("utf-8"))
|
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"])
|
print(them_d["message"])
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
import os, sys, json
|
import os, sys, json, binascii
|
||||||
from wormhole.blocking.transcribe import Initiator, WrongPasswordError
|
from wormhole.blocking.transcribe import Initiator, WrongPasswordError
|
||||||
from wormhole.blocking.transit import TransitSender
|
from wormhole.blocking.transit import TransitSender
|
||||||
from .progress import start_progress, update_progress, finish_progress
|
from .progress import start_progress, update_progress, finish_progress
|
||||||
|
@ -18,6 +18,20 @@ def send_file(args):
|
||||||
print("Wormhole code is '%s'" % code)
|
print("Wormhole code is '%s'" % code)
|
||||||
print()
|
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
|
filesize = os.stat(filename).st_size
|
||||||
data = json.dumps({
|
data = json.dumps({
|
||||||
"file": {
|
"file": {
|
||||||
|
|
|
@ -1,19 +1,34 @@
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
import sys, json
|
import sys, json, binascii
|
||||||
from wormhole.blocking.transcribe import Initiator, WrongPasswordError
|
from wormhole.blocking.transcribe import Initiator, WrongPasswordError
|
||||||
|
|
||||||
APPID = "lothar.com/wormhole/text-xfer"
|
APPID = "lothar.com/wormhole/text-xfer"
|
||||||
|
|
||||||
def send_text(args):
|
def send_text(args):
|
||||||
# we're sending
|
# we're sending
|
||||||
message = args.text
|
|
||||||
data = json.dumps({"message": message,
|
|
||||||
}).encode("utf-8")
|
|
||||||
i = Initiator(APPID, args.relay_url)
|
i = Initiator(APPID, args.relay_url)
|
||||||
code = i.get_code(args.code_length)
|
code = i.get_code(args.code_length)
|
||||||
print("On the other computer, please run: wormhole receive-text")
|
print("On the other computer, please run: wormhole receive-text")
|
||||||
print("Wormhole code is: %s" % code)
|
print("Wormhole code is: %s" % code)
|
||||||
print("")
|
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:
|
try:
|
||||||
them_bytes = i.get_data(data)
|
them_bytes = i.get_data(data)
|
||||||
except WrongPasswordError as e:
|
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")
|
metavar="tcp:HOST:PORT", help="transit relay to use")
|
||||||
g.add_argument("-c", "--code-length", type=int, default=2,
|
g.add_argument("-c", "--code-length", type=int, default=2,
|
||||||
metavar="WORDS", help="length of code (in bytes/words)")
|
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",
|
subparsers = parser.add_subparsers(title="subcommands",
|
||||||
dest="subcommand")
|
dest="subcommand")
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user