Blame contrib/RSA_SecurID/RSA_SecurID_getpasswd.c

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