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(); }
Status loginRecoveryQuestions(std::string &result, Lobby &lobby) { // Load CarePackage: CarePackage carePackage; ABC_CHECK(loginServerGetCarePackage(lobby, carePackage)); // Verify that the questions exist: if (!carePackage.questionBox()) return ABC_ERROR(ABC_CC_NoRecoveryQuestions, "No recovery questions"); // Create questionKey (unlocks questions): DataChunk questionKey; ABC_CHECK(carePackage.snrp4().hash(questionKey, lobby.username())); // Decrypt: DataChunk questions; ABC_CHECK(carePackage.questionBox().decrypt(questions, questionKey)); result = toString(questions); return Status(); }