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