コード例 #1
0
ファイル: SCARDTest.cpp プロジェクト: Fedict/eid-edt
void testStatus(SCARDCONTEXT* phContext)
{
	wchar_t szReaderName[1024];
	DWORD dwReaderLen = 1024;
	DWORD dwState;
	DWORD dwProtocol;
	BYTE bAttribute[32];
	DWORD dwAtrLen;

		BYTE pbRecvBuffer[200];
	DWORD dwRecvLength, dwReturn;


	dwReturn = SCardControl(*phContext, 
		SCARD_CTL_CODE(3400),
		NULL,
		0,
		pbRecvBuffer,
		sizeof(pbRecvBuffer),
		&dwRecvLength);

 SCardStatus( *phContext, 
  szReaderName, 
  &dwReaderLen, 
  &dwState, 
  &dwProtocol, 
  &bAttribute[0], 
  &dwAtrLen 
);
}
コード例 #2
0
static UINT32 smartcard_Control_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation, Control_Call* call)
{
	LONG status;
	Control_Return ret;
	IRP* irp = operation->irp;

	ret.cbOutBufferSize = call->cbOutBufferSize;
	ret.pvOutBuffer = (BYTE*) malloc(call->cbOutBufferSize);

	if (!ret.pvOutBuffer)
		return SCARD_E_NO_MEMORY;

	status = ret.ReturnCode = SCardControl(operation->hCard,
			call->dwControlCode, call->pvInBuffer, call->cbInBufferSize,
			ret.pvOutBuffer, call->cbOutBufferSize, &ret.cbOutBufferSize);

	smartcard_trace_control_return(smartcard, &ret);

	status = smartcard_pack_control_return(smartcard, irp->output, &ret);

	if (status != SCARD_S_SUCCESS)
		return status;

	if (call->pvInBuffer)
		free(call->pvInBuffer);
	if (ret.pvOutBuffer)
		free(ret.pvOutBuffer);

	return ret.ReturnCode;
}
コード例 #3
0
int transmitVerifyPinAPDUviaPCSC(struct p11Slot_t *slot,
	unsigned char pinformat, unsigned char minpinsize, unsigned char maxpinsize,
	unsigned char pinblockstring, unsigned char pinlengthformat,
	unsigned char *capdu, size_t capdu_len,
	unsigned char *rapdu, size_t rapdu_len)
{
	LONG rc;
	DWORD lenr;
	PIN_VERIFY_DIRECT_STRUCTURE_t verify;

	FUNC_CALLED();

	if (!slot->card) {
		FUNC_FAILS(-1, "No card handle");
	}

	verify.bTimeOut = 0x00;
	verify.bTimeOut2 = 0x00;
	verify.bmFormatString = pinformat;
	verify.bmPINBlockString = pinblockstring;
	verify.bmPINLengthFormat = pinlengthformat;

	verify.wPINMaxExtraDigit = (minpinsize << 8) | maxpinsize;

	/*
	 * Bit 7-3: RFU
	 * Bit   2: Timout occurred
	 * Bit   1: Validation Key pressed
	 * Bit   0: Max size reached
	 */
	verify.bEntryValidationCondition = 0x02;

	verify.bNumberMessage = 0x01;
	verify.wLangID        = 0x0904;
	verify.bMsgIndex      = 0;

	verify.bTeoPrologue[0]= 0;
	verify.bTeoPrologue[1]= 0;
	verify.bTeoPrologue[2]= 0;

	verify.ulDataLength = capdu_len;
	memcpy(verify.abData, capdu, capdu_len);

	lenr = rapdu_len;

	rc = SCardControl(slot->card, slot->hasFeatureVerifyPINDirect, &verify,  18 + capdu_len + 1, rapdu, rapdu_len, &lenr);

#ifdef DEBUG
	debug("SCardControl (VERIFY_PIN_DIRECT): %s\n", pcsc_error_to_string(rc));
#endif

	if (rc != SCARD_S_SUCCESS) {
		FUNC_FAILS(-1, "SCardControl failed");
	}

	FUNC_RETURNS(lenr);
}
コード例 #4
0
ファイル: jpcsc.c プロジェクト: hideout/c-beam
/*
 * Send control bytes.
 */
JNIEXPORT jbyteArray JNICALL GEN_FUNCNAME(Card_NativeControl)
(JNIEnv *env, jobject _this, jint jcc, jbyteArray jin, jint joff, jint jlen)
{
    SCARDHANDLE card;
    unsigned char *cin;
    jboolean isCopy;
    unsigned char cout[RECEIVE_BUFFER_SIZE];
    DWORD clen = RECEIVE_BUFFER_SIZE;
    jbyteArray jout;
    LONG rv;

    card = (SCARDHANDLE) (*env)->GetLongField(env, _this, CardField);

    cin = (*env)->GetByteArrayElements(env, jin, &isCopy);

    /*
    #ifndef WIN32
        rv =  SCardControl(card, cin + joff, jlen, cout, &clen);
    #else
        JPCSC_LOG(("NativeControl()-win32: control code 0x%x 0x%x\n", jcc, SCARD_CTL_CODE(jcc)));
        rv =  SCardControl(card, SCARD_CTL_CODE(jcc), cin + joff, jlen, cout, clen, &clen);
    #endif
    */
#if defined(WIN32) || defined(HAVE_SCARD_ATTRIBUTES) || !defined(USE_SCARD_CONTROL_112)
    rv =  SCardControl(card, SCARD_CTL_CODE(jcc), cin + joff, jlen, cout, clen, &clen);
#else
    rv =  SCardControl(card, cin + joff, jlen, cout, &clen);
#endif /* defined(WIN32) || defined(HAVE_SCARD_ATTRIBUTES) */

    JPCSC_LOG(("NativeControl(): returns 0x%x\n", rv));

    (*env)->ReleaseByteArrayElements(env, jin, cin, JNI_ABORT);

    if (rv != SCARD_S_SUCCESS) {
        pcscex_throw(env, "Card.Control() failed", rv);
        return NULL;
    }

    jout = (*env)->NewByteArray(env, clen);
    (*env)->SetByteArrayRegion(env, jout, 0, clen, cout);

    return jout;
}
コード例 #5
0
ファイル: card-belpic.c プロジェクト: securez/opendnie
static LONG SCR_SCardInit(LPCTSTR szPinPadDll, LPCTSTR szReader, DWORD version,
			  SCR_SupportConstants * supported)
{
	LONG rv;
	unsigned char sendbuf[256];
	unsigned char recvbuf[2];
	char szTemp[32];
	DWORD dwRecvLength;
	struct tTLV tlv;

	memset(szTemp, 0, sizeof(szTemp));
	memset(sendbuf, 0, sizeof(sendbuf));
	memset(recvbuf, 0, sizeof(recvbuf));
	dwRecvLength = sizeof(recvbuf);

	/* Make TLV buffer */
	TLVInit(&tlv, sendbuf, sizeof(sendbuf));
	TLVNext(&tlv, 0x01);	/* Function ID */
	sprintf(szTemp, "%ld", SCR_INIT_ID);
	TLVAddBuffer(&tlv, (u8 *) szTemp, strlen(szTemp));
	TLVNext(&tlv, 0x02);	/* PinPad Dll */
	TLVAddBuffer(&tlv, (u8 *) szPinPadDll, strlen(szPinPadDll));
	TLVNext(&tlv, 0x03);	/* Reader Name */
	TLVAddBuffer(&tlv, (u8 *) szReader, strlen(szReader));
	TLVNext(&tlv, 0x04);	/* Version */
	sprintf(szTemp, "%ld", version);
	TLVAddBuffer(&tlv, (u8 *) szTemp, strlen(szTemp));

#ifdef HAVE_PCSC_OLD
	rv = SCardControl(SCR_CARD_HANDLE, sendbuf, TLVLen(&tlv), recvbuf, &dwRecvLength);
#else
	rv = SCardControl(SCR_CARD_HANDLE, 0, sendbuf, TLVLen(&tlv),
			  recvbuf, dwRecvLength, &dwRecvLength);
#endif
	if (dwRecvLength > 0) {
		*supported = recvbuf[0];
	} else {
		rv = SC_ERROR_UNKNOWN_DATA_RECEIVED;
	}

	return rv;
}
コード例 #6
0
int PCSCv2Part10_find_TLV_property_by_tag_from_hcard(SCARDHANDLE hCard,
	int property, int * value)
{
	unsigned char buffer[MAX_BUFFER_SIZE];
	LONG rv;
	DWORD length;
	unsigned int i;
	PCSC_TLV_STRUCTURE *pcsc_tlv;
	DWORD properties_in_tlv_ioctl;
	int found;

	rv = SCardControl(hCard, CM_IOCTL_GET_FEATURE_REQUEST, NULL, 0,
		buffer, sizeof buffer, &length);
	if (rv != SCARD_S_SUCCESS)
		return -1;

	/* get the number of elements instead of the complete size */
	length /= sizeof(PCSC_TLV_STRUCTURE);

	pcsc_tlv = (PCSC_TLV_STRUCTURE *)buffer;
	found = 0;
	for (i = 0; i < length; i++)
	{
		if (FEATURE_GET_TLV_PROPERTIES == pcsc_tlv[i].tag)
		{
			properties_in_tlv_ioctl = ntohl(pcsc_tlv[i].value);
			found = 1;
		}
	}

	if (! found)
		return -3;

	rv= SCardControl(hCard, properties_in_tlv_ioctl, NULL, 0,
		buffer, sizeof buffer, &length);
	if (rv != SCARD_S_SUCCESS)
		return -1;

	return PCSCv2Part10_find_TLV_property_by_tag_from_buffer(buffer,
		length, property, value);
}
コード例 #7
0
ファイル: acr122.c プロジェクト: copacetic/tabulator
bool
acr122_led_red (nfc_device *pnd, bool bOn)
{
  uint8_t  abtLed[9] = { 0xFF, 0x00, 0x40, 0x05, 0x04, 0x00, 0x00, 0x00, 0x00 };
  uint8_t  abtBuf[2];
  DWORD dwBufLen = sizeof (abtBuf);
  (void) bOn;
  if (DRIVER_DATA (pnd)->ioCard.dwProtocol == SCARD_PROTOCOL_UNDEFINED) {
    return (SCardControl (DRIVER_DATA (pnd)->hCard, IOCTL_CCID_ESCAPE_SCARD_CTL_CODE, abtLed, sizeof (abtLed), abtBuf, dwBufLen, &dwBufLen) == SCARD_S_SUCCESS);
  } else {
    return (SCardTransmit (DRIVER_DATA (pnd)->hCard, &(DRIVER_DATA (pnd)->ioCard), abtLed, sizeof (abtLed), NULL, abtBuf, &dwBufLen) == SCARD_S_SUCCESS);
  }
}
コード例 #8
0
long CardControl(SCARDHANDLE hCard, DWORD dwControlCode,
	LPCVOID lpInBuffer, DWORD nInBufferSize,
	LPVOID lpOutBuffer, DWORD nOutBufferSize, LPDWORD lpBytesReturned)
{
#ifndef __OLD_PCSC_API__
	long lRet = SCardControl(hCard, dwControlCode,
		lpInBuffer, nInBufferSize,
		lpOutBuffer, nOutBufferSize, lpBytesReturned);

	//printf("SCardControl()\n");

	return lRet;
#else
        long lRet = SCardControl(hCard,
                (const unsigned char *) lpInBuffer, nInBufferSize,
                (unsigned char*) lpOutBuffer, lpBytesReturned);

	//printf("SCardControl()\n");

	return lRet;
#endif
}
コード例 #9
0
ファイル: edna_emu.cpp プロジェクト: credentials/edna
bool edna_emulator::transceive_control(SCARDHANDLE reader, const bytestring& cmd, bytestring& rdata)
{
	DWORD pcsc_rv;
	DWORD rlen;
	
	rdata.resize(512);
	if ((pcsc_rv = SCardControl(reader, IOCTL_CCID_ESCAPE_DIRECT, cmd.const_byte_str(), cmd.size(), rdata.byte_str(), 512, &rlen)) != SCARD_S_SUCCESS)
	{
		ERROR_MSG("Failed to exchange control command (0x%08X)", pcsc_rv);
		
		SCardDisconnect(reader, SCARD_UNPOWER_CARD);
		SCardReleaseContext(pcsc_context);
		
		return false;
	}
	
	rdata.resize(rlen);
	
	return true;
}
コード例 #10
0
ファイル: acr122.c プロジェクト: copacetic/tabulator
char   *
acr122_firmware (nfc_device *pnd)
{
  uint8_t  abtGetFw[5] = { 0xFF, 0x00, 0x48, 0x00, 0x00 };
  uint32_t uiResult;

  static char abtFw[11];
  DWORD dwFwLen = sizeof (abtFw);
  memset (abtFw, 0x00, sizeof (abtFw));
  if (DRIVER_DATA (pnd)->ioCard.dwProtocol == SCARD_PROTOCOL_UNDEFINED) {
    uiResult = SCardControl (DRIVER_DATA (pnd)->hCard, IOCTL_CCID_ESCAPE_SCARD_CTL_CODE, abtGetFw, sizeof (abtGetFw), (uint8_t *) abtFw, dwFwLen-1, &dwFwLen);
  } else {
    uiResult = SCardTransmit (DRIVER_DATA (pnd)->hCard, &(DRIVER_DATA (pnd)->ioCard), abtGetFw, sizeof (abtGetFw), NULL, (uint8_t *) abtFw, &dwFwLen);
  }

  if (uiResult != SCARD_S_SUCCESS) {
    log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "No ACR122 firmware received, Error: %08x", uiResult);
  }

  return abtFw;
}
コード例 #11
0
    void OmnikeyXX21ReaderUnit::getT_CL_ISOType(bool& isTypeA, bool& isTypeB)
    {
        unsigned char outBuffer[64];
        DWORD dwOutBufferSize;
        unsigned char inBuffer[2];
        DWORD dwInBufferSize;
        DWORD dwBytesReturned;
        DWORD dwControlCode = CM_IOCTL_GET_SET_RFID_BAUDRATE;
        DWORD dwStatus;

        memset(outBuffer, 0x00, sizeof(outBuffer));
        dwOutBufferSize = sizeof(outBuffer);
        dwInBufferSize = sizeof(inBuffer);
        dwBytesReturned = 0;

        inBuffer[0] = 0x01;	// Version of command
        inBuffer[1] = 0x00; // Get asymmetric baud rate information

        isTypeA = false;
        isTypeB = false;

        dwStatus = SCardControl(getHandle(), dwControlCode, (LPVOID)inBuffer, dwInBufferSize, (LPVOID)outBuffer, dwOutBufferSize, &dwBytesReturned);
        if (dwStatus == SCARD_S_SUCCESS && dwBytesReturned >= 10)
        {
            switch (outBuffer[9])
            {
            case 0x04:
                isTypeA = true;
                break;

            case 0x08:
                isTypeB = true;
                break;
            }
        }
    }
