Esempio n. 1
0
bool PCSCReader::open(
	void)
{
	// No valid context so we should leave ...
	if (0x00 == m_hScardContext)
		return false;

	long retValue = SCARD_S_SUCCESS;
	retValue = SCardReconnect(m_hCard, SCARD_SHARE_SHARED, SCARD_PROTOCOL_ANY,
							  SCARD_LEAVE_CARD, &m_dwProtocol);
#if !defined(__APPLE__)
	BYTE atr[512];
	DWORD len = sizeof(atr);
	SCardGetAttrib(m_hCard, SCARD_ATTR_ATR_STRING, (LPBYTE) &atr, &len);
#else
	unsigned char atr[512];
	uint32_t len = sizeof(atr);
	char szReader[128];
	uint32_t cch = 128;
	uint32_t dwState;
	uint32_t dwProtocol;
	SCardStatus(m_hCard, szReader, &cch, &dwState, &dwProtocol, (unsigned char *)&atr, &len);
#endif
	return true;
}
Esempio n. 2
0
static void smartcard_check_status (SCARDCONTEXT hContext,
		const char* pReader,
		SCARDHANDLE hCardHandle, /* Can be 0 on the first call */
		SCARDHANDLE* newCardHandle, /* The handle returned */
		DWORD* pdwState) {
	DWORD shareMode = SCARD_SHARE_SHARED;
	DWORD preferredProtocols = SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1;
	DWORD dwAP;
	LONG result;

	if (hCardHandle == 0) {
		result = SCardConnect(hContext, pReader, shareMode, preferredProtocols, &hCardHandle, &dwAP);
		DEBUG_SCARD_STATUS("SCardConnect", result);
		if (SCARD_S_SUCCESS != result) {
			hCardHandle = 0;
		}
	}

	char szReader[200];
	DWORD cch = sizeof(szReader);
	BYTE bAttr[32];
	DWORD cByte = 32;
	size_t countStatusAttempts = 0;

	while (hCardHandle && (countStatusAttempts < 2)) {
		*pdwState = SCARD_UNKNOWN;

		result = SCardStatus(hCardHandle, /* Unfortunately we can't use NULL here */ szReader, &cch, pdwState, NULL, (LPBYTE)&bAttr, &cByte);
		DEBUG_SCARD_STATUS("SCardStatus", result);
		countStatusAttempts++;

		if ((SCARD_W_RESET_CARD == result) && (countStatusAttempts < 2)) {
			result = SCardReconnect(hCardHandle, shareMode, preferredProtocols, SCARD_RESET_CARD, &dwAP);
			DEBUG_SCARD_STATUS("SCardReconnect", result);
			if (SCARD_S_SUCCESS != result) {
				break;
			}
		}
		else {
			break;
		}
	}

	if (SCARD_S_SUCCESS != result) {
		if (SCARD_E_NO_SMARTCARD == result || SCARD_W_REMOVED_CARD == result) {
			*pdwState = SCARD_ABSENT;
		}
		else {
			*pdwState = SCARD_UNKNOWN;
		}
	}

	if (newCardHandle == NULL) {
		result = SCardDisconnect(hCardHandle, SCARD_LEAVE_CARD);
		DEBUG_SCARD_STATUS("SCardDisconnect", result);
	}
	else {
		*newCardHandle = hCardHandle;
	}
}
Esempio n. 3
0
vector<BYTE> PCSCReader::getATRForPresentCard()
{
	vector<BYTE> atr;

	if (0x00 == m_hCard)
		return atr;

#if !defined(__APPLE__)
	DWORD atrSize;
	SCardGetAttrib(m_hCard, SCARD_ATTR_ATR_STRING, 0x00, &atrSize);
	atr.reserve(atrSize);
	atr.resize(atrSize);
	SCardGetAttrib(m_hCard, SCARD_ATTR_ATR_STRING, &atr[0], &atrSize);
#else
	unsigned char atr_[512];
	uint32_t len = sizeof(atr_);
	char szReader[128];
	uint32_t cch = 128;
	uint32_t dwState;
	uint32_t dwProtocol;
	SCardStatus(m_hCard, szReader, &cch, &dwState, &dwProtocol, (unsigned char *)&atr_, &len);

	for (int i = 0; i < len; i++)
		atr.push_back(atr_[i]);

#endif
	return atr;
}
Esempio n. 4
0
/*
 * Transmit.
 */
JNIEXPORT jint JNICALL GEN_FUNCNAME(Card_NativeStatus)
(JNIEnv *env, jobject _this, jobject jrstate)
{
    SCARDHANDLE card;
    char rdrname[256];
    jbyteArray jatr;
    DWORD rdrlen = 256;
    DWORD pdwState;
    DWORD pdwProto;
    unsigned char pbAtr[64];
    DWORD pcbAtrLen = 64;
    LONG rv;

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

    rv = SCardStatus(card, &rdrname[0], &rdrlen, &pdwState, &pdwProto, &pbAtr[0], &pcbAtrLen);
    if (rv != SCARD_S_SUCCESS) {
        JPCSC_LOG(("NativeCardStatus(): error 0x%lx\n", rv));
        return rv;
    }

    (*env)->SetIntField(env, jrstate, CurrentStateField, pdwState);
    (*env)->SetIntField(env, jrstate, ProtoStateField, pdwProto);

    (*env)->SetObjectField(env, jrstate, ReaderStateField, (*env)->NewStringUTF(env, rdrname));

    jatr = (*env)->NewByteArray(env, pcbAtrLen);
    (*env)->SetByteArrayRegion(env, jatr, 0, pcbAtrLen, pbAtr);
    (*env)->SetObjectField(env, jrstate, AtrStateField, jatr);

    return rv;
}
Esempio n. 5
0
/*
 * Begin transaction.
 */
JNIEXPORT jint JNICALL GEN_FUNCNAME(Card_NativeBeginTransaction)
(JNIEnv *env, jobject _this)
{
    SCARDHANDLE card;
    LONG rv;

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

    rv = SCardBeginTransaction(card);

#ifdef WIN32
    /* Handle MS Resouce Manager bug on Win9x/Me/NT4/Winxpsp1
       http://support.microsoft.com/default.aspx?scid=kb;en-us;230031 */
    if (rv == SCARD_S_SUCCESS) {
        char rdrname[256];
        DWORD rdrlen = 256;
        DWORD pdwState;
        DWORD pdwProto;
        char pbAtr[64];
        DWORD pcbAtrLen = 64;

        /* verify card handle not reset */
        rv = SCardStatus(card, &rdrname[0], &rdrlen, &pdwState, &pdwProto, &pbAtr[0], &pcbAtrLen);

        if (rv == SCARD_S_SUCCESS && pdwState < SCARD_NEGOTIABLE)
            rv = SCARD_W_RESET_CARD;
    }
#endif /* WIN32 */

    return rv;
}
Esempio n. 6
0
static int32_t pcsc_check_card_inserted(struct s_reader *pcsc_reader)
{
    struct pcsc_data *crdr_data = pcsc_reader->crdr_data;
    DWORD dwState, dwAtrLen, dwReaderLen;
    unsigned char pbAtr[64];
    SCARDHANDLE rv;

    dwAtrLen = sizeof(pbAtr);
    rv=0;
    dwState=0;
    dwReaderLen=0;

    // Do we have a card ?
    if (!crdr_data->pcsc_has_card && !crdr_data->hCard) {
        // try connecting to the card
        rv = SCardConnect(crdr_data->hContext, crdr_data->pcsc_name, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &crdr_data->hCard, &crdr_data->dwActiveProtocol);
        if (rv == (LONG)SCARD_E_NO_SMARTCARD) {
            // no card in pcsc_reader
            crdr_data->pcsc_has_card=0;
            if(crdr_data->hCard) {
                SCardDisconnect(crdr_data->hCard, SCARD_RESET_CARD);
                crdr_data->hCard=0;
            }
            // rdr_debug_mask(pcsc_reader, D_DEVICE, "PCSC card in %s removed / absent [dwstate=%lx rv=(%lx)]", crdr_data->pcsc_name, dwState, (unsigned long)rv );
            return OK;
        }
        else if (rv == (LONG)SCARD_W_UNRESPONSIVE_CARD) {
            // there is a problem with the card in the pcsc_reader
            crdr_data->pcsc_has_card=0;
            crdr_data->hCard=0;
            rdr_log(pcsc_reader, "PCSC card in %s is unresponsive. Eject and re-insert please.", crdr_data->pcsc_name);
            return ERROR;
        }
        else if( rv == SCARD_S_SUCCESS ) {
            // we have a card
            crdr_data->pcsc_has_card=1;
            rdr_log(pcsc_reader, "PCSC was opened with handle: %ld", (long)crdr_data->hCard);
        }
        else {
            // if we get here we have a bigger problem -> display status and debug
            // rdr_debug_mask(pcsc_reader, D_DEVICE, "PCSC pcsc_reader %s status [dwstate=%lx rv=(%lx)]", crdr_data->pcsc_name, dwState, (unsigned long)rv );
            return ERROR;
        }

    }

    // if we get there the card is ready, check its status
    rv = SCardStatus(crdr_data->hCard, NULL, &dwReaderLen, &dwState, &crdr_data->dwActiveProtocol, pbAtr, &dwAtrLen);

    if (rv == SCARD_S_SUCCESS && (dwState & (SCARD_PRESENT | SCARD_NEGOTIABLE | SCARD_POWERED ) )) {
        return OK;
    }
    else {
        SCardDisconnect(crdr_data->hCard, SCARD_RESET_CARD);
        crdr_data->hCard = 0;
        crdr_data->pcsc_has_card = 0;
    }

    return ERROR;
}
Esempio n. 7
0
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 
);
}
Esempio n. 8
0
static const bytestring_t* pcsc_last_atr(cardreader_t* cr)
{
    pcsc_data_t* pcsc = cr->extra_data;
    DWORD state;
    DWORD protocol;
    BYTE pbAtr[MAX_ATR_SIZE];
    DWORD atrlen=MAX_ATR_SIZE;
    char readername[MAX_READERNAME];
    DWORD readernamelen=MAX_READERNAME;
    /*char *tmp;*/

    pcsc->status = SCardStatus(pcsc->hcard,
                               readername,&readernamelen,
                               &state,
                               &protocol,
                               pbAtr,&atrlen);

    if (pcsc->status==SCARD_S_SUCCESS)
    {
        bytestring_assign_data(cr->atr,atrlen,pbAtr);
        /*tmp = bytestring_to_format("%D",cr->atr);
        log_printf(LOG_INFO,"ATR is %i bytes: %s",atrlen,tmp);
        free(tmp);*/
    }
    else
    {
        bytestring_clear(cr->atr);
        log_printf(LOG_ERROR,"Failed to query card status: %s (error 0x%08x).",
                   pcsc_stringify_error(pcsc->status),
                   pcsc->status );
    }
    return cr->atr;
}
Esempio n. 9
0
int32_t pcsc_check_card_inserted(struct s_reader *pcsc_reader)
{
    DWORD dwState, dwAtrLen, dwReaderLen;
    BYTE pbAtr[64];
    LONG rv;

    dwAtrLen = sizeof(pbAtr);
    rv=0;
    dwState=0;
    dwReaderLen=0;

    // Do we have a card ?
    if (!pcsc_reader->pcsc_has_card && !(SCARDHANDLE)(pcsc_reader->hCard)) {
        // try connecting to the card
        rv = SCardConnect(pcsc_reader->hContext, pcsc_reader->pcsc_name, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &pcsc_reader->hCard, &pcsc_reader->dwActiveProtocol);
        if (rv==SCARD_E_NO_SMARTCARD) {
            // no card in pcsc_reader
            pcsc_reader->pcsc_has_card=0;
            if((SCARDHANDLE)(pcsc_reader->hCard)) {
                SCardDisconnect((SCARDHANDLE)(pcsc_reader->hCard),SCARD_RESET_CARD);
                pcsc_reader->hCard=0;
            }
            // rdr_debug_mask(pcsc_reader, D_DEVICE, "PCSC card in %s removed / absent [dwstate=%lx rv=(%lx)]", pcsc_reader->pcsc_name, dwState, (unsigned long)rv );
            return 0;
        }
        else if( rv == SCARD_W_UNRESPONSIVE_CARD ) {
            // there is a problem with the card in the pcsc_reader
            pcsc_reader->pcsc_has_card=0;
            pcsc_reader->hCard=0;
            rdr_log(pcsc_reader, "PCSC card in %s is unresponsive. Eject and re-insert please.", pcsc_reader->pcsc_name);
            return 0;
        }
        else if( rv == SCARD_S_SUCCESS ) {
            // we have a card
            pcsc_reader->pcsc_has_card=1;
        }
        else {
            // if we get here we have a bigger problem -> display status and debug
            // rdr_debug_mask(pcsc_reader, D_DEVICE, "PCSC pcsc_reader %s status [dwstate=%lx rv=(%lx)]", pcsc_reader->pcsc_name, dwState, (unsigned long)rv );
            return 0;
        }

    }

    // if we get there the card is ready, check its status
    rv = SCardStatus((SCARDHANDLE)(pcsc_reader->hCard), NULL, &dwReaderLen, &dwState, &pcsc_reader->dwActiveProtocol, pbAtr, &dwAtrLen);

    if (rv == SCARD_S_SUCCESS && (dwState & (SCARD_PRESENT | SCARD_NEGOTIABLE | SCARD_POWERED ) )) {
        return CARD_INSERTED;
    }
    else {
        SCardDisconnect((SCARDHANDLE)(pcsc_reader->hCard),SCARD_RESET_CARD);
        pcsc_reader->hCard=0;
        pcsc_reader->pcsc_has_card=0;
    }

    return 0;
}
Esempio n. 10
0
testA(int argc,char** argv ) {
	int i;
myprintf("=============================\n");
myprintf("Part A: Checking card monitor\n");
myprintf("=============================\n");
	(rgReaderStates[0])->dwCurrentState = SCARD_STATE_UNAWARE;
	 rv =SCardGetStatusChange( hContext, INFINITE, rgReaderStates[0], 1 ); 
	 if( (rgReaderStates[0])->dwEventState & SCARD_STATE_PRESENT ) {
		myprintf("<<  Please remove smart card \n");
		(rgReaderStates[0])->dwCurrentState = SCARD_STATE_PRESENT;
	 	rv =SCardGetStatusChange( hContext, INFINITE, rgReaderStates[0], 1 ); 
	 }
	printit("1.Please insert smart card");
		(rgReaderStates[0])->dwCurrentState = SCARD_STATE_EMPTY;
		rv =SCardGetStatusChange( hContext, INFINITE, rgReaderStates[0], 1 );
	 myprintf("Passed\n");
	 printit("2. IOCTL_SMARTCARD_IS_PRESENT");
	 myprintf("Passed\n");
	 printit("3. Please remove smart card ");
	 (rgReaderStates[0])->dwCurrentState = SCARD_STATE_PRESENT; 
     rv =SCardGetStatusChange( hContext, INFINITE, rgReaderStates[0], 1 );
     if( rv != SCARD_S_SUCCESS )
        return -1;
	 if( (rgReaderStates[0])->dwEventState & SCARD_STATE_EMPTY) myprintf("Passed\n");
	 else 
		myprintf("Failed \n");
	 printit("4. IOCTL_SMARTCARD_IS_ABSENT");
	 myprintf("Passed\n");
	 printit("5. Insert and remove a smart card repeatedly");
	(rgReaderStates[0])->dwCurrentState = SCARD_STATE_EMPTY;
	for(i=0;i<10;i++) {
	 	rv =SCardGetStatusChange( hContext, INFINITE, rgReaderStates[0], 1 ); 
		(rgReaderStates[0])->dwCurrentState = (rgReaderStates[0])->dwEventState;
	 }
	 myprintf("Passed \n");
	 if( more_details ) {
		 rv = SCardConnect(hContext, readerName,
            SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0| SCARD_PROTOCOL_T1,
            &hCard, &dwPref);
     	if ( rv != SCARD_S_SUCCESS ) {
     		SCardReleaseContext( hContext );
    		return 0;
 	 	}                         
		readerlen=100;
	 	rv = SCardStatus(hCard,readerName,&readerlen,&readerstate,&protocol,r,&atrlen);
	 	if( rv != SCARD_S_SUCCESS ) {
			return -1;
		 }
		 myprintf("ATR :");
		 for(i=0;i<atrlen;i++) {
			myprintf("%0x ",r[i]);
		 }
		 myprintf("\n");
		 myprintf("Powered up successfully \n");
	 }
	 return 0;
}
Esempio n. 11
0
File: sctest.c Progetto: S010/test
int
get_card_state(SCARDHANDLE card, struct card_state *cst) {
    char *reader_names = NULL;
    size_t reader_names_size = 0;
    int rc;
    
    cst->atr = NULL;
    cst->atr_len = SCARD_AUTOALLOCATE;
    return SCardStatus(card, NULL, &reader_names_size, &cst->state, &cst->proto, (char *) &cst->atr, &cst->atr_len);
}
Esempio n. 12
0
bool Token::checkATR(){
	LONG lReturn;
	char szReader[200];
	DWORD cch = 200;
	DWORD dwState, dwProtocol;

	lReturn = SCardStatus(hCardHandle, szReader, &cch, &dwState, &dwProtocol, (LPBYTE)&(this->ATR), &(this->lATR));
	if (this->lATR == laladdinATR && memcmp(this->ATR, aladdinATR, this->lATR) == 0){
		return true;
	}
	else {
		return false;
	}
}
static void smartcard_check_status (SCARDCONTEXT hContext,
		const char* pReader,
		SCARDHANDLE hCardHandle, /* Can be 0 on the first call */
		SCARDHANDLE* newCardHandle, /* The handle returned */
		DWORD* pdwState) {
	if (hCardHandle == 0) {
		DWORD dwAP;
		LONG result = SCardConnect(hContext, pReader, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &hCardHandle, &dwAP);
		if (SCARD_S_SUCCESS != result) {
			hCardHandle = 0;
			if (SCARD_E_NO_SMARTCARD == result || SCARD_W_REMOVED_CARD == result) {
				*pdwState = SCARD_ABSENT;
			}
			else {
				*pdwState = SCARD_UNKNOWN;
			}

			if (newCardHandle == NULL) {
				(void) SCardDisconnect(hCardHandle, SCARD_LEAVE_CARD);
				hCardHandle = 0;
			}
			else {
				*newCardHandle = hCardHandle;
			}
		}
	}

	char szReader[200];
	DWORD cch = sizeof(szReader);
	BYTE bAttr[32];
	DWORD cByte = 32;
	LONG result = SCardStatus(hCardHandle, /* Unfortunately we can't use NULL here */ szReader, &cch, pdwState, NULL, (LPBYTE)&bAttr, &cByte);

	if (SCARD_S_SUCCESS != result) {
		if (SCARD_E_NO_SMARTCARD == result || SCARD_W_REMOVED_CARD == result) {
			*pdwState = SCARD_ABSENT;
		}
		else {
			*pdwState = SCARD_UNKNOWN;
		}
	}

	if (newCardHandle == NULL) {
		(void) SCardDisconnect(hCardHandle, SCARD_LEAVE_CARD);
		hCardHandle = 0;
	}
	else {
		*newCardHandle = hCardHandle;
	}
}
Esempio n. 14
0
/**
 * checkForRemovedPCSCToken looks into a specific slot for a removed 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 checkForRemovedPCSCToken(struct p11Slot_t *slot)
{
	int rc;
	LONG rv;

	FUNC_CALLED();

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

	if (!slot->card) {
		FUNC_RETURNS(CKR_TOKEN_NOT_PRESENT);
	}

	rv = SCardStatus(slot->card, NULL, 0, 0, 0, 0, 0);

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

	if (rv == SCARD_S_SUCCESS) {
		FUNC_RETURNS(CKR_OK);
	} else if ((rv == SCARD_W_REMOVED_CARD) || (rv == SCARD_E_INVALID_HANDLE) || (rv == SCARD_E_READER_UNAVAILABLE)) {
		rc = removeToken(slot);
		if (rc != CKR_OK) {
			FUNC_RETURNS(rc);
		}

		rc = SCardDisconnect(slot->card, SCARD_UNPOWER_CARD);

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

		// Check if a new token was inserted in the meantime
		rc = checkForNewPCSCToken(slot);

		if (rc == CKR_TOKEN_NOT_PRESENT) {
			FUNC_RETURNS(CKR_DEVICE_REMOVED);
		}
	} else {
		FUNC_FAILS(CKR_DEVICE_ERROR, "Error getting PC/SC card terminal status");
	}

	FUNC_RETURNS(rc);
}
Esempio n. 15
0
static int32_t pcsc_activate_card(struct s_reader *pcsc_reader, uchar *atr, uint16_t *atr_size)
{
	struct pcsc_data *crdr_data = pcsc_reader->crdr_data;
	LONG rv;
	DWORD dwState, dwAtrLen, dwReaderLen;
	unsigned char pbAtr[ATR_MAX_SIZE];
	char tmp[sizeof(pbAtr) * 3 + 1];

	rdr_log_dbg(pcsc_reader, D_DEVICE, "PCSC initializing card in (%s)", crdr_data->pcsc_name);
	dwAtrLen = sizeof(pbAtr);
	dwReaderLen = 0;

	rdr_log_dbg(pcsc_reader, D_DEVICE, "PCSC resetting card in (%s) with handle %ld", crdr_data->pcsc_name, (long)(crdr_data->hCard));
	rv = SCardReconnect(crdr_data->hCard, SCARD_SHARE_EXCLUSIVE, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1,  SCARD_RESET_CARD, &crdr_data->dwActiveProtocol);

	if(rv != SCARD_S_SUCCESS)
	{
		rdr_log_dbg(pcsc_reader, D_DEVICE, "ERROR: PCSC failed to reset card (%lx)", (unsigned long)rv);
		return ERROR;
	}

	rdr_log_dbg(pcsc_reader, D_DEVICE, "PCSC resetting done on card in (%s)", crdr_data->pcsc_name);
	rdr_log_dbg(pcsc_reader, D_DEVICE, "PCSC Protocol (T=%d)", (crdr_data->dwActiveProtocol == SCARD_PROTOCOL_T0 ? 0 :  1));

	rdr_log_dbg(pcsc_reader, D_DEVICE, "PCSC getting ATR for card in (%s)", crdr_data->pcsc_name);
	rv = SCardStatus(crdr_data->hCard, NULL, &dwReaderLen, &dwState, &crdr_data->dwActiveProtocol, pbAtr, &dwAtrLen);
	if(rv == SCARD_S_SUCCESS)
	{
		rdr_log_dbg(pcsc_reader, D_DEVICE, "PCSC Protocol (T=%d)", (crdr_data->dwActiveProtocol == SCARD_PROTOCOL_T0 ? 0 :  1));
		memcpy(atr, pbAtr, dwAtrLen);
		*atr_size = dwAtrLen;

		rdr_log(pcsc_reader, "ATR: %s", cs_hexdump(1, (uchar *)pbAtr, dwAtrLen, tmp, sizeof(tmp)));
		memcpy(pcsc_reader->card_atr, pbAtr, dwAtrLen);
		pcsc_reader->card_atr_length = dwAtrLen;
		return OK;
	}
	else
	{
		rdr_log_dbg(pcsc_reader, D_DEVICE, "ERROR: PCSC failed to get ATR for card (%lx)", (unsigned long)rv);
	}

	return ERROR;
}
Esempio n. 16
0
bool silvia_pcsc_card::status()
{
	if (!connected) return false;
	
	DWORD active_protocol;
	DWORD state;
	DWORD atr_len = MAX_ATR_SIZE;
	DWORD reader_len = 0;
	BYTE atr[MAX_ATR_SIZE];
	
	LONG rv = SCardStatus(card_handle, NULL, &reader_len, &state, &active_protocol, atr, &atr_len);
	
	connected = (rv == SCARD_S_SUCCESS) && (FLAG_SET(state, SCARD_PRESENT));
	
	if (!connected)
	{
		SCardDisconnect(card_handle, SCARD_UNPOWER_CARD);
	}
	
	return connected;
}
Esempio n. 17
0
void testGetATR_2(SCARDHANDLE* phCard)
{
	WCHAR readerName[256];
	DWORD readerNameLen = 256;
	BYTE  pbAtr[32];
	DWORD dwLen = 32;
	DWORD dwState;
	DWORD dwProtocol;
	DWORD retval;

	retval = SCardStatus(*phCard, readerName, &readerNameLen, &dwState,
		&dwProtocol, pbAtr,	&dwLen); 

	printf ("trying to get the card's ATR by calling SCardStatus\n");
	printf ("returned: ATR length = %d retval: 0x%08x\n",dwLen, retval);
	printf ("ATR = ");
	for(int i = 0; i < dwLen; i++)
	{
		printf(" 0x%02x",pbAtr[i]);
	}
	printf ("\n");

}
Esempio n. 18
0
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;
}
Esempio n. 19
0
int CPCSCMngr::GetSCStatusString(CString* pSCStatus) {
    int             status = STAT_OK;
	char            *Readers=(char *)1, selected_reader[1000],msg[10000],msg_help[1000],convention[1000];	
	unsigned long   len=SCARD_AUTOALLOCATE;
	DWORD           protocol,state,a_len,r_len;
	unsigned char   atr[40],TS,T0,TA1,TB1,TC1,TD1,FI,DI,TA2,TB2,TC2,TD2,TA3,TB3,TC3,TD3;
	int             number_of_historical,pointer,ta1_sent=0,tb1_sent=0,tc1_sent=0,td1_sent=0,F,D;
	int             transmission_protocol1,ta2_sent=0,tb2_sent=0,tc2_sent=0,td2_sent=0;
	int             transmission_protocol2,ta3_sent=0,tb3_sent=0,tc3_sent=0,td3_sent=0;
	double          work_etu,cycles;
    
    if (m_cardContext && m_hCard) {

	    r_len=sizeof(selected_reader);
	    a_len=sizeof(atr);
    
        status = TranslateSCardError(SCardStatus(m_hCard, selected_reader,&r_len,&state,&protocol,atr,&a_len));
    }
    else status = STAT_SESSION_NOT_OPEN;

    if (status == STAT_OK) {
	    sprintf_s(msg,10000,"Reader: %s\nState: %s\nProtocol: %s\nATR: %s\n\n",selected_reader,card_state(state),card_protocol(protocol),card_atr(atr,a_len));								
	    
	    TS=atr[0];
	    switch(TS){
	     case 59: strcpy_s(convention,1000,"Direct convention"); break;
	     case 63: strcpy_s(convention,1000,"Inverse convention"); break;
	     default: strcpy_s(convention,1000,"Unknown initial character"); 				 
	    }

	    T0=atr[1];
	    number_of_historical=T0&0xF;				
	    ta1_sent=T0&16;
	    tb1_sent=T0&32;
	    tc1_sent=T0&64;
	    td1_sent=T0&128;				
	    pointer=2;
	    if(ta1_sent){ TA1=atr[pointer++]; DI=TA1&0xF; FI=TA1>>4; 								  
	      switch(FI){
	      case 0: F=372; break;
	      case 1: F=372; break;
	      case 2: F=558; break;
	      case 3: F=744; break;
	      case 4: F=1116; break;
	      case 5: F=1488; break;
	      case 6: F=1860; break;
	      case 9: F=512; break;
	      case 10: F=768; break;
	      case 11: F=1024; break;
	      case 12: F=1536; break;
	      case 13: F=2048; break;
	      default: F=0;
	      }
	      switch(DI){								  
	      case 1: D=1; break;
	      case 2: D=2; break;
	      case 3: D=4; break;
	      case 4: D=8; break;
	      case 5: D=16; break;
	      case 6: D=32; break;
	      case 8: D=12; break;
	      case 9: D=20; break;								  
	      default: D=0;
	      }
	      if(D==0||F==0) strcat_s(msg,10000,"Uncorrect frequency data in ATR\n");
	      work_etu=(double)(((double)F)/(double)((double)D*4000));
	      cycles=(double)(15/4)*(double)((((double)F)/(double)D));
	    }
	    if(tb1_sent)TB1=atr[pointer++]; 								  
	    if(tc1_sent)TC1=atr[pointer++];													  
	    if(td1_sent){
            TD1=atr[pointer++];					
	        transmission_protocol1=TD1&0xF;
            ta2_sent=TD1&16;
            tb2_sent=TD1&32;
            tc2_sent=TD1&64;
            td2_sent=TD1&128;								  
            if(ta2_sent)TA2=atr[pointer++];
            if(tb2_sent)TB2=atr[pointer++];
            if(tc2_sent)TC2=atr[pointer++];
            if(td2_sent) {
                TD2=atr[pointer++];
                transmission_protocol2=TD2&0xF;
                ta3_sent=TD2&16;
                tb3_sent=TD2&32;
                tc3_sent=TD2&64;
                td3_sent=TD2&128;									  
                if(ta3_sent)TA3=atr[pointer++];
                if(tb3_sent)TB3=atr[pointer++];
                if(tc3_sent)TC3=atr[pointer++];
                if(td3_sent){ TD3=atr[pointer++]; strcat_s(msg,10000,"Unusual ATR - not handling TD3 and further\n"); }
            }
        }
	    
	    sprintf_s(msg_help,1000,"Initial character: %s\n",convention);
	    strcat_s(msg,10000,msg_help);
	    if(!ta1_sent) sprintf_s(msg_help,1000,"TA1: not present\n");
	     else sprintf_s(msg_help,1000,"TA1: %02Xh (DI: %i, FI: %i -> D: %i, F: %i -> Work etu: %f ms, 15 Mhz cycles: %i)\n",(int)TA1,DI,FI,D,F,work_etu,(int)cycles);
	    strcat_s(msg,10000,msg_help);
	    if(!tb1_sent) sprintf_s(msg_help,1000,"TB1: not present\n");
	     else sprintf_s(msg_help,1000,"TB1: %02Xh (II: %i, PI1: %i [currently not used, should always be 0])\n",(int)TB1,(int)TB1>>5,(int)TB1&0x1F);
	    strcat_s(msg,10000,msg_help);
	    if(!tc1_sent) sprintf_s(msg_help,1000,"TC1: not present\n");
	     else if((int)TC1==255) sprintf_s(msg_help,1000,"TC1: %02Xh (special value: for T=0 guard time 2 etu, for T=1 guard time 1 etu)\n",(int)TC1);
		       else sprintf_s(msg_help,1000,"TC1: %02Xh (extra guard time %i etu)\n",(int)TC1,(int)TC1);
	    strcat_s(msg,10000,msg_help);

	    if(td1_sent)
	    {
	    sprintf_s(msg_help,1000,"Protocol: %i\n",transmission_protocol1);
	    strcat_s(msg,10000,msg_help);
	    if(!ta2_sent) sprintf_s(msg_help,1000,"   TA2: not present\n");
	    else if(transmission_protocol1==1)sprintf_s(msg_help,1000,"   TA2: %02Xh (Protocol T=%i to be used, %s, %s)\n",(int)TA2,(int)TA2&0xF,TA2&0x80?"switching betweeen negotiable and specific modes not possible":"switching betweeen negotiable and specific modes possible",TA2&0x10?"transmission parameters implicitely defined":"transmission parameters explicitely defined");
		       else sprintf_s(msg_help,1000,"   TA2: %02Xh\n",(int)TA2);
	    strcat_s(msg,10000,msg_help);
	    if(!tb2_sent) sprintf_s(msg_help,1000,"   TB2: not present\n");
	     else sprintf_s(msg_help,1000,"   TB2: %02Xh\n",(int)TB2);
	    strcat_s(msg,10000,msg_help);
	    if(!tc2_sent) sprintf_s(msg_help,1000,"   TC2: not present\n");
	     else if(transmission_protocol1==0) sprintf_s(msg_help,1000,"   TC2: %02Xh (WI: %i -> work waiting time: %i work etu)\n",(int)TC2,(int)TC2,960*D*(int)TC2);
		       else sprintf_s(msg_help,1000,"   TC2: %02Xh\n",(int)TC2);
	    strcat_s(msg,10000,msg_help);
	    }

	    if(td2_sent)
	    {
	    sprintf_s(msg_help,1000,"Protocol: %i\n",transmission_protocol2);
	    strcat_s(msg,10000,msg_help);
	    if(!ta3_sent) sprintf_s(msg_help,1000,"   TA3: not present\n");
	     else if(transmission_protocol2==1) sprintf_s(msg_help,1000,"   TA3: %02Xh (IFSC: %i) \n",(int)TA3,(int)TA3);
		       else sprintf_s(msg_help,1000,"   TA3: %02Xh\n",(int)TA3);
	    strcat_s(msg,10000,msg_help);
	    if(!tb3_sent) sprintf_s(msg_help,1000,"   TB3: not present\n");
	     else if(transmission_protocol2==1)sprintf_s(msg_help,1000,"   TB3: %02Xh (BWI: %i, CWI: %i -> BWT: %f s + 11 work etu , CWT: %i work etu)\n",(int)TB3,(int)TB3>>4,(int)TB3&0xF,(double)((1<<(TB3>>4))*960*372)/4000000,(1<<(TB3&0xF))+11);
		       else sprintf_s(msg_help,1000,"   TB3: %02Xh\n",(int)TB3);
	    strcat_s(msg,10000,msg_help);
	    if(!tc3_sent) sprintf_s(msg_help,1000,"   TC3: not present\n");
	    else if(transmission_protocol2==1)sprintf_s(msg_help,1000,"   TC3: %02Xh (%s)\n",(int)TC3,TC3?"CRC used":"LRC used");
		       else sprintf_s(msg_help,1000,"   TC3: %02Xh\n",(int)TC3);
	    strcat_s(msg,10000,msg_help);
	    }
Esempio n. 20
0
static uint32 handle_State(IRP* irp)
{
	LONG rv;
	SCARDHANDLE hCard;
	DWORD state = 0, protocol = 0;
	DWORD readerLen;
	DWORD atrLen = MAX_ATR_SIZE;
	char * readerName;
	BYTE pbAtr[MAX_ATR_SIZE];

#ifdef WITH_DEBUG_SCARD
	int i;
#endif

	stream_seek(irp->input, 0x24);
	stream_seek_uint32(irp->input);	/* atrLen */

	stream_seek(irp->input, 0x0c);
	stream_read_uint32(irp->input, hCard);
	stream_seek(irp->input, 0x04);

#ifdef SCARD_AUTOALLOCATE
	readerLen = SCARD_AUTOALLOCATE;

	rv = SCardStatus(hCard, (LPSTR) &readerName, &readerLen, &state, &protocol, pbAtr, &atrLen);
#else
	readerLen = 256;
	readerName = xmalloc(readerLen);

	rv = SCardStatus(hCard, (LPSTR) readerName, &readerLen, &state, &protocol, pbAtr, &atrLen);
#endif

	if (rv != SCARD_S_SUCCESS)
	{
		DEBUG_SCARD("Failure: %s (0x%08x)", pcsc_stringify_error(rv), (unsigned) rv);
		return sc_output_return(irp, rv);
	}

	DEBUG_SCARD("Success (hcard: 0x%08x len: %d state: 0x%08x, proto: 0x%08x)",
		(unsigned) hCard, (int) atrLen, (unsigned) state, (unsigned) protocol);

#ifdef WITH_DEBUG_SCARD
	printf("       ATR: ");
	for (i = 0; i < atrLen; i++)
		printf("%02x%c", pbAtr[i], (i == atrLen - 1) ? ' ' : ':');
	printf("\n");
#endif

	state = sc_map_state(state);

	stream_write_uint32(irp->output, state);
	stream_write_uint32(irp->output, protocol);
	stream_write_uint32(irp->output, atrLen);
	stream_write_uint32(irp->output, 0x00000001);
	stream_write_uint32(irp->output, atrLen);
	stream_write(irp->output, pbAtr, atrLen);

	sc_output_repos(irp, atrLen);
	sc_output_alignment(irp, 8);

