Blame contrib/RSA_SecurID/RSA_SecurID_getpasswd.c

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