⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 minica.cpp

📁 MiniCA V2.0版本源码。《小型CA系统V2.1含源码》发表以来
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	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 + -