]> git.saurik.com Git - apple/security.git/blob - OSX/sec/securityd/SecDbItem.h
Security-57740.1.18.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 majorVersion;
112 int minorVersion;
113 const SecDbClass *classes[];
114 } SecDbSchema;
115
116
117 #define SecDbForEachAttr(class, attr) for (const SecDbAttr * const* _pattr = (class)->attrs, *attr = *_pattr; attr; attr = *(++_pattr))
118
119 #define SecDbForEachAttrWithMask(class, attr, flag_mask) SecDbForEachAttr(class, attr) if ((attr->flags & (flag_mask)) == (flag_mask))
120
121 CFTypeRef SecDbAttrCopyDefaultValue(const SecDbAttr *attr, CFErrorRef *error);
122
123
124 // MARK: SecDbItem
125
126 enum SecDbItemState {
127 kSecDbItemDirty, // We have no edata (or if we do it's invalid), attributes are the truth
128 kSecDbItemEncrypted, // Attributes haven't been decrypted yet from edata
129 kSecDbItemClean, // Attributes and _edata are in sync.
130 kSecDbItemDecrypting, // Temporary state while we are decrypting so set knows not to blow away the edata.
131 kSecDbItemEncrypting, // Temporary state while we are encrypting so set knows to move to clean.
132 kSecDbItemAlwaysEncrypted, // As kSecDbItemEncrypted, but decryption is never attempted
133 };
134
135 struct SecDbItem {
136 CFRuntimeBase _base;
137 const SecDbClass *class;
138 keyclass_t keyclass;
139 keybag_handle_t keybag;
140 //sqlite3_int64 _rowid;
141 //CFDataRef _primaryKey;
142 //CFDataRef _sha1;
143 //CFDataRef _edata;
144 enum SecDbItemState _edataState;
145 CFMutableDictionaryRef attributes;
146 CFTypeRef credHandle;
147 CFTypeRef cryptoOp;
148 CFArrayRef callerAccessGroups;
149 };
150
151 // TODO: Make this a callback to client
152 bool SecDbItemDecrypt(SecDbItemRef item, CFDataRef edata, CFErrorRef *error);
153
154 CFTypeID SecDbItemGetTypeID(void);
155
156 static inline size_t SecDbClassAttrCount(const SecDbClass *dbClass) {
157 size_t n_attrs = 0;
158 SecDbForEachAttr(dbClass, attr) { n_attrs++; }
159 return n_attrs;
160 }
161
162 const SecDbAttr *SecDbClassAttrWithKind(const SecDbClass *class, SecDbAttrKind kind, CFErrorRef *error);
163
164 SecDbItemRef SecDbItemCreateWithAttributes(CFAllocatorRef allocator, const SecDbClass *class, CFDictionaryRef attributes, keybag_handle_t keybag, CFErrorRef *error);
165
166 const SecDbClass *SecDbItemGetClass(SecDbItemRef item);
167 keybag_handle_t SecDbItemGetKeybag(SecDbItemRef item);
168 bool SecDbItemSetKeybag(SecDbItemRef item, keybag_handle_t keybag, CFErrorRef *error);
169 void SecDbItemSetCredHandle(SecDbItemRef item, CFTypeRef cred_handle);
170 void SecDbItemSetCallerAccessGroups(SecDbItemRef item, CFArrayRef caller_access_groups);
171
172 CFTypeRef SecDbItemGetCachedValueWithName(SecDbItemRef item, CFStringRef name);
173 CFTypeRef SecDbItemGetValue(SecDbItemRef item, const SecDbAttr *desc, CFErrorRef *error);
174
175 bool SecDbItemSetValue(SecDbItemRef item, const SecDbAttr *desc, CFTypeRef value, CFErrorRef *error);
176 bool SecDbItemSetValues(SecDbItemRef item, CFDictionaryRef values, CFErrorRef *error);
177 bool SecDbItemSetValueWithName(SecDbItemRef item, CFStringRef name, CFTypeRef value, CFErrorRef *error);
178
179 sqlite3_int64 SecDbItemGetRowId(SecDbItemRef item, CFErrorRef *error);
180 bool SecDbItemSetRowId(SecDbItemRef item, sqlite3_int64 rowid, CFErrorRef *error);
181 bool SecDbItemClearRowId(SecDbItemRef item, CFErrorRef *error);
182
183 bool SecDbItemIsSyncableOrCorrupted(SecDbItemRef item);
184 bool SecDbItemIsSyncable(SecDbItemRef item);
185
186 bool SecDbItemSetSyncable(SecDbItemRef item, bool sync, CFErrorRef *error);
187
188 bool SecDbItemIsTombstone(SecDbItemRef item);
189
190 CFMutableDictionaryRef SecDbItemCopyPListWithMask(SecDbItemRef item, CFOptionFlags mask, CFErrorRef *error);
191
192 CFDataRef SecDbItemGetPrimaryKey(SecDbItemRef item, CFErrorRef *error);
193 CFDataRef SecDbItemGetSHA1(SecDbItemRef item, CFErrorRef *error);
194
195 CFDataRef SecDbItemCopyEncryptedDataToBackup(SecDbItemRef item, uint64_t handle, CFErrorRef *error);
196
197 SecDbItemRef SecDbItemCreateWithStatement(CFAllocatorRef allocator, const SecDbClass *class, sqlite3_stmt *stmt, keybag_handle_t keybag, CFErrorRef *error, bool (^return_attr)(const SecDbAttr *attr));
198
199 SecDbItemRef SecDbItemCreateWithEncryptedData(CFAllocatorRef allocator, const SecDbClass *class,
200 CFDataRef edata, keybag_handle_t keybag, CFErrorRef *error);
201
202 SecDbItemRef SecDbItemCreateWithPrimaryKey(CFAllocatorRef allocator, const SecDbClass *class, CFDataRef primary_key);
203
204 #if 0
205 SecDbItemRef SecDbItemCreateWithRowId(CFAllocatorRef allocator, const SecDbClass *class, sqlite_int64 row_id, keybag_handle_t keybag, CFErrorRef *error);
206 #endif
207
208 bool SecDbItemEnsureDecrypted(SecDbItemRef item, CFErrorRef *error);
209
210 SecDbItemRef SecDbItemCopyWithUpdates(SecDbItemRef item, CFDictionaryRef updates, CFErrorRef *error);
211
212 bool SecDbItemInsertOrReplace(SecDbItemRef item, SecDbConnectionRef dbconn, CFErrorRef *error, void(^duplicate)(SecDbItemRef item, SecDbItemRef *replace));
213
214 bool SecDbItemInsert(SecDbItemRef item, SecDbConnectionRef dbconn, CFErrorRef *error);
215
216 bool SecDbItemDelete(SecDbItemRef item, SecDbConnectionRef dbconn, CFBooleanRef makeTombstone, CFErrorRef *error);
217
218 bool SecDbItemDoDeleteSilently(SecDbItemRef item, SecDbConnectionRef dbconn, CFErrorRef *error);
219
220 // Low level update, just do the update
221 bool SecDbItemDoUpdate(SecDbItemRef old_item, SecDbItemRef new_item, SecDbConnectionRef dbconn, CFErrorRef *error, bool (^use_attr_in_where)(const SecDbAttr *attr));
222
223 // High level update, will replace tombstones and create them if needed.
224 bool SecDbItemUpdate(SecDbItemRef old_item, SecDbItemRef new_item, SecDbConnectionRef dbconn, CFBooleanRef makeTombstone, CFErrorRef *error);
225
226
227 // MARK: -
228 // MARK: SQL Construction helpers -- These should become private in the future
229
230 void SecDbAppendElement(CFMutableStringRef sql, CFStringRef value, bool *needComma);
231 void SecDbAppendWhereOrAnd(CFMutableStringRef sql, bool *needWhere);
232 void SecDbAppendWhereOrAndEquals(CFMutableStringRef sql, CFStringRef col, bool *needWhere);
233 void SecDbAppendWhereOrAndNotEquals(CFMutableStringRef sql, CFStringRef col, bool *needWhere);
234 void SecDbAppendWhereOrAndIn(CFMutableStringRef sql, CFStringRef col, bool *needWhere, CFIndex count);
235 void SecDbAppendWhereOrAndNotIn(CFMutableStringRef sql, CFStringRef col, bool *needWhere, CFIndex count);
236
237 // MARK: type converters.
238 // TODO: these should be static and private to SecDbItem, or part of the schema
239
240 CFStringRef copyString(CFTypeRef obj);
241 CFDataRef copyData(CFTypeRef obj);
242 CFTypeRef copyBlob(CFTypeRef obj);
243 CFDataRef copySHA1(CFTypeRef obj);
244 CFTypeRef copyNumber(CFTypeRef obj);
245 CFDateRef copyDate(CFTypeRef obj);
246 CFTypeRef copyUUID(CFTypeRef obj);
247
248 // MARK: cFErrorPropagate which handles errSecAuthNeeded
249 static inline
250 bool SecErrorPropagate(CFErrorRef possibleError CF_CONSUMED, CFErrorRef *error) {
251 if (possibleError && error && *error && CFErrorGetCode(*error) == errSecAuthNeeded)
252 CFReleaseNull(*error);
253 return CFErrorPropagate(possibleError, error);
254 }
255
256 // TODO: Hack
257 bool SecDbItemInV2(SecDbItemRef item);
258 bool SecDbItemInV2AlsoInV0(SecDbItemRef item);
259
260 __END_DECLS
261
262 #endif /* _SECURITYD_SECDBITEM_H_ */