📄 ca.cpp
字号:
{
ret = 0;
goto err;
}
if (!X509_check_private_key(x509,prkey))
{
sprintf(outMsg,"CA certificate and CA private key do not match\n");
ret = 0;
goto err;
}
if(!mkReq(&(sCERT->SUBJECT),&req,&pkey, bits,outMsg))
{
sprintf(outMsg,"Make CertReq error");
ret = 0;
goto err;
}
md="sha1";//////////!!!!!!!!!!!!!!!!!////////////////////////////
if ((dgst=EVP_get_digestbyname(md)) == NULL)//return an EVP_MD structure when passed a digest name
{
sprintf(outMsg,"%s is an unsupported message digest type\n",md);
ret = 0;
goto err;
}
ok=certify(&x,req,prkey,x509,dgst,//公钥证书out,请求,根私钥,根公钥,
serial,"today",enddate,days,&(sCERT->KUSAGE),&(sCERT->EKUSAGE),outMsg);
if (ok <= 0)
{
ret=0;
goto err;
}
/* if (type==DER)
{
i=i2d_X509_bio(memcert,x);
j=i2d_PrivateKey_bio(memkey,pkey);//生成的结果错误!?????????????
}
else if(type==PEM)
*/ {
i=PEM_write_bio_X509(memcert,x);
j=PEM_write_bio_PrivateKey(memkey,pkey,NULL,NULL,0,NULL, NULL);
}
if(!i||!j)
{
strcpy(outMsg,"Get Mem Cert or Key File Error");
ret=0;
goto err;
}
BIO_get_mem_ptr(memcert, &bptrcert);
*certl=bptrcert->length;
memcpy(cert,bptrcert->data,*certl);
BIO_get_mem_ptr(memkey, &bptrkey);
*keyl=bptrkey->length;
memcpy(key,bptrkey->data,*keyl);
err:
BIO_free_all(memcert);
BIO_free_all(memkey);
EVP_PKEY_free(pkey);
EVP_PKEY_free(prkey);
X509_free(x509);
X509_free(x);
if (req != NULL) X509_REQ_free(req);
EVP_cleanup();//frees all three stacks and sets their pointers to NULL ---- EVP_CIPHER
return ret;
}
//////////////////////////////////////////////////////////////////////
///////////////////////// begin //////////////////////////////////////
/*添加链表节点*/
void AddRevoke(stuREVOKE *& Head,int index,time_t time)
{
stuREVOKE * End=new stuREVOKE(index,time);//钥增加的节点
if(Head==NULL)
{
Head=End;
}
else
{
stuREVOKE * p=Head;
while(p->Link!=NULL)
p=p->Link;
p->Link=End;
}
return;
}
int Add_ExtCrl(X509_CRL *crl/*正被添加的证书*/,X509 * root/*根证书(从中得到信息)*/,
int nid, char *value)
{
X509V3_CTX ctx;
X509_EXTENSION *ex;
/* This sets the 'context' of the extensions. */
/* No configuration database */
// X509V3_set_ctx_nodb(&ctx);
X509V3_set_ctx(&ctx, root, NULL, NULL, crl, 0);
// issuerAltName authorityKeyIdentifier
ex = X509V3_EXT_conf_nid(NULL, &ctx, nid, value);
if (!ex)
return 0;
X509_CRL_add_ext(crl,ex,-1);
X509_EXTENSION_free(ex);
return 1;
}
BOOL MakeCrl(char *certfile/*根证书公钥*/,int certlen,/*为0则certfile为磁盘文件,否则为内存区域*/
char *keyfile/*根证书私钥*/,int keylen,
stuREVOKE * Head/*作废链表*/,PNewCrlMem NewCrlMem/*回调函数*/,char *& outCrl,int * crll,char * outfile/*crl文件*/,
char * outMsg/*操作结果*/)
{
X509_CRL_INFO *ci = NULL;
X509_CRL *crl = NULL;
int ret=1,i=0;
char *key=NULL;
char *md=NULL;
EVP_PKEY *pkey=NULL;
X509 *x509=NULL;
BIO *in=NULL,*out=NULL;
const EVP_MD *dgst=NULL;
X509_REVOKED *r=NULL;
long crldays=30;
long crlhours=0;
stuREVOKE * temp =NULL;
BIO * memcrl=NULL;
BUF_MEM *bptrcrl=NULL;
OpenSSL_add_all_algorithms();
pkey=LoadKey(keyfile,keylen,NULL,outMsg);
if (pkey == NULL)
{
ret = 0;
goto err;
}
x509=LoadCert(certfile,certlen,outMsg);
if (x509 == NULL)
{
ret = 0;
goto err;
}
if (!X509_check_private_key(x509,pkey))
{
sprintf(outMsg,"CA certificate and CA private key do not match\n");
ret = 0;
goto err;
}
md="md5";//////////!!!!!!!!!!!!!!!!!////////////////////////////
if ((dgst=EVP_get_digestbyname(md)) == NULL)//return an EVP_MD structure when passed a digest name
{
sprintf(outMsg,"%s is an unsupported message digest type\n",md);
ret = 0;
goto err;
}
if ((crl=X509_CRL_new()) == NULL)
{
ret = 0;
goto err;
}
ci=crl->crl;
X509_NAME_free(ci->issuer);
ci->issuer=X509_NAME_dup(x509->cert_info->subject);
if (ci->issuer == NULL)
{
ret = 0;
goto err;
}
X509_gmtime_adj(ci->lastUpdate,0);
if (ci->nextUpdate == NULL)
ci->nextUpdate=ASN1_UTCTIME_new();
X509_gmtime_adj(ci->nextUpdate,(crldays*24+crlhours)*60*60);
if(!ci->revoked)
ci->revoked = sk_X509_REVOKED_new_null();
while(Head!=NULL)//遍历链表
{
temp=Head;
X509_REVOKED *r = NULL;
BIGNUM *serial_bn = NULL;
r = X509_REVOKED_new();
ASN1_TIME_set(r->revocationDate,Head->time);//时间
char index[100];
BN_hex2bn(&serial_bn,itoa(Head->Index,index,10));//序号
BN_to_ASN1_INTEGER(serial_bn,r->serialNumber);
sk_X509_REVOKED_push(ci->revoked,r);
Head=Head->Link;
delete temp;
}
// sk_X509_REVOKED_sort(ci->revoked);
for (i=0; i<sk_X509_REVOKED_num(ci->revoked); i++)
{
r=sk_X509_REVOKED_value(ci->revoked,i);
r->sequence=i;
}
if (ci->version == NULL)
if ((ci->version=ASN1_INTEGER_new()) == NULL)
{
ret = 0;
goto err;
}
ASN1_INTEGER_set(ci->version,1);
// issuerAltName authorityKeyIdentifier
// Add_ExtCrl(crl,x509,NID_subject_alt_name,"DNS:hpxs,email:hpxs@hotmail.com,RID:1.2.3.4,URI:https://hpxs,IP:192.168.0.22");
Add_ExtCrl(crl,x509,NID_issuer_alt_name, "DNS:hpxs,email:hpxs@hotmail.com,RID:1.2.3.4,URI:https://hpxs,IP:192.168.0.22");
Add_ExtCrl(crl,x509,NID_authority_key_identifier, "keyid,issuer:always");
if (!X509_CRL_sign(crl,pkey,dgst))
{
ret = 0;
goto err;
}
if(NewCrlMem)//输出内存
{
memcrl= BIO_new(BIO_s_mem());
BIO_set_close(memcrl, BIO_CLOSE); /* BIO_free() free BUF_MEM */
PEM_write_bio_X509_CRL(memcrl,crl);
BIO_get_mem_ptr(memcrl, &bptrcrl);
*crll=bptrcrl->length;
outCrl=NewCrlMem(*crll);
memcpy(outCrl,bptrcrl->data,*crll);
}
if(outfile)//输出文件
{
out=BIO_new_file(outfile, "w");
if(out==NULL)
{
sprintf(outMsg,"%s is error",outfile);
ret = 0;
goto err;
}
PEM_write_bio_X509_CRL(out,crl);
}
X509V3_EXT_cleanup();//cleanup the extension code if any custom extensions have been added
err:
if(out)
BIO_free_all(out);
if(memcrl)
BIO_free_all(memcrl);
BIO_free(in);
EVP_PKEY_free(pkey);
X509_CRL_free(crl);
X509_free(x509);
EVP_cleanup();//frees all three stacks and sets their pointers to NULL ---- EVP_CIPHER
if(ret==1)
strcpy(outMsg,"CRL制作成功");
return ret;
}
BOOL CertFormatConver(char * buf/*文件内容或文件名称*/,int len/*内存长度为0则buf为文件名*/,
char * pwd/*p12文件密码*/,char * pem/*输出文件*/,
int outformat,char * out/*操作结果*/)
{
EVP_PKEY *key=NULL;
X509 *cert=NULL;
BIO *biout=NULL;
int i=0;
//输出文件
if ((biout=BIO_new_file(pem, "w")) == NULL)
{
return false;
}
cert = LoadCert(buf,len,out);//首先尝试公钥,bio被改写
if(cert)//输入文件为公钥文件
{
if (outformat == DER)
i=i2d_X509_bio(biout,cert);
else if (outformat == PEM)
{
// if (trustout) i=PEM_write_bio_X509_AUX(biout,x);
i=PEM_write_bio_X509(biout,cert);
}
if(!i)//失败
strcpy(out,"保存公钥失败");
else
strcpy(out,"公钥证书格式转换成功");
}
else//输入文件为私钥文件
{
key=LoadKey(buf,len,pwd,out);
if(!key)
{
strcpy(out,"不能识别的文件格式");
return false;
}
if(outformat==PEM)
{
PEM_write_bio_PrivateKey(biout, key, NULL, NULL, 0, 0, NULL);
}
if(outformat==DER)
{
i2d_PrivateKey_bio(biout,key);//得到解密后的私钥
}
strcpy(out,"私钥证书格式转换成功");
}
if (biout != NULL) BIO_free(biout);
X509_free(cert);
EVP_PKEY_free(key);
return true;
}
//分解p12包
BOOL ParseDB(char * strP12/*包文件*/,char * strPwd/*私钥密码*/,char * strCert/*公钥存放*/,
char * strkey/*私钥存放*/,int outformat/*输出格式*/,char * out/*返回结果*/)
{
EVP_PKEY *key=NULL;
X509 *cert=NULL;
STACK_OF(X509) *ca = NULL;
BIO * bio=NULL,*bioCert=NULL,*bioKey=NULL;
PKCS12 *p12=NULL;
int i=0,j=0;
if((bio=BIO_new_file(strP12, "r")) == NULL)
{
strcpy(out,"打开文件错误");
return false;
}
SSLeay_add_all_algorithms();
p12 = d2i_PKCS12_bio(bio, NULL);
if (!PKCS12_parse(p12, strPwd, &key, &cert/*PEM*/, &ca))
{
strcpy(out,"解包失败");
return false;
}
PKCS12_free(p12);
//输出文件
if ((bioCert=BIO_new_file(strCert, "w")) == NULL)
{
return false;
}
if ((bioKey=BIO_new_file(strkey, "w")) == NULL)
{
return false;
}
if(outformat == DER)
{
i=i2d_X509_bio(bioCert,cert);
j=i2d_PrivateKey_bio(bioKey,key);
}
else if (outformat == PEM)
{
i=PEM_write_bio_X509(bioCert,cert);
j=PEM_write_bio_PrivateKey(bioKey, key, NULL, NULL, 0, 0, NULL);
}
if (bio != NULL) BIO_free(bio);
if (bioCert != NULL) BIO_free(bioCert);
if (bioKey != NULL) BIO_free(bioKey);
X509_free(cert);
EVP_PKEY_free(key);
EVP_cleanup();//frees all three stacks and sets their pointers to NULL ---- EVP_CIPHER
if(i!=0&&j!=0)
{
strcpy(out,"分解P12成功");
return true;
}
return false;
}
//组合p12包
BOOL CreateDB(char * strP12/*OUT包文件*/,char * strPwd/*IN密码*/,char * strCert/*IN公钥*/,
char * strkey/*IN私钥*/,char * out/*返回结果*/)
{
FILE *fp=NULL;
EVP_PKEY *key=NULL;
X509 *cert=NULL;
PKCS12 *p12;
cert =LoadCert(strCert,0,out);
if(!cert)
{
strcpy(out,"读取公钥文件失败");
return false;
}
key=LoadKey(strkey,0,NULL,out);//解密后私钥
if(!key)
{
strcpy(out,"读取私钥文件失败");
return false;
}
SSLeay_add_all_algorithms();
p12 = PKCS12_create(strPwd,"(hpxs)", key, cert, NULL, 0,0,0,0,0);
if(!p12)
{
strcpy(out,"创建p12结构失败");
return false;
}
if (!(fp = fopen(strP12, "wb")))
{
strcpy(out,"保存p12文件失败");
}
i2d_PKCS12_fp(fp, p12);
PKCS12_free(p12);
fclose(fp);
strcpy(out,"合并P12成功");
X509_free(cert);
EVP_PKEY_free(key);
EVP_cleanup();//frees all three stacks and sets their pointers to NULL ---- EVP_CIPHER
return true;
}
//修改p12包密码
BOOL ChangePB(char * strP12/*in包文件*/,char * strPwd/*IN原密码*/,char * strPwd2/*IN新密码*/,
char * strOutP12/*in包文件*/,char * out/*返回结果*/)
{
FILE *fp=NULL;
EVP_PKEY *key=NULL;
X509 *cert=NULL;
STACK_OF(X509) *ca = NULL;
PKCS12 *p12=NULL;
int len=0,wlen=0;
SSLeay_add_all_algorithms();
if (!(fp = fopen(strP12, "rb")))
{
strcpy(out,"打开文件错误");
return false;
}
p12 = d2i_PKCS12_fp(fp, NULL);
fclose (fp);
if (!p12)
{
strcpy(out,"读取包文件错误");
return false;
}
if (!PKCS12_parse(p12, strPwd, &key, &cert, &ca))
{
strcpy(out,"解包失败");
return false;
}
PKCS12_free(p12);
fclose(fp);
p12=NULL;
///////////////////////////////////////
p12 = PKCS12_create(strPwd2,"(null)", key, cert, NULL, 0,0,0,0,0);
if(!p12)
{
strcpy(out,"创建p12结构失败");
return false;
}
if (!(fp = fopen(strOutP12, "wb")))
{
strcpy(out,"保存p12文件失败");
}
i2d_PKCS12_fp(fp, p12);
PKCS12_free(p12);
fclose(fp);
strcpy(out,"转换P12密码成功");
X509_free(cert);
EVP_PKEY_free(key);
return true;
}
BOOL CertPairCheck(char * cert,char * key,char * out)//检验公钥、私钥是否配对
{
EVP_PKEY *pkey=NULL;
X509 *x509=NULL;
x509=LoadCert(cert,0,out);
if(x509==NULL)
{
strcpy(out,"不能打开公钥文件");
return FALSE;
}
pkey=LoadKey(key,0,NULL,out);
if(pkey==NULL)
{
strcpy(out,"不能打开私钥文件");
X509_free(x509);
return FALSE;
}
if(X509_check_private_key(x509,pkey))//匹配
{
X509_free(x509);
EVP_PKEY_free(pkey);
return TRUE;
}
else
{
strcpy(out,"公私钥对不匹配");
X509_free(x509);
EVP_PKEY_free(pkey);
return FALSE;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -