[Pcsclite-cvs-commit] r1947 - trunk/PCSC/doc

Ludovic Rousseau rousseau at costa.debian.org
Mon Mar 20 10:35:07 CET 2006


Author: rousseau
Date: 2006-03-20 09:35:04 +0000 (Mon, 20 Mar 2006)
New Revision: 1947

Modified:
   trunk/PCSC/doc/pcsc-lite.bib
   trunk/PCSC/doc/pcsc-lite.tex
Log:
document VERIFY_PIN and MODIFY_PIN commands using PCSCv2 part 10
instead of the "proprietary" mechanism now unsupported


Modified: trunk/PCSC/doc/pcsc-lite.bib
===================================================================
--- trunk/PCSC/doc/pcsc-lite.bib	2006-03-20 09:17:49 UTC (rev 1946)
+++ trunk/PCSC/doc/pcsc-lite.bib	2006-03-20 09:35:04 UTC (rev 1947)
@@ -4,6 +4,12 @@
 	note = "\url{http://www.pcscworkgroup.com/}"
 }
 
+ at misc{pcsc_v2_part10,
+	key = "PC/SC workgroup",
+	title = "{Interoperability Specification for ICCs and Personal Computer Systems, Part 10 IFDs with Secure Pin Entry Capabilities}",
+	note = "\url{http://www.pcscworkgroup.com/specifications/specdownload.php}"
+}
+
 @misc{ccid_spec,
 	key = "CCID",
 	title = "{Universal Serial Bus, Device Class Specification for USB Chip/Smart Card Interface Devices}",

Modified: trunk/PCSC/doc/pcsc-lite.tex
===================================================================
--- trunk/PCSC/doc/pcsc-lite.tex	2006-03-20 09:17:49 UTC (rev 1946)
+++ trunk/PCSC/doc/pcsc-lite.tex	2006-03-20 09:35:04 UTC (rev 1947)
@@ -1563,98 +1563,111 @@
 
 
 %---------%---------%---------%---------%---------%---------
-\subsection{VERIFY\_PIN}
+\subsection{VERIFY\_PIN and MODIFY\_PIN}
 
-This command is used to perform a secure PIN verification using a smart
-card reader equipped with a keyboard or keypad.
-
 The CCID specification~\cite{ccid_spec} describes a
-\texttt{PC\_to\_RDR\_Secure} command to perform such a PIN verification.
+\texttt{PC\_to\_RDR\_Secure} command to perform a PIN verification or
+PIN modification without sending the PIN to the host. The reader must
+have a keyboard, and optionnaly a display.
 
+The command format is described in the PCSCv2 part 10
+specifications~\cite{pcsc_v2_part10}.
+
 The \texttt{bSendBuffer} to pass to \texttt{SCardControl()} contains:
 \begin{itemize}
+\item the CCID \texttt{abPINDataStructure}
+
+This is the CCID structure used to parameter the PIN verification
+command.
+
 \item the VERIFY APDU
 
 That is the APDU sent to the card with the PIN code values replaced by
 the actually entered PIN code. See the CCID
 specification~\cite{ccid_spec} for a more precise descruption.
 
-\item the CCID \texttt{abPINDataStructure}
-
-This is the CCID structure used to parameter the PIN verification
-command.
-
-You can omit to send the 3 bytes of the \texttt{bTeoPrologue} field.
-This field is only significant with a T=1 card.
-
 \end{itemize}
 
 \example
 
 \begin{verbatim}
-#include <wintypes.h>
 #include <winscard.h>
+#include <reader.h>
 
-#define SCARD_CTL_CODE(code) (0x42000000 + (code))
-#define IOCTL_SMARTCARD_VENDOR_VERIFY_PIN SCARD_CTL_CODE(2)
-
 LONG rv;
 SCARDHANDLE hCard;
-char attribute[1];
-DWORD attribute_length;
+unsigned char bSendBuffer[MAX_BUFFER_SIZE];
+unsigned char bRecvBuffer[MAX_BUFFER_SIZE];
+DWORD verify_ioctl = 0;
+DWORD modify_ioctl = 0;
+PIN_VERIFY_STRUCTURE *pin_verify;
 
 /* does the reader support PIN verification? */
-attribute_length = sizeof(attribute);
-rv = SCardGetAttrib(hCard, IOCTL_SMARTCARD_VENDOR_VERIFY_PIN, attribute,
-    &attribute_length);
-if (TRUE == attribute[0])
+rv = SCardControl(hCard, CM_IOCTL_GET_FEATURE_REQUEST, NULL, 0,
+    bRecvBuffer, sizeof(bRecvBuffer), &length);
+
+/* 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++)
 {
-    int i, offset;
-    unsigned char bSendBuffer[MAX_BUFFER_SIZE];
-    unsigned char bRecvBuffer[MAX_BUFFER_SIZE];
-    DWORD length;
+    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;
+}
 
-    /* verify PIN */
-    offset = 0;
-    /* 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' */
-    
-    /* 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++] = 0x04;   /* wPINMaxExtraDigit: min */
-    bSendBuffer[offset++] = 0x04;   /* wPINMaxExtraDigit: max */
-    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;   /* " */
-    
-    rv = SCardControl(hCard, IOCTL_SMARTCARD_VENDOR_VERIFY_PIN,
-        bSendBuffer, offset, bRecvBuffer, sizeof(bRecvBuffer), &length);
-    
-    printf(" card response:");
-    for (i=0; i<length; i++)
-        printf(" %02X", bRecvBuffer[i]);
-    printf("\n");
+if (0 == verify_ioctl)
+{
+    printf("Reader %s does not support PIN verification\n",
+        readers[reader_nb]);
+    return;
 }
+
+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_16(0x0408); /* Min Max */
+pin_verify -> bEntryValidationCondition = 0x02; /* validation key pressed */
+pin_verify -> bNumberMessage = 0x01;
+pin_verify -> wLangId = HOST_TO_CCID_16(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 = HOST_TO_CCID_32(offset);   /* APDU size */
+
+length = sizeof(PIN_VERIFY_STRUCTURE) + offset -1;
+    /* -1 because PIN_VERIFY_STRUCTURE contains the first byte of abData[] */
+
+printf("Enter your PIN: ");
+fflush(stdout);
+
+rv = SCardControl(hCard, verify_ioctl, bSendBuffer,
+    length, bRecvBuffer, sizeof(bRecvBuffer), &length);
 \end{verbatim}
 
 




More information about the Pcsclite-cvs-commit mailing list