Status loginRecovery(std::shared_ptr<Login> &result, Lobby &lobby, const std::string &recoveryAnswers, AuthError &authError) { std::string LRA = lobby.username() + recoveryAnswers; // Get the CarePackage: CarePackage carePackage; ABC_CHECK(loginServerGetCarePackage(lobby, carePackage)); // Make recoveryAuthKey (unlocks the server): DataChunk recoveryAuthKey; ABC_CHECK(usernameSnrp().hash(recoveryAuthKey, LRA)); // Get the LoginPackage: LoginPackage loginPackage; JsonPtr rootKeyBox; ABC_CHECK(loginServerGetLoginPackage(lobby, U08Buf(), recoveryAuthKey, loginPackage, rootKeyBox, authError)); // Make recoveryKey (unlocks dataKey): DataChunk recoveryKey; ABC_CHECK(carePackage.snrp3().hash(recoveryKey, LRA)); // Decrypt dataKey (unlocks the account): DataChunk dataKey; ABC_CHECK(loginPackage.recoveryBox().decrypt(dataKey, recoveryKey)); // Create the Login object: std::shared_ptr<Login> out; ABC_CHECK(Login::create(out, lobby, dataKey, loginPackage, rootKeyBox, false)); // Set up the on-disk login: ABC_CHECK(carePackage.save(out->paths.carePackagePath())); ABC_CHECK(loginPackage.save(out->paths.loginPackagePath())); result = std::move(out); return Status(); }