コード例 #12
0
int main(int argc, char *argv[])
{
	LONG rv;
	SCARDCONTEXT hContext;
	DWORD dwReaders;
	LPSTR mszReaders = NULL;
	char *ptr, **readers = NULL;
	int nbReaders;
	SCARDHANDLE hCard;
	DWORD dwActiveProtocol, dwReaderLen, dwState, dwProt, dwAtrLen;
	BYTE pbAtr[MAX_ATR_SIZE] = "";
	char pbReader[MAX_READERNAME] = "";
	int reader_nb;
	unsigned int i;
	unsigned char bSendBuffer[MAX_BUFFER_SIZE];
	unsigned char bRecvBuffer[MAX_BUFFER_SIZE];
	DWORD send_length, length;
	DWORD verify_ioctl = 0;
	DWORD modify_ioctl = 0;
	DWORD pin_properties_ioctl = 0;
	DWORD mct_readerdirect_ioctl = 0;
	DWORD properties_in_tlv_ioctl = 0;
	DWORD ccid_esc_command = 0;
	SCARD_IO_REQUEST pioRecvPci;
	SCARD_IO_REQUEST pioSendPci;
	PCSC_TLV_STRUCTURE *pcsc_tlv;
#if defined(VERIFY_PIN) | defined(MODIFY_PIN)
	int offset;
#endif
#ifdef VERIFY_PIN
	PIN_VERIFY_STRUCTURE *pin_verify;
#endif
#ifdef MODIFY_PIN
	PIN_MODIFY_STRUCTURE *pin_modify;
#endif

	printf("SCardControl sample code\n");
	printf("V 1.4 © 2004-2010, Ludovic Rousseau <*****@*****.**>\n\n");

	printf(MAGENTA "THIS PROGRAM IS NOT DESIGNED AS A TESTING TOOL!\n");
	printf("Do NOT use it unless you really know what you do.\n\n" NORMAL);

	rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);
	if (rv != SCARD_S_SUCCESS)
	{
		printf("SCardEstablishContext: Cannot Connect to Resource Manager %ulX\n", rv);
		return 1;
	}

	/* Retrieve the available readers list */
	rv = SCardListReaders(hContext, NULL, NULL, &dwReaders);
	PCSC_ERROR_EXIT(rv, "SCardListReaders")

	mszReaders = malloc(sizeof(char)*dwReaders);
	if (mszReaders == NULL)
	{
		printf("malloc: not enough memory\n");
		goto end;
	}

	rv = SCardListReaders(hContext, NULL, mszReaders, &dwReaders);
	if (rv != SCARD_S_SUCCESS)
		printf("SCardListReader: %ulX\n", rv);

	/* Extract readers from the null separated string and get the total
	 * number of readers */
	nbReaders = 0;
	ptr = mszReaders;
	while (*ptr != '\0')
	{
		ptr += strlen(ptr)+1;
		nbReaders++;
	}

	if (nbReaders == 0)
	{
		printf("No reader found\n");
		goto end;
	}

	/* allocate the readers table */
	readers = calloc(nbReaders, sizeof(char *));
	if (NULL == readers)
	{
		printf("Not enough memory for readers[]\n");
		goto end;
	}

	/* fill the readers table */
	nbReaders = 0;
	ptr = mszReaders;
	printf("Available readers (use command line argument to select)\n");
	while (*ptr != '\0')
	{
		printf("%d: %s\n", nbReaders, ptr);
		readers[nbReaders] = ptr;
		ptr += strlen(ptr)+1;
		nbReaders++;
	}
	printf("\n");

	if (argc > 1)
	{
		reader_nb = atoi(argv[1]);
		if (reader_nb < 0 || reader_nb >= nbReaders)
		{
			printf("Wrong reader index: %d\n", reader_nb);
			goto end;
		}
	}
	else
		reader_nb = 0;

	/* connect to a reader (even without a card) */
	dwActiveProtocol = -1;
	printf("Using reader: " GREEN "%s\n" NORMAL, readers[reader_nb]);
	rv = SCardConnect(hContext, readers[reader_nb], SCARD_SHARE_SHARED,
		SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &hCard, &dwActiveProtocol);
	printf(" Protocol: " GREEN "%uld\n" NORMAL, dwActiveProtocol);
	PCSC_ERROR_EXIT(rv, "SCardConnect")

#ifdef GET_GEMPC_FIRMWARE
	/* get GemPC firmware */
	printf(" Get GemPC Firmware\n");

	/* this is specific to Gemalto readers */
	bSendBuffer[0] = 0x02;
	rv = SCardControl(hCard, IOCTL_SMARTCARD_VENDOR_IFD_EXCHANGE, bSendBuffer,
		1, bRecvBuffer, sizeof(bRecvBuffer), &length);

	printf(" Firmware: " GREEN);
	for (i=0; i<length; i++)
		printf("%02X ", bRecvBuffer[i]);
	printf(NORMAL "\n");

	bRecvBuffer[length] = '\0';
	printf(" Firmware: " GREEN "%s" NORMAL" (length " GREEN "%ld" NORMAL " bytes)\n", bRecvBuffer, length);

	PCSC_ERROR_CONT(rv, "SCardControl")
#endif

	/* does the reader support PIN verification? */
	rv = SCardControl(hCard, CM_IOCTL_GET_FEATURE_REQUEST, NULL, 0,
		bRecvBuffer, sizeof(bRecvBuffer), &length);
	PCSC_ERROR_EXIT(rv, "SCardControl")

	printf(" TLV (%uld): " GREEN, length);
	for (i=0; i<length; i++)
		printf("%02X ", bRecvBuffer[i]);
	printf(NORMAL "\n");

	PCSC_ERROR_CONT(rv, "SCardControl(CM_IOCTL_GET_FEATURE_REQUEST)")

	if (length % sizeof(PCSC_TLV_STRUCTURE))
	{
		printf("Inconsistent result! Bad TLV values!\n");
		goto end;
	}

	/* get the number of elements instead of the complete size */
	length /= sizeof(PCSC_TLV_STRUCTURE);

	pcsc_tlv = (PCSC_TLV_STRUCTURE *)bRecvBuffer;
	for (i = 0; i < length; i++)
	{
		switch (pcsc_tlv[i].tag)
		{
			case FEATURE_VERIFY_PIN_DIRECT:
				PRINT_GREEN("Reader supports", "FEATURE_VERIFY_PIN_DIRECT");
				verify_ioctl = ntohl(pcsc_tlv[i].value);
				break;
			case FEATURE_MODIFY_PIN_DIRECT:
				PRINT_GREEN("Reader supports", "FEATURE_MODIFY_PIN_DIRECT");
				modify_ioctl = ntohl(pcsc_tlv[i].value);
				break;
			case FEATURE_IFD_PIN_PROPERTIES:
				PRINT_GREEN("Reader supports", "FEATURE_IFD_PIN_PROPERTIES");
				pin_properties_ioctl = ntohl(pcsc_tlv[i].value);
				break;
			case FEATURE_MCT_READER_DIRECT:
				PRINT_GREEN("Reader supports", "FEATURE_MCT_READER_DIRECT");
				mct_readerdirect_ioctl = ntohl(pcsc_tlv[i].value);
				break;
			case FEATURE_GET_TLV_PROPERTIES:
				PRINT_GREEN("Reader supports", "FEATURE_GET_TLV_PROPERTIES");
				properties_in_tlv_ioctl = ntohl(pcsc_tlv[i].value);
				break;
			case FEATURE_CCID_ESC_COMMAND:
				PRINT_GREEN("Reader supports", "FEATURE_CCID_ESC_COMMAND");
				ccid_esc_command = ntohl(pcsc_tlv[i].value);
				break;
			default:
				PRINT_RED_DEC("Can't parse tag", pcsc_tlv[i].tag);
		}
	}
	printf("\n");

	if (properties_in_tlv_ioctl)
	{
		int value;
		int ret;

		rv = SCardControl(hCard, properties_in_tlv_ioctl, NULL, 0,
			bRecvBuffer, sizeof(bRecvBuffer), &length);
		PCSC_ERROR_CONT(rv, "SCardControl(GET_TLV_PROPERTIES)")

		printf("GET_TLV_PROPERTIES (" GREEN "%uld" NORMAL "): " GREEN, length);
		for (i=0; i<length; i++)
			printf("%02X ", bRecvBuffer[i]);
		printf(NORMAL "\n");

		printf("\nDisplay all the properties:\n");
		parse_properties(bRecvBuffer, length);

		printf("\nFind a specific property:\n");
		ret = PCSCv2Part10_find_TLV_property_by_tag_from_buffer(bRecvBuffer, length, PCSCv2_PART10_PROPERTY_wIdVendor, &value);
		if (ret)
			PRINT_RED_DEC(" wIdVendor", ret);
		else
			PRINT_GREEN_HEX4(" wIdVendor", value);

		ret = PCSCv2Part10_find_TLV_property_by_tag_from_hcard(hCard, PCSCv2_PART10_PROPERTY_wIdProduct, &value);
		if (ret)
			PRINT_RED_DEC(" wIdProduct", ret);
		else
			PRINT_GREEN_HEX4(" wIdProduct", value);

		printf("\n");
	}

	if (mct_readerdirect_ioctl)
	{
		char secoder_info[] = { 0x20, 0x70, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 };

		rv = SCardControl(hCard, mct_readerdirect_ioctl, secoder_info,
			sizeof(secoder_info), bRecvBuffer, sizeof(bRecvBuffer), &length);
		PCSC_ERROR_CONT(rv, "SCardControl(MCT_READER_DIRECT)")

		printf("MCT_READER_DIRECT (%uld): ", length);
		for (i=0; i<length; i++)
			printf("%02X ", bRecvBuffer[i]);
		printf("\n");
	}

	if (pin_properties_ioctl)
	{
		PIN_PROPERTIES_STRUCTURE *pin_properties;

		rv = SCardControl(hCard, pin_properties_ioctl, NULL, 0,
			bRecvBuffer, sizeof(bRecvBuffer), &length);
		PCSC_ERROR_CONT(rv, "SCardControl(pin_properties_ioctl)")

		printf("PIN PROPERTIES (" GREEN "%uld" NORMAL "): " GREEN, length);
		for (i=0; i<length; i++)
			printf("%02X ", bRecvBuffer[i]);
		printf(NORMAL "\n");

		pin_properties = (PIN_PROPERTIES_STRUCTURE *)bRecvBuffer;
		PRINT_GREEN_HEX4(" wLcdLayout", pin_properties -> wLcdLayout);
		PRINT_GREEN_DEC(" bEntryValidationCondition", pin_properties ->	bEntryValidationCondition);
		PRINT_GREEN_DEC(" bTimeOut2", pin_properties -> bTimeOut2);

		printf("\n");
	}

#ifdef GET_GEMPC_FIRMWARE
	if (ccid_esc_command)
	{
		/* get GemPC firmware */
		printf("Get GemPC Firmware\n");

		/* this is specific to Gemalto readers */
		bSendBuffer[0] = 0x02;
		rv = SCardControl(hCard, ccid_esc_command, bSendBuffer,
			1, bRecvBuffer, sizeof(bRecvBuffer), &length);

		printf(" Firmware: " GREEN);
		for (i=0; i<length; i++)
			printf("%02X ", bRecvBuffer[i]);
		printf(NORMAL "\n");

		bRecvBuffer[length] = '\0';
		printf(" Firmware: " GREEN "%s" NORMAL" (length " GREEN "%ld" NORMAL " bytes)\n", bRecvBuffer, length);

		PCSC_ERROR_CONT(rv, "SCardControl")
	}
#endif

	if (0 == verify_ioctl)
	{
		printf("Reader %s does not support PIN verification\n",
			readers[reader_nb]);
		goto end;
	}

	/* get card status */
	dwAtrLen = sizeof(pbAtr);
	dwReaderLen = sizeof(pbReader);
	rv = SCardStatus(hCard, pbReader, &dwReaderLen, &dwState, &dwProt,
		pbAtr, &dwAtrLen);
	printf(" Reader: %s (length %uld bytes)\n", pbReader, dwReaderLen);
	printf(" State: 0x%04ulX\n", dwState);
	printf(" Prot: %uld\n", dwProt);
	printf(" ATR (length %uld bytes):", dwAtrLen);
	for (i=0; i<dwAtrLen; i++)
		printf(" %02X", pbAtr[i]);
	printf("\n");
	PCSC_ERROR_CONT(rv, "SCardStatus")

	if (dwState & SCARD_ABSENT)
	{
		printf("No card inserted\n");
		goto end;
	}

	/* connect to a reader (even without a card) */
	dwActiveProtocol = -1;
	rv = SCardReconnect(hCard, SCARD_SHARE_SHARED,
		SCARD_PROTOCOL_T0|SCARD_PROTOCOL_T1, SCARD_LEAVE_CARD,
		&dwActiveProtocol);
	printf(" Protocol: %uld\n", dwActiveProtocol);
	PCSC_ERROR_EXIT(rv, "SCardReconnect")

	switch(dwActiveProtocol)
	{
		case SCARD_PROTOCOL_T0:
			pioSendPci = *SCARD_PCI_T0;
			break;
		case SCARD_PROTOCOL_T1:
			pioSendPci = *SCARD_PCI_T1;
			break;
		default:
			printf("Unknown protocol. No card present?\n");
			return -1;
	}

	/* APDU select applet */
	printf("Select applet: ");
	send_length = 11;
	memcpy(bSendBuffer, "\x00\xA4\x04\x00\x06\xA0\x00\x00\x00\x18\xFF",
		send_length);
	for (i=0; i<send_length; i++)
		printf(" %02X", bSendBuffer[i]);
	printf("\n");
	length = sizeof(bRecvBuffer);
	rv = SCardTransmit(hCard, &pioSendPci, bSendBuffer, send_length,
		&pioRecvPci, bRecvBuffer, &length);
	printf(" card response:");
	for (i=0; i<length; i++)
		printf(" %02X", bRecvBuffer[i]);
	printf("\n");
	PCSC_ERROR_EXIT(rv, "SCardTransmit")
	if ((bRecvBuffer[0] != 0x90) || (bRecvBuffer[1] != 0x00))
	{
		printf("Error: test applet not found!\n");
		goto end;
	}

