static int32_t pcsc_do_api(struct s_reader *pcsc_reader, const uchar *buf, uchar *cta_res, uint16_t *cta_lr, int32_t l) { LONG rv; DWORD dwSendLength, dwRecvLength; *cta_lr = 0; if(!l) { rdr_log(pcsc_reader, "ERROR: Data length to be send to the pcsc_reader is %d", l); return ERROR; } char tmp[l * 3]; dwRecvLength = CTA_RES_LEN; struct pcsc_data *crdr_data = pcsc_reader->crdr_data; if(crdr_data->dwActiveProtocol == SCARD_PROTOCOL_T0) { // explanantion as to why we do the test on buf[4] : // Issuing a command without exchanging data : //To issue a command to the card that does not involve the exchange of data (either sent or received), the send and receive buffers must be formatted as follows. //The pbSendBuffer buffer must contain the CLA, INS, P1, and P2 values for the T=0 operation. The P3 value is not sent. (This is to differentiate the header from the case where 256 bytes are expected to be returned.) //The cbSendLength parameter must be set to four, the size of the T=0 header information (CLA, INS, P1, and P2). //The pbRecvBuffer will receive the SW1 and SW2 status codes from the operation. //The pcbRecvLength should be at least two and will be set to two upon return. if(buf[4]) { dwSendLength = l; } else { dwSendLength = l - 1; } rdr_log_dbg(pcsc_reader, D_DEVICE, "sending %lu bytes to PCSC : %s", (unsigned long)dwSendLength, cs_hexdump(1, buf, l, tmp, sizeof(tmp))); rv = SCardTransmit(crdr_data->hCard, SCARD_PCI_T0, (LPCBYTE) buf, dwSendLength, NULL, (LPBYTE) cta_res, (LPDWORD) &dwRecvLength); *cta_lr = dwRecvLength; } else if(crdr_data->dwActiveProtocol == SCARD_PROTOCOL_T1) { dwSendLength = l; rdr_log_dbg(pcsc_reader, D_DEVICE, "sending %lu bytes to PCSC : %s", (unsigned long)dwSendLength, cs_hexdump(1, buf, l, tmp, sizeof(tmp))); rv = SCardTransmit(crdr_data->hCard, SCARD_PCI_T1, (LPCBYTE) buf, dwSendLength, NULL, (LPBYTE) cta_res, (LPDWORD) &dwRecvLength); *cta_lr = dwRecvLength; } else { rdr_log_dbg(pcsc_reader, D_DEVICE, "PCSC invalid protocol (T=%lu)", (unsigned long)crdr_data->dwActiveProtocol); return ERROR; } rdr_log_dbg(pcsc_reader, D_DEVICE, "received %d bytes from PCSC with rv=%lx : %s", *cta_lr, (unsigned long)rv, cs_hexdump(1, cta_res, *cta_lr, tmp, sizeof(tmp))); rdr_log_dbg(pcsc_reader, D_DEVICE, "PCSC doapi (%lx ) (T=%d), %d", (unsigned long)rv, (crdr_data->dwActiveProtocol == SCARD_PROTOCOL_T0 ? 0 : 1), *cta_lr); if(rv == SCARD_S_SUCCESS) { return OK; } else { return ERROR; } }
LONG isobase3(HANDLE hReader,unsigned char *apduData,int svAPDULen,unsigned char *srResp,int *srRespLen) { BYTE ResponseBuffer[MAX_RESPDATA_LENGTH] = {0}; DWORD ResponseLength = 1024; WORD retval = 0; unsigned char responeCMD[5] = {0x00, 0xC0, 0x00, 0x00, 0x00}; short respLen; IO_Request.dwProtocol = ActiveProtocol; IO_Request.cbPciLength = (DWORD) sizeof(SCARD_IO_REQUEST); ret = SCardTransmit((SCARDHANDLE)hReader, &IO_Request, apduData, svAPDULen, 0, (BYTE *)ResponseBuffer, &ResponseLength); if (ret != SCARD_S_SUCCESS) { return ret; } if ( ResponseLength >= 2 ) { retval = ((BYTE)ResponseBuffer[ResponseLength-2]) * 256 + (BYTE)ResponseBuffer[ResponseLength-1] ; //if rf if(retval==0x9000) { *srRespLen = (short)ResponseLength - 2; memcpy(srResp,ResponseBuffer,*srRespLen); }else if((retval & 0xFF00) == 0x6100){ respLen = (BYTE)ResponseBuffer[ResponseLength-1] ; responeCMD[4] = (unsigned char)respLen; ResponseLength = respLen + 2; ret = SCardTransmit((SCARDHANDLE)hReader, &IO_Request, responeCMD, RESPONECMD_LEN, 0, (BYTE *)&ResponseBuffer, &ResponseLength); if (ret != SCARD_S_SUCCESS) { return ret; } retval = ((BYTE)ResponseBuffer[ResponseLength-2]) * 256 + (BYTE)ResponseBuffer[ResponseLength-1] ; memcpy(srResp,ResponseBuffer,respLen); }else{ return retval; } } else { return ILLEGAL_RESPONSE_LENGTH; } return EXCUTE_SUC ; }
/* * Transmit. */ JNIEXPORT jint JNICALL GEN_FUNCNAME(Card_NativeTransmit___3BII_3BI) (JNIEnv *env, jobject _this, jbyteArray jin, jint inoff, jint inlen, jbyteArray jout, jint outoff) { SCARD_IO_REQUEST sendPci; SCARDHANDLE card; unsigned char *cin; unsigned char *cout; jboolean isCopy; LONG rv; int proto; DWORD outlen; card = (SCARDHANDLE) (*env)->GetLongField(env, _this, CardField); proto = (int) (*env)->GetIntField(env, _this, ProtoField); sendPci.dwProtocol = proto; sendPci.cbPciLength = sizeof(SCARD_IO_REQUEST); cin = (*env)->GetByteArrayElements(env, jin, &isCopy); cout = (*env)->GetByteArrayElements(env, jout, &isCopy); outlen = (*env)->GetArrayLength(env, jout) - outoff; if (proto == SCARD_PROTOCOL_T0) { if (5 + (cin[inoff + 4] & 0xff) < inlen) inlen = 5 + (cin[inoff + 4] & 0xff); } JPCSC_LOG(("NativeTransmit2(): inlen %d\n", inlen)); rv = SCardTransmit(card, &sendPci, cin + inoff, inlen, NULL, cout + outoff, &outlen); JPCSC_LOG(("NativeTransmit2(): return code 0x%x, return length %d\n", (int) rv, (int) outlen)); if ((proto == SCARD_PROTOCOL_T0) && (outlen == 2)) { if (cout[outoff] == 0x6c && ((*env)->GetBooleanField(env, _this, ResendOnWrongLeField) != 0)) { outlen = (*env)->GetArrayLength(env, jout) - outoff; cin[inoff + 4] = cout[outoff + 1]; rv = SCardTransmit(card, &sendPci, cin + inoff, inlen, NULL, cout + outoff, &outlen); } else { if ((cout[outoff] == 0x61) && ((*env)->GetBooleanField(env, _this, T0GetResponseField) != 0)) { rv = t0_get_response(card, proto, cout, outoff, (*env)->GetArrayLength(env, jout) - outoff, &outlen); } } } (*env)->ReleaseByteArrayElements(env, jin, cin, JNI_ABORT); (*env)->ReleaseByteArrayElements(env, jout, cout, 0); if (rv != SCARD_S_SUCCESS) { pcscex_throw(env, "SCardTransmit()", rv); return SCARD_S_SUCCESS; } assert(outlen >= 0); return outlen; }
/* * Transmit. */ JNIEXPORT jbyteArray JNICALL GEN_FUNCNAME(Card_NativeTransmit___3BII) (JNIEnv *env, jobject _this, jbyteArray jin, jint joff, jint jlen) { SCARD_IO_REQUEST sendPci; SCARDHANDLE card; unsigned char *cin; jboolean isCopy; LONG rv; int proto; unsigned char cout[RECEIVE_BUFFER_SIZE]; DWORD clen = RECEIVE_BUFFER_SIZE; jbyteArray jout; card = (SCARDHANDLE) (*env)->GetLongField(env, _this, CardField); proto = (int) (*env)->GetIntField(env, _this, ProtoField); sendPci.dwProtocol = proto; sendPci.cbPciLength = sizeof(SCARD_IO_REQUEST); cin = (*env)->GetByteArrayElements(env, jin, &isCopy); if (proto == SCARD_PROTOCOL_T0) { if (5 + (cin[joff + 4] & 0xff) < jlen) jlen = 5 + (cin[joff + 4] & 0xff); } JPCSC_LOG(("NativeTransmit1(): proto %d, inlen %d\n", proto, jlen)); rv = SCardTransmit(card, &sendPci, cin + joff, jlen, NULL, cout, &clen); JPCSC_LOG(("NativeTransmit1(): return code 0x%x, return length %d\n", (int) rv, (int) clen)); if ((proto == SCARD_PROTOCOL_T0) && (clen == 2)) { if (cout[0] == 0x6c && ((*env)->GetBooleanField(env, _this, ResendOnWrongLeField) != 0)) { clen = RECEIVE_BUFFER_SIZE; cin[joff + 4] = cout[1]; rv = SCardTransmit(card, &sendPci, cin + joff, jlen, NULL, cout, &clen); } else { if ((cout[0] == 0x61) && ((*env)->GetBooleanField(env, _this, T0GetResponseField) != 0)) { rv = t0_get_response(card, proto, cout, 0, RECEIVE_BUFFER_SIZE, &clen); } } } (*env)->ReleaseByteArrayElements(env, jin, cin, JNI_ABORT); if (rv != SCARD_S_SUCCESS) { pcscex_throw(env, "SCardTransmit()", rv); return NULL; } jout = (*env)->NewByteArray(env, clen); (*env)->SetByteArrayRegion(env, jout, 0, clen, cout); return jout; }
int Token::dump_primary(vector<BYTE> &res, DWORD id){ LONG lReturn; BYTE cont_number = 0; BYTE *pbSend, *pbRecv; DWORD dwRecv; const DWORD cdwRecv = 1024; const DWORD cdwSend = 128; // need to login if (0 != this->et72k_Login()) return 11; res.clear(); pbSend = new BYTE[cdwSend]; pbRecv = new BYTE[cdwRecv]; //begin transaction lReturn = SCardBeginTransaction(this->hCardHandle); if (SCARD_S_SUCCESS != lReturn){ cout << "[*] ERROR: Failed SCardBeginTransaction: " << lReturn << endl; return 20; } memset(pbSend, 0, cdwSend); memcpy(pbSend, s11, ls11); pbSend[14] = id; dwRecv = cdwRecv; SCardTransmit(this->hCardHandle, SCARD_PCI_T1, pbSend, ls11, NULL, pbRecv, &dwRecv); //send s11 with container id if (memcmp(pbRecv, noFile, 2) == 0){ //file not found delete[] pbRecv; delete[] pbSend; return 10; //no such container id } //cout << ">>>(s11) "; showarr(pbSend, ls11, ':'); //DEBUG //cout << "<<< "; showarr(pbRecv, dwRecv, ':'); //DEBUG dwRecv = cdwRecv; SCardTransmit(this->hCardHandle, SCARD_PCI_T1, cmdGET_PRIMARY, lcmdGET_PRIMARY, NULL, pbRecv, &dwRecv); //claim primary.key for (int i = 0; i < dwRecv - 2; i++) res.push_back(pbRecv[i]); //cout << ">>> "; showarr(cmdGET_MASKS, lcmdGET_MASKS, ':'); //DEBUG //cout << "<<< "; showarr(pbRecv, dwRecv, ':'); //DEBUG //End transaction SCardEndTransaction(this->hCardHandle, SCARD_LEAVE_CARD); delete[] pbRecv; delete[] pbSend; return 0; }
int Token::dump_name(vector<BYTE> &res, DWORD id){ LONG lReturn; BYTE cont_number = 0; BYTE *pbSend, *pbRecv; DWORD dwRecv; const DWORD cdwRecv = 1024; const DWORD cdwSend = 128; res.clear(); pbSend = new BYTE[cdwSend]; pbRecv = new BYTE[cdwRecv]; //begin transaction lReturn = SCardBeginTransaction(this->hCardHandle); if (SCARD_S_SUCCESS != lReturn){ cout << "[*] ERROR: Failed SCardBeginTransaction: " << lReturn << endl; return 20; } this->sendPreambula(); memset(pbSend, 0, cdwSend); memcpy(pbSend, s5, ls5); pbSend[14] = id; dwRecv = cdwRecv; SCardTransmit(this->hCardHandle, SCARD_PCI_T1, pbSend, ls6, NULL, pbRecv, &dwRecv); //send s6 with container id if (memcmp(pbRecv, noFile, 2) == 0){ //file not found delete[] pbRecv; delete[] pbSend; return 10; //no such container id } //cout << ">>>(s5) "; showarr(pbSend, ls5, ':'); //DEBUG //cout << "<<< "; showarr(pbRecv, dwRecv, ':'); //DEBUG dwRecv = cdwRecv; SCardTransmit(this->hCardHandle, SCARD_PCI_T1, cmdGIVE_ALL_name, lcmdGIVE_ALL_name, NULL, pbRecv, &dwRecv); //claim first 10 bytes of header.key for (int i = 0; i < dwRecv - 2 && pbRecv[i] != 0x00; i++) res.push_back(pbRecv[i]); //cout << ">>>(1st 10) "; showarr(cmdGIVE_ALL_name, lcmdGIVE_ALL_name, ':'); //DEBUG //cout << "<<< "; showarr(pbRecv, dwRecv, ':'); //DEBUG //End transaction SCardEndTransaction(this->hCardHandle, SCARD_LEAVE_CARD); delete[] pbRecv; delete[] pbSend; return 0; }
void testMacNewcardIssue(SCARDHANDLE* phCard) { BYTE pbSendBuffer[7] = {0x00 ,0xA4 ,0x02 ,0x0C ,0x02 ,0x50 ,0x38}; BYTE pbRecvBuffer[4]; BYTE pbSendBuffer2[5] = {0x00 ,0xB0 ,0x00 ,0x00 ,0xF8}; BYTE pbRecvBuffer2[248];//248=F8 //00 A4 08 0C 04 DF 00 50 32 DWORD cbSendLength = sizeof(pbSendBuffer); DWORD cbRecvLength = sizeof(pbRecvBuffer); DWORD cbSendLength2 = sizeof(pbSendBuffer2); DWORD cbRecvLength2 = sizeof(pbRecvBuffer2); DWORD retval; BYTE SW1 = 0x90; BYTE SW2 = 0x00; //select authentication cert retval = SCardTransmit(*phCard,SCARD_PCI_T0,pbSendBuffer,cbSendLength,NULL, pbRecvBuffer,&cbRecvLength); SW1 = pbRecvBuffer2[cbRecvLength-2]; SW2 = pbRecvBuffer2[cbRecvLength-1]; if( (SW1 != 0x90) || (SW2 != 0x00) || retval != SCARD_S_SUCCESS ) printf ("select authentication cert SW1 = 0x%x SW1 = 0x%x retval = 0x%x\n",SW1,SW2,retval); //read the authentication cert retval = SCardTransmit(*phCard,SCARD_PCI_T0,pbSendBuffer2,cbSendLength2,NULL, pbRecvBuffer2,&cbRecvLength2); SW1 = pbRecvBuffer2[cbRecvLength2-2]; SW2 = pbRecvBuffer2[cbRecvLength2-1]; if( (SW1 != 0x90) || (SW2 != 0x00) || retval != SCARD_S_SUCCESS ) printf ("read authentication cert SW1 = 0x%x SW1 = 0x%x retval = 0x%x\n",SW1,SW2,retval); while ( (SW1 == 0x90) && (SW2 == 0x00) ) { SCardTransmit(*phCard,SCARD_PCI_T0,pbSendBuffer2,cbSendLength2,NULL, pbRecvBuffer2,&cbRecvLength2); SW1 = pbRecvBuffer2[cbRecvLength2-2]; SW2 = pbRecvBuffer2[cbRecvLength2-1]; printf ("received: 0x%x 0x%x len = %d - retval: 0x%x\n",pbRecvBuffer2[0],pbRecvBuffer2[1],cbRecvLength2, retval); } if(SW1 == 0x6c) { cbRecvLength2 = SW2; SCardTransmit(*phCard,SCARD_PCI_T0,pbSendBuffer2,cbSendLength2,NULL, pbRecvBuffer2,&cbRecvLength2); SW1 = pbRecvBuffer2[cbRecvLength2-2]; SW2 = pbRecvBuffer2[cbRecvLength2-1]; printf ("final received: 0x%x 0x%x len = %d - retval: 0x%x\n",pbRecvBuffer2[0],pbRecvBuffer2[1],cbRecvLength2, retval); } //retval = SCardTransmit(*phCard,SCARD_PCI_T0,pbSendBuffer,cbSendLength,NULL, pbRecvBuffer,&cbRecvLength); //printf ("received: 0x%x 0x%x len = %d - retval: 0x%x\n",pbRecvBuffer2[0],pbRecvBuffer2[1],cbRecvLength2, retval); printf ("testMacNewcardIssue completed \n"); }
QPCSCReader::Result QPCSCReader::transfer( const QByteArray &cmd ) const { static const SCARD_IO_REQUEST T0 = { 1, 8 }; static const SCARD_IO_REQUEST T1 = { 2, 8 }; QByteArray data( 255 + 3, 0 ); DWORD size = data.size(); qDebug() << "Send:" << cmd.toHex(); DWORD ret = SCardTransmit( d->card, d->proto == SCARD_PROTOCOL_T0 ? &T0 : &T1, LPCBYTE(cmd.constData()), cmd.size(), 0, LPBYTE(data.data()), &size ); if( ret != SCARD_S_SUCCESS ) { qDebug() << "Err:" << ret; return Result(); } Result result( data.mid( size-2, 2 ), data.left( size - 2 ) ); qDebug() << "Recv:" << result.first.toHex() << result.second.toHex(); if( result.first.at( 0 ) == 0x61 ) { QByteArray cmd( "\x00\xC0\x00\x00\x00", 5 ); cmd[4] = data.at( size-1 ); return transfer( cmd ); } return result; }
void PCSCDataTransport::send(const std::vector<unsigned char>& data) { d_response.clear(); EXCEPTION_ASSERT_WITH_LOG(getPCSCReaderUnit(), LibLogicalAccessException, "The PCSC reader unit object" "is null. We cannot send."); if (data.size() > 0) { unsigned char returnedData[255]; ULONG ulNoOfDataReceived = sizeof(returnedData); LPCSCARD_IO_REQUEST ior = NULL; switch (getPCSCReaderUnit()->getActiveProtocol()) { case SCARD_PROTOCOL_T0: ior = SCARD_PCI_T0; break; case SCARD_PROTOCOL_T1: ior = SCARD_PCI_T1; break; case SCARD_PROTOCOL_RAW: ior = SCARD_PCI_RAW; break; } LOG(LogLevel::COMS) << "APDU command: " << BufferHelper::getHex(data); unsigned int errorFlag = SCardTransmit(getPCSCReaderUnit()->getHandle(), ior, &data[0], static_cast<DWORD>(data.size()), NULL, returnedData, &ulNoOfDataReceived); CheckCardError(errorFlag); d_response = std::vector<unsigned char>(returnedData, returnedData + ulNoOfDataReceived); } }
void PCSC::TransmitUID(){ //choix du protocole en fonction d'active protocole switch (ActiveProtocol) { case SCARD_PROTOCOL_T0: Request = SCARD_PCI_T0; //transmission en character-oriented half-duplex break; case SCARD_PROTOCOL_T1: Request = SCARD_PCI_T1; //transmision en block-oriented half-duplex transmission break; default: Request = SCARD_PCI_RAW; break; } //recuperation de l'uid : *ReturnValue = SCardTransmit(Cardhandle, //handle. Request, //le protocole Commande, // La commande (DWORD)sizeof(Commande), // taille de la commande NULL, ResponseUID, // buffer de reponse &SizeReponse); // taille de la reponse Status(); }
BOOL PCSC_IccTransmit (MRTD_CTX_ST * ctx, const BYTE send[], WORD send_sz, BYTE recv[], WORD * recv_sz) { LONG rc; DWORD recv_sz_dw = 0; const SCARD_IO_REQUEST *pioSendPci = NULL; if (ctx == NULL) return FALSE; if (recv_sz != NULL) recv_sz_dw = *recv_sz; if (ctx->reader.pcsc.protocol == SCARD_PROTOCOL_T0) { pioSendPci = SCARD_PCI_T0; } else if (ctx->reader.pcsc.protocol == SCARD_PROTOCOL_T1) { pioSendPci = SCARD_PCI_T1; } rc = SCardTransmit (ctx->reader.pcsc.hcard, pioSendPci, send, send_sz, NULL, recv, &recv_sz_dw); if (recv_sz != NULL) *recv_sz = (WORD) recv_sz_dw; if (rc != SCARD_S_SUCCESS) { MrtdVerbose("SCardTransmit : PC/SC error %08lX", rc); MrtdSetLastError (ctx, MRTD_E_CARD_LOST); return FALSE; } return TRUE; }
/* * handle all the APDU's that are common to all CAC applets */ static VCardStatus passthru_process_apdu(VCard *card, VCardAPDU *apdu, VCardResponse **response) { LONG rv; unsigned char buf[MAX_RESPONSE_LENGTH]; uint32_t len = MAX_RESPONSE_LENGTH; VCardAppletPrivate *applet_private = NULL; SCARD_IO_REQUEST receive_io; applet_private = vcard_get_current_applet_private(card, 0); if (applet_private == NULL) { *response = vcard_make_response(VCARD7816_STATUS_EXC_ERROR); return VCARD_DONE; } rv = SCardTransmit(applet_private->hCard, applet_private->send_io, apdu->a_data, apdu->a_len, &receive_io, buf, &len); if (rv != SCARD_S_SUCCESS) { *response = vcard_make_response(VCARD7816_STATUS_EXC_ERROR); return VCARD_DONE; } *response = vcard_response_new_data(buf,len); if (*response == NULL) { *response = vcard_make_response(VCARD7816_STATUS_EXC_ERROR_MEMORY_FAILURE); } else { (*response)->b_total_len = (*response)->b_len; } return VCARD_DONE; }
/** * Transmit APDU using PC/SC * * @param slot the slot to use for communication * @param capdu the command APDU * @param capdu_len the length of the command APDU * @param rapdu the response APDU * @param rapdu_len the length of the response APDU * @return -1 for error or length of received response APDU */ int transmitAPDUviaPCSC(struct p11Slot_t *slot, unsigned char *capdu, size_t capdu_len, unsigned char *rapdu, size_t rapdu_len) { LONG rc; DWORD lenr; FUNC_CALLED(); if (!slot->card) { FUNC_FAILS(-1, "No card handle"); } lenr = rapdu_len; rc = SCardTransmit(slot->card, SCARD_PCI_T1, capdu, capdu_len, NULL, rapdu, &lenr); #ifdef DEBUG debug("SCardTransmit: %s\n", pcsc_error_to_string(rc)); #endif if (rc != SCARD_S_SUCCESS) { FUNC_FAILS(-1, "SCardTransmit failed"); } FUNC_RETURNS(lenr); }
bool silvia_pcsc_card::transmit(bytestring APDU, bytestring& data_sw) { if (!connected) return false; data_sw.resize(65536); DWORD out_len = 65536; SCARD_IO_REQUEST recv_req; LONG rv = SCardTransmit( card_handle, protocol == SCARD_PROTOCOL_T0 ? SCARD_PCI_T0 : SCARD_PCI_T1, APDU.byte_str(), APDU.size(), &recv_req, data_sw.byte_str(), &out_len); if (rv != SCARD_S_SUCCESS) { return false; } data_sw.resize(out_len); if (data_sw.size() < 2) { return false; } return true; }
int SmartCardReader::transmit( ) { char tempstr[262]; char tempstr2[262]; int index; sprintf( tempstr, ">" ); for( index = 0; index <= SendLen-1 ; index++ ) { sprintf( tempstr, "%s %02X", tempstr, SendBuff[index] ); } sprintf( tempstr, "%s\n", tempstr ); //DisplayOut( tempstr, BLACK ); retCode = SCardTransmit(card, NULL, SendBuff, SendLen, NULL, RecvBuff, &RecvLen); cout << "buff : " << endl << RecvBuff << endl ; cout << "vlen" << endl << RecvLen << endl ; if( retCode != SCARD_S_SUCCESS ) { ofLogError( " SCardTransmit Error " ) << getSCardErrorMessage( retCode ) ; //DisplayOut( GetScardErrMsg( retCode ), RED ); } else { ofLogNotice( "transmit was a success!" ) ; sprintf( tempstr2, ">" ); for( index = 0; index <= RecvLen - 1; index++ ) { sprintf( tempstr2, "%s %02X",tempstr2, RecvBuff[index] ); } sprintf( tempstr2, "%s \n", tempstr2 ); cout << tempstr2 << endl ; //DisplayOut( tempstr2, BLACK ); } return retCode; }
void Token::sendPreambula(){ BYTE *pbRecv; DWORD dwRecv; const DWORD cdwRecv = 1024; pbRecv = new BYTE[cdwRecv]; dwRecv = cdwRecv; SCardTransmit(this->hCardHandle, SCARD_PCI_T1, s1, ls1, NULL, pbRecv, &dwRecv); //send s1 dwRecv = cdwRecv; SCardTransmit(this->hCardHandle, SCARD_PCI_T1, s2, ls2, NULL, pbRecv, &dwRecv); //send s2 dwRecv = cdwRecv; SCardTransmit(this->hCardHandle, SCARD_PCI_T1, s3, ls3, NULL, pbRecv, &dwRecv); //send s3 //cout << ">>>(s3) "; showarr(s3, ls3, ':'); //DEBUG //cout << "<<< "; showarr(pbRecv, dwRecv, ':'); //DEBUG delete[] pbRecv; }
void Token::sendAPDUFromFile(char *f){ LONG lReturn; const DWORD cdwRecv = 1024; DWORD dwRecv; BYTE *pbRecv; pbRecv = new BYTE[cdwRecv]; ifstream fin(f); if (!fin.is_open()){ cout << "[*] ERROR: Failed open '" << f <<"'" << endl; return; } string line; while (getline(fin, line)){ if (line.find(">>> ") == 0){ line.replace(0, 4, ""); vector<string> sar; vector<BYTE> bar; split(line, ":", sar); hex2byte(sar, bar); // // Send data to card // DWORD dwRecv = cdwRecv; lReturn = SCardTransmit(hCardHandle, SCARD_PCI_T1, bar.data(), bar.size(), NULL, pbRecv, &dwRecv); if (SCARD_S_SUCCESS != lReturn) { cout << "[*] ERROR: Failed SCardTransmit (" << bar << "):" << lReturn << endl; goto THE_END; } if (this->debug){ cout << ">>> "; showarr(bar.data(), bar.size(), ':'); cout << "<<< "; showarr(pbRecv, dwRecv, ':'); } } } THE_END: fin.close(); delete[] pbRecv; }
static long sendAPDU(SCARDHANDLE hCard, const char *apdu, unsigned char *recvBuf, DWORD *recvBufLen, const char *chipNr, int idx, bool doDump) { unsigned char sendBuf[280]; size_t sendBufLen = sizeof(sendBuf); // Hex string -> byte array if (0 == hex2bin(apdu, sendBuf, &sendBufLen)) { // Check the APDU if (sendBufLen < 4) { printf("ERR: APDU should be at least 4 bytes\n"); DebugMessage("ERR: APDU should be at least 4 bytes\n"); } else if (sendBufLen > 5 && (5 + sendBuf[4] != sendBufLen)) { printf("ERR: wrong P3 byte in case 3 APDU\n"); DebugMessage("ERR: wrong P3 byte in case 3 APDU\n"); } else { if (doDump) dumphex2(" - sending ", sendBuf, sendBufLen); #if TRANSMIT_DEBUG long ret = SCardTransmit2(hCard, &g_rgSCardT0Pci, sendBuf, (DWORD) sendBufLen, NULL, recvBuf, recvBufLen); #else long ret = SCardTransmit(hCard, &g_rgSCardT0Pci, sendBuf, (DWORD) sendBufLen, NULL, recvBuf, recvBufLen); #endif CHECK_PCSC_RET("SCardTransmit", ret); if (SCARD_S_SUCCESS == ret) { if (doDump) { dumphex2(" received ", recvBuf, *recvBufLen); printf("\n"); DebugMessage("\n"); } if (NULL != chipNr) StoreAPDUs(chipNr, idx, sendBuf, sendBufLen, recvBuf, *recvBufLen); return 0; // success } } } return -1; // failed }
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); } }
long CardTransmit(SCARDHANDLE hCard, LPCSCARD_IO_REQUEST pioSendPci, LPCBYTE pbSendBuffer, DWORD cbSendLength, LPSCARD_IO_REQUEST pioRecvPci, LPBYTE pbRecvBuffer, LPDWORD pcbRecvLength) { long lRet = SCardTransmit(hCard, pioSendPci, pbSendBuffer, cbSendLength, pioRecvPci, pbRecvBuffer, pcbRecvLength); //printf("SCardTransmit(hCard=0x%0x, sendprot=0x%0x, sent %d bytes, recvprot=0x%0x): r = 0x%0x (%d), recv %d bytes\n", //hCard, pioSendPci->dwProtocol, cbSendLength, pioRecvPci->dwProtocol, lRet, lRet, * pcbRecvLength); return lRet; }
int ttl_io(SCARDHANDLE card, DWORD protocol, struct c_apdu *c_apdu, struct r_apdu *r_apdu) { LONG rc; SCARD_IO_REQUEST send_io_req, recv_io_req; BYTE send_buf[256 + 5], recv_buf[NELEMS(send_buf)]; DWORD send_buf_len, recv_buf_len; if (protocol != SCARD_PROTOCOL_T0) { fprintf(stderr, "only T0 protocol is currently supported"); return -1; } memset(&send_io_req, 0, sizeof(send_io_req)); memset(&recv_io_req, 0, sizeof(recv_io_req)); memset(send_buf, 0, sizeof(send_buf)); memset(recv_buf, 0, sizeof(recv_buf)); send_buf_len = recv_buf_len = 0; if (c_apdu->body.len == -1) { memcpy(send_buf, c_apdu, 4); send_buf_len = 4; } else { memcpy(send_buf, c_apdu, 4); send_buf[4] = (BYTE) c_apdu->body.len; memcpy(send_buf + 5, c_apdu->body.data, c_apdu->body.len); send_buf_len = 4 + 1 + c_apdu->body.len; } recv_buf_len = 2; if (c_apdu->body.max_r_len > 0) recv_buf_len += c_apdu->body.max_r_len; fprintf(stderr, "calling SCardTransmit\n"); if ((rc = SCardTransmit(card, protocol == SCARD_PROTOCOL_T0 ? SCARD_PCI_T0 : SCARD_PCI_T1, send_buf, send_buf_len, NULL, recv_buf, &recv_buf_len)) != SCARD_S_SUCCESS) { fprintf(stderr, "SCardTransmit failed with code %d\n", rc); return -1; } memcpy(r_apdu, recv_buf + recv_buf_len - 2, 2); if (recv_buf_len > 2) { memcpy(r_apdu->body.data, recv_buf, recv_buf_len - 2); r_apdu->body.len = recv_buf_len - 2; } else { r_apdu->body.len = -1; } return 0; }
void testFullPathSelect(SCARDHANDLE* phCard) { BYTE SW1 = 0x90; BYTE SW2 = 0x00; BYTE pbSendBuffer[] = {0x00 ,0xA4 ,0x08 ,0x0C ,0x04 ,0xDF ,0x01 ,0x40 ,0x31}; BYTE pbRecvBuffer[4]; DWORD cbSendLength = sizeof(pbSendBuffer); DWORD cbRecvLength = sizeof(pbRecvBuffer); DWORD retval; retval = SCardTransmit(*phCard,SCARD_PCI_T0,pbSendBuffer,cbSendLength,NULL, pbRecvBuffer,&cbRecvLength); printf ("trying to select EF(ID) by its full path\n"); printf ("received: 0x%x 0x%x len = %d - retval: 0x%08x\n",pbRecvBuffer[0],pbRecvBuffer[1],cbRecvLength, retval); getchar(); }
bool CPCSCClass::Transmit(CString cstrApdu) { unsigned char sendbuff[270]; unsigned char recvbuff[270]; int apdulen = 0; DWORD recvlen = 2; CConvertData cvrtObj; memset(sendbuff,0,270); memset(recvbuff,0,270); cvrtObj.HexStringToByteArray(cstrApdu,NULL,&apdulen); cvrtObj.HexStringToByteArray(cstrApdu,sendbuff,&apdulen); mylog.AddToLogs(0,m_logobj,"send:",sendbuff,apdulen,true); if(apdulen < 5) { mylog.AddToLogs(m_logobj,"error: command too short"); } if(apdulen == 5) recvlen = 2 + sendbuff[4]; RetCode = SCardTransmit( hCard, &IO_REQ, sendbuff, apdulen, NULL, // IN OUT LPSCARD_IO_REQUEST pioRecvPci, recvbuff, &recvlen); if (RetCode != SCARD_S_SUCCESS) { mylog.AddToLogs(m_logobj,"error: SCardTransmit failed"); mylog.AddToLogs(m_logobj,TranslatePCSCError()); return false; } mylog.AddToLogs(m_logobj,"SCardTransmit Success"); mylog.AddToLogs(0,m_logobj,"recv:",recvbuff,recvlen,true); return true; }
unsigned short isobase3(HANDLE devNo,unsigned char *svAPDU,short svAPDULen,unsigned char *srResp,short *srRespLen, short ivCardSet) { BYTE ResponseBuffer[2000]; DWORD ResponseLength ; WORD retval = CER_PCSC_SCardTransmit_Data_LOST; // IO_Request.dwProtocol = SCARD_PROTOCOL_T1; IO_Request.dwProtocol = ActiveProtocol; IO_Request.cbPciLength = (DWORD) sizeof(SCARD_IO_REQUEST); ResponseLength=2000; ret = SCardTransmit((SCARDHANDLE)devNo, &IO_Request, svAPDU, svAPDULen, 0, (BYTE *)&ResponseBuffer, &ResponseLength); if (ret != SCARD_S_SUCCESS) { DebugMessage(ret); return CER_PCSC_SCardTransmit; } if ( ResponseLength >= 2 ) { retval = ((BYTE)ResponseBuffer[ResponseLength-2]) * 256 + (BYTE)ResponseBuffer[ResponseLength-1] ; //if rf if(retval==0x9000) { *srRespLen = (short)ResponseLength - 2; memcpy(srResp,ResponseBuffer,ResponseLength-2); } } else { DebugMessage(1); retval = CER_PCSC_SCardTransmit_Data_LOST; } return retval ; }
vector <unsigned char> PCSCReader::sendAPDU( const vector<unsigned char>& cmd) { BYTE res[RAPDU::RAPDU_EXTENDED_MAX]; DWORD reslen = sizeof res; DWORD r = SCARD_S_SUCCESS; vector <unsigned char> result; if (0x00 == m_hCard) throw WrongHandle(); r = SCardTransmit(m_hCard, SCARD_PCI_T1, cmd.data(), (DWORD) cmd.size(), NULL, res, &reslen); if (r != SCARD_S_SUCCESS) throw TransactionFailed(); return vector<unsigned char>(res, res + reslen); }
void testBELPICAIDSelect(SCARDHANDLE* phCard) { // static const unsigned char APPLET_AID[] = {0xA0,0x00,0x00,0x00,0x30,0x29,0x05,0x70,0x00,0xAD,0x13,0x10,0x01,0x01,0xFF}; //static const unsigned char BELPIC_AID[] = {0xA0,0x00,0x00,0x01,0x77,0x50,0x4B,0x43,0x53,0x2D,0x31,0x35}; //static const unsigned char ID_AID[] = {0xA0,0x00,0x00,0x01,0x77,0x49,0x64,0x46,0x69,0x6C,0x65,0x73}; BYTE pbSendBuffer[] = {0x00 ,0xA4 ,0x04 ,0x0C , 0x0C ,0xA0,0x00,0x00,0x01,0x77,0x50,0x4B,0x43,0x53,0x2D,0x31,0x35}; BYTE pbRecvBuffer[4]; DWORD cbSendLength = sizeof(pbSendBuffer); DWORD cbRecvLength = sizeof(pbRecvBuffer); DWORD retval; retval = SCardTransmit(*phCard,SCARD_PCI_T0,pbSendBuffer,cbSendLength,NULL, pbRecvBuffer,&cbRecvLength); printf ("trying to select DF(BELPIC) by its AID\n"); printf ("received: 0x%x 0x%x len = %d - retval: 0x%08x\n",pbRecvBuffer[0],pbRecvBuffer[1],cbRecvLength, retval); getchar(); }
static UINT32 smartcard_Transmit_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation, Transmit_Call* call) { LONG status; Transmit_Return ret; IRP* irp = operation->irp; ret.cbRecvLength = 0; ret.pbRecvBuffer = NULL; if (call->cbRecvLength && !call->fpbRecvBufferIsNULL) { if (call->cbRecvLength >= 66560) call->cbRecvLength = 66560; ret.cbRecvLength = call->cbRecvLength; ret.pbRecvBuffer = (BYTE*) malloc(ret.cbRecvLength); } ret.pioRecvPci = call->pioRecvPci; status = ret.ReturnCode = SCardTransmit(operation->hCard, call->pioSendPci, call->pbSendBuffer, call->cbSendLength, ret.pioRecvPci, ret.pbRecvBuffer, &(ret.cbRecvLength)); smartcard_trace_transmit_return(smartcard, &ret); status = smartcard_pack_transmit_return(smartcard, irp->output, &ret); if (status != SCARD_S_SUCCESS) return status; if (call->pbSendBuffer) free(call->pbSendBuffer); if (ret.pbRecvBuffer) free(ret.pbRecvBuffer); if (call->pioSendPci) free(call->pioSendPci); if (call->pioRecvPci) free(call->pioRecvPci); return ret.ReturnCode; }
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; }
int acr122_receive (nfc_device *pnd, uint8_t *pbtData, const size_t szData, int timeout) { // FIXME: timeout is not handled (void) timeout; int len; uint8_t abtRxCmd[5] = { 0xFF, 0xC0, 0x00, 0x00 }; if (DRIVER_DATA (pnd)->ioCard.dwProtocol == SCARD_PROTOCOL_T0) { /* * Retrieve the PN532 response. */ DWORD dwRxLen = sizeof (DRIVER_DATA (pnd)->abtRx); abtRxCmd[4] = DRIVER_DATA (pnd)->abtRx[1]; if (SCardTransmit (DRIVER_DATA (pnd)->hCard, &(DRIVER_DATA (pnd)->ioCard), abtRxCmd, sizeof (abtRxCmd), NULL, DRIVER_DATA (pnd)->abtRx, &dwRxLen) != SCARD_S_SUCCESS) { pnd->last_error = NFC_EIO; return pnd->last_error; } DRIVER_DATA (pnd)->szRx = dwRxLen; } else { /* * We already have the PN532 answer, it was saved by acr122_send(). */ } LOG_HEX ("RX", DRIVER_DATA (pnd)->abtRx, DRIVER_DATA (pnd)->szRx); // Make sure we have an emulated answer that fits the return buffer if (DRIVER_DATA (pnd)->szRx < 4 || (DRIVER_DATA (pnd)->szRx - 4) > szData) { pnd->last_error = NFC_EIO; return pnd->last_error; } // Wipe out the 4 APDU emulation bytes: D5 4B .. .. .. 90 00 len = DRIVER_DATA (pnd)->szRx - 4; memcpy (pbtData, DRIVER_DATA (pnd)->abtRx + 2, len); return len; }
/********************************************************************************************** 10 PCSC_ApduT0 卡命令处理函数,该命令接收APDU Case2 Case3格式的指令。 HD_ApduT0( HANDLE hReader, unsigned char *apduData, short srAPDULen, unsigned char *respData, short *respDataLen) 参数说明 hReader 由PCSC_OpenReader返回的设备句柄 apduData APDU命令(字节串)用CLA、INS、P1、P2以及一个可变长度的条件体来表示,条件体的定义为Lc、Data(Lc个字节)和Le。 根据Lc和Le值的不同,共有四种命令情况,如下表所示: 情况 结构 1 CLA INS P1 P2 2 CLA INS P1 P2 Le 3 CLA INS P1 P2 Lc Data 4 CLA INS P1 P2 Lc Data Le srAPDULen 存放发送的APDU数据的长度 respData 卡响应数据 respDataLen 卡响应数据的长度 返回值 当操作Case1和 Case2时,respData无意义。当操作Case3和 Case4时,函数返回0x9000,respData有意义;其余响应,respData无意义。 ***********************************************************************************************/ LONG isobase2(HANDLE hReader, unsigned char *apduData, int svAPDULen, unsigned char *srResp, int *srRespLen) { BYTE ResponseBuffer[MAX_RESPDATA_LENGTH]; DWORD ResponseLength = 1024; WORD retval = 0; *srRespLen = 0 ; *srResp = '\0' ; IO_Request.dwProtocol = ActiveProtocol; IO_Request.cbPciLength = (DWORD) sizeof(SCARD_IO_REQUEST); ResponseLength=2000; ret = SCardTransmit((SCARDHANDLE)hReader, &IO_Request, apduData, svAPDULen, 0, (BYTE *)&ResponseBuffer, &ResponseLength); if (ret != SCARD_S_SUCCESS) { return ret; } if ( ResponseLength >= 2 ) { retval = ((BYTE)ResponseBuffer[ResponseLength-2]) * 256 + (BYTE)ResponseBuffer[ResponseLength-1] ; *srRespLen = (short)ResponseLength - 2; memcpy(srResp,ResponseBuffer,ResponseLength-2); }else{ return ret; } return EXCUTE_SUC ; }