// // Verify a putative database passphrase. // If the database is already unlocked, just check the passphrase. // Otherwise, unlock with that passphrase and report success. // Caller must hold the common lock. // bool KeychainDatabase::validatePassphrase(const CssmData &passphrase) const { if (common().hasMaster()) { // verify against known secret return common().validatePassphrase(passphrase); } else { // no master secret - perform "blind" unlock to avoid actual unlock try { DatabaseCryptoCore test; test.setup(mBlob, passphrase); test.decodeCore(mBlob, NULL); return true; } catch (...) { return false; } } }
// // Make another DatabaseCryptoCore's operational secrets our own. // Intended for keychain synchronization. // void DatabaseCryptoCore::importSecrets(const DatabaseCryptoCore &src) { assert(src.isValid()); // must have called src.decodeCore() first assert(hasMaster()); mEncryptionKey = src.mEncryptionKey; mSigningKey = src.mSigningKey; mIsValid = true; }
// // Make another DatabaseCryptoCore's operational secrets our own. // Intended for keychain synchronization. // void DatabaseCryptoCore::importSecrets(const DatabaseCryptoCore &src) { assert(src.isValid()); // must have called src.decodeCore() first assert(hasMaster()); mEncryptionKey = src.mEncryptionKey; mSigningKey = src.mSigningKey; mBlobVersion = src.mBlobVersion; // make sure we copy over all state mIsValid = true; }
// // Copy everything from another databasecryptocore // void DatabaseCryptoCore::initializeFrom(DatabaseCryptoCore& core, uint32 requestedVersion) { if(core.hasMaster()) { mMasterKey = core.mMasterKey; memcpy(mSalt, core.mSalt, sizeof(mSalt)); mHaveMaster = core.mHaveMaster; } else { mHaveMaster = false; } if(core.isValid()) { importSecrets(core); } else { mIsValid = false; } // As the last thing we do, check if we should be changing the version of this blob. if(requestedVersion == CommonBlob::version_none) { mBlobVersion = core.mBlobVersion; } else { mBlobVersion = requestedVersion; } }