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
43// MARK SecDbAttrKind, SecDbFlag
44
45typedef enum {
46    kSecDbBlobAttr,  // CFString or CFData, preserves caller provided type.
47    kSecDbDataAttr,
48    kSecDbStringAttr,
49    kSecDbNumberAttr,
50    kSecDbDateAttr,
51    kSecDbCreationDateAttr,
52    kSecDbModificationDateAttr,
53    kSecDbSHA1Attr,
54    kSecDbRowIdAttr,
55    kSecDbEncryptedDataAttr,
56    kSecDbPrimaryKeyAttr,
57    kSecDbSyncAttr,
58    kSecDbTombAttr,
59    kSecDbAccessAttr,
60    kSecDbAccessControlAttr
61} SecDbAttrKind;
62
63enum {
64    kSecDbPrimaryKeyFlag    = (1 <<  0),    // attr is part of primary key
65    kSecDbInFlag            = (1 <<  1),    // attr exists in db
66    kSecDbIndexFlag         = (1 <<  2),    // attr should have a db index
67    kSecDbSHA1ValueInFlag   = (1 <<  3),    // col in db is sha1 of attr value
68    kSecDbReturnAttrFlag    = (1 <<  4),
69    kSecDbReturnDataFlag    = (1 <<  5),
70    kSecDbReturnRefFlag     = (1 <<  6),
71    kSecDbInCryptoDataFlag  = (1 <<  7),
72    kSecDbInHashFlag        = (1 <<  8),
73    kSecDbInBackupFlag      = (1 <<  9),
74    kSecDbDefault0Flag      = (1 << 10),    // default attr value is 0
75    kSecDbDefaultEmptyFlag  = (1 << 11),    // default attr value is ""
76    kSecDbNotNullFlag       = (1 << 12),    // attr value can't be null
77    kSecDbInAuthenticatedDataFlag = (1 << 13),
78};
79
80#define SecVersionDbFlag(v) ((v & 0xFF) << 8)
81
82#define SecDbFlagGetVersion(flags) ((flags >> 8) & 0xFF)
83
84#define SECDB_ATTR(var, name, kind, flags) const SecDbAttr var = { CFSTR(name), kSecDb ## kind ## Attr, flags }
85
86typedef struct SecDbAttr {
87    CFStringRef name;
88    SecDbAttrKind kind;
89    CFOptionFlags flags;
90} SecDbAttr;
91
92typedef struct SecDbClass {
93    CFStringRef name;
94    const SecDbAttr *attrs[];
95} SecDbClass;
96
97
98#define SecDbForEachAttr(class, attr) for (const SecDbAttr * const* _pattr = (class)->attrs, *attr = *_pattr; attr; attr = *(++_pattr))
99
100#define SecDbForEachAttrWithMask(class, attr, flag_mask) SecDbForEachAttr(class, attr) if ((attr->flags & (flag_mask)) == (flag_mask))
101
102// MARK: Stuff that needs to move out of SecItemServer.c
103
104
105CFDataRef kc_copy_sha1(size_t len, const void *data, CFErrorRef *error);
106CFDataRef kc_copy_plist_sha1(CFPropertyListRef plist, CFErrorRef *error);
107CFDataRef kc_plist_copy_der(CFPropertyListRef plist, CFErrorRef *error);
108
109// MARK: SecDbItem
110
111typedef struct SecDbItem *SecDbItemRef;
112
113enum SecDbItemState {
114    kSecDbItemDirty,          // We have no edata (or if we do it's invalid), attributes are the truth
115    kSecDbItemEncrypted,      // Attributes haven't been decrypted yet from edata
116    kSecDbItemClean,          // Attributes and _edata are in sync.
117    kSecDbItemDecrypting,     // Temporary state while we are decrypting so set knows not to blow away the edata.
118    kSecDbItemEncrypting,     // Temporary state while we are encrypting so set knows to move to clean.
119};
120
121struct SecDbItem {
122    CFRuntimeBase _base;
123    const SecDbClass *class;
124    keyclass_t keyclass;
125    keybag_handle_t keybag;
126    //sqlite3_int64 _rowid;
127    //CFDataRef _primaryKey;
128    //CFDataRef _sha1;
129    //CFDataRef _edata;
130    enum SecDbItemState _edataState;
131    CFMutableDictionaryRef attributes;
132    CFTypeRef credHandle;
133    enum SecKsCryptoOp cryptoOp;
134    CFArrayRef callerAccessGroups;
135};
136
137// TODO: Make this a callback to client
138bool SecDbItemDecrypt(SecDbItemRef item, CFDataRef edata, CFDataRef *neededAuth, CFErrorRef *error);
139
140CFTypeID SecDbItemGetTypeID(void);
141
142static inline size_t SecDbClassAttrCount(const SecDbClass *dbClass) {
143    size_t n_attrs = 0;
144    SecDbForEachAttr(dbClass, attr) { n_attrs++; }
145    return n_attrs;
146}
147
148const SecDbAttr *SecDbClassAttrWithKind(const SecDbClass *class, SecDbAttrKind kind, CFErrorRef *error);
149
150SecDbItemRef SecDbItemCreateWithAttributes(CFAllocatorRef allocator, const SecDbClass *class, CFDictionaryRef attributes, keybag_handle_t keybag, CFErrorRef *error);
151
152const SecDbClass *SecDbItemGetClass(SecDbItemRef item);
153keybag_handle_t SecDbItemGetKeybag(SecDbItemRef item);
154bool SecDbItemSetKeybag(SecDbItemRef item, keybag_handle_t keybag, CFErrorRef *error);
155SecAccessControlRef SecDbItemCopyAccessControl(SecDbItemRef item, CFErrorRef *error);
156bool SecDbItemSetAccessControl(SecDbItemRef item, SecAccessControlRef access_control, CFErrorRef *error);
157void SecDbItemSetCredHandle(SecDbItemRef item, CFTypeRef cred_handle);
158void SecDbItemSetCallerAccessGroups(SecDbItemRef item, CFArrayRef caller_access_groups);
159
160CFTypeRef SecDbItemGetCachedValueWithName(SecDbItemRef item, CFStringRef name);
161CFTypeRef SecDbItemGetValue(SecDbItemRef item, const SecDbAttr *desc, CFErrorRef *error);
162
163bool SecDbItemSetValue(SecDbItemRef item, const SecDbAttr *desc, CFTypeRef value, CFErrorRef *error);
164bool SecDbItemSetValues(SecDbItemRef item, CFDictionaryRef values, CFErrorRef *error);
165bool SecDbItemSetValueWithName(SecDbItemRef item, CFStringRef name, CFTypeRef value, CFErrorRef *error);
166
167sqlite3_int64 SecDbItemGetRowId(SecDbItemRef item, CFErrorRef *error);
168bool SecDbItemSetRowId(SecDbItemRef item, sqlite3_int64 rowid, CFErrorRef *error);
169
170bool SecDbItemIsSyncableOrCorrupted(SecDbItemRef item);
171bool SecDbItemIsSyncable(SecDbItemRef item);
172
173bool SecDbItemSetSyncable(SecDbItemRef item, bool sync, CFErrorRef *error);
174
175bool SecDbItemIsTombstone(SecDbItemRef item);
176
177CFMutableDictionaryRef SecDbItemCopyPListWithMask(SecDbItemRef item, CFOptionFlags mask, CFErrorRef *error);
178
179CFDataRef SecDbItemGetPrimaryKey(SecDbItemRef item, CFErrorRef *error);
180CFDataRef SecDbItemGetSHA1(SecDbItemRef item, CFErrorRef *error);
181
182CFDataRef SecDbItemCopyEncryptedDataToBackup(SecDbItemRef item, uint64_t handle, CFErrorRef *error);
183
184SecDbItemRef SecDbItemCreateWithStatement(CFAllocatorRef allocator, const SecDbClass *class, sqlite3_stmt *stmt, keybag_handle_t keybag, CFErrorRef *error, bool (^return_attr)(const SecDbAttr *attr));
185
186SecDbItemRef SecDbItemCreateWithEncryptedData(CFAllocatorRef allocator, const SecDbClass *class,
187                                              CFDataRef edata, keybag_handle_t keybag, CFErrorRef *error);
188
189SecDbItemRef SecDbItemCreateWithPrimaryKey(CFAllocatorRef allocator, const SecDbClass *class, CFDataRef primary_key);
190
191#if 0
192SecDbItemRef SecDbItemCreateWithRowId(CFAllocatorRef allocator, const SecDbClass *class, sqlite_int64 row_id, keybag_handle_t keybag, CFErrorRef *error);
193#endif
194
195bool SecDbItemEnsureDecrypted(SecDbItemRef item, CFDataRef *authNeeded, CFTypeRef *credHandle, CFErrorRef *error);
196
197SecDbItemRef SecDbItemCopyWithUpdates(SecDbItemRef item, CFDictionaryRef updates, CFErrorRef *error);
198
199SecDbItemRef SecDbItemCopyTombstone(SecDbItemRef item, CFErrorRef *error);
200
201bool SecDbItemInsertOrReplace(SecDbItemRef item, SecDbConnectionRef dbconn, CFMutableArrayRef authlist, CFErrorRef *error, void(^duplicate)(SecDbItemRef item, SecDbItemRef *replace));
202
203bool SecDbItemInsert(SecDbItemRef item, SecDbConnectionRef dbconn, CFMutableArrayRef authlist, CFErrorRef *error);
204
205bool SecDbItemDelete(SecDbItemRef item, SecDbConnectionRef dbconn, bool makeTombstone, CFErrorRef *error);
206
207// Low level update, just do the update
208bool SecDbItemDoUpdate(SecDbItemRef old_item, SecDbItemRef new_item, SecDbConnectionRef dbconn, CFErrorRef *error, bool (^use_attr_in_where)(const SecDbAttr *attr));
209
210// High level update, will replace tombstones and create them if needed.
211bool SecDbItemUpdate(SecDbItemRef old_item, SecDbItemRef new_item, SecDbConnectionRef dbconn, bool makeTombstone, CFErrorRef *error);
212
213
214// MARK: -
215// MARK: SQL Construction helpers -- These should become private in the future
216
217void SecDbAppendElement(CFMutableStringRef sql, CFStringRef value, bool *needComma);
218void SecDbAppendWhereOrAnd(CFMutableStringRef sql, bool *needWhere);
219void SecDbAppendWhereOrAndEquals(CFMutableStringRef sql, CFStringRef col, bool *needWhere);
220
221
222// MARK: type converters.
223// TODO: these should be static and private to SecDbItem, or part of the schema
224
225CFStringRef copyString(CFTypeRef obj);
226CFDataRef copyData(CFTypeRef obj);
227CFTypeRef copyBlob(CFTypeRef obj);
228CFDataRef copySHA1(CFTypeRef obj);
229CFTypeRef copyNumber(CFTypeRef obj);
230CFDateRef copyDate(CFTypeRef obj);
231
232__END_DECLS
233
234#endif /* _SECURITYD_SECDBITEM_H_ */
235