📄 cacore.cpp
字号:
if(req == NULL ) return CA_FAIL;
// 生成证书对象
X509 *ptemp=NULL;
if(isCA)
{
m_pCACert = X509_new();
ptemp = m_pCACert;
}
else
{
m_pClientCert = X509_new();
ptemp = m_pClientCert;
}
if( !isCA&&m_pCACert == NULL )
{
strcpy(szErrorString,"缺少CA证书!");
if(ptemp != NULL ) X509_free(ptemp);
ptemp = NULL;
return CA_FAIL;
}
// 设置证书基本项目
if (!X509_set_version(ptemp, 2))
{
strcpy(szErrorString,"设置版本号失败!");
if(ptemp != NULL ) X509_free(ptemp);
ptemp = NULL;
return CA_FAIL;
}
if (!ASN1_INTEGER_set(X509_get_serialNumber(ptemp),sn))
{
strcpy(szErrorString,"设置序列号失败!");
if(ptemp != NULL ) X509_free(ptemp);
ptemp = NULL;
return CA_FAIL;
}
if (!X509_gmtime_adj(X509_get_notBefore(ptemp),0))
{
strcpy(szErrorString,"设置开始时间失败!");
if(ptemp != NULL ) X509_free(ptemp);
ptemp = NULL;
return CA_FAIL;
}
if (!X509_gmtime_adj(X509_get_notAfter(ptemp), (long)60*60*24*days))
{
strcpy(szErrorString,"设置终止时间失败!");
if(ptemp != NULL ) X509_free(ptemp);
ptemp = NULL;
return CA_FAIL;
}
if (!X509_set_subject_name(ptemp, X509_REQ_get_subject_name(req)))
{
strcpy(szErrorString,"设置主体名失败!");
if(ptemp != NULL ) X509_free(ptemp);
ptemp = NULL;
return CA_FAIL;
}
EVP_PKEY *tmppkey = X509_REQ_get_pubkey(req);
if (!tmppkey || !X509_set_pubkey(ptemp,tmppkey))
{
strcpy(szErrorString,"设置公钥失败!");
if(ptemp != NULL ) X509_free(ptemp);
if(tmppkey != NULL )EVP_PKEY_free(tmppkey);
ptemp = NULL;
tmppkey = NULL;
return CA_FAIL;
}
EVP_PKEY_free(tmppkey);
X509_NAME *pName=X509_NAME_new();
if (pName == NULL )
{
strcpy(szErrorString,"创建X509名字对象失败!");
if(ptemp != NULL ) X509_free(ptemp);
ptemp = NULL;
return CA_FAIL;
}
if(isCA == TRUE )
{
pName = X509_REQ_get_subject_name(req);
}
else if(m_pCACert != NULL)
{
pName = X509_get_subject_name(m_pCACert);
}
else
{
pName = NULL;
}
if( pName == NULL)
{
strcpy(szErrorString,"设置证书签发者失败!");
if(ptemp != NULL ) X509_free(ptemp);
ptemp = NULL;
return CA_FAIL;
}
if (!X509_set_issuer_name(ptemp, pName))
{
strcpy(szErrorString,"设置证书签发者失败!");
if(ptemp != NULL ) X509_free(ptemp);
ptemp = NULL;
return CA_FAIL;
}
// 设置扩展项目
X509V3_CTX ctx;
if(isCA)
X509V3_set_ctx(&ctx, m_pCACert, m_pCACert, NULL, NULL, 0);
else
X509V3_set_ctx(&ctx, m_pCACert, m_pClientCert, NULL, NULL, 0);
for(int i = 0; i < EXT_COUNT ; i++)
{
X509_EXTENSION *x509_ext = X509_EXTENSION_new();
x509_ext = X509V3_EXT_conf(NULL,&ctx,
isCA?ca_ext_entry[i].name:client_ext_entry[i].name,
isCA?ca_ext_entry[i].value:client_ext_entry[i].value);
if(!x509_ext)
{
sprintf(szErrorString,"建立证书扩展(%s = %s)对象失败!",
isCA?ca_ext_entry[i].name:client_ext_entry[i].name,
isCA?ca_ext_entry[i].value:client_ext_entry[i].value);
if(ptemp != NULL ) X509_free(ptemp);
ptemp = NULL;
return CA_FAIL;
}
if(!X509_add_ext(isCA?m_pCACert:m_pClientCert,x509_ext,-1))
{
strcpy(szErrorString,"加入证书扩展对象失败!");
if(ptemp != NULL ) X509_free(ptemp);
ptemp = NULL;
return CA_FAIL;
}
X509_EXTENSION_free(x509_ext);
}
// 加入可选名
int san_pos = -100;
X509_EXTENSION *tmpsan = NULL;
STACK_OF(X509_EXTENSION) *req_exts;
req_exts = X509_REQ_get_extensions(req);
while(req_exts != NULL)
{
san_pos = X509v3_get_ext_by_NID(req_exts,OBJ_sn2nid(REQ_SUBJECT_ALT_NAME),
-1);
tmpsan =X509v3_get_ext(req_exts,san_pos);
break;
}
if(tmpsan != NULL)
{
if(!X509_add_ext(ptemp,tmpsan,-1))
{
strcpy(szErrorString,"加入主体可选名失败!");
if(ptemp != NULL ) X509_free(ptemp);
ptemp = NULL;
return CA_FAIL;
}
}
// 签名
if (!X509_sign(isCA?m_pCACert:m_pClientCert,m_pCAKey,digest))
{
strcpy(szErrorString,"为证书签名失败!");
if(ptemp != NULL ) X509_free(ptemp);
ptemp = NULL;
return CA_FAIL;
}
return CA_OK;
}
int CCACore::ToPKCS12(CString strPwd,CString strFileName,
CString strFriendlyName)
{
if(m_pClientCert == NULL || m_pClientKey == NULL)
{
sprintf(szErrorString,"%s","缺少证书与私钥!");
return CA_FAIL;
}
BIO *pbio;
pbio = BIO_new_file((LPSTR)(LPCTSTR)strFileName,"w");
PKCS12 *p12;
p12 = PKCS12_create((LPSTR)(LPCTSTR)strPwd,
(LPSTR)(LPCTSTR)strFriendlyName,m_pClientKey, m_pClientCert,
NULL, 0,0,0,0,0);
if(!p12)
{
sprintf(szErrorString, "创建 PKCS#12 结构失败!");
goto err;
}
i2d_PKCS12_bio(pbio,p12);
PKCS12_free(p12);
p12 = NULL;
BIO_free(pbio);
pbio = NULL;
return CA_OK;
err:
PKCS12_free(p12);
p12 = NULL;
BIO_free(pbio);
pbio = NULL;
return CA_FAIL;
}
int CCACore::MakeCRL(CString strFileName,
CRevokeCertList *prev,
long crldays,
long crlhours)
{
// 初始化
int it = 0;
int count = 0;
BIO *hex=NULL;
X509_REVOKED * xrev = NULL;
STACK_OF(X509_REVOKED) *revoked ;
revoked = sk_X509_REVOKED_new_null();
if(revoked == NULL)
{
sprintf(szErrorString,"%s","申请吊销内容空间失败!");
goto err;
}
m_pCrl = X509_CRL_new();
if(m_pCrl == NULL)
{
sprintf(szErrorString,"%s","生成CRL对象失败!");
return CA_FAIL;
}
if ((hex=BIO_new(BIO_s_mem())) == NULL)
{
sprintf(szErrorString,"%s","申请BIO内存空间失败!");
goto err;
}
BIO *pbio;
pbio = BIO_new_file((LPSTR)(LPCTSTR)strFileName,"w");
// 合法性检查
if(m_pCACert == NULL)
{
strcpy(szErrorString,"缺少CA证书!");
return CA_FAIL;
}
// 生成基本项目
m_pCrlInfo = m_pCrl->crl;
if ((m_pCrlInfo->version=ASN1_INTEGER_new()) == NULL)
{
sprintf(szErrorString,"%s","申请版本号内存空间失败!");
goto err;
}
ASN1_INTEGER_set(m_pCrlInfo->version,1); /* version 2 CRL */
X509_NAME_free(m_pCrlInfo->issuer);
m_pCrlInfo->issuer=X509_NAME_dup(m_pCACert->cert_info->subject);
if (m_pCrlInfo->issuer == NULL)
{
sprintf(szErrorString,"%s","无法取得CA名称");
goto err;
}
X509_gmtime_adj(m_pCrlInfo->lastUpdate,0);
if (m_pCrlInfo->nextUpdate == NULL)
m_pCrlInfo->nextUpdate=ASN1_UTCTIME_new();
X509_gmtime_adj(m_pCrlInfo->nextUpdate,(crldays*24+crlhours)*60*60);
// 生成吊销的内容
// revokeCertificates := SEQUENCE OF SEQUENCE
// {
// userCertificate CertificateSerialNumber,
// revocationDate Time,
// crlEntryExtensions Extensions OPTIONAL(if present,shall be V2)
// }
count = prev->GetCount();
if(count <= 0)
{
sprintf(szErrorString,"%s","没有证书供吊销!");
goto err;
}
for(it=0; it<count ; it++)
{
xrev = X509_REVOKED_new();
if(xrev == NULL)
{
sprintf(szErrorString,"%s","申请X509_REVOKED内容失败!");
goto err;
}
time_t t;
//time(&t);
t=prev->GetTime_t(it);
if(t == -1L)
{
sprintf(szErrorString,"%s","取证书吊销时间失败!");
goto err;
}
ASN1_TIME_set(xrev->revocationDate,t);
ASN1_INTEGER_set(xrev->serialNumber,atol(prev->GetSerialStr(it)));
sk_X509_REVOKED_push(m_pCrlInfo->revoked,xrev);
}
sk_X509_REVOKED_sort(m_pCrlInfo->revoked);
for (it=0; it<sk_X509_REVOKED_num(m_pCrlInfo->revoked); it++)
{
xrev=sk_X509_REVOKED_value(m_pCrlInfo->revoked,it);
xrev->sequence=it;
}
// 签名
if (!X509_CRL_sign(m_pCrl,m_pCAKey,digest))
{
sprintf(szErrorString,"%s","为CRL签名失败!");
goto err;
}
// 输出到文件
if(!PEM_write_bio_X509_CRL(pbio,m_pCrl))
{
sprintf(szErrorString,"%s","CRL写入文件失败!");
goto err;
}
if(hex != NULL) BIO_free(hex);
if(pbio != NULL) BIO_free(pbio);
if(revoked != NULL) sk_X509_REVOKED_pop_free(revoked,X509_REVOKED_free);
if(m_pCrl != NULL) X509_CRL_free(m_pCrl);
return CA_OK;
// 集中进行出错处理,以解决内存泄漏问题
err:
if(hex != NULL) BIO_free(hex);
if(pbio != NULL) BIO_free(pbio);
if(revoked != NULL) sk_X509_REVOKED_pop_free(revoked,X509_REVOKED_free);
if(m_pCrl != NULL) X509_CRL_free(m_pCrl);
return CA_FAIL;
}
void CCACore::FreeCertificate(BOOL isCA)
{
if(isCA&&m_pCACert != NULL)
{
X509_free(m_pCACert);
m_pCACert = NULL;
}
if(!isCA&&m_pClientCert != NULL)
{
X509_free(m_pCACert);
m_pCACert = NULL;
}
}
// 将私钥转成pem字符串
int CCACore::PrivateKeyToPEM(
BOOL isCA, // 是否为CA
CString strPwd, // 密码
char *buf, // 外面缓冲区
int len) // 缓冲区的长度
{
BIO *pbio;
pbio = BIO_new(BIO_s_mem());
// 写入缓冲区
if(!PEM_write_bio_PrivateKey(pbio,isCA?m_pCAKey:m_pClientKey,
EVP_des_cbc(),(unsigned char*)(LPCTSTR)strPwd,
strPwd.GetLength(),0,NULL))
goto err;
// 拷贝到buf中
BUF_MEM * bptr;
BIO_get_mem_ptr(pbio,&bptr);
if(bptr->length < len)
{
memcpy(buf,bptr->data,bptr->length);
buf[bptr->length]='\0';
}
else
buf[0]='\0';
BIO_set_close(pbio,BIO_CLOSE);
BIO_free(pbio);
pbio = NULL;
return CA_OK;
err:
strcpy(szErrorString,"将私钥转成PEM失败!");
BIO_free(pbio);
pbio = NULL;
return CA_FAIL;
}
// 将证书转成pem字符串
int CCACore::CertificateToPEM(BOOL isCA,char *buf, int len)
{
BIO *pbio;
pbio = BIO_new(BIO_s_mem());
// 写入缓冲区
if(!PEM_write_bio_X509(pbio,isCA?m_pCACert:m_pClientCert))
goto err;
// 拷贝到buf中
BUF_MEM * bptr;
BIO_get_mem_ptr(pbio,&bptr);
if(bptr->length < len)
{
memcpy(buf,bptr->data,bptr->length);
buf[bptr->length]='\0';
}
else
buf[0]='\0';
BIO_set_close(pbio,BIO_CLOSE);
BIO_free(pbio);
pbio = NULL;
return CA_OK;
err:
strcpy(szErrorString,"将私钥转成PEM失败!");
BIO_free(pbio);
pbio = NULL;
return CA_FAIL;
}
BOOL CCACore::HasValidCA()
{
BOOL bRet = FALSE;
if(m_pCAKey != NULL && m_pCACert != NULL&&X509_check_private_key(m_pCACert,m_pCAKey))
bRet = TRUE;
return bRet;
}
int CCACore::add_ext(STACK_OF(X509_REQUEST) *sk, int nid, char *value)
{
X509_EXTENSION *ex;
ex = X509V3_EXT_conf_nid(NULL, NULL, nid, value);
if (!ex)
return CA_FAIL;
sk_X509_EXTENSION_push(sk, ex);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -