Hello!

Here's an patch against latest ccid/pcsc-lite cvs versions that
somewhat add support for teletrust class 2 spec style pin operations.
If compared with previous patch - Now it CCID ifdhandler actually
accpets teletrust spec structures. Due to the fact that CCID spec at
the same time is somewhat lacking proper information about such
things, the translation between teletrust and ccid blocks is somewhat
ugly - but it works. I'm afraid there have to be several reader
specific hacks in that function anyway (And for example - CCID spec
does not define an error situation like 'pins don't match' so possible
statuses are only 'timeout' and 'cancel')

It has been tested with spr532/linux.

Feedback welcome.

-- 
Martin Paljak
[EMAIL PROTECTED]
http://martin.paljak.pri.ee/
+372.5156495 - phone
Index: src/winscard.c
===================================================================
RCS file: /cvsroot/pcsclite/PCSC/src/winscard.c,v
retrieving revision 1.51
diff -u -r1.51 winscard.c
--- src/winscard.c	1 Mar 2005 09:22:52 -0000	1.51
+++ src/winscard.c	14 Mar 2005 10:24:56 -0000
@@ -1122,10 +1122,6 @@
 	if (rv != SCARD_S_SUCCESS)
 		return rv;
 
-	if (IFD_HVERSION_2_0 == rContext->dwVersion)
-		if (NULL == pbSendBuffer || 0 == cbSendLength)
-			return SCARD_E_INVALID_PARAMETER;
-
 	/*
 	 * Make sure the reader is working properly
 	 */
Index: src/winscard_clnt.c
===================================================================
RCS file: /cvsroot/pcsclite/PCSC/src/winscard_clnt.c,v
retrieving revision 1.54
diff -u -r1.54 winscard_clnt.c
--- src/winscard_clnt.c	2 Mar 2005 15:12:49 -0000	1.54
+++ src/winscard_clnt.c	14 Mar 2005 10:24:57 -0000
@@ -1486,9 +1486,6 @@
 	if (NULL != lpBytesReturned)
 		*lpBytesReturned = 0;
 
-	if (pbSendBuffer == 0)
-		return SCARD_E_INVALID_PARAMETER;
-
 	if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
 		return SCARD_E_NO_SERVICE;
 
Index: src/PCSC/pcsclite.h.in
===================================================================
RCS file: /cvsroot/pcsclite/PCSC/src/PCSC/pcsclite.h.in,v
retrieving revision 1.47
diff -u -r1.47 pcsclite.h.in
--- src/PCSC/pcsclite.h.in	24 Aug 2004 21:46:57 -0000	1.47
+++ src/PCSC/pcsclite.h.in	14 Mar 2005 10:24:57 -0000
@@ -314,6 +314,31 @@
  */
 char *pcsc_stringify_error(long);
 
+/*
+ * Provide source compatibility on different platforms
+ */
+#define SCARD_CTL_CODE(code) (0x42000000 + (code))
+
+/*
+ * TeleTrust Class 2 reader tags
+ */
+#define CM_IOCTL_GET_FEATURE_REQUEST SCARD_CTL_CODE(3400) /* FIXME: bincompat? */
+
+#define FEATURE_VERIFY_PIN_START 0x01 /* OMNIKEY Proposal */
+#define FEATURE_VERIFY_PIN_FINISH 0x02 /* OMNIKEY Proposal */
+#define FEATURE_MODIFY_PIN_START 0x03 /* OMNIKEY Proposal */
+#define FEATURE_MODIFY_PIN_FINISH 0x04 /* OMNIKEY Proposal */
+#define FEATURE_GET_KEY_PRESSED 0x05 /* OMNIKEY Proposal */
+#define FEATURE_VERIFY_PIN_DIRECT 0x06 /* USB CCID PIN Verify */
+#define FEATURE_MODIFY_PIN_DIRECT 0x07 /* USB CCID PIN Modify */
+#define FEATURE_MCT_READERDIRECT 0x08 /* KOBIL Proposal */
+#define FEATURE_MCT_UNIVERSAL 0x09 /* KOBIL Proposal */
+#define FEATURE_IFD_PIN_PROP 0x0A /* Gemplus Proposal */
+#define FEATURE_ABORT 0x0B /* SCM Proposal */
+
+/* Utility for handling big endian IOCTL codes */
+#define dw2i_be(a, x) ((((((a[x] << 8) + a[x+1]) << 8) + a[x+2]) << 8) + a[x+3])
+
 #ifdef __cplusplus
 }
 #endif
