Blame SOURCES/coolkey-latest.patch

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,