UINT8 ucMakePrinterCmd(UINT8* ucInBuf, UINT32 uiInLen, UINT8* ucOutBuf, UINT32* uiOutLen) { UINT8 ucPrinterKey[20]; UINT32 i; UINT8 ucTmpBuf[1000]; UINT32 uiTmpLen; memset(ucPrinterKey, 0, sizeof(ucPrinterKey)); memset(ucTmpBuf, 0, sizeof(ucTmpBuf)); memcpy(ucPrinterKey, "\xC8\xF0\xC8\xDA\xD0\xC5\xB4\xE5\xB4\xE5\xCD\xA8", 12); ucOutBuf[0] = 0x20; *uiOutLen = 0; uiTmpLen = 0; for (i = 0;i < uiInLen; ++i) { ucTmpBuf[i] = ucInBuf[i] ^ ucPrinterKey[i%12]; ++uiTmpLen; } ucOutBuf[0] = 0x20; bcd_to_asc(ucOutBuf +1, ucTmpBuf, uiTmpLen *2, 0); *uiOutLen = uiTmpLen *2 +1; ucOutBuf[*uiOutLen] = 0x21; (*uiOutLen) += 1; return 0; }
int unionpay_calc_mac( unsigned char *Buf, int Len, unsigned char *MacKey, unsigned char *Mac ) { int i; int nRet; unsigned char mac_tmp[8+1]; unsigned char tmp_str[16+1]; unsigned char tmp[17]; /* 按每8个字节做异或,如果最后不满8个字节, 则添加“0X00” */ memset( mac_tmp, 0, sizeof(mac_tmp) ); XOR( Buf, Len, mac_tmp ); /* 将异或运算后的最后8个字节(RESULT BLOCK)转换成16 个HEXDECIMAL */ memset( tmp_str, 0, sizeof(tmp_str) ); bcd_to_asc( (uchar *)tmp_str, (uchar *)mac_tmp, 16, 0 ); /* 取前8个字节用MAC_KEY加密 */ memset( mac_tmp, 0, sizeof(mac_tmp) ); nRet = HsmCalcMacPid( X99_CALC_MAC, MacKey, tmp_str, 8, mac_tmp ); /* 将加密后的结果与后8个字节异或 */ for( i=0; i<8; i++ ) { mac_tmp[i] ^= tmp_str[8+i]; } /* 用异或的结果TEMP BLOCK再进行一次单倍长密钥算法运算 */ memset( tmp_str, 0, sizeof(tmp_str) ); nRet = HsmCalcMacPid( X99_CALC_MAC, MacKey, mac_tmp, 8, tmp_str ); /* 将运算后的结果(ENC BLOCK2)转换成16个HEXDECIMAL */ memset( tmp, 0, sizeof(tmp) ); bcd_to_asc( (uchar *)tmp, (uchar *)tmp_str, 16, 0 ); /* 取前8个字节作为MAC值 */ memcpy( Mac, tmp, 8 ); return ( SUCC ); }
/* * ��֤�ն����͵�PIN�Ƿ������ݿ��е�PINһ�� * * ��2��: * 1����PIK��PIN���ļ��� * 2�����ն����͵����Ľ��бȽ� * * ���� face->data ���ݿ�����������(8�ֽ�)+�ն�PIN����(8�ֽ�) * ��Ӧ face->data SUCC-һ�� FAIL-��һ�� */ int UphsmVerifyPin(struct interface *face, int nSekPosIndex) { char szInData[1024], szOutData[1024], szPanBlock[17], szEncPin[17]; int nLen, nRet, nSndLen; memset( szPanBlock, '0', 16 ); szPanBlock[16] = 0; nLen = 0; memcpy( szInData, "60", 2 ); /* ���� */ nLen += 2; /* ����PIK�Ĵ洢������Կ���� */ sprintf( szInData+nLen, "S%04ld", nSekPosIndex ); nLen += 5; /* PIK��Կ���ȱ�ʶ��16λ�� */ szInData[nLen] = 'Y'; nLen ++; /* PIK��Կ���� */ bcd_to_asc( (uchar *)(szInData+nLen), (uchar *)(face->pin_key), 32, 0 ); nLen += 32; /* PinBlock��ʽ */ memcpy( szInData+nLen, "01", 2 ); nLen += 2; /* PIN���� */ memcpy( szInData+nLen, "08", 2 ); nLen += 2; memcpy( szInData+nLen, face->data, 8 ); nLen += 8; memcpy( szInData+nLen, "FFFFFFFF", 6 ); nLen += 6; /* �ʺ� */ memcpy( szInData+nLen, szPanBlock, 16 ); nLen += 16; nRet = commu_with_hsm( szInData, nLen, szOutData ); if( nRet == FAIL ) { ErrorLog( ERROR, "commu with hsm fail" ); strcpy( face->return_code, ERR_SYSTEM_ERROR ); return FAIL; } if( memcmp(szOutData, "61", 2) != 0 || memcmp(szOutData+2, "00", 2) != 0 ) { DispUphsmErrorMsg( szOutData+2, face->return_code ); ErrorLog( ERROR, "hsm encrypt pin fail[%2.2s]", szOutData+2 ); return SUCC; } asc_to_bcd( (uchar *)szEncPin, (uchar *)(szOutData+4), 16, 0 ); if( memcmp( face->data+8, szEncPin, 8 ) == 0 ) { strcpy( face->data, "SUCC" ); } else { strcpy( face->data, "FAIL" ); } face->data_len = 4; strcpy( face->return_code, TRANS_SUCC ); return SUCC; }
/* * ��ԴPIN������ԴPIK���ܣ�����PIN��ʽת����Ȼ����Ŀ��PIK��������� * * ���� face->data Դ�ʺ�(16�ֽ�)+��������(8�ֽ�)+Ŀ���ʺ�(16�ֽ�) * ��Ӧ face->data ת���ܺ����������(8�ֽ�) */ int UphsmChangePin(struct interface *face, int nSekPosIndex, int nSekPppIndex) { char szInData[1024], szOutData[1024], szPanBlock[17], szTargetPan[17]; int nLen, nRet, nSndLen; sprintf( szPanBlock, "0000%12.12s", face->data+3 ); szPanBlock[16] = 0; sprintf( szTargetPan, "0000%12.12s", face->data+27 ); szTargetPan[16] = 0; nLen = 0; memcpy( szInData, "P0", 2 ); /* ���� */ nLen += 2; /* ����ԴPIK�Ĵ洢������Կ���� */ sprintf( szInData+nLen, "S%04ld", nSekPosIndex ); nLen += 5; /* ����Ŀ��PIK�Ĵ洢������Կ���� */ sprintf( szInData+nLen, "S%04ld", nSekPppIndex ); nLen += 5; /* ԴPIK��Կ���ȱ�ʶ��16λ�� */ szInData[nLen] = 'Y'; nLen ++; /* ԴPIK��Կ���� */ bcd_to_asc( (uchar *)(szInData+nLen), (uchar *)(face->pin_key), 32, 0 ); nLen += 32; /* Ŀ��PIK��Կ���ȱ�ʶ��16λ�� */ szInData[nLen] = 'Y'; nLen ++; /* Ŀ��PIK��Կ���� */ bcd_to_asc( (uchar *)(szInData+nLen), (uchar *)(face->mac_key), 32, 0 ); nLen += 32; /* ԴPinBlock��ʽ */ memcpy( szInData+nLen, "01", 2 ); nLen += 2; /* Ŀ��PinBlock��ʽ */ memcpy( szInData+nLen, "01", 2 ); nLen += 2; /* ԴPinBlock���� */ bcd_to_asc( (uchar *)(szInData+nLen), (uchar *)(face->data+16), 16, 0 ); nLen += 16; /* Դ�ʺ� */ memcpy( szInData+nLen, szPanBlock, 16 ); nLen += 16; /* Ŀ���ʺ� */ memcpy( szInData+nLen, szTargetPan, 16 ); nLen += 16; debug_disp("UphsmChangePin szInData:", szInData, nLen); nRet = commu_with_hsm( szInData, nLen, szOutData ); if( nRet == FAIL ) { ErrorLog( ERROR, "commu with hsm fail" ); strcpy( face->return_code, ERR_SYSTEM_ERROR ); return FAIL; } debug_disp("UphsmChangePin szOutData:", szOutData, nRet); if( memcmp(szOutData, "P1", 2) != 0 || memcmp(szOutData+2, "00", 2) != 0 ) { DispUphsmErrorMsg( szOutData+2, face->return_code ); ErrorLog( ERROR, "hsm pin change fail[%2.2s]", szOutData+2 ); return SUCC; } asc_to_bcd( (uchar *)(face->data), (uchar *)(szOutData+4), 16, 0 ); face->data_len = 8; strcpy( face->return_code, TRANS_SUCC ); return SUCC; }
/* * ��ANSI X9.9 MAC�㷨��������MAC�� * * ���� face->data ����MAC��������ݣ�������data_lenָ�� * ��Ӧ face->data MAC(8�ֽ�) */ int UphsmCalcMac(struct interface *face, int nSekIndex) { char szInData[2048], szOutData[2048]; int nLen, nRet, nSndLen; nLen = 0; memcpy( szInData, "M0", 2 ); /* ���� */ nLen += 2; /* MAC�㷨 1-XOR 2-X9.9 3-X9.19 */ if( face->alog == X99_CALC_MAC ) { szInData[nLen] = '2'; } else if( face->alog == XOR_CALC_MAC ) { szInData[nLen] = '1'; } else { szInData[nLen] = '3'; } nLen += 1; sprintf( szInData+nLen, "S%04ld", nSekIndex ); /* ������Կ���� */ nLen += 5; szInData[nLen] = 'Y'; /* ��Կ���ȱ�ʶ��16λ�� */ nLen ++; bcd_to_asc( (uchar *)(szInData+nLen), (uchar *)(face->mac_key), 32, 0 ); /*MAC��Կ����*/ nLen += 32; sprintf( szInData+nLen, "%04ld", face->data_len ); nLen += 4; memcpy( szInData+nLen, face->data, face->data_len ); nLen += face->data_len; nRet = commu_with_hsm( szInData, nLen, szOutData ); if( nRet == FAIL ) { ErrorLog( ERROR, "commu with hsm fail" ); strcpy( face->return_code, ERR_SYSTEM_ERROR ); return FAIL; } if( memcmp(szOutData, "M1", 2) != 0 || memcmp(szOutData+2, "00", 2) != 0 ) { DispUphsmErrorMsg( szOutData+2, face->return_code ); ErrorLog( ERROR, "hsm calc mac fail[%2.2s]", szOutData+2 ); return SUCC; } asc_to_bcd( (uchar *)(face->data), (uchar *)(szOutData+4), 16, 0 ); face->data_len = 8; strcpy( face->return_code, TRANS_SUCC ); return SUCC; }
/********************* ***转换外部消息内容*** *********************/ int MessOutToIn(unsigned char *sMess, TXN_MSG_DTL *pstMsgDtl ) { unsigned char sTmp[16]; unsigned char sTmp2[16]; unsigned char cFlwCd[6]; unsigned char sBuf[256]; int i, j, iTmp; int iLen , iCnt; int iMacFlg; /*MAC标志*/ iMacFlg = 0; /*报文类型*/ i = 0; memset(sTmp, 0, sizeof(sTmp)); memcpy(sTmp, sMess, 1 ); Hex2Str(sTmp, pstMsgDtl->sMsqType, 1 ); i += 1; HtLog(gsLogFile, HT_LOG_MODE_ERROR, __FILE__, __LINE__, "报文类型[%2.2s]", pstMsgDtl->sMsqType ); /*结束标志*/ memcpy(sTmp, sMess+i, 1 ); sprintf((char *)pstMsgDtl->sEndFlg, "%02d", sTmp[0] ); i += 1; HtLog(gsLogFile, HT_LOG_MODE_ERROR, __FILE__, __LINE__, "结束标志[%2.2s]", pstMsgDtl->sEndFlg ); /**程序版本号*/ memset(sTmp, 0, sizeof(sTmp)); memcpy(sTmp, sMess+i, 2 ); bcd_to_asc(pstMsgDtl->sProVer, sTmp, 4, 1 ); i += 2; HtLog(gsLogFile, HT_LOG_MODE_ERROR, __FILE__, __LINE__, "程序版本号[%4.4s]", pstMsgDtl->sProVer ); /**应用版本号**/ memset(sTmp, 0, sizeof(sTmp)); memcpy(sTmp, sMess+i, 4 ); bcd_to_asc(pstMsgDtl->sAppVer, sTmp, 8, 1 ); i += 4; HtLog(gsLogFile, HT_LOG_MODE_ERROR, __FILE__, __LINE__, "应用版本号[%8.8s]", pstMsgDtl->sAppVer ); /**来电显示标志**/ memset(sTmp, 0, sizeof(sTmp)); memcpy(sTmp, sMess+i, 1 ); sprintf((char *)pstMsgDtl->sShowFlg, "%02s", sTmp ); i += 1; HtLog(gsLogFile, HT_LOG_MODE_ERROR, __FILE__, __LINE__, "来电显示标志[%2.2s]", pstMsgDtl->sShowFlg ); /**序列号**/ memset(sTmp, 0, sizeof(sTmp)); memcpy(sTmp, sMess+i, 8 ); bcd_to_asc(pstMsgDtl->sTsamNo, sTmp, 16, 1 ); i += 8; HtLog(gsLogFile, HT_LOG_MODE_ERROR, __FILE__, __LINE__, "序列号[%16.16s]", pstMsgDtl->sTsamNo ); /**交易流水号**/ memset(sTmp, 0, sizeof(sTmp)); memcpy(sTmp, sMess+i, 3 ); bcd_to_asc(pstMsgDtl->sTxnSeq, sTmp, 6, 1 ); i += 3; HtLog(gsLogFile, HT_LOG_MODE_ERROR, __FILE__, __LINE__, "交易流水号[%6.6s]", pstMsgDtl->sTxnSeq ); /**交易代码**/ memcpy(pstMsgDtl->sTxnCode, sMess+i, 3 ); i += 3; HtLog(gsLogFile, HT_LOG_MODE_ERROR, __FILE__, __LINE__, "交易代码[%3.3s]", pstMsgDtl->sTxnCode ); /*流程代码总数*/ memset(sTmp, 0, sizeof(sTmp)); memcpy(sTmp, sMess+i, 1 ); iCnt = sTmp[0]; sprintf((char *)pstMsgDtl->sFlowNum , "%02X", iCnt ); i += 1; HtLog(gsLogFile, HT_LOG_MODE_ERROR, __FILE__, __LINE__, "流程代码总数[%2.2s]", pstMsgDtl->sFlowNum ); /*流程代码集*/ iLen = 0; memset(sBuf, 0, sizeof(sBuf)); for(j=0; j < iCnt; j ++ ) { iTmp = 0; memset(sTmp, 0, sizeof(sTmp)); memset(sTmp2, 0, sizeof(sTmp2)); memset(cFlwCd, 0, sizeof(cFlwCd)); memcpy(sTmp, sMess+i, 1 ); HtLog(gsLogFile, HT_LOG_MODE_ERROR, __FILE__, __LINE__, "流程代码第1个字节[%X]", sTmp[0] ); sTmp[0] = sTmp[0] >> 6; if(sTmp[0] == 0x03 ) { /*3字节操作码*/ memcpy(sTmp2, sMess+i, 3 ); Hex2Str(sTmp2, cFlwCd, 3 ); memcpy(sBuf+iLen, cFlwCd, 6 ); i = i + 3; iLen = iLen + 6; /*判断是否有MAC*/ if(memcmp(cFlwCd, "CD", 2 ) == 0 ) iMacFlg = 1; } else if(sTmp[0] == 0x00 ) { /*双字节操作码*/ memcpy(sTmp2, sMess+i, 2 ); Hex2Str(sTmp2, cFlwCd, 2 ); memcpy(sBuf+iLen, cFlwCd, 4 ); i = i + 2; iLen = iLen + 4; /*判断是否有MAC*/ if(memcmp(cFlwCd, "0D", 2 ) == 0 ) iMacFlg = 1; } else { /*单字节码*/ memcpy(sTmp2, sMess+i, 1 ); Hex2Str(sTmp2, cFlwCd, 1 ); memcpy(sBuf+iLen, cFlwCd, 2 ); i = i + 1; iLen = iLen + 2; /*判断是否有MAC*/ if(memcmp(cFlwCd, "8D", 2 ) == 0 ) iMacFlg = 1; } } if(iLen > 128 ) { HtLog(gsLogFile, HT_LOG_MODE_DEBUG, __FILE__, __LINE__, "流程代码超长" ); return -1; } memcpy(pstMsgDtl->sFlowCode, sBuf, iLen ); HtLog(gsLogFile, HT_LOG_MODE_ERROR, __FILE__, __LINE__, "流程代码[%128.128s]", pstMsgDtl->sFlowCode ); /**有效数据长度**/ memset(sTmp, 0, sizeof(sTmp)); memcpy(sTmp, sMess+i, 2 ); i += 2; iLen = sTmp[0]*256 + sTmp[1]; /*sprintf((char *)pstMsgDtl->sDataLen[0], "%04X", iLen ); */ sprintf((char *)&pstMsgDtl->sDataLen[0], "%04X", iLen ); HtLog(gsLogFile, HT_LOG_MODE_ERROR, __FILE__, __LINE__, "有效数据长度[%d] 报文当前位置[%d]", iLen, i ); /**有效数据,不包括MAC**/ if((iLen < 8 )&&(iMacFlg == 1)) { HtLog(gsLogFile, HT_LOG_MODE_ERROR, __FILE__, __LINE__, "报文不正确" ); return -1; } /* HtDebugString (gsLogFile, HT_LOG_MODE_DEBUG, __FILE__, __LINE__, (char *)(sMess+i) , iLen);*/ if(iMacFlg == 1 ) { memcpy(pstMsgDtl->sDataDtl, sMess+i, (iLen - 8)); i += (iLen - 8 ); /**取MAC**/ memcpy(pstMsgDtl->sMac, sMess+i, 8 ); } else { memcpy(pstMsgDtl->sDataDtl, sMess+i, iLen ); i += iLen ; /**没有MAC**/ memcpy(pstMsgDtl->sMac, "00000000", 8 ); } HtLog(gsLogFile, HT_LOG_MODE_DEBUG, __FILE__, __LINE__, "有效数据:" ); /* HtDebugString (gsLogFile, HT_LOG_MODE_DEBUG, __FILE__, __LINE__, (char *)pstMsgDtl->sDataDtl, iLen );*/ return 0; }