]> git.saurik.com Git - apple/security.git/blob - keychain/securityd/SecDbItem.h
Security-59754.80.3.tar.gz
[apple/security.git] / keychain / 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 "keychain/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 kSecDbSyncSOSCannotSyncFlag= (1 << 17),
85 };
86
87 #define SecVersionDbFlag(v) ((v & 0xFF) << 8)
88
89 #define SecDbFlagGetVersion(flags) ((flags >> 8) & 0xFF)
90
91 #define SECDB_ATTR(var, name, kind, flags, copyValue, setValue) const SecDbAttr var = { CFSTR(name), kSecDb ## kind ## Attr, flags, copyValue, setValue }
92
93 typedef struct SecDbItem *SecDbItemRef;
94 typedef struct SecDbAttr SecDbAttr;
95
96 typedef CFTypeRef (*SecDbItemCopyAttrValue)(SecDbItemRef item, const SecDbAttr *attr, CFErrorRef *error);
97 typedef bool (*SecDbItemSetAttrValue)(SecDbItemRef item, const SecDbAttr *desc, CFTypeRef value, CFErrorRef *error);
98
99 struct SecDbAttr {
100 CFStringRef name;
101 SecDbAttrKind kind;
102 CFOptionFlags flags;
103 SecDbItemCopyAttrValue copyValue;
104 SecDbItemSetAttrValue setValue;
105 };
106
107 typedef struct SecDbClass {
108 CFStringRef name;
109 bool itemclass; // true if keychain items are stored in this class, false otherwise
110 const SecDbAttr *attrs[];
111 } SecDbClass;
112
113 typedef struct SecDbSchema {
114 int majorVersion;
115 int minorVersion;
116 const SecDbClass *classes[];
117 } SecDbSchema;
118
119
120 #define SecDbForEachAttr(class, attr) for (const SecDbAttr * const* _pattr = (class)->attrs, *attr = *_pattr; attr; attr = *(++_pattr))
121
122 #define SecDbForEachAttrWithMask(class, attr, flag_mask) SecDbForEachAttr(class, attr) if ((attr->flags & (flag_mask)) == (flag_mask))
123
124 CFTypeRef SecDbAttrCopyDefaultValue(const SecDbAttr *attr, CFErrorRef *error);
125
126
127 // MARK: SecDbItem
128
129 enum SecDbItemState {
130 kSecDbItemDirty, // We have no edata (or if we do it's invalid), attributes are the truth
131 kSecDbItemEncrypted, // Attributes haven't been decrypted yet from edata
132 kSecDbItemClean, // Attributes and _edata are in sync.
133 kSecDbItemDecrypting, // Temporary state while we are decrypting so set knows not to blow away the edata.
134 kSecDbItemEncrypting, // Temporary state while we are encrypting so set knows to move to clean.
135 kSecDbItemAlwaysEncrypted, // As kSecDbItemEncrypted, but decryption is never attempted
136 kSecDbItemSecretEncrypted, // Metadata is clean, but the secret data remains encrypted
137 };
138
139 struct SecDbItem {
140 CFRuntimeBase _base;
141 const SecDbClass *class;
142 keyclass_t keyclass;
143 keybag_handle_t keybag;
144 enum SecDbItemState _edataState;
145 CFMutableDictionaryRef attributes;
146 CFDataRef credHandle;
147 CFTypeRef cryptoOp;
148 CFArrayRef callerAccessGroups;
149 };
150
151 // TODO: Make this a callback to client
152 bool SecDbItemDecrypt(SecDbItemRef item, bool decryptSecretData, 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 CFTypeRef SecDbItemGetValueKind(SecDbItemRef item, SecDbAttrKind desc, CFErrorRef *error);
175
176 bool SecDbItemSetValue(SecDbItemRef item, const SecDbAttr *desc, CFTypeRef value, CFErrorRef *error);
177 bool SecDbItemSetValues(SecDbItemRef item, CFDictionaryRef values, CFErrorRef *error);
178 bool SecDbItemSetValueWithName(SecDbItemRef item, CFStringRef name, CFTypeRef value, CFErrorRef *error);
179
180 // Copies a given attribute from source to target. If source does not have that atttribute,
181 // doesn't modify target.
182 bool SecItemPreserveAttribute(SecDbItemRef target, SecDbItemRef source, const SecDbAttr* attr);
183
184 sqlite3_int64 SecDbItemGetRowId(SecDbItemRef item, CFErrorRef *error);
185 bool SecDbItemSetRowId(SecDbItemRef item, sqlite3_int64 rowid, CFErrorRef *error);
186 bool SecDbItemClearRowId(SecDbItemRef item, CFErrorRef *error);
187
188 bool SecDbItemIsSyncableOrCorrupted(SecDbItemRef item);
189 bool SecDbItemIsSyncable(SecDbItemRef item);
190
191 bool SecDbItemSetSyncable(SecDbItemRef item, bool sync, CFErrorRef *error);
192
193 bool SecDbItemIsTombstone(SecDbItemRef item);
194
195 CFMutableDictionaryRef SecDbItemCopyPListWithMask(SecDbItemRef item, CFOptionFlags mask, CFErrorRef *error);
196
197 /*
198 * Note that "mask" requires a single option, but flagsToSkip can have any number combined.
199 */
200 CFMutableDictionaryRef SecDbItemCopyPListWithFlagAndSkip(SecDbItemRef item,
201 CFOptionFlags mask,
202 CFOptionFlags flagsToSkip,
203 CFErrorRef *error);
204
205 CFDataRef SecDbItemGetPrimaryKey(SecDbItemRef item, CFErrorRef *error);
206 CFDataRef SecDbItemGetSHA1(SecDbItemRef item, CFErrorRef *error);
207
208 CFDataRef SecDbItemCopyEncryptedDataToBackup(SecDbItemRef item, uint64_t handle, CFErrorRef *error);
209
210 SecDbItemRef SecDbItemCreateWithStatement(CFAllocatorRef allocator, const SecDbClass *class, sqlite3_stmt *stmt, keybag_handle_t keybag, CFErrorRef *error, bool (^return_attr)(const SecDbAttr *attr));
211
212 SecDbItemRef SecDbItemCreateWithEncryptedData(CFAllocatorRef allocator, const SecDbClass *class,
213 CFDataRef edata, keybag_handle_t keybag, CFErrorRef *error);
214
215 SecDbItemRef SecDbItemCreateWithPrimaryKey(CFAllocatorRef allocator, const SecDbClass *class, CFDataRef primary_key);
216
217 #if 0
218 SecDbItemRef SecDbItemCreateWithRowId(CFAllocatorRef allocator, const SecDbClass *class, sqlite_int64 row_id, keybag_handle_t keybag, CFErrorRef *error);
219 #endif
220
221 bool SecDbItemEnsureDecrypted(SecDbItemRef item, bool decryptSecretData, CFErrorRef *error);
222
223 SecDbItemRef SecDbItemCopyWithUpdates(SecDbItemRef item, CFDictionaryRef updates, CFErrorRef *error);
224
225 bool SecDbItemInsertOrReplace(SecDbItemRef item, SecDbConnectionRef dbconn, CFErrorRef *error, void(^duplicate)(SecDbItemRef item, SecDbItemRef *replace));
226
227 // SecDbItemInsertOrReplace returns an error even when it succeeds; use this to determine if it's spurious
228 bool SecErrorIsSqliteDuplicateItemError(CFErrorRef error);
229
230 // Note: this function might modify item, unless always_use_uuid_from_new_item is true
231 bool SecDbItemInsert(SecDbItemRef item, SecDbConnectionRef dbconn, bool always_use_uuid_from_new_item, CFErrorRef *error);
232
233 bool SecDbItemDelete(SecDbItemRef item, SecDbConnectionRef dbconn, CFBooleanRef makeTombstone, bool tombstone_time_from_item, CFErrorRef *error);
234
235 bool SecDbItemDoDeleteSilently(SecDbItemRef item, SecDbConnectionRef dbconn, CFErrorRef *error);
236
237 // Low level update, just do the update
238 bool SecDbItemDoUpdate(SecDbItemRef old_item, SecDbItemRef new_item, SecDbConnectionRef dbconn, CFErrorRef *error, bool (^use_attr_in_where)(const SecDbAttr *attr));
239
240 // High level update, will replace tombstones and create them if needed.
241 bool SecDbItemUpdate(SecDbItemRef old_item, SecDbItemRef new_item, SecDbConnectionRef dbconn, CFBooleanRef makeTombstone, bool uuid_from_primary_key, CFErrorRef *error);
242
243
244 // MARK: -
245 // MARK: SQL Construction helpers -- These should become private in the future
246
247 void SecDbAppendElement(CFMutableStringRef sql, CFStringRef value, bool *needComma);
248 void SecDbAppendWhereOrAnd(CFMutableStringRef sql, bool *needWhere);
249 void SecDbAppendWhereOrAndEquals(CFMutableStringRef sql, CFStringRef col, bool *needWhere);
250 void SecDbAppendWhereOrAndNotEquals(CFMutableStringRef sql, CFStringRef col, bool *needWhere);
251 void SecDbAppendWhereOrAndIn(CFMutableStringRef sql, CFStringRef col, bool *needWhere, CFIndex count);
252 void SecDbAppendWhereOrAndNotIn(CFMutableStringRef sql, CFStringRef col, bool *needWhere, CFIndex count);
253
254 // MARK: type converters.
255 // TODO: these should be static and private to SecDbItem, or part of the schema
256
257 CFStringRef copyString(CFTypeRef obj);
258 CFDataRef copyData(CFTypeRef obj);
259 CFTypeRef copyBlob(CFTypeRef obj);
260 CFDataRef copySHA1(CFTypeRef obj);
261 CFTypeRef copyNumber(CFTypeRef obj);
262 CFDateRef copyDate(CFTypeRef obj);
263 CFTypeRef copyUUID(CFTypeRef obj);
264
265 // MARK: cFErrorPropagate which handles errSecAuthNeeded
266 static inline
267 bool SecErrorPropagate(CFErrorRef possibleError CF_CONSUMED, CFErrorRef *error) {
268 if (possibleError && error && *error && CFErrorGetCode(*error) == errSecAuthNeeded)
269 CFReleaseNull(*error);
270 return CFErrorPropagate(possibleError, error);
271 }
272
273 // TODO: Hack
274 bool SecDbItemInV2(SecDbItemRef item);
275 bool SecDbItemInV2AlsoInV0(SecDbItemRef item);
276
277 // For debug output filtering
278 bool SecDbItemIsEngineInternalState(SecDbItemRef itemObject);
279
280 __END_DECLS
281
282 #endif /* _SECURITYD_SECDBITEM_H_ */