#ifdef VERIFY_PIN
	/* verify PIN */
	printf(" Secure verify PIN\n");
	pin_verify = (PIN_VERIFY_STRUCTURE *)bSendBuffer;

	/* table for bEntryValidationCondition
	 * 0x01: Max size reached
	 * 0x02: Validation key pressed
	 * 0x04: Timeout occured
	 */
	/* PC/SC v2.02.05 Part 10 PIN verification data structure */
	pin_verify -> bTimerOut = 0x00;
	pin_verify -> bTimerOut2 = 0x00;
	pin_verify -> bmFormatString = 0x82;
	pin_verify -> bmPINBlockString = 0x04;
	pin_verify -> bmPINLengthFormat = 0x00;
	pin_verify -> wPINMaxExtraDigit = 0x0408; /* Min Max */
	pin_verify -> bEntryValidationCondition = 0x02;	/* validation key pressed */
	pin_verify -> bNumberMessage = 0x01;
	pin_verify -> wLangId = 0x0904;
	pin_verify -> bMsgIndex = 0x00;
	pin_verify -> bTeoPrologue[0] = 0x00;
	pin_verify -> bTeoPrologue[1] = 0x00;
	pin_verify -> bTeoPrologue[2] = 0x00;
	/* pin_verify -> ulDataLength = 0x00; we don't know the size yet */

	/* APDU: 00 20 00 00 08 30 30 30 30 00 00 00 00 */
	offset = 0;
	pin_verify -> abData[offset++] = 0x00;	/* CLA */
	pin_verify -> abData[offset++] = 0x20;	/* INS: VERIFY */
	pin_verify -> abData[offset++] = 0x00;	/* P1 */
	pin_verify -> abData[offset++] = 0x00;	/* P2 */
	pin_verify -> abData[offset++] = 0x08;	/* Lc: 8 data bytes */
	pin_verify -> abData[offset++] = 0x30;	/* '0' */
	pin_verify -> abData[offset++] = 0x30;	/* '0' */
	pin_verify -> abData[offset++] = 0x30;	/* '0' */
	pin_verify -> abData[offset++] = 0x30;	/* '0' */
	pin_verify -> abData[offset++] = 0x00;	/* '\0' */
	pin_verify -> abData[offset++] = 0x00;	/* '\0' */
	pin_verify -> abData[offset++] = 0x00;	/* '\0' */
	pin_verify -> abData[offset++] = 0x00;	/* '\0' */
	pin_verify -> ulDataLength = offset;	/* APDU size */

	length = sizeof(PIN_VERIFY_STRUCTURE) + offset -1;	/* -1 because PIN_VERIFY_STRUCTURE contains the first byte of abData[] */

	printf(" command:");
	for (i=0; i<length; i++)
		printf(" %02X", bSendBuffer[i]);
	printf("\n");
	printf("Enter your PIN: ");
	fflush(stdout);
	rv = SCardControl(hCard, verify_ioctl, bSendBuffer,
		length, bRecvBuffer, sizeof(bRecvBuffer), &length);

	{
#ifndef S_SPLINT_S
		fd_set fd;
#endif
		struct timeval timeout;

		FD_ZERO(&fd);
		FD_SET(STDIN_FILENO, &fd);	/* stdin */
		timeout.tv_sec = 0;			/* timeout = 0.1s */
		timeout.tv_usec = 100000;

		/* we only try to read stdin if the pinpad is on a keyboard
		 * we do not read stdin for a SPR 532 for example */
		if (select(1, &fd, NULL, NULL, &timeout) > 0)
		{
			/* read the fake digits */
			char in[40];	/* 4 digits + \n + \0 */
			(void)fgets(in, sizeof(in), stdin);

			printf("keyboard sent: %s", in);
		}
		else
			/* if it is not a keyboard */
			printf("\n");
	}

	printf(" card response:");
	for (i=0; i<length; i++)
		printf(" %02X", bRecvBuffer[i]);
	printf("\n");
	PCSC_ERROR_CONT(rv, "SCardControl")

	/* verify PIN dump */
	printf("\nverify PIN dump: ");
	send_length = 5;
	memcpy(bSendBuffer, "\x00\x40\x00\x00\xFF",
		send_length);
	for (i=0; i<send_length; i++)
		printf(" %02X", bSendBuffer[i]);
	printf("\n");
	length = sizeof(bRecvBuffer);
	rv = SCardTransmit(hCard, &pioSendPci, bSendBuffer, send_length,
		&pioRecvPci, bRecvBuffer, &length);
	printf(" card response:");
	for (i=0; i<length; i++)
		printf(" %02X", bRecvBuffer[i]);
	printf("\n");
	PCSC_ERROR_EXIT(rv, "SCardTransmit")

	if ((2 == length) && (0x6C == bRecvBuffer[0]))
	{
		printf("\nverify PIN dump: ");
		send_length = 5;
		memcpy(bSendBuffer, "\x00\x40\x00\x00\xFF",
			send_length);
		bSendBuffer[4] = bRecvBuffer[1];
		for (i=0; i<send_length; i++)
			printf(" %02X", bSendBuffer[i]);
		printf("\n");
		length = sizeof(bRecvBuffer);
		rv = SCardTransmit(hCard, &pioSendPci, bSendBuffer, send_length,
			&pioRecvPci, bRecvBuffer, &length);
		printf(" card response:");
		for (i=0; i<length; i++)
			printf(" %02X", bRecvBuffer[i]);
		printf("\n");
		PCSC_ERROR_EXIT(rv, "SCardTransmit")
	}
コード例 #13
0
static uint32 handle_Control(IRP* irp)
{
	LONG rv;
	SCARDCONTEXT hContext;
	SCARDHANDLE hCard;
	uint32 map[3];
	uint32 controlCode;
	uint32 controlFunction;
	BYTE *recvBuffer = NULL, *sendBuffer = NULL;
	uint32 recvLength;
	DWORD nBytesReturned;
	DWORD outBufferSize;

	stream_seek(irp->input, 0x14);
	stream_read_uint32(irp->input, map[0]);
	stream_seek(irp->input, 0x4);
	stream_read_uint32(irp->input, map[1]);
	stream_read_uint32(irp->input, controlCode);
	stream_read_uint32(irp->input, recvLength);
	stream_read_uint32(irp->input, map[2]);
	stream_seek(irp->input, 0x4);
	stream_read_uint32(irp->input, outBufferSize);
	stream_seek(irp->input, 0x4);
	stream_read_uint32(irp->input, hContext);
	stream_seek(irp->input, 0x4);
	stream_read_uint32(irp->input, hCard);

	/* Translate Windows SCARD_CTL_CODE's to corresponding local code */
	if (WIN_CTL_DEVICE_TYPE(controlCode) == WIN_FILE_DEVICE_SMARTCARD)
	{
		controlFunction = WIN_CTL_FUNCTION(controlCode);
		controlCode = SCARD_CTL_CODE(controlFunction);
	}
	DEBUG_SCARD("controlCode: 0x%08x", (unsigned) controlCode);

	if (map[2] & SCARD_INPUT_LINKED)
	{
		/* read real input size */
		stream_read_uint32(irp->input, recvLength);

		recvBuffer = xmalloc(recvLength);

		if (!recvBuffer)
			return sc_output_return(irp, SCARD_E_NO_MEMORY);

		stream_read(irp->input, recvBuffer, recvLength);
	}

	nBytesReturned = outBufferSize;
	sendBuffer = xmalloc(outBufferSize);

	if (!sendBuffer)
		return sc_output_return(irp, SCARD_E_NO_MEMORY);

	rv = SCardControl(hCard, (DWORD) controlCode, recvBuffer, (DWORD) recvLength,
		sendBuffer, (DWORD) outBufferSize, &nBytesReturned);

	if (rv != SCARD_S_SUCCESS)
		DEBUG_SCARD("Failure: %s (0x%08x)", pcsc_stringify_error(rv), (unsigned) rv);
	else
		DEBUG_SCARD("Success (out: %u bytes)", (unsigned) nBytesReturned);

	stream_write_uint32(irp->output, (uint32) nBytesReturned);
	stream_write_uint32(irp->output, 0x00000004);
	stream_write_uint32(irp->output, nBytesReturned);

	if (nBytesReturned > 0)
	{
		stream_write(irp->output, sendBuffer, nBytesReturned);
		sc_output_repos(irp, nBytesReturned);
	}

	sc_output_alignment(irp, 8);

	xfree(recvBuffer);
	xfree(sendBuffer);

	return rv;
}
コード例 #14
0
ファイル: testpcsc.c プロジェクト: ZuyingWo/PCSC
int main(/*@unused@*/ int argc, /*@unused@*/ char **argv)
{
	SCARDHANDLE hCard;
	SCARDCONTEXT hContext;
	SCARD_READERSTATE rgReaderStates[1];
	DWORD dwReaderLen, dwState, dwProt, dwAtrLen;
	DWORD dwPref, dwReaders = 0;
	char *pcReader = NULL, *mszReaders;
#ifdef USE_AUTOALLOCATE
	unsigned char *pbAtr = NULL;
#else
	unsigned char pbAtr[MAX_ATR_SIZE];
#endif
	union {
		unsigned char as_char[100];
		DWORD as_DWORD;
		uint32_t as_uint32_t;
	} buf;
	DWORD dwBufLen;
	unsigned char *pbAttr = NULL;
	DWORD pcbAttrLen;
	char *mszGroups;
	DWORD dwGroups = 0;
	long rv;
	DWORD i;
	int p, iReader;
	int iList[16] = {0};
	SCARD_IO_REQUEST ioRecvPci = *SCARD_PCI_T0;	/* use a default value */
	const SCARD_IO_REQUEST *pioSendPci;
	unsigned char bSendBuffer[MAX_BUFFER_SIZE];
	unsigned char bRecvBuffer[MAX_BUFFER_SIZE];
	DWORD send_length, length;

	(void)argc;
	(void)argv;

	printf("\nMUSCLE PC/SC Lite unitary test Program\n\n");

	printf(MAGENTA "THIS PROGRAM IS NOT DESIGNED AS A TESTING TOOL FOR END USERS!\n");
	printf("Do NOT use it unless you really know what you do.\n\n" NORMAL);

	printf("Testing SCardEstablishContext\t: ");
	rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);
	test_rv(rv, hContext, PANIC);

	printf("Testing SCardIsValidContext\t: ");
	rv = SCardIsValidContext(hContext);
	test_rv(rv, hContext, PANIC);

	printf("Testing SCardIsValidContext\t: ");
	rv = SCardIsValidContext(hContext+1);
	test_rv(rv, hContext, DONT_PANIC);

	printf("Testing SCardListReaderGroups\t: ");
#ifdef USE_AUTOALLOCATE
	dwGroups = SCARD_AUTOALLOCATE;
	rv = SCardListReaderGroups(hContext, (LPSTR)&mszGroups, &dwGroups);
#else
	rv = SCardListReaderGroups(hContext, NULL, &dwGroups);
	test_rv(rv, hContext, PANIC);

	printf("Testing SCardListReaderGroups\t: ");
	mszGroups = calloc(dwGroups, sizeof(char));
	rv = SCardListReaderGroups(hContext, mszGroups, &dwGroups);
#endif
	test_rv(rv, hContext, PANIC);

	/*
	 * Have to understand the multi-string here
	 */
	p = 0;
	for (i = 0; i+1 < dwGroups; i++)
	{
		++p;
		printf(GREEN "Group %02d: %s\n" NORMAL, p, &mszGroups[i]);
		while (mszGroups[++i] != 0) ;
	}

#ifdef USE_AUTOALLOCATE
	printf("Testing SCardFreeMemory\t\t: ");
	rv = SCardFreeMemory(hContext, mszGroups);
	test_rv(rv, hContext, PANIC);
#else
	free(mszGroups);
#endif

wait_for_card_again:
	mszGroups = NULL;
	printf("Testing SCardListReaders\t: ");
	rv = SCardListReaders(hContext, mszGroups, NULL, &dwReaders);
	test_rv(rv, hContext, DONT_PANIC);
	if (SCARD_E_NO_READERS_AVAILABLE == rv)
	{
		printf("Testing SCardGetStatusChange \n");
		printf("Please insert a working reader\t: ");
		(void)fflush(stdout);
		rgReaderStates[0].szReader = "\\\\?PnP?\\Notification";
		rgReaderStates[0].dwCurrentState = SCARD_STATE_EMPTY;

		rv = SCardGetStatusChange(hContext, INFINITE, rgReaderStates, 1);
		test_rv(rv, hContext, PANIC);
	}

	printf("Testing SCardListReaders\t: ");
#ifdef USE_AUTOALLOCATE
	dwReaders = SCARD_AUTOALLOCATE;
	rv = SCardListReaders(hContext, mszGroups, (LPSTR)&mszReaders, &dwReaders);
#else
	rv = SCardListReaders(hContext, mszGroups, NULL, &dwReaders);
	test_rv(rv, hContext, PANIC);

	printf("Testing SCardListReaders\t: ");
	mszReaders = calloc(dwReaders, sizeof(char));
	rv = SCardListReaders(hContext, mszGroups, mszReaders, &dwReaders);
#endif
	test_rv(rv, hContext, DONT_PANIC);

	/*
	 * Have to understand the multi-string here
	 */
	p = 0;
	for (i = 0; i+1 < dwReaders; i++)
	{
		++p;
		printf(GREEN "Reader %02d: %s\n" NORMAL, p, &mszReaders[i]);
		iList[p] = i;
		while (mszReaders[++i] != 0) ;
	}

	if (p > 1)
		do
		{
			char input[80];
			char *r;

			printf("Enter the reader number\t\t: ");
			r = fgets(input, sizeof(input), stdin);
			if (NULL == r)
				iReader = -1;
			else
				iReader = atoi(input);

			if (iReader > p || iReader <= 0)
				printf("Invalid Value - try again\n");
		}
		while (iReader > p || iReader <= 0);
	else
		iReader = 1;

	rgReaderStates[0].szReader = &mszReaders[iList[iReader]];
	rgReaderStates[0].dwCurrentState = SCARD_STATE_EMPTY;

	printf("Waiting for card insertion\t: ");
	(void)fflush(stdout);
	rv = SCardGetStatusChange(hContext, INFINITE, rgReaderStates, 1);
	test_rv(rv, hContext, PANIC);
	if (rgReaderStates[0].dwEventState & SCARD_STATE_UNKNOWN)
	{
		printf("\nA reader has been connected/disconnected\n");
		goto wait_for_card_again;
	}

	printf("Testing SCardConnect\t\t: ");
	rv = SCardConnect(hContext, &mszReaders[iList[iReader]],
		SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1,
		&hCard, &dwPref);
	test_rv(rv, hContext, PANIC);

	switch(dwPref)
	{
		case SCARD_PROTOCOL_T0:
			pioSendPci = SCARD_PCI_T0;
			break;
		case SCARD_PROTOCOL_T1:
			pioSendPci = SCARD_PCI_T1;
			break;
		case SCARD_PROTOCOL_RAW:
			pioSendPci = SCARD_PCI_RAW;
			break;
		default:
			printf("Unknown protocol\n");
			return -1;
	}

	/* APDU select file */
	printf("Select file:");
	send_length = 7;
	memcpy(bSendBuffer, "\x00\xA4\x00\x00\x02\x3F\x00", send_length);
	for (i=0; i<send_length; i++)
		printf(" %02X", bSendBuffer[i]);
	printf("\n");
	length = sizeof(bRecvBuffer);

	printf("Testing SCardTransmit\t\t: ");
	rv = SCardTransmit(hCard, pioSendPci, bSendBuffer, send_length,
		&ioRecvPci, bRecvBuffer, &length);
	test_rv(rv, hContext, PANIC);
	printf(" card response:" GREEN);
	for (i=0; i<length; i++)
		printf(" %02X", bRecvBuffer[i]);
	printf("\n" NORMAL);

	printf("Testing SCardControl\t\t: ");
#ifdef PCSC_PRE_120
	{
		char buffer[1024] = "Foobar";
		DWORD cbRecvLength = sizeof(buffer);

		rv = SCardControl(hCard, buffer, 7, buffer, &cbRecvLength);
	}
#else
	{
		char buffer[1024] = { 0x02 };
		DWORD cbRecvLength = sizeof(buffer);

		rv = SCardControl(hCard, SCARD_CTL_CODE(1), buffer, 1, buffer,
			sizeof(buffer), &cbRecvLength);
		if (cbRecvLength && (SCARD_S_SUCCESS == rv))
		{
			for (i=0; i<cbRecvLength; i++)
				printf("%c", buffer[i]);
			printf(" ");
		}
	}
#endif
	test_rv(rv, hContext, DONT_PANIC);

	printf("Testing SCardGetAttrib\t\t: ");
#ifdef USE_AUTOALLOCATE
	pcbAttrLen = SCARD_AUTOALLOCATE;
	rv = SCardGetAttrib(hCard, SCARD_ATTR_DEVICE_FRIENDLY_NAME, (unsigned char *)&pbAttr,
		&pcbAttrLen);
#else
	rv = SCardGetAttrib(hCard, SCARD_ATTR_DEVICE_FRIENDLY_NAME, NULL, &pcbAttrLen);
	test_rv(rv, hContext, DONT_PANIC);
	if (rv == SCARD_S_SUCCESS)
	{
		printf("SCARD_ATTR_DEVICE_FRIENDLY_NAME length: " GREEN "%ld\n" NORMAL, pcbAttrLen);
		pbAttr = malloc(pcbAttrLen);
	}

	printf("Testing SCardGetAttrib\t\t: ");
	rv = SCardGetAttrib(hCard, SCARD_ATTR_DEVICE_FRIENDLY_NAME, pbAttr, &pcbAttrLen);
#endif
	test_rv(rv, hContext, DONT_PANIC);
	if (rv == SCARD_S_SUCCESS)
		printf("SCARD_ATTR_DEVICE_FRIENDLY_NAME: " GREEN "%s\n" NORMAL, pbAttr);

#ifdef USE_AUTOALLOCATE
	printf("Testing SCardFreeMemory\t\t: ");
	rv = SCardFreeMemory(hContext, pbAttr);
	test_rv(rv, hContext, PANIC);
#else
	if (pbAttr)
		free(pbAttr);
#endif

	printf("Testing SCardGetAttrib\t\t: ");
#ifdef USE_AUTOALLOCATE
	pcbAttrLen = SCARD_AUTOALLOCATE;
	rv = SCardGetAttrib(hCard, SCARD_ATTR_ATR_STRING, (unsigned char *)&pbAttr,
		&pcbAttrLen);
#else
	rv = SCardGetAttrib(hCard, SCARD_ATTR_ATR_STRING, NULL, &pcbAttrLen);
	test_rv(rv, hContext, DONT_PANIC);
	if (rv == SCARD_S_SUCCESS)
	{
		printf("SCARD_ATTR_ATR_STRING length: " GREEN "%ld\n" NORMAL, pcbAttrLen);
		pbAttr = malloc(pcbAttrLen);
	}

	printf("Testing SCardGetAttrib\t\t: ");
	rv = SCardGetAttrib(hCard, SCARD_ATTR_ATR_STRING, pbAttr, &pcbAttrLen);
#endif
	test_rv(rv, hContext, DONT_PANIC);
	if (rv == SCARD_S_SUCCESS)
	{
		printf("SCARD_ATTR_ATR_STRING length: " GREEN "%ld\n" NORMAL, pcbAttrLen);
		printf("SCARD_ATTR_ATR_STRING: " GREEN);
		for (i = 0; i < pcbAttrLen; i++)
			printf("%02X ", pbAttr[i]);
		printf("\n" NORMAL);
	}

#ifdef USE_AUTOALLOCATE
	printf("Testing SCardFreeMemory\t\t: ");
	rv = SCardFreeMemory(hContext, pbAttr);
	test_rv(rv, hContext, PANIC);
#else
	if (pbAttr)
		free(pbAttr);
#endif

	printf("Testing SCardGetAttrib\t\t: ");
	dwBufLen = sizeof(buf);
	rv = SCardGetAttrib(hCard, SCARD_ATTR_VENDOR_IFD_VERSION, buf.as_char, &dwBufLen);
	test_rv(rv, hContext, DONT_PANIC);
	if (rv == SCARD_S_SUCCESS)
	{
		int valid = 1;	/* valid value by default */
		long value;
		printf("Vendor IFD version\t\t: ");
		if (dwBufLen == sizeof(DWORD))
			value = buf.as_DWORD;
		else
		{
			if (dwBufLen == sizeof(uint32_t))
				value = buf.as_uint32_t;
			else
			{
				printf(RED "Unsupported size\n" NORMAL);
				valid = 0;	/* invalid value */
			}
		}

		if (valid)
		{
			int M = (value & 0xFF000000) >> 24;		/* Major */
			int m = (value & 0x00FF0000) >> 16;		/* Minor */
			int b = (value & 0x0000FFFF);			/* build */
			printf(GREEN "%d.%d.%d\n" NORMAL, M, m, b);
		}
	}
コード例 #15
0
ファイル: QPCSC.cpp プロジェクト: Krabi/idkaart_public
QPCSCReader::QPCSCReader( const QString &reader, QPCSC *parent )
	: QObject( parent )
	, d( new QPCSCReaderPrivate( parent->d ) )
{
	d->reader = reader.toUtf8();
	d->state.szReader = d->reader.constData();
	if( !d->updateState() )
		return;

	/* Use DIRECT mode only if there is no card in the reader */
	if( !isPresent() )
	{
#ifndef Q_OS_WIN /* Apple 10.5.7 and pcsc-lite previous to v1.5.5 do not support 0 as protocol identifier */
		DWORD proto = SCARD_PROTOCOL_T0|SCARD_PROTOCOL_T1;
#else
		DWORD proto = 0;
#endif
		LONG rv = SCardConnect( d->d->context, d->state.szReader, SCARD_SHARE_DIRECT, proto, &d->card, &d->proto );
		// Assume that there is a card in the reader in shared mode if direct communcation failed
		if( rv == LONG(SCARD_E_SHARING_VIOLATION) && !connect() )
			return;
	}
	else if( !connect() )
		return;

	d->friendlyName = d->attrib( SCARD_ATTR_DEVICE_FRIENDLY_NAME_A );
#if 0
	qDebug() << "SCARD_ATTR_DEVICE_FRIENDLY_NAME:" << d->attrib( SCARD_ATTR_DEVICE_FRIENDLY_NAME_A );
	qDebug() << "SCARD_ATTR_DEVICE_SYSTEM_NAME:" << d->attrib( SCARD_ATTR_DEVICE_SYSTEM_NAME_A );
	qDebug() << "SCARD_ATTR_DEVICE_UNIT:" << d->attrib( SCARD_ATTR_DEVICE_UNIT );
	qDebug() << "SCARD_ATTR_VENDOR_IFD_SERIAL_NO:" << d->attrib( SCARD_ATTR_VENDOR_IFD_SERIAL_NO );
	qDebug() << "SCARD_ATTR_VENDOR_IFD_TYPE:" << d->attrib( SCARD_ATTR_VENDOR_IFD_TYPE );
	qDebug() << "SCARD_ATTR_VENDOR_IFD_VERSION:" << d->attrib( SCARD_ATTR_VENDOR_IFD_VERSION );
	qDebug() << "SCARD_ATTR_VENDOR_NAME:" << d->attrib( SCARD_ATTR_VENDOR_NAME );
#endif

	DWORD size = 0;
	BYTE feature[256];
	LONG rv = SCardControl( d->card, CM_IOCTL_GET_FEATURE_REQUEST, 0, 0, feature, sizeof(feature), &size );
	if( rv == SCARD_S_SUCCESS && (size % sizeof(PCSC_TLV_STRUCTURE)) == 0 )
	{
		size /= sizeof(PCSC_TLV_STRUCTURE);
		PCSC_TLV_STRUCTURE *pcsc_tlv = (PCSC_TLV_STRUCTURE *)feature;
		for( DWORD i = 0; i < size; i++ )
			d->ioctl[DRIVER_FEATURES(pcsc_tlv[i].tag)] = ntohl( pcsc_tlv[i].value );
	}

	if( DWORD ioctl = d->ioctl.value(FEATURE_GET_TLV_PROPERTIES) )
	{
		DWORD size = 0;
		BYTE recv[256];
		rv = SCardControl( d->card, ioctl, 0, 0, recv, sizeof(recv), &size );
		unsigned char *p = recv;
		while( DWORD(p-recv) < size )
		{
			int tag = *p++, len = *p++, value = -1;
			switch( len )
			{
			case 1: value = *p; break;
			case 2: value = *p + (*(p+1)<<8); break;
			case 4: value = *p + (*(p+1)<<8) + (*(p+2)<<16) + (*(p+3)<<24); break;
			default: break;
			}
			p += len;
			d->properties[Properties(tag)] = value;
		}
	}

	if( DWORD ioctl = d->ioctl.value(FEATURE_IFD_PIN_PROPERTIES) )
	{
		DWORD size = 0;
		BYTE recv[256];
		DWORD rv = SCardControl( d->card, ioctl, 0, 0, recv, sizeof(recv), &size );
		if( rv == SCARD_S_SUCCESS )
		{
			PIN_PROPERTIES_STRUCTURE *caps = (PIN_PROPERTIES_STRUCTURE *)recv;
			d->display = caps->wLcdLayout > 0;
		}
	}

	disconnect();
}
コード例 #16
0
ファイル: acr122.c プロジェクト: copacetic/tabulator
int
acr122_send (nfc_device *pnd, const uint8_t *pbtData, const size_t szData, int timeout)
{
  // FIXME: timeout is not handled
  (void) timeout;

  // Make sure the command does not overflow the send buffer
  if (szData > ACR122_COMMAND_LEN) {
    pnd->last_error = NFC_EINVARG;
    return pnd->last_error;
  }

  // Prepare and transmit the send buffer
  const size_t szTxBuf = szData + 6;
  uint8_t  abtTxBuf[ACR122_WRAP_LEN + ACR122_COMMAND_LEN] = { 0xFF, 0x00, 0x00, 0x00, szData + 1, 0xD4 };
  memcpy (abtTxBuf + 6, pbtData, szData);
  LOG_HEX ("TX", abtTxBuf, szTxBuf);

  DRIVER_DATA (pnd)->szRx = 0;

  DWORD dwRxLen = sizeof (DRIVER_DATA (pnd)->abtRx);

  if (DRIVER_DATA (pnd)->ioCard.dwProtocol == SCARD_PROTOCOL_UNDEFINED) {
    /*
     * In this communication mode, we directly have the response from the
     * PN532.  Save it in the driver data structure so that it can be retrieved
     * in ac122_receive().
     *
     * Some devices will never enter this state (e.g. Touchatag) but are still
     * supported through SCardTransmit calls (see bellow).
     *
     * This state is generaly reached when the ACR122 has no target in it's
     * field.
     */
    if (SCardControl (DRIVER_DATA (pnd)->hCard, IOCTL_CCID_ESCAPE_SCARD_CTL_CODE, abtTxBuf, szTxBuf, DRIVER_DATA (pnd)->abtRx, ACR122_RESPONSE_LEN, &dwRxLen) != SCARD_S_SUCCESS) {
      pnd->last_error = NFC_EIO;
      return pnd->last_error;
    }
  } else {
    /*
     * In T=0 mode, we receive an acknoledge from the MCU, in T=1 mode, we
     * receive the response from the PN532.
     */
    if (SCardTransmit (DRIVER_DATA (pnd)->hCard, &(DRIVER_DATA (pnd)->ioCard), abtTxBuf, szTxBuf, NULL, DRIVER_DATA (pnd)->abtRx, &dwRxLen) != SCARD_S_SUCCESS) {
      pnd->last_error = NFC_EIO;
      return pnd->last_error;
    }
  }

  if (DRIVER_DATA (pnd)->ioCard.dwProtocol == SCARD_PROTOCOL_T0) {
   /*
    * Check the MCU response
    */

    // Make sure we received the byte-count we expected
    if (dwRxLen != 2) {
      pnd->last_error = NFC_EIO;
      return pnd->last_error;
    }
    // Check if the operation was successful, so an answer is available
    if (DRIVER_DATA (pnd)->abtRx[0] == SCARD_OPERATION_ERROR) {
      pnd->last_error = NFC_EIO;
      return pnd->last_error;
    }
  } else {
    DRIVER_DATA (pnd)->szRx = dwRxLen;
  }

  return NFC_SUCCESS;
}
コード例 #17
0
ファイル: testpcsc_testrun.c プロジェクト: denehs/pcsc-lite
int main(/*@unused@*/ int argc, /*@unused@*/ char **argv)
{
	SCARDHANDLE hCard;
	SCARDCONTEXT hContext;
	SCARD_READERSTATE_A rgReaderStates[1];
	DWORD dwReaderLen, dwState, dwProt, dwAtrLen;
	DWORD dwPref, dwReaders = 0;
	char *pcReaders = NULL, *mszReaders;
#ifdef USE_AUTOALLOCATE
	unsigned char *pbAtr = NULL;
#else
	unsigned char pbAtr[MAX_ATR_SIZE];
#endif
	union {
		unsigned char as_char[100];
		DWORD as_DWORD;
		uint32_t as_uint32_t;
	} buf;
	DWORD dwBufLen;
	unsigned char *pbAttr = NULL;
	DWORD pcbAttrLen;
	char *mszGroups;
	DWORD dwGroups = 0;
	long rv;
	DWORD i;
	int p, iReader;
	int iList[16];
	SCARD_IO_REQUEST pioRecvPci;
	SCARD_IO_REQUEST pioSendPci;
	unsigned char bSendBuffer[MAX_BUFFER_SIZE];
	unsigned char bRecvBuffer[MAX_BUFFER_SIZE];
	DWORD send_length, length;

	(void)argc;
	(void)argv;

	printf("\nMUSCLE PC/SC Lite unitary test Program\n\n");

	printf(MAGENTA "THIS PROGRAM IS NOT DESIGNED AS A TESTING TOOL FOR END USERS!\n");
	printf("Do NOT use it unless you really know what you do.\n\n" NORMAL);

	printf("Testing SCardEstablishContext\t: ");
	rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);
	test_rv(rv, hContext, PANIC);

	printf("Testing SCardIsValidContext\t: ");
	rv = SCardIsValidContext(hContext);
	test_rv(rv, hContext, PANIC);

	printf("Testing SCardIsValidContext\t: ");
	rv = SCardIsValidContext(hContext+1);
	test_rv(rv, hContext, DONT_PANIC);

	printf("Testing SCardListReaderGroups\t: ");
