|
Packit Service |
aee942 |
/*
|
|
Packit Service |
aee942 |
RSA_SecurID_getpasswd.c: get the one-use password from a RSA sid-800 token
|
|
Packit Service |
aee942 |
Copyright (C) 2006 Ludovic Rousseau <ludovic.rousseau@free.fr>
|
|
Packit Service |
aee942 |
|
|
Packit Service |
aee942 |
This program is free software; you can redistribute it and/or modify
|
|
Packit Service |
aee942 |
it under the terms of the GNU General Public License as published by
|
|
Packit Service |
aee942 |
the Free Software Foundation; either version 2 of the License, or
|
|
Packit Service |
aee942 |
(at your option) any later version.
|
|
Packit Service |
aee942 |
|
|
Packit Service |
aee942 |
This program is distributed in the hope that it will be useful,
|
|
Packit Service |
aee942 |
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit Service |
aee942 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
Packit Service |
aee942 |
GNU General Public License for more details.
|
|
Packit Service |
aee942 |
|
|
Packit Service |
aee942 |
You should have received a copy of the GNU General Public License along
|
|
Packit Service |
aee942 |
with this program; if not, write to the Free Software Foundation, Inc., 51
|
|
Packit Service |
aee942 |
Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
Packit Service |
aee942 |
*/
|
|
Packit Service |
aee942 |
|
|
Packit Service |
aee942 |
#include <stdio.h>
|
|
Packit Service |
aee942 |
#include <stdlib.h>
|
|
Packit Service |
aee942 |
#include <string.h>
|
|
Packit Service |
aee942 |
#include <winscard.h>
|
|
Packit Service |
aee942 |
|
|
Packit Service |
aee942 |
/* DWORD printf(3) format */
|
|
Packit Service |
aee942 |
#ifdef __APPLE__
|
|
Packit Service |
aee942 |
/* Apple defines DWORD as uint32_t so %d is correct */
|
|
Packit Service |
aee942 |
#define LF
|
|
Packit Service |
aee942 |
#else
|
|
Packit Service |
aee942 |
/* pcsc-lite defines DWORD as unsigned long so %ld is correct */
|
|
Packit Service |
aee942 |
#define LF "l"
|
|
Packit Service |
aee942 |
#endif
|
|
Packit Service |
aee942 |
|
|
Packit Service |
aee942 |
/* PCSC error message pretty print */
|
|
Packit Service |
aee942 |
#define PCSC_ERROR_EXIT(rv, text) \
|
|
Packit Service |
aee942 |
if (rv != SCARD_S_SUCCESS) \
|
|
Packit Service |
aee942 |
{ \
|
|
Packit Service |
aee942 |
printf(text ": %s (0x%"LF"X)\n", pcsc_stringify_error(rv), rv); \
|
|
Packit Service |
aee942 |
goto end; \
|
|
Packit Service |
aee942 |
}
|
|
Packit Service |
aee942 |
|
|
Packit Service |
aee942 |
int main(void)
|
|
Packit Service |
aee942 |
{
|
|
Packit Service |
aee942 |
unsigned char cmd1[] = { 0x00, 0xa4, 0x04, 0x00, 0x0a, 0xa0, 0x00, 0x00, 0x00, 0x63, 0x86, 0x53, 0x49, 0x44, 0x01};
|
|
Packit Service |
aee942 |
unsigned char cmd2[] = { 0x80, 0x56, 0x00, 0x00, 0x04 };
|
|
Packit Service |
aee942 |
unsigned char cmd3[] = { 0x80, 0x48, 0x00, 0x00, 0x04, 0xff, 0xff, 0xff, 0xff };
|
|
Packit Service |
aee942 |
unsigned char cmd4[] = { 0x80, 0x44, 0x00, 0x00, 0x05};
|
|
Packit Service |
aee942 |
LONG rv;
|
|
Packit Service |
aee942 |
SCARDCONTEXT hContext;
|
|
Packit Service |
aee942 |
DWORD dwReaders;
|
|
Packit Service |
aee942 |
LPSTR mszReaders = NULL;
|
|
Packit Service |
aee942 |
char **readers = NULL;
|
|
Packit Service |
aee942 |
SCARDHANDLE hCard;
|
|
Packit Service |
aee942 |
DWORD dwActiveProtocol;
|
|
Packit Service |
aee942 |
unsigned char bRecvBuffer[MAX_BUFFER_SIZE];
|
|
Packit Service |
aee942 |
DWORD length;
|
|
Packit Service |
aee942 |
SCARD_IO_REQUEST pioRecvPci;
|
|
Packit Service |
aee942 |
SCARD_IO_REQUEST pioSendPci;
|
|
Packit Service |
aee942 |
|
|
Packit Service |
aee942 |
rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);
|
|
Packit Service |
aee942 |
if (rv != SCARD_S_SUCCESS)
|
|
Packit Service |
aee942 |
{
|
|
Packit Service |
aee942 |
printf("SCardEstablishContext: Cannot Connect to Resource Manager %"LF"X\n", rv);
|
|
Packit Service |
aee942 |
return 1;
|
|
Packit Service |
aee942 |
}
|
|
Packit Service |
aee942 |
|
|
Packit Service |
aee942 |
/* Retrieve the available readers list */
|
|
Packit Service |
aee942 |
rv = SCardListReaders(hContext, NULL, NULL, &dwReaders);
|
|
Packit Service |
aee942 |
PCSC_ERROR_EXIT(rv, "SCardListReader");
|
|
Packit Service |
aee942 |
|
|
Packit Service |
aee942 |
if (dwReaders < 4)
|
|
Packit Service |
aee942 |
{
|
|
Packit Service |
aee942 |
printf("No reader found!\n");
|
|
Packit Service |
aee942 |
return -1;
|
|
Packit Service |
aee942 |
}
|
|
Packit Service |
aee942 |
|
|
Packit Service |
aee942 |
mszReaders = malloc(sizeof(char)*dwReaders);
|
|
Packit Service |
aee942 |
if (mszReaders == NULL)
|
|
Packit Service |
aee942 |
{
|
|
Packit Service |
aee942 |
printf("malloc: not enough memory\n");
|
|
Packit Service |
aee942 |
goto end;
|
|
Packit Service |
aee942 |
}
|
|
Packit Service |
aee942 |
|
|
Packit Service |
aee942 |
rv = SCardListReaders(hContext, NULL, mszReaders, &dwReaders);
|
|
Packit Service |
aee942 |
PCSC_ERROR_EXIT(rv, "SCardListReader");
|
|
Packit Service |
aee942 |
|
|
Packit Service |
aee942 |
/* connect to the first reader */
|
|
Packit Service |
aee942 |
dwActiveProtocol = -1;
|
|
Packit Service |
aee942 |
rv = SCardConnect(hContext, mszReaders, SCARD_SHARE_EXCLUSIVE,
|
|
Packit Service |
aee942 |
SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &hCard, &dwActiveProtocol);
|
|
Packit Service |
aee942 |
PCSC_ERROR_EXIT(rv, "SCardConnect")
|
|
Packit Service |
aee942 |
|
|
Packit Service |
aee942 |
switch(dwActiveProtocol)
|
|
Packit Service |
aee942 |
{
|
|
Packit Service |
aee942 |
case SCARD_PROTOCOL_T0:
|
|
Packit Service |
aee942 |
pioSendPci = *SCARD_PCI_T0;
|
|
Packit Service |
aee942 |
break;
|
|
Packit Service |
aee942 |
case SCARD_PROTOCOL_T1:
|
|
Packit Service |
aee942 |
pioSendPci = *SCARD_PCI_T1;
|
|
Packit Service |
aee942 |
break;
|
|
Packit Service |
aee942 |
default:
|
|
Packit Service |
aee942 |
printf("Unknown protocol\n");
|
|
Packit Service |
aee942 |
return -1;
|
|
Packit Service |
aee942 |
}
|
|
Packit Service |
aee942 |
|
|
Packit Service |
aee942 |
/* APDU select applet */
|
|
Packit Service |
aee942 |
length = sizeof(bRecvBuffer);
|
|
Packit Service |
aee942 |
rv = SCardTransmit(hCard, &pioSendPci, cmd1, sizeof cmd1,
|
|
Packit Service |
aee942 |
&pioRecvPci, bRecvBuffer, &length);
|
|
Packit Service |
aee942 |
PCSC_ERROR_EXIT(rv, "SCardTransmit")
|
|
Packit Service |
aee942 |
if ((length != 2) || (bRecvBuffer[0] != 0x90) || (bRecvBuffer[1] != 0x00))
|
|
Packit Service |
aee942 |
{
|
|
Packit Service |
aee942 |
printf("cmd1 failed (%"LF"d): %02X%02X\n", length, bRecvBuffer[length-2],
|
|
Packit Service |
aee942 |
bRecvBuffer[length-1]);
|
|
Packit Service |
aee942 |
goto end;
|
|
Packit Service |
aee942 |
}
|
|
Packit Service |
aee942 |
|
|
Packit Service |
aee942 |
/* non ISO APDU */
|
|
Packit Service |
aee942 |
length = sizeof(bRecvBuffer);
|
|
Packit Service |
aee942 |
rv = SCardTransmit(hCard, &pioSendPci, cmd2, sizeof cmd2,
|
|
Packit Service |
aee942 |
&pioRecvPci, bRecvBuffer, &length);
|
|
Packit Service |
aee942 |
PCSC_ERROR_EXIT(rv, "SCardTransmit")
|
|
Packit Service |
aee942 |
if ((length != 6) || (bRecvBuffer[4] != 0x90) || (bRecvBuffer[5] != 0x00))
|
|
Packit Service |
aee942 |
{
|
|
Packit Service |
aee942 |
printf("cmd2 failed (%"LF"d) : %02X%02X\n", length,
|
|
Packit Service |
aee942 |
bRecvBuffer[length-2], bRecvBuffer[length-1]);
|
|
Packit Service |
aee942 |
goto end;
|
|
Packit Service |
aee942 |
}
|
|
Packit Service |
aee942 |
|
|
Packit Service |
aee942 |
/* get the argument for cmd3 from result of cmd2 */
|
|
Packit Service |
aee942 |
memcpy(cmd3+5, bRecvBuffer, 4);
|
|
Packit Service |
aee942 |
|
|
Packit Service |
aee942 |
/* non ISO APDU */
|
|
Packit Service |
aee942 |
length = sizeof(bRecvBuffer);
|
|
Packit Service |
aee942 |
rv = SCardTransmit(hCard, &pioSendPci, cmd3, sizeof cmd3,
|
|
Packit Service |
aee942 |
&pioRecvPci, bRecvBuffer, &length);
|
|
Packit Service |
aee942 |
PCSC_ERROR_EXIT(rv, "SCardTransmit")
|
|
Packit Service |
aee942 |
if ((length != 2) || (bRecvBuffer[0] != 0x90) || (bRecvBuffer[1] != 0x00))
|
|
Packit Service |
aee942 |
{
|
|
Packit Service |
aee942 |
printf("cmd3 failed (%"LF"d): %02X%02X\n", length, bRecvBuffer[length-2],
|
|
Packit Service |
aee942 |
bRecvBuffer[length-1]);
|
|
Packit Service |
aee942 |
goto end;
|
|
Packit Service |
aee942 |
}
|
|
Packit Service |
aee942 |
|
|
Packit Service |
aee942 |
/* non iSO APDU */
|
|
Packit Service |
aee942 |
length = sizeof(bRecvBuffer);
|
|
Packit Service |
aee942 |
rv = SCardTransmit(hCard, &pioSendPci, cmd4, sizeof cmd4,
|
|
Packit Service |
aee942 |
&pioRecvPci, bRecvBuffer, &length);
|
|
Packit Service |
aee942 |
PCSC_ERROR_EXIT(rv, "SCardTransmit")
|
|
Packit Service |
aee942 |
if ((length != 7) || (bRecvBuffer[5] != 0x90) || (bRecvBuffer[6] != 0x00))
|
|
Packit Service |
aee942 |
{
|
|
Packit Service |
aee942 |
printf("cmd4 failed (%"LF"d): %02X%02X\n", length, bRecvBuffer[length-2],
|
|
Packit Service |
aee942 |
bRecvBuffer[length-1]);
|
|
Packit Service |
aee942 |
goto end;
|
|
Packit Service |
aee942 |
}
|
|
Packit Service |
aee942 |
|
|
Packit Service |
aee942 |
printf("%02X%02X%02X\n", bRecvBuffer[2], bRecvBuffer[3], bRecvBuffer[4]);
|
|
Packit Service |
aee942 |
|
|
Packit Service |
aee942 |
end:
|
|
Packit Service |
aee942 |
/* We try to leave things as clean as possible */
|
|
Packit Service |
aee942 |
rv = SCardReleaseContext(hContext);
|
|
Packit Service |
aee942 |
if (rv != SCARD_S_SUCCESS)
|
|
Packit Service |
aee942 |
printf("SCardReleaseContext: %s (0x%"LF"X)\n", pcsc_stringify_error(rv),
|
|
Packit Service |
aee942 |
rv);
|
|
Packit Service |
aee942 |
|
|
Packit Service |
aee942 |
/* free allocated memory */
|
|
Packit Service |
aee942 |
free(mszReaders);
|
|
Packit Service |
aee942 |
free(readers);
|
|
Packit Service |
aee942 |
|
|
Packit Service |
aee942 |
return 0;
|
|
Packit Service |
aee942 |
} /* main */
|
|
Packit Service |
aee942 |
|