#ifndef _TOKEND_TOKEN_H_
#define _TOKEND_TOKEN_H_
#include <SecurityTokend/SecTokend.h>
#include <security_utilities/osxcode.h>
#include <security_cdsa_utilities/context.h>
#include <security_cdsa_utilities/cssmpods.h>
#include <security_cdsa_utilities/cssmbridge.h>
#include <security_cdsa_utilities/cssmdb.h>
#include <security_cdsa_utilities/cssmaclpod.h>
#include <security_cdsa_utilities/cssmcred.h>
#include <security_utilities/debugging.h>
#include <security_utilities/pcsc++.h>
#include <string>
#include "TokenContext.h"
namespace Tokend
{
class Cursor;
class Schema;
class TokenContext;
class Token : public SecTokendSupport
{
NOCOPY(Token)
public:
Token();
virtual ~Token();
bool cachedObject(CSSM_DB_RECORDTYPE relationId, const std::string &name,
CssmData &data) const;
void cacheObject(CSSM_DB_RECORDTYPE relationId, const std::string &name,
const CssmData &object) const;
virtual const SecTokendCallbacks *callbacks();
virtual SecTokendSupport *support();
virtual void initial();
virtual uint32 probe(SecTokendProbeFlags flags,
char tokenUid[TOKEND_MAX_UID]) = 0;
virtual void establish(const CSSM_GUID *guid, uint32 subserviceId,
SecTokendEstablishFlags flags, const char *cacheDirectory,
const char *workDirectory, char mdsDirectory[PATH_MAX],
char printName[PATH_MAX]);
virtual void terminate(uint32 reason, uint32 options);
virtual void authenticate(CSSM_DB_ACCESS_TYPE mode,
const AccessCredentials *cred);
virtual void getOwner(AclOwnerPrototype &owner) = 0;
virtual void getAcl(const char *tag, uint32 &count,
AclEntryInfo *&acls) = 0;
virtual Cursor *createCursor(const CSSM_QUERY *inQuery);
virtual void changeOwner(const AclOwnerPrototype &owner);
virtual void changeAcl(const AccessCredentials &cred, const AclEdit &edit);
virtual void generateRandom(const Context &context, CssmData &result);
virtual void getStatistics(CSSM_CSP_OPERATIONAL_STATISTICS &result);
virtual void getTime(CSSM_ALGORITHMS algorithm, CssmData &result);
virtual void getCounter(CssmData &result);
virtual void selfVerify();
virtual void changePIN(int pinNum,
const unsigned char *oldPin, size_t oldPinLength,
const unsigned char *newPin, size_t newPinLength);
virtual uint32_t pinStatus(int pinNum);
virtual void verifyPIN(int pinNum,
const unsigned char *pin, size_t pinLength);
virtual void unverifyPIN(int pinNum);
virtual bool isLocked();
TokenContext *tokenContext() { return mTokenContext; }
protected:
std::string cachedObjectPath(CSSM_DB_RECORDTYPE relationId,
const std::string &name) const;
static CSSM_RETURN _initial();
static CSSM_RETURN _probe(SecTokendProbeFlags flags, uint32 *score,
char tokenUid[TOKEND_MAX_UID]);
static CSSM_RETURN _establish(const CSSM_GUID *guid, uint32 subserviceId,
SecTokendEstablishFlags flags, const char *cacheDirectory,
const char *workDirectory, char mdsDirectory[PATH_MAX],
char printName[PATH_MAX]);
static CSSM_RETURN _terminate(uint32 reason, uint32 options);
static CSSM_RETURN _findFirst(const CSSM_QUERY *query,
TOKEND_RETURN_DATA *data, CSSM_HANDLE *hSearch);
static CSSM_RETURN _findNext(CSSM_HANDLE hSearch,
TOKEND_RETURN_DATA *data);
static CSSM_RETURN _findRecordHandle(CSSM_HANDLE hRecord,
TOKEND_RETURN_DATA *data);
static CSSM_RETURN _insertRecord(CSSM_DB_RECORDTYPE recordType,
const CSSM_DB_RECORD_ATTRIBUTE_DATA *attributes, const CSSM_DATA *data,
CSSM_HANDLE *hRecord);
static CSSM_RETURN _modifyRecord(CSSM_DB_RECORDTYPE recordType,
CSSM_HANDLE *hRecord, const CSSM_DB_RECORD_ATTRIBUTE_DATA *attributes,
const CSSM_DATA *data, CSSM_DB_MODIFY_MODE modifyMode);
static CSSM_RETURN _deleteRecord(CSSM_HANDLE hRecord);
static CSSM_RETURN _releaseSearch(CSSM_HANDLE hSearch);
static CSSM_RETURN _releaseRecord(CSSM_HANDLE hRecord);
static CSSM_RETURN _freeRetrievedData(TOKEND_RETURN_DATA *data);
static CSSM_RETURN _releaseKey(CSSM_HANDLE hKey);
static CSSM_RETURN _getKeySize(CSSM_HANDLE hKey, CSSM_KEY_SIZE *size);
static CSSM_RETURN _getOutputSize(const CSSM_CONTEXT *context,
CSSM_HANDLE hKey, uint32 inputSize, CSSM_BOOL encrypting,
uint32 *outputSize);
static CSSM_RETURN _generateSignature(const CSSM_CONTEXT *context,
CSSM_HANDLE hKey, CSSM_ALGORITHMS signOnly, const CSSM_DATA *input,
CSSM_DATA *signature);
static CSSM_RETURN _verifySignature(const CSSM_CONTEXT *context,
CSSM_HANDLE hKey, CSSM_ALGORITHMS signOnly, const CSSM_DATA *input,
const CSSM_DATA *signature);
static CSSM_RETURN _generateMac(const CSSM_CONTEXT *context,
CSSM_HANDLE hKey, const CSSM_DATA *input, CSSM_DATA *mac);
static CSSM_RETURN _verifyMac(const CSSM_CONTEXT *context,
CSSM_HANDLE hKey, const CSSM_DATA *input, const CSSM_DATA *mac);
static CSSM_RETURN _encrypt(const CSSM_CONTEXT *context, CSSM_HANDLE hKey,
const CSSM_DATA *clear, CSSM_DATA *cipher);
static CSSM_RETURN _decrypt(const CSSM_CONTEXT *context, CSSM_HANDLE hKey,
const CSSM_DATA *cipher, CSSM_DATA *clear);
static CSSM_RETURN _generateKey(const CSSM_CONTEXT *context,
const CSSM_ACCESS_CREDENTIALS *creds,
const CSSM_ACL_ENTRY_PROTOTYPE *owner, CSSM_KEYUSE usage,
CSSM_KEYATTR_FLAGS attrs, CSSM_HANDLE *hKey, CSSM_KEY *header);
static CSSM_RETURN _generateKeyPair(const CSSM_CONTEXT *context,
const CSSM_ACCESS_CREDENTIALS *creds,
const CSSM_ACL_ENTRY_PROTOTYPE *owner,
CSSM_KEYUSE pubUsage, CSSM_KEYATTR_FLAGS pubAttrs,
CSSM_KEYUSE privUsage, CSSM_KEYATTR_FLAGS privAttrs,
CSSM_HANDLE *hPubKey, CSSM_KEY *pubHeader,
CSSM_HANDLE *hPrivKey, CSSM_KEY *privHeader);
static CSSM_RETURN _wrapKey(const CSSM_CONTEXT *context,
CSSM_HANDLE hWrappingKey, const CSSM_KEY *wrappingKey,
const CSSM_ACCESS_CREDENTIALS *cred, CSSM_HANDLE hSubjectKey,
const CSSM_KEY *subjectKey, const CSSM_DATA *descriptiveData,
CSSM_KEY *wrappedKey);
static CSSM_RETURN _unwrapKey(const CSSM_CONTEXT *context,
CSSM_HANDLE hWrappingKey, const CSSM_KEY *wrappingKey,
const CSSM_ACCESS_CREDENTIALS *cred,
const CSSM_ACL_ENTRY_PROTOTYPE *access,
CSSM_HANDLE hPublicKey, const CSSM_KEY *publicKey,
const CSSM_KEY *wrappedKey, CSSM_KEYUSE usage,
CSSM_KEYATTR_FLAGS attributes, CSSM_DATA *descriptiveData,
CSSM_HANDLE *hUnwrappedKey, CSSM_KEY *unwrappedKey);
static CSSM_RETURN _deriveKey(const CSSM_CONTEXT *context,
CSSM_HANDLE hSourceKey, const CSSM_KEY *sourceKey,
const CSSM_ACCESS_CREDENTIALS *cred,
const CSSM_ACL_ENTRY_PROTOTYPE *access, CSSM_DATA *parameters,
CSSM_KEYUSE usage, CSSM_KEYATTR_FLAGS attributes,
CSSM_HANDLE *hKey, CSSM_KEY *hKey);
static CSSM_RETURN _getObjectOwner(CSSM_HANDLE hKey,
CSSM_ACL_OWNER_PROTOTYPE *owner);
static CSSM_RETURN _getObjectAcl(CSSM_HANDLE hKey,
const char *tag, uint32 *count, CSSM_ACL_ENTRY_INFO **entries);
static CSSM_RETURN _getDatabaseOwner(CSSM_ACL_OWNER_PROTOTYPE *owner);
static CSSM_RETURN _getDatabaseAcl(const char *tag, uint32 *count,
CSSM_ACL_ENTRY_INFO **entries);
static CSSM_RETURN _getKeyOwner(CSSM_HANDLE hKey,
CSSM_ACL_OWNER_PROTOTYPE *owner);
static CSSM_RETURN _getKeyAcl(CSSM_HANDLE hKey, const char *tag,
uint32 *count, CSSM_ACL_ENTRY_INFO **entries);
static CSSM_RETURN _freeOwnerData(CSSM_ACL_OWNER_PROTOTYPE *owner);
static CSSM_RETURN _freeAclData(uint32 count,
CSSM_ACL_ENTRY_INFO *entries);
static CSSM_RETURN _authenticateDatabase(CSSM_DB_ACCESS_TYPE mode,
const CSSM_ACCESS_CREDENTIALS *cred);
static CSSM_RETURN _changeDatabaseOwner(const CSSM_ACL_OWNER_PROTOTYPE *
owner);
static CSSM_RETURN _changeDatabaseAcl(const CSSM_ACCESS_CREDENTIALS *cred,
const CSSM_ACL_EDIT *edit);
static CSSM_RETURN _changeObjectOwner(CSSM_HANDLE hRecord,
const CSSM_ACL_OWNER_PROTOTYPE *owner);
static CSSM_RETURN _changeObjectAcl(CSSM_HANDLE hRecord,
const CSSM_ACCESS_CREDENTIALS *cred, const CSSM_ACL_EDIT *edit);
static CSSM_RETURN _changeKeyOwner(CSSM_HANDLE key,
const CSSM_ACL_OWNER_PROTOTYPE *owner);
static CSSM_RETURN _changeKeyAcl(CSSM_HANDLE key,
const CSSM_ACCESS_CREDENTIALS *cred, const CSSM_ACL_EDIT *edit);
static CSSM_RETURN _generateRandom(const CSSM_CONTEXT *context,
CSSM_DATA *result);
static CSSM_RETURN _getStatistics(CSSM_CSP_OPERATIONAL_STATISTICS *result);
static CSSM_RETURN _getTime(CSSM_ALGORITHMS algorithm, CSSM_DATA *result);
static CSSM_RETURN _getCounter(CSSM_DATA *result);
static CSSM_RETURN _selfVerify();
static CSSM_RETURN _cspPassThrough(uint32 id, const CSSM_CONTEXT *context,
CSSM_HANDLE hKey, const CSSM_KEY *key, const CSSM_DATA *input,
CSSM_DATA *output);
static CSSM_RETURN _dlPassThrough(uint32 id, const CSSM_DATA *input,
CSSM_DATA *output);
static CSSM_RETURN _isLocked(uint32 *locked);
private:
static const SecTokendCallbacks mCallbacks;
protected:
Schema *mSchema;
TokenContext *mTokenContext;
Guid mGuid;
uint32 mSubserviceId;
std::string mCacheDirectory;
};
class ISO7816Token : public Token, public TokenContext, public PCSC::Card
{
NOCOPY(ISO7816Token)
public:
ISO7816Token();
virtual ~ISO7816Token();
virtual uint32 probe(SecTokendProbeFlags flags,
char tokenUid[TOKEND_MAX_UID]);
virtual void establish(const CSSM_GUID *guid, uint32 subserviceId,
SecTokendEstablishFlags flags, const char *cacheDirectory,
const char *workDirectory, char mdsDirectory[PATH_MAX],
char printName[PATH_MAX]);
uint16_t transmitAPDU(uint8_t cla, uint8_t ins, uint8_t p1, uint8_t p2,
size_t dataSize = 0, const uint8_t *data = NULL,
size_t outputLength = 0, std::vector<uint8_t> *output = NULL);
protected:
PCSC::Session mSession;
char mPrintName[PATH_MAX];
virtual void name(const char *printName);
};
}
extern Tokend::Token *token;
#endif