[Pcsclite-cvs-commit] r1631 - trunk/Drivers/ccid/examples
Ludovic Rousseau
rousseau at costa.debian.org
Thu Sep 1 09:13:39 UTC 2005
Author: rousseau
Date: 2005-09-01 09:13:38 +0000 (Thu, 01 Sep 2005)
New Revision: 1631
Modified:
trunk/Drivers/ccid/examples/scardcontrol.c
Log:
add sample code to perform FEATURE_VERIFY_PIN_DIRECT and
FEATURE_MODIFY_PIN_DIRECT if the reader supports it
Modified: trunk/Drivers/ccid/examples/scardcontrol.c
===================================================================
--- trunk/Drivers/ccid/examples/scardcontrol.c 2005-09-01 09:11:30 UTC (rev 1630)
+++ trunk/Drivers/ccid/examples/scardcontrol.c 2005-09-01 09:13:38 UTC (rev 1631)
@@ -35,9 +35,6 @@
#endif
#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) \
@@ -72,9 +69,12 @@
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;
+ DWORD modify_ioctl = 0;
SCARD_IO_REQUEST pioRecvPci;
+ PCSC_TLV_STRUCTURE *pcsc_tlv;
+ PIN_VERIFY_STRUCTURE *pin_verify;
+ PIN_MODIFY_STRUCTURE *pin_modify;
printf("SCardControl sample code\n");
printf("V 1.0 2004, Ludovic Rousseau <ludovic.rousseau at free.fr>\n");
@@ -194,12 +194,36 @@
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);
+
+ printf(" TLV (%ld): ", length);
+ for (i=0; i<length; i++)
+ printf("%02X ", bRecvBuffer[i]);
+ printf("\n");
+
+ PCSC_ERROR_CONT(rv, "SCardControl(CM_IOCTL_GET_FEATURE_REQUEST)")
+
+ if (length % sizeof(PCSC_TLV_STRUCTURE))
{
+ printf("Inconsistent result! Bad TLV values!\n");
+ goto end;
+ }
+
+ /* get the number of elements instead of the complete size */
+ length /= sizeof(PCSC_TLV_STRUCTURE);
+
+ pcsc_tlv = (PCSC_TLV_STRUCTURE *)bRecvBuffer;
+ for (i = 0; i < length; i++)
+ {
+ if (pcsc_tlv[i].tag == FEATURE_VERIFY_PIN_DIRECT)
+ verify_ioctl = pcsc_tlv[i].value;
+ if (pcsc_tlv[i].tag == FEATURE_MODIFY_PIN_DIRECT)
+ modify_ioctl = pcsc_tlv[i].value;
+ }
+
+ if (0 == verify_ioctl)
+ {
printf("Reader %s does not support PIN verification\n",
readers[reader_nb]);
goto end;
@@ -236,47 +260,138 @@
/* verify PIN */
printf(" Secure verify PIN\n");
+ pin_verify = (PIN_VERIFY_STRUCTURE *)bSendBuffer;
+
+ /* PC/SC v2.0.2 Part 10 PIN verification data structure */
+ pin_verify -> bTimerOut = 0x00;
+ pin_verify -> bTimerOut2 = 0x00;
+ pin_verify -> bmFormatString = 0x82;
+ pin_verify -> bmPINBlockString = 0x04;
+ pin_verify -> bmPINLengthFormat = 0x00;
+ pin_verify -> wPINMaxExtraDigit = HOST_TO_CCID(0x0408); /* Min Max */
+ pin_verify -> bEntryValidationCondition = 0x02;
+ pin_verify -> bNumberMessage = 0x00;
+ pin_verify -> wLangId = HOST_TO_CCID(0x0904);
+ pin_verify -> bMsgIndex = 0x00;
+ pin_verify -> bTeoPrologue[0] = 0x00;
+ pin_verify -> bTeoPrologue[1] = 0x00;
+ pin_verify -> bTeoPrologue[2] = 0x00;
+ /* pin_verify -> ulDataLength = 0x00; we don't know the size yet */
+
+ /* APDU: 00 20 00 00 08 30 30 30 30 00 00 00 00 */
offset = 0;
+ pin_verify -> abData[offset++] = 0x00; /* CLA */
+ pin_verify -> abData[offset++] = 0x20; /* INS: VERIFY */
+ pin_verify -> abData[offset++] = 0x00; /* P1 */
+ pin_verify -> abData[offset++] = 0x00; /* P2 */
+ pin_verify -> abData[offset++] = 0x08; /* Lc: 8 data bytes */
+ pin_verify -> abData[offset++] = 0x30; /* '0' */
+ pin_verify -> abData[offset++] = 0x30; /* '0' */
+ pin_verify -> abData[offset++] = 0x30; /* '0' */
+ pin_verify -> abData[offset++] = 0x30; /* '0' */
+ pin_verify -> abData[offset++] = 0x00; /* '\0' */
+ pin_verify -> abData[offset++] = 0x00; /* '\0' */
+ pin_verify -> abData[offset++] = 0x00; /* '\0' */
+ pin_verify -> abData[offset++] = 0x00; /* '\0' */
+ pin_verify -> ulDataLength = offset; /* APDU size */
- /* CCID PIN verification data structure */
- bSendBuffer[offset++] = 0x00; /* bTimeOut */
- bSendBuffer[offset++] = 0x82; /* bmFormatString */
- bSendBuffer[offset++] = 0x04; /* bmPINBlockString (PIN length) */
- bSendBuffer[offset++] = 0x00; /* bmPINLengthFormat */
- bSendBuffer[offset++] = 0x08; /* wPINMaxExtraDigit: max */
- bSendBuffer[offset++] = 0x04; /* wPINMaxExtraDigit: min */
- bSendBuffer[offset++] = 0x02; /* bEntryValidationCondition */
- bSendBuffer[offset++] = 0x00; /* bNumberMessage */
- bSendBuffer[offset++] = 0x04; /* wLangId: english */
- bSendBuffer[offset++] = 0x09; /* " */
- bSendBuffer[offset++] = 0x00; /* bMsgIndex */
- bSendBuffer[offset++] = 0x00; /* bTeoPrologue */
- bSendBuffer[offset++] = 0x00; /* " */
- bSendBuffer[offset++] = 0x00; /* " */
+ length = sizeof(PIN_VERIFY_STRUCTURE) + offset -1; /* -1 because PIN_VERIFY_STRUCTURE contains the first byte of abData[] */
+ printf(" command:");
+ for (i=0; i<length; i++)
+ printf(" %02X", bSendBuffer[i]);
+ printf("\n");
+ printf("Enter your PIN: ");
+ fflush(stdout);
+ rv = SCardControl(hCard, verify_ioctl, bSendBuffer,
+ length, bRecvBuffer, sizeof(bRecvBuffer), &length);
+
+ printf(" card response:");
+ for (i=0; i<length; i++)
+ printf(" %02X", bRecvBuffer[i]);
+ printf("\n");
+ PCSC_ERROR_CONT(rv, "SCardControl")
+
+ {
+#ifndef S_SPLINT_S
+ fd_set fd;
+#endif
+ struct timeval timeout;
+
+ FD_ZERO(&fd);
+ FD_SET(STDIN_FILENO, &fd); /* stdin */
+ timeout.tv_sec = 0; /* timeout = 0 */
+ timeout.tv_usec = 0;
+
+ /* we only try to read stdin if the pinpad is on a keyboard
+ * we do not read stdin for a SPR 532 for example */
+ if (select(1, &fd, NULL, NULL, &timeout) > 0)
+ {
+ /* read the fake digits */
+ char in[10]; /* 4 digits + \n + \0 */
+ (void)fgets(in, sizeof(in), stdin);
+
+ printf("keyboard sent: %s", in);
+ }
+ }
+
+ if (0 == modify_ioctl)
+ {
+ printf("Reader %s does not support PIN modification\n",
+ readers[reader_nb]);
+ goto end;
+ }
+
+ /* Modify PIN */
+ printf(" Secure modify PIN\n");
+ pin_modify = (PIN_MODIFY_STRUCTURE *)bSendBuffer;
+
+ /* PC/SC v2.0.2 Part 10 PIN verification data structure */
+ pin_modify -> bTimerOut = 0x00;
+ pin_modify -> bTimerOut2 = 0x00;
+ pin_modify -> bmFormatString = 0x82;
+ pin_modify -> bmPINBlockString = 0x04;
+ pin_modify -> bmPINLengthFormat = 0x00;
+ pin_modify -> bInsertionOffsetOld = 0x00;
+ pin_modify -> bInsertionOffsetNew = 0x00;
+ pin_modify -> wPINMaxExtraDigit = HOST_TO_CCID(0x0408); /* Min Max */
+ pin_modify -> bConfirmPIN = 0x00;
+ pin_modify -> bEntryValidationCondition = 0x02;
+ pin_modify -> bNumberMessage = 0x00;
+ pin_modify -> wLangId = HOST_TO_CCID(0x0904);
+ pin_modify -> bMsgIndex1 = 0x00;
+ pin_modify -> bMsgIndex2 = 0x00;
+ pin_modify -> bMsgIndex3 = 0x00;
+ pin_modify -> bTeoPrologue[0] = 0x00;
+ pin_modify -> bTeoPrologue[1] = 0x00;
+ pin_modify -> bTeoPrologue[2] = 0x00;
+ pin_modify -> ulDataLength = 0x0D;
+
/* APDU: 00 20 00 00 08 30 30 30 30 00 00 00 00 */
- bSendBuffer[offset++] = 0x00; /* CLA */
- bSendBuffer[offset++] = 0x20; /* INS: VERIFY */
- bSendBuffer[offset++] = 0x00; /* P1 */
- bSendBuffer[offset++] = 0x00; /* P2 */
- bSendBuffer[offset++] = 0x08; /* Lc: 8 data bytes */
- bSendBuffer[offset++] = 0x30; /* '0' */
- bSendBuffer[offset++] = 0x30; /* '0' */
- bSendBuffer[offset++] = 0x30; /* '0' */
- bSendBuffer[offset++] = 0x30; /* '0' */
- bSendBuffer[offset++] = 0x00; /* '\0' */
- bSendBuffer[offset++] = 0x00; /* '\0' */
- bSendBuffer[offset++] = 0x00; /* '\0' */
- bSendBuffer[offset++] = 0x00; /* '\0' */
+ offset = 0;
+ pin_modify -> abData[offset++] = 0x00; /* CLA */
+ pin_modify -> abData[offset++] = 0x20; /* INS: VERIFY */
+ pin_modify -> abData[offset++] = 0x00; /* P1 */
+ pin_modify -> abData[offset++] = 0x00; /* P2 */
+ pin_modify -> abData[offset++] = 0x08; /* Lc: 8 data bytes */
+ pin_modify -> abData[offset++] = 0x30; /* '0' */
+ pin_modify -> abData[offset++] = 0x30; /* '0' */
+ pin_modify -> abData[offset++] = 0x30; /* '0' */
+ pin_modify -> abData[offset++] = 0x30; /* '0' */
+ pin_modify -> abData[offset++] = 0x00; /* '\0' */
+ pin_modify -> abData[offset++] = 0x00; /* '\0' */
+ pin_modify -> abData[offset++] = 0x00; /* '\0' */
+ pin_modify -> abData[offset++] = 0x00; /* '\0' */
+ length = sizeof(PIN_VERIFY_STRUCTURE) + offset -1;
printf(" command:");
- for (i=0; i<offset; i++)
+ for (i=0; i<length; i++)
printf(" %02X", bSendBuffer[i]);
printf("\n");
printf("Enter your PIN: ");
fflush(stdout);
- rv = SCardControl(hCard, IOCTL_SMARTCARD_VENDOR_VERIFY_PIN, bSendBuffer,
- offset, bRecvBuffer, sizeof(bRecvBuffer), &length);
+ rv = SCardControl(hCard, verify_ioctl, bSendBuffer,
+ length, bRecvBuffer, sizeof(bRecvBuffer), &length);
printf(" card response:");
for (i=0; i<length; i++)
More information about the Pcsclite-cvs-commit
mailing list