#ifdef USE_AUTOALLOCATE
	dwGroups = SCARD_AUTOALLOCATE;
	rv = SCardListReaderGroups(hContext, (LPSTR)&mszGroups, &dwGroups);
#else
	rv = SCardListReaderGroups(hContext, NULL, &dwGroups);
	test_rv(rv, hContext, PANIC);

	printf("Testing SCardListReaderGroups\t: ");
	mszGroups = calloc(dwGroups, sizeof(char));
	rv = SCardListReaderGroups(hContext, mszGroups, &dwGroups);
#endif
	test_rv(rv, hContext, PANIC);

	/*
	 * Have to understand the multi-string here
	 */
	p = 0;
	for (i = 0; i+1 < dwGroups; i++)
	{
		++p;
		printf(GREEN "Group %02d: %s\n" NORMAL, p, &mszGroups[i]);
		while (mszGroups[++i] != 0) ;
	}

#ifdef USE_AUTOALLOCATE
	printf("Testing SCardFreeMemory\t\t: ");
	rv = SCardFreeMemory(hContext, mszGroups);
	test_rv(rv, hContext, PANIC);
#else
	free(mszGroups);
#endif

wait_for_card_again:
	mszGroups = NULL;
	printf("Testing SCardListReaders\t: ");
	rv = SCardListReaders(hContext, mszGroups, NULL, &dwReaders);
	test_rv(rv, hContext, DONT_PANIC);
	if (SCARD_E_NO_READERS_AVAILABLE == rv)
	{
		printf("Testing SCardGetStatusChange \n");
		printf("Please insert a working reader\t: ");
		(void)fflush(stdout);
		rgReaderStates[0].szReader = "\\\\?PnP?\\Notification";
		rgReaderStates[0].dwCurrentState = SCARD_STATE_EMPTY;

		rv = SCardGetStatusChange(hContext, INFINITE, rgReaderStates, 1);
		test_rv(rv, hContext, PANIC);
	}

	printf("Testing SCardListReaders\t: ");
#ifdef USE_AUTOALLOCATE
	dwReaders = SCARD_AUTOALLOCATE;
	rv = SCardListReaders(hContext, mszGroups, (LPSTR)&mszReaders, &dwReaders);
#else
	rv = SCardListReaders(hContext, mszGroups, NULL, &dwReaders);
	test_rv(rv, hContext, PANIC);

	printf("Testing SCardListReaders\t: ");
	mszReaders = calloc(dwReaders, sizeof(char));
	rv = SCardListReaders(hContext, mszGroups, mszReaders, &dwReaders);
#endif
	test_rv(rv, hContext, DONT_PANIC);

	/*
	 * Have to understand the multi-string here
	 */
	p = 0;
	for (i = 0; i+1 < dwReaders; i++)
	{
		++p;
		printf(GREEN "Reader %02d: %s\n" NORMAL, p, &mszReaders[i]);
		iList[p] = i;
		while (mszReaders[++i] != 0) ;
	}

	if (p > 1)
		do
		{
			char input[80];

			printf("Enter the reader number\t\t: ");
			(void)fgets(input, sizeof(input), stdin);
			(void)sscanf(input, "%d", &iReader);

			if (iReader > p || iReader <= 0)
				printf("Invalid Value - try again\n");
		}
		while (iReader > p || iReader <= 0);
	else
		iReader = 1;

	rgReaderStates[0].szReader = &mszReaders[iList[iReader]];
	rgReaderStates[0].dwCurrentState = SCARD_STATE_EMPTY;

	printf("Waiting for card insertion\t: ");
	(void)fflush(stdout);
	rv = SCardGetStatusChange(hContext, INFINITE, rgReaderStates, 1);
	test_rv(rv, hContext, PANIC);
	if (rgReaderStates[0].dwEventState & SCARD_STATE_UNKNOWN)
	{
		printf("\nA reader has been connected/disconnected\n");
		goto wait_for_card_again;
	}

	printf("Testing SCardConnect\t\t: ");
	rv = SCardConnect(hContext, &mszReaders[iList[iReader]],
		SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1,
		&hCard, &dwPref);
	test_rv(rv, hContext, PANIC);

	switch(dwPref)
	{
		case SCARD_PROTOCOL_T0:
			pioSendPci = *SCARD_PCI_T0;
			break;
		case SCARD_PROTOCOL_T1:
			pioSendPci = *SCARD_PCI_T1;
			break;
		case SCARD_PROTOCOL_RAW:
			pioSendPci = *SCARD_PCI_RAW;
			break;
		default:
			printf("Unknown protocol\n");
			return -1;
	}

	int bBreak = 0;

	while (1)
	{
		char inputCommand[1024];	
		char inputAPDU[1024];
		int inputAPDULen = sizeof(inputAPDU);
		printf("Enter APDU to send, (e.g. 00:A4:04:00:00)\n");
		printf("Command APDU: ");
		(void)fgets(inputCommand, sizeof(inputCommand), stdin);
		
		int stringlen = strlen(inputCommand);
		if( inputCommand[stringlen-1] == '\n' ) { inputCommand[stringlen-1] = 0; } //remove newline

		int bError = sc_hex_to_bin(inputCommand, inputAPDU, &inputAPDULen);
		//printf("debug - value bError: %i\n",bError);
		if (bError) { printf("Error parsing input\n\n"); continue; }

		send_length = inputAPDULen;
		if (inputAPDULen == 0) { break; }
		printf("debug inputAPDULen: %i\n",inputAPDULen); 
		memcpy(bSendBuffer, inputAPDU, send_length);
		length = sizeof(bRecvBuffer);

		printf("Testing SCardTransmit:\n "); printf("-> ");
		for (i=0; i<send_length; i++) { printf(" %02X", bSendBuffer[i]); }
		printf("\n");
		rv = SCardTransmit(hCard, &pioSendPci, bSendBuffer, send_length,
			&pioRecvPci, bRecvBuffer, &length);
		test_rv(rv, hContext, PANIC);
		printf("<- " GREEN);
		for (i=0; i<length; i++)
			printf(" %02X", bRecvBuffer[i]);
		printf("\n" NORMAL);
	}

	testrun(&hCard, &hContext, &pioSendPci, 0);
	testrun(&hCard, &hContext, &pioSendPci, 1);
	testrun(&hCard, &hContext, &pioSendPci, 2);
	testrun(&hCard, &hContext, &pioSendPci, 3);

	printf("Testing SCardControl\t\t: ");
#ifdef PCSC_PRE_120
	{
		char buffer[1024] = "Foobar";
		DWORD cbRecvLength = sizeof(buffer);

		rv = SCardControl(hCard, buffer, 7, buffer, &cbRecvLength);
	}
#else
	{
		char buffer[1024] = { 0x02 };
		DWORD cbRecvLength = sizeof(buffer);

		rv = SCardControl(hCard, SCARD_CTL_CODE(1), buffer, 1, buffer,
			sizeof(buffer), &cbRecvLength);
		if (cbRecvLength && (SCARD_S_SUCCESS == rv))
		{
			for (i=0; i<cbRecvLength; i++)
				printf("%c", buffer[i]);
			printf(" ");
		}
	}
#endif
	test_rv(rv, hContext, DONT_PANIC);

	printf("Testing SCardGetAttrib\t\t: ");
#ifdef USE_AUTOALLOCATE
	pcbAttrLen = SCARD_AUTOALLOCATE;
	rv = SCardGetAttrib(hCard, SCARD_ATTR_DEVICE_FRIENDLY_NAME, (unsigned char *)&pbAttr,
		&pcbAttrLen);
#else
	rv = SCardGetAttrib(hCard, SCARD_ATTR_DEVICE_FRIENDLY_NAME, NULL, &pcbAttrLen);
	test_rv(rv, hContext, DONT_PANIC);
	if (rv == SCARD_S_SUCCESS)
	{
		printf("SCARD_ATTR_DEVICE_FRIENDLY_NAME length: " GREEN "%ld\n" NORMAL, pcbAttrLen);
		pbAttr = malloc(pcbAttrLen);
	}

	printf("Testing SCardGetAttrib\t\t: ");
	rv = SCardGetAttrib(hCard, SCARD_ATTR_DEVICE_FRIENDLY_NAME, pbAttr, &pcbAttrLen);
#endif
	test_rv(rv, hContext, DONT_PANIC);
	if (rv == SCARD_S_SUCCESS)
		printf("SCARD_ATTR_DEVICE_FRIENDLY_NAME: " GREEN "%s\n" NORMAL, pbAttr);

#ifdef USE_AUTOALLOCATE
	printf("Testing SCardFreeMemory\t\t: ");
	rv = SCardFreeMemory(hContext, pbAttr);
	test_rv(rv, hContext, PANIC);
#else
	if (pbAttr)
		free(pbAttr);
#endif

	printf("Testing SCardGetAttrib\t\t: ");
#ifdef USE_AUTOALLOCATE
	pcbAttrLen = SCARD_AUTOALLOCATE;
	rv = SCardGetAttrib(hCard, SCARD_ATTR_ATR_STRING, (unsigned char *)&pbAttr,
		&pcbAttrLen);
#else
	rv = SCardGetAttrib(hCard, SCARD_ATTR_ATR_STRING, NULL, &pcbAttrLen);
	test_rv(rv, hContext, DONT_PANIC);
	if (rv == SCARD_S_SUCCESS)
	{
		printf("SCARD_ATTR_ATR_STRING length: " GREEN "%ld\n" NORMAL, pcbAttrLen);
		pbAttr = malloc(pcbAttrLen);
	}

	printf("Testing SCardGetAttrib\t\t: ");
	rv = SCardGetAttrib(hCard, SCARD_ATTR_ATR_STRING, pbAttr, &pcbAttrLen);
#endif
	test_rv(rv, hContext, DONT_PANIC);
	if (rv == SCARD_S_SUCCESS)
	{
		printf("SCARD_ATTR_ATR_STRING length: " GREEN "%ld\n" NORMAL, pcbAttrLen);
		printf("SCARD_ATTR_ATR_STRING: " GREEN);
		for (i = 0; i < pcbAttrLen; i++)
			printf("%02X ", pbAttr[i]);
		printf("\n" NORMAL);
	}

#ifdef USE_AUTOALLOCATE
	printf("Testing SCardFreeMemory\t\t: ");
	rv = SCardFreeMemory(hContext, pbAttr);
	test_rv(rv, hContext, PANIC);
#else
	if (pbAttr)
		free(pbAttr);
#endif

	printf("Testing SCardGetAttrib\t\t: ");
	dwBufLen = sizeof(buf);
	rv = SCardGetAttrib(hCard, SCARD_ATTR_VENDOR_IFD_VERSION, buf.as_char, &dwBufLen);
	test_rv(rv, hContext, DONT_PANIC);
	if (rv == SCARD_S_SUCCESS)
		printf("Vendor IFD version\t\t: " GREEN "0x%08lX\n" NORMAL,
			buf.as_DWORD);

	printf("Testing SCardGetAttrib\t\t: ");
	dwBufLen = sizeof(buf);
	rv = SCardGetAttrib(hCard, SCARD_ATTR_MAXINPUT, buf.as_char, &dwBufLen);
	test_rv(rv, hContext, DONT_PANIC);
	if (rv == SCARD_S_SUCCESS)
	{
		if (dwBufLen == sizeof(uint32_t))
			printf("Max message length\t\t: " GREEN "%d\n" NORMAL,
				buf.as_uint32_t);
		else
			printf(RED "Wrong size" NORMAL);
	}

	printf("Testing SCardGetAttrib\t\t: ");
	dwBufLen = sizeof(buf);
	rv = SCardGetAttrib(hCard, SCARD_ATTR_VENDOR_NAME, buf.as_char, &dwBufLen);
	test_rv(rv, hContext, DONT_PANIC);
	if (rv == SCARD_S_SUCCESS)
		printf("Vendor name\t\t\t: " GREEN "%s\n" NORMAL, buf.as_char);

	printf("Testing SCardSetAttrib\t\t: ");
	rv = SCardSetAttrib(hCard, SCARD_ATTR_ATR_STRING, (LPCBYTE)"", 1);
	test_rv(rv, hContext, DONT_PANIC);

	printf("Testing SCardStatus\t\t: ");

#ifdef USE_AUTOALLOCATE
	dwReaderLen = SCARD_AUTOALLOCATE;
	dwAtrLen = SCARD_AUTOALLOCATE;
	rv = SCardStatus(hCard, (LPSTR)&pcReaders, &dwReaderLen, &dwState, &dwProt,
		(LPBYTE)&pbAtr, &dwAtrLen);
#else
	dwReaderLen = 100;
	pcReaders   = malloc(sizeof(char) * 100);
	dwAtrLen    = MAX_ATR_SIZE;

	rv = SCardStatus(hCard, pcReaders, &dwReaderLen, &dwState, &dwProt,
		pbAtr, &dwAtrLen);
#endif
	test_rv(rv, hContext, PANIC);

	printf("Current Reader Name\t\t: " GREEN "%s\n" NORMAL, pcReaders);
	printf("Current Reader State\t\t: " GREEN "0x%.4lx\n" NORMAL, dwState);
	printf("Current Reader Protocol\t\t: T=" GREEN "%ld\n" NORMAL, dwProt - 1);
	printf("Current Reader ATR Size\t\t: " GREEN "%ld" NORMAL " bytes\n",
		dwAtrLen);
	printf("Current Reader ATR Value\t: " GREEN);

	for (i = 0; i < dwAtrLen; i++)
	{
		printf("%02X ", pbAtr[i]);
	}
	printf(NORMAL "\n");

#ifdef USE_AUTOALLOCATE
	printf("Testing SCardFreeMemory\t\t: ");
	rv = SCardFreeMemory(hContext, pcReaders);
	test_rv(rv, hContext, PANIC);
	printf("Testing SCardFreeMemory\t\t: ");
	rv = SCardFreeMemory(hContext, pbAtr);
	test_rv(rv, hContext, PANIC);
