X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/80e2389990082500d76eb566d4946be3e786c3ef..d8f41ccd20de16f8ebe2ccc84d47bf1cb2b26bbb:/Security/libsecurity_keychain/lib/Keychains.h?ds=inline diff --git a/Security/libsecurity_keychain/lib/Keychains.h b/Security/libsecurity_keychain/lib/Keychains.h new file mode 100644 index 00000000..df870843 --- /dev/null +++ b/Security/libsecurity_keychain/lib/Keychains.h @@ -0,0 +1,267 @@ +/* + * Copyright (c) 2000-2004,2011-2014 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +// +// Keychains.h - The Keychain class +// +#ifndef _SECURITY_KEYCHAINS_H_ +#define _SECURITY_KEYCHAINS_H_ + +#include +#include +#include +#include +#include +#include +#include +#include "SecCFTypes.h" +#include "defaultcreds.h" + +class EventBuffer; + +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: + virtual ~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; + bool hasRecordType(CSSM_DB_RECORDTYPE recordType) const; + + void didCreateRelation(CSSM_DB_RECORDTYPE inRelationID, + const char *inRelationName, + uint32 inNumberOfAttributes, + const CSSM_DB_SCHEMA_ATTRIBUTE_INFO *pAttributeInfo, + uint32 inNumberOfIndexes, + const CSSM_DB_SCHEMA_INDEX_INFO *pIndexInfo); + +private: + typedef map PrimaryKeyInfoMap; + PrimaryKeyInfoMap mPrimaryKeyInfoMap; + + typedef map RelationInfoMap; + typedef map DatabaseInfoMap; + DatabaseInfoMap mDatabaseInfoMap; + Mutex mMutex; + +private: + const RelationInfoMap &relationInfoMapFor(CSSM_DB_RECORDTYPE recordType) const; +}; + + +class KeychainSchema : public RefPointer +{ +public: + KeychainSchema() {} + KeychainSchema(KeychainSchemaImpl *impl) : RefPointer(impl) {} + KeychainSchema(const CssmClient::Db &db) : RefPointer(new KeychainSchemaImpl(db)) {} + ~KeychainSchema(); + + 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 ItemImpl; + +class KeychainImpl : public SecCFObject, private CssmClient::Db::DefaultCredentialsMaker +{ + NOCOPY(KeychainImpl) +public: + SECCFFUNCTIONS(KeychainImpl, SecKeychainRef, errSecInvalidKeychain, gTypes().KeychainImpl) + + friend class Keychain; + friend class ItemImpl; +protected: + KeychainImpl(const CssmClient::Db &db); + +protected: + // Methods called by ItemImpl; + void didUpdate(const Item &inItem, PrimaryKey &oldPK, + PrimaryKey &newPK); + void completeAdd(Item &item, PrimaryKey &key); + +public: + virtual ~KeychainImpl(); + + Mutex* getKeychainMutex(); + Mutex* getMutexForObject(); + void aboutToDestruct(); + + bool operator ==(const KeychainImpl &) const; + + // Item calls + void add(Item &item); + void addCopy(Item &item); + void deleteItem(Item &item); // item must be persistant. + + // Keychain calls + void create(UInt32 passwordLength, const void *inPassword); + void createWithBlob(CssmData &blob); + void create(ConstStringPtr inPassword); + void create(); + void create(const ResourceControlContext *rcc); + void open(); + + // Locking and unlocking a keychain. + void lock(); + void unlock(); + void unlock(const CssmData &password); + void unlock(ConstStringPtr password); // @@@ This has a length limit, we should remove it. + void stash(); + void stashCheck(); + + void getSettings(uint32 &outIdleTimeOut, bool &outLockOnSleep); + void setSettings(uint32 inIdleTimeOut, bool inLockOnSleep); + + // Passing in NULL for either oldPassword or newPassword will cause them to be prompted for. + // To specify a zero length password in either case the oldPasswordLength or newPasswordLength + // value must be 0 and the oldPassword or newPassword must not be NULL. + 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); // Does not do an unlock. + + 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(ItemImpl *inItemImpl); + + void recode(const CssmData &data, const CssmData &extraData); + void copyBlob(CssmData &dbBlob); + + void setBatchMode(Boolean mode, Boolean rollBack); + + // yield default open() credentials for this keychain (as of now) + const AccessCredentials *defaultCredentials(); + + // Only call these functions while holding globals().apiLock. + bool inCache() const throw() { return mInCache; } + void inCache(bool inCache) throw() { mInCache = inCache; } + + void postEvent(SecKeychainEvent kcEvent, ItemImpl* item); + + void addItem(const PrimaryKey &primaryKey, ItemImpl *dbItemImpl); + + bool mayDelete(); + +private: + void removeItem(const PrimaryKey &primaryKey, ItemImpl *inItemImpl); + ItemImpl *_lookupItem(const PrimaryKey &primaryKey); + + const AccessCredentials *makeCredentials(); + + typedef map DbItemMap; + // Weak reference map of all items we know about that have a primaryKey + DbItemMap mDbItemMap; + // True iff we are in the cache of keychains in StorageManager + bool mInCache; + + CssmClient::Db mDb; + + KeychainSchema mKeychainSchema; + + // Data for auto-unlock credentials + DefaultCredentials mCustomUnlockCreds; + bool mIsInBatchMode; + EventBuffer *mEventBuffer; + Mutex mMutex; +}; + + +CFIndex GetKeychainRetainCount(Keychain& kc); + +class Keychain : public SecPointer +{ +public: + Keychain(); + Keychain(KeychainImpl *impl) : SecPointer(impl) {} + ~Keychain(); + + static Keychain optional(SecKeychainRef handle); + +private: + friend class StorageManager; + Keychain(const CssmClient::Db &db) + : SecPointer(new KeychainImpl(db)) {} + + typedef KeychainImpl Impl; +}; + + +} // end namespace KeychainCore + +} // end namespace Security + +#endif // !_SECURITY_KEYCHAINS_H_