]> git.saurik.com Git - apple/security.git/blob - OSX/sec/securityd/SecDbItem.h
Security-57337.20.44.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 } SecDbAttrKind;
64
65 enum {
66 kSecDbPrimaryKeyFlag = (1 << 0), // attr is part of primary key
67 kSecDbInFlag = (1 << 1), // attr exists in db
68 kSecDbIndexFlag = (1 << 2), // attr should have a db index
69 kSecDbSHA1ValueInFlag = (1 << 3), // col in db is sha1 of attr value
70 kSecDbReturnAttrFlag = (1 << 4),
71 kSecDbReturnDataFlag = (1 << 5),
72 kSecDbReturnRefFlag = (1 << 6),
73 kSecDbInCryptoDataFlag = (1 << 7),
74 kSecDbInHashFlag = (1 << 8),
75 kSecDbInBackupFlag = (1 << 9),
76 kSecDbDefault0Flag = (1 << 10), // default attr value is 0
77 kSecDbDefaultEmptyFlag = (1 << 11), // default attr value is ""
78 kSecDbNotNullFlag = (1 << 12), // attr value can't be null
79 kSecDbInAuthenticatedDataFlag = (1 << 13), // attr is in authenticated data
80 };
81
82 #define SecVersionDbFlag(v) ((v & 0xFF) << 8)
83
84 #define SecDbFlagGetVersion(flags) ((flags >> 8) & 0xFF)
85
86 #define SECDB_ATTR(var, name, kind, flags, copyValue, setValue) const SecDbAttr var = { CFSTR(name), kSecDb ## kind ## Attr, flags, copyValue, setValue }
87
88 typedef struct SecDbItem *SecDbItemRef;
89 typedef struct SecDbAttr SecDbAttr;
90
91 typedef CFTypeRef (*SecDbItemCopyAttrValue)(SecDbItemRef item, const SecDbAttr *attr, CFErrorRef *error);
92 typedef bool (*SecDbItemSetAttrValue)(SecDbItemRef item, const SecDbAttr *desc, CFTypeRef value, CFErrorRef *error);
93
94 struct SecDbAttr {
95 CFStringRef name;
96 SecDbAttrKind kind;
97 CFOptionFlags flags;
98 SecDbItemCopyAttrValue copyValue;
99 SecDbItemSetAttrValue setValue;
100 };
101
102 typedef struct SecDbClass {
103 CFStringRef name;
104 const SecDbAttr *attrs[];
105 } SecDbClass;
106
107 typedef struct SecDbSchema {
108 int version;
109 const SecDbClass *classes[];
110 } SecDbSchema;
111
112
113 #define SecDbForEachAttr(class, attr) for (const SecDbAttr * const* _pattr = (class)->attrs, *attr = *_pattr; attr; attr = *(++_pattr))
114
115 #define SecDbForEachAttrWithMask(class, attr, flag_mask) SecDbForEachAttr(class, attr) if ((attr->flags & (flag_mask)) == (flag_mask))
116
117 CFTypeRef SecDbAttrCopyDefaultValue(const SecDbAttr *attr, CFErrorRef *error);
118
119
120 // MARK: SecDbItem
121
122 enum SecDbItemState {
123 kSecDbItemDirty, // We have no edata (or if we do it's invalid), attributes are the truth
124 kSecDbItemEncrypted, // Attributes haven't been decrypted yet from edata
125 kSecDbItemClean, // Attributes and _edata are in sync.
126 kSecDbItemDecrypting, // Temporary state while we are decrypting so set knows not to blow away the edata.
127 kSecDbItemEncrypting, // Temporary state while we are encrypting so set knows to move to clean.
128 kSecDbItemAlwaysEncrypted, // As kSecDbItemEncrypted, but decryption is never attempted
129 };
130
131 struct SecDbItem {
132 CFRuntimeBase _base;
133 const SecDbClass *class;
134 keyclass_t keyclass;
135 keybag_handle_t keybag;
136 //sqlite3_int64 _rowid;
137 //CFDataRef _primaryKey;
138 //CFDataRef _sha1;
139 //CFDataRef _edata;
140 enum SecDbItemState _edataState;
141 CFMutableDictionaryRef attributes;
142 CFTypeRef 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
171 bool SecDbItemSetValue(SecDbItemRef item, const SecDbAttr *desc, CFTypeRef value, CFErrorRef *error);
172 bool SecDbItemSetValues(SecDbItemRef item, CFDictionaryRef values, CFErrorRef *error);
173 bool SecDbItemSetValueWithName(SecDbItemRef item, CFStringRef name, CFTypeRef value, CFErrorRef *error);
174
175 sqlite3_int64 SecDbItemGetRowId(SecDbItemRef item, CFErrorRef *error);
176 bool SecDbItemSetRowId(SecDbItemRef item, sqlite3_int64 rowid, CFErrorRef *error);
177
178 bool SecDbItemIsSyncableOrCorrupted(SecDbItemRef item);
179 bool SecDbItemIsSyncable(SecDbItemRef item);
180
181 bool SecDbItemSetSyncable(SecDbItemRef item, bool sync, CFErrorRef *error);
182
183 bool SecDbItemIsTombstone(SecDbItemRef item);
184
185 CFMutableDictionaryRef SecDbItemCopyPListWithMask(SecDbItemRef item, CFOptionFlags mask, CFErrorRef *error);
186
187 CFDataRef SecDbItemGetPrimaryKey(SecDbItemRef item, CFErrorRef *error);
188 CFDataRef SecDbItemGetSHA1(SecDbItemRef item, CFErrorRef *error);
189
190 CFDataRef SecDbItemCopyEncryptedDataToBackup(SecDbItemRef item, uint64_t handle, CFErrorRef *error);
191
192 SecDbItemRef SecDbItemCreateWithStatement(CFAllocatorRef allocator, const SecDbClass *class, sqlite3_stmt *stmt, keybag_handle_t keybag, CFErrorRef *error, bool (^return_attr)(const SecDbAttr *attr));
193
194 SecDbItemRef SecDbItemCreateWithEncryptedData(CFAllocatorRef allocator, const SecDbClass *class,
195 CFDataRef edata, keybag_handle_t keybag, CFErrorRef *error);
196
197 SecDbItemRef SecDbItemCreateWithPrimaryKey(CFAllocatorRef allocator, const SecDbClass *class, CFDataRef primary_key);
198
199 #if 0
200 SecDbItemRef SecDbItemCreateWithRowId(CFAllocatorRef allocator, const SecDbClass *class, sqlite_int64 row_id, keybag_handle_t keybag, CFErrorRef *error);
201 #endif
202
203 bool SecDbItemEnsureDecrypted(SecDbItemRef item, CFErrorRef *error);
204
205 SecDbItemRef SecDbItemCopyWithUpdates(SecDbItemRef item, CFDictionaryRef updates, CFErrorRef *error);
206
207 bool SecDbItemInsertOrReplace(SecDbItemRef item, SecDbConnectionRef dbconn, CFErrorRef *error, void(^duplicate)(SecDbItemRef item, SecDbItemRef *replace));
208
209 bool SecDbItemInsert(SecDbItemRef item, SecDbConnectionRef dbconn, CFErrorRef *error);
210
211 bool SecDbItemDelete(SecDbItemRef item, SecDbConnectionRef dbconn, CFBooleanRef makeTombstone, CFErrorRef *error);
212
213 bool SecDbItemDoDeleteSilently(SecDbItemRef item, SecDbConnectionRef dbconn, CFErrorRef *error);
214
215 // Low level update, just do the update
216 bool SecDbItemDoUpdate(SecDbItemRef old_item, SecDbItemRef new_item, SecDbConnectionRef dbconn, CFErrorRef *error, bool (^use_attr_in_where)(const SecDbAttr *attr));
217
218 // High level update, will replace tombstones and create them if needed.
219 bool SecDbItemUpdate(SecDbItemRef old_item, SecDbItemRef new_item, SecDbConnectionRef dbconn, CFBooleanRef makeTombstone, CFErrorRef *error);
220
221
222 // MARK: -
223 // MARK: SQL Construction helpers -- These should become private in the future
224
225 void SecDbAppendElement(CFMutableStringRef sql, CFStringRef value, bool *needComma);
226 void SecDbAppendWhereOrAnd(CFMutableStringRef sql, bool *needWhere);
227 void SecDbAppendWhereOrAndEquals(CFMutableStringRef sql, CFStringRef col, bool *needWhere);
228 void SecDbAppendWhereOrAndNotEquals(CFMutableStringRef sql, CFStringRef col, bool *needWhere);
229 void SecDbAppendWhereOrAndIn(CFMutableStringRef sql, CFStringRef col, bool *needWhere, CFIndex count);
230 void SecDbAppendWhereOrAndNotIn(CFMutableStringRef sql, CFStringRef col, bool *needWhere, CFIndex count);
231
232 // MARK: type converters.
233 // TODO: these should be static and private to SecDbItem, or part of the schema
234
235 CFStringRef copyString(CFTypeRef obj);
236 CFDataRef copyData(CFTypeRef obj);
237 CFTypeRef copyBlob(CFTypeRef obj);
238 CFDataRef copySHA1(CFTypeRef obj);
239 CFTypeRef copyNumber(CFTypeRef obj);
240 CFDateRef copyDate(CFTypeRef obj);
241
242 // MARK: cFErrorPropagate which handles errSecAuthNeeded
243 static inline
244 bool SecErrorPropagate(CFErrorRef possibleError CF_CONSUMED, CFErrorRef *error) {
245 if (possibleError && error && *error && CFErrorGetCode(*error) == errSecAuthNeeded)
246 CFReleaseNull(*error);
247 return CFErrorPropagate(possibleError, error);
248 }
249
250 // TODO: Hack
251 bool SecDbItemInV2(SecDbItemRef item);
252 bool SecDbItemInV2AlsoInV0(SecDbItemRef item);
253
254 __END_DECLS
255
256 #endif /* _SECURITYD_SECDBITEM_H_ */