📄 ca.cpp
字号:
const char * strPwd2/*IN新密码*/,
const char * strOutP12/*in新包文件*/,
char * outMsg/*返回结果*/)
{
BIO *bin = NULL;
BIO *biout = NULL;
EVP_PKEY *key = NULL;
X509 *pCert = NULL;
PKCS12 *p12 = NULL;
int len = 0,
wlen = 0;
BOOL bRet = TRUE;
OpenSSL_add_all_algorithms();
//输入文件
if ((bin=BIO_new_file(strP12, "rw")) == NULL)
{
strcpy(outMsg,"加载PFX文件错误");
bRet = FALSE;
goto err;
}
p12 = d2i_PKCS12_bio(bin, NULL);
if (!p12)
{
strcpy(outMsg,"加载包文件失败");
bRet = FALSE;
goto err;
}
if (!PKCS12_parse(p12, strPwd, &key, &pCert, NULL))
{
strcpy(outMsg,"解包失败");
bRet = FALSE;
goto err;
}
///////////////////////////////////////
if(p12)
PKCS12_free(p12);
p12 = NULL;
p12 = PKCS12_create((char *)strPwd2,"MiniCA", key, pCert, NULL, 0,0,0,0,0);
if(!p12)
{
strcpy(outMsg,"创建p12结构失败");
bRet = FALSE;
goto err;
}
//输出文件
if ((biout = BIO_new_file(strP12, "w")) == NULL)
{
strcpy(outMsg,"创建输出文件失败");
bRet = FALSE;
goto err;
}
i2d_PKCS12_bio(biout, p12);
err:
if(p12)
PKCS12_free(p12);
if(pCert)
X509_free(pCert);
if(key)
EVP_PKEY_free(key);
if (bin)
BIO_free(bin);
if (biout)
BIO_free(biout);
// EVP_cleanup();//frees all three stacks and sets their pointers to NULL ---- EVP_CIPHER
return bRet;
}
//检验公钥、私钥是否配对
BOOL CertPairCheck(const char * pCert,
const char * key,
char * outMsg,
const char * priPwd )//检验公钥、私钥是否配对
{
EVP_PKEY *pkey=NULL;
X509 *px509=NULL;
px509=LoadCert(pCert,0,"",outMsg);
if(px509==NULL)
{
strcpy(outMsg,"不能加载公钥文件");
return FALSE;
}
pkey=LoadKey(key,0,priPwd,outMsg);
if(pkey==NULL)
{
strcpy(outMsg,"不能加载私钥文件");
X509_free(px509);
return FALSE;
}
if(X509_check_private_key(px509,pkey))//匹配
{
X509_free(px509);
EVP_PKEY_free(pkey);
return TRUE;
}
else
{
strcpy(outMsg,"公私钥对不匹配");
X509_free(px509);
EVP_PKEY_free(pkey);
return FALSE;
}
}
int HexToTen(const char * pHex)
{
DWORD dwHexNum=0;
for (; *pHex!=0 ; pHex++)
{
dwHexNum *= 16;
if ((*pHex>='0') && (*pHex<='9'))
dwHexNum += *pHex-'0';
else if ((*pHex>='a') && (*pHex<='f'))
dwHexNum += *pHex-'a'+10;
else if ((*pHex>='A') && (*pHex<='F'))
dwHexNum += *pHex-'A'+10;
else
-1;
}
return dwHexNum;
}
void Utf8ToAnsi(const UCHAR * lpsrc,const int srclen, LPSTR lpdst, int& dstlen)
{
WCHAR * Unicode;
int len = MultiByteToWideChar ( CP_UTF8 , 0 ,(char*) lpsrc ,-1 ,NULL,0);
Unicode = new WCHAR[len * sizeof(WCHAR)];
MultiByteToWideChar ( CP_UTF8 , 0 ,( char * ) lpsrc, -1, Unicode , len );
len = WideCharToMultiByte(CP_ACP,0,Unicode,-1,NULL,0,NULL,NULL);
dstlen = WideCharToMultiByte (CP_ACP,0,Unicode,-1,lpdst,len,NULL,NULL);
delete []Unicode;
}
/////////////////////////////////////////////////////////////////////////////
// 通过黑名单验证证书,验证通过返回真,否则返回假
BOOL CheckCertWithCrl(const char *pubCert,const int pubCertLen,
const char *crlData,const int crlLen,char * outMsg)
{
BOOL bRet = TRUE;
int i = 0;
BOOL bf = TRUE;
int num;
ASN1_INTEGER *serial = NULL;
STACK_OF(X509_REVOKED) *revoked = NULL;
X509_REVOKED *rc;
X509_CRL * crl = NULL;
BIO * in=NULL;
X509 *x509 = LoadCert(pubCert,pubCertLen,NULL,outMsg);
if (x509 == NULL)
{
strcpy(outMsg,"加载证书失败");
bRet = FALSE;
goto end;
}
if(crlLen==0)
{
if((in=BIO_new_file(crlData, "r"))==NULL)
{
strcpy(outMsg,"Create File Error");
bRet = FALSE;
goto end;
}
}
else
{
if((in=BIO_new_mem_buf((void *)crlData,crlLen))== NULL)
{
strcpy(outMsg,"GlobalLock mem Error");
bRet = FALSE;
goto end;
}
}
crl = d2i_X509_CRL_bio(in,NULL); //DER 格式?
if(crl == NULL)
{
BIO_reset(in);//恢复bio
crl = PEM_read_bio_X509_CRL(in,NULL,NULL,NULL); //PEM格式?
}
if(crl == NULL)
{
strcpy(outMsg,"加载 crl 失败");
bRet = FALSE;
goto end;
}
revoked = crl->crl->revoked;
serial = X509_get_serialNumber(x509);
num = sk_X509_REVOKED_num(revoked);
for(i=0;i<num;i++)
{
rc=sk_X509_REVOKED_pop(revoked); //leak
if(ASN1_INTEGER_cmp(serial,rc->serialNumber)==0)
{
strcpy(outMsg,"证书已作废");
bf = FALSE;
}
X509_REVOKED_free(rc); //leak
}
end:
if(crl)
X509_CRL_free(crl);
if(x509)
X509_free(x509);
if(in)
BIO_free(in);
if(bRet)
{
if(bf)
strcpy(outMsg,"证书有效");
}
return bf;
}
/////////////////////////////////////////////////////////////////////////////
// 通过根证书验证证书ENGINE_load_private_key
BOOL CheckCertWithRoot(const char *pubCert,const int pubCertLen,
const char *rootCert,const int rootCertLen,char * outMsg)
{
OpenSSL_add_all_algorithms();
BOOL bRet = TRUE;
EVP_PKEY * pcert = NULL;
X509 *pRoot = NULL;
int ret =0;
X509 *x509 = LoadCert(pubCert,pubCertLen,NULL,outMsg);
if (x509 == NULL)
{
strcpy(outMsg,"加载证书失败");
bRet = FALSE;
goto end;
}
pRoot = LoadCert(rootCert,rootCertLen,NULL,outMsg);
if (pRoot == NULL)
{
strcpy(outMsg,"加载根证书失败");
bRet = FALSE;
goto end;
}
pcert = X509_get_pubkey(pRoot);
if (pcert == NULL)
{
strcpy(outMsg,"读取根证书公钥信息失败");
bRet = FALSE;
goto end;
}
ret = X509_verify(x509,pcert);
end:
if(pcert)
EVP_PKEY_free (pcert);
if(x509)
X509_free(x509);
if(pRoot)
X509_free(pRoot);
// EVP_cleanup();
if(bRet)
{
if(ret==1)
{
strcpy(outMsg,"证书与根证书匹配");
return TRUE;
}
else
{
strcpy(outMsg,"证书与根证书不匹配");
return FALSE;
}
}
else
return FALSE;
}
/////////////////////////////////////////////////////////////////////////////
// 检查证书有效期,在有效期内返回真,否则返回假
BOOL CheckCertLife(const char *pubCert,const int pubCertLen,char * outMsg)
{
X509 *x509 = LoadCert(pubCert,pubCertLen,NULL,outMsg);
if (x509 == NULL)
{
strcpy(outMsg,"加载证书失败");
return FALSE;
}
time_t ct;
time( &ct );
asn1_string_st *before=X509_get_notBefore(x509),
*after=X509_get_notAfter(x509);
ASN1_UTCTIME *be=ASN1_STRING_dup(before),
*af=ASN1_STRING_dup(after);
BOOL bf;
if(ASN1_UTCTIME_cmp_time_t(be,ct)>=0||ASN1_UTCTIME_cmp_time_t(af,ct)<=0)
{
strcpy(outMsg,"证书超出有效期");
bf = FALSE;
}
else
{
strcpy(outMsg,"证书有效");
bf = TRUE;
}
M_ASN1_UTCTIME_free(be);
M_ASN1_UTCTIME_free(af);
X509_free(x509);
return bf;
}
/*组合P7包*/
BOOL CreateP7b(std::list<std::string> * pCertList,
const char * lpszCrl,
const char * outP7b,
const int outformat,
char * outMsg/*返回结果*/)
{
int i = 0;
BIO *in = NULL,
*out = NULL;
PKCS7 *p7 = NULL;
PKCS7_SIGNED *p7s = NULL;
X509_CRL *crl = NULL;
STACK *certflst = NULL;
STACK_OF(X509_CRL) *crl_stack = NULL;
STACK_OF(X509) *cert_stack = NULL;
in = BIO_new(BIO_s_file());
if(lpszCrl && strlen(lpszCrl) != 0) //有黑名单文件
{
//加载CRL结构
if (BIO_read_filename(in,lpszCrl) <= 0)
{
sprintf(outMsg, "加载CRL%s失败", lpszCrl);
goto end;
}
crl = d2i_X509_CRL_bio(in,NULL); //DER 格式?
if(crl == NULL)
{
BIO_reset(in);//恢复bio
crl = PEM_read_bio_X509_CRL(in,NULL,NULL,NULL); //PEM格式?
}
}
if ((p7 = PKCS7_new()) == NULL) goto end;
if ((p7s = PKCS7_SIGNED_new()) == NULL) goto end;
p7->type = OBJ_nid2obj(NID_pkcs7_signed);
p7->d.sign = p7s;
p7s->contents->type = OBJ_nid2obj(NID_pkcs7_data);
if (!ASN1_INTEGER_set(p7s->version,1))
goto end;
if ((crl_stack=sk_X509_CRL_new_null()) == NULL)
goto end;
p7s->crl = crl_stack;
if (crl != NULL)
{
sk_X509_CRL_push(crl_stack,crl);
crl = NULL; /* now part of p7 for OPENSSL_freeing */
}
if ((cert_stack = sk_X509_new_null()) == NULL) goto end;
p7s->cert = cert_stack;
if(pCertList)
{
std::list<std::string>::const_iterator pos;
for(pos = pCertList->begin(); pos != pCertList->end(); ++pos)
{
std::string strCert = *pos;
X509 * pX509 = LoadCert(strCert.c_str(), 0, 0, outMsg);
if(pX509)
{
sk_X509_push(cert_stack, pX509);
}
}
}
out = BIO_new(BIO_s_file());
if (BIO_write_filename(out, const_cast<char *>(outP7b)) <= 0)
{
goto end;
}
if(outformat == DER)
i=i2d_PKCS7_bio(out,p7);
else if(outformat == PEM)
i=PEM_write_bio_PKCS7(out,p7);
end:
if (in != NULL) BIO_free(in);
if (out != NULL) BIO_free_all(out);
if (p7 != NULL) PKCS7_free(p7); //free cert_stack
if (crl != NULL) X509_CRL_free(crl);
return i;
}
/*分解P7包*/
BOOL ParseP7b(const char * lpszInP7b/*包文件或内存*/,
const UINT iP12Len/* 如果包为文件,则为0,否则为内存长度*/,
const int outformat/*输出格式*/,
const char * lpszCert/*公钥存放*/,
const char * lpszCrl/*CRL存放*/,
const char * lpszOutP7b/*用于转换P7格式的输出文件名*/,
char * outMsg/*返回结果*/)
{
PKCS7 *p7 = NULL;
int i,badops=0;
BIO *in = NULL,
*out = NULL;
int ret = 1;
STACK_OF(X509) *certs=NULL;
STACK_OF(X509_CRL) *crls=NULL;
in=BIO_new(BIO_s_file());
out=BIO_new(BIO_s_file());
if ((in == NULL) || (out == NULL))
{
ret = 0;
goto end;
}
if (BIO_read_filename(in, lpszInP7b) <= 0)
if (in == NULL)
{
sprintf(outMsg, "读取P7B%s失败", lpszInP7b);
ret = 0;
goto end;
}
p7 = d2i_PKCS7_bio(in,NULL);
if(!p7)
{
BIO_reset(in);//恢复bio
p7=PEM_read_bio_PKCS7(in,NULL,NULL,NULL);
}
if (p7 == NULL)
{
sprintf(outMsg, "加载P7B%s失败", lpszInP7b);
ret = 0;
goto end;
}
i=OBJ_obj2nid(p7->type);
switch (i)
{
case NID_pkcs7_signed:
certs=p7->d.sign->cert;
crls=p7->d.sign->crl;
break;
case NID_pkcs7_signedAndEnveloped:
certs=p7->d.signed_and_enveloped->cert;
crls=p7->d.signed_and_enveloped->crl;
break;
default:
break;
}
if (certs != NULL && lpszCert && strlen(lpszCert) !=0 )
{
X509 *x;
for (i=0; i<sk_X509_num(certs); i++)
{
BIO * bioCert = NULL;
char buf[256] = {0};
sprintf(buf, "%s-%d.Cer", lpszCert, i);
if((bioCert = BIO_new_file(buf, "w")) == NULL)
{
goto end;
ret = 0;
}
x = sk_X509_value(certs,i); //保存证书公钥
if (outformat == DER)
{
i2d_X
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -