📄 certsetup.cpp
字号:
// CertSetup.cpp: implementation of the CCertSetup class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "CertSetup.h"
#include "bca_all.h"
#include <io.h>
#include <direct.h>
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CCertSetup::CCertSetup()
{
dwCertCount = 0;
LoadSetupConfig();
memset(&CERTINFO,0,sizeof(CERTINFO));
}
CCertSetup::~CCertSetup()
{
}
//安装证书,sContainerName:容器名,1:智能卡证书
//dwType=0:文件证书, sContainerName=cbi文件路径
BOOL CCertSetup::InstallCert(CString sContainerName, DWORD dwType)
{
memset(&CERTINFO,0,sizeof(CERTINFO));
if(dwType == 1)//智能卡证书
{
if(!GetCertAndSavetoDisk(sContainerName))
{
return FALSE;
}
if(!SetXMLConfigNodeInfo(sContainerName))
{
return FALSE;
}
DisableOldCert(sContainerName);
UpdateXmlConfig();
return TRUE;
}
else if(dwType == 0)//cbi证书
{
CString sContainerName1;
if(!ParseCBIFileAndSaveCertToDisk(sContainerName,sContainerName1))
{
return FALSE;
}
if(!SetXMLConfigNodeInfo(sContainerName1))
{
return FALSE;
}
DisableOldCert(sContainerName1);
return TRUE;
}
else
{
ErrMsg = "无效参数";
return FALSE;
}
return FALSE;
}
//枚举证书
BOOL CCertSetup::EnumUsrCertificates()
{
int rv;
DWORD i;
char errcode[128];
BCA_USR_CERT_ENUMLIST usrCerts;
CString sTmp;
CString sNotBefor;
CString sNotAfter;
CString sIssue;
CString sSubjectName;
rv = BCA_Initialize(BCA_PROVIDER_CSP,provider.GetBuffer(0),1,privateDll.GetBuffer(0));
provider.ReleaseBuffer();
privateDll.ReleaseBuffer();
if(rv)
{
switch(rv)
{
case RV_ProviderTypeErr:
ErrMsg = "设备Provider错误!";
break;
case RV_LoadProviderErr:
ErrMsg = "打开设备错误,请检查USB KEY设备驱动是否安装正确!";
break;
case RV_OpenDevErr:
ErrMsg = "打开设备出错, 请检查是否正确插入USB KEY设备!";
break;
default:
sprintf(errcode,"%d",rv);
ErrMsg = "初始化设备错误,错误码:";
ErrMsg += errcode;
break;
}
return FALSE;
}
rv = BCA_EnumUsrCertificates(&usrCerts);
if(rv)
{
sprintf(errcode,"%d",rv);
ErrMsg = "枚举证书错误,错误码:";
ErrMsg += errcode;
return FALSE;
}
dwCertCount = usrCerts.certCount;
//清除原来的列表
sNotAfters.RemoveAll();
sNotBefors.RemoveAll();
sIssues.RemoveAll();
sSubjectNames.RemoveAll();
for(i=0; i<dwCertCount; i++)
{
sTmp = usrCerts.containerName[i];
sContainerNames.Add(sTmp);
if(!GetCertValidTime(usrCerts.certificate[i],usrCerts.certificateLen[i],sNotBefor,sNotAfter))
{
BCA_EnumUsrCertificatesFree(&usrCerts);
dwCertCount = i;
return FALSE;
}
sNotBefors.Add(sNotBefor);
sNotAfters.Add(sNotAfter);
if(!GetCertName(usrCerts.certificate[i],usrCerts.certificateLen[i],sIssue,sSubjectName))
{
BCA_EnumUsrCertificatesFree(&usrCerts);
dwCertCount = i;
return FALSE;
}
sIssues.Add(sIssue);
sSubjectNames.Add(sSubjectName);
}
BCA_EnumUsrCertificatesFree(&usrCerts);
return TRUE;
}
DWORD CCertSetup::GetCertCount()
{
return dwCertCount;
}
CString CCertSetup::GetContainerNameByIndex(DWORD dwIndex)
{
return sContainerNames.GetAt(dwIndex);
}
CString CCertSetup::GetIssueByIndex(DWORD dwIndex)
{
return sIssues.GetAt(dwIndex);
}
CString CCertSetup::GetSubjectNameByIndex(DWORD dwIndex)
{
return sSubjectNames.GetAt(dwIndex);
}
CString CCertSetup::GetNotBeforByIndex(DWORD dwIndex)
{
return sNotBefors.GetAt(dwIndex);
}
CString CCertSetup::GetNotAfterByIndex(DWORD dwIndex)
{
return sNotAfters.GetAt(dwIndex);
}
BOOL CCertSetup::GetCertValidTime(BYTE *cert, DWORD dwCertLen, CString &sNotBefor, CString &sNotAfter)
{
int rv;
char notBefor[128] = {0};
char notAfter[128] = {0};
int infoLen;
rv = BCA_GetCertificateInfo(cert,dwCertLen,11,notBefor,&infoLen);
if(rv)
{
ErrMsg = "获取证书有效起始日期失败";
return FALSE;
}
sNotBefor = notBefor;
rv = BCA_GetCertificateInfo(cert,dwCertLen,12,notAfter,&infoLen);
if(rv)
{
ErrMsg = "获取证书有效终止日期失败";
return FALSE;
}
sNotAfter = notAfter;
//时间格式20061126
sNotBefor = sNotBefor.Left(8);
sNotBefor.Insert(4,"年");
sNotBefor.Insert(8,"月");
sNotBefor.Insert(12,"日");
sNotAfter = sNotAfter.Left(8);
sNotAfter.Insert(4,"年");
sNotAfter.Insert(8,"月");
sNotAfter.Insert(12,"日");
ErrMsg.Empty();
return TRUE;
}
BOOL CCertSetup::GetCertName(BYTE *cert, DWORD dwCertLen, CString &sIssue, CString &sSubjectName)
{
int rv;
char issuename[256] = {0};
char subjectname[256] = {0};
int infoLen;
rv = BCA_GetCertificateInfo(cert,dwCertLen,8,issuename,&infoLen);
if(rv)
{
ErrMsg = "获取证书颁发者通用名失败";
return FALSE;
}
issuename[infoLen] = '\0';
sIssue = issuename;
rv = BCA_GetCertificateInfo(cert,dwCertLen,17,subjectname,&infoLen);
if(rv)
{
ErrMsg = "获取证书拥有者通用名失败";
return FALSE;
}
subjectname[infoLen] = '\0';
sSubjectName = subjectname;
ErrMsg.Empty();
return TRUE;
}
BOOL CCertSetup::UpdateXmlConfig()
{
int rv;
char XMLPath[256]={0};
if(CN_GetXmlPath(XMLPath))
{
ErrMsg = "读取XML配置文件失败!";
return FALSE;
}
rv = CN_IsDevTypeNoExist(XMLPath,devType.GetBuffer(0));
if(rv == -1)
{
//节点不存在,添加节点
rv = CN_AddDeviceTypeNode(XMLPath,devType.GetBuffer(0));
if(rv!=0)
{
ErrMsg = "添加XML配置文件节点失败!";
return FALSE;
}
}
rv = CN_AddDeviceName(XMLPath,devType.GetBuffer(0),DevName.GetBuffer(0));
if(rv)
{
ErrMsg = "修改XML配置文件,添加设备名称失败!";
return FALSE;
}
rv = CN_AddDeviceProvider(XMLPath,devType.GetBuffer(0),provider.GetBuffer(0));
if(rv)
{
ErrMsg = "修改XML配置文件,添加csp名称失败!";
return FALSE;
}
rv = CN_AddDeviceAffix(XMLPath,devType.GetBuffer(0),privateDll.GetBuffer(0));
if(rv)
{
ErrMsg = "修改XML配置文件,添加扩展dll名称失败!";
return FALSE;
}
return TRUE;
}
BOOL CCertSetup::LoadSetupConfig()
{
SetupIniFile.SetFileName("setup.ini");
devType = SetupIniFile.GetString("dev","devType","");
if(devType.IsEmpty())
{
devType = "BJCSP0004";
}
provider = SetupIniFile.GetString("dev","provider","");
if(provider.IsEmpty())
{
provider = "M&W eKey XCSP";
}
privateDll = SetupIniFile.GetString("dev","privateDll","");
if(privateDll.IsEmpty())
{
privateDll = "BjcaKey_MW.dll";
}
DevName = SetupIniFile.GetString("dev","DevName","");
if(DevName.IsEmpty())
{
DevName = "明华(EKII-PKXC-64K)";
}
caType = SetupIniFile.GetString("dev","caType","");
tradeType = SetupIniFile.GetString("dev","tradeType","");
return TRUE;
}
//dwType :1 加密证书,2:签名证书 3:加密证书pfx,4:签名证书pfx
CString CCertSetup::GetFilePathByContainerName(CString sContainerName,DWORD dwType)
{
CString rv;
char certfilepath[256];
char syspath[256];
char *ContainerName = NULL;
ContainerName = sContainerName.GetBuffer(0);
GetSystemDirectory(syspath,256);
strcpy(certfilepath,"C:\\BJCAROOT\\Cert\\");
certfilepath[0] = syspath[0];
//检查C:\\BJCAROOT\\Cert\\是否存在
if(_access(certfilepath,0) != 0)//不存在建目录
{
_mkdir(certfilepath);
}
strcat(certfilepath,ContainerName);
//检查以ContainerName命名的文件夹是否存在
if(_access(certfilepath,0) != 0)//不存在建目录
{
_mkdir(certfilepath);
}
strcat(certfilepath,"\\");
strcat(certfilepath,ContainerName);
switch(dwType)
{
case 1:
strcat(certfilepath,"-Encipherment.der");
break;
case 2:
strcat(certfilepath,"-Signature.der");
break;
case 3:
strcat(certfilepath,"-Encipherment.pfx");
break;
case 4:
strcat(certfilepath,"-Signature.pfx");
break;
default:
ErrMsg = "无效参数";
return "";
}
rv = certfilepath;
ErrMsg.Empty();
sContainerName.ReleaseBuffer();
return rv;
}
//dwType 1:加密证书,2:签名证书
BOOL CCertSetup::GetCertAndSavetoDisk(CString sContainerName,DWORD dwType)
{
BYTE cert[4096];
DWORD certLen;
int rv;
char *FilePath = NULL;
FILE *fp;
CString sFilePath;
rv = BCA_GetUsrCertificate((BYTE *)sContainerName.GetBuffer(0),sContainerName.GetLength(),dwType,cert,&certLen);
if(rv)
{
ErrMsg ="从usbkey获得证书失败";
sContainerName.ReleaseBuffer();
return FALSE;
}
if(!GetCertInfo(cert,certLen,dwType,&CERTINFO))
{
return FALSE;
}
sFilePath = GetFilePathByContainerName(sContainerName,dwType);
FilePath = sFilePath.GetBuffer(0);
fp = fopen(FilePath,"wb");
if(fp == NULL)
{
ErrMsg ="保存证书失败";
sFilePath.ReleaseBuffer();
sContainerName.ReleaseBuffer();
return FALSE;
}
fwrite(cert,1,certLen,fp);
fclose(fp);
ErrMsg.Empty();
sContainerName.ReleaseBuffer();
sFilePath.ReleaseBuffer();
return TRUE;
}
BOOL CCertSetup::GetCertAndSavetoDisk(CString sContainerName)
{
if(!GetCertAndSavetoDisk(sContainerName,1))
{
return FALSE;
}
if(GetCertAndSavetoDisk(sContainerName,2))//没找到签名证书
{
CERTINFO.keyType = 2;
}
else
{
CERTINFO.keyType = 1;
}
strcpy(CERTINFO.devType,devType.GetBuffer(0));
strcpy(CERTINFO.caType,caType.GetBuffer(0));
strcpy(CERTINFO.tradeType,tradeType.GetBuffer(0));
devType.ReleaseBuffer();
caType.ReleaseBuffer();
tradeType.ReleaseBuffer();
return TRUE;
}
//输入参数:新安装的容器名,
//函数说明:根据容器名找到主题名,把其他已经存在主题名设置为无效.
BOOL CCertSetup::DisableOldCert(CString sNewContainerName)
{
int rv;
char XMLPath[256]={0};
char *containername;
char subject[1024]={0};
CString sSubject;
CStringArray sTmpcontainers;
sTmpcontainers.RemoveAll();
containername = sNewContainerName.GetBuffer(0);
if(CN_GetXmlPath(XMLPath))
{
ErrMsg = "读取XML配置文件失败!";
sNewContainerName.ReleaseBuffer();
return FALSE;
}
rv = CN_GetCertSubject(XMLPath,containername,subject);
if(rv)
{
ErrMsg = "读取XML配置文件失败!";
sNewContainerName.ReleaseBuffer();
return FALSE;
}
sSubject = subject;
int i = 0;
int count = 0;
CN_GetAvailContainerCount(XMLPath,&count);
CString sTmpContainer;
CString sTmpSubject;
for(i=0; i<count; i++)
{
char tmpcontainer[256];
memset(tmpcontainer,0,256);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -