/** \brief * 计算mab * \param in: pData TRADEDATA结构指针 * \param in: obj8583 8583包 * \param out: bMac 8字节 * \return 失败返回非0,成功返回0 */ int CTradeBase::GenMacData( TRADEDATA * pData,BYTE* bMabTmp,int bMabLen,BYTE* bMac) { int nLenMab=0,nLen=0; int inum = 0; BYTE bMak[17]={0},bTmp[8]={0},bOut[8]={0},bMakTemp[8+1] = {0}; BYTE bMab[1024],temp1[32] = {0},temp2[32] = {0}; //nLenMab=BuildMab(obj8583,bMab); nLenMab = bMabLen; memcpy(bMab,bMabTmp,bMabLen); trace_log(DBG, "bMab,pData->RcvBrchCode:%s,pData->SndBrchCode:%s",pData->RcvBrchCode,pData->SndBrchCode); trace_mem(bMabTmp, bMabLen); if(bSoftEncrypt) { /**< 软计算 */ nLen=8*((nLenMab+7)/8); for(int i=nLenMab;i<nLen;i++) bMab[i]=0x00; inum = nLen/8; Ccommon::Asc2Bcd((char *)pData->bMacKey,bMak, 32); memcpy(bMakTemp,bMak,8); memcpy(bTmp,bMab,8); for(int j = 1;j<inum;j++) { memset(bOut,0,8); memcpy(bOut,bMab+j*8,8); Ccommon::ExclusiveOR(bTmp,bOut,bTmp,8); } BcdToAsc(temp1, bTmp, 16); memcpy(temp2,temp1,8); memset(bTmp,0x00,sizeof(bTmp)); des.DesEncrypt(ENCRYPT, temp2, bMakTemp, bTmp); Ccommon::ExclusiveOR(bTmp,bTmp,temp1+8,8); memset(temp1,0x00,sizeof(temp1)); des.DesEncrypt(ENCRYPT, bTmp, bMakTemp, temp1); BcdToAsc(temp2, temp1, 16); memcpy(bMac,temp2,8); }else{ /**< 硬计算 */ if(!cryptComm.CalculateMac(pData->RcvBrchCode, pData->SndBrchCode,bMab, nLenMab,bMac)) { trace_log(ERR, "Get mac failed!"); return RET_PACK; } } return 0; }
/* 主函数 */ int main(void) { int icomp = 0; char szKeyText[100]; int i; /* 选择密钥长度(单倍长、双倍长) */ iKeyLen = setKeyArgu(PrtKEYLTMenu) * 16; /* 选择密钥分量数(一个分量、两个分量、三个分量) */ iComponent = setKeyArgu(PrtKeyCompMenu); /* 根据密钥长度及分量数读取分量并合成密钥 */ memset(uszaKeyComp, 0, sizeof(uszaKeyComp)); while (icomp < iComponent) { setKeyComp(icomp, uszaKeyComp); icomp++; } memset(szKeyText, 0, sizeof(szKeyText)); BcdToAsc(uszaKeyComp, iKeyLen, 0, szKeyText); /* 保存密钥 */ PrtSaveComHead(); if (SaveMasterKey(szKeyText, iKeyLen) != FAIL) { printf(SAVECOM_SUCC); } else { printf(SAVECOM_SUCC); } }
/************************************************************************ 函数功能:CalculateMac(计算mac)--快钱 参数说明: cRcvCode[in] 受理机构号 cSndCode[in] 接入机构号 ucMab[in] 用于mac签名的数据 iMabLen[in] 数据长度 ucMac[out] mac值 返回值: true 成功,false 失败 ************************************************************************/ bool EnCryptComm::CalculateMac(char * cMercId, char * cTermId, const unsigned char * ucMab, int iMabLen, unsigned char * ucMac,int nFlag) { unsigned char ucTmpMab[1024]={0}; memcpy(ucTmpMab, ucMab, iMabLen); int nMabLen = (iMabLen+7)/8*8; for(int i = iMabLen; i < nMabLen; i++) ucTmpMab[i] = 0x00; unsigned char Buffer[1024*2]={0}; unsigned vLen = 0; /**< CMD */ if(1==nFlag) { Buffer[vLen++] = 0x68; } else { Buffer[vLen++] = 0x61; } Buffer[vLen++] =1; /**< 受理机构号 */ memset(&Buffer[vLen], ' ', 20); memcpy((char*)&Buffer[vLen], cMercId, strlen(cMercId)); vLen += 20; /**< 接入机构号 */ memset(&Buffer[vLen], ' ', 16); memcpy((char*)&Buffer[vLen], cTermId, strlen(cTermId)); vLen += 16; /**< MAC计算方式*/ memset(&Buffer[vLen], 0x01, 1); vLen += 1; /**< 初始向量*/ memset(&Buffer[vLen], 0x00, 8); vLen += 8; /**< MAB */ Buffer[vLen++] = nMabLen/256; Buffer[vLen++] = nMabLen%256; memcpy((char*)&Buffer[vLen], ucTmpMab, nMabLen); vLen += nMabLen; if(!GetDataFromHsm(Buffer, vLen)) { trace_log(ERR, "DesMac call GetDataFromHsm return false."); return false; } unsigned char ucMacTmp[9]={0}; memcpy(ucMacTmp, Buffer+LEN_MER_TERM+3, 4);/**< 取前4个字节 */ BcdToAsc(ucMac,ucMacTmp,4); trace_log(DBG,"CalculateMac ucMac LEN=%d",8); trace_mem(ucMac,8); return true; }
/***************************************************************** ** 功 能:从TLV格式数据中获取Value值 ** 输入参数: ** szBuf TLV格式数据 ** iLen Value值占用字节数 ** iValueType Value类型,说明参考_set_value函数参数说明 ** 输出参数: ** szValueBuf 存放Value值Buf ** 返 回 值: ** >0 Value长度 ** -1 读取失败 ** 作 者: ** fengwei ** 日 期: ** 2012/09/24 ** 调用说明: ** 仅供tlv库函数内部调用,外部不调用 ** 修改日志: ****************************************************************/ int _get_value(char* szBuf, int iLen, int iValueType, char* szValueBuf) { int iValueLen; switch(iValueType) { case VALUE_NORMAL: memcpy(szValueBuf, szBuf, iLen); iValueLen = iLen; break; case VALUE_BCD_RIGHT: BcdToAsc(szBuf, iLen, 1, szValueBuf); if(iLen%2 == 0) { iValueLen = iLen/2; } else { iValueLen = iLen/2 + 1; } break; case VALUE_BCD_LEFT: BcdToAsc(szBuf, iLen, 0, szValueBuf); if(iLen%2 == 0) { iValueLen = iLen/2; } else { iValueLen = iLen/2 + 1; } break; default: iValueLen = -1; break; } return iValueLen; }
/* ---------------------------------------------------------------- * 功 能:密码明文还原 * 输入参数:uszValuse 被账号异或后的密码 * szPan 账号 * 输出参数:uszResult 密码明文 * 返 回 值:SUCC 成功 FAIL 失败 * 作 者: * 日 期: * 调用说明: * 修改日志:修改日期 修改者 修改内容简述 * ---------------------------------------------------------------- */ int _A_(unsigned char *uszValue, char *szPan, unsigned char *uszResult) { unsigned char tmp[17], tmp1[17], passwd0[17]; int i, len; memcpy(tmp, szPan + 3, 13); for (i = 0; i < 13; i++) { if (tmp[i] < '0' || tmp[i] > '9') { tmp[i] = 'F'; } } AscToBcd(tmp, 12, 0, tmp1); tmp[0] = uszValue[0]; tmp[1] = uszValue[1]; for (i = 0; i < 6; i++) { tmp[i+2] = uszValue[2+i]^tmp1[i]; } BcdToAsc(tmp, 16, 0, passwd0); memcpy((char *) tmp1, (char *)passwd0, 2); tmp1[2] = '\0'; len = atoi (tmp1); if (len > 8) { return FAIL; } memcpy((char *)uszResult, (char *)passwd0 + 2, len); uszResult[len] = '\0'; return SUCC; }
/* ---------------------------------------------------------------- * 功 能:TLV库Debug函数 * 输入参数:pTLV TLV格式数据 * 输出参数:无 * 返 回 值:无 * 作 者:fengwei * 日 期:2012-9-24 * 调用说明:DebugTLV(pTLV) * 修改日志:修改日期 修改者 修改内容简述 * * ---------------------------------------------------------------- */ void DebugTLV(T_TLVStru *pTLV) { int i,j; int iTagLen; T_TLVData *pData; char szTagBuf[64+1]; char szValueBuf[MAX_VALUE_LEN*2+1]; if (pTLV == NULL) { return; } for (i=0; i<MAX_TLV_NUM; i++) { pData = pTLV->tTLVData + i; memset(szTagBuf, 0, sizeof(szTagBuf)); memset(szValueBuf, 0, sizeof(szValueBuf)); if (pData->iFlag == DATA_NOTNULL) { iTagLen = _calc_tag_len(pData->szTag, pTLV->iTagType); for (j=0;j<iTagLen;j++) { sprintf(szTagBuf+j*4, "0x%02x", pData->szTag[j]); } BcdToAsc(pData->szValue, pData->iLen*2, LEFT_ALIGN, szValueBuf); WriteLog(TRACE, "TLV:[%d] Tag:[%s] Len:[%d] Value:[%s]", i, szTagBuf, pData->iLen, szValueBuf); } /*if*/ } /*for*/ return; }
int CTradeConsume::DoPack(SAConnection *saConn, void * pNode,unsigned char * pBuffer, unsigned & iBufLen) { if(saConn == NULL || pNode == NULL || pBuffer == NULL) { trace_log(ERR, "Paramter error!"); return RET_SYSEXP; } trace_log(DBG,"-----Consume-----"); TRADEDATA * pData = (TRADEDATA *)pNode; int nTlvLen=0; char cICCID[4]={0},cICData[256]={0}; CTLVTemplet tlvObj; if(1 != tlvObj.UnPackTLVData(pData->TransData.TlvDataLen, pData->TransData.TlvData)) { trace_log(ERR, "UnPackTLVData fail!"); return RET_SYSEXP; } bool bFlag = true; bool bHasPin = false, bHasTrack = false; //0消息类型 bFlag &= sndObj.SetValueByStr(0 , "0200"); if(!bFlag) { trace_log(ERR, "Pack right CUPS8583 fail!"); return RET_PACK; } //2账号 bFlag &= sndObj.SetValueByStr(2 ,pData->TransData.HeadData.Account ); trace_log(DBG,"pData->TransData.HeadData.Account2:%s",pData->TransData.HeadData.Account); if(!bFlag) { trace_log(ERR, "Pack right CUPS8583 fail!"); return RET_PACK; } //3处理码 bFlag &= sndObj.SetValueByStr(3 , "190000"); if(!bFlag) { trace_log(ERR, "Pack right CUPS8583 fail!"); return RET_PACK; } //4交易金额 bFlag &= sndObj.SetValueByStr(4 , pData->TransData.HeadData.ReqAmount); if(!bFlag) { trace_log(ERR, "Pack right CUPS8583 fail!"); return RET_PACK; } //7交易金额 bFlag &= sndObj.SetValueByHex(7 ,(unsigned char*) (pData->cDateTime+4),10); if(!bFlag) { trace_log(ERR, "Pack right CUPS8583 fail!"); return RET_PACK; } //11流水号 bFlag &= sndObj.SetValueByStr(11, pData->VouchNo); if(!bFlag) { trace_log(ERR, "Pack right CUPS8583 fail!"); return RET_PACK; } //本地交易时间 bFlag &= sndObj.SetValueByHex(12,(unsigned char*) (pData->cDateTime+8),6); //本地交易日期 bFlag &= sndObj.SetValueByHex(13, (unsigned char*) (pData->cDateTime+4),4); //F22服务点输入码 bFlag &= sndObj.SetValueByStr(22,(char *)pData->TransData.HeadData.SvrPointCode );//"022" if(!bFlag) { trace_log(ERR, "Pack right CUPS8583 fail!"); return RET_PACK; } //F23 卡片序列号 nTlvLen= tlvObj.GetTLVItemByHex(TAG_ICCID, (BYTE *)cICCID, sizeof(cICCID)); if(nTlvLen>0) { char cICNO[5]={0}; BcdToAsc((BYTE *)cICNO,(BYTE *)cICCID,nTlvLen); bFlag &= sndObj.SetValueByStr(23, cICNO+1); if(!bFlag) { trace_log(ERR, "Pack right CUPS8583 fail!"); return RET_PACK; } } //F25 服务点条件码 bFlag &= sndObj.SetValueByStr(25, "82"); if(!bFlag) { trace_log(ERR, "Pack right CUPS8583 fail!"); return RET_PACK; } //F26 服务点PIN获取码 if('1'==pData->TransData.HeadData.SvrPointCode[2]) { bFlag &= sndObj.SetValueByStr(26, "12"); if(!bFlag) { trace_log(ERR, "Pack right CUPS8583 fail!"); return RET_PACK; } } //F32 受理机构标识码 bFlag &= sndObj.SetValueByStr(32, pData->RcvBrchCode); if(!bFlag) { trace_log(ERR, "Pack right CUPS8583 fail!"); return RET_PACK; } //F33 发送机构标识码 bFlag &= sndObj.SetValueByStr(33, pData->SndBrchCode); if(!bFlag) { trace_log(ERR, "Pack right CUPS8583 fail!"); return RET_PACK; } /**< 磁道处理*/ if(SetTrack(pData, tlvObj, bHasTrack)!=0) { trace_log(ERR, "SetTrack faile"); return -1; }else{ trace_log(DBG, "SetTrack SUCCESS"); } //F37 检索参考号 bFlag &= sndObj.SetValueByStr(37, pData->cReference); if(!bFlag) { trace_log(ERR, "Pack right CUPS8583 fail!"); return RET_PACK; } //41终端号 bFlag &= sndObj.SetValueByStr(41, pData->TransData.HeadData.arrRTermNo); if(!bFlag) { trace_log(ERR, "Pack right CUPS8583 fail!"); return RET_PACK; } //42商户号 bFlag &= sndObj.SetValueByStr(42,pData->TransData.HeadData.arrRMerchNo); if(!bFlag) { trace_log(ERR, "Pack right CUPS8583 fail!"); return RET_PACK; } //43受卡方名称地址 char cDest[41]={0}; GBK2UTF8(pData->TransData.HeadData.RPrintMerName,cDest); bFlag &= sndObj.SetValueByStr(43, cDest);//"ME31S" if(!bFlag) { trace_log(ERR, "Pack right CUPS8583 fail!"); return RET_PACK; } //49货币代码 bFlag &= sndObj.SetValueByStr(49, "156"); if(!bFlag) { trace_log(ERR, "Pack right CUPS8583 fail!"); return RET_PACK; } /**< 52密码*/ trace_log(DBG,"pData->TransData.HeadData.Account3:%s",pData->TransData.HeadData.Account); if(SetPinKey(pData, tlvObj, bHasPin)!=0) { trace_log(ERR, "SetPinKey faile"); return -1; }else{ trace_log(DBG, "SetPinKey SUCCESS"); } //53安全控制信息 bFlag &= sndObj.SetValueByStr(53, "2600000000000000"); if(!bFlag) { trace_log(ERR, "Pack right CUPS8583 fail!"); return RET_PACK; } //55 C卡数据域 nTlvLen= tlvObj.GetTLVItemByHex(TAG_FIELD55_RSP, (BYTE *)cICData, sizeof(cICData)); if(nTlvLen>0) { bFlag &= sndObj.SetValueByHex(55, (BYTE *)cICData,nTlvLen); if(!bFlag) { trace_log(ERR, "Pack right CUPS8583 fail!"); return RET_PACK; } } //128MAC bFlag &= sndObj.SetValueByHex(128, (unsigned char*)"00000000", 8); if(!bFlag) { trace_log(ERR, "Pack right CUPS8583 fail!"); return RET_PACK; } /**< 组包*/ iBufLen = PACK_MAXLEN; bFlag &= sndObj.Pack(pBuffer, iBufLen); if(!bFlag) { trace_log(ERR, "Pack right CUPS8583 fail!"); return RET_PACK; } trace_log(DBG,"sndObj.Pack:"); trace_mem(pBuffer, iBufLen); /**< 计算Mac */ BYTE bMac[9] = {0}; int nMacLen = 8; if(0!=GenMacData(pData,sndObj,bMac)) { return RET_GETMACERR; } memcpy(pBuffer + iBufLen -nMacLen, bMac, nMacLen); return RET_SUCCESS; }
/***************************************************************** ** 功 能:验证终端上送的PIN是否与数据库中的PIN一致 分2步: 1、用PIK对PIN明文加密 2、与终端上送的密文进行比较 ** 输入参数: tInterface->szData 数据库中密码明文(8字节)+终端PIN密文(8字节) iSekPosIndex 加密PIK的存储加密密钥索引 ** 输出参数: tInterface->szData SUCC-一致 FAIL-不一致 ** 返 回 值: 成功 - SUCC 失败 - FAIL ** 作 者:Robin ** 日 期:2009/08/25 ** 调用说明: ** 修改日志:mod by wukj 20121031规范命名及排版修订 ** ****************************************************************/ int Sjl06sVerifyPin(T_Interface *tInterface, int iSekPosIndex) { char szInData[1024], szOutData[1024], szPanBlock[17], szEncPin[17]; int iLen, iRet, iSndLen; memset( szPanBlock, '0', 16 ); szPanBlock[16] = 0; iLen = 0; memcpy( szInData, "XI", 2 ); /* 命令 */ iLen += 2; /*PIN类型 ANSIX9.8算法*/ memcpy( szInData+iLen, "3", 1 ); iLen += 1; /* 加密PIK的存储加密密钥索引 */ sprintf( szInData+iLen, "%03ld", iSekPosIndex ); iLen += 3; /* PIK密钥密文 */ BcdToAsc( (uchar *)(tInterface->szPinKey), 32, 0 , (uchar *)(szInData+iLen)); iLen += 32; /* PIN明文 */ memcpy( szInData+iLen, "08", 2 ); iLen += 2; memcpy( szInData+iLen, tInterface->szData, 8 ); iLen += 8; memcpy( szInData+iLen, "FFFFFFFF", 6 ); iLen += 6; /* 帐号 */ memcpy( szInData+iLen, szPanBlock, 16 ); iLen += 16; iRet = CommuWithHsm( szInData, iLen, szOutData ); if( iRet == FAIL ) { WriteLog( ERROR, "commu with hsm fail" ); strcpy( tInterface->szReturnCode, ERR_SYSTEM_ERROR ); return FAIL; } if( memcmp(szOutData, "E", 1) == 0 ) { DispUphsmErrorMsg( szOutData+1, tInterface->szReturnCode ); WriteLog( ERROR, "hsm encrypt pin fail[%2.2s]", szOutData+1 ); return SUCC; } else if(memcmp(szOutData, "A", 1) == 0 ) { AscToBcd( (uchar *)(szOutData+1), 16, 0 ,(uchar *)szEncPin); if( memcmp( tInterface->szData+8, szEncPin, 8 ) == 0 ) { strcpy( tInterface->szData, "SUCC" ); } else { strcpy( tInterface->szData, "FAIL" ); } tInterface->iDataLen = 4; strcpy( tInterface->szReturnCode, TRANS_SUCC ); } return SUCC; }
int CTradeRepeal::DoPack(SAConnection *saConn, void * pNode, unsigned char * pBuffer, unsigned & iBufLen) { if(saConn == NULL || pNode == NULL || pBuffer == NULL) { trace_log(ERR, "Paramter error!"); return RET_SYSEXP; } trace_log(DBG,"-----Repeal-----"); TRADEDATA * pData = (TRADEDATA *)pNode; int nTlvLen=0; char cICCID[4]={0},cLField61[20]={0},cICData[256]={0}; CTLVTemplet tlvObj; if(1 != tlvObj.UnPackTLVData(pData->TransData.TlvDataLen, pData->TransData.TlvData)) { trace_log(ERR, "UnPackTLVData fail!"); return RET_SYSEXP; } bool bFlag = true; bool bHasPin = false, bHasTrack = false; //0消息类型 bFlag &= sndObj.SetValueByStr(0 , "0200"); //2账号 bFlag &= sndObj.SetValueByStr(2 , pData->TransData.HeadData.Account); //3处理码 bFlag &= sndObj.SetValueByStr(3 , "280000"); //4交易金额 bFlag &= sndObj.SetValueByStr(4 , pData->TransData.HeadData.ReqAmount); //11流水号 bFlag &= sndObj.SetValueByStr(11, pData->VouchNo); /**< 22服务点输入方式码*/ bFlag &= sndObj.SetValueByStr(22,(char*)pData->TransData.HeadData.SvrPointCode); //F23 卡片序列号 nTlvLen= tlvObj.GetTLVItemByHex(TAG_ICCID, (BYTE *)cICCID, sizeof(cICCID)); if(nTlvLen>0) { char cICNO[5]={0}; BcdToAsc((BYTE *)cICNO,(BYTE *)cICCID,nTlvLen); bFlag &= sndObj.SetValueByStr(23, cICNO+1); } //25服务点条件码 bFlag &= sndObj.SetValueByStr(25,"82"); // 35 36磁道处理 if(SetTrack(pData,tlvObj,bHasTrack)!=0) { trace_log(ERR, "SetTrack faile"); return -1; } trace_log(DBG, "SetTrack SUCCESS"); //37参考号 bFlag &= sndObj.SetValueByStr(37, pData->TransData.HeadData.SysRefNo); //41终端号 bFlag &= sndObj.SetValueByStr(41, pData->TransData.HeadData.arrRTermNo); //42商户号 bFlag &= sndObj.SetValueByStr(42, pData->TransData.HeadData.arrRMerchNo); //49货币代码 bFlag &= sndObj.SetValueByStr(49, "156"); // 52 53密码 安全信息控制 trace_log(DBG, "pData->TransData.HeadData.SvrPointCode[2]==%c",pData->TransData.HeadData.SvrPointCode[2]); if(0==memcmp((char *)&(pData->TransData.HeadData.SvrPointCode[2]),"1",1)) { if(SetPinKey(pData, tlvObj, bHasPin)!=0) { trace_log(ERR, "SetPinKey faile"); return -1; } trace_log(DBG, "SetPinKey SUCCESS"); //53安全控制信息 bFlag &= sndObj.SetValueByStr(53, "2600000000000000"); //26服务点PIN获取码 该域描述了服务点设备所能接受的PIN所能容纳的最多字符数 bFlag &= sndObj.SetValueByStr(26, "06"); } trace_log(DBG, "SetPinKey SUCCESS"); /* bool bIC = false; ///55 IC卡数据域 nTlvLen= tlvObj.GetTLVItemByHex(TAG_FIELD55_RSP, (BYTE *)cICData, sizeof(cICData)); if(nTlvLen>0) { bFlag &= sndObj.SetValueByHex(55, (BYTE *)cICData,nTlvLen); bIC=true; } else { char cTrace[128]={0}; tlvObj.GetTLVItemByHex(TAG_TRACK2,(unsigned char*) cTrace, sizeof(cTrace)); int i=0; for(i=0;i<strlen(cTrace);i++) { if(0==memcmp(cTrace+i,"D",1)) { if((0==memcmp(cTrace+i+5,"2",1)||0==memcmp(cTrace+i+5,"6",1))) { memcpy(pData->TransData.HeadData.RspCode,"45",2); strcpy(pData->TransData.HeadData.RspDecs,"不允许降级交易"); return RET_PACK; }else{ break; } } } } */ //60 域 BYTE F60[101]={0}; int iLen=0; memcpy(F60,"22",2); //—— 60.1 消息类型码 N2 iLen+=2; memcpy(F60+iLen,pData->BatchNo,6); //—— 60.2 批次号 N6 iLen+=6; memcpy(F60+iLen,"000",3); //—— 60.3 网络管理信息码 N3 iLen+=3; memcpy(F60+iLen,"0",1); //—— 60.4 保留 N2 iLen+=1; memcpy(F60+iLen,"00",2); //—— 60.6 支持部分扣款和返回余额标志 N1 iLen+=2; memcpy(F60+iLen,"5",1); //—— 60.6 终端读取能力 N1 iLen+=1; memcpy(F60+iLen,"0",1); //—— 60.7 基于PBOC借/贷记标准的IC卡条件代码 N1 iLen+=1; bFlag &=sndObj.SetValueByStr(60,(char *)F60); //61自定义域 char cOri_Date[4]; memset(cLField61,0x00,sizeof(cLField61)); strcpy((char *)cLField61,(char *)pData->TransData.HeadData.OrigLBatchNo); strcat((char *)cLField61,(char *)pData->TransData.HeadData.OrigLPosSeq); memcpy(cOri_Date,pData->cOri_DateTime,4); trace_log(DBG,"cOri_Date=%s",cOri_Date); strcat((char *)cLField61,(char *)cOri_Date); bFlag &= sndObj.SetValueByStr(61, (char *)cLField61); //64MAC bFlag &= sndObj.SetValueByHex(64, (unsigned char*)"00000000", 8); /**< 组包*/ iBufLen = PACK_MAXLEN; if(!sndObj.Pack(pBuffer, iBufLen)) { trace_log(ERR, "Pack right CUPS8583 fail!"); return RET_PACK; } /**< 计算Mac */ BYTE bMac[9] = {0}; int nMacLen = 8; BYTE bMab[512] = {0}; memcpy(bMab,pBuffer+13,iBufLen-13-nMacLen); if(GenMacData(pData,bMab,iBufLen-13-nMacLen,bMac)) { return RET_GETMACERR; } memcpy(pBuffer + iBufLen -nMacLen, bMac, nMacLen); return RET_SUCCESS; }
/***************************************************************** ** 功 能: 验证终端上送的PIN是否与数据库中的PIN一致 分3步: 1、用LMK对PIN明文加密,得szLmkEncPin1 2、将终端PIN密文从TPK翻译到LMK,得szLmkEncPin2 3、比较szLmkEncPin1 szLmkEncPin2 ** 输入参数: tInterface->szData 数据库中密码明文(8字节)+终端PIN密文(8字节) ** 输出参数: tInterface->szData SUCC-一致 FAIL-不一致 ** 返 回 值: 成功 - SUCC 失败 - FAIL ** 作 者: ** 日 期: ** 调用说明: ** 修改日志:mod by wukj 20121031规范命名及排版修订 ** ****************************************************************/ int Sjl06eRacalVerifyPin(T_Interface *tInterface) { char szInData[1024], szOutData[1024], szPanBlock[17], szLmkEncPin1[17], szLmkEncPin2[17]; char szSndData[1024], szRcvData[1024]; int iLen, iRet, iSndLen; memset( szPanBlock, '0', 16 ); szPanBlock[16] = 0; /*========用LMK对PIN明文加密 开始==============*/ iLen = 0; memcpy( szInData, "BA", 2 ); /* 命令 */ iLen += 2; /* PIN明文 */ memcpy( szInData+iLen, tInterface->szData, 8 ); iLen += 8; memcpy( szInData+iLen, "FFFF", 4 ); iLen += 4; /* 帐号 */ memcpy( szInData+iLen, szPanBlock, 12 ); iLen += 12; szInData[iLen] = 0; memset( szRcvData, 0, 1024 ); memset( szOutData, 0, 1024 ); memcpy( szSndData, SJL06E_RACAL_HEAD_DATA, SJL06E_RACAL_HEAD_LEN ); memcpy( szSndData+SJL06E_RACAL_HEAD_LEN, szInData, iLen ); iLen += SJL06E_RACAL_HEAD_LEN; iRet = CommuWithHsm( szSndData, iLen, szRcvData ); if(iRet == FAIL) { WriteLog( ERROR, "commu with hsm fail" ); return FAIL; } else if( iRet - SJL06E_RACAL_HEAD_LEN >= 0) { memcpy( szOutData, szRcvData+SJL06E_RACAL_HEAD_LEN, iRet-SJL06E_RACAL_HEAD_LEN ); } else { WriteLog(ERROR,"请检查加密机消息头长度,是否>=[%d]" , SJL06E_RACAL_HEAD_LEN ); return FAIL; } if( memcmp(szOutData, "BB", 2) != 0 || memcmp(szOutData+2, "00", 2) != 0 ) { DispSjl06eRacalErrorMsg( szOutData+2, tInterface->szReturnCode ); WriteLog( ERROR, "hsm encrypt pin fail[%2.2s]", szOutData+2 ); return SUCC; } memcpy( szLmkEncPin1, szOutData+4, 16 ); /*========用LMK对PIN明文加密 结束=============*/ /*========将终端PIN密文从TPK翻译到LMK 开始=============*/ iLen = 0; memcpy( szInData, "JC", 2 ); /* 命令 */ iLen += 2; /* PIK密钥长度标识,16位长 */ szInData[iLen] = 'X'; iLen ++; /* PIK密钥密文 */ BcdToAsc( (uchar *)(tInterface->szPinKey), 32, 0, (uchar *)(szInData+iLen) ); iLen += 32; /* 终端PIN密文 */ BcdToAsc( (uchar *)(tInterface->szData+8), 16, 0 , (uchar *)(szInData+iLen)); iLen += 16; /* PIN块格式代码 */ memcpy( szInData+iLen, "01", 2 ); iLen += 2; /* 帐号 */ memcpy( szInData+iLen, szPanBlock, 12 ); iLen += 12; szInData[iLen] = 0; memset( szRcvData, 0, 1024 ); memset( szOutData, 0, 1024 ); memcpy( szSndData, SJL06E_RACAL_HEAD_DATA, SJL06E_RACAL_HEAD_LEN ); memcpy( szSndData+SJL06E_RACAL_HEAD_LEN, szInData, iLen ); iLen += SJL06E_RACAL_HEAD_LEN; iRet = CommuWithHsm( szSndData, iLen, szRcvData ); if(iRet == FAIL) { WriteLog( ERROR, "commu with hsm fail" ); return FAIL; } else if( iRet - SJL06E_RACAL_HEAD_LEN >= 0) { memcpy( szOutData, szRcvData+SJL06E_RACAL_HEAD_LEN, iRet-SJL06E_RACAL_HEAD_LEN ); } else { WriteLog(ERROR,"请检查加密机消息头长度,是否>=[%d]" , SJL06E_RACAL_HEAD_LEN ); return FAIL; } if( memcmp(szOutData, "JD", 2) != 0 || memcmp(szOutData+2, "00", 2) != 0 ) { DispSjl06eRacalErrorMsg( szOutData+2, tInterface->szReturnCode ); WriteLog( ERROR, "hsm encrypt pin fail[%2.2s]", szOutData+2 ); return SUCC; } memcpy( szLmkEncPin2, szOutData+4, 16 ); /*========将PIN从TPK翻译到LMK 结束=============*/ if( memcmp( szLmkEncPin1, szLmkEncPin2, 16 ) == 0 ) { strcpy( tInterface->szData, "SUCC" ); } else { strcpy( tInterface->szData, "FAIL" ); } tInterface->iDataLen = 4; strcpy( tInterface->szReturnCode, TRANS_SUCC ); return SUCC; }
/***************************************************************** ** 功 能:MAC计算 ** 输入参数: tInterface->szData 参与MAC运算的数据,长度由tInterface->iDataLen指定 ** 输出参数: tInterface->szData MAC(8字节) ** 返 回 值: 成功 - SUCC 失败 - FAIL ** 作 者: ** 日 期: ** 调用说明: ** 修改日志:mod by wukj 20121031规范命名及排版修订 ** ****************************************************************/ int Sjl06eRacalCalcMac(T_Interface *tInterface) { char szInData[1024], szOutData[1024]; char szSndData[1024], szRcvData[1024], szTmpStr[20]; int iLen, iRet, iSndLen; iLen = 0; memcpy( szInData, "MS", 2 ); /* 命令 */ iLen += 2; /*消息块号:0-仅1块 1-第1块 2-中间块 3-尾块 */ memcpy( szInData+iLen, "0", 1 ); iLen += 1; /*密钥类型:0-TAK终端认证密钥 1-ZAK区域认证密钥 */ memcpy( szInData+iLen, "0", 1 ); iLen += 1; /*密钥长度:0-单倍长度 1-双倍长度 */ memcpy( szInData+iLen, "1", 1 ); iLen += 1; /*消息类型:0-二进制 1-扩展十六进制 */ memcpy( szInData+iLen, "0", 1 ); iLen += 1; /*MAC密钥方案 */ memcpy( szInData+iLen, "X", 1 ); iLen += 1; /*MAC密钥密文*/ BcdToAsc((uchar *)(tInterface->szMacKey), 32, 0 , (uchar *)(szInData+iLen)); iLen += 32; /* MAC算法 1-XOR 2-X9.9 3-X9.19 */ if( tInterface->iAlog == XOR_CALC_MAC ) { /*消息长度*/ memcpy( szInData+iLen, "0008", 8 ); iLen += 4; /*消息块*/ XOR( tInterface->szData, tInterface->iDataLen, szOutData ); memcpy( szInData+iLen, szOutData, 8 ); iLen += 8; } else { /*消息长度*/ szTmpStr[0] = tInterface->iDataLen/256; szTmpStr[1] = tInterface->iDataLen%256; BcdToAsc( (uchar *)szTmpStr, 4, 0 , (uchar *)(szInData+iLen)); iLen += 4; /*消息块*/ memcpy( szInData+iLen, tInterface->szData, tInterface->iDataLen ); iLen = iLen+tInterface->iDataLen; } szInData[iLen] = 0; memset( szRcvData, 0, 1024 ); memset( szOutData, 0, 1024 ); memcpy( szSndData, SJL06E_RACAL_HEAD_DATA, SJL06E_RACAL_HEAD_LEN ); memcpy( szSndData+SJL06E_RACAL_HEAD_LEN, szInData, iLen ); iLen += SJL06E_RACAL_HEAD_LEN; iRet = CommuWithHsm( szSndData, iLen, szRcvData ); if(iRet == FAIL) { WriteLog( ERROR, "commu with hsm fail" ); return FAIL; } else if( iRet - SJL06E_RACAL_HEAD_LEN >= 0) { memcpy( szOutData, szRcvData+SJL06E_RACAL_HEAD_LEN, iRet-SJL06E_RACAL_HEAD_LEN ); } else { WriteLog(ERROR,"请检查加密机消息头长度,是否>=[%d]" , SJL06E_RACAL_HEAD_LEN ); return FAIL; } if( memcmp(szOutData, "MT", 2) != 0 || memcmp(szOutData+2, "00", 2) != 0 ) { DispSjl06eRacalErrorMsg( szOutData+2, tInterface->szReturnCode ); WriteLog( ERROR, "hsm calc mac fail[%2.2s]", szOutData+2 ); return SUCC; } AscToBcd( (uchar *)(szOutData+4), 16, 0 ,(uchar *)(tInterface->szData)); tInterface->iDataLen = 8; strcpy( tInterface->szReturnCode, TRANS_SUCC ); return SUCC; }
//预授权完成 int CTradePreAuthCptReq::DoPack(SAConnection *saConn, void * pNode, unsigned char * pBuffer, unsigned & iBufLen) { if(saConn == NULL || pNode == NULL || pBuffer == NULL) { trace_log(ERR, "Paramter error!"); return RET_SYSEXP; } trace_log(DBG,"-----PreAuthCptReq-----"); TRADEDATA * pData = (TRADEDATA *)pNode; int nTlvLen=0; char cICCID[4]={0},cICData[256]={0}; unsigned char bFieldData[FIELD_MAXLEN] = {0}; int iFieldDataLen; CTLVTemplet tlvObj; if(1 != tlvObj.UnPackTLVData(pData->TransData.TlvDataLen, pData->TransData.TlvData)) { trace_log(ERR, "UnPackTLVData fail!"); return RET_SYSEXP; } bool bFlag = true; bool bHasPin = false, bHasTrack = false; BYTE bTmpData[FIELD_MAXLEN]={0}; //0消息类型 bFlag &= sndObj.SetValueByStr(0 , "0200"); //2账号 bFlag &= sndObj.SetValueByStr(2 , pData->TransData.HeadData.Account); //3处理码 bFlag &= sndObj.SetValueByStr(3 , "003000"); //4交易金额 bFlag &= sndObj.SetValueByStr(4 , pData->TransData.HeadData.ReqAmount); //11流水号 bFlag &= sndObj.SetValueByStr(11, pData->VouchNo); //14卡有效期 iFieldDataLen=0; memset(bFieldData, 0, sizeof(bFieldData)); iFieldDataLen = tlvObj.GetTLVItemByHex(TAG_INPUTEXPDATE, bFieldData, sizeof(bFieldData)); if(iFieldDataLen > 0) { char cExpDate[5]={0}; BcdToAsc((BYTE *)cExpDate,bFieldData,iFieldDataLen); bFlag &= sndObj.SetValueByStr(14, cExpDate); } //F23 卡片序列号 nTlvLen= tlvObj.GetTLVItemByHex(TAG_ICCID, (BYTE *)cICCID, sizeof(cICCID)); if(nTlvLen>0) { char cICNO[5]={0}; BcdToAsc((BYTE *)cICNO,(BYTE *)cICCID,nTlvLen); bFlag &= sndObj.SetValueByStr(23, cICNO+1); } //32 受理机构代码 bFlag &= sndObj.SetValueByStr(32, pData->RcvBrchCode); //33 发送机构代码 bFlag &= sndObj.SetValueByStr(33, pData->SndBrchCode); /**< 磁道处理*/ if(SetTrack(pData,tlvObj,bHasTrack)!=0) { trace_log(ERR, "SetTrack faile"); return -1; }else{ trace_log(DBG, "SetTrack SUCCESS"); } //37系统参考号 bFlag &= sndObj.SetValueByStr(37, pData->TransData.HeadData.SysRefNo); //38授权码 bFlag &= sndObj.SetValueByStr(38, pData->TransData.HeadData.OrigAuthCode); //41终端号 bFlag &= sndObj.SetValueByStr(41, pData->TransData.HeadData.arrRTermNo); //42商户号 bFlag &= sndObj.SetValueByStr(42, pData->TransData.HeadData.arrRMerchNo); //49货币代码 bFlag &= sndObj.SetValueByStr(49, "156"); /**< 52密码*/ if(SetPinKey(pData, tlvObj,bHasPin)!=0) { trace_log(ERR, "SetPinKey faile"); return -1; }else{ trace_log(DBG, "SetPinKey SUCCESS"); } //55 C卡数据域 nTlvLen= tlvObj.GetTLVItemByHex(TAG_FIELD55_RSP, (BYTE *)cICData, sizeof(cICData)); if(nTlvLen>0) { bFlag &= sndObj.SetValueByHex(55, (BYTE *)cICData,nTlvLen); } /**< 22服务点输入方式码*/ bFlag &= sndObj.SetValueByStr(22,(char*)pData->TransData.HeadData.SvrPointCode); //60 应用版本 bFlag &= sndObj.SetValueByStr(60, "310"); //62 凭证号批次号 memset(bTmpData, 0, sizeof(bTmpData)); sprintf((char *)bTmpData, "%s%s", pData->VouchNo, pData->BatchNo); bFlag &= sndObj.SetValueByStr(62, (char *)bTmpData); //64MAC bFlag &= sndObj.SetValueByHex(64, (unsigned char*)"00000000", 8); /**< 组包*/ iBufLen = PACK_MAXLEN; bFlag &= sndObj.Pack(pBuffer, iBufLen); if(!bFlag) { trace_log(ERR, "Pack right CUPS8583 fail!"); return RET_PACK; } /**< 计算Mac */ BYTE bMac[9] = {0},bMab[512]={0}; int nMacLen = 8,nMabLen=0; nMabLen=iBufLen-7-nMacLen; memcpy(bMab,pBuffer+7,nMabLen); GenMacData(pData,bMab,nMabLen,bMac); memcpy(pBuffer + iBufLen -nMacLen, bMac, nMacLen); return RET_SUCCESS; }
int CTradeConsume::DoPack(SAConnection *saConn, void * pNode,unsigned char * pBuffer, unsigned & iBufLen) { if( NULL == saConn || NULL == pNode || NULL == pBuffer ) { trace_log(ERR, "Paramter error!"); return RET_SYSEXP; } trace_log(DBG,"-----Consume-----"); TRADEDATA * pData = (TRADEDATA *)pNode; int nTlvLen=0; char cICCID[4]={0},cICData[256]={0},cLField60[18]={0}; CTLVTemplet tlvObj; if(1 != tlvObj.UnPackTLVData(pData->TransData.TlvDataLen, pData->TransData.TlvData)) { trace_log(ERR, "UnPackTLVData fail!"); return RET_SYSEXP; } bool bFlag = true; bool bHasPin = false, bHasTrack = false; //0消息类型 bFlag &= sndObj.SetValueByStr(0 , "0200"); //银联--消费:0200 //2账号 bFlag &= sndObj.SetValueByStr(2 , pData->TransData.HeadData.Account); //3处理码 bFlag &= sndObj.SetValueByStr(3 , "000000"); //银联--消费:000000 --未选卡种 //4交易金额 bFlag &= sndObj.SetValueByStr(4 , pData->TransData.HeadData.ReqAmount); //7 交易传输时间 bFlag &= sndObj.SetValueByHex(7 ,(unsigned char*) (pData->cDateTime+4),10); //11流水号 bFlag &= sndObj.SetValueByStr(11, pData->VouchNo); //12本地交易时间 bFlag &= sndObj.SetValueByHex(12,(unsigned char*) (pData->cDateTime+8),6); //13本地交易日期 bFlag &= sndObj.SetValueByHex(13, (unsigned char*) (pData->cDateTime+4),4); //18 商户类型 n4 bFlag &=sndObj.SetValueByStr(18,pData->cMcc); //25服务点条件码 bFlag &= sndObj.SetValueByStr(25, "00"); //00 正常提交 //32 受理机构标识码 bFlag &=sndObj.SetValueByStr(32,pData->RcvBrchCode); //33 发送机构标识码 bFlag &=sndObj.SetValueByStr(33,pData->SndBrchCode); //F37 检索参考号 bFlag &= sndObj.SetValueByStr(37, pData->cReference); //41终端号 bFlag &= sndObj.SetValueByStr(41, pData->TransData.HeadData.arrRTermNo); //42商户号 bFlag &= sndObj.SetValueByStr(42, pData->TransData.HeadData.arrRMerchNo); //43收卡方名称地址 bFlag &=sndObj.SetValueByStr(43,pData->TransData.HeadData.RPrintMerName); //49货币代码 bFlag &= sndObj.SetValueByStr(49, "156"); //F22服务点输入码 n3 即持卡人数据(如PAN和PIN)的输入方式 如:020 021 050 051 bFlag &= sndObj.SetValueByStr(22, (char *)pData->TransData.HeadData.SvrPointCode); ///F23 卡片序列号 nTlvLen= tlvObj.GetTLVItemByHex(TAG_ICCID, (BYTE *)cICCID, sizeof(cICCID)); if(nTlvLen>0) { char cICNO[5]={0}; BcdToAsc((BYTE *)cICNO,(BYTE *)cICCID,nTlvLen); bFlag &= sndObj.SetValueByStr(23, cICNO+1); } bool bIC = false; ///55 IC卡数据域 nTlvLen= tlvObj.GetTLVItemByHex(TAG_FIELD55_RSP, (BYTE *)cICData, sizeof(cICData)); if(nTlvLen>0) { bFlag &= sndObj.SetValueByHex(55, (BYTE *)cICData,nTlvLen); bIC=true; } else { char cTrace[128]={0}; tlvObj.GetTLVItemByHex(TAG_TRACK2,(unsigned char*) cTrace, sizeof(cTrace)); int i=0; for(i=0;i<strlen(cTrace);i++) { if(0==memcmp(cTrace+i,"D",1)) { if((0==memcmp(cTrace+i+5,"2",1)||0==memcmp(cTrace+i+5,"6",1))) { memcpy(pData->TransData.HeadData.RspCode,"45",2); strcpy(pData->TransData.HeadData.RspDecs,"不允许降级交易"); return RET_PACK; }else{ break; } } } } // 35 36磁道处理 if(SetTrack(pData,tlvObj,bHasTrack)!=0) { trace_log(ERR, "SetTrack faile"); return -1; } trace_log(DBG, "SetTrack SUCCESS"); // 52密码 trace_log(DBG, "pData->TransData.HeadData.SvrPointCode[2]==%c",pData->TransData.HeadData.SvrPointCode[2]); if(0==memcmp((char *)&(pData->TransData.HeadData.SvrPointCode[2]),"1",1)) { if(SetPinKey(pData, tlvObj, bHasPin)!=0) { trace_log(ERR, "SetPinKey faile"); return -1; } trace_log(DBG, "SetPinKey SUCCESS"); //53安全控制信息 bFlag &= sndObj.SetValueByStr(53, "2600000000000000"); //26服务点PIN获取码 该域描述了服务点设备所能接受的PIN所能容纳的最多字符数 bFlag &= sndObj.SetValueByStr(26, "06"); } //60 域 BYTE F60[101]={0}; int iLen=0; memcpy(F60,"0000",4); //60.1 交易类型为 0200 时 填充 0000 iLen+=4; memcpy(F60+iLen,"0",1);//60.2.1 //保留使用,填充“0” iLen+=1; memcpy(F60+iLen,"5",1);//60.2.2 // 0 终端读取能力不可知 iLen+=1; memcpy(F60+iLen,"0",1);//60.2.3 //0 未使用或后续子域存在 iLen+=1; memcpy(F60+iLen,"0",1);//60.2.4 //保留使用,填充“0” iLen+=1; memcpy(F60+iLen,"03",2);//60.2.5 //03 销售点终端 11 移动POS iLen+=2; memcpy(F60+iLen,"0",1);//60.2.6 //保留使用,填充“0” iLen+=1; memcpy(F60+iLen,"0",1);//60.2.7 //第8位或后继位存在时的填充值 iLen+=1; memcpy(F60+iLen,"00",2);//60.2.8 //保留使用 iLen+=2; memcpy(F60+iLen,"00",2);//60.3 //60.3 业务种类定义 iLen+=2; memcpy(F60+iLen,"0000",4);//60.4 //60.4 行业卡种类 iLen+=4; bFlag &=sndObj.SetValueByStr(60,(char *)F60); //128MAC bFlag &= sndObj.SetValueByHex(128, (unsigned char*)"00000000", 8); // 组包 iBufLen = PACK_MAXLEN; bFlag &= sndObj.Pack(pBuffer, iBufLen); if(!bFlag) { trace_log(ERR, "Pack right CUPS8583 fail!"); return RET_PACK; } // 计算Mac // BYTE bMac[9] = {0}; int nMacLen = 8; if( 0 != GenMacData(pData,sndObj,bMac) ) { return RET_GETMACERR; } memcpy(pBuffer + iBufLen -nMacLen, bMac, nMacLen); //trace_log(DBG,"pBuffer[%d]=",iBufLen); //trace_mem(pBuffer,iBufLen); return RET_SUCCESS; }
LRESULT CMainFrame::OnRegLeftDbClick(WPARAM wParam,LPARAM lParam) { HTREEITEM hItem = (HTREEITEM) wParam; if(hItem == NULL || hItem == pRegTreeView->GetTreeCtrl().GetRootItem() || m_MissionData.m_RecvSocket == 0) return FALSE; char m_KeyName[1024] = {0}; if(!GetMyRegLeftPath(hItem,m_KeyName)) return FALSE; m_MissionData.m_Command = CLIENT_REG_QUERY; strcpy(m_MissionData.m_TransData,m_KeyName); m_MissionData.m_TransLen = strlen(m_KeyName); if(!ProcessOneTrans(&m_MissionData)) { ShowResponse(m_MissionData.m_Command); return FALSE; } if(m_MissionData.m_Command == NOT_FIND_ANY_FILE) { pRegListView->GetListCtrl().DeleteAllItems(); pRegListView->GetListCtrl().InsertItem(0,"(默认)",1); pRegListView->GetListCtrl().SetItemText(0,1,"REG_SZ"); pRegListView->GetListCtrl().SetItemText(0,2,"(数值未设置)"); DisplayButton(&pRegTreeView->GetTreeCtrl(),hItem,0); return FALSE; } else if(m_MissionData.m_Command != 0) { ShowResponse(m_MissionData.m_Command); DisplayButton(&pRegTreeView->GetTreeCtrl(),hItem,0); return FALSE; } DWORD dwFileSize = m_MissionData.m_TransLen; BYTE * m_DesBuf = (LPBYTE) m_MissionData.m_TransData; if (pRegTreeView->GetTreeCtrl().ItemHasChildren(hItem)) { HTREEITEM hNextItem; HTREEITEM hChildItem = pRegTreeView->GetTreeCtrl().GetChildItem(hItem); while (hChildItem != NULL) { hNextItem = pRegTreeView->GetTreeCtrl().GetNextItem(hChildItem,TVGN_NEXT); pRegTreeView->GetTreeCtrl().DeleteItem(hChildItem); hChildItem = hNextItem; } } pRegListView->GetListCtrl().DeleteAllItems(); REGINFO m_RegInfo = {0}; TV_INSERTSTRUCT tvstruct; int nItem = 0; BOOL IsHasChild = FALSE; for(ULONG i = 0; i < (dwFileSize/sizeof(REGINFO)); i++) { memset(&m_RegInfo,0,sizeof(REGINFO)); memcpy(&m_RegInfo,m_DesBuf + i * sizeof(REGINFO),sizeof(REGINFO)); m_RegInfo.m_Name[m_RegInfo.m_NameLen] = 0; if(!m_RegInfo.m_IsKey) { if(m_RegInfo.m_DataType == REG_SZ) { nItem = pRegListView->GetListCtrl().InsertItem (pRegListView->GetListCtrl().GetItemCount(),m_RegInfo.m_Name,1); pRegListView->GetListCtrl().SetItemText(nItem,1,"REG_SZ"); m_RegInfo.m_Data[m_RegInfo.m_Datalen] = 0; pRegListView->GetListCtrl().SetItemText(nItem,2,m_RegInfo.m_Data); } else if(m_RegInfo.m_DataType == REG_BINARY) { nItem = pRegListView->GetListCtrl().InsertItem (pRegListView->GetListCtrl().GetItemCount(),m_RegInfo.m_Name,0); pRegListView->GetListCtrl().SetItemText(nItem,1,"REG_BINARY"); char m_Tmpbuf[4096] = {0}; BcdToAsc((BYTE*) m_RegInfo.m_Data,(BYTE*) m_Tmpbuf,m_RegInfo.m_Datalen); pRegListView->GetListCtrl().SetItemText(nItem,2,m_Tmpbuf); } else { nItem = pRegListView->GetListCtrl().InsertItem (pRegListView->GetListCtrl().GetItemCount(),m_RegInfo.m_Name,0); pRegListView->GetListCtrl().SetItemText(nItem,1,"REG_DWORD"); char m_Tmpbuf[40] = {0}; sprintf(m_Tmpbuf,"0x%08lx(%ld)",(UINT) *((DWORD*) m_RegInfo.m_Data), (UINT) *((DWORD*) m_RegInfo.m_Data)); pRegListView->GetListCtrl().SetItemText(nItem,2,m_Tmpbuf); } } else { tvstruct.hParent = hItem; tvstruct.hInsertAfter = TVI_LAST; tvstruct.item.iImage = 0; tvstruct.item.iSelectedImage = 1; tvstruct.item.pszText = m_RegInfo.m_Name; tvstruct.item.mask = TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_TEXT; HTREEITEM m_Parent = pRegTreeView->GetTreeCtrl().InsertItem(&tvstruct); DisplayButton(&pRegTreeView->GetTreeCtrl(),m_Parent,1); pRegTreeView->GetTreeCtrl().SetItemData(m_Parent,0); IsHasChild = TRUE; } } if(!IsHasChild) { DisplayButton(&pRegTreeView->GetTreeCtrl(),hItem,0); } pRegTreeView->GetTreeCtrl().Expand(hItem,TVE_EXPAND); return TRUE; }
/******************************************************************************* * 函数功能:将固网支付规范报文(脚本POS报文)解析到公共数据结构。 * 指令被多次使用,则从第2次起输出数据解析到szReserved自定义字段中,这些 * 数据按TLV格式组织。需要用到这些数据的模块按TLV格式自行解析。TAG编码 * 规则如下: * a) Tag为三字节 * b) 第一位0xDF * c) 第二位 bit8为1,表示TAG有后续位,bit7-bit1表示指令编号,例如9号 * 指令,读取商务应用号为 0x89 * d) 第三位 bit8为0,bit7-bit1表示指令出现次数,例如第二次执行,则为 * 0x02 * e) 例如第二次执行商务应用号时,数据保存Tag为 \xDF\x89\x02 * 输入参数: * ptApp - 公共数据结构指针 * szInData - 接收到的数据 * iInLen - 接收到的数据长度 * 输出参数: * ptApp - 公共数据结构指针 * 返 回 值: * FAIL - 拆包失败 * SUCC - 拆包成功 * INVALID_PACK - 非法报文 * 作 者:Robin * 日 期:2012/12/11 * 修订日志: * ******************************************************************************/ int UnpackScriptPos(T_App *ptApp, char *szInData, int iInLen) { int i; int iIndex; /* 报文拆解索引值 */ char szTmpBuf[1024+1]; /* 临时变量 */ int iMsgLen; /* 消息内容长度 */ int iMsgIndex; /* 消息内容开始索引值 */ int iCmdNum; /* 流程代码个数 */ int iCmdLen; /* 流程代码长度 */ char szCmdData[512+1]; /* 流程代码内容 */ int iDataLen; /* 有效数据长度 */ int iDataIndex; /* 有效数据开始索引值 */ char szAuthCode[4]; /* 网关认证码 */ /* 报文拆解 */ iIndex = 0; /* TPDU */ /* 跳过60 */ iIndex += 1; /* 目的地址 */ memcpy(ptApp->szTargetTpdu, szInData+iIndex, 2); iIndex += 2; #ifdef DEBUG WriteLog(TRACE, "TPDU 目的地址:[%02x %02x]", ptApp->szTargetTpdu[0], ptApp->szTargetTpdu[1]); #endif /* 源地址 */ memcpy(ptApp->szSourceTpdu, szInData+iIndex, 2); iIndex += 2; #ifdef DEBUG WriteLog(TRACE, "TPDU 源地址:[%02x %02x]", ptApp->szSourceTpdu[0], ptApp->szSourceTpdu[1]); #endif /* 上送电话号码 */ if(memcmp(szInData+iIndex, "\x4C\x52\x49\x00\x1C", 5) == 0) { /* 电话号码标识头 */ iIndex += 5; /* 主叫号码 */ memset(szTmpBuf, 0, sizeof(szTmpBuf)); BcdToAsc(szInData+iIndex, 16, LEFT_ALIGN, (uchar*)szTmpBuf); for(i=0;i<16;i++) { if(szTmpBuf[i] != '0') { break; } } memcpy(ptApp->szCallingTel, szTmpBuf+i, 16-i); iIndex += 8; #ifdef DEBUG WriteLog(TRACE, "主叫号码:[%s]", ptApp->szCallingTel); #endif /* 被叫号码 */ memset(szTmpBuf, 0, sizeof(szTmpBuf)); BcdToAsc(szInData+iIndex, 16, LEFT_ALIGN, (uchar*)szTmpBuf); for(i=0;i<16;i++) { if(szTmpBuf[i] != '0') { break; } } memcpy(ptApp->szCalledTelByNac, szTmpBuf+i, 16-i); iIndex += 8; #ifdef DEBUG WriteLog(TRACE, "被叫号码:[%s]", ptApp->szCalledTelByNac); #endif /* 电话号码标识尾 */ iIndex += 12; } /* 报文同步序号 */ iIndex += 1; /* 交易数据索引号 */ iIndex += 2; /* 呼叫类型 */ iIndex += 1; /* 接入网关编号 */ ptApp->iFskId = (uchar)szInData[iIndex]; iIndex ++; #ifdef DEBUG WriteLog(TRACE, "接入网关编号:[%d]", ptApp->iFskId); #endif /* 接入网关模块号 */ ptApp->iModuleId = (uchar)szInData[iIndex]; iIndex ++; #ifdef DEBUG WriteLog(TRACE, "接入网关模块号:[%d]", ptApp->iModuleId); #endif /* 接入网关通道号 */ ptApp->iChannelId = (uchar)szInData[iIndex]; iIndex ++; #ifdef DEBUG WriteLog(TRACE, "接入网关通道号:[%d]", ptApp->iChannelId); #endif /******************************消息内容数据拆包******************************/ /* 消息内容长度 */ iMsgLen = ((uchar)szInData[iIndex])*256 + (uchar)szInData[iIndex+1]; iIndex += 2; /* 扣除MAC长度 */ iMsgLen = iMsgLen - 8; #ifdef DEBUG WriteLog(TRACE, "消息内容长度:[%d]", iMsgLen); #endif /* 判断消息内容长度是否超出 */ if(iMsgLen <= 0 || iMsgLen > 1024 || iMsgLen > (iInLen-iIndex-8)) { WriteLog(ERROR, "消息内容长度[%d]非法!实际消息内容长度[%d]", iMsgLen, iInLen-iIndex-8); return INVALID_PACK; } /* 消息内容 */ /* 记录消息内容开始索引值,用于MAC计算 */ iMsgIndex = iIndex; /* 报文类型 */ #ifdef DEBUG WriteLog(TRACE, "报文类型:[%02x]", szInData[iIndex]); #endif iIndex += 1; /* 结束标志 */ #ifdef DEBUG WriteLog(TRACE, "结束标志:[%02x]", szInData[iIndex]); #endif iIndex += 1; /* 报文版本 */ memcpy(ptApp->szMsgVer, szInData+iIndex, 2); iIndex += 2; #ifdef DEBUG WriteLog(TRACE, "报文版本:[%02x%02x]", ptApp->szMsgVer[0], ptApp->szMsgVer[1]); #endif /* 应用脚本版本 */ memcpy(ptApp->szAppVer, szInData+iIndex, 4); iIndex += 4; #ifdef DEBUG WriteLog(TRACE, "应用脚本版本:[%02x%02x%02x%02x]", ptApp->szAppVer[0], ptApp->szAppVer[1], ptApp->szAppVer[2], ptApp->szAppVer[3]); #endif /* 终端程序版本 */ BcdToAsc(szInData+iIndex, 8, LEFT_ALIGN, ptApp->szPosCodeVer); iIndex += 4; #ifdef DEBUG WriteLog(TRACE, "终端程序版本:[%s]", ptApp->szPosCodeVer); #endif /* 终端类型 */ memcpy(ptApp->szPosType, szInData+iIndex, 10); iIndex += 10; #ifdef DEBUG WriteLog(TRACE, "终端类型:[%s]", ptApp->szPosType); #endif /* 网关认证码 */ memcpy(szAuthCode, szInData+iIndex, 4); iIndex += 4; #ifdef DEBUG WriteLog(TRACE, "网关认证码:[%02x%02x%02x%02x]", szAuthCode[0] & 0xFF, szAuthCode[1] & 0xFF, szAuthCode[2] & 0xFF, szAuthCode[3] & 0xFF); #endif /* POS上送被叫号码 */ memcpy(ptApp->szCalledTelByTerm, szInData+iIndex, 15); iIndex += 15; DelTailSpace(ptApp->szCalledTelByTerm); #ifdef DEBUG WriteLog(TRACE, "POS上送被叫号码:[%s]", ptApp->szCalledTelByTerm); #endif /* 来电显示标志 */ #ifdef DEBUG WriteLog(TRACE, "来电显示标志:[%c]", szInData[iIndex]); #endif iIndex += 1; /* 安全模块号 */ memcpy(ptApp->szPsamNo, szInData+iIndex, 16); iIndex += 16; #ifdef DEBUG WriteLog(TRACE, "安全模块号:[%s]", ptApp->szPsamNo); #endif /* POS流水号 */ memset(szTmpBuf, 0, sizeof(szTmpBuf)); BcdToAsc(szInData+iIndex, 6, LEFT_ALIGN, (uchar*)szTmpBuf); ptApp->lPosTrace = atol(szTmpBuf); iIndex += 3; #ifdef DEBUG WriteLog(TRACE, "POS流水号:[%ld]", ptApp->lPosTrace); #endif /* 交易代码 */ BcdToAsc(szInData+iIndex, 8, LEFT_ALIGN, ptApp->szTransCode); iIndex += 4; #ifdef DEBUG WriteLog(TRACE, "交易代码:[%s]", ptApp->szTransCode); #endif /* 根据szTransCode获取交易信息 */ if(GetTranInfo(ptApp) != SUCC) { WriteLog(ERROR, "获取交易码[%s]对应交易定义失败!", ptApp->szTransCode); return FAIL; } /* trans_def交易定义表中trans_code标识终端交易,trans_type标识平台交易。并约定trans_type低4位相同, 对平台而言,这些交易对应平台同一个交易,可以采用完全相同的交易流程。即在此trans_type做模10000处 理,这样对于平台的所有模块都只需要按一个交易处理。*/ ptApp->iTransType = ptApp->iTransType % 10000; /* 交易重发报文 */ if(szInData[iMsgIndex] == 0x03) { ptApp->iOldTransType = ptApp->iTransType; ptApp->iTransType = RESEND; } /* 获取终端信息,检查终端是否需要更新 */ if(ChkTermInfo(ptApp) != SUCC) { return FAIL; } /******************************流程代码数据拆包******************************/ /* 流程代码个数 */ iCmdNum = (uchar)szInData[iIndex]; iIndex ++; #ifdef DEBUG WriteLog(TRACE, "流程代码个数:[%d]", iCmdNum); #endif /* 计算流程代码长度 */ iCmdLen = 0; for(i=0;i<iCmdNum;i++) { iCmdLen += CalcCmdBytes((uchar)szInData[iIndex+iCmdLen]); } #ifdef DEBUG WriteLog(TRACE, "流程代码长度:[%d]", iCmdLen); #endif /* 流程代码 */ memset(szCmdData, 0, sizeof(szCmdData)); memcpy(szCmdData, szInData+iIndex, iCmdLen); iIndex += iCmdLen; /* 有效数据长度 */ iDataLen = ((uchar)szInData[iIndex])*256 + (uchar)szInData[iIndex+1]; iIndex += 2; /* 判断有效数据长度是否超出 */ if(iDataLen > 1024 || iDataLen > (iInLen-iIndex)) { WriteLog(ERROR, "有效数据长度[%d]非法!实际消息内容长度[%d]", iDataLen, iInLen-iIndex); return INVALID_PACK; } /******************************指令数据解析******************************/ /* 记录有效数据开始索引值 */ iDataIndex = iIndex; if(PosOutput(ptApp, iCmdNum, szCmdData, iCmdLen, szInData+iDataIndex, iDataLen) != SUCC) { return INVALID_PACK; } /* 除了签到、回响测试、柜员签到交易以外,都需要进行MAC校验 */ if((ptApp->iTransType != LOGIN && ptApp->iTransType != ECHO_TEST && ptApp->iTransType != DOWN_ALL_FUNCTION && ptApp->iTransType != DOWN_ALL_MENU && ptApp->iTransType != DOWN_ALL_PRINT && ptApp->iTransType != DOWN_ALL_TERM && ptApp->iTransType != DOWN_ALL_PSAM && ptApp->iTransType != DOWN_ALL_ERROR && ptApp->iTransType != TEST_DISP_OPER_INFO && ptApp->iTransType != TEST_PRINT && ptApp->iTransType != DOWN_ALL_OPERATION && ptApp->iTransType != CENDOWN_ALL_OPERATION && ptApp->iTransType != REGISTER && ptApp->iTransType != TERM_REGISTER && ptApp->iTransType != AUTO_VOID && ptApp->iTransType != OPER_LOGIN) && giMacChk == 1) { memset(szTmpBuf, 0, sizeof(szTmpBuf)); if(HsmCalcMac(ptApp, XOR_CALC_MAC, ptApp->szMacKey, szInData+iMsgIndex, iMsgLen, szTmpBuf) != SUCC) { WriteLog(ERROR, "计算报文MAC错误!"); strcpy(ptApp->szRetCode, ERR_SYSTEM_ERROR); return FAIL; } if(memcmp(ptApp->szMac, szTmpBuf, 8) != 0) { WriteLog(ERROR, "报文MAC错误!"); strcpy(ptApp->szRetCode, ERR_MAC); #ifdef DEBUG WriteLog(TRACE, "报文上送MAC:[%02x%02x%02x%02x] 计算MAC:[%02x%02x%02x%02x]", ptApp->szMac[0] & 0xFF, ptApp->szMac[1] & 0xFF, ptApp->szMac[2] & 0xFF, ptApp->szMac[3] & 0xFF, szTmpBuf[0] & 0xFF, szTmpBuf[1] & 0xFF, szTmpBuf[2] & 0xFF, szTmpBuf[3] & 0xFF); #endif return FAIL; } } WriteAppStru(ptApp, "Read from ePos"); /* 校验网关认证码 */ if(CheckAuthCode(szAuthCode, ptApp->szPsamNo) != SUCC) { WriteLog(ERROR, "验证网关认证码失败!"); strcpy(ptApp->szRetCode, ERR_AUTHCODE); return FAIL; } return SUCC; }
/**************************************************************** ** 功 能:POS指令输出数据拆解 ** 输入参数: ** iCmdNum 指令个数 ** szCmdData 指令数据 ** iCmdLen 指令数据长度 ** szData 有效数据 ** iDataLen 有效数据长度 ** 输出参数: ** ptApp app结构指针 ** 返 回 值: ** SUCC 成功 ** FAIL 失败 ** 作 者: ** Robin ** 日 期: ** 2008/07/31 ** 调用说明: ** ** 修改日志: ****************************************************************/ int PosOutput(T_App *ptApp, int iCmdNum, char *szCmdData, int iCmdLen, char *szData, int iDataLen) { int i, j; T_TLVStru tTlv; /* TLV数据结构 */ int iCmdIndex; /* 指令索引 */ int iDataIndex; /* 有效数据索引 */ int iCmdBytes; /* 指令长度 */ uchar ucOrgCmd; /* 原始指令 */ char szTmpBuf[1024+1]; /* 临时变量 */ int iTmp; /* 临时变量 */ char szTlvTag[3+1]; /* TLV TAG */ int iTlvLen; /* TLV数据长度 */ char szTlvBuf[2048+1]; /* TLV数据 */ int iCopyIndex; /* 数据拷贝索引 */ int iControlNum; /* 流程控制码个数 */ int iMenuNum; /* 动态菜单个数 */ int iaTimes[MAX_COMMAND_NUM]; /* 记录指令出现的次数 */ /* 记录POS指令解析日志 */ WriteCmdData(ptApp->szTransName, ptApp->lPosTrace, "RCVBEGIN", ptApp->iTransType); /* 指令数据解析 */ /* TLV初始化 */ InitTLV(&tTlv, TAG_STANDARD, LEN_STANDARD, VALUE_NORMAL); iControlNum = 0; iMenuNum = 0; iCmdIndex = 0; iDataIndex = 0; for(i=0; i<MAX_COMMAND_NUM; i++) { iaTimes[i] = 0; } for(i=0;i<iCmdNum;i++) { /* 判断是否是特殊指令 */ /* 新增操作码均为3个字节。 第一个字节固定为C0。 第二个字节表示操作指令号所对应的操作提示信息索引号(HEX),若为0表示无操作提示信息,为255表示使用临时操作提示信息(临时操作提示信息由中心返回)。在下文中用XX表示。 第三个字节表示具体的指令类型。 */ if((szCmdData[iCmdIndex] & 0xFF) == SPECIAL_CMD_HEAD) { if((iTmp = SpecialOutput(ptApp, szCmdData+iCmdIndex, szData+iDataIndex)) == FAIL) { WriteLog(ERROR, "解析自定义指令输出数据失败!"); return FAIL; } if(iTmp == 0) { WriteCmdData(szCmdData+iCmdIndex, i, "FF", 2); } else { WriteCmdData(szCmdData+iCmdIndex, i, szData+iDataIndex, iTmp); } iDataIndex += iTmp; iCmdIndex += SPECIAL_CMD_LEN; } else { iCmdBytes = CalcCmdBytes((uchar)szCmdData[iCmdIndex]); ucOrgCmd = szCmdData[iCmdIndex] & 0x3F; /* 记录指令出现次数 */ iaTimes[ucOrgCmd]++; /* 保存当前数据索引值,用于拷贝TLV */ iCopyIndex = iDataIndex; switch(ucOrgCmd) { /* 读取安全模块号 */ case 0x02: WriteCmdData(szCmdData+iCmdIndex, i, szData+iDataIndex, 16); iDataIndex += 16; break; /* 磁道明文数据 */ case 0x03: /* 卡序号 */ memset(szTmpBuf, 0, sizeof(szTmpBuf)); BcdToAsc(szData+iDataIndex, 2, 0, szTmpBuf); memcpy(ptApp->szEmvCardNo, szTmpBuf, 3); iDataIndex += 2; #ifdef DEBUG WriteLog(TRACE, "卡序号:[%s]", ptApp->szEmvCardNo); #endif if((iTmp = GetTrack(ptApp, szData+iDataIndex)) == FAIL) { return FAIL; } WriteCmdData(szCmdData+iCmdIndex, i, szData+iDataIndex, iTmp); iDataIndex += iTmp; if(iaTimes[ucOrgCmd] == 1) { /* 根据磁道信息获取卡号 */ if(GetCardType(ptApp) != SUCC) { WriteLog(ERROR, "根据磁道信息获取卡号失败!"); return FAIL; } } break; /* 磁道密文数据 */ case 0x04: /* 磁道数据密文长度 */ iTmp = (uchar)(szData[iDataIndex]); if(iTmp > 88) { WriteLog(ERROR, "磁道密文数据长度[%d]非法!", iTmp); strcpy(ptApp->szRetCode, ERR_DATA_FORMAT); return FAIL; } iDataIndex += 1; /* /解密磁道数据 */ if(iaTimes[ucOrgCmd] == 1) { if(HsmDecryptTrack(ptApp, ptApp->szTrackKey, szData+iDataIndex, iTmp) != SUCC) { WriteLog(ERROR, "解密磁道密文数据失败!"); strcpy(ptApp->szRetCode, ERR_SYSTEM_ERROR); return FAIL; } /* 根据磁道信息获取卡号 */ if(GetCardType(ptApp) != SUCC) { WriteLog(ERROR, "根据磁道信息获取卡号失败!"); return FAIL; } } /* 记录指令数据 */ WriteCmdData(szCmdData+iCmdIndex, i, szData+iDataIndex, iTmp); iDataIndex += iTmp; break; /* 密码密文 */ case 0x05: if(iaTimes[ucOrgCmd] == 1) { memcpy(ptApp->szPasswd, szData+iDataIndex, 8); } else { memcpy(ptApp->szNewPasswd, szData+iDataIndex, 8); } WriteCmdData(szCmdData+iCmdIndex, i, szData+iDataIndex, 8); iDataIndex += 8; break; /* 交易数量 */ case 0x06: if(iaTimes[ucOrgCmd] == 1) { memset(szTmpBuf, 0, sizeof(szTmpBuf)); BcdToAsc((uchar*)(szData+iDataIndex), 6, LEFT_ALIGN, (uchar*)szTmpBuf); ptApp->iTransNum = atol(szTmpBuf); ptApp->lOldPosTrace= atol(szTmpBuf); } WriteCmdData(szCmdData+iCmdIndex, i, szData+iDataIndex, 3); iDataIndex += 3; break; /* 交易金额 */ case 0x07: if(iaTimes[ucOrgCmd] == 1) { BcdToAsc((uchar*)(szData+iDataIndex), 12, LEFT_ALIGN, ptApp->szAmount); } WriteCmdData(szCmdData+iCmdIndex, i, szData+iDataIndex, 6); iDataIndex += 6; break; /* 金融应用号 */ case 0x08: /* 金融应用号长度 */ iTmp = (uchar)(szData[iDataIndex]); if(iTmp > 40) { WriteLog(ERROR, "金融应用号长度[%d]非法!", iTmp); strcpy(ptApp->szRetCode, ERR_DATA_FORMAT); return FAIL; } iDataIndex += 1; if(iaTimes[ucOrgCmd] == 1) { memcpy(ptApp->szFinancialCode, szData+iDataIndex, iTmp); ptApp->szFinancialCode[iTmp] = 0; strcpy(ptApp->szAccount2, ptApp->szFinancialCode); /* 根据第二卡号获取卡信息 */ if(GetAcctType(ptApp) != SUCC) { WriteLog(ERROR, "根据第二卡号获取卡信息失败!"); return FAIL; } } WriteCmdData(szCmdData+iCmdIndex, i, szData+iDataIndex, iTmp); iDataIndex += iTmp; break; /* 商务应用号 */ case 0x09: /* 商务应用号长度 */ iTmp = (uchar)(szData[iDataIndex]); if(iTmp > 40) { WriteLog(ERROR, "商务应用号长度[%d]非法!", iTmp); strcpy(ptApp->szRetCode, ERR_DATA_FORMAT); return FAIL; } iDataIndex += 1; if(iaTimes[ucOrgCmd] == 1) { memcpy(ptApp->szBusinessCode, szData+iDataIndex, iTmp); ptApp->szBusinessCode[iTmp] = 0; } WriteCmdData(szCmdData+iCmdIndex, i, szData+iDataIndex, iTmp); iDataIndex += iTmp; break; /* 日期YYYYMMDD */ case 0x0A: if(iaTimes[ucOrgCmd] == 1) { BcdToAsc((uchar*)(szData+iDataIndex), 8, LEFT_ALIGN, (uchar*)ptApp->szInDate); } WriteCmdData(szCmdData+iCmdIndex, i, szData+iDataIndex, 4); iDataIndex += 4; break; /* 年月YYYYMM */ case 0x0B: if(iaTimes[ucOrgCmd] == 1) { BcdToAsc((uchar*)(szData+iDataIndex), 6, LEFT_ALIGN, (uchar*)ptApp->szInMonth); } WriteCmdData(szCmdData+iCmdIndex, i, szData+iDataIndex, 3); iDataIndex += 3; break; /* 自定义数据 */ case 0x0C: /* 自定义数据长度 */ iTmp = (uchar)(szData[iDataIndex]); if(iTmp > 40) { WriteLog(ERROR, "自定义数据长度[%d]非法!", iTmp); strcpy(ptApp->szRetCode, ERR_DATA_FORMAT); return FAIL; } iDataIndex += 1; if(iaTimes[ucOrgCmd] == 1) { memcpy(ptApp->szUserData, szData+iDataIndex, iTmp); ptApp->szUserData[iTmp] = 0; } WriteCmdData(szCmdData+iCmdIndex, i, szData+iDataIndex, iTmp); iDataIndex += iTmp; break; /* MAC */ case 0x0D: if(ptApp->iTransType != AUTO_VOID) { memcpy(ptApp->szMac, szData+iDataIndex, 8); } WriteCmdData(szCmdData+iCmdIndex, i, szData+iDataIndex, 8); iDataIndex += 8; break; /* 冲正信息[原交易流水号(3 bytes)+原交易MAC(8 bytes)] */ case 0x0F: WriteCmdData(szCmdData+iCmdIndex, i, szData+iDataIndex, 11); memset(szTmpBuf, 0, sizeof(szTmpBuf)); BcdToAsc((uchar*)(szData+iDataIndex), 6, LEFT_ALIGN, (uchar*)szTmpBuf); ptApp->lOldPosTrace = atol(szTmpBuf); iDataIndex += 3; memcpy(ptApp->szMac, szData+iDataIndex, 8); iDataIndex += 8; break; /* 报文版本号 */ case 0x10: WriteCmdData(szCmdData+iCmdIndex, i, szData+iDataIndex, 2); iDataIndex += 2; break; /* 终端应用脚本版本号 */ case 0x11: WriteCmdData(szCmdData+iCmdIndex, i, szData+iDataIndex, 4); iDataIndex += 4; break; /* 终端序列号 */ case 0x12: memcpy(ptApp->szTermSerialNo, szData+iDataIndex, 10); WriteCmdData(szCmdData+iCmdIndex, i, szData+iDataIndex, 10); iDataIndex += 10; break; /* 加密报文数据 */ case 0x13: /* 加密报文数据长度 */ iTmp = (uchar)(szData[iDataIndex]); if(iTmp > 256) { WriteLog(ERROR, "加密报文数据长度[%d]非法!", iTmp); strcpy(ptApp->szRetCode, ERR_DATA_FORMAT); return FAIL; } iDataIndex += 1; WriteCmdData(szCmdData+iCmdIndex, i, szData+iDataIndex, iTmp); iDataIndex += iTmp; break; /* 解密报文数据 */ case 0x14: /* 解密报文数据长度 */ iTmp = (uchar)(szData[iDataIndex]); if(iTmp > 240) { WriteLog(ERROR, "解密报文数据长度[%d]非法!", iTmp); strcpy(ptApp->szRetCode, ERR_DATA_FORMAT); return FAIL; } iDataIndex += 1; WriteCmdData(szCmdData+iCmdIndex, i, szData+iDataIndex, iTmp); iDataIndex += iTmp; break; /* 提取帐单支付数据 */ case 0x15: /* 账单支付数据长度 */ iTmp = (uchar)(szData[iDataIndex]); if(iTmp > 40) { WriteLog(ERROR, "账单支付数据长度[%d]非法!", iTmp); strcpy(ptApp->szRetCode, ERR_DATA_FORMAT); return FAIL; } iDataIndex += 1; memcpy(ptApp->szBusinessCode, szData+iDataIndex, iTmp); WriteCmdData(szCmdData+iCmdIndex, i, szData+iDataIndex, iTmp); iDataIndex += iTmp; break; /* 更新终端参数 */ case 0x16: /* 更新安全模块参数 */ case 0x17: /* 更新菜单参数 */ case 0x18: /* 更新功能提示 */ case 0x19: /* 更新操作提示 */ case 0x1A: /* 更新首页信息 */ case 0x1B: /* 更新打印模板记录 */ case 0x1C: /* 更新错误提示信息 */ case 0x1D: WriteCmdData(szCmdData+iCmdIndex, i, szData+iDataIndex, 2); memcpy(ptApp->szHostRetCode, szData+iDataIndex, 2); iDataIndex += 2; break; /* 存储帐单 */ case 0x1E: /* 账单支付数据长度 */ iTmp = (uchar)(szData[iDataIndex]); if(iTmp > 42) { WriteLog(ERROR, "账单支付数据长度[%d]非法!", iTmp); strcpy(ptApp->szRetCode, ERR_DATA_FORMAT); return FAIL; } iDataIndex += 1; WriteCmdData(szCmdData+iCmdIndex, i, szData+iDataIndex-1, iTmp+1); /* 存储结果 */ memcpy(ptApp->szHostRetCode, szData+iDataIndex, 2); iDataIndex += 2; memcpy(ptApp->szBusinessCode, szData+iDataIndex, iTmp-2); iDataIndex = iDataIndex+iTmp-2; break; /* 记录日志 */ case 0x1F: /* 存储短信 */ case 0x20: /* 打印数据 */ case 0x21: WriteCmdData(szCmdData+iCmdIndex, i, szData+iDataIndex, 2); memcpy(ptApp->szHostRetCode, szData+iDataIndex, 2); iDataIndex += 2; break; /* 显示结果信息 */ case 0x22: /* 连接系统 */ case 0x23: /* 发送数据 */ case 0x24: /* 接收数据 */ case 0x25: /* 挂机 */ case 0x26: /* 验证固网支付密码 */ case 0x27: /* 验证MAC */ case 0x28: /* 免提拨号 */ case 0x29: /* 交易确认 */ case 0x2A: /* 指令0x22至0x2A没有输出数据 */ WriteCmdData(szCmdData+iCmdIndex, i, "FF", 2); break; /* 用户选择动态菜单 */ case 0x2B: WriteCmdData(szCmdData+iCmdIndex, i, szData+iDataIndex, 1); /* 动态菜单项 */ iTmp = (uchar)(szData[iDataIndex]); if(iTmp >= 5) { WriteLog(ERROR, "动态菜单项[%d]非法!", iTmp); strcpy(ptApp->szRetCode, ERR_DATA_FORMAT); return FAIL; } iDataIndex += 1; ptApp->iaMenuItem[iMenuNum] = iTmp; iMenuNum++; break; /* 静态菜单更新 */ case 0x2C: WriteCmdData(szCmdData+iCmdIndex, i, szData+iDataIndex, 2); memcpy(ptApp->szHostRetCode, szData+iDataIndex, 2); iDataIndex += 2; break; /* 静态菜单显示与选择 */ case 0x2D: /* 静态菜单ID */ ptApp->iStaticMenuId = (uchar)(szData[iDataIndex]); iDataIndex += 1; /* 静态菜单输出长度 */ iTmp = (uchar)(szData[iDataIndex]); if(iTmp > 30) { WriteLog(ERROR, "静态菜单输出长度[%d]非法!", iTmp); strcpy(ptApp->szRetCode, ERR_DATA_FORMAT); return FAIL; } iDataIndex += 1; memcpy(ptApp->szStaticMenuOut, szData+iDataIndex, iTmp); ptApp->szStaticMenuOut[iTmp] = 0; WriteCmdData(szCmdData+iCmdIndex, i, szData+iDataIndex-2, iTmp+2); iDataIndex += iTmp; break; /* 上传卡号 */ case 0x2E: /* 卡号记录数 */ iTmp = (uchar)(szData[iDataIndex]); if(iTmp > MAX_REC_CARD_NUM) { WriteLog(ERROR, "一次上传卡号条数[%d]太多!最大上传数:[%d]", iTmp, MAX_REC_CARD_NUM); strcpy(ptApp->szRetCode, ERR_DATA_FORMAT); return FAIL; } iDataIndex += 1; WriteCmdData(szCmdData+iCmdIndex, i, szData+iDataIndex-1, 17*iTmp+1); iDataIndex += 17*iTmp; break; /* 系统临时操作提示信息 */ case 0x2F: WriteCmdData(szCmdData+iCmdIndex, i, "FF", 2); break; /* 获取流程控制码 */ case 0x30: if(iControlNum <= 5) { ptApp->szControlCode[iControlNum] = szData[iDataIndex]; } else { WriteLog(ERROR, "流程控制码超过5个"); strcpy(ptApp->szRetCode, ERR_DATA_FORMAT); return FAIL; } /* 不执行下一个指令码,跳过 */ if(szData[iDataIndex] == '0') { WriteCmdData(szCmdData+iCmdIndex+iCmdBytes, i, "FF", 2); iCmdIndex += CalcCmdBytes((uchar)szCmdData[iCmdIndex+iCmdBytes]); i++; } WriteCmdData(szCmdData+iCmdIndex, i, szData+iDataIndex, 1); iDataIndex += 1; iControlNum++; break; /* IC卡指令(预留) */ case 0x31: /* 文件数据处理 */ case 0x32: WriteCmdData(szCmdData+iCmdIndex, i, "FF", 2); break; /* 读取二磁道卡号 */ case 0x33: if(iaTimes[ucOrgCmd] == 1) { memset(szTmpBuf, 0, sizeof(szTmpBuf)); BcdToAsc((uchar*)(szData+iDataIndex), 20, LEFT_ALIGN, (uchar*)szTmpBuf); iDataIndex += 10; for(j=0;j<20;j++) { if(szTmpBuf[j] == 'F') { szTmpBuf[j] = 0; break; } } strcpy(ptApp->szPan, szTmpBuf); } WriteCmdData(szCmdData+iCmdIndex, i, szData+iDataIndex, 10); iDataIndex += 10; break; /* 上传交易日志 */ case 0x34: /* 暂不实现 */ break; /* 上传错误日志 */ case 0x35: /* 暂不实现 */ break; /* 利率数据 */ case 0x36: if(iaTimes[ucOrgCmd] == 1) { memset(szTmpBuf, 0, sizeof(szTmpBuf)); BcdToAsc((uchar*)(szData+iDataIndex), 6, LEFT_ALIGN, (uchar*)szTmpBuf); ptApp->lRate = atol(szTmpBuf); } WriteCmdData(szCmdData+iCmdIndex, i, szData+iDataIndex, 3); iDataIndex += 3; break; /* 从串口接收数据 */ case 0x37: iTlvLen = (uchar)szData[iDataIndex]; szTlvTag[0] = 0xDF; szTlvTag[1] = 0x80|ucOrgCmd; szTlvTag[2] = iaTimes[ucOrgCmd]; SetTLV(&tTlv, szTlvTag, iTlvLen, szData+iDataIndex+1); WriteCmdData(szCmdData+iCmdIndex, i, szData+iDataIndex, iTlvLen+1); iDataIndex += (iTlvLen+1); break; /* 发送数据给串口 */ case 0x38: iTlvLen = (uchar)szData[iDataIndex]; szTlvTag[0] = 0xDF; szTlvTag[1] = 0x80|ucOrgCmd; szTlvTag[2] = iaTimes[ucOrgCmd]; SetTLV(&tTlv, szTlvTag, iTlvLen, szData+iDataIndex+1); WriteCmdData(szCmdData+iCmdIndex, i, szData+iDataIndex, iTlvLen+1); iDataIndex += (iTlvLen+1); break; /* 签到更新密钥 */ case 0x39: WriteCmdData(szCmdData+iCmdIndex, i, szData+iDataIndex, 2); memcpy(ptApp->szHostRetCode, szData+iDataIndex, 2); iDataIndex += 2; break; /* 预拨号 */ case 0x3A: /* 清空菜单 */ case 0x3B: /* 冲正重发控制 */ case 0x3C: WriteCmdData(szCmdData+iCmdIndex, i, "FF", 2); break; /* 显示后台返回数据(选择继续) */ case 0x3D: WriteCmdData(szCmdData+iCmdIndex, i, szData+iDataIndex, 1); iDataIndex += 1; break; /* TMS参数下载 */ case 0x3E: WriteCmdData(szCmdData+iCmdIndex, i, szData+iDataIndex, 2); memcpy(ptApp->szHostRetCode, szData+iDataIndex, 2); iDataIndex += 2; break; /* 预留 */ case 0x3F: break; default: break; } /* 第2次出现的指令数据,以TLV格式记录在szReserved字段中 */ if(iaTimes[ucOrgCmd] >= 2) { szTlvTag[0] = 0xDF; szTlvTag[1] = 0x80|ucOrgCmd; szTlvTag[2] = iaTimes[ucOrgCmd]; SetTLV(&tTlv, szTlvTag, iDataIndex-iCopyIndex, szData+iCopyIndex); } iCmdIndex = iCmdIndex+iCmdBytes; } } /* 记录POS指令解析日志 */ WriteCmdData(ptApp->szTransName, ptApp->lPosTrace, "RCVEND", ptApp->iTransType); /* 保存TLV数据 */ memset(szTlvBuf, 0, sizeof(szTlvBuf)); iTlvLen = PackTLV(&tTlv, szTlvBuf); if(iTlvLen == FAIL) { WriteLog(ERROR, "TLV数据格式转换为字符串失败!"); strcpy(ptApp->szRetCode, ERR_SYSTEM_ERROR); return FAIL; } if((iTlvLen+ptApp->iReservedLen) > sizeof(ptApp->szReserved)) { WriteLog(ERROR, "需要存入szReserved的数据长度太长!当前长度:[%d] 待保存数据长度:[%d] 最大数据长度:[%d]", ptApp->iReservedLen, iTlvLen, sizeof(ptApp->szReserved)); strcpy(ptApp->szRetCode, ERR_SYSTEM_ERROR); return FAIL; } memcpy(ptApp->szReserved+ptApp->iReservedLen, szTlvBuf, iTlvLen); ptApp->iReservedLen += iTlvLen; return SUCC; }
/**************************************************************** ** 功 能:解析自定义指令输出数据 ** 输入参数: ** ptApp app结构指针 ** szCmdData 指令数据 ** szData 有效数据 ** 输出参数: ** 无 ** 返 回 值: ** >0 数据长度 ** FAIL 失败 ** 作 者: ** fengwei ** 日 期: ** 2013/03/06 ** 调用说明: ** ** 修改日志: ****************************************************************/ int SpecialOutput(T_App *ptApp, char *szCmdData, char *szData) { uchar uCmd; /* 指令号 */ int iDataIndex; /* 有效数据索引 */ char szTmpBuf[1024+1]; /* 临时变量 */ int iTmp; /* 临时变量 */ iDataIndex = 0; uCmd = szCmdData[SPECIAL_CMD_LEN-1]; switch(uCmd) { /* EMV参数版本号 */ case 0x01: memcpy(ptApp->szEmvParaVer, szData+iDataIndex, 12); iDataIndex += 12; #ifdef DEBUG WriteLog(TRACE, "EMV参数版本号:[%s]", ptApp->szEmvParaVer); #endif break; /* 保存EMV参数 */ case 0x02: /* EMV参数版本号 */ memcpy(ptApp->szEmvParaVer, szData+iDataIndex, 12); iDataIndex += 12; #ifdef DEBUG WriteLog(TRACE, "EMV参数版本号:[%s]", ptApp->szEmvParaVer); #endif /* 保存结果 */ memcpy(ptApp->szHostRetCode, szData+iDataIndex, 2); iDataIndex += 2; #ifdef DEBUG WriteLog(TRACE, "保存结果:[%s]", ptApp->szHostRetCode); #endif break; /* 读取终端当前公钥版本号 */ case 0x03: /* EMV公钥版本号 */ memcpy(ptApp->szEmvKeyVer, szData+iDataIndex, 8); iDataIndex += 8; #ifdef DEBUG WriteLog(TRACE, "EMV公钥版本号:[%s]", ptApp->szEmvKeyVer); #endif break; /* 保存EMV公钥 */ case 0x04: /* EMV参数版本号 */ memcpy(ptApp->szEmvKeyVer, szData+iDataIndex, 8); iDataIndex += 8; #ifdef DEBUG WriteLog(TRACE, "EMV公钥版本号:[%s]", ptApp->szEmvKeyVer); #endif /* 保存结果 */ memcpy(ptApp->szHostRetCode, szData+iDataIndex, 2); iDataIndex += 2; #ifdef DEBUG WriteLog(TRACE, "保存结果:[%s]", ptApp->szHostRetCode); #endif break; /* EMV完整流程处理 */ case 0x05: /* 交易金额 */ memset(szTmpBuf, 0, sizeof(szTmpBuf)); BcdToAsc((uchar*)(szData+iDataIndex), 12, LEFT_ALIGN, szTmpBuf); memcpy(ptApp->szAmount, szTmpBuf, 12); iDataIndex += 6; #ifdef DEBUG WriteLog(TRACE, "交易金额:[%s]", ptApp->szAmount); #endif /* 密码密文 */ memcpy(ptApp->szPasswd, szData+iDataIndex, 8); iDataIndex += 8; /* 卡序号 */ memset(szTmpBuf, 0, sizeof(szTmpBuf)); BcdToAsc((uchar*)(szData+iDataIndex), 4, LEFT_ALIGN, szTmpBuf); iDataIndex += 2; #ifdef DEBUG WriteLog(TRACE, "卡序号:[%s]", ptApp->szEmvCardNo); #endif /* 持卡人姓名长度 */ iTmp = (uchar)(szData[iDataIndex]); iDataIndex += 1; /* 持卡人姓名 */ if(iTmp > 0) { memcpy(ptApp->szHolderName, szData+iDataIndex, iTmp>40?40:iTmp); iDataIndex += iTmp; } #ifdef DEBUG WriteLog(TRACE, "持卡人姓名:[%s]", ptApp->szHolderName); #endif /* 磁道信息 */ if((iTmp = GetTrack(ptApp, szData+iDataIndex)) == FAIL) { return FAIL; } iDataIndex += iTmp; /* 根据磁道信息获取卡号 */ if(GetCardType(ptApp) != SUCC) { WriteLog(ERROR, "根据磁道信息获取卡号失败!"); return FAIL; } /* EMV数据长度 */ ptApp->iEmvDataLen = (uchar)(szData[iDataIndex]); iDataIndex += 1; /* EMV数据 */ if(ptApp->iEmvDataLen > 0) { memcpy(ptApp->szEmvData, szData+iDataIndex, ptApp->iEmvDataLen); iDataIndex += ptApp->iEmvDataLen; } break; /* EMV联机数据处理 */ case 0x06: /* 交易结果 */ memcpy(ptApp->szHostRetCode, szData+iDataIndex, 2); iDataIndex += 2; /* 以下数据根据实际情况处理 */ /* 原交易日期 */ iDataIndex += 4; /* 原交易流水号 */ memset(szTmpBuf, 0, sizeof(szTmpBuf)); BcdToAsc(szData+iDataIndex, 6, 0, szTmpBuf); iDataIndex += 3; ptApp->lOldPosTrace = atol(szTmpBuf); /* EMV证书长度 */ ptApp->iEmvTcLen = (uchar)(szData[iDataIndex]); iDataIndex += 1; /* EMV证书 */ if(ptApp->iEmvTcLen > 0) { memcpy(ptApp->szEmvTc, szData+iDataIndex, ptApp->iEmvTcLen); } iDataIndex += ptApp->iEmvTcLen; /* EMV脚本长度 */ ptApp->iEmvScriptLen = (uchar)(szData[iDataIndex]); iDataIndex += 1; /* EMV脚本 */ if(ptApp->iEmvScriptLen > 0) { memcpy(ptApp->szEmvScript, szData+iDataIndex, ptApp->iEmvScriptLen); } iDataIndex += ptApp->iEmvScriptLen; break; default: WriteLog(ERROR, "非法自定义指令[%d]", uCmd); return FAIL; } return iDataIndex; }
int CTradeMagRechConfirm::DoPack(SAConnection *saConn, void * pNode, unsigned char * pBuffer, unsigned & iBufLen) { if(saConn == NULL || pNode == NULL || pBuffer == NULL) { trace_log(ERR, "Paramter error!"); return RET_SYSEXP; } TRADEDATA * pData = (TRADEDATA *)pNode; CTLVTemplet tlvObj; if(1 != tlvObj.UnPackTLVData(pData->TransData.TlvDataLen, pData->TransData.TlvData)) { trace_log(ERR, "UnPackTLVData fail!"); return RET_SYSEXP; } bool bFlag = true, bIsICC = false; bool bHasPin = true, bHasTrack = true; unsigned char bFieldData[FIELD_MAXLEN]={0}; BYTE bTmpData[FIELD_MAXLEN]={0}; unsigned int iFieldDataLen = 0; //0消息类型 bFlag &= sndObj.SetValueByStr(0 , "0220"); //2账号 if(strlen(pData->TransData.HeadData.Account) > 0) bFlag &= sndObj.SetValueByStr(2 , pData->TransData.HeadData.Account); //3处理码 bFlag &= sndObj.SetValueByStr(3 , "630000"); //金额 bFlag &= sndObj.SetValueByStr(4 , pData->TransData.HeadData.ReqAmount); //11流水号 bFlag &= sndObj.SetValueByStr(11, pData->VouchNo); //14卡有效期 memset(bFieldData, 0, sizeof(bFieldData)); iFieldDataLen = tlvObj.GetTLVItemByHex(TAG_INPUTEXPDATE, bFieldData, sizeof(bFieldData)); if(iFieldDataLen > 0) { bFlag &= sndObj.SetValueByStr(14, (char *)bFieldData); } //22服务点输入方式码 tlvObj.GetTLVItemByHex(TAG_POSENTMODE, pData->TransData.HeadData.SvrPointCode, 2); if(memcmp(pData->TransData.HeadData.SvrPointCode, "\x00\x00", 2) == 0) {//未指明 memset(bFieldData, 0, sizeof(bFieldData)); iFieldDataLen = tlvObj.GetTLVItemByHex(TAG_TRACK2, bFieldData, sizeof(bFieldData)); if(iFieldDataLen > 0) {//有磁道信息 pData->TransData.HeadData.SvrPointCode[0] = 0x02; } else { pData->TransData.HeadData.SvrPointCode[0] = 0x01; } memset(bFieldData, 0, sizeof(bFieldData)); iFieldDataLen = tlvObj.GetTLVItemByHex(TAG_ENCRYPTPWD, bFieldData, sizeof(bFieldData)); if(iFieldDataLen > 0) {//有密码 pData->TransData.HeadData.SvrPointCode[1] = 0x10; } else { pData->TransData.HeadData.SvrPointCode[1] = 0x20; } } if(pData->TransData.HeadData.SvrPointCode[0] == 0x01) {//手输卡号,无磁道信息 bHasTrack = false; } if(pData->TransData.HeadData.SvrPointCode[1] != 0x10) {//无密码 bHasPin = false; } //BcdToAsc(bFieldData, pData->TransData.HeadData.SvrPointCode, 2); bFlag &= sndObj.SetValueByHex(22, pData->TransData.HeadData.SvrPointCode, 2); //23卡序列号 if(pData->TransData.HeadData.SvrPointCode[0] == 0x05 || pData->TransData.HeadData.SvrPointCode[0] == 0x07 || pData->TransData.HeadData.SvrPointCode[0] == 0x91 || pData->TransData.HeadData.SvrPointCode[0] == 0x95 || pData->TransData.HeadData.SvrPointCode[0] == 0x98) { bIsICC = true; } //25服务点条件码 /*memset(bFieldData, 0, sizeof(bFieldData)); iFieldDataLen = tlvObj.GetTLVItemByHex(TAG_SCC, bFieldData, sizeof(bFieldData)); if(iFieldDataLen > 0) { bFlag &= sndObj.SetValueByStr(25, (char*)bFieldData); }*/ if(strlen(pData->TransData.HeadData.SerConCode) > 0) { bFlag &= sndObj.SetValueByStr(25, pData->TransData.HeadData.SerConCode); } else { //trace_log(ERR, "GetTLVItemByHex[0F01] fail!"); trace_log(ERR, "Get point of service condition code failed!"); bFlag &= sndObj.SetValueByStr(25, "00"); } if(bHasTrack) { memset(bFieldData, 0, sizeof(bFieldData)); iFieldDataLen = tlvObj.GetTLVItemByHex(TAG_TRACK2, bFieldData, sizeof(bFieldData)); if(iFieldDataLen > 0) {//35 二磁道必须存在 //bFlag &= sndObj.SetValueByStr(35, (char *)bFieldData); bFlag &= sndObj.SetValueByHex(35, bFieldData, iFieldDataLen); } else { trace_log(ERR, "GetTLVItemByHex[57] fail!"); return RET_SYSEXP; } memset(bFieldData, 0, sizeof(bFieldData)); iFieldDataLen = tlvObj.GetTLVItemByHex(TAG_TRACK3, bFieldData, sizeof(bFieldData)); if(iFieldDataLen > 0) {//36 三磁道可不存在 //bFlag &= sndObj.SetValueByStr(36, (char *)bFieldData); bFlag &= sndObj.SetValueByHex(36, bFieldData, iFieldDataLen); } } //41终端号 bFlag &= sndObj.SetValueByStr(41, pData->TransData.HeadData.arrRTermNo); //42商户号 bFlag &= sndObj.SetValueByStr(42, pData->TransData.HeadData.arrRMerchNo); //49交易货币代码 bFlag &= sndObj.SetValueByStr(49, "156"); //60 memset(bFieldData, 0, sizeof(bFieldData)); iFieldDataLen = tlvObj.GetTLVItemByHex(TAG_RESERVED1, bFieldData, sizeof(bFieldData)); if(iFieldDataLen > 0) { //60.2 流水号 memset(bTmpData, 0, sizeof(bTmpData)); Ccommon::Str2Hex(pData->BatchNo, bTmpData, 6); memcpy(bFieldData + 1, bTmpData, 3); bFlag &= sndObj.SetValueByHex(60, bFieldData, iFieldDataLen); } else { trace_log(ERR, "Get tag[0F3C] value fail!"); return RET_SYSEXP; } //64MAC bFlag &= sndObj.SetValueByHex(64, (unsigned char*)"00000000", 8); /*unsigned char cMacBuf[FIELD_MAXLEN] = {0}; if(1 != sndObj.GetMacData(cMacBuf, sizeof(cMacBuf))) { trace_log(ERR,"Get mac failed!"); return RET_GETMACERR; } bFlag &= sndObj.SetValueByHex(64, cMacBuf, 8);*/ //组包 iBufLen = PACK_MAXLEN; bFlag &= sndObj.Pack(pBuffer, iBufLen); if(!bFlag) { trace_log(ERR, "Pack right CUPS8583 fail!"); return RET_PACK; } //计算MAC #if 0 unsigned char ucMab[1024]={0}, ucMac[9]={0}; unsigned char ucTmp[9] = {0}; int iMabLen = sndObj.GetMacData(ucMab, sizeof(ucMab)); if(iMabLen > 0) { if(!g_EncComm->CalculateMac(g_Cfg.SndBrchCode, g_Cfg.RcvBrchCode, ucMab, iMabLen, ucTmp, 2, 0)) { trace_log(ERR,"CalculateMac fail!"); return RET_SYSEXP; } BcdToAsc(pBuffer+iBufLen-8, ucTmp, 4); } else { trace_log(ERR,"GetMacData fail!"); return RET_SYSEXP; } #endif return RET_SUCCESS; }
int CTradeDoReset::DoPack(SAConnection *saConn, void * pNode, unsigned char * pBuffer, unsigned & iBufLen) { if(saConn == NULL || pNode == NULL || pBuffer == NULL) { trace_log(ERR, "Paramter error!"); return RET_SYSEXP; } trace_log(DBG,"-----DoReset-----"); TRADEDATA * pData = (TRADEDATA *)pNode; int nTlvLen=0; char cICCID[4]={0},cLField60[18]={0},cICData[256]={0},cLField61[20]={0}; bool bHasTrack = false; CTLVTemplet tlvObj; if(1 != tlvObj.UnPackTLVData(pData->TransData.TlvDataLen, pData->TransData.TlvData)) { trace_log(ERR, "UnPackTLVData fail!"); return RET_SYSEXP; } //冲正的时候不能隔批次 if(strcmp(pData->BatchNo, pData->TransData.HeadData.OrigLBatchNo)) { trace_log(ERR, "The original BatchNo is different with the current one"); return RET_SYSEXP; } //获取冲正数据并打包 if(COperateDB::GetResetData(saConn, pData,&sndObj)!=0) { trace_log(ERR, "GetResetData faile"); return RET_SYSEXP; } bool bFlag = true; //打包冲正剩余数据 //0消息类型 bFlag &= sndObj.SetValueByStr(0 , "0400"); //3处理码 bFlag &= sndObj.SetValueByStr(3 , "000000"); //4交易金额 bFlag &= sndObj.SetValueByStr(4 , pData->TransData.HeadData.ReqAmount); //11原交易流水 bFlag &= sndObj.SetValueByStr(11 , (char *)pData->TransData.HeadData.OrigLPosSeq); //14卡有效期 nTlvLen= tlvObj.GetTLVItemByHex(TAG_INPUTEXPDATE, (BYTE *)cICCID, sizeof(cICCID)); if(nTlvLen>0) { char cICNO[5]={0}; BcdToAsc((BYTE *)cICNO,(BYTE *)cICCID,nTlvLen); bFlag &= sndObj.SetValueByStr(14, cICNO); } //22服务点输入代码 bFlag &= sndObj.SetValueByStr(22, (const char *)pData->TransData.HeadData.SvrPointCode); //F23 卡片序列号 nTlvLen= tlvObj.GetTLVItemByHex(TAG_ICCID, (BYTE *)cICCID, sizeof(cICCID)); if(nTlvLen>0) { char cICNO[5]={0}; BcdToAsc((BYTE *)cICNO,(BYTE *)cICCID,nTlvLen); bFlag &= sndObj.SetValueByStr(23, cICNO+1); } //25服务点条件码 bFlag &= sndObj.SetValueByStr(25,"00"); //32 受理机构标识码 bFlag &=sndObj.SetValueByStr(32,pData->RcvBrchCode); // 35 36磁道处理 if(SetTrack(pData,tlvObj,bHasTrack)!=0) { trace_log(ERR, "SetTrack faile"); return -1; } trace_log(DBG, "SetTrack SUCCESS"); //F37 检索参考号 bFlag &= sndObj.SetValueByStr(37, pData->TransData.HeadData.SysRefNo); //F39 应答码 bFlag &= sndObj.SetValueByStr(39, "98"); //41终端号 bFlag &= sndObj.SetValueByStr(41, pData->TransData.HeadData.arrRTermNo); //42商户号 bFlag &= sndObj.SetValueByStr(42, pData->TransData.HeadData.arrRMerchNo); //49货币代码 bFlag &= sndObj.SetValueByStr(49, "156"); ///55 IC卡数据域 bool bIC = false; nTlvLen= tlvObj.GetTLVItemByHex(TAG_FIELD55_RSP, (BYTE *)cICData, sizeof(cICData)); if(nTlvLen>0) { bFlag &= sndObj.SetValueByHex(55, (BYTE *)cICData,nTlvLen); bIC=true; } else { char cTrace[128]={0}; tlvObj.GetTLVItemByHex(TAG_TRACK2,(unsigned char*) cTrace, sizeof(cTrace)); int i=0; for(i=0;i<strlen(cTrace);i++) { if(0==memcmp(cTrace+i,"D",1)) { if((0==memcmp(cTrace+i+5,"2",1)||0==memcmp(cTrace+i+5,"6",1))) { memcpy(pData->TransData.HeadData.RspCode,"45",2); strcpy(pData->TransData.HeadData.RspDecs,"不允许降级交易"); return RET_PACK; }else{ break; } } } } //60 域 BYTE F60[101]={0}; int iLen=0; if(0==memcmp((char *)&(pData->cOrgTradeType),"q",1)) { trace_log(DBG,"消费撤销"); memcpy(F60,"23",2); //—— 60.1 消息类型码 N2 iLen+=2; memcpy(F60+iLen,pData->BatchNo,6); //—— 60.2 批次号 N6 iLen+=6; //61自定义域 memset(cLField61,0x00,sizeof(cLField61)); strcpy((char *)cLField61,(char *)pData->TransData.HeadData.OrigLBatchNo); strcat((char *)cLField61,(char *)pData->TransData.HeadData.OrigLPosSeq); strcat((char *)cLField61,(char *)pData->cOri_DateTime); bFlag &= sndObj.SetValueByStr(61, (char *)cLField61); } else { trace_log(DBG,"原类型为消费"); memcpy(F60,"22",2); //—— 60.1 消息类型码 N2 iLen+=2; memcpy(F60+iLen,pData->BatchNo,6); //—— 60.2 批次号 N6 iLen+=6; } bFlag &= sndObj.SetValueByStr(60, (char *)F60); //64MAC bFlag &= sndObj.SetValueByHex(64, (unsigned char*)"00000000", 8); /**< 组包*/ iBufLen = PACK_MAXLEN; bFlag &= sndObj.Pack(pBuffer, iBufLen); if(!bFlag) { trace_log(ERR, "Pack right CUPS8583 fail!"); return RET_PACK; } /**< 计算Mac */ BYTE bMac[9] = {0}; int nMacLen = 8; BYTE bMab[512] = {0}; memcpy(bMab,pBuffer+13,iBufLen-13-nMacLen); if(GenMacData(pData,bMab,iBufLen-13-nMacLen,bMac)) { return RET_GETMACERR; } memcpy(pBuffer + iBufLen -nMacLen, bMac, nMacLen); return RET_SUCCESS; }
int CTradeRepeal::DoPack(SAConnection *saConn, void * pNode, unsigned char * pBuffer, unsigned & iBufLen) { if(saConn == NULL || pNode == NULL || pBuffer == NULL) { trace_log(ERR, "Paramter error!"); return RET_SYSEXP; } trace_log(DBG,"-----Repeal-----"); TRADEDATA * pData = (TRADEDATA *)pNode; int nTlvLen=0; char cICCID[4]={0},cLField60[18]={0},cLField61[20]={0},cLField62[32]={0}; CTLVTemplet tlvObj; if(1 != tlvObj.UnPackTLVData(pData->TransData.TlvDataLen, pData->TransData.TlvData)) { trace_log(ERR, "UnPackTLVData fail!"); return RET_SYSEXP; } bool bFlag = true; bool bHasPin = false, bHasTrack = false; //0消息类型 bFlag &= sndObj.SetValueByStr(0 , "0200"); //2账号 bFlag &= sndObj.SetValueByStr(2 , pData->TransData.HeadData.Account); //3处理码 bFlag &= sndObj.SetValueByStr(3 , "200000"); //4交易金额 bFlag &= sndObj.SetValueByStr(4 , pData->TransData.HeadData.ReqAmount); //11流水号 bFlag &= sndObj.SetValueByStr(11, pData->VouchNo); //f14 卡有效期 BYTE field14[6]={0}; BYTE field14ASC[6]={0}; nTlvLen=tlvObj.GetTLVItemByHex(TAG_EXPDATE,(BYTE *)field14,sizeof(field14)); BcdToAsc((BYTE *)field14,(BYTE *)field14ASC,nTlvLen); if(nTlvLen>0) { bFlag &=sndObj.SetValueByStr(14,(char *)field14ASC); } else { bFlag &=sndObj.SetValueByStr(14,"0000"); } /**< 22服务点输入方式码*/ bFlag &= sndObj.SetValueByStr(22,(char*)pData->TransData.HeadData.SvrPointCode); //SetDateTime(); /**< 设置时间12域和日期13域 */ //F23 卡片序列号 nTlvLen= tlvObj.GetTLVItemByHex(TAG_ICCID, (BYTE *)cICCID, sizeof(cICCID)); if(nTlvLen>0) { char cICNO[5]={0}; BcdToAsc((BYTE *)cICNO,(BYTE *)cICCID,nTlvLen); bFlag &= sndObj.SetValueByStr(23, cICNO+1); } //服务点条件码 bFlag &= sndObj.SetValueByStr(25,"00"); //26服务点PIN获取码 bFlag &= sndObj.SetValueByStr(26, "06"); if(!bFlag) { trace_log(ERR, "Pack right CUPS8583 fail!"); return RET_PACK; } //32 受理方标识码 //bFlag &=sndObj.SetValueByStr(32,"90000118"); /**< 磁道处理*/ if(SetTrack(pData,tlvObj,bHasTrack)!=0) { trace_log(ERR, "SetTrack faile"); return -1; }else{ trace_log(DBG, "SetTrack SUCCESS"); } //37参考号 bFlag &= sndObj.SetValueByStr(37, pData->TransData.HeadData.SysRefNo); //38授权码 if(strlen(pData->TransData.HeadData.OrigAuthCode) > 0) { bFlag &= sndObj.SetValueByStr(38, pData->TransData.HeadData.OrigAuthCode); } //终端号 bFlag &= sndObj.SetValueByStr(41, pData->TransData.HeadData.arrRTermNo); //42商户号 bFlag &= sndObj.SetValueByStr(42, pData->TransData.HeadData.arrRMerchNo); //49货币代码 bFlag &= sndObj.SetValueByStr(49, "156"); /**< 52密码*/ if(SetPinKey(pData, tlvObj,bHasPin)!=0) { trace_log(ERR, "SetPinKey faile"); return -1; }else{ trace_log(DBG, "SetPinKey SUCCESS"); } //60自定义域 memset(cLField60,0x00,sizeof(cLField60)); strcpy((char *)cLField60,(char *)"23"); strcat((char *)cLField60,(char *)pData->BatchNo); strcat((char *)cLField60,(char *)"000"); strcat((char *)cLField60,(char *)"501"); bFlag &= sndObj.SetValueByStr(60, (char *)cLField60); //61自定义域 memset(cLField61,0x00,sizeof(cLField61)); strcpy((char *)cLField61,(char *)pData->TransData.HeadData.OrigLBatchNo); strcat((char *)cLField61,(char *)pData->TransData.HeadData.OrigLPosSeq); bFlag &= sndObj.SetValueByStr(61, (char *)cLField61); //62域 memset(cLField62,0x00,sizeof(cLField62)); memcpy(cLField62,"SD=",3); strcat((char *)cLField62,g_Cfg.RcvBrchCode); bFlag &= sndObj.SetValueByStr(62, (char *)cLField62); //63 自定义域 //bFlag &= sndObj.SetValueByStr(63, (char *)"999"); //64MAC bFlag &= sndObj.SetValueByHex(64, (unsigned char*)"00000000", 8); /**< 组包*/ iBufLen = PACK_MAXLEN; if(!sndObj.Pack(pBuffer, iBufLen)) { trace_log(ERR, "Pack right CUPS8583 fail!"); return RET_PACK; } /**< 计算Mac */ BYTE bMac[9] = {0}; int nMacLen = 8; int iRet = 0; BYTE bMab[512] = {0}; memcpy(bMab,pBuffer+13,iBufLen-21); iRet = GenMacData(pData,bMab,iBufLen-21,bMac); if(iRet != 0) return iRet; memcpy(pBuffer + iBufLen - nMacLen, bMac, nMacLen); return RET_SUCCESS; }
int CTradePayback::DoPack(SAConnection *saConn, void * pNode, unsigned char * pBuffer, unsigned & iBufLen) { if(saConn == NULL || pNode == NULL || pBuffer == NULL) { trace_log(ERR, "Parameter error!"); return RET_SYSEXP; } TRADEDATA * pData = (TRADEDATA *)pNode; CTLVTemplet tlvObj; if(1 != tlvObj.UnPackTLVData(pData->TransData.TlvDataLen, pData->TransData.TlvData)) { trace_log(ERR, "UnPackTLVData fail!"); return RET_SYSEXP; } bool bFlag = true; bool bHasPin = true, bHasTrack = true; unsigned char bFieldData[FIELD_MAXLEN]={0}; BYTE bTmpData[FIELD_MAXLEN]={0}; unsigned int iFieldDataLen = 0 ; //char cCurTime[15] = {0}; BYTE bT2Data[120] = {0}; char cLenData[5] = {0}; //0消息类型 bFlag &= sndObj.SetValueByStr(0 , "0220"); //2主账号 bFlag &= sndObj.SetValueByStr(2 , pData->TransData.HeadData.Account); //3 交易处理码 if(!strncmp(pData->TransData.HeadData.SerConCode, "65", 2)) bFlag &= sndObj.SetValueByStr(3, "021000"); else bFlag &= sndObj.SetValueByStr(3, "020000"); //4金额 bFlag &= sndObj.SetValueByStr(4, pData->TransData.HeadData.ReqAmount); //11流水号 bFlag &= sndObj.SetValueByStr(11, pData->VouchNo); /*struct tm stCurTime; time_t ltime; pthread_mutex_lock(&tm_lock); time( <ime ); strftime(cCurTime, sizeof(cCurTime)-1, "%Y%m%d%H%M%S", localtime_xgd(<ime, &stCurTime)); pthread_mutex_unlock(&tm_lock); //12 交易时间 memset(bTmpData, 0, sizeof(bTmpData)); memcpy(bTmpData, cCurTime + 8, 6); bFlag &= sndObj.SetValueByStr(12, (char *)bTmpData); //13 交易日期 memset(bTmpData, 0, sizeof(bTmpData)); memcpy(bTmpData, cCurTime + 4, 4); bFlag &= sndObj.SetValueByStr(13, (char *)bTmpData);*/ //14卡有效期 memset(bFieldData, 0, sizeof(bFieldData)); iFieldDataLen = tlvObj.GetTLVItemByHex(TAG_INPUTEXPDATE, bFieldData, sizeof(bFieldData)); if(iFieldDataLen > 0) { bFlag &= sndObj.SetValueByStr(14, (char *)bFieldData); } //22服务点输入方式码 //tlvObj.GetTLVItemByHex(TAG_POSENTMODE, pData->TransData.HeadData.SvrPointCode, 2); if(memcmp(pData->TransData.HeadData.SvrPointCode, "\x00\x00", 2) == 0) {//未指明 memset(bFieldData, 0, sizeof(bFieldData)); iFieldDataLen = tlvObj.GetTLVItemByHex(TAG_TRACK2, bFieldData, sizeof(bFieldData)); if(iFieldDataLen > 0) {//有磁道信息 pData->TransData.HeadData.SvrPointCode[0] = 0x02; } else { pData->TransData.HeadData.SvrPointCode[0] = 0x01; } memset(bFieldData, 0, sizeof(bFieldData)); iFieldDataLen = tlvObj.GetTLVItemByHex(TAG_ENCRYPTPWD, bFieldData, sizeof(bFieldData)); if(iFieldDataLen > 0) {//有密码 pData->TransData.HeadData.SvrPointCode[1] = 0x10; } else { pData->TransData.HeadData.SvrPointCode[1] = 0x20; } } if(pData->TransData.HeadData.SvrPointCode[0] == 0x01) {//手输卡号,无磁道信息 bHasTrack = false; } if(pData->TransData.HeadData.SvrPointCode[1] != 0x10) {//无密码 bHasPin = false; } memset(bFieldData, 0, sizeof(bFieldData)); BcdToAsc(bFieldData, pData->TransData.HeadData.SvrPointCode, 2); bFieldData[3] = 0; bFlag &= sndObj.SetValueByStr(22, (char *)bFieldData); //32 受理机构代码 bFlag &= sndObj.SetValueByStr(32, pData->RcvBrchCode); //33 发送机构代码 bFlag &= sndObj.SetValueByStr(33, pData->SndBrchCode); if(bHasTrack) { int nResult = EncryptTrack(bFlag, tlvObj, pData); if(nResult) { trace_log(ERR, "Encrypt Track failed!"); return nResult; } } //系统参考号 bFlag &= sndObj.SetValueByStr(37, pData->TransData.HeadData.SysRefNo); //41终端号 bFlag &= sndObj.SetValueByStr(41, pData->TransData.HeadData.arrRTermNo); //42商户号 bFlag &= sndObj.SetValueByStr(42, pData->TransData.HeadData.arrRMerchNo); if(bHasPin) { int nResult = ChangePinBlock(bFlag, tlvObj, pData); if(nResult) { trace_log(DBG, "ChangePinBlock return failed!"); return nResult; } } //60 应用版本 bFlag &= sndObj.SetValueByStr(60, "310"); //62 凭证号批次号,凭证号用原来的 memset(bTmpData, 0, sizeof(bTmpData)); sprintf((char *)bTmpData, "%s%s", pData->TransData.HeadData.OrigLPosSeq, pData->TransData.HeadData.OrigLBatchNo); bFlag &= sndObj.SetValueByStr(62, (char *)bTmpData); //64MAC bFlag &= sndObj.SetValueByHex(64, (unsigned char*)"00000000", 8); //组包 iBufLen = PACK_MAXLEN; bFlag &= sndObj.Pack(pBuffer, iBufLen); if(!bFlag) { trace_log(ERR, "Pack right CUPS8583 fail!"); return RET_PACK; } //计算Mac bool bIsOrg = true; int nReturn = CalcMac(bIsOrg, iBufLen, pBuffer, pData); if(nReturn) { trace_log(ERR, "Calc Mac failed!"); return nReturn; } return RET_SUCCESS; }
//预授权完成 int CTradePreAuthCptReq::DoPack(SAConnection *saConn, void * pNode, unsigned char * pBuffer, unsigned & iBufLen) { if(saConn == NULL || pNode == NULL || pBuffer == NULL) { trace_log(ERR, "Paramter error!"); return RET_SYSEXP; } trace_log(DBG,"-----PreAuthCptReq-----"); TRADEDATA * pData = (TRADEDATA *)pNode; int nTlvLen=0; char cICCID[4]={0},cICData[256]={0},cLField60[18]={0}; CTLVTemplet tlvObj; if(1 != tlvObj.UnPackTLVData(pData->TransData.TlvDataLen, pData->TransData.TlvData)) { trace_log(ERR, "UnPackTLVData fail!"); return RET_SYSEXP; } bool bFlag = true; bool bHasPin = false, bHasTrack = false; BYTE bTmpData[FIELD_MAXLEN]={0}; //0消息类型 bFlag &= sndObj.SetValueByStr(0 , "0200"); //2账号 bFlag &= sndObj.SetValueByStr(2 , pData->TransData.HeadData.Account); //3处理码 bFlag &= sndObj.SetValueByStr(3 , "000000"); //4交易金额 bFlag &= sndObj.SetValueByStr(4 , pData->TransData.HeadData.ReqAmount); //11流水号 bFlag &= sndObj.SetValueByStr(11, pData->VouchNo); //SetDateTime(); /**< 设置时间12域和日期13域 */ //F22服务点输入码 bFlag &= sndObj.SetValueByStr(22, (char *)pData->TransData.HeadData.SvrPointCode); //F23 卡片序列号 nTlvLen= tlvObj.GetTLVItemByHex(TAG_ICCID, (BYTE *)cICCID, sizeof(cICCID)); if(nTlvLen>0) { char cICNO[5]={0}; BcdToAsc((BYTE *)cICNO,(BYTE *)cICCID,nTlvLen); bFlag &= sndObj.SetValueByStr(23, cICNO+1); } //NII //bFlag &= sndObj.SetValueByStr(24,"009"); //服务点条件码 bFlag &= sndObj.SetValueByStr(25,"06"); //32 受理机构代码 bFlag &= sndObj.SetValueByStr(32, g_Cfg.RcvBrchCode); //33 发送机构代码 //bFlag &= sndObj.SetValueByStr(33, pData->SndBrchCode); /**< 磁道处理*/ if(SetTrack(pData,tlvObj,bHasTrack)!=0) { trace_log(ERR, "SetTrack faile"); return -1; }else{ trace_log(DBG, "SetTrack SUCCESS"); } //38授权码 if(strlen(pData->TransData.HeadData.OrigAuthCode) > 0) { bFlag &= sndObj.SetValueByStr(38, pData->TransData.HeadData.OrigAuthCode); } //终端号 bFlag &= sndObj.SetValueByStr(41, pData->TransData.HeadData.arrRTermNo); //42商户号 bFlag &= sndObj.SetValueByStr(42, pData->TransData.HeadData.arrRMerchNo); //49货币代码 bFlag &= sndObj.SetValueByStr(49, "156"); /**< 52密码*/ if(SetPinKey(pData, tlvObj,bHasPin)!=0) { trace_log(ERR, "SetPinKey faile"); return -1; }else{ trace_log(DBG, "SetPinKey SUCCESS"); } //53安全控制信息 bFlag &= sndObj.SetValueByStr(53, "2610000000000000"); if(!bFlag) { trace_log(ERR, "Pack right CUPS8583 fail!"); return RET_PACK; } //55 C卡数据域 nTlvLen= tlvObj.GetTLVItemByHex(TAG_FIELD55_RSP, (BYTE *)cICData, sizeof(cICData)); if(nTlvLen>0) { bFlag &= sndObj.SetValueByHex(55, (BYTE *)cICData,nTlvLen); } //60自定义域 memset(cLField60,0x00,sizeof(cLField60)); memcpy(cLField60,"20",2); strcat((char *)cLField60,(char *)pData->BatchNo); strcat((char *)cLField60,(char *)"000"); //strcat((char *)cLField60,(char *)"501"); bFlag &= sndObj.SetValueByStr(60, (char *)cLField60); if(!bFlag) { trace_log(ERR, "Pack right CUPS8583 fail!"); return RET_PACK; } //62原始交易信息(信息类型码,系统跟踪号,交易日期和时间) memset(bTmpData, 0, sizeof(bTmpData)); sprintf((char *)bTmpData, "%s%s%s",pData->TransData.HeadData.OrigLBatchNo, pData->TransData.HeadData.OrigLPosSeq,pData->cOri_DateTime); bFlag &= sndObj.SetValueByStr(61, (char *)bTmpData); //64MAC bFlag &= sndObj.SetValueByHex(64, (unsigned char*)"00000000", 8); /**< 组包*/ iBufLen = PACK_MAXLEN; bFlag &= sndObj.Pack(pBuffer, iBufLen); if(!bFlag) { trace_log(ERR, "Pack right CUPS8583 fail!"); return RET_PACK; } /**< 计算Mac */ BYTE bMac[9] = {0}; int nMacLen = 8,iRet = 0; BYTE bMab[512] = {0}; memcpy(bMab,pBuffer+13,iBufLen-21); iRet = GenMacData(pData,bMab,iBufLen-21,bMac); if(iRet != 0) return -1; memcpy(pBuffer + iBufLen -nMacLen, bMac, nMacLen); return RET_SUCCESS; }
//冲正 int CTradeDoReset::DoPack(SAConnection *saConn, void * pNode, unsigned char * pBuffer, unsigned & iBufLen) { if(saConn == NULL || pNode == NULL || pBuffer == NULL) { trace_log(ERR, "Paramter error!"); return RET_SYSEXP; } trace_log(DBG,"-----DoReset-----"); TRADEDATA * pData = (TRADEDATA *)pNode; int nTlvLen=0; char cICCID[4]={0},cLField60[18]={0},cLField61[20]={0},cICData[256]={0}; CTLVTemplet tlvObj; if(1 != tlvObj.UnPackTLVData(pData->TransData.TlvDataLen, pData->TransData.TlvData)) { trace_log(ERR, "UnPackTLVData fail!"); return RET_SYSEXP; } //冲正的时候不能隔批次 if(strcmp(pData->BatchNo, pData->TransData.HeadData.OrigLBatchNo)) { trace_log(ERR, "The original BatchNo is different with the current one"); return RET_SYSEXP; } //获取冲正数据并打包 if(COperateDB::GetResetData(saConn, pData,&sndObj)!=0) { trace_log(ERR, "GetResetData faile"); return RET_SYSEXP; } bool bFlag = true; //打包冲正剩余数据 //0消息类型 bFlag &= sndObj.SetValueByStr(0 , "0400"); //11原交易流水 bFlag &= sndObj.SetValueByStr(11 , (char *)pData->TransData.HeadData.OrigLPosSeq); //F23 卡片序列号 nTlvLen= tlvObj.GetTLVItemByHex(TAG_ICCID, (BYTE *)cICCID, sizeof(cICCID)); if(nTlvLen>0) { char cICNO[5]={0}; BcdToAsc((BYTE *)cICNO,(BYTE *)cICCID,nTlvLen); bFlag &= sndObj.SetValueByStr(23, cICNO+1); } //服务点条件码 bFlag &= sndObj.SetValueByStr(25,"00"); // 冲正原因 bFlag &= sndObj.SetValueByStr(39,(char *)"98"); //55 C卡数据域 nTlvLen= tlvObj.GetTLVItemByHex(TAG_FIELD55_RSP, (BYTE *)cICData, sizeof(cICData)); if(nTlvLen>0) { bFlag &= sndObj.SetValueByHex(55, (BYTE *)cICData,nTlvLen); } //60自定义域 memset(cLField60,0x00,sizeof(cLField60)); memcpy(cLField60,"22",2); strcat((char *)cLField60,(char *)pData->BatchNo); strcat((char *)cLField60,(char *)"000"); strcat((char *)cLField60,(char *)"501"); bFlag &= sndObj.SetValueByStr(60, (char *)cLField60); //61自定义域 memset(cLField61,0x00,sizeof(cLField61)); strcpy((char *)cLField61,(char *)pData->TransData.HeadData.OrigLBatchNo); strcat((char *)cLField61,(char *)pData->TransData.HeadData.OrigLPosSeq); strncat((char *)cLField61,(char *)pData->cOri_DateTime,4); trace_log(DBG, "61 field is %s",cLField61); bFlag &= sndObj.SetValueByStr(61, (char *)cLField61); //64MAC bFlag &= sndObj.SetValueByHex(64, (unsigned char*)"00000000", 8); /**< 组包*/ iBufLen = PACK_MAXLEN; bFlag &= sndObj.Pack(pBuffer, iBufLen); if(!bFlag) { trace_log(ERR, "Pack right CUPS8583 fail!"); return RET_PACK; } /**< 计算Mac */ BYTE bMac[9] = {0}; int nMacLen = 8; BYTE bMab[512] = {0}; memcpy(bMab,pBuffer+13,iBufLen-21); GenMacData(pData,bMab,iBufLen-21,bMac); memcpy(pBuffer + iBufLen -nMacLen, bMac, nMacLen); return RET_SUCCESS; }
/**< 将消息包的信息赋予MyData */ int Dataprocess::GetFieldValue(void) { unsigned char cTemp[TLV_DATA_MAX_LEN]={0}; unsigned int nLen=TLV_DATA_MAX_LEN; CTLVTemplet tlvData; int rLen; for(int index = 0; index < FIELDCOUNT; index++) { if(pMsg8583recv->FieldExist(index)) { switch(index) { case 0: rLen = pMsg8583recv->GetValueByStr(0, (char *)myData.cMsgType, sizeof(myData.cMsgType)); //消息类型 break; case 2: rLen = pMsg8583recv->GetValueByStr(2, (char *)myData.cPriAccount, sizeof(myData.cPriAccount)); //主账号 memcpy(trasData.HeadData.Account,myData.cPriAccount,strlen((char*)myData.cPriAccount)); break; case 3: rLen = pMsg8583recv->GetValueByStr(3, (char *)myData.cTransProcess, sizeof(myData.cTransProcess)); //处理码 break; case 4: rLen = pMsg8583recv->GetValueByStr(4, (char *)myData.cTranAmount, sizeof(myData.cTranAmount)); //F4 交易金额 memcpy(trasData.HeadData.ReqAmount,myData.cTranAmount,strlen((char*)myData.cTranAmount)); break; case 11: rLen = pMsg8583recv->GetValueByStr(11, (char *)myData.cSysTraceNo, sizeof(myData.cSysTraceNo)); //受卡方系统跟踪号 memcpy(trasData.HeadData.LPosSeq,myData.cSysTraceNo,strlen((char *)myData.cSysTraceNo)); break; case 14: rLen = pMsg8583recv->GetValueByHex(14, myData.cExpiredDate, sizeof(myData.cExpiredDate)); //卡有效期 if(tlvData.AddTLVItemByEnum(TAG_INPUTEXPDATE,rLen,myData.cExpiredDate)!=1) { trace_log(ERR,"field14 AddTLV failse,myData.cExpiredDate is %s,len is %d",myData.cExpiredDate,strlen((char*)myData.cExpiredDate)); pMsg8583recv->SetValueByStr(39,"ZZ"); pMsg8583recv->SetValueByStr(56,"field14 AddTLV fail"); return -1; } rLen = pMsg8583recv->GetValueByStr(14, (char *)myData.cExpiredDate, sizeof(myData.cExpiredDate)); //卡有效期 break; case 22: rLen = pMsg8583recv->GetValueByStr(22, (char *)myData.cServiceEntry, sizeof(myData.cServiceEntry)); //F22 服务点输入码 memcpy(trasData.HeadData.SvrPointCode,myData.cServiceEntry,strlen((char*)myData.cServiceEntry)); break; case 23: rLen = pMsg8583recv->GetValueByHex(23, myData.cCardSequence, sizeof(myData.cCardSequence)); //F23 卡片序列号 if(tlvData.AddTLVItemByEnum(TAG_ICCID,rLen,myData.cCardSequence)!=1) { trace_log(ERR,"field23 AddTLV failse,myData.cCardAccepCode is %s,len is %d",myData.cCardAccepCode,strlen((char*)myData.cCardAccepCode)); pMsg8583recv->SetValueByStr(39,"ZZ"); pMsg8583recv->SetValueByStr(56,"field23 AddTLV fail"); return -1; } rLen = pMsg8583recv->GetValueByStr(23, (char *)myData.cCardSequence, sizeof(myData.cCardSequence)); //F23 卡片序列号 break; case 25: rLen = pMsg8583recv->GetValueByStr(25, (char *)myData.cServiceCondition, sizeof(myData.cServiceCondition));//F25 服务点条件码 memcpy(trasData.HeadData.SerConCode,myData.cServiceCondition,strlen((char *)myData.cServiceCondition)); break; case 27: rLen = pMsg8583recv->GetValueByStr(27, (char *)myData.cSettle, sizeof(myData.cSettle)); //跟老系统的清算类型 break; case 31: rLen = pMsg8583recv->GetValueByStr(31,(char *)myData.cOrgCode, sizeof(myData.cOrgCode)); //接入机构标识码 break; case 32: rLen = pMsg8583recv->GetValueByStr(32,(char *)myData.cAcquirIdenti,sizeof(myData.cAcquirIdenti));//受理方标识码 break; case 35: { rLen = pMsg8583recv->GetValueByHex(35, myData.cTrack2Data, sizeof(myData.cTrack2Data));//2磁道数据 break; } case 36: { rLen = pMsg8583recv->GetValueByHex(36, myData.cTrack3Data, sizeof(myData.cTrack3Data));//3磁道数据 break; } case 37: rLen = pMsg8583recv->GetValueByStr(37, (char *)myData.cOldReferenceNo, sizeof(myData.cOldReferenceNo)); //检索参考号 break; case 38: rLen = pMsg8583recv->GetValueByStr(38, (char *)myData.cAuthResponse, sizeof(myData.cAuthResponse)); //F38 授权标识应答码 //memcpy(trasData.HeadData.OrigAuthCode,myData.cAuthResponse,strlen((char *)myData.cAuthResponse)); break; case 39: { char cTmp[3]={0}; rLen = pMsg8583recv->GetValueByStr(39, cTmp, sizeof(cTmp)); //F39 返回码 if(0==memcmp(cTmp,"00",2)) pMsg8583recv->RemoveField(39); break; } case 41: rLen = pMsg8583recv->GetValueByStr(41, (char *)myData.cCardAccepTerm, sizeof(myData.cCardAccepTerm)); //受卡机终端标识码 memcpy(trasData.HeadData.LTermNo,myData.cCardAccepTerm,strlen((char *)myData.cCardAccepTerm)); break; case 42: rLen = pMsg8583recv->GetValueByStr(42,(char *)myData.cCardAccepCode, sizeof(myData.cCardAccepCode)); //F42 //受卡方标识码 memcpy(trasData.HeadData.LMerchNo,myData.cCardAccepCode,strlen((char *)myData.cCardAccepCode)); break; case 48: rLen = pMsg8583recv->GetValueByStr(48,(char *)myData.cAddDataPri, sizeof(myData.cAddDataPri)); //F48 //附加数据 - 私有 break; case 52: rLen = pMsg8583recv->GetValueByHex(52, myData.cPinData, sizeof(myData.cPinData));//F52 密码密文 if(tlvData.AddTLVItemByEnum(TAG_ENCRYPTPWD,rLen,myData.cPinData)!=1) { trace_log(ERR,"field52 AddTLV failse,myData.cPinData is %s,len is %d",myData.cPinData,rLen); pMsg8583recv->SetValueByStr(39,"ZZ"); pMsg8583recv->SetValueByStr(56,"field52 AddTLV fail"); return -1; } break; case 53: rLen = pMsg8583recv->GetValueByHex(53, myData.cSecurityControlInfo, sizeof(myData.cSecurityControlInfo)); //F53 安全控制信息 if(tlvData.AddTLVItemByEnum(TAG_PINENCTYPE,rLen,myData.cSecurityControlInfo)!=1) { trace_log(ERR,"field52 AddTLV failse,myData.cPinData is %s,len is %d",myData.cPinData,strlen((char *)myData.cSecurityControlInfo)); pMsg8583recv->SetValueByStr(39,"ZZ"); pMsg8583recv->SetValueByStr(56,"field53 AddTLV fail"); return -1; } rLen = pMsg8583recv->GetValueByStr(53, (char *)myData.cSecurityControlInfo, sizeof(myData.cSecurityControlInfo)); //F53 安全控制信息 break; case 55: rLen = pMsg8583recv->GetValueByHex(55, myData.cICData, sizeof(myData.cICData)); //IC卡数据域 if(tlvData.AddTLVItemByEnum(TAG_FIELD55_RSP,rLen,myData.cICData)!=1) { trace_log(ERR,"field55 AddTLV failse,myData.cICData is %s,len is %d",myData.cICData,strlen((char *)myData.cICData)); pMsg8583recv->SetValueByStr(39,"ZZ"); pMsg8583recv->SetValueByStr(56,"field55 AddTLV fail"); return -1; } rLen = pMsg8583recv->GetValueByStr(55, (char *)myData.cICData, sizeof(myData.cICData)); break; case 60: rLen = pMsg8583recv->GetValueByHex(60, myData.cRerervedPri60, sizeof(myData.cRerervedPri60)); if(tlvData.AddTLVItemByEnum(TAG_RESERVED1,rLen,myData.cRerervedPri60)!=1) { trace_log(ERR,"field60 AddTLV failse,myData.cRerervedPri60 is %s,len is %d",myData.cRerervedPri60,strlen((char*)myData.cRerervedPri60)); pMsg8583recv->SetValueByStr(39,"ZZ"); pMsg8583recv->SetValueByStr(56,"field60 AddTLV fail"); return -1; } rLen = pMsg8583recv->GetValueByStr(60, (char *)myData.cRerervedPri60, sizeof(myData.cRerervedPri60)); memcpy(trasData.HeadData.LBatchNo,myData.cRerervedPri60+2,6); break; case 61: rLen = pMsg8583recv->GetValueByHex(61, myData.cOriginalMsg, sizeof(myData.cOriginalMsg)); if(tlvData.AddTLVItemByEnum(TAG_RESERVED2,rLen,myData.cOriginalMsg)!=1) { trace_log(ERR,"TranBase::field61 AddTLV failse,myData.cOriginalMsg is %s,len is %d",myData.cOriginalMsg,strlen((char *)myData.cOriginalMsg)); pMsg8583recv->SetValueByStr(39,"ZZ"); pMsg8583recv->SetValueByStr(56,"field61 AddTLV fail"); return -1; } rLen = pMsg8583recv->GetValueByStr(61, (char *)myData.cOriginalMsg, sizeof(myData.cOriginalMsg)); break; case 62: rLen = pMsg8583recv->GetValueByHex(62,myData.cRerervedPri62,sizeof(myData.cRerervedPri62)); break; case 63: rLen = pMsg8583recv->GetValueByHex(63,myData.cRerervedPri63,sizeof(myData.cRerervedPri63)); if(tlvData.AddTLVItemByEnum(TAG_RESERVED3,rLen,myData.cRerervedPri63)!=1) { trace_log(ERR,"field63 AddTLV failse,myData.cRerervedPri63 is %s,len is %d",myData.cRerervedPri63,rLen); pMsg8583recv->SetValueByStr(39,"ZZ"); pMsg8583recv->SetValueByStr(56,"field63 AddTLV fail"); return -1; } break; default: break; } } } // 35域处理 if( pMsg8583recv->FieldExist(35)) { int nTrack=0; unsigned char cData[256]={0}; char cTrace[256]={0}; char cAccount[48]={0}; nTrack=pMsg8583recv->GetValueByHex(35, myData.cTrack2Data, sizeof(myData.cTrack2Data)); memcpy(cData,myData.cTrack2Data,nTrack); trace_log(NML," strat Decrypt data Track,track2 len:%d",nTrack); EnCrypt enCrypt; bool bRes = enCrypt.DecryptTrack((char*)myData.cCardAccepCode,(char*)myData.cCardAccepTerm,cData,nTrack,cTrace,cAccount); if(bRes) { if( CheckAccount(cAccount) ) { int nAccLen=strlen(cAccount); memcpy(myData.cPriAccount,cAccount,nAccLen); pMsg8583recv->SetValueByStr(2,cAccount);//可根据22域 和2磁道数据设置 memset(trasData.HeadData.Account, 0, sizeof(trasData.HeadData.Account)); memcpy(trasData.HeadData.Account,cAccount,nAccLen); } else { trace_log(ERR,"ERR IN encrypt Trace: %s,len is %d",cTrace,strlen(cTrace)); pMsg8583recv->SetValueByStr(39,"ZZ"); pMsg8583recv->SetValueByStr(56,"Encrypt Trace Field3535 Fail"); return -1; } if(tlvData.AddTLVItemByEnum(TAG_TRACK2,strlen(cTrace),(unsigned char*)cTrace)!=1) { trace_log(ERR,"field35 AddTLV failse,Trace2 is %s,len is %d",cTrace,strlen(cTrace)); pMsg8583recv->SetValueByStr(39,"ZZ"); pMsg8583recv->SetValueByStr(56,"field35 AddTLV fail"); return -1; } } else { trace_log(ERR,"Decrypt data of field35 fail"); pMsg8583recv->SetValueByStr(39,"ZZ"); pMsg8583recv->SetValueByStr(56,"Decrypt data of field35 fail"); return -1; } } // 36域处理 if( pMsg8583recv->FieldExist(36)) { int nTrack = 0; unsigned char cData[256] = {0}; char cTrace[256] = {0}; char cAccount[48]= {0}; nTrack = pMsg8583recv->GetValueByHex(36, myData.cTrack3Data, sizeof(myData.cTrack3Data)); memcpy(cData, myData.cTrack3Data, nTrack); trace_log(NML," strat Decrypt data Track,track3 len:%d", nTrack); EnCrypt enCrypt; bool bRes = enCrypt.DecryptTrack((char*)myData.cCardAccepCode, (char*)myData.cCardAccepTerm, cData, nTrack, cTrace, cAccount); if(bRes) { if(tlvData.AddTLVItemByEnum(TAG_TRACK3, strlen(cTrace), (unsigned char*)cTrace)!=1) { trace_log(ERR,"field36 AddTLV failse,Trace3 is %s,len is %d", cTrace, strlen(cTrace)); pMsg8583recv->SetValueByStr(39,"ZZ"); pMsg8583recv->SetValueByStr(56,"field36 AddTLV fail"); return -1; } } else { trace_log(ERR,"Decrypt data of field36 feild"); pMsg8583recv->SetValueByStr(39,"ZZ"); pMsg8583recv->SetValueByStr(56,"Decrypt data of field36 feild"); return -1; } } unsigned char cTpdu[30] = {0}, cATpdu[30] = {0}; rLen = pMsg8583recv->GetTpdu(cTpdu, 30); BcdToAsc(cATpdu,cTpdu,rLen); memcpy(trasData.HeadData.arrTPDU, (char*)cATpdu, strlen((char*)cATpdu)); /**< TLV打包 */ int nResult = tlvData.PackTLVData(cTemp, nLen); if(nResult != 1) { trace_log(ERR,"tlv pack failse :%d", nResult); pMsg8583recv->SetValueByStr(39,"ZZ"); pMsg8583recv->SetValueByStr(56,"tlv pack fail"); return -1; } memcpy(trasData.TlvData, cTemp, nLen); trasData.TlvDataLen = nLen; trace_log(NML,"##################cTpdu is %s, cATpdu is %s , arrTPDU is %s", cTpdu, cATpdu, trasData.HeadData.arrTPDU); return 0; }
/***************************************************************** ** 功 能:用ANSI X9.9 MAC算法对数据做MAC。 ** 输入参数: tInterface->szData 参与MAC运算的数据,长度由data_len指定 iSekIndex 存储加密密钥索引 ** 输出参数: tInterface->szData MAC(8字节) ** 返 回 值: 成功 - SUCC 失败 - FAIL ** 作 者:Robin ** 日 期:2009/08/25 ** 调用说明: ** 修改日志:mod by wukj 20121031规范命名及排版修订 ** ****************************************************************/ int Sjl06sCalcMac(T_Interface *tInterface, int iSekIndex) { char szInData[2048], szOutData[2048], szMacData[17]; int iLen, iRet, iSndLen; char szDisp[1024]; iLen = 0; /* 命令 */ memcpy( szInData, "XR", 2 ); iLen += 2; /*存储加密密钥索引*/ sprintf( szInData+iLen, "%03ld", iSekIndex ); iLen += 3; /*MAC密钥密文*/ BcdToAsc( (uchar *)(tInterface->szMacKey), 32, 0 ,(uchar *)(szInData+iLen)); iLen += 32; #ifdef TEST_SAFE_PRT memset(szDisp, 0x00, sizeof(szDisp)); BcdToAsc((uchar*)(tInterface->szMacKey), 32, 0,(uchar*)szDisp); WriteLog(TRACE, "===mac key[%s]===", szDisp); #endif if( tInterface->iAlog == XOR_CALC_MAC ) { XOR( tInterface->szData, tInterface->iDataLen, szMacData ); sprintf( szInData+iLen, "%03ld", 8 ); iLen += 3; memcpy( szInData+iLen, szMacData, 8 ); iLen += 8; } else { sprintf( szInData+iLen, "%03ld", tInterface->iDataLen ); iLen += 3; memcpy( szInData+iLen, tInterface->szData, tInterface->iDataLen ); iLen += tInterface->iDataLen; } iRet = CommuWithHsm( szInData, iLen, szOutData ); if( iRet == FAIL ) { WriteLog( ERROR, "commu with hsm fail" ); strcpy( tInterface->szReturnCode, ERR_SYSTEM_ERROR ); return FAIL; } if( memcmp(szOutData, "E", 1) == 0 ) { DispUphsmErrorMsg( szOutData+1, tInterface->szReturnCode ); WriteLog( ERROR, "hsm calc mac fail[%2.2s]", szOutData+1 ); return SUCC; } else if(memcmp(szOutData, "A", 1) == 0 ) { AscToBcd( (uchar *)(szOutData+1), 16, 0 ,(uchar *)(tInterface->szData)); tInterface->iDataLen = 8; strcpy( tInterface->szReturnCode, TRANS_SUCC ); } return SUCC; }
/***************************************************************** ** 功 能:将PIN密文用源PIK解密,进行PIN格式转换,然后用LMK对(02-03)加密输出. ** 输入参数: tInterface->szData 帐号(16字节)+密码密文(8字节) ** 输出参数: tInterface->szData 转加密后的密码密文(8字节) ** 返 回 值: 成功 - SUCC 失败 - FAIL ** 作 者: ** 日 期: ** 调用说明: ** 修改日志:mod by wukj 20121031规范命名及排版修订 ** ****************************************************************/ int Sjl06eRacalChangePin_TPK2LMK(T_Interface *tInterface) { char szInData[1024], szOutData[1024], szPanBlock[17]; char szSndData[1024], szRcvData[1024]; int iLen, iRet, iSndLen; sprintf( szPanBlock, "%12.12s", tInterface->szData+3 ); szPanBlock[12] = 0; iLen = 0; memcpy( szInData, "JC", 2 ); /* 命令 */ iLen += 2; /* 源PIK密钥长度标识,16位长 */ szInData[iLen] = 'X'; iLen ++; /* 源PIK密钥密文 */ BcdToAsc( (uchar *)(tInterface->szPinKey), 32, 0 , (uchar *)(szInData+iLen)); iLen += 32; /* PinBlock密文 */ BcdToAsc( (uchar *)(tInterface->szData+16), 16, 0 , (uchar *)(szInData+iLen)); iLen += 16; /* PinBlock格式 */ memcpy( szInData+iLen, "01", 2 ); iLen += 2; /* 帐号 */ memcpy( szInData+iLen, szPanBlock, 12 ); iLen += 12; szInData[iLen] = 0; //WriteLog( TRACE, "ChgPinSnd[%s]", szInData ); memset( szRcvData, 0, 1024 ); memset( szOutData, 0, 1024 ); memcpy( szSndData, SJL06E_RACAL_HEAD_DATA, SJL06E_RACAL_HEAD_LEN ); memcpy( szSndData+SJL06E_RACAL_HEAD_LEN, szInData, iLen ); iLen += SJL06E_RACAL_HEAD_LEN; iRet = CommuWithHsm( szSndData, iLen, szRcvData ); if(iRet == FAIL) { WriteLog( ERROR, "commu with hsm fail" ); return FAIL; } else if( iRet - SJL06E_RACAL_HEAD_LEN >= 0) { memcpy( szOutData, szRcvData+SJL06E_RACAL_HEAD_LEN, iRet-SJL06E_RACAL_HEAD_LEN ); } else { WriteLog(ERROR,"请检查加密机消息头长度,是否>=[%d]" , SJL06E_RACAL_HEAD_LEN ); return FAIL; } if( memcmp(szOutData, "JD", 2) != 0 || memcmp(szOutData+2, "00", 2) != 0 ) { DispSjl06eRacalErrorMsg( szOutData+2, tInterface->szReturnCode ); WriteLog( ERROR, "hsm pin change fail[%2.2s]", szOutData+2 ); return SUCC; } /* WriteLog( TRACE, "ChgPinRcv[%s]", szOutData ); */ tInterface->iDataLen = strlen(szOutData)-4; memcpy( tInterface->szData, szOutData+4, tInterface->iDataLen ); tInterface->szData[tInterface->iDataLen] = 0; strcpy( tInterface->szReturnCode, TRANS_SUCC ); return SUCC; }
/***************************************************************** ** 功 能:将源PIN密文用源PIK解密,进行PIN格式转换,然后用目的PIK加密输出。 ** 输入参数: tInterface->szData 源帐号(16字节)+密码密文(8字节)+目的帐号(16字节) iSekPosIndex 加密源PIK的存储加密密钥索引 iSekHostIndex 加密目的PIK的存储加密密钥索引 ** 输出参数: tInterface->szData 转加密后的密码密文(8字节) ** 返 回 值: 成功 - SUCC 失败 - FAIL ** 作 者:Robin ** 日 期:2009/08/25 ** 调用说明: ** 修改日志:mod by wukj 20121031规范命名及排版修订 ** ****************************************************************/ int Sjl06sChangePin(T_Interface *tInterface, int iSekPosIndex, int iSekHostIndex) { char szInData[1024], szOutData[1024], szPanBlock[17], szTargetPan[17]; int iLen, iRet, iSndLen; sprintf( szPanBlock, "0000%12.12s", tInterface->szData+3 ); szPanBlock[16] = 0; sprintf( szTargetPan, "0000%12.12s", tInterface->szData+27 ); szTargetPan[16] = 0; iLen = 0; memcpy( szInData, "XP", 2 ); /* 命令 */ iLen += 2; /* 加密源PIK的存储加密密钥索引 */ sprintf( szInData+iLen, "%03ld", iSekPosIndex ); iLen += 3; /* 源PIK密钥密文 */ BcdToAsc( (uchar *)(tInterface->szPinKey), 32, 0 , (uchar *)(szInData+iLen)); iLen += 32; /* 加密目的PIK的存储加密密钥索引 */ sprintf( szInData+iLen, "%03ld", iSekHostIndex ); iLen += 3; /* 目的PIK密钥密文 */ BcdToAsc( (uchar *)(tInterface->szMacKey), 32, 0 , (uchar *)(szInData+iLen)); iLen += 32; /* 源PinBlock密文 */ BcdToAsc( (uchar *)(tInterface->szData+16), 16, 0 , (uchar *)(szInData+iLen)); iLen += 16; /* 源帐号 */ memcpy( szInData+iLen, szPanBlock, 16 ); iLen += 16; /* 目的帐号 */ memcpy( szInData+iLen, szTargetPan, 16 ); iLen += 16; iRet = CommuWithHsm( szInData, iLen, szOutData ); if( iRet == FAIL ) { WriteLog( ERROR, "commu with hsm fail" ); strcpy( tInterface->szReturnCode, ERR_SYSTEM_ERROR ); return FAIL; } if( memcmp(szOutData, "E", 1) == 0 ) { DispUphsmErrorMsg( szOutData+1, tInterface->szReturnCode ); WriteLog( ERROR, "hsm pin change fail[%2.2s]", szOutData+1 ); return SUCC; } else if(memcmp(szOutData, "A", 1) == 0 ) { AscToBcd( (uchar *)(szOutData+1), 16, 0 ,(uchar *)(tInterface->szData)); tInterface->iDataLen = 8; strcpy( tInterface->szReturnCode, TRANS_SUCC ); } return SUCC; }
//预授权完成 int CTradePreAuthCptReq::DoPack(SAConnection *saConn, void * pNode, unsigned char * pBuffer, unsigned & iBufLen) { if(saConn == NULL || pNode == NULL || pBuffer == NULL) { trace_log(ERR, "Paramter error!"); return RET_SYSEXP; } trace_log(DBG,"-----PreAuthCptReq-----"); TRADEDATA * pData = (TRADEDATA *)pNode; int nTlvLen=0; char cICCID[4]={0},cICData[256]={0},cLField60[18]={0}; CTLVTemplet tlvObj; if(1 != tlvObj.UnPackTLVData(pData->TransData.TlvDataLen, pData->TransData.TlvData)) { trace_log(ERR, "UnPackTLVData fail!"); return RET_SYSEXP; } bool bFlag = true; bool bHasPin = false, bHasTrack = false; BYTE bTmpData[FIELD_MAXLEN]={0}; //0消息类型 bFlag &= sndObj.SetValueByStr(0 , "0200"); //2账号 bFlag &= sndObj.SetValueByStr(2 , pData->TransData.HeadData.Account); //3处理码 bFlag &= sndObj.SetValueByStr(3 , "000000"); //4交易金额 bFlag &= sndObj.SetValueByStr(4 , pData->TransData.HeadData.ReqAmount); //11流水号 bFlag &= sndObj.SetValueByStr(11, pData->VouchNo); SetDateTime(); /**< 设置时间12域和日期13域 */ //F23 卡片序列号 /*nTlvLen= tlvObj.GetTLVItemByHex(TAG_ICCID, (BYTE *)cICCID, sizeof(cICCID)); if(nTlvLen>0) { char cICNO[5]={0}; BcdToAsc((BYTE *)cICNO,(BYTE *)cICCID,nTlvLen); bFlag &= sndObj.SetValueByStr(23, cICNO+1); }*/ //NII bFlag &= sndObj.SetValueByStr(24,"009"); //服务点条件码 bFlag &= sndObj.SetValueByStr(25,"14"); //32 受理机构代码 bFlag &= sndObj.SetValueByStr(32, pData->RcvBrchCode); //33 发送机构代码 bFlag &= sndObj.SetValueByStr(33, pData->SndBrchCode); /**< 磁道处理*/ /*if(SetTrack(pData,tlvObj,bHasTrack)!=0) { trace_log(ERR, "SetTrack faile"); return -1; }else{ trace_log(DBG, "SetTrack SUCCESS"); }*/ //38授权码 if(strlen(pData->TransData.HeadData.OrigAuthCode) > 0) { bFlag &= sndObj.SetValueByStr(38, pData->TransData.HeadData.OrigAuthCode); } sndObj.SetValueByStr(39, "00"); //终端号 bFlag &= sndObj.SetValueByStr(41, pData->TransData.HeadData.arrRTermNo); //42商户号 bFlag &= sndObj.SetValueByStr(42, pData->TransData.HeadData.arrRMerchNo); //49货币代码 bFlag &= sndObj.SetValueByStr(49, "156"); /**< 52密码*/ /*if(SetPinKey(pData, tlvObj,bHasPin)!=0) { trace_log(ERR, "SetPinKey faile"); return -1; }else{ trace_log(DBG, "SetPinKey SUCCESS"); }*/ /* //55 IC卡数据域 nTlvLen= tlvObj.GetTLVItemByHex(TAG_FIELD55_RSP, (BYTE *)cICData, sizeof(cICData)); if(nTlvLen>0) { // bFlag &= sndObj.SetValueByHex(55, (BYTE *)cICData,nTlvLen); }else{ char cTrace[128]={0}; tlvObj.GetTLVItemByHex(TAG_TRACK2,(unsigned char*) cTrace, sizeof(cTrace)); int i=0; for(i=0;i<strlen(cTrace);i++) { if(0==memcmp(cTrace+i,"D",1)) { if((0==memcmp(cTrace+i+5,"2",1)||0==memcmp(cTrace+i+5,"6",1))) { memcpy(pData->TransData.HeadData.RspCode,"45",2); strcpy(pData->TransData.HeadData.RspDecs,"不允许降级交易"); return RET_PACK; }else{ break; } } } } */ /**< 22服务点输入方式码*/ bFlag &= sndObj.SetValueByStr(22,"021");//(char*)pData->TransData.HeadData.SvrPointCode //61凭证号批次号 nTlvLen= tlvObj.GetTLVItemByHex(TAG_RESERVED1, (BYTE *)cLField60, sizeof(cLField60)); memset(bTmpData, 0, sizeof(bTmpData)); if(nTlvLen>=6) { char cF60[18]={0}; BcdToAsc((BYTE *)cF60,(BYTE *)cLField60,nTlvLen); sprintf((char *)bTmpData, "%s%s%s%s%s", pData->BatchNo, "001","000000","00","0000000000"); memcpy(bTmpData+27,cF60+11,2); }else{ sprintf((char *)bTmpData, "%s%s%s", pData->BatchNo, "001","000000"); } bFlag &= sndObj.SetValueByStr(61, (char *)bTmpData); //62原始交易信息(信息类型码,系统跟踪号,交易日期和时间) memset(bTmpData, 0, sizeof(bTmpData)); sprintf((char *)bTmpData, "%s%s%s","0200", pData->TransData.HeadData.OrigLPosSeq,pData->cOri_DateTime); bFlag &= sndObj.SetValueByStr(62, (char *)bTmpData); //64MAC bFlag &= sndObj.SetValueByHex(64, (unsigned char*)"00000000", 8); /**< 组包*/ iBufLen = PACK_MAXLEN; bFlag &= sndObj.Pack(pBuffer, iBufLen); if(!bFlag) { trace_log(ERR, "Pack right CUPS8583 fail!"); return RET_PACK; } /**< 计算Mac */ /*BYTE bMac[9] = {0}; int nMacLen = 8; GenMacData(pData,sndObj,bMac); memcpy(pBuffer + iBufLen -nMacLen, bMac, nMacLen); return RET_SUCCESS;*/ }
//冲正 int CTradeDoReset::DoPack(SAConnection *saConn, void * pNode, unsigned char * pBuffer, unsigned & iBufLen) { if(saConn == NULL || pNode == NULL || pBuffer == NULL) { trace_log(ERR, "Paramter error!"); return RET_SYSEXP; } TRADEDATA * pData = (TRADEDATA *)pNode; CTLVTemplet tlvObj; if(1 != tlvObj.UnPackTLVData(pData->TransData.TlvDataLen, pData->TransData.TlvData)) { trace_log(ERR, "UnPackTLVData fail!"); return RET_SYSEXP; } bool bFlag = true, bIsICC = false; unsigned char cFieldData[FIELD_MAXLEN]={0};//bFieldData[FIELD_MAXLEN]={0}, unsigned int iFieldDataLen = 0; POS_TRADE_TYPE posType = (POS_TRADE_TYPE)pData->TransData.HeadData.RTradeType; if(m_unTradeOrgMap.empty()) initTredeTypeMap(); SAString sSql; SACommand Cmd; Cmd.setConnection(saConn); try { sSql.Format("select * from T_CHANNEL_RESETLIST where FIELD11='%s' and FIELD41='%s' and FIELD42='%s'" " and CRT_TYPE='%c' and CRT_BATCHNO='%s'", pData->TransData.HeadData.OrigLPosSeq, pData->TransData.HeadData.arrRTermNo, pData->TransData.HeadData.arrRMerchNo, m_unTradeOrgMap[posType], pData->TransData.HeadData.OrigLBatchNo); Cmd.setCommandText(sSql); Cmd.Execute(); if(!Cmd.FetchNext()) { trace_log(ERR, "select original trade record fail[%s]!", _T(sSql)); strcpy(pData->TransData.HeadData.RspCode, "25"); return RET_SYSEXP; } //0消息类型 bFlag &= sndObj.SetValueByStr(0, "0400"); //2账号 SAString str = Cmd.Field("FIELD2").asString(); if(str.GetLength() > 0) { bFlag &= sndObj.SetValueByStr(2, _T(str)); } //3处理码 bFlag &= sndObj.SetValueByStr(3, _T(Cmd.Field("FIELD3").asString())); //4金额 bFlag &= sndObj.SetValueByStr(4, _T(Cmd.Field("FIELD4").asString())); //11流水号 bFlag &= sndObj.SetValueByStr(11, _T(Cmd.Field("FIELD11").asString())); //14 卡的有效期 str = Cmd.Field("FIELD14").asString(); if(str.GetLength() > 0) { bFlag &= sndObj.SetValueByStr(14, _T(str)); } //22服务点输入方式 /*iFieldDataLen = tlvObj.GetTLVItemByHex(TAG_POSENTMODE, pData->TransData.HeadData.SvrPointCode, 2); if(iFieldDataLen > 0) { bFlag &= sndObj.SetValueByHex(22, pData->TransData.HeadData.SvrPointCode, 2); if(memcmp(pData->TransData.HeadData.SvrPointCode, "05", 2) == 0 || memcmp(pData->TransData.HeadData.SvrPointCode, "07", 2) == 0 || memcmp(pData->TransData.HeadData.SvrPointCode, "98", 2) == 0 || memcmp(pData->TransData.HeadData.SvrPointCode, "95", 2) == 0) bIsICC = true; }*/ str = Cmd.Field("FIELD22").asString(); if(str.GetLength() > 0) { bFlag &= sndObj.SetValueByStr(22, _T(str)); //char Field22[3] = {0}; //strcpy(Field22,_T(str)); if(memcmp(_T(str), "05", 2) == 0 ||memcmp(_T(str), "07", 2) == 0 || memcmp(_T(str), "98", 2) == 0 ||memcmp(_T(str), "95", 2) == 0) bIsICC = true; trace_log(DBG, "bIsICC=%d", bIsICC); } else { trace_log(ERR, "get FIELD22 from database failed!"); return RET_PACK; } //23IC卡序列号 if(pData->TransData.HeadData.RTradeType < POS_UNELEWALLETLOAD || pData->TransData.HeadData.RTradeType > POS_UNWALLETDEPOSIT) { str = Cmd.Field("FIELD23").asString(); if(str.GetLength() > 0) { bFlag &= sndObj.SetValueByStr(23, _T(str)); } } //25服务点条件码 bFlag &= sndObj.SetValueByStr(25, _T(Cmd.Field("FIELD25").asString())); //38原授权码 str = Cmd.Field("FIELD38").asString(); if(str.GetLength() > 0) { bFlag &= sndObj.SetValueByStr(38, _T(str)); } else if(posType == POS_UNPREAUTHREVE ||posType == POS_UNPREAUTHCPLREQ) { trace_log(ERR, "get FIELD38 from database failed!"); return RET_PACK; } //39 响应码 bFlag &= sndObj.SetValueByStr(39, _T(Cmd.Field("FIELD39").asString())); //41终端号 bFlag &= sndObj.SetValueByStr(41, _T(Cmd.Field("FIELD41").asString())); //42商户号 bFlag &= sndObj.SetValueByStr(42, _T(Cmd.Field("FIELD42").asString())); //48附加数据-私有 if(posType == POS_UNWALLETDEPOSIT || posType == POS_UNECTRANSLOAD) { bFlag &= sndObj.SetValueByStr(48, _T(Cmd.Field("FIELD48").asString())); } //49货币代码 bFlag &= sndObj.SetValueByStr(49, _T(Cmd.Field("FIELD49").asString())); //53安全控制信息 if(posType >= POS_UNREPEAL || posType <= POS_UNELEWALLETLOAD) { str = _T(Cmd.Field("").asString()); if(str.GetLength() > 0) { bFlag &= sndObj.SetValueByStr(53, _T(Cmd.Field("FIELD53").asString())); } } //55IC卡数据 if(bIsICC && (posType < POS_UNELEWALLETLOAD || posType > POS_UNWALLETDEPOSIT)) { memset(cFieldData, 0, sizeof(cFieldData)); CTLVTemplet tlvDB, tlvF55; unsigned char cICData[1024]={0}; str = Cmd.Field("FIELD55").asString(); iFieldDataLen = str.GetLength(); if(iFieldDataLen > 0) { AscToBcd(cICData, (unsigned char *)_T(str), iFieldDataLen); iFieldDataLen /= 2; if(1 != tlvDB.UnPackTLVData(iFieldDataLen, cICData)) { trace_log(ERR,"UnPackTLVData error!"); strcpy(pData->TransData.HeadData.RspCode, ERR_PACKMESSAGE); return RET_PACK; } if(pData->TransData.HeadData.RTradeType == POS_UNCONSUME || pData->TransData.HeadData.RTradeType == POS_UNPREAUTH || pData->TransData.HeadData.RTradeType == POS_UNFILLECASH|| pData->TransData.HeadData.RTradeType == POS_UNELECASHLOAD|| pData->TransData.HeadData.RTradeType == POS_UNECTRANSLOAD) {//消费冲正或预授权冲正需上送55域 iFieldDataLen = tlvObj.GetTLVItemByHex(TAG_TERMVERRET, cFieldData, sizeof(cFieldData)); if(iFieldDataLen > 0) { bFlag &= tlvF55.AddTLVItemByHex(GetTagTxt(TAG_TERMVERRET), iFieldDataLen, cFieldData); } iFieldDataLen = tlvDB.GetTLVItemByHex(TAG_INTDEVSERNO, cFieldData, sizeof(cFieldData)); if(iFieldDataLen > 0) { bFlag &= tlvF55.AddTLVItemByHex(GetTagTxt(TAG_INTDEVSERNO), iFieldDataLen, cFieldData); } iFieldDataLen = tlvObj.GetTLVItemByHex(TAG_ISSAPPDATA, cFieldData, sizeof(cFieldData)); if(iFieldDataLen > 0) { bFlag &= tlvF55.AddTLVItemByHex(GetTagTxt(TAG_ISSAPPDATA), iFieldDataLen, cFieldData); } iFieldDataLen = tlvDB.GetTLVItemByHex(TAG_APPTRACOU, cFieldData, sizeof(cFieldData)); if(iFieldDataLen > 0) { bFlag &= tlvF55.AddTLVItemByHex(GetTagTxt(TAG_APPTRACOU), iFieldDataLen, cFieldData); } iFieldDataLen = tlvObj.GetTLVItemByHex(TAG_ISSCRIRET, cFieldData, sizeof(cFieldData)); if(iFieldDataLen > 0) { bFlag &= tlvF55.AddTLVItemByHex(GetTagTxt(TAG_ISSCRIRET), iFieldDataLen, cFieldData); } iFieldDataLen = sizeof(cFieldData); bFlag &= tlvF55.PackTLVData(cFieldData, (unsigned &)iFieldDataLen); bFlag &= sndObj.SetValueByHex(55, cFieldData, iFieldDataLen); } } } //58 PBOC电子钱包/存折标准的交易信息 if(posType >= POS_UNELEWALLETLOAD && posType <= POS_UNWALLETDEPOSIT) { bFlag &= sndObj.SetValueByStr(58, _T(Cmd.Field("FIELD58").asString())); } //60 bFlag &= sndObj.SetValueByStr(60, _T(Cmd.Field("FIELD60").asString())); //61 原始信息域 if(posType == POS_UNPREAUTHCPLREQ || (posType >= POS_REPEAL && posType <= POS_FILLECASHREVE)) { bFlag &= sndObj.SetValueByStr(61, _T(Cmd.Field("FIELD61").asString())); } //62 if(posType == POS_UNWALLETDEPOSIT || posType == POS_UNECTRANSLOAD || posType == POS_UNCONSUME) { str = _T(Cmd.Field("FIELD62").asString()); if(str.GetLength() > 0) { bFlag &= sndObj.SetValueByStr(62, _T(str)); } else if(posType != POS_UNCONSUME) { trace_log(ERR, "get FIELD62 from database failed!"); return RET_PACK; } } } catch (SAException &e) { saConn->Rollback(); trace_log(ERR,"database exceptions:%s ,SQL = [%s]",_T(e.ErrText()),_T(sSql)); return -1; } catch (...) { trace_log(ERR, "Execute sql fail[sql:%s]!", _T(sSql)); return -1; } //64MAC bFlag &= sndObj.SetValueByHex(64, (unsigned char*)"00000000", 8); /*unsigned char cMacBuf[FIELD_MAXLEN] = {0}; if(1 != sndObj.GetMacData(cMacBuf, sizeof(cMacBuf))) { trace_log(ERR,"Get mac failed!"); return RET_GETMACERR; } bFlag &= sndObj.SetValueByHex(64, cMacBuf, 8);*/ //组包 iBufLen = PACK_MAXLEN; bFlag &= sndObj.Pack(pBuffer, iBufLen); if(!bFlag) { trace_log(ERR, "Pack right CUPS8583 fail!"); return RET_PACK; } //计算MAC BYTE bMab[PACK_MAXLEN] = {0}; BYTE bMac[9] = {0}; BYTE bTak[17] = {0}; int nMabPos = 2 + 5 + 6; int nMacLen = 8; Ccommon::Str2Hex((char *)pData->bMacKey, bTak, (sizeof(bTak) - 1)*2); memcpy(bMab, pBuffer + nMabPos, iBufLen - nMabPos - nMacLen); if(!m_checkMesValue.GenMacData(bMab, iBufLen - nMabPos - nMacLen, bTak, bMac)) { memcpy((pBuffer + iBufLen -nMacLen), bMac, nMacLen); } #if 0 unsigned char ucMab[1024]={0}; unsigned char ucTmp[9] = {0}; // 如果是非指定账户转账类圈存算MAC需要修改为转账类的计算MAC方法 if (pData->TransData.HeadData.RTradeType == POS_UNECTRANSLOAD) ucMab[0] = 1; int iMabLen = sndObj.GetMacData(ucMab, sizeof(ucMab)); if(iMabLen > 0) { if(!g_EncComm->CalculateMac(g_Cfg.SndBrchCode, g_Cfg.RcvBrchCode, ucMab, iMabLen, ucTmp, 2, 0)) { trace_log(ERR,"CalculateMac fail!"); return RET_SYSEXP; } BcdToAsc(pBuffer+iBufLen-8, ucTmp, 4); } else { trace_log(ERR,"GetMacData fail!"); return RET_SYSEXP; } #endif return RET_SUCCESS; }