2 * Copyright (c) 2012 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@
26 The functions provided in SecDbItem provide an interface to
27 database items (certificates, keys, identities, and passwords).
30 #ifndef _SECURITYD_SECDBITEM_H_
31 #define _SECURITYD_SECDBITEM_H_
33 #include <CoreFoundation/CoreFoundation.h>
34 #include <TargetConditionals.h>
35 #include <corecrypto/ccsha1.h> // For CCSHA1_OUTPUT_SIZE
37 #include <utilities/SecCFError.h>
38 #include <utilities/SecCFWrappers.h>
39 #include <utilities/SecDb.h>
40 #include <utilities/SecAKSWrappers.h>
42 #if TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_IPHONE_SIMULATOR)
43 #define USE_KEYSTORE 1
44 #elif TARGET_OS_EMBEDDED && !TARGET_IPHONE_SIMULATOR
45 #define USE_KEYSTORE 1
46 #else /* no keystore on this platform */
47 #define USE_KEYSTORE 0
51 #include <Kernel/IOKit/crypto/AppleKeyStoreDefs.h>
52 #endif /* USE_KEYSTORE */
56 // TODO: Get this out of this file
58 typedef int32_t keyclass_t
;
61 /* TODO: this needs to be available in the sim! */
62 #define kAppleKeyStoreKeyWrap 0
63 #define kAppleKeyStoreKeyUnwrap 1
64 typedef int32_t keyclass_t
;
65 typedef int32_t key_handle_t
;
74 #endif /* !USE_KEYSTORE */
76 // MARK SecDbAttrKind, SecDbFlag
79 kSecDbBlobAttr
, // CFString or CFData, preserves caller provided type.
84 kSecDbCreationDateAttr
,
85 kSecDbModificationDateAttr
,
88 kSecDbEncryptedDataAttr
,
96 kSecDbPrimaryKeyFlag
= (1 << 0), // attr is part of primary key
97 kSecDbInFlag
= (1 << 1), // attr exists in db
98 kSecDbIndexFlag
= (1 << 2), // attr should have a db index
99 kSecDbSHA1ValueInFlag
= (1 << 3), // col in db is sha1 of attr value
100 kSecDbReturnAttrFlag
= (1 << 4),
101 kSecDbReturnDataFlag
= (1 << 5),
102 kSecDbReturnRefFlag
= (1 << 6),
103 kSecDbInCryptoDataFlag
= (1 << 7),
104 kSecDbInHashFlag
= (1 << 8),
105 kSecDbInBackupFlag
= (1 << 9),
106 kSecDbDefault0Flag
= (1 << 10), // default attr value is 0
107 kSecDbDefaultEmptyFlag
= (1 << 11), // default attr value is ""
108 kSecDbNotNullFlag
= (1 << 12), // attr value can't be null
111 #define SecVersionDbFlag(v) ((v & 0xFF) << 8)
113 #define SecDbFlagGetVersion(flags) ((flags >> 8) & 0xFF)
115 #define SECDB_ATTR(var, name, kind, flags) const SecDbAttr var = { CFSTR(name), kSecDb ## kind ## Attr, flags }
117 typedef struct SecDbAttr
{
123 typedef struct SecDbClass
{
125 const SecDbAttr
*attrs
[];
128 typedef struct Pair
*SecDbPairRef
;
129 typedef struct Query
*SecDbQueryRef
;
132 typedef uint32_t ReturnTypeMask
;
135 kSecReturnDataMask
= 1 << 0,
136 kSecReturnAttributesMask
= 1 << 1,
137 kSecReturnRefMask
= 1 << 2,
138 kSecReturnPersistentRefMask
= 1 << 3,
141 /* Constant indicating there is no limit to the number of results to return. */
144 kSecMatchUnlimited
= kCFNotFound
153 /* Nothing in this struct is retained since all the
154 values below are extracted from the dictionary passed in by the
158 /* Class of this query. */
159 const SecDbClass
*q_class
;
161 /* Dictionary with all attributes and values in clear (to be encrypted). */
162 CFMutableDictionaryRef q_item
;
164 /* q_pairs is an array of Pair structs. Elements with indices
165 [0, q_attr_end) contain attribute key value pairs. Elements with
166 indices [q_match_begin, q_match_end) contain match key value pairs.
167 Thus q_attr_end is the number of attrs in q_pairs and
168 q_match_begin - q_match_end is the number of matches in q_pairs. */
169 CFIndex q_match_begin
;
174 ReturnTypeMask q_return_type
;
178 sqlite_int64 q_row_id
;
180 CFArrayRef q_use_item_list
;
181 CFBooleanRef q_use_tomb
;
182 #if defined(MULTIPLE_KEYCHAINS)
183 CFArrayRef q_use_keychain
;
184 CFArrayRef q_use_keychain_list
;
185 #endif /* !defined(MULTIPLE_KEYCHAINS) */
187 /* Value of kSecMatchLimit key if present. */
190 /* True if query contained a kSecAttrSynchronizable attribute,
191 * regardless of its actual value. If this is false, then we
192 * will add an explicit sync=0 to the query. */
195 // Set to true if we modified any item as part of executing this query
198 // Set to true if we modified any synchronizable item as part of executing this query
201 /* Keybag handle to use for this item. */
202 keybag_handle_t q_keybag
;
203 keyclass_t q_keyclass
;
204 //CFStringRef q_keyclass_s;
206 // SHA1 digest of DER encoded primary key
207 CFDataRef q_primary_key_digest
;
209 CFArrayRef q_match_issuer
;
211 /* Store all the corrupted rows found during the query */
212 CFMutableArrayRef corrupted_rows
;
218 #define SecDbForEachAttr(class, attr) for (const SecDbAttr * const* _pattr = (class)->attrs, *attr = *_pattr; attr; attr = *(++_pattr))
220 #define SecDbForEachAttrWithMask(class, attr, flag_mask) SecDbForEachAttr(class, attr) if ((attr->flags & (flag_mask)) == (flag_mask))
222 // MARK: Stuff that needs to move out of SecItemServer.c
224 // Move this or do crypto in a block
225 bool ks_encrypt_data(keybag_handle_t keybag
, keyclass_t keyclass
, CFDataRef plainText
, CFDataRef
*pBlob
, CFErrorRef
*error
);
226 bool ks_decrypt_data(keybag_handle_t keybag
, keyclass_t
*pkeyclass
, CFDataRef blob
, CFDataRef
*pPlainText
,
227 uint32_t *version_p
, CFErrorRef
*error
);
229 CFDataRef
kc_copy_sha1(size_t len
, const void *data
, CFErrorRef
*error
);
230 CFDataRef
kc_copy_plist_sha1(CFPropertyListRef plist
, CFErrorRef
*error
);
231 CFDataRef
kc_plist_copy_der(CFPropertyListRef plist
, CFErrorRef
*error
);
232 Query
*query_create(const SecDbClass
*qclass
, CFDictionaryRef query
, CFErrorRef
*error
);
233 bool query_destroy(Query
*q
, CFErrorRef
*error
);
237 typedef struct SecDbItem
*SecDbItemRef
;
239 enum SecDbItemState
{
240 kSecDbItemDirty
, // We have no edata (or if we do it's invalid), attributes are the truth
241 kSecDbItemEncrypted
, // Attributes haven't been decrypted yet from edata
242 kSecDbItemClean
, // Attributes and _edata are in sync.
243 kSecDbItemDecrypting
, // Temporary state while we are decrypting so set knows not to blow away the edata.
244 kSecDbItemEncrypting
, // Temporary state while we are encrypting so set knows to move to clean.
249 const SecDbClass
*class;
251 keybag_handle_t keybag
;
252 //sqlite3_int64 _rowid;
253 //CFDataRef _primaryKey;
256 enum SecDbItemState _edataState
;
257 CFMutableDictionaryRef attributes
;
260 // TODO: Make this a callback to client
261 bool SecDbItemDecrypt(SecDbItemRef item
, CFDataRef edata
, CFErrorRef
*error
);
263 CFTypeID
SecDbItemGetTypeID(void);
265 static inline size_t SecDbClassAttrCount(const SecDbClass
*dbClass
) {
267 SecDbForEachAttr(dbClass
, attr
) { n_attrs
++; }
271 const SecDbAttr
*SecDbClassAttrWithKind(const SecDbClass
*class, SecDbAttrKind kind
, CFErrorRef
*error
);
273 SecDbItemRef
SecDbItemCreateWithAttributes(CFAllocatorRef allocator
, const SecDbClass
*class, CFDictionaryRef attributes
, keybag_handle_t keybag
, CFErrorRef
*error
);
275 const SecDbClass
*SecDbItemGetClass(SecDbItemRef item
);
276 const keybag_handle_t
SecDbItemGetKeybag(SecDbItemRef item
);
277 bool SecDbItemSetKeybag(SecDbItemRef item
, keybag_handle_t keybag
, CFErrorRef
*error
);
278 keyclass_t
SecDbItemGetKeyclass(SecDbItemRef item
, CFErrorRef
*error
);
279 bool SecDbItemSetKeyclass(SecDbItemRef item
, keyclass_t keyclass
, CFErrorRef
*error
);
281 CFTypeRef
SecDbItemGetCachedValueWithName(SecDbItemRef item
, CFStringRef name
);
282 CF_RETURNS_NOT_RETAINED CFTypeRef
SecDbItemGetValue(SecDbItemRef item
, const SecDbAttr
*desc
, CFErrorRef
*error
);
284 bool SecDbItemSetValue(SecDbItemRef item
, const SecDbAttr
*desc
, CFTypeRef value
, CFErrorRef
*error
);
285 bool SecDbItemSetValues(SecDbItemRef item
, CFDictionaryRef values
, CFErrorRef
*error
);
286 bool SecDbItemSetValueWithName(SecDbItemRef item
, CFStringRef name
, CFTypeRef value
, CFErrorRef
*error
);
288 sqlite3_int64
SecDbItemGetRowId(SecDbItemRef item
, CFErrorRef
*error
);
289 bool SecDbItemSetRowId(SecDbItemRef item
, sqlite3_int64 rowid
, CFErrorRef
*error
);
291 bool SecDbItemIsSyncable(SecDbItemRef item
);
293 bool SecDbItemSetSyncable(SecDbItemRef item
, bool sync
, CFErrorRef
*error
);
295 bool SecDbItemIsTombstone(SecDbItemRef item
);
297 CFMutableDictionaryRef
SecDbItemCopyPListWithMask(SecDbItemRef item
, CFOptionFlags mask
, CFErrorRef
*error
);
299 CFDataRef
SecDbItemGetPrimaryKey(SecDbItemRef item
, CFErrorRef
*error
);
300 CFDataRef
SecDbItemGetSHA1(SecDbItemRef item
, CFErrorRef
*error
);
302 CFDataRef
SecDbItemCopyEncryptedDataToBackup(SecDbItemRef item
, uint64_t handle
, CFErrorRef
*error
);
304 SecDbItemRef
SecDbItemCreateWithStatement(CFAllocatorRef allocator
, const SecDbClass
*class, sqlite3_stmt
*stmt
, keybag_handle_t keybag
, CFErrorRef
*error
, bool (^return_attr
)(const SecDbAttr
*attr
));
306 SecDbItemRef
SecDbItemCreateWithEncryptedData(CFAllocatorRef allocator
, const SecDbClass
*class,
307 CFDataRef edata
, keybag_handle_t keybag
, CFErrorRef
*error
);
309 SecDbItemRef
SecDbItemCreateWithPrimaryKey(CFAllocatorRef allocator
, const SecDbClass
*class, CFDataRef primary_key
);
312 SecDbItemRef
SecDbItemCreateWithRowId(CFAllocatorRef allocator
, const SecDbClass
*class, sqlite_int64 row_id
, keybag_handle_t keybag
, CFErrorRef
*error
);
315 SecDbItemRef
SecDbItemCopyWithUpdates(SecDbItemRef item
, CFDictionaryRef updates
, CFErrorRef
*error
);
317 SecDbItemRef
SecDbItemCopyTombstone(SecDbItemRef item
, CFErrorRef
*error
);
319 bool SecDbItemInsertOrReplace(SecDbItemRef item
, SecDbConnectionRef dbconn
, CFErrorRef
*error
, void(^duplicate
)(SecDbItemRef item
, SecDbItemRef
*replace
));
321 bool SecDbItemInsert(SecDbItemRef item
, SecDbConnectionRef dbconn
, CFErrorRef
*error
);
323 bool SecDbItemDelete(SecDbItemRef item
, SecDbConnectionRef dbconn
, bool makeTombstone
, CFErrorRef
*error
);
325 // Low level update, just do the update
326 bool SecDbItemDoUpdate(SecDbItemRef old_item
, SecDbItemRef new_item
, SecDbConnectionRef dbconn
, CFErrorRef
*error
, bool (^use_attr_in_where
)(const SecDbAttr
*attr
));
328 // High level update, will replace tombstones and create them if needed.
329 bool SecDbItemUpdate(SecDbItemRef old_item
, SecDbItemRef new_item
, SecDbConnectionRef dbconn
, bool makeTombstone
, CFErrorRef
*error
);
331 bool SecDbItemSelect(SecDbQueryRef query
, SecDbConnectionRef dbconn
, CFErrorRef
*error
,
332 bool (^use_attr_in_where
)(const SecDbAttr
*attr
),
333 bool (^add_where_sql
)(CFMutableStringRef sql
, bool *needWhere
),
334 bool (^bind_added_where
)(sqlite3_stmt
*stmt
, int col
),
335 void (^handle_row
)(SecDbItemRef item
, bool *stop
));
337 CFStringRef
SecDbItemCopySelectSQL(SecDbQueryRef query
,
338 bool (^return_attr
)(const SecDbAttr
*attr
),
339 bool (^use_attr_in_where
)(const SecDbAttr
*attr
),
340 bool (^add_where_sql
)(CFMutableStringRef sql
, bool *needWhere
));
341 bool SecDbItemSelectBind(SecDbQueryRef query
, sqlite3_stmt
*stmt
, CFErrorRef
*error
,
342 bool (^use_attr_in_where
)(const SecDbAttr
*attr
),
343 bool (^bind_added_where
)(sqlite3_stmt
*stmt
, int col
));
347 // MARK: SQL Construction helpers -- These should become private in the future
349 void SecDbAppendElement(CFMutableStringRef sql
, CFStringRef value
, bool *needComma
);
350 void SecDbAppendWhereOrAnd(CFMutableStringRef sql
, bool *needWhere
);
351 void SecDbAppendWhereOrAndEquals(CFMutableStringRef sql
, CFStringRef col
, bool *needWhere
);
354 // MARK: SecItemDb (a SecDb of SecDbItems)
356 typedef struct SecItemDb
*SecItemDbRef
;
357 typedef struct SecItemDbConnection
*SecItemDbConnectionRef
;
362 CFDictionaryRef classes
; // className -> SecItemClass mapping
365 struct SecItemDbConnection
{
366 SecDbConnectionRef db
;
369 SecItemDbRef
SecItemDbCreate(SecDbRef db
);
370 SecItemDbRef
SecItemDbRegisterClass(SecItemDbRef db
, const SecDbClass
*class, void(^upgrade
)(SecDbItemRef item
, uint32_t current_version
));
372 SecItemDbConnectionRef
SecItemDbAquireConnection(SecItemDbRef db
);
373 void SecItemDbReleaseConnection(SecItemDbRef db
, SecItemDbConnectionRef dbconn
);
375 bool SecItemDbInsert(SecItemDbConnectionRef dbconn
, SecDbItemRef item
, CFErrorRef
*error
);
377 bool SecItemDbDelete(SecItemDbConnectionRef dbconn
, SecDbItemRef item
, CFErrorRef
*error
);
379 // Low level update, just do the update
380 bool SecItemDbDoUpdate(SecItemDbConnectionRef dbconn
, SecDbItemRef old_item
, SecDbItemRef new_item
, CFErrorRef
*error
,
381 bool (^use_attr_in_where
)(const SecDbAttr
*attr
));
383 // High level update, will replace tombstones and create them if needed.
384 bool SecItemDbUpdate(SecItemDbConnectionRef dbconn
, SecDbItemRef old_item
, SecDbItemRef new_item
, CFErrorRef
*error
);
386 bool SecItemDbSelect(SecItemDbConnectionRef dbconn
, SecDbQueryRef query
, CFErrorRef
*error
,
387 bool (^use_attr_in_where
)(const SecDbAttr
*attr
),
388 bool (^add_where_sql
)(CFMutableStringRef sql
, bool *needWhere
),
389 bool (^bind_added_where
)(sqlite3_stmt
*stmt
, int col
),
390 void (^handle_row
)(SecDbItemRef item
, bool *stop
));
392 // MARK: type converters.
393 // TODO: these should be static and private to SecDbItem, or part of the schema
395 CFStringRef
copyString(CFTypeRef obj
);
396 CFDataRef
copyData(CFTypeRef obj
);
397 CFTypeRef
copyBlob(CFTypeRef obj
);
398 CFDataRef
copySHA1(CFTypeRef obj
);
399 CFTypeRef
copyNumber(CFTypeRef obj
);
400 CFDateRef
copyDate(CFTypeRef obj
);
404 #endif /* _SECURITYD_SECDBITEM_H_ */