]> git.saurik.com Git - apple/security.git/blob - OSX/sec/securityd/SecDbItem.h
Security-57740.60.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 enum SecDbItemState _edataState;
141 CFMutableDictionaryRef attributes;
142 CFDataRef credHandle;
143 CFTypeRef cryptoOp;
144 CFArrayRef callerAccessGroups;
145 };
146
147 // TODO: Make this a callback to client
148 bool SecDbItemDecrypt(SecDbItemRef item, CFDataRef edata, CFErrorRef *error);
149
150 CFTypeID SecDbItemGetTypeID(void);
151
152 static inline size_t SecDbClassAttrCount(const SecDbClass *dbClass) {
153 size_t n_attrs = 0;
154 SecDbForEachAttr(dbClass, attr) { n_attrs++; }
155 return n_attrs;
156 }
157
158 const SecDbAttr *SecDbClassAttrWithKind(const SecDbClass *class, SecDbAttrKind kind, CFErrorRef *error);
159
160 SecDbItemRef SecDbItemCreateWithAttributes(CFAllocatorRef allocator, const SecDbClass *class, CFDictionaryRef attributes, keybag_handle_t keybag, CFErrorRef *error);
161
162 const SecDbClass *SecDbItemGetClass(SecDbItemRef item);
163 keybag_handle_t SecDbItemGetKeybag(SecDbItemRef item);
164 bool SecDbItemSetKeybag(SecDbItemRef item, keybag_handle_t keybag, CFErrorRef *error);
165 void SecDbItemSetCredHandle(SecDbItemRef item, CFTypeRef cred_handle);
166 void SecDbItemSetCallerAccessGroups(SecDbItemRef item, CFArrayRef caller_access_groups);
167
168 CFTypeRef SecDbItemGetCachedValueWithName(SecDbItemRef item, CFStringRef name);
169 CFTypeRef SecDbItemGetValue(SecDbItemRef item, const SecDbAttr *desc, CFErrorRef *error);
170 CFTypeRef SecDbItemGetValueKind(SecDbItemRef item, SecDbAttrKind desc, CFErrorRef *error);
171
172 bool SecDbItemSetValue(SecDbItemRef item, const SecDbAttr *desc, CFTypeRef value, CFErrorRef *error);
173 bool SecDbItemSetValues(SecDbItemRef item, CFDictionaryRef values, CFErrorRef *error);
174 bool SecDbItemSetValueWithName(SecDbItemRef item, CFStringRef name, CFTypeRef value, CFErrorRef *error);
175
176 sqlite3_int64 SecDbItemGetRowId(SecDbItemRef item, CFErrorRef *error);
177 bool SecDbItemSetRowId(SecDbItemRef item, sqlite3_int64 rowid, CFErrorRef *error);
178 bool SecDbItemClearRowId(SecDbItemRef item, CFErrorRef *error);
179
180 bool SecDbItemIsSyncableOrCorrupted(SecDbItemRef item);
181 bool SecDbItemIsSyncable(SecDbItemRef item);
182
183 bool SecDbItemSetSyncable(SecDbItemRef item, bool sync, CFErrorRef *error);
184
185 bool SecDbItemIsTombstone(SecDbItemRef item);
186
187 CFMutableDictionaryRef SecDbItemCopyPListWithMask(SecDbItemRef item, CFOptionFlags mask, CFErrorRef *error);
188
189 CFDataRef SecDbItemGetPrimaryKey(SecDbItemRef item, CFErrorRef *error);
190 CFDataRef SecDbItemGetSHA1(SecDbItemRef item, CFErrorRef *error);
191
192 CFDataRef SecDbItemCopyEncryptedDataToBackup(SecDbItemRef item, uint64_t handle, CFErrorRef *error);
193
194 SecDbItemRef SecDbItemCreateWithStatement(CFAllocatorRef allocator, const SecDbClass *class, sqlite3_stmt *stmt, keybag_handle_t keybag, CFErrorRef *error, bool (^return_attr)(const SecDbAttr *attr));
195
196 SecDbItemRef SecDbItemCreateWithEncryptedData(CFAllocatorRef allocator, const SecDbClass *class,
197 CFDataRef edata, keybag_handle_t keybag, CFErrorRef *error);
198
199 SecDbItemRef SecDbItemCreateWithPrimaryKey(CFAllocatorRef allocator, const SecDbClass *class, CFDataRef primary_key);
200
201 #if 0
202 SecDbItemRef SecDbItemCreateWithRowId(CFAllocatorRef allocator, const SecDbClass *class, sqlite_int64 row_id, keybag_handle_t keybag, CFErrorRef *error);
203 #endif
204
205 bool SecDbItemEnsureDecrypted(SecDbItemRef item, CFErrorRef *error);
206
207 SecDbItemRef SecDbItemCopyWithUpdates(SecDbItemRef item, CFDictionaryRef updates, CFErrorRef *error);
208
209 bool SecDbItemInsertOrReplace(SecDbItemRef item, SecDbConnectionRef dbconn, CFErrorRef *error, void(^duplicate)(SecDbItemRef item, SecDbItemRef *replace));
210
211 bool SecDbItemInsert(SecDbItemRef item, SecDbConnectionRef dbconn, CFErrorRef *error);
212
213 bool SecDbItemDelete(SecDbItemRef item, SecDbConnectionRef dbconn, CFBooleanRef makeTombstone, CFErrorRef *error);
214
215 bool SecDbItemDoDeleteSilently(SecDbItemRef item, SecDbConnectionRef dbconn, CFErrorRef *error);
216
217 // Low level update, just do the update
218 bool SecDbItemDoUpdate(SecDbItemRef old_item, SecDbItemRef new_item, SecDbConnectionRef dbconn, CFErrorRef *error, bool (^use_attr_in_where)(const SecDbAttr *attr));
219
220 // High level update, will replace tombstones and create them if needed.
221 bool SecDbItemUpdate(SecDbItemRef old_item, SecDbItemRef new_item, SecDbConnectionRef dbconn, CFBooleanRef makeTombstone, CFErrorRef *error);
222
223
224 // MARK: -
225 // MARK: SQL Construction helpers -- These should become private in the future
226
227 void SecDbAppendElement(CFMutableStringRef sql, CFStringRef value, bool *needComma);
228 void SecDbAppendWhereOrAnd(CFMutableStringRef sql, bool *needWhere);
229 void SecDbAppendWhereOrAndEquals(CFMutableStringRef sql, CFStringRef col, bool *needWhere);
230 void SecDbAppendWhereOrAndNotEquals(CFMutableStringRef sql, CFStringRef col, bool *needWhere);
231 void SecDbAppendWhereOrAndIn(CFMutableStringRef sql, CFStringRef col, bool *needWhere, CFIndex count);
232 void SecDbAppendWhereOrAndNotIn(CFMutableStringRef sql, CFStringRef col, bool *needWhere, CFIndex count);
233
234 // MARK: type converters.
235 // TODO: these should be static and private to SecDbItem, or part of the schema
236
237 CFStringRef copyString(CFTypeRef obj);
238 CFDataRef copyData(CFTypeRef obj);
239 CFTypeRef copyBlob(CFTypeRef obj);
240 CFDataRef copySHA1(CFTypeRef obj);
241 CFTypeRef copyNumber(CFTypeRef obj);
242 CFDateRef copyDate(CFTypeRef obj);
243 CFTypeRef copyUUID(CFTypeRef obj);
244
245 // MARK: cFErrorPropagate which handles errSecAuthNeeded
246 static inline
247 bool SecErrorPropagate(CFErrorRef possibleError CF_CONSUMED, CFErrorRef *error) {
248 if (possibleError && error && *error && CFErrorGetCode(*error) == errSecAuthNeeded)
249 CFReleaseNull(*error);
250 return CFErrorPropagate(possibleError, error);
251 }
252
253 // TODO: Hack
254 bool SecDbItemInV2(SecDbItemRef item);
255 bool SecDbItemInV2AlsoInV0(SecDbItemRef item);
256
257 __END_DECLS
258
259 #endif /* _SECURITYD_SECDBITEM_H_ */