Index: examples/scardcontrol.c
===================================================================
RCS file: /cvsroot/pcsclite/Drivers/ccid/examples/scardcontrol.c,v
retrieving revision 1.14
diff -u -r1.14 scardcontrol.c
--- examples/scardcontrol.c	23 Feb 2005 13:19:23 -0000	1.14
+++ examples/scardcontrol.c	14 Mar 2005 10:21:13 -0000
@@ -33,12 +33,7 @@
 #define FALSE 0
 #endif
 
-#define SCARD_CTL_CODE(code) (0x42000000 + (code))
-
 #define IOCTL_SMARTCARD_VENDOR_IFD_EXCHANGE     SCARD_CTL_CODE(1)
-#define IOCTL_SMARTCARD_VENDOR_VERIFY_PIN       SCARD_CTL_CODE(2)
-#define IOCTL_SMARTCARD_VENDOR_MODIFY_PIN       SCARD_CTL_CODE(3)
-#define IOCTL_SMARTCARD_VENDOR_TRANSFER_PIN     SCARD_CTL_CODE(4)
 
 /* PCSC error message pretty print */
 #define PCSC_ERROR_EXIT(rv, text) \
@@ -73,8 +68,7 @@
 	unsigned char bSendBuffer[MAX_BUFFER_SIZE];
 	unsigned char bRecvBuffer[MAX_BUFFER_SIZE];
 	DWORD length;
-	unsigned char attribute[1];
-	DWORD attribute_length;
+	DWORD verify_ioctl = 0;
 	SCARD_IO_REQUEST pioRecvPci;
 
 	printf("SCardControl sample code\n");
@@ -195,11 +189,20 @@
 	PCSC_ERROR_CONT(rv, "SCardStatus")
 
 	/* does the reader support PIN verification? */
