📄 cacore.cpp
字号:
// CACore.cpp: implementation of the CCACore class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "CACore.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
#include "RevokeCertList.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
struct entry
{
char *name;
char *value;
};
static struct entry client_ext_entry[EXT_COUNT]=
{
{"basicConstraints","CA:FALSE"},
{"nsComment","\"CES-CA Generate Certificate\""},
{"subjectKeyIdentifier","hash"},
{"authorityKeyIdentifier","keyid,issuer:always"},
{"keyUsage","nonRepudiation,digitalSignature,keyEncipherment,keyAgreement"}
};
static struct entry ca_ext_entry[EXT_COUNT]=
{
{"basicConstraints","CA:true"},
{"nsComment","\"CES-CA Generate Certificate\""},
{"subjectKeyIdentifier","hash"},
{"authorityKeyIdentifier","keyid:always,issuer:always"},
{"keyUsage","cRLSign,keyCertSign"}
};
IMPLEMENT_DYNCREATE(CCACore, CObject)
CCACore::CCACore()
{
szKeyLength[0] ='\0';
szCountryName[0] ='\0';
szProvinceName[0] ='\0';
szCityName[0] ='\0';
szOrgName[0] ='\0';
szDeptName[0] ='\0';
szCommonName[0] ='\0';
szSubjectAltName[0] ='\0';
szEmail[0] ='\0';
szCertValidate[0] ='\0';
// error reason
szErrorString[0] ='\0';
//
pNewRsaKey = NULL;
pSubjectName = NULL;
ext = NULL;
extlist = NULL;
digest = NULL;
m_pClientKey = NULL;
m_pClientCert = NULL;
m_pCAKey = NULL;
m_pCACert = NULL;
digest = EVP_sha1();
m_pCrl = NULL;
m_pCrlInfo = NULL;
OpenSSL_add_all_algorithms();
ERR_load_crypto_strings();
}
CCACore::~CCACore()
{
}
void CCACore::SetCountryName(CString strCNN)
{
sprintf(szCountryName,"%s",(LPSTR)(LPCTSTR)strCNN);
}
void CCACore::SetProvinceName(CString strPRN)
{
sprintf(szProvinceName,"%s",(LPSTR)(LPCTSTR)strPRN);
}
void CCACore::SetCityName(CString strCTN)
{
sprintf(szCityName,"%s",(LPSTR)(LPCTSTR)strCTN);
}
void CCACore::SetOrgName(CString strORGN)
{
sprintf(szOrgName,"%s",(LPSTR)(LPCTSTR)strORGN);
}
void CCACore::SetDeptName(CString strDPN)
{
sprintf(szDeptName,"%s",(LPSTR)(LPCTSTR)strDPN);
}
void CCACore::SetCommonName(CString strCMN)
{
sprintf(szCommonName,"%s",(LPSTR)(LPCTSTR)strCMN);
}
void CCACore::SetSubjectAltName(CString strSAN)
{
sprintf(szSubjectAltName,"%s",(LPSTR)(LPCTSTR)strSAN);
}
void CCACore::GetErrString(char *pErrStr)
{
strcpy(pErrStr,szErrorString);
}
void CCACore::SetEmail(CString strEmail)
{
sprintf(szEmail,"%s",(LPSTR)(LPCTSTR)strEmail);
}
void CCACore::SetCertValidate(CString strCertValidate)
{
sprintf(szCertValidate,"%s",(LPSTR)(LPCTSTR)strCertValidate);
}
void CCACore::SetKeyLength(CString strLength)
{
sprintf(szKeyLength,"%s",(LPSTR)(LPCTSTR)strLength);
}
int CCACore::GenerateRSAKeyPair()
{
if(strlen(szKeyLength)==0) return -1;
int keylength=atoi(szKeyLength);
// 注意内存泄漏
if ((pNewRsaKey=EVP_PKEY_new()) == NULL) return CA_FAIL;
int ret = EVP_PKEY_assign_RSA(pNewRsaKey,
RSA_generate_key(keylength,0x10001,
NULL, // req_cb
NULL)); // cb args
if(ret != 1) return CA_FAIL;
return CA_OK;
}
void CCACore::AddPukToREQ()
{
X509_REQ_set_pubkey(req,pNewRsaKey);
}
void CCACore::FreeEvpKey(BOOL isCA)
{
if(isCA&&m_pCAKey != NULL)
{
EVP_PKEY_free(m_pCAKey);
m_pCAKey = NULL;
}
if(!isCA&&m_pClientKey != NULL)
{
EVP_PKEY_free(m_pCAKey);
m_pClientKey = NULL;
}
}
int CCACore::AddSubjectEntry(char *key, char *value)
{
int nid;
X509_NAME_ENTRY *ent;
if( (nid =OBJ_txt2nid(key)) == NID_undef )
{
sprintf(szErrorString,"没有找到NID:%s",key);
return CA_FAIL;
}
ent = X509_NAME_ENTRY_create_by_NID(NULL,nid,MBSTRING_UTF8,
(unsigned char*)value,-1);
if(ent == NULL)
{
sprintf(szErrorString,"创建%s名字实体失败!",key);
return CA_FAIL;
}
if(X509_NAME_add_entry(pSubjectName,ent,-1,0) != 1)
{
sprintf(szErrorString,"加入%s名字实体失败!",key);
return CA_FAIL;
}
return CA_OK;
}
int CCACore::AddSubjectToREQ()
{
int ret ;
// 0.生成主体名对象
pSubjectName = X509_NAME_new();
if(pSubjectName == NULL)
{
strcpy(szErrorString,"建立主体名对象失败!");
return CA_FAIL;
}
// 1.加入国家的名称
if(strlen(szCountryName)==0)
{
strcpy(szErrorString,"国家名不能为空!");
return CA_FAIL;
}
ret = AddSubjectEntry(REQ_COUNTRY_NAME,szCountryName);
if( ret == CA_FAIL ) return CA_FAIL;
// 2.加入省份的名字(可选)
if(strlen(szProvinceName) > 0)
{
ret = AddSubjectEntry(REQ_STATA_OR_PROVINCE_NAME,szProvinceName);
if( ret == CA_FAIL ) return CA_FAIL;
}
// 3.加入城市的名字
if(strlen(szCityName)==0)
{
strcpy(szErrorString,"城市名不能为空!");
return CA_FAIL;
}
ret = AddSubjectEntry(REQ_LOCALITE_NAME,szCityName);
if( ret == CA_FAIL ) return CA_FAIL;
// 4.加入组织/单位的名字
if(strlen(szOrgName)==0)
{
strcpy(szErrorString,"组织名或单位名不能为空!");
return CA_FAIL;
}
ret = AddSubjectEntry(REQ_ORG_NAME,szOrgName);
if( ret == CA_FAIL ) return CA_FAIL;
// 5.加入部门名称(可选)
if(strlen(szDeptName) > 0)
{
ret = AddSubjectEntry(REQ_DEPT_NAME,szDeptName);
if( ret == CA_FAIL ) return CA_FAIL;
}
// 6.加入通用名
if(strlen(szCommonName)==0)
{
strcpy(szErrorString,"证书请求者名字不能为空!");
return CA_FAIL;
}
ret = AddSubjectEntry(REQ_COMMON_NAME,szCommonName);
if( ret == CA_FAIL ) return CA_FAIL;
// 加入主体名
if(X509_REQ_set_subject_name(req,pSubjectName) != 1)
{
strcpy(szErrorString,"主体名加入证书请求对象失败!");
return CA_FAIL;
}
// 最后返回成功
return CA_OK;
}
int CCACore::AddExtEntry(char *name, char *value)
{
ext = X509V3_EXT_conf(NULL,NULL,name,value);
if(ext == NULL)
{
sprintf(szErrorString,"生成生成扩展对象%s失败!",name);
return CA_FAIL;
}
sk_X509_EXTENSION_push(extlist,ext);
return CA_OK;
}
int CCACore::GenerateREQ(BOOL isCA)
{
int ret;
// 生成证书请求对象
req = X509_REQ_new();
if( req == NULL)
{
strcpy(szErrorString,"建立证书请求对象失败!");
return CA_FAIL;
}
// 生成密钥对
if(GenerateRSAKeyPair() != CA_OK)
{
strcpy(szErrorString,"生成RSA密钥失败!");
return CA_FAIL;
}
AddPukToREQ();
if(isCA) m_pCAKey = pNewRsaKey;
else m_pClientKey = pNewRsaKey;
// 加入主体名
ret = AddSubjectToREQ();
if( ret != CA_OK) return CA_FAIL;
if(strlen(szSubjectAltName) == 0) return CA_OK;
// 加入扩展
extlist = sk_X509_EXTENSION_new_null();
// 加入具体项目
ret = AddExtEntry(REQ_SUBJECT_ALT_NAME,szSubjectAltName);
if( ret != CA_OK) return CA_FAIL;
ret = CA_OK;
if(!X509_REQ_add_extensions(req,extlist))
{
strcpy(szErrorString,"加入证书扩展项目失败!");
ret = CA_FAIL;
}
sk_X509_EXTENSION_pop_free(extlist,X509_EXTENSION_free);
extlist = NULL;
if(ret == CA_FAIL) return CA_FAIL;
szSubjectAltName[0] = '\0';
return CA_OK;
}
// 证书存取接口
int CCACore::SavePrivateKey(CString strFileName,CString strPwd,
int FileFormat,BOOL isCA)
{
BIO *pbio;
pbio = BIO_new_file((LPSTR)(LPCTSTR)strFileName,"w");
if(isCA)
{
if(!PEM_write_bio_PrivateKey(pbio,m_pCAKey,EVP_des_cbc(),
(unsigned char*)(LPCTSTR)strPwd,strPwd.GetLength(),0,NULL))
goto err;
}
else
{
if(!PEM_write_bio_PrivateKey(pbio,m_pClientKey,EVP_des_cbc(),
(unsigned char*)(LPCTSTR)strPwd,strPwd.GetLength(),0,NULL))
goto err;
}
BIO_free(pbio);
pbio = NULL;
return CA_OK;
err:
strcpy(szErrorString,"将私钥写入文件失败!");
BIO_free(pbio);
pbio = NULL;
return CA_FAIL;
}
int CCACore::GetPrivateKey(CString strFileName,CString strPwd,
int FileFormat,BOOL isCA)
{
BIO *pbio;
pbio = BIO_new_file((LPSTR)(LPCTSTR)strFileName,"r");
if(isCA)
{
m_pCAKey = PEM_read_bio_PrivateKey(pbio,NULL,0,
(unsigned char*)(LPCTSTR)strPwd);
if(m_pCAKey == NULL)goto err;
}
else
{
m_pClientKey = PEM_read_bio_PrivateKey(pbio,NULL,0,
(unsigned char*)(LPCTSTR)strPwd);
if(m_pClientKey == NULL)goto err;
}
BIO_free(pbio);
pbio = NULL;
return CA_OK;
err:
strcpy(szErrorString,"读私钥文件失败!");
BIO_free(pbio);
pbio = NULL;
return CA_FAIL;
}
int CCACore::SaveCertificate(CString strFileName,int FileFormat,
BOOL isCA)
{
BIO *pbio;
pbio = BIO_new_file((LPSTR)(LPCTSTR)strFileName,"w");
if(FileFormat?
!i2d_X509_bio(pbio,isCA?m_pCACert:m_pClientCert):
!PEM_write_bio_X509(pbio,isCA?m_pCACert:m_pClientCert)
)goto err;
BIO_free(pbio);
pbio = NULL;
return CA_OK;
err:
strcpy(szErrorString,"证书写入文件失败!");
BIO_free(pbio);
pbio = NULL;
return CA_FAIL;
}
int CCACore::GetCertificate(CString strFileName,int FileFormat,
BOOL isCA)
{
BIO *pbio;
pbio = BIO_new_file((LPSTR)(LPCTSTR)strFileName,"r");
if(isCA)
{
m_pCACert = FileFormat?
d2i_X509_bio(pbio,NULL):
PEM_read_bio_X509(pbio,NULL,NULL,NULL);
if(!m_pCACert)goto err;
}
else
{
m_pClientCert = FileFormat?
d2i_X509_bio(pbio,NULL):
PEM_read_bio_X509(pbio,NULL,NULL,NULL);
if(!m_pCACert)goto err;
}
BIO_free(pbio);
pbio = NULL;
return CA_OK;
err:
strcpy(szErrorString,"读证书文件失败!");
BIO_free(pbio);
pbio = NULL;
return CA_FAIL;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -