1/*
2 * Copyright (c) 2000-2004,2012-2013 Apple Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24
25//
26// Item.h
27//
28#ifndef _SECURITY_ITEM_H_
29#define _SECURITY_ITEM_H_
30
31#include <security_keychain/Keychains.h>
32#include <security_keychain/PrimaryKey.h>
33#include <security_cdsa_client/securestorage.h>
34#include <security_keychain/Access.h>
35
36namespace Security
37{
38
39using namespace CssmClient;
40
41namespace KeychainCore
42{
43class Keychain;
44
45class ItemImpl : public SecCFObject
46{
47public:
48	SECCFFUNCTIONS(ItemImpl, SecKeychainItemRef, errSecInvalidItemRef, gTypes().ItemImpl)
49
50    friend class Item;
51	friend class KeychainImpl;
52protected:
53
54	// new item constructors
55    ItemImpl(SecItemClass itemClass, OSType itemCreator, UInt32 length, const void* data, bool inhibitCheck = false);
56
57	ItemImpl(SecItemClass itemClass, SecKeychainAttributeList *attrList, UInt32 length, const void* data);
58
59	// db item constructor
60    ItemImpl(const Keychain &keychain, const PrimaryKey &primaryKey, const CssmClient::DbUniqueRecord &uniqueId);
61
62	// PrimaryKey item constructor
63    ItemImpl(const Keychain &keychain, const PrimaryKey &primaryKey);
64
65public:
66
67	static ItemImpl* make(const Keychain &keychain, const PrimaryKey &primaryKey, const CssmClient::DbUniqueRecord &uniqueId);
68	static ItemImpl* make(const Keychain &keychain, const PrimaryKey &primaryKey);
69
70	ItemImpl(ItemImpl &item);
71
72	// Return true if we got the attribute, false if we only got the actualLength.
73	void getAttributeFrom(CssmDbAttributeData *data, SecKeychainAttribute &attr,  UInt32 *actualLength);
74	void getClass(SecKeychainAttribute &attr,  UInt32 *actualLength);
75
76	// For iOS keys
77	void setPersistentRef(CFDataRef ref);
78	// returns NULL for securityd keys, or the (non-NULL) persistent ref for iOS keys
79	CFDataRef getPersistentRef();
80
81	PrimaryKey addWithCopyInfo(Keychain &keychain, bool isCopy);
82	Mutex* getMutexForObject();
83
84protected:
85	// Methods called by KeychainImpl;
86
87	// Add the receiver to keychain
88	virtual PrimaryKey add(Keychain &keychain);
89
90	// Get the default value for an attribute
91	static const CSSM_DATA &defaultAttributeValue(const CSSM_DB_ATTRIBUTE_INFO &info);
92
93public:
94    virtual ~ItemImpl();
95    bool isPersistent();
96    bool isModified();
97
98	virtual void update();
99
100	void aboutToDestruct();
101
102	// put a copy of the item into a given keychain
103	virtual Item copyTo(const Keychain &keychain, Access *newAccess = NULL);
104
105    CSSM_DB_RECORDTYPE recordType();
106
107	// Used for writing the record to the database.
108    CssmClient::DbUniqueRecord dbUniqueRecord();
109	const CssmClient::DbAttributes *modifiedAttributes();
110	const CssmData *modifiedData();
111	virtual void didModify(); // Forget any attributes and data we just wrote to the db
112
113	Keychain keychain();
114	PrimaryKey primaryKey();
115	bool operator < (const ItemImpl &other);
116
117	void getAttribute(SecKeychainAttribute& attr,  UInt32 *actualLength);
118	void getData(CssmDataContainer& outData);
119
120	void modifyContent(const SecKeychainAttributeList *attrList, UInt32 dataLength, const void *inData);
121	void getContent(SecItemClass *itemClass, SecKeychainAttributeList *attrList, UInt32 *length, void **outData);
122	static void freeContent(SecKeychainAttributeList *attrList, void *data);
123	static void freeAttributesAndData(SecKeychainAttributeList *attrList, void *data);
124
125	void getAttributesAndData(SecKeychainAttributeInfo *info, SecItemClass *itemClass,
126							  SecKeychainAttributeList **attrList, UInt32 *length, void **outData);
127	void modifyAttributesAndData(const SecKeychainAttributeList *attrList, UInt32 dataLength, const void *inData);
128
129	void setAttribute(SecKeychainAttribute& attr);
130	void setAttribute(const CssmDbAttributeInfo &info, const CssmPolyData &data);
131	void setData(UInt32 length,const void *data);
132	void setAccess(Access *newAccess);
133	void copyRecordIdentifier(CSSM_DATA &data);
134	SSGroup group();
135
136    void getContent(DbAttributes *dbAttributes, CssmDataContainer *itemData);
137    void getLocalContent(SecKeychainAttributeList *attributeList, UInt32 *outLength, void **outData);
138
139    bool useSecureStorage(const CssmClient::Db &db);
140	virtual void willRead();
141
142    // create a persistent reference to this item
143    void copyPersistentReference(CFDataRef &outDataRef, bool isSecIdentityRef=false);
144	static Item makeFromPersistentReference(const CFDataRef persistentRef, bool *isIdentityRef=NULL);
145
146	// for keychain syncing
147	void doNotEncrypt () {mDoNotEncrypt = true;}
148
149	// for posting events on this item
150	void postItemEvent (SecKeychainEvent theEvent);
151
152	// Only call these functions while holding globals().apiLock.
153	bool inCache() const throw() { return mInCache; }
154	void inCache(bool inCache) throw() { mInCache = inCache; }
155
156	/* For binding to extended attributes. */
157	virtual const CssmData &itemID();
158
159	/* Overrides for SecCFObject methods */
160	bool equal(SecCFObject &other);
161    virtual CFHashCode hash();
162
163    bool mayDelete();
164
165protected:
166	// new item members
167	RefPointer<CssmDataContainer> mData;
168	auto_ptr<CssmClient::DbAttributes> mDbAttributes;
169	SecPointer<Access> mAccess;
170
171	// db item members
172	CssmClient::DbUniqueRecord mUniqueId;
173	Keychain mKeychain;
174	PrimaryKey mPrimaryKey;
175
176	// non-NULL only for secd items (managed by secd, not securityd)
177	CFDataRef secd_PersistentRef;
178
179private:
180	// keychain syncing flags
181	bool mDoNotEncrypt;
182
183	// mInCache is protected by globals().apiLock
184	// True iff we are in the cache of items in mKeychain
185	bool mInCache;
186
187protected:
188	Mutex mMutex;
189};
190
191
192class Item : public SecPointer<ItemImpl>
193{
194public:
195    Item();
196    Item(ItemImpl *impl);
197    Item(SecItemClass itemClass, OSType itemCreator, UInt32 length, const void* data, bool inhibitCheck);
198	Item(SecItemClass itemClass, SecKeychainAttributeList *attrList, UInt32 length, const void* data);
199    Item(const Keychain &keychain, const PrimaryKey &primaryKey, const CssmClient::DbUniqueRecord &uniqueId);
200    Item(const Keychain &keychain, const PrimaryKey &primaryKey);
201	Item(ItemImpl &item);
202};
203
204
205CFIndex GetItemRetainCount(Item& item);
206
207} // end namespace KeychainCore
208
209} // end namespace Security
210
211
212
213#endif // !_SECURITY_ITEM_H_
214