-	attribute_length = sizeof(attribute);
-	rv = SCardGetAttrib(hCard, IOCTL_SMARTCARD_VENDOR_VERIFY_PIN, attribute,
-		&attribute_length);
-	PCSC_ERROR_CONT(rv, "SCardGetAttrib")
-	if (FALSE == attribute[0])
+	rv = SCardControl(hCard, CM_IOCTL_GET_FEATURE_REQUEST, NULL, 0, 
+		bRecvBuffer, sizeof(bRecvBuffer), &length);
+	
+	PCSC_ERROR_CONT(rv, "SCardControl(CM_IOCTL_GET_FEATURE_REQUEST)")
+	
+	if (length % 6)
+		printf("Inconsistent result! Bad TLV values!\n");
+		
+	for (i = 0; i < length; i += 6) {
+		if (bRecvBuffer[i] == FEATURE_VERIFY_PIN_DIRECT)
+			verify_ioctl = dw2i_be(bRecvBuffer, i + 2);
+	}
+	
+	if (verify_ioctl == 0)
 	{
 		printf("Reader %s does not support PIN verification\n",
 			readers[reader_nb]);
@@ -239,8 +242,9 @@
 	printf(" Secure verify PIN\n");
 	offset = 0;
 
-	/* CCID PIN verification data structure */
+	/* TeleTrust Class 2 PIN verification data structure */
 	bSendBuffer[offset++] = 0x00;	/* bTimeOut */
+	bSendBuffer[offset++] = 0x00;	/* bTimeOut2 */
 	bSendBuffer[offset++] = 0x82;	/* bmFormatString */
 	bSendBuffer[offset++] = 0x04;	/* bmPINBlockString (PIN length) */
 	bSendBuffer[offset++] = 0x00;	/* bmPINLengthFormat */
@@ -254,7 +258,8 @@
 	bSendBuffer[offset++] = 0x00;	/* bTeoPrologue */
 	bSendBuffer[offset++] = 0x00;	/* " */
 	bSendBuffer[offset++] = 0x00;	/* " */
-
+	bSendBuffer[offset++] = 0x0d;	/* ulDataLength */
+	
 	/* APDU: 00 20 00 00 08 30 30 30 30 00 00 00 00 */
 	bSendBuffer[offset++] = 0x00;	/* CLA */
 	bSendBuffer[offset++] = 0x20;	/* INS: VERIFY */
@@ -276,7 +281,7 @@
 	printf("\n");
 	printf("Enter your PIN: ");
 	fflush(stdout);
-	rv = SCardControl(hCard, IOCTL_SMARTCARD_VENDOR_VERIFY_PIN, bSendBuffer,
+	rv = SCardControl(hCard, verify_ioctl, bSendBuffer,
 		offset, bRecvBuffer, sizeof(bRecvBuffer), &length);
 
 	printf(" card response:");
Index: src/ccid_ifdhandler.h
===================================================================
RCS file: /cvsroot/pcsclite/Drivers/ccid/src/ccid_ifdhandler.h,v
retrieving revision 1.13
diff -u -r1.13 ccid_ifdhandler.h
--- src/ccid_ifdhandler.h	19 Oct 2004 08:40:42 -0000	1.13
+++ src/ccid_ifdhandler.h	14 Mar 2005 10:21:13 -0000
@@ -24,16 +24,15 @@
 #ifndef _ccid_ifd_handler_h_
 #define _ccid_ifd_handler_h_
 
-#define SCARD_CTL_CODE(code) (0x42000000 + (code))
-
 #define IOCTL_SMARTCARD_VENDOR_IFD_EXCHANGE	SCARD_CTL_CODE(1)
-#define IOCTL_SMARTCARD_VENDOR_VERIFY_PIN	SCARD_CTL_CODE(2)
-#define IOCTL_SMARTCARD_VENDOR_MODIFY_PIN	SCARD_CTL_CODE(3)
-#define IOCTL_SMARTCARD_VENDOR_TRANSFER_PIN	SCARD_CTL_CODE(4)
 
 #define DRIVER_OPTION_CCID_EXCHANGE_AUTHORIZED 1
 #define DRIVER_OPTION_GEMPC_TWIN_KEY_APDU 2
 #define DRIVER_OPTION_USE_BOGUS_FIRMWARE 4
+
+#define CLASS2_IOCTL_MAGIC 0x33
+#define IOCTL_FEATURE_VERIFY_PIN_DIRECT SCARD_CTL_CODE(FEATURE_VERIFY_PIN_DIRECT + CLASS2_IOCTL_MAGIC)
+#define IOCTL_FEATURE_MODIFY_PIN_DIRECT SCARD_CTL_CODE(FEATURE_MODIFY_PIN_DIRECT + CLASS2_IOCTL_MAGIC)
 
 extern int LogLevel;
 extern int DriverOptions;
Index: src/commands.c
===================================================================
RCS file: /cvsroot/pcsclite/Drivers/ccid/src/commands.c,v
retrieving revision 1.37
diff -u -r1.37 commands.c
--- src/commands.c	13 Jan 2005 09:35:16 -0000	1.37
+++ src/commands.c	14 Mar 2005 10:21:13 -0000
@@ -33,6 +33,7 @@
 #include "ccid_ifdhandler.h"
 #include "config.h"
 #include "debug.h"
+#include "utils.h"
 
 /*
  * Possible values :
@@ -60,8 +61,6 @@
 	unsigned int tx_length, unsigned char tx_buffer[], unsigned int *rx_length,
 	unsigned char rx_buffer[]);
 
-static void i2dw(int value, unsigned char *buffer);
-
 
 /*****************************************************************************
  *
@@ -154,55 +153,163 @@
 
 /*****************************************************************************
  *
- *					SecurePIN
+ *					SecurePINVerify
  *
  ****************************************************************************/
-RESPONSECODE SecurePIN(unsigned int reader_index,
+RESPONSECODE SecurePINVerify(unsigned int reader_index,
 	const unsigned char TxBuffer[], unsigned int TxLength,
 	unsigned char RxBuffer[], unsigned int *RxLength)
 {
 	unsigned char cmd[11+14+CMD_BUF_SIZE];
+	unsigned int a, b;
 	_ccid_descriptor *ccid_descriptor = get_ccid_descriptor(reader_index);
 
 	cmd[0] = 0x69;	/* Secure */
-	i2dw(TxLength+1, cmd+1);	/* command length (includes bPINOperation) */
 	cmd[5] = ccid_descriptor->bCurrentSlotIndex;	/* slot number */
 	cmd[6] = (*ccid_descriptor->pbSeq)++;
 	cmd[7] = 0;		/* bBWI */
 	cmd[8] = 0;		/* wLevelParameter */
 	cmd[9] = 0;
+	
+	if ((TxLength > 20+CMD_BUF_SIZE) || (TxLength < 20))
+		return IFD_NOT_SUPPORTED;
+	
+	/* Build a CCID block from TeleTrust block */
 	cmd[10] = 0;	/* bPINOperation: PIN Verification */
+	
+	for (a = 11, b = 0; b < TxLength; b++) {
+		switch(b) {
+		case 1: /* bTimeOut2 */
+			/* Ignore the second timeout as there's nothing we can do with it currently */
+			break;
+		case 15: /* ulDataLength */
+			/* Validate */
+			if (TxBuffer[b] + b + 1!= TxLength)
+				return IFD_NOT_SUPPORTED;
+			/* SPR532 and Case 1 APDU */
+			if ((SPR532 == ccid_descriptor->readerID) && (TxBuffer[b] == 4))
+			{
+				RESPONSECODE return_value;
+				unsigned char cmd[] = { 0x80,0x02, 0x00 };
+				unsigned char res[1];
+				unsigned int res_length = sizeof(res);
+
+				/* SPR532 will append the PIN code without any padding */
+				return_value = CmdEscape(reader_index, cmd, sizeof(cmd), res, &res_length);
+				if (return_value != IFD_SUCCESS)
+				{
+					ccid_error(res[ERROR_OFFSET], __FILE__, __LINE__, __FUNCTION__);
+					return return_value;
+				}
+			}
+			break;
+		default:
+			/* Default is to copy the CCID block 'verbatim' */
+			cmd[a] = TxBuffer[b];
+			a++;
+		}
+	}
+	
+	i2dw(a - 10, cmd + 1);	/* CCID message length */
+	
+	if (WritePort(reader_index, a, cmd) != STATUS_SUCCESS)
+		return IFD_COMMUNICATION_ERROR;
 
-	/* check that the command is not too large */
-	if (TxLength > 14+CMD_BUF_SIZE)
-		return IFD_NOT_SUPPORTED;
+	return CCID_Receive(reader_index, RxLength, RxBuffer);
+} /* SecurePINVerify */
 
-	/* CCID data structure + APDU */
-	memcpy(cmd + 11, TxBuffer, TxLength);
 
-	/* SPR532 and Case 1 APDU */
-	if ((SPR532 == ccid_descriptor->readerID) && (TxLength - 14 == 4))
-	{
-		RESPONSECODE return_value;
-		unsigned char cmd[] = { 0x80,0x02, 0x00 };
-		unsigned char res[1];
-		unsigned int res_length = sizeof(res);
-
-		/* the SPR532 will append the PIN code without any padding */
-		return_value = CmdEscape(reader_index, cmd, sizeof(cmd), res,
-			&res_length);
-		if (return_value != IFD_SUCCESS)
-		{
-			ccid_error(res[ERROR_OFFSET], __FILE__, __LINE__, __FUNCTION__);
-			return return_value;
+/*****************************************************************************
+ *
+ *					SecurePINModify
+ *
+ ****************************************************************************/
+RESPONSECODE SecurePINModify(unsigned int reader_index,
+	const unsigned char TxBuffer[], unsigned int TxLength,
+	unsigned char RxBuffer[], unsigned int *RxLength)
+
+{
+	unsigned char cmd[11+19+CMD_BUF_SIZE];
+	unsigned int a, b;
+	_ccid_descriptor *ccid_descriptor = get_ccid_descriptor(reader_index);
+	
+	cmd[0] = 0x69;	/* Secure */
+	cmd[5] = ccid_descriptor->bCurrentSlotIndex;	/* slot number */
+	cmd[6] = (*ccid_descriptor->pbSeq)++;
+	cmd[7] = 0;		/* bBWI */
+	cmd[8] = 0;		/* wLevelParameter */
+	cmd[9] = 0;
+
+	/* Build a CCID block from TeleTrust block */
+	cmd[10] = 1;	/* bPINOperation: PIN Modification */
+	
+	if (TxLength < 21)
+		return IFD_NOT_SUPPORTED;
+		
+	/* Make sure in the beginning if bNumberMessage is valid or not */
+	if (TxBuffer[11] > 3)
+		return IFD_NOT_SUPPORTED;
+	
+	/*
+	 * Do adjustments as needed - CCID spec is not exact with some
+	 * details in the format of the structure, per-reader adaptions
+	 * might be needed.
+	 */
+	for (a = 11, b = 0; b < TxLength; ) {
+		switch(b) {
+		case 1: /* bTimeOut2 */
+			/* Ignore the second timeout as there's nothing we can do with it currently */
+			b++;
+			continue;
+		default:
+			/* 
+			 * OK, this is ugly. TeleTrust tells that exactly so many bMsgIndex 
+			 * elements must exist in the structure as indicated by bNumberMessage
+			 * At the same time CCID spec tells that only bMsgIndex3 might be missing
+			 * and it depends on the value of bNumberMessage. SPR 532 takes all bMsgIndex
+			 * fields for example and bNumberMessage must be equal to 0.
+			 */
+			 
+			switch(a) {
+			case 24:
+			case 25:
+			case 26:
+				/* 
+				 * SPR 532 has no display but requires _all_ bMsgIndex 
+				 * fields with bNumberMessage set to 0.
+				 */
+				if (SPR532 == ccid_descriptor->readerID) {
+					cmd[21] = 0x00; /* cast bNumberMessages to 0 */
+					cmd[a++] = 0x00; /* bMsgIndex123 */
+					b = TxBuffer[11] + 14;
+					continue;
+				}
+			}
+
+			/* Thanks to bNumberMessage ulDataLength is with a floating location */
+			if ((b == TxBuffer[11] + 17)) {
+				/* Validate */
+				if (TxBuffer[b] + b + 1 != TxLength) {
+					return IFD_NOT_SUPPORTED;
+				} else {
+					b++;
+					continue;
+				}
+			}	
+			/* Default is to copy to the CCID block 'verbatim' */
+			cmd[a] = TxBuffer[b];
+			a++; b++;
 		}
 	}
-
-	if (WritePort(reader_index, TxLength+1+10, cmd) != STATUS_SUCCESS)
+	
+	/* We know the size of the CCID message now */
+	i2dw(a - 10, cmd + 1);	/* command length (includes bPINOperation) */
+	
+	if (WritePort(reader_index, a, cmd) != STATUS_SUCCESS)
 		return IFD_COMMUNICATION_ERROR;
 
 	return CCID_Receive(reader_index, RxLength, RxBuffer);
-} /* SecurePIN */
+} /* SecurePINModify */
 
 
 /*****************************************************************************
@@ -483,6 +590,26 @@
 	if (cmd[STATUS_OFFSET] & CCID_COMMAND_FAILED)
 	{
 		ccid_error(cmd[ERROR_OFFSET], __FILE__, __LINE__, __FUNCTION__);    /* bError */
+		
+		if (0xEF == cmd[ERROR_OFFSET]) /* cancel */
+		{
+			if (*rx_length < 2)
+				return IFD_COMMUNICATION_ERROR;
+			rx_buffer[0]= 0x64;
+			rx_buffer[1]= 0x01;
+			*rx_length = 2;
+			return IFD_SUCCESS;
+		} 
+		else if (0xF0 == cmd[ERROR_OFFSET]) /* timeout */
+		{
+			if (*rx_length < 2)
+				return IFD_COMMUNICATION_ERROR;
+			rx_buffer[0]= 0x64;
+			rx_buffer[1]= 0x00;
+			*rx_length = 2;
+			return IFD_SUCCESS;
+		}
+		
 		*rx_length = 0; /* nothing received */
 		if (0xFD == cmd[ERROR_OFFSET]) /* Parity error during exchange */
 			return IFD_PARITY_ERROR;
@@ -932,18 +1059,3 @@
 {
 	return CCID_CLASS_CHARACTER == (get_ccid_descriptor(reader_index)->dwFeatures & CCID_CLASS_EXCHANGE_MASK);
 } /* isCharLevel */
-
-
-/*****************************************************************************
- *
- *					i2dw
- *
- ****************************************************************************/
-static void i2dw(int value, unsigned char buffer[])
-{
-	buffer[0] = value & 0xFF;
-	buffer[1] = (value >> 8) & 0xFF;
-	buffer[2] = (value >> 16) & 0xFF;
-	buffer[3] = (value >> 24) & 0xFF;
-} /* i2dw */
-
Index: src/commands.h
===================================================================
RCS file: /cvsroot/pcsclite/Drivers/ccid/src/commands.h,v
retrieving revision 1.13
diff -u -r1.13 commands.h
--- src/commands.h	19 Oct 2004 07:22:06 -0000	1.13
+++ src/commands.h	14 Mar 2005 10:21:13 -0000
@@ -28,7 +28,11 @@
 RESPONSECODE CmdPowerOn(unsigned int reader_index, unsigned int * nlength,
 	unsigned char buffer[]);
 
-RESPONSECODE SecurePIN(unsigned int reader_index,
+RESPONSECODE SecurePINVerify(unsigned int reader_index,
+	const unsigned char TxBuffer[], unsigned int TxLength,
+	unsigned char RxBuffer[], unsigned int *RxLength);
+
+RESPONSECODE SecurePINModify(unsigned int reader_index,
 	const unsigned char TxBuffer[], unsigned int TxLength,
 	unsigned char RxBuffer[], unsigned int *RxLength);
 
Index: src/ifdhandler.c
===================================================================
RCS file: /cvsroot/pcsclite/Drivers/ccid/src/ifdhandler.c,v
retrieving revision 1.58
diff -u -r1.58 ifdhandler.c
--- src/ifdhandler.c	28 Feb 2005 09:35:56 -0000	1.58
+++ src/ifdhandler.c	14 Mar 2005 10:21:13 -0000
@@ -291,14 +291,6 @@
 			}
 			break;
 
-		case IOCTL_SMARTCARD_VENDOR_VERIFY_PIN:
-			if (*Length >= 1)
-			{
-				*Length = 1;
-				*Value = get_ccid_descriptor(reader_index) -> bPINSupport & CCID_CLASS_PIN_VERIFY;
-			}
-			break;
-
 		default:
 			return IFD_ERROR_TAG;
 	}
@@ -833,8 +825,7 @@
 	DEBUG_INFO3("lun: %X, ControlCode: 0x%X", Lun, dwControlCode);
 
 	reader_index = LunToReaderIndex(Lun);
-	if ((-1 == reader_index) || (NULL == pdwBytesReturned)
-		|| (NULL == RxBuffer))
+	if ((-1 == reader_index) || (NULL == pdwBytesReturned))
 		return return_value;
 
 	/* Set the return length to 0 to avoid problems */
@@ -857,17 +848,58 @@
 			*pdwBytesReturned = iBytesReturned;
 		}
 	}
-
-	if (IOCTL_SMARTCARD_VENDOR_VERIFY_PIN == dwControlCode)
+	/* Implement the TeleTrust Class2 IOCTL mechanism */
+	
+	/* Query for features */
+	if (CM_IOCTL_GET_FEATURE_REQUEST == dwControlCode)
+	{
+		unsigned int iBytesReturned = 0;
+		/* We can only support direct verify and/or modify currently */
+		if (get_ccid_descriptor(reader_index) -> bPINSupport & CCID_CLASS_PIN_VERIFY)
+		{
+			if (iBytesReturned + 6 > RxLength)
+				return return_value;
+			RxBuffer[iBytesReturned + 0] = FEATURE_VERIFY_PIN_DIRECT;
+			RxBuffer[iBytesReturned + 1] = 0x04; /* always 0x04 */
+			i2dw_be(IOCTL_FEATURE_VERIFY_PIN_DIRECT, RxBuffer + iBytesReturned + 2);
+			iBytesReturned += 6;
+		}
+		
+		if (get_ccid_descriptor(reader_index) -> bPINSupport & CCID_CLASS_PIN_MODIFY)
+		{
+			if (iBytesReturned + 6 > RxLength)
+				return return_value;
+			RxBuffer[iBytesReturned + 0] = FEATURE_MODIFY_PIN_DIRECT;
+			RxBuffer[iBytesReturned + 1] = 0x04; /* always 0x04 */
+			i2dw_be(IOCTL_FEATURE_MODIFY_PIN_DIRECT, RxBuffer + iBytesReturned + 2);
+			iBytesReturned += 6;
+		}
+		*pdwBytesReturned = iBytesReturned;
+		return_value = IFD_SUCCESS;
+	}
+	
+	/* Verify a PIN, plain CCID */
+	if (IOCTL_FEATURE_VERIFY_PIN_DIRECT == dwControlCode)
 	{
-		unsigned int iBytesReturned;
+		unsigned int iBytesReturned = 0;
 
 		iBytesReturned = RxLength;
-		return_value = SecurePIN(reader_index, TxBuffer, TxLength, RxBuffer,
+		return_value = SecurePINVerify(reader_index, TxBuffer, TxLength, RxBuffer,
 			&iBytesReturned);
 		*pdwBytesReturned = iBytesReturned;
 	}
+	
+	/* Modify a PIN, plain CCID */
+	if (IOCTL_FEATURE_MODIFY_PIN_DIRECT == dwControlCode)
+	{
+		unsigned int iBytesReturned = 0;
 
+		iBytesReturned = RxLength;
+		return_value = SecurePINModify(reader_index, TxBuffer, TxLength, RxBuffer,
+			&iBytesReturned);
+		*pdwBytesReturned = iBytesReturned;
+	}
+	
 	return return_value;
 } /* IFDHControl */
 
Index: src/utils.c
===================================================================
RCS file: /cvsroot/pcsclite/Drivers/ccid/src/utils.c,v
retrieving revision 1.11
diff -u -r1.11 utils.c
--- src/utils.c	24 Aug 2004 07:30:21 -0000	1.11
+++ src/utils.c	14 Mar 2005 10:21:13 -0000
@@ -73,3 +73,18 @@
 	return 0;
 } /* ReleaseReaderIndex */
 
