#ifndef _H_SSCLIENT
#define _H_SSCLIENT
#include "sscommon.h"
#include <Security/Authorization.h>
#include <Security/AuthSession.h>
#ifdef __cplusplus
#include <security_utilities/osxcode.h>
#include <security_utilities/unix++.h>
#include <security_utilities/globalizer.h>
#include <security_cdsa_utilities/cssmerrors.h>
#include "ssnotify.h"
namespace Security {
namespace SecurityServer {
#endif //__cplusplus
typedef struct KeyUID {
uint8 signature[20];
} KeyUID;
#define maxUcspHashLength 64
typedef struct AuthorizationBlob {
uint32 data[2];
#ifdef __cplusplus
bool operator < (const AuthorizationBlob &other) const
{ return memcmp(data, other.data, sizeof(data)) < 0; }
bool operator == (const AuthorizationBlob &other) const
{ return memcmp(data, other.data, sizeof(data)) == 0; }
size_t hash() const { return data[0] ^ data[1] << 3;
}
#endif
} AuthorizationBlob;
typedef struct {
uint32_t order;
uint32_t version;
} ClientSetupInfo;
#define SSPROTOVERSION 20000
typedef struct {
uint32_t idleTimeout; uint8_t lockOnSleep; } DBParameters;
#ifdef __cplusplus
class ClientSession : public ClientCommon {
public:
ClientSession(Allocator &standard = Allocator::standard(),
Allocator &returning = Allocator::standard());
virtual ~ClientSession();
public:
void activate();
void reset();
public:
void contactName(const char *name);
const char *contactName() const;
static GenericHandle toIPCHandle(CSSM_HANDLE h) {
if (h & (CSSM_HANDLE(~0) ^ GenericHandle(~0)))
CssmError::throwMe(CSSM_ERRCODE_INVALID_CONTEXT_HANDLE);
return h & GenericHandle(~0);
}
public:
void authenticateDb(DbHandle db, CSSM_DB_ACCESS_TYPE type, const AccessCredentials *cred);
void releaseDb(DbHandle db);
DbHandle openToken(uint32 ssid, const AccessCredentials *cred, const char *name = NULL);
RecordHandle insertRecord(DbHandle db,
CSSM_DB_RECORDTYPE recordType,
const CssmDbRecordAttributeData *attributes,
const CssmData *data);
void deleteRecord(DbHandle db, RecordHandle record);
void modifyRecord(DbHandle db, RecordHandle &record,
CSSM_DB_RECORDTYPE recordType,
const CssmDbRecordAttributeData *attributesToBeModified,
const CssmData *dataToBeModified,
CSSM_DB_MODIFY_MODE modifyMode);
RecordHandle findFirst(DbHandle db,
const CssmQuery &query,
SearchHandle &outSearchHandle,
CssmDbRecordAttributeData *inOutAttributes,
CssmData *outData, KeyHandle &key);
RecordHandle findNext(SearchHandle searchHandle,
CssmDbRecordAttributeData *inOutAttributes,
CssmData *inOutData, KeyHandle &key);
void findRecordHandle(RecordHandle record,
CssmDbRecordAttributeData *inOutAttributes,
CssmData *inOutData, KeyHandle &key);
void releaseSearch(SearchHandle searchHandle);
void releaseRecord(RecordHandle record);
void getDbName(DbHandle db, std::string &name);
void setDbName(DbHandle db, const std::string &name);
DbHandle createDb(const DLDbIdentifier &dbId,
const AccessCredentials *cred, const AclEntryInput *owner,
const DBParameters ¶ms);
DbHandle cloneDb(const DLDbIdentifier &newDbId, DbHandle srcDb);
DbHandle cloneDbForSync(const CssmData &secretsBlob, DbHandle srcDb,
const CssmData &agentData);
DbHandle recodeDbForSync(DbHandle dbToClone, DbHandle srcDb);
DbHandle recodeDbToVersion(uint32 newVersion, DbHandle srcDb);
void recodeFinished(DbHandle db);
DbHandle authenticateDbsForSync(const CssmData &dbHandleArray, const CssmData &agentData);
void commitDbForSync(DbHandle srcDb, DbHandle cloneDb, CssmData &blob, Allocator &alloc);
DbHandle decodeDb(const DLDbIdentifier &dbId,
const AccessCredentials *cred, const CssmData &blob);
void encodeDb(DbHandle db, CssmData &blob, Allocator &alloc);
void encodeDb(DbHandle db, CssmData &blob) { return encodeDb(db, blob, returnAllocator); }
void setDbParameters(DbHandle db, const DBParameters ¶ms);
void getDbParameters(DbHandle db, DBParameters ¶ms);
void changePassphrase(DbHandle db, const AccessCredentials *cred);
void lock(DbHandle db);
void lockAll(bool forSleep);
void unlock(DbHandle db);
void unlock(DbHandle db, const CssmData &passPhrase);
void stashDb(DbHandle db);
void stashDbCheck(DbHandle db);
bool isLocked(DbHandle db);
void verifyKeyStorePassphrase(uint32_t retries);
void resetKeyStorePassphrase(const CssmData &passphrase);
void changeKeyStorePassphrase();
public:
void encodeKey(KeyHandle key, CssmData &blob, KeyUID *uid, Allocator &alloc);
void encodeKey(KeyHandle key, CssmData &blob, KeyUID *uid = NULL)
{ return encodeKey(key, blob, uid, returnAllocator); }
KeyHandle decodeKey(DbHandle db, const CssmData &blob, CssmKey::Header &header);
void recodeKey(DbHandle oldDb, KeyHandle key, DbHandle newDb, CssmData &blob);
void releaseKey(KeyHandle key);
CssmKeySize queryKeySizeInBits(KeyHandle key);
uint32 getOutputSize(const Security::Context &context, KeyHandle key,
uint32 inputSize, bool encrypt = true);
void getKeyDigest(KeyHandle key, CssmData &digest, Allocator &alloc);
void getKeyDigest(KeyHandle key, CssmData &digest)
{ return getKeyDigest(key, digest, returnAllocator); }
void wrapKey(const Security::Context &context, KeyHandle key, KeyHandle keyToBeWrapped,
const AccessCredentials *cred,
const CssmData *descriptiveData, CssmWrappedKey &wrappedKey, Allocator &alloc);
void wrapKey(const Security::Context &context, KeyHandle key, KeyHandle keyToBeWrapped,
const AccessCredentials *cred,
const CssmData *descriptiveData, CssmWrappedKey &wrappedKey)
{ return wrapKey(context, key, keyToBeWrapped, cred,
descriptiveData, wrappedKey, returnAllocator); }
void unwrapKey(DbHandle db, const Security::Context &context, KeyHandle key, KeyHandle publicKey,
const CssmWrappedKey &wrappedKey, uint32 keyUsage, uint32 keyAttr,
const AccessCredentials *cred, const AclEntryInput *owner,
CssmData &data, KeyHandle &newKey, CssmKey::Header &newKeyHeader, Allocator &alloc);
void unwrapKey(DbHandle db, const Security::Context &context, KeyHandle key, KeyHandle publicKey,
const CssmWrappedKey &wrappedKey, uint32 keyUsage, uint32 keyAttr,
const AccessCredentials *cred, const AclEntryInput *owner, CssmData &data,
KeyHandle &newKey, CssmKey::Header &newKeyHeader)
{ return unwrapKey(db, context, key, publicKey, wrappedKey, keyUsage, keyAttr,
cred, owner, data, newKey, newKeyHeader, returnAllocator); }
void generateKey(DbHandle db, const Security::Context &context, uint32 keyUsage, uint32 keyAttr,
const AccessCredentials *cred, const AclEntryInput *owner,
KeyHandle &newKey, CssmKey::Header &newHeader);
void generateKey(DbHandle db, const Security::Context &context,
uint32 pubKeyUsage, uint32 pubKeyAttr,
uint32 privKeyUsage, uint32 privKeyAttr,
const AccessCredentials *cred, const AclEntryInput *owner,
KeyHandle &pubKey, CssmKey::Header &pubHeader,
KeyHandle &privKey, CssmKey::Header &privHeader);
void deriveKey(DbHandle db, const Security::Context &context, KeyHandle baseKey,
uint32 keyUsage, uint32 keyAttr, CssmData ¶m,
const AccessCredentials *cred, const AclEntryInput *owner,
KeyHandle &newKey, CssmKey::Header &newHeader, Allocator &alloc);
void deriveKey(DbHandle db, const Security::Context &context, KeyHandle baseKey,
uint32 keyUsage, uint32 keyAttr, CssmData ¶m,
const AccessCredentials *cred, const AclEntryInput *owner,
KeyHandle &newKey, CssmKey::Header &newHeader)
{ return deriveKey(db, context, baseKey, keyUsage, keyAttr, param, cred, owner, newKey, newHeader, returnAllocator); }
void generateRandom(const Security::Context &context, CssmData &data, Allocator &alloc);
void generateRandom(const Security::Context &context, CssmData &data)
{ return generateRandom(context, data, returnAllocator); }
void encrypt(const Security::Context &context, KeyHandle key,
const CssmData &in, CssmData &out, Allocator &alloc);
void encrypt(const Security::Context &context, KeyHandle key, const CssmData &in, CssmData &out)
{ return encrypt(context, key, in, out, returnAllocator); }
void decrypt(const Security::Context &context, KeyHandle key,
const CssmData &in, CssmData &out, Allocator &alloc);
void decrypt(const Security::Context &context, KeyHandle key, const CssmData &in, CssmData &out)
{ return decrypt(context, key, in, out, returnAllocator); }
void generateSignature(const Security::Context &context, KeyHandle key,
const CssmData &data, CssmData &signature, Allocator &alloc,
CSSM_ALGORITHMS signOnlyAlgorithm = CSSM_ALGID_NONE);
void generateSignature(const Security::Context &context, KeyHandle key,
const CssmData &data, CssmData &signature, CSSM_ALGORITHMS signOnlyAlgorithm = CSSM_ALGID_NONE)
{ return generateSignature(context, key, data, signature, returnAllocator, signOnlyAlgorithm); }
void verifySignature(const Security::Context &context, KeyHandle key,
const CssmData &data, const CssmData &signature,
CSSM_ALGORITHMS verifyOnlyAlgorithm = CSSM_ALGID_NONE);
void generateMac(const Security::Context &context, KeyHandle key,
const CssmData &data, CssmData &mac, Allocator &alloc);
void generateMac(const Security::Context &context, KeyHandle key,
const CssmData &data, CssmData &mac)
{ return generateMac(context, key, data, mac, returnAllocator); }
void verifyMac(const Security::Context &context, KeyHandle key,
const CssmData &data, const CssmData &mac);
void getKeyAcl(KeyHandle key, const char *tag,
uint32 &count, AclEntryInfo * &info, Allocator &alloc);
void getKeyAcl(KeyHandle key, const char *tag,
uint32 &count, AclEntryInfo * &info)
{ return getKeyAcl(key, tag, count, info, returnAllocator); }
void changeKeyAcl(KeyHandle key, const AccessCredentials &cred, const AclEdit &edit);
void getKeyOwner(KeyHandle key, AclOwnerPrototype &owner, Allocator &alloc);
void getKeyOwner(KeyHandle key, AclOwnerPrototype &owner)
{ return getKeyOwner(key, owner, returnAllocator); }
void changeKeyOwner(KeyHandle key, const AccessCredentials &cred,
const AclOwnerPrototype &edit);
void getDbAcl(DbHandle db, const char *tag,
uint32 &count, AclEntryInfo * &info, Allocator &alloc);
void getDbAcl(DbHandle db, const char *tag,
uint32 &count, AclEntryInfo * &info)
{ return getDbAcl(db, tag, count, info, returnAllocator); }
void changeDbAcl(DbHandle db, const AccessCredentials &cred, const AclEdit &edit);
void getDbOwner(DbHandle db, AclOwnerPrototype &owner, Allocator &alloc);
void getDbOwner(DbHandle db, AclOwnerPrototype &owner)
{ return getDbOwner(db, owner, returnAllocator); }
void changeDbOwner(DbHandle db, const AccessCredentials &cred,
const AclOwnerPrototype &edit);
void extractMasterKey(DbHandle db, const Context &context, DbHandle sourceDb,
uint32 keyUsage, uint32 keyAttr,
const AccessCredentials *cred, const AclEntryInput *owner,
KeyHandle &newKey, CssmKey::Header &newHeader, Allocator &alloc);
void extractMasterKey(DbHandle db, const Context &context, DbHandle sourceDb,
uint32 keyUsage, uint32 keyAttr,
const AccessCredentials *cred, const AclEntryInput *owner,
KeyHandle &newKey, CssmKey::Header &newHeader)
{ return extractMasterKey(db, context, sourceDb, keyUsage, keyAttr, cred, owner,
newKey, newHeader, returnAllocator); }
public:
void getUserPromptAttempts(uint32_t& attempts);
public:
void postNotification(NotificationDomain domain, NotificationEvent event, const CssmData &data);
typedef OSStatus ConsumeNotification(NotificationDomain domain, NotificationEvent event,
const void *data, size_t dataLength, void *context);
public:
void childCheckIn(Port serverPort, Port taskPort);
public:
typedef void DidChangeKeyAclCallback(void *context, ClientSession &clientSession,
KeyHandle key, CSSM_ACL_AUTHORIZATION_TAG tag);
void registerForAclEdits(DidChangeKeyAclCallback *callback, void *context);
private:
static Port findSecurityd();
void getAcl(AclKind kind, GenericHandle key, const char *tag,
uint32 &count, AclEntryInfo * &info, Allocator &alloc);
void changeAcl(AclKind kind, GenericHandle key,
const AccessCredentials &cred, const AclEdit &edit);
void getOwner(AclKind kind, GenericHandle key,
AclOwnerPrototype &owner, Allocator &alloc);
void changeOwner(AclKind kind, GenericHandle key,
const AccessCredentials &cred, const AclOwnerPrototype &edit);
static OSStatus consumerDispatch(NotificationDomain domain, NotificationEvent event,
const void *data, size_t dataLength, void *context);
void notifyAclChange(KeyHandle key, CSSM_ACL_AUTHORIZATION_TAG tag);
void returnAttrsAndData(CssmDbRecordAttributeData *inOutAttributes,
CssmDbRecordAttributeData *attrs, CssmDbRecordAttributeData *attrsBase, mach_msg_type_number_t attrsLength,
CssmData *inOutData, void *dataPtr, mach_msg_type_number_t dataLength);
private:
DidChangeKeyAclCallback *mCallback;
void *mCallbackContext;
static UnixPlusPlus::StaticForkMonitor mHasForked;
struct Thread {
Thread() : registered(false), notifySeq(0) { }
operator bool() const { return registered; }
ReceivePort replyPort; bool registered; uint32 notifySeq; };
struct Global {
Global();
Port serverPort;
RefPointer<OSXCode> myself;
ThreadNexus<Thread> thread;
};
static ModuleNexus<Global> mGlobal;
static const char *mContactName;
};
} }
#endif //__cplusplus
#endif //_H_SSCLIENT