#else
	if (pcReaders)
		free(pcReaders);
#endif

	if (rv != SCARD_S_SUCCESS)
	{
		(void)SCardDisconnect(hCard, SCARD_RESET_CARD);
		(void)SCardReleaseContext(hContext);
	}

	printf("Press enter: ");
	(void)getchar();
	printf("Testing SCardReconnect\t\t: ");
	rv = SCardReconnect(hCard, SCARD_SHARE_SHARED,
		SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, SCARD_UNPOWER_CARD, &dwPref);
	test_rv(rv, hContext, PANIC);

	printf("Testing SCardDisconnect\t\t: ");
	rv = SCardDisconnect(hCard, SCARD_UNPOWER_CARD);
	test_rv(rv, hContext, PANIC);

#ifdef USE_AUTOALLOCATE
	printf("Testing SCardFreeMemory\t\t: ");
	rv = SCardFreeMemory(hContext, mszReaders);
	test_rv(rv, hContext, PANIC);
#else
	free(mszReaders);
#endif

	printf("Testing SCardReleaseContext\t: ");
	rv = SCardReleaseContext(hContext);
	test_rv(rv, hContext, PANIC);

	printf("\n");
	printf("PC/SC Test Completed Successfully !\n");

	return 0;
}
コード例 #18
0
ファイル: card-belpic.c プロジェクト: securez/opendnie
static LONG SCR_SCardPIN(long lAction, LPCTSTR szPinPadDll, const SCR_Card * pCard, BYTE pinID,
			 const SCR_PinUsage * pUsage, const SCR_Application * pApp,
			 BYTE * pCardStatus)
{
	LONG rv;
	unsigned char sendbuf[256];
	unsigned char recvbuf[2];
	char szTemp[32];
	DWORD dwRecvLength;
	struct tTLV tlv;

	memset(szTemp, 0, sizeof(szTemp));
	memset(recvbuf, 0, sizeof(recvbuf));
	dwRecvLength = sizeof(recvbuf);

	/* Make TLV buffer */
	TLVInit(&tlv, sendbuf, sizeof(sendbuf));
	TLVNext(&tlv, 0x01);	/* Function ID */
	sprintf(szTemp, "%ld", lAction);
	TLVAddBuffer(&tlv, (u8 *) szTemp, strlen(szTemp));
	TLVNext(&tlv, 0x02);	/* PinPad Dll */
	TLVAddBuffer(&tlv, (u8 *) szPinPadDll, strlen(szPinPadDll));
	TLVNext(&tlv, 0x03);	/* SCR_Card Handle */
	sprintf(szTemp, "%ld", pCard->hCard);
	TLVAddBuffer(&tlv, (u8 *) szTemp, strlen(szTemp));
	if (pCard->language != NULL) {
		TLVNext(&tlv, 0x04);	/* SCR_Card language */
		TLVAddBuffer(&tlv, (u8 *) pCard->language, strlen(pCard->language));
	}
	if (pCard->id.data != NULL) {
		TLVNext(&tlv, 0x05);	/* SCR_Card id */
		TLVAddBuffer(&tlv, pCard->id.data, pCard->id.length);
	}
	TLVNext(&tlv, 0x06);	/* PinID */
	TLVAdd(&tlv, pinID);
	if (pUsage != NULL) {
		TLVNext(&tlv, 0x07);	/* SCR_PinUsage code */
		sprintf(szTemp, "%ld", pUsage->code);
		TLVAddBuffer(&tlv, (u8 *) szTemp, strlen(szTemp));
		if (pUsage->shortString != NULL) {
			TLVNext(&tlv, 0x08);	/* SCR_PinUsage shortstring */
			TLVAddBuffer(&tlv, (u8 *) pUsage->shortString, strlen(pUsage->shortString));
		}
		if (pUsage->longString != NULL) {
			TLVNext(&tlv, 0x09);	/* SCR_PinUsage longstring */
			TLVAddBuffer(&tlv, (u8 *) pUsage->longString, strlen(pUsage->longString));
		}
	}
	if (pApp->id.data != NULL) {
		TLVNext(&tlv, 0x0A);	/* SCR_Application id */
		TLVAddBuffer(&tlv, (u8 *) pApp->id.data, pApp->id.length);
	}
	if (pApp->shortString != NULL) {
		TLVNext(&tlv, 0x0B);	/* SCR_Application shortstring */
		TLVAddBuffer(&tlv, (u8 *) pApp->shortString, strlen(pApp->shortString));
	}
	if (pApp->longString != NULL) {
		TLVNext(&tlv, 0x0C);	/* SCR_Application longstring */
		TLVAddBuffer(&tlv, (u8 *) pApp->longString, strlen(pApp->longString));
	}
#ifdef HAVE_PCSC_OLD
	rv = SCardControl(SCR_CARD_HANDLE, sendbuf, TLVLen(&tlv), recvbuf, &dwRecvLength);
#else
	rv = SCardControl(SCR_CARD_HANDLE, 0, sendbuf, TLVLen(&tlv),
			  recvbuf, dwRecvLength, &dwRecvLength);
#endif
	if (dwRecvLength < 2) {
		rv = SC_ERROR_UNKNOWN_DATA_RECEIVED;
	} else {
		memcpy(pCardStatus, recvbuf, 2);
	}

	return rv;
}
コード例 #19
0
/**
 * checkForNewPCSCToken looks into a specific slot for a token.
 *
 * @param slot       Pointer to slot structure.
 *
 * @return
 *                   <P><TABLE>
 *                   <TR><TD>Code</TD><TD>Meaning</TD></TR>
 *                   <TR>
 *                   <TD>CKR_OK                                 </TD>
 *                   <TD>Success                                </TD>
 *                   </TR>
 *                   <TR>
 *                   <TD>CKR_HOST_MEMORY                        </TD>
 *                   <TD>Error getting memory (malloc)          </TD>
 *                   </TR>
 *                   <TR>
 *                   <TD>CKR_GENERAL_ERROR                      </TD>
 *                   <TD>Error opening slot directory           </TD>
 *                   </TR>
 *                   </TABLE></P>
 */
static int checkForNewPCSCToken(struct p11Slot_t *slot)
{
	struct p11Token_t *ptoken;
	int rc, i;
	LONG rv;
	DWORD dwActiveProtocol;
	WORD feature;
	DWORD featurecode, lenr, atrlen,readernamelen,state,protocol;
	unsigned char buf[256];
	unsigned char atr[36];
	char *po;

	FUNC_CALLED();

	if (slot->closed) {
		FUNC_RETURNS(CKR_TOKEN_NOT_PRESENT);
	}

	rv = SCardConnect(slot->context, slot->readername, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T1, &(slot->card), &dwActiveProtocol);

#ifdef DEBUG
	debug("SCardConnect (%i, %s): %s\n", slot->id, slot->readername, pcsc_error_to_string(rv));
#endif

	if (rv == SCARD_E_NO_SMARTCARD || rv == SCARD_W_REMOVED_CARD || rv == SCARD_E_SHARING_VIOLATION) {
		FUNC_RETURNS(CKR_TOKEN_NOT_PRESENT);
	}

	if (rv != SCARD_S_SUCCESS) {
		closeSlot(slot);
		FUNC_FAILS(CKR_DEVICE_ERROR, pcsc_error_to_string(rv));
	}

	if (!slot->hasFeatureVerifyPINDirect) {
		rv = SCardControl(slot->card, SCARD_CTL_CODE(3400), NULL,0, buf, sizeof(buf), &lenr);

#ifdef DEBUG
		debug("SCardControl (CM_IOCTL_GET_FEATURE_REQUEST): %s\n", pcsc_error_to_string(rv));
#endif

		/* Ignore the feature codes if an error occured */
		if (rv == SCARD_S_SUCCESS) {
			for (i = 0; i < lenr; i += 6) {
				feature = buf[i];
				featurecode = (buf[i + 2] << 24) + (buf[i + 3] << 16) + (buf[i + 4] << 8) + buf[i + 5];
	#ifdef DEBUG
				debug("%s - 0x%08X\n", pcsc_feature_to_string(feature), featurecode);
	#endif
				if (feature == FEATURE_VERIFY_PIN_DIRECT) {
					po = getenv("PKCS11_IGNORE_PINPAD");
	#ifdef DEBUG
					if (po) {
						debug("PKCS11_IGNORE_PINPAD=%s\n", po);
					} else {
						debug("PKCS11_IGNORE_PINPAD not found\n");
					}
	#endif
					if (!po || (*po == '0')) {
	#ifdef DEBUG
						debug("Slot supports feature VERIFY_PIN_DIRECT - setting CKF_PROTECTED_AUTHENTICATION_PATH for token\n");
	#endif
						slot->hasFeatureVerifyPINDirect = featurecode;
					}
				}
			}
		}
	}

	readernamelen = 0;
	atrlen = sizeof(atr);

	rc = SCardStatus(slot->card, NULL, &readernamelen, &state, &protocol, atr, &atrlen);

	if (rc != SCARD_S_SUCCESS) {
		closeSlot(slot);
		FUNC_FAILS(CKR_DEVICE_ERROR, pcsc_error_to_string(rc));
	}

	rc = newToken(slot, atr, atrlen, &ptoken);

	if (rc != CKR_OK) {
		FUNC_FAILS(rc, "newToken() failed");
	}

	FUNC_RETURNS(rc);
}
コード例 #20
0
ファイル: ifdnfc-activate.c プロジェクト: benmehlman/ifdnfc
int
main(int argc, char *argv[])
{
  LONG rv;
  SCARDCONTEXT hContext;
  SCARDHANDLE hCard;
  char *reader;
  BYTE pbSendBuffer[1 + 1 + sizeof(nfc_connstring)];
  DWORD dwSendLength;
  BYTE pbRecvBuffer[1];
  DWORD dwActiveProtocol, dwRecvLength, dwReaders;
  char* mszReaders = NULL;

  if (argc == 1 ||
      (argc == 2 && (strncmp(argv[1], "yes", strlen("yes")) == 0)))
    pbSendBuffer[0] = IFDNFC_SET_ACTIVE;
  else if (argc == 2 && (strncmp(argv[1], "no", strlen("no")) == 0))
    pbSendBuffer[0] = IFDNFC_SET_INACTIVE;
  else if (argc == 2 && (strncmp(argv[1], "se", strlen("se")) == 0))
    pbSendBuffer[0] = IFDNFC_SET_ACTIVE_SE;
  else if (argc == 2 && (strncmp(argv[1], "status", strlen("status")) == 0))
    pbSendBuffer[0] = IFDNFC_GET_STATUS;
  else {
    printf("Usage: %s [yes|no|status]\n", argv[0]);
    exit(EXIT_FAILURE);
  }


  rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);
  if (rv < 0)
    goto pcsc_error;

  dwReaders = 0;
  // Ask how many bytes readers list take
  rv = SCardListReaders(hContext, NULL, NULL, &dwReaders);
  if (rv < 0)
    goto pcsc_error;
  // Then allocate and fill mszReaders
  mszReaders = malloc(dwReaders);
  rv = SCardListReaders(hContext, NULL, mszReaders, &dwReaders);
  if (rv < 0)
    goto pcsc_error;

  int l;
  for (reader = mszReaders;
       dwReaders > 0;
       l = strlen(reader) + 1, dwReaders -= l, reader += l) {
    if (strcmp(IFDNFC_READER_NAME, reader) <= 0)
      break;
  }
  if (dwReaders <= 0) {
    printf("Could not find a reader named: %s\n", IFDNFC_READER_NAME);
    rv = SCARD_E_NO_READERS_AVAILABLE;
    goto pcsc_error;
  }

  // TODO Handle multiple ifdnfc instance for multiple NFC device ?
  rv = SCardConnect(hContext, reader, SCARD_SHARE_DIRECT, 0, &hCard,
                    &dwActiveProtocol);
  if (rv < 0)
    goto pcsc_error;

  if ((pbSendBuffer[0] == IFDNFC_SET_ACTIVE) || (pbSendBuffer[0] == IFDNFC_SET_ACTIVE_SE))  {
    const BYTE command = pbSendBuffer[0];
    // To correctly probe NFC devices, ifdnfc must be disactivated first
    pbSendBuffer[0] = IFDNFC_SET_INACTIVE;
    dwSendLength = 1;
    rv = SCardControl(hCard, IFDNFC_CTRL_ACTIVE, pbSendBuffer,
                      dwSendLength, pbRecvBuffer, sizeof(pbRecvBuffer),
                      &dwRecvLength);
    if (rv < 0) {
      goto pcsc_error;
    }

    pbSendBuffer[0] = command;
    // Initialize libnfc
    nfc_context *context;
    nfc_init(&context);
    if (context == NULL) {
      fprintf(stderr, "Unable to init libnfc (malloc)\n");
      goto error;
    }
    // Allocate nfc_connstring array
    nfc_connstring connstrings[MAX_DEVICE_COUNT];
    // List devices
    size_t szDeviceFound = nfc_list_devices(context, connstrings, MAX_DEVICE_COUNT);

    int connstring_index = -1;
    switch (szDeviceFound) {
      case 0:
        fprintf(stderr, "Unable to activate ifdnfc: no NFC device found.\n");
        nfc_exit(context);
        goto error;
        break;
      case 1:
        // Only one NFC device available, so auto-select it!
        connstring_index = 0;
        break;
      default:
        // More than one available NFC devices, propose a shell menu:
        printf("%d NFC devices found, please select one:\n", (int)szDeviceFound);
        for (size_t i = 0; i < szDeviceFound; i++) {
          nfc_device *pnd = nfc_open(context, connstrings[i]);
          if (pnd != NULL) {
            printf("[%d] %s\t  (%s)\n", (int)i, nfc_device_get_name(pnd), nfc_device_get_connstring(pnd));
            nfc_close(pnd);
          } else {
            fprintf(stderr, "nfc_open failed for %s\n", connstrings[i]);
          }
        }
        // libnfc isn't needed anymore
        nfc_exit(context);
        printf(">> ");
        // Take user's choice
        if (1 != scanf("%2d", &connstring_index)) {
          fprintf(stderr, "Value must an integer.\n");
          goto error;
        }
        if ((connstring_index < 0) || (connstring_index >= (int)szDeviceFound)) {
          fprintf(stderr, "Invalid index selection.\n");
          goto error;
        }
        break;
    }
    printf("Activating ifdnfc with \"%s\"...\n", connstrings[connstring_index]);
    // pbSendBuffer = { IFDNFC_SET_ACTIVE (1 byte), length (2 bytes), nfc_connstring (lenght bytes)}
    const uint16_t u16ConnstringLength = strlen(connstrings[connstring_index]) + 1;
    memcpy(pbSendBuffer + 1, &u16ConnstringLength, sizeof(u16ConnstringLength));
    memcpy(pbSendBuffer + 1 + sizeof(u16ConnstringLength), connstrings[connstring_index], u16ConnstringLength);
    dwSendLength = 1 + sizeof(u16ConnstringLength) + u16ConnstringLength;
  } else {
    // pbSendBuffer[0] != IFDNFC_SET_ACTIVE
    dwSendLength = 1;
  }

  rv = SCardControl(hCard, IFDNFC_CTRL_ACTIVE, pbSendBuffer,
                    dwSendLength, pbRecvBuffer, sizeof(pbRecvBuffer),
                    &dwRecvLength);
  if (rv < 0) {
    goto pcsc_error;
  }
  if (dwRecvLength < 1) {
    rv = SCARD_F_INTERNAL_ERROR;
    goto pcsc_error;
  }

  switch (pbRecvBuffer[0]) {
    case IFDNFC_IS_ACTIVE: {
      uint16_t u16ConnstringLength;
      if (dwRecvLength < (1 + sizeof(u16ConnstringLength))) {
        rv = SCARD_F_INTERNAL_ERROR;
        goto pcsc_error;
      }
      memcpy(&u16ConnstringLength, pbRecvBuffer + 1, sizeof(u16ConnstringLength));
      if ((dwRecvLength - (1 + sizeof(u16ConnstringLength))) != u16ConnstringLength) {
        rv = SCARD_F_INTERNAL_ERROR;
        goto pcsc_error;
      }
      nfc_connstring connstring;
      memcpy(connstring, pbRecvBuffer + 1 + sizeof(u16ConnstringLength), u16ConnstringLength);
      printf("%s is active using %s.\n", IFDNFC_READER_NAME, connstring);
    }
    break;
    case IFDNFC_IS_INACTIVE:
      printf("%s is inactive.\n", IFDNFC_READER_NAME);
      break;
    default:
      rv = SCARD_F_INTERNAL_ERROR;
      goto pcsc_error;
  }


  rv = SCardDisconnect(hCard, SCARD_LEAVE_CARD);
  if (rv < 0)
    goto pcsc_error;

  free(mszReaders);

  exit(EXIT_SUCCESS);

pcsc_error:
  puts(pcsc_stringify_error(rv));
error:
  if (mszReaders)
    free(mszReaders);

  exit(EXIT_FAILURE);
}
コード例 #21
0
PaceOutput PCSCReader::establishPACEChannel(const PaceInput &input) const
{
	PaceOutput output;
	DWORD r, recvlen;
	uint8_t length_CHAT, length_PIN, PinID;
	uint16_t lengthInputData, lengthCertificateDescription;
	BYTE recvbuf[1024];

	if (input.get_chat().size() > 0xff || input.get_pin().size() > 0xff)
		throw PACEException();

	length_CHAT = (uint8_t) input.get_chat().size();
	length_PIN = (uint8_t) input.get_pin().size();
	//FIXME input.get_certificate_description().size();
	// The certificate description we get is in wrong format
	lengthCertificateDescription = 0;
	lengthInputData = sizeof PinID
					  + sizeof length_CHAT + length_CHAT
					  + sizeof length_PIN + length_PIN
					  + sizeof lengthCertificateDescription + lengthCertificateDescription;
	size_t sendlen = 1 + 2 + lengthInputData;
	BYTE *sendbuf = (BYTE *) malloc(sendlen);

	if (!sendbuf)
		throw TransactionFailed();

	switch (input.get_pin_id()) {
		case PaceInput::mrz:
			PinID = PIN_ID_MRZ;
			break;
		case PaceInput::pin:
			PinID = PIN_ID_PIN;
			break;
		case PaceInput::can:
			PinID = PIN_ID_CAN;
			break;
		case PaceInput::puk:
			PinID = PIN_ID_PUK;
			break;
		default:
			PinID = 0;
			break;
	}

	*sendbuf = FUNCTION_EstabishPACEChannel;
	memcpy(sendbuf + 1,
		   &lengthInputData, sizeof lengthInputData);
	memcpy(sendbuf + 1 + sizeof lengthInputData,
		   &PinID, sizeof PinID);
	memcpy(sendbuf + 1 + sizeof lengthInputData + sizeof PinID,
		   &length_CHAT, sizeof length_CHAT);
	memcpy(sendbuf + 1 + sizeof lengthInputData + sizeof PinID + sizeof length_CHAT,
		   input.get_chat().data(), length_CHAT);
	memcpy(sendbuf + 1 + sizeof lengthInputData + sizeof PinID + sizeof length_CHAT + length_CHAT,
		   &length_PIN, sizeof length_PIN);
	memcpy(sendbuf + 1 + sizeof lengthInputData + sizeof PinID + sizeof length_CHAT + length_CHAT + sizeof length_PIN,
		   input.get_pin().data(), length_PIN);
	memcpy(sendbuf + 1 + sizeof lengthInputData + sizeof PinID + sizeof length_CHAT + length_CHAT + sizeof length_PIN + length_PIN,
		   &lengthCertificateDescription, sizeof lengthCertificateDescription);
	memcpy(sendbuf + 1 + sizeof lengthInputData + sizeof PinID + sizeof length_CHAT + length_CHAT + sizeof length_PIN + length_PIN + sizeof lengthCertificateDescription,
		   input.get_certificate_description().data(), lengthCertificateDescription);
	hexdump(DEBUG_LEVEL_CARD, "Execute PACE Input Data (FUNCTION=EstabishPACEChannel)", sendbuf, sendlen);
	recvlen = sizeof(recvbuf);
	r = SCardControl(m_hCard, m_ioctl_pace, sendbuf, sendlen,
					 recvbuf, sizeof(recvbuf), &recvlen);
	hexdump(DEBUG_LEVEL_CARD, "Execute PACE Output Data (FUNCTION=EstabishPACEChannel)", recvbuf, recvlen);
	free(sendbuf);
	return parse_EstablishPACEChannel_OutputData(recvbuf, recvlen);
}
コード例 #22
0
ファイル: client.c プロジェクト: rhvall/SmartCard
LC_CLIENT_RESULT LC_Client_ExecApdu(LC_CLIENT *cl,
                                    LC_CARD *card,
                                    const char *apdu,
				    unsigned int apdulen,
                                    GWEN_BUFFER *rbuf,
                                    LC_CLIENT_CMDTARGET t) {
  LONG rv;
  unsigned char rbuffer[300];
  DWORD rblen;

  assert(cl);
  assert(card);
  assert(apdu);
  assert(apdulen>3);

  if (t==LC_Client_CmdTargetReader) {
    int feature;
    uint32_t controlCode;

    feature=apdu[0];
    controlCode=
        (apdu[1]<<24)+
        (apdu[2]<<16)+
        (apdu[3]<<8)+
      apdu[4];
    if (feature && controlCode==0)
      controlCode=LC_Card_GetFeatureCode(card, feature);

    if (controlCode==0) {
      DBG_ERROR(LC_LOGDOMAIN,
                "Bad control code for feature %d of reader \"%s\"",
                feature,
		LC_Card_GetReaderName(card));
      return LC_Client_ResultInvalid;
    }

    DBG_DEBUG(LC_LOGDOMAIN, "Sending command to reader (control: %08x):",
              controlCode);
    GWEN_Text_LogString((const char*)apdu+5, apdulen-5,
                        LC_LOGDOMAIN,
			GWEN_LoggerLevel_Debug);

    rblen=sizeof(rbuffer);
    rv=SCardControl(LC_Card_GetSCardHandle(card),
		    controlCode,
		    apdu+5,
		    apdulen-5,
		    rbuffer,
		    sizeof(rbuffer),
                    &rblen);
    if (rv!=SCARD_S_SUCCESS) {
      DBG_ERROR(LC_LOGDOMAIN,
                "SCardControl: %04lx", (long unsigned int) rv);
      return LC_Client_ResultIoError;
    }
    if (rblen) {
      GWEN_Buffer_AppendBytes(rbuf, (const char*)rbuffer, rblen);
      if (rblen>1) {
	LC_Card_SetLastResult(card, "ok",
			      "SCardControl succeeded",
			      rbuffer[rblen-2],
			      rbuffer[rblen-1]);
      }
    }
    return LC_Client_ResultOk;
  }
  else {
    SCARD_IO_REQUEST txHeader;
    SCARD_IO_REQUEST rxHeader;

    DBG_DEBUG(LC_LOGDOMAIN, "Sending command to card:");
    GWEN_Text_LogString((const char*)apdu, apdulen,
                        LC_LOGDOMAIN,
                        GWEN_LoggerLevel_Debug);
    txHeader.dwProtocol=LC_Card_GetProtocol(card);
    //txHeader.dwProtocol=1;
    txHeader.cbPciLength=sizeof(txHeader);
    rxHeader.cbPciLength=sizeof(rxHeader);
    rblen=sizeof(rbuffer);
    rv=SCardTransmit(LC_Card_GetSCardHandle(card),
                     &txHeader,
                     (LPCBYTE) apdu,
                     apdulen,
                     &rxHeader,
                     rbuffer,
                     &rblen);
    if (rv!=SCARD_S_SUCCESS) {
      DBG_ERROR(LC_LOGDOMAIN,
                "SCardControl: %04lx", (long unsigned int) rv);
      return LC_Client_ResultIoError;
    }
    DBG_DEBUG(LC_LOGDOMAIN, "Received response:");
    GWEN_Text_LogString((const char*)rbuffer, rblen,
			LC_LOGDOMAIN,
			GWEN_LoggerLevel_Debug);
    if (rblen) {
      GWEN_Buffer_AppendBytes(rbuf, (const char*)rbuffer, rblen);
      if (rblen>1) {
	LC_Card_SetLastResult(card, "ok",
			      "SCardTransmit succeeded",
			      rbuffer[rblen-2],
			      rbuffer[rblen-1]);
      }
    }
    else {
      DBG_DEBUG(LC_LOGDOMAIN, "Empty response");
    }
    return LC_Client_ResultOk;
  }
}
コード例 #23
0
PCSCReader::PCSCReader(
	const string &readerName,
	vector<ICardDetector *>& detector) : IReader(readerName, detector),
	m_hCard(0x0),
#if defined(_WIN32)
	m_dwProtocol(SCARD_PROTOCOL_UNDEFINED),
#else
	m_dwProtocol(SCARD_PROTOCOL_UNSET),
