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/* PCSC error message pretty print */ 26#define PCSC_ERROR_EXIT(rv, text) \ 27if (rv != SCARD_S_SUCCESS) \ 28{ \ 29 printf(text ": %s (0x%ulX)\n", pcsc_stringify_error(rv), rv); \ 30 goto end; \ 31} 32 33int main(void) 34{ 35 unsigned char cmd1[] = { 0x00, 0xa4, 0x04, 0x00, 0x0a, 0xa0, 0x00, 0x00, 0x00, 0x63, 0x86, 0x53, 0x49, 0x44, 0x01}; 36 unsigned char cmd2[] = { 0x80, 0x56, 0x00, 0x00, 0x04 }; 37 unsigned char cmd3[] = { 0x80, 0x48, 0x00, 0x00, 0x04, 0xff, 0xff, 0xff, 0xff }; 38 unsigned char cmd4[] = { 0x80, 0x44, 0x00, 0x00, 0x05}; 39 LONG rv; 40 SCARDCONTEXT hContext; 41 DWORD dwReaders; 42 LPSTR mszReaders = NULL; 43 char **readers = NULL; 44 SCARDHANDLE hCard; 45 DWORD dwActiveProtocol; 46 unsigned char bRecvBuffer[MAX_BUFFER_SIZE]; 47 DWORD length; 48 SCARD_IO_REQUEST pioRecvPci; 49 SCARD_IO_REQUEST pioSendPci; 50 51 rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext); 52 if (rv != SCARD_S_SUCCESS) 53 { 54 printf("SCardEstablishContext: Cannot Connect to Resource Manager %ulX\n", rv); 55 return 1; 56 } 57 58 /* Retrieve the available readers list */ 59 rv = SCardListReaders(hContext, NULL, NULL, &dwReaders); 60 PCSC_ERROR_EXIT(rv, "SCardListReader"); 61 62 if (dwReaders < 4) 63 { 64 printf("No reader found!\n"); 65 return -1; 66 } 67 68 mszReaders = malloc(sizeof(char)*dwReaders); 69 if (mszReaders == NULL) 70 { 71 printf("malloc: not enough memory\n"); 72 goto end; 73 } 74 75 rv = SCardListReaders(hContext, NULL, mszReaders, &dwReaders); 76 PCSC_ERROR_EXIT(rv, "SCardListReader"); 77 78 /* connect to the first reader */ 79 dwActiveProtocol = -1; 80 rv = SCardConnect(hContext, mszReaders, SCARD_SHARE_EXCLUSIVE, 81 SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &hCard, &dwActiveProtocol); 82 PCSC_ERROR_EXIT(rv, "SCardConnect") 83 84 switch(dwActiveProtocol) 85 { 86 case SCARD_PROTOCOL_T0: 87 pioSendPci = *SCARD_PCI_T0; 88 break; 89 case SCARD_PROTOCOL_T1: 90 pioSendPci = *SCARD_PCI_T1; 91 break; 92 default: 93 printf("Unknown protocol\n"); 94 return -1; 95 } 96 97 /* APDU select applet */ 98 length = sizeof(bRecvBuffer); 99 rv = SCardTransmit(hCard, &pioSendPci, cmd1, sizeof cmd1, 100 &pioRecvPci, bRecvBuffer, &length); 101 PCSC_ERROR_EXIT(rv, "SCardTransmit") 102 if ((length != 2) || (bRecvBuffer[0] != 0x90) || (bRecvBuffer[1] != 0x00)) 103 { 104 printf("cmd1 failed (%uld): %02X%02X\n", length, bRecvBuffer[length-2], 105 bRecvBuffer[length-1]); 106 goto end; 107 } 108 109 /* non ISO APDU */ 110 length = sizeof(bRecvBuffer); 111 rv = SCardTransmit(hCard, &pioSendPci, cmd2, sizeof cmd2, 112 &pioRecvPci, bRecvBuffer, &length); 113 PCSC_ERROR_EXIT(rv, "SCardTransmit") 114 if ((length != 6) || (bRecvBuffer[4] != 0x90) || (bRecvBuffer[5] != 0x00)) 115 { 116 printf("cmd2 failed (%uld) : %02X%02X\n", length, bRecvBuffer[length-2], 117 bRecvBuffer[length-1]); 118 goto end; 119 } 120 121 /* get the argument for cmd3 from result of cmd2 */ 122 memcpy(cmd3+5, bRecvBuffer, 4); 123 124 /* non ISO APDU */ 125 length = sizeof(bRecvBuffer); 126 rv = SCardTransmit(hCard, &pioSendPci, cmd3, sizeof cmd3, 127 &pioRecvPci, bRecvBuffer, &length); 128 PCSC_ERROR_EXIT(rv, "SCardTransmit") 129 if ((length != 2) || (bRecvBuffer[0] != 0x90) || (bRecvBuffer[1] != 0x00)) 130 { 131 printf("cmd3 failed (%uld): %02X%02X\n", length, bRecvBuffer[length-2], 132 bRecvBuffer[length-1]); 133 goto end; 134 } 135 136 /* non iSO APDU */ 137 length = sizeof(bRecvBuffer); 138 rv = SCardTransmit(hCard, &pioSendPci, cmd4, sizeof cmd4, 139 &pioRecvPci, bRecvBuffer, &length); 140 PCSC_ERROR_EXIT(rv, "SCardTransmit") 141 if ((length != 7) || (bRecvBuffer[5] != 0x90) || (bRecvBuffer[6] != 0x00)) 142 { 143 printf("cmd4 failed (%uld): %02X%02X\n", length, bRecvBuffer[length-2], 144 bRecvBuffer[length-1]); 145 goto end; 146 } 147 148 printf("%02X%02X%02X\n", bRecvBuffer[2], bRecvBuffer[3], bRecvBuffer[4]); 149 150end: 151 /* We try to leave things as clean as possible */ 152 rv = SCardReleaseContext(hContext); 153 if (rv != SCARD_S_SUCCESS) 154 printf("SCardReleaseContext: %s (0x%ulX)\n", pcsc_stringify_error(rv), 155 rv); 156 157 /* free allocated memory */ 158 free(mszReaders); 159 free(readers); 160 161 return 0; 162} /* main */ 163 164