diff --git a/src/wormhole/errors.py b/src/wormhole/errors.py index 08ebae7..2a271c6 100644 --- a/src/wormhole/errors.py +++ b/src/wormhole/errors.py @@ -36,6 +36,12 @@ class WrongPasswordError(Exception): # or the data blob was corrupted, and that's why decrypt failed pass +class KeyFormatError(Exception): + """ + The key you entered contains spaces. Magic-wormhole expects keys to be + separated by dashes. + """ + class ReflectionAttack(Exception): """An attacker (or bug) reflected our outgoing message back to us.""" diff --git a/src/wormhole/test/test_wormhole.py b/src/wormhole/test/test_wormhole.py index ba54123..eae68af 100644 --- a/src/wormhole/test/test_wormhole.py +++ b/src/wormhole/test/test_wormhole.py @@ -7,7 +7,8 @@ from twisted.internet import reactor from twisted.internet.defer import Deferred, gatherResults, inlineCallbacks from .common import ServerBase from .. import wormhole -from ..errors import WrongPasswordError, WelcomeError, UsageError +from ..errors import (WrongPasswordError, WelcomeError, UsageError, + KeyFormatError) from spake2 import SPAKE2_Symmetric from ..timing import DebugTiming from ..util import (bytes_to_dict, dict_to_bytes, @@ -818,6 +819,20 @@ class Wormholes(ServerBase, unittest.TestCase): yield w2.close() self.flushLoggedErrors(WrongPasswordError) + @inlineCallbacks + def test_wrong_password_with_spaces(self): + w1 = wormhole.wormhole(APPID, self.relayurl, reactor) + w2 = wormhole.wormhole(APPID, self.relayurl, reactor) + code = yield w1.get_code() + code_no_dashes = code.replace('-', ' ') + + with self.assertRaises(KeyFormatError): + w2.set_code(code_no_dashes) + + yield w1.close() + yield w2.close() + self.flushLoggedErrors(ValueError) + @inlineCallbacks def test_verifier(self): w1 = wormhole.wormhole(APPID, self.relayurl, reactor) @@ -875,4 +890,3 @@ class Errors(ServerBase, unittest.TestCase): yield self.assertFailure(w.get_code(), UsageError) yield self.assertFailure(w.input_code(), UsageError) yield w.close() -