Blame SOURCES/coolkey-latest.patch

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