📄 ca.cpp
字号:
X509V3_EXT_cleanup();//cleanup the extension code if any custom extensions have been added
OBJ_cleanup();
if (!X509_REQ_sign(x,pk,EVP_sha1()))//用自己的公钥签名私钥
goto err;
*req=x;
*pkeyp=pk;
return(1);
err:
return(0);
}
BOOL MakeReq(const stuSUBJECT * reqInfo,/*请求信息IN*/
const int bits/*位数IN*/,
const char * priPwd/*私钥密码,IN*/,
char * reqMem/*证书请求文件OUT*/,
UINT * reqLen/*证书请求文件长度OUT*/,
char * priMem/*私钥文件OUT*/,
UINT * priLen/*私钥文件文件长度OUT*/,
char * outMsg/*操作结果OUT*/,
const int iType/*类型pem-der*/)
{
X509_REQ * req=NULL;
EVP_PKEY * pkey=NULL;
BIO * breq = NULL,
* bkey = NULL;
int i = 0,
j = 0;
breq = BIO_new(BIO_s_mem());
bkey = BIO_new(BIO_s_mem());
BIO_set_close(breq, BIO_CLOSE); /* BIO_free() free BUF_MEM */
BIO_set_close(bkey, BIO_CLOSE); /* BIO_free() free BUF_MEM */
/* if(((breq = BIO_new_file(reqFile, "w"))== NULL)||((bkey = BIO_new_file(priFile, "w")) == NULL))
{
strcpy(outMsg,"Create File Error");
return FALSE;
}
*/
if(!mkReq(reqInfo,&req,&pkey,bits,outMsg))
{
strcpy(outMsg,"Make CertReq Error");
return FALSE;
}
if(iType == PEM)
{
i = PEM_write_bio_X509_REQ(breq,req); //写入公钥
if(NULL == priPwd || strlen(priPwd) == 0)
j = PEM_write_bio_PrivateKey(bkey,pkey,NULL,NULL,0,NULL, NULL); //私钥不加密
else
j = PEM_write_bio_PrivateKey(bkey,pkey,EVP_des_ede3_cbc(),NULL,0,NULL, (void *)priPwd); //私钥加密
}
else if(iType == DER)
{
i = i2d_X509_REQ_bio(breq,req); //写入公钥
if(NULL == priPwd || strlen(priPwd) == 0) //写入私钥
j = i2d_PrivateKey_bio(bkey,pkey);//私钥未加密
else
{
//添加加密链
unsigned char key[EVP_MAX_KEY_LENGTH] = "";//算法最长的KEY长度
unsigned char iv[EVP_MAX_IV_LENGTH] = "";//算法最长的IV长度
BIO * bEnc = NULL;
bEnc = BIO_new(BIO_f_cipher());
const EVP_CIPHER * cipher = NULL;
cipher = EVP_des_ede3_cbc(); // 3DES-EDE-CBC
if(EVP_BytesToKey(cipher,EVP_sha1(),NULL,(unsigned char *)priPwd,
strlen(priPwd),1,key,iv))
{
BIO_set_cipher(bEnc,cipher,key,iv, 1);//1-加密、0-解密
bkey = BIO_push(bEnc, bkey);
j = i2d_PrivateKey_bio(bkey,pkey);//私钥加密
BIO_flush(bkey);
bkey = BIO_pop(bkey);
BIO_free(bEnc);
}
else
strcpy(outMsg,"初始化key or iv 失败,");
}
}
//转换BIO->MEM
if(i&&j)
{
i = Bio2Mem(breq, reqMem, reqLen);
j = Bio2Mem(bkey, priMem, priLen);
}
BIO_free(breq);
BIO_free_all(bkey);
X509_REQ_free(req);
EVP_PKEY_free(pkey);
if(!i||!j)
{
strcat(outMsg,"Save Cert or Key File Error");
return FALSE;
}
return TRUE;
}
////////////////////////// end //////////////////////////////////////
////////////////////////////////////////////////////////////////////
/////////////////////////// begin ////////////////////////////////////////
int copy_extensions(X509 *x, X509_REQ *req, const int copy_type)//在证书中加入req自带扩展信息
{
STACK_OF(X509_EXTENSION) * exts = NULL;
X509_EXTENSION * ext = NULL,
* tmpext = NULL;
ASN1_OBJECT * obj = NULL;
int i = 0,
idx = 0,
ret = 0;
if (!x || !req || (copy_type == EXT_COPY_NONE))
return 1;
exts = X509_REQ_get_extensions(req);
for(i = 0; i < sk_X509_EXTENSION_num(exts); i++)
{
ext = sk_X509_EXTENSION_value(exts, i);
obj = X509_EXTENSION_get_object(ext);
idx = X509_get_ext_by_OBJ(x, obj, -1);
/* Does extension exist? */
if (idx != -1)
{
/* If normal copy don't override existing extension */
if (copy_type == EXT_COPY_ADD)
continue;
/* Delete all extensions of same type */
do
{
tmpext = X509_get_ext(x, idx);
X509_delete_ext(x, idx);
X509_EXTENSION_free(tmpext);
idx = X509_get_ext_by_OBJ(x, obj, -1);
} while (idx != -1);
}
if (!X509_add_ext(x, ext, -1))
goto end;
}
ret = 1;
end:
sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
return ret;
}
int do_body(X509 **xret, EVP_PKEY *pkey, X509 *px509,
const EVP_MD *dgst,const long serial,
const char *startdate, const char *enddate,
const int days,X509_REQ * req,const char * kusage,
const char * ekusage,const stuCERTEXT * pCertExt,char * outMsg)
{
X509_NAME * name = NULL, * CAname = NULL;
X509 * ret = NULL;
X509_CINF * ci = NULL;
EVP_PKEY * pktmp = NULL;
int ok= -1,
i=0;
// STACK_OF (X509_EXTENSION) * req_exts;//如何释放??
name = X509_REQ_get_subject_name(req);
if ((ret = X509_new()) == NULL)
{
ok=0;
goto err;
}
ci = ret->cert_info;
/* Make it an X509 v3 certificate. 版本1扩展*/
if (!X509_set_version(ret,2L)) //版本
{
ok=0;
goto err;
}
ASN1_INTEGER_set(X509_get_serialNumber(ret),serial);//序列号
if (!X509_set_issuer_name(ret,X509_get_subject_name(px509)))//发行者
{
ok=0;
goto err;
}
//X509_gmtime_adj(X509_get_notBefore(x),0);//起始时间
//X509_gmtime_adj(X509_get_notAfter(x),(long)60*60*24*days);//结束时间
if (strcmp(startdate,"today") == 0)
X509_gmtime_adj(X509_get_notBefore(ret),0);//开始日期
else ASN1_UTCTIME_set_string(X509_get_notBefore(ret),(char *)startdate);
if (enddate == NULL)
X509_gmtime_adj(X509_get_notAfter(ret),(long)60*60*24*days);//结束日期
else ASN1_UTCTIME_set_string(X509_get_notAfter(ret),(char *)enddate);
// X509_gmtime_adj(X509_get_notBefore(ret),0);//起始时间
// X509_gmtime_adj(X509_get_notAfter(ret),(long)60*60*24*days);//结束时间
if (!X509_set_subject_name(ret,name)) //主体 ---所有者
{
ok=0;
goto err;
}
pktmp = X509_REQ_get_pubkey(req);
i = X509_set_pubkey(ret,pktmp);//公钥
EVP_PKEY_free(pktmp);
if (!i)
{
ok = 0;
goto err;
}
//加入req自带扩展信息,生成REQ文件时候加入的
if (!copy_extensions(ret, req, EXT_COPY_ALL))
{
strcpy("加入自带扩展信息失败",outMsg);
goto err;
}
//CRL签名、仅仅加密、仅仅解密
if(kusage && strlen(kusage))
Add_ExtCert(ret,ret, NID_key_usage, kusage);
AddExtCert(ret,px509,pCertExt);
if(ekusage && strlen(ekusage))
Add_ExtCert(ret,ret,NID_ext_key_usage,ekusage);
/*
Application keyUsage Values
SSL Client digitalSignature
SSL Server keyEncipherment
S/MIME Signing digitalSignature
S/MIME Encryption keyEncipherment
Certificate Signing keyCertSign
Object Signing digitalSignature */
//加入自定义信息end
X509V3_EXT_cleanup();//cleanup the extension code if any custom extensions have been added
OBJ_cleanup();
if (!X509_sign(ret,pkey,dgst))//加入签名,签名算法
{
ok=0;
goto err;
}
ok=1;
err:
if (CAname != NULL)
X509_NAME_free(CAname);
if (ok <= 0)
{
if (ret != NULL) X509_free(ret);
ret=NULL;
}
else
* xret = ret;
return(ok);
}
int certify(X509 **xret, X509_REQ *req, EVP_PKEY *pkey,
X509 *px509,const EVP_MD *dgst,
const long serial, const char *startdate, const char *enddate,
const int days,const char * KUSAGE,
const char * EKUSAGE,const stuCERTEXT * pCertExt,char * outMsg)
{//返回公钥证书,请求文件,根私钥,根公钥,
EVP_PKEY *pktmp=NULL;
int ok= -1,i=0;
if ((pktmp=X509_REQ_get_pubkey(req)) == NULL)//得到公钥
{
sprintf(outMsg,"error unpacking public key\n");
ok=0;
goto err;
}
i=X509_REQ_verify(req,pktmp);//证书请求里面有私要签名,这里验证一下,看此公钥主人是否持有私钥
EVP_PKEY_free(pktmp);
if (i < 0)
{
ok=0;
sprintf(outMsg,"Signature verification problems....\n");
goto err;
}
if (i == 0)
{
ok=0;
sprintf(outMsg,"Signature did not match the certificate request\n");
goto err;
}
ok=do_body(xret,pkey,px509,dgst,serial,startdate, enddate,
days,req,KUSAGE,EKUSAGE,pCertExt,outMsg);
err:
return(ok);
}
BOOL MakeCert(const stuCertPair & RootPair/*根证书对*/,
const long serial/*序列号*/,
const char *enddate/*作废日期*/,
const int days/*有效期*/,
const char * reqMem/*请求文件或内存*/,
const int reqLen/*请求的长度,0-标示文件*/,
const char * KUSAGE/*密钥用法*/,
const char * EKUSAGE/*增强密钥用法*/,
const stuCERTEXT * pCertExt,/*证书扩展*/
char * outMem/*结果公钥文件*/,
UINT * MemLen/*结果长度*/,
char * outMsg/*操作结果*/,
const int type/*结果类型DER,PEM*/)//通过证书请求,得到证书
{
int ret=1;
char * md=NULL;
EVP_PKEY *pkey=NULL;
X509 * px509=NULL;
X509_REQ *req=NULL;
X509 * x=NULL;
BIO * bcert=NULL,* reqbio=NULL;
int j;
const EVP_MD *dgst=NULL;
OpenSSL_add_all_algorithms();//加入签名算法
X509 * x509 = NULL;
if(reqLen == 0)//输入为磁盘文件
{
if((reqbio=BIO_new_file(reqMem, "r")) == NULL)
{
strcpy(outMsg,"找不到证书请求文件");
ret=0;
goto err;
}
}
else//输入为内存中文件
{
if((reqbio = BIO_new_mem_buf((void *)reqMem, reqLen)) == NULL)//只读类型
{
sprintf(outMsg,"Make Mem Bio Error");
ret=0;
goto err;
}
}
if ((req=PEM_read_bio_X509_REQ(reqbio,NULL,NULL,NULL)) == NULL)//PEM_read_X509_REQ
{
BIO_reset(reqbio);
if ((req=d2i_X509_REQ_bio(reqbio,NULL)) == NULL)
{
sprintf(outMsg,"Error get certificate request");
ret=0;
goto err;
}
}
if(!CertPair2XE(RootPair,px509,pkey,outMsg))
{
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;
}
j=certify(&x,req,pkey,px509,dgst,//公钥证书out,请求文件,根私钥,根公钥,
serial,"today",enddate,days,KUSAGE,EKUSAGE,pCertExt,outMsg);
if (j <= 0)
{
ret=0;
goto err;
}
bcert = BIO_new(BIO_s_mem());
BIO_set_close(bcert, BIO_CLOSE); /* BIO_free() free BUF_MEM */
if (type==DER)
{
ret = i2d_X509_bio(bcert,x);
}
else if(type==PEM)
{
ret = PEM_write_bio_X509(bcert,x);
}
//转换BIO->内存
if(ret)
{
ret = Bio2Mem(bcert, outMem, MemLen);
}
err:
if (reqbio != NULL) BIO_free(reqbio);
BIO_free_all(bcert);
EVP_PKEY_free(pkey);
X509_free(px509);
X509_free(x);
if (req != NULL) X509_REQ_free(req);
// EVP_cleanup();//frees all three stacks and sets their pointers to NULL ---- EVP_CIPHER
// CRYPTO_cleanup_all_ex_data();
return ret;
}
///////////////////////// end ////////////////////////////////////////
BOOL DirectCert(const stuCertPair & RootPair/*根证书对*/,
const int bits/*[IN]*/,
const long serial/*[IN]序列号*/,
const char * enddate/*[IN]作废日期*/,
const int days/*[IN]有效期*/,
const char * priPwd /*私钥加密密码,IN*/,
const stuSUBJECT * sSUBJECT/*[IN]用户信息*/,
const char * friendlyName/*好记的名称*/,
const char * keyUsage/*密钥用法*/,
const char * ekeyUsage/*扩展密钥用法*/,
const stuCERTEXT * pCertExt,/*证书扩展结构*/
char * pCert/*[OUT]输出证书公钥*/,
UINT * certl/*[OUT]长度*/,
char * key/*[OUT]输出证书私钥*/,
UINT * keyl/*[OUT]长度*/,
char * p12/*[OUT]输出证书私钥*/,
UINT * p12l/*[OUT]长度*/,
char * outMsg/*[OUT]返回错误信息*/,
const int iType/*结果类型DER,PEM*/)
{
X509_REQ * req=NULL;
EVP_PKEY * pkey=NULL, * prkey=NULL;//证书私钥,//根私钥
X509 * px509=NULL,* x=NULL;//根公钥,证书公钥
int ret=1;
char * md=NULL;
int i=0,j=0,ok=0;
const EVP_MD *dgst=NULL;
OpenSSL_add_all_algorithms();//加入签名算法
if(!CertPair2XE(RootPair,px509,prkey,outMsg))
{
ret = 0;
goto err;
}
if(!mkReq(sSUBJECT,&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,px509,dgst,//公钥证书out,请求,根私钥,根公钥,
serial,"today",enddate,days,keyUsage,ekeyUsage,pCertExt,outMsg);
if (ok > 0)
{
X5092Mem(x,iType,pCert,certl);
Key2Mem(pkey,iType,priPwd,key,keyl);
CreateMemPfx(x, pkey, priPwd, friendlyName, p12, p12l);
}
err:
EVP_PKEY_free(pkey);
EVP_PKEY_free(prkey);
X509_free(px509);
X509_free(x);
if (req != NULL) X509_REQ_free(req);
// EVP_cleanup();//frees all three stacks and sets their pointers to NULL ---- EVP_CIPHER
// CRYPTO_cleanup_all_ex_data();
return ret;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -