]> git.saurik.com Git - apple/security.git/blob - OSX/sec/securityd/SecDbItem.h
Security-57337.50.23.tar.gz
[apple/security.git] / OSX / sec / securityd / SecDbItem.h
1 /*
2 * Copyright (c) 2012-2014 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 <securityd/SecKeybagSupport.h>
41 #include <Security/SecAccessControl.h>
42 #include <Security/SecBasePriv.h>
43
44 // MARK SecDbAttrKind, SecDbFlag
45
46 typedef enum {
47 kSecDbBlobAttr, // CFString or CFData, preserves caller provided type.
48 kSecDbDataAttr,
49 kSecDbStringAttr,
50 kSecDbNumberAttr,
51 kSecDbDateAttr,
52 kSecDbCreationDateAttr,
53 kSecDbModificationDateAttr,
54 kSecDbSHA1Attr,
55 kSecDbRowIdAttr,
56 kSecDbEncryptedDataAttr,
57 kSecDbPrimaryKeyAttr,
58 kSecDbSyncAttr,
59 kSecDbTombAttr,
60 kSecDbUTombAttr,
61 kSecDbAccessAttr,
62 kSecDbAccessControlAttr,
63 kSecDbUUIDAttr,
64 } SecDbAttrKind;
65
66 enum {
67 kSecDbPrimaryKeyFlag = (1 << 0), // attr is part of primary key
68 kSecDbInFlag = (1 << 1), // attr exists in db
69 kSecDbIndexFlag = (1 << 2), // attr should have a db index
70 kSecDbSHA1ValueInFlag = (1 << 3), // col in db is sha1 of attr value
71 kSecDbReturnAttrFlag = (1 << 4),
72 kSecDbReturnDataFlag = (1 << 5),
73 kSecDbReturnRefFlag = (1 << 6),
74 kSecDbInCryptoDataFlag = (1 << 7),
75 kSecDbInHashFlag = (1 << 8),
76 kSecDbInBackupFlag = (1 << 9),
77 kSecDbDefault0Flag = (1 << 10), // default attr value is 0
78 kSecDbDefaultEmptyFlag = (1 << 11), // default attr value is ""
79 kSecDbNotNullFlag = (1 << 12), // attr value can't be null
80 kSecDbInAuthenticatedDataFlag = (1 << 13), // attr is in authenticated data
81 kSecDbSyncPrimaryKeyV0 = (1 << 14),
82 kSecDbSyncPrimaryKeyV2 = (1 << 15),
83 };
84
85 #define SecVersionDbFlag(v) ((v & 0xFF) << 8)
86
87 #define SecDbFlagGetVersion(flags) ((flags >> 8) & 0xFF)
88
89 #define SECDB_ATTR(var, name, kind, flags, copyValue, setValue) const SecDbAttr var = { CFSTR(name), kSecDb ## kind ## Attr, flags, copyValue, setValue }
90
91 typedef struct SecDbItem *SecDbItemRef;
92 typedef struct SecDbAttr SecDbAttr;
93
94 typedef CFTypeRef (*SecDbItemCopyAttrValue)(SecDbItemRef item, const SecDbAttr *attr, CFErrorRef *error);
95 typedef bool (*SecDbItemSetAttrValue)(SecDbItemRef item, const SecDbAttr *desc, CFTypeRef value, CFErrorRef *error);
96
97 struct SecDbAttr {
98 CFStringRef name;
99 SecDbAttrKind kind;
100 CFOptionFlags flags;
101 SecDbItemCopyAttrValue copyValue;
102 SecDbItemSetAttrValue setValue;
103 };
104
105 typedef struct SecDbClass {
106 CFStringRef name;
107 const SecDbAttr *attrs[];
108 } SecDbClass;
109
110 typedef struct SecDbSchema {
111 int version;
112 const SecDbClass *classes[];
113 } SecDbSchema;
114
115
116 #define SecDbForEachAttr(class, attr) for (const SecDbAttr * const* _pattr = (class)->attrs, *attr = *_pattr; attr; attr = *(++_pattr))
117
118 #define SecDbForEachAttrWithMask(class, attr, flag_mask) SecDbForEachAttr(class, attr) if ((attr->flags & (flag_mask)) == (flag_mask))
119
120 CFTypeRef SecDbAttrCopyDefaultValue(const SecDbAttr *attr, CFErrorRef *error);
121
122
123 // MARK: SecDbItem
124
125 enum SecDbItemState {
126 kSecDbItemDirty, // We have no edata (or if we do it's invalid), attributes are the truth
127 kSecDbItemEncrypted, // Attributes haven't been decrypted yet from edata
128 kSecDbItemClean, // Attributes and _edata are in sync.
129 kSecDbItemDecrypting, // Temporary state while we are decrypting so set knows not to blow away the edata.
130 kSecDbItemEncrypting, // Temporary state while we are encrypting so set knows to move to clean.
131 kSecDbItemAlwaysEncrypted, // As kSecDbItemEncrypted, but decryption is never attempted
132 };
133
134 struct SecDbItem {
135 CFRuntimeBase _base;
136 const SecDbClass *class;
137 keyclass_t keyclass;
138 keybag_handle_t keybag;
139 //sqlite3_int64 _rowid;
140 //CFDataRef _primaryKey;
141 //CFDataRef _sha1;
142 //CFDataRef _edata;
143 enum SecDbItemState _edataState;
144 CFMutableDictionaryRef attributes;
145 CFTypeRef credHandle;
146 CFTypeRef cryptoOp;
147 CFArrayRef callerAccessGroups;
148 };
149
150 // TODO: Make this a callback to client
151 bool SecDbItemDecrypt(SecDbItemRef item, CFDataRef edata, CFErrorRef *error);
152
153 CFTypeID SecDbItemGetTypeID(void);
154
155 static inline size_t SecDbClassAttrCount(const SecDbClass *dbClass) {
156 size_t n_attrs = 0;
157 SecDbForEachAttr(dbClass, attr) { n_attrs++; }
158 return n_attrs;
159 }
160
161 const SecDbAttr *SecDbClassAttrWithKind(const SecDbClass *class, SecDbAttrKind kind, CFErrorRef *error);
162
163 SecDbItemRef SecDbItemCreateWithAttributes(CFAllocatorRef allocator, const SecDbClass *class, CFDictionaryRef attributes, keybag_handle_t keybag, CFErrorRef *error);
164
165 const SecDbClass *SecDbItemGetClass(SecDbItemRef item);
166 keybag_handle_t SecDbItemGetKeybag(SecDbItemRef item);
167 bool SecDbItemSetKeybag(SecDbItemRef item, keybag_handle_t keybag, CFErrorRef *error);
168 void SecDbItemSetCredHandle(SecDbItemRef item, CFTypeRef cred_handle);
169 void SecDbItemSetCallerAccessGroups(SecDbItemRef item, CFArrayRef caller_access_groups);
170
171 CFTypeRef SecDbItemGetCachedValueWithName(SecDbItemRef item, CFStringRef name);
172 CFTypeRef SecDbItemGetValue(SecDbItemRef item, const SecDbAttr *desc, CFErrorRef *error);
173
174 bool SecDbItemSetValue(SecDbItemRef item, const SecDbAttr *desc, CFTypeRef value, CFErrorRef *error);
175 bool SecDbItemSetValues(SecDbItemRef item, CFDictionaryRef values, CFErrorRef *error);
176 bool SecDbItemSetValueWithName(SecDbItemRef item, CFStringRef name, CFTypeRef value, CFErrorRef *error);
177
178 sqlite3_int64 SecDbItemGetRowId(SecDbItemRef item, CFErrorRef *error);
179 bool SecDbItemSetRowId(SecDbItemRef item, sqlite3_int64 rowid, CFErrorRef *error);
180 bool SecDbItemClearRowId(SecDbItemRef item, CFErrorRef *error);
181
182 bool SecDbItemIsSyncableOrCorrupted(SecDbItemRef item);
183 bool SecDbItemIsSyncable(SecDbItemRef item);
184
185 bool SecDbItemSetSyncable(SecDbItemRef item, bool sync, CFErrorRef *error);
186
187 bool SecDbItemIsTombstone(SecDbItemRef item);
188
189 CFMutableDictionaryRef SecDbItemCopyPListWithMask(SecDbItemRef item, CFOptionFlags mask, CFErrorRef *error);
190
191 CFDataRef SecDbItemGetPrimaryKey(SecDbItemRef item, CFErrorRef *error);
192 CFDataRef SecDbItemGetSHA1(SecDbItemRef item, CFErrorRef *error);
193
194 CFDataRef SecDbItemCopyEncryptedDataToBackup(SecDbItemRef item, uint64_t handle, CFErrorRef *error);
195
196 SecDbItemRef SecDbItemCreateWithStatement(CFAllocatorRef allocator, const SecDbClass *class, sqlite3_stmt *stmt, keybag_handle_t keybag, CFErrorRef *error, bool (^return_attr)(const SecDbAttr *attr));
197
198 SecDbItemRef SecDbItemCreateWithEncryptedData(CFAllocatorRef allocator, const SecDbClass *class,
199 CFDataRef edata, keybag_handle_t keybag, CFErrorRef *error);
200
201 SecDbItemRef SecDbItemCreateWithPrimaryKey(CFAllocatorRef allocator, const SecDbClass *class, CFDataRef primary_key);
202
203 #if 0
204 SecDbItemRef SecDbItemCreateWithRowId(CFAllocatorRef allocator, const SecDbClass *class, sqlite_int64 row_id, keybag_handle_t keybag, CFErrorRef *error);
205 #endif
206
207 bool SecDbItemEnsureDecrypted(SecDbItemRef item, CFErrorRef *error);
208
209 SecDbItemRef SecDbItemCopyWithUpdates(SecDbItemRef item, CFDictionaryRef updates, CFErrorRef *error);
210
211 bool SecDbItemInsertOrReplace(SecDbItemRef item, SecDbConnectionRef dbconn, CFErrorRef *error, void(^duplicate)(SecDbItemRef item, SecDbItemRef *replace));
212
213 bool SecDbItemInsert(SecDbItemRef item, SecDbConnectionRef dbconn, CFErrorRef *error);
214
215 bool SecDbItemDelete(SecDbItemRef item, SecDbConnectionRef dbconn, CFBooleanRef makeTombstone, CFErrorRef *error);
216
217 bool SecDbItemDoDeleteSilently(SecDbItemRef item, SecDbConnectionRef dbconn, CFErrorRef *error);
218
219 // Low level update, just do the update
220 bool SecDbItemDoUpdate(SecDbItemRef old_item, SecDbItemRef new_item, SecDbConnectionRef dbconn, CFErrorRef *error, bool (^use_attr_in_where)(const SecDbAttr *attr));
221
222 // High level update, will replace tombstones and create them if needed.
223 bool SecDbItemUpdate(SecDbItemRef old_item, SecDbItemRef new_item, SecDbConnectionRef dbconn, CFBooleanRef makeTombstone, CFErrorRef *error);
224
225
226 // MARK: -
227 // MARK: SQL Construction helpers -- These should become private in the future
228
229 void SecDbAppendElement(CFMutableStringRef sql, CFStringRef value, bool *needComma);
230 void SecDbAppendWhereOrAnd(CFMutableStringRef sql, bool *needWhere);
231 void SecDbAppendWhereOrAndEquals(CFMutableStringRef sql, CFStringRef col, bool *needWhere);
232 void SecDbAppendWhereOrAndNotEquals(CFMutableStringRef sql, CFStringRef col, bool *needWhere);
233 void SecDbAppendWhereOrAndIn(CFMutableStringRef sql, CFStringRef col, bool *needWhere, CFIndex count);
234 void SecDbAppendWhereOrAndNotIn(CFMutableStringRef sql, CFStringRef col, bool *needWhere, CFIndex count);
235
236 // MARK: type converters.
237 // TODO: these should be static and private to SecDbItem, or part of the schema
238
239 CFStringRef copyString(CFTypeRef obj);
240 CFDataRef copyData(CFTypeRef obj);
241 CFTypeRef copyBlob(CFTypeRef obj);
242 CFDataRef copySHA1(CFTypeRef obj);
243 CFTypeRef copyNumber(CFTypeRef obj);
244 CFDateRef copyDate(CFTypeRef obj);
245 CFTypeRef copyUUID(CFTypeRef obj);
246
247 // MARK: cFErrorPropagate which handles errSecAuthNeeded
248 static inline
249 bool SecErrorPropagate(CFErrorRef possibleError CF_CONSUMED, CFErrorRef *error) {
250 if (possibleError && error && *error && CFErrorGetCode(*error) == errSecAuthNeeded)
251 CFReleaseNull(*error);
252 return CFErrorPropagate(possibleError, error);
253 }
254
255 // TODO: Hack
256 bool SecDbItemInV2(SecDbItemRef item);
257 bool SecDbItemInV2AlsoInV0(SecDbItemRef item);
258
259 __END_DECLS
260
261 #endif /* _SECURITYD_SECDBITEM_H_ */