📄 minica.cpp
字号:
char outBuf[10240] = {0};
UINT outLen = 10240;
char out[1024] = {0};
//转换证书格式为DER
if(CertFormatConver(lpCert, lenCert, "",
outBuf, &outLen, "", DER,out))
{
pCertContext = CertCreateCertificateContext(PKCS_7_ASN_ENCODING | X509_ASN_ENCODING,
(PBYTE)outBuf, outLen);
if(!pCertContext)
return FALSE;
hLinkStoreHandle = CertOpenSystemStore(NULL,"ROOT");//源
// Add a certificate to hLinkStoreHandle store.
bAdd = CertAddCertificateContextToStore(
hLinkStoreHandle, // The store handle.
pCertContext, // A pointer to a Cert.
CERT_STORE_ADD_USE_EXISTING, // If a matching cert exists use it.
NULL // Do not make any extra copy of the certificate.
);
CertCloseStore(hLinkStoreHandle,CERT_CLOSE_STORE_CHECK_FLAG);
}
return bAdd;
}
void CMiniCaApp::WinHelp(DWORD dwData, UINT nCmd)
{
// TODO: Add your specialized code here and/or call the base class
CString strHelp,strId;
strHelp=m_pszHelpFilePath;
strHelp+="::/html/";
// int index=((CPropertySheet *)AfxGetMainWnd())->GetActiveIndex();
// strHelp+=m_HelpArray[index];
// HtmlHelp(NULL,strHelp, HH_DISPLAY_TOPIC, 0);
//CWinApp::WinHelp(dwData, nCmd);
}
CString CMiniCaApp::GetMachineCode()//得到机器码
{
DWORD dwCpuSerial = 0;
CGetMachineInfo m_Info;
CString strIdeSerial(m_Info.HardDriveSerialNumber);
if(strIdeSerial.IsEmpty()) //没有取得硬盘序号
{
HKEY hKey;
LONG rc = ::RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Hardware\\Description\\System\\CentralProcessor\\0", 0, KEY_READ, &hKey);
if(rc == ERROR_SUCCESS)
{
DWORD cbBuffer = sizeof (DWORD);
rc = ::RegQueryValueEx(hKey, "FeatureSet", NULL, NULL, (LPBYTE)(&dwCpuSerial), &cbBuffer);
RegCloseKey (hKey);
}
}
// GetVolumeInformation("C:\\",NULL,NULL,&strIdeSerial,NULL,NULL,NULL,NULL);//得到c盘序号
CString strIDE;
strIDE.Format("%X%s",dwCpuSerial * 2, strIdeSerial);
// AfxMessageBox(strIDE);
//首先根据硬盘序号sha1
CString mdname("sha1");
char outMsg[100]="";
unsigned char md_value[MAX_MD_SIZE]="";
char buf[1024*2]="";
unsigned int md_len;
UCHAR bufsign[1024]={0};
UINT lensign=0;
// CString strADD;//附加信息
// strADD.LoadString(IDS_STR_MINICA);
// strIDE += strADD;
if(!CEvp::Digest(mdname.GetBuffer(0),strIDE.GetBuffer(0),strIDE.GetLength(),
md_value,&md_len, outMsg))//消息摘要
{
return "";
}
for(UINT i=0;i<md_len;i++)
{
sprintf((char *)&buf[i*2],"%02X",md_value[i]);//02x标示1个16进制变为2个字符,空补零
}
CString str512(buf);
return str512;
}
BOOL CMiniCaApp::CheckRegCode(CString username,CString regcode,BOOL type)//检验注册码
{
//首先根据用户名sha1
CString mdname("sha1");
char outMsg[100]="";
unsigned char md_value[MAX_MD_SIZE]="";
char buf[1024*2]="";
unsigned int md_len;
UCHAR bufsign[1024]={0};
int lensign=0;
char lm[257]={0};//保存乱码
char temp[3]={0};//临时变量
username += GetMachineCode();
CString strADD = "父景存&&母桂珍&&雪松&&妻会平&&儿子健";//附加信息
// strADD.LoadString(IDS_STR_MINICA);
username += strADD;
if(!CEvp::Digest(mdname.GetBuffer(0),username.GetBuffer(0),username.GetLength(),
md_value,&md_len, outMsg))//消息摘要
{
// m_RegListB.AddMsg(outMsg, M_ERROR);
return FALSE;
}
char * Cert = 0;
if(type)
{
Cert = MAKEINTRESOURCE(IDR_REGE_CERT);//企业
}
else
Cert = MAKEINTRESOURCE(IDR_REGI_CERT);//个人
HRSRC hRsrc=FindResource(NULL,Cert,"CERT");
DWORD lenCert = SizeofResource(NULL, hRsrc);
HGLOBAL hgCert=LoadResource(NULL,hRsrc);
LPSTR lpCert=(LPSTR)LockResource(hgCert);
//regcode 保存16进制数据 类似B5C3 D6F8->对应2个乱码汉字
//取出B5转换成10进制,存入乱码的一个位置
for(int j=0;j<regcode.GetLength();j+=2)
{
strncpy(temp,regcode.GetBuffer(0)+j,2);
lm[j/2]=HexToTen(temp);
}
if(CEvp::VerifySign(lpCert,lenCert,NULL,mdname.GetBuffer(0),(char *)md_value,md_len,//内存区域
lm/*签名结果,注册表->转换*/,outMsg))
{
return TRUE;
}
else
return FALSE;
}
UINT CMiniCaApp::IsReg()
{
HKEY hKEY;//定义有关的 hKEY, 在查询结束时要关闭。
CString strMiniCA,strUser,strRegCode;
strMiniCA.LoadString(IDS_REG_KEY);// IDS_REG_KEY为在注册表中的子目录字符串
strUser.LoadString(IDS_REG_USER);
strRegCode.LoadString(IDS_REG_CODE);
//hKEY,第一个参数为根键名称,第二个参数表。
//表示要访问的键的位置,第三个参数必须为0,KEY_READ表示以查询的方式。
//访问注册表,hKEY则保存此函数所打开的键的句柄。
long ret0=(::RegOpenKeyEx(HKEY_LOCAL_MACHINE,strMiniCA, 0, KEY_READ, &hKEY));
if(ret0!=ERROR_SUCCESS)//如果无法打开hKEY,则终止程序的执行
{
return FALSE;
}
//查询用户名
DWORD Type=REG_SZ;
DWORD UserLen=256;
LPBYTE lUser=new BYTE[UserLen];
//hKEY为刚才RegOpenKeyEx()函数所打开的键的句柄,″RegisteredOwner″。
//表示要查 询的键值名,type_1表示查询数据的类型,owner_Get保存所。
//查询的数据,cbData_1表示预设置的数据长度。
long ret=::RegQueryValueEx(hKEY, strUser, NULL, &Type, lUser, &UserLen);
if(ret!=ERROR_SUCCESS)
{
delete [] lUser;
::RegCloseKey(hKEY);
return FALSE;
}
//查询注册吗
DWORD RegLen=513; //长度+1
LPBYTE lRegCode=new BYTE[RegLen];
ret=::RegQueryValueEx(hKEY, strRegCode, NULL,&Type,lRegCode,&RegLen);
if(ret!=ERROR_SUCCESS)
{
delete [] lUser;
delete [] lRegCode;
::RegCloseKey(hKEY);
return FALSE;
}
//将 owner_Get 和 company_Get 转换为 CString 字符串, 以便显示输出。
CString User = CString(lUser);
CString RegCode = CString(lRegCode);
delete [] lUser;
delete [] lRegCode;
//校验用户名和注册吗
BOOL bType = FALSE;
UINT len = RegCode.GetLength();
if(len == 256)
bType = TRUE;
else if(len == 128)
bType = FALSE;
ret = CheckRegCode(User,RegCode,bType);
if(!ret)
{
::RegCloseKey(hKEY);
return 0;
}
::RegCloseKey(hKEY);
return (bType)?2:1; //0 - 未注册 1 - 个人版 2 -企业版
}
//根证书 100 110
//服务器证书 200 210
//客户端证书 300 310
//加密证书 400 410
//签名证书 500 510
//注册用户首先查询外部证书不存在或不使用则取得内部证书
//未注册用户取得内部证书
//如果bInsideOnly == TRUE,则只读取内部证书
BOOL CMiniCaApp::GetCertPair(UINT ID, char * sCert, DWORD & dLen, CString & sPwd,
BOOL bInsideOnly, CColorListBox * pList)
{
BOOL bExter = FALSE;//外部
UINT uResource = 0;
CString strInfo;
CColorListBox * p_List = NULL;
if(!pList)
{
p_List = &((CMiniMainDlg *)AfxGetMainWnd())->m_ListBox;
}
else
{
p_List = pList;
}
switch(ID) //根,服务器(加密),客户端(签名)
{
case 100:
uResource = IDR_ROOT_CERT;
strInfo = "根公钥";
break;
case 110:
uResource = IDR_ROOT_KEY;
strInfo = "根私钥";
break;
case 200:
case 400:
strInfo = "加密公钥";
uResource = IDR_ENC_CERT;
break;
case 210:
case 410:
strInfo = "加密私钥";
uResource = IDR_ENC_KEY;
break;
case 300:
case 500:
strInfo = "验证公钥";
uResource = IDR_SIGN_CERT;
break;
case 310:
case 510:
strInfo = "签名私钥";
uResource = IDR_SIGN_KEY;
break;
case 600:
strInfo = "文件公钥";
uResource = IDR_FILE_CERT;
break;
case 610:
strInfo = "文件私钥";
uResource = IDR_FILE_KEY;
break;
default:
return FALSE;
}
if(!bInsideOnly && IsReg())
{
CFile file;
CString m_CdbPath = GetAppPath() + "\\CertDB.CDB";
if(file.Open(m_CdbPath,CFile::modeRead))
{
for(;;)
{
stuCertDB CertDB;
int len = file.Read(&CertDB,sizeof(stuCertDB));
if(len==0)
break;
CString str;
// if(CertDB._bUSED)//证书库中存在项目并且使用
if(CertDB._uID == ID && CertDB._bUSED)//证书库中存在项目并且使用
{
//sCert = CertDB._chINFO;
memcpy(sCert, CertDB._chINFO, CertDB._uLENGTH);
dLen = CertDB._uLENGTH;
sPwd = CertDB._chPWD;
bExter = TRUE; //已经加载到了
if(IsWindow(p_List->m_hWnd))
{
CString str;
// str.Format("加载外部...",strInfo);
str.Format("加载外部证书...",strInfo);
p_List->AddMsg(str,M_WARING);
break;
}
}
}
file.Close();
}
}
if(!bExter) //没有加载到外部证书
{
HRSRC hRsrc=FindResource(NULL,MAKEINTRESOURCE(uResource),"CERT");
dLen = SizeofResource(NULL, hRsrc);
HGLOBAL hgCert=LoadResource(NULL,hRsrc);
memcpy(sCert, (LPSTR)LockResource(hgCert), dLen);
if(IsWindow(p_List->m_hWnd))
{
CString str;
// str.Format("加载内部%s...",strInfo);
str.Format("加载内部证书...",strInfo);
p_List->AddMsg(str,M_WARING);
}
}
return TRUE;
}
//new 外部证书全部改为根证书,也就是可以在5各根证书中选择任何一个
BOOL CMiniCaApp::GetRootCert(char * sCert, DWORD & dCertLen, char * sKey, DWORD & dKeyLen, CString & sPwd,
BOOL bInsideOnly, CColorListBox * pList)
{
BOOL bExter = FALSE;//外部
UINT uResource = 0;
CString strInfo;
CColorListBox * p_List = NULL;
if(!pList)
{
p_List = &((CMiniMainDlg *)AfxGetMainWnd())->m_ListBox;
}
else
{
p_List = pList;
}
if(!bInsideOnly && IsReg())
{
stuCertDB CertDB[10]; //zui多10各证书
stuCertDB * pCertDB[10]; //指针数组 按顺序指向上面的证书 [0] -> 100, [1] -> 110 , [2] -> [200];
// int len = sizeof(stuCertDB * [10]);
memset(pCertDB, 0, sizeof(stuCertDB * [10]));
int nIndex = 0;
CFile file;
CString m_CdbPath = GetAppPath() + "\\CertDB.CDB";
if(file.Open(m_CdbPath,CFile::modeRead))
{
for(nIndex = 0; ;nIndex++)
{
//由于保存证书的无序性,导致可能公鈅在后,私鈅在前,而且顺序也不一定是100,110,200,210
int len = file.Read(&CertDB[nIndex], sizeof(stuCertDB));
if(len==0)
break;
}
file.Close();
}
//顺序排列指针
for(int i = 0; i <= nIndex; i++)
{
switch(CertDB[i]._uID)
{
case 100:
pCertDB[0] = &CertDB[i];
break;
case 110:
pCertDB[1] = &CertDB[i];
break;
case 200:
pCertDB[2] = &CertDB[i];
case 210:
pCertDB[3] = &CertDB[i];
break;
case 300:
pCertDB[4] = &CertDB[i];
break;
case 310:
pCertDB[5] = &CertDB[i];
break;
case 400:
pCertDB[6] = &CertDB[i];
break;
case 410:
pCertDB[7] = &CertDB[i];
break;
case 500:
pCertDB[8] = &CertDB[i];
break;
case 510:
pCertDB[9] = &CertDB[i];
break;
}
}
for(i = 0; i < 5; i++)
{
int j = i*2;
if(pCertDB[j] && pCertDB[j+1]) //首先判断是否有效
{
if(pCertDB[j]->_bUSED && pCertDB[j+1]->_bUSED)//证书库中存在项目并且使用
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -