pinpadimpl.cpp 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702
  1. #include "pinpadimpl.h"
  2. #include "cmb.h"
  3. PinPadImpl::PinPadImpl()
  4. {
  5. m_MacType = EPP_MAC_ALGO_ASNIX99;
  6. m_PinType = EPP_PIN_ALGO_ISO9564_1_ANSI;
  7. m_Ecb_Cbc = EPP_ALGO_MODE_ECB;
  8. memset(&m_DevErrInfo, 0, sizeof(m_DevErrInfo));
  9. m_bIsOPen = false;
  10. m_pPinpad=new PinPadXZF31();
  11. m_iPinLen = 0;
  12. m_sCardNo[0] = 0;
  13. m_iWorkKey = -1;
  14. m_EncType = EPP_ALGO_METHOD_3DES;
  15. m_bSMMode = false;
  16. m_bPinMode = false;
  17. m_iKeyGot = 0;
  18. }
  19. PinPadImpl::~PinPadImpl()
  20. {
  21. delete m_pPinpad;
  22. }
  23. int getFileVer(char* sFile, short& ch1, short& ch2)
  24. {
  25. ch1 = 0;
  26. ch2 = 0;
  27. char* pFind = strstr(sFile, ".so");
  28. char* pTemp = pFind;
  29. while (pTemp)
  30. {
  31. pFind = pTemp;
  32. pTemp = strstr(pFind + 3, ".so");
  33. }
  34. if (pFind == NULL) return 0;
  35. pTemp = pFind - 1;
  36. while(isdigit(*pTemp) && pTemp > sFile) pTemp--;
  37. if (*pTemp == '.')
  38. ch2 = atoi(pTemp+1);
  39. pTemp--;
  40. while(isdigit(*pTemp) && pTemp > sFile) pTemp--;
  41. if (*pTemp == '.')
  42. ch1 = atoi(pTemp+1);
  43. return 1;
  44. }
  45. ErrorCodeEnum PinPadImpl::GetDevCategory(DevCategoryInfo &devCategory)
  46. {
  47. LOG4VTM_FUNCTION();
  48. if (!m_bIsOPen)
  49. return GetErrorInfo(-1, "GetDevCategory");
  50. char szType[] = {"PVER=SUNSON#MID=SNK088A"};
  51. char szModel[] = {"PM=V2.0#MID=00000000#PID=00000000#FWID=%s"};
  52. char szVendor[] = {"cw"};
  53. ErrorCodeEnum err = Error_Succeed;
  54. strcpy(devCategory.szType, szType);
  55. strcpy(devCategory.szVendor, szVendor);
  56. char sPath[256], sFile[128] = {0};
  57. GetCurLibsPath(sPath, sFile);
  58. short v1,v2;
  59. getFileVer(sFile, v1, v2);
  60. devCategory.version.wMajor = v1;
  61. devCategory.version.wMinor = v2;
  62. devCategory.version.wRevision = 0xffff;
  63. devCategory.version.wBuild = FILE_VERSION;
  64. unsigned char sTemp[256];
  65. int iRet = m_pPinpad->getEppVersion(sTemp);
  66. iRet = GetErrorInfo(iRet, "GetDevCategory");
  67. if (iRet == Error_Succeed)
  68. {
  69. char* pSP = strstr((char*)sTemp, "F31-V");
  70. if (pSP)
  71. sprintf(devCategory.szModel, szModel, pSP + 5); //XZ-H602-F31-V1.03-D015
  72. else
  73. sprintf(devCategory.szModel, szModel, "00000000");
  74. }
  75. else
  76. {
  77. sprintf(devCategory.szModel, szModel, "00000000");
  78. }
  79. switch(iRet){
  80. case Error_Succeed:
  81. case Error_Param:
  82. devCategory.eState = DEVICE_STATUS_NORMAL;
  83. break;
  84. case Error_Closed:
  85. devCategory.eState = DEVICE_STATUS_NOT_READY;
  86. break;
  87. case Error_Hardware:
  88. default:
  89. devCategory.eState = DEVICE_STATUS_FAULT;
  90. }
  91. char sLog[512];
  92. sprintf(sLog, "GetDevCategory devCategory.version.wBuild =%d, devCategory.szType=%s ", devCategory.version.wBuild, devCategory.szType);
  93. LOG4VTM(INFO, sLog);
  94. return Error_Succeed;
  95. }
  96. // Get the encrypt method supported.
  97. // return value:
  98. // 0x1:3des only; 0x2:sm4 only; 0x3:both 3des and sm4
  99. int PinPadImpl::GetEncryptFunc()
  100. {
  101. return 3;
  102. }
  103. // Reset device.
  104. // Do the cleaning work and initialize device again in order to return to
  105. // the normal condition.
  106. ErrorCodeEnum PinPadImpl::Reset()
  107. {
  108. LOG4VTM_FUNCTION();
  109. if (!m_bIsOPen)
  110. return GetErrorInfo(-1, "Reset");
  111. int iRet = m_pPinpad->resetEpp();
  112. iRet = GetErrorInfo(iRet, "Reset");
  113. return (ErrorCodeEnum)iRet;
  114. }
  115. // Close device and do the cleaning work.
  116. // ex. close connection,close port,release memery and so on
  117. ErrorCodeEnum PinPadImpl::DevClose()
  118. {
  119. LOG4VTM_FUNCTION();
  120. if (!m_bIsOPen)
  121. return GetErrorInfo(-1, "DevClose");
  122. StopInput();
  123. m_pPinpad->closeDevice();
  124. LOG4VTM(INFO, "device closed");
  125. m_bIsOPen = false;
  126. return Error_Succeed;
  127. }
  128. // Get last error the device issued.
  129. // Error message must include explanatory memorandum ,the original error
  130. // code and anything in favour of location problem.
  131. ErrorCodeEnum PinPadImpl::GetLastErr(DevErrorInfo &devErrInfo)
  132. {
  133. memcpy(&devErrInfo, &m_DevErrInfo, sizeof(DevErrorInfo));
  134. return Error_Succeed;
  135. }
  136. //
  137. // Open device.
  138. // Arguments:
  139. // - dwPort[in] com port number
  140. // - dwBaudRate[in] Baud rate
  141. //
  142. ErrorCodeEnum PinPadImpl::DevOpen(DWORD dwPort,DWORD dwBaudRate)
  143. {
  144. LOG4VTM_FUNCTION();
  145. char sPort[16],sGet[32];
  146. m_bIsOPen = false;
  147. sprintf(sPort, "COM%d", dwPort);
  148. if (SIni::GetValueFromIniFile("/cashway/setting/cashway.ini", "Serial", sPort, sGet, 30))
  149. strcpy(sPort, sGet);
  150. // if (!SIni::GetValueFromIniFile("/cashway/setting/cashway.ini", "Serial", "SMFlg", m_sKeyAttr, 32))
  151. // strcpy(m_sKeyAttr, "00000000000000000000000000000000");
  152. // m_sKeyAttr[32] = 0;
  153. if (m_pPinpad->Open(sPort, dwBaudRate))
  154. {
  155. m_bIsOPen = true;
  156. int iRet = m_pPinpad->resetEpp();
  157. iRet = GetErrorInfo(iRet, "DevOpen resetEpp");
  158. if (iRet != 0)
  159. return (ErrorCodeEnum)iRet;
  160. unsigned char sMode[32];
  161. iRet = m_pPinpad->GetEPPSMMode(sMode);
  162. iRet = GetErrorInfo(iRet, "DevOpen GetEPPSMMode");
  163. if (iRet != 0)
  164. return (ErrorCodeEnum)iRet;
  165. m_bSMMode = sMode[0] == 1;
  166. return GetErrorInfo(0, "DevOpen");
  167. }
  168. return GetErrorInfo(-1, "DevOpen");
  169. }
  170. // DEC_SUCCESS DEC_HARDWARE DEC_TIMEOUT DEC_INVALID_PARAMETER DEC_INVALID_MASTER_KEY
  171. const static CmbErrorDef sunsonErrInfo[] = {
  172. {0, "成功", Error_Succeed, DEC_SUCCESS},
  173. {-1, "指定的设备未打开", Error_Hardware, DEC_DEV_NOT_OPENED},
  174. {-2, "设备响应超时", Error_DevCommFailed, DEC_TIMEOUT},
  175. {-3, "传入参数错误", Error_Param, DEC_INVALID_PARAMETER},
  176. // //8088 错误码
  177. // {0x04, "命令成功执行", Error_Succeed, DEC_SUCCESS},
  178. // {0x15, "命令参数错", Error_Param, DEC_INVALID_PARAMETER},
  179. // {0x80, "超时错误", Error_Hardware, DEC_HARDWARE},
  180. // {0xA4, "主密钥无效", Error_Param, DEC_INVALID_PARAMETER},
  181. // {0xB5, "命令主密钥无效", Error_Param, DEC_HARDWARE},
  182. // {0xC4, "键盘电池可能损坏", Error_Hardware, DEC_HARDWARE},
  183. // {0xD5, "命令无效且电池损坏", Error_Param, DEC_HARDWARE},
  184. // {0xE0, "无效命令", Error_Param, DEC_INVALID_PARAMETER},
  185. // {0xF0, "CPU 错", Error_Hardware, DEC_HARDWARE},
  186. // {0xF1, "SRAM 错", Error_Hardware, DEC_HARDWARE},
  187. // {0xF2, "键盘有短路", Error_Hardware, DEC_HARDWARE},
  188. // {0xF3, "串口电平错", Error_Hardware, DEC_HARDWARE},
  189. // {0xF4, "CPU 卡出错", Error_Hardware, DEC_HARDWARE},
  190. // {0xF5, "电池可能损坏", Error_Hardware, DEC_HARDWARE},
  191. // {0xF6, "主密钥失效", Error_Hardware, DEC_HARDWARE},
  192. // {0xF7, "杂项错", Error_Hardware, DEC_HARDWARE},
  193. //F31错误码
  194. {0x02, "算法模式错误", Error_Param, DEC_INVALID_PARAMETER},
  195. {0x03, "指令格式错", Error_Param, DEC_INVALID_PARAMETER},
  196. {0x03, "密钥不存在", Error_Param, DEC_INVALID_PARAMETER},
  197. {0x0e, "密钥不存在", Error_Param, DEC_INVALID_PARAMETER},
  198. {0x0f, "密钥存在", Error_Param, DEC_INVALID_PARAMETER},
  199. {0x10, "密钥属性错", Error_Param, DEC_INVALID_PARAMETER},
  200. {0x12, "下载密钥失败", Error_Hardware, DEC_HARDWARE},
  201. {0x13, "Hash 类型错误", Error_Param, DEC_INVALID_PARAMETER},
  202. {0x17, "密钥号超出范围", Error_Param, DEC_INVALID_PARAMETER},
  203. {0x19, "无 PIN", Error_Param, DEC_INVALID_PARAMETER},
  204. {0x1c, "PIN 长度错", Error_Param, DEC_INVALID_PARAMETER},
  205. {0x1d, "卡号长度错", Error_Param, DEC_INVALID_PARAMETER},
  206. {0x30, "PINBLOCK 时卡号有误", Error_Param, DEC_INVALID_PARAMETER},
  207. {0x31, "数据运算时数据长度出错", Error_Param, DEC_INVALID_PARAMETER},
  208. {0x40, "无客户信息", Error_Param, DEC_INVALID_PARAMETER},
  209. {0x42, "密钥长度错", Error_Param, DEC_INVALID_PARAMETER},
  210. {0x47, "国密运算超时", Error_Hardware, DEC_HARDWARE},
  211. {0x48, "国密运算错误", Error_Hardware, DEC_HARDWARE},
  212. {0x50, "RSA E 值错误", Error_Hardware, DEC_HARDWARE},
  213. {0x51, "RSA 密钥长度错误", Error_Hardware, DEC_HARDWARE},
  214. {0x52, "RSA 签名数据错误", Error_Hardware, DEC_HARDWARE},
  215. {0x53, "RSA DER 错误", Error_Hardware, DEC_HARDWARE},
  216. {0x54, "RSA 运算错误", Error_Hardware, DEC_HARDWARE},
  217. {0x55, "RSA 公钥不存在", Error_Hardware, DEC_HARDWARE},
  218. {0xb0, "DER 数据长度错误", Error_Param, DEC_INVALID_PARAMETER},
  219. {0xb1, "填充算法错误", Error_Param, DEC_INVALID_PARAMETER},
  220. {0xb2, "密钥模长 N 错误", Error_Param, DEC_INVALID_PARAMETER},
  221. {0xb3, "运算数据长度错误", Error_Param, DEC_INVALID_PARAMETER},
  222. {0xb4, "内存不足", Error_Hardware, DEC_HARDWARE},
  223. {0xb5, "HASH 算法错误", Error_Param, DEC_INVALID_PARAMETER},
  224. {0xb6, "数据包错误", Error_Param, DEC_INVALID_PARAMETER},
  225. {0xb7, "---", Error_Hardware, DEC_HARDWARE},
  226. {0xb8, "验签失败", Error_Hardware, DEC_HARDWARE},
  227. };
  228. ErrorCodeEnum PinPadImpl::GetErrorInfo(int iCode, char* sErr, ...)
  229. {
  230. size_t iLenOne = sizeof(CmbErrorDef);
  231. size_t iLenAll = sizeof(sunsonErrInfo);
  232. int iCount = iLenAll / iLenOne;
  233. char sErrInfo[256]="";
  234. DWORD dSta = 0;
  235. int iErr = -1;
  236. for (int ia = 0; ia < iCount; ia++)
  237. {
  238. if (sunsonErrInfo[ia].iCode == iCode)
  239. {
  240. dSta = sunsonErrInfo[ia].iInf;
  241. strcpy(sErrInfo, sunsonErrInfo[ia].sInf);
  242. iErr = sunsonErrInfo[ia].iRet;
  243. break;
  244. }
  245. }
  246. if (iErr == -1)
  247. {
  248. sprintf(sErrInfo, "error code %02x", iCode);
  249. iErr = Error_Hardware;
  250. dSta = DEC_HARDWARE;
  251. }
  252. char sErrAll[300];
  253. va_list arglist;
  254. va_start(arglist, sErr);
  255. _vsnprintf(sErrAll, 128, sErr, arglist);
  256. va_end(arglist);
  257. if (sErrInfo[0])
  258. {
  259. strcat(sErrAll, " ");
  260. strcat(sErrAll, sErrInfo);
  261. }
  262. sErrAll[200] = 0;
  263. iLenOne = strlen(sErrAll);
  264. sprintf(m_DevErrInfo.szErrMsg, "{\"ErrCode\":\"%04x\",\"Description\":\"%s\"}", iErr, sErrAll);
  265. // strcpy(m_DevErrInfo.szErrMsg, sErrAll);
  266. m_DevErrInfo.dwErrMsgLen = ((dSta << 16) & 0xffff0000) + iLenOne;
  267. if (iErr != 0)
  268. LOG4VTM(WARN, m_DevErrInfo.szErrMsg);
  269. else
  270. LOG4VTM(INFO, m_DevErrInfo.szErrMsg);
  271. return (ErrorCodeEnum)iErr;
  272. }
  273. // Set pinpad parameter.
  274. ErrorCodeEnum PinPadImpl::SetParam(SetParamTypeEnum eType,SetParamValueEnum eValue)
  275. {
  276. LOG4VTM_FUNCTION();
  277. char sLog[512];
  278. sprintf(sLog, "SetParam eType=%d, eValue=%d", (int)eType, (int)eValue);
  279. LOG4VTM(INFO, sLog);
  280. ErrorCodeEnum eRt = Error_Succeed;
  281. switch(eType)
  282. {
  283. case EPP_PT_SET_ENCRYPT_METHOD:
  284. m_EncType = eValue;
  285. break;
  286. case EPP_PT_SET_MAC_ALGORITH:
  287. m_MacType = eValue;
  288. break;
  289. case EPP_PT_SET_PIN_ALGORITH:
  290. m_PinType = eValue;
  291. break;
  292. case EPP_PT_SET_ECB_CBC_MODE:
  293. m_Ecb_Cbc = eValue;
  294. break;
  295. default:
  296. eRt = Error_Param;
  297. break;
  298. }
  299. return Error_Succeed;
  300. }
  301. ErrorCodeEnum PinPadImpl::SetAccNo(AccountInfo accInfo)
  302. {
  303. LOG4VTM_FUNCTION();
  304. int iLen = accInfo.dwAccLen;
  305. unsigned char sTemp[33];
  306. memcpy(sTemp, accInfo.account, 32);
  307. sTemp[iLen] = 0;
  308. unsigned char* pNo = sTemp;
  309. if (iLen > 13)
  310. {
  311. pNo += (iLen - 13);
  312. iLen = 13;
  313. }
  314. if (iLen > 12)
  315. {
  316. pNo[12] = 0;
  317. iLen = 12;
  318. }
  319. strcpy(m_sCardNo, (char*)pNo);
  320. char sLog[256];
  321. sprintf(sLog, "SetAccNo %s", m_sCardNo);
  322. LOG4VTM(DEBUG, sLog);
  323. return Error_Succeed;
  324. }
  325. ErrorCodeEnum PinPadImpl::KeyRead(BYTE &ch)
  326. {
  327. LOG4VTM_FUNCTION();
  328. if (!m_bIsOPen)
  329. return GetErrorInfo(-1, "KeyRead");
  330. int iRet = m_pPinpad->scankeyPress(ch);
  331. if (iRet < 0)
  332. return GetErrorInfo(JT_HARDWARE_ERROR, "KeyRead");
  333. if (iRet == 0)
  334. return GetErrorInfo(JT_TIMEOUT, "KeyRead");
  335. if (m_bPinMode)
  336. {
  337. if (ch == 0x0d)
  338. return GetErrorInfo(JT_TIMEOUT, "KeyRead ch=0d");
  339. m_iKeyGot++;
  340. char sLog[256];
  341. sprintf(sLog, "KeyRead pin mode len =%d key=%d", m_iKeyGot, ch);
  342. LOG4VTM(INFO, sLog);
  343. if (ch == 0x2a) ch = 0x3f;
  344. if (ch == 0x2e || ch == 0x54) ch = 0x3d;
  345. if (ch == 0x08)
  346. {
  347. StartPinInput(m_iPinLen, m_bAutoEnd);
  348. m_iKeyGot = 0;
  349. }
  350. if (ch == 0x1b || //ch == 0x0d ||
  351. m_iKeyGot >= m_iPinLen)
  352. {
  353. unsigned char sTemp[32];
  354. m_pPinpad->SetBuzzerEnabled(0x31, sTemp);
  355. }
  356. }
  357. return Error_Succeed;
  358. }
  359. // Load master key. (in plain text)
  360. // [key]:byte value in string type. ex. 0x123456FF --> "123456FF"
  361. ErrorCodeEnum PinPadImpl::LoadMasterKey(MasterKeyParam masterKey)
  362. {
  363. LOG4VTM_FUNCTION();
  364. if (!m_bIsOPen)
  365. return GetErrorInfo(-1, "LoadMasterKey");
  366. int iLen = strlen((char*)masterKey.key);
  367. if (iLen != 32)
  368. return GetErrorInfo(JT_PARA_ERR, "LoadMasterKey keylen= %d", iLen);
  369. char sLog[256];
  370. int iRet = 0;
  371. if (m_bSMMode != masterKey.smFlag)
  372. {
  373. iRet = m_pPinpad->SetEPPSMMode(masterKey.smFlag);
  374. sprintf(sLog, "LoadMasterKey SetEPPSMMode %d ret%d", masterKey.smFlag, iRet);
  375. LOG4VTM(INFO, sLog);
  376. if (iRet != Error_Succeed)
  377. return GetErrorInfo(iRet, "LoadMasterKey SetEPPSMMode");
  378. m_bSMMode = masterKey.smFlag;
  379. }
  380. unsigned char sTemp[32];
  381. m_pPinpad->EnableLoadSameKey(0x00, sTemp);
  382. ::HexStrToANSI((char*)masterKey.key, sTemp, iLen);
  383. int iMK = MK_HEAD + masterKey.dwSN;
  384. // m_sKeyAttr[iMK] = '0';
  385. iRet = m_pPinpad->LoadUserKey(iMK, 0xffff, 0x27, iLen>>1, sTemp, sTemp);
  386. iRet = GetErrorInfo(iRet, "LoadMasterKey sm=%d mk= %d", masterKey.smFlag, masterKey.dwSN);
  387. // if (iRet == 0)
  388. // {
  389. // if (m_sKeyAttr[iMK] - '0' != masterKey.smFlag)
  390. // {
  391. // m_sKeyAttr[iMK] = masterKey.smFlag + '0';
  392. // SIni::SetValueToIniFile("/cashway/setting/cashway.ini", "Serial", "SMFlg", m_sKeyAttr);
  393. // sprintf(sLog, "LoadMasterKey save key SM flag %d %d", iMK, masterKey.smFlag);
  394. // LOG4VTM(INFO, sLog);
  395. // }
  396. // }
  397. return (ErrorCodeEnum)iRet;
  398. }
  399. // Load working key. (encrypted data)
  400. // Use the according master key to decrypt the key,then load result into pinpad
  401. // [key]:byte value in string type. ex. 0x123456FF --> "123456FF"
  402. ErrorCodeEnum PinPadImpl::LoadWorkingKey(WorkKeyParam wkKey)
  403. {
  404. LOG4VTM_FUNCTION();
  405. if (!m_bIsOPen)
  406. return GetErrorInfo(-1, "LoadWorkingKey");
  407. int iLen = strlen((char*)wkKey.key);
  408. if (iLen != 32)
  409. return GetErrorInfo(JT_PARA_ERR, "LoadWorkingKey keylen= %d", iLen);
  410. bool bSM = wkKey.smFlag == 1;
  411. int iRet = 0;
  412. if (m_bSMMode != bSM)
  413. {
  414. iRet = m_pPinpad->SetEPPSMMode(wkKey.smFlag);
  415. if (iRet != Error_Succeed)
  416. return GetErrorInfo(iRet, "LoadMasterKey setModeSMAlgorithm");
  417. m_bSMMode = bSM;
  418. }
  419. iRet = m_pPinpad->CheckEPPSMMode(m_bSMMode);
  420. if (iRet != Error_Succeed)
  421. return GetErrorInfo(iRet, "LoadMasterKey setModeSMAlgorithm");
  422. unsigned char sTemp[32];
  423. ::HexStrToANSI((char*)wkKey.key, sTemp, iLen);
  424. int iWk = WK_HEAD + wkKey.dwMasterSN * 4 + wkKey.dwWorkingSN;
  425. iRet = m_pPinpad->LoadUserKey(iWk, MK_HEAD + wkKey.dwMasterSN, 0x07, iLen>>1, sTemp, sTemp);
  426. iRet = GetErrorInfo(iRet, "LoadWorkingKey activeKey sm=%d mk= %d wk = %d", wkKey.smFlag, wkKey.dwMasterSN, wkKey.dwWorkingSN);
  427. // if (iRet == 0)
  428. // {
  429. // if (m_sKeyAttr[iWk] - '0' != wkKey.smFlag)
  430. // {
  431. // m_sKeyAttr[iWk] = wkKey.smFlag + '0';
  432. // SIni::SetValueToIniFile("/cashway/setting/cashway.ini", "Serial", "SMFlg", m_sKeyAttr);
  433. // }
  434. // }
  435. return (ErrorCodeEnum)iRet;
  436. }
  437. // - dwMkSN:master key serial number
  438. // - dwWkSN:working key serial number
  439. // - ActiveWorkingKey(主密钥序号,99)表示激活“主密钥序号”的主密钥作为当前工作密钥
  440. ErrorCodeEnum PinPadImpl::ActiveWorkingKey(DWORD dwMkSN, DWORD dwWkSN)
  441. {
  442. LOG4VTM_FUNCTION();
  443. if (!m_bIsOPen)
  444. return GetErrorInfo(-1, "ActiveWorkingKey");
  445. int iRet = 0;
  446. if (dwWkSN == 99)
  447. m_iWorkKey = MK_HEAD + dwMkSN;
  448. else
  449. m_iWorkKey = WK_HEAD + dwMkSN * 4 + dwWkSN;
  450. iRet = GetErrorInfo(iRet, "ActiveWorkingKey mk= %d wk= %d", dwMkSN, dwWkSN);
  451. /*
  452. if (m_bSMMode != m_sKeyAttr[m_iWorkKey] - '0')
  453. {
  454. iRet = m_pPinpad->SetEPPSMMode(m_sKeyAttr[m_iWorkKey] - '0');
  455. if (iRet != Error_Succeed)
  456. return GetErrorInfo(iRet, "ActiveWorkingKey setModeSMAlgorithm");
  457. m_bSMMode = m_sKeyAttr[m_iWorkKey] - '0';
  458. }
  459. //*/
  460. return (ErrorCodeEnum)iRet;
  461. }
  462. ErrorCodeEnum PinPadImpl::StartPinInput(int iLen, bool bAutoEnd)
  463. {
  464. m_iPinLen = iLen;
  465. m_bAutoEnd = bAutoEnd;
  466. m_iKeyGot = 0;
  467. int iRet = 0;
  468. unsigned char sTemp[33];
  469. bool bSM = (m_PinType == EPP_PIN_ALGO_SM4);
  470. if (m_bSMMode != bSM)
  471. {
  472. int iRet = m_pPinpad->SetEPPSMMode(bSM);
  473. char sLog[256];
  474. sprintf(sLog, "StartPinInput SetEPPSMMode %d ret%d", bSM, iRet);
  475. LOG4VTM(INFO, sLog);
  476. if (iRet != Error_Succeed)
  477. return GetErrorInfo(iRet, "SetParam SetEPPSMMode");
  478. m_bSMMode = bSM;
  479. }
  480. Sleep(50);
  481. iRet = m_pPinpad->SetBuzzerEnabled(0x30, sTemp);
  482. iRet = GetErrorInfo(iRet, "StartPinInput SetBuzzerEnabled");
  483. if (iRet != Error_Succeed) return (ErrorCodeEnum)iRet;
  484. Sleep(50);
  485. iRet = m_pPinpad->GetPin(iLen, iLen, bAutoEnd, sTemp);
  486. iRet = GetErrorInfo(iRet, "StartPinInput ret %d %02x", iRet, iRet);
  487. if (iRet == 0)
  488. m_bPinMode = true;
  489. return (ErrorCodeEnum)iRet;
  490. }
  491. // Start key press(pin mode).
  492. // byLen:输入密码长度,键盘检测到用户输入确认键后结束输入,计算pinblock
  493. //
  494. ErrorCodeEnum PinPadImpl::StartPinInputConfirm(BYTE byLen)
  495. {
  496. LOG4VTM_FUNCTION();
  497. if (!m_bIsOPen)
  498. return GetErrorInfo(-1, "StartPinInputConfirm");
  499. return StartPinInput(byLen, true);
  500. }
  501. ErrorCodeEnum PinPadImpl::StartPinInput(BYTE byLen)
  502. {
  503. LOG4VTM_FUNCTION();
  504. if (!m_bIsOPen)
  505. return GetErrorInfo(-1, "StartPinInput");
  506. return StartPinInput(byLen, false);
  507. }
  508. // Start key press(plain text mode).
  509. ErrorCodeEnum PinPadImpl::StartPlainInput()
  510. {
  511. LOG4VTM_FUNCTION();
  512. if (!m_bIsOPen)
  513. return GetErrorInfo(-1, "StartPlainInput");
  514. unsigned char sTemp[33];
  515. int iRet = 0;
  516. iRet = m_pPinpad->SetBuzzerEnabled(0x30, sTemp);
  517. iRet = GetErrorInfo(iRet, "StartPlainInput SetBuzzerEnabled");
  518. if (iRet != Error_Succeed) return (ErrorCodeEnum)iRet;
  519. iRet = m_pPinpad->UseEppPlainTextMode(0, 0, sTemp);
  520. iRet = GetErrorInfo(iRet, "StartPlainInput");
  521. m_bPinMode = false;
  522. return (ErrorCodeEnum)iRet;
  523. }
  524. ErrorCodeEnum PinPadImpl::StopInput()
  525. {
  526. LOG4VTM_FUNCTION();
  527. if (!m_bIsOPen)
  528. return GetErrorInfo(-1, "StopInput");
  529. m_bPinMode = false;
  530. unsigned char sTemp[33];
  531. int iRet = m_pPinpad->CloseEppPlainTextMode(sTemp);
  532. iRet = GetErrorInfo(iRet, "StopInput ");
  533. iRet = m_pPinpad->SetBuzzerEnabled(0x31, sTemp);
  534. iRet = GetErrorInfo(iRet, "StopInput SetBuzzerEnabled");
  535. return (ErrorCodeEnum)iRet;
  536. }
  537. ErrorCodeEnum PinPadImpl::GetPinBlock(PinBlock &block)
  538. {
  539. LOG4VTM_FUNCTION();
  540. if (!m_bIsOPen)
  541. return GetErrorInfo(-1, "GetPinBlock");
  542. unsigned char sPinRead[32];
  543. int iMode = 0x34;
  544. if (m_PinType == EPP_PIN_ALGO_ISO9564_1_ANSI || m_PinType == EPP_PIN_ALGO_SM4)
  545. iMode = 0x30;
  546. int iLenOut = 0;
  547. int iRet = m_pPinpad->GetPinBlock(m_iWorkKey, iMode, 0x00, strlen(m_sCardNo), (unsigned char*)m_sCardNo, sPinRead, iLenOut);
  548. iRet = GetErrorInfo(iRet, "GetPinBlock");
  549. if (iRet == Error_Succeed)
  550. {
  551. int iLength = m_bSMMode ? 16 : 8;
  552. block.dwSize = (iLength << 1);
  553. ANSIToHexStr(sPinRead, iLength, (char*)block.data);
  554. }
  555. return (ErrorCodeEnum)iRet;
  556. }
  557. // - srcInfo.data:source plain text data
  558. // (byte value in string type. ex. 0x123456FF --> "123456FF")
  559. // - destInfo.data:destination encrypted data
  560. ErrorCodeEnum PinPadImpl::EncryptData(EnDecryptInfo srcInfo, EnDecryptInfo &destInfo)
  561. {
  562. LOG4VTM_FUNCTION();
  563. if (!m_bIsOPen)
  564. return GetErrorInfo(-1, "DevClose");
  565. bool bSM = (m_EncType == EPP_ALGO_METHOD_SM4);
  566. if (m_bSMMode != bSM)
  567. {
  568. int iRet = m_pPinpad->SetEPPSMMode(bSM);
  569. char sLog[256];
  570. sprintf(sLog, "EncryptData SetEPPSMMode %d ret%d", bSM, iRet);
  571. LOG4VTM(INFO, sLog);
  572. if (iRet != Error_Succeed)
  573. return GetErrorInfo(iRet, "EncryptData SetEPPSMMode");
  574. m_bSMMode = bSM;
  575. }
  576. unsigned char sData[260], sOut[260];
  577. int iSize = min((size_t)srcInfo.dwSize, strlen((char*)srcInfo.data));
  578. HexStrToANSI((const char*)srcInfo.data, sData, iSize);
  579. int iRet = 0;
  580. iSize /= 2;
  581. int iOut = 0;
  582. switch (m_Ecb_Cbc)
  583. {
  584. case EPP_ALGO_MODE_DEC_ECB:
  585. case EPP_ALGO_MODE_3DEC_ECB:
  586. case EPP_ALGO_MODE_ECB:
  587. iRet = m_pPinpad->DataCompute(m_iWorkKey, 0x31, 0x30, 0x0f, iSize, sData, sOut, iOut);
  588. break;
  589. case EPP_ALGO_MODE_DEC_CBC:
  590. case EPP_ALGO_MODE_3DEC_CBC:
  591. case EPP_ALGO_MODE_CBC:
  592. iRet = m_pPinpad->DataCompute(m_iWorkKey, 0x31, 0x31, 0x0f, iSize, sData, sOut, iOut);
  593. break;
  594. default:
  595. iRet = JT_PARA_ERR;
  596. }
  597. iRet = GetErrorInfo(iRet, "EncryptData");
  598. if (iRet == Error_Succeed)
  599. {
  600. destInfo.dwSize = (iOut << 1);
  601. ANSIToHexStr(sOut, iOut, (char*)destInfo.data);
  602. }
  603. return (ErrorCodeEnum)iRet;
  604. }
  605. // - srcInfo.data:source plain text data
  606. // (byte value in string type. ex. 0x123456FF --> "123456FF")
  607. // - destInfo.data:destination encrypted data
  608. ErrorCodeEnum PinPadImpl::MacEncrypt(EnDecryptInfo srcInfo, EnDecryptInfo &destInfo)
  609. {
  610. //该功能没有使用,实际传入参数不清楚
  611. LOG4VTM_FUNCTION();
  612. if (!m_bIsOPen)
  613. return GetErrorInfo(-1, "MacEncrypt");
  614. bool bSM = (m_MacType == EPP_ALGO_METHOD_SM4);
  615. if (m_bSMMode != bSM)
  616. {
  617. int iRet = m_pPinpad->SetEPPSMMode(bSM);
  618. char sLog[256];
  619. sprintf(sLog, "EncryptData SetEPPSMMode %d ret%d", bSM, iRet);
  620. LOG4VTM(INFO, sLog);
  621. if (iRet != Error_Succeed)
  622. return GetErrorInfo(iRet, "EncryptData SetEPPSMMode");
  623. m_bSMMode = bSM;
  624. }
  625. unsigned char sData[260], sOut[64];
  626. int iSize = ((int)srcInfo.dwSize, strlen((char*)srcInfo.data));
  627. HexStrToANSI((const char*)srcInfo.data, sData, iSize);
  628. int iRet = 0;
  629. iSize /= 2;
  630. BYTE IV[16] = {0x00};
  631. m_pPinpad->SetStartValue(IV, sOut);
  632. int iRecv = 0;
  633. switch(m_MacType)
  634. {
  635. case EPP_MAC_ALGO_ASNIX99:
  636. iRet = m_pPinpad->MakeMac(m_iWorkKey, 0x33, iSize, sData, sOut, iRecv);
  637. break;
  638. case EPP_MAC_ALGO_PBOC:
  639. iRet = m_pPinpad->MakeMac(m_iWorkKey, 0x34, iSize, sData, sOut, iRecv);
  640. break;
  641. }
  642. iRet = GetErrorInfo(iRet, "EncryptData");
  643. if (iRet == Error_Succeed)
  644. {
  645. destInfo.dwSize = iRecv*2;
  646. ANSIToHexStr(sOut, iRecv, (char*)destInfo.data);
  647. }
  648. return (ErrorCodeEnum)iRet;
  649. }