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 main(): config = get_json(ISSUER + "/.well-known/fxa-client-configuration") if os.path.exists("./credentials.json"): with open("./credentials.json") as f: creds = json.loads(f.read()) print "Loaded credentials from ./credentials.json" else: creds = authenticate(config) with open("./credentials.json", "w") as f: f.write(json.dumps(creds, indent=4)) print "Saved credentials to ./credentials.json" access_token = creds["access_token"] sync_key = jwcrypto.jwk.JWK(**creds["keys"][SCOPE]) raw_sync_key = decode_bytes(sync_key.get_op_key('encrypt')) sync_key_bundle = KeyBundle( raw_sync_key[:32], raw_sync_key[32:], ) tokenserver_url = config["sync_tokenserver_base_url"] sync_creds = get_json(tokenserver_url + '/1.0/sync/1.5', headers={ 'Authorization': 'Bearer ' + access_token, 'X-KeyID': sync_key.key_id }) auth = HawkTokenAuth(b"0" * (3 * 32), "whatevz") auth.id = sync_creds["id"].encode('ascii') auth.auth_key = sync_creds["key"].encode('ascii') try: keys = get_json(sync_creds["api_endpoint"] + "/storage/crypto/keys", auth=auth) keys = decrypt_bso(sync_key_bundle, keys) default_key_bundle = KeyBundle( base64.b64decode(keys["default"][0]), base64.b64decode(keys["default"][1]), ) passwords = get_json(sync_creds["api_endpoint"] + "/storage/passwords?full=1", auth=auth) if not passwords: print "No synced passwords." else: passwords = [decrypt_bso(default_key_bundle, p) for p in passwords] passwords = [(p["id"], p["hostname"], p["username"], p["password"]) for p in passwords if not p.get("deleted", False)] print tabulate.tabulate( passwords, headers=["id", "hostname", "username", "password"], tablefmt="grid" ) except requests.exceptions.HTTPError as e: if e.response.status_code != 404: raise print "No synced passwords."
def verify_reset_code(self, token, code): body = { "code": code, } url = "/password/forgot/verify_code" auth = HawkTokenAuth(token, "passwordForgotToken", self.apiclient) return self.apiclient.post(url, body, auth=auth)
def finish_password_change(self, token, stretchpwd, wrapkb): body = { "authPW": hexstr(derive_key(stretchpwd, "authPW")), "wrapKb": hexstr(wrapkb), } auth = HawkTokenAuth(token, "passwordChangeToken", self.apiclient) self.apiclient.post("/password/change/finish", body, auth=auth)
def reset_account(self, email, token, password=None, stretchpwd=None): stretchpwd = self._get_stretched_password(email, password, stretchpwd) body = { "authPW": hexstr(derive_key(stretchpwd, "authPW")), } url = "/account/reset" auth = HawkTokenAuth(token, "accountResetToken", self.apiclient) self.apiclient.post(url, body, auth=auth)
def resend_reset_code(self, email, token, **kwds): body = { "email": email, } for extra in kwds: if extra in ("service", "redirectTo", "resume"): body[extra] = kwds[extra] else: msg = "Unexpected keyword argument: {0}".format(extra) raise TypeError(msg) url = "/password/forgot/resend_code" auth = HawkTokenAuth(token, "passwordForgotToken", self.apiclient) return self.apiclient.post(url, body, auth=auth)
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
def __init__(self, client, email, stretchpwd, uid, token, key_fetch_token=None, verified=False, verificationMethod=None, auth_timestamp=0, cert_keypair=None): self.client = client self.email = email self.uid = uid self.token = token self.verified = verified self.verificationMethod = verificationMethod self.auth_timestamp = auth_timestamp self.cert_keypair = None self.keys = None self._auth = HawkTokenAuth(token, "sessionToken", self.apiclient) self._key_fetch_token = key_fetch_token self._stretchpwd = stretchpwd
def get_reset_code_status(self, token): url = "/password/forgot/status" auth = HawkTokenAuth(token, "passwordForgotToken", self.apiclient) return self.apiclient.get(url, auth=auth)