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:
parent
1ad001bbc3
commit
fd9a62e8ff
|
@ -16,6 +16,11 @@ from ..channel_monitor import monitor
|
||||||
SECOND = 1
|
SECOND = 1
|
||||||
MINUTE = 60*SECOND
|
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):
|
def to_bytes(u):
|
||||||
return unicodedata.normalize("NFC", u).encode("utf-8")
|
return unicodedata.normalize("NFC", u).encode("utf-8")
|
||||||
|
|
||||||
|
@ -318,8 +323,10 @@ class Wormhole:
|
||||||
self.verifier = self.derive_key(u"wormhole:verifier")
|
self.verifier = self.derive_key(u"wormhole:verifier")
|
||||||
if not self._send_confirm:
|
if not self._send_confirm:
|
||||||
return
|
return
|
||||||
conf = self.derive_key(u"wormhole:confirmation")
|
confkey = self.derive_key(u"wormhole:confirmation")
|
||||||
self._channel.send(u"_confirm", conf)
|
nonce = os.urandom(CONFMSG_NONCE_LENGTH)
|
||||||
|
confmsg = make_confmsg(confkey, nonce)
|
||||||
|
self._channel.send(u"_confirm", confmsg)
|
||||||
|
|
||||||
@close_on_error
|
@close_on_error
|
||||||
def get_verifier(self):
|
def get_verifier(self):
|
||||||
|
@ -365,7 +372,9 @@ class Wormhole:
|
||||||
phases.append(phase)
|
phases.append(phase)
|
||||||
(got_phase, body) = self._channel.get_first_of(phases)
|
(got_phase, body) = self._channel.get_first_of(phases)
|
||||||
if got_phase == u"_confirm":
|
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
|
raise WrongPasswordError
|
||||||
self._got_confirmation = True
|
self._got_confirmation = True
|
||||||
(got_phase, body) = self._channel.get_first_of([phase])
|
(got_phase, body) = self._channel.get_first_of([phase])
|
||||||
|
|
|
@ -18,6 +18,11 @@ from ..errors import ServerError, WrongPasswordError, UsageError
|
||||||
from ..util.hkdf import HKDF
|
from ..util.hkdf import HKDF
|
||||||
from ..channel_monitor import monitor
|
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):
|
def to_bytes(u):
|
||||||
return unicodedata.normalize("NFC", u).encode("utf-8")
|
return unicodedata.normalize("NFC", u).encode("utf-8")
|
||||||
|
|
||||||
|
@ -336,8 +341,10 @@ class Wormhole:
|
||||||
self.verifier = self.derive_key(u"wormhole:verifier")
|
self.verifier = self.derive_key(u"wormhole:verifier")
|
||||||
if not self._send_confirm:
|
if not self._send_confirm:
|
||||||
return key
|
return key
|
||||||
conf = self.derive_key(u"wormhole:confirmation")
|
confkey = self.derive_key(u"wormhole:confirmation")
|
||||||
d1 = self._channel.send(u"_confirm", conf)
|
nonce = os.urandom(CONFMSG_NONCE_LENGTH)
|
||||||
|
confmsg = make_confmsg(confkey, nonce)
|
||||||
|
d1 = self._channel.send(u"_confirm", confmsg)
|
||||||
d1.addCallback(lambda _: key)
|
d1.addCallback(lambda _: key)
|
||||||
return d1
|
return d1
|
||||||
d.addCallback(_got_pake)
|
d.addCallback(_got_pake)
|
||||||
|
@ -387,7 +394,9 @@ class Wormhole:
|
||||||
def _maybe_got_confirm(phase_and_body):
|
def _maybe_got_confirm(phase_and_body):
|
||||||
(got_phase, body) = phase_and_body
|
(got_phase, body) = phase_and_body
|
||||||
if got_phase == u"_confirm":
|
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
|
raise WrongPasswordError
|
||||||
self._got_confirmation = True
|
self._got_confirmation = True
|
||||||
return self._channel.get_first_of([phase])
|
return self._channel.get_first_of([phase])
|
||||||
|
|
Loading…
Reference in New Issue
Block a user