#ifndef _SECURITYD_SECDBITEM_H_
#define _SECURITYD_SECDBITEM_H_
#include <CoreFoundation/CoreFoundation.h>
#include <TargetConditionals.h>
#include <corecrypto/ccsha1.h> // For CCSHA1_OUTPUT_SIZE
#include <sqlite3.h>
#include <utilities/SecCFError.h>
#include <utilities/SecCFWrappers.h>
#include <utilities/SecDb.h>
#include <securityd/SecKeybagSupport.h>
#include <Security/SecAccessControl.h>
typedef enum {
kSecDbBlobAttr, kSecDbDataAttr,
kSecDbStringAttr,
kSecDbNumberAttr,
kSecDbDateAttr,
kSecDbCreationDateAttr,
kSecDbModificationDateAttr,
kSecDbSHA1Attr,
kSecDbRowIdAttr,
kSecDbEncryptedDataAttr,
kSecDbPrimaryKeyAttr,
kSecDbSyncAttr,
kSecDbTombAttr,
kSecDbAccessAttr,
kSecDbAccessControlAttr
} SecDbAttrKind;
enum {
kSecDbPrimaryKeyFlag = (1 << 0), kSecDbInFlag = (1 << 1), kSecDbIndexFlag = (1 << 2), kSecDbSHA1ValueInFlag = (1 << 3), kSecDbReturnAttrFlag = (1 << 4),
kSecDbReturnDataFlag = (1 << 5),
kSecDbReturnRefFlag = (1 << 6),
kSecDbInCryptoDataFlag = (1 << 7),
kSecDbInHashFlag = (1 << 8),
kSecDbInBackupFlag = (1 << 9),
kSecDbDefault0Flag = (1 << 10), kSecDbDefaultEmptyFlag = (1 << 11), kSecDbNotNullFlag = (1 << 12), kSecDbInAuthenticatedDataFlag = (1 << 13),
};
#define SecVersionDbFlag(v) ((v & 0xFF) << 8)
#define SecDbFlagGetVersion(flags) ((flags >> 8) & 0xFF)
#define SECDB_ATTR(var, name, kind, flags) const SecDbAttr var = { CFSTR(name), kSecDb ## kind ## Attr, flags }
typedef struct SecDbAttr {
CFStringRef name;
SecDbAttrKind kind;
CFOptionFlags flags;
} SecDbAttr;
typedef struct SecDbClass {
CFStringRef name;
const SecDbAttr *attrs[];
} SecDbClass;
#define SecDbForEachAttr(class, attr) for (const SecDbAttr * const* _pattr = (class)->attrs, *attr = *_pattr; attr; attr = *(++_pattr))
#define SecDbForEachAttrWithMask(class, attr, flag_mask) SecDbForEachAttr(class, attr) if ((attr->flags & (flag_mask)) == (flag_mask))
CFDataRef kc_copy_sha1(size_t len, const void *data, CFErrorRef *error);
CFDataRef kc_copy_plist_sha1(CFPropertyListRef plist, CFErrorRef *error);
CFDataRef kc_plist_copy_der(CFPropertyListRef plist, CFErrorRef *error);
typedef struct SecDbItem *SecDbItemRef;
enum SecDbItemState {
kSecDbItemDirty, kSecDbItemEncrypted, kSecDbItemClean, kSecDbItemDecrypting, kSecDbItemEncrypting, };
struct SecDbItem {
CFRuntimeBase _base;
const SecDbClass *class;
keyclass_t keyclass;
keybag_handle_t keybag;
enum SecDbItemState _edataState;
CFMutableDictionaryRef attributes;
CFTypeRef credHandle;
enum SecKsCryptoOp cryptoOp;
CFArrayRef callerAccessGroups;
};
bool SecDbItemDecrypt(SecDbItemRef item, CFDataRef edata, CFDataRef *neededAuth, CFErrorRef *error);
CFTypeID SecDbItemGetTypeID(void);
static inline size_t SecDbClassAttrCount(const SecDbClass *dbClass) {
size_t n_attrs = 0;
SecDbForEachAttr(dbClass, attr) { n_attrs++; }
return n_attrs;
}
const SecDbAttr *SecDbClassAttrWithKind(const SecDbClass *class, SecDbAttrKind kind, CFErrorRef *error);
SecDbItemRef SecDbItemCreateWithAttributes(CFAllocatorRef allocator, const SecDbClass *class, CFDictionaryRef attributes, keybag_handle_t keybag, CFErrorRef *error);
const SecDbClass *SecDbItemGetClass(SecDbItemRef item);
keybag_handle_t SecDbItemGetKeybag(SecDbItemRef item);
bool SecDbItemSetKeybag(SecDbItemRef item, keybag_handle_t keybag, CFErrorRef *error);
SecAccessControlRef SecDbItemCopyAccessControl(SecDbItemRef item, CFErrorRef *error);
bool SecDbItemSetAccessControl(SecDbItemRef item, SecAccessControlRef access_control, CFErrorRef *error);
void SecDbItemSetCredHandle(SecDbItemRef item, CFTypeRef cred_handle);
void SecDbItemSetCallerAccessGroups(SecDbItemRef item, CFArrayRef caller_access_groups);
CFTypeRef SecDbItemGetCachedValueWithName(SecDbItemRef item, CFStringRef name);
CFTypeRef SecDbItemGetValue(SecDbItemRef item, const SecDbAttr *desc, CFErrorRef *error);
bool SecDbItemSetValue(SecDbItemRef item, const SecDbAttr *desc, CFTypeRef value, CFErrorRef *error);
bool SecDbItemSetValues(SecDbItemRef item, CFDictionaryRef values, CFErrorRef *error);
bool SecDbItemSetValueWithName(SecDbItemRef item, CFStringRef name, CFTypeRef value, CFErrorRef *error);
sqlite3_int64 SecDbItemGetRowId(SecDbItemRef item, CFErrorRef *error);
bool SecDbItemSetRowId(SecDbItemRef item, sqlite3_int64 rowid, CFErrorRef *error);
bool SecDbItemIsSyncableOrCorrupted(SecDbItemRef item);
bool SecDbItemIsSyncable(SecDbItemRef item);
bool SecDbItemSetSyncable(SecDbItemRef item, bool sync, CFErrorRef *error);
bool SecDbItemIsTombstone(SecDbItemRef item);
CFMutableDictionaryRef SecDbItemCopyPListWithMask(SecDbItemRef item, CFOptionFlags mask, CFErrorRef *error);
CFDataRef SecDbItemGetPrimaryKey(SecDbItemRef item, CFErrorRef *error);
CFDataRef SecDbItemGetSHA1(SecDbItemRef item, CFErrorRef *error);
CFDataRef SecDbItemCopyEncryptedDataToBackup(SecDbItemRef item, uint64_t handle, CFErrorRef *error);
SecDbItemRef SecDbItemCreateWithStatement(CFAllocatorRef allocator, const SecDbClass *class, sqlite3_stmt *stmt, keybag_handle_t keybag, CFErrorRef *error, bool (^return_attr)(const SecDbAttr *attr));
SecDbItemRef SecDbItemCreateWithEncryptedData(CFAllocatorRef allocator, const SecDbClass *class,
CFDataRef edata, keybag_handle_t keybag, CFErrorRef *error);
SecDbItemRef SecDbItemCreateWithPrimaryKey(CFAllocatorRef allocator, const SecDbClass *class, CFDataRef primary_key);
#if 0
SecDbItemRef SecDbItemCreateWithRowId(CFAllocatorRef allocator, const SecDbClass *class, sqlite_int64 row_id, keybag_handle_t keybag, CFErrorRef *error);
#endif
bool SecDbItemEnsureDecrypted(SecDbItemRef item, CFDataRef *authNeeded, CFTypeRef *credHandle, CFErrorRef *error);
SecDbItemRef SecDbItemCopyWithUpdates(SecDbItemRef item, CFDictionaryRef updates, CFErrorRef *error);
SecDbItemRef SecDbItemCopyTombstone(SecDbItemRef item, CFErrorRef *error);
bool SecDbItemInsertOrReplace(SecDbItemRef item, SecDbConnectionRef dbconn, CFMutableArrayRef authlist, CFErrorRef *error, void(^duplicate)(SecDbItemRef item, SecDbItemRef *replace));
bool SecDbItemInsert(SecDbItemRef item, SecDbConnectionRef dbconn, CFMutableArrayRef authlist, CFErrorRef *error);
bool SecDbItemDelete(SecDbItemRef item, SecDbConnectionRef dbconn, bool makeTombstone, CFErrorRef *error);
bool SecDbItemDoUpdate(SecDbItemRef old_item, SecDbItemRef new_item, SecDbConnectionRef dbconn, CFErrorRef *error, bool (^use_attr_in_where)(const SecDbAttr *attr));
bool SecDbItemUpdate(SecDbItemRef old_item, SecDbItemRef new_item, SecDbConnectionRef dbconn, bool makeTombstone, CFErrorRef *error);
void SecDbAppendElement(CFMutableStringRef sql, CFStringRef value, bool *needComma);
void SecDbAppendWhereOrAnd(CFMutableStringRef sql, bool *needWhere);
void SecDbAppendWhereOrAndEquals(CFMutableStringRef sql, CFStringRef col, bool *needWhere);
CFStringRef copyString(CFTypeRef obj);
CFDataRef copyData(CFTypeRef obj);
CFTypeRef copyBlob(CFTypeRef obj);
CFDataRef copySHA1(CFTypeRef obj);
CFTypeRef copyNumber(CFTypeRef obj);
CFDateRef copyDate(CFTypeRef obj);
__END_DECLS
#endif