#ifndef _SECURITY_KEYCHAINS_H_
#define _SECURITY_KEYCHAINS_H_
#include <Security/cspclient.h>
#include <Security/dlclient.h>
#include <Security/refcount.h>
#include <Security/utilities.h>
#include <Security/DLDBListCFPref.h>
#include <Security/SecRuntime.h>
#include <Security/SecKeychain.h>
#include <Security/SecKeychainItem.h>
#include <memory>
namespace Security
{
namespace KeychainCore
{
class KCCursor;
class Item;
class PrimaryKey;
class StorageManager;
class KeychainSchemaImpl : public RefCount
{
NOCOPY(KeychainSchemaImpl)
public:
friend class KeychainSchema;
protected:
KeychainSchemaImpl(const CssmClient::Db &db);
public:
~KeychainSchemaImpl();
CSSM_DB_ATTRIBUTE_FORMAT attributeFormatFor(CSSM_DB_RECORDTYPE recordType, uint32 attributeId) const;
const CssmAutoDbRecordAttributeInfo &primaryKeyInfosFor(CSSM_DB_RECORDTYPE recordType) const;
bool operator <(const KeychainSchemaImpl &other) const;
bool operator ==(const KeychainSchemaImpl &other) const;
void getAttributeInfoForRecordType(CSSM_DB_RECORDTYPE recordType, SecKeychainAttributeInfo **Info) const;
CssmDbAttributeInfo attributeInfoFor(CSSM_DB_RECORDTYPE recordType, uint32 attributeId) const;
bool hasAttribute(CSSM_DB_RECORDTYPE recordType, uint32 attributeId) const;
private:
typedef map<CSSM_DB_RECORDTYPE, CssmAutoDbRecordAttributeInfo *> PrimaryKeyInfoMap;
PrimaryKeyInfoMap mPrimaryKeyInfoMap;
typedef map<uint32, CSSM_DB_ATTRIBUTE_FORMAT> RelationInfoMap;
typedef map<CSSM_DB_RECORDTYPE, RelationInfoMap> DatabaseInfoMap;
DatabaseInfoMap mDatabaseInfoMap;
private:
const RelationInfoMap &relationInfoMapFor(CSSM_DB_RECORDTYPE recordType) const;
};
class KeychainSchema : public RefPointer<KeychainSchemaImpl>
{
public:
KeychainSchema() {}
KeychainSchema(KeychainSchemaImpl *impl) : RefPointer<KeychainSchemaImpl>(impl) {}
KeychainSchema(const CssmClient::Db &db) : RefPointer<KeychainSchemaImpl>(new KeychainSchemaImpl(db)) {}
bool operator <(const KeychainSchema &other) const
{ return ptr && other.ptr ? *ptr < *other.ptr : ptr < other.ptr; }
bool operator ==(const KeychainSchema &other) const
{ return ptr && other.ptr ? *ptr == *other.ptr : ptr == other.ptr; }
private:
typedef KeychainSchemaImpl Impl;
};
class KeychainImpl : public SecCFObject
{
NOCOPY(KeychainImpl)
public:
SECCFFUNCTIONS(KeychainImpl, SecKeychainRef, errSecInvalidKeychain)
friend class Keychain;
friend class ItemImpl;
protected:
KeychainImpl(const CssmClient::Db &db);
protected:
void didUpdate(ItemImpl *inItemImpl, PrimaryKey &oldPK,
PrimaryKey &newPK);
public:
virtual ~KeychainImpl() throw();
bool operator ==(const KeychainImpl &) const;
void add(Item &item); void deleteItem(Item &item);
void create(UInt32 passwordLength, const void *inPassword);
void create(ConstStringPtr inPassword);
void create();
void create(const ResourceControlContext *rcc);
void open();
void lock();
void unlock();
void unlock(const CssmData &password);
void unlock(ConstStringPtr password);
void getSettings(uint32 &outIdleTimeOut, bool &outLockOnSleep);
void setSettings(uint32 inIdleTimeOut, bool inLockOnSleep);
void changePassphrase(UInt32 oldPasswordLength, const void *oldPassword,
UInt32 newPasswordLength, const void *newPassword);
void changePassphrase(ConstStringPtr oldPassword, ConstStringPtr newPassword);
void authenticate(const CSSM_ACCESS_CREDENTIALS *cred);
const char *name() const { return mDb->name(); }
UInt32 status() const;
bool exists();
bool isActive() const;
KCCursor createCursor(const SecKeychainAttributeList *attrList);
KCCursor createCursor(SecItemClass itemClass, const SecKeychainAttributeList *attrList);
CssmClient::Db database() { return mDb; }
DLDbIdentifier dLDbIdentifier() const { return mDb->dlDbIdentifier(); }
CssmClient::CSP csp();
PrimaryKey makePrimaryKey(CSSM_DB_RECORDTYPE recordType, CssmClient::DbUniqueRecord &uniqueId);
void gatherPrimaryKeyAttributes(CssmClient::DbAttributes& primaryKeyAttrs);
const CssmAutoDbRecordAttributeInfo &primaryKeyInfosFor(CSSM_DB_RECORDTYPE recordType);
Item item(const PrimaryKey& primaryKey);
Item item(CSSM_DB_RECORDTYPE recordType, CssmClient::DbUniqueRecord &uniqueId);
CssmDbAttributeInfo attributeInfoFor(CSSM_DB_RECORDTYPE recordType, UInt32 tag);
void getAttributeInfoForItemID(CSSM_DB_RECORDTYPE itemID, SecKeychainAttributeInfo **Info);
static void freeAttributeInfo(SecKeychainAttributeInfo *Info);
KeychainSchema keychainSchema();
void resetSchema();
void didDeleteItem(const ItemImpl *inItemImpl);
private:
void addItem(const PrimaryKey &primaryKey, ItemImpl *dbItemImpl);
void removeItem(const PrimaryKey &primaryKey, const ItemImpl *inItemImpl);
CssmClient::Db mDb;
Mutex mDbItemMapLock;
typedef map<PrimaryKey, ItemImpl *> DbItemMap;
DbItemMap mDbItemMap;
KeychainSchema mKeychainSchema;
};
class Keychain : public SecPointer<KeychainImpl>
{
public:
Keychain() {}
Keychain(KeychainImpl *impl) : SecPointer<KeychainImpl>(impl) {}
static Keychain optional(SecKeychainRef handle);
private:
friend class StorageManager;
Keychain(const CssmClient::Db &db)
: SecPointer<KeychainImpl>(new KeychainImpl(db)) {}
typedef KeychainImpl Impl;
};
}
}
#endif // !_SECURITY_KEYCHAINS_H_