mod_AccessAuth.cpp 39 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441
  1. #include "stdafx.h"
  2. #include "SpBase.h"
  3. #include "mod_AccessAuth.h"
  4. #include "RVCComm.h"
  5. #include "comm.h"
  6. #include "access_basefun.h"
  7. #include "DeviceBaseClass.h"
  8. #include <fileutil.h>
  9. #include <iniutil.h>
  10. #include <cmath>
  11. #include "TokenKeeper_client_g.h"
  12. using namespace TokenKeeper;
  13. #include "PinPad_client_g.h"
  14. using namespace PinPad;
  15. #ifdef RVC_OS_WIN
  16. #include "WMIDeviceQuery.h"
  17. #include <Strsafe.h>
  18. #endif
  19. #define KEY_SIZE 16
  20. #define BUF_SIZE 256
  21. /** TODO(gifur): expand the time to 10s*/
  22. #define DEFUALT_INVOKE_PINPAD_TIMEOUT 3000
  23. typedef struct _REG_TZI_FORMAT
  24. {
  25. LONG Bias;
  26. LONG StandardBias;
  27. LONG DaylightBias;
  28. SYSTEMTIME StandardDate;
  29. SYSTEMTIME DaylightDate;
  30. } REG_TZI_FORMAT;
  31. void CAccessAuthSession::Handle_Regist(SpOnewayCallContext<AccessAuthService_Regist_Info>::Pointer ctx)
  32. {
  33. m_pEntity->Regist();
  34. }
  35. void CAccessAuthSession::Handle_Unregist(SpOnewayCallContext<AccessAuthService_Unregist_Info>::Pointer ctx)
  36. {
  37. m_pEntity->Unregist(ctx->Info.nReason, ctx->Info.nWay);
  38. }
  39. void CAccessAuthSession::Handle_Reregist(SpOnewayCallContext<AccessAuthService_Reregist_Info>::Pointer ctx)
  40. {
  41. m_pEntity->Reregist();
  42. }
  43. void CAccessAuthSession::Handle_PushTerminalStage(SpOnewayCallContext<AccessAuthService_PushTerminalStage_Info>::Pointer ctx)
  44. {
  45. m_pEntity->PushTerminalStage(ctx->Info.cNewStage, ctx->Info.dwNewStageTime, ctx->Info.cOldStage, ctx->Info.dwOldStageTime);
  46. }
  47. void CAccessAuthSession::Handle_InitDev(SpReqAnsContext<AccessAuthService_InitDev_Req, AccessAuthService_InitDev_Ans>::Pointer ctx)
  48. {
  49. m_pEntity->InitDevice(ctx);
  50. }
  51. void CAccessAuthSession::Handle_SyncTime(SpOnewayCallContext<AccessAuthService_SyncTime_Info>::Pointer ctx)
  52. {
  53. m_pEntity->SyncTime();
  54. }
  55. void CAccessAuthEntity::OnStarted()
  56. {
  57. //设置时区为北京标准时区
  58. if (!SetLocalTimeZoneByKeyName("China Standard Time", FALSE))
  59. {
  60. m_FSM.doWarnMsg(ERR_ACCESSAUTH_SETTIMEZONE,GetOutPutStr("%s%s","设置时区错误","False").c_str());
  61. }
  62. m_FSM.Init(this);
  63. CSimpleStringA strErrMsg;
  64. CSmartPointer<IEntityFunction> spFunction = this->GetFunction();
  65. memset(&m_info,0, sizeof(CSystemStaticInfo));
  66. auto rc = GetFunction()->GetSystemStaticInfo(m_info);
  67. if (rc != Error_Succeed)
  68. {
  69. strErrMsg = "HasPinPad()=>GetSystemStaticInfo() fail";
  70. SetAuthErrMsg((const char*)strErrMsg);
  71. m_FSM.doWarnMsg(ERR_ACCESSAUTH_GET_SYSTEM_STATIC_INFO,
  72. GetOutPutStr("%s%08X", "获取系统静态信息错误", rc).c_str(), strErrMsg.GetData());
  73. }
  74. }
  75. void CAccessAuthEntity::OnPreStart(CAutoArray<CSimpleStringA> strArgs,CSmartPointer<ITransactionContext> pTransactionContext)
  76. {
  77. ErrorCodeEnum Error = Error_Succeed;
  78. pTransactionContext->SendAnswer(Error) ;
  79. }
  80. void CAccessAuthEntity::OnPreClose(EntityCloseCauseEnum eCloseCause,CSmartPointer<ITransactionContext> pTransactionContext)
  81. {
  82. m_FSM.PostExitEvent();
  83. pTransactionContext->SendAnswer(Error_Succeed);
  84. }
  85. void CAccessAuthEntity::OnSysVarEvent(const char *pszKey, const char *pszValue,const char *pszOldValue,const char *pszEntityName)
  86. {
  87. }
  88. // 开始准入
  89. ErrorCodeEnum CAccessAuthEntity::Regist()
  90. {
  91. m_FSM.PostEventFIFO(new FSMEvent(CAccessAuthFSM::Event_StartRegist));
  92. return Error_Succeed;
  93. }
  94. // 重新准入
  95. ErrorCodeEnum CAccessAuthEntity::Reregist()
  96. {
  97. m_FSM.PostEventFIFO(new FSMEvent(CAccessAuthFSM::Event_StartReregist));
  98. return Error_Succeed;
  99. }
  100. // 准入退出
  101. ErrorCodeEnum CAccessAuthEntity::Unregist(int nReason, int nWay)
  102. {
  103. FSMEvent *pEvent = new FSMEvent(CAccessAuthFSM::Event_StartUnregist);
  104. pEvent->param1 = nReason;
  105. pEvent->param2 = nWay;
  106. m_FSM.PostEventFIFO(pEvent);
  107. return Error_Succeed;
  108. }
  109. DWORD CAccessAuthEntity::SyncTime()
  110. {
  111. return m_FSM.SyncTime();
  112. }
  113. ErrorCodeEnum CAccessAuthEntity::PushTerminalStage(char cNewStage, DWORD dwNewStageTime, char cOldStage, DWORD dwOldStageTime)
  114. {
  115. Dbg("on PushTerminalStage, cNewStage: %c", cNewStage);
  116. CAccessAuthFSM::ReportStateEvent *pEvent = new CAccessAuthFSM::ReportStateEvent(cNewStage, dwNewStageTime, cOldStage, dwOldStageTime);
  117. m_FSM.PostEventFIFO(pEvent);
  118. return Error_Succeed;
  119. }
  120. // KMC初始化
  121. DWORD CAccessAuthEntity::InitKMC()
  122. {
  123. return Error_Succeed;
  124. }
  125. // 获取WK更新请求包
  126. // @nAlgFlag: 1:3des only; 2: sm4 only; 3: both 3des and sm4
  127. ErrorCodeEnum CAccessAuthEntity::GetKmcWKUpdateData(char *pBuf, int &nLen, int nAlgFlag)
  128. {
  129. return Error_Succeed;
  130. }
  131. DWORD CAccessAuthEntity::ParseWKUpdateResult(char *pBuf, int nLen, int nAlgFlag)
  132. {
  133. return Error_Succeed;
  134. }
  135. CSimpleStringA CAccessAuthEntity::GetKMCLastErrMsg()
  136. {
  137. return "";
  138. }
  139. ErrorCodeEnum CAccessAuthEntity::ReleaseKMC()
  140. {
  141. return Error_Succeed;
  142. }
  143. // 加载新WK
  144. DWORD CAccessAuthEntity::LoadPinPadWK(bool bSM)
  145. {
  146. Dbg("load sm key to pinpad...");
  147. CSimpleString strErrMsg;
  148. CSmartPointer<IEntityFunction> spFunction = this->GetFunction();
  149. PinPadService_ClientBase* pPinPad = new PinPadService_ClientBase(this);
  150. DWORD rc = pPinPad->Connect();
  151. if (rc == Error_Succeed)
  152. {
  153. PinPadService_LoadKeysSM_Req req = {};
  154. req.smflag = 1;
  155. req.initializeflag = true;
  156. if (m_bGetKMCKey) {
  157. Dbg("使用云接口更新KMC密钥");
  158. req.masterkey = m_TMK.c_str();
  159. req.workingkey1 = m_TPK.c_str();
  160. req.workingkey2 = m_EDK.c_str();
  161. req.reserved3 = m_index.c_str();
  162. }
  163. else {
  164. strErrMsg = "更新KMC密钥失败";
  165. SetAuthErrMsg((const char*)strErrMsg);
  166. spFunction->SetSysVar("AuthErrMsg", (const char*)strErrMsg, false);
  167. LogWarn(Severity_Middle, Error_Unexpect, ERR_ACCESSAUTH_GET_KMC_NULL,
  168. GetOutPutStr("%s%s", "m_bGetKMCKey", "False").c_str());
  169. rc = ERR_ACCESSAUTH_GET_KMC_NULL;
  170. return rc;
  171. }
  172. if (req.initializeflag) Dbg("initializeflag is true");
  173. else Dbg("initializeflag is false");
  174. Dbg("req.smflag=%d", req.smflag);
  175. Dbg("req.masterkey=%s", req.masterkey.GetData());
  176. Dbg("req.workingkey1=%s", req.workingkey1.GetData());
  177. Dbg("req.workingkey2=%s", req.workingkey2.GetData());
  178. Dbg("req.reserved3=%s", req.reserved3.GetData());
  179. PinPadService_LoadKeysSM_Ans ans = {};
  180. rc = pPinPad->LoadKeysSM(req, ans, 30000);
  181. if (rc == Error_Succeed)
  182. Dbg("load sm key to pinpad succ");
  183. else
  184. {
  185. strErrMsg = "加载SM密钥到PinPad失败";
  186. SetAuthErrMsg((const char*)strErrMsg);
  187. spFunction->SetSysVar("AuthErrMsg", (const char*)strErrMsg, false);
  188. LogWarn(Severity_Middle, Error_Unexpect, ERR_ACCESSAUTH_LOAD_KEYS_TO_PINPAD,
  189. GetOutPutStr("%s%08x%s%s", "LoadKeysSM", rc, "strErrMsg", strErrMsg.GetData()).c_str());
  190. rc = ERR_ACCESSAUTH_LOAD_KEYS_TO_PINPAD;
  191. }
  192. pPinPad->GetFunction()->CloseSession();
  193. }
  194. else
  195. {
  196. strErrMsg = "连接PinPad实体失败";
  197. SetAuthErrMsg((const char*)strErrMsg);
  198. spFunction->SetSysVar("AuthErrMsg", (const char*)strErrMsg, false);
  199. LogWarn(Severity_Middle, Error_Unexpect, ERR_ACCESSAUTH_CONNECT_PINPAD,
  200. GetOutPutStr("%s%08x%s%s", "Connect", rc, "strErrMsg", strErrMsg).c_str());
  201. rc = ERR_ACCESSAUTH_CONNECT_PINPAD;
  202. //@test 没连接成功调用此接口释放
  203. pPinPad->SafeDelete();
  204. }
  205. return rc;
  206. }
  207. DWORD CAccessAuthEntity::LoadKeysToPinPadNew(string TMK, string TPK, string EDK, string index)
  208. {
  209. LOG_FUNCTION();
  210. Dbg("load sm key to pinpad...");
  211. PinPadService_ClientBase* pPinPad = new PinPadService_ClientBase(this);
  212. DWORD rc = pPinPad->Connect();
  213. if (rc == Error_Succeed)
  214. {
  215. PinPadService_LoadKeysSM_Req req = {};
  216. req.initializeflag = true;
  217. req.smflag = 1;
  218. Dbg("使用云接口获取的KMC密钥");
  219. req.masterkey = TMK.c_str();
  220. req.workingkey1 = TPK.c_str();
  221. req.workingkey2 = EDK.c_str();
  222. req.reserved3 = index.c_str();
  223. if (req.initializeflag) Dbg("initializeflag is true");
  224. else Dbg("initializeflag is false");
  225. Dbg("req.smflag=%d", req.smflag);
  226. Dbg("req.masterkey=%s", req.masterkey.GetData());
  227. Dbg("req.workingkey1=%s", req.workingkey1.GetData());
  228. Dbg("req.workingkey2=%s", req.workingkey2.GetData());
  229. Dbg("req.reserved3=%s", req.reserved3.GetData());
  230. PinPadService_LoadKeysSM_Ans ans = {};
  231. rc = pPinPad->LoadKeysSM(req, ans, 30000);
  232. if (rc == Error_Succeed)
  233. Dbg("load sm key to pinpad succ");
  234. else
  235. {
  236. SetAuthErrMsg("加载SM密钥到PinPad失败");
  237. m_FSM.doWarnMsg(ERR_INITIALIZER_LOAD_KEYS_TO_PINPAD,
  238. GetOutPutStr("%s%08x%s%s", "LoadKeys", rc, "strErrMsg", "加载SM密钥到PinPad失败").c_str());
  239. rc = ERR_INITIALIZER_LOAD_KEYS_TO_PINPAD;
  240. }
  241. pPinPad->GetFunction()->CloseSession();
  242. }
  243. else
  244. {
  245. SetAuthErrMsg("连接PinPad实体失败");
  246. m_FSM.doWarnMsg(ERR_INITIALIZER_CONNECT_PINPAD,
  247. GetOutPutStr("%s%08x%s%s", "Connect", rc, "strErrMsg", "连接PinPad实体失败").c_str());
  248. rc = ERR_INITIALIZER_CONNECT_PINPAD;
  249. pPinPad->SafeDelete();
  250. }
  251. return rc;
  252. }
  253. // 将16进制字符串转成BYTE数据
  254. bool CAccessAuthEntity::HexStrToByteArray(const char* pHex, BYTE *pBuf, int *pBufLen)
  255. {
  256. int nHexLen = strlen(pHex);
  257. if (nHexLen %2 != 0)
  258. {
  259. Dbg("error hex string length");
  260. return false;
  261. }
  262. if (nHexLen /2 > *pBufLen)
  263. {
  264. Dbg("not enough buf length");
  265. return false;
  266. }
  267. for(int i=0; i<nHexLen; i++)
  268. {
  269. BYTE b =0;
  270. char ch1 = pHex[i];
  271. if (ch1 >='0' && ch1<='9')
  272. b = ch1 - '0';
  273. else if (ch1 >='A' && ch1 <='F')
  274. b = ch1 - 'A' + 10;
  275. else
  276. {
  277. Dbg("invalid hex string");
  278. return false;
  279. }
  280. if (i %2 ==0)
  281. {
  282. pBuf[i/2] = b;
  283. }
  284. else
  285. {
  286. pBuf[i/2] = pBuf[i/2] << 4 | b;
  287. }
  288. }
  289. *pBufLen = nHexLen / 2;
  290. return true;
  291. }
  292. string CAccessAuthEntity::ByteArrayToHexStr(BYTE *pBuf, int nBufLen)
  293. {
  294. char szBuf[1024];
  295. memset(szBuf, 0, sizeof(szBuf));
  296. for(int i=0; i<nBufLen; i++)
  297. {
  298. BYTE b1 = (pBuf[i] >> 4) & 0x0F;
  299. BYTE b2 = pBuf[i] & 0x0F;
  300. if (b1 <= 9)
  301. szBuf[i*2] = '0' + b1;
  302. else
  303. szBuf[i*2] = 'A' + b1 - 10;
  304. if (b2 <= 9)
  305. szBuf[i*2+1] = '0' + b2;
  306. else
  307. szBuf[i*2+1] = 'A' + b2 - 10;
  308. }
  309. return szBuf;
  310. }
  311. // 调用密码键盘加密
  312. DWORD CAccessAuthEntity::EncryptDataWithPinPad(const CBlob &raw, CBlob &enc)
  313. {
  314. #ifdef IGNORE_PINPAD
  315. enc.Alloc(raw.m_iLength);
  316. memcpy(enc.m_pData, raw.m_pData, raw.m_iLength);
  317. return Error_Succeed;
  318. #else
  319. CSimpleStringA strErrMsg;
  320. CSmartPointer<IEntityFunction> spFunction = this->GetFunction();
  321. PinPadService_EncryptDataSM_Req req = {};
  322. PinPadService_EncryptDataSM_Ans ans = {};
  323. req.data = ByteArrayToHexStr((BYTE*)raw.m_pData, raw.m_iLength).c_str();
  324. Dbg("begin encrpyt data with pinpad");
  325. PinPadService_ClientBase *pPinPad = new PinPadService_ClientBase(this);
  326. DWORD rc = pPinPad->Connect();
  327. if (rc == Error_Succeed)
  328. {
  329. rc = pPinPad->EncryptDataSM(req, ans, 10000);
  330. if (rc == Error_Succeed)
  331. Dbg("encrypt data with pinpad succ: [%s]", (const char*)ans.ciphertext);
  332. else
  333. {
  334. strErrMsg = "调用PinPad实体中的EncryptData方法加密数据失败";
  335. SetAuthErrMsg((const char *)strErrMsg);
  336. m_FSM.doWarnMsg(ERR_ACCESSAUTH_FROM_PINPAD,
  337. GetOutPutStr("%s%08x%s%s", "EncryptData", rc, "strErrMsg", strErrMsg).c_str());
  338. rc = ERR_ACCESSAUTH_FROM_PINPAD;
  339. }
  340. pPinPad->GetFunction()->CloseSession();
  341. }
  342. else
  343. {
  344. strErrMsg = "连接PinPad实体失败";
  345. SetAuthErrMsg((const char *)strErrMsg);
  346. m_FSM.doWarnMsg(ERR_ACCESSAUTH_CONNECT_PINPAD,
  347. GetOutPutStr("%s%08x%s%s", "Connect", rc, "strErrMsg", strErrMsg).c_str());
  348. rc = ERR_ACCESSAUTH_CONNECT_PINPAD;
  349. pPinPad->SafeDelete();
  350. }
  351. if (rc != Error_Succeed)
  352. return rc;
  353. BYTE buf[512];
  354. int nLen = 512;
  355. memset(buf, 0, 512);
  356. if (!HexStrToByteArray((const char*)ans.ciphertext, buf, &nLen))
  357. {
  358. strErrMsg = "加密数据转化十六进制失败";
  359. SetAuthErrMsg((const char *)strErrMsg);
  360. m_FSM.doWarnMsg(ERR_ACCESSAUTH_HEX_TO_BYTE,
  361. GetOutPutStr("%s%s%s%s", "HexStrToByteArray", "False", "strErrMsg", strErrMsg).c_str());
  362. return ERR_ACCESSAUTH_HEX_TO_BYTE;
  363. }
  364. enc.Alloc(nLen);
  365. memcpy(enc.m_pData, buf, nLen);
  366. return Error_Succeed;
  367. #endif
  368. }
  369. // 生成临时SM2密钥对
  370. DWORD CAccessAuthEntity::CreateSM2KeyPair(CBlob &pubKey, CBlob &priKey)
  371. {
  372. int nPubKeyLen = 256;
  373. int nPriKeyLen = 256;
  374. pubKey.Alloc(nPubKeyLen);
  375. priKey.Alloc(nPriKeyLen);
  376. if (!::CreateSM2KeyPair((BYTE*)(pubKey.m_pData), &nPubKeyLen, (BYTE*)(priKey.m_pData), &nPriKeyLen))
  377. {
  378. SetAuthErrMsg("创建SM2密钥对失败");
  379. CSmartPointer<IEntityFunction> spFunction = this->GetFunction();
  380. m_FSM.doWarnMsg(ERR_ACCESSAUTH_CREATE_RSA_KEY_PAIR,
  381. GetOutPutStr("%s%s","CreateRsaKeyPair","False").c_str(), "创建SM2密钥对失败");
  382. return ERR_ACCESSAUTH_CREATE_RSA_KEY_PAIR;
  383. }
  384. pubKey.Resize(nPubKeyLen);
  385. priKey.Resize(nPriKeyLen);
  386. return Error_Succeed;
  387. }
  388. // 保存到令牌管理实体中
  389. DWORD CAccessAuthEntity::SaveSM2KeyPair(const CBlob &pubKey, const CBlob &priKey)
  390. {
  391. LOG_FUNCTION();
  392. CSimpleStringA strErrMsg;
  393. CSmartPointer<IEntityFunction> spFunction = this->GetFunction();
  394. TokenService_ClientBase *pTokenServiceClient = new TokenService_ClientBase(this);
  395. DWORD rc = pTokenServiceClient->Connect();
  396. if (rc != Error_Succeed)
  397. {
  398. strErrMsg = "连接令牌管理实体失败";
  399. SetAuthErrMsg((const char *)strErrMsg);
  400. rc = ERR_ACCESSAUTH_CONNECT_TOKEN_SERVICE;
  401. m_FSM.doWarnMsg(rc,
  402. GetOutPutStr("%s%08X%s%s", "Connect", rc,"strErrMsg", strErrMsg).c_str());
  403. pTokenServiceClient->SafeDelete();
  404. }
  405. else
  406. {
  407. TokenService_SetKeyPair_Req req;
  408. req.pub_key = pubKey;
  409. req.pri_key = priKey;
  410. TokenService_SetKeyPair_Ans ans;
  411. rc = pTokenServiceClient->SetKeyPair(req, ans, DEFUALT_INVOKE_PINPAD_TIMEOUT);
  412. pTokenServiceClient->GetFunction()->CloseSession();
  413. if (rc != Error_Succeed)
  414. {
  415. strErrMsg = "保存密钥对失败";
  416. SetAuthErrMsg((const char *)strErrMsg);
  417. rc = ERR_ACCESSAUTH_FROM_TOKEN_SERVICE_SET_KEYS;
  418. m_FSM.doWarnMsg(rc,
  419. GetOutPutStr("%s%08X%s%s", "SetKeyPair", rc,"strErrMsg", (const char*)strErrMsg).c_str());
  420. }
  421. else
  422. Dbg("set sm2 key pair succ");
  423. }
  424. return rc;
  425. }
  426. ErrorCodeEnum CAccessAuthEntity::SaveTokenAndSharedSK(const CBlob &token, const CBlob &sharedSK)
  427. {
  428. LOG_FUNCTION();
  429. CSimpleStringA strErrMsg;
  430. CSmartPointer<IEntityFunction> spFunction = this->GetFunction();
  431. TokenService_ClientBase *pTokenServiceClient = new TokenService_ClientBase(this);
  432. ErrorCodeEnum rc = pTokenServiceClient->Connect();
  433. if (rc != Error_Succeed)
  434. {
  435. strErrMsg = "连接令牌管理实体失败";
  436. SetAuthErrMsg((const char *)strErrMsg);
  437. m_FSM.doWarnMsg(ERR_ACCESSAUTH_CONNECT_TOKEN_SERVICE,
  438. GetOutPutStr("%s%08X%s%s", "Connect", rc,"strErrMsg", (const char*)strErrMsg).c_str());
  439. pTokenServiceClient->SafeDelete();
  440. }
  441. else
  442. {
  443. TokenService_SetToken_Req req = {};
  444. req.token = token;
  445. TokenService_SetToken_Ans ans;
  446. rc = pTokenServiceClient->SetToken(req, ans, 5000);
  447. if (rc == Error_Succeed)
  448. Dbg("save token succ, token: [%s]", ByteArrayToHexStr((BYTE*)token.m_pData, token.m_iLength).c_str());
  449. else
  450. {
  451. strErrMsg = "保存令牌失败";
  452. SetAuthErrMsg((const char *)strErrMsg);
  453. m_FSM.doWarnMsg(ERR_ACCESSAUTH_FROM_TOKEN_SERVICE_SET_TOKEN,
  454. GetOutPutStr("%s%08X%s%s", "SetToken", rc,"strErrMsg", strErrMsg).c_str());
  455. }
  456. TokenService_SetSharedSK_Req req2 = {};
  457. req2.ssk = sharedSK;
  458. TokenService_SetSharedSK_Ans ans2 = {};
  459. rc = pTokenServiceClient->SetSharedSK(req2, ans2, 5000);
  460. if (rc == Error_Succeed)
  461. Dbg("save shared session key succ");
  462. else
  463. {
  464. strErrMsg = "保存会话密钥失败";
  465. SetAuthErrMsg((const char *)strErrMsg);
  466. m_FSM.doWarnMsg(ERR_ACCESSAUTH_FROM_TOKEN_SERVICE_SET_SHAREKEY,
  467. GetOutPutStr("%s%08X%s%s", "SetSharedSK", rc,"strErrMsg", (const char*)strErrMsg).c_str());
  468. }
  469. pTokenServiceClient->GetFunction()->CloseSession();
  470. }
  471. return rc;
  472. }
  473. bool CAccessAuthEntity::HasPinPad()
  474. {
  475. CSimpleStringA strErrMsg;
  476. CSmartPointer<IEntityFunction> spFunction = this->GetFunction();
  477. //oilyang@20210514
  478. if (!IsMachineTypeConfigurePinPad(m_info.strMachineType))
  479. {
  480. Dbg("MachineType[%s], not exist pinpad", m_info.strMachineType);
  481. return false;
  482. }
  483. else if (stricmp(m_info.strMachineType, "RVC.PAD") == 0) // Pad机型
  484. {
  485. // 根据PinPad实体状态确定是否连接密码键盘
  486. bool bPinPadExist = false;
  487. auto pPinPadClient = new PinPadService_ClientBase(this);
  488. if (pPinPadClient->Connect() != Error_Succeed)
  489. {
  490. Dbg("connect PinPad fail, assume no pinpad");
  491. m_FSM.doWarnMsg(ERR_ACCESSAUTH_CONNECT_PINPAD,
  492. GetOutPutStr("%s%s", "连接pinpad错误", "False").c_str());
  493. pPinPadClient->SafeDelete();
  494. }
  495. else
  496. {
  497. PinPadService_GetDevInfo_Req req = {};
  498. PinPadService_GetDevInfo_Ans ans = {};
  499. auto rc = pPinPadClient->GetDevInfo(req, ans, DEFUALT_INVOKE_PINPAD_TIMEOUT);
  500. if (rc != Error_Succeed)
  501. {
  502. strErrMsg = "PinPad::GetDevInfo() fail";
  503. SetAuthErrMsg((const char *)strErrMsg);
  504. m_FSM.doWarnMsg(ERR_ACCESSAUTH_FROM_PINPAD,
  505. GetOutPutStr("%s%08X", "来自pinpad的错误", rc).c_str(), strErrMsg.GetData());
  506. }
  507. else
  508. {
  509. Dbg("PinPad::GetDevInfo() return state: %d", ans.state);
  510. bPinPadExist = ans.state != DEVICE_STATUS_NOT_READY;
  511. }
  512. pPinPadClient->GetFunction()->CloseSession();
  513. }
  514. pPinPadClient = NULL;
  515. return bPinPadExist;
  516. }
  517. else
  518. {
  519. // 其它VTM机型,全部有内置密码键盘
  520. return true;
  521. }
  522. }
  523. // 1:3des only; 2: sm4 only; 3: both 3des and sm4
  524. // 由当前已初始化的密钥文件决定,兼容旧版本终端
  525. int CAccessAuthEntity::GetPinPadCapability()
  526. {
  527. int nCapability = 0;
  528. if (!IsMachineTypeConfigurePinPad(m_info.strMachineType))
  529. return nCapability;
  530. PinPadService_ClientBase *pPinPad = new PinPadService_ClientBase(this);
  531. auto rc = pPinPad->Connect();
  532. if (rc == Error_Succeed)
  533. {
  534. PinPadService_QueryFunc_Req req;
  535. PinPadService_QueryFunc_Ans ans;
  536. rc = pPinPad->QueryFunc(req,ans, DEFUALT_INVOKE_PINPAD_TIMEOUT);
  537. if (rc == Error_Succeed)
  538. {
  539. nCapability = ans.reserved1;
  540. Dbg("QueryFunc from pinpad succ, nCapability[%d]", nCapability);
  541. }
  542. else
  543. {
  544. SetAuthErrMsg("从PinPad获取主密钥类型失败");
  545. CSmartPointer<IEntityFunction> spFunction = this->GetFunction();
  546. m_FSM.doWarnMsg(ERR_ACCESSAUTH_FROM_PINPAD,
  547. GetOutPutStr("%s%s%s%s", "QueryFunc", "False", "AuthErrMsg", "从PinPad获取主密钥类型失败").c_str());
  548. }
  549. pPinPad->GetFunction()->CloseSession();
  550. }
  551. else
  552. {
  553. SetAuthErrMsg("连接PinPad实体失败");
  554. CSmartPointer<IEntityFunction> spFunction = this->GetFunction();
  555. m_FSM.doWarnMsg(ERR_ACCESSAUTH_CONNECT_PINPAD,
  556. GetOutPutStr("%s%08X%s%s", "Connect", rc,"AuthErrMsg", "连接PinPad实体失败").c_str());
  557. pPinPad->SafeDelete();
  558. }
  559. return nCapability;
  560. }
  561. void CAccessAuthEntity::printPasswdError(){
  562. string strErrMsg = "密钥集丢失,请重新初始化密钥!";
  563. SetAuthErrMsg(strErrMsg.c_str());
  564. GetFunction()->SetSysVar("AuthErrMsg", strErrMsg.c_str(), true);
  565. m_FSM.doWarnMsg( ERROR_ACCESSAUTH_OPENCRYPTCONTEXT, strErrMsg.c_str(),false, strErrMsg);
  566. }
  567. int Char2Int(char * ch) {
  568. int num = 0;
  569. for (int i = 0;i < strlen(ch);i++) {
  570. num += ((int)(ch[i] - '0')) * pow((float)10, (float)(strlen(ch) - i - 1));
  571. }
  572. return num;
  573. }
  574. bool CAccessAuthEntity::SaveAuthVerAndKey(int nAuthVer, BYTE *pKey)
  575. {
  576. LOG_FUNCTION();
  577. m_nAuthVersion = nAuthVer;
  578. memset(m_AuthSessionKey, 0, 140);
  579. if (m_nAuthVersion == 2)
  580. {
  581. CSimpleString runInfoPath;
  582. auto rc = GetFunction()->GetPath("runinfo", runInfoPath);
  583. if (rc != Error_Succeed) {
  584. Dbg("GetPath runinfo error=%d.", rc);
  585. return false;
  586. }
  587. char privateKey[BUF_SIZE] = { 0 };
  588. runInfoPath += SPLIT_SLASH_STR "runcfg" SPLIT_SLASH_STR "Initializer.ini";
  589. #ifdef RVC_OS_WIN
  590. GetPrivateProfileString("TerminalPD", "PrivateKey", "", privateKey, BUF_SIZE, runInfoPath.GetData());
  591. #else
  592. Dbg("path ex:%s", runInfoPath.GetData());
  593. char* tmp = inifile_read_str(runInfoPath.GetData(),"TerminalPD", "PrivateKey", "");
  594. strcpy(privateKey, tmp);
  595. delete tmp;
  596. #endif // RVC_OS_WIN
  597. if (strlen(privateKey) <= 0) {
  598. printPasswdError();
  599. return false;
  600. }
  601. Dbg("privateKey=%s,%d", privateKey, strlen(privateKey));
  602. int decodedPrivateKeyLen;
  603. char* pDecodedPrivateKey = Hex2Str(privateKey, decodedPrivateKeyLen);
  604. Dbg("decodedPrivateKeyLen=%d", decodedPrivateKeyLen);
  605. char pDecryptPrivateKey[BUF_SIZE] = { 0 };
  606. int decryprtLen = BUF_SIZE;
  607. if (!DecWithSM4_ECB("s5da69gnh4!963@6s5da69gnh4!963@6", (BYTE*)pDecodedPrivateKey, decodedPrivateKeyLen, (BYTE*)pDecryptPrivateKey, &decryprtLen)) {
  608. Dbg("DecWithSM4_ECB decrypt privateKey error.");
  609. printPasswdError();
  610. delete[] pDecodedPrivateKey;
  611. return false;
  612. }
  613. delete[] pDecodedPrivateKey;
  614. //添加调试信息
  615. char * pEncPriKey = Str2Hex((char*)pDecryptPrivateKey, decryprtLen);
  616. Dbg("DecWithSM4_ECB succeess.privateKey=%s", pEncPriKey);
  617. delete pEncPriKey;
  618. char pPlainKey[KEY_SIZE];
  619. int plainKeyLen = KEY_SIZE;
  620. char pKeyLen[4] = { 0 };
  621. memcpy(pKeyLen, pKey, 4);
  622. int kenLen = Char2Int(pKeyLen);
  623. Dbg("kenLen=%d", kenLen);
  624. char* pEncodeKey = Str2Hex((char*)pKey,kenLen + 4);
  625. Dbg("pEncodeKey=%s", pEncodeKey);
  626. delete pEncodeKey;
  627. char* key = new char[kenLen + 1];
  628. memset(key, 0, kenLen + 1);
  629. memcpy(key, pKey + 4, kenLen);
  630. if (!DecWithSM2PriKey((BYTE*)key, kenLen, (BYTE*)pPlainKey, &plainKeyLen, (BYTE*)pDecryptPrivateKey, decryprtLen)) {
  631. Dbg("使用私钥解密失败!");
  632. printPasswdError();
  633. return false;
  634. }
  635. Dbg("使用私钥解密成功");
  636. if (plainKeyLen != KEY_SIZE) {
  637. Dbg("私钥解密后的会话密钥长度不等于16!");
  638. }
  639. memcpy(m_AuthSessionKey, pPlainKey, KEY_SIZE);
  640. }
  641. return true;
  642. }
  643. static BYTE* ConvertHexStrToBytes(const char *pszStr)
  644. {
  645. if (pszStr == NULL || strlen(pszStr) == 0)
  646. return NULL;
  647. int nLen = strlen(pszStr) / 2;
  648. BYTE *pRet = (BYTE*)malloc(nLen);
  649. memset(pRet, 0, nLen);
  650. for (int i = 0; i < nLen; i++)
  651. {
  652. int nTmp(0);
  653. if (sscanf(&pszStr[i * 2], "%2X", &nTmp) != 1)
  654. {
  655. free(pRet);
  656. return NULL;
  657. }
  658. pRet[i] = (BYTE)nTmp;
  659. }
  660. return pRet;
  661. }
  662. // 使用准入会话密钥加密
  663. ErrorCodeEnum CAccessAuthEntity::EncryptDataWithSessionKey(const CBlob &raw, CBlob &enc)
  664. {
  665. LOG_FUNCTION();
  666. assert(m_nAuthVersion ==2);
  667. //这里不需要delete,由CBlob析构函数去执行
  668. BYTE* pEncData = new BYTE[1024];
  669. int pEncDataSize = 1024;
  670. Dbg("pEncDataSize=%d", pEncDataSize);
  671. char* pPlainInfo = Str2Hex((char*)raw.m_pData, raw.m_iLength);
  672. Dbg("raw data=%s,raw.m_iLength=%d", pPlainInfo, raw.m_iLength);
  673. delete[] pPlainInfo;
  674. //char *sessionKey = Str2Hex((char*)m_AuthSessionKey, KEY_SIZE);
  675. char sessionKey[KEY_SIZE] = { 0 };
  676. memcpy(sessionKey,m_AuthSessionKey,KEY_SIZE);
  677. char* tmpKey = Str2Hex((char*)m_AuthSessionKey, KEY_SIZE);
  678. Dbg("sessionKey=%s", tmpKey);
  679. delete[] tmpKey;
  680. if (!EncWithSM4_ECB((BYTE*)sessionKey, (BYTE*)(raw.m_pData), raw.m_iLength, pEncData, &pEncDataSize)) {
  681. Dbg("会话密钥加密准入信息失败!");
  682. return Error_Unexpect;
  683. }
  684. enc.Attach(pEncData,pEncDataSize);
  685. char* tmp = Str2Hex((char*)pEncData, pEncDataSize);
  686. Dbg("pEncData=%s,%d", tmp, pEncDataSize);
  687. delete[] tmp;
  688. tmp = Str2Hex((char*)enc.m_pData, enc.m_iLength);
  689. Dbg("EncWithSM4_ECB data=%s,%d", tmp, enc.m_iLength);
  690. delete[] tmp;
  691. return Error_Succeed;
  692. }
  693. bool CAccessAuthEntity::GetMD5Hash(const char *pStr, BYTE md5[16])
  694. {
  695. return false;
  696. }
  697. static char* ConvertBytesToHexStr(BYTE *pBuf, int nLen)
  698. {
  699. char *pRet = (char*)malloc(nLen * 2 + 1);
  700. memset(pRet, 0, nLen * 2 + 1);
  701. char *p = pRet;
  702. for (int i = 0; i < nLen; i++)
  703. {
  704. BYTE b = pBuf[i];
  705. BYTE l = (b >> 4) & 0x0F;
  706. if (l >= 10)
  707. *p = l - 10 + 'A';
  708. else
  709. *p = l + '0';
  710. p++;
  711. BYTE r = b & 0x0F;
  712. if (r >= 10)
  713. *p = r - 10 + 'A';
  714. else
  715. *p = r + '0';
  716. p++;
  717. }
  718. return pRet;
  719. }
  720. bool CAccessAuthEntity::GetTerminalFingerPrint(BYTE *pBuf, int &nBufLen)
  721. {
  722. char szTmp[1024] = {};
  723. string strTmp;
  724. int nTmpBufLen = 1024;
  725. CSimpleStringA strErrMsg;
  726. CSmartPointer<IEntityFunction> spFunction = this->GetFunction();
  727. CSimpleStringA strRet;
  728. #ifdef RVC_OS_WIN
  729. if (!QueryWMIDevice(Processor, "ProcessorId", szTmp, &nTmpBufLen))
  730. #else
  731. CSimpleStringA runInfoPath;
  732. auto rc = GetFunction()->GetPath("runinfo", runInfoPath);
  733. if (rc != Error_Succeed) {
  734. Dbg("GetPath runinfo error=%d.", rc);
  735. return false;
  736. }
  737. runInfoPath += SPLIT_SLASH_STR "runcfg";
  738. if (!get_cpu_id_by_system(strTmp, runInfoPath.GetData()))
  739. #endif // RVC_OS_WIN
  740. {
  741. strErrMsg = CSimpleStringA::Format("查询CPU ID失败,请重启机器并重新初始化");
  742. SetAuthErrMsg((const char *)strErrMsg);
  743. m_FSM.doWarnMsg(ERR_ACCESSAUTH_GET_TERMINAL_FINGERPRINT,
  744. GetOutPutStr("%s%s", "Processor", "False").c_str());
  745. return false;
  746. }
  747. #ifdef RVC_OS_WIN
  748. strRet = szTmp;
  749. nTmpBufLen = 1024;
  750. memset(szTmp, 0, sizeof(szTmp));
  751. if (!QueryWMIDevice(BaseBoard, "SerialNumber", szTmp, &nTmpBufLen))
  752. #else
  753. Dbg("cpu id: %s", strTmp.c_str());
  754. strRet = strTmp.c_str();
  755. strTmp.clear();
  756. if (!get_board_serial_by_system(strTmp, runInfoPath.GetData()))
  757. #endif // RVC_OS_WIN
  758. {
  759. strErrMsg = CSimpleStringA::Format("查询主板序列号失败, 请重启机器并重新初始化");
  760. SetAuthErrMsg((const char *)strErrMsg);
  761. m_FSM.doWarnMsg(ERR_ACCESSAUTH_GET_TERMINAL_FINGERPRINT,
  762. GetOutPutStr("%s%s", "BaseBoard", "False").c_str());
  763. return false;
  764. }
  765. strRet += "|";
  766. #ifdef RVC_OS_WIN
  767. strRet += szTmp;
  768. nTmpBufLen = 1024;
  769. memset(szTmp, 0, sizeof(szTmp));
  770. if (!QueryWMIDevice(DiskDrive, "SerialNumber", szTmp, &nTmpBufLen))
  771. #else
  772. Dbg("baseboard sn: %s", strTmp.c_str());
  773. strRet += strTmp.c_str();
  774. vector<string> disk;
  775. int errCode = 0;
  776. if (!get_disk_serial_by_system(disk, errCode, runInfoPath.GetData()))
  777. #endif // RVC_OS_WIN
  778. {
  779. Dbg("get_disk_serial_by_system errCode:%d", errCode);
  780. strErrMsg = CSimpleStringA::Format("查询磁盘序列号失败, 请重启机器并重新初始化");
  781. SetAuthErrMsg((const char*)strErrMsg);
  782. m_FSM.doWarnMsg(ERR_INITIALIZER_GET_DISKDRIVE_ID,
  783. GetOutPutStr("%s%s", "DiskDrive", "False").c_str());
  784. return false;
  785. }
  786. strRet += "|";
  787. #ifdef RVC_OS_WIN
  788. strRet += szTmp;
  789. #else
  790. strTmp = "";
  791. vector<string>::iterator it = disk.begin();
  792. while (it != disk.end()) {
  793. strTmp += *it;
  794. it++;
  795. }
  796. Dbg("harddisk sn: %s", strTmp.c_str());
  797. strRet += strTmp.c_str();
  798. #endif // RVC_OS_WIN
  799. Dbg("device info: [%s]", (const char*)strRet);
  800. BYTE sm3[32] = { 0 };
  801. if(!SM3Hash(reinterpret_cast<BYTE*>(const_cast<char*>(strRet.GetData())),strRet.GetLength(),sm3))
  802. {
  803. strErrMsg = "get sm3 hash as fingerprint fail";
  804. SetAuthErrMsg((const char *)strErrMsg);
  805. spFunction->SetSysVar("AuthErrMsg", (const char *)strErrMsg, true);
  806. m_FSM.doWarnMsg(ERROR_ACCESSAUTH_GETSM3HASH, (const char *)strErrMsg);
  807. return false;
  808. }
  809. if (nBufLen < 32)
  810. {
  811. //Dbg("buf len is too small");
  812. m_FSM.doWarnMsg(ERROR_ACCESSAUTH_GETSM3HASH, "buf len is too small fail");
  813. return false;
  814. }
  815. nBufLen = 32;
  816. memcpy(pBuf, sm3, nBufLen);
  817. char *pszSM3 = ConvertBytesToHexStr(sm3, nBufLen);
  818. Dbg("fringerprint: [%s]", pszSM3);
  819. free(pszSM3);
  820. return true;
  821. }
  822. // 生成SM2密钥对,并导出公钥
  823. bool CAccessAuthEntity::GetTerminalPublicKey(BYTE *pBuf, int &nBufLen)
  824. {
  825. CSimpleString runInfoPath;
  826. auto rc = GetFunction()->GetPath("runinfo", runInfoPath);
  827. if (rc != Error_Succeed) {
  828. Dbg("GetPath runinfo error=%d.", rc);
  829. return false;
  830. }
  831. runInfoPath += SPLIT_SLASH_STR "runcfg" SPLIT_SLASH_STR "Initializer.ini";
  832. char publicKey[BUF_SIZE] = { 0 };
  833. #ifdef RVC_OS_WIN
  834. GetPrivateProfileString("TerminalPD", "PublicKey", "", publicKey, BUF_SIZE, runInfoPath.GetData());
  835. #else
  836. char* tmp = inifile_read_str(runInfoPath.GetData(), "TerminalPD", "PublicKey", "");
  837. strcpy(publicKey, tmp);
  838. delete tmp;
  839. #endif // RVC_OS_WIN
  840. if (strlen(publicKey) <= 0) {
  841. Dbg("读取公钥失败,公钥长度小于等于零!");
  842. printPasswdError();
  843. return false;
  844. }
  845. Dbg("publickey=%s,%d",publicKey,strlen(publicKey));
  846. char* pDecodedPublickey = Hex2Str(publicKey,nBufLen);
  847. Dbg("pDecodedPublickey=[%s],len=%d", pDecodedPublickey, nBufLen);
  848. memcpy(pBuf, pDecodedPublickey, nBufLen);
  849. Dbg("pBuf[0]=%02X,nBufLen=%d", pBuf[0], nBufLen);
  850. delete[] pDecodedPublickey;
  851. return true;
  852. }
  853. DWORD CAccessAuthEntity::InitDevice(SpReqAnsContext<AccessAuthService_InitDev_Req, AccessAuthService_InitDev_Ans>::Pointer &ctx)
  854. {
  855. return m_FSM.InitDevice(ctx);
  856. }
  857. //oilyang@20210510 嵌入"bool CAccessAuthEntity::HasPinPad()"的逻辑
  858. // 返回1:只有PinPadID;2:只有DeviceID;3:两者都有;0:没有;-1表示失败
  859. int CAccessAuthEntity::GetPinPadIDAndDeviceID(CSimpleStringA &strPinPadID, CSimpleStringA &strDeviceID, bool& bHasPinPad)
  860. {
  861. bHasPinPad = false;
  862. CSimpleStringA strErrMsg;
  863. CSmartPointer<IEntityFunction> spFunction = this->GetFunction();
  864. //oilyang@20210514
  865. if (!IsMachineTypeConfigurePinPad(m_info.strMachineType))
  866. return 0;
  867. int nRet = -1;
  868. auto pPinPadClient = new PinPadService_ClientBase(this);
  869. bool bPinPadID = false;
  870. bool bDeviceID = false;
  871. bool bVendor = false;
  872. bool bBluetooth = false;
  873. CSimpleStringA strVendor;
  874. CSimpleStringA strBluetoothID;
  875. CSimpleStringA strPID;
  876. CSimpleStringA strMID;
  877. bHasPinPad = true;
  878. auto rc = 0;
  879. if ( (rc = pPinPadClient->Connect()) == Error_Succeed)
  880. {
  881. PinPadService_GetDevInfo_Req req = {};
  882. PinPadService_GetDevInfo_Ans ans = {};
  883. rc = pPinPadClient->GetDevInfo(req, ans, DEFUALT_INVOKE_PINPAD_TIMEOUT);
  884. if (rc == Error_Succeed) {
  885. if (ans.state == DEVICE_STATUS_NORMAL) {
  886. nRet = 0;
  887. Dbg("pinpad model: %s", (const char*)ans.model);
  888. // CM = V2.0#PM = V1.0#MID = 75500001#PID = 12345678#FWID = V1234567#Vendor = nantian
  889. // 密码键盘ID,PID,8到16字节; 设备ID,MID,8到16字节; 固件版本号,FWID,8字节
  890. CSimpleStringA str = ans.model;
  891. if (!str.IsNullOrEmpty())
  892. {
  893. auto arr = str.Split('#');
  894. if (arr.GetCount() > 0)
  895. {
  896. for (int i = 0; i < arr.GetCount(); i++)
  897. {
  898. auto arr2 = arr[i].Split('=');
  899. if (arr2.GetCount() != 2)
  900. continue;
  901. //if (arr2[0] == "PID")
  902. if(!strnicmp((LPCTSTR)arr2[0], "PID", strlen("PID")))
  903. {
  904. strPID = arr2[1];
  905. if (!strPID.IsNullOrEmpty())
  906. bPinPadID = true;
  907. }
  908. //else if (arr2[0] == "MID")
  909. else if(!strnicmp((LPCTSTR)arr2[0], "MID", strlen("MID")))
  910. {
  911. strMID = arr2[1];
  912. if (!strMID.IsNullOrEmpty())
  913. bDeviceID = true;
  914. }
  915. //else if (arr2[0] == "Vendor")
  916. else if(!strnicmp((LPCTSTR)arr2[0], "Vendor", strlen("Vendor")))
  917. {
  918. strVendor = arr2[1];
  919. if (!strVendor.IsNullOrEmpty())
  920. bVendor = true;
  921. }
  922. else if (!strnicmp((LPCTSTR)arr2[0], "FWBID", strlen("FWBID")))
  923. {
  924. strBluetoothID = arr2[1];
  925. Dbg("strBluetoothID=%s", strBluetoothID);
  926. if (!strBluetoothID.IsNullOrEmpty())
  927. bBluetooth = true;
  928. }
  929. }
  930. }
  931. }
  932. }
  933. else
  934. {
  935. if (m_info.strMachineType.IsStartWith("RVC.PAD", true))
  936. bHasPinPad = false;
  937. Dbg("pinpad not exist, state: %d", ans.state);
  938. }
  939. }
  940. else
  941. {
  942. if (m_info.strMachineType.IsStartWith("RVC.PAD", true))
  943. bHasPinPad = false;
  944. strErrMsg = "调用PinPad实体的GetDevInfo方法失败";
  945. SetAuthErrMsg((const char *)strErrMsg);
  946. m_FSM.doWarnMsg(ERR_ACCESSAUTH_FROM_PINPAD,
  947. GetOutPutStr("%s%08X%s%s", "GetDevInfo", rc, "strErrMsg", (const char*)strErrMsg ).c_str());
  948. }
  949. pPinPadClient->GetFunction()->CloseSession();
  950. }
  951. else
  952. {
  953. if (m_info.strMachineType.IsStartWith("RVC.PAD", true))
  954. bHasPinPad = false;
  955. strErrMsg = "连接PinPad实体失败";
  956. SetAuthErrMsg((const char *)strErrMsg);
  957. m_FSM.doWarnMsg(ERR_ACCESSAUTH_CONNECT_PINPAD,
  958. GetOutPutStr("%s%08X%s%s", "Connect", rc, "strErrMsg", "连接PinPad实体失败").c_str());
  959. pPinPadClient->SafeDelete();
  960. }
  961. pPinPadClient = NULL;
  962. if (bPinPadID)
  963. {
  964. if (bVendor)
  965. strPinPadID = strVendor + "_" + strPID;
  966. else
  967. strPinPadID = strPID;
  968. nRet += 1;
  969. }
  970. if (bDeviceID)
  971. {
  972. if (bVendor)
  973. strDeviceID = strVendor + "_" + strMID;
  974. else
  975. strDeviceID = strMID;
  976. if (bBluetooth)
  977. strDeviceID = strDeviceID + "_" + strBluetoothID;
  978. nRet += 2;
  979. }
  980. else if (bBluetooth)
  981. {
  982. strDeviceID = strDeviceID + "_" + strBluetoothID;
  983. nRet += 2;
  984. }
  985. return nRet;
  986. }
  987. bool CAccessAuthEntity::HasCkCodeFlg()
  988. {
  989. CSimpleStringA strErrMsg;
  990. CSmartPointer<IEntityFunction> spFunction = this->GetFunction();
  991. //oilyang@20210514
  992. if (!IsMachineTypeConfigurePinPad(m_info.strMachineType))
  993. {
  994. Dbg("MachineType is [%s], not exist pinpad entity", m_info.strMachineType);
  995. return false;
  996. }
  997. auto pPinPadClient = new PinPadService_ClientBase(this);
  998. bool bCheckCode = false;
  999. CSimpleStringA strSpeficiCM;
  1000. if (pPinPadClient->Connect() == Error_Succeed)
  1001. {
  1002. PinPadService_GetDevInfo_Req req = {};
  1003. PinPadService_GetDevInfo_Ans ans = {};
  1004. auto rc = pPinPadClient->GetDevInfo(req, ans, DEFUALT_INVOKE_PINPAD_TIMEOUT);
  1005. if (rc == Error_Succeed)
  1006. {
  1007. if (ans.state == DEVICE_STATUS_NORMAL)
  1008. {
  1009. Dbg("pinpad model: %s", (const char*)ans.model);
  1010. // CM = V2.0#PM = V1.0#MID = 75500001#PID = 12345678#FWID = V1234567#Vendor = nantian
  1011. // 密码键盘ID,PID,8到16字节; 设备ID,MID,8到16字节; 固件版本号,FWID,8字节
  1012. CSimpleStringA str = ans.model;
  1013. if (!str.IsNullOrEmpty())
  1014. {
  1015. auto arr = str.Split('#');
  1016. if (arr.GetCount() > 0)
  1017. {
  1018. for (int i = 0; i < arr.GetCount(); i++)
  1019. {
  1020. auto arr2 = arr[i].Split('=');
  1021. if (arr2.GetCount() != 2)
  1022. continue;
  1023. if(!strnicmp((LPCTSTR)arr2[0], "CM", strlen("CM")))
  1024. {
  1025. strSpeficiCM = arr2[1];
  1026. if (strSpeficiCM.GetLength() > 3 && _strnicmp(strSpeficiCM, "V2.0", strlen("V2.0")) == 0)
  1027. {
  1028. //Support checkcode, then operate checkcode routine..
  1029. bCheckCode = true;
  1030. }
  1031. }
  1032. }
  1033. }
  1034. }
  1035. }
  1036. else
  1037. {
  1038. Dbg("pinpad not exist, state: %d", ans.state);
  1039. m_FSM.doWarnMsg(ERR_ACCESSAUTH_FROM_PINPAD,
  1040. GetOutPutStr("%s%d", "密码键盘异常,请检查。ans.state", ans.state).c_str());
  1041. }
  1042. }
  1043. else
  1044. {
  1045. strErrMsg = "调用PinPad实体(GetDevInfo)失败";
  1046. SetAuthErrMsg((const char *)strErrMsg);
  1047. m_FSM.doWarnMsg(ERR_ACCESSAUTH_FROM_PINPAD,
  1048. GetOutPutStr("%s%08X", "GetDevInfo", rc).c_str(), strErrMsg.GetData());
  1049. }
  1050. pPinPadClient->GetFunction()->CloseSession();
  1051. }
  1052. else
  1053. {
  1054. strErrMsg = "连接PinPad实体失败";
  1055. SetAuthErrMsg((const char *)strErrMsg);
  1056. m_FSM.doWarnMsg(ERR_ACCESSAUTH_CONNECT_PINPAD,
  1057. GetOutPutStr("%s%s", "连接pinpad错误, strErrMsg", strErrMsg).c_str());
  1058. pPinPadClient->SafeDelete();
  1059. }
  1060. pPinPadClient = NULL;
  1061. return bCheckCode? true:false;
  1062. }
  1063. wstring CAccessAuthEntity::ANSIToUnicode(const string& str)
  1064. {
  1065. int len = 0;
  1066. len = str.length();
  1067. int unicodeLen = ::MultiByteToWideChar(CP_ACP,
  1068. 0,
  1069. str.c_str(),
  1070. -1,
  1071. NULL,
  1072. 0);
  1073. wchar_t * pUnicode;
  1074. pUnicode = new wchar_t[unicodeLen+1];
  1075. memset(pUnicode,0,(unicodeLen+1)*sizeof(wchar_t));
  1076. ::MultiByteToWideChar( CP_ACP,
  1077. 0,
  1078. str.c_str(),
  1079. -1,
  1080. (LPWSTR)pUnicode,
  1081. unicodeLen);
  1082. wstring rt;
  1083. rt = (wchar_t*)pUnicode;
  1084. delete pUnicode;
  1085. return rt;
  1086. }
  1087. //China Standard Time
  1088. BOOL CAccessAuthEntity::SetLocalTimeZoneByKeyName(const TCHAR* szTimeZoneKeyName, BOOL isDaylightSavingTime)
  1089. {
  1090. #ifdef RVC_OS_WIN
  1091. HKEY hKey;
  1092. LONG ErrorCode;
  1093. TCHAR szSubKey[256];
  1094. TCHAR szStandardName[32];
  1095. TCHAR szDaylightName[32];
  1096. REG_TZI_FORMAT regTZI;
  1097. DWORD dwByteLen;
  1098. // 检测入口参数
  1099. if ((szTimeZoneKeyName == NULL) || (strlen(szTimeZoneKeyName) == 0))
  1100. {
  1101. // 时区标识符不能为空
  1102. return FALSE;
  1103. }
  1104. StringCchCopy(szSubKey, 256, TEXT("Software\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones\\"));
  1105. StringCchCat(szSubKey, 256, szTimeZoneKeyName);
  1106. ErrorCode = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szSubKey, 0, KEY_QUERY_VALUE, &hKey);
  1107. if (ErrorCode != ERROR_SUCCESS)
  1108. {
  1109. Dbg("RegOpenKeyEx Software\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones\\China Standard Time fail");
  1110. return FALSE;
  1111. }
  1112. // 标准名
  1113. dwByteLen = sizeof(szStandardName);
  1114. ErrorCode = RegQueryValueEx(hKey, TEXT("Std"), NULL, NULL, reinterpret_cast<LPBYTE>(&szStandardName), &dwByteLen);
  1115. if (ErrorCode != ERROR_SUCCESS)
  1116. {
  1117. RegCloseKey(hKey);
  1118. Dbg("RegQueryValueEx Software\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones\\China Standard Time\\Std fail");
  1119. return FALSE;
  1120. }
  1121. // 夏时制名
  1122. dwByteLen = sizeof(szDaylightName);
  1123. ErrorCode = RegQueryValueEx(hKey, TEXT("Dlt"), NULL, NULL, reinterpret_cast<LPBYTE>(&szDaylightName), &dwByteLen);
  1124. if (ErrorCode != ERROR_SUCCESS)
  1125. {
  1126. RegCloseKey(hKey);
  1127. Dbg("RegQueryValueEx Software\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones\\China Standard Time\\Dlt fail");
  1128. return FALSE;
  1129. }
  1130. // 时区信息
  1131. dwByteLen = sizeof(regTZI);
  1132. ErrorCode = RegQueryValueEx(hKey, TEXT("TZI"), NULL, NULL, reinterpret_cast<LPBYTE>(&regTZI), &dwByteLen);
  1133. RegCloseKey(hKey);
  1134. if ((ErrorCode != ERROR_SUCCESS) || (dwByteLen > sizeof(regTZI)))
  1135. {
  1136. Dbg("RegQueryValueEx Software\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones\\China Standard Time\\TZI fail");
  1137. return FALSE;
  1138. }
  1139. // 开启权限
  1140. HANDLE hToken;
  1141. TOKEN_PRIVILEGES tkp;
  1142. BOOL isOK;
  1143. if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY, &hToken))
  1144. {
  1145. Dbg("OpenProcessToken Standard Time\\Dlt fail");
  1146. return FALSE;
  1147. }
  1148. LookupPrivilegeValue(NULL, SE_TIME_ZONE_NAME, &tkp.Privileges[0].Luid);
  1149. tkp.PrivilegeCount = 1;
  1150. tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
  1151. AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0);
  1152. if (GetLastError() != ERROR_SUCCESS)
  1153. {
  1154. CloseHandle(hToken);
  1155. Dbg("AdjustTokenPrivileges fail");
  1156. return FALSE;
  1157. }
  1158. // 设置新时区
  1159. DYNAMIC_TIME_ZONE_INFORMATION tzi;
  1160. tzi.Bias = regTZI.Bias;
  1161. tzi.StandardDate = regTZI.StandardDate;
  1162. tzi.StandardBias = regTZI.StandardBias;
  1163. tzi.DaylightDate = regTZI.DaylightDate;
  1164. tzi.DaylightBias = regTZI.DaylightBias;
  1165. tzi.DynamicDaylightTimeDisabled = !isDaylightSavingTime;
  1166. wcscpy(tzi.StandardName, ANSIToUnicode(szStandardName).c_str());
  1167. wcscpy(tzi.DaylightName, ANSIToUnicode(szDaylightName).c_str());
  1168. wcscpy(tzi.TimeZoneKeyName, ANSIToUnicode(szTimeZoneKeyName).c_str());
  1169. isOK = SetDynamicTimeZoneInformation(&tzi); // 设置动态时区
  1170. if (!isOK)
  1171. {
  1172. Dbg("SetDynamicTimeZoneInformation fail");
  1173. }
  1174. // 关闭权限
  1175. tkp.Privileges[0].Attributes = 0;
  1176. AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0);
  1177. CloseHandle(hToken);
  1178. return isOK;
  1179. #else
  1180. //temporarily not relased at linux
  1181. return TRUE;
  1182. #endif // RVC_OS_WIN
  1183. }
  1184. int CAccessAuthEntity::ConvertStr2Byte(string input, BYTE* output, int outputLen) {
  1185. if (input.size() > outputLen) return 1;
  1186. for (int i = 0;i < input.size();i++) {
  1187. output[i] = input[i];
  1188. }
  1189. return 0;
  1190. }
  1191. int CAccessAuthEntity::GetOrSetIsFirstSM(int type) {
  1192. CSmartPointer<IConfigInfo> pConfig;
  1193. int isFirst = 0;
  1194. auto rc = GetFunction()->OpenConfig(Config_Run, pConfig);
  1195. if (rc != Error_Succeed) {
  1196. Dbg("OpenConfig Config_Run error=%d.", rc);
  1197. return isFirst;
  1198. }
  1199. CSimpleStringA sIsFirst;
  1200. if (type == 0) {
  1201. return 0;//oilyang@20211208 这个逻辑没有存在的必要了
  1202. rc = pConfig->ReadConfigValue("SM", "IsFirst", sIsFirst);
  1203. if (rc != Error_Succeed || sIsFirst.IsNullOrEmpty()) {
  1204. rc = pConfig->WriteConfigValue("SM", "IsFirst", "Yes");
  1205. if (rc != Error_Succeed) {
  1206. Dbg("WriteConfigValue Config_Run SM IsFirst error.");
  1207. return isFirst;
  1208. }
  1209. isFirst = 1;
  1210. }
  1211. else if (sIsFirst == "Yes") {
  1212. isFirst = 1;
  1213. }
  1214. else
  1215. isFirst = 0;
  1216. return isFirst;
  1217. }
  1218. else {
  1219. rc = pConfig->WriteConfigValue("SM", "IsFirst", "No");
  1220. if (rc != Error_Succeed) {
  1221. Dbg("WriteConfigValue Config_Run SM IsFirst error.");
  1222. return isFirst;
  1223. } else {
  1224. isFirst = 1;
  1225. }
  1226. return isFirst;
  1227. }
  1228. }
  1229. bool CAccessAuthEntity::IsMachineTypeConfigurePinPad(CSimpleStringA strMachineType)
  1230. {
  1231. // 回单打印机、卡库、简化版
  1232. if (strMachineType.IsStartWith("RPM", true) || strMachineType.IsStartWith("RVC.CardStore", true)
  1233. || strMachineType.IsStartWith("RVC.IL", true))
  1234. {
  1235. return false;
  1236. }
  1237. else
  1238. return true;
  1239. }
  1240. SP_BEGIN_ENTITY_MAP()
  1241. SP_ENTITY(CAccessAuthEntity)
  1242. SP_END_ENTITY_MAP()