#ifndef _H_SSCLIENT
#define _H_SSCLIENT
#include <Security/cssm.h>
#include <Security/utilities.h>
#include <Security/cssmalloc.h>
#include <Security/cssmacl.h>
#include <Security/context.h>
#include <Security/globalizer.h>
#include <Security/unix++.h>
#include <Security/mach++.h>
#include <Security/cssmdb.h>
#include <Security/osxsigning.h>
#include <Security/Authorization.h>
#include <Security/AuthSession.h>
namespace Security {
namespace SecurityServer {
using MachPlusPlus::Port;
using MachPlusPlus::ReceivePort;
typedef CSSM_HANDLE KeyHandle;
typedef CSSM_HANDLE DbHandle;
static const CSSM_HANDLE noDb = 0;
static const CSSM_HANDLE noKey = 0;
struct KeyUID {
uint8 signature[20];
};
struct AuthorizationBlob {
uint32 data[2];
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;
}
};
enum AclKind { dbAcl, keyAcl, loginAcl };
class DBParameters {
public:
uint32 idleTimeout; uint8 lockOnSleep; };
class ClientSession {
NOCOPY(ClientSession)
public:
ClientSession(CssmAllocator &standard, CssmAllocator &returning);
virtual ~ClientSession();
CssmAllocator &internalAllocator;
CssmAllocator &returnAllocator;
public:
typedef CSSM_DB_ACCESS_TYPE DBAccessType;
typedef uint32 NotifyEvent;
typedef uint32 NotifyEvents;
enum {
allEvents = uint32(-1)
};
typedef uint32 NotifyDomain;
enum {
databaseNotifications = 1
};
public:
void activate();
void terminate();
public:
DbHandle createDb(const DLDbIdentifier &dbId,
const AccessCredentials *cred, const AclEntryInput *owner,
const DBParameters ¶ms);
DbHandle decodeDb(const DLDbIdentifier &dbId,
const AccessCredentials *cred, const CssmData &blob);
void encodeDb(DbHandle db, CssmData &blob, CssmAllocator &alloc);
void encodeDb(DbHandle db, CssmData &blob) { return encodeDb(db, blob, returnAllocator); }
void releaseDb(DbHandle db);
void authenticateDb(DbHandle db, DBAccessType type, const AccessCredentials *cred);
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 unlock(DbHandle db);
void unlock(DbHandle db, const CssmData &passPhrase);
bool isLocked(DbHandle db);
void encodeKey(KeyHandle key, CssmData &blob, KeyUID *uid, CssmAllocator &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 releaseKey(KeyHandle key);
CssmKeySize queryKeySizeInBits(KeyHandle key);
uint32 getOutputSize(const Context &context, KeyHandle key,
uint32 inputSize, bool encrypt = true);
public:
void wrapKey(const Context &context, KeyHandle key, KeyHandle keyToBeWrapped,
const AccessCredentials *cred,
const CssmData *descriptiveData, CssmWrappedKey &wrappedKey, CssmAllocator &alloc);
void wrapKey(const 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 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, CssmAllocator &alloc);
void unwrapKey(DbHandle db, const 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 Context &context, uint32 keyUsage, uint32 keyAttr,
const AccessCredentials *cred, const AclEntryInput *owner,
KeyHandle &newKey, CssmKey::Header &newHeader);
void generateKey(DbHandle db, const 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 Context &context, KeyHandle baseKey,
uint32 keyUsage, uint32 keyAttr, CssmData ¶m,
const AccessCredentials *cred, const AclEntryInput *owner,
KeyHandle &newKey, CssmKey::Header &newHeader, CssmAllocator &alloc);
void deriveKey(DbHandle db, const 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(CssmData &data);
void encrypt(const Context &context, KeyHandle key,
const CssmData &in, CssmData &out, CssmAllocator &alloc);
void encrypt(const Context &context, KeyHandle key, const CssmData &in, CssmData &out)
{ return encrypt(context, key, in, out, returnAllocator); }
void decrypt(const Context &context, KeyHandle key,
const CssmData &in, CssmData &out, CssmAllocator &alloc);
void decrypt(const Context &context, KeyHandle key, const CssmData &in, CssmData &out)
{ return decrypt(context, key, in, out, returnAllocator); }
void generateSignature(const Context &context, KeyHandle key,
const CssmData &data, CssmData &signature, CssmAllocator &alloc,
CSSM_ALGORITHMS signOnlyAlgorithm = CSSM_ALGID_NONE);
void generateSignature(const 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 Context &context, KeyHandle key,
const CssmData &data, const CssmData &signature,
CSSM_ALGORITHMS verifyOnlyAlgorithm = CSSM_ALGID_NONE);
void generateMac(const Context &context, KeyHandle key,
const CssmData &data, CssmData &mac, CssmAllocator &alloc);
void generateMac(const Context &context, KeyHandle key,
const CssmData &data, CssmData &mac)
{ return generateMac(context, key, data, mac, returnAllocator); }
void verifyMac(const Context &context, KeyHandle key,
const CssmData &data, const CssmData &mac);
void getKeyAcl(KeyHandle key, const char *tag,
uint32 &count, AclEntryInfo * &info, CssmAllocator &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, CssmAllocator &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, CssmAllocator &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, CssmAllocator &alloc);
void getDbOwner(DbHandle db, AclOwnerPrototype &owner)
{ return getDbOwner(db, owner, returnAllocator); }
void changeDbOwner(DbHandle db, const AccessCredentials &cred,
const AclOwnerPrototype &edit);
public:
void authCreate(const AuthorizationItemSet *rights, const AuthorizationItemSet *environment,
AuthorizationFlags flags,AuthorizationBlob &result);
void authRelease(const AuthorizationBlob &auth, AuthorizationFlags flags);
void authCopyRights(const AuthorizationBlob &auth,
const AuthorizationItemSet *rights, const AuthorizationItemSet *environment,
AuthorizationFlags flags, AuthorizationItemSet **result);
void authCopyInfo(const AuthorizationBlob &auth, const char *tag, AuthorizationItemSet * &info);
void authExternalize(const AuthorizationBlob &auth, AuthorizationExternalForm &extForm);
void authInternalize(const AuthorizationExternalForm &extForm, AuthorizationBlob &auth);
public:
void getSessionInfo(SecuritySessionId &sessionId, SessionAttributeBits &attrs);
void setupSession(SessionCreationFlags flags, SessionAttributeBits attrs);
public:
void requestNotification(Port receiver, NotifyDomain domain, NotifyEvents events);
void stopNotification(Port receiver);
void postNotification(NotifyDomain domain, NotifyEvent event, const CssmData &data);
typedef OSStatus ConsumeNotification(NotifyDomain domain, NotifyEvent event,
const void *data, size_t dataLength, void *context);
OSStatus dispatchNotification(const mach_msg_header_t *message,
ConsumeNotification *consumer, void *context);
private:
void getAcl(AclKind kind, KeyHandle key, const char *tag,
uint32 &count, AclEntryInfo * &info, CssmAllocator &alloc);
void changeAcl(AclKind kind, KeyHandle key,
const AccessCredentials &cred, const AclEdit &edit);
void getOwner(AclKind kind, KeyHandle key, AclOwnerPrototype &owner, CssmAllocator &alloc);
void changeOwner(AclKind kind, KeyHandle key, const AccessCredentials &cred,
const AclOwnerPrototype &edit);
private:
static UnixPlusPlus::StaticForkMonitor mHasForked;
struct Thread {
Thread() : registered(false) { }
operator bool() const { return registered; }
ReceivePort replyPort; bool registered; };
struct Global {
Global();
Port serverPort;
RefPointer<CodeSigning::OSXCode> myself;
ThreadNexus<Thread> thread;
};
static ModuleNexus<Global> mGlobal;
static bool mSetupSession;
};
} }
#endif //_H_SSCLIENT