protomac.c

来自「这是用VB6.0写的一个通用的CPU卡操作程序,支持PC/SC接口 安装任何一个」· C语言 代码 · 共 998 行 · 第 1/2 页

C
998
字号
				//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);		}		free(r_tpdu);	} else {		if (block_number==0) {			sprintf(tpdu,"0A01%s",apdu);			block_number = 1;		} else {			sprintf(tpdu,"0B01%s",apdu);			block_number = 0;		}		LOG1("TCK","send %s",apdu);		res = send_simumsg_to_card(sT,gInterface,tpdu,0x00);		if (res!=JY_OK) {			exit(-1);		}		res = receive_simumsg_from_card(sT,&r_tpdu,0);		if (res!=JY_OK) {			exit(-1);		}		strncpy(tpdu,&r_tpdu[4],strlen(r_tpdu)-8);		tpdu[strlen(r_tpdu)-8] = '\0';		LOG1("TCK","receive %s.",tpdu);		gnTPDU = hexa2bytes(gTPDU,tpdu);		free(r_tpdu);	}extract_err:	/* extract SW1SW2 */	sw1 = gTPDU[gnTPDU-2];	sw2 = gTPDU[gnTPDU-1];	sw1sw2 = (((jword)sw1)<<8) | ((jword)sw2);}/* ============================================================================	APDU_RES(char* apdu,jbyte lenR,jword Rsw1sw2)   ========================================================================= */void APDU_RES(char* apdu,jbyte lenR,jword Rsw1sw2){	APDU(apdu,lenR);	if (sw1sw2!=Rsw1sw2) {		fprintf(stderr,"APDU_RES(0x%.4X): Unattended sw1sw2 received 0x%.4X !\n",Rsw1sw2,sw1sw2);		exit(-1);	}}/* ============================================================================	HALTA()   ========================================================================= */void HALTA(void){	char	tpdu[1204];	jresult	res;	strcpy(tpdu,"5000");	LOG1("TCK","send HALTA = %s ",tpdu);	res = send_simumsg_to_card(sT,gInterface,tpdu,0x00);	if (res!=JY_OK) {		exit(-1);	}}/* ============================================================================	REQA()   ========================================================================= */void REQA(void){	char	tpdu[1204];	char*	r_tpdu;	jresult	res;	strcpy(tpdu,"26");	LOG1("TCK","send REQA = %s ",tpdu);	res = send_simumsg_to_card(sT,gInterface,tpdu,0x00);	if (res!=JY_OK) {		exit(-1);	}	res = receive_simumsg_from_card(sT,&r_tpdu,0);	if (res!=JY_OK) {		exit(-1);	}	r_tpdu[4] = 0x00;	LOG1("TCK","receive ATQA %s.",r_tpdu);	free(r_tpdu);}/* ============================================================================	WAKEUPA()   ========================================================================= */void WAKEUPA(void){	char	tpdu[1204];	char*	r_tpdu;	jresult	res;	strcpy(tpdu,"52");	LOG1("TCK","send REQA = %s ",tpdu);	res = send_simumsg_to_card(sT,gInterface,tpdu,0x00);	if (res!=JY_OK) {		exit(-1);	}	res = receive_simumsg_from_card(sT,&r_tpdu,0);	if (res!=JY_OK) {		exit(-1);	}	r_tpdu[4] = 0x00;	LOG1("TCK","receive ATQA %s.",r_tpdu);	free(r_tpdu);}/* ============================================================================	ANTICOLA()   ========================================================================= */void ANTICOLA(void){	char	tpdu[1204];	char*	r_tpdu;	jresult	res;	strcpy(tpdu,"9320");	LOG1("TCK","send ANTICOL = %s ",tpdu);	res = send_simumsg_to_card(sT,gInterface,tpdu,0x00);	if (res!=JY_OK) {		exit(-1);	}	res = receive_simumsg_from_card(sT,&r_tpdu,0);	if (res!=JY_OK) {		exit(-1);	}	r_tpdu[8] = 0x00;	LOG1("TCK","receive UUID %s.",r_tpdu);	hexa2bytes(chip,r_tpdu);	free(r_tpdu);}/* ============================================================================	SELECTA()   ========================================================================= */void SELECTA(void){	char	uuid[1024];	char	tpdu[1204];	char*	r_tpdu;	jresult	res;	bytes2hexa(uuid,chip,4,'\0');	strcpy(tpdu,"9370");	strcat(tpdu,uuid);	LOG1("TCK","send SELECT = %s ",tpdu);	res = send_simumsg_to_card(sT,gInterface,tpdu,0x00);	if (res!=JY_OK) {		exit(-1);	}	res = receive_simumsg_from_card(sT,&r_tpdu,0);	if (res!=JY_OK) {		exit(-1);	}	LOG1("TCK","receive SAK %s.",r_tpdu);	free(r_tpdu);}/* ============================================================================	NACK()   ========================================================================= */void NACK(void){/*	jresult	res; */	LOG("TCK","send NACK = .");	/*	res = send_simumsg_to_card(sT,gInterface,"5000",0x00);	if (res!=JY_OK) {		exit(-1);	}	*/}/* ============================================================================	ACK()   ========================================================================= */void ACK(void){/*	jresult	res; */	LOG("TCK","send ACK = .");	/*	res = send_simumsg_to_card(sT,gInterface,"5000",0x00);	if (res!=JY_OK) {		exit(-1);	}	*/}/* ============================================================================	PPSA()   ========================================================================= */void PPSA(jbyte baud){	char	tpdu[1024];	char*	pps;	jresult	res;	sprintf(tpdu,"D111%.2X",baud|(baud<<2));	LOG2("TCK","send PPS = %s;CID=1, PPS1 present, PPS1= (%d) Kbit/s.",tpdu,baud);	res = send_simumsg_to_card(sT,gInterface,tpdu,0x00);	if (res!=JY_OK) {		exit(-1);	}	res = receive_simumsg_from_card(sT,&pps,0);	if (res!=JY_OK) {		exit(-1);	}	LOG1("TCK","receive PPS Response %s.",pps);	free(pps);}/* ============================================================================	INIT()   ========================================================================= */void INIT(void){	jresult	res;	LOG("TCK","INIT: init socket.");	res = init_socket();	if (res!=JY_OK) {		exit(-1);	}	LOG1("TCK","INIT: connect socket on port %d.",gPort);	res = connect_socket("127.0.0.1",gPort, &sT);	if (res!=JY_OK) {		exit(-1);	}	block_number = 0;}/* ============================================================================	DONE()   ========================================================================= */void DONE(int bExit){	jresult	res;	if (bExit) {		LOG("TCK","send EXIT_SIMULATOR.");		res = send_simumsg_to_card(sT,gInterface,"EXIT_SIMULATOR",0x00);		if (res!=JY_OK) {			exit(-1);		}	} else {		LOG("TCK","send CLOSE_CONNECTION.");		res = send_simumsg_to_card(sT,gInterface,"CLOSE_CONNECTION",0x00);		if (res!=JY_OK) {			exit(-1);		}	}	LOG("TCK","DONE: close socket.");	res = close_socket(sT);	if (res!=JY_OK) {		exit(-1);	}	LOG("TCK","DONE: done socket.");	res = done_socket();	if (res!=JY_OK) {		exit(-1);	}}/* ============================================================================	ATR(is 3B present ?)   ========================================================================= */void ATR(jbool b3B){	char*	atr;	char*	s3b;	char*	slen;	jbyte	blen;	jbyte	len;	jresult	res;	if (b3B) {		res = receive_simumsg_from_card(sT,&s3b,1);		if (res!=JY_OK) {			fprintf(stderr,"error 0x%X receiving 3B from ATR !\n",res);			exit(-1);		}	}	res = receive_simumsg_from_card(sT,&slen,1);	if (res!=JY_OK) {		fprintf(stderr,"error 0x%X receiving len byte from ATR !\n",res);		exit(-1);	}	blen = hexa2byte(slen[0],slen[1]);	len = blen & 0x0F;	if ((blen&0x80)==0x80) len++;	if ((blen&0x40)==0x40) len++;	if ((blen&0x20)==0x20) len++;	if ((blen&0x10)==0x10) len++;	res = receive_simumsg_from_card(sT,&atr,len);	if (res!=JY_OK) {		fprintf(stderr,"error 0x%X receiving next %d bytes from ATR !\n",res,len);		exit(-1);	}	if (b3B) {		LOG7("TCK","receive ATR %s%s%c%c%c%c %s.",s3b,slen,atr[0],atr[1],atr[2],atr[3],&atr[4]);	} else {		LOG6("TCK","receive ATR %s%c%c%c%c %s.",slen,atr[0],atr[1],atr[2],atr[3],&atr[4]);	}	/* decode historicalBytes */	hexa2bytes(historicalBytes,&atr[4]);	HISTORICAL_BYTES();}/* ============================================================================	GETCHALLENGE()   ========================================================================= */void GETCHALLENGE(void){	APDU_RES("0084000008",8,0x9000);}/* ============================================================================	EXTERNALAUTHENTICATE()	bInFile == jtrue	use EF_KEYS to authenticate	bInFile == jfalse	use MSK/PSK to authenticate   ========================================================================= */void EXTERNALAUTHENTICATE(jbyte* key,jbool bInFile,jbyte byKeyNum){	char	chiffre[128];	char	str[128];	if (gnTPDU!=10) {		fprintf(stderr,"EXTERNALAUTHENTICATE(): Hmmm. Don't have my random number (%d) !\n",gnTPDU);		return;	}	memcpy(&u.bBlock[JAYA_BCRYPTO_INPUT0],gTPDU,8);	/* 3DES2(random,MSK|key)		devnote: it is not a good idea to use the same cryptographic source	 	code than the COS to test the external authenticate command. but for		now, we need to go quickly on our roadmap. inKit scripts *will use*		its own cryptographic layer to avoid any potential problem.	*/	BIOS_SETCIPHERALGO(CIPHER_ALGO_ECB_3DES2);	BIOS_SETPADDING(REFDATA_PAD_NOPAD);	if (key==NULL) {		memcpy(&r.bBlock[JAYA_BCRYPTO_KEYCRC],MSK,sizeof(MSK));	} else {		memcpy(&r.bBlock[JAYA_BCRYPTO_KEYA],key,16);	}	BIOS_CIPHER_INIT();	BIOS_CIPHER(gTPDU,8,ENCIPHER);	/* */	bytes2hexa(chiffre,&u.bBlock[JAYA_BCRYPTO_OUTPUT0],8,'\0');	if (bInFile) {        sprintf(str,"008200%.2X08%s",byKeyNum,chiffre);	} else {		sprintf(str,"0082000008%s",chiffre);	}	APDU_RES(str,0,0x9000);}/* ============================================================================    INTERNALAUTHENTICATE()   ========================================================================= */void INTERNALAUTHENTICATE(jbyte* key,jbool bInFile,jbyte byKeyNum){    char    chiffre[128];    char    str[128];    int     i;    jbyte   rando[8];    RANDOM();    memcpy(rando,&u.bBlock[JAYA_BCRYPTO_RANDOM0],8);    bytes2hexa(chiffre,rando,8,'\0');    if (bInFile) {        sprintf(str,"008800%.2X08%s",byKeyNum,chiffre);    } else {        sprintf(str,"0088000008%s",chiffre);    }    APDU_RES(str,0,0x6108);    sprintf(str,"00C0000008");    APDU_RES(str,8,0x9000);    /* 3DES2(random,MSK|key)        devnote: it is not a good idea to use the same cryptographic source        code than the COS to test the external authenticate command. but for        now, we need to go quickly on our roadmap. inKit scripts *will use*        its own cryptographic layer to avoid any potential problem.    */    BIOS_SETCIPHERALGO(CIPHER_ALGO_ECB_3DES2);    BIOS_SETPADDING(REFDATA_PAD_NOPAD);    if (key==NULL) {        memcpy(&r.bBlock[JAYA_BCRYPTO_KEYCRC],MSK,sizeof(MSK));    } else {        memcpy(&r.bBlock[JAYA_BCRYPTO_KEYA],key,16);    }    BIOS_CIPHER_INIT();    BIOS_CIPHER(gTPDU,8,DECIPHER);    for (i=0; i<8;i++) {        if (gTPDU[i] != rando[i]) {            fprintf(stderr,"iauth %d failure 0x%.2X != received 0x%.2X !\n",i,u.bBlock[JAYA_BCRYPTO_RANDOM0+i],gTPDU[i]);            exit(-1);        }    }}/* ============================================================================	That's all folks !   ========================================================================= */

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?