#ifdef SCARD_AUTOALLOCATE
	xfree(readerName);
#else
	xfree(readerName);
#endif

	return rv;
}
Esempio n. 21
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);
}
PCSCREADERDRIVERDLL_API unsigned short CCONV HD_ResetCard( HANDLE devNo, unsigned char	*srATR, short	*srATRLen, short ivCardSeat)
{
//	DWORD ActiveProtocol;
	DWORD dwCardState=0;
	BYTE  AtrBuffer[32];
	DWORD AtrLen ;

//	LPTSTR cardname;
	char cardname[256];
	DWORD dw = 0;
	BYTE buf[32];

//	ret = SCardStatus((SCARDHANDLE)devNo, NULL, NULL, &dwCardState, &ActiveProtocol, NULL, &AtrLen);
	ret = SCardStatus((SCARDHANDLE)devNo, cardname, &dw, &dwCardState, &ActiveProtocol, buf, &AtrLen);
	if (ret != SCARD_S_SUCCESS)
	{
//		GetErrorCode(ret);
		return CER_PCSC_SCardStatus;
	}

	switch ( dwCardState )
	{
		case SCARD_ABSENT:
	//		printf("Card absent.\n");
			return CER_NOCARD;

		case SCARD_SWALLOWED:
	//        printf("Card swallowed.\n");

			//
			//The SCardReconnect function reestablishes an existing connection between 
			//the calling application and a smart card. 
			//This function moves a card handle from direct access to general access, 
			//or acknowledges and clears an error condition that is preventing further 
			//access to the card.
			//

			//SCARD_LEAVE_CARD  Don't do anything special on reconnect. 
			//SCARD_RESET_CARD  Reset the card (Warm Reset). 
			//SCARD_UNPOWER_CARD  Power down the card and reset it (Cold Reset).
			ret = SCardReconnect((SCARDHANDLE)devNo,SCARD_SHARE_SHARED , ActiveProtocol , SCARD_UNPOWER_CARD , &ActiveProtocol);
			if (ret != SCARD_S_SUCCESS)
			{
				GetErrorCode(ret);
				return CER_PCSC_SCardReconnect;
			}

			break;

		case SCARD_PRESENT:
	//        printf("Card present.\n");
		case SCARD_NEGOTIABLE:
	//        printf("Card reset and waiting PTS negotiation.\n");
		case SCARD_SPECIFIC:
	//        printf("Card has specific communication protocols set.\n");

			//
			//The SCardReconnect function reestablishes an existing connection between 
			//the calling application and a smart card. 
			//This function moves a card handle from direct access to general access, 
			//or acknowledges and clears an error condition that is preventing further 
			//access to the card.
			//

			//SCARD_LEAVE_CARD  Don't do anything special on reconnect. 
			//SCARD_RESET_CARD  Reset the card (Warm Reset). 
			//SCARD_UNPOWER_CARD  Power down the card and reset it (Cold Reset). 

			ret = SCardReconnect((SCARDHANDLE)devNo,SCARD_SHARE_SHARED , ActiveProtocol, SCARD_RESET_CARD , &ActiveProtocol);
			if (ret != SCARD_S_SUCCESS)
			{
				//GetErrorCode(ret);
				return CER_PCSC_SCardReconnect;
			}
			break;

		case SCARD_POWERED:
	//        printf("Card has power.\n");

			//
			//The SCardReconnect function reestablishes an existing connection between 
			//the calling application and a smart card. 
			//This function moves a card handle from direct access to general access, 
			//or acknowledges and clears an error condition that is preventing further 
			//access to the card.
			//

			//SCARD_LEAVE_CARD  Don't do anything special on reconnect. 
			//SCARD_RESET_CARD  Reset the card (Warm Reset). 
			//SCARD_UNPOWER_CARD  Power down the card and reset it (Cold Reset). 
/*
			ret = SCardReconnect((SCARDHANDLE)devNo,SCARD_SHARE_SHARED , SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1 , SCARD_RESET_CARD , &ActiveProtocol);
			if (ret != SCARD_S_SUCCESS)
			{
//				GetErrorCode(ret);
				return CER_PCSC_SCardReconnect;
			}
*/			break;

		default:
	//        printf("Unknown or unexpected card state.\n");
			return CER_UNKNOWN;
	}

	AtrLen = 0x20;		//Microsoft Define Atrlen<=0x20;
	ret = SCardStatus((SCARDHANDLE)devNo, NULL, NULL, &dwCardState, &ActiveProtocol, (LPBYTE)&AtrBuffer, &AtrLen);
	if (ret != SCARD_S_SUCCESS)
	{
//		GetErrorCode(ret);
		return CER_PCSC_SCardStatus;
	}

		
	*srATRLen = (short)AtrLen;
	memcpy(srATR, AtrBuffer, AtrLen);

	/*if ((memcmp(srATR+4,"\x00\x81",2)!=0)&&(memcmp(srATR+5,"\x00\x81",2)!=0)&&(memcmp(srATR+7,"\x00\x81",2)!=0)&&(memcmp(srATR+4,"\x86\x01",2)!=0)&&(memcmp(srATR+5,"\x86\x01",2)!=0)&&(memcmp(srATR+7,"\x86\x01",2)!=0))
	{
		return CER_NOCARD;
	}
*/
	return EXCUTE_SUC ;	

}
PCSCREADERDRIVERDLL_API unsigned short CCONV HD_GetDescriptor( HANDLE devNo, char *descriptor )
{
//	unsigned char tmpstr[100] ;
//	unsigned long pcbAttrLen;
//	unsigned short i;

	//
	//The SCardGetAttrib function gets the current reader attributes for the given handle. 
	//It does not affect the state of the reader, driver, or card.
	//
	
//	DWORD ActiveProtocol;
	DWORD dwCardState=0;
	BYTE  AtrBuffer[32];
	DWORD AtrLen ;
	short i;
	char tmpstr[100];

	ret = SCardStatus((SCARDHANDLE)devNo, NULL, NULL, &dwCardState, &ActiveProtocol, NULL, &AtrLen);
	if (ret != SCARD_S_SUCCESS)
	{
//		GetErrorCode(ret);
		return CER_PCSC_SCardStatus;
	}
/*
	ret = SCardGetAttrib((SCARDHANDLE)devNo, SCARD_ATTR_DEVICE_FRIENDLY_NAME, NULL, &pcbAttrLen);
	if (ret != SCARD_S_SUCCESS)
	{
//		GetErrorCode(ret);
		return CER_PCSC_SCardGetAttrib;
	}

	ret = SCardGetAttrib((SCARDHANDLE)devNo, SCARD_ATTR_DEVICE_FRIENDLY_NAME, tmpstr, &pcbAttrLen);
	if (ret != SCARD_S_SUCCESS)
	{
//		GetErrorCode(ret);
		return CER_PCSC_SCardGetAttrib;
	}

*/
	AtrLen = 0x20;		//Microsoft Define Atrlen<=0x20;
	ret = SCardStatus((SCARDHANDLE)devNo, NULL, NULL, &dwCardState, &ActiveProtocol, (LPBYTE)&AtrBuffer, &AtrLen);
	if (ret != SCARD_S_SUCCESS)
	{
//		GetErrorCode(ret);
		return CER_PCSC_SCardStatus;
	}

	descriptor[0] = '\0' ;
	tmpstr[0] = '\0';

	for( i=0 ; i < (short)AtrLen ; i++) 
		byte2str_chen(tmpstr,AtrBuffer[i]) ;

	HD_RightChar(tmpstr,26,descriptor);
	descriptor[26] = '\0' ;

//	SCardFreeMemory((SCARDCONTEXT)ContextNo,&pcbAttrLen);

	return EXCUTE_SUC ;

}
Esempio n. 24
0
LC_CLIENT_RESULT LC_Client_ConnectCard(LC_CLIENT *cl,
				       const char *rname,
				       LC_CARD **pCard) {
  LC_CLIENT_RESULT res;
  LONG rv;
  SCARDHANDLE scardHandle;
  DWORD dwActiveProtocol;
  LC_CARD *card;
  char readerName[256];
  DWORD pcchReaderLen;
  BYTE pbAtr[MAX_ATR_SIZE];
  DWORD dwAtrLen;
  DWORD dwState;
  GWEN_BUFFER *bDriverType;
  GWEN_BUFFER *bReaderType;
  uint32_t rflags=0;

  assert(cl);

  DBG_INFO(LC_LOGDOMAIN, "Trying protocol T1");
  rv=SCardConnect(cl->scardContext,
		  rname,
                  SCARD_SHARE_EXCLUSIVE,
                  SCARD_PROTOCOL_T1,
                  &scardHandle,
                  &dwActiveProtocol);
  if (rv!=SCARD_S_SUCCESS) {
    DBG_INFO(LC_LOGDOMAIN, "Trying protocol T0");
    rv=SCardConnect(cl->scardContext,
		    rname,
		    SCARD_SHARE_EXCLUSIVE,
		    SCARD_PROTOCOL_T0,
                    &scardHandle,
                    &dwActiveProtocol);
  }
#ifdef SCARD_PROTOCOL_RAW
  if (rv!=SCARD_S_SUCCESS) {
    DBG_INFO(LC_LOGDOMAIN, "Trying protocol RAW");
    rv=SCardConnect(cl->scardContext,
		    rname,
		    SCARD_SHARE_EXCLUSIVE,
		    SCARD_PROTOCOL_RAW,
		    &scardHandle,
		    &dwActiveProtocol);
  }
#endif

  if (rv!=SCARD_S_SUCCESS) {
    DBG_INFO(LC_LOGDOMAIN,
	     "SCardConnect: %04lx", (long unsigned int) rv);
    return LC_Client_ResultIoError;
  }

  /* get protocol and ATR */
  DBG_INFO(LC_LOGDOMAIN, "Reading protocol and ATR");
  pcchReaderLen=sizeof(readerName);
  dwAtrLen=sizeof(pbAtr);
  rv=SCardStatus(scardHandle,
                 readerName,
                 &pcchReaderLen,
                 &dwState,
                 &dwActiveProtocol,
                 pbAtr,
                 &dwAtrLen);

  if (rv!=SCARD_S_SUCCESS) {
    DBG_ERROR(LC_LOGDOMAIN,
	      "SCardStatus: %04lx", (long unsigned int) rv);
    SCardDisconnect(scardHandle, SCARD_UNPOWER_CARD);
    return LC_Client_ResultIoError;
  }

  /* derive reader and driver type from name */
  DBG_INFO(LC_LOGDOMAIN, "Getting reader- and driver type");
  bDriverType=GWEN_Buffer_new(0, 32, 0, 1);
  bReaderType=GWEN_Buffer_new(0, 32, 0, 1);
  res=LC_Client_GetReaderAndDriverType(cl,
				       readerName,
				       bDriverType,
				       bReaderType,
				       &rflags);
  if (res) {
    DBG_INFO(LC_LOGDOMAIN,
	     "Unable to determine type of reader [%s] (%d), assuming generic pcsc",
	     readerName,
	     res);
    GWEN_Buffer_AppendString(bDriverType, "generic_pcsc");
    GWEN_Buffer_AppendString(bReaderType, "generic_pcsc");
  }

  /* create new card */
  card=LC_Card_new(cl,
		   scardHandle,
		   readerName,
		   dwActiveProtocol,
		   "processor",      /* cardType */
		   rflags,
		   dwAtrLen?pbAtr:0, /* atrBuf */
		   dwAtrLen);        /* atrLen */

  /* complete card data */
  LC_Card_SetDriverType(card, GWEN_Buffer_GetStart(bDriverType));
  LC_Card_SetReaderType(card, GWEN_Buffer_GetStart(bReaderType));

  GWEN_Buffer_free(bReaderType);
  GWEN_Buffer_free(bDriverType);

  *pCard=card;

  return LC_Client_ResultOk;
}
Esempio n. 25
0
//
// FUNCTION NAME: SIM_Status
//
// DESCRIPTION: this is a wrapper for pcsclite SCardStatus function.
//              Its job is to call that function and manage error messages
//              eventually returned.
//
// INPUT PARAMETERS: 
//   SCARDHANDLE hCard    connection handler for this card.
//
// OUTPUT PARAMETERS: RESPONSE*
//   If nothing goes wrong, atr from the card is returned.
//
RESPONSE* SIM_Status(SCARDHANDLE hCard) {
  LONG rv;
  DWORD pcchReaderLen, dwState, dwProtocol;
  BYTE pbAtr[MAX_ATR_SIZE];
  DWORD pcbAtrLen;

  int const buf_size = 1024;
  LPSTR lettori = (LPSTR)malloc(sizeof(char) * buf_size);
  pcchReaderLen = buf_size;
  
  rv = SCardStatus(hCard, lettori, &pcchReaderLen, &dwState, &dwProtocol, pbAtr, &pcbAtrLen);
  switch(rv) {
    case SCARD_E_READER_UNAVAILABLE: {
      bail(EXIT_FAILURE, "SIM_Status:", ERR_READER_REMOVED);
    }
    case SCARD_E_INSUFFICIENT_BUFFER: {
      bail(EXIT_FAILURE, "SIM_Status:",ERR_INSUFFICIENT_BUFFER);
    }
    case SCARD_E_INVALID_HANDLE: {
      bail(EXIT_FAILURE, "SIM_Status:",ERR_INVALID_CONTEXT_HANDLER);
    }
    case SCARD_S_SUCCESS: {
      printf("\n\nCARD STATUS = :\n");
      switch(dwState) {
        case SCARD_ABSENT: {
          printf("\tThere is no card into the reader.");
          break;
        }
        case SCARD_PRESENT: {
          printf("\tCard present but not ready to be used.");
          break;
        }
        case SCARD_SWALLOWED: {
          printf("\tCard present and ready to be used, but not powered.");
          break;
        }
        case SCARD_POWERED: {
          printf("\tCard powered, but mode not recognized by the driver.");
          break;
        }
        case SCARD_NEGOTIABLE: {
          printf("\tCard reset and waiting PTS negotiation.");
          break;
        }
        case SCARD_SPECIFIC: {
          printf("\tCard reset and specific communication protocols established.");
          break;
        }
        default: {
          printf("\tCARD ANSWERED WITH AN UNKNOWN STATE: %.2X.",dwState);
        }
      }

      printf("\n\nCommunication protocol is:\n");
      switch(dwProtocol) {
        case SCARD_PROTOCOL_T0: {
          printf("\tT=0.\n");
          break;
        }
        case SCARD_PROTOCOL_T1: {
          printf("\tT=1.\n");
          break;
        }
        default: {
          printf("\tCARD ANSWERED WITH AN UNKNOWN PROTOCOL.\n");
        }
      }

      printf("\n\nATR = ");
      print_array(pbAtr,pcbAtrLen);
      printf("\n\nATR length = %i.\n",pcbAtrLen);

      RESPONSE* resp = create_b_list();
      int i;
      for(i=0; i<pcbAtrLen; i++) {
        blist_add_element(resp,pbAtr[i]);
      }

      return(resp);
    }
    default: {
      int errno_saved = errno;
      printf("\nValue returned =  %.2X\n",rv);
      bail_with_errno(EXIT_FAILURE, errno_saved, "SIM_Status:",ERR_WRONG_RETURN_VALUE);
    }
  }
}
Esempio n. 26
0
static LONG MSGRemoveContext(SCARDCONTEXT hContext, SCONTEXT * threadContext)
{
	LONG rv;
	int lrv;

	if (threadContext->hContext != hContext)
		return SCARD_E_INVALID_VALUE;

	(void)pthread_mutex_lock(&threadContext->cardsList_lock);
	while (list_size(&threadContext->cardsList) != 0)
	{
		READER_CONTEXT * rContext = NULL;
		SCARDHANDLE hCard, hLockId;
		void *ptr;

		/*
		 * Disconnect each of these just in case
		 */
		ptr = list_get_at(&threadContext->cardsList, 0);
		if (NULL == ptr)
		{
			Log1(PCSC_LOG_CRITICAL, "list_get_at failed");
			continue;
		}
		hCard = *(int32_t *)ptr;

		/*
		 * Unlock the sharing
		 */
		rv = RFReaderInfoById(hCard, &rContext);
		if (rv != SCARD_S_SUCCESS)
		{
			(void)pthread_mutex_unlock(&threadContext->cardsList_lock);
			return rv;
		}

		hLockId = rContext->hLockId;
		rContext->hLockId = 0;

		if (hCard != hLockId)
		{
			/*
			 * if the card is locked by someone else we do not reset it
			 * and simulate a card removal
			 */
			rv = SCARD_W_REMOVED_CARD;
		}
		else
		{
			/*
			 * We will use SCardStatus to see if the card has been
			 * reset there is no need to reset each time
			 * Disconnect is called
			 */
			rv = SCardStatus(hCard, NULL, NULL, NULL, NULL, NULL, NULL);
		}

		if (rv == SCARD_W_RESET_CARD || rv == SCARD_W_REMOVED_CARD)
			(void)SCardDisconnect(hCard, SCARD_LEAVE_CARD);
		else
			(void)SCardDisconnect(hCard, SCARD_RESET_CARD);

		/* Remove entry from the list */
		lrv = list_delete_at(&threadContext->cardsList, 0);
		if (lrv < 0)
			Log2(PCSC_LOG_CRITICAL,
				"list_delete_at failed with return value: %d", lrv);

		UNREF_READER(rContext)
	}
	(void)pthread_mutex_unlock(&threadContext->cardsList_lock);
	list_destroy(&threadContext->cardsList);

	/* We only mark the context as no longer in use.
	 * The memory is freed in MSGCleanupCLient() */
	threadContext->hContext = 0;

	return SCARD_S_SUCCESS;
}
Esempio n. 27
0
static DWORD handle_Status(IRP *irp, tbool wide)
{
	LONG rv;
	SCARDHANDLE hCard;
	DWORD state, protocol;
	DWORD readerLen = 0;
	DWORD atrLen = 0;
	char * readerName;
	BYTE pbAtr[MAX_ATR_SIZE];
	uint32 dataLength;
	int pos, poslen1, poslen2;

#ifdef WITH_DEBUG_SCARD
	int i;
#endif

	stream_seek(irp->input, 0x24);
	stream_read_uint32(irp->input, readerLen);
	stream_read_uint32(irp->input, atrLen);
	stream_seek(irp->input, 0x0c);
	stream_read_uint32(irp->input, hCard);
	stream_seek(irp->input, 0x4);

	atrLen = MAX_ATR_SIZE;

#ifdef SCARD_AUTOALLOCATE
	readerLen = SCARD_AUTOALLOCATE;

	rv = SCardStatus(hCard, (LPSTR) &readerName, &readerLen, &state, &protocol, pbAtr, &atrLen);
#else
	readerLen = 256;
	readerName = xmalloc(readerLen);

	rv = SCardStatus(hCard, (LPSTR) readerName, &readerLen, &state, &protocol, pbAtr, &atrLen);
#endif

	if (rv != SCARD_S_SUCCESS)
	{
		DEBUG_SCARD("Failure: %s (0x%08x)", pcsc_stringify_error(rv), (unsigned) rv);
		return sc_output_return(irp, rv);
	}

	DEBUG_SCARD("Success (state: 0x%08x, proto: 0x%08x)", (unsigned) state, (unsigned) protocol);
	DEBUG_SCARD("       Reader: \"%s\"", readerName ? readerName : "NULL");

#ifdef WITH_DEBUG_SCARD
	printf("       ATR: ");
	for (i = 0; i < atrLen; i++)
		printf("%02x%c", pbAtr[i], (i == atrLen - 1) ? ' ' : ':');
	printf("\n");
#endif

	state = sc_map_state(state);

	poslen1 = stream_get_pos(irp->output);
	stream_write_uint32(irp->output, readerLen);
	stream_write_uint32(irp->output, 0x00020000);
	stream_write_uint32(irp->output, state);
	stream_write_uint32(irp->output, protocol);
	stream_write(irp->output, pbAtr, atrLen);

	if (atrLen < 32)
		stream_write_zero(irp->output, 32 - atrLen);
	stream_write_uint32(irp->output, atrLen);

	poslen2 = stream_get_pos(irp->output);
	stream_write_uint32(irp->output, readerLen);

	dataLength = sc_output_string(irp, readerName, wide);
	dataLength += sc_output_string(irp, "\0", wide);
	sc_output_repos(irp, dataLength);

	pos = stream_get_pos(irp->output);
	stream_set_pos(irp->output, poslen1);
	stream_write_uint32(irp->output,dataLength);
	stream_set_pos(irp->output, poslen2);
	stream_write_uint32(irp->output,dataLength);
	stream_set_pos(irp->output, pos);

	sc_output_alignment(irp, 8);

#ifdef SCARD_AUTOALLOCATE
	/* SCardFreeMemory(NULL, readerName); */
	free(readerName);
#else
	xfree(readerName);
#endif

	return rv;
}
Esempio n. 28
0
/************************ READER CHECK ***************************/
LONG   acr122UReaderCheck(
    tReader   *pReader,
    BOOL      *pReaderSupported
)
{
    static  char     pbReader[MAX_READERNAME] = "";

    DWORD  dwAtrLen, dwReaderLen, dwState, dwProt;
    DWORD  dwRecvLength;
    BYTE   pbAtr[MAX_ATR_SIZE] = "";
    int    i;
    LONG   rv;
    BYTE	  pbRecvBuffer[MAX_FIRMWARE_STRING_LENGTH];

    *pReaderSupported = FALSE;

    /* First check the name reported by pcscd to see if it's possible supported */
    for (i = 0; (i < SUPPORTED_READER_NAME_ARRAY_COUNT) & (*pReaderSupported == FALSE) ; i++)
    {
        if ( strncmp( pReader->name, SUPPORTED_READER_NAME_ARRAY[i],
                      sizeof(SUPPORTED_READER_NAME_ARRAY[i])-1) == 0 )
            *pReaderSupported = TRUE;
    }

    /* If even the name is not supported, then we're done */
    if ( *pReaderSupported == FALSE )
        return (SCARD_S_SUCCESS );

    /* just because the name was OK, doesn't mean it'll actually work! */
    *pReaderSupported = FALSE;

    /* Get firmware version and check it's really a ACR122* */
    dwRecvLength = sizeof(pbRecvBuffer);
    rv = apduSend(pReader->hCard, APDU_GET_READER_FIRMWARE,
                  sizeof(APDU_GET_READER_FIRMWARE),
                  pbRecvBuffer, &dwRecvLength);
    if (rv != SCARD_S_SUCCESS)
        return (rv);

    /* Search the list of supported firmware versions (reader versions) */
    /* to check we are compatible with it - or have tested with it      */

    /* NULL terminate the BYTE array for subsequent string compares */
    pbRecvBuffer[dwRecvLength] = '\0';

    for (i = 0; (i < SUPPORTED_READER_FIRMWARE_ARRAY_COUNT) & (*pReaderSupported == FALSE) ; i++)
    {
        if ( strncmp( ((char *)pbRecvBuffer), SUPPORTED_READER_FIRMWARE_ARRAY[i],
                      sizeof(SUPPORTED_READER_FIRMWARE_ARRAY[i])-1) == 0 )
            *pReaderSupported = TRUE;
    }

    /* if we didn't find that we support it, then we're done */
    if ( *pReaderSupported == FALSE )
        return( SCARD_S_SUCCESS ); /* no actual communication errors to report */

    /* If we got this far then the general name and specific firmware version is supported */
    /* Get ATR so we can tell if there is a SAM in the reader */
    dwAtrLen = sizeof(pbAtr);
    dwReaderLen = sizeof(pbReader);
    SCardStatus( (SCARDHANDLE) (pReader->hCard), pbReader, &dwReaderLen, &dwState, &dwProt, pbAtr, &dwAtrLen);

    dwRecvLength = sizeof(pbRecvBuffer);
    rv = apduSend(pReader->hCard, APDU_SET_RETRY, sizeof(APDU_SET_RETRY),
                  pbRecvBuffer, &dwRecvLength);
    if (rv != SCARD_S_SUCCESS)
        return (rv);

    /* get card status ATR first two bytes = ACS_NO_SAM= '3B00' */
    if ( (pbAtr[SW1] != 0x3B) || (pbAtr[SW2] != 0x00) )
    {
        dwRecvLength = sizeof(pbRecvBuffer);
        rv = apduSend(pReader->hCard, APDU_GET_SAM_SERIAL,
                      sizeof(APDU_GET_SAM_SERIAL),
                      pbRecvBuffer, &dwRecvLength);
        if (rv == SCARD_S_SUCCESS)
        {
            sPrintBufferHex(pReader->SAM_serial, dwRecvLength, pbRecvBuffer);
#if 0
            sprintf(messageString, "SAM Serial: %s", pReader->SAM_serial);
            readersLogMessage(LOG_INFO, 1, messageString);
#endif
        }
        else
            return (rv);

        dwRecvLength = sizeof(pbRecvBuffer);
        rv = apduSend(pReader->hCard, APDU_GET_SAM_ID, sizeof(APDU_GET_SAM_ID),
                      pbRecvBuffer, &dwRecvLength);
        if (rv == SCARD_S_SUCCESS)
        {
            sPrintBufferHex(pReader->SAM_id, dwRecvLength, pbRecvBuffer);
#if 0
            sprintf(messageString, "SAM ID: %s", pReader->SAM_id);
            readersLogMessage(LOG_INFO, 1, messageString);
#endif
        }
        else
            return( rv );

        pReader->SAM = TRUE;
    }

    /* Turning RATS off thus a JCOP tag will be detected as emulating a DESFIRE */
    apduSend(pReader->hCard, APDU_RATS_14443_4_OFF, sizeof(APDU_RATS_14443_4_OFF), pbRecvBuffer, &dwRecvLength);

    return( SCARD_S_SUCCESS );

}
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")
	}
Esempio n. 30
0
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);
}