2 * Copyright (c) 2012-2014 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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.
21 * @APPLE_LICENSE_HEADER_END@
26 The functions provided in SecDbItem provide an interface to
27 database items (certificates, keys, identities, and passwords).
30 #ifndef _SECURITYD_SECDBITEM_H_
31 #define _SECURITYD_SECDBITEM_H_
33 #include <CoreFoundation/CoreFoundation.h>
34 #include <TargetConditionals.h>
35 #include <corecrypto/ccsha1.h> // For CCSHA1_OUTPUT_SIZE
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>
44 // MARK SecDbAttrKind, SecDbFlag
47 kSecDbBlobAttr
, // CFString or CFData, preserves caller provided type.
52 kSecDbCreationDateAttr
,
53 kSecDbModificationDateAttr
,
56 kSecDbEncryptedDataAttr
,
62 kSecDbAccessControlAttr
,
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),
85 #define SecVersionDbFlag(v) ((v & 0xFF) << 8)
87 #define SecDbFlagGetVersion(flags) ((flags >> 8) & 0xFF)
89 #define SECDB_ATTR(var, name, kind, flags, copyValue, setValue) const SecDbAttr var = { CFSTR(name), kSecDb ## kind ## Attr, flags, copyValue, setValue }
91 typedef struct SecDbItem
*SecDbItemRef
;
92 typedef struct SecDbAttr SecDbAttr
;
94 typedef CFTypeRef (*SecDbItemCopyAttrValue
)(SecDbItemRef item
, const SecDbAttr
*attr
, CFErrorRef
*error
);
95 typedef bool (*SecDbItemSetAttrValue
)(SecDbItemRef item
, const SecDbAttr
*desc
, CFTypeRef value
, CFErrorRef
*error
);
101 SecDbItemCopyAttrValue copyValue
;
102 SecDbItemSetAttrValue setValue
;
105 typedef struct SecDbClass
{
107 const SecDbAttr
*attrs
[];
110 typedef struct SecDbSchema
{
112 const SecDbClass
*classes
[];
116 #define SecDbForEachAttr(class, attr) for (const SecDbAttr * const* _pattr = (class)->attrs, *attr = *_pattr; attr; attr = *(++_pattr))
118 #define SecDbForEachAttrWithMask(class, attr, flag_mask) SecDbForEachAttr(class, attr) if ((attr->flags & (flag_mask)) == (flag_mask))
120 CFTypeRef
SecDbAttrCopyDefaultValue(const SecDbAttr
*attr
, CFErrorRef
*error
);
125 enum SecDbItemState
{
126 kSecDbItemDirty
, // We have no edata (or if we do it's invalid), attributes are the truth
127 kSecDbItemEncrypted
, // Attributes haven't been decrypted yet from edata
128 kSecDbItemClean
, // Attributes and _edata are in sync.
129 kSecDbItemDecrypting
, // Temporary state while we are decrypting so set knows not to blow away the edata.
130 kSecDbItemEncrypting
, // Temporary state while we are encrypting so set knows to move to clean.
131 kSecDbItemAlwaysEncrypted
, // As kSecDbItemEncrypted, but decryption is never attempted
136 const SecDbClass
*class;
138 keybag_handle_t keybag
;
139 //sqlite3_int64 _rowid;
140 //CFDataRef _primaryKey;
143 enum SecDbItemState _edataState
;
144 CFMutableDictionaryRef attributes
;
145 CFTypeRef credHandle
;
147 CFArrayRef callerAccessGroups
;
150 // TODO: Make this a callback to client
151 bool SecDbItemDecrypt(SecDbItemRef item
, CFDataRef edata
, CFErrorRef
*error
);
153 CFTypeID
SecDbItemGetTypeID(void);
155 static inline size_t SecDbClassAttrCount(const SecDbClass
*dbClass
) {
157 SecDbForEachAttr(dbClass
, attr
) { n_attrs
++; }
161 const SecDbAttr
*SecDbClassAttrWithKind(const SecDbClass
*class, SecDbAttrKind kind
, CFErrorRef
*error
);
163 SecDbItemRef
SecDbItemCreateWithAttributes(CFAllocatorRef allocator
, const SecDbClass
*class, CFDictionaryRef attributes
, keybag_handle_t keybag
, CFErrorRef
*error
);
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
);
171 CFTypeRef
SecDbItemGetCachedValueWithName(SecDbItemRef item
, CFStringRef name
);
172 CFTypeRef
SecDbItemGetValue(SecDbItemRef item
, const SecDbAttr
*desc
, CFErrorRef
*error
);
174 bool SecDbItemSetValue(SecDbItemRef item
, const SecDbAttr
*desc
, CFTypeRef value
, CFErrorRef
*error
);
175 bool SecDbItemSetValues(SecDbItemRef item
, CFDictionaryRef values
, CFErrorRef
*error
);
176 bool SecDbItemSetValueWithName(SecDbItemRef item
, CFStringRef name
, CFTypeRef value
, CFErrorRef
*error
);
178 sqlite3_int64
SecDbItemGetRowId(SecDbItemRef item
, CFErrorRef
*error
);
179 bool SecDbItemSetRowId(SecDbItemRef item
, sqlite3_int64 rowid
, CFErrorRef
*error
);
180 bool SecDbItemClearRowId(SecDbItemRef item
, CFErrorRef
*error
);
182 bool SecDbItemIsSyncableOrCorrupted(SecDbItemRef item
);
183 bool SecDbItemIsSyncable(SecDbItemRef item
);
185 bool SecDbItemSetSyncable(SecDbItemRef item
, bool sync
, CFErrorRef
*error
);
187 bool SecDbItemIsTombstone(SecDbItemRef item
);
189 CFMutableDictionaryRef
SecDbItemCopyPListWithMask(SecDbItemRef item
, CFOptionFlags mask
, CFErrorRef
*error
);
191 CFDataRef
SecDbItemGetPrimaryKey(SecDbItemRef item
, CFErrorRef
*error
);
192 CFDataRef
SecDbItemGetSHA1(SecDbItemRef item
, CFErrorRef
*error
);
194 CFDataRef
SecDbItemCopyEncryptedDataToBackup(SecDbItemRef item
, uint64_t handle
, CFErrorRef
*error
);
196 SecDbItemRef
SecDbItemCreateWithStatement(CFAllocatorRef allocator
, const SecDbClass
*class, sqlite3_stmt
*stmt
, keybag_handle_t keybag
, CFErrorRef
*error
, bool (^return_attr
)(const SecDbAttr
*attr
));
198 SecDbItemRef
SecDbItemCreateWithEncryptedData(CFAllocatorRef allocator
, const SecDbClass
*class,
199 CFDataRef edata
, keybag_handle_t keybag
, CFErrorRef
*error
);
201 SecDbItemRef
SecDbItemCreateWithPrimaryKey(CFAllocatorRef allocator
, const SecDbClass
*class, CFDataRef primary_key
);
204 SecDbItemRef
SecDbItemCreateWithRowId(CFAllocatorRef allocator
, const SecDbClass
*class, sqlite_int64 row_id
, keybag_handle_t keybag
, CFErrorRef
*error
);
207 bool SecDbItemEnsureDecrypted(SecDbItemRef item
, CFErrorRef
*error
);
209 SecDbItemRef
SecDbItemCopyWithUpdates(SecDbItemRef item
, CFDictionaryRef updates
, CFErrorRef
*error
);
211 bool SecDbItemInsertOrReplace(SecDbItemRef item
, SecDbConnectionRef dbconn
, CFErrorRef
*error
, void(^duplicate
)(SecDbItemRef item
, SecDbItemRef
*replace
));
213 bool SecDbItemInsert(SecDbItemRef item
, SecDbConnectionRef dbconn
, CFErrorRef
*error
);
215 bool SecDbItemDelete(SecDbItemRef item
, SecDbConnectionRef dbconn
, CFBooleanRef makeTombstone
, CFErrorRef
*error
);
217 bool SecDbItemDoDeleteSilently(SecDbItemRef item
, SecDbConnectionRef dbconn
, CFErrorRef
*error
);
219 // Low level update, just do the update
220 bool SecDbItemDoUpdate(SecDbItemRef old_item
, SecDbItemRef new_item
, SecDbConnectionRef dbconn
, CFErrorRef
*error
, bool (^use_attr_in_where
)(const SecDbAttr
*attr
));
222 // High level update, will replace tombstones and create them if needed.
223 bool SecDbItemUpdate(SecDbItemRef old_item
, SecDbItemRef new_item
, SecDbConnectionRef dbconn
, CFBooleanRef makeTombstone
, CFErrorRef
*error
);
227 // MARK: SQL Construction helpers -- These should become private in the future
229 void SecDbAppendElement(CFMutableStringRef sql
, CFStringRef value
, bool *needComma
);
230 void SecDbAppendWhereOrAnd(CFMutableStringRef sql
, bool *needWhere
);
231 void SecDbAppendWhereOrAndEquals(CFMutableStringRef sql
, CFStringRef col
, bool *needWhere
);
232 void SecDbAppendWhereOrAndNotEquals(CFMutableStringRef sql
, CFStringRef col
, bool *needWhere
);
233 void SecDbAppendWhereOrAndIn(CFMutableStringRef sql
, CFStringRef col
, bool *needWhere
, CFIndex count
);
234 void SecDbAppendWhereOrAndNotIn(CFMutableStringRef sql
, CFStringRef col
, bool *needWhere
, CFIndex count
);
236 // MARK: type converters.
237 // TODO: these should be static and private to SecDbItem, or part of the schema
239 CFStringRef
copyString(CFTypeRef obj
);
240 CFDataRef
copyData(CFTypeRef obj
);
241 CFTypeRef
copyBlob(CFTypeRef obj
);
242 CFDataRef
copySHA1(CFTypeRef obj
);
243 CFTypeRef
copyNumber(CFTypeRef obj
);
244 CFDateRef
copyDate(CFTypeRef obj
);
245 CFTypeRef
copyUUID(CFTypeRef obj
);
247 // MARK: cFErrorPropagate which handles errSecAuthNeeded
249 bool SecErrorPropagate(CFErrorRef possibleError CF_CONSUMED
, CFErrorRef
*error
) {
250 if (possibleError
&& error
&& *error
&& CFErrorGetCode(*error
) == errSecAuthNeeded
)
251 CFReleaseNull(*error
);
252 return CFErrorPropagate(possibleError
, error
);
256 bool SecDbItemInV2(SecDbItemRef item
);
257 bool SecDbItemInV2AlsoInV0(SecDbItemRef item
);
261 #endif /* _SECURITYD_SECDBITEM_H_ */