#endif
	m_hScardContext(0x0)
{
	DWORD retValue = SCARD_S_SUCCESS;
	BYTE sendbuf[] = {
		FUNCTION_GetReadersPACECapabilities,
		0x00,              /* lengthInputData */
		0x00,              /* lengthInputData */
	};

	if ((retValue = SCardEstablishContext(/*SCARD_SCOPE_USER*/ SCARD_SCOPE_SYSTEM,
					0x0, 0x0, &m_hScardContext)) != SCARD_S_SUCCESS)
		eCardCore_warn(DEBUG_LEVEL_CARD,  "SCardEstablishContext failed. 0x%08X (%s:%d)", retValue,
					   __FILE__, __LINE__);

#if defined(UNICODE) || defined(_UNICODE)
	WCHAR *_readerName = new WCHAR[m_readerName.size() + 1];
	mbstowcs(_readerName, m_readerName.c_str(), m_readerName.size());
	_readerName[m_readerName.size()] = 0;
	retValue = SCardConnect(m_hScardContext, _readerName, SCARD_SHARE_DIRECT,
							m_dwProtocol, &m_hCard, &m_dwProtocol);
	delete [] _readerName;
#else
	retValue = SCardConnect(m_hScardContext, m_readerName.c_str(), SCARD_SHARE_DIRECT,
							m_dwProtocol, &m_hCard, &m_dwProtocol);
#endif

	if (retValue != SCARD_S_SUCCESS) {
		eCardCore_warn(DEBUG_LEVEL_CARD,  "SCardConnect for %s failed. 0x%08X (%s:%d)",
					   m_readerName.c_str(), retValue,  __FILE__, __LINE__);
	}

	/* does the reader support PACE? */
	m_ioctl_pace = 0;
#if ENABLE_PACE
	BYTE recvbuf[1024];
	DWORD recvlen = sizeof(recvbuf);
	retValue = SCardControl(m_hCard, CM_IOCTL_GET_FEATURE_REQUEST, NULL, 0,
							recvbuf, sizeof(recvbuf), &recvlen);

	if (retValue != SCARD_S_SUCCESS) {
		eCardCore_warn(DEBUG_LEVEL_CARD,  "SCardControl for the reader's features failed. 0x%08X (%s:%d)",
					   retValue,  __FILE__, __LINE__);

	} else {
		for (size_t i = 0; i + PCSC_TLV_ELEMENT_SIZE <= recvlen; i += PCSC_TLV_ELEMENT_SIZE)
			if (recvbuf[i] == FEATURE_EXECUTE_PACE)
				memcpy(&m_ioctl_pace, recvbuf + i + 2, 4);
	}

	if (0 == m_ioctl_pace) {
		eCardCore_info(DEBUG_LEVEL_CARD, "Reader does not support PACE");

	} else {
		/* convert to host byte order to use for SCardControl */
		m_ioctl_pace = ntohl(m_ioctl_pace);
		hexdump(DEBUG_LEVEL_CARD, "Execute PACE Input Data (FUNCTION=GetReadersPACECapabilities)", sendbuf, sizeof sendbuf);
		recvlen = sizeof(recvbuf);
		retValue = SCardControl(m_hCard, m_ioctl_pace, sendbuf, sizeof sendbuf,
								recvbuf, sizeof(recvbuf), &recvlen);
		hexdump(DEBUG_LEVEL_CARD, "Execute PACE Output Data (FUNCTION=GetReadersPACECapabilities)", recvbuf, recvlen);

		if (retValue == SCARD_S_SUCCESS
			&& recvlen == 7
			&& recvbuf[0] == 0 && recvbuf[1] == 0
			&& recvbuf[2] == 0 && recvbuf[3] == 0) {
			if (recvbuf[6] & BITMAP_Qualified_Signature)
				eCardCore_info(DEBUG_LEVEL_CARD, "Reader supports qualified signature");

			if (recvbuf[6] & BITMAP_German_eID)
				eCardCore_info(DEBUG_LEVEL_CARD, "Reader supports German eID");

			if (recvbuf[6] & BITMAP_PACE) {
				eCardCore_info(DEBUG_LEVEL_CARD, "Reader supports PACE");

			} else
				m_ioctl_pace = 0;

			if (recvbuf[6] & BITMAP_DestroyPACEChannel)
				eCardCore_info(DEBUG_LEVEL_CARD, "Reader supports DestroyPACEChannel");

		} else {
			eCardCore_warn(DEBUG_LEVEL_CARD, "Error executing GetReadersPACECapabilities");
			m_ioctl_pace = 0;
		}
	}

#endif
}
コード例 #24
0
ファイル: winscard_svc.c プロジェクト: ZuyingWo/PCSC
static void ContextThread(LPVOID newContext)
{
	SCONTEXT * threadContext = (SCONTEXT *) newContext;
	int32_t filedes = threadContext->dwClientID;

	if (IsClientAuthorized(filedes, "access_pcsc", NULL) == 0)
	{
		Log1(PCSC_LOG_CRITICAL, "Rejected unauthorized PC/SC client");
		goto exit;
	}
	else
	{
		Log1(PCSC_LOG_DEBUG, "Authorized PC/SC client");
	}

	Log3(PCSC_LOG_DEBUG, "Thread is started: dwClientID=%d, threadContext @%p",
		threadContext->dwClientID, threadContext);

	while (1)
	{
		struct rxHeader header;
		int32_t ret = MessageReceive(&header, sizeof(header), filedes);

		if (ret != SCARD_S_SUCCESS)
		{
			/* Clean up the dead client */
			Log2(PCSC_LOG_DEBUG, "Client die: %d", filedes);
			EHTryToUnregisterClientForEvent(filedes);
			goto exit;
		}

		if ((header.command > CMD_ENUM_FIRST)
			&& (header.command < CMD_ENUM_LAST))
			Log3(PCSC_LOG_DEBUG, "Received command: %s from client %d",
				CommandsText[header.command], filedes);

		switch (header.command)
		{
			/* pcsc-lite client/server protocol version */
			case CMD_VERSION:
			{
				struct version_struct veStr;

				READ_BODY(veStr)

				Log3(PCSC_LOG_DEBUG, "Client is protocol version %d:%d",
					veStr.major, veStr.minor);

				veStr.rv = SCARD_S_SUCCESS;

				/* client and server use different protocol */
				if ((veStr.major != PROTOCOL_VERSION_MAJOR)
					|| (veStr.minor != PROTOCOL_VERSION_MINOR))
				{
					Log3(PCSC_LOG_CRITICAL, "Client protocol is %d:%d",
						veStr.major, veStr.minor);
					Log3(PCSC_LOG_CRITICAL, "Server protocol is %d:%d",
						PROTOCOL_VERSION_MAJOR, PROTOCOL_VERSION_MINOR);
					veStr.rv = SCARD_E_NO_SERVICE;
				}

				/* set the server protocol version */
				veStr.major = PROTOCOL_VERSION_MAJOR;
				veStr.minor = PROTOCOL_VERSION_MINOR;

				/* send back the response */
				WRITE_BODY(veStr)
			}
			break;

			case CMD_GET_READERS_STATE:
			{
				/* nothing to read */

#ifdef USE_USB
				/* wait until all readers are ready */
				RFWaitForReaderInit();
#endif

				/* dump the readers state */
				ret = MessageSend(readerStates, sizeof(readerStates), filedes);
			}
			break;

			case CMD_WAIT_READER_STATE_CHANGE:
			{
				struct wait_reader_state_change waStr;

				READ_BODY(waStr)

				/* add the client fd to the list */
				EHRegisterClientForEvent(filedes);

				/* We do not send anything here.
				 * Either the client will timeout or the server will
				 * answer if an event occurs */
			}
			break;

			case CMD_STOP_WAITING_READER_STATE_CHANGE:
			{
				struct wait_reader_state_change waStr;

				READ_BODY(waStr)

				/* add the client fd to the list */
				waStr.rv = EHUnregisterClientForEvent(filedes);

				WRITE_BODY(waStr)
			}
			break;

			case SCARD_ESTABLISH_CONTEXT:
			{
				struct establish_struct esStr;
				SCARDCONTEXT hContext;

				READ_BODY(esStr)

				hContext = esStr.hContext;
				esStr.rv = SCardEstablishContext(esStr.dwScope, 0, 0,
					&hContext);
				esStr.hContext = hContext;

				if (esStr.rv == SCARD_S_SUCCESS)
					esStr.rv = MSGAddContext(esStr.hContext, threadContext);

				WRITE_BODY(esStr)
			}
			break;

			case SCARD_RELEASE_CONTEXT:
			{
				struct release_struct reStr;

				READ_BODY(reStr)

				reStr.rv = SCardReleaseContext(reStr.hContext);

				if (reStr.rv == SCARD_S_SUCCESS)
					reStr.rv = MSGRemoveContext(reStr.hContext, threadContext);

				WRITE_BODY(reStr)
			}
			break;

			case SCARD_CONNECT:
			{
				struct connect_struct coStr;
				SCARDHANDLE hCard;
				DWORD dwActiveProtocol;

				READ_BODY(coStr)

				coStr.szReader[sizeof(coStr.szReader)-1] = 0;
				hCard = coStr.hCard;
				dwActiveProtocol = coStr.dwActiveProtocol;

				if (IsClientAuthorized(filedes, "access_card", coStr.szReader) == 0)
				{
					Log2(PCSC_LOG_CRITICAL, "Rejected unauthorized client for '%s'", coStr.szReader);
					goto exit;
				}
				else
				{
					Log2(PCSC_LOG_DEBUG, "Authorized client for '%s'", coStr.szReader);
				}

				coStr.rv = SCardConnect(coStr.hContext, coStr.szReader,
					coStr.dwShareMode, coStr.dwPreferredProtocols,
					&hCard, &dwActiveProtocol);

				coStr.hCard = hCard;
				coStr.dwActiveProtocol = dwActiveProtocol;

				if (coStr.rv == SCARD_S_SUCCESS)
					coStr.rv = MSGAddHandle(coStr.hContext, coStr.hCard,
						threadContext);

				WRITE_BODY(coStr)
			}
			break;

			case SCARD_RECONNECT:
			{
				struct reconnect_struct rcStr;
				DWORD dwActiveProtocol;

				READ_BODY(rcStr)

				if (MSGCheckHandleAssociation(rcStr.hCard, threadContext))
					goto exit;

				rcStr.rv = SCardReconnect(rcStr.hCard, rcStr.dwShareMode,
					rcStr.dwPreferredProtocols, rcStr.dwInitialization,
					&dwActiveProtocol);
				rcStr.dwActiveProtocol = dwActiveProtocol;

				WRITE_BODY(rcStr)
			}
			break;

			case SCARD_DISCONNECT:
			{
				struct disconnect_struct diStr;

				READ_BODY(diStr)

				if (MSGCheckHandleAssociation(diStr.hCard, threadContext))
					goto exit;

				diStr.rv = SCardDisconnect(diStr.hCard, diStr.dwDisposition);

				if (SCARD_S_SUCCESS == diStr.rv)
					diStr.rv = MSGRemoveHandle(diStr.hCard, threadContext);

				WRITE_BODY(diStr)
			}
			break;

			case SCARD_BEGIN_TRANSACTION:
			{
				struct begin_struct beStr;

				READ_BODY(beStr)

				if (MSGCheckHandleAssociation(beStr.hCard, threadContext))
					goto exit;

				beStr.rv = SCardBeginTransaction(beStr.hCard);

				WRITE_BODY(beStr)
			}
			break;

			case SCARD_END_TRANSACTION:
			{
				struct end_struct enStr;

				READ_BODY(enStr)

				if (MSGCheckHandleAssociation(enStr.hCard, threadContext))
					goto exit;

				enStr.rv = SCardEndTransaction(enStr.hCard,
					enStr.dwDisposition);

				WRITE_BODY(enStr)
			}
			break;

			case SCARD_CANCEL:
			{
				struct cancel_struct caStr;
				SCONTEXT * psTargetContext = NULL;
				READ_BODY(caStr)

				/* find the client */
				(void)pthread_mutex_lock(&contextsList_lock);
				psTargetContext = (SCONTEXT *) list_seek(&contextsList,
					&caStr.hContext);
				(void)pthread_mutex_unlock(&contextsList_lock);
				if (psTargetContext != NULL)
				{
					uint32_t fd = psTargetContext->dwClientID;
					caStr.rv = MSGSignalClient(fd, SCARD_E_CANCELLED);

					/* the client should not receive the event
					 * notification now the waiting has been cancelled */
					EHUnregisterClientForEvent(fd);
				}
				else
					caStr.rv = SCARD_E_INVALID_HANDLE;

				WRITE_BODY(caStr)
			}
			break;

			case SCARD_STATUS:
			{
				struct status_struct stStr;

				READ_BODY(stStr)

				if (MSGCheckHandleAssociation(stStr.hCard, threadContext))
					goto exit;

				/* only hCard and return value are used by the client */
				stStr.rv = SCardStatus(stStr.hCard, NULL, NULL, NULL,
					NULL, 0, NULL);

				WRITE_BODY(stStr)
			}
			break;

			case SCARD_TRANSMIT:
			{
				struct transmit_struct trStr;
				unsigned char pbSendBuffer[MAX_BUFFER_SIZE_EXTENDED];
				unsigned char pbRecvBuffer[MAX_BUFFER_SIZE_EXTENDED];
				SCARD_IO_REQUEST ioSendPci;
				SCARD_IO_REQUEST ioRecvPci;
				DWORD cbRecvLength;

				READ_BODY(trStr)

				if (MSGCheckHandleAssociation(trStr.hCard, threadContext))
					goto exit;

				/* avoids buffer overflow */
				if ((trStr.pcbRecvLength > sizeof(pbRecvBuffer))
					|| (trStr.cbSendLength > sizeof(pbSendBuffer)))
					goto buffer_overflow;

				/* read sent buffer */
				ret = MessageReceive(pbSendBuffer, trStr.cbSendLength, filedes);
				if (ret != SCARD_S_SUCCESS)
				{
					Log2(PCSC_LOG_DEBUG, "Client die: %d", filedes);
					goto exit;
				}

				ioSendPci.dwProtocol = trStr.ioSendPciProtocol;
				ioSendPci.cbPciLength = trStr.ioSendPciLength;
				ioRecvPci.dwProtocol = trStr.ioRecvPciProtocol;
				ioRecvPci.cbPciLength = trStr.ioRecvPciLength;
				cbRecvLength = sizeof pbRecvBuffer;

				trStr.rv = SCardTransmit(trStr.hCard, &ioSendPci,
					pbSendBuffer, trStr.cbSendLength, &ioRecvPci,
					pbRecvBuffer, &cbRecvLength);

				if (cbRecvLength > trStr.pcbRecvLength)
					/* The client buffer is not large enough.
					 * The pbRecvBuffer buffer will NOT be sent a few
					 * lines bellow. So no buffer overflow is expected. */
					trStr.rv = SCARD_E_INSUFFICIENT_BUFFER;

				trStr.ioSendPciProtocol = ioSendPci.dwProtocol;
				trStr.ioSendPciLength = ioSendPci.cbPciLength;
				trStr.ioRecvPciProtocol = ioRecvPci.dwProtocol;
				trStr.ioRecvPciLength = ioRecvPci.cbPciLength;
				trStr.pcbRecvLength = cbRecvLength;

				WRITE_BODY(trStr)

				/* write received buffer */
				if (SCARD_S_SUCCESS == trStr.rv)
					ret = MessageSend(pbRecvBuffer, cbRecvLength, filedes);
			}
			break;

			case SCARD_CONTROL:
			{
				struct control_struct ctStr;
				unsigned char pbSendBuffer[MAX_BUFFER_SIZE_EXTENDED];
				unsigned char pbRecvBuffer[MAX_BUFFER_SIZE_EXTENDED];
				DWORD dwBytesReturned;

				READ_BODY(ctStr)

				if (MSGCheckHandleAssociation(ctStr.hCard, threadContext))
					goto exit;

				/* avoids buffer overflow */
				if ((ctStr.cbRecvLength > sizeof(pbRecvBuffer))
					|| (ctStr.cbSendLength > sizeof(pbSendBuffer)))
				{
					goto buffer_overflow;
				}

				/* read sent buffer */
				ret = MessageReceive(pbSendBuffer, ctStr.cbSendLength, filedes);
				if (ret != SCARD_S_SUCCESS)
				{
					Log2(PCSC_LOG_DEBUG, "Client die: %d", filedes);
					goto exit;
				}

				dwBytesReturned = ctStr.dwBytesReturned;

				ctStr.rv = SCardControl(ctStr.hCard, ctStr.dwControlCode,
					pbSendBuffer, ctStr.cbSendLength,
					pbRecvBuffer, ctStr.cbRecvLength,
					&dwBytesReturned);

				ctStr.dwBytesReturned = dwBytesReturned;

				WRITE_BODY(ctStr)

				/* write received buffer */
				if (SCARD_S_SUCCESS == ctStr.rv)
					ret = MessageSend(pbRecvBuffer, dwBytesReturned, filedes);
			}
			break;

			case SCARD_GET_ATTRIB:
			{
				struct getset_struct gsStr;
				DWORD cbAttrLen;

				READ_BODY(gsStr)

				if (MSGCheckHandleAssociation(gsStr.hCard, threadContext))
					goto exit;

				/* avoids buffer overflow */
				if (gsStr.cbAttrLen > sizeof(gsStr.pbAttr))
					goto buffer_overflow;

				cbAttrLen = gsStr.cbAttrLen;

				gsStr.rv = SCardGetAttrib(gsStr.hCard, gsStr.dwAttrId,
					gsStr.pbAttr, &cbAttrLen);

				gsStr.cbAttrLen = cbAttrLen;

				WRITE_BODY(gsStr)
			}
			break;

			case SCARD_SET_ATTRIB:
			{
				struct getset_struct gsStr;

				READ_BODY(gsStr)

				if (MSGCheckHandleAssociation(gsStr.hCard, threadContext))
					goto exit;

				/* avoids buffer overflow */
				if (gsStr.cbAttrLen > sizeof(gsStr.pbAttr))
					goto buffer_overflow;

				gsStr.rv = SCardSetAttrib(gsStr.hCard, gsStr.dwAttrId,
					gsStr.pbAttr, gsStr.cbAttrLen);

				WRITE_BODY(gsStr)
			}
			break;

			default:
				Log2(PCSC_LOG_CRITICAL, "Unknown command: %d", header.command);
				goto exit;
		}

		/* MessageSend() failed */
		if (ret != SCARD_S_SUCCESS)
		{
			/* Clean up the dead client */
			Log2(PCSC_LOG_DEBUG, "Client die: %d", filedes);
			goto exit;
		}
	}

buffer_overflow:
	Log2(PCSC_LOG_DEBUG, "Buffer overflow detected: %d", filedes);
	goto exit;
wrong_length:
	Log2(PCSC_LOG_DEBUG, "Wrong length: %d", filedes);
exit:
	(void)close(filedes);
	(void)MSGCleanupClient(threadContext);
	(void)pthread_exit((LPVOID) NULL);
}