Status Login::createNew(const char *password) { LoginPackage loginPackage; JsonSnrp snrp; // Set up care package: CarePackage carePackage; ABC_CHECK(snrp.create()); ABC_CHECK(carePackage.passwordKeySnrpSet(snrp)); // Set up syncKey: DataChunk syncKey; JsonBox syncKeyBox; ABC_CHECK(randomData(syncKey, SYNC_KEY_LENGTH)); ABC_CHECK(syncKeyBox.encrypt(syncKey, dataKey_)); ABC_CHECK(loginPackage.syncKeyBoxSet(syncKeyBox)); // Set up passwordAuth (LP1): if (password) { std::string LP = store.username() + password; // Generate passwordAuth: ABC_CHECK(usernameSnrp().hash(passwordAuth_, LP)); // We have a password, so use it to encrypt dataKey: DataChunk passwordKey; JsonBox passwordBox; ABC_CHECK(carePackage.passwordKeySnrp().hash(passwordKey, LP)); ABC_CHECK(passwordBox.encrypt(dataKey_, passwordKey)); ABC_CHECK(loginPackage.passwordBoxSet(passwordBox)); } else { // Generate passwordAuth: ABC_CHECK(randomData(passwordAuth_, scryptDefaultSize)); } JsonBox passwordAuthBox; ABC_CHECK(passwordAuthBox.encrypt(passwordAuth_, dataKey_)); ABC_CHECK(loginPackage.passwordAuthBoxSet(passwordAuthBox)); // Create the account and repo on server: ABC_CHECK(loginServerCreate(store, passwordAuth_, carePackage, loginPackage, base16Encode(syncKey))); // Set up the on-disk login: ABC_CHECK(store.paths(paths, true)); ABC_CHECK(carePackage.save(paths.carePackagePath())); ABC_CHECK(loginPackage.save(paths.loginPackagePath())); ABC_CHECK(rootKeyUpgrade()); // Save the bare minimum needed to access the Airbitz account: LoginStashJson stashJson; ABC_CHECK(stashJson.loginIdSet(base64Encode(store.userId()))); ABC_CHECK(stashJson.syncKeyBoxSet(syncKeyBox)); stashJson.save(paths.stashPath()); // Latch the account: ABC_CHECK(loginServerActivate(*this)); return Status(); }