Author: rrelyea
Update of /cvs/dirsec/coolkey/src/libckyapplet
In directory cvs01.phx2.fedoraproject.org:/tmp/cvs-serv6855/src/libckyapplet
Modified Files:
cky_applet.c cky_applet.h cky_base.c cky_base.h cky_factory.c
cky_factory.h
Log Message:
New CAC support
Index: cky_applet.c
===================================================================
RCS file: /cvs/dirsec/coolkey/src/libckyapplet/cky_applet.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- cky_applet.c 19 Feb 2009 02:03:08 -0000 1.2
+++ cky_applet.c 8 Sep 2010 20:14:41 -0000 1.3
@@ -41,7 +41,13 @@
CKYStatus
CKYAppletFactory_SelectFile(CKYAPDU *apdu, const void *param)
{
- return CKYAPDUFactory_SelectFile(apdu,(const CKYBuffer *)param);
+ return CKYAPDUFactory_SelectFile(apdu, 4, 0, (const CKYBuffer *)param);
+}
+
+CKYStatus
+CACAppletFactory_SelectFile(CKYAPDU *apdu, const void *param)
+{
+ return CKYAPDUFactory_SelectFile(apdu, 2, 12, (const CKYBuffer *)param);
}
CKYStatus
@@ -225,10 +231,17 @@
}
CKYStatus
-CACAppletFactory_SignDecrypt(CKYAPDU *apdu, const void *param)
+CACAppletFactory_SignDecryptStep(CKYAPDU *apdu, const void *param)
+{
+ const CKYBuffer *buf=(CKYBuffer *)param;
+ return CACAPDUFactory_SignDecrypt(apdu, CAC_P1_STEP, buf);
+}
+
+CKYStatus
+CACAppletFactory_SignDecryptFinal(CKYAPDU *apdu, const void *param)
{
const CKYBuffer *buf=(CKYBuffer *)param;
- return CACAPDUFactory_SignDecrypt(apdu, buf);
+ return CACAPDUFactory_SignDecrypt(apdu, CAC_P1_FINAL, buf);
}
CKYStatus
@@ -246,6 +259,13 @@
}
CKYStatus
+CACAppletFactory_ReadFile(CKYAPDU *apdu, const void *param)
+{
+ const CACAppletArgReadFile *rfs = (const CACAppletArgReadFile *)param;
+ return CACAPDUFactory_ReadFile(apdu, rfs->offset, rfs->type, rfs->count);
+}
+
+CKYStatus
CACAppletFactory_GetProperties(CKYAPDU *apdu, const void *param)
{
return CACAPDUFactory_GetProperties(apdu);
@@ -457,7 +477,7 @@
CKYISOStatus *apduRC)
{
return CKYApplet_HandleAPDU(conn, CKYAppletFactory_SelectFile, AID, NULL,
- 0, CKYAppletFill_Null, NULL, apduRC);
+ CKY_SIZE_UNKNOWN, CKYAppletFill_Null, NULL, apduRC);
}
static CKYByte coolkeyid[] = {0x62, 0x76, 0x01, 0xff, 0x00, 0x00, 0x00 };
@@ -477,22 +497,23 @@
return ret;
}
-static CKYByte CACPKIid[] = {0xa0, 0x00, 0x00, 0x00, 0x79, 0x01, 0x00 };
+static CKYByte CACPKIid[] = { 0xa0, 0x00, 0x00, 0x00, 0x79, 0x01 };
/*
* Select the CoolKey applet. Must happen after we start a transaction and
* before we issue any applet specific command.
*/
CKYStatus
-CACApplet_SelectPKI(CKYCardConnection *conn, CKYByte instance,
- CKYISOStatus *apduRC)
+CACApplet_SelectPKI(CKYCardConnection *conn, CKYBuffer *cacAID,
+ CKYByte instance, CKYISOStatus *apduRC)
{
CKYStatus ret;
- CKYBuffer CACPKIAID;
- CKYBuffer_InitFromData(&CACPKIAID, CACPKIid, sizeof(CACPKIid));
- CKYBuffer_SetChar(&CACPKIAID, 6, instance);
- ret = CKYApplet_HandleAPDU(conn, CKYAppletFactory_SelectFile, &CACPKIAID,
+ CKYBuffer_AppendData(cacAID, CACPKIid, sizeof(CACPKIid));
+ CKYBuffer_AppendChar(cacAID, instance);
+ ret = CKYApplet_HandleAPDU(conn, CKYAppletFactory_SelectFile, cacAID,
NULL, CKY_SIZE_UNKNOWN, CKYAppletFill_Null, NULL, apduRC);
- CKYBuffer_FreeData(&CACPKIAID);
+ if (ret != CKYSUCCESS) {
+ CKYBuffer_Resize(cacAID, 0);
+ }
return ret;
}
@@ -515,11 +536,38 @@
CKYBuffer CAC_CM_AID;
CKYBuffer_InitFromData(&CAC_CM_AID, cacmgrid, sizeof(cacmgrid));
ret = CKYApplet_HandleAPDU(conn, CKYAppletFactory_SelectFile, &CAC_CM_AID,
- NULL, 0, CKYAppletFill_Null, NULL, apduRC);
+ NULL, CKY_SIZE_UNKNOWN, CKYAppletFill_Null, NULL, apduRC);
CKYBuffer_FreeData(&CAC_CM_AID);
return ret;
}
+static CKYByte cacCCCid[] = {0xa0, 0x00, 0x00, 0x01, 0x16, 0xdb, 0x00 };
+CKYStatus
+CACApplet_SelectCCC(CKYCardConnection *conn, CKYISOStatus *apduRC)
+{
+ CKYStatus ret;
+ CKYBuffer CAC_CM_AID;
+ CKYBuffer_InitFromData(&CAC_CM_AID, cacCCCid, sizeof(cacCCCid));
+ ret = CKYApplet_HandleAPDU(conn, CKYAppletFactory_SelectFile, &CAC_CM_AID,
+ NULL, CKY_SIZE_UNKNOWN, CKYAppletFill_Null, NULL, apduRC);
+ CKYBuffer_FreeData(&CAC_CM_AID);
+ return ret;
+}
+
+CKYStatus
+CACApplet_SelectFile(CKYCardConnection *conn, unsigned short ef,
+ CKYISOStatus *apduRC)
+{
+ CKYStatus ret;
+ CKYBuffer efBuf;
+ CKYBuffer_InitEmpty(&efBuf);
+ CKYBuffer_AppendShortLE(&efBuf, ef);
+ ret = CKYApplet_HandleAPDU(conn, CACAppletFactory_SelectFile, &efBuf,
+ NULL, CKY_SIZE_UNKNOWN, CKYAppletFill_Null, NULL, apduRC);
+ CKYBuffer_FreeData(&efBuf);
+ return ret;
+}
+
/*
* GetCPLC cluster -- must be called with CM selected
*/
@@ -673,8 +721,8 @@
ccd.keyNumber = keyNumber;
ccd.location = location;
ccd.data = data;
- return CKYApplet_HandleAPDU(conn, CKYAppletFactory_ComputeCryptProcess, &ccd,
- nonce, 0, CKYAppletFill_Null, NULL, apduRC);
+ return CKYApplet_HandleAPDU(conn, CKYAppletFactory_ComputeCryptProcess,
+ &ccd, nonce, 0, CKYAppletFill_Null, NULL, apduRC);
}
/* computeCrypt returns data in the form :
@@ -832,11 +880,39 @@
CKYBuffer *result, CKYISOStatus *apduRC)
{
CKYStatus ret;
-
- ret = CKYApplet_HandleAPDU(conn,
- CACAppletFactory_SignDecrypt, data, NULL,
- CKYBuffer_Size(data), CKYAppletFill_ReplaceBuffer,
+ CKYSize dataSize = CKYBuffer_Size(data);
+ CKYOffset offset = 0;
+ CKYBuffer tmp;
+
+ CKYBuffer_InitEmpty(&tmp);
+
+ CKYBuffer_Resize(result, 0);
+ for(offset = 0; (dataSize-offset) > CKY_MAX_WRITE_CHUNK_SIZE;
+ offset += CKY_MAX_WRITE_CHUNK_SIZE) {
+ CKYBuffer_Resize(&tmp,0);
+ CKYBuffer_AppendBuffer(&tmp, data, offset, CKY_MAX_WRITE_CHUNK_SIZE);
+ ret = CKYApplet_HandleAPDU(conn, CACAppletFactory_SignDecryptStep,
+ &tmp, NULL, CKY_SIZE_UNKNOWN,
+ CKYAppletFill_AppendBuffer,
result, apduRC);
+ if (ret != CKYSUCCESS) {
+ goto done;
+ }
+ }
+ CKYBuffer_Resize(&tmp,0);
+ CKYBuffer_AppendBuffer(&tmp, data, offset, dataSize - offset);
+ ret = CKYApplet_HandleAPDU(conn, CACAppletFactory_SignDecryptFinal,
+ &tmp, NULL, CKY_SIZE_UNKNOWN,
+ CKYAppletFill_AppendBuffer,
+ result, apduRC);
+
+ if ((ret == CKYSUCCESS) && (CKYBuffer_Size(result) != dataSize)) {
+ /* RSA returns the same data size as input, didn't happen, so
+ * something is wrong. */
+ }
+
+done:
+ CKYBuffer_FreeData(&tmp);
return ret;
}
@@ -895,6 +971,63 @@
}
return ret;
}
+
+/*
+ * Read a CAC Tag/Value file
+ */
+CKYStatus
+CACApplet_ReadFile(CKYCardConnection *conn, CKYByte type, CKYBuffer *buffer,
+ CKYISOStatus *apduRC)
+{
+ CKYStatus ret;
+ CKYISOStatus status;
+ CKYByte maxtransfer;
+ unsigned short offset = 0;
+ unsigned short size;
+ CACAppletArgReadFile rfs;
+
+ CKYBuffer_Resize(buffer,0);
+ if (apduRC == NULL) {
+ apduRC = &status;
+ }
+ rfs.offset = 0;
+ rfs.count = 2;
+ rfs.type = type;
+
+ /* APDU's are expensive, Grab a big chunk of the file first if possible */
+ ret = CKYApplet_HandleAPDU(conn,
+ CACAppletFactory_ReadFile, &rfs, NULL,
+ rfs.count, CKYAppletFill_AppendBuffer,
+ buffer, apduRC);
+ /* file is probably smaller than 100 bytes, get the actual size first */
+ if (ret != CKYSUCCESS) {
+ return ret;
+ }
+ size = CKYBuffer_GetShortLE(buffer, 0) + 2 /* include the length itself */;
+ maxtransfer = CKY_MAX_READ_CHUNK_SIZE;
+ /* get the rest of the buffer if necessary */
+ for (offset = CKYBuffer_Size(buffer); size > offset;
+ offset = CKYBuffer_Size(buffer)) {
+ rfs.offset = offset;
+ rfs.count = MIN(size - offset, maxtransfer);
+ ret = CKYApplet_HandleAPDU(conn,
+ CACAppletFactory_ReadFile, &rfs, NULL,
+ rfs.count, CKYAppletFill_AppendBuffer,
+ buffer, apduRC);
+ if (ret != CKYSUCCESS) {
+ if (*apduRC == CAC_INVALID_PARAMS) {
+ maxtransfer = maxtransfer/2;
+ if (maxtransfer == 0) {
+ return ret;
+ }
+ } else {
+ return ret;
+ }
+ }
+ }
+ return ret;
+}
+
CKYStatus
CACApplet_GetCertificateFirst(CKYCardConnection *conn, CKYBuffer *cert,
CKYSize *nextSize, CKYISOStatus *apduRC)
Index: cky_applet.h
===================================================================
RCS file: /cvs/dirsec/coolkey/src/libckyapplet/cky_applet.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- cky_applet.h 19 Feb 2009 02:03:08 -0000 1.2
+++ cky_applet.h 8 Sep 2010 20:14:41 -0000 1.3
@@ -43,6 +43,7 @@
#define CKYISO_MORE_MASK 0xff00 /* More data mask */
#define CKYISO_MORE 0x6300 /* More data available */
#define CKYISO_DATA_INVALID 0x6984
+#define CKYISO_CONDITION_NOT_SATISFIED 0x6985 /* AKA not logged in */
/* Applet Defined Return codes */
#define CKYISO_NO_MEMORY_LEFT 0x9c01 /* There have been memory
* problems on the card */
@@ -71,6 +72,15 @@
#define CKYISO_INTERNAL_ERROR 0x9cff /* Reserved for debugging,
* shouldn't happen */
+#define CAC_INVALID_PARAMS 0x6a83
+#define CAC_TAG_FILE 1
+#define CAC_VALUE_FILE 2
+
+
+#define CAC_TAG_CARDURL 0xf3
+#define CAC_TAG_CERTIFICATE 0x70
+#define CAC_TLV_APP_PKI 0x04
+
/*
* Pin Constants as used by our applet
*/
@@ -209,6 +219,12 @@
const CKYBuffer *sig;
} CKYAppletArgComputeCrypt;
+typedef struct _CACAppletArgReadFile {
+ CKYByte type;
+ CKYByte count;
+ unsigned short offset;
+} CACAppletArgReadFile;
+
/* fills in an APDU from a structure -- form of all the generic factories*/
typedef CKYStatus (*CKYAppletFactory)(CKYAPDU *apdu, const void *param);
/* fills in an a structure from a response -- form of all the fill structures*/
@@ -451,9 +467,17 @@
/* Select the CAC card manager. Can happen with either applet selected */
CKYStatus CACApplet_SelectCardManager(CKYCardConnection *conn,
CKYISOStatus *apduRC);
-/* Can happen with either applet selected */
-CKYStatus CACApplet_SelectPKI(CKYCardConnection *conn, CKYByte instance,
- CKYISOStatus *apduRC);
+/* Select the CAC CC container. Can happen with either applet selected */
+CKYStatus CACApplet_SelectCCC(CKYCardConnection *conn, CKYISOStatus *apduRC);
+/* Select an old CAC applet and fill in the cardAID */
+CKYStatus CACApplet_SelectPKI(CKYCardConnection *conn, CKYBuffer *cardAid,
+ CKYByte instance, CKYISOStatus *apduRC);
+/* read a TLV file */
+CKYStatus CACApplet_ReadFile(CKYCardConnection *conn, CKYByte type,
+ CKYBuffer *buffer, CKYISOStatus *apduRC);
+CKYStatus CACApplet_SelectFile(CKYCardConnection *conn, unsigned short ef,
+ CKYISOStatus *apduRC);
+
/* must happen with PKI applet selected */
CKYStatus CACApplet_SignDecrypt(CKYCardConnection *conn, const CKYBuffer *data,
CKYBuffer *result, CKYISOStatus *apduRC);
Index: cky_base.c
===================================================================
RCS file: /cvs/dirsec/coolkey/src/libckyapplet/cky_base.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- cky_base.c 9 Jun 2006 18:44:17 -0000 1.1
+++ cky_base.c 8 Sep 2010 20:14:41 -0000 1.2
@@ -220,6 +220,22 @@
return CKYSUCCESS;
}
+/* append a short in network order */
+CKYStatus
+CKYBuffer_AppendShortLE(CKYBuffer *buf, unsigned short val)
+{
+ CKYStatus ret;
+
+ ret = CKYBuffer_Reserve(buf, buf->len + 2);
+ if (ret != CKYSUCCESS) {
+ return ret;
+ }
+ buf->data[buf->len+1] = (CKYByte) ((val >> 8) & 0xff);
+ buf->data[buf->len+0] = (CKYByte) ((val >> 0) & 0xff);
+ buf->len += 2;
+ return CKYSUCCESS;
+}
+
/* append a long in applet order */
CKYStatus
CKYBuffer_AppendLong(CKYBuffer *buf, unsigned long val)
@@ -238,6 +254,24 @@
return CKYSUCCESS;
}
+/* append a long in applet order */
+CKYStatus
+CKYBuffer_AppendLongLE(CKYBuffer *buf, unsigned long val)
+{
+ CKYStatus ret;
+
+ ret = CKYBuffer_Reserve(buf, buf->len + 4);
+ if (ret != CKYSUCCESS) {
+ return ret;
+ }
+ buf->data[buf->len+3] = (CKYByte) ((val >> 24) & 0xff);
+ buf->data[buf->len+2] = (CKYByte) ((val >> 16) & 0xff);
+ buf->data[buf->len+1] = (CKYByte) ((val >> 8) & 0xff);
+ buf->data[buf->len+0] = (CKYByte) ((val >> 0) & 0xff);
+ buf->len += 4;
+ return CKYSUCCESS;
+}
+
CKYStatus
CKYBuffer_Replace(CKYBuffer *buf, CKYOffset offset, const CKYByte *data, CKYSize len)
{
@@ -351,6 +385,22 @@
}
CKYStatus
+CKYBuffer_SetShortLE(CKYBuffer *buf, CKYOffset offset, unsigned short val)
+{
+ CKYStatus ret;
+
+ if (buf->len < offset+2) {
+ ret = CKYBuffer_Resize(buf,offset+2);
+ if (ret != CKYSUCCESS) {
+ return ret;
+ }
+ }
+ buf->data[offset+1] = (CKYByte) ((val >> 8) & 0xff);
+ buf->data[offset+0] = (CKYByte) ((val >> 0) & 0xff);
+ return CKYSUCCESS;
+}
+
+CKYStatus
CKYBuffer_SetLong(CKYBuffer *buf, CKYOffset offset, unsigned long val)
{
CKYStatus ret;
@@ -368,6 +418,24 @@
return CKYSUCCESS;
}
+CKYStatus
+CKYBuffer_SetLongLE(CKYBuffer *buf, CKYOffset offset, unsigned long val)
+{
+ CKYStatus ret;
+
+ if (buf->len < offset+4) {
+ ret = CKYBuffer_Resize(buf,offset+4);
+ if (ret != CKYSUCCESS) {
+ return ret;
+ }
+ }
+ buf->data[offset+3] = (CKYByte) ((val >> 24) & 0xff);
+ buf->data[offset+2] = (CKYByte) ((val >> 16) & 0xff);
+ buf->data[offset+1] = (CKYByte) ((val >> 8) & 0xff);
+ buf->data[offset+0] = (CKYByte) ((val >> 0) & 0xff);
+ return CKYSUCCESS;
+}
+
CKYByte
CKYBuffer_GetChar(const CKYBuffer *buf, CKYOffset offset)
{
@@ -388,6 +456,18 @@
val |= ((unsigned short)buf->data[offset+1]) << 0;
return val;
}
+
+unsigned short
+CKYBuffer_GetShortLE(const CKYBuffer *buf, CKYOffset offset)
+{
+ unsigned short val;
+ if (buf->len < offset+2) {
+ return 0;
+ }
+ val = ((unsigned short)buf->data[offset+1]) << 8;
+ val |= ((unsigned short)buf->data[offset+0]) << 0;
+ return val;
+}
unsigned long
CKYBuffer_GetLong(const CKYBuffer *buf, CKYOffset offset)
@@ -402,6 +482,20 @@
val |= ((unsigned long)buf->data[offset+3]) << 0;
return val;
}
+
+unsigned long
+CKYBuffer_GetLongLE(const CKYBuffer *buf, CKYOffset offset)
+{
+ unsigned long val;
+ if (buf->len < offset+4) {
+ return 0;
+ }
+ val = ((unsigned long)buf->data[offset+3]) << 24;
+ val |= ((unsigned long)buf->data[offset+2]) << 16;
+ val |= ((unsigned long)buf->data[offset+1]) << 8;
+ val |= ((unsigned long)buf->data[offset+0]) << 0;
+ return val;
+}
CKYStatus
CKYBuffer_Resize(CKYBuffer *buf, CKYSize newLen)
Index: cky_base.h
===================================================================
RCS file: /cvs/dirsec/coolkey/src/libckyapplet/cky_base.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- cky_base.h 9 Jun 2006 18:44:17 -0000 1.1
+++ cky_base.h 8 Sep 2010 20:14:41 -0000 1.2
@@ -170,9 +170,15 @@
/* append a short in applet order */
CKYStatus CKYBuffer_AppendShort(CKYBuffer *buf, unsigned short val);
+/* append a short in little endian order */
+CKYStatus CKYBuffer_AppendShortLE(CKYBuffer *buf, unsigned short val);
+
/* append a long in applet order */
CKYStatus CKYBuffer_AppendLong(CKYBuffer *buf, unsigned long val);
+/* append a long in little endian order */
+CKYStatus CKYBuffer_AppendLongLE(CKYBuffer *buf, unsigned long val);
+
/* append data. the data starts at data and extends len bytes */
CKYStatus CKYBuffer_AppendData(CKYBuffer *buf, const CKYByte *data, CKYSize len);
@@ -210,12 +216,18 @@
CKYStatus CKYBuffer_SetShort(CKYBuffer *buf, CKYOffset offset, unsigned short val);
CKYStatus CKYBuffer_SetLong(CKYBuffer *buf, CKYOffset offset, unsigned long val);
+/* These functions work in little endian order */
+CKYStatus CKYBuffer_SetShortLE(CKYBuffer *buf, CKYOffset offset, unsigned short val);
+CKYStatus CKYBuffer_SetLongLE(CKYBuffer *buf, CKYOffset offset, unsigned long val);
/* read a character from offset. If offset is beyond the end of the buffer,
* then the function returns '0' */
CKYByte CKYBuffer_GetChar(const CKYBuffer *buf, CKYOffset offset);
/* These functions work in applet order */
unsigned short CKYBuffer_GetShort(const CKYBuffer *buf, CKYOffset offset);
unsigned long CKYBuffer_GetLong(const CKYBuffer *buf, CKYOffset offset);
+/* These functions work in little endian order */
+unsigned short CKYBuffer_GetShortLE(const CKYBuffer *buf, CKYOffset offset);
+unsigned long CKYBuffer_GetLongLE(const CKYBuffer *buf, CKYOffset offset);
/* clear out all the data in a buffer */
void CKYBuffer_Zero(CKYBuffer *buf);
Index: cky_factory.c
===================================================================
RCS file: /cvs/dirsec/coolkey/src/libckyapplet/cky_factory.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- cky_factory.c 19 Feb 2009 02:03:08 -0000 1.2
+++ cky_factory.c 8 Sep 2010 20:14:41 -0000 1.3
@@ -25,12 +25,13 @@
* special commands can be issued at any time
*/
CKYStatus
-CKYAPDUFactory_SelectFile(CKYAPDU *apdu, const CKYBuffer *AID)
+CKYAPDUFactory_SelectFile(CKYAPDU *apdu, CKYByte p1, CKYByte p2,
+ const CKYBuffer *AID)
{
CKYAPDU_SetCLA(apdu, CKY_CLASS_ISO7816);
CKYAPDU_SetINS(apdu, CKY_INS_SELECT_FILE);
- CKYAPDU_SetP1(apdu, 0x04);
- CKYAPDU_SetP2(apdu, 0x00);
+ CKYAPDU_SetP1(apdu, p1);
+ CKYAPDU_SetP2(apdu, p2);
return CKYAPDU_SetSendDataBuffer(apdu, AID);
}
@@ -131,6 +132,7 @@
return ret;
}
+
CKYStatus
CKYAPDUFactory_ComputeCryptFinal(CKYAPDU *apdu, CKYByte keyNumber,
CKYByte location, const CKYBuffer *data, const CKYBuffer *sig)
@@ -572,11 +574,11 @@
}
CKYStatus
-CACAPDUFactory_SignDecrypt(CKYAPDU *apdu, const CKYBuffer *data)
+CACAPDUFactory_SignDecrypt(CKYAPDU *apdu, CKYByte type, const CKYBuffer *data)
{
CKYAPDU_SetCLA(apdu, CKY_CLASS_ISO7816);
CKYAPDU_SetINS(apdu, CAC_INS_SIGN_DECRYPT);
- CKYAPDU_SetP1(apdu, 0x00);
+ CKYAPDU_SetP1(apdu, type);
CKYAPDU_SetP2(apdu, 0x00);
return CKYAPDU_SetSendDataBuffer(apdu, data);
}
@@ -592,6 +594,36 @@
}
CKYStatus
+CACAPDUFactory_ReadFile(CKYAPDU *apdu, unsigned short offset,
+ CKYByte type, CKYByte count)
+{
+ CKYStatus ret;
+ CKYBuffer buf;
+
+ CKYBuffer_InitEmpty(&buf);
+ CKYAPDU_SetCLA(apdu, CKY_CLASS_GLOBAL_PLATFORM);
+ CKYAPDU_SetINS(apdu, CAC_INS_READ_FILE);
+ CKYAPDU_SetP1(apdu, (offset >> 8) & 0xff);
+ CKYAPDU_SetP2(apdu, offset & 0xff);
+ ret = CKYBuffer_Reserve(&buf, 2);
+ if (ret != CKYSUCCESS) {
+ goto fail;
+ }
+ ret = CKYBuffer_AppendChar(&buf, type);
+ if (ret != CKYSUCCESS) {
+ goto fail;
+ }
+ ret = CKYBuffer_AppendChar(&buf, count);
+ if (ret != CKYSUCCESS) {
+ goto fail;
+ }
+ ret = CKYAPDU_SetSendDataBuffer(apdu, &buf);
+fail:
+ CKYBuffer_FreeData(&buf);
+ return ret;
+}
+
+CKYStatus
CACAPDUFactory_GetProperties(CKYAPDU *apdu)
{
CKYAPDU_SetCLA(apdu, CKY_CLASS_ISO7816);
Index: cky_factory.h
===================================================================
RCS file: /cvs/dirsec/coolkey/src/libckyapplet/cky_factory.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- cky_factory.h 19 Feb 2009 02:03:08 -0000 1.2
+++ cky_factory.h 8 Sep 2010 20:14:41 -0000 1.3
@@ -86,7 +86,11 @@
#define CAC_INS_SIGN_DECRYPT 0x42
#define CAC_INS_VERIFY_PIN 0x20
#define CAC_INS_GET_PROPERTIES 0x56
+#define CAC_INS_READ_FILE 0x52
+
#define CAC_SIZE_GET_PROPERTIES 48
+#define CAC_P1_STEP 0x80
+#define CAC_P1_FINAL 0x00
/*
* Fixed return sized from various commands
@@ -169,7 +173,8 @@
CKY_BEGIN_PROTOS
/* function based factorys */
-CKYStatus CKYAPDUFactory_SelectFile(CKYAPDU *apdu, const CKYBuffer *AID);
+CKYStatus CKYAPDUFactory_SelectFile(CKYAPDU *apdu, CKYByte p1, CKYByte p2,
+ const CKYBuffer *AID);
CKYStatus CKYAPDUFactory_SelectCardManager(CKYAPDU *apdu);
CKYStatus CKYAPDUFactory_GetCPLCData(CKYAPDU *apdu);
CKYStatus CKYAPDUFactory_ListKeys(CKYAPDU *apdu, CKYByte sequence);
@@ -211,9 +216,12 @@
CKYStatus CKYAPDUFactory_GetIssuerInfo(CKYAPDU *apdu);
CKYStatus CKYAPDUFactory_GetBuiltinACL(CKYAPDU *apdu);
-CKYStatus CACAPDUFactory_SignDecrypt(CKYAPDU *apdu, const CKYBuffer *data);
+CKYStatus CACAPDUFactory_SignDecrypt(CKYAPDU *apdu, CKYByte type,
+ const CKYBuffer *data);
CKYStatus CACAPDUFactory_VerifyPIN(CKYAPDU *apdu, const char *pin);
CKYStatus CACAPDUFactory_GetCertificate(CKYAPDU *apdu, CKYSize size);
+CKYStatus CACAPDUFactory_ReadFile(CKYAPDU *apdu, unsigned short offset,
+ CKYByte type, CKYByte count);
CKYStatus CACAPDUFactory_GetProperties(CKYAPDU *apdu);
CKY_END_PROTOS