change confirmation message: must be different on each side

The previous same-message-for-both-sides approach failed, because the
Channel filters out duplicates.
This commit is contained in:
Brian Warner 2015-11-19 16:06:30 -08:00
parent 1ad001bbc3
commit fd9a62e8ff
2 changed files with 24 additions and 6 deletions

View File

@ -16,6 +16,11 @@ from ..channel_monitor import monitor
SECOND = 1
MINUTE = 60*SECOND
CONFMSG_NONCE_LENGTH = 128//8
CONFMSG_MAC_LENGTH = 256//8
def make_confmsg(confkey, nonce):
return nonce+HKDF(confkey, CONFMSG_MAC_LENGTH, nonce)
def to_bytes(u):
return unicodedata.normalize("NFC", u).encode("utf-8")
@ -318,8 +323,10 @@ class Wormhole:
self.verifier = self.derive_key(u"wormhole:verifier")
if not self._send_confirm:
return
conf = self.derive_key(u"wormhole:confirmation")
self._channel.send(u"_confirm", conf)
confkey = self.derive_key(u"wormhole:confirmation")
nonce = os.urandom(CONFMSG_NONCE_LENGTH)
confmsg = make_confmsg(confkey, nonce)
self._channel.send(u"_confirm", confmsg)
@close_on_error
def get_verifier(self):
@ -365,7 +372,9 @@ class Wormhole:
phases.append(phase)
(got_phase, body) = self._channel.get_first_of(phases)
if got_phase == u"_confirm":
if body != self.derive_key(u"wormhole:confirmation"):
confkey = self.derive_key(u"wormhole:confirmation")
nonce = body[:CONFMSG_NONCE_LENGTH]
if body != make_confmsg(confkey, nonce):
raise WrongPasswordError
self._got_confirmation = True
(got_phase, body) = self._channel.get_first_of([phase])

View File

@ -18,6 +18,11 @@ from ..errors import ServerError, WrongPasswordError, UsageError
from ..util.hkdf import HKDF
from ..channel_monitor import monitor
CONFMSG_NONCE_LENGTH = 128//8
CONFMSG_MAC_LENGTH = 256//8
def make_confmsg(confkey, nonce):
return nonce+HKDF(confkey, CONFMSG_MAC_LENGTH, nonce)
def to_bytes(u):
return unicodedata.normalize("NFC", u).encode("utf-8")
@ -336,8 +341,10 @@ class Wormhole:
self.verifier = self.derive_key(u"wormhole:verifier")
if not self._send_confirm:
return key
conf = self.derive_key(u"wormhole:confirmation")
d1 = self._channel.send(u"_confirm", conf)
confkey = self.derive_key(u"wormhole:confirmation")
nonce = os.urandom(CONFMSG_NONCE_LENGTH)
confmsg = make_confmsg(confkey, nonce)
d1 = self._channel.send(u"_confirm", confmsg)
d1.addCallback(lambda _: key)
return d1
d.addCallback(_got_pake)
@ -387,7 +394,9 @@ class Wormhole:
def _maybe_got_confirm(phase_and_body):
(got_phase, body) = phase_and_body
if got_phase == u"_confirm":
if body != self.derive_key(u"wormhole:confirmation"):
confkey = self.derive_key(u"wormhole:confirmation")
nonce = body[:CONFMSG_NONCE_LENGTH]
if body != make_confmsg(confkey, nonce):
raise WrongPasswordError
self._got_confirmation = True
return self._channel.get_first_of([phase])