offer a wrong-password error message

This commit is contained in:
Brian Warner 2015-02-20 00:32:48 -08:00
parent 3171a4bb56
commit f5741f9a52
5 changed files with 60 additions and 12 deletions

View File

@ -1,7 +1,7 @@
from __future__ import print_function from __future__ import print_function
import sys, os, json import sys, os, json
from nacl.secret import SecretBox from nacl.secret import SecretBox
from wormhole.blocking.transcribe import Receiver from wormhole.blocking.transcribe import Receiver, WrongPasswordError
from wormhole.blocking.transit import TransitReceiver from wormhole.blocking.transit import TransitReceiver
APPID = "lothar.com/wormhole/file-xfer" APPID = "lothar.com/wormhole/file-xfer"
@ -18,7 +18,11 @@ mydata = json.dumps({
r = Receiver(APPID, mydata) r = Receiver(APPID, mydata)
r.set_code(r.input_code("Enter receive-file wormhole code: ")) r.set_code(r.input_code("Enter receive-file wormhole code: "))
data = json.loads(r.get_data().decode("utf-8")) try:
data = json.loads(r.get_data().decode("utf-8"))
except WrongPasswordError as e:
print("ERROR: " + e.explain(), file=sys.stderr)
sys.exit(1)
#print("their data: %r" % (data,)) #print("their data: %r" % (data,))
file_data = data["file"] file_data = data["file"]

View File

@ -1,6 +1,6 @@
from __future__ import print_function from __future__ import print_function
import time, json import sys, time, json
from wormhole.blocking.transcribe import Receiver from wormhole.blocking.transcribe import Receiver, WrongPasswordError
APPID = "lothar.com/wormhole/text-xfer" APPID = "lothar.com/wormhole/text-xfer"
@ -9,7 +9,11 @@ data = json.dumps({"message": "ok"}).encode("utf-8")
r = Receiver(APPID, data) r = Receiver(APPID, data)
r.set_code(r.input_code("Enter receive-text wormhole code: ")) r.set_code(r.input_code("Enter receive-text wormhole code: "))
start = time.time() start = time.time()
them_bytes = r.get_data() try:
them_bytes = r.get_data()
except WrongPasswordError as e:
print("ERROR: " + e.explain(), file=sys.stderr)
sys.exit(1)
them_d = json.loads(them_bytes.decode("utf-8")) them_d = json.loads(them_bytes.decode("utf-8"))
print(them_d["message"]) print(them_d["message"])
print("elapsed time: %.2f" % (time.time() - start)) print("elapsed time: %.2f" % (time.time() - start))

View File

@ -1,7 +1,7 @@
from __future__ import print_function from __future__ import print_function
import os, sys, json import os, sys, json
from nacl.secret import SecretBox from nacl.secret import SecretBox
from wormhole.blocking.transcribe import Initiator from wormhole.blocking.transcribe import Initiator, WrongPasswordError
from wormhole.blocking.transit import TransitSender from wormhole.blocking.transit import TransitSender
APPID = "lothar.com/wormhole/file-xfer" APPID = "lothar.com/wormhole/file-xfer"
@ -28,7 +28,11 @@ code = i.get_code()
print("On the other computer, please run: receive_file") print("On the other computer, please run: receive_file")
print("Wormhole code is '%s'" % code) print("Wormhole code is '%s'" % code)
print("") print("")
them_bytes = i.get_data() try:
them_bytes = i.get_data()
except WrongPasswordError as e:
print("ERROR: " + e.explain(), file=sys.stderr)
sys.exit(1)
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) xfer_key = i.derive_key(APPID+"/xfer-key", SecretBox.KEY_SIZE)

View File

@ -1,6 +1,6 @@
from __future__ import print_function from __future__ import print_function
import sys, json import sys, json
from wormhole.blocking.transcribe import Initiator from wormhole.blocking.transcribe import Initiator, WrongPasswordError
APPID = "lothar.com/wormhole/text-xfer" APPID = "lothar.com/wormhole/text-xfer"
@ -13,6 +13,10 @@ code = i.get_code()
print("On the other computer, please run: receive_text") print("On the other computer, please run: receive_text")
print("Wormhole code is: %s" % code) print("Wormhole code is: %s" % code)
print("") print("")
them_bytes = i.get_data() try:
them_bytes = i.get_data()
except WrongPasswordError as e:
print("ERROR: " + e.explain(), file=sys.stderr)
sys.exit(1)
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,))

View File

@ -1,7 +1,8 @@
import time, requests, json import time, requests, json, textwrap
from binascii import hexlify, unhexlify from binascii import hexlify, unhexlify
from spake2 import SPAKE2_A, SPAKE2_B from spake2 import SPAKE2_A, SPAKE2_B
from nacl.secret import SecretBox from nacl.secret import SecretBox
from nacl.exceptions import CryptoError
from nacl import utils from nacl import utils
from .. import codes from .. import codes
from ..util.hkdf import HKDF from ..util.hkdf import HKDF
@ -13,6 +14,29 @@ MINUTE = 60*SECOND
class Timeout(Exception): class Timeout(Exception):
pass pass
class WrongPasswordError(Exception):
"""
Key confirmation failed.
"""
# or the data blob was corrupted, and that's why decrypt failed
def explain(self):
return textwrap.dedent(self.__doc__)
class InitiatorWrongPasswordError(WrongPasswordError):
"""
Key confirmation failed. Either your correspondent typed the code wrong,
or a would-be man-in-the-middle attacker guessed incorrectly. You could
try again, giving both your correspondent and the attacker another
chance.
"""
class ReceiverWrongPasswordError(WrongPasswordError):
"""
Key confirmation failed. Either you typed the code wrong, or a would-be
man-in-the-middle attacker guessed incorrectly. You could try again,
giving both you and the attacker another chance.
"""
# POST /allocate -> {channel-id: INT} # POST /allocate -> {channel-id: INT}
# POST /CHANNEL-ID/SIDE/pake/post {message: STR} -> {messages: [STR..]} # POST /CHANNEL-ID/SIDE/pake/post {message: STR} -> {messages: [STR..]}
# POST /CHANNEL-ID/SIDE/pake/poll -> {messages: [STR..]} # POST /CHANNEL-ID/SIDE/pake/poll -> {messages: [STR..]}
@ -116,7 +140,11 @@ class Initiator(Common):
inbound_encrypted = self._poll_data(other_msgs) inbound_encrypted = self._poll_data(other_msgs)
inbound_key = self.derive_key(b"receiver") inbound_key = self.derive_key(b"receiver")
inbound_data = self._decrypt_data(inbound_key, inbound_encrypted) try:
inbound_data = self._decrypt_data(inbound_key,
inbound_encrypted)
except CryptoError:
raise InitiatorWrongPasswordError
finally: finally:
self._deallocate() self._deallocate()
return inbound_data return inbound_data
@ -169,7 +197,11 @@ class Receiver(Common):
inbound_encrypted = self._poll_data(other_msgs) inbound_encrypted = self._poll_data(other_msgs)
inbound_key = self.derive_key(b"sender") inbound_key = self.derive_key(b"sender")
inbound_data = self._decrypt_data(inbound_key, inbound_encrypted) try:
inbound_data = self._decrypt_data(inbound_key,
inbound_encrypted)
except CryptoError:
raise ReceiverWrongPasswordError
finally: finally:
self._deallocate() self._deallocate()
return inbound_data return inbound_data