int eDVBCIMMISession::doAction() { switch (state) { case stateStarted: state = stateIdle; break; case stateDisplayReply: { unsigned char tag[] = {0x9f, 0x88, 0x02}; unsigned char data[] = {0x01, 0x01}; sendAPDU(tag, data, 2); state = stateIdle; break; } case stateFakeOK: { unsigned char tag[] = {0x9f, 0x88, 0x0b}; unsigned char data[] = {5}; sendAPDU(tag, data, 1); state = stateIdle; break; } case stateIdle: break; default: break; } return 0; }
int eDVBCIApplicationManagerSession::doAction() { switch (state) { case stateStarted: { const unsigned char tag[3]={0x9F, 0x80, 0x20}; // application manager info e sendAPDU(tag); sendAPDU(tag); state=stateFinal; return 1; } case stateFinal: eDebug("[CI AM] in final state."); wantmenu = 0; if (wantmenu) { eDebug("[CI AM] wantmenu: sending Tenter_menu"); const unsigned char tag[3]={0x9F, 0x80, 0x22}; // Tenter_menu sendAPDU(tag); wantmenu=0; return 0; } else return 0; default: return 0; } }
static int testMisc(SCARDCONTEXT hCard) { int ret = 0; int errCount = 0; unsigned char recvBuf[258]; DWORD recvBufLen = sizeof(recvBuf); ret = sendAPDU(hCard, "80:E4:00:00:1C", recvBuf, &recvBufLen); CHECK_PCSC_RET("sendAPDU(Get Card Data)", ret); if (recvBufLen != 0x1E || recvBuf[recvBufLen - 2] != 0x90 || recvBuf[recvBufLen - 1] != 0x00) { printf("ERR: Get Card Data didn't return 90 00\n"); errCount++; } ret = sendAPDU(hCard, "80:E4:00:00:1B", recvBuf, &recvBufLen); CHECK_PCSC_RET("sendAPDU(Get Card Data)", ret); if (recvBufLen != 0x1D || recvBuf[recvBufLen - 2] != 0x61 || recvBuf[recvBufLen - 1] != 0x01) { printf("ERR: Get Card Data didn't return 61 01\n"); errCount++; } return errCount; }
int eDVBCIResourceManagerSession::doAction() { #if 1 printf("%s >\n", __func__); #endif switch (state) { case stateStarted: { const unsigned char tag[3]={0x9F, 0x80, 0x10}; // profile enquiry sendAPDU(tag); state = stateFirstProfileEnquiry; #if 1 printf("%s <\n", __func__); #endif return 0; } case stateFirstProfileEnquiry: { const unsigned char tag[3]={0x9F, 0x80, 0x12}; // profile change sendAPDU(tag); state=stateProfileChange; #if 1 printf("%s <\n", __func__); #endif return 0; } case stateProfileChange: { printf("bla kaputt\n"); break; } case stateProfileEnquiry: { const unsigned char tag[3]={0x9F, 0x80, 0x11}; const unsigned char data[][4]= { {0x00, 0x01, 0x00, 0x41}, {0x00, 0x02, 0x00, 0x41}, {0x00, 0x03, 0x00, 0x41}, // {0x00, 0x20, 0x00, 0x41}, // host control {0x00, 0x24, 0x00, 0x41}, {0x00, 0x40, 0x00, 0x41} // {0x00, 0x10, 0x00, 0x41} // auth. }; sendAPDU(tag, data, sizeof(data)); state=stateFinal; return 0; } case stateFinal: printf("stateFinal und action! kann doch garnicht sein ;)\n"); default: break; } #if 1 printf("%s <\n", __func__); #endif return 0; }
static long sendAPDUS(SCARDCONTEXT ctx, const char *readerName, int apduCount, const char **apdus) { SCARDHANDLE hCard; DWORD protocol; char debugString[2048]; printf("Using reader \"%s\"\n\n", readerName); sprintf_s(debugString, 2047, "Using reader \"%s\"\n\n", readerName); DebugMessage(debugString); long ret = SCardConnectA(ctx, readerName, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0, &hCard, &protocol); CHECK_PCSC_RET("SCardConnect", ret); if (SCARD_S_SUCCESS == ret) { unsigned char recvBuf[258]; DWORD recvBufLen; for (int i = 0; i < apduCount; i++) { recvBufLen = (DWORD) sizeof(recvBuf); sendAPDU(hCard, apdus[i], recvBuf, &recvBufLen, NULL, 0, true); } ret = SCardDisconnect(hCard, SCARD_LEAVE_CARD); CHECK_PCSC_RET("SCardDisconnect", ret); } return 0; }
int eDVBCICAManagerSession::doAction() { #ifdef __sh__ printf("%s >\n", __func__); #endif switch (state) { case stateStarted: { const unsigned char tag[3]={0x9F, 0x80, 0x30}; // ca info enq sendAPDU(tag); state=stateFinal; #ifdef __sh__ printf("%s <", __func__); #endif return 0; } case stateFinal: printf("stateFinal und action! kann doch garnicht sein ;)\n"); default: #ifdef __sh__ printf("%s <\n", __func__); #endif return 0; } #ifdef __sh__ printf("%s <\n", __func__); #endif }
static const char *GetChipNrFromCard(SCARDHANDLE hCard, char *chipNrBuf) { unsigned char recvBuf[258]; DWORD recvBufLen = (DWORD) sizeof(recvBuf); memset(chipNrBuf, 0, 2 * CHIP_NR_LEN + 1); // Send "Get Card Data" command, the first 16 bytes that are returned is the chip nr long ret = sendAPDU(hCard, "80:E4:00:00:1C", recvBuf, &recvBufLen, NULL, 0, false); if (0 != ret) return NULL; else if (recvBufLen != 28 + 2) { printf("ERR: Get Card Data command returned %d bytes instead of 30\n", (int) recvBufLen); return NULL; } // Convert the chip nr into a hex string for (int i = 0; i < 16; i++) { chipNrBuf[2 * i + 0] = HEX_TABLE[recvBuf[i] / 16]; chipNrBuf[2 * i + 1] = HEX_TABLE[recvBuf[i] % 16]; } return chipNrBuf; }
int eDVBCIResourceManagerSession::doAction() { switch (state) { case stateStarted: { const unsigned char tag[3]={0x9F, 0x80, 0x10}; // profile enquiry sendAPDU(tag); state = stateFirstProfileEnquiry; return 0; } case stateFirstProfileEnquiry: { const unsigned char tag[3]={0x9F, 0x80, 0x12}; // profile change sendAPDU(tag); state=stateProfileChange; return 0; } case stateProfileChange: { eDebug("[CI RM] cannot deal with statProfileChange"); break; } case stateProfileEnquiry: { const unsigned char tag[3]={0x9F, 0x80, 0x11}; const unsigned char data[][4]= { {0x00, 0x01, 0x00, 0x41}, {0x00, 0x02, 0x00, 0x41}, {0x00, 0x03, 0x00, 0x41}, // {0x00, 0x20, 0x00, 0x41}, // host control {0x00, 0x24, 0x00, 0x41}, {0x00, 0x40, 0x00, 0x41}, // {0x00, 0x10, 0x00, 0x41}, // auth. }; sendAPDU(tag, data, sizeof(data)); state=stateFinal; return 0; } case stateFinal: eDebug("[CI RM] Should not happen: action on stateFinal"); default: break; } return 0; }
int eDVBCICAManagerSession::sendCAPMT(unsigned char *data, int len) { const unsigned char tag[3] = {0x9F, 0x80, 0x32}; // ca_pmt sendAPDU(tag, data, len); return 0; }
int eDVBCIApplicationManagerSession::doAction() { #if 1 printf("%s >", __func__); #endif switch (state) { case stateStarted: { const unsigned char tag[3]={0x9F, 0x80, 0x20}; // application manager info e sendAPDU(tag); sendAPDU(tag); state=stateFinal; #if 1 printf("%s <", __func__); #endif return 1; } case stateFinal: printf("in final state."); wantmenu = 0; if (wantmenu) { printf("wantmenu: sending Tenter_menu\n"); const unsigned char tag[3]={0x9F, 0x80, 0x22}; // Tenter_menu sendAPDU(tag); wantmenu=0; #if 1 printf("%s <\n", __func__); #endif return 0; } else return 0; default: #if 1 printf("%s <\n", __func__); #endif return 0; } #if 1 printf("%s <\n", __func__); #endif }
vector<vector<unsigned char> > PCSCReader::sendAPDUs( const vector<vector<unsigned char> > &cmds) { vector<vector<unsigned char> > resp; for (size_t i = 0; i < cmds.size(); i++) { resp.push_back(sendAPDU(cmds[i])); } return resp; }
int eDVBCIMMISession::stopMMI() { unsigned char tag[] = {0x9f, 0x88, 0x00}; unsigned char data[] = {0x00}; sendAPDU(tag, data, 1); slot->mmiOpened = false; return 0; }
int eDVBCIApplicationManagerSession::startMMI() { eDebug("[CI AM] in appmanager -> startmmi()"); const unsigned char tag[3]={0x9F, 0x80, 0x22}; // Tenter_menu sendAPDU(tag); #ifdef __sh__ slot->mmiOpened(); #endif return 0; }
int eDVBCIMMISession::cancelEnq() { eDebug("eDVBCIMMISession::cancelEnq()"); unsigned char tag[]={0x9f, 0x88, 0x08}; unsigned char data[]={0x00}; // canceled sendAPDU(tag, data, 1); return 0; }
int eDVBCIMMISession::stopMMI() { eDebug("eDVBCIMMISession::stopMMI()"); unsigned char tag[]={0x9f, 0x88, 0x00}; unsigned char data[]={0x00}; sendAPDU(tag, data, 1); return 0; }
int eDVBCIMMISession::cancelEnq() { printf("eDVBCIMMISession::cancelEnq()\n"); unsigned char tag[] = {0x9f, 0x88, 0x08}; unsigned char data[] = {0x00}; // canceled sendAPDU(tag, data, 1); slot->mmiOpened = false; return 0; }
int eDVBCIMMISession::answerText(int answer) { printf("eDVBCIMMISession::answerText(%d)\n", answer); unsigned char tag[] = {0x9f, 0x88, 0x0B}; unsigned char data[] = {0x00}; data[0] = answer & 0xff; sendAPDU(tag, data, 1); return 0; }
int eDVBCIMMISession::answerEnq(char * answer, int len) { printf("eDVBCIMMISession::answerEnq(%d bytes)\n", len); unsigned char data[len + 1]; data[0] = 0x01; // answer ok memcpy(data + 1, answer, len); unsigned char tag[] = {0x9f, 0x88, 0x08}; sendAPDU(tag, data, len + 1); return 0; }
int eDVBCIMMISession::doAction() { #ifdef __sh__ printf("%s >\n", __func__); #endif switch (state) { case stateStarted: state=stateIdle; break; case stateDisplayReply: { unsigned char tag[]={0x9f, 0x88, 0x02}; unsigned char data[]={0x01, 0x01}; sendAPDU(tag, data, 2); state=stateIdle; //state=stateFakeOK; //return 1; break; } case stateFakeOK: { unsigned char tag[]={0x9f, 0x88, 0x0b}; unsigned char data[]={5}; sendAPDU(tag, data, 1); state=stateIdle; break; } case stateIdle: break; default: break; } #ifdef __sh__ printf("%s <\n", __func__); #endif return 0; }
int eDVBCIMMISession::answerEnq(char *answer) { unsigned int len = strlen(answer); eDebug("eDVBCIMMISession::answerEnq(%d bytes)", len); unsigned char data[len+1]; data[0] = 0x01; // answer ok memcpy(data+1, answer, len); unsigned char tag[]={0x9f, 0x88, 0x08}; sendAPDU(tag, data, len+1); return 0; }
int eDVBCIMMISession::stopMMI() { printf("eDVBCIMMISession::stopMMI()"); unsigned char tag[]={0x9f, 0x88, 0x00}; unsigned char data[]={0x00}; sendAPDU(tag, data, 1); slot->mmiOpened = false; #ifdef __sh__ printf("%s <\n", __func__); #endif return 0; }
int eDVBCICAManagerSession::sendCAPMT(unsigned char *data, int len) { const unsigned char tag[3]={0x9F, 0x80, 0x32}; // ca_pmt #ifdef __sh__ printf("%s >\n", __func__); #endif sendAPDU(tag, data, len); #ifdef __sh__ printf("%s <\n", __func__); #endif return 0; }
int eDVBCIMMISession::answerText(int answer) { printf("eDVBCIMMISession::answerText(%d)\n",answer); unsigned char tag[]={0x9f, 0x88, 0x0B}; unsigned char data[]={0x00}; data[0] = answer & 0xff; sendAPDU(tag, data, 1); #ifdef __sh__ printf("%s <\n", __func__); #endif return 0; }
int eDVBCICAManagerSession::doAction() { switch (state) { case stateStarted: { const unsigned char tag[3]= {0x9F, 0x80, 0x30}; // ca info enq sendAPDU(tag); state=stateFinal; return 0; } case stateFinal: eDebug("[CI CA] stateFinal and action should not happen"); default: return 0; } }
int eDVBCIApplicationManagerSession::startMMI() { #if 1 printf("%s >\n", __func__); #endif printf("in appmanager -> startmmi()\n"); const unsigned char tag[3]={0x9F, 0x80, 0x22}; // Tenter_menu sendAPDU(tag); slot->mmiOpened = true; #if 1 //fixme slot->mmiOpened(); printf("%s <\n", __func__); #endif return 0; }
int eDVBCICAManagerSession::doAction() { switch (state) { case stateStarted: { const unsigned char tag[3]={0x9F, 0x80, 0x30}; // ca info enq sendAPDU(tag); state=stateFinal; return 0; } case stateFinal: dprintf(DEBUG_DEBUG, "stateFinal und action! kann doch garnicht sein ;)\n"); default: return 0; } }
int eDVBCIDateTimeSession::doAction() { switch (state) { case stateStarted: return 0; case stateSendDateTime: { unsigned char tag[3]={0x9f, 0x84, 0x41}; // date_time_response unsigned char msg[7]={0, 0, 0, 0, 0, 0, 0}; sendAPDU(tag, msg, 7); return 0; } case stateFinal: eDebug("stateFinal und action! kann doch garnicht sein ;)"); default: return 0; } }
static int testScardReconnect(SCARDCONTEXT hCard, DWORD dwShareMode, DWORD dwPreferredProtocols) { int ret = 0; int errCount = 0; DWORD dwAP = 0; for (int i = 0; i < 2; i++) { ret = SCardReconnect(hCard, dwShareMode, dwPreferredProtocols, SCARD_RESET_CARD, &dwAP); if (SCARD_S_SUCCESS != ret) { printf("ERR: SCardReconnect(RESET) failed: 0x%0x (%d)\n", ret, ret); errCount++; } ret = SCardReconnect(hCard, dwShareMode, dwPreferredProtocols, SCARD_UNPOWER_CARD, &dwAP); if (SCARD_S_SUCCESS != ret) { printf("ERR: SCardReconnect(UNPOWER) failed: 0x%0x (%d)\n", ret, ret); errCount++; } ret = SCardReconnect(hCard, dwShareMode, dwPreferredProtocols, SCARD_LEAVE_CARD, &dwAP); if (SCARD_S_SUCCESS != ret) { printf("ERR: SCardReconnect(LEAVE) failed: 0x%0x (%d)\n", ret, ret); errCount++; } unsigned char recvBuf[2]; DWORD recvBufLen = (DWORD) sizeof(recvBuf); ret = sendAPDU(hCard, "00:A4:04:0C:0C:A0:00:00:01:77:50:4B:43:53:2D:31:35", recvBuf, &recvBufLen); CHECK_PCSC_RET("sendAPDU(Get Card Data)", ret); } return errCount; }
static int testConnect(SCARDCONTEXT ctx, const char *readerName) { int returnValue = 0; SCARDHANDLE hCard; DWORD protocol; long ret = SCardConnectA(ctx, readerName, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0, &hCard, &protocol); if (SCARD_S_SUCCESS != ret) returnValue |= 0x1; //-------1 if (SCARD_S_SUCCESS == ret) { delayMS(200); unsigned char recvBuf[258]; DWORD recvBufLen; recvBufLen = (DWORD) sizeof(recvBuf); sendAPDU(hCard, "00:A4:04:0C:0C:A0:00:00:01:77:50:4B:43:53:2D:31:35", recvBuf, &recvBufLen, NULL, 0, true); if (!(recvBufLen == 2)) returnValue |= 0x2; //------1- if (!(recvBuf[0] == 0x90 && recvBuf[1] == 0x00)) returnValue |= 0x2; //------1- ret = SCardDisconnect(hCard, SCARD_LEAVE_CARD); if (SCARD_S_SUCCESS != ret) returnValue |= 0x4; //-----1-- ret = SCardDisconnect(1111, SCARD_LEAVE_CARD); if (SCARD_S_SUCCESS == ret) returnValue |= 0x4; //-----1-- } return returnValue; }
static int testLongFileRead(SCARDCONTEXT hCard) { int ret = 0; int errCount = 0; unsigned char recvBuf[258]; DWORD recvBufLen = sizeof(recvBuf); // Select the file ret = sendAPDU(hCard, "00:A4:04:0C:0C:A0:00:00:01:77:50:4B:43:53:2D:31:35", recvBuf, &recvBufLen); CHECK_PCSC_RET("sendAPDU(select MF)", ret); ret = sendAPDU(hCard, "00:A4:02:0C:02:50:38", recvBuf, &recvBufLen); CHECK_PCSC_RET("sendAPDU(select 5038)", ret); // Get the file size char apdu[20]; int offs = 0; int fileLen = 0; for (; offs < 5000; offs += 0xfc) { sprintf(apdu, "00B0%02X%02XFC", offs / 256, offs % 256); recvBufLen = sizeof(recvBuf); ret = sendAPDU(hCard, apdu, recvBuf, &recvBufLen); CHECK_PCSC_RET("sendAPDU(Read Binary)", ret); if (recvBufLen == 2 && recvBuf[0] == 0x6c) { fileLen = offs + recvBuf[1]; break; } } // Read 1 byte at filesize - 1 sprintf(apdu, "00B0%02X%02X01", (fileLen - 1) / 256, (fileLen - 1) % 256); recvBufLen = sizeof(recvBuf); ret = sendAPDU(hCard, apdu, recvBuf, &recvBufLen); CHECK_PCSC_RET("sendAPDU(Read Binary)", ret); if (recvBufLen != 3 || recvBuf[1] != 0x90 || recvBuf[2] != 0x00) { printf("ERR: ReadBinary(offset = filesize-1, len = 1) didn't return 1 byte\n"); errCount++; } // Read 1 byte at filesize sprintf(apdu, "00B0%02X%02X01", (fileLen) / 256, (fileLen) % 256); recvBufLen = sizeof(recvBuf); ret = sendAPDU(hCard, apdu, recvBuf, &recvBufLen); CHECK_PCSC_RET("sendAPDU(Read Binary)", ret); if (recvBufLen != 2 || recvBuf[0] != 0x6B || recvBuf[1] != 0x00) { printf("ERR: ReadBinary(offset = filesize, len = 1) didn't return 6B 00\n"); errCount++; } // Read 1 byte at filesize + 1 sprintf(apdu, "00B0%02X%02X01", (fileLen + 1) / 256, (fileLen + 1) % 256); recvBufLen = sizeof(recvBuf); ret = sendAPDU(hCard, apdu, recvBuf, &recvBufLen); CHECK_PCSC_RET("sendAPDU(Read Binary)", ret); if (recvBufLen != 2 || recvBuf[0] != 0x6B || recvBuf[1] != 0x00) { printf("ERR: ReadBinary(offset = filesize+1, len = 1) didn't return 6B 00\n"); errCount++; } return errCount; }