#ifndef _H_KCDATABASE
#define _H_KCDATABASE
#include "localdatabase.h"
#include <securityd_client/ss_types.h>
class KeychainDatabase;
class KeychainDbCommon;
class KeychainKey;
class DbIdentifier {
public:
DbIdentifier(const DLDbIdentifier &id, DbBlob::Signature sig)
: mIdent(id), mSig(sig) { }
const DLDbIdentifier &dlDbIdentifier() const { return mIdent; }
const DbBlob::Signature &signature() const { return mSig; }
operator const DLDbIdentifier &() const { return dlDbIdentifier(); }
operator const DbBlob::Signature &() const { return signature(); }
const char *dbName() const { return mIdent.dbName(); }
bool operator < (const DbIdentifier &id) const {
if (mIdent < id.mIdent) return true;
if (id.mIdent < mIdent) return false;
return mSig < id.mSig;
}
bool operator == (const DbIdentifier &id) const
{ return mIdent == id.mIdent && mSig == id.mSig; }
private:
DLDbIdentifier mIdent;
DbBlob::Signature mSig;
};
class KeychainDbGlobal : public PerGlobal {
public:
KeychainDbGlobal(const DbIdentifier &id);
~KeychainDbGlobal();
const DbIdentifier &identifier() const { return mIdentifier; }
private:
DbIdentifier mIdentifier; };
class KeychainDbCommon : public LocalDbCommon,
public DatabaseCryptoCore, public MachServer::Timer {
public:
KeychainDbCommon(Session &ssn, const DbIdentifier &id);
~KeychainDbCommon();
KeychainDbGlobal &global() const;
bool unlockDb(DbBlob *blob, void **privateAclBlob = NULL);
void lockDb(); bool isLocked() { return mIsLocked; } void setUnlocked();
void invalidateBlob() { version++; }
void activity();
void makeNewSecrets();
const DbIdentifier &identifier() const {return mIdentifier; }
const DLDbIdentifier &dlDbIdent() const { return identifier(); }
const char *dbName() const { return dlDbIdent().dbName(); }
bool isLoginKeychain() const { return mLoginKeychain; }
DbBlob *encode(KeychainDatabase &db);
void notify(NotificationEvent event) { DbCommon::notify(event, identifier()); }
void sleepProcessing();
void lockProcessing();
bool belongsToSystem() const;
public:
IFDUMP(void dumpNode());
protected:
void action();
void select();
void unselect();
public:
uint32 sequence; DBParameters mParams;
uint32 version;
private:
DbIdentifier mIdentifier; bool mIsLocked; bool mValidParams; bool mLoginKeychain;
};
class KeychainDatabase : public LocalDatabase, private virtual SecurityServerAcl {
friend class KeychainDbCommon;
public:
KeychainDatabase(const DLDbIdentifier &id, const DBParameters ¶ms, Process &proc,
const AccessCredentials *cred, const AclEntryPrototype *owner);
KeychainDatabase(const DLDbIdentifier &id, const DbBlob *blob, Process &proc,
const AccessCredentials *cred);
KeychainDatabase(KeychainDatabase &src, Process &proc, DbHandle dbToClone);
virtual ~KeychainDatabase();
KeychainDbCommon &common() const;
const char *dbName() const;
bool transient() const;
KeychainDbGlobal &global() const { return common().global(); }
public:
static const int maxUnlockTryCount = 3;
public:
const DbIdentifier &identifier() const { return common().identifier(); }
public:
DbBlob *blob();
void authenticate(CSSM_DB_ACCESS_TYPE mode, const AccessCredentials *cred);
void changePassphrase(const AccessCredentials *cred);
RefPointer<Key> extractMasterKey(Database &db, const AccessCredentials *cred,
const AclEntryPrototype *owner, uint32 usage, uint32 attrs);
void commitSecretsForSync(KeychainDatabase &cloneDb);
void lockDb(); void unlockDb(); void unlockDb(const CssmData &passphrase);
void stashDbCheck(); void stashDb();
bool decode(); bool decode(const CssmData &passphrase);
bool validatePassphrase(const CssmData &passphrase) const; bool isLocked() { return common().isLocked(); } void notify(NotificationEvent event) { return common().notify(event); }
void activity() const { common().activity(); }
void decodeKey(KeyBlob *blob, CssmKey &key, void * &pubAcl, void * &privAcl);
KeyBlob *encodeKey(const CssmKey &key, const CssmData &pubAcl, const CssmData &privAcl);
KeyBlob *recodeKey(KeychainKey &oldKey);
bool validBlob() const { return mBlob && version == common().version; }
void setParameters(const DBParameters ¶ms);
void getParameters(DBParameters ¶ms);
SecurityServerAcl &acl();
AclKind aclKind() const;
Database *relatedDatabase();
void instantiateAcl();
void changedAcl();
static void validateBlob(const DbBlob *blob);
IFDUMP(void dumpNode());
protected:
RefPointer<Key> makeKey(const CssmKey &newKey, uint32 moreAttributes, const AclEntryPrototype *owner);
RefPointer<Key> makeKey(Database &db, const CssmKey &newKey, uint32 moreAttributes, const AclEntryPrototype *owner);
void makeUnlocked(); void makeUnlocked(const AccessCredentials *cred); void makeUnlocked(const CssmData &passphrase);
void establishOldSecrets(const AccessCredentials *creds);
void establishNewSecrets(const AccessCredentials *creds, SecurityAgent::Reason reason);
bool interactiveUnlock();
CssmClient::Key keyFromCreds(const TypedList &sample, unsigned int requiredLength);
void encode();
private:
bool mValidData; CssmAutoData mSecret;
bool mSaveSecret;
uint32 version; DbBlob *mBlob;
AccessCredentials *mCred;
RefPointer<KeychainDatabase> mRecodingSource; };
#endif //_H_KCDATABASE