示例#1
0
Status
Login::loadOffline()
{
    ABC_CHECK(store.paths(paths, true));

    LoginPackage loginPackage;
    ABC_CHECK(loginPackage.load(paths.loginPackagePath()));
    ABC_CHECK(loginPackage.passwordAuthBox().decrypt(passwordAuth_, dataKey_));

    // Look for an existing rootKeyBox:
    JsonBox rootKeyBox;
    if (fileExists(paths.rootKeyPath()))
    {
        ABC_CHECK(rootKeyBox.load(paths.rootKeyPath()));
    }
    else
    {
        // Try asking the server:
        AuthJson authJson;
        LoginReplyJson loginJson;
        ABC_CHECK(authJson.loginSet(*this));
        ABC_CHECK(loginServerLogin(loginJson, authJson));
        ABC_CHECK(loginJson.save(*this));
        rootKeyBox = loginJson.rootKeyBox();
    }
    // Otherwise, there just isn't one.

    // Extract the rootKey:
    if (rootKeyBox.ok())
        ABC_CHECK(rootKeyBox.decrypt(rootKey_, dataKey_));
    else
        ABC_CHECK(rootKeyUpgrade());

    return Status();
}
示例#2
0
Status
loginRecoverySet(Login &login,
                 const std::string &recoveryQuestions,
                 const std::string &recoveryAnswers)
{
    std::string LRA = login.lobby.username() + recoveryAnswers;

    // Load the packages:
    CarePackage carePackage;
    LoginPackage loginPackage;
    ABC_CHECK(carePackage.load(login.paths.carePackagePath()));
    ABC_CHECK(loginPackage.load(login.paths.loginPackagePath()));

    // Load the old keys:
    DataChunk authKey = login.authKey();

    // Update scrypt parameters:
    JsonSnrp snrp;
    ABC_CHECK(snrp.create());
    ABC_CHECK(carePackage.snrp3Set(snrp));
    ABC_CHECK(snrp.create());
    ABC_CHECK(carePackage.snrp4Set(snrp));

    // Make questionKey (unlocks questions):
    DataChunk questionKey;
    ABC_CHECK(carePackage.snrp4().hash(questionKey, login.lobby.username()));

    // Encrypt the questions:
    JsonBox box;
    ABC_CHECK(box.encrypt(recoveryQuestions, questionKey));
    ABC_CHECK(carePackage.questionBoxSet(box));

    // Make recoveryKey (unlocks dataKey):
    DataChunk recoveryKey;
    ABC_CHECK(carePackage.snrp3().hash(recoveryKey, LRA));

    // Encrypt dataKey:
    ABC_CHECK(box.encrypt(login.dataKey(), recoveryKey));
    ABC_CHECK(loginPackage.recoveryBoxSet(box));

    // Make recoveryAuthKey (unlocks the server):
    DataChunk recoveryAuthKey;
    ABC_CHECK(usernameSnrp().hash(recoveryAuthKey, LRA));

    // Encrypt recoveryAuthKey (needed for atomic password updates):
    ABC_CHECK(box.encrypt(recoveryAuthKey, login.dataKey()));
    ABC_CHECK(loginPackage.ELRA1Set(box));

    // Change the server login:
    ABC_CHECK(loginServerChangePassword(login, authKey, recoveryAuthKey,
                                        carePackage, loginPackage));

    // Change the on-disk login:
    ABC_CHECK(carePackage.save(login.paths.carePackagePath()));
    ABC_CHECK(loginPackage.save(login.paths.loginPackagePath()));

    return Status();
}
示例#3
0
Status
loginRecoverySet(Login &login,
                 const std::string &recoveryQuestions,
                 const std::string &recoveryAnswers)
{
    std::string LRA = login.store.username() + recoveryAnswers;

    // Load the packages:
    CarePackage carePackage;
    LoginPackage loginPackage;
    ABC_CHECK(carePackage.load(login.paths.carePackagePath()));
    ABC_CHECK(loginPackage.load(login.paths.loginPackagePath()));

    // Load the old keys:
    DataChunk passwordAuth = login.passwordAuth();

    // Update scrypt parameters:
    JsonSnrp snrp;
    ABC_CHECK(snrp.create());
    ABC_CHECK(carePackage.recoveryKeySnrpSet(snrp));
    ABC_CHECK(snrp.create());
    ABC_CHECK(carePackage.questionKeySnrpSet(snrp));

    // Make questionKey (unlocks questions):
    DataChunk questionKey;
    ABC_CHECK(carePackage.questionKeySnrp().hash(questionKey,
              login.store.username()));

    // Encrypt the questions:
    JsonBox questionBox;
    ABC_CHECK(questionBox.encrypt(recoveryQuestions, questionKey));
    ABC_CHECK(carePackage.questionBoxSet(questionBox));

    // Make recoveryKey (unlocks dataKey):
    DataChunk recoveryKey;
    ABC_CHECK(carePackage.recoveryKeySnrp().hash(recoveryKey, LRA));

    // Encrypt dataKey:
    JsonBox recoveryBox;
    ABC_CHECK(recoveryBox.encrypt(login.dataKey(), recoveryKey));
    ABC_CHECK(loginPackage.recoveryBoxSet(recoveryBox));

    // Make recoveryAuth (unlocks the server):
    DataChunk recoveryAuth;
    ABC_CHECK(usernameSnrp().hash(recoveryAuth, LRA));

    // Change the server login:
    ABC_CHECK(loginServerChangePassword(login, passwordAuth, recoveryAuth,
                                        carePackage, loginPackage));

    // Change the on-disk login:
    ABC_CHECK(carePackage.save(login.paths.carePackagePath()));
    ABC_CHECK(loginPackage.save(login.paths.loginPackagePath()));

    return Status();
}
示例#4
0
Status
Login::repoFindLocal(JsonPtr &result, const std::string &type)
{
    // If this is an Airbitz account, try the legacy `syncKey`:
    if (repoTypeAirbitzAccount == type)
    {
        LoginPackage loginPackage;
        ABC_CHECK(loginPackage.load(paths.loginPackagePath()));
        if (loginPackage.syncKeyBox().ok())
        {
            DataChunk syncKey;
            ABC_CHECK(loginPackage.syncKeyBox().decrypt(syncKey, dataKey_));

            AccountRepoJson repoJson;
            ABC_CHECK(repoJson.syncKeySet(base64Encode(syncKey)));
            ABC_CHECK(repoJson.dataKeySet(base64Encode(dataKey_)));

            result = repoJson;
            return Status();
        }
    }

    // Search the on-disk array:
    LoginStashJson stashJson;
    if (stashJson.load(paths.stashPath()))
    {
        auto keyBoxesJson = stashJson.keyBoxes();
        size_t keyBoxesSize = keyBoxesJson.size();
        for (size_t i = 0; i < keyBoxesSize; i++)
        {
            JsonBox boxJson(keyBoxesJson[i]);

            DataChunk keyBytes;
            KeyJson keyJson;
            ABC_CHECK(boxJson.decrypt(keyBytes, dataKey_));
            ABC_CHECK(keyJson.decode(toString(keyBytes)));

            if (keyJson.typeOk() && type == keyJson.type())
            {
                result = keyJson.keys();
                return Status();
            }
        }
    }

    return ABC_ERROR(ABC_CC_AccountDoesNotExist, "No such repo");
}