2 * Copyright (c) 2000-2004,2011-2014 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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.
21 * @APPLE_LICENSE_HEADER_END@
28 #ifndef _SECURITY_ITEM_H_
29 #define _SECURITY_ITEM_H_
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>
39 using namespace CssmClient
;
41 namespace KeychainCore
45 class ItemImpl
: public SecCFObject
48 SECCFFUNCTIONS_CREATABLE(ItemImpl
, SecKeychainItemRef
, gTypes().ItemImpl
)
50 static ItemImpl
*required(SecKeychainItemRef ptr
);
51 static ItemImpl
*optional(SecKeychainItemRef ptr
);
54 friend class KeychainImpl
;
57 // new item constructors
58 ItemImpl(SecItemClass itemClass
, OSType itemCreator
, UInt32 length
, const void* data
, bool inhibitCheck
= false);
60 ItemImpl(SecItemClass itemClass
, SecKeychainAttributeList
*attrList
, UInt32 length
, const void* data
);
62 // db item constructor
63 ItemImpl(const Keychain
&keychain
, const PrimaryKey
&primaryKey
, const CssmClient::DbUniqueRecord
&uniqueId
);
65 // PrimaryKey item constructor
66 ItemImpl(const Keychain
&keychain
, const PrimaryKey
&primaryKey
);
70 static ItemImpl
* make(const Keychain
&keychain
, const PrimaryKey
&primaryKey
, const CssmClient::DbUniqueRecord
&uniqueId
);
71 static ItemImpl
* make(const Keychain
&keychain
, const PrimaryKey
&primaryKey
);
73 ItemImpl(ItemImpl
&item
);
75 // Return true if we got the attribute, false if we only got the actualLength.
76 void getAttributeFrom(CssmDbAttributeData
*data
, SecKeychainAttribute
&attr
, UInt32
*actualLength
);
77 void getClass(SecKeychainAttribute
&attr
, UInt32
*actualLength
);
80 void setPersistentRef(CFDataRef ref
);
81 // returns NULL for securityd keys, or the (non-NULL) persistent ref for iOS keys
82 CFDataRef
getPersistentRef();
84 PrimaryKey
addWithCopyInfo(Keychain
&keychain
, bool isCopy
);
85 Mutex
* getMutexForObject() const;
87 // Return true iff the item integrity has not been compromised.
88 virtual bool checkIntegrity();
89 bool checkIntegrity(AclBearer
& key
);
90 static bool checkIntegrityFromDictionary(AclBearer
& key
, DbAttributes
* dbAttributes
);
93 // Methods called by KeychainImpl;
95 // Add the receiver to keychain
96 virtual PrimaryKey
add(Keychain
&keychain
);
98 // Prepare a dbAttributes to extract all possible attributes with a call to
100 void fillDbAttributesFromSchema(DbAttributes
& dbAttributes
, CSSM_DB_RECORDTYPE recordType
, Keychain keychain
= NULL
);
102 // Get all current attributes of this item. This will call out to the
103 // database (if there is one) and then overly the current pending updates.
104 // You must delete the returned object.
105 DbAttributes
* getCurrentAttributes();
107 // Return a canonical form of this item's attributes
108 void encodeAttributes(CssmOwnedData
&attributeBlob
);
110 // Return a canonical form of the attributes passed in
111 static void encodeAttributesFromDictionary(CssmOwnedData
&attributeBlob
, DbAttributes
* dbAttributes
);
113 // Return a canonical digest of the record type and attributes of the item
114 void computeDigest(CssmOwnedData
&sha2
);
116 // Return a canonical digest of the record type and attributes passed in
117 static void computeDigestFromDictionary(CssmOwnedData
&sha2
, DbAttributes
* dbAttributes
);
119 // Get the default value for an attribute
120 static const CSSM_DATA
&defaultAttributeValue(const CSSM_DB_ATTRIBUTE_INFO
&info
);
127 virtual void update();
129 void aboutToDestruct();
131 // put a copy of the item into a given keychain
132 virtual Item
copyTo(const Keychain
&keychain
, Access
*newAccess
= NULL
);
134 CSSM_DB_RECORDTYPE
recordType();
136 // Used for writing the record to the database.
137 CssmClient::DbUniqueRecord
dbUniqueRecord();
138 const CssmClient::DbAttributes
*modifiedAttributes();
139 const CssmData
*modifiedData();
140 virtual void didModify(); // Forget any attributes and data we just wrote to the db
143 PrimaryKey
primaryKey();
144 bool operator < (const ItemImpl
&other
);
146 void getAttribute(SecKeychainAttribute
& attr
, UInt32
*actualLength
);
147 void getData(CssmDataContainer
& outData
);
149 void modifyContent(const SecKeychainAttributeList
*attrList
, UInt32 dataLength
, const void *inData
);
150 void getContent(SecItemClass
*itemClass
, SecKeychainAttributeList
*attrList
, UInt32
*length
, void **outData
);
151 static void freeContent(SecKeychainAttributeList
*attrList
, void *data
);
152 static void freeAttributesAndData(SecKeychainAttributeList
*attrList
, void *data
);
154 void getAttributesAndData(SecKeychainAttributeInfo
*info
, SecItemClass
*itemClass
,
155 SecKeychainAttributeList
**attrList
, UInt32
*length
, void **outData
);
156 void modifyAttributesAndData(const SecKeychainAttributeList
*attrList
, UInt32 dataLength
, const void *inData
);
158 void setAttribute(SecKeychainAttribute
& attr
);
159 void setAttribute(const CssmDbAttributeInfo
&info
, const CssmPolyData
&data
);
160 void setData(UInt32 length
,const void *data
);
161 void setAccess(Access
*newAccess
);
162 void copyRecordIdentifier(CSSM_DATA
&data
);
165 void getContent(DbAttributes
*dbAttributes
, CssmDataContainer
*itemData
);
166 void getLocalContent(SecKeychainAttributeList
*attributeList
, UInt32
*outLength
, void **outData
);
168 bool useSecureStorage(const CssmClient::Db
&db
);
169 virtual void willRead();
171 // create a persistent reference to this item
172 void copyPersistentReference(CFDataRef
&outDataRef
, bool isSecIdentityRef
=false);
173 static Item
makeFromPersistentReference(const CFDataRef persistentRef
, bool *isIdentityRef
=NULL
);
175 // for keychain syncing
176 void doNotEncrypt () {mDoNotEncrypt
= true;}
178 // for posting events on this item
179 void postItemEvent (SecKeychainEvent theEvent
);
181 // Only call these functions while holding globals().apiLock.
182 bool inCache() const _NOEXCEPT
{ return mInCache
; }
183 void inCache(bool inCache
) _NOEXCEPT
{ mInCache
= inCache
; }
185 /* For binding to extended attributes. */
186 virtual const CssmData
&itemID();
188 /* Overrides for SecCFObject methods */
189 bool equal(SecCFObject
&other
);
190 virtual CFHashCode
hash();
196 /* Saves the item with a new SSGroup and ACL. If you pass in an old SSGroup,
197 * the ACL will be copied from the old group, and the old group deleted. */
198 void updateSSGroup(Db
& db
, CSSM_DB_RECORDTYPE recordType
, CssmDataContainer
* data
, Keychain keychain
= NULL
, SecPointer
<Access
> access
= NULL
);
200 // Helper function to abstract out error handling. Does not report any errors.
201 void deleteSSGroup(SSGroup
& ssgroup
, const AccessCredentials
* nullCred
);
203 void doChange(Keychain keychain
, CSSM_DB_RECORDTYPE recordType
, void (^tryChange
) () );
205 // Add integrity acl entry to access.
206 void addIntegrity(Access
&access
, bool force
= false);
208 // Set the integrity of this item to whatever my attributes are now
209 // If force, then perform this even if the underlying keychain claims to not
210 // support it. (This is needed because during an upgrade, the underlying
211 // keychain is confused about its actual version until it's written to disk.)
212 virtual void setIntegrity(bool force
= false);
214 // Set the integrity of this bearer to be whatever my attributes are now
215 virtual void setIntegrity(AclBearer
&bearer
, bool force
= false);
217 // Call this function to remove the integrity and partition_id ACLs from
218 // this item. You're not supposed to be able to do this, so force the issue
219 // by providing credentials to this keychain.
220 virtual void removeIntegrity(const AccessCredentials
*cred
);
221 virtual void removeIntegrity(AclBearer
&bearer
, const AccessCredentials
*cred
);
224 RefPointer
<CssmDataContainer
> mData
;
225 unique_ptr
<CssmClient::DbAttributes
> mDbAttributes
;
226 SecPointer
<Access
> mAccess
;
229 CssmClient::DbUniqueRecord mUniqueId
;
231 PrimaryKey mPrimaryKey
;
233 // non-NULL only for secd items (managed by secd, not securityd)
234 CFDataRef secd_PersistentRef
;
237 // keychain syncing flags
240 // mInCache is protected by globals().apiLock
241 // True iff we are in the cache of items in mKeychain
249 class Item
: public SecPointer
<ItemImpl
>
253 Item(ItemImpl
*impl
);
254 Item(SecItemClass itemClass
, OSType itemCreator
, UInt32 length
, const void* data
, bool inhibitCheck
);
255 Item(SecItemClass itemClass
, SecKeychainAttributeList
*attrList
, UInt32 length
, const void* data
);
256 Item(const Keychain
&keychain
, const PrimaryKey
&primaryKey
, const CssmClient::DbUniqueRecord
&uniqueId
);
257 Item(const Keychain
&keychain
, const PrimaryKey
&primaryKey
);
258 Item(ItemImpl
&item
);
262 CFIndex
GetItemRetainCount(Item
& item
);
264 } // end namespace KeychainCore
266 } // end namespace Security
270 #endif // !_SECURITY_ITEM_H_