]> git.saurik.com Git - apple/security.git/blob - OSX/sec/securityd/SecDbItem.h
Security-58286.41.2.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 kSecDbSyncFlag = (1 << 16),
84 };
85
86 #define SecVersionDbFlag(v) ((v & 0xFF) << 8)
87
88 #define SecDbFlagGetVersion(flags) ((flags >> 8) & 0xFF)
89
90 #define SECDB_ATTR(var, name, kind, flags, copyValue, setValue) const SecDbAttr var = { CFSTR(name), kSecDb ## kind ## Attr, flags, copyValue, setValue }
91
92 typedef struct SecDbItem *SecDbItemRef;
93 typedef struct SecDbAttr SecDbAttr;
94
95 typedef CFTypeRef (*SecDbItemCopyAttrValue)(SecDbItemRef item, const SecDbAttr *attr, CFErrorRef *error);
96 typedef bool (*SecDbItemSetAttrValue)(SecDbItemRef item, const SecDbAttr *desc, CFTypeRef value, CFErrorRef *error);
97
98 struct SecDbAttr {
99 CFStringRef name;
100 SecDbAttrKind kind;
101 CFOptionFlags flags;
102 SecDbItemCopyAttrValue copyValue;
103 SecDbItemSetAttrValue setValue;
104 };
105
106 typedef struct SecDbClass {
107 CFStringRef name;
108 bool itemclass; // true if keychain items are stored in this class, false otherwise
109 const SecDbAttr *attrs[];
110 } SecDbClass;
111
112 typedef struct SecDbSchema {
113 int majorVersion;
114 int minorVersion;
115 const SecDbClass *classes[];
116 } SecDbSchema;
117
118
119 #define SecDbForEachAttr(class, attr) for (const SecDbAttr * const* _pattr = (class)->attrs, *attr = *_pattr; attr; attr = *(++_pattr))
120
121 #define SecDbForEachAttrWithMask(class, attr, flag_mask) SecDbForEachAttr(class, attr) if ((attr->flags & (flag_mask)) == (flag_mask))
122
123 CFTypeRef SecDbAttrCopyDefaultValue(const SecDbAttr *attr, CFErrorRef *error);
124
125
126 // MARK: SecDbItem
127
128 enum SecDbItemState {
129 kSecDbItemDirty, // We have no edata (or if we do it's invalid), attributes are the truth
130 kSecDbItemEncrypted, // Attributes haven't been decrypted yet from edata
131 kSecDbItemClean, // Attributes and _edata are in sync.
132 kSecDbItemDecrypting, // Temporary state while we are decrypting so set knows not to blow away the edata.
133 kSecDbItemEncrypting, // Temporary state while we are encrypting so set knows to move to clean.
134 kSecDbItemAlwaysEncrypted, // As kSecDbItemEncrypted, but decryption is never attempted
135 };
136
137 struct SecDbItem {
138 CFRuntimeBase _base;
139 const SecDbClass *class;
140 keyclass_t keyclass;
141 keybag_handle_t keybag;
142 enum SecDbItemState _edataState;
143 CFMutableDictionaryRef attributes;
144 CFDataRef credHandle;
145 CFTypeRef cryptoOp;
146 CFArrayRef callerAccessGroups;
147 };
148
149 // TODO: Make this a callback to client
150 bool SecDbItemDecrypt(SecDbItemRef item, CFDataRef edata, CFErrorRef *error);
151
152 CFTypeID SecDbItemGetTypeID(void);
153
154 static inline size_t SecDbClassAttrCount(const SecDbClass *dbClass) {
155 size_t n_attrs = 0;
156 SecDbForEachAttr(dbClass, attr) { n_attrs++; }
157 return n_attrs;
158 }
159
160 const SecDbAttr *SecDbClassAttrWithKind(const SecDbClass *class, SecDbAttrKind kind, CFErrorRef *error);
161
162 SecDbItemRef SecDbItemCreateWithAttributes(CFAllocatorRef allocator, const SecDbClass *class, CFDictionaryRef attributes, keybag_handle_t keybag, CFErrorRef *error);
163
164 const SecDbClass *SecDbItemGetClass(SecDbItemRef item);
165 keybag_handle_t SecDbItemGetKeybag(SecDbItemRef item);
166 bool SecDbItemSetKeybag(SecDbItemRef item, keybag_handle_t keybag, CFErrorRef *error);
167 void SecDbItemSetCredHandle(SecDbItemRef item, CFTypeRef cred_handle);
168 void SecDbItemSetCallerAccessGroups(SecDbItemRef item, CFArrayRef caller_access_groups);
169
170 CFTypeRef SecDbItemGetCachedValueWithName(SecDbItemRef item, CFStringRef name);
171 CFTypeRef SecDbItemGetValue(SecDbItemRef item, const SecDbAttr *desc, CFErrorRef *error);
172 CFTypeRef SecDbItemGetValueKind(SecDbItemRef item, SecDbAttrKind 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 // SecDbItemInsertOrReplace returns an error even when it succeeds; use this to determine if it's spurious
214 bool SecErrorIsSqliteDuplicateItemError(CFErrorRef error);
215
216 bool SecDbItemInsert(SecDbItemRef item, SecDbConnectionRef dbconn, CFErrorRef *error);
217
218 bool SecDbItemDelete(SecDbItemRef item, SecDbConnectionRef dbconn, CFBooleanRef makeTombstone, CFErrorRef *error);
219
220 bool SecDbItemDoDeleteSilently(SecDbItemRef item, SecDbConnectionRef dbconn, CFErrorRef *error);
221
222 // Low level update, just do the update
223 bool SecDbItemDoUpdate(SecDbItemRef old_item, SecDbItemRef new_item, SecDbConnectionRef dbconn, CFErrorRef *error, bool (^use_attr_in_where)(const SecDbAttr *attr));
224
225 // High level update, will replace tombstones and create them if needed.
226 bool SecDbItemUpdate(SecDbItemRef old_item, SecDbItemRef new_item, SecDbConnectionRef dbconn, CFBooleanRef makeTombstone, bool uuid_from_primary_key, CFErrorRef *error);
227
228
229 // MARK: -
230 // MARK: SQL Construction helpers -- These should become private in the future
231
232 void SecDbAppendElement(CFMutableStringRef sql, CFStringRef value, bool *needComma);
233 void SecDbAppendWhereOrAnd(CFMutableStringRef sql, bool *needWhere);
234 void SecDbAppendWhereOrAndEquals(CFMutableStringRef sql, CFStringRef col, bool *needWhere);
235 void SecDbAppendWhereOrAndNotEquals(CFMutableStringRef sql, CFStringRef col, bool *needWhere);
236 void SecDbAppendWhereOrAndIn(CFMutableStringRef sql, CFStringRef col, bool *needWhere, CFIndex count);
237 void SecDbAppendWhereOrAndNotIn(CFMutableStringRef sql, CFStringRef col, bool *needWhere, CFIndex count);
238
239 // MARK: type converters.
240 // TODO: these should be static and private to SecDbItem, or part of the schema
241
242 CFStringRef copyString(CFTypeRef obj);
243 CFDataRef copyData(CFTypeRef obj);
244 CFTypeRef copyBlob(CFTypeRef obj);
245 CFDataRef copySHA1(CFTypeRef obj);
246 CFTypeRef copyNumber(CFTypeRef obj);
247 CFDateRef copyDate(CFTypeRef obj);
248 CFTypeRef copyUUID(CFTypeRef obj);
249
250 // MARK: cFErrorPropagate which handles errSecAuthNeeded
251 static inline
252 bool SecErrorPropagate(CFErrorRef possibleError CF_CONSUMED, CFErrorRef *error) {
253 if (possibleError && error && *error && CFErrorGetCode(*error) == errSecAuthNeeded)
254 CFReleaseNull(*error);
255 return CFErrorPropagate(possibleError, error);
256 }
257
258 // TODO: Hack
259 bool SecDbItemInV2(SecDbItemRef item);
260 bool SecDbItemInV2AlsoInV0(SecDbItemRef item);
261
262 // For debug output filtering
263 bool SecDbItemIsEngineInternalState(SecDbItemRef itemObject);
264
265 __END_DECLS
266
267 #endif /* _SECURITYD_SECDBITEM_H_ */