#ifndef _H_DATABASE
#define _H_DATABASE
#include "structure.h"
#include "acls.h"
#include "dbcrypto.h"
#include "notifications.h"
#include <security_utilities/utilities.h>
#include <security_cdsa_utilities/u32handleobject.h>
#include <security_cdsa_utilities/cssmdb.h>
#include <security_utilities/machserver.h>
#include <security_utilities/timeflow.h>
#include <string>
#include <map>
class Key;
class Connection;
class Process;
class Session;
using MachPlusPlus::MachServer;
class DbCommon : public PerSession {
public:
DbCommon(Session &ssn);
Session &session() const;
virtual void sleepProcessing(); virtual void lockProcessing();
virtual bool belongsToSystem() const;
virtual uint32 dbVersion() = 0;
protected:
void notify(NotificationEvent event, const DLDbIdentifier &ident);
};
class Database : public PerProcess, public AclSource {
static const NotificationEvent lockedEvent = kNotificationEventLocked;
static const NotificationEvent unlockedEvent = kNotificationEventUnlocked;
static const NotificationEvent passphraseChangedEvent = kNotificationEventPassphraseChanged;
protected:
Database(Process &proc);
public:
Process& process() const;
virtual bool transient() const = 0;
public:
class Subsidiary : public PerProcess {
public:
Subsidiary(Database &db) { referent(db); }
Database &database() const { return referent<Database>(); }
Process &process() const { return database().process(); }
};
virtual void releaseKey(Key &key);
virtual void queryKeySizeInBits(Key &key, CssmKeySize &result) = 0;
virtual void getOutputSize(const Context &context, Key &key,
uint32 inputSize, bool encrypt, uint32 &result) = 0;
virtual void generateSignature(const Context &context, Key &key,
CSSM_ALGORITHMS signOnlyAlgorithm, const CssmData &data, CssmData &signature) = 0;
virtual void verifySignature(const Context &context, Key &key,
CSSM_ALGORITHMS verifyOnlyAlgorithm, const CssmData &data, const CssmData &signature) = 0;
virtual void generateMac(const Context &context, Key &key,
const CssmData &data, CssmData &mac) = 0;
virtual void verifyMac(const Context &context, Key &key,
const CssmData &data, const CssmData &mac) = 0;
virtual void encrypt(const Context &context, Key &key, const CssmData &clear, CssmData &cipher) = 0;
virtual void decrypt(const Context &context, Key &key, const CssmData &cipher, CssmData &clear) = 0;
virtual void generateKey(const Context &context,
const AccessCredentials *cred, const AclEntryPrototype *owner,
uint32 usage, uint32 attrs, RefPointer<Key> &newKey) = 0;
virtual void generateKey(const Context &context,
const AccessCredentials *cred, const AclEntryPrototype *owner,
uint32 pubUsage, uint32 pubAttrs, uint32 privUsage, uint32 privAttrs,
RefPointer<Key> &publicKey, RefPointer<Key> &privateKey) = 0;
virtual void wrapKey(const Context &context, const AccessCredentials *cred,
Key *wrappingKey, Key &keyToBeWrapped,
const CssmData &descriptiveData, CssmKey &wrappedKey) = 0;
virtual void unwrapKey(const Context &context,
const AccessCredentials *cred, const AclEntryPrototype *owner,
Key *wrappingKey, Key *publicKey, CSSM_KEYUSE usage, CSSM_KEYATTR_FLAGS attrs,
const CssmKey wrappedKey, RefPointer<Key> &unwrappedKey, CssmData &descriptiveData) = 0;
virtual void deriveKey(const Context &context, Key *key,
const AccessCredentials *cred, const AclEntryPrototype *owner,
CssmData *param, uint32 usage, uint32 attrs, RefPointer<Key> &derivedKey) = 0;
virtual void authenticate(CSSM_DB_ACCESS_TYPE mode, const AccessCredentials *cred);
virtual bool checkCredentials(const AccessCredentials *cred);
virtual SecurityServerAcl &acl();
virtual bool isLocked();
public:
class Search : public Subsidiary {
public:
Search(Database &db) : Subsidiary(db) { }
};
class Record : public Subsidiary {
public:
Record(Database &db) : Subsidiary(db) { }
};
virtual void findFirst(const CssmQuery &query,
CssmDbRecordAttributeData *inAttributes, mach_msg_type_number_t inAttributesLength,
CssmData *data, RefPointer<Key> &key, RefPointer<Search> &search,
RefPointer<Record> &record,
CssmDbRecordAttributeData * &outAttributes, mach_msg_type_number_t &outAttributesLength);
virtual void findNext(Search *search,
CssmDbRecordAttributeData *inAttributes, mach_msg_type_number_t inAttributesLength,
CssmData *data, RefPointer<Key> &key, RefPointer<Record> &record,
CssmDbRecordAttributeData * &outAttributes, mach_msg_type_number_t &outAttributesLength);
virtual void findRecordHandle(Record *record,
CssmDbRecordAttributeData *inAttributes, mach_msg_type_number_t inAttributesLength,
CssmData *data, RefPointer<Key> &key,
CssmDbRecordAttributeData * &outAttributes, mach_msg_type_number_t &outAttributesLength);
virtual void insertRecord(CSSM_DB_RECORDTYPE recordtype,
const CssmDbRecordAttributeData *attributes, mach_msg_type_number_t inAttributesLength,
const CssmData &data, RecordHandle &record);
virtual void modifyRecord(CSSM_DB_RECORDTYPE recordtype, Record *record,
const CssmDbRecordAttributeData *attributes, mach_msg_type_number_t inAttributesLength,
const CssmData *data, CSSM_DB_MODIFY_MODE modifyMode);
virtual void deleteRecord(Database::Record *record);
virtual void releaseSearch(Search &search);
virtual void releaseRecord(Record &record);
public:
AclKind aclKind() const;
Database *relatedDatabase();
bool belongsToSystem() const { return common().belongsToSystem(); }
public:
virtual bool validateSecret(const AclSubject *subject, const AccessCredentials *cred);
public:
static const int maxUnlockTryCount = 3;
public:
DbCommon& common() const { return parent<DbCommon>(); }
virtual const char *dbName() const = 0;
virtual void dbName(const char *name);
virtual uint32 dbVersion() { return common().dbVersion(); }
};
class SystemKeychainKey {
public:
SystemKeychainKey(const char *path);
~SystemKeychainKey();
bool matches(const DbBlob::Signature &signature);
CssmKey &key() { return mKey; }
private:
std::string mPath; CssmKey mKey;
bool mValid; UnlockBlob mBlob;
Time::Absolute mCachedDate; Time::Absolute mUpdateThreshold;
static const int checkDelay = 1;
bool update();
};
#endif //_H_DATABASE