📄 protomac.c
字号:
/* ============================================================================ Project Name : jayaCard TCK Module Name : proto/tck/cos/common/protomac.c Version : $Id: protomac.c,v 1.39 2004/04/24 12:19:25 dgil Exp $ Description: common sources of protocol macros The Original Code is jayaCard TCK code. The Initial Developer of the Original Code is Gilles Dumortier. Portions created by the Initial Developer are Copyright (C) 2002-2004 the Initial Developer. All Rights Reserved. Contributor(s): Permission is granted to any individual to use, copy, or redistribute this software so long as all of the original files are included unmodified, that it is not sold for profit, and that this copyright notice is retained. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. History Rev Description 021503 dgil wrote it from scratch 072203 dgil remove specific message for Type A protocol ============================================================================*/#include "precomp.h"/* ============================================================================ Interface currently in use ========================================================================= */jbyte gInterface = TCK_INTERFACE_CONTACTLESS_A;/* ============================================================================ Baudrate currently in use (only for contactless interface) ========================================================================= */jword current_baudrate = 0;/* ============================================================================ Socket port currently in use ========================================================================= */short gPort = 2000;SOCKET sT;/* ============================================================================ T=CL block-number ========================================================================= */jbyte block_number = 0;/* ============================================================================ Historical Bytes ========================================================================= */jbyte historicalBytes[24];jbyte life;/* ============================================================================ TPDU ========================================================================= */jbyte gTPDU[JAYACFG_APDU_LENGTH];jword gnTPDU = 0;jbyte sw1;jbyte sw2;jword sw1sw2;/* ============================================================================ chipUUID ========================================================================= */jbyte chip[8];/* ============================================================================ RANDOM() ========================================================================= */void RANDOM(void){ u.bBlock[JAYA_BCRYPTO_RANDOM0+0] = 0x00; u.bBlock[JAYA_BCRYPTO_RANDOM0+1] = 0x00; u.bBlock[JAYA_BCRYPTO_RANDOM0+2] = 0x00; u.bBlock[JAYA_BCRYPTO_RANDOM0+3] = 0x00; u.bBlock[JAYA_BCRYPTO_RANDOM0+4] = 0x00; u.bBlock[JAYA_BCRYPTO_RANDOM0+5] = 0x00; u.bBlock[JAYA_BCRYPTO_RANDOM0+6] = 0x00; u.bBlock[JAYA_BCRYPTO_RANDOM0+7] = 0x00;}/* ============================================================================ POWERON() ========================================================================= */void POWERON(jbyte interf){ char szInterface[40]; jresult res; jbyte i; /* init the MSK */ read_MSK(); /* init the historical bytes and current card cycle life */ for (i=0; i<sizeof(historicalBytes); i++) historicalBytes[i] = 0; life = 0x00; /* unknown for now */ switch (interf) { case TCK_INTERFACE_CONTACT: strcpy(szInterface,"CONTACT T=0"); break; case TCK_INTERFACE_CONTACTLESS_A: strcpy(szInterface,"CONTACTLESS TypeA"); tcl_type = TCL_TYPEA; break; case TCK_INTERFACE_CONTACTLESS_B: strcpy(szInterface,"CONTACTLESS TypeB"); tcl_type = TCL_TYPEB; break; default: strcpy(szInterface,"???"); break; } gInterface = interf; BAUDRATE(0); LOG1("TCK","send POWERON on %s.",szInterface); res = send_simumsg_to_card(sT,gInterface,"POWERON",0x00); if (res!=JY_OK) { exit(-1); }}/* ============================================================================ HISTORICAL_BYTES() ========================================================================= */void HISTORICAL_BYTES(void){ life = historicalBytes[6]; switch(life) { case LIFECYCLE_INIT: LOG("TCK","Card Life Cycle : LIFE_INIT"); break; case LIFECYCLE_PERSO: LOG("TCK","Card Life Cycle : LIFE_PERSO"); break; case LIFECYCLE_APPLI: LOG("TCK","Card Life Cycle : LIFE_APPLI"); break; case LIFECYCLE_BLOCKED: LOG("TCK","Card Life Cycle : LIFE_BLOCKED"); break; case LIFECYCLE_INVALID: LOG("TCK","Card Life Cycle : LIFE_???? INVALID IN THE CARD !"); break; default: LOG1("TCK","Unknown Card Life Cycle returned ! 0x%.2X",life); life = LIFECYCLE_INVALID; /* to continue */ break; }}/* ============================================================================ POWEROFF() ========================================================================= */void POWEROFF(void){ jresult res; LOG("TCK","send POWEROFF."); res = send_simumsg_to_card(sT,gInterface,"POWEROFF",0x00); if (res!=JY_OK) { exit(-1); }}/* ============================================================================ RESET() ========================================================================= */void RESET(void){ jresult res; BAUDRATE(0); LOG("TCK","send RESET (WARM)."); res = send_simumsg_to_card(sT,gInterface,"RESET",0x00); if (res!=JY_OK) { exit(-1); }}/* ============================================================================ UNLOCK_INIT() ========================================================================= */void UNLOCK_INIT(void){ jresult res; LOG("TCK","send UNLOCK_INIT."); res = send_simumsg_to_card(sT,gInterface,"UNLOCK_INIT",0x00); if (res!=JY_OK) { exit(-1); }}/* ============================================================================ UNLOCK_BOOTSTRAP() ========================================================================= */void UNLOCK_BOOTSTRAP(void){ jresult res; LOG("TCK","send UNLOCK_BOOTSTRAP."); res = send_simumsg_to_card(sT,gInterface,"UNLOCK_BOOTSTRAP",0x00); if (res!=JY_OK) { exit(-1); }}/* ============================================================================ UNLOCK_PERSO() ========================================================================= */void UNLOCK_PERSO(void){ jresult res; LOG("TCK","send UNLOCK_PERSO."); res = send_simumsg_to_card(sT,gInterface,"UNLOCK_PERSO",0x00); if (res!=JY_OK) { exit(-1); }}/* ============================================================================ UNLOCK_BLOCKED() ========================================================================= */void UNLOCK_BLOCKED(void){ jresult res; LOG("TCK","send UNLOCK_BLOCKED."); res = send_simumsg_to_card(sT,gInterface,"UNLOCK_BLOCKED",0x00); if (res!=JY_OK) { exit(-1); }}/* ============================================================================ SAVE_EEPROM() ========================================================================= */void SAVE_EEPROM(jbyte num){ jresult res; LOG1("TCK","send SAVE_EEPROM %d.",num); res = send_simumsg_to_card(sT,gInterface,"SAVE_EEPROM",num); if (res!=JY_OK) { exit(-1); }}/* ============================================================================ SAVE_RAM() ========================================================================= */void SAVE_RAM(jbyte num){ jresult res; LOG1("TCK","send SAVE_RAM %d.",num); res = send_simumsg_to_card(sT,gInterface,"SAVE_RAM",num); if (res!=JY_OK) { exit(-1); }}/* ============================================================================ LOAD_EEPROM() ========================================================================= */void LOAD_EEPROM(jbyte num){ jresult res; LOG1("TCK","send LOAD_EEPROM %d.",num); res = send_simumsg_to_card(sT,gInterface,"LOAD_EEPROM",num); if (res!=JY_OK) { exit(-1); }}/* ============================================================================ CLEAR_EEPROM() ========================================================================= */void CLEAR_EEPROM(void){ jresult res; LOG("TCK","send CLEAR_EEPROM."); res = send_simumsg_to_card(sT,gInterface,"CLEAR_EEPROM",0x00); if (res!=JY_OK) { exit(-1); }}/* ============================================================================ BAUDRATE() ========================================================================= */void BAUDRATE(jbyte num){ current_baudrate = num << (6+8);}/* ============================================================================ ATS() ========================================================================= */void ATS(void){ char* ats; jresult res; LOG("TCK","send RATS = E081 ; CID=1, FSD=256(FSDI=8)."); res = send_simumsg_to_card(sT,gInterface,"E081",0x00); if (res!=JY_OK) { exit(-1); } res = receive_simumsg_from_card(sT,&ats,0); if (res!=JY_OK) { exit(-1); } LOG3("TCK","receive ATS %c%c %s.",ats[0],ats[1],&ats[2]); /* decode historicalBytes */ hexa2bytes(historicalBytes,&ats[10]); HISTORICAL_BYTES(); free(ats);}/* ============================================================================ IBLOCK() ========================================================================= */void IBLOCK(char* apdu){ char tpdu[1204]; char* r_tpdu; jresult res; if (block_number==0) { sprintf(tpdu,"0A01%s",apdu); block_number = 1; } else { sprintf(tpdu,"0B01%s",apdu); block_number = 0; } LOG1("TCK","send IBLOCK = %s ; CID=1.",tpdu); res = send_simumsg_to_card(sT,gInterface,tpdu,current_baudrate); if (res!=JY_OK) { exit(-1); } res = receive_simumsg_from_card(sT,&r_tpdu,current_baudrate); if (res!=JY_OK) { exit(-1); } LOG1("TCK","receive IBLOCK %s.",r_tpdu); free(r_tpdu);}/* ============================================================================ DESELECT() ========================================================================= */void DESELECT(void){ char tpdu[1204]; char* r_tpdu; jresult res; strcpy(tpdu,"CA01"); LOG1("TCK","send DESELECT = %s ; CID=1.",tpdu); res = send_simumsg_to_card(sT,gInterface,tpdu,current_baudrate); if (res!=JY_OK) { exit(-1); } res = receive_simumsg_from_card(sT,&r_tpdu,current_baudrate); if (res!=JY_OK) { exit(-1); } LOG1("TCK","receive AnswerToDESELET %s.",r_tpdu); BAUDRATE(0); free(r_tpdu);}/* ============================================================================ APDU(char* apdu,jbyte lenR) ========================================================================= */void APDU(char* apdu,int lenR){ char tpdu[1204]; char* r_tpdu; int i_apdu; jbyte ins; jbyte r_ins; jresult res; if (gInterface==TCK_INTERFACE_CONTACT) { /* __x XXX replacing dubious hexa2byte(&ins,tpdu); */ ins = hexa2byte(apdu[2], apdu[3]); if (strlen(apdu)<10) { fprintf(stderr,"APDU(): Hmmm. APDU %s Too Short !\n",apdu); exit(-1); } if (strlen(apdu)==10) { /* send just the command (header of 5 bytes) */ LOG1("TCK","send %s",apdu); /* Phil: XXX check baudrate stuff */ res = send_simumsg_to_card(sT,TCK_INTERFACE_CONTACT,apdu,0x00); if (res!=JY_OK) { exit(-1); } } else { /* send just the header */ strncpy(tpdu,apdu,10); tpdu[10] = '\0'; i_apdu = 10; LOG1("TCK","send %s",tpdu); res = send_simumsg_to_card(sT,TCK_INTERFACE_CONTACT,tpdu,0x00); if (res!=JY_OK) { exit(-1); } /* wait for INS or !INS */loop: res = receive_simumsg_from_card(sT,&r_tpdu,1); if (res!=JY_OK) { exit(-1); } /* __x XXX replacing dubious hexa2byte(&r_ins,r_tpdu); */ r_ins = hexa2byte(r_tpdu[0], r_tpdu[1]); LOG2("TCK","receive %.2X (%s)",r_ins,r_ins==ins?"INS":ins==(jbyte)(~r_ins)?"!INS":"???"); if (ins==r_ins) { /* send the remaining bytes */ LOG1("TCK"," %s",&apdu[i_apdu]); res = send_simumsg_to_card(sT,TCK_INTERFACE_CONTACT,&apdu[i_apdu],0x00); if (res!=JY_OK) { exit(-1); } } else if (ins==(jbyte)(~r_ins)) { /* send only one byte */ strncpy(tpdu,&apdu[i_apdu],2); tpdu[2] = '\0'; i_apdu+=2; LOG1("TCK"," %s",tpdu); res = send_simumsg_to_card(sT,TCK_INTERFACE_CONTACT,tpdu,0x00); if (res!=JY_OK) { exit(-1); } if (apdu[i_apdu]!='\0') goto loop; } else { //fprintf(stderr,"APDU(): Unattend byte received 0x%.2X !\n",r_ins); gTPDU[0] = r_ins; free(r_tpdu); res = receive_simumsg_from_card(sT,&r_tpdu,1); if (res!=JY_OK) { exit(-1); } gTPDU[1] = hexa2byte(r_tpdu[0], r_tpdu[1]); gnTPDU = 2; free(r_tpdu); LOG2("TCK","=> receive bytes %.2X%.2X",gTPDU[0],gTPDU[1]); goto extract_err; } } if (lenR==-1) return; /* read the answer */ res = receive_simumsg_from_card(sT,&r_tpdu,lenR+2+((lenR>0)?1:0)); if (res!=JY_OK) { exit(-1); } if (lenR>0) { r_ins = hexa2byte(r_tpdu[0], r_tpdu[1]); if (r_ins!=ins) { fprintf(stderr,"APDU(): Unattend byte received 0x%.2X !\n",r_ins); exit(-1); } LOG3("TCK","receive %c%c %s.",r_tpdu[0],r_tpdu[1],&r_tpdu[2]); gnTPDU = hexa2bytes(gTPDU,&r_tpdu[2]); } else { LOG1("TCK","receive %s.",r_tpdu); gnTPDU = hexa2bytes(gTPDU,r_tpdu);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -