tests: exercise Key receiving PAKE before set_code

This commit is contained in:
Brian Warner 2017-04-06 10:44:04 -07:00
parent 0da9cbdeeb
commit df1b2338b1
4 changed files with 61 additions and 2 deletions

View File

@ -69,6 +69,7 @@ class Key(object):
def __attrs_post_init__(self):
self._SK = _SortedKey(self._appid, self._versions, self._side,
self._timing)
self._debug_pake_stashed = False # for tests
def wire(self, boss, mailbox, receive):
self._SK.wire(boss, mailbox, receive)
@ -90,6 +91,7 @@ class Key(object):
@m.output()
def stash_pake(self, body):
self._pake = body
self._debug_pake_stashed = True
@m.output()
def deliver_code(self, code):
self._SK.got_code(code)

View File

@ -1,6 +1,6 @@
# no unicode_literals untill twisted update
from twisted.application import service
from twisted.internet import defer, task
from twisted.internet import defer, task, reactor
from twisted.python import log
from click.testing import CliRunner
import mock
@ -84,3 +84,10 @@ def config(*argv):
cfg = go.call_args[0][1]
return cfg
@defer.inlineCallbacks
def poll_until(predicate):
# return a Deferred that won't fire until the predicate is True
while not predicate():
d = defer.Deferred()
reactor.callLater(0.001, d.callback, None)
yield d

View File

@ -257,6 +257,34 @@ class Key(unittest.TestCase):
k.got_pake(dict_to_bytes(bad_pake_d))
self.assertEqual(events, [("b.scared",)])
def test_reversed(self):
# A receiver using input_code() will choose the nameplate first, then
# the rest of the code. Once the nameplate is selected, we'll claim
# it and open the mailbox, which will cause the senders PAKE to
# arrive before the code has been set. Key() is supposed to stash the
# PAKE message until the code is set (allowing the PAKE computation
# to finish). This test exercises that PAKE-then-code sequence.
k, b, m, r, events = self.build()
code = u"1-foo"
sp = SPAKE2_Symmetric(to_bytes(code), idSymmetric=to_bytes(u"appid"))
msg2_bytes = sp.start()
msg2 = dict_to_bytes({"pake_v1": bytes_to_hexstr(msg2_bytes)})
k.got_pake(msg2)
self.assertEqual(len(events), 0)
k.got_code(code)
self.assertEqual(len(events), 5)
self.assertEqual(events[0][:2], ("m.add_message", "pake"))
msg1_json = events[0][2].decode("utf-8")
msg1 = json.loads(msg1_json)
msg1_bytes = hexstr_to_bytes(msg1["pake_v1"])
key2 = sp.finish(msg1_bytes)
self.assertEqual(events[1], ("b.got_key", key2))
self.assertEqual(events[2][0], "b.got_verifier")
self.assertEqual(events[3][:2], ("m.add_message", "version"))
self.assertEqual(events[4], ("r.got_key", key2))
class Code(unittest.TestCase):
def build(self):
events = []

View File

@ -4,7 +4,7 @@ import mock
from twisted.trial import unittest
from twisted.internet import reactor
from twisted.internet.defer import gatherResults, inlineCallbacks
from .common import ServerBase
from .common import ServerBase, poll_until
from .. import wormhole, _rendezvous
from ..errors import (WrongPasswordError,
KeyFormatError, WormholeClosed, LonelyError,
@ -234,6 +234,28 @@ class Wormholes(ServerBase, unittest.TestCase):
yield w1.close()
yield w2.close()
@inlineCallbacks
def test_input_code(self):
w1 = wormhole.create(APPID, self.relayurl, reactor)
w2 = wormhole.create(APPID, self.relayurl, reactor)
w1.set_code("123-purple-elephant")
h = w2.input_code()
h.choose_nameplate("123")
# Pause to allow some messages to get delivered. Specifically we want
# to wait until w2 claims the nameplate, opens the mailbox, and
# receives the PAKE message, to exercise the PAKE-before-CODE path in
# Key.
yield poll_until(lambda: w2._boss._K._debug_pake_stashed)
h.choose_words("purple-elephant")
w1.send(b"data1"), w2.send(b"data2")
dl = yield self.doBoth(w1.when_received(), w2.when_received())
(dataX, dataY) = dl
self.assertEqual(dataX, b"data2")
self.assertEqual(dataY, b"data1")
yield w1.close()
yield w2.close()
@inlineCallbacks
def test_multiple_messages(self):