]> git.saurik.com Git - apple/security.git/blame - sec/securityd/SecDbItem.h
Security-55471.14.18.tar.gz
[apple/security.git] / sec / securityd / SecDbItem.h
CommitLineData
427c49bc
A
1/*
2 * Copyright (c) 2012 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 @header SecDbItem
26 The functions provided in SecDbItem provide an interface to
27 database items (certificates, keys, identities, and passwords).
28 */
29
30#ifndef _SECURITYD_SECDBITEM_H_
31#define _SECURITYD_SECDBITEM_H_
32
33#include <CoreFoundation/CoreFoundation.h>
34#include <TargetConditionals.h>
35#include <corecrypto/ccsha1.h> // For CCSHA1_OUTPUT_SIZE
36#include <sqlite3.h>
37#include <utilities/SecCFError.h>
38#include <utilities/SecCFWrappers.h>
39#include <utilities/SecDb.h>
40#include <utilities/SecAKSWrappers.h>
41
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
48#endif
49
50#if USE_KEYSTORE
51#include <Kernel/IOKit/crypto/AppleKeyStoreDefs.h>
52#endif /* USE_KEYSTORE */
53
54__BEGIN_DECLS
55
56// TODO: Get this out of this file
57#if USE_KEYSTORE
58typedef int32_t keyclass_t;
59#else
60
61/* TODO: this needs to be available in the sim! */
62#define kAppleKeyStoreKeyWrap 0
63#define kAppleKeyStoreKeyUnwrap 1
64typedef int32_t keyclass_t;
65typedef int32_t key_handle_t;
66enum key_classes {
67 key_class_ak = 6,
68 key_class_ck,
69 key_class_dk,
70 key_class_aku,
71 key_class_cku,
72 key_class_dku
73};
74#endif /* !USE_KEYSTORE */
75
76// MARK SecDbAttrKind, SecDbFlag
77
78typedef enum {
79 kSecDbBlobAttr, // CFString or CFData, preserves caller provided type.
80 kSecDbDataAttr,
81 kSecDbStringAttr,
82 kSecDbNumberAttr,
83 kSecDbDateAttr,
84 kSecDbCreationDateAttr,
85 kSecDbModificationDateAttr,
86 kSecDbSHA1Attr,
87 kSecDbRowIdAttr,
88 kSecDbEncryptedDataAttr,
89 kSecDbPrimaryKeyAttr,
90 kSecDbSyncAttr,
91 kSecDbTombAttr,
92 kSecDbAccessAttr
93} SecDbAttrKind;
94
95enum {
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
109};
110
111#define SecVersionDbFlag(v) ((v & 0xFF) << 8)
112
113#define SecDbFlagGetVersion(flags) ((flags >> 8) & 0xFF)
114
115#define SECDB_ATTR(var, name, kind, flags) const SecDbAttr var = { CFSTR(name), kSecDb ## kind ## Attr, flags }
116
117typedef struct SecDbAttr {
118 CFStringRef name;
119 SecDbAttrKind kind;
120 CFOptionFlags flags;
121} SecDbAttr;
122
123typedef struct SecDbClass {
124 CFStringRef name;
125 const SecDbAttr *attrs[];
126} SecDbClass;
127
128typedef struct Pair *SecDbPairRef;
129typedef struct Query *SecDbQueryRef;
130
131/* Return types. */
132typedef uint32_t ReturnTypeMask;
133enum
134{
135 kSecReturnDataMask = 1 << 0,
136 kSecReturnAttributesMask = 1 << 1,
137 kSecReturnRefMask = 1 << 2,
138 kSecReturnPersistentRefMask = 1 << 3,
139};
140
141/* Constant indicating there is no limit to the number of results to return. */
142enum
143{
144 kSecMatchUnlimited = kCFNotFound
145};
146
147typedef struct Pair
148{
149 const void *key;
150 const void *value;
151} Pair;
152
153/* Nothing in this struct is retained since all the
154 values below are extracted from the dictionary passed in by the
155 caller. */
156typedef struct Query
157{
158 /* Class of this query. */
159 const SecDbClass *q_class;
160
161 /* Dictionary with all attributes and values in clear (to be encrypted). */
162 CFMutableDictionaryRef q_item;
163
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;
170 CFIndex q_match_end;
171 CFIndex q_attr_end;
172
173 CFErrorRef q_error;
174 ReturnTypeMask q_return_type;
175
176 CFDataRef q_data;
177 CFTypeRef q_ref;
178 sqlite_int64 q_row_id;
179
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) */
186
187 /* Value of kSecMatchLimit key if present. */
188 CFIndex q_limit;
189
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. */
193 bool q_sync;
194
195 // Set to true if we modified any item as part of executing this query
196 bool q_changed;
197
198 // Set to true if we modified any synchronizable item as part of executing this query
199 bool q_sync_changed;
200
201 /* Keybag handle to use for this item. */
202 keybag_handle_t q_keybag;
203 keyclass_t q_keyclass;
204 //CFStringRef q_keyclass_s;
205
206 // SHA1 digest of DER encoded primary key
207 CFDataRef q_primary_key_digest;
208
209 CFArrayRef q_match_issuer;
210
211 /* Store all the corrupted rows found during the query */
212 CFMutableArrayRef corrupted_rows;
213
214 Pair q_pairs[];
215} Query;
216
217
218#define SecDbForEachAttr(class, attr) for (const SecDbAttr * const* _pattr = (class)->attrs, *attr = *_pattr; attr; attr = *(++_pattr))
219
220#define SecDbForEachAttrWithMask(class, attr, flag_mask) SecDbForEachAttr(class, attr) if ((attr->flags & (flag_mask)) == (flag_mask))
221
222// MARK: Stuff that needs to move out of SecItemServer.c
223
224// Move this or do crypto in a block
225bool ks_encrypt_data(keybag_handle_t keybag, keyclass_t keyclass, CFDataRef plainText, CFDataRef *pBlob, CFErrorRef *error);
226bool ks_decrypt_data(keybag_handle_t keybag, keyclass_t *pkeyclass, CFDataRef blob, CFDataRef *pPlainText,
227 uint32_t *version_p, CFErrorRef *error);
228
229CFDataRef kc_copy_sha1(size_t len, const void *data, CFErrorRef *error);
230CFDataRef kc_copy_plist_sha1(CFPropertyListRef plist, CFErrorRef *error);
231CFDataRef kc_plist_copy_der(CFPropertyListRef plist, CFErrorRef *error);
232Query *query_create(const SecDbClass *qclass, CFDictionaryRef query, CFErrorRef *error);
233bool query_destroy(Query *q, CFErrorRef *error);
234
235// MARK: SecDbItem
236
237typedef struct SecDbItem *SecDbItemRef;
238
239enum 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.
245};
246
247struct SecDbItem {
248 CFRuntimeBase _base;
249 const SecDbClass *class;
250 keyclass_t keyclass;
251 keybag_handle_t keybag;
252 //sqlite3_int64 _rowid;
253 //CFDataRef _primaryKey;
254 //CFDataRef _sha1;
255 //CFDataRef _edata;
256 enum SecDbItemState _edataState;
257 CFMutableDictionaryRef attributes;
258};
259
260// TODO: Make this a callback to client
261bool SecDbItemDecrypt(SecDbItemRef item, CFDataRef edata, CFErrorRef *error);
262
263CFTypeID SecDbItemGetTypeID(void);
264
265static inline size_t SecDbClassAttrCount(const SecDbClass *dbClass) {
266 size_t n_attrs = 0;
267 SecDbForEachAttr(dbClass, attr) { n_attrs++; }
268 return n_attrs;
269}
270
271const SecDbAttr *SecDbClassAttrWithKind(const SecDbClass *class, SecDbAttrKind kind, CFErrorRef *error);
272
273SecDbItemRef SecDbItemCreateWithAttributes(CFAllocatorRef allocator, const SecDbClass *class, CFDictionaryRef attributes, keybag_handle_t keybag, CFErrorRef *error);
274
275const SecDbClass *SecDbItemGetClass(SecDbItemRef item);
276const keybag_handle_t SecDbItemGetKeybag(SecDbItemRef item);
277bool SecDbItemSetKeybag(SecDbItemRef item, keybag_handle_t keybag, CFErrorRef *error);
278keyclass_t SecDbItemGetKeyclass(SecDbItemRef item, CFErrorRef *error);
279bool SecDbItemSetKeyclass(SecDbItemRef item, keyclass_t keyclass, CFErrorRef *error);
280
281CFTypeRef SecDbItemGetCachedValueWithName(SecDbItemRef item, CFStringRef name);
282CF_RETURNS_NOT_RETAINED CFTypeRef SecDbItemGetValue(SecDbItemRef item, const SecDbAttr *desc, CFErrorRef *error);
283
284bool SecDbItemSetValue(SecDbItemRef item, const SecDbAttr *desc, CFTypeRef value, CFErrorRef *error);
285bool SecDbItemSetValues(SecDbItemRef item, CFDictionaryRef values, CFErrorRef *error);
286bool SecDbItemSetValueWithName(SecDbItemRef item, CFStringRef name, CFTypeRef value, CFErrorRef *error);
287
288sqlite3_int64 SecDbItemGetRowId(SecDbItemRef item, CFErrorRef *error);
289bool SecDbItemSetRowId(SecDbItemRef item, sqlite3_int64 rowid, CFErrorRef *error);
290
291bool SecDbItemIsSyncable(SecDbItemRef item);
292
293bool SecDbItemSetSyncable(SecDbItemRef item, bool sync, CFErrorRef *error);
294
295bool SecDbItemIsTombstone(SecDbItemRef item);
296
297CFMutableDictionaryRef SecDbItemCopyPListWithMask(SecDbItemRef item, CFOptionFlags mask, CFErrorRef *error);
298
299CFDataRef SecDbItemGetPrimaryKey(SecDbItemRef item, CFErrorRef *error);
300CFDataRef SecDbItemGetSHA1(SecDbItemRef item, CFErrorRef *error);
301
302CFDataRef SecDbItemCopyEncryptedDataToBackup(SecDbItemRef item, uint64_t handle, CFErrorRef *error);
303
304SecDbItemRef SecDbItemCreateWithStatement(CFAllocatorRef allocator, const SecDbClass *class, sqlite3_stmt *stmt, keybag_handle_t keybag, CFErrorRef *error, bool (^return_attr)(const SecDbAttr *attr));
305
306SecDbItemRef SecDbItemCreateWithEncryptedData(CFAllocatorRef allocator, const SecDbClass *class,
307 CFDataRef edata, keybag_handle_t keybag, CFErrorRef *error);
308
309SecDbItemRef SecDbItemCreateWithPrimaryKey(CFAllocatorRef allocator, const SecDbClass *class, CFDataRef primary_key);
310
311#if 0
312SecDbItemRef SecDbItemCreateWithRowId(CFAllocatorRef allocator, const SecDbClass *class, sqlite_int64 row_id, keybag_handle_t keybag, CFErrorRef *error);
313#endif
314
315SecDbItemRef SecDbItemCopyWithUpdates(SecDbItemRef item, CFDictionaryRef updates, CFErrorRef *error);
316
317SecDbItemRef SecDbItemCopyTombstone(SecDbItemRef item, CFErrorRef *error);
318
319bool SecDbItemInsertOrReplace(SecDbItemRef item, SecDbConnectionRef dbconn, CFErrorRef *error, void(^duplicate)(SecDbItemRef item, SecDbItemRef *replace));
320
321bool SecDbItemInsert(SecDbItemRef item, SecDbConnectionRef dbconn, CFErrorRef *error);
322
323bool SecDbItemDelete(SecDbItemRef item, SecDbConnectionRef dbconn, bool makeTombstone, CFErrorRef *error);
324
325// Low level update, just do the update
326bool SecDbItemDoUpdate(SecDbItemRef old_item, SecDbItemRef new_item, SecDbConnectionRef dbconn, CFErrorRef *error, bool (^use_attr_in_where)(const SecDbAttr *attr));
327
328// High level update, will replace tombstones and create them if needed.
329bool SecDbItemUpdate(SecDbItemRef old_item, SecDbItemRef new_item, SecDbConnectionRef dbconn, bool makeTombstone, CFErrorRef *error);
330
331bool 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));
336
337CFStringRef 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));
341bool 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));
344
345
346// MARK: -
347// MARK: SQL Construction helpers -- These should become private in the future
348
349void SecDbAppendElement(CFMutableStringRef sql, CFStringRef value, bool *needComma);
350void SecDbAppendWhereOrAnd(CFMutableStringRef sql, bool *needWhere);
351void SecDbAppendWhereOrAndEquals(CFMutableStringRef sql, CFStringRef col, bool *needWhere);
352
353// MARK: -
354// MARK: SecItemDb (a SecDb of SecDbItems)
355
356typedef struct SecItemDb *SecItemDbRef;
357typedef struct SecItemDbConnection *SecItemDbConnectionRef;
358
359struct SecItemDb {
360 CFRuntimeBase _base;
361 SecDbRef db;
362 CFDictionaryRef classes; // className -> SecItemClass mapping
363};
364
365struct SecItemDbConnection {
366 SecDbConnectionRef db;
367};
368
369SecItemDbRef SecItemDbCreate(SecDbRef db);
370SecItemDbRef SecItemDbRegisterClass(SecItemDbRef db, const SecDbClass *class, void(^upgrade)(SecDbItemRef item, uint32_t current_version));
371
372SecItemDbConnectionRef SecItemDbAquireConnection(SecItemDbRef db);
373void SecItemDbReleaseConnection(SecItemDbRef db, SecItemDbConnectionRef dbconn);
374
375bool SecItemDbInsert(SecItemDbConnectionRef dbconn, SecDbItemRef item, CFErrorRef *error);
376
377bool SecItemDbDelete(SecItemDbConnectionRef dbconn, SecDbItemRef item, CFErrorRef *error);
378
379// Low level update, just do the update
380bool SecItemDbDoUpdate(SecItemDbConnectionRef dbconn, SecDbItemRef old_item, SecDbItemRef new_item, CFErrorRef *error,
381 bool (^use_attr_in_where)(const SecDbAttr *attr));
382
383// High level update, will replace tombstones and create them if needed.
384bool SecItemDbUpdate(SecItemDbConnectionRef dbconn, SecDbItemRef old_item, SecDbItemRef new_item, CFErrorRef *error);
385
386bool 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));
391
392// MARK: type converters.
393// TODO: these should be static and private to SecDbItem, or part of the schema
394
395CFStringRef copyString(CFTypeRef obj);
396CFDataRef copyData(CFTypeRef obj);
397CFTypeRef copyBlob(CFTypeRef obj);
398CFDataRef copySHA1(CFTypeRef obj);
399CFTypeRef copyNumber(CFTypeRef obj);
400CFDateRef copyDate(CFTypeRef obj);
401
402__END_DECLS
403
404#endif /* _SECURITYD_SECDBITEM_H_ */