]> git.saurik.com Git - apple/security.git/blob - keychain/securityd/SecDbItem.h
Security-59306.80.4.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 };
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 kSecDbItemSecretEncrypted, // Metadata is clean, but the secret data remains encrypted
136 };
137
138 struct SecDbItem {
139 CFRuntimeBase _base;
140 const SecDbClass *class;
141 keyclass_t keyclass;
142 keybag_handle_t keybag;
143 enum SecDbItemState _edataState;
144 CFMutableDictionaryRef attributes;
145 CFDataRef credHandle;
146 CFTypeRef cryptoOp;
147 CFArrayRef callerAccessGroups;
148 };
149
150 // TODO: Make this a callback to client
151 bool SecDbItemDecrypt(SecDbItemRef item, bool decryptSecretData, 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 CFTypeRef SecDbItemGetValueKind(SecDbItemRef item, SecDbAttrKind 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, bool decryptSecretData, 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 // SecDbItemInsertOrReplace returns an error even when it succeeds; use this to determine if it's spurious
215 bool SecErrorIsSqliteDuplicateItemError(CFErrorRef error);
216
217 bool SecDbItemInsert(SecDbItemRef item, SecDbConnectionRef dbconn, CFErrorRef *error);
218
219 bool SecDbItemDelete(SecDbItemRef item, SecDbConnectionRef dbconn, CFBooleanRef makeTombstone, CFErrorRef *error);
220
221 bool SecDbItemDoDeleteSilently(SecDbItemRef item, SecDbConnectionRef dbconn, CFErrorRef *error);
222
223 // Low level update, just do the update
224 bool SecDbItemDoUpdate(SecDbItemRef old_item, SecDbItemRef new_item, SecDbConnectionRef dbconn, CFErrorRef *error, bool (^use_attr_in_where)(const SecDbAttr *attr));
225
226 // High level update, will replace tombstones and create them if needed.
227 bool SecDbItemUpdate(SecDbItemRef old_item, SecDbItemRef new_item, SecDbConnectionRef dbconn, CFBooleanRef makeTombstone, bool uuid_from_primary_key, CFErrorRef *error);
228
229
230 // MARK: -
231 // MARK: SQL Construction helpers -- These should become private in the future
232
233 void SecDbAppendElement(CFMutableStringRef sql, CFStringRef value, bool *needComma);
234 void SecDbAppendWhereOrAnd(CFMutableStringRef sql, bool *needWhere);
235 void SecDbAppendWhereOrAndEquals(CFMutableStringRef sql, CFStringRef col, bool *needWhere);
236 void SecDbAppendWhereOrAndNotEquals(CFMutableStringRef sql, CFStringRef col, bool *needWhere);
237 void SecDbAppendWhereOrAndIn(CFMutableStringRef sql, CFStringRef col, bool *needWhere, CFIndex count);
238 void SecDbAppendWhereOrAndNotIn(CFMutableStringRef sql, CFStringRef col, bool *needWhere, CFIndex count);
239
240 // MARK: type converters.
241 // TODO: these should be static and private to SecDbItem, or part of the schema
242
243 CFStringRef copyString(CFTypeRef obj);
244 CFDataRef copyData(CFTypeRef obj);
245 CFTypeRef copyBlob(CFTypeRef obj);
246 CFDataRef copySHA1(CFTypeRef obj);
247 CFTypeRef copyNumber(CFTypeRef obj);
248 CFDateRef copyDate(CFTypeRef obj);
249 CFTypeRef copyUUID(CFTypeRef obj);
250
251 // MARK: cFErrorPropagate which handles errSecAuthNeeded
252 static inline
253 bool SecErrorPropagate(CFErrorRef possibleError CF_CONSUMED, CFErrorRef *error) {
254 if (possibleError && error && *error && CFErrorGetCode(*error) == errSecAuthNeeded)
255 CFReleaseNull(*error);
256 return CFErrorPropagate(possibleError, error);
257 }
258
259 // TODO: Hack
260 bool SecDbItemInV2(SecDbItemRef item);
261 bool SecDbItemInV2AlsoInV0(SecDbItemRef item);
262
263 // For debug output filtering
264 bool SecDbItemIsEngineInternalState(SecDbItemRef itemObject);
265
266 __END_DECLS
267
268 #endif /* _SECURITYD_SECDBITEM_H_ */