Ejemplo n.º 1
24
static int testStatus(SCARDCONTEXT ctx, const char *readerName, const char *readerList)
{
	SCARDHANDLE hCard;
	DWORD       pcchReaderLen = 2048; //can this be calculated beforehand!?
	DWORD       pdwState;
	DWORD       pdwProtocol;
	BYTE        pbAtr[32];
	DWORD       pcbAtrLen = 32;
	char readerName2[2048];
	int  returnValue = 0;

	long        ret = SCardConnectA(ctx, readerName,
		SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0, &hCard, &pdwProtocol);

	CHECK_PCSC_RET("SCardConnect", ret);
	if (SCARD_S_SUCCESS == ret)
	{
		delayMS(200);

		// Normal case: fail position ----1
		ret = SCardStatusA(hCard, readerName2, &pcchReaderLen, &pdwState, &pdwProtocol, (LPBYTE) &pbAtr, &pcbAtrLen);
		if (ret != SCARD_S_SUCCESS)
			returnValue |= 1;

		// ReaderLen = 0: fail position ---1-
		pcchReaderLen  = NULL;
		readerName2[0] = '\0'; //make sure refreshed with new values
		ret            = SCardStatusA(hCard, (LPSTR) readerName2, &pcchReaderLen, &pdwState, &pdwProtocol, (LPBYTE) &pbAtr, &pcbAtrLen);
		if (ret != SCARD_S_SUCCESS)
			returnValue |= 2;

		// ReaderLen = 1: fail position ---1--
		pcchReaderLen  = 1;
		readerName2[0] = '\0'; //make sure refreshed with new values
		ret            = SCardStatusA(hCard, (LPSTR) readerName2, &pcchReaderLen, &pdwState, &pdwProtocol, (LPBYTE) &pbAtr, &pcbAtrLen);

		CHECK_PCSC_RET_PASS(0x4)

		//AtrLen = 0: fail position --1---
		pcchReaderLen = 2048;
		pcbAtrLen     = 0;
		ret           = SCardStatusA(hCard, (LPSTR) readerName2, &pcchReaderLen, &pdwState, &pdwProtocol, (LPBYTE) &pbAtr, &pcbAtrLen);
		if (ret != SCARD_S_SUCCESS)
			returnValue |= 8;

		//AtrLen = 1: fail position -1----
		pcbAtrLen = 1;
		ret       = SCardStatusA(hCard, (LPSTR) readerName2, &pcchReaderLen, &pdwState, &pdwProtocol, (LPBYTE) &pbAtr, &pcbAtrLen);
		if (ret != SCARD_S_SUCCESS)
			returnValue |= 16;

		//AtrLen = 33 (bigger than returned): fail position 1-----
		pcbAtrLen = 33;
		ret       = SCardStatusA(hCard, (LPSTR) readerName2, &pcchReaderLen, &pdwState, &pdwProtocol, (LPBYTE) &pbAtr, &pcbAtrLen);
		if (ret != SCARD_S_SUCCESS)
			returnValue |= 32;
	}

	return returnValue;
}
Ejemplo n.º 2
0
static int testMisc(SCARDCONTEXT hCard)
{
	int           ret      = 0;
	int           errCount = 0;
	unsigned char recvBuf[258];
	DWORD         recvBufLen = sizeof(recvBuf);

	ret = sendAPDU(hCard, "80:E4:00:00:1C", recvBuf, &recvBufLen);
	CHECK_PCSC_RET("sendAPDU(Get Card Data)", ret);
	if (recvBufLen != 0x1E || recvBuf[recvBufLen - 2] != 0x90 || recvBuf[recvBufLen - 1] != 0x00)
	{
		printf("ERR: Get Card Data didn't return 90 00\n");
		errCount++;
	}

	ret = sendAPDU(hCard, "80:E4:00:00:1B", recvBuf, &recvBufLen);
	CHECK_PCSC_RET("sendAPDU(Get Card Data)", ret);
	if (recvBufLen != 0x1D || recvBuf[recvBufLen - 2] != 0x61 || recvBuf[recvBufLen - 1] != 0x01)
	{
		printf("ERR: Get Card Data didn't return 61 01\n");
		errCount++;
	}

	return errCount;
}
Ejemplo n.º 3
0
static int testSCardGetAttrib(SCARDCONTEXT hContext, SCARDCONTEXT hCard)
{
	int           errCount = 0;
    BYTE          *attrib = NULL;
    DWORD         attribLen = SCARD_AUTOALLOCATE;

    int ret = SCardGetAttrib(hCard, SCARD_ATTR_ATR_STRING, (LPBYTE)&attrib, &attribLen);
	CHECK_PCSC_RET("SCardGetAttrib()", ret);

    if (attribLen < 8)
	{
        printf("ERR: SCardGetAttrib(): ATR length looks too small (%d) for a BE eID card\n", (int) attribLen);
		errCount++;
	}
    else if (attrib[0] != 0x3B)
    {
        printf("ERR: SCardGetAttrib(): ATR should start with 0x3B (instead of 0x%0x) for a BE eID card\n", attrib[0]);
		errCount++;
    }

    ret = SCardFreeMemory(hContext, attrib);
	CHECK_PCSC_RET("SCardFreeMemory()", ret);

    return errCount;
}
Ejemplo n.º 4
0
static long sendAPDUS(SCARDCONTEXT ctx, const char *readerName, int apduCount, const char **apdus)
{
	SCARDHANDLE hCard;
	DWORD       protocol;
	char        debugString[2048];

	printf("Using reader \"%s\"\n\n", readerName);
	sprintf_s(debugString, 2047, "Using reader \"%s\"\n\n", readerName);
	DebugMessage(debugString);

	long ret = SCardConnectA(ctx, readerName,
		SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0, &hCard, &protocol);
	CHECK_PCSC_RET("SCardConnect", ret);
	if (SCARD_S_SUCCESS == ret)
	{
		unsigned char recvBuf[258];
		DWORD         recvBufLen;
		for (int i = 0; i < apduCount; i++)
		{
			recvBufLen = (DWORD) sizeof(recvBuf);
			sendAPDU(hCard, apdus[i], recvBuf, &recvBufLen, NULL, 0, true);
		}

		ret = SCardDisconnect(hCard, SCARD_LEAVE_CARD);
		CHECK_PCSC_RET("SCardDisconnect", ret);
	}

	return 0;
}
Ejemplo n.º 5
0
static const char *listReaders(SCARDCONTEXT ctx, char *readerList, size_t readerListSize,
	bool printList, int readerNr)
{
	DWORD      dwLen       = (DWORD) readerListSize;
	const char *readerName = NULL;

	long       ret = SCardListReadersA(ctx, NULL, readerList, &dwLen);
	CHECK_PCSC_RET("SCardListReaders", ret);
	if (SCARD_S_SUCCESS == ret)
	{
		if (dwLen < 2)
			printf("No reader found, exiting\n");
		else
		{
			if (printList)
				printf("Reader list:\n");
			int readerCount = 0;
			while (readerList[0] != '\0')
			{
				if (printList)
					printf("  %d : %s\n", readerCount, readerList);
				if (readerCount == readerNr)
					readerName = readerList;
				readerList += strlen(readerList) + 1;
				readerCount++;
			}
		}
	}

	if (readerNr > 0 && NULL == readerName)
		printf("ERR: readernr (%d) too high, not enough readers present\n", readerNr);

	return readerName;
}
Ejemplo n.º 6
0
static int testListReadersA(SCARDCONTEXT hContext)
{
	int errCount = 0;

    char staticBuf[2000];
    DWORD staticLen = (DWORD) sizeof(staticBuf);
    long ret = SCardListReadersA(hContext, NULL, staticBuf, &staticLen);
    CHECK_PCSC_RET("SCardListReadersA(1)", ret);

    char *dynBuf = NULL;
    DWORD dynLen = 0;
    ret = SCardListReadersA(hContext, NULL, dynBuf, &dynLen);
    CHECK_PCSC_RET("SCardListReadersA(2)", ret);
    dynBuf = (char *) malloc(dynLen);
    ret = SCardListReadersA(hContext, NULL, dynBuf, &dynLen);
    CHECK_PCSC_RET("SCardListReadersA(1)", ret);

#ifndef MAC_OS_X
    char *autoBuf = NULL;
    DWORD autoLen = SCARD_AUTOALLOCATE;
    ret = SCardListReadersA(hContext, NULL, (char*) &autoBuf, &autoLen);
    CHECK_PCSC_RET("SCardListReadersA(3)", ret);

    if (staticLen != dynLen || dynLen != autoLen)
    {
		printf("ERR: SCardListReadersA() returned buffers lengths of different size\n");
        errCount++;
    }
    else if (memcmp(staticBuf, dynBuf, dynLen) != 0 || memcmp(dynBuf, autoBuf, dynLen) != 0)
    {
		printf("ERR: SCardListReadersA() returned different data\n");
        errCount++;
    }

    ret = SCardFreeMemory(hContext, autoBuf);
    CHECK_PCSC_RET("SCardFreeMemory()", ret);
#endif

    free(dynBuf);

    return errCount;
}
Ejemplo n.º 7
0
static long sendAPDU(SCARDHANDLE hCard, const char *apdu,
	unsigned char *recvBuf, DWORD *recvBufLen,
	const char *chipNr, int idx, bool doDump)
{
	unsigned char sendBuf[280];
	size_t        sendBufLen = sizeof(sendBuf);

	// Hex string -> byte array
	if (0 == hex2bin(apdu, sendBuf, &sendBufLen))
	{
		// Check the APDU
		if (sendBufLen < 4)
		{
			printf("ERR: APDU should be at least 4 bytes\n");
			DebugMessage("ERR: APDU should be at least 4 bytes\n");
		}
		else if (sendBufLen > 5 && (5 + sendBuf[4] != sendBufLen))
		{
			printf("ERR: wrong P3 byte in case 3 APDU\n");
			DebugMessage("ERR: wrong P3 byte in case 3 APDU\n");
		}
		else
		{
			if (doDump)
				dumphex2("  - sending ", sendBuf, sendBufLen);

#if TRANSMIT_DEBUG
			long ret = SCardTransmit2(hCard, &g_rgSCardT0Pci, sendBuf, (DWORD) sendBufLen, NULL, recvBuf, recvBufLen);
#else
			long ret = SCardTransmit(hCard, &g_rgSCardT0Pci, sendBuf, (DWORD) sendBufLen, NULL, recvBuf, recvBufLen);
#endif
			CHECK_PCSC_RET("SCardTransmit", ret);

			if (SCARD_S_SUCCESS == ret)
			{
				if (doDump)
				{
					dumphex2("    received ", recvBuf, *recvBufLen);
					printf("\n");
					DebugMessage("\n");
				}

				if (NULL != chipNr)
					StoreAPDUs(chipNr, idx, sendBuf, sendBufLen, recvBuf, *recvBufLen);

				return 0; // success
			}
		}
	}

	return -1; // failed
}
Ejemplo n.º 8
0
static void getStatusChange(SCARDCONTEXT ctx, const char *readerList, DWORD timeout)
{
	SCARD_READERSTATEA readerStates[MAX_READER_STATES];
	int                readerCount = 0;

	while (readerList[0] != '\0' && readerCount < MAX_READER_STATES)
	{
		readerStates[readerCount].szReader       = readerList;
		readerStates[readerCount].dwCurrentState = SCARD_STATE_UNAWARE;

		readerList += strlen(readerList) + 1;
		readerCount++;
	}

	if (timeout == (DWORD) -1)
	{
		timeout = INFINITE;
		printf("Remove insert card(s) (or not) and hit ENTER\n");
		printf("Or type 'q' stop\n\n");
	}
	else
		printf("Remove insert card(s) or type Ctrl-C to stop\n\n");


	char keybd = 0;
	while (keybd != 'q' && keybd != 'Q')
	{
		long ret = SCardGetStatusChangeA(ctx, timeout, readerStates, (DWORD) readerCount);
		if ((long) SCARD_S_SUCCESS != ret && (long) SCARD_E_TIMEOUT != ret)
		{
			CHECK_PCSC_RET("SCardGetStatusChange", ret);
			break;
		}

		if ((long) SCARD_E_TIMEOUT == ret)
			printf(" - timeout (nothing changed)\n");
		else
		{
			for (int i = 0; i < readerCount; i++)
			{
				printState(&readerStates[i]);
				readerStates[i].dwCurrentState = readerStates[i].dwEventState &
												 ~SCARD_STATE_CHANGED & ~SCARD_STATE_UNKNOWN;
			}
		}

		// Wait until the user hits a key
		if (timeout != (DWORD) -1)
			keybd = getchar();
	}
}
Ejemplo n.º 9
0
static std:: vector<BYTE> sendAPDU2(SCARDHANDLE hCard, const char *apdu,
	unsigned char *recvBuf, DWORD *recvBufLen,
	const char *chipNr, int idx, bool doDump)
{
	unsigned char      sendBuf[280];
	size_t             sendBufLen = sizeof(sendBuf);
	std:: vector<BYTE> result;

	// Hex string -> byte array
	if (0 == hex2bin(apdu, sendBuf, &sendBufLen))
	{
		// Check the APDU
		if (sendBufLen < 4)
		{
			printf("ERR: APDU should be at least 4 bytes\n");
			DebugMessage("ERR: APDU should be at least 4 bytes\n");
		}
		else if (sendBufLen > 5 && (size_t) (5 + sendBuf[4]) != sendBufLen)
		{
			printf("ERR: wrong P3 byte in case 3 APDU\n");
			DebugMessage("ERR: wrong P3 byte in case 3 APDU\n");
		}
		else
		{
			if (doDump)
				dumphex2("  - sending ", sendBuf, sendBufLen);

			//long ret = SCardTransmit(hCard,&g_rgSCardT0Pci, sendBuf, (DWORD) sendBufLen,NULL, recvBuf, recvBufLen);
			long ret = SCardTransmit2(hCard, &g_rgSCardT0Pci, sendBuf, (DWORD) sendBufLen, NULL, recvBuf, recvBufLen);

			CHECK_PCSC_RET("SCardTransmit", ret);

			if (SCARD_S_SUCCESS == ret)
			{
				for (int i = 0; i < (int) *recvBufLen; i++)
				{
					result.push_back(recvBuf[i]);
				}
				dumphex2("  - received ", recvBuf, (int) *recvBufLen);

				return result; // success
			}
		}
	}

	return result; // failed
}
Ejemplo n.º 10
0
static int testListReadersW(SCARDCONTEXT hContext)
{
	int errCount = 0;

    wchar_t staticBuf[2000];
    DWORD staticLen = (DWORD) (sizeof(staticBuf) / sizeof(wchar_t));
    long ret = SCardListReadersW(hContext, NULL, staticBuf, &staticLen);
	CHECK_PCSC_RET("SCardListReadersW(1)", ret);

    wchar_t *dynBuf = NULL;
    DWORD dynLen = 0;
    ret = SCardListReadersW(hContext, NULL, dynBuf, &dynLen);
	CHECK_PCSC_RET("SCardListReadersW(2)", ret);

    dynBuf = (wchar_t *) malloc(dynLen * sizeof(wchar_t));
    ret = SCardListReadersW(hContext, NULL, dynBuf, &dynLen);
	CHECK_PCSC_RET("SCardListReadersW(3)", ret);

    wchar_t *autoBuf = NULL;
    DWORD autoLen = SCARD_AUTOALLOCATE;
    ret = SCardListReadersW(hContext, NULL, (wchar_t*) &autoBuf, &autoLen);
	CHECK_PCSC_RET("SCardListReadersW(4)", ret);

    wchar_t *auto2Buf = NULL;
    DWORD auto2Len = SCARD_AUTOALLOCATE;
    ret = SCardListReadersW(hContext, NULL, (wchar_t*) &auto2Buf, &auto2Len);
	CHECK_PCSC_RET("SCardListReadersW(5)", ret);

    if (staticLen != dynLen || dynLen != autoLen || dynLen != auto2Len)
    {
		printf("ERR: SCardListReadersW() returned buffers lengths of different size\n");
        printf("  (staticLen = %d, dynLen = %d, autoLen = %d, auto2Len = %d\n", staticLen, dynLen, autoLen, auto2Len);
        errCount++;
    }
    else if (memcmp(staticBuf, dynBuf, dynLen) != 0 || memcmp(dynBuf, autoBuf, dynLen) != 0 ||
        memcmp(dynBuf, auto2Buf, dynLen) != 0)
    {
		printf("ERR: SCardListReadersW() returned different data\n");
        dump("  staticBuf = '%S'\n", staticBuf, dynLen);
        dump("  dynBuf = '%S'\n", dynBuf, dynLen);
        dump("  autoBuf = '%S'\n", autoBuf, dynLen);
        dump("  auto2Buf = '%S'\n", auto2Buf, dynLen);
        errCount++;
    }

    free(dynBuf);

    ret = SCardFreeMemory(hContext, autoBuf);
	CHECK_PCSC_RET("SCardFreeMemory()", ret);

    return errCount;
}
Ejemplo n.º 11
0
static int testCardFunctionality(SCARDCONTEXT ctx, const char *readerName)
{
	SCARDHANDLE hCard;
	DWORD       protocol;
	int         errCount = 0;

	printf("Using reader \"%s\"\n\n", readerName);

	long ret = SCardConnectA(ctx, readerName,
		SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0, &hCard, &protocol);

	CHECK_PCSC_RET("SCardConnect", ret);
	if (SCARD_S_SUCCESS == ret)
	{
		delayMS(200);

		printf("--- Get Response tests ---\n");
		errCount += testGetResponse(hCard);

		printf("\n--- Get Response tests within a transaction ---\n");
		ret = SCardBeginTransaction(hCard);
		CHECK_PCSC_RET("SCardBeginTransaction", ret);
		errCount += testGetResponse(hCard);
		ret       = SCardEndTransaction(hCard, SCARD_LEAVE_CARD);
		CHECK_PCSC_RET("SCardBeginTransaction", ret);

		printf("\n--- Test reading a long file ---\n");
		errCount += testLongFileRead(hCard);

		printf("\n--- Test reading a long file within a transaction ---\n");
		ret = SCardBeginTransaction(hCard);
		CHECK_PCSC_RET("SCardBeginTransaction", ret);
		errCount += testLongFileRead(hCard);
		ret       = SCardEndTransaction(hCard, SCARD_LEAVE_CARD);
		CHECK_PCSC_RET("SCardBeginTransaction", ret);

		printf("\n--- Misc tests ---\n");
		errCount += testMisc(hCard);

		ret = SCardDisconnect(hCard, SCARD_LEAVE_CARD);
		CHECK_PCSC_RET("SCardDisconnect", ret);
	}

	if (errCount == 0)
		printf("\nFunctional tests done, no errors\n");
	else
		printf("\nFunctional tests done, %d errors\n", errCount);

	return 0;
}
Ejemplo n.º 12
0
static int testScardReconnect(SCARDCONTEXT hCard, DWORD dwShareMode, DWORD dwPreferredProtocols)
{
	int           ret      = 0;
	int           errCount = 0;
    DWORD         dwAP = 0;

    for (int i = 0; i < 2; i++)
    {
        ret = SCardReconnect(hCard, dwShareMode, dwPreferredProtocols, SCARD_RESET_CARD, &dwAP);
        if (SCARD_S_SUCCESS != ret)
	    {
            printf("ERR: SCardReconnect(RESET) failed: 0x%0x (%d)\n", ret, ret);
		    errCount++;
	    }

        ret = SCardReconnect(hCard, dwShareMode, dwPreferredProtocols, SCARD_UNPOWER_CARD, &dwAP);
        if (SCARD_S_SUCCESS != ret)
	    {
            printf("ERR: SCardReconnect(UNPOWER) failed: 0x%0x (%d)\n", ret, ret);
		    errCount++;
	    }

        ret = SCardReconnect(hCard, dwShareMode, dwPreferredProtocols, SCARD_LEAVE_CARD, &dwAP);
        if (SCARD_S_SUCCESS != ret)
	    {
            printf("ERR: SCardReconnect(LEAVE) failed: 0x%0x (%d)\n", ret, ret);
		    errCount++;
	    }

        unsigned char recvBuf[2];
        DWORD recvBufLen = (DWORD) sizeof(recvBuf);
        ret = sendAPDU(hCard, "00:A4:04:0C:0C:A0:00:00:01:77:50:4B:43:53:2D:31:35", recvBuf, &recvBufLen);
	    CHECK_PCSC_RET("sendAPDU(Get Card Data)", ret);
    }

    return errCount;
}
Ejemplo n.º 13
0
static int testSCardState(SCARDCONTEXT hCard)
{
	int           errCount = 0;
    DWORD         dwState = 0;
    DWORD         dwProt = 0;
    BYTE          tucAtr[32];
    DWORD         dwAtrLen = (DWORD) sizeof(tucAtr);

    int ret = SCardState(hCard, &dwState, &dwProt, tucAtr, &dwAtrLen);
	CHECK_PCSC_RET("SCardState()", ret);

    if (dwState == 0)
	{
        printf("ERR: SCardState(): dwState not filled in\n");
		errCount++;
	}

    if (dwProt != SCARD_PROTOCOL_T0)
	{
        printf("ERR: SCardState(): dwProtocol should be SCARD_PROTOCOL_T0 (as least for a BE eID test)\n");
		errCount++;
	}

    if (dwAtrLen < 8)
	{
        printf("ERR: SCardState(): ATR length looks too small (%d) for a BE eID card\n", dwAtrLen);
		errCount++;
	}
    else if (tucAtr[0] != 0x3B)
	{
        printf("ERR: SCardState(): ATR should start with 0x3B (instead of 0x%0x) for a BE eID card\n", tucAtr[0]);
		errCount++;
	}

    return errCount;
}
Ejemplo n.º 14
0
static int testAPDUS(SCARDCONTEXT ctx, const char *readerName, const char *chipnrForCompare)
{
	SCARDHANDLE hCard;
	DWORD       protocol;
	int         err      = 0;
	int         errCount = 0;

	printf("Using reader \"%s\"\n\n", readerName);

	long ret = SCardConnectA(ctx, readerName,
		SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0, &hCard, &protocol);

	CHECK_PCSC_RET("SCardConnect", ret);
	if (SCARD_S_SUCCESS == ret)
	{
		delayMS(200);

		unsigned char recvBuf[258];
		DWORD         recvBufLen = sizeof(recvBuf);

		// If chipnrForCompare == NULL then we retrieve the chip number
		// of this card to store all APDUs
		const char *thisChipNr = NULL;
		char       chipNrBuf[2 * CHIP_NR_LEN + 1];
		if (NULL == chipnrForCompare)
		{
			thisChipNr = GetChipNrFromCard(hCard, chipNrBuf);
			if (NULL == thisChipNr)
			{
				SCardDisconnect(hCard, SCARD_LEAVE_CARD);
				return -1;
			}
		}

		// Send all APDUs
		for (int i = 0; fixedTestAPDUS[i] != NULL; i++)
		{
			recvBufLen = (DWORD) sizeof(recvBuf);
			ret        = sendAPDU(hCard, fixedTestAPDUS[i],
				recvBuf, &recvBufLen, thisChipNr, i, NULL == chipnrForCompare);

			if (0 == ret && NULL != chipnrForCompare)
			{
				err = compareAPDUS(fixedTestAPDUS[i], recvBuf, recvBufLen,
					chipnrForCompare, i);
				if (err < 0)
					break;
				errCount += err;
			}
		}

		ret = SCardDisconnect(hCard, SCARD_LEAVE_CARD);
		CHECK_PCSC_RET("SCardDisconnect", ret);

		if (NULL == chipnrForCompare)
			printf("Done, stored APDUs to files who's names start with %s\n", thisChipNr);
		else if (err >= 0)
			printf("APDU Tests done, %d differences with chip %s)\n", errCount, chipnrForCompare);
	}

	return 0;
}
Ejemplo n.º 15
0
static std:: vector<BYTE> sendAPDU(const char *apdu)
{
	SCARDHANDLE   hCard;
	unsigned char *recvBuf;
	//char debugString[2048];

	unsigned char      sendBuf[280];
	size_t             sendBufLen = sizeof(sendBuf);
	std:: vector<BYTE> result;
	SCARDCONTEXT       ctx;
	const char         *readerName;

	long               ret = SCardEstablishContext(SCARD_SCOPE_USER, NULL, NULL, &ctx);
	CHECK_PCSC_RET("SCardEstablishContext", ret);
	if (SCARD_S_SUCCESS == ret)
	{
		char readerList[2000];
		readerName = listReaders(ctx, readerList, sizeof(readerList), true, -1);

		DWORD protocol;
		char  *chipnrForCompare = NULL;

		long  ret = SCardConnectA(ctx, readerName,
			SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0, &hCard, &protocol);
		CHECK_PCSC_RET("SCardConnect", ret);
		if (SCARD_S_SUCCESS == ret)
		{
			DWORD         recvBufLen = sizeof(recvBuf);
			unsigned char recvBuf[258];

			// If chipnrForCompare == NULL then we retrieve the chip number
			// of this card to store all APDUs
			const char *thisChipNr = NULL;
			char       chipNrBuf[2 * CHIP_NR_LEN + 1];
			if (NULL == chipnrForCompare)
			{
				thisChipNr = GetChipNrFromCard(hCard, chipNrBuf);
				if (NULL == thisChipNr)
				{
					SCardDisconnect(hCard, SCARD_LEAVE_CARD);
					//return -1;
				}
			} //if (NULL == chipnrForCompare)

			recvBufLen = (DWORD) sizeof(recvBuf); //0x00000102

			if (0 == hex2bin(apdu, sendBuf, &sendBufLen))
			{
				// Check the APDU
				if (sendBufLen < 4)
				{
					printf("ERR: APDU should be at least 4 bytes\n");
					DebugMessage("ERR: APDU should be at least 4 bytes\n");
				}
				else if (sendBufLen > 5 && (size_t) (5 + sendBuf[4]) != sendBufLen)
				{
					printf("ERR: wrong P3 byte in case 3 APDU\n");
					DebugMessage("ERR: wrong P3 byte in case 3 APDU\n");
				}
				else
				{
					long ret = SCardTransmit2(hCard, &g_rgSCardT0Pci, sendBuf, (DWORD) sendBufLen, NULL, recvBuf, &recvBufLen);

					if (SCARD_S_SUCCESS == ret)
					{
						for (int i = 0; i < (int) recvBufLen; i++)
						{
							result.push_back(recvBuf[i]);
						}
						return result; // success
					}
				}
			}
		}
	}
	return result; // failed
}
Ejemplo n.º 16
0
static int testCardFunctionality(SCARDCONTEXT ctx, const char *readerName)
{
	SCARDHANDLE hCard;
	DWORD       protocol;
	int         errCount = 0;

	printf("Using reader \"%s\"\n\n", readerName);
	printf("NOTE: make sure no-one else is accessing the card!\n\n");

	long ret = SCardConnectA(ctx, readerName,
		SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0, &hCard, &protocol);

	CHECK_PCSC_RET("SCardConnect", ret);
	if (SCARD_S_SUCCESS == ret)
	{
		delayMS(200);

        printf("--- SCardReconnect tests ---\n");
        errCount += testScardReconnect(hCard, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0);

#ifdef _WIN32
		printf("\n--- SCardState tests ---\n");
		errCount += testSCardState(hCard);
#endif

		printf("\n--- SCardStatus tests ---\n");
		errCount += testSCardStatus(hCard);

#ifndef MAC_OS_X
		printf("\n--- SCardGetAttrib tests ---\n");
		errCount += testSCardGetAttrib(ctx, hCard);
#endif

		printf("\n--- Get Response tests ---\n");
		errCount += testGetResponse(hCard);

		printf("\n--- Get Response tests within a transaction ---\n");
		ret = SCardBeginTransaction(hCard);
		CHECK_PCSC_RET("SCardBeginTransaction", ret);
		errCount += testGetResponse(hCard);
		ret       = SCardEndTransaction(hCard, SCARD_LEAVE_CARD);
		CHECK_PCSC_RET("SCardBeginTransaction", ret);

		printf("\n--- Test reading a long file ---\n");
		errCount += testLongFileRead(hCard);

		printf("\n--- Test reading a long file within a transaction ---\n");
		ret = SCardBeginTransaction(hCard);
		CHECK_PCSC_RET("SCardBeginTransaction", ret);
		errCount += testLongFileRead(hCard);
		ret       = SCardEndTransaction(hCard, SCARD_LEAVE_CARD);
		CHECK_PCSC_RET("SCardBeginTransaction", ret);

		printf("\n--- Misc tests ---\n");
		errCount += testMisc(hCard);

		printf("\n--- Test ListReaders ---\n");
		errCount += testListReaders(ctx);

		ret = SCardDisconnect(hCard, SCARD_LEAVE_CARD);
		CHECK_PCSC_RET("SCardDisconnect", ret);
	}

	if (errCount == 0)
		printf("\nFunctional tests done, no errors\n");
	else
		printf("\nFunctional tests done, %d errors\n", errCount);

	return 0;
}
Ejemplo n.º 17
0
int main(int argc, const char **argv)
{
	Params       params;
	SCARDCONTEXT ctx;

	int          returnValue = 0;

	if (0 != parseCommandLine(argc, argv, &params))
		return -1;

	long ret = SCardEstablishContext(SCARD_SCOPE_USER, NULL, NULL, &ctx);
	CHECK_PCSC_RET("SCardEstablishContext", ret);
	if (SCARD_S_SUCCESS == ret)
	{
		char       readerList[2000];

#ifdef LOOP_LIST_READERS
again:
#endif

		const char *readerName = listReaders(ctx, readerList, sizeof(readerList),
			'l' == params.command, params.readerNr);

#ifdef LOOP_LIST_READERS
		if (params.command == 'l')
		{
			getchar();
			goto again;
		}
#endif

		if (NULL != readerName)
		{
			switch (params.command) {
			case 's':
				getStatusChange(ctx, readerList, params.timeout);
				break;
			case 'l':
				// already done in listReaders()
				break;
			case 'a':
				sendAPDUS(ctx, readerName, params.apduCount, params.apdus);
				break;
			case 'f':
				testCardFunctionality(ctx, readerName);
				break;
			case 't':
				testAPDUS(ctx, readerName, params.chipnr);
				break;
			case 'x':
				switch (params.test) {
				case 1:
					returnValue = testStatus(ctx, readerName, readerList);
					break;
				case 2:
					returnValue = testConnect(ctx, readerName);
					break;
				case 3:
					returnValue = testTransaction(ctx, readerName);
					break;
				case 4:
					returnValue = testTransmit(ctx, readerName, params.apdus);
					break;
				default:
					printf("Unknown -x parameter '%d', exiting\n", params.test);
				}

				break;
			default:
				printf("Unknown command '%c', exiting\n", params.command);
			}
		}
	}

	ret = SCardReleaseContext(ctx);

	return returnValue;
}
Ejemplo n.º 18
0
static int testLongFileRead(SCARDCONTEXT hCard)
{
	int           ret      = 0;
	int           errCount = 0;
	unsigned char recvBuf[258];
	DWORD         recvBufLen = sizeof(recvBuf);

	// Select the file
	ret = sendAPDU(hCard, "00:A4:04:0C:0C:A0:00:00:01:77:50:4B:43:53:2D:31:35", recvBuf, &recvBufLen);
	CHECK_PCSC_RET("sendAPDU(select MF)", ret);
	ret = sendAPDU(hCard, "00:A4:02:0C:02:50:38", recvBuf, &recvBufLen);
	CHECK_PCSC_RET("sendAPDU(select 5038)", ret);

	// Get the file size
	char apdu[20];
	int  offs    = 0;
	int  fileLen = 0;
	for (; offs < 5000; offs += 0xfc)
	{
		sprintf(apdu, "00B0%02X%02XFC", offs / 256, offs % 256);
		recvBufLen = sizeof(recvBuf);
		ret        = sendAPDU(hCard, apdu, recvBuf, &recvBufLen);
		CHECK_PCSC_RET("sendAPDU(Read Binary)", ret);
		if (recvBufLen == 2 && recvBuf[0] == 0x6c)
		{
			fileLen = offs + recvBuf[1];
			break;
		}
	}

	// Read 1 byte at filesize - 1
	sprintf(apdu, "00B0%02X%02X01", (fileLen - 1) / 256, (fileLen - 1) % 256);
	recvBufLen = sizeof(recvBuf);
	ret        = sendAPDU(hCard, apdu, recvBuf, &recvBufLen);
	CHECK_PCSC_RET("sendAPDU(Read Binary)", ret);
	if (recvBufLen != 3 || recvBuf[1] != 0x90 || recvBuf[2] != 0x00)
	{
		printf("ERR: ReadBinary(offset = filesize-1, len = 1) didn't return 1 byte\n");
		errCount++;
	}

	// Read 1 byte at filesize
	sprintf(apdu, "00B0%02X%02X01", (fileLen) / 256, (fileLen) % 256);
	recvBufLen = sizeof(recvBuf);
	ret        = sendAPDU(hCard, apdu, recvBuf, &recvBufLen);
	CHECK_PCSC_RET("sendAPDU(Read Binary)", ret);
	if (recvBufLen != 2 || recvBuf[0] != 0x6B || recvBuf[1] != 0x00)
	{
		printf("ERR: ReadBinary(offset = filesize, len = 1) didn't return 6B 00\n");
		errCount++;
	}

	// Read 1 byte at filesize + 1
	sprintf(apdu, "00B0%02X%02X01", (fileLen + 1) / 256, (fileLen + 1) % 256);
	recvBufLen = sizeof(recvBuf);
	ret        = sendAPDU(hCard, apdu, recvBuf, &recvBufLen);
	CHECK_PCSC_RET("sendAPDU(Read Binary)", ret);
	if (recvBufLen != 2 || recvBuf[0] != 0x6B || recvBuf[1] != 0x00)
	{
		printf("ERR: ReadBinary(offset = filesize+1, len = 1) didn't return 6B 00\n");
		errCount++;
	}

	return errCount;
}
Ejemplo n.º 19
0
static int testGetResponse(SCARDCONTEXT hCard)
{
	int           ret      = 0;
	int           errCount = 0;
	unsigned char recvBuf[258];
	DWORD         recvBufLen = sizeof(recvBuf);

	////////////////////// Tests on the virtual card ////////////////////

	// If the 1st command is a "Get Card Data", it's no possible to
	// do a "Get Response" to it. So we first do a "Select".
	ret = sendAPDU(hCard, "00:A4:04:0C:0C:A0:00:00:01:77:50:4B:43:53:2D:31:35", recvBuf, &recvBufLen);
	CHECK_PCSC_RET("sendAPDU(Get Card Data)", ret);

	// Get Card Data, only 16 bytes out of the 28
	recvBufLen = sizeof(recvBuf);
	ret        = sendAPDU(hCard, "80:E4:00:00:10", recvBuf, &recvBufLen);
	CHECK_PCSC_RET("sendAPDU(Get Card Data)", ret);
	if (recvBufLen != 18 || recvBuf[recvBufLen - 2] != 0x61 || recvBuf[recvBufLen - 1] != 0x0C)
	{
		printf("ERR: Get Response didn't return 61 0C\n");
		errCount++;
	}

	// Get Response, 11 bytes (so 1 byte left afterwards)
	ret = sendAPDU(hCard, "00:C0:00:00:0B", recvBuf, &recvBufLen);
	CHECK_PCSC_RET("sendAPDU(Get Card Data)", ret);
	if (recvBufLen != 13 || recvBuf[recvBufLen - 2] != 0x61 || recvBuf[recvBufLen - 1] != 0x01)
	{
		printf("ERR: Get Response didn't return 61 01\n");
		errCount++;
	}

	// Get Response, 1 byte (so no byte left afterwards)
	ret = sendAPDU(hCard, "00:C0:00:00:01", recvBuf, &recvBufLen);
	CHECK_PCSC_RET("sendAPDU(Get Card Data)", ret);
	if (recvBufLen != 3 || recvBuf[recvBufLen - 2] != 0x90 || recvBuf[recvBufLen - 1] != 0x00)
	{
		printf("ERR: Get Response didn't return 90 00\n");
		errCount++;
	}

	// Get Response, 1 byte (but no bytes left)
	ret = sendAPDU(hCard, "00:C0:00:00:01", recvBuf, &recvBufLen);
	CHECK_PCSC_RET("sendAPDU(Get Card Data)", ret);
	if (recvBufLen != 2 || recvBuf[0] != 0x6D || recvBuf[1] != 0x00)
	{
		printf("ERR: Get Response didn't return 6D 00\n");
		errCount++;
	}

	/////////////////////// Tests on the real card /////////////////////

	ret = sendAPDU(hCard, "00:20:00:01:08:24:12:34:FF:FF:FF:FF:FF", recvBuf, &recvBufLen);
	CHECK_PCSC_RET("sendAPDU(Verify PIN)", ret);

	ret = sendAPDU(hCard, "00:22:41:B6:05:04:80:01:84:82", recvBuf, &recvBufLen);
	CHECK_PCSC_RET("sendAPDU(MSE SET)", ret);

	ret = sendAPDU(hCard, "00:2A:9E:9A:08:11:22:33:44:55:66:77:88", recvBuf, &recvBufLen);
	CHECK_PCSC_RET("sendAPDU(Sign)", ret);

	// Get Response
	recvBufLen = sizeof(recvBuf);
	ret        = sendAPDU(hCard, "00:C0:00:00:80", recvBuf, &recvBufLen);
	CHECK_PCSC_RET("sendAPDU(Get Card Data)", ret);
	if (recvBufLen != 0x82 || recvBuf[recvBufLen - 2] != 0x90 || recvBuf[recvBufLen - 1] != 0x00)
	{
		printf("ERR: Get Response didn't return 6D 00\n");
		errCount++;
	}

	return errCount;
}
Ejemplo n.º 20
0
static int testSCardStatusA(SCARDCONTEXT hCard)
{
    int errCount = 0;
    DWORD dwState;
    DWORD dwProt;

    char staticReader[250];
    DWORD staticReaderLen = (DWORD) sizeof(staticReader);
    BYTE staticAtr[32];
    DWORD staticAtrLen = (DWORD) sizeof(staticAtr);
    long ret = SCardStatusA(hCard, (char *) &staticReader, &staticReaderLen, &dwState, &dwProt, staticAtr, &staticAtrLen);
    CHECK_PCSC_RET("SCardStatusA(1)", ret);

    char *dynReader = NULL;
    DWORD dynReaderLen = 0;
    BYTE *dynAtr = NULL;
    DWORD dynAtrLen = 0;
    ret = SCardStatusA(hCard, dynReader, &dynReaderLen, &dwState, &dwProt, dynAtr, &dynAtrLen);
    CHECK_PCSC_RET("SCardStatusA(2)", ret);
    dynReader = new char[staticReaderLen];
    dynAtr = new BYTE[dynAtrLen];
    ret = SCardStatusA(hCard, dynReader, &dynReaderLen, &dwState, &dwProt, dynAtr, &dynAtrLen);
    CHECK_PCSC_RET("SCardStatusA(3)", ret);

#ifndef MAC_OS_X
    char *autoReader = NULL;
    DWORD autoReaderLen = SCARD_AUTOALLOCATE;
    BYTE *autoAtr = NULL;
    DWORD autoAtrLen = SCARD_AUTOALLOCATE;
    ret = SCardStatusA(hCard, (char *) &autoReader, &autoReaderLen, &dwState, &dwProt, (BYTE *) &autoAtr, &autoAtrLen);
    CHECK_PCSC_RET("SCardStatusA(4)", ret);
    
    if (staticReaderLen != dynReaderLen || dynReaderLen != autoReaderLen)
    {
        printf("ERR: SCardStatusA() returned buffers lengths of different reader size\n");
        printf("  (staticLen = %d, dynLen = %d, autoLen = %d\n", (int) staticReaderLen, (int) dynReaderLen, (int) autoReaderLen);
        errCount++;
    }
    else if (memcmp(staticReader, dynReader, dynReaderLen) != 0 || memcmp(dynReader, autoReader, dynReaderLen) != 0)
    {
        printf("ERR: SCardStatusA() returned different reader names\n");
        dump("  staticReader = '%s' (%d bytes)\n", staticReader, dynReaderLen);
        dump("  dynReader = '%s' (%d bytes)\n", dynReader, dynReaderLen);
        dump("  autoReader = '%s' (%d bytes)\n", autoReader, dynReaderLen);
        errCount++;
    }

    if (staticAtrLen != dynAtrLen || dynAtrLen != autoAtrLen)
    {
        printf("ERR: SCardStatusA() returned buffers lengths of different ATR size\n");
        printf("  (staticLen = %d, dynLen = %d, autoLen = %d\n", (int) staticAtrLen, (int) dynAtrLen, (int) autoAtrLen);
        errCount++;
    }
    else if (memcmp(staticAtr, dynAtr, dynAtrLen) != 0 || memcmp(dynAtr, autoAtr, dynAtrLen) != 0)
    {
        printf("ERR: SCardStatusA() returned different ATRs\n");
        errCount++;
    }
#endif

    return errCount;
}
Ejemplo n.º 21
0
static int testSCardStatusW(SCARDCONTEXT hCard)
{
    int errCount = 0;
    DWORD dwState;
    DWORD dwProt;

    wchar_t staticReader[250];
    DWORD staticReaderLen = (DWORD) (sizeof(staticReader) / sizeof(wchar_t));
    BYTE staticAtr[32];
    DWORD staticAtrLen = (DWORD) sizeof(staticAtr);
    long ret = SCardStatusW(hCard, staticReader, &staticReaderLen, &dwState, &dwProt, staticAtr, &staticAtrLen);
	CHECK_PCSC_RET("SCardStatusW(1)", ret);

    wchar_t *dynReader = NULL;
    DWORD dynReaderLen = 0;
    BYTE *dynAtr = NULL;
    DWORD dynAtrLen = 0;
    ret = SCardStatusW(hCard, dynReader, &dynReaderLen, &dwState, &dwProt, dynAtr, &dynAtrLen);
	CHECK_PCSC_RET("SCardStatusW(2)", ret);
    dynReader = new wchar_t[staticReaderLen];
    dynAtr = new BYTE[dynAtrLen];
    ret = SCardStatusW(hCard, dynReader, &dynReaderLen, &dwState, &dwProt, dynAtr, &dynAtrLen);
	CHECK_PCSC_RET("SCardStatusW(3)", ret);
    
    wchar_t *autoReader = NULL;
    DWORD autoReaderLen = SCARD_AUTOALLOCATE;
    BYTE *autoAtr = NULL;
    DWORD autoAtrLen = SCARD_AUTOALLOCATE;
    ret = SCardStatusW(hCard, (wchar_t *) &autoReader, &autoReaderLen, &dwState, &dwProt, (BYTE *) &autoAtr, &autoAtrLen);
	CHECK_PCSC_RET("SCardStatusW(4)", ret);
    
    wchar_t *auto2Reader = (wchar_t *) 1;
    DWORD auto2ReaderLen = SCARD_AUTOALLOCATE;
    BYTE *auto2Atr = (BYTE *) 2;
    DWORD auto2AtrLen = SCARD_AUTOALLOCATE;
    ret = SCardStatusW(hCard, (wchar_t *) &auto2Reader, &auto2ReaderLen, &dwState, &dwProt, (BYTE *) &auto2Atr, &auto2AtrLen);
	CHECK_PCSC_RET("SCardStatusW(5)", ret);
    
    if (staticReaderLen != dynReaderLen || dynReaderLen != autoReaderLen || auto2ReaderLen != autoReaderLen)
    {
		printf("ERR: SCardStatusW() returned buffers lengths of different reader size\n");
        printf("  (staticLen = %d, dynLen = %d, autoLen = %d, autoLen = %d\n",
            (int) staticReaderLen, (int) dynReaderLen, (int) autoReaderLen, (int) auto2ReaderLen);
        errCount++;
    }
    else if (memcmp(staticReader, dynReader, dynReaderLen) != 0 || memcmp(dynReader, autoReader, dynReaderLen) != 0 ||
        memcmp(dynReader, auto2Reader, dynReaderLen) != 0)
    {
		printf("ERR: SCardStatusW() returned different reader names\n");
        dump("  staticReader = '%S'\n", staticReader, dynReaderLen);
        dump("  dynReader = '%S'\n", dynReader, dynReaderLen);
        dump("  autoReader = '%S'\n", autoReader, dynReaderLen);
        dump("  auto2Reader = '%S'\n", auto2Reader, dynReaderLen);
        errCount++;
    }

    if (staticAtrLen != dynAtrLen || dynAtrLen != autoAtrLen || dynAtrLen != auto2AtrLen)
    {
		printf("ERR: SCardStatusA() returned buffers lengths of different ATR size\n");
        printf("  (staticLen = %d, dynLen = %d, autoLen = %d, auto2Len = %d\n",
            (int) staticAtrLen, (int) dynAtrLen, (int) autoAtrLen, (int) auto2AtrLen);
        errCount++;
    }
    else if (memcmp(staticAtr, dynAtr, dynAtrLen) != 0 || memcmp(dynAtr, autoAtr, dynAtrLen) != 0 ||
        memcmp(dynAtr, auto2Atr, dynAtrLen) != 0)
    {
		printf("ERR: SCardStatusA() returned different ATRs\n");
        errCount++;
    }

    return errCount;
}