[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