+void i2dw(int value, unsigned char buffer[])
+{
+	buffer[0] = value & 0xFF;
+	buffer[1] = (value >> 8) & 0xFF;
+	buffer[2] = (value >> 16) & 0xFF;
+	buffer[3] = (value >> 24) & 0xFF;
+} /* i2dw */
+
+void i2dw_be(int value, unsigned char buffer[])
+{
+	buffer[0] = (value >> 24) & 0xFF;
+	buffer[1] = (value >> 16) & 0xFF;
+	buffer[2] = (value >> 8) & 0xFF;
+	buffer[3] = value & 0xFF;
+}
Index: src/utils.h
===================================================================
RCS file: /cvsroot/pcsclite/Drivers/ccid/src/utils.h,v
retrieving revision 1.2
diff -u -r1.2 utils.h
--- src/utils.h	28 Jul 2004 08:30:30 -0000	1.2
+++ src/utils.h	14 Mar 2005 10:21:13 -0000
@@ -30,4 +30,6 @@
 int GetNewReaderIndex(const DWORD Lun);
 int LunToReaderIndex(DWORD Lun);
 int ReleaseReaderIndex(const int index);
+void i2dw(int value, unsigned char *buffer);
+void i2dw_be(int value, unsigned char *buffer);
 
_______________________________________________
Muscle mailing list
[email protected]
http://lists.drizzle.com/mailman/listinfo/muscle

Reply via email to