[389-commits] esc/mac/Tokend-35209/CoolKey CoolKeyAttributeCoder.cpp, NONE, 1.1 CoolKeyAttributeCoder.h, NONE, 1.1 CoolKeyError.cpp, NONE, 1.1 CoolKeyError.h, NONE, 1.1 CoolKeyHandle.cpp, NONE, 1.1 CoolKeyHandle.h, NONE, 1.1 CoolKeyPK11.cpp, NONE, 1.1 CoolKeyPK11.h, NONE, 1.1 CoolKeyRecord.cpp, NONE, 1.1 CoolKeyRecord.h, NONE, 1.1 CoolKeySchema.cpp, NONE, 1.1 CoolKeySchema.h, NONE, 1.1 CoolKeyToken.cpp, NONE, 1.1 CoolKeyToken.h, NONE, 1.1 Info.plist, NONE, 1.1 coolkey.cpp, NONE, 1.1 dlfcn.h, NONE, 1.1

Jack Magne jmagne at fedoraproject.org
Tue Mar 16 23:55:35 UTC 2010


Author: jmagne

Update of /cvs/dirsec/esc/mac/Tokend-35209/CoolKey
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv16499/CoolKey

Added Files:
	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 at 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 at users.sourceforge.net> &
		Peter O'Gorman <ogorman at 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_ */



More information about the 389-commits mailing list