Initial commit
[platform/upstream/ccid.git] / contrib / RSA_SecurID / RSA_SecurID_getpasswd.c
1 /*
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>
4
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.
9
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.
14
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.
18 */
19
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <winscard.h>
24
25 /* DWORD printf(3) format */
26 #ifdef __APPLE__
27 /* Apple defines DWORD as uint32_t so %d is correct */
28 #define LF
29 #else
30 /* pcsc-lite defines DWORD as unsigned long so %ld is correct */
31 #define LF "l"
32 #endif
33
34 /* PCSC error message pretty print */
35 #define PCSC_ERROR_EXIT(rv, text) \
36 if (rv != SCARD_S_SUCCESS) \
37 { \
38         printf(text ": %s (0x%"LF"X)\n", pcsc_stringify_error(rv), rv); \
39         goto end; \
40 }
41
42 int main(void)
43 {
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};
48         LONG rv;
49         SCARDCONTEXT hContext;
50         DWORD dwReaders;
51         LPSTR mszReaders = NULL;
52         char **readers = NULL;
53         SCARDHANDLE hCard;
54         DWORD dwActiveProtocol;
55         unsigned char bRecvBuffer[MAX_BUFFER_SIZE];
56         DWORD length;
57         SCARD_IO_REQUEST pioRecvPci;
58         SCARD_IO_REQUEST pioSendPci;
59
60         rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);
61         if (rv != SCARD_S_SUCCESS)
62         {
63                 printf("SCardEstablishContext: Cannot Connect to Resource Manager %"LF"X\n", rv);
64                 return 1;
65         }
66
67         /* Retrieve the available readers list */
68         rv = SCardListReaders(hContext, NULL, NULL, &dwReaders);
69         PCSC_ERROR_EXIT(rv, "SCardListReader");
70
71         if (dwReaders < 4)
72         {
73                 printf("No reader found!\n");
74                 return -1;
75         }
76
77         mszReaders = malloc(sizeof(char)*dwReaders);
78         if (mszReaders == NULL)
79         {
80                 printf("malloc: not enough memory\n");
81                 goto end;
82         }
83
84         rv = SCardListReaders(hContext, NULL, mszReaders, &dwReaders);
85         PCSC_ERROR_EXIT(rv, "SCardListReader");
86
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")
92
93     switch(dwActiveProtocol)
94     {
95         case SCARD_PROTOCOL_T0:
96             pioSendPci = *SCARD_PCI_T0;
97             break;
98         case SCARD_PROTOCOL_T1:
99             pioSendPci = *SCARD_PCI_T1;
100             break;
101         default:
102             printf("Unknown protocol\n");
103             return -1;
104     }
105
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))
112         {
113                 printf("cmd1 failed (%"LF"d): %02X%02X\n", length, bRecvBuffer[length-2],
114                         bRecvBuffer[length-1]);
115                 goto end;
116         }
117
118         /* non ISO APDU */
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))
124         {
125                 printf("cmd2 failed (%"LF"d) : %02X%02X\n", length,
126                         bRecvBuffer[length-2], bRecvBuffer[length-1]);
127                 goto end;
128         }
129
130         /* get the argument for cmd3 from result of cmd2 */
131         memcpy(cmd3+5, bRecvBuffer, 4);
132
133         /* non ISO APDU */
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))
139         {
140                 printf("cmd3 failed (%"LF"d): %02X%02X\n", length, bRecvBuffer[length-2],
141                         bRecvBuffer[length-1]);
142                 goto end;
143         }
144
145         /* non iSO APDU */
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))
151         {
152                 printf("cmd4 failed (%"LF"d): %02X%02X\n", length, bRecvBuffer[length-2],
153                         bRecvBuffer[length-1]);
154                 goto end;
155         }
156
157         printf("%02X%02X%02X\n", bRecvBuffer[2], bRecvBuffer[3], bRecvBuffer[4]);
158
159 end:
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),
164             rv);
165
166     /* free allocated memory */
167     free(mszReaders);
168     free(readers);
169
170         return 0;
171 } /* main */
172