#include "stdafx.h" #include "SpBase.h" #include "mod_AccessAuth.h" #include "RVCComm.h" #include "access_basefun.h" #include #include #include #include "Event.h" #include "comm.h" #include "CommEntityRestful.hpp" #include "CommEntityUtil.hpp" #include "TokenKeeper_client_g.h" using namespace TokenKeeper; #include "PinPad_client_g.h" using namespace PinPad; #ifdef RVC_OS_WIN #include "WMIDeviceQuery.h" #include #include #include "MyBase64.h" #endif struct InitializerInitMKTask : ITaskSp { CAccessAuthFSM* m_fsm; CAccessAuthEntity* m_entity; InitializerInitMKTask(CAccessAuthFSM* fsm, CAccessAuthEntity* entity) :m_fsm(fsm), m_entity(entity) {} void Process() { CSystemStaticInfo si; m_fsm->GetEntityBase()->GetFunction()->GetSystemStaticInfo(si); CInitlizerMKReq instanceReq;//oiltest dev module count bool initFlag = m_entity->SendInitMKReqACS(instanceReq); if (!initFlag) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setResultCode("RTA5204")("连接密码键盘异常"); m_entity->EndInitMK(ERR_ACCESSAUTH_CONNECT_PINPAD, "连接密码键盘异常,请检查");//,待完善细化错误码oiltest return; } if (m_fsm->containsChinese(m_fsm->GetmAccessAuthHost().GetData())) { m_entity->EndInitMK(ERR_INITIALIZER_EXCEPTION, CSimpleStringA::Format("初始化服务连接失败,URL含中文。").GetData()); return; } auto tmkpair = m_entity->GenerateTmkToKMC(); instanceReq.encRandom = tmkpair.first; DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("iniTerminalInfo: %s", instanceReq.iniTerminalInfo.c_str()); DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("auth:%s", instanceReq.auth.c_str()); DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("curEdkKeyCheck: %s", instanceReq.curEdkKeyCheck.c_str()); DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("curKeyIndex: %s", instanceReq.curKeyIndex.c_str()); DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("curTpkKeyCheck: %s", instanceReq.curTpkKeyCheck.c_str()); DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("encRandom: %s", instanceReq.encRandom.c_str()); DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("publicKey: %s", instanceReq.publicKey.c_str()); DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("terminalNo: %s", instanceReq.terminalNo.c_str()); DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("terminalVersion: %s", instanceReq.terminalVersion.c_str()); DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("user: %s", instanceReq.user.c_str()); DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("loginWay: %d", instanceReq.loginWay); CInitlizerMKAns instanceAns; HttpClientResponseResult result; HttpClientRequestConfig config(HttpRequestMethod::POST, m_entity->GetInitUrl().GetData(), &SpGetToken); config.SetChildUri("/api/v6/initmk"); SP::Module::Restful::FulfillRequestJsonBody(&config, instanceReq); RestfulClient client = RestfulClient::getInstance(); PROCESS_LINK_CONTEXT("LR0402502Initmk"); config.PreDo(); client.Do(&config, &result, &nextLink); if (result.ResponseOK()) { SP::Module::Restful::CommResponseJson responseStatus; SP::Module::Restful::GetStatusFromDebranchResponse(result.content, responseStatus); if (!responseStatus.IsOperatedOK()) { CSimpleStringA errMsg = CSimpleStringA::Format("%s|%s", responseStatus.errorCode.c_str(), responseStatus.errorMsg.c_str()); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("initmk failed: %s", errMsg.GetData()); m_entity->EndInitMK(ERR_INITIALIZER_EXCEPTION, errMsg.GetData()); } else { //服务端返回成功再将数据写入AcessAuthourization.ini CSmartPointer pConfig; auto rc = m_entity->GetFunction()->OpenConfig(Config_Run, pConfig); rc = pConfig->WriteConfigValue("TerminalPD", "PrivateKey", m_entity->m_privateKey); if (rc != Error_Succeed) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("write pri key failed."); m_entity->EndInitMK(ERR_INITIALIZER_EXCEPTION, "私钥写入失败,请重新初始化。"); return; } if (m_entity->HasPinPad()) { const bool testResult = SP::Module::Restful::ExtractDataFromDebranchResponse(result.content, instanceAns); if (m_entity->LoadKeysToPinPadACS(tmkpair.second, instanceAns.TPK, instanceAns.EDK, instanceAns.keyIndex, instanceAns.tpkKeyCheck, instanceAns.edkKeyCheck) == Error_Succeed) { m_entity->EndInitMK(Error_Succeed, ""); } else { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setResultCode("RTA5204")("连接密码键盘异常"); m_entity->EndInitMK(ERR_ACCESSAUTH_CONNECT_PINPAD, "密钥加载失败,请检查密码键盘连接。");//,待完善细化错误码oiltest } } else { m_entity->EndInitMK(Error_Succeed, ""); } } } else { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("post wk failed: %s", result.WhatError().c_str()); m_entity->EndInitMK(ERR_INITIALIZER_EXCEPTION, CSimpleStringA::Format("初始化服务连接失败。%s", result.WhatError().c_str()).GetData()); } } }; struct GetTermSysInfoTask : ITaskSp { CAccessAuthEntity* m_entity; GetTermSysInfoTask(CAccessAuthEntity* entity) :m_entity(entity) {} void Process() { m_entity->GetHardWareInfo(); } }; typedef struct _REG_TZI_FORMAT { LONG Bias; LONG StandardBias; LONG DaylightBias; SYSTEMTIME StandardDate; SYSTEMTIME DaylightDate; } REG_TZI_FORMAT; void CAccessAuthSession::Handle_Regist(SpOnewayCallContext::Pointer ctx) { DbgToBeidou(ctx->link, __FUNCTION__)(); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_USER).setAPI(__FUNCTION__)("call Handle_Regist"); m_pEntity->Regist(); } void CAccessAuthSession::Handle_UpdateWK(SpOnewayCallContext::Pointer ctx) { DbgToBeidou(ctx->link, __FUNCTION__)(); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_USER).setAPI(__FUNCTION__)("call Handle_UpdateWK"); m_pEntity->UpdateWK(); } void CAccessAuthSession::Handle_InitializeNew(SpReqAnsContext::Pointer ctx) { DbgToBeidou(ctx->link, __FUNCTION__)(); DbgWithLink(LOG_LEVEL_INFO, ctx->link.checkEmpty() ? LOG_TYPE_SYSTEM : LOG_TYPE_USER).setAPI(__FUNCTION__)("Handle_InitializeNew"); m_pEntity->m_ctx = ctx; m_pEntity->m_strUserID = ctx->Req.strUserID.GetData(); m_pEntity->m_strPassword = ctx->Req.strPassword.GetData(); m_pEntity->BeginInitMKACS(); } void CAccessAuthSession::Handle_InitDev(SpReqAnsContext::Pointer ctx) { DbgToBeidou(ctx->link, __FUNCTION__)(); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_USER).setAPI(__FUNCTION__)("call Handle_InitDev"); m_pEntity->InitDevice(ctx); } void CAccessAuthSession::Handle_GetNetMsg(SpReqAnsContext::Pointer ctx) { DbgToBeidou(ctx->link, __FUNCTION__)(); m_pEntity->GetNetMsg(ctx); } void CAccessAuthEntity::OnStarted() { //设置时区为北京标准时区 if (!SetLocalTimeZoneByKeyName("China Standard Time", FALSE)) { m_FSM.doWarnMsg(ERR_ACCESSAUTH_SETTIMEZONE,GetOutPutStr("%s%s","设置时区错误","False").c_str()); DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setResultCode("RTA5202")(GetOutPutStr("%s%s", "设置时区错误", "False").c_str()); } m_FSM.Init(this); CSimpleStringA strErrMsg; CSmartPointer spFunction = this->GetFunction(); auto rc = GetFunction()->GetSystemStaticInfo(m_info); if (rc != Error_Succeed) { strErrMsg = "GetSystemStaticInfo fail"; SetAuthErrMsg((const char*)strErrMsg); m_FSM.doWarnMsg(ERR_ACCESSAUTH_GET_SYSTEM_STATIC_INFO, GetOutPutStr("%s%08X", "获取系统静态信息错误", rc).c_str(), strErrMsg.GetData()); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)(GetOutPutStr("%s%08X", "获取系统静态信息错误", rc).c_str()); } CSmartPointer getTermSysInfoTask = new GetTermSysInfoTask(this); GetFunction()->PostThreadPoolTask(getTermSysInfoTask.GetRawPointer()); } void CAccessAuthEntity::OnPreStart(CAutoArray strArgs,CSmartPointer pTransactionContext) { ErrorCodeEnum Error = Error_Succeed; pTransactionContext->SendAnswer(Error) ; } void CAccessAuthEntity::OnPreClose(EntityCloseCauseEnum eCloseCause,CSmartPointer pTransactionContext) { m_FSM.PostExitEvent(); pTransactionContext->SendAnswer(Error_Succeed); } void CAccessAuthEntity::OnSysVarEvent(const char *pszKey, const char *pszValue,const char *pszOldValue,const char *pszEntityName) { } // 开始准入 ErrorCodeEnum CAccessAuthEntity::Regist() { m_FSM.PostEventFIFO(new FSMEvent(CAccessAuthFSM::Event_StartRegist)); return Error_Succeed; } string CAccessAuthEntity::ByteArrayToHexStr(BYTE *pBuf, int nBufLen) { char szBuf[1024]; memset(szBuf, 0, sizeof(szBuf)); for(int i=0; i> 4) & 0x0F; BYTE b2 = pBuf[i] & 0x0F; if (b1 <= 9) szBuf[i*2] = '0' + b1; else szBuf[i*2] = 'A' + b1 - 10; if (b2 <= 9) szBuf[i*2+1] = '0' + b2; else szBuf[i*2+1] = 'A' + b2 - 10; } return szBuf; } // 生成临时SM2密钥对 DWORD CAccessAuthEntity::CreateSM2KeyPair(CBlob &pubKey, CBlob &priKey) { int nPubKeyLen = 256; int nPriKeyLen = 256; pubKey.Alloc(nPubKeyLen); priKey.Alloc(nPriKeyLen); if (!::CreateSM2KeyPair((BYTE*)(pubKey.m_pData), &nPubKeyLen, (BYTE*)(priKey.m_pData), &nPriKeyLen)) { SetAuthErrMsg("创建SM2密钥对失败"); CSmartPointer spFunction = this->GetFunction(); m_FSM.doWarnMsg(ERR_ACCESSAUTH_CREATE_RSA_KEY_PAIR, GetOutPutStr("%s%s","CreateRsaKeyPair","False").c_str(), true, "创建SM2密钥对失败"); DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("创建SM2密钥对失败"); return ERR_ACCESSAUTH_CREATE_RSA_KEY_PAIR; } pubKey.Resize(nPubKeyLen); priKey.Resize(nPriKeyLen); return Error_Succeed; } // 保存到令牌管理实体中 DWORD CAccessAuthEntity::SaveSM2KeyPair(const CBlob &pubKey, const CBlob &priKey) { LOG_FUNCTION(); CSimpleStringA strErrMsg; CSmartPointer spFunction = this->GetFunction(); TokenService_ClientBase *pTokenServiceClient = new TokenService_ClientBase(this); DWORD rc = pTokenServiceClient->Connect(); if (rc != Error_Succeed) { strErrMsg = "连接令牌管理实体失败"; SetAuthErrMsg(strErrMsg.GetData()); rc = ERR_ACCESSAUTH_CONNECT_TOKEN_SERVICE; m_FSM.doWarnMsg(rc, "连接令牌管理实体失败", true); DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setResultCode("RTA5206") (GetOutPutStr("%s%08X%s%s", "Connect", rc, "strErrMsg", strErrMsg.GetData()).c_str()); pTokenServiceClient->SafeDelete(); } else { TokenService_SetKeyPair_Req req; req.pub_key = pubKey; req.pri_key = priKey; TokenService_SetKeyPair_Ans ans; rc = pTokenServiceClient->SetKeyPair(req, ans, 3000); pTokenServiceClient->GetFunction()->CloseSession(); if (rc != Error_Succeed) { strErrMsg = "保存密钥对失败"; SetAuthErrMsg(strErrMsg.GetData()); rc = ERR_ACCESSAUTH_FROM_TOKEN_SERVICE_SET_KEYS; m_FSM.doWarnMsg(rc, "保存密钥对失败", true); DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setResultCode("RTA5207") (GetOutPutStr("%s%08X%s%s", "SetKeyPair", rc, "strErrMsg", strErrMsg.GetData()).c_str()); } } return rc; } ErrorCodeEnum CAccessAuthEntity::SaveTokenAndSharedSK(const CBlob &token, const CBlob &sharedSK) { LOG_FUNCTION(); CSimpleStringA strErrMsg; CSmartPointer spFunction = this->GetFunction(); TokenService_ClientBase *pTokenServiceClient = new TokenService_ClientBase(this); ErrorCodeEnum rc = pTokenServiceClient->Connect(); if (rc != Error_Succeed) { strErrMsg = "连接令牌管理实体失败"; SetAuthErrMsg(strErrMsg.GetData()); string outStr = GetOutPutStr("%s%08X%s%s", "Connect", rc, "strErrMsg", strErrMsg.GetData()); m_FSM.doWarnMsg(ERR_ACCESSAUTH_CONNECT_TOKEN_SERVICE, outStr.c_str()); DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)(outStr.c_str()); pTokenServiceClient->SafeDelete(); } else { TokenService_SetToken_Req req = {}; req.token = token; TokenService_SetToken_Ans ans; rc = pTokenServiceClient->SetToken(req, ans, 5000); if (rc == Error_Succeed) DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM).setAPI("SetToken") ("save token succ, token: [%s]", ByteArrayToHexStr((BYTE*)token.m_pData, token.m_iLength).c_str()); else { strErrMsg = "保存令牌失败"; SetAuthErrMsg(strErrMsg.GetData()); string outStr = GetOutPutStr("%s%08X%s%s", "SetToken", rc, "strErrMsg", strErrMsg.GetData()); m_FSM.doWarnMsg(ERR_ACCESSAUTH_FROM_TOKEN_SERVICE_SET_TOKEN, outStr.c_str()); DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)(outStr.c_str()); } TokenService_SetSharedSK_Req req2 = {}; req2.ssk = sharedSK; TokenService_SetSharedSK_Ans ans2 = {}; rc = pTokenServiceClient->SetSharedSK(req2, ans2, 5000); if (rc != Error_Succeed) { strErrMsg = "保存会话密钥失败"; SetAuthErrMsg(strErrMsg.GetData()); string outStr = GetOutPutStr("%s%08X%s%s", "SetSharedSK", rc, "strErrMsg", strErrMsg.GetData()); m_FSM.doWarnMsg(ERR_ACCESSAUTH_FROM_TOKEN_SERVICE_SET_SHAREKEY, outStr.c_str()); DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)(outStr.c_str()); } pTokenServiceClient->GetFunction()->CloseSession(); } return rc; } bool CAccessAuthEntity::HasPinPad() { CSimpleStringA strErrMsg; CSmartPointer spFunction = this->GetFunction(); //oilyang@20210514 if (!IsMachineTypeConfigurePinPad(m_info.strMachineType)) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("MachineType[%s], not exist pinpad", m_info.strMachineType.GetData()); return false; } else { // 其它VTM机型,全部有内置密码键盘 return true; } } // 1:3des only; 2: sm4 only; 3: both 3des and sm4 // 由当前已初始化的密钥文件决定,兼容旧版本终端 int CAccessAuthEntity::GetPinPadCapability() { LOG_FUNCTION(); int nCapability = 0; if (!IsMachineTypeConfigurePinPad(m_info.strMachineType)) return nCapability; PinPadService_ClientBase *pPinPad = new PinPadService_ClientBase(this); auto rc = pPinPad->Connect(); if (rc == Error_Succeed) { PinPadService_QueryFunc_Req req; PinPadService_QueryFunc_Ans ans; rc = pPinPad->QueryFunc(req, ans, 3000); if (rc == Error_Succeed) { nCapability = ans.encryptkey; DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("QueryFunc from pinpad succ, nCapability[%d]", nCapability); } else if (rc != Error_DevNotAvailable) { SetAuthErrMsg("从PinPad获取主密钥类型失败"); CSmartPointer spFunction = this->GetFunction(); m_FSM.doWarnMsg(ERR_ACCESSAUTH_FROM_PINPAD, GetOutPutStr("%s%s%s%s", "QueryFunc", "False", "AuthErrMsg", "从PinPad获取主密钥类型失败").c_str()); DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setResultCode("RTA5205") (GetOutPutStr("%s%s%s%s", "QueryFunc", "False", "AuthErrMsg", "从PinPad获取主密钥类型失败").c_str()); } pPinPad->GetFunction()->CloseSession(); } else { SetAuthErrMsg("连接PinPad实体失败"); CSmartPointer spFunction = this->GetFunction(); m_FSM.doWarnMsg(ERR_ACCESSAUTH_CONNECT_PINPAD, GetOutPutStr("%s%08X%s%s", "Connect", rc,"AuthErrMsg", "连接PinPad实体失败").c_str()); DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)(GetOutPutStr("%s%08X%s%s", "Connect", rc, "AuthErrMsg", "连接PinPad实体失败").c_str()); pPinPad->SafeDelete(); } return nCapability; } void CAccessAuthEntity::printPasswdError(const string& strErrMsg){ SetAuthErrMsg(strErrMsg.c_str()); GetFunction()->SetSysVar("AuthErrMsg", strErrMsg.c_str()); m_FSM.doWarnMsg( ERROR_ACCESSAUTH_OPENCRYPTCONTEXT, strErrMsg.c_str(),true, strErrMsg); DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setResultCode("RTA520C")(strErrMsg.c_str()); } bool CAccessAuthEntity::SaveAuthKey(BYTE *pKey) { memset(m_AuthSessionKey, 0, 140); CSimpleStringA runInfoPath, iniPath; auto rc = GetFunction()->GetPath("runinfo", runInfoPath); if (rc != Error_Succeed) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("GetPath runinfo error=%d.", rc); return false; } char privateKey[BUF_SIZE] = { 0 }; iniPath = runInfoPath + SPLIT_SLASH_STR "runcfg" SPLIT_SLASH_STR "AccessAuthorization.ini"; char* tmp = inifile_read_str(iniPath.GetData(), "TerminalPD", "PrivateKey", ""); strcpy(privateKey, tmp); delete tmp; if (strlen(privateKey) <= 0) { iniPath = runInfoPath + SPLIT_SLASH_STR "runcfg" SPLIT_SLASH_STR "Initializer.ini"; char* tmp2 = inifile_read_str(iniPath.GetData(), "TerminalPD", "PrivateKey", ""); strcpy(privateKey, tmp2); delete tmp2; if (strlen(privateKey) <= 0) { printPasswdError("私钥为空,请重置秘钥进行初始化"); return false; } } int decodedPrivateKeyLen; char* pDecodedPrivateKey = SP::Module::Util::Hex2Str(privateKey, decodedPrivateKeyLen); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("privateKey len:%d, decodedPrivateKeyLen=%d", strlen(privateKey), decodedPrivateKeyLen); char pDecryptPrivateKey[BUF_SIZE] = { 0 }; int decryprtLen = BUF_SIZE; if (!DecWithSM4_ECB("s5da69gnh4!963@6s5da69gnh4!963@6", (BYTE*)pDecodedPrivateKey, decodedPrivateKeyLen, (BYTE*)pDecryptPrivateKey, &decryprtLen)) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("DecWithSM4_ECB decrypt privateKey error. SM4解密私钥失败"); printPasswdError("终端初始化未完成,请重置秘钥进行初始化"); delete[] pDecodedPrivateKey; return false; } delete[] pDecodedPrivateKey; char pPlainKey[KEY_SIZE]; int plainKeyLen = KEY_SIZE; char pKeyLen[4] = { 0 }; memcpy(pKeyLen, pKey, 4); int kenLen = SP::Module::Util::Char2Int(pKeyLen); char* pEncodeKey = SP::Module::Util::Str2Hex((char*)pKey, kenLen + 4); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("kenLen=%d", kenLen); delete [] pEncodeKey; char* key = new char[kenLen + 1]; memset(key, 0, kenLen + 1); memcpy(key, pKey + 4, kenLen); if (!DecWithSM2PriKey((BYTE*)key, kenLen, (BYTE*)pPlainKey, &plainKeyLen, (BYTE*)pDecryptPrivateKey, decryprtLen)) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("使用私钥解密失败!"); printPasswdError("终端初始化未完成,请重置秘钥进行初始化"); delete[] key; return false; } if (plainKeyLen != KEY_SIZE) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI("SaveAuthVerAndKey")("私钥解密后的会话密钥长度不等于16!"); } memcpy(m_AuthSessionKey, pPlainKey, KEY_SIZE); delete[] key; return true; } // 使用密钥加密 ErrorCodeEnum CAccessAuthEntity::EncryptDataWithKey(const CBlob &raw, CBlob &enc, BYTE* key) { LOG_FUNCTION(); //这里不需要delete,由CBlob析构函数去执行 BYTE* pEncData = new BYTE[1024]; int pEncDataSize = 1024; DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("pEncDataSize=%d", pEncDataSize); char* pPlainInfo = SP::Module::Util::Str2Hex((char*)raw.m_pData, raw.m_iLength); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("raw Length=%d", raw.m_iLength); delete[] pPlainInfo; if (!EncWithSM4_ECB(key, (BYTE*)(raw.m_pData), raw.m_iLength, pEncData, &pEncDataSize)) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("会话密钥加密准入信息失败!"); SetAuthErrMsg("会话密钥加密准入信息失败"); return Error_Unexpect; } enc.Attach(pEncData,pEncDataSize); char* tmp = SP::Module::Util::Str2Hex((char*)pEncData, pEncDataSize); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("pEncData size:%d", pEncDataSize); delete[] tmp; tmp = SP::Module::Util::Str2Hex((char*)enc.m_pData, enc.m_iLength); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("EncWithSM4_ECB data size:%d", enc.m_iLength); delete[] tmp; return Error_Succeed; } // 生成RSA密钥对,并导出公钥 bool CAccessAuthEntity::GetTerminalPublicKey(BYTE* pBuf, int& nBufLen, string& pubkey) { LOG_FUNCTION(); CSimpleString runCfgPath(true); auto rc = GetFunction()->GetPath("RunCfg", runCfgPath); if (rc != Error_Succeed) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI("GetTerminalPublicKey")("GetPath RunCfg error=%d.", rc); return false; } if (!ExistsDirA(runCfgPath)) { if (!CreateDirA(runCfgPath, TRUE)) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI("GetTerminalPublicKey")("Create %s dir failed!", runCfgPath.GetData()); } } DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("GetTerminalPublicKey")("Dir=%s", runCfgPath.GetData()); CSmartPointer pConfig; rc = GetFunction()->OpenConfig(Config_Run, pConfig); if (rc != Error_Succeed) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("GetTerminalPublicKey")("OpenConfig Config_Run error=%d.", rc); return false; } CSimpleString publicKey; rc = pConfig->ReadConfigValue("TerminalPD", "PublicKey", publicKey); if (rc != Error_Succeed || publicKey.IsNullOrEmpty()) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("GetTerminalPublicKey")("ReadConfig publicKey error=%d or publicKey is NULL.", rc); } BYTE btPublicKey[BUF_SIZE] = { 0 }, btPrivateKey[BUF_SIZE] = { 0 }; int iPublicKeyLen = sizeof(btPublicKey); int iPrivateKeyLen = sizeof(btPrivateKey); if (!::CreateSM2KeyPair(btPublicKey, &iPublicKeyLen, btPrivateKey, &iPrivateKeyLen)) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("GetTerminalPublicKey")("Create SM2 key pair error."); return false; } DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("GetTerminalPublicKey")("iPublicKeyLen=%d,iPrivateKeyLen=%d", iPublicKeyLen, iPrivateKeyLen); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("GetTerminalPublicKey")("[btPublicKey=%s]", (char*)btPublicKey); char* pEncode = SP::Module::Util::Str2Hex((char*)btPublicKey, iPublicKeyLen); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("GetTerminalPublicKey")("pEncode=%s,%d", pEncode, strlen(pEncode)); m_publicKey = pEncode; pubkey = pEncode; DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("GetTerminalPublicKey")("write public key success."); BYTE pCryptPrivateKey[BUF_SIZE] = { 0 }; int cryptPrivateKeyLen = BUF_SIZE; if (!EncWithSM4_ECB("s5da69gnh4!963@6s5da69gnh4!963@6", btPrivateKey, iPrivateKeyLen, pCryptPrivateKey, &cryptPrivateKeyLen)) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("GetTerminalPublicKey")("sm4 crypt privateKey error."); /*rc = pConfig->WriteConfigValue("TerminalPD", "PublicKey", "");*/ m_publicKey = ""; delete[] pEncode; return false; } DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("GetTerminalPublicKey")("sm4 encrypt pri key success."); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("GetTerminalPublicKey")("cryptPrivateKeyLen=%d", cryptPrivateKeyLen); char* pEncodedCryptPrivateKey = SP::Module::Util::Str2Hex((char*)pCryptPrivateKey, cryptPrivateKeyLen); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("GetTerminalPublicKey")("encode pri key success."); m_privateKey = pEncodedCryptPrivateKey; /*//不在这里写入私钥,将逻辑修改到函数外部,等服务端返回成功后再写入私钥 rc = pConfig->WriteConfigValue("TerminalPD", "PrivateKey", pEncodedCryptPrivateKey); if (rc != Error_Succeed) { rc = pConfig->WriteConfigValue("TerminalPD", "PublicKey", ""); delete[] pEncodedCryptPrivateKey; return false; } DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("GetTerminalPublicKey")("write pri key success.");*/ publicKey = pEncode; delete[] pEncode; delete[] pEncodedCryptPrivateKey; char* pDecode = SP::Module::Util::Hex2Str(publicKey.GetData(), nBufLen); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("GetTerminalPublicKey")("pDecode=[%s],len=%d", pDecode, nBufLen); memcpy(pBuf, pDecode, nBufLen); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("GetTerminalPublicKey")("pBuf[0]=%02X,nBufLen=%d", pBuf[0], nBufLen); delete[] pDecode; return true; } ErrorCodeEnum CAccessAuthEntity::GetPinPadModel(CSimpleStringA& pinpadModel, bool& bPinPadOnline) { bPinPadOnline = false; int waitMS = 0; CSmartPointer spConfig; ErrorCodeEnum Error = GetFunction()->OpenConfig(Config_CenterSetting, spConfig); ErrorCodeEnum errCode = spConfig->ReadConfigValueInt("AccessAuthorization", "WaitPinPadMS", waitPinPadMS); if (waitPinPadMS <= 0) { waitPinPadMS = DEFALT_WAIT_PINPAD_MS; //默认不等待 } CSimpleStringA strErrMsg; CSmartPointer spFunction = this->GetFunction(); std::map errInfo; //oilyang@20210514 if (!IsMachineTypeConfigurePinPad(m_info.strMachineType)) { pinpadModel = ""; return Error_Succeed; } ErrorCodeEnum nRet = Error_Unexpect; ErrorCodeEnum rc = Error_Unexpect; do { auto pPinPadClient = new PinPadService_ClientBase(this); if ((rc = pPinPadClient->Connect()) == Error_Succeed) { PinPadService_GetDevInfo_Req req = {}; PinPadService_GetDevInfo_Ans ans = {}; rc = pPinPadClient->GetDevInfo(req, ans, 3000); if (rc == Error_Succeed) { bPinPadOnline = true; nRet = Error_Succeed; DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("pinpad model: %s", ans.model.GetData()); // CM = V2.0#PM = V1.0#MID = 75500001#PID = 12345678#FWID = V1234567#Vendor = nantian // 密码键盘ID,PID,8到16字节; 设备ID,MID,8到16字节; 固件版本号,FWID,8字节 pinpadModel = ans.model; pPinPadClient->GetFunction()->CloseSession(); pPinPadClient->SafeDelete(); pPinPadClient = NULL; break; } pPinPadClient->GetFunction()->CloseSession(); } pPinPadClient->SafeDelete(); pPinPadClient = NULL; waitMS += INTERVAL_WAIT_PINPAD_MS; if (waitPinPadMS > 0) //配置有效时才进行等待,不然直接跳出循环 { Sleep(INTERVAL_WAIT_PINPAD_MS); //等待200ms } } while (bPinPadOnline == false && waitMS < waitPinPadMS); //获取pinpad成功,或者时间超过阈值跳出 if (rc == Error_NotInit) { strErrMsg = "PinPad超时未打开"; SetAuthErrMsg(strErrMsg.GetData()); string outStr = GetOutPutStr("%s%08X%s%s", "GetDevInfo", rc, "strErrMsg", strErrMsg.GetData()); m_FSM.doWarnMsg(ERR_ACCESSAUTH_PINPAD_OPEN_OVERTIME, outStr.c_str()); DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setResultCode("RTA5204")(outStr.c_str()); errInfo["errcode"] = "RTA5204"; errInfo["msg"] = "PinPad超时未打开"; errInfo["getLastErr"] = to_string(GetLastError()); pinpadModel = generateJsonStr(errInfo).second.c_str(); } else if(rc == Error_DevNotAvailable) { strErrMsg = "PinPad打开失败"; SetAuthErrMsg(strErrMsg.GetData()); string outStr = GetOutPutStr("%s%08X%s%s", "GetDevInfo", rc, "strErrMsg", strErrMsg.GetData()); m_FSM.doWarnMsg(ERR_ACCESSAUTH_PINPAD_OPEN_FAILED, outStr.c_str()); DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setResultCode("RTA5218")(outStr.c_str()); errInfo["errcode"] = "RTA5218"; errInfo["msg"] = "PinPad打开失败"; errInfo["getLastErr"] = to_string(GetLastError()); pinpadModel = generateJsonStr(errInfo).second.c_str(); } else if(rc != Error_Succeed) { strErrMsg = "连接PinPad取数据异常"; SetAuthErrMsg(strErrMsg.GetData()); string outStr = GetOutPutStr("%s%08X%s%s", "GetPinPadModel", rc, "strErrMsg", strErrMsg.GetData()); m_FSM.doWarnMsg(ERR_ACCESSAUTH_PINPAD_GETDATA_FAILED, outStr.c_str()); DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setResultCode("RTA5205")(outStr.c_str()); errInfo["errcode"] = "RTA5205"; errInfo["msg"] = "连接PinPad取数据异常"; errInfo["getLastErr"] = to_string(GetLastError()); pinpadModel = generateJsonStr(errInfo).second.c_str(); } return nRet; } wstring CAccessAuthEntity::ANSIToUnicode(const string& str) { int len = 0; len = str.length(); int unicodeLen = ::MultiByteToWideChar(CP_ACP, 0, str.c_str(), -1, NULL, 0); wchar_t * pUnicode; pUnicode = new wchar_t[unicodeLen+1]; memset(pUnicode,0,(unicodeLen+1)*sizeof(wchar_t)); ::MultiByteToWideChar( CP_ACP, 0, str.c_str(), -1, (LPWSTR)pUnicode, unicodeLen); wstring rt; rt = (wchar_t*)pUnicode; delete pUnicode; return rt; } //China Standard Time BOOL CAccessAuthEntity::SetLocalTimeZoneByKeyName(const TCHAR* szTimeZoneKeyName, BOOL isDaylightSavingTime) { #ifdef RVC_OS_WIN HKEY hKey; LONG ErrorCode; TCHAR szSubKey[256]; TCHAR szStandardName[32]; TCHAR szDaylightName[32]; REG_TZI_FORMAT regTZI; DWORD dwByteLen; // 检测入口参数 if ((szTimeZoneKeyName == NULL) || (strlen(szTimeZoneKeyName) == 0)) { // 时区标识符不能为空 return FALSE; } StringCchCopy(szSubKey, 256, TEXT("Software\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones\\")); StringCchCat(szSubKey, 256, szTimeZoneKeyName); ErrorCode = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szSubKey, 0, KEY_QUERY_VALUE, &hKey); if (ErrorCode != ERROR_SUCCESS) { DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("RegOpenKeyEx Software\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones\\China Standard Time fail"); return FALSE; } // 标准名 dwByteLen = sizeof(szStandardName); ErrorCode = RegQueryValueEx(hKey, TEXT("Std"), NULL, NULL, reinterpret_cast(&szStandardName), &dwByteLen); if (ErrorCode != ERROR_SUCCESS) { RegCloseKey(hKey); DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("RegQueryValueEx Software\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones\\China Standard Time\\Std fail"); return FALSE; } // 夏时制名 dwByteLen = sizeof(szDaylightName); ErrorCode = RegQueryValueEx(hKey, TEXT("Dlt"), NULL, NULL, reinterpret_cast(&szDaylightName), &dwByteLen); if (ErrorCode != ERROR_SUCCESS) { RegCloseKey(hKey); DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("RegQueryValueEx Software\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones\\China Standard Time\\Dlt fail"); return FALSE; } // 时区信息 dwByteLen = sizeof(regTZI); ErrorCode = RegQueryValueEx(hKey, TEXT("TZI"), NULL, NULL, reinterpret_cast(®TZI), &dwByteLen); RegCloseKey(hKey); if ((ErrorCode != ERROR_SUCCESS) || (dwByteLen > sizeof(regTZI))) { DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("RegQueryValueEx Software\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones\\China Standard Time\\TZI fail"); return FALSE; } // 开启权限 HANDLE hToken; TOKEN_PRIVILEGES tkp; BOOL isOK; if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) { DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("OpenProcessToken Standard Time\\Dlt fail"); return FALSE; } LookupPrivilegeValue(NULL, SE_TIME_ZONE_NAME, &tkp.Privileges[0].Luid); tkp.PrivilegeCount = 1; tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0); if (GetLastError() != ERROR_SUCCESS) { CloseHandle(hToken); DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("AdjustTokenPrivileges fail"); return FALSE; } // 设置新时区 DYNAMIC_TIME_ZONE_INFORMATION tzi; tzi.Bias = regTZI.Bias; tzi.StandardDate = regTZI.StandardDate; tzi.StandardBias = regTZI.StandardBias; tzi.DaylightDate = regTZI.DaylightDate; tzi.DaylightBias = regTZI.DaylightBias; tzi.DynamicDaylightTimeDisabled = !isDaylightSavingTime; wcscpy(tzi.StandardName, ANSIToUnicode(szStandardName).c_str()); wcscpy(tzi.DaylightName, ANSIToUnicode(szDaylightName).c_str()); wcscpy(tzi.TimeZoneKeyName, ANSIToUnicode(szTimeZoneKeyName).c_str()); isOK = SetDynamicTimeZoneInformation(&tzi); // 设置动态时区 if (!isOK) { DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("SetDynamicTimeZoneInformation fail"); } // 关闭权限 tkp.Privileges[0].Attributes = 0; AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0); CloseHandle(hToken); return isOK; #else //temporarily not relased at linux return TRUE; #endif // RVC_OS_WIN } bool CAccessAuthEntity::IsMachineTypeConfigurePinPad(const CSimpleStringA& strMachineType) { CSmartPointer spConfig; GetFunction()->OpenConfig(Config_CenterSetting, spConfig); CSimpleStringA mcType = CSimpleStringA("CoreBootList.") + strMachineType; CSimpleStringA loaderConifg(""); ErrorCodeEnum errCode = spConfig->ReadConfigValue("VtmLoader", mcType.GetData(), loaderConifg); if (errCode != Error_Succeed) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("Get VtmLoader config failed!"); } if (string(loaderConifg.GetData()).find("PinPad") != string::npos) //集中配置配了启动pinpad实体 { return true; } else { return false; } } void CAccessAuthEntity::UpdateWK() { m_FSM.UpdateWK(); } void CAccessAuthEntity::BeginInitMKACS() { LOG_FUNCTION(); // 1:3des only; 2: sm4 only; 3: both 3des and sm4 int nCapability = GetPinPadCapability(); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("pinpad capability: %d", nCapability); CSmartPointer spConfig; ErrorCodeEnum Error = GetFunction()->OpenConfig(Config_CenterSetting, spConfig); if (Error_Succeed == Error) { Error = spConfig->ReadConfigValue("AccessAuthorization", "HostInitUrl", m_strInitUrl); if (Error_Succeed != Error) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("get InitUrl from CenterSetting failed"); return; } } else { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("open InitUrl from CenterSetting.ini failed"); return; } CSmartPointer initUpdateWKTask = new InitializerInitMKTask(&this->m_FSM, this); GetFunction()->PostThreadPoolTask(initUpdateWKTask.GetRawPointer()); } bool CAccessAuthEntity::SendInitMKReqACS(CInitlizerMKReq& initMKReq) { LOG_FUNCTION(); CSmartPointer pFunc = GetFunction(); ErrorCodeEnum nRet = Error_Unexpect; CBlob encInfo; char* hexStr = "21009872C31CBC00D0C8F421D09CF707"; BYTE key[KEY_SIZE] = { 0 }; PBYTE btTmp(NULL); SP::Module::Util::StrBuf2HexBuf(hexStr, &btTmp); memcpy(key, btTmp, KEY_SIZE); if (btTmp != NULL) { delete[] btTmp; btTmp = NULL; } nRet = (ErrorCodeEnum)m_FSM.GetEncTerminalInfoWithKey(encInfo, key); if (nRet != Error_Succeed) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("GetEncTerminalInfo failed:%d", nRet); return false; } char* pTmp = SP::Module::Util::Str2Hex((char*)encInfo.m_pData, encInfo.m_iLength); initMKReq.iniTerminalInfo = pTmp; delete[] pTmp; CSystemStaticInfo si; pFunc->GetSystemStaticInfo(si); initMKReq.terminalVersion = si.InstallVersion.ToString(); initMKReq.terminalNo = si.strTerminalID.GetData(); BYTE xPublicKey[148]; int nBufLen = sizeof(xPublicKey); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("SendInitMKReqACS")("开始获取公钥。。。"); memset(xPublicKey, 0, nBufLen); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("SendInitMKReqACS")("nBufLen=%d", nBufLen); if (!GetTerminalPublicKey(xPublicKey, nBufLen, initMKReq.publicKey)) { LogWarn(Severity_Middle, Error_Unexpect, ERR_ACCESSAUTH_GET_TERMINAL_PUBKEY, GetOutPutStr("%s%s", "GetTerminalPublicKey", "False").c_str()); return false; } initMKReq.user = m_strUserID.GetData(); if (!m_strUserID.IsNullOrEmpty() && !m_strPassword.IsNullOrEmpty()) { LogWarn(Severity_Low, Error_Succeed, AccessAuthorization_UserErrorCode_Init_From_ClosePage, "Init by ClosePage."); initMKReq.loginWay = 1; } else { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("no need to call login again as User Desktop have logined."); initMKReq.loginWay = 0; } PinPadService_ClientBase* pPinPad = new PinPadService_ClientBase(this); auto errRc = pPinPad->Connect(); if (errRc == Error_Succeed) { PinPadService_GetCheckCode_Req req = {}; PinPadService_GetCheckCode_Ans ans = {}; req.mSN.Init(1); req.wSN.Init(1); req.mSN[0] = 1; req.wSN[0] = 0; errRc = (*pPinPad)(EntityResource::getLink().upgradeLink())->GetCheckCode(req, ans, 10000); if (errRc == Error_Succeed) { initMKReq.curTpkKeyCheck = ans.checkcode[0].GetData(); initMKReq.curKeyIndex = ans.index[0].GetData(); } else { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("Get keyChek && keyIndex failed."); } pPinPad->GetFunction()->CloseSession(); } else { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("connect to pinpad failed.error code:%d", errRc); } return true; } void CAccessAuthEntity::EndInitMK(DWORD rc, const char *pszErrMsg) { LOG_FUNCTION(); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setLogCode(AccessAuthService_LogCode_InitializeNew) ("EndInitMK:rc:%d,errMsg:%s", rc, pszErrMsg); GetFunction()->KillTimer(22); m_strLastErrMsg = pszErrMsg; if (rc != Error_Succeed) { LogWarn(Severity_Middle, Error_Unexpect, rc, GetOutPutStr("%s%08X%s%s", "EndInitMK", rc,"pszErrMsg", pszErrMsg).c_str()); GetFunction()->ShowFatalError(pszErrMsg); } else { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("初始化成功。。。"); } m_eErrNum = rc; bool bSuc = rc == Error_Succeed; // 通知UI窗口 if (m_ctx != NULL) { m_ctx->Ans.Errcode = rc; m_ctx->Ans.ErrMsg = m_strLastErrMsg; m_ctx->Answer(Error_Succeed); } } ErrorCodeEnum CAccessAuthEntity::LoadKeysToPinPadACS(string TMK, string TPK, string EDK, string index, string tpkCheck, string edkCheck) { LOG_FUNCTION(); //加载到密码键盘 PinPadService_ClientBase* pPinPad = new PinPadService_ClientBase(this); auto rc = pPinPad->Connect(); if (rc == Error_Succeed) { PinPadService_LoadKeysSM_Req req = {}; req.initializeflag = true; req.smflag = 1; req.masterkey = TMK.c_str(); req.workingkey1 = TPK.c_str(); req.workingkey2 = EDK.c_str(); req.reserved3 = index.c_str(); req.reserved4 = tpkCheck.c_str(); if (!req.initializeflag) DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("LoadKeysToPinPadACS")("initializeflag is false"); PinPadService_LoadKeysSM_Ans ans = {}; rc = pPinPad->LoadKeysSM(req, ans, 30000); if (rc != Error_Succeed) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("load sm key to pinpad failed."); return Error_Unexpect; } pPinPad->GetFunction()->CloseSession(); } else { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("connect to pinpad failed %x", rc); return Error_Unexpect; } return Error_Succeed; } DWORD CAccessAuthEntity::InitDevice(SpReqAnsContext::Pointer& ctx) { return m_FSM.InitDevice(ctx); } void CAccessAuthEntity::GetNetMsg(SpReqAnsContext::Pointer& ctx) { m_FSM.GetNetMsg(ctx); return; } bool CAccessAuthEntity::GenerateRandomNum() { LOG_FUNCTION(); const int MAX_KEY_SIZE = 256; //get public key-->send random number --> set working key int ret1, ret2, ret3, ret4; unsigned int ram[4]; #ifdef RVC_OS_WIN ret1 = rand_s(&ram[0]); ret2 = rand_s(&ram[1]); ret3 = rand_s(&ram[2]); ret4 = rand_s(&ram[3]); if ((ret1 != 0) || (ret2 != 0) || (ret3 != 0) || (ret4 != 0)) return false; ZeroMemory(m_btRam, 16); #else ram[0] = rand(); ram[1] = rand(); ram[2] = rand(); ram[3] = rand(); memset(m_btRam, 0, 16); #endif // RVC_OS_WIN for (int i = 0, j = 0; j < 4; ++j) { m_btRam[i + 0] = ((ram[j] & 0xff000000) >> 24); m_btRam[i + 1] = ((ram[j] & 0x00ff0000) >> 16); m_btRam[i + 2] = ((ram[j] & 0x0000ff00) >> 8); m_btRam[i + 3] = (ram[j] & 0x000000ff); i += 4; } return true; } pair CAccessAuthEntity::GenerateTmkToKMC() { LOG_FUNCTION(); if (!GenerateRandomNum()) return make_pair("", ""); #ifdef DEVOPS_ON_ST /*DevOps流水线编译,ST环境*/ CSimpleStringA tmpPubKey = "0445FAF2B721207A39A9F3DEE3B3D89E2EF8924882968D31FC54FDA4F41D3D94AED4DA1B3C38B17193AD2952BD24407B7C01A80E65630A2FAD5073691613EAA814"; #elif defined(DEVOPS_ON_UAT)/*DevOps流水线编译,UAT环境*/ CSimpleStringA tmpPubKey = "040AEC50A1FC9C5E9B1162FE4520C9E18E6F471A3F6DB77B147F0A464B5BFD0EDBE08AE8377C458CA204456E7A86568AAA9240F1C843E47988A6A197B232539DC8"; #elif defined(DEVOPS_ON_PRD)/*DevOps流水线编译,PRD环境*/ CSimpleStringA tmpPubKey = "04E0A4FDA2484A1A0FAB0844F59110AEB7A08D314B5E451E816FC0E78CBA383B461474E1167B86FC48D704CB482DD5164A73AB9E019CCE26EE382B89C394B5ACE1"; #elif defined(DEVOPS_ON_DEV)/*DevOps流水线编译,Dev环境*/ CSimpleStringA tmpPubKey = "0445FAF2B721207A39A9F3DEE3B3D89E2EF8924882968D31FC54FDA4F41D3D94AED4DA1B3C38B17193AD2952BD24407B7C01A80E65630A2FAD5073691613EAA814"; #else/*本地编译等非DevOps环境编译的版本*/ CSimpleStringA tmpPubKey = "0445FAF2B721207A39A9F3DEE3B3D89E2EF8924882968D31FC54FDA4F41D3D94AED4DA1B3C38B17193AD2952BD24407B7C01A80E65630A2FAD5073691613EAA814"; #endif return EncryptedByPubKey(tmpPubKey); } pair CAccessAuthEntity::EncryptedByPubKey(CSimpleStringA pubKey, bool bNeed04Head) { //TODO: New了那么多对象,什么时候Delete?? [Gifur@202585] if (pubKey.GetLength() <= 0) return make_pair("", ""); PCHAR strRam = new CHAR[512]; memset(strRam, 0, 512); memcpy(strRam, &(m_btRam[0]), 16); SP::Module::Util::HexBuf2StrBuf((PBYTE)m_btRam, &strRam, 16); const int MAX_KEY_SIZE = 256; char random_enc_bypbk[MAX_KEY_SIZE]; memset(random_enc_bypbk, 0, MAX_KEY_SIZE); //公钥加密随机数 int outMsgLen = MAX_KEY_SIZE; PBYTE pxxKey = new BYTE[256]; PBYTE pOldPubKey = new BYTE[256]; memset(pOldPubKey, 0, 256); memset(pxxKey, 0, 256); int size = SP::Module::Util::StrBuf2HexBuf(pubKey.GetData(), &pOldPubKey); if (bNeed04Head) { pxxKey[0] = 0x04; memcpy(pxxKey + 1, pOldPubKey, size); } else { memcpy(pxxKey, pOldPubKey, 65); } int retSM2 = EncWithSM2PubKey((unsigned char*)m_btRam, 16, (unsigned char*)random_enc_bypbk, &outMsgLen, (unsigned char*)pxxKey, 65); if (!retSM2 || outMsgLen != 113) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("EncWithSM2PubKey failed outMsgLen:%d.", outMsgLen); return make_pair("", ""); } PBYTE tmp_enc_bypbk = new BYTE[112]; memset(tmp_enc_bypbk, 0, 112); if (bNeed04Head) { memcpy(tmp_enc_bypbk, &(random_enc_bypbk[1]), 112); } else { memcpy(tmp_enc_bypbk, &(random_enc_bypbk[1]), 64); memcpy(tmp_enc_bypbk + 64, &(random_enc_bypbk[97]), 16); memcpy(tmp_enc_bypbk + 80, &(random_enc_bypbk[65]), 32); } PCHAR pBlock = new CHAR[512]; memset(pBlock, 0, 512); BYTE tmpRandomEnc[512]; memset(tmpRandomEnc, 0, 512); memcpy(tmpRandomEnc, &(tmp_enc_bypbk[0]), outMsgLen - 1); size = SP::Module::Util::HexBuf2StrBuf((PBYTE)tmpRandomEnc, &pBlock, 112); return make_pair(pBlock, strRam); } void CAccessAuthEntity::GetHardWareInfo() { std::map errInfo; //oilyang@20231008 to get system info from runcfg first //no matter calculating from runcfg succeed or not,we also get system info from system api for update runcfg bool bGetFromRunCfg = false; CSimpleString csInfo, strErrMsg, strRet; CSmartPointer pConfigRun; ErrorCodeEnum eErr = GetFunction()->OpenConfig(Config_Run, pConfigRun); if (eErr == Error_Succeed && pConfigRun->ReadConfigValue("system", "info", csInfo) == Error_Succeed && !csInfo.IsNullOrEmpty()) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("read device info from runcfg: [%s]", csInfo.GetData()); CAutoArray sysInfo = csInfo.Split('|'); if (sysInfo.GetCount() == 3) { m_cpuId = sysInfo[0]; m_mainBoardId = sysInfo[1]; m_hardDiskId = sysInfo[2]; bGetFromRunCfg = true; m_iGetTermSysInfo = 1; } else { m_iGetTermSysInfo = -1; DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI("GetTerminalFingerPrint")("get sm3 hash as fingerprint fail"); } } else DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("GetTermSysInfo, OpenConfig Config_Run error=%d.", eErr); #ifdef RVC_OS_LINUX char szTmp[1024] = {}; string strTmp; int nTmpBufLen = 1024; CSimpleStringA runInfoPath; auto rc = GetFunction()->GetPath("runinfo", runInfoPath); if (rc != Error_Succeed) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("GetPath runinfo error=%d.", rc); return; } runInfoPath += SPLIT_SLASH_STR "runcfg"; //CPU if (!get_cpu_id_by_system(strTmp, runInfoPath.GetData())) { if (!bGetFromRunCfg) { errInfo["errcode"] = "RTA5213"; errInfo["msg"] = "调用系统api获取CPU序号失败"; errInfo["getLastErr"] = to_string(GetLastError()); m_cpuId = generateJsonStr(errInfo).second.c_str(); m_iGetTermSysInfo = -1; } strErrMsg = CSimpleStringA::Format("查询CPU ID失败,请重启机器并重新初始化"); SetAuthErrMsg((const char*)strErrMsg); LogWarn(Severity_Middle, Error_Unexpect, ERR_ACCESSAUTH_GET_TERMINAL_FINGERPRINT, GetOutPutStr("%s%s%s%d", "QueryWMIDevice", "False", "Processor", GetLastError()).c_str()); DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setResultCode("RTA5213") (GetOutPutStr("%s%s", "Processor", "False").c_str()); return; } m_cpuId = strTmp.c_str(); strRet = strTmp.c_str(); strTmp.clear(); //主板 if (!get_board_serial_by_system(strTmp, runInfoPath.GetData())) { if (!bGetFromRunCfg) { errInfo["errcode"] = "RTA5214"; errInfo["msg"] = "调用系统api获取主板ID号失败"; errInfo["getLastErr"] = to_string(GetLastError()); m_mainBoardId = generateJsonStr(errInfo).second.c_str(); m_iGetTermSysInfo = -1; } strErrMsg = CSimpleStringA::Format("查询主板序列号失败, 请重启机器并重新初始化"); SetAuthErrMsg((const char*)strErrMsg); LogWarn(Severity_Middle, Error_Unexpect, ERR_ACCESSAUTH_GET_TERMINAL_FINGERPRINT, GetOutPutStr("%s%s%s%d", "QueryWMIDevice", "False", "BaseBoard", GetLastError()).c_str()); DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setResultCode("RTA5214") (GetOutPutStr("%s%s", "BaseBoard", "False").c_str()); return; } m_mainBoardId = strTmp.c_str(); strRet += "|"; strRet += strTmp.c_str(); //硬盘 vector diskArr; int errCode = 0; if (!get_disk_serial_by_system(diskArr, errCode, runInfoPath.GetData())) { if (!bGetFromRunCfg) { errInfo["errcode"] = "RTA5215"; errInfo["msg"] = "调用系统api获取硬盘ID号失败"; errInfo["getLastErr"] = to_string(GetLastError()); m_hardDiskId = generateJsonStr(errInfo).second.c_str(); m_iGetTermSysInfo = -1; } DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("get_disk_serial_by_system errCode:%d", errCode); strErrMsg = CSimpleStringA::Format("查询磁盘序列号失败, 请重启机器并重新初始化"); SetAuthErrMsg((const char*)strErrMsg); LogWarn(Severity_Middle, Error_Unexpect, ERR_ACCESSAUTH_GET_TERMINAL_FINGERPRINT, GetOutPutStr("%s%s%s%d", "QueryWMIDevice", "False", "BaseBoard", GetLastError()).c_str()); DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setResultCode("RTA5215") (GetOutPutStr("%s%s", "DiskDrive", "False").c_str()); return; } strRet += "|"; strTmp = ""; vector::iterator it = diskArr.begin(); while (it != diskArr.end()) { strTmp += *it; it++; } strRet += strTmp.c_str(); m_hardDiskId = strTmp.c_str(); #else ULONGLONG ullStart = GetTickCount64(); char szTmp[1024] = {}; int nTmpBufLen = 1024; if (!QueryWMIDevice(Processor, "ProcessorId", szTmp, &nTmpBufLen)) { if (!bGetFromRunCfg) { errInfo["errcode"] = "RTA5213"; errInfo["msg"] = "调用系统api获取CPU序号失败"; errInfo["getLastErr"] = to_string(GetLastError()); m_cpuId = generateJsonStr(errInfo).second.c_str(); m_iGetTermSysInfo = -1; } strErrMsg = CSimpleStringA::Format("查询 cpu id 失败: %d, 请尝试重启应用", GetLastError()); SetAuthErrMsg((const char*)strErrMsg); LogWarn(Severity_Middle, Error_Unexpect, ERR_ACCESSAUTH_GET_TERMINAL_FINGERPRINT, GetOutPutStr("%s%s%s%d", "QueryWMIDevice", "False", "Processor", GetLastError()).c_str()); DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setResultCode("RTA5213") (GetOutPutStr("%s%s%s%d", "QueryWMIDevice", "False", "Processor", GetLastError()).c_str()); return; } strRet = szTmp; m_cpuId = szTmp; nTmpBufLen = 1024; memset(szTmp, 0, sizeof(szTmp)); if (!QueryWMIDevice(BaseBoard, "SerialNumber", szTmp, &nTmpBufLen)) { if (!bGetFromRunCfg) { errInfo["errcode"] = "RTA5214"; errInfo["msg"] = "调用系统api获取主板ID号失败"; errInfo["getLastErr"] = to_string(GetLastError()); m_mainBoardId = generateJsonStr(errInfo).second.c_str(); m_iGetTermSysInfo = -1; } strErrMsg = CSimpleStringA::Format("查询 baseboard sn 失败: %d, 请尝试重启应用", GetLastError()); SetAuthErrMsg((const char*)strErrMsg); LogWarn(Severity_Middle, Error_Unexpect, ERR_ACCESSAUTH_GET_TERMINAL_FINGERPRINT, GetOutPutStr("%s%s%s%d", "QueryWMIDevice", "False", "BaseBoard", GetLastError()).c_str()); DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setResultCode("RTA5214") (GetOutPutStr("%s%s%s%d", "QueryWMIDevice", "False", "BaseBoard", GetLastError()).c_str()); return; } strRet += "|"; strRet += szTmp; m_mainBoardId = szTmp; nTmpBufLen = 1024; memset(szTmp, 0, sizeof(szTmp)); if (!QueryWMIDevice(DiskDrive, "SerialNumber", szTmp, &nTmpBufLen)) { if (!bGetFromRunCfg) { errInfo["errcode"] = "RTA5215"; errInfo["msg"] = "调用系统api获取硬盘ID号失败"; errInfo["getLastErr"] = to_string(GetLastError()); m_hardDiskId = generateJsonStr(errInfo).second.c_str(); m_iGetTermSysInfo = -1; } strErrMsg = CSimpleStringA::Format("查询 harddisk sn 失败: %d, 请尝试重启应用", GetLastError()); SetAuthErrMsg((const char*)strErrMsg); LogWarn(Severity_Middle, Error_Unexpect, ERR_ACCESSAUTH_GET_TERMINAL_FINGERPRINT, GetOutPutStr("%s%s%s%d", "QueryWMIDevice", "False", "DiskDrive", GetLastError()).c_str()); DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setResultCode("RTA5215") (GetOutPutStr("%s%s", "DiskDrive", "False").c_str()); return; } strRet += "|"; strRet += szTmp; m_hardDiskId = szTmp; ULONGLONG ullEnd = GetTickCount64(); if (ullEnd - ullStart > 5000) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setResultCode("RTA5201") ("获取系统信息耗时过长:%d秒", (ullEnd - ullStart) / 1000); LogWarn(Severity_Middle, Error_Unexpect, AccessAuthorization_UserErrorCode_GetTermCostTooLong, CSimpleStringA::Format("获取系统信息耗时过长:%d秒", (ullEnd - ullStart) / 1000)); } #endif // RVC_OS_LINUX if (!bGetFromRunCfg || csInfo.Compare(strRet) != 0) { eErr = pConfigRun->WriteConfigValue("system", "info", strRet.GetData()); DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("device info changed,before[%s],current[%s],write to runcfg:%d" , csInfo.GetData(), strRet.GetData(), eErr); } else DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("device info: [%s]", strRet.GetData()); m_iGetTermSysInfo = 1; return; } SP_BEGIN_ENTITY_MAP() SP_ENTITY(CAccessAuthEntity) SP_END_ENTITY_MAP()