|
|
ed074c |
diff -up ./src/coolkey/slot.cpp.coolkey-latest ./src/coolkey/slot.cpp
|
|
|
ed074c |
--- ./src/coolkey/slot.cpp.coolkey-latest 2009-09-11 13:58:24.423487305 -0700
|
|
|
ed074c |
+++ ./src/coolkey/slot.cpp 2009-09-11 14:04:30.813488220 -0700
|
|
|
ed074c |
@@ -203,6 +203,29 @@ SlotList::readerExists(const char *reade
|
|
|
ed074c |
return FALSE;
|
|
|
ed074c |
}
|
|
|
ed074c |
|
|
|
ed074c |
+bool
|
|
|
ed074c |
+SlotList::readerNameExistsInList(const char *readerName,CKYReaderNameList *readerNameList)
|
|
|
ed074c |
+{
|
|
|
ed074c |
+ if( !readerName || !readerNameList) {
|
|
|
ed074c |
+ return FALSE;
|
|
|
ed074c |
+ }
|
|
|
ed074c |
+
|
|
|
ed074c |
+ int i = 0;
|
|
|
ed074c |
+ int readerNameCnt = CKYReaderNameList_GetCount(*readerNameList);
|
|
|
ed074c |
+
|
|
|
ed074c |
+ const char *curReaderName = NULL;
|
|
|
ed074c |
+ for(i=0; i < readerNameCnt; i++) {
|
|
|
ed074c |
+ curReaderName = CKYReaderNameList_GetValue(*readerNameList,i);
|
|
|
ed074c |
+
|
|
|
ed074c |
+ if(!strcmp(curReaderName,readerName)) {
|
|
|
ed074c |
+ return TRUE;
|
|
|
ed074c |
+ }
|
|
|
ed074c |
+
|
|
|
ed074c |
+ }
|
|
|
ed074c |
+
|
|
|
ed074c |
+ return FALSE;
|
|
|
ed074c |
+}
|
|
|
ed074c |
+
|
|
|
ed074c |
/*
|
|
|
ed074c |
* you need to hold the ReaderList Lock before you can update the ReaderList
|
|
|
ed074c |
*/
|
|
|
ed074c |
@@ -256,6 +279,27 @@ SlotList::updateReaderList()
|
|
|
ed074c |
* don't recognize.
|
|
|
ed074c |
*/
|
|
|
ed074c |
|
|
|
ed074c |
+ /* first though, let's check to see if any previously removed readers have
|
|
|
ed074c |
+ * come back from the dead. If the ignored bit has been set, we do not need
|
|
|
ed074c |
+ * it any more.
|
|
|
ed074c |
+ */
|
|
|
ed074c |
+
|
|
|
ed074c |
+ const char *curReaderName = NULL;
|
|
|
ed074c |
+ unsigned long knownState = 0;
|
|
|
ed074c |
+ for(int ri = 0 ; ri < numReaders; ri ++) {
|
|
|
ed074c |
+
|
|
|
ed074c |
+ knownState = CKYReader_GetKnownState(&readerStates[ri]);
|
|
|
ed074c |
+ if( !(knownState & SCARD_STATE_IGNORE)) {
|
|
|
ed074c |
+ continue;
|
|
|
ed074c |
+ }
|
|
|
ed074c |
+
|
|
|
ed074c |
+ curReaderName = CKYReader_GetReaderName(&readerStates[ri]);
|
|
|
ed074c |
+ if(readerNameExistsInList(curReaderName,&readerNames)) {
|
|
|
ed074c |
+ CKYReader_SetKnownState(&readerStates[ri], knownState & ~SCARD_STATE_IGNORE);
|
|
|
ed074c |
+
|
|
|
ed074c |
+ }
|
|
|
ed074c |
+ }
|
|
|
ed074c |
+
|
|
|
ed074c |
const char *newReadersData[MAX_READER_DELTA];
|
|
|
ed074c |
const char **newReaders = &newReadersData[0];
|
|
|
ed074c |
unsigned int newReaderCount = 0;
|
|
|
ed074c |
@@ -528,7 +572,7 @@ SlotList::getSlotList(CK_BBOOL tokenPres
|
|
|
ed074c |
void
|
|
|
ed074c |
Slot::connectToToken()
|
|
|
ed074c |
{
|
|
|
ed074c |
- CKYStatus status;
|
|
|
ed074c |
+ CKYStatus status = CKYSCARDERR;
|
|
|
ed074c |
OSTime time = OSTimeNow();
|
|
|
ed074c |
|
|
|
ed074c |
mCoolkey = 0;
|
|
|
ed074c |
@@ -537,13 +581,31 @@ Slot::connectToToken()
|
|
|
ed074c |
|
|
|
ed074c |
// try to connect to the card
|
|
|
ed074c |
if( ! CKYCardConnection_IsConnected(conn) ) {
|
|
|
ed074c |
- status = CKYCardConnection_Connect(conn, readerName);
|
|
|
ed074c |
- if( status != CKYSUCCESS ) {
|
|
|
ed074c |
- log->log("Unable to connect to token\n");
|
|
|
ed074c |
+ int i = 0;
|
|
|
ed074c |
+ //for cranky readers try again a few more times
|
|
|
ed074c |
+ while( i++ < 5 && status != CKYSUCCESS )
|
|
|
ed074c |
+ {
|
|
|
ed074c |
+ status = CKYCardConnection_Connect(conn, readerName);
|
|
|
ed074c |
+ if( status != CKYSUCCESS &&
|
|
|
ed074c |
+ CKYCardConnection_GetLastError(conn) == SCARD_E_PROTO_MISMATCH )
|
|
|
ed074c |
+ {
|
|
|
ed074c |
+ log->log("Unable to connect to token status %d ConnGetGetLastError %x .\n",status,CKYCardConnection_GetLastError(conn));
|
|
|
ed074c |
+
|
|
|
ed074c |
+ }
|
|
|
ed074c |
+ else
|
|
|
ed074c |
+ {
|
|
|
ed074c |
+ break;
|
|
|
ed074c |
+ }
|
|
|
ed074c |
+ OSSleep(100000);
|
|
|
ed074c |
+ }
|
|
|
ed074c |
+
|
|
|
ed074c |
+ if( status != CKYSUCCESS)
|
|
|
ed074c |
+ {
|
|
|
ed074c |
state = UNKNOWN;
|
|
|
ed074c |
return;
|
|
|
ed074c |
}
|
|
|
ed074c |
}
|
|
|
ed074c |
+
|
|
|
ed074c |
log->log("time connect: Connect Time %d ms\n", OSTimeNow() - time);
|
|
|
ed074c |
if (!slotInfoFound) {
|
|
|
ed074c |
readSlotInfo();
|
|
|
ed074c |
@@ -562,15 +624,10 @@ Slot::connectToToken()
|
|
|
ed074c |
state = CARD_PRESENT;
|
|
|
ed074c |
}
|
|
|
ed074c |
|
|
|
ed074c |
- if ( CKYBuffer_DataIsEqual(&cardATR, ATR, sizeof (ATR)) ||
|
|
|
ed074c |
- CKYBuffer_DataIsEqual(&cardATR, ATR1, sizeof(ATR1)) ||
|
|
|
ed074c |
- CKYBuffer_DataIsEqual(&cardATR, ATR2, sizeof(ATR2)) ) {
|
|
|
ed074c |
-
|
|
|
ed074c |
- if (Params::hasParam("noAppletOK"))
|
|
|
ed074c |
- {
|
|
|
ed074c |
- state |= APPLET_SELECTABLE;
|
|
|
ed074c |
- mCoolkey = 1;
|
|
|
ed074c |
- }
|
|
|
ed074c |
+ if (Params::hasParam("noAppletOK"))
|
|
|
ed074c |
+ {
|
|
|
ed074c |
+ state |= APPLET_SELECTABLE;
|
|
|
ed074c |
+ mCoolkey = 1;
|
|
|
ed074c |
}
|
|
|
ed074c |
|
|
|
ed074c |
/* support CAC card. identify the card based on applets, not the ATRS */
|
|
|
ed074c |
@@ -631,7 +688,7 @@ Slot::connectToToken()
|
|
|
ed074c |
* unfriendly */
|
|
|
ed074c |
isVersion1Key = 0;
|
|
|
ed074c |
needLogin = 1;
|
|
|
ed074c |
-
|
|
|
ed074c |
+ mCoolkey = 0;
|
|
|
ed074c |
return;
|
|
|
ed074c |
}
|
|
|
ed074c |
mCoolkey = 1;
|
|
|
ed074c |
@@ -1077,6 +1134,7 @@ SlotList::waitForSlotEvent(CK_FLAGS flag
|
|
|
ed074c |
}
|
|
|
ed074c |
throw;
|
|
|
ed074c |
}
|
|
|
ed074c |
+
|
|
|
ed074c |
if (myNumReaders != numReaders) {
|
|
|
ed074c |
if (myReaderStates) {
|
|
|
ed074c |
delete [] myReaderStates;
|
|
|
ed074c |
@@ -1103,6 +1161,7 @@ SlotList::waitForSlotEvent(CK_FLAGS flag
|
|
|
ed074c |
}
|
|
|
ed074c |
}
|
|
|
ed074c |
}
|
|
|
ed074c |
+
|
|
|
ed074c |
if (found || (flag == CKF_DONT_BLOCK) || shuttingDown) {
|
|
|
ed074c |
break;
|
|
|
ed074c |
}
|
|
|
ed074c |
@@ -1272,6 +1331,19 @@ class ObjectHandleMatch {
|
|
|
ed074c |
}
|
|
|
ed074c |
};
|
|
|
ed074c |
|
|
|
ed074c |
+class KeyNumMatch {
|
|
|
ed074c |
+ private:
|
|
|
ed074c |
+ CKYByte keyNum;
|
|
|
ed074c |
+ const Slot &slo;;
|
|
|
ed074c |
+ public:
|
|
|
ed074c |
+ KeyNumMatch(CKYByte keyNum_, const Slot &s) : keyNum(keyNum_), slot(s) { }
|
|
|
ed074c |
+ bool operator() (const PKCS11Object& obj) {
|
|
|
ed074c |
+ unsigned long objID = obj.getMuscleObjID();
|
|
|
ed074c |
+ return (slot.getObjectClass(objID) == 'k')
|
|
|
ed074c |
+ && (slot.getObjectIndex(objID) == keyNum);
|
|
|
ed074c |
+ }
|
|
|
ed074c |
+};
|
|
|
ed074c |
+
|
|
|
ed074c |
class ObjectCertCKAIDMatch {
|
|
|
ed074c |
private:
|
|
|
ed074c |
CKYByte cka_id;
|
|
|
ed074c |
@@ -3007,8 +3079,9 @@ Slot::sign(SessionHandleSuffix suffix, C
|
|
|
ed074c |
CK_ULONG ulDataLen, CK_BYTE_PTR pSignature,
|
|
|
ed074c |
CK_ULONG_PTR pulSignatureLen)
|
|
|
ed074c |
{
|
|
|
ed074c |
+ RSASignatureParams params(CryptParams::DEFAULT_KEY_SIZE);
|
|
|
ed074c |
cryptRSA(suffix, pData, ulDataLen, pSignature, pulSignatureLen,
|
|
|
ed074c |
- RSASignatureParams(CryptParams::FIXED_KEY_SIZE));
|
|
|
ed074c |
+ params);
|
|
|
ed074c |
}
|
|
|
ed074c |
|
|
|
ed074c |
void
|
|
|
ed074c |
@@ -3016,14 +3089,15 @@ Slot::decrypt(SessionHandleSuffix suffix
|
|
|
ed074c |
CK_ULONG ulDataLen, CK_BYTE_PTR pDecryptedData,
|
|
|
ed074c |
CK_ULONG_PTR pulDecryptedDataLen)
|
|
|
ed074c |
{
|
|
|
ed074c |
+ RSADecryptParams params(CryptParams::DEFAULT_KEY_SIZE);
|
|
|
ed074c |
cryptRSA(suffix, pData, ulDataLen, pDecryptedData, pulDecryptedDataLen,
|
|
|
ed074c |
- RSADecryptParams(CryptParams::FIXED_KEY_SIZE));
|
|
|
ed074c |
+ params);
|
|
|
ed074c |
}
|
|
|
ed074c |
|
|
|
ed074c |
void
|
|
|
ed074c |
Slot::cryptRSA(SessionHandleSuffix suffix, CK_BYTE_PTR pInput,
|
|
|
ed074c |
CK_ULONG ulInputLen, CK_BYTE_PTR pOutput,
|
|
|
ed074c |
- CK_ULONG_PTR pulOutputLen, const CryptParams& params)
|
|
|
ed074c |
+ CK_ULONG_PTR pulOutputLen, CryptParams& params)
|
|
|
ed074c |
{
|
|
|
ed074c |
refreshTokenState();
|
|
|
ed074c |
SessionIter session = findSession(suffix);
|
|
|
ed074c |
@@ -3041,6 +3115,11 @@ Slot::cryptRSA(SessionHandleSuffix suffi
|
|
|
ed074c |
CKYBuffer *result = &opState.result;
|
|
|
ed074c |
CKYByte keyNum = opState.keyNum;
|
|
|
ed074c |
|
|
|
ed074c |
+ unsigned int keySize = getKeySize(keyNum);
|
|
|
ed074c |
+
|
|
|
ed074c |
+ if(keySize != CryptParams::DEFAULT_KEY_SIZE)
|
|
|
ed074c |
+ params.setKeySize(keySize);
|
|
|
ed074c |
+
|
|
|
ed074c |
if( CKYBuffer_Size(result) == 0 ) {
|
|
|
ed074c |
// we haven't already peformed the decryption, so do it now.
|
|
|
ed074c |
if( pInput == NULL || ulInputLen == 0) {
|
|
|
ed074c |
@@ -3243,3 +3322,36 @@ Slot::generateRandom(SessionHandleSuffix
|
|
|
ed074c |
throw PKCS11Exception(CKR_DEVICE_ERROR);
|
|
|
ed074c |
}
|
|
|
ed074c |
}
|
|
|
ed074c |
+
|
|
|
ed074c |
+#define MAX_NUM_KEYS 8
|
|
|
ed074c |
+unsigned int
|
|
|
ed074c |
+Slot::getKeySize(CKYByte keyNum)
|
|
|
ed074c |
+{
|
|
|
ed074c |
+ unsigned int keySize = CryptParams::DEFAULT_KEY_SIZE;
|
|
|
ed074c |
+ int modSize = 0;
|
|
|
ed074c |
+
|
|
|
ed074c |
+ if(keyNum >= MAX_NUM_KEYS) {
|
|
|
ed074c |
+ return keySize;
|
|
|
ed074c |
+ }
|
|
|
ed074c |
+
|
|
|
ed074c |
+ ObjectConstIter iter;
|
|
|
ed074c |
+ iter = find_if(tokenObjects.begin(), tokenObjects.end(),
|
|
|
ed074c |
+ KeyNumMatch(keyNum,*this));
|
|
|
ed074c |
+
|
|
|
ed074c |
+ if( iter == tokenObjects.end() ) {
|
|
|
ed074c |
+ return keySize;
|
|
|
ed074c |
+ }
|
|
|
ed074c |
+
|
|
|
ed074c |
+ CKYBuffer const *modulus = iter->getAttribute(CKA_MODULUS);
|
|
|
ed074c |
+
|
|
|
ed074c |
+ if(modulus) {
|
|
|
ed074c |
+ modSize = CKYBuffer_Size(modulus);
|
|
|
ed074c |
+ if(CKYBuffer_GetChar(modulus,0) == 0x0) {
|
|
|
ed074c |
+ modSize--;
|
|
|
ed074c |
+ }
|
|
|
ed074c |
+ if(modSize > 0)
|
|
|
ed074c |
+ keySize = modSize * 8;
|
|
|
ed074c |
+ }
|
|
|
ed074c |
+
|
|
|
ed074c |
+ return keySize;
|
|
|
ed074c |
+}
|
|
|
ed074c |
diff -up ./src/coolkey/slot.h.coolkey-latest ./src/coolkey/slot.h
|
|
|
ed074c |
--- ./src/coolkey/slot.h.coolkey-latest 2006-06-09 11:39:11.000000000 -0700
|
|
|
ed074c |
+++ ./src/coolkey/slot.h 2009-09-11 13:58:24.462488099 -0700
|
|
|
ed074c |
@@ -270,10 +270,9 @@ class CryptParams {
|
|
|
ed074c |
protected:
|
|
|
ed074c |
unsigned int getKeySize() const { return keySize; }
|
|
|
ed074c |
public:
|
|
|
ed074c |
- // !!!XXX hack. The right way to get the key size is to get all the
|
|
|
ed074c |
- // key information from the token with MSCListKeys, the same way
|
|
|
ed074c |
- // we get all the object information with MSCListObjects.
|
|
|
ed074c |
- enum { FIXED_KEY_SIZE = 1024 };
|
|
|
ed074c |
+ // set the actual key size obtained from the card
|
|
|
ed074c |
+ void setKeySize(unsigned int newKeySize) { keySize = newKeySize; }
|
|
|
ed074c |
+ enum { DEFAULT_KEY_SIZE = 1024 };
|
|
|
ed074c |
|
|
|
ed074c |
|
|
|
ed074c |
CryptParams(unsigned int keySize_) : keySize(keySize_) { }
|
|
|
ed074c |
@@ -422,7 +421,7 @@ class Slot {
|
|
|
ed074c |
|
|
|
ed074c |
void cryptRSA(SessionHandleSuffix suffix, CK_BYTE_PTR pInput,
|
|
|
ed074c |
CK_ULONG ulInputLen, CK_BYTE_PTR pOutput,
|
|
|
ed074c |
- CK_ULONG_PTR pulOutputLen, const CryptParams& params);
|
|
|
ed074c |
+ CK_ULONG_PTR pulOutputLen, CryptParams& params);
|
|
|
ed074c |
|
|
|
ed074c |
void performRSAOp(CKYBuffer *out, const CKYBuffer *input, CKYByte keyNum,
|
|
|
ed074c |
CKYByte direction);
|
|
|
ed074c |
@@ -460,6 +459,8 @@ class Slot {
|
|
|
ed074c |
return (char )((objectID >> 16) & 0xff) - '0';
|
|
|
ed074c |
}
|
|
|
ed074c |
|
|
|
ed074c |
+ // actually get the size of a key in bits from the card
|
|
|
ed074c |
+ unsigned int getKeySize(CKYByte keyNum);
|
|
|
ed074c |
|
|
|
ed074c |
SessionHandleSuffix openSession(Session::Type type);
|
|
|
ed074c |
void closeSession(SessionHandleSuffix handleSuffix);
|
|
|
ed074c |
@@ -527,6 +528,8 @@ class SlotList {
|
|
|
ed074c |
* has called 'C_GetSlotList' with a NULL parameter */
|
|
|
ed074c |
void updateReaderList();
|
|
|
ed074c |
|
|
|
ed074c |
+ /* see if a reader name exists in a caller provided reader name list. */
|
|
|
ed074c |
+ bool readerNameExistsInList(const char *readerName,CKYReaderNameList *readerNameList );
|
|
|
ed074c |
bool readerExists(const char *readerName, unsigned int *hint = 0);
|
|
|
ed074c |
public:
|
|
|
ed074c |
SlotList(Log *log);
|
|
|
ed074c |
diff -up ./src/libckyapplet/cky_applet.c.coolkey-latest ./src/libckyapplet/cky_applet.c
|
|
|
ed074c |
--- ./src/libckyapplet/cky_applet.c.coolkey-latest 2006-06-09 11:44:17.000000000 -0700
|
|
|
ed074c |
+++ ./src/libckyapplet/cky_applet.c 2009-09-11 13:58:24.464487796 -0700
|
|
|
ed074c |
@@ -134,6 +134,13 @@ CKYAppletFactory_Logout(CKYAPDU *apdu, c
|
|
|
ed074c |
/* Future add WriteObject */
|
|
|
ed074c |
|
|
|
ed074c |
CKYStatus
|
|
|
ed074c |
+CKYAppletFactory_WriteObject(CKYAPDU *apdu, const void *param)
|
|
|
ed074c |
+{
|
|
|
ed074c |
+ const CKYAppletArgWriteObject *wos = (const CKYAppletArgWriteObject *)param;
|
|
|
ed074c |
+ return CKYAPDUFactory_WriteObject(apdu,wos->objectID,wos->offset,wos->size,wos->data);
|
|
|
ed074c |
+}
|
|
|
ed074c |
+
|
|
|
ed074c |
+CKYStatus
|
|
|
ed074c |
CKYAppletFactory_CreateObject(CKYAPDU *apdu, const void *param)
|
|
|
ed074c |
{
|
|
|
ed074c |
const CKYAppletArgCreateObject *cos=(const CKYAppletArgCreateObject *)param;
|
|
|
ed074c |
@@ -192,7 +199,6 @@ CKYAppletFactory_GetLifeCycleV2(CKYAPDU
|
|
|
ed074c |
{
|
|
|
ed074c |
return CKYAPDUFactory_GetLifeCycleV2(apdu);
|
|
|
ed074c |
}
|
|
|
ed074c |
-
|
|
|
ed074c |
CKYStatus
|
|
|
ed074c |
CKYAppletFactory_GetRandom(CKYAPDU *apdu, const void *param)
|
|
|
ed074c |
{
|
|
|
ed074c |
@@ -725,24 +731,48 @@ CKYApplet_ComputeCrypt(CKYCardConnection
|
|
|
ed074c |
CKYAppletArgComputeCrypt ccd;
|
|
|
ed074c |
CKYBuffer empty;
|
|
|
ed074c |
CKYISOStatus status;
|
|
|
ed074c |
+ short dataSize = 0;
|
|
|
ed074c |
int use2APDUs = 0;
|
|
|
ed074c |
+ int use_dl_object = CKYBuffer_Size(data) > 200 ;
|
|
|
ed074c |
|
|
|
ed074c |
CKYBuffer_InitEmpty(&empty);
|
|
|
ed074c |
ccd.keyNumber = keyNumber;
|
|
|
ed074c |
ccd.mode = mode;
|
|
|
ed074c |
ccd.direction = direction;
|
|
|
ed074c |
- ccd.location = CKY_DL_APDU;
|
|
|
ed074c |
+ ccd.location = use_dl_object ? CKY_DL_OBJECT : CKY_DL_APDU;
|
|
|
ed074c |
|
|
|
ed074c |
if (!apduRC)
|
|
|
ed074c |
apduRC = &status;
|
|
|
ed074c |
|
|
|
ed074c |
+ if (use_dl_object) {
|
|
|
ed074c |
+ CKYBuffer sizeBuf;
|
|
|
ed074c |
+
|
|
|
ed074c |
+ CKYBuffer_InitEmpty(&sizeBuf);
|
|
|
ed074c |
+ CKYBuffer_AppendShort(&sizeBuf, CKYBuffer_Size(data));
|
|
|
ed074c |
+
|
|
|
ed074c |
+ ret = CKYApplet_WriteObjectFull(conn, 0xffffffff,
|
|
|
ed074c |
+ 0, CKYBuffer_Size(&sizeBuf), nonce,
|
|
|
ed074c |
+ &sizeBuf, apduRC);
|
|
|
ed074c |
+
|
|
|
ed074c |
+ CKYBuffer_FreeData(&sizeBuf);
|
|
|
ed074c |
+ if( ret != CKYSUCCESS)
|
|
|
ed074c |
+ goto fail;
|
|
|
ed074c |
+
|
|
|
ed074c |
+ ret = CKYApplet_WriteObjectFull(conn, 0xffffffff,
|
|
|
ed074c |
+ 2, CKYBuffer_Size(data), nonce,
|
|
|
ed074c |
+ data, apduRC);
|
|
|
ed074c |
+
|
|
|
ed074c |
+ if(ret != CKYSUCCESS)
|
|
|
ed074c |
+ goto fail;
|
|
|
ed074c |
+ }
|
|
|
ed074c |
+
|
|
|
ed074c |
if (mode == CKY_RSA_NO_PAD) {
|
|
|
ed074c |
- ccd.data = data;
|
|
|
ed074c |
+ ccd.data = use_dl_object ? &empty : data;
|
|
|
ed074c |
ccd.sig = sig;
|
|
|
ed074c |
ret = CKYApplet_HandleAPDU(conn,
|
|
|
ed074c |
CKYAppletFactory_ComputeCryptOneStep, &ccd, nonce,
|
|
|
ed074c |
CKY_SIZE_UNKNOWN, ckyAppletFill_ComputeCryptFinal,
|
|
|
ed074c |
- result, apduRC);
|
|
|
ed074c |
+ use_dl_object ? NULL : result, apduRC);
|
|
|
ed074c |
if (ret == CKYAPDUFAIL && *apduRC == CKYISO_INCORRECT_P2) {
|
|
|
ed074c |
use2APDUs = 1; /* maybe it's an old applet */
|
|
|
ed074c |
}
|
|
|
ed074c |
@@ -759,13 +789,38 @@ CKYApplet_ComputeCrypt(CKYCardConnection
|
|
|
ed074c |
CKYAppletFactory_ComputeCryptInit, &ccd, nonce,
|
|
|
ed074c |
0, CKYAppletFill_Null, NULL, apduRC);
|
|
|
ed074c |
if (ret == CKYSUCCESS) {
|
|
|
ed074c |
- ccd.data = data;
|
|
|
ed074c |
+ ccd.data = use_dl_object ? &empty : data;
|
|
|
ed074c |
ret = CKYApplet_HandleAPDU(conn,
|
|
|
ed074c |
CKYAppletFactory_ComputeCryptFinal, &ccd, nonce,
|
|
|
ed074c |
CKY_SIZE_UNKNOWN, ckyAppletFill_ComputeCryptFinal,
|
|
|
ed074c |
- result, apduRC);
|
|
|
ed074c |
+ use_dl_object ? NULL : result, apduRC);
|
|
|
ed074c |
}
|
|
|
ed074c |
}
|
|
|
ed074c |
+
|
|
|
ed074c |
+ if (use_dl_object && ret == CKYSUCCESS) {
|
|
|
ed074c |
+ CKYBuffer sizeOutBuf;
|
|
|
ed074c |
+ CKYBuffer_InitEmpty(&sizeOutBuf);
|
|
|
ed074c |
+
|
|
|
ed074c |
+ ret = CKYApplet_ReadObjectFull(conn,0xffffffff,
|
|
|
ed074c |
+ 0, 2,
|
|
|
ed074c |
+ nonce,&sizeOutBuf,apduRC);
|
|
|
ed074c |
+
|
|
|
ed074c |
+ if(ret != CKYSUCCESS) {
|
|
|
ed074c |
+ CKYBuffer_FreeData(&sizeOutBuf);
|
|
|
ed074c |
+ goto fail;
|
|
|
ed074c |
+ }
|
|
|
ed074c |
+
|
|
|
ed074c |
+ dataSize = CKYBuffer_GetShort(&sizeOutBuf, 0);
|
|
|
ed074c |
+
|
|
|
ed074c |
+ CKYBuffer_FreeData(&sizeOutBuf);
|
|
|
ed074c |
+
|
|
|
ed074c |
+ ret = CKYApplet_ReadObjectFull(conn,0xffffffff,
|
|
|
ed074c |
+ 2, dataSize,
|
|
|
ed074c |
+ nonce,result,apduRC);
|
|
|
ed074c |
+ }
|
|
|
ed074c |
+
|
|
|
ed074c |
+fail:
|
|
|
ed074c |
+
|
|
|
ed074c |
return ret;
|
|
|
ed074c |
}
|
|
|
ed074c |
|
|
|
ed074c |
@@ -1036,6 +1091,44 @@ CKYApplet_ReadObjectFull(CKYCardConnecti
|
|
|
ed074c |
}
|
|
|
ed074c |
|
|
|
ed074c |
/*
|
|
|
ed074c |
+ * Write Object
|
|
|
ed074c |
+ * This makes multiple APDU calls to write the entire object.
|
|
|
ed074c |
+ *
|
|
|
ed074c |
+ */
|
|
|
ed074c |
+
|
|
|
ed074c |
+CKYStatus
|
|
|
ed074c |
+CKYApplet_WriteObjectFull(CKYCardConnection *conn, unsigned long objectID,
|
|
|
ed074c |
+ CKYOffset offset, CKYSize size, const CKYBuffer *nonce,
|
|
|
ed074c |
+ const CKYBuffer *data, CKYISOStatus *apduRC)
|
|
|
ed074c |
+{
|
|
|
ed074c |
+
|
|
|
ed074c |
+ CKYBuffer chunk;
|
|
|
ed074c |
+ CKYOffset srcOffset = 0;
|
|
|
ed074c |
+ CKYAppletArgWriteObject wod;
|
|
|
ed074c |
+ CKYStatus ret = CKYSUCCESS;
|
|
|
ed074c |
+
|
|
|
ed074c |
+ wod.objectID = objectID;
|
|
|
ed074c |
+ wod.offset = offset;
|
|
|
ed074c |
+ do {
|
|
|
ed074c |
+ wod.size = (CKYByte) MIN(size, 220);
|
|
|
ed074c |
+ ret = CKYBuffer_InitFromBuffer(&chunk, data,
|
|
|
ed074c |
+ srcOffset, wod.size);
|
|
|
ed074c |
+ if(ret == CKYSUCCESS) {
|
|
|
ed074c |
+ wod.data = &chunk;
|
|
|
ed074c |
+ ret = CKYApplet_HandleAPDU(conn, CKYAppletFactory_WriteObject, &wod,
|
|
|
ed074c |
+ nonce, 0, CKYAppletFill_Null, NULL, apduRC);
|
|
|
ed074c |
+ size -= wod.size;
|
|
|
ed074c |
+ wod.offset += wod.size;
|
|
|
ed074c |
+ srcOffset += wod.size;
|
|
|
ed074c |
+ CKYBuffer_FreeData(&chunk);
|
|
|
ed074c |
+ }
|
|
|
ed074c |
+
|
|
|
ed074c |
+ } while ((size > 0) && (ret == CKYSUCCESS));
|
|
|
ed074c |
+
|
|
|
ed074c |
+ return ret;
|
|
|
ed074c |
+}
|
|
|
ed074c |
+
|
|
|
ed074c |
+/*
|
|
|
ed074c |
* List Object cluster
|
|
|
ed074c |
*/
|
|
|
ed074c |
static CKYStatus
|
|
|
ed074c |
diff -up ./src/libckyapplet/cky_applet.h.coolkey-latest ./src/libckyapplet/cky_applet.h
|
|
|
ed074c |
--- ./src/libckyapplet/cky_applet.h.coolkey-latest 2006-06-09 11:44:17.000000000 -0700
|
|
|
ed074c |
+++ ./src/libckyapplet/cky_applet.h 2009-09-11 13:58:24.466487772 -0700
|
|
|
ed074c |
@@ -192,6 +192,14 @@ typedef struct _CKYAppletArgReadObject {
|
|
|
ed074c |
CKYByte size;
|
|
|
ed074c |
} CKYAppletArgReadObject;
|
|
|
ed074c |
|
|
|
ed074c |
+typedef struct _CKYAppletArgWriteObject {
|
|
|
ed074c |
+ unsigned long objectID;
|
|
|
ed074c |
+ CKYOffset offset;
|
|
|
ed074c |
+ CKYByte size;
|
|
|
ed074c |
+ CKYBuffer *data;
|
|
|
ed074c |
+
|
|
|
ed074c |
+} CKYAppletArgWriteObject;
|
|
|
ed074c |
+
|
|
|
ed074c |
typedef struct _CKYAppletArgComputeCrypt {
|
|
|
ed074c |
CKYByte keyNumber;
|
|
|
ed074c |
CKYByte mode;
|
|
|
ed074c |
@@ -250,6 +258,8 @@ CKYStatus CKYAppletFactory_ListPINs(CKYA
|
|
|
ed074c |
/* param == CKYByte * (pointer to pinNumber) */
|
|
|
ed074c |
CKYStatus CKYAppletFactory_Logout(CKYAPDU *apdu, const void *param);
|
|
|
ed074c |
/* Future add WriteObject */
|
|
|
ed074c |
+/* parm == CKYAppletArgWriteObject */
|
|
|
ed074c |
+CKYStatus CKYAppletFactory_WriteObject(CKYAPDU *apdu, const void *param);
|
|
|
ed074c |
/* param == CKYAppletArgCreateObject */
|
|
|
ed074c |
CKYStatus CKYAppletFactory_CreateObject(CKYAPDU *apdu, const void *param);
|
|
|
ed074c |
/* param == CKYAppletArgDeleteObject */
|
|
|
ed074c |
@@ -482,6 +492,17 @@ CKYStatus CKYApplet_ReadObjectAppend(CKY
|
|
|
ed074c |
CKYStatus CKYApplet_ReadObjectFull(CKYCardConnection *conn,
|
|
|
ed074c |
unsigned long objectID, CKYOffset offset, CKYSize size,
|
|
|
ed074c |
const CKYBuffer *nonce, CKYBuffer *data, CKYISOStatus *apduRC);
|
|
|
ed074c |
+/*
|
|
|
ed074c |
+ * There is 1 write command:
|
|
|
ed074c |
+ * CKYApplet_WriteObjectFull can write an entire data object. It makes multiple
|
|
|
ed074c |
+ * apdu calls in order to write the full amount into the buffer. The buffer is
|
|
|
ed074c |
+ * overwritten.
|
|
|
ed074c |
+*/
|
|
|
ed074c |
+
|
|
|
ed074c |
+CKYStatus CKYApplet_WriteObjectFull(CKYCardConnection *conn,
|
|
|
ed074c |
+ unsigned long objectID, CKYOffset offset, CKYSize size,
|
|
|
ed074c |
+ const CKYBuffer *nonce, const CKYBuffer *data, CKYISOStatus *apduRC);
|
|
|
ed074c |
+
|
|
|
ed074c |
CKYStatus CKYApplet_ListObjects(CKYCardConnection *conn, CKYByte seq,
|
|
|
ed074c |
CKYAppletRespListObjects *lop, CKYISOStatus *apduRC);
|
|
|
ed074c |
CKYStatus CKYApplet_GetStatus(CKYCardConnection *conn,
|
|
|
ed074c |
diff -up ./src/libckyapplet/cky_card.c.coolkey-latest ./src/libckyapplet/cky_card.c
|
|
|
ed074c |
--- ./src/libckyapplet/cky_card.c.coolkey-latest 2006-06-09 11:44:17.000000000 -0700
|
|
|
ed074c |
+++ ./src/libckyapplet/cky_card.c 2009-09-11 13:58:24.468487469 -0700
|
|
|
ed074c |
@@ -129,6 +129,7 @@ typedef struct _SCard {
|
|
|
ed074c |
SCardGetStatusChangeFn SCardGetStatusChange;
|
|
|
ed074c |
SCardCancelFn SCardCancel;
|
|
|
ed074c |
SCARD_IO_REQUEST *SCARD_PCI_T0_;
|
|
|
ed074c |
+ SCARD_IO_REQUEST *SCARD_PCI_T1_;
|
|
|
ed074c |
} SCard;
|
|
|
ed074c |
|
|
|
ed074c |
#define GET_ADDRESS(library, scard, name) \
|
|
|
ed074c |
@@ -195,6 +196,12 @@ ckySCard_Init(void)
|
|
|
ed074c |
if( status != CKYSUCCESS ) {
|
|
|
ed074c |
goto fail;
|
|
|
ed074c |
}
|
|
|
ed074c |
+
|
|
|
ed074c |
+ status = ckyShLibrary_getAddress( library,
|
|
|
ed074c |
+ (void**) &scard->SCARD_PCI_T1_, MAKE_DLL_SYMBOL(g_rgSCardT1Pci));
|
|
|
ed074c |
+ if( status != CKYSUCCESS ) {
|
|
|
ed074c |
+ goto fail;
|
|
|
ed074c |
+ }
|
|
|
ed074c |
return scard;
|
|
|
ed074c |
|
|
|
ed074c |
fail:
|
|
|
ed074c |
@@ -884,6 +891,7 @@ struct _CKYCardConnection {
|
|
|
ed074c |
SCARDHANDLE cardHandle;
|
|
|
ed074c |
unsigned long lastError;
|
|
|
ed074c |
CKYBool inTransaction;
|
|
|
ed074c |
+ unsigned long protocol;
|
|
|
ed074c |
};
|
|
|
ed074c |
|
|
|
ed074c |
static void
|
|
|
ed074c |
@@ -894,6 +902,7 @@ ckyCardConnection_init(CKYCardConnection
|
|
|
ed074c |
conn->cardHandle = 0;
|
|
|
ed074c |
conn->lastError = 0;
|
|
|
ed074c |
conn->inTransaction = 0;
|
|
|
ed074c |
+ conn->protocol = SCARD_PROTOCOL_T0;
|
|
|
ed074c |
}
|
|
|
ed074c |
|
|
|
ed074c |
CKYCardConnection *
|
|
|
ed074c |
@@ -934,14 +943,13 @@ CKYCardConnection_Connect(CKYCardConnect
|
|
|
ed074c |
{
|
|
|
ed074c |
CKYStatus ret;
|
|
|
ed074c |
unsigned long rv;
|
|
|
ed074c |
- unsigned long protocol;
|
|
|
ed074c |
|
|
|
ed074c |
ret = CKYCardConnection_Disconnect(conn);
|
|
|
ed074c |
if (ret != CKYSUCCESS) {
|
|
|
ed074c |
return ret;
|
|
|
ed074c |
}
|
|
|
ed074c |
rv = conn->scard->SCardConnect( conn->ctx->context, readerName,
|
|
|
ed074c |
- SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0, &conn->cardHandle, &protocol);
|
|
|
ed074c |
+ SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &conn->cardHandle, &conn->protocol);
|
|
|
ed074c |
if (rv != SCARD_S_SUCCESS) {
|
|
|
ed074c |
conn->lastError = rv;
|
|
|
ed074c |
return CKYSCARDERR;
|
|
|
ed074c |
@@ -978,7 +986,7 @@ ckyCardConnection_reconnectRaw(CKYCardCo
|
|
|
ed074c |
unsigned long protocol;
|
|
|
ed074c |
|
|
|
ed074c |
rv = conn->scard->SCardReconnect(conn->cardHandle,
|
|
|
ed074c |
- SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0, init, &protocol);
|
|
|
ed074c |
+ SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1 , init, &protocol);
|
|
|
ed074c |
if (rv != SCARD_S_SUCCESS) {
|
|
|
ed074c |
conn->lastError = rv;
|
|
|
ed074c |
return CKYSCARDERR;
|
|
|
ed074c |
@@ -1039,10 +1047,17 @@ CKYCardConnection_TransmitAPDU(CKYCardCo
|
|
|
ed074c |
return ret;
|
|
|
ed074c |
}
|
|
|
ed074c |
|
|
|
ed074c |
- rv = conn->scard->SCardTransmit(conn->cardHandle,
|
|
|
ed074c |
- conn->scard->SCARD_PCI_T0_,
|
|
|
ed074c |
- CKYBuffer_Data(&apdu->apduBuf), CKYBuffer_Size(&apdu->apduBuf),
|
|
|
ed074c |
- NULL, response->data, &response->len);
|
|
|
ed074c |
+ if( conn->protocol == SCARD_PROTOCOL_T0 ) {
|
|
|
ed074c |
+ rv = conn->scard->SCardTransmit(conn->cardHandle,
|
|
|
ed074c |
+ conn->scard->SCARD_PCI_T0_,
|
|
|
ed074c |
+ CKYBuffer_Data(&apdu->apduBuf), CKYBuffer_Size(&apdu->apduBuf),
|
|
|
ed074c |
+ NULL, response->data, &response->len);
|
|
|
ed074c |
+ } else {
|
|
|
ed074c |
+ rv = conn->scard->SCardTransmit(conn->cardHandle,
|
|
|
ed074c |
+ conn->scard->SCARD_PCI_T1_,
|
|
|
ed074c |
+ CKYBuffer_Data(&apdu->apduBuf), CKYBuffer_Size(&apdu->apduBuf),
|
|
|
ed074c |
+ NULL, response->data, &response->len);
|
|
|
ed074c |
+ }
|
|
|
ed074c |
|
|
|
ed074c |
if (rv != SCARD_S_SUCCESS) {
|
|
|
ed074c |
conn->lastError =rv;
|
|
|
ed074c |
diff -up ./src/libckyapplet/cky_factory.c.coolkey-latest ./src/libckyapplet/cky_factory.c
|
|
|
ed074c |
--- ./src/libckyapplet/cky_factory.c.coolkey-latest 2006-06-09 11:44:17.000000000 -0700
|
|
|
ed074c |
+++ ./src/libckyapplet/cky_factory.c 2009-09-11 13:58:24.470495267 -0700
|
|
|
ed074c |
@@ -190,8 +190,11 @@ CKYAPDUFactory_ComputeCryptOneStep(CKYAP
|
|
|
ed074c |
CKYSize len;
|
|
|
ed074c |
CKYBuffer buf;
|
|
|
ed074c |
|
|
|
ed074c |
- if (!idata || !(len = CKYBuffer_Size(idata)) || location != CKY_DL_APDU)
|
|
|
ed074c |
- return ret;
|
|
|
ed074c |
+ if (!idata)
|
|
|
ed074c |
+ return ret;
|
|
|
ed074c |
+
|
|
|
ed074c |
+ if (!(len = CKYBuffer_Size(idata)) && location != CKY_DL_OBJECT)
|
|
|
ed074c |
+ return ret;
|
|
|
ed074c |
|
|
|
ed074c |
CKYAPDU_SetCLA(apdu, CKY_CLASS_COOLKEY);
|
|
|
ed074c |
CKYAPDU_SetINS(apdu, CKY_INS_COMPUTE_CRYPT);
|
|
|
ed074c |
@@ -314,8 +317,6 @@ CKYAPDUFactory_Logout(CKYAPDU *apdu, CKY
|
|
|
ed074c |
return CKYSUCCESS;
|
|
|
ed074c |
}
|
|
|
ed074c |
|
|
|
ed074c |
-/* Future add WriteObject */
|
|
|
ed074c |
-
|
|
|
ed074c |
CKYStatus
|
|
|
ed074c |
CKYAPDUFactory_CreateObject(CKYAPDU *apdu, unsigned long objectID, CKYSize size,
|
|
|
ed074c |
unsigned short readACL, unsigned short writeACL, unsigned short deleteACL)
|
|
|
ed074c |
@@ -419,6 +420,58 @@ fail:
|
|
|
ed074c |
}
|
|
|
ed074c |
|
|
|
ed074c |
CKYStatus
|
|
|
ed074c |
+CKYAPDUFactory_WriteObject(CKYAPDU *apdu, unsigned long objectID,
|
|
|
ed074c |
+ CKYOffset offset,CKYSize size,CKYBuffer *data)
|
|
|
ed074c |
+{
|
|
|
ed074c |
+ CKYBuffer buf;
|
|
|
ed074c |
+ CKYStatus ret = CKYSUCCESS;
|
|
|
ed074c |
+ unsigned short dataSize = 0;
|
|
|
ed074c |
+
|
|
|
ed074c |
+ CKYAPDU_SetCLA(apdu, CKY_CLASS_COOLKEY);
|
|
|
ed074c |
+ CKYAPDU_SetINS(apdu, CKY_INS_WRITE_OBJ);
|
|
|
ed074c |
+ CKYAPDU_SetP1(apdu, 0x00);
|
|
|
ed074c |
+ CKYAPDU_SetP2(apdu, 0x00);
|
|
|
ed074c |
+ CKYBuffer_InitEmpty(&buf;;
|
|
|
ed074c |
+
|
|
|
ed074c |
+ dataSize = (unsigned short) CKYBuffer_Size(data);
|
|
|
ed074c |
+
|
|
|
ed074c |
+ if(!dataSize) {
|
|
|
ed074c |
+ ret = CKYINVALIDARGS;
|
|
|
ed074c |
+ goto fail;
|
|
|
ed074c |
+ }
|
|
|
ed074c |
+
|
|
|
ed074c |
+ ret = CKYBuffer_AppendLong(&buf,objectID);
|
|
|
ed074c |
+ if (ret != CKYSUCCESS) {
|
|
|
ed074c |
+ goto fail;
|
|
|
ed074c |
+ }
|
|
|
ed074c |
+ ret = CKYBuffer_AppendLong(&buf,offset);
|
|
|
ed074c |
+ if (ret != CKYSUCCESS) {
|
|
|
ed074c |
+ goto fail;
|
|
|
ed074c |
+ }
|
|
|
ed074c |
+ ret = CKYBuffer_AppendChar(&buf, size);
|
|
|
ed074c |
+ if (ret != CKYSUCCESS) {
|
|
|
ed074c |
+ goto fail;
|
|
|
ed074c |
+ }
|
|
|
ed074c |
+
|
|
|
ed074c |
+ ret = CKYAPDU_SetSendDataBuffer(apdu,&buf;;
|
|
|
ed074c |
+
|
|
|
ed074c |
+ if (ret != CKYSUCCESS) {
|
|
|
ed074c |
+ goto fail;
|
|
|
ed074c |
+ }
|
|
|
ed074c |
+
|
|
|
ed074c |
+ ret = CKYAPDU_AppendSendDataBuffer(apdu, data);
|
|
|
ed074c |
+
|
|
|
ed074c |
+ if (ret != CKYSUCCESS) {
|
|
|
ed074c |
+ goto fail;
|
|
|
ed074c |
+ }
|
|
|
ed074c |
+
|
|
|
ed074c |
+fail:
|
|
|
ed074c |
+ CKYBuffer_FreeData(&buf;;
|
|
|
ed074c |
+ return ret;
|
|
|
ed074c |
+
|
|
|
ed074c |
+}
|
|
|
ed074c |
+
|
|
|
ed074c |
+CKYStatus
|
|
|
ed074c |
CKYAPDUFactory_ListObjects(CKYAPDU *apdu, CKYByte sequence)
|
|
|
ed074c |
{
|
|
|
ed074c |
CKYAPDU_SetCLA(apdu, CKY_CLASS_COOLKEY);
|
|
|
ed074c |
diff -up ./src/libckyapplet/cky_factory.h.coolkey-latest ./src/libckyapplet/cky_factory.h
|
|
|
ed074c |
--- ./src/libckyapplet/cky_factory.h.coolkey-latest 2006-06-09 11:44:17.000000000 -0700
|
|
|
ed074c |
+++ ./src/libckyapplet/cky_factory.h 2009-09-11 13:58:24.472487421 -0700
|
|
|
ed074c |
@@ -190,7 +190,8 @@ CKYStatus CKYAPDUFactory_ChangePIN(CKYAP
|
|
|
ed074c |
const char *oldPin, const char *newPin);
|
|
|
ed074c |
CKYStatus CKYAPDUFactory_ListPINs(CKYAPDU *apdu);
|
|
|
ed074c |
CKYStatus CKYAPDUFactory_Logout(CKYAPDU *apdu, CKYByte pinNumber);
|
|
|
ed074c |
-
|
|
|
ed074c |
+CKYStatus CKYAPDUFactory_WriteObject(CKYAPDU *apdu, unsigned long objectID,
|
|
|
ed074c |
+ CKYOffset offset,CKYSize size,CKYBuffer *data);
|
|
|
ed074c |
/* Future add WriteObject */
|
|
|
ed074c |
CKYStatus CKYAPDUFactory_CreateObject(CKYAPDU *apdu, unsigned long objectID,
|
|
|
ed074c |
CKYSize size, unsigned short readACL, unsigned short writeACL,
|