2 RSA_SecurID_getpasswd.c: get the one-use password from a RSA sid-800 token
3 Copyright (C) 2006 Ludovic Rousseau <ludovic.rousseau@free.fr>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc., 51
17 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
25 /* DWORD printf(3) format */
27 /* Apple defines DWORD as uint32_t so %d is correct */
30 /* pcsc-lite defines DWORD as unsigned long so %ld is correct */
34 /* PCSC error message pretty print */
35 #define PCSC_ERROR_EXIT(rv, text) \
36 if (rv != SCARD_S_SUCCESS) \
38 printf(text ": %s (0x%"LF"X)\n", pcsc_stringify_error(rv), rv); \
44 unsigned char cmd1[] = { 0x00, 0xa4, 0x04, 0x00, 0x0a, 0xa0, 0x00, 0x00, 0x00, 0x63, 0x86, 0x53, 0x49, 0x44, 0x01};
45 unsigned char cmd2[] = { 0x80, 0x56, 0x00, 0x00, 0x04 };
46 unsigned char cmd3[] = { 0x80, 0x48, 0x00, 0x00, 0x04, 0xff, 0xff, 0xff, 0xff };
47 unsigned char cmd4[] = { 0x80, 0x44, 0x00, 0x00, 0x05};
49 SCARDCONTEXT hContext;
51 LPSTR mszReaders = NULL;
52 char **readers = NULL;
54 DWORD dwActiveProtocol;
55 unsigned char bRecvBuffer[MAX_BUFFER_SIZE];
57 SCARD_IO_REQUEST pioRecvPci;
58 SCARD_IO_REQUEST pioSendPci;
60 rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);
61 if (rv != SCARD_S_SUCCESS)
63 printf("SCardEstablishContext: Cannot Connect to Resource Manager %"LF"X\n", rv);
67 /* Retrieve the available readers list */
68 rv = SCardListReaders(hContext, NULL, NULL, &dwReaders);
69 PCSC_ERROR_EXIT(rv, "SCardListReader");
73 printf("No reader found!\n");
77 mszReaders = malloc(sizeof(char)*dwReaders);
78 if (mszReaders == NULL)
80 printf("malloc: not enough memory\n");
84 rv = SCardListReaders(hContext, NULL, mszReaders, &dwReaders);
85 PCSC_ERROR_EXIT(rv, "SCardListReader");
87 /* connect to the first reader */
88 dwActiveProtocol = -1;
89 rv = SCardConnect(hContext, mszReaders, SCARD_SHARE_EXCLUSIVE,
90 SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &hCard, &dwActiveProtocol);
91 PCSC_ERROR_EXIT(rv, "SCardConnect")
93 switch(dwActiveProtocol)
95 case SCARD_PROTOCOL_T0:
96 pioSendPci = *SCARD_PCI_T0;
98 case SCARD_PROTOCOL_T1:
99 pioSendPci = *SCARD_PCI_T1;
102 printf("Unknown protocol\n");
106 /* APDU select applet */
107 length = sizeof(bRecvBuffer);
108 rv = SCardTransmit(hCard, &pioSendPci, cmd1, sizeof cmd1,
109 &pioRecvPci, bRecvBuffer, &length);
110 PCSC_ERROR_EXIT(rv, "SCardTransmit")
111 if ((length != 2) || (bRecvBuffer[0] != 0x90) || (bRecvBuffer[1] != 0x00))
113 printf("cmd1 failed (%"LF"d): %02X%02X\n", length, bRecvBuffer[length-2],
114 bRecvBuffer[length-1]);
119 length = sizeof(bRecvBuffer);
120 rv = SCardTransmit(hCard, &pioSendPci, cmd2, sizeof cmd2,
121 &pioRecvPci, bRecvBuffer, &length);
122 PCSC_ERROR_EXIT(rv, "SCardTransmit")
123 if ((length != 6) || (bRecvBuffer[4] != 0x90) || (bRecvBuffer[5] != 0x00))
125 printf("cmd2 failed (%"LF"d) : %02X%02X\n", length,
126 bRecvBuffer[length-2], bRecvBuffer[length-1]);
130 /* get the argument for cmd3 from result of cmd2 */
131 memcpy(cmd3+5, bRecvBuffer, 4);
134 length = sizeof(bRecvBuffer);
135 rv = SCardTransmit(hCard, &pioSendPci, cmd3, sizeof cmd3,
136 &pioRecvPci, bRecvBuffer, &length);
137 PCSC_ERROR_EXIT(rv, "SCardTransmit")
138 if ((length != 2) || (bRecvBuffer[0] != 0x90) || (bRecvBuffer[1] != 0x00))
140 printf("cmd3 failed (%"LF"d): %02X%02X\n", length, bRecvBuffer[length-2],
141 bRecvBuffer[length-1]);
146 length = sizeof(bRecvBuffer);
147 rv = SCardTransmit(hCard, &pioSendPci, cmd4, sizeof cmd4,
148 &pioRecvPci, bRecvBuffer, &length);
149 PCSC_ERROR_EXIT(rv, "SCardTransmit")
150 if ((length != 7) || (bRecvBuffer[5] != 0x90) || (bRecvBuffer[6] != 0x00))
152 printf("cmd4 failed (%"LF"d): %02X%02X\n", length, bRecvBuffer[length-2],
153 bRecvBuffer[length-1]);
157 printf("%02X%02X%02X\n", bRecvBuffer[2], bRecvBuffer[3], bRecvBuffer[4]);
160 /* We try to leave things as clean as possible */
161 rv = SCardReleaseContext(hContext);
162 if (rv != SCARD_S_SUCCESS)
163 printf("SCardReleaseContext: %s (0x%"LF"X)\n", pcsc_stringify_error(rv),
166 /* free allocated memory */