def fetch_keys(self, key_fetch_token, stretchpwd): url = "/account/keys" auth = HawkTokenAuth(key_fetch_token, "keyFetchToken", self.apiclient) resp = self.apiclient.get(url, auth=auth) bundle = unhexlify(resp["bundle"]) keys = auth.unbundle("account/keys", bundle) unwrap_key = derive_key(stretchpwd, "unwrapBkey") return (keys[:32], xor(keys[32:], unwrap_key))
def change_password(self, oldpwd, newpwd): stretched_oldpwd = quick_stretch_password(self.email, oldpwd) resp = self.start_password_change(stretched_oldpwd) keys = self.fetch_keys(resp["keyFetchToken"], stretched_oldpwd) token = resp["passwordChangeToken"] stretched_newpwd = quick_stretch_password(self.email, newpwd) new_wrapkb = xor(keys[1], derive_key(stretched_newpwd, "unwrapBkey")) self.finish_password_change(token, stretched_newpwd, new_wrapkb)
def change_password(self, email, oldpwd=None, newpwd=None, oldstretchpwd=None, newstretchpwd=None): oldstretchpwd = self._get_stretched_password(email, oldpwd, oldstretchpwd) newstretchpwd = self._get_stretched_password(email, newpwd, newstretchpwd) resp = self.start_password_change(email, oldstretchpwd) keys = self.fetch_keys(resp["keyFetchToken"], oldstretchpwd) token = resp["passwordChangeToken"] new_wrapkb = xor(keys[1], derive_key(newstretchpwd, "unwrapBkey")) self.finish_password_change(token, newstretchpwd, new_wrapkb)
def test_xor(self): self.assertEqual(xor("", ""), "") self.assertEqual(xor("\x01", "\x01"), "\x00") self.assertEqual(xor("\x01", "\x02"), "\x03") self.assertEqual(xor("abc", "def"), "\x05\x07\x05") with self.assertRaises(ValueError): xor("shorter", "longer string")
def fetch_keys(self, key_fetch_token=None, stretchpwd=None): # Use values from session construction, if not overridden. if key_fetch_token is None: key_fetch_token = self._key_fetch_token if key_fetch_token is None: # XXX TODO: what error? raise RuntimeError("missing key_fetch_token") if stretchpwd is None: stretchpwd = self._stretchpwd if stretchpwd is None: # XXX TODO: what error? raise RuntimeError("missing stretchpwd") # Fetch the keys, and clear cached values from session construction. url = "/v1/account/keys" auth = HawkTokenAuth(key_fetch_token, "keyFetchToken", self.apiclient) resp = self.apiclient.get(url, auth=auth) self._key_fetch_token = None self._stretchpwd = None # Decrypt kB using the stretchpwd. bundle = unhexlify(resp["bundle"]) keys = auth.unbundle("account/keys", bundle) unwrap_key = derive_key(stretchpwd, "unwrapBkey") self.keys = (keys[:32], xor(keys[32:], unwrap_key)) return self.keys