]> git.saurik.com Git - apple/security.git/blob - OSX/sec/securityd/SecDbItem.h
Security-57740.31.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 };
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
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 bool SecDbItemClearRowId(SecDbItemRef item, CFErrorRef *error);
178
179 bool SecDbItemIsSyncableOrCorrupted(SecDbItemRef item);
180 bool SecDbItemIsSyncable(SecDbItemRef item);
181
182 bool SecDbItemSetSyncable(SecDbItemRef item, bool sync, CFErrorRef *error);
183
184 bool SecDbItemIsTombstone(SecDbItemRef item);
185
186 CFMutableDictionaryRef SecDbItemCopyPListWithMask(SecDbItemRef item, CFOptionFlags mask, CFErrorRef *error);
187
188 CFDataRef SecDbItemGetPrimaryKey(SecDbItemRef item, CFErrorRef *error);
189 CFDataRef SecDbItemGetSHA1(SecDbItemRef item, CFErrorRef *error);
190
191 CFDataRef SecDbItemCopyEncryptedDataToBackup(SecDbItemRef item, uint64_t handle, CFErrorRef *error);
192
193 SecDbItemRef SecDbItemCreateWithStatement(CFAllocatorRef allocator, const SecDbClass *class, sqlite3_stmt *stmt, keybag_handle_t keybag, CFErrorRef *error, bool (^return_attr)(const SecDbAttr *attr));
194
195 SecDbItemRef SecDbItemCreateWithEncryptedData(CFAllocatorRef allocator, const SecDbClass *class,
196 CFDataRef edata, keybag_handle_t keybag, CFErrorRef *error);
197
198 SecDbItemRef SecDbItemCreateWithPrimaryKey(CFAllocatorRef allocator, const SecDbClass *class, CFDataRef primary_key);
199
200 #if 0
201 SecDbItemRef SecDbItemCreateWithRowId(CFAllocatorRef allocator, const SecDbClass *class, sqlite_int64 row_id, keybag_handle_t keybag, CFErrorRef *error);
202 #endif
203
204 bool SecDbItemEnsureDecrypted(SecDbItemRef item, CFErrorRef *error);
205
206 SecDbItemRef SecDbItemCopyWithUpdates(SecDbItemRef item, CFDictionaryRef updates, CFErrorRef *error);
207
208 bool SecDbItemInsertOrReplace(SecDbItemRef item, SecDbConnectionRef dbconn, CFErrorRef *error, void(^duplicate)(SecDbItemRef item, SecDbItemRef *replace));
209
210 bool SecDbItemInsert(SecDbItemRef item, SecDbConnectionRef dbconn, CFErrorRef *error);
211
212 bool SecDbItemDelete(SecDbItemRef item, SecDbConnectionRef dbconn, CFBooleanRef makeTombstone, CFErrorRef *error);
213
214 bool SecDbItemDoDeleteSilently(SecDbItemRef item, SecDbConnectionRef dbconn, CFErrorRef *error);
215
216 // Low level update, just do the update
217 bool SecDbItemDoUpdate(SecDbItemRef old_item, SecDbItemRef new_item, SecDbConnectionRef dbconn, CFErrorRef *error, bool (^use_attr_in_where)(const SecDbAttr *attr));
218
219 // High level update, will replace tombstones and create them if needed.
220 bool SecDbItemUpdate(SecDbItemRef old_item, SecDbItemRef new_item, SecDbConnectionRef dbconn, CFBooleanRef makeTombstone, CFErrorRef *error);
221
222
223 // MARK: -
224 // MARK: SQL Construction helpers -- These should become private in the future
225
226 void SecDbAppendElement(CFMutableStringRef sql, CFStringRef value, bool *needComma);
227 void SecDbAppendWhereOrAnd(CFMutableStringRef sql, bool *needWhere);
228 void SecDbAppendWhereOrAndEquals(CFMutableStringRef sql, CFStringRef col, bool *needWhere);
229 void SecDbAppendWhereOrAndNotEquals(CFMutableStringRef sql, CFStringRef col, bool *needWhere);
230 void SecDbAppendWhereOrAndIn(CFMutableStringRef sql, CFStringRef col, bool *needWhere, CFIndex count);
231 void SecDbAppendWhereOrAndNotIn(CFMutableStringRef sql, CFStringRef col, bool *needWhere, CFIndex count);
232
233 // MARK: type converters.
234 // TODO: these should be static and private to SecDbItem, or part of the schema
235
236 CFStringRef copyString(CFTypeRef obj);
237 CFDataRef copyData(CFTypeRef obj);
238 CFTypeRef copyBlob(CFTypeRef obj);
239 CFDataRef copySHA1(CFTypeRef obj);
240 CFTypeRef copyNumber(CFTypeRef obj);
241 CFDateRef copyDate(CFTypeRef obj);
242 CFTypeRef copyUUID(CFTypeRef obj);
243
244 // MARK: cFErrorPropagate which handles errSecAuthNeeded
245 static inline
246 bool SecErrorPropagate(CFErrorRef possibleError CF_CONSUMED, CFErrorRef *error) {
247 if (possibleError && error && *error && CFErrorGetCode(*error) == errSecAuthNeeded)
248 CFReleaseNull(*error);
249 return CFErrorPropagate(possibleError, error);
250 }
251
252 // TODO: Hack
253 bool SecDbItemInV2(SecDbItemRef item);
254 bool SecDbItemInV2AlsoInV0(SecDbItemRef item);
255
256 __END_DECLS
257
258 #endif /* _SECURITYD_SECDBITEM_H_ */