Author: jmagne
Update of /cvs/dirsec/esc/mac/Tokend-35209/CoolKey
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv18528/CoolKey
Added Files:
Tag: PKI_8_0_RTM_BRANCH
CoolKeyAttributeCoder.cpp CoolKeyAttributeCoder.h
CoolKeyError.cpp CoolKeyError.h CoolKeyHandle.cpp
CoolKeyHandle.h CoolKeyPK11.cpp CoolKeyPK11.h
CoolKeyRecord.cpp CoolKeyRecord.h CoolKeySchema.cpp
CoolKeySchema.h CoolKeyToken.cpp CoolKeyToken.h Info.plist
coolkey.cpp dlfcn.h
Log Message:
Add directory for Tokend-35209 for Leopard.
--- NEW FILE CoolKeyAttributeCoder.cpp ---
/*CoolKey
* Copyright (c) 2004 Apple Computer, Inc. All Rights Reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
*
http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
* CoolKeyAttributeCoder.cpp
* Tokend CoolKey
*/
#include "CoolKeyAttributeCoder.h"
#include "Adornment.h"
#include "MetaAttribute.h"
#include "MetaRecord.h"
#include "Attribute.h"
#include <security_utilities/logging.h>
#include "CoolKeyRecord.h"
#include "CoolKeyToken.h"
#include "CoolKeyPK11.h"
#include <Security/cssmtype.h>
#include <Security/SecKeychainItem.h>
#include <security_cdsa_utilities/cssmkey.h>
#include <Security/SecCertificate.h>
#include <Security/SecKey.h>
using namespace Tokend;
//
// CoolKeyDataAttributeCoder
//
CoolKeyDataAttributeCoder::~CoolKeyDataAttributeCoder()
{
}
void CoolKeyDataAttributeCoder::decode(TokenContext *tokenContext,
const MetaAttribute &metaAttribute, Record &record)
{
Syslog::notice("CoolKeyDataAttributeCoder::decode");
}
CoolKeyCertAttributeCoder:: ~CoolKeyCertAttributeCoder()
{
}
void CoolKeyCertAttributeCoder::decode(Tokend::TokenContext *tokenContext,
const Tokend::MetaAttribute &metaAttribute, Tokend::Record
&record)
{
uint32 id = metaAttribute.attributeId();
MetaAttribute::Format format = metaAttribute.attributeFormat();
CoolKeyToken *token = (CoolKeyToken *) tokenContext;
if(!token)
return;
CoolKeyRecord &coolRec = dynamic_cast<CoolKeyRecord &> (record);
CoolKeyCertObject *cert = (CoolKeyCertObject *) coolRec.getCoolKeyObject();
Syslog::notice("CertAttributeCoder::decode coder %p cert object %p id %lu format
%lu record %p",this,cert,id,format,&record);
if(!cert)
return;
CK_BYTE tData[2048];
CK_ULONG dataLen = 2048;
CK_ULONG type = 0;
switch(id)
{
case kSecAlias:
Syslog::notice("kSecAlias");
cert->getLabel(tData,&dataLen);
record.attributeAtIndex(metaAttribute.attributeIndex(), new Attribute((const
void *)tData,dataLen));
break;
case kSecSubjectItemAttr:
cert->getSubject(tData,&dataLen);
Syslog::notice("kSecSubjectItemAttr retrieved data %p datalen
%lu",tData,dataLen);
record.attributeAtIndex(metaAttribute.attributeIndex(), new Attribute((const
void *)tData,dataLen));
break;
case kSecIssuerItemAttr:
cert->getIssuer(tData,&dataLen);
Syslog::notice("kSecIssuertItemAttr retrieved data %p datalen
%lu",tData,dataLen);
record.attributeAtIndex(metaAttribute.attributeIndex(), new Attribute((const
void *)tData,dataLen));
break;
case kSecSerialNumberItemAttr:
cert->getSerialNo(tData,&dataLen);
Syslog::notice("kSecSerialNumnberItemAttr retrieved data %p datalen
%lu",tData,dataLen);
record.attributeAtIndex(metaAttribute.attributeIndex(), new Attribute((const
void *)tData,dataLen));
break;
case kSecPublicKeyHashItemAttr:
Syslog::notice("kSecPublicKeyHashItemAttr");
getCertAttributeFromData(cert,kSecPublicKeyHashItemAttr, tData,
&dataLen);
record.attributeAtIndex(metaAttribute.attributeIndex(),
new Attribute((const void *)tData, dataLen));
break;
case kSecSubjectKeyIdentifierItemAttr:
Syslog::notice("kSecSubjectKeyIdentifierItemAttr");
break;
case kSecCertTypeItemAttr:
type = cert->getType();
Syslog::notice("kSecCertTypeItemAttr type %lu",type);
if(type == CKC_X_509)
type = CSSM_CERT_X_509v3;
else
if(type == CKC_X_509_ATTR_CERT)
type = CSSM_CERT_X_509_ATTRIBUTE;
else
type = CSSM_CERT_UNKNOWN;
Syslog::notice("kSecCertTypeItemAttr final type %lu",type);
record.attributeAtIndex(metaAttribute.attributeIndex(),new
Attribute((uint32)type));
break;
case kSecCertEncodingItemAttr:
Syslog::notice("kSecCertEncodingItemAttr");
type = CSSM_CERT_ENCODING_BER;
record.attributeAtIndex(metaAttribute.attributeIndex(), new
Attribute((uint32)type));
break;
case kSecLabelItemAttr:
cert->getLabel(tData,&dataLen);
Syslog::notice("kSecLabelItemAttr retrieved data %p datalen
%lu",tData,dataLen);
record.attributeAtIndex(metaAttribute.attributeIndex(), new Attribute((const
void *)tData,dataLen));
break;
default:
Syslog::notice("missed one");
break;
};
}
void CoolKeyCertAttributeCoder::getCertAttributeFromData(CoolKeyCertObject *aCert,CK_ULONG
aAttribute, CK_BYTE *aData, CK_ULONG *aDataLen)
{
CSSM_DATA csData;
CK_BYTE certData[2048];
CK_ULONG certDataLen = 2048;
OSStatus status = 0;
if(!aCert || !aData || *aDataLen <= 0)
return;
CK_ULONG size_in = *aDataLen;
*aDataLen = 0;
Syslog::notice("CoolKeyCertAttributeCoder::getCertAttributeFromData");
aCert->getData(certData,&certDataLen);
SecCertificateRef theCertificate;
csData.Data = certData;
csData.Length = certDataLen;
status = SecCertificateCreateFromData((CSSM_DATA * )&csData, CSSM_CERT_X_509v3,
CSSM_CERT_ENCODING_BER, &theCertificate);
if(status)
return;
Syslog::notice("CoolKeyCertAttributeCoder::getCertAttributeFromData done created
cert");
SecKeychainAttribute ska = { kSecPublicKeyHashItemAttr };
SecKeychainItemRef tRef = (SecKeychainItemRef) theCertificate;
SecKeychainAttributeList skal = { 1, &ska };
status = SecKeychainItemCopyContent(tRef, NULL, &skal,
NULL, NULL);
Syslog::notice("CoolKeyCertAttributeCoder::getCertAttributeFromData done got
attribute");
if(!status)
return;
if(ska.length < size_in)
{
memcpy(aData,ska.data,ska.length);
*aDataLen = ska.length;
}
SecKeychainItemFreeContent(&skal, NULL);
}
CoolKeyKeyAttributeCoder:: ~CoolKeyKeyAttributeCoder()
{
}
void CoolKeyKeyAttributeCoder::decode(Tokend::TokenContext *tokenContext,
const Tokend::MetaAttribute &metaAttribute, Tokend::Record
&record)
{
Syslog::notice("CoolKeyKeyAttributeCoder::decode");
uint32 id = metaAttribute.attributeId();
MetaAttribute::Format format = metaAttribute.attributeFormat();
CoolKeyRecord &coolRec = dynamic_cast<CoolKeyRecord &> (record);
CoolKeyKeyObject *key = (CoolKeyKeyObject *) coolRec.getCoolKeyObject();
if(!key)
return;
CK_BYTE tData[2048];
CK_ULONG dataLen = 2048;
CK_ULONG value = 0;
CK_BYTE attrib = 0;
Syslog::notice("CoolKeyKeyAttributeCoder::decode coder %p id %d format %d record
%p",this,id,format,&record);
switch(id)
{
case kSecKeyKeyClass:
Syslog::notice("kSecKeyKeyClass");
break;
case kSecKeyPrintName:
Syslog::notice("kSecKeyPrintName");
key->getLabel(tData,&dataLen);
record.attributeAtIndex(metaAttribute.attributeIndex(), new Attribute((const
void *)tData,dataLen));
break;
case kSecKeyAlias:
Syslog::notice("kSecKeyAlias");
break;
case kSecKeyPermanent:
Syslog::notice("kSecKeyPermanent");
break;
case kSecKeyPrivate:
Syslog::notice("kSecKeyKeyPrivate");
record.attributeAtIndex(metaAttribute.attributeIndex(), new
Attribute((uint32)1));
break;
case kSecKeyModifiable:
Syslog::notice("kSecKeyKeyModifiable");
record.attributeAtIndex(metaAttribute.attributeIndex(), new
Attribute((uint32)0));
break;
case kSecKeyApplicationTag:
Syslog::notice("kSecKeyApplicationTag");
break;
case kSecKeyKeyCreator:
Syslog::notice("kSecKeyKeyCreator");
break;
case kSecKeyKeyType:
Syslog::notice("kSecKeyType");
record.attributeAtIndex(metaAttribute.attributeIndex(), new
Attribute((uint32)CSSM_ALGID_RSA));
break;
case kSecKeyKeySizeInBits:
Syslog::notice("kSecKeyKeySizeInBits");
value = key->getKeySize();
record.attributeAtIndex(metaAttribute.attributeIndex(), new
Attribute((uint32)value));
Syslog::notice("kSecKeyKeySizeInBits %d",value);
break;
case kSecKeyEffectiveKeySize:
Syslog::notice("kSecKeyEffectiveKeySize");
value = key->getKeySize();;
record.attributeAtIndex(metaAttribute.attributeIndex(), new
Attribute((uint32)value));
Syslog::notice("kSecKeyEffectiveKeySizeInBits %d",value);
break;
case kSecKeyStartDate:
Syslog::notice("kSecKeyKeyStartDate");
break;
case kSecKeyEndDate:
Syslog::notice("kSecKeyKeyEndDate");
break;
case kSecKeySensitive:
attrib = key->getSensitive();
Syslog::notice("kSecKeySensitive %d",attrib);
record.attributeAtIndex(metaAttribute.attributeIndex(), new
Attribute((uint32)attrib));
break;
case kSecKeyAlwaysSensitive:
attrib = key->getAlwaysSensitive();
Syslog::notice("kSecKeyAlwaysSensitive %d", attrib);
record.attributeAtIndex(metaAttribute.attributeIndex(), new
Attribute((uint32)attrib));
break;
case kSecKeyExtractable:
Syslog::notice("kSecKeyExtractable");
attrib = key->getKeyExtractable();
record.attributeAtIndex(metaAttribute.attributeIndex(), new
Attribute((uint32)attrib));
break;
case kSecKeyNeverExtractable:
Syslog::notice("kSecKeyNeverExtractable");
attrib = key->getKeyNeverExtractable();
record.attributeAtIndex(metaAttribute.attributeIndex(), new
Attribute((uint32)attrib));
break;
case kSecKeyEncrypt:
Syslog::notice("kSecKeyKeyEncrypt");
attrib = key->getKeyEncrypt();
Syslog::notice("kSecKeyEncrypt value %d",attrib);
record.attributeAtIndex(metaAttribute.attributeIndex(), new
Attribute((uint32)attrib));
break;
case kSecKeyDecrypt:
attrib = key->getKeyDecrypt();
Syslog::notice("kSecKeyDecrypt value %d",attrib);
record.attributeAtIndex(metaAttribute.attributeIndex(), new
Attribute((uint32)attrib));
break;
case kSecKeyDerive:
attrib = key->getKeyDerive();
Syslog::notice("kSecKeyKeyDerive %d", attrib);
record.attributeAtIndex(metaAttribute.attributeIndex(), new
Attribute((uint32)attrib));
break;
case kSecKeySign:
attrib = key->getKeySign();
Syslog::notice("kSecKeyKeySign value %d",attrib);
record.attributeAtIndex(metaAttribute.attributeIndex(), new
Attribute((uint32)attrib));
break;
case kSecKeyVerify:
attrib = key->getKeyVerify();
Syslog::notice("kSecKeyKeyVerify value %d",attrib);
record.attributeAtIndex(metaAttribute.attributeIndex(), new
Attribute((uint32)attrib));
break;
case kSecKeySignRecover:
attrib = key->getKeySignRecover();
Syslog::notice("kSecKeyKeySignRecover %d", attrib);
record.attributeAtIndex(metaAttribute.attributeIndex(), new
Attribute((uint32)attrib));
break;
case kSecKeyVerifyRecover:
attrib = key->getKeyVerifyRecover();
Syslog::notice("kSecKeyKeyVerifyRecover %d", attrib);
record.attributeAtIndex(metaAttribute.attributeIndex(), new
Attribute((uint32)attrib));
break;
case kSecKeyWrap:
attrib = key->getKeyWrap();
Syslog::notice("kSecKeyKeyWrap %d", attrib);
record.attributeAtIndex(metaAttribute.attributeIndex(), new
Attribute((uint32)attrib));
break;
case kSecKeyUnwrap:
attrib = key->getKeyUnwrap();
Syslog::notice("kSecKeyKeyUnwrap %d", attrib);
record.attributeAtIndex(metaAttribute.attributeIndex(), new
Attribute((uint32)attrib));
break;
case kSecKeyLabel:
Syslog::notice("kSecKeyLabel");
key->getLabel(tData,&dataLen);
record.attributeAtIndex(metaAttribute.attributeIndex(), new Attribute((const
void *)tData,dataLen));
break;
};
}
/* arch-tag: 36510900-0DBC-11D9-9CFC-000A9595DEEE */
--- NEW FILE CoolKeyAttributeCoder.h ---
/*
* Copyright (c) 2004 Apple Computer, ICoolKeync. All Rights Reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
*
http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
* CoolKeyAttributeCoder.h
* Tokend CoolKey
*/
#ifndef _COOLKEY_ATTRIBUTECODER_H_
#define _COOLKEY_ATTRIBUTECODER_H_
#include "AttributeCoder.h"
#include <string>
#include <PCSC/musclecard.h>
#include "CoolKeyPK11.h"
//
// A coder that reads the data of an object
//
class CoolKeyDataAttributeCoder : public Tokend::AttributeCoder
{
NOCOPY(CoolKeyDataAttributeCoder)
public:
CoolKeyDataAttributeCoder() {}
virtual ~CoolKeyDataAttributeCoder();
virtual void decode(Tokend::TokenContext *tokenContext,
const Tokend::MetaAttribute &metaAttribute, Tokend::Record &record);
};
class CoolKeyCertAttributeCoder : public Tokend::AttributeCoder
{
NOCOPY(CoolKeyCertAttributeCoder)
public:
CoolKeyCertAttributeCoder() {}
virtual ~CoolKeyCertAttributeCoder();
virtual void decode(Tokend::TokenContext *tokenContext,
const Tokend::MetaAttribute &metaAttribute, Tokend::Record
&record);
protected:
void getCertAttributeFromData(CoolKeyCertObject *aCert,CK_ULONG aAttribute,
CK_BYTE *aData, CK_ULONG *aDataLen);
};
class CoolKeyKeyAttributeCoder : public Tokend::AttributeCoder
{
NOCOPY(CoolKeyKeyAttributeCoder)
public:
CoolKeyKeyAttributeCoder() {}
virtual ~CoolKeyKeyAttributeCoder();
virtual void decode(Tokend::TokenContext *tokenContext,
const Tokend::MetaAttribute &metaAttribute, Tokend::Record
&record);
};
#endif /* !_CoolKeyATTRIBUTECODER_H_ */
/* arch-tag: 366E16D4-0DBC-11D9-B030-000A9595DEEE */
--- NEW FILE CoolKeyError.cpp ---
/*
* Copyright (c) 2004 Apple Computer, Inc. All Rights Reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
*
http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
* CoolKeyError.cpp
* TokendMuscle
*/
#include "CoolKeyError.h"
#include <Security/cssmerr.h>
//
// CoolKeyError exceptions
//
CoolKeyError::CoolKeyError(uint16_t sw) : SCardError(sw)
{
IFDEBUG(debugDiagnose(this));
}
const char *CoolKeyError::what() const throw ()
{ return "CoolKey Error"; }
OSStatus CoolKeyError::osStatus() const
{
switch (statusWord)
{
case COOLKEY_AUTHENTICATION_FAILED_0:
case COOLKEY_AUTHENTICATION_FAILED_1:
case COOLKEY_AUTHENTICATION_FAILED_2:
case COOLKEY_AUTHENTICATION_FAILED_3:
return CSSM_ERRCODE_OPERATION_AUTH_DENIED;
default:
return SCardError::osStatus();
}
}
void CoolKeyError::throwMe(uint16_t sw)
{ throw CoolKeyError(sw); }
#if !defined(NDEBUG)
void CoolKeyError::debugDiagnose(const void *id) const
{
secdebug("exception", "%p CoolKeyError %s (%04hX)",
id, errorstr(statusWord), statusWord);
}
const char *CoolKeyError::errorstr(uint16_t sw) const
{
switch (sw)
{
case COOLKEY_AUTHENTICATION_FAILED_0:
return "Authentication failed, 0 retries left.";
case COOLKEY_AUTHENTICATION_FAILED_1:
return "Authentication failed, 1 retry left.";
case COOLKEY_AUTHENTICATION_FAILED_2:
return "Authentication failed, 2 retries left.";
case COOLKEY_AUTHENTICATION_FAILED_3:
return "Authentication failed, 3 retries left.";
default:
return SCardError::errorstr(sw);
}
}
#endif //NDEBUG
/* arch-tag: 0D984528-10D9-11D9-84A3-000393D5F80A */
--- NEW FILE CoolKeyError.h ---
/*
* Copyright (c) 2004 Apple Computer, Inc. All Rights Reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
*
http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
* CoolKeyError.h
* TokendMuscle
*/
#ifndef _COOLKEY_ERROR_H_
#define _COOLKEY_ERROR_H_
/** Entered PIN is not correct and pin was blocked. */
#define COOLKEY_AUTHENTICATION_FAILED_0 0x6300
/** Entered PIN is not correct, 1 try left. */
#define COOLKEY_AUTHENTICATION_FAILED_1 0x6301
/** Entered PIN is not correct, 2 tries left. */
#define COOLKEY_AUTHENTICATION_FAILED_2 0x6302
/** Entered PIN is not correct, 3 tries left. */
#define COOLKEY_AUTHENTICATION_FAILED_3 0x6303
#include "SCardError.h"
class CoolKeyError : public Tokend::SCardError
{
protected:
CoolKeyError(uint16_t sw);
public:
OSStatus osStatus() const;
virtual const char *what () const throw ();
static void check(uint16_t sw) { if (sw != SCARD_SUCCESS) throwMe(sw); }
static void throwMe(uint16_t sw) __attribute__((noreturn));
protected:
IFDEBUG(void debugDiagnose(const void *id) const;)
IFDEBUG(const char *errorstr(uint16_t sw) const;)
};
#endif /* !_CoolKeyERROR_H_ */
/* arch-tag: 0EB9B81B-10D9-11D9-BA83-000393D5F80A */
--- NEW FILE CoolKeyHandle.cpp ---
/*
* Copyright (c) 2004 Apple Computer, Inc. All Rights Reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
*
http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
* CoolKeyKeyHandle.cpp
* Tokend CoolKey
*/
#include "CoolKeyHandle.h"
#include "CoolKeyRecord.h"
#include "CoolKeyToken.h"
#include <security_utilities/debugging.h>
#include <security_utilities/utilities.h>
#include <security_cdsa_utilities/cssmerrors.h>
#include <security_cdsa_client/aclclient.h>
#include <Security/cssmerr.h>
#include <security_utilities/logging.h>
static const unsigned char sha1sigheader[] =
{
0x30, // SEQUENCE
0x21, // LENGTH
0x30, // SEQUENCE
0x09, // LENGTH
0x06, 0x05, 0x2B, 0x0E, 0x03, 0x02, 0x1a, // SHA1 OID (1 4 14 3 2 26)
0x05, 0x00, // OPTIONAL ANY algorithm params (NULL)
0x04, 0x14 // OCTECT STRING (20 bytes)
};
static const unsigned char md5sigheader[] =
{
0x30, // SEQUENCE
0x20, // LENGTH
0x30, // SEQUENCE
0x0C, // LENGTH
// MD5 OID (1 2 840 113549 2 5)
0x06, 0x08, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x05,
0x05, 0x00, // OPTIONAL ANY algorithm params (NULL)
0x04, 0x10 // OCTECT STRING (16 bytes)
};
using CssmClient::AclFactory;
//
// CoolKeyKeyHandle
//
CoolKeyKeyHandle::CoolKeyKeyHandle(CoolKeyToken &coolToken,
const Tokend::MetaRecord &metaRecord, CoolKeyRecord &coolKey) :
Tokend::KeyHandle(metaRecord, &coolKey),
mToken(coolToken),mRecord(coolKey)
{
}
CoolKeyKeyHandle::~CoolKeyKeyHandle()
{
}
void CoolKeyKeyHandle::getKeySize(CSSM_KEY_SIZE &keySize)
{
Syslog::notice("CoolKeyHandle::getKeySize");
CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
}
uint32 CoolKeyKeyHandle::getOutputSize(const Context &context, uint32 inputSize,
bool encrypting)
{
Syslog::notice("CoolKeyHandle::getOutputSize");
CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
return 0;
}
void CoolKeyKeyHandle::generateSignature(const Context &context,
CSSM_ALGORITHMS signOnly, const CssmData &input, CssmData &signature)
{
Syslog::notice("CoolKeyHandle::generateSignature Input length %d context.type %d
context.alg %d",input.length(),context.type(),context.algorithm());
CoolKeyObject * coolObj = mRecord.getCoolKeyObject();
if(!coolObj || coolObj->getClass() != CKO_PRIVATE_KEY)
{
Syslog::notice("Can't find object for record %p or incorrect object
type", &mRecord);
CssmError::throwMe(CSSM_ERRCODE_INVALID_DATA);
}
CoolKeyKeyObject * keyObj = (CoolKeyKeyObject *) coolObj;
CK_ULONG keyLength = keyObj->getKeySize() / 8;
Syslog::notice("keyLength %d",keyLength);
if (context.type() != CSSM_ALGCLASS_SIGNATURE)
CssmError::throwMe(CSSMERR_CSP_INVALID_CONTEXT);
if (context.algorithm() != CSSM_ALGID_RSA)
CssmError::throwMe(CSSMERR_CSP_INVALID_ALGORITHM);
// Find out if we are doing a SHA1 or MD5 signature and setup header to
// point to the right asn1 blob.
const unsigned char *header = NULL;
size_t headerLength = 0;
if (signOnly == CSSM_ALGID_SHA1)
{
Syslog::notice("Asking for SHA1");
header = sha1sigheader;
headerLength = sizeof(sha1sigheader);
Syslog::notice("header is sha1sigheader, len %d", headerLength);
if (input.Length != 20)
CssmError::throwMe(CSSMERR_CSP_BLOCK_SIZE_MISMATCH);
}
else if (signOnly == CSSM_ALGID_MD5)
{
Syslog::notice("Asking for MD5");
header = md5sigheader;
headerLength = sizeof(md5sigheader);
Syslog::notice("header is md5sigheader, len %d", headerLength);
if (input.Length != 16)
CssmError::throwMe(CSSMERR_CSP_BLOCK_SIZE_MISMATCH);
}
else if (signOnly == CSSM_ALGID_NONE)
{
header = NULL;
headerLength = 0;
Syslog::notice("Asking for CSSM_ALGID_NONE");
// Special case used by SSL it's an RSA signature, without the ASN1 stuff
}
else
CssmError::throwMe(CSSMERR_CSP_INVALID_DIGEST_ALGORITHM);
CoolKeyPK11 pk11Manager = mToken.getPK11Manager();
int loggedIn = pk11Manager.isTokenLoggedIn();
if(!loggedIn)
{
Syslog::error("Can't sign , not logged in.");
CssmError::throwMe(CSSM_ERRCODE_OPERATION_AUTH_DENIED);
}
signature.Data =( uint8*) malloc(keyLength);
// Create an input buffer in which we construct the data we will send to
// the token.
size_t inputDataSize = headerLength + input.Length;
Syslog::notice("inputDataSize %d", inputDataSize);
auto_array<unsigned char> inputData(keyLength);
unsigned char *to = inputData.get();
// Get padding, but default to pkcs1 style padding
uint32 padding = CSSM_PADDING_NONE;
context.getInt(CSSM_ATTRIBUTE_PADDING, padding);
Syslog::notice("padding value %d",padding);
if (padding == CSSM_PADDING_PKCS1)
{
Syslog::notice("CSSM_PADDING_PKCS1.");
// Add PKCS1 style padding
*(to++) = 0;
*(to++) = 1; /* Private Key Block Type. */
size_t padLength = keyLength - 3 - inputDataSize;
Syslog::notice("padlength %d",padLength);
memset(to, 0xff, padLength);
to += padLength;
*(to++) = 0;
inputDataSize = keyLength;
}
else if (padding == CSSM_PADDING_NONE)
{
Syslog::notice("CSSM_PADDING_NONE");
// Token will fail if the input data isn't exactly keysize / 8 octects
// long
}
else
CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_PADDING);
if (headerLength)
{
memcpy(to, header, headerLength);
to += headerLength;
}
// Finally copy the passed in data to the input buffer.
memcpy(to, input.Data, input.Length);
if(!signature.Data)
{
Syslog::error("Can't allocate memory for signature operation.");
CssmError::throwMe(CSSM_ERRCODE_INVALID_DATA);
}
signature.Length = (size_t) keyLength;
int result =
pk11Manager.generateSignature(coolObj,inputData.get(),inputDataSize,signature.Data,&signature.Length);
if(!result)
{
Syslog::notice("Problem generating signature");
if(signature.Data)
free(signature.Data);
CssmError::throwMe(CSSMERR_CSP_FUNCTION_FAILED);
}
Syslog::notice("generateSignature returned %d data lenght %d", result,
signature.Length);
}
void CoolKeyKeyHandle::verifySignature(const Context &context,
CSSM_ALGORITHMS signOnly, const CssmData &input, const CssmData &signature)
{
Syslog::notice("CoolKeyHandle::verifySignature");
CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
}
void CoolKeyKeyHandle::generateMac(const Context &context,
const CssmData &input, CssmData &output)
{
Syslog::notice("CoolKeyHandle::generateMac");
CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
}
void CoolKeyKeyHandle::verifyMac(const Context &context,
const CssmData &input, const CssmData &compare)
{
Syslog::notice("CoolKeyHandle::verifyMac");
CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
}
void CoolKeyKeyHandle::encrypt(const Context &context,
const CssmData &clear, CssmData &cipher)
{
Syslog::notice("CoolKeyHandle::encrypt");
CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
}
void CoolKeyKeyHandle::decrypt(const Context &context,
const CssmData &cipher, CssmData &clear)
{
Syslog::notice("CoolKeyHandle::decrypt type %d alg %d length
%d",context.type(), context.algorithm(),cipher.length());
CoolKeyObject * coolObj = mRecord.getCoolKeyObject();
if(!coolObj || coolObj->getClass() != CKO_PRIVATE_KEY )
{
Syslog::notice("Can't find object for record or incorrect object
%p", &mRecord);
CssmError::throwMe(CSSM_ERRCODE_INVALID_DATA);
}
CoolKeyKeyObject * keyObj = (CoolKeyKeyObject *) coolObj;
CK_ULONG keyLength = keyObj->getKeySize() / 8;
Syslog::notice("keyLength %d",keyLength);
if (context.type() != CSSM_ALGCLASS_ASYMMETRIC)
{
Syslog::error("In decrypt wrong key type, not asymmetric");
CssmError::throwMe(CSSMERR_CSP_INVALID_CONTEXT);
}
if (context.algorithm() != CSSM_ALGID_RSA)
{
Syslog::error("In decrypt wrong algorithm, not RSA");
CssmError::throwMe(CSSMERR_CSP_INVALID_ALGORITHM);
}
CoolKeyPK11 pk11Manager = mToken.getPK11Manager();
int loggedIn = pk11Manager.isTokenLoggedIn();
if(!loggedIn)
{
Syslog::error("Can't decrypt , not logged in.");
CssmError::throwMe(CSSM_ERRCODE_OPERATION_AUTH_DENIED);
}
clear.Data = (uint8 *) malloc((size_t) keyLength);
clear.Length = keyLength;
if(!clear.Data)
{
Syslog::error("Can't allocate data for decrype operation.");
CssmError::throwMe(CSSM_ERRCODE_INVALID_DATA);
}
int result =
pk11Manager.decryptData(coolObj,cipher.Data,cipher.Length,clear.Data,&clear.Length);
if(!result)
{
Syslog::error("Problem with decrypt operation");
if(clear.Data)
{
free(clear.Data);
}
CssmError::throwMe(CSSMERR_CSP_FUNCTION_FAILED);
}
Syslog::notice("decryptData returned %d data lenght %d", result,
clear.Length);
}
void CoolKeyKeyHandle::exportKey(const Context &context,
const AccessCredentials *cred, CssmKey &wrappedKey)
{
Syslog::notice("CoolKeyHandle::exportKey");
CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
}
void CoolKeyKeyHandle::getOwner(AclOwnerPrototype &owner)
{
Syslog::notice("CoolKeyKeyHandle::getOwner");
if (!mAclOwner) {
Allocator &alloc = Allocator::standard();
mAclOwner.allocator(alloc);
mAclOwner = AclFactory::AnySubject(alloc);
}
owner = mAclOwner;
}
void CoolKeyKeyHandle::getAcl(const char *tag, uint32 &count, AclEntryInfo
*&aclList)
{
Syslog::notice("CoolKeyKeyHandle::getAcl tag %s",tag);
// we don't (yet) support queries by tag
if (tag)
CssmError::throwMe(CSSM_ERRCODE_INVALID_ACL_ENTRY_TAG);
if(!mAclEntries) {
mAclEntries.allocator(Allocator::standard());
// Anyone can read the DB record for this key (which is a reference
// CSSM_KEY)
mAclEntries.add(CssmClient::AclFactory::AnySubject(
mAclEntries.allocator()),
AclAuthorizationSet(CSSM_ACL_AUTHORIZATION_DB_READ, 0));
CssmData prompt;
CoolKeyPK11 pk11Manager = mToken.getPK11Manager();
int loggedIn = pk11Manager.isTokenLoggedIn();
if(!loggedIn)
{
Syslog::notice("CoolKeyKeyHandle:getAcl token NOT logged in
already");
mAclEntries.add(CssmClient::AclFactory::PromptPWSubject(
mAclEntries.allocator(), prompt),
AclAuthorizationSet(
CSSM_ACL_AUTHORIZATION_SIGN
,
CSSM_ACL_AUTHORIZATION_DECRYPT,CSSM_ACL_AUTHORIZATION_ENCRYPT, 0));
}
else
{
Syslog::notice("CoolKeyKeyHandle:getAcl token logged in
already");
mAclEntries.add(CssmClient::AclFactory::AnySubject(
mAclEntries.allocator()),
AclAuthorizationSet(
CSSM_ACL_AUTHORIZATION_SIGN
, CSSM_ACL_AUTHORIZATION_DECRYPT,CSSM_ACL_AUTHORIZATION_ENCRYPT, 0));
}
}
count = mAclEntries.size();
aclList = mAclEntries.entries();
}
//
// CoolKeyKeyHandleFactory
//
CoolKeyKeyHandleFactory::~CoolKeyKeyHandleFactory()
{
}
Tokend::KeyHandle *CoolKeyKeyHandleFactory::keyHandle(
Tokend::TokenContext *tokenContext, const Tokend::MetaRecord &metaRecord,
Tokend::Record &record) const
{
Syslog::notice("CoolKeyKeyHandleFactory::keyHandle record %p
",&record);
CoolKeyToken &theToken = static_cast<CoolKeyToken& >(*tokenContext);
CoolKeyRecord &keyRecord = dynamic_cast<CoolKeyRecord &>(record);
return new CoolKeyKeyHandle(theToken, metaRecord, keyRecord);
}
/* arch-tag: 3685A262-0DBC-11D9-BC66-000A9595DEEE */
--- NEW FILE CoolKeyHandle.h ---
/*
* Copyright (c) 2004 Apple Computer, Inc. All Rights Reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
*
http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
* CoolKeyKeyHandle.h
* Tokend CoolKey
*/
#ifndef _COOLKEY_KEYHANDLE_H_
#define _COOLKEY_KEYHANDLE_H_
#include "KeyHandle.h"
class CoolKeyToken;
class CoolKeyRecord;
//
// A KeyHandle object which implements the crypto interface to muscle.
//
class CoolKeyKeyHandle: public Tokend::KeyHandle
{
NOCOPY(CoolKeyKeyHandle)
public:
CoolKeyKeyHandle(CoolKeyToken &cacToken, const Tokend::MetaRecord
&metaRecord,
CoolKeyRecord &cacKey);
~CoolKeyKeyHandle();
virtual void getKeySize(CSSM_KEY_SIZE &keySize);
virtual uint32 getOutputSize(const Context &context, uint32 inputSize,
bool encrypting);
virtual void generateSignature(const Context &context,
CSSM_ALGORITHMS signOnly, const CssmData &input, CssmData &signature);
virtual void verifySignature(const Context &context,
CSSM_ALGORITHMS signOnly, const CssmData &input,
const CssmData &signature);
virtual void generateMac(const Context &context, const CssmData &input,
CssmData &output);
virtual void verifyMac(const Context &context, const CssmData &input,
const CssmData &compare);
virtual void encrypt(const Context &context, const CssmData &clear,
CssmData &cipher);
virtual void decrypt(const Context &context, const CssmData &cipher,
CssmData &clear);
virtual void exportKey(const Context &context,
const AccessCredentials *cred, CssmKey &wrappedKey);
virtual void getOwner(AclOwnerPrototype &owner);
virtual void getAcl(const char *tag, uint32 &count, AclEntryInfo *&aclList);
private:
AutoAclOwnerPrototype mAclOwner;
AutoAclEntryInfoList mAclEntries;
CoolKeyToken &mToken;
CoolKeyRecord &mRecord;
};
//
// A factory that creates CoolKeyKeyHandle objects.
//
class CoolKeyKeyHandleFactory : public Tokend::KeyHandleFactory
{
NOCOPY(CoolKeyKeyHandleFactory)
public:
CoolKeyKeyHandleFactory() {}
virtual ~CoolKeyKeyHandleFactory();
virtual Tokend::KeyHandle *keyHandle(Tokend::TokenContext *tokenContext,
const Tokend::MetaRecord &metaRecord, Tokend::Record &record) const;
};
#endif /* !_CoolKeyKEYHANDLE_H_ */
/* arch-tag: 36A35766-0DBC-11D9-BB4D-000A9595DEEE */
--- NEW FILE CoolKeyPK11.cpp ---
/*
* CoolKeyPK11.cpp - CoolKey.tokend PKCS11 helper class
*/
#include "CoolKeyPK11.h"
#include <security_utilities/logging.h>
#include <dlfcn.h>
CK_ATTRIBUTE obj_classTemplate[] = {
{CKA_CLASS,NULL,0}
};
CK_ATTRIBUTE certTemplate[] = {
{CKA_CERTIFICATE_TYPE,NULL,0},{CKA_LABEL,NULL,0},
{CKA_SUBJECT,NULL,0},{CKA_ID,NULL,0},{CKA_ISSUER,NULL,0},
{CKA_SERIAL_NUMBER,NULL,0}, {CKA_VALUE,NULL,0}
};
CK_ATTRIBUTE public_keyTemplate[] = {
{CKA_KEY_TYPE,NULL,0},{CKA_ID,NULL,0},{CKA_LABEL,NULL,0},{CKA_MODULUS,NULL,0},
{CKA_PUBLIC_EXPONENT,NULL,0},{CKA_START_DATE,NULL,0},
{CKA_END_DATE,NULL,0},
{CKA_ENCRYPT,NULL,0},{CKA_VERIFY,NULL,0},{CKA_VERIFY_RECOVER,NULL,0},
{CKA_WRAP,NULL,0}
};
CK_ATTRIBUTE private_keyTemplate[] = {
{CKA_KEY_TYPE,NULL,0},{CKA_ID,NULL,0},{CKA_MODULUS,NULL,0},
{CKA_LABEL,NULL,0},{CKA_START_DATE,NULL,0},
{CKA_END_DATE,NULL,0}, {CKA_SENSITIVE,NULL,0},
{CKA_DECRYPT,NULL,0}, {CKA_SIGN,NULL,0}, {CKA_SIGN_RECOVER,NULL,0},
{CKA_UNWRAP,NULL,0}, {CKA_EXTRACTABLE,NULL,0}, {CKA_ALWAYS_SENSITIVE,NULL,0},
{CKA_NEVER_EXTRACTABLE,NULL,0},
{CKA_UNWRAP_TEMPLATE,NULL,0},{CKA_ALWAYS_AUTHENTICATE}
};
CK_ATTRIBUTE secret_keyTemplate[] = {
{CKA_KEY_TYPE,NULL,0},{CKA_ID,NULL,0},{CKA_LABEL,NULL,0},
{CKA_SENSITIVE,NULL,0},{CKA_ENCRYPT,NULL,0},{CKA_DECRYPT,NULL,0},
{CKA_SIGN,NULL,0},{CKA_VERIFY,NULL,0},{CKA_WRAP,NULL,0},{CKA_UNWRAP,NULL,0},
{CKA_EXTRACTABLE,NULL,0},{CKA_ALWAYS_SENSITIVE,NULL,0},{CKA_NEVER_EXTRACTABLE,NULL,0},
{CKA_CHECK_VALUE,NULL,0},{CKA_WRAP_WITH_TRUSTED,NULL,0},{CKA_TRUSTED,NULL,0},
{CKA_WRAP_TEMPLATE,NULL,0}
};
int CoolKeyPK11::loginToken(char *aPIN)
{
if(!mInitialized)
return 0;
if(!aPIN)
return 0;
CK_RV ck_rv = mEpv->C_Login(mSessHandle,CKU_USER,(CK_UTF8CHAR_PTR ) aPIN,(CK_ULONG)
strlen(aPIN));
Syslog::notice("CoolKeyPK11::loginToken result %d aPin %s
",ck_rv,"****");
if(ck_rv == CKR_OK && !mCachedPIN.size())
{
//Syslog::notice("CoolKeyPK11::loginToken setting cached PIN");
mCachedPIN = aPIN;
}
return ck_rv;
}
void CoolKeyPK11::logoutToken()
{
if(!mInitialized)
return;
CK_RV ck_rv = mEpv->C_Logout(mSessHandle);
//clear cached pin
mCachedPIN = "";
Syslog::notice("CoolKeyPK11::logout result %d ",ck_rv);
}
int CoolKeyPK11::verifyCachedPIN(char *aPIN)
{
if(!aPIN || !mInitialized)
return CKR_PIN_INCORRECT;
if(!strcmp(aPIN,(char *) mCachedPIN.c_str()))
{
Syslog::notice("PIN OK!");
return CKR_OK;
}
Syslog::notice("PIN not OK!");
return CKR_PIN_INCORRECT;
}
int CoolKeyPK11::isTokenLoggedIn()
{
CK_RV ck_rv;
if(!mInitialized)
return 0;
CK_SESSION_INFO sinfo;
CK_SESSION_HANDLE h = (CK_SESSION_HANDLE)0;
ck_rv = mEpv->C_GetSessionInfo(mSessHandle, &sinfo);
if( CKR_OK != ck_rv ) {
Syslog::notice("isTokenLoggedIn C_GetSessionInfo(0x%08x) returned %lu
ulDeviceError %lu", mSessHandle, ck_rv,sinfo.ulDeviceError);
ck_rv = mEpv->C_OpenSession(mSlots[mOurSlotIndex], CKF_SERIAL_SESSION,
(CK_VOID_PTR)CK_NULL_PTR, (CK_NOTIFY)CK_NULL_PTR, &h);
if( CKR_OK != ck_rv ) {
Syslog::error("C_OpenSession(%lu, CKF_SERIAL_SESSION, , ) returned
0x%08x", mSlots[mOurSlotIndex], ck_rv);
return 0;
}
ck_rv = mEpv->C_GetSessionInfo(h, &sinfo);
if( CKR_OK != ck_rv) {
Syslog::error("Failed second chance to get session info!!");
return 0;
}
else
{
Syslog::notice("Created new session handle, old one is invalid! 0x%08x
",h);
mSessHandle = h;
}
}
int loggedIn = 0;
Syslog::notice("isTokenLoggedIn token state %d", sinfo.state);
if(sinfo.state == CKS_RO_USER_FUNCTIONS || sinfo.state == CKS_RW_USER_FUNCTIONS)
{
Syslog::notice("isTokenLoggedIn Token IS logged in");
loggedIn = 1;
}
else
{
Syslog::notice("isTokenLoggedIn Token IS NOT logged in");
}
return loggedIn;
}
int CoolKeyPK11::loadModule()
{
CK_RV ck_rv;
CK_FUNCTION_LIST_PTR epv = (CK_FUNCTION_LIST_PTR) NULL;
CK_C_GetFunctionList gfl;
CK_C_INITIALIZE_ARGS InitArgs;
InitArgs.CreateMutex=0; //CK_CREATEMUTEX
InitArgs.DestroyMutex=0; //CK_DESTROYMUTEX
InitArgs.LockMutex=0; //CK_LOCKMUTEX
InitArgs.UnlockMutex=0; //CK_UNLOCKMUTEX
InitArgs.flags=0; //CK_FLAGS
InitArgs.pReserved=0; //CK_C_INITIALIZE_ARGS
mTokenUid[0] = 0;
mPk11Driver = dlopen(PKCS11_PATH_NAME,RTLD_LAZY);
if(!mPk11Driver)
{
Syslog::error("Can't load pkcs11 driver error: %d ",dlerror());
return 0;
}
else
{
Syslog::debug("In CoolKeyToken::loadPKCS11() . past load lib %p
",mPk11Driver);
}
// Now try to load the functions
gfl =(CK_C_GetFunctionList) dlsym(mPk11Driver,"C_GetFunctionList");
if(gfl == NULL)
{
Syslog::error("In CoolKeyToken::loadPKCS11() Can't load symbol
C_GetFunctionList error: $d ",dlerror());
dlclose(mPk11Driver);
mPk11Driver = NULL;
return 0;
}
//Syslog::debug("Found C_GetFunctionList : %p " , gfl);
ck_rv = (*gfl)(&epv);
if(ck_rv != CKR_OK)
{
Syslog::error("Can't get actual function list ");
dlclose(mPk11Driver);
mPk11Driver = NULL;
return 0;
}
//Syslog::debug("Function list found %p ", epv);
mEpv = epv;
//Now try to actually initialize the module
ck_rv = mEpv->C_Initialize(&InitArgs);
if(ck_rv != CKR_OK)
{
Syslog::error("Error initializing PKCS11 module result: %d ",ck_rv);
dlclose(mPk11Driver);
mPk11Driver = NULL;
mEpv = NULL;
return 0;
}
//Syslog::debug("Successfully Initialized PKCS11 module. ");
mInitialized = 1;
int res = loadSlotList();
if(res)
{
mIsOurToken = 1;
}
else
mInitialized = 0;
return res;
}
int CoolKeyPK11::freeModule()
{
if(!mInitialized)
{
return 1;
}
if(mEpv)
{
mEpv->C_Finalize(NULL);
mInitialized = NULL;
}
return 1;
}
int CoolKeyPK11::freeObjects()
{
return 1;
}
int CoolKeyPK11::loadObjects()
{
CK_RV ck_rv;
if(!mInitialized)
return 0;
CK_SESSION_HANDLE h = (CK_SESSION_HANDLE)0;
CK_SESSION_INFO sinfo;
CK_ULONG tnObjects = 0;
mSessHandle = 0;
ck_rv = mEpv->C_OpenSession(mSlots[mOurSlotIndex], CKF_SERIAL_SESSION,
(CK_VOID_PTR)CK_NULL_PTR, (CK_NOTIFY)CK_NULL_PTR, &h);
if( CKR_OK != ck_rv ) {
Syslog::error("C_OpenSession(%lu, CKF_SERIAL_SESSION, , ) returned
0x%08x", mSlots[mOurSlotIndex], ck_rv);
return 0;
}
Syslog::notice(" Opened a session: handle = 0x%08x", h);
mSessHandle = h;
ck_rv = mEpv->C_GetSessionInfo(h, &sinfo);
if( CKR_OK != ck_rv ) {
Syslog::notice("C_GetSessionInfo(%lu, ) returned 0x%08x", h, ck_rv);
return 0;
}
Syslog::notice(" SESSION INFO:");
Syslog::notice(" slotID = %lu", sinfo.slotID);
Syslog::notice(" state = %lu", sinfo.state);
Syslog::notice(" flags = 0x%08x", sinfo.flags);
Syslog::notice(" ulDeviceError = %lu", sinfo.ulDeviceError);
ck_rv = mEpv->C_FindObjectsInit(h, (CK_ATTRIBUTE_PTR)CK_NULL_PTR, 0);
if( CKR_OK != ck_rv ) {
Syslog::error("C_FindObjectsInit(%lu, NULL_PTR, 0) returned 0x%08x", h,
ck_rv);
return 0;
}
Syslog::notice(" All objects:");
while(1) {
CK_OBJECT_HANDLE o = (CK_OBJECT_HANDLE)0;
CK_ULONG nObjects = 0;
ck_rv = mEpv->C_FindObjects(h, &o, 1, &nObjects);
if( CKR_OK != ck_rv ) {
Syslog::notice("C_FindObjects(%lu, , 1, ) returned 0x%08x", h,
ck_rv);
return 0;
}
if( 0 == nObjects ) {
break;
}
tnObjects++;
Syslog::notice(" OBJECT HANDLE %lu", o);
ck_rv = mEpv->C_GetAttributeValue(h, o, obj_classTemplate, 1);
//Syslog::notice("ck_rv %d",ck_rv);
switch( ck_rv ) {
case CKR_OK:
case CKR_ATTRIBUTE_SENSITIVE:
case CKR_ATTRIBUTE_TYPE_INVALID:
case CKR_BUFFER_TOO_SMALL:
break;
default:
Syslog::notice("C_GetAtributeValue(%lu, %lu, {one attribute type},
%lu) returned 0x%08x",
h, o, 1, ck_rv);
return 0;
}
if( 1 ) {
if( -1 != (CK_LONG)obj_classTemplate[0].ulValueLen ) {
obj_classTemplate[0].pValue = (CK_VOID_PTR) new
char[obj_classTemplate[0].ulValueLen];
if(!obj_classTemplate[0].pValue)
{
Syslog::notice("Can't allocate memory for attribute of size
%d",(int) obj_classTemplate[0].ulValueLen);
continue;
}
ck_rv = mEpv->C_GetAttributeValue(h, o, obj_classTemplate, 1);
if(ck_rv == CKR_OK)
{
CK_LONG obj_class = (CK_LONG) *((CK_LONG *)
obj_classTemplate[0].pValue);
Syslog::notice("objclass: %lu",obj_class);
CoolKeyObject *newObject = NULL;
switch(obj_class)
{
case CKO_CERTIFICATE:
Syslog::notice("Found
certificate:-----------------");
newObject = (CoolKeyObject *) new
CoolKeyCertObject(o,h,obj_class,this);
break;
case CKO_PUBLIC_KEY:
Syslog::notice("Found public
key:----------------");
newObject = (CoolKeyObject *) new
CoolKeyKeyObject(o,h,obj_class,this);
Syslog::notice("Found public key:");
break;
case CKO_PRIVATE_KEY:
Syslog::notice("Found private
key:-------------------");
newObject = (CoolKeyObject *) new
CoolKeyKeyObject(o,h,obj_class,this);
break;
default:
Syslog::notice("Found something else:");
break;
};
if(newObject)
{
mObjects[o] = newObject;
}
}
if(obj_classTemplate[0].pValue)
delete [] (char *) obj_classTemplate[0].pValue;
obj_classTemplate[0].pValue = NULL;
}
}
} /* while(1) */
ck_rv = mEpv->C_FindObjectsFinal(h);
if( CKR_OK != ck_rv ) {
Syslog::notice("C_FindObjectsFinal(%lu) returned 0x%08x", h, ck_rv);
return 0;
}
Syslog::notice(" (%lu objects total)", tnObjects);
ck_rv = mEpv->C_CloseSession(h);
if( CKR_OK != ck_rv ) {
Syslog::notice( "C_CloseSession(%lu) returned 0x%08x", h, ck_rv);
return 0;
}
return 1;
}
int CoolKeyPK11::loadSlotList()
{
mTokenUid[0] = 0;
int result = 0;
if(!mInitialized)
{
return result;
}
CK_RV ck_rv = 0;
CK_ULONG nSlots = 0;
ck_rv = mEpv->C_GetSlotList(CK_FALSE,(CK_SLOT_ID) CK_NULL_PTR,&nSlots);
if(ck_rv == CKR_OK)
{
Syslog::notice("In CoolKeyPK11:loadSlotList() GetSlotList found %d slot(s)
",nSlots);
}
else
{
Syslog::notice("In CoolKeyToken::probe() GetSlotList error: %d
",ck_rv);
}
if(nSlots > COOLKEY_MAX_SLOTS)
{
return result;
}
if(nSlots > 0)
{
ck_rv = mEpv->C_GetSlotList(CK_FALSE,mSlots, &nSlots);
if(ck_rv != CKR_OK)
{
Syslog::debug("In CoolKeyToken::probe() GetSlotList error: %d
",ck_rv);
}
mOurSlotIndex = nSlots - 1;
for(CK_ULONG i = 0; i < nSlots ; i++)
{
CK_SLOT_INFO sinfo;
int j = 0;
while( j++ < 5)
{
ck_rv = mEpv->C_GetSlotInfo(mSlots[i],&sinfo);
if(ck_rv != CKR_OK)
{
Syslog::error("In CoolKeyPK11::loadSlotListe() GetSlotInfo error: %d
",ck_rv);
break;
//continue;
}
Syslog::notice(" Slot Info: Slot: %d" ,i);
Syslog::notice(" slotDescription = \"%.64s\"",
sinfo.slotDescription);
Syslog::notice(" manufacturerID = \"%.32s\"",
sinfo.manufacturerID);
Syslog::notice(" flags = 0x%08lx", sinfo.flags);
Syslog::notice(" -> TOKEN PRESENT = %s",
sinfo.flags & CKF_TOKEN_PRESENT ? "TRUE" :
"FALSE");
Syslog::notice(" -> REMOVABLE DEVICE = %s",
sinfo.flags & CKF_REMOVABLE_DEVICE ? "TRUE" :
"FALSE");
Syslog::notice(" -> HW SLOT = %s",
sinfo.flags & CKF_HW_SLOT ? "TRUE" :
"FALSE");
Syslog::notice(" hardwareVersion = %lu.%02lu",
sinfo.hardwareVersion.major, sinfo.hardwareVersion.minor);
Syslog::notice(" firmwareVersion = %lu.%02lu",
sinfo.firmwareVersion.major, sinfo.firmwareVersion.minor);
Syslog::notice(" See if token is present in reader");
if(!(sinfo.flags & CKF_TOKEN_PRESENT))
{
Syslog::notice(" Failed to connect to the token try again.");
usleep(100000);
continue;
}
Syslog::notice(" Token is really present!");
break;
}
if(sinfo.flags & CKF_TOKEN_PRESENT )
{
CK_TOKEN_INFO tinfo;
(void)memset(&tinfo, 0, sizeof(CK_TOKEN_INFO));
ck_rv = mEpv->C_GetTokenInfo(mSlots[i], &tinfo);
if( CKR_OK != ck_rv ) {
Syslog::debug("C_GetTokenInfo(%lu, ) returned 0x%08x",
mSlots[i], ck_rv);
return result;
}
Syslog::notice(" Token Info:");
Syslog::notice(" label = \"%.32s\"",
tinfo.label);
Syslog::notice(" manufacturerID = \"%.32s\"",
tinfo.manufacturerID);
Syslog::notice(" model = \"%.16s\"",
tinfo.model);
Syslog::notice(" serialNumber = \"%.16s\"",
tinfo.serialNumber);
Syslog::notice(" flags = 0x%08lx", tinfo.flags);
/*
Syslog::notice(" -> RNG = %s",
tinfo.flags & CKF_RNG ? "TRUE" :
"FALSE");
Syslog::notice(" -> WRITE PROTECTED = %s",
tinfo.flags & CKF_WRITE_PROTECTED ? "TRUE" :
"FALSE");
Syslog::notice(" -> LOGIN REQUIRED = %s",
tinfo.flags & CKF_LOGIN_REQUIRED ? "TRUE" :
"FALSE");
Syslog::notice(" -> USER PIN INITIALIZED = %s",
tinfo.flags & CKF_USER_PIN_INITIALIZED ? "TRUE" :
"FALSE");
Syslog::notice(" -> RESTORE KEY NOT NEEDED =
%s",
tinfo.flags & CKF_RESTORE_KEY_NOT_NEEDED ? "TRUE" :
"FALSE");
Syslog::debug(" -> CLOCK ON TOKEN = %s",
tinfo.flags & CKF_CLOCK_ON_TOKEN ? "TRUE" :
"FALSE");
Syslog::notice( " ulMaxSessionCount = %lu",
tinfo.ulMaxSessionCount);
Syslog::notice( " ulSessionCount = %lu",
tinfo.ulSessionCount);
Syslog::notice( " ulMaxRwSessionCount = %lu",
tinfo.ulMaxRwSessionCount);
Syslog::notice(" ulRwSessionCount = %lu",
tinfo.ulRwSessionCount);
Syslog::notice( " ulMaxPinLen = %lu",
tinfo.ulMaxPinLen);
Syslog::notice(" ulMinPinLen = %lu",
tinfo.ulMinPinLen);
Syslog::notice(" ulTotalPublicMemory = %lu",
tinfo.ulTotalPublicMemory);
Syslog::notice(" ulFreePublicMemory = %lu",
tinfo.ulFreePublicMemory);
Syslog::notice(" ulTotalPrivateMemory = %lu",
tinfo.ulTotalPrivateMemory);
Syslog::notice(" ulFreePrivateMemory = %lu",
tinfo.ulFreePrivateMemory);
Syslog::notice(" hardwareVersion = %lu.%02lu",
(uint32)tinfo.hardwareVersion.major,
(uint32)tinfo.hardwareVersion.minor);
Syslog::notice(" firmwareVersion = %lu.%02lu",
(uint32)tinfo.firmwareVersion.major,
(uint32)tinfo.firmwareVersion.minor);
Syslog::notice(" utcTime = \"%.16s\"",
tinfo.utcTime);
*/
Syslog::notice(" Token is present uid %s",tinfo.label);
int label_size = 32;
memcpy((void *) mTokenUid, (void *) tinfo.label,label_size);
mTokenUid[label_size -1] = 0;
}
else
{
Syslog::error(" Token not present in slot ");
return result;
}
}
}else
{
return result;
}
return 1;
}
//Actual crypto ops
int CoolKeyPK11::decryptData(CoolKeyObject *aObj,CK_BYTE *aEncData, CK_ULONG aEncDataLen,
CK_BYTE *aData, CK_ULONG *aDataLen)
{
int result = 0;
if( !mEpv || !aObj || !aEncData || !aEncDataLen || !aData || !aDataLen
|| aDataLen <=0 || *aDataLen <= 0)
{
Syslog::error(" CoolKeyPK11::decryptData bad input data");
return result;
}
CK_OBJECT_HANDLE objHandle = aObj->getHandle();
CK_RV ck_rv = mEpv->C_DecryptInit(mSessHandle,NULL,objHandle);
Syslog::notice("decryptData C_DecryptInit Init result %d", ck_rv);
if(ck_rv != CKR_OK)
{
Syslog::notice("decryptData error calling C_DecryptInit");
return result;
}
ck_rv = mEpv->C_Decrypt(mSessHandle,aEncData,aEncDataLen,aData,aDataLen);
Syslog::notice("C_Decrypt result %d", ck_rv);
if(ck_rv != CKR_OK)
{
Syslog::notice("C_Decrypt result in error");
return 0;
}
Syslog::notice("decryptData return success");
return 1;
}
int CoolKeyPK11::generateSignature(CoolKeyObject *aObj,CK_BYTE *aData, CK_ULONG aDataLen,
CK_BYTE *aSignature, CK_ULONG *aSignatureLen)
{
int result = 0;
if( !mEpv || !aObj || !aData || !aDataLen || !aSignature || !aSignatureLen
|| aDataLen <=0 || *aSignatureLen <= 0)
{
Syslog::error(" CoolKeyPK11::generateSignature bad input data");
return result;
}
CK_OBJECT_HANDLE objHandle = aObj->getHandle();
CK_RV ck_rv = mEpv->C_SignInit(mSessHandle,NULL,objHandle);
Syslog::notice("generateSignature C_SignInit result %d", ck_rv);
if(ck_rv != CKR_OK)
{
Syslog::notice("generatSignature error calling C_SignInit");
return result;
}
ck_rv = mEpv->C_Sign(mSessHandle,aData,aDataLen,aSignature,aSignatureLen);
Syslog::notice("C_Sign result %d", ck_rv);
if(ck_rv != CKR_OK)
{
Syslog::notice("C_Sign result in error");
return 0;
}
Syslog::notice("generateSignature return success");
return 1;
}
void CoolKeyObject::dumpData(CK_CHAR *aData, CK_ULONG aDataLen)
{
char line[256];
Syslog::notice("dumping data %p len %lu",aData,aDataLen);
CK_ULONG max = 8;
for(CK_ULONG i = 0 ; i < aDataLen; i ++)
{
if(i > max)
break;
sprintf(line," val[%lu]= %X",i,aData[i]);
Syslog::notice(line);
}
}
void CoolKeyObject::loadAttributes(CK_ATTRIBUTE *aTemplate,int aTemplateSize)
{
CK_RV ck_rv;
Syslog::notice("CoolKeyObject::loadAttributes with args template size
%d",aTemplateSize);
if(!aTemplate || aTemplateSize <= 0 || mAttributesLoaded)
return;
CK_FUNCTION_LIST_PTR funcPtr = NULL;
if(mParent && (funcPtr = mParent->getFunctionPointer()))
{
Syslog::notice("CoolKeyObject::loadAttributes got function pointer");
ck_rv = funcPtr->C_GetAttributeValue(mSessHandle, mObjHandle, aTemplate,
aTemplateSize);
switch(ck_rv)
{
case CKR_OK:
case CKR_ATTRIBUTE_SENSITIVE:
case CKR_ATTRIBUTE_TYPE_INVALID:
case CKR_BUFFER_TOO_SMALL:
break;
default:
Syslog::notice("CoolKeyObject::loadAttributes failed ck_rv
%d",ck_rv);
return;
break;
};
for(int i = 0 ; i < aTemplateSize ; i++)
{
Syslog::notice("Object attribute: name % stype 0x%lx , size %d",
attributeName(aTemplate[i].type),aTemplate[i].type,
aTemplate[i].ulValueLen);
}
//Do it again to get actual data
for(int i = 0; i < aTemplateSize ; i++)
{
int size = (int)aTemplate[i].ulValueLen;
if(size && size != -1)
{
char *objData = new char [aTemplate[i].ulValueLen];
if(!objData)
{
continue;
}
aTemplate[i].pValue = objData;
}
}
//Now have the data alocated go get it.
ck_rv = funcPtr->C_GetAttributeValue(mSessHandle, mObjHandle, aTemplate,
aTemplateSize);
switch(ck_rv)
{
case CKR_OK:
case CKR_ATTRIBUTE_SENSITIVE:
case CKR_ATTRIBUTE_TYPE_INVALID:
case CKR_BUFFER_TOO_SMALL:
break;
default:
Syslog::notice("CoolKeyObject::loadAttributes failed ck_rv
%d",ck_rv);
return;
break;
};
//print out results of actually getting the data
for(int i = 0 ; i < aTemplateSize ; i++)
{
int size = aTemplate[i].ulValueLen;
char *data = (char *) aTemplate[i].pValue;
if(size && size != -1 && data)
{
Syslog::notice("Legitimate Object attribute saving.... Name: %s :
type 0x%lx , size %d",
attributeName(aTemplate[i].type),aTemplate[i].type,
aTemplate[i].ulValueLen);
CK_ATTRIBUTE * newAttr = new CK_ATTRIBUTE ;
//Check for CAC data, we want to let the Apple CAC TokenD take care of
these.
if(strstr(data,"CAC"))
{
Syslog::notice("CAC related item found, exiting... \n");
// exit(0);
}
if(!newAttr)
{
Syslog::notice("Can't allocate memory for new
attribute");
continue;
}
newAttr->ulValueLen = aTemplate[i].ulValueLen;
newAttr->type = aTemplate[i].type;
newAttr->pValue = aTemplate[i].pValue;
CoolKeyObject::dumpData((CK_BYTE
*)newAttr->pValue,newAttr->ulValueLen);
// put the attribute in our local map
aTemplate[i].ulValueLen = 0;
aTemplate[i].pValue = NULL;
mAttributes[newAttr->type] = newAttr;
}
}
}
}
void CoolKeyKeyObject::loadAttributes()
{
Syslog::notice("CoolKeyKeyObject::loadAttributes no args");
if(mAttributesLoaded)
return;
int templateSize = 0;
if(mObjClass == CKO_PRIVATE_KEY)
{
templateSize = sizeof(private_keyTemplate)/sizeof(CK_ATTRIBUTE);
CoolKeyObject::loadAttributes((CK_ATTRIBUTE *)private_keyTemplate,templateSize);
}
else
{
templateSize = sizeof(public_keyTemplate)/sizeof(CK_ATTRIBUTE);
CoolKeyObject::loadAttributes((CK_ATTRIBUTE *)public_keyTemplate, templateSize);
}
}
CK_BYTE CoolKeyKeyObject::getSensitive()
{
CK_BYTE result = 0;
result = getByteAttribute(CKA_SENSITIVE);
Syslog::notice("In CoolKeyObject::getID type %c",result);
return result;
}
CK_BYTE CoolKeyKeyObject::getKeyEncrypt()
{
CK_BYTE result = 0;
result = getByteAttribute(CKA_ENCRYPT);
Syslog::notice("In CoolKeyObject::getKeyEncrypt result %d",result);
return result;
}
CK_BYTE CoolKeyKeyObject::getKeyDecrypt()
{
CK_BYTE result = 0;
result = getByteAttribute(CKA_DECRYPT);
Syslog::notice("In CoolKeyObject::getKeyDecrypt type %d",result);
return result;
}
CK_BYTE CoolKeyKeyObject::getKeySign()
{
CK_BYTE result = 0;
result = getByteAttribute(CKA_SIGN);
Syslog::notice("In CoolKeyKeyObject::getKeySign type %d",result);
return result;
}
CK_BYTE CoolKeyKeyObject::getKeyWrap()
{
CK_BYTE result = 0;
result = getByteAttribute(CKA_WRAP);
Syslog::notice("In CoolKeyKeyObject::getKeyWrap type %d",result);
return result;
}
CK_BYTE CoolKeyKeyObject::getKeyVerify()
{
CK_BYTE result = 0;
result = getByteAttribute(CKA_VERIFY);
Syslog::notice("In CoolKeyKeyObject::getKeyVerify type %d",result);
return result;
}
CK_BYTE CoolKeyKeyObject::getKeyDerive()
{
CK_BYTE result = 0;
result = getByteAttribute(CKA_DERIVE);
Syslog::notice("In CoolKeyKeyObject::getKeyDerive type %d",result);
return result;
}
CK_BYTE CoolKeyKeyObject::getKeyUnwrap()
{
CK_BYTE result = 0;
result = getByteAttribute(CKA_UNWRAP);
Syslog::notice("In CoolKeyKeyObject::getKeyUnwrap type %d",result);
return result;
}
CK_BYTE CoolKeyKeyObject::getKeySignRecover()
{
CK_BYTE result = 0;
result = getByteAttribute(CKA_SIGN_RECOVER);
Syslog::notice("In CoolKeyKeyObject::getKeySignRecover type %d",result);
return result;
}
CK_BYTE CoolKeyKeyObject::getKeyVerifyRecover()
{
CK_BYTE result = 0;
result = getByteAttribute(CKA_VERIFY_RECOVER);
Syslog::notice("In CoolKeyObject::getKeyKeyVerifyRecover type %d",result);
return result;
}
CK_BYTE CoolKeyKeyObject::getKeyExtractable()
{
CK_BYTE result = 0;
result = getByteAttribute(CKA_EXTRACTABLE);
Syslog::notice("In CoolKeyKeyObject::getExtractable type %d",result);
return result;
}
CK_BYTE CoolKeyKeyObject::getKeyNeverExtractable()
{
CK_BYTE result = 0;
result = getByteAttribute(CKA_NEVER_EXTRACTABLE);
Syslog::notice("In CoolKeyKeyObject::getNeverExtractable type %d",result);
return result;
}
CK_BYTE CoolKeyKeyObject::getAlwaysSensitive()
{
CK_BYTE result = 0;
result = getByteAttribute(CKA_ALWAYS_SENSITIVE);
Syslog::notice("In CoolKeyKeyObject::getAlwaysSensitive type %d",result);
return result;
}
void CoolKeyKeyObject::getLabel(CK_BYTE *aData, CK_ULONG *aDataLen)
{
if(!aData || !aDataLen || *aDataLen < 1)
return;
aData[0] = 0;
getByteDataAttribute(CKA_LABEL,aData,aDataLen);
Syslog::notice("In CoolKeyKeyObject::getLabel %s",aData);
}
CK_BYTE CoolKeyObject::getID()
{
CK_BYTE result = 0;
result = getByteAttribute(CKA_ID);
Syslog::notice("In CoolKeyObject::getID type %c",result);
return result;
}
void CoolKeyObject::freeAttributes()
{
Syslog::notice("CoolKeyObject::freeAttributes");
map< CK_ATTRIBUTE_TYPE, CK_ATTRIBUTE * >::iterator i;
CK_ATTRIBUTE *cur = NULL;
for(i = mAttributes.begin(); i!= mAttributes.end(); i++)
{
cur = (*i).second;
if(cur)
{
if(cur->pValue)
delete [] (char *) cur->pValue;
delete cur;
}
}
}
void CoolKeyObject::loadAttributes()
{
//Syslog::notice("CoolKeyObject::loadAttributes no args");
}
void CoolKeyCertObject::loadAttributes()
{
//Syslog::notice("In CoolKeyCertObject::loadAttributes no args");
if(mAttributesLoaded)
return;
int templateSize = sizeof(certTemplate)/sizeof(CK_ATTRIBUTE);
if(!templateSize)
return;
CoolKeyObject::loadAttributes(certTemplate,templateSize);
}
CoolKeyKeyObject::CoolKeyKeyObject(CK_OBJECT_HANDLE aObjHandle, CK_SESSION_HANDLE
aSessHandle,CK_LONG aObjClass,CoolKeyPK11 *aParent) :
CoolKeyObject(aObjHandle,aSessHandle,aObjClass,aParent)
{
//Syslog::notice("CoolKeyKeyObject::CoolKeyKeyObject");
loadAttributes();
}
CK_ULONG CoolKeyKeyObject::getKeySize()
{
CK_ULONG size = 0;
CK_ATTRIBUTE *theMod = getAttribute(CKA_MODULUS);
if(theMod)
{
size = (theMod->ulValueLen - 1 ) * 8;
}
return size;
}
CoolKeyCertObject::CoolKeyCertObject(CK_OBJECT_HANDLE aObjHandle, CK_SESSION_HANDLE
aSessHandle,CK_LONG aObjClass,CoolKeyPK11 *aParent) :
CoolKeyObject(aObjHandle,aSessHandle,aObjClass,aParent)
{
loadAttributes();
}
void CoolKeyCertObject::getIssuer(CK_BYTE *aData, CK_ULONG *aDataLen)
{
if(!aData || !aDataLen || *aDataLen < 1)
return;
aData[0] = 0;
getByteDataAttribute(CKA_ISSUER,aData,aDataLen);
}
void CoolKeyCertObject::getSerialNo(CK_BYTE *aData,CK_ULONG *aDataLen)
{
if(!aData || !aDataLen || *aDataLen < 1)
return;
aData[0] = 0;
getByteDataAttribute(CKA_SERIAL_NUMBER,aData,aDataLen);
}
void CoolKeyCertObject::getLabel(CK_BYTE *aData, CK_ULONG *aDataLen)
{
if(!aData || !aDataLen || *aDataLen < 1)
return;
aData[0] = 0;
getByteDataAttribute(CKA_LABEL,aData,aDataLen);
}
void CoolKeyCertObject::getPublicKeyHash(CK_BYTE *aData,CK_ULONG *aDataLen)
{
if(!aData || !aDataLen || *aDataLen < 1)
return;
aData[0] = 0;
}
void CoolKeyCertObject::getData(CK_BYTE *aData, CK_ULONG *aDataLen)
{
if(!aData || !aDataLen || *aDataLen < 1)
return;
aData[0] = 0;
getByteDataAttribute(CKA_VALUE,aData,aDataLen);
}
void CoolKeyCertObject::getSubject(CK_BYTE *aData, CK_ULONG *aDataLen)
{
if(!aData || !aDataLen || *aDataLen < 1)
return;
aData[0] = 0;
getByteDataAttribute(CKA_SUBJECT,aData,aDataLen);
}
CK_ULONG CoolKeyCertObject::getType()
{
CK_ULONG result = 0;
result = getULongAttribute(CKA_CERTIFICATE_TYPE);
Syslog::notice("In CoolKeyCertObject::getType type %lu",result);
return result;
}
CoolKeyObject::CoolKeyObject(CK_OBJECT_HANDLE aObjHandle, CK_SESSION_HANDLE
aSessHandle,CK_LONG aObjClass,CoolKeyPK11 *aParent) :
mObjHandle(aObjHandle),mSessHandle(aSessHandle),mAttributesLoaded(0),mObjClass(aObjClass),mParent(aParent)
{
Syslog::notice("In CoolKeyObject::CoolKeyObject mObjClass %d",mObjClass);
}
CK_ATTRIBUTE * CoolKeyObject::getAttribute(CK_ATTRIBUTE_TYPE aAttr)
{
CK_ATTRIBUTE *theAttr = mAttributes[aAttr];
return theAttr;
}
CK_LONG CoolKeyObject::getLongAttribute(CK_ATTRIBUTE_TYPE aAttr)
{
CK_ATTRIBUTE *theAttr = getAttribute(aAttr);
if(!theAttr)
return 0;
CK_ULONG size = theAttr->ulValueLen ;
if(size != sizeof(CK_LONG))
return 0;
if(!theAttr->pValue)
return 0;
return (CK_LONG) *((CK_LONG *) theAttr->pValue);
}
CK_ULONG CoolKeyObject::getULongAttribute(CK_ATTRIBUTE_TYPE aAttr)
{
CK_ATTRIBUTE *theAttr = getAttribute(aAttr);
Syslog::notice("In CoolKeyObject::getULongAttr attr %p size %d value
%p",theAttr,theAttr->ulValueLen,theAttr->pValue);
if(!theAttr)
return 0;
CK_ULONG size = theAttr->ulValueLen ;
if(size != sizeof(CK_ULONG))
return 0;
if(!theAttr->pValue)
return 0;
return (CK_ULONG) *((CK_ULONG *) theAttr->pValue);
}
CK_BYTE CoolKeyObject::getByteAttribute(CK_ATTRIBUTE_TYPE aAttr)
{
CK_ATTRIBUTE *theAttr = getAttribute(aAttr);
if(!theAttr)
return 0;
CK_ULONG size = theAttr->ulValueLen ;
if(size != sizeof(CK_BYTE))
return 0;
if(!theAttr->pValue)
return 0;
return (CK_BYTE) *((CK_BYTE *) theAttr->pValue);
}
void CoolKeyObject::getByteDataAttribute(CK_ATTRIBUTE_TYPE aAttr,CK_BYTE *aData, CK_ULONG
*aDataLen)
{
if(!aData || !aDataLen || *aDataLen <= 0 )
return;
CK_ATTRIBUTE *theAttr = getAttribute(aAttr);
Syslog::notice("In CoolKeyObject::getByteData attr %p attr size %d
",theAttr,theAttr->ulValueLen);
if(!theAttr)
return ;
CK_ULONG size = theAttr->ulValueLen ;
if(size < 1 || size >= *aDataLen)
return;
*aDataLen = 0;
aData[0] = 0;
if(!theAttr->pValue)
return;
memcpy( aData, theAttr->pValue,size);
*aDataLen = size;
}
char *CoolKeyObject::attributeName(uint32_t attributeId)
{
static char buffer[20];
switch (attributeId)
{
case CKA_CLASS: return "CLASS";
case CKA_TOKEN: return "TOKEN";
case CKA_PRIVATE: return "PRIVATE";
case CKA_LABEL: return "LABEL";
case CKA_APPLICATION: return "APPLICATION";
case CKA_VALUE: return "VALUE";
case CKA_OBJECT_ID: return "OBJECT_ID";
case CKA_CERTIFICATE_TYPE: return "CERTIFICATE_TYPE";
case CKA_ISSUER: return "ISSUER";
case CKA_SERIAL_NUMBER: return "SERIAL_NUMBER";
case CKA_AC_ISSUER: return "AC_ISSUER";
case CKA_OWNER: return "OWNER";
case CKA_ATTR_TYPES: return "ATTR_TYPES";
case CKA_TRUSTED: return "TRUSTED";
case CKA_KEY_TYPE: return "KEY_TYPE";
case CKA_SUBJECT: return "SUBJECT";
case CKA_ID: return "ID";
case CKA_SENSITIVE: return "SENSITIVE";
case CKA_ENCRYPT: return "ENCRYPT";
case CKA_DECRYPT: return "DECRYPT";
case CKA_WRAP: return "WRAP";
case CKA_WRAP_TEMPLATE: return "WRAP_TEMPLATE";
case CKA_UNWRAP: return "UNWRAP";
case CKA_SIGN: return "SIGN";
case CKA_SIGN_RECOVER: return "SIGN_RECOVER";
case CKA_VERIFY: return "VERIFY";
case CKA_VERIFY_RECOVER: return "VERIFY_RECOVER";
case CKA_DERIVE: return "DERIVE";
case CKA_START_DATE: return "START_DATE";
case CKA_END_DATE: return "END_DATE";
case CKA_MODULUS: return "MODULUS";
case CKA_MODULUS_BITS: return "MODULUS_BITS";
case CKA_PUBLIC_EXPONENT: return "PUBLIC_EXPONENT";
case CKA_PRIVATE_EXPONENT: return "PRIVATE_EXPONENT";
case CKA_PRIME_1: return "PRIME_1";
case CKA_PRIME_2: return "PRIME_2";
case CKA_EXPONENT_1: return "EXPONENT_1";
case CKA_EXPONENT_2: return "EXPONENT_2";
case CKA_COEFFICIENT: return "COEFFICIENT";
case CKA_PRIME: return "PRIME";
case CKA_SUBPRIME: return "SUBPRIME";
case CKA_BASE: return "BASE";
case CKA_PRIME_BITS: return "PRIME_BITS";
case CKA_SUB_PRIME_BITS: return "SUB_PRIME_BITS";
case CKA_VALUE_BITS: return "VALUE_BITS";
case CKA_VALUE_LEN: return "VALUE_LEN";
case CKA_EXTRACTABLE: return "EXTRACTABLE";
case CKA_LOCAL: return "LOCAL";
case CKA_NEVER_EXTRACTABLE: return "NEVER_EXTRACTABLE";
case CKA_ALWAYS_SENSITIVE: return "ALWAYS_SENSITIVE";
case CKA_KEY_GEN_MECHANISM: return "KEY_GEN_MECHANISM";
case CKA_MODIFIABLE: return "MODIFIABLE";
case CKA_EC_PARAMS: return "EC_PARAMS";
case CKA_EC_POINT: return "EC_POINT";
case CKA_SECONDARY_AUTH: return "SECONDARY_AUTH";
case CKA_AUTH_PIN_FLAGS: return "AUTH_PIN_FLAGS";
case CKA_HW_FEATURE_TYPE: return "HW_FEATURE_TYPE";
case CKA_RESET_ON_INIT: return "RESET_ON_INIT";
case CKA_HAS_RESET: return "HAS_RESET";
case CKA_VENDOR_DEFINED: return "VENDOR_DEFINED";
case CKA_ALWAYS_AUTHENTICATE: return "ALWAYS_AUTHENTICATE";
case CKA_WRAP_WITH_TRUSTED: return "WRAP_WITH_TRUSTED";
case CKA_UNWRAP_TEMPLATE: return "UNWRAP_TEMPLATE";
case CKA_HASH_OF_SUBJECT_PUBLIC_KEY: return
"HASH_OF_SUBJECT_PUBLIC_KEY";
case CKA_HASH_OF_ISSUER_PUBLIC_KEY: return "HASH_OF_ISSUER_PUBLIC_KEY";
default:
snprintf(buffer, sizeof(buffer), "unknown(%0x08X)",
attributeId);
return buffer;
}
}
--- NEW FILE CoolKeyPK11.h ---
/*
* CoolKeyPK11.h
* Tokend CoolKey
*/
#ifndef _COOLKEYPK11_H_
#define _COOLKEYPK11_H_
#include "mypkcs11.h"
//#include <Security/SecKey.h>
#include <map>
#include <string>
#define COOLKEY_MAX_SLOTS 20
#define PKCS11_PATH_NAME "/Library/Application
Support/CoolKey/PKCS11/libcoolkeypk11.dylib"
class CoolKeyPK11;
class CoolKeyObject
{
public:
CoolKeyObject(CK_OBJECT_HANDLE aObjHandle, CK_SESSION_HANDLE aSessHandle,CK_LONG
aObjClass,CoolKeyPK11 *aParent);
virtual ~CoolKeyObject() { freeAttributes();};
virtual void loadAttributes() ;
char *CoolKeyObject::attributeName(uint32_t attributeId);
CK_ATTRIBUTE * getAttribute(CK_ATTRIBUTE_TYPE aAttr);
CK_LONG getLongAttribute(CK_ATTRIBUTE_TYPE aAttr);
CK_ULONG getULongAttribute(CK_ATTRIBUTE_TYPE aAttr);
CK_BYTE getByteAttribute(CK_ATTRIBUTE_TYPE aAttr);
CK_BYTE getID();
void getByteDataAttribute(CK_ATTRIBUTE_TYPE aAttr,CK_BYTE *aData, CK_ULONG
*aDataLen);
CK_OBJECT_CLASS getClass() {return mObjClass;}
static void dumpData(CK_BYTE *aData, CK_ULONG aDataLen);
CK_OBJECT_HANDLE getHandle() { return mObjHandle;}
CK_SESSION_HANDLE getSessHandle() { return mSessHandle; }
protected:
void loadAttributes(CK_ATTRIBUTE *aTemplate,int aTemplateSize);
void freeAttributes();
CK_OBJECT_HANDLE mObjHandle;
CK_SESSION_HANDLE mSessHandle;
int mAttributesLoaded;
CK_LONG mObjClass;
std::map< CK_ATTRIBUTE_TYPE, CK_ATTRIBUTE* > mAttributes;
private:
CoolKeyPK11 *mParent;
public:
};
class CoolKeyKeyObject : public CoolKeyObject
{
public:
CoolKeyKeyObject(CK_OBJECT_HANDLE aObjHandle, CK_SESSION_HANDLE aSessionHandle,CK_LONG
aObjClass,CoolKeyPK11 *aParent) ;
CK_ULONG getKeySize();
void getLabel(CK_BYTE *aData, CK_ULONG *aDataLen);
CK_BYTE getSensitive();
CK_BYTE getAlwaysSensitive();
CK_BYTE getKeyEncrypt();
CK_BYTE getKeyDecrypt();
CK_BYTE getKeySign();
CK_BYTE getKeyWrap();
CK_BYTE getKeyExtractable();
CK_BYTE getKeyNeverExtractable();
CK_BYTE getKeyVerify();
CK_BYTE getKeyDerive();
CK_BYTE getKeyUnwrap();
CK_BYTE getKeySignRecover();
CK_BYTE getKeyVerifyRecover();
void loadAttributes();
~CoolKeyKeyObject() {};
};
class CoolKeyCertObject : public CoolKeyObject
{
public:
CoolKeyCertObject(CK_OBJECT_HANDLE aObjHandle, CK_SESSION_HANDLE
aSessionHandle,CK_LONG aObjClass,CoolKeyPK11 *aParent) ;
void loadAttributes();
void getSubject(CK_BYTE *aData, CK_ULONG *aDataLen);
void getIssuer(CK_BYTE *aData, CK_ULONG *aDataLen);
void getSerialNo(CK_BYTE *aData,CK_ULONG *aDataLen);
void getLabel(CK_BYTE *aData, CK_ULONG *aDataLen);
void getData(CK_BYTE *aData, CK_ULONG *aDataLen);
void getPublicKeyHash(CK_BYTE *aData,CK_ULONG *aDataLen);
CK_ULONG getType();
~CoolKeyCertObject() {};
};
class CoolKeyPK11
{
public:
typedef std::map< CK_OBJECT_HANDLE, CoolKeyObject * >::iterator ObjIterator;
CoolKeyPK11():
mPk11Driver(NULL),mEpv(NULL),mInitialized(0),mOurSlotIndex(0),mIsOurToken(0),mCachedPIN("")
{} ;
virtual ~CoolKeyPK11() {};
int loadModule();
int freeModule();
int loginToken(char *aPIN);
void logoutToken();
int isTokenLoggedIn();
int loadObjects();
int freeObjects();
int getIsOurToken() { return mIsOurToken;}
char *getTokenId() {
if(mTokenUid[0] != 0)
return mTokenUid;
else
return NULL;
};
CK_FUNCTION_LIST_PTR getFunctionPointer() { return mEpv;}
int getInitialized() { return mInitialized; }
int verifyCachedPIN(char *aPIN);
//Actual cryto operations
int generateSignature(CoolKeyObject *aObj,CK_BYTE *aData, CK_ULONG aDataLen, CK_BYTE
*aSignature, CK_ULONG *aSignatureLen);
int decryptData(CoolKeyObject *aObj,CK_BYTE *aEncData, CK_ULONG aEncDataLen, CK_BYTE
*aData, CK_ULONG *aDataLen);
protected:
private:
int loadSlotList();
void * mPk11Driver;
CK_FUNCTION_LIST_PTR mEpv;
int mInitialized;
CK_SLOT_ID mSlots[COOLKEY_MAX_SLOTS];
int mOurSlotIndex;
CK_SLOT_INFO mOurSlotInfo;
char mTokenUid[32];
int mIsOurToken;
CK_SESSION_HANDLE mSessHandle;
std::map<CK_OBJECT_HANDLE , CoolKeyObject * > mObjects;
std::string mCachedPIN;
public:
ObjIterator begin() { return ObjIterator(mObjects.begin()); }
ObjIterator end() { return ObjIterator(mObjects.end()); }
};
#endif /* !_COOLKEYPK11_H_ */
--- NEW FILE CoolKeyRecord.cpp ---
/*
* Copyright (c) 2004 Apple Computer, Inc. All Rights Reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source LicenseCoolKey
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
*
http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
* CoolKeyRecord.cpp
* Tokend CoolKey
*/
#include "CoolKeyPK11.h"
#include "CoolKeyRecord.h"
#include "CoolKeyError.h"
#include "CoolKeyToken.h"
//#include "Attribute.h"
#include "MetaAttribute.h"
#include "MetaRecord.h"
#include <security_cdsa_client/aclclient.h>
#include <Security/SecKey.h>
#include <security_utilities/logging.h>
//
// CoolKeyRecord
//
CoolKeyRecord::~CoolKeyRecord()
{
}
Tokend::Attribute *CoolKeyRecord::getDataAttribute(Tokend::TokenContext *tokenContext)
{
Syslog::notice("CoolKeyRecord::getDataAttribute");
CoolKeyObject *obj = (CoolKeyObject *) getCoolKeyObject();
CK_OBJECT_CLASS theClass = 0;
if(obj)
{
theClass = obj->getClass();
}
if(!obj)
return NULL;
CK_BYTE tData[2048];
CK_ULONG dataLen = 2048;
CoolKeyCertObject *theCert = NULL;
switch(theClass)
{
case CKO_CERTIFICATE:
Syslog::notice("getDataAttribute: Found
certificate:-----------------");
theCert = (CoolKeyCertObject *) obj;
if(theCert)
{
theCert->getData((CK_BYTE *)tData,&dataLen);
}
return new Tokend::Attribute((const void *)tData,dataLen);
break;
case CKO_PUBLIC_KEY:
Syslog::notice("getDataAttribute:Found public
key:----------------");
break;
case CKO_PRIVATE_KEY:
Syslog::notice("getDataAttribute:Found private
key:-------------------");
break;
default:
Syslog::notice("getDataAttribute:Found something else:");
break;
};
return NULL;
}
void CoolKeyRecord::getAcl(const char *tag, uint32 &count, AclEntryInfo *&acls)
{
Allocator &alloc = Allocator::standard();
Syslog::notice("CoolKeyRecord::getAcl ----------------");
if (!mAclEntries) {
mAclEntries.allocator(alloc);
// Anyone can read the DB record for this key (which is a reference
// CSSM_KEY)
mAclEntries.add(CssmClient::AclFactory::AnySubject(
mAclEntries.allocator()),
AclAuthorizationSet(CSSM_ACL_AUTHORIZATION_DB_READ, 0));
}
count = mAclEntries.size();
acls = mAclEntries.entries();
Syslog::notice("CoolKeyRecord::getAcl done");
}
/* arch-tag: 9703BFF8-0E73-11D9-ACDD-000A9595DEEE */
--- NEW FILE CoolKeyRecord.h ---
/*
* Copyright (c) 2004 Apple Computer, Inc. All Rights Reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
*
http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
* CoolKeyRecord.h
* TokendMuscle
*/
#ifndef _COOLKEYRECORD_H_
#define _COOLKEYRECORD_H_
#include "Record.h"
#include "CoolKeyPK11.h"
//class CoolKeyObject;
class CoolKeyRecord : public Tokend::Record
{
NOCOPY(CoolKeyRecord)
public:
CoolKeyRecord(CoolKeyObject *aObject) :
mObject(aObject) {}
virtual ~CoolKeyRecord();
CoolKeyObject *getCoolKeyObject() { return mObject; }
virtual Tokend::Attribute *getDataAttribute(Tokend::TokenContext *tokenContext);
virtual void getAcl(const char *tag, uint32 &count,
AclEntryInfo *&aclList);
private:
AutoAclEntryInfoList mAclEntries;
protected:
CoolKeyObject *mObject;
};
#endif /* !_CACRECORD_H_ */
/* arch-tag: 96BC854C-0E73-11D9-B9B1-000A9595DEEE */
--- NEW FILE CoolKeySchema.cpp ---
/*
* Copyright (c) 2004 Apple Computer, Inc. All Rights Reserved.
*
* @APPLE_LICENSE_HEADER_START@
* CoolKey
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
*
http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
* CoolKeySchema.cpp
* Tokend CoolKey
*/
#include "CoolKeySchema.h"
#include "MetaAttribute.h"
#include "MetaRecord.h"
#include <Security/SecCertificate.h>
#include <Security/SecKeychainItem.h>
#include <Security/SecKey.h>
#include <Security/SecKeychainItemPriv.h>
#include <security_utilities/logging.h>
#include <Security/cssmapple.h>
using namespace Tokend;
CoolKeySchema::CoolKeySchema()
{
}
CoolKeySchema::~CoolKeySchema()
{
}
Tokend::Relation *CoolKeySchema::createKeyRelation(CSSM_DB_RECORDTYPE keyType)
{
Relation *rn = createStandardRelation(keyType);
Syslog::info("createKeyRelation coder %p",&mCoolKeyKeyAttributeCoder);
// Set up coders for key records.
MetaRecord &mr = rn->metaRecord();
mr.keyHandleFactory(&mCoolKeyKeyHandleFactory);
mr.attributeCoder(kSecKeyPrintName, &mCoolKeyKeyAttributeCoder);
// Other key valuess
mr.attributeCoder(kSecKeyKeyType, &mCoolKeyKeyAttributeCoder);
mr.attributeCoder(kSecKeyKeySizeInBits, &mCoolKeyKeyAttributeCoder);
mr.attributeCoder(kSecKeyEffectiveKeySize, &mCoolKeyKeyAttributeCoder);
// Key attributes
mr.attributeCoder(kSecKeyExtractable, &mCoolKeyKeyAttributeCoder);
mr.attributeCoder(kSecKeySensitive, &mCoolKeyKeyAttributeCoder);
mr.attributeCoder(kSecKeyModifiable, &mCoolKeyKeyAttributeCoder);
mr.attributeCoder(kSecKeyPrivate, &mCoolKeyKeyAttributeCoder);
mr.attributeCoder(kSecKeyNeverExtractable, &mCoolKeyKeyAttributeCoder);
mr.attributeCoder(kSecKeyAlwaysSensitive, &mCoolKeyKeyAttributeCoder);
// Key usage
mr.attributeCoder(kSecKeyEncrypt, &mCoolKeyKeyAttributeCoder);
mr.attributeCoder(kSecKeyDecrypt, &mCoolKeyKeyAttributeCoder);
mr.attributeCoder(kSecKeyWrap, &mCoolKeyKeyAttributeCoder);
mr.attributeCoder(kSecKeyUnwrap,&mCoolKeyKeyAttributeCoder);
mr.attributeCoder(kSecKeyVerify, &mCoolKeyKeyAttributeCoder);
mr.attributeCoder(kSecKeyDerive, &mCoolKeyKeyAttributeCoder);
mr.attributeCoder(kSecKeySignRecover, &mCoolKeyKeyAttributeCoder);
mr.attributeCoder(kSecKeyVerifyRecover, &mCoolKeyKeyAttributeCoder);
mr.attributeCoder(kSecKeyLabel, &mPublicKeyHashCoder);
mr.attributeCoder(kSecKeySign, &mCoolKeyKeyAttributeCoder);
return rn;
}
Tokend::Relation *CoolKeySchema::createCertRelation(CSSM_DB_RECORDTYPE certType)
{
Relation *rn = createStandardRelation(certType);
// Set up coders for key records.
MetaRecord &mr = rn->metaRecord();
Syslog::info("createCertRelation coder
%p",&mCoolKeyCertAttributeCoder);
// cert attributes
mr.attributeCoder(kSecAlias,&mCoolKeyCertAttributeCoder);
mr.attributeCoder(kSecSubjectItemAttr, &mCoolKeyCertAttributeCoder);
mr.attributeCoder(kSecLabelItemAttr,&mCoolKeyCertAttributeCoder);
mr.attributeCoder(kSecIssuerItemAttr, &mCoolKeyCertAttributeCoder);
mr.attributeCoder(kSecSerialNumberItemAttr, &mCoolKeyCertAttributeCoder);
mr.attributeCoder(kSecPublicKeyHashItemAttr, &mCoolKeyCertAttributeCoder);
mr.attributeCoder(kSecSubjectKeyIdentifierItemAttr, &mCoolKeyCertAttributeCoder);
mr.attributeCoder(kSecCertTypeItemAttr, &mCoolKeyCertAttributeCoder);
mr.attributeCoder(kSecCertEncodingItemAttr, &mCoolKeyCertAttributeCoder);
return rn;
}
void CoolKeySchema::create()
{
Schema::create();
createStandardRelation(CSSM_DL_DB_RECORD_X509_CERTIFICATE);
createKeyRelation(CSSM_DL_DB_RECORD_PRIVATE_KEY);
Relation *rn_publ = createKeyRelation(CSSM_DL_DB_RECORD_PUBLIC_KEY);
// @@@ We need a coder that calculates the public key hash of a public key
rn_publ->metaRecord().attributeCoder(kSecKeyLabel, &mPublicKeyHashCoder);
}
/* arch-tag: 36BF1864-0DBC-11D9-8518-000A9595DEEE */
--- NEW FILE CoolKeySchema.h ---
/*
* Copyright (c) 2004 Apple Computer, Inc. All Rights Reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
*
http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
* CoolKeySchema.h
* TokendMuscle
*/
#ifndef _COOLKEYCHEMA_H_
#define _COOLKEYSCHEMA_H_
#include "Schema.h"
#include "CoolKeyAttributeCoder.h"
#include "CoolKeyHandle.h"
namespace Tokend
{
class Relation;
class MetaRecord;
class AttributeCoder;
}
class CoolKeySchema : public Tokend::Schema
{
NOCOPY(CoolKeySchema)
public:
CoolKeySchema();
virtual ~CoolKeySchema();
virtual void create();
protected:
Tokend::Relation *createKeyRelation(CSSM_DB_RECORDTYPE keyType);
Tokend::Relation *createCertRelation(CSSM_DB_RECORDTYPE certType);
private:
// Coders we need.
CoolKeyDataAttributeCoder mCoolKeyDataAttributeCoder;
CoolKeyCertAttributeCoder mCoolKeyCertAttributeCoder;
CoolKeyKeyAttributeCoder mCoolKeyKeyAttributeCoder;
CoolKeyKeyHandleFactory mCoolKeyKeyHandleFactory;
};
#endif /* !_CACSCHEMA_H_ */
/* arch-tag: 36DB400E-0DBC-11D9-A9F5-000A9595DEEE */
--- NEW FILE CoolKeyToken.cpp ---
/*
* Copyright (c) 2004 Apple Computer, Inc. All Rights Reserved.
* CoolKey
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
*
http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
* CoolKeyToken.cpp
* Tokend CoolKey
*/
#include "CoolKeyToken.h"
#include "Adornment.h"
#include "AttributeCoder.h"
#include "CoolKeyError.h"
#include "CoolKeyRecord.h"
#include "CoolKeySchema.h"
#include <security_cdsa_client/aclclient.h>
#include <security_cdsa_utilities/cssmerrors.h>
#include <security_utilities/logging.h>
#include <security_utilities/refcount.h>
#include <map>
#include <vector>
#include <dlfcn.h>
#include <csignal>
using CssmClient::AclFactory;
static CoolKeyPK11 *coolKeyModule = NULL;
CoolKeyToken::CoolKeyToken() :
mCurrentApplet(NULL),
mPinStatus(1)
{
mTokenContext = this;
}
CoolKeyToken::~CoolKeyToken()
{
Syslog::notice("CoolKeyToken::~CoolKeyToken");
delete mSchema;
}
// Here is where we initialize our PKCS11 module
void CoolKeyToken::initial()
{
Syslog::notice("In CoolKeyToken::initial() . " );
}
bool CoolKeyToken::identify()
{
Syslog::notice("In CoolKeyToken::identify");
return true;
}
void CoolKeyToken::select(const unsigned char *applet)
{
Syslog::debug("In CoolKeyToken::select");
}
uint32_t CoolKeyToken::exchangeAPDU(const unsigned char *apdu, size_t apduLength,
unsigned char *result, size_t &resultLength)
{
return 0;
}
void CoolKeyToken::didDisconnect()
{
Syslog::debug("In CoolKeyToken::didDisconnect");
}
void CoolKeyToken::didEnd()
{
mCurrentApplet = NULL;
}
void CoolKeyToken::changePIN(int pinNum,
const unsigned char *oldPin, size_t oldPinLength,
const unsigned char *newPin, size_t newPinLength)
{
Syslog::debug("In CoolKeyToken::changePIN");
}
uint32_t CoolKeyToken::pinStatus(int pinNum)
{
Syslog::notice("In CoolKeyToken::pinStatus num %d",pinNum);
CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
}
bool CoolKeyToken::isLocked()
{
int result = mCoolKey.isTokenLoggedIn();
mPinStatus = 1 - result;
Syslog::notice("In CoolKeyToken::isLocked mPinStatus %d",mPinStatus);
return mPinStatus;
}
void CoolKeyToken::verifyPIN(int pinNum,
const unsigned char *pin, size_t pinLength)
{
Syslog::notice("In CoolKeyToken::verifyPIN");
int result = 0;
if(mCoolKey.isTokenLoggedIn())
{
result = mCoolKey.verifyCachedPIN((char *) pin);
}
else
{
result = mCoolKey.loginToken((char *) pin);
}
Syslog::notice("Result of loginToken %d",result);
if(result == CKR_OK)
return;
//logout because we failed
mCoolKey.logoutToken();
//any other error complain
CssmError::throwMe(CSSM_ERRCODE_OPERATION_AUTH_DENIED);
}
void CoolKeyToken::unverifyPIN(int pinNum)
{
Syslog::notice("In CoolKeyToken::unverifyPIN");
mPinStatus = 1;
}
uint32_t CoolKeyToken::getData(unsigned char *result, size_t &resultLength)
{
Syslog::notice("In CoolKeyToken::getData");
return NULL;
}
uint32 CoolKeyToken::probe(SecTokendProbeFlags flags,
char tokenUid[TOKEND_MAX_UID])
{
uint32 score = 0; //Tokend::ISO7816Token::probe(flags, tokenUid);
uint32 max_uid = TOKEND_MAX_UID;
const SCARD_READERSTATE &readerState = *(*startupReaderInfo)();
Syslog::notice("TOKEND_MAX_UID %d",max_uid);
Syslog::notice("READER_STATE -> szReader %s", (char *)
readerState.szReader);
Syslog::notice ("READER_STATE -> dwCurrentState
%u",readerState.dwCurrentState);
Syslog::notice ("READER_STATE -> dwEventState
%u",readerState.dwEventState);
Syslog::notice ("READER_STATE -> cbAtr %u",readerState.cbAtr);
Syslog::notice("READER_STATE -> rgbAtr %32x",(char *)
readerState.rgbAtr);
int res = mCoolKey.loadModule();
/* if(res)
res = mCoolKey.loadObjects();
*/
if(!res || ! mCoolKey.getIsOurToken())
{
Syslog::error(" Can't load CoolKey pkcs11 module. ");
return score;
}
if(coolKeyModule == NULL)
coolKeyModule = &mCoolKey;
char *tUid = mCoolKey.getTokenId();
if(tUid)
{
sprintf((char *) tokenUid,"%s",(char *)tUid);
Syslog::notice("tokenUid %s",(char *) tokenUid);
}
score = 299;
signal(SIGTERM, cleanup); // register a SIGTERM handler
return score;
}
void CoolKeyToken::establish(const CSSM_GUID *guid, uint32 subserviceId,
SecTokendEstablishFlags flags, const char *cacheDirectory,
const char *workDirectory, char mdsDirectory[PATH_MAX],
char printName[PATH_MAX])
{
char *mCuid = mCoolKey.getTokenId();
int pathSize = PATH_MAX;
if(mCuid)
{
Syslog::notice("printName size %d", pathSize);
int predictedSize = strlen(mCuid);
if(predictedSize < pathSize)
{
sprintf((char *) printName, (char *) "%s",mCuid);
}
}
Syslog::notice("In CoolKeyToken::establish setting printName to: %s subserviceId:
%d",printName,subserviceId);
int res = mCoolKey.loadObjects();
if(!res)
return;
mSchema = new CoolKeySchema();
mSchema->create();
populate();
}
//
// Authenticate to the token
//
void CoolKeyToken::authenticate(CSSM_DB_ACCESS_TYPE mode, const AccessCredentials *cred)
{
Syslog::notice("In CoolKeyToken::authenticate mode %d cred %p tag %s size
%d",mode, cred,cred->tag(),cred->size());
if (cred) {
if(mode == CSSM_DB_ACCESS_RESET)
{
Syslog::notice("authenticate CSSM_DB_ACCESS_RESET");
return;
}
const TypedList &sample = (*cred)[0];
switch (sample.type()) {
case CSSM_SAMPLE_TYPE_PASSWORD:
case CSSM_SAMPLE_TYPE_PROMPTED_PASSWORD:
case CSSM_SAMPLE_TYPE_PROTECTED_PASSWORD:
{
Syslog::notice("sample type %d",sample.type());
CssmData &pin = sample[1].data();
verifyPIN(1, pin.Data,pin.Length);
}
break;
default:
Syslog::notice("sample type %ld not supported", sample.type());
CssmError::throwMe(CSSM_ERRCODE_ACL_SUBJECT_TYPE_NOT_SUPPORTED);
}
} else
Syslog::notice("authenticate without credentials ignored");
}
//
// Database-level ACLs
//
void CoolKeyToken::getOwner(AclOwnerPrototype &owner)
{
Syslog::notice("In CoolKeyToken::getOwner");
// we don't really know (right now), so claim we're owned by PIN #0
if (!mAclOwner)
{
mAclOwner.allocator(Allocator::standard());
mAclOwner = AclFactory::PinSubject(Allocator::standard(), 0);
}
owner = mAclOwner;
}
void CoolKeyToken::getAcl(const char *tag, uint32 &count, AclEntryInfo *&acls)
{
Syslog::notice("In CoolKeyToken::getAcl.");
Allocator &alloc = Allocator::standard();
// mAclEntries sets the handle of each AclEntryInfo to the
// offset in the array.
if (!mAclEntries) {
mAclEntries.allocator(alloc);
// Anyone can read the attributes and data of any record on this token
// (it's further limited by the object itself).
mAclEntries.add(CssmClient::AclFactory::AnySubject(
mAclEntries.allocator()),
AclAuthorizationSet(CSSM_ACL_AUTHORIZATION_DB_READ, 0));
// We support PIN1 with either a passed in password
// subject or a prompted password subject.
mAclEntries.addPin(AclFactory::PWSubject(alloc),1);
mAclEntries.addPin(AclFactory::PromptPWSubject(alloc,CssmData()), 1);
}
count = mAclEntries.size();
acls = mAclEntries.entries();
}
#pragma mark ---------------- CoolKey Specific --------------
void CoolKeyToken::populate()
{
Syslog::notice("In CoolKeyToken::populate");
Tokend::Relation &certRelation =
mSchema->findRelation(CSSM_DL_DB_RECORD_X509_CERTIFICATE);
Tokend::Relation &privateKeyRelation =
mSchema->findRelation(CSSM_DL_DB_RECORD_PRIVATE_KEY);
Tokend::Relation &publicKeyRelation =
mSchema->findRelation(CSSM_DL_DB_RECORD_PUBLIC_KEY);
std::map<int, CoolKeyObject *> certs;
std::map< CoolKeyObject *, RefPointer<CoolKeyRecord> > keys;
std::map< CoolKeyObject *, RefPointer<CoolKeyRecord> > certRecs;
for(CoolKeyPK11::ObjIterator i = mCoolKey.begin(); i != mCoolKey.end() ; i++)
{
CoolKeyObject *obj =(*i).second;
CK_OBJECT_CLASS oClass;
if(obj)
{
CK_BYTE id = obj->getID();
oClass = obj->getClass();
Syslog::notice("Retrieved object %p class %lu id %d",obj,oClass,id);
CoolKeyRecord *newRecord = new CoolKeyRecord(obj);
RefPointer<CoolKeyRecord> theRecord( newRecord);
if(!theRecord)
continue;
switch(oClass)
{
case CKO_PRIVATE_KEY:
privateKeyRelation.insertRecord(theRecord);
Syslog::notice("Inserting private key record
%p",newRecord);
keys[obj] = theRecord;
break;
case CKO_PUBLIC_KEY:
Syslog::notice("Inserting public key record %p theRefRecord
%p",newRecord,theRecord.get());
publicKeyRelation.insertRecord(theRecord);
keys[obj] = theRecord;
break;
case CKO_CERTIFICATE:
certs[id] = obj;
certRecs[obj] = theRecord;
Syslog::notice("Inserting cert record %p",newRecord);
certRelation.insertRecord(theRecord);
break;
default:
break;
};
}
}
for(CoolKeyPK11::ObjIterator i = mCoolKey.begin(); i != mCoolKey.end() ; i++)
{
CoolKeyObject *obj =(*i).second;
CoolKeyObject *cert = NULL;
CK_OBJECT_CLASS oClass;
if(obj)
{
CK_BYTE id = obj->getID();
oClass = obj->getClass();
switch(oClass)
{
case CKO_PRIVATE_KEY:
case CKO_PUBLIC_KEY:
cert = certs[id];
if(cert)
{
RefPointer<CoolKeyRecord> coolKeyRecRef = keys[obj];
CoolKeyRecord * coolKeyRec = coolKeyRecRef.get();
Syslog::notice("Key %p linked to cert %p",obj,cert);
if(coolKeyRec)
{
Syslog::notice("Found record to create adornment record:
%p",coolKeyRec);
if(certRecs[cert])
{
Tokend::LinkedRecordAdornment * lra = new
Tokend::LinkedRecordAdornment(certRecs[cert]);
Syslog::notice("lra %p",lra);
if(lra)
{
coolKeyRec->setAdornment(mSchema->publicKeyHashCoder().certificateKey(),
lra);
Syslog::notice("certificateKey %p certRecs[cert]
%p",mSchema->publicKeyHashCoder().certificateKey(),certRecs[cert].get());
}
}
}
}
else
Syslog::notice("Key %p not linked to found cert");
break;
default:
break;
};
}
}
}
void CoolKeyToken::cleanup(int aSig)
{
Syslog::notice("We are going away!");
if(coolKeyModule)
{
coolKeyModule->logoutToken();
coolKeyModule->freeModule();
}
}
/* arch-tag: 36F733B4-0DBC-11D9-914C-000A9595DEEE */
--- NEW FILE CoolKeyToken.h ---
/*
* Copyright (c) 2004 Apple Computer, Inc. All Rights Reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this filCoolKeye except in
* compliance with the License. Please obtain a copy of the License at
*
http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
* CoolKeyToken.h
* Tokend CoolKey
*/
#ifndef _COOLKEY_TOKEN_H_
#define _COOLKEY_TOKEN_H_
#include "mypkcs11.h"
#include <Token.h>
#include "TokenContext.h"
#include "CoolKeyPK11.h"
#include <security_utilities/pcsc++.h>
class CoolKeySchema;
#define PKCS11_PATH_NAME "/Library/Application
Support/CoolKey/PKCS11/libcoolkeypk11.dylib"
#define COOLKEY_PRESENT_SCORE 10000000
//
// "The" token
//
class CoolKeyToken : public Tokend::ISO7816Token
{
NOCOPY(CoolKeyToken)
public:
CoolKeyToken() ;
~CoolKeyToken();
virtual void didDisconnect();
virtual void didEnd();
virtual void initial();
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]);
virtual void getOwner(AclOwnerPrototype &owner);
virtual void getAcl(const char *tag, uint32 &count, AclEntryInfo *&acls);
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 void authenticate(CSSM_DB_ACCESS_TYPE mode, const AccessCredentials
*cred);
virtual bool isLocked();
bool identify();
void select(const unsigned char *applet);
uint32_t exchangeAPDU(const unsigned char *apdu, size_t apduLength,
unsigned char *result, size_t &resultLength);
uint32_t getData(unsigned char *result, size_t &resultLength);
CoolKeyPK11 &getPK11Manager() { return mCoolKey; }
protected:
void populate();
CoolKeyPK11 mCoolKey;
public:
const unsigned char *mCurrentApplet;
uint32_t mPinStatus;
// temporary ACL cache hack - to be removed
AutoAclOwnerPrototype mAclOwner;
AutoAclEntryInfoList mAclEntries;
private:
static void cleanup(int aSig);
};
#endif /* !_CACTOKEN_H_ */
/* arch-tag: 3714259E-0DBC-11D9-8D58-000A9595DEEE */
--- NEW FILE Info.plist ---
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>COOLKEY</string>
<key>CFBundleIdentifier</key>
<string>com.apple.tokend.coolkey</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>COOLKEY</string>
<key>CFBundlePackageType</key>
<string>????</string>
<key>CFBundleShortVersionString</key>
<string>1.1.1</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>30557</string>
</dict>
</plist>
--- NEW FILE coolkey.cpp ---
/*
* Copyright (c) 2004 Apple Computer, Inc. All Rights Reserved.
*
* @APPLE_LICENSE_HEADER_START@CoolKey
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
*
http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
* CoolKey.cpp - CoolKey.tokend main program
*/
#include "CoolKeyToken.h"
#include <security_utilities/logging.h>
int main(int argc, const char *argv[])
{
secdebug("CoolKey.tokend", "main starting with %d arguments",
argc);
secdelay("/tmp/delay/CoolKey");
Syslog::notice("argc %d",argc);
for(int i = 0; i < argc ; i++)
{
Syslog::notice("coolkey arg[%d]: %s",i,argv[i]);
}
token = new CoolKeyToken();
return SecTokendMain(argc, argv, token->callbacks(), token->support());
Syslog::notice("CoolKey.tokend exiting.... ");
}
/* arch-tag: 372EB7FE-0DBC-11D9-9A28-000A9595DEEE */
--- NEW FILE dlfcn.h ---
/*
* Copyright (c) 2004-2006 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
*
http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
Based on the dlcompat work done by:
Jorge Acereda <jacereda(a)users.sourceforge.net> &
Peter O'Gorman <ogorman(a)users.sourceforge.net>
*/
#ifndef _DLFCN_H_
#define _DLFCN_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <sys/cdefs.h>
#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)
#include <stdbool.h>
#include <AvailabilityMacros.h>
/*
* Structure filled in by dladdr().
*/
typedef struct dl_info {
const char *dli_fname; /* Pathname of shared object */
void *dli_fbase; /* Base address of shared object */
const char *dli_sname; /* Name of nearest symbol */
void *dli_saddr; /* Address of nearest symbol */
} Dl_info;
extern int dladdr(const void *, Dl_info *);
#endif /* not POSIX */
extern int dlclose(void * __handle);
extern char * dlerror(void);
extern void * dlopen(const char * __path, int __mode);
extern void * dlsym(void * __handle, const char * __symbol);
#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)
extern bool dlopen_preflight(const char* __path)
AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER;
#endif /* not POSIX */
#define RTLD_LAZY 0x1
#define RTLD_NOW 0x2
#define RTLD_LOCAL 0x4
#define RTLD_GLOBAL 0x8
#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)
#define RTLD_NOLOAD 0x10
#define RTLD_NODELETE 0x80
#define RTLD_FIRST 0x100 /* Mac OS X 10.5 and later */
/*
* Special handle arguments for dlsym().
*/
#define RTLD_NEXT ((void *) -1) /* Search subsequent objects. */
#define RTLD_DEFAULT ((void *) -2) /* Use default search algorithm. */
#define RTLD_SELF ((void *) -3) /* Search this and subsequent objects (Mac OS X 10.5 and
later) */
#endif /* not POSIX */
#ifdef __cplusplus
}
#endif
#endif /* _DLFCN_H_ */