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
{
113 const SecDbClass
*classes
[];
117 #define SecDbForEachAttr(class, attr) for (const SecDbAttr * const* _pattr = (class)->attrs, *attr = *_pattr; attr; attr = *(++_pattr))
119 #define SecDbForEachAttrWithMask(class, attr, flag_mask) SecDbForEachAttr(class, attr) if ((attr->flags & (flag_mask)) == (flag_mask))
121 CFTypeRef
SecDbAttrCopyDefaultValue(const SecDbAttr
*attr
, CFErrorRef
*error
);
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
137 const SecDbClass
*class;
139 keybag_handle_t keybag
;
140 enum SecDbItemState _edataState
;
141 CFMutableDictionaryRef attributes
;
142 CFDataRef credHandle
;
144 CFArrayRef callerAccessGroups
;
147 // TODO: Make this a callback to client
148 bool SecDbItemDecrypt(SecDbItemRef item
, CFDataRef edata
, CFErrorRef
*error
);
150 CFTypeID
SecDbItemGetTypeID(void);
152 static inline size_t SecDbClassAttrCount(const SecDbClass
*dbClass
) {
154 SecDbForEachAttr(dbClass
, attr
) { n_attrs
++; }
158 const SecDbAttr
*SecDbClassAttrWithKind(const SecDbClass
*class, SecDbAttrKind kind
, CFErrorRef
*error
);
160 SecDbItemRef
SecDbItemCreateWithAttributes(CFAllocatorRef allocator
, const SecDbClass
*class, CFDictionaryRef attributes
, keybag_handle_t keybag
, CFErrorRef
*error
);
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
);
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
);
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
);
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
);
180 bool SecDbItemIsSyncableOrCorrupted(SecDbItemRef item
);
181 bool SecDbItemIsSyncable(SecDbItemRef item
);
183 bool SecDbItemSetSyncable(SecDbItemRef item
, bool sync
, CFErrorRef
*error
);
185 bool SecDbItemIsTombstone(SecDbItemRef item
);
187 CFMutableDictionaryRef
SecDbItemCopyPListWithMask(SecDbItemRef item
, CFOptionFlags mask
, CFErrorRef
*error
);
189 CFDataRef
SecDbItemGetPrimaryKey(SecDbItemRef item
, CFErrorRef
*error
);
190 CFDataRef
SecDbItemGetSHA1(SecDbItemRef item
, CFErrorRef
*error
);
192 CFDataRef
SecDbItemCopyEncryptedDataToBackup(SecDbItemRef item
, uint64_t handle
, CFErrorRef
*error
);
194 SecDbItemRef
SecDbItemCreateWithStatement(CFAllocatorRef allocator
, const SecDbClass
*class, sqlite3_stmt
*stmt
, keybag_handle_t keybag
, CFErrorRef
*error
, bool (^return_attr
)(const SecDbAttr
*attr
));
196 SecDbItemRef
SecDbItemCreateWithEncryptedData(CFAllocatorRef allocator
, const SecDbClass
*class,
197 CFDataRef edata
, keybag_handle_t keybag
, CFErrorRef
*error
);
199 SecDbItemRef
SecDbItemCreateWithPrimaryKey(CFAllocatorRef allocator
, const SecDbClass
*class, CFDataRef primary_key
);
202 SecDbItemRef
SecDbItemCreateWithRowId(CFAllocatorRef allocator
, const SecDbClass
*class, sqlite_int64 row_id
, keybag_handle_t keybag
, CFErrorRef
*error
);
205 bool SecDbItemEnsureDecrypted(SecDbItemRef item
, CFErrorRef
*error
);
207 SecDbItemRef
SecDbItemCopyWithUpdates(SecDbItemRef item
, CFDictionaryRef updates
, CFErrorRef
*error
);
209 bool SecDbItemInsertOrReplace(SecDbItemRef item
, SecDbConnectionRef dbconn
, CFErrorRef
*error
, void(^duplicate
)(SecDbItemRef item
, SecDbItemRef
*replace
));
211 bool SecDbItemInsert(SecDbItemRef item
, SecDbConnectionRef dbconn
, CFErrorRef
*error
);
213 bool SecDbItemDelete(SecDbItemRef item
, SecDbConnectionRef dbconn
, CFBooleanRef makeTombstone
, CFErrorRef
*error
);
215 bool SecDbItemDoDeleteSilently(SecDbItemRef item
, SecDbConnectionRef dbconn
, CFErrorRef
*error
);
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
));
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
);
225 // MARK: SQL Construction helpers -- These should become private in the future
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
);
234 // MARK: type converters.
235 // TODO: these should be static and private to SecDbItem, or part of the schema
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
);
245 // MARK: cFErrorPropagate which handles errSecAuthNeeded
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
);
254 bool SecDbItemInV2(SecDbItemRef item
);
255 bool SecDbItemInV2AlsoInV0(SecDbItemRef item
);
259 #endif /* _SECURITYD_SECDBITEM_H_ */