openssl主要流程程序代码(三)
cies,"OK");
//颁发机构信息访问
Add_ExtCert(ret,ret,NID_info_access,"OCSP;URI:https://hpxs");//或者caIssuers;URI:http://my.ca/ca.html
//CRL分发点
Add_ExtCert(ret,x509, NID_crl_distribution_points, "URI:https://hpxs/hpxs.crl");
/* Some Netscape specific extensions */
// Add_ExtCert(ret,ret, NID_crl_number, "sslCA");
// Add_ExtCert(ret,x509, NID_netscape_comment, "See http://cert.umd.edu/root for details.");
/* In each case the 'value' of the extension is placed directly in the
extension. Currently supported extensions in this category are: nsBaseUrl,
nsRevocationUrl, nsCaRevocationUrl, nsRenewalUrl, nsCaPolicyUrl,
nsSslServerName and nsComment */
// Add_ExtCert(ret,x509, NID_netscape_cert_type, "client, server, email,objsign, reserved, sslCA,emailCA, objCA");
/*nsCertType (netscape certificate type) takes the flags: client, server, email,
objsign, reserved, sslCA, emailCA, objCA.*/
/* Maybe even add our own extension based on existing */
//加入自定义信息begin
int nid;
nid = OBJ_create("1.2.3.4.9", "Hpxs", "I love OpenSSL!");
X509V3_EXT_add_alias(nid, NID_netscape_comment);
Add_ExtCert(ret,ret, nid, "I love OpenSSL");
//加入自定义信息end
X509V3_EXT_cleanup();//cleanup the extension code if any custom extensions have been added
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 *x509,const EVP_MD *dgst,
int serial, char *startdate, char *enddate, int days,stuKEYUSAGE * KUSAGE,
stuEKEYUSAGE * EKUSAGE,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,x509,dgst,serial,startdate, enddate,
days,req,KUSAGE,EKUSAGE,outMsg);
err:
return(ok);
}
BOOL MakeCert(char *certfile/*根证书公钥*/,int certlen,/*为0则certfile为磁盘文件,否则为内存区域*/
char *keyfile/*根证书私钥*/,int keylen,int serial/*序列号*/,char *enddate/*作废日期*/,
int days/*有效期*/, char *reqfile/*请求文件*/,stuKEYUSAGE * KUSAGE/*密钥用法*/,
stuEKEYUSAGE * EKUSAGE/*增强密钥用法*/,char *outfile/*结果文件*/,
char * outMsg/*操作结果*/,int type/*结果类型DER,PEM*/)//通过证书请求,得到证书
{
int ret=1;
char * md=NULL;
EVP_PKEY *pkey=NULL;
X509 * x509=NULL;
X509_REQ *req=NULL;
X509 * x=NULL;
BIO * bcert=NULL,* reqbio=NULL;
int j;
const EVP_MD *dgst=NULL;
OpenSSL_add_all_digests();//加入签名算法
if((reqbio=BIO_new_file(reqfile, "r")) == NULL)
{
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;
}
}
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="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,x509,dgst,//公钥证书out,请求文件,根私钥,根公钥,
serial,"today",enddate,days,KUSAGE,EKUSAGE,outMsg);
if (j <= 0)
{
ret=0;
goto err;
}
if(((bcert=BIO_new_file(outfile, "w"))== NULL))
{
strcpy(outMsg,"Create File Error");
goto err;
}
if (type==DER)
{
i2d_X509_bio(bcert,x);
}
else if(type==PEM)
{
PEM_write_bio_X509(bcert,x);
}
err:
if (reqbio != NULL) BIO_free(reqbio);
BIO_free_all(bcert);
EVP_PKEY_free(pkey);
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;
}
///////////////////////// end ////////////////////////////////////////
BOOL DirectCert(char *certfile/*根证书公钥*/,int certlen,/*为0则certfile为磁盘文件,否则为内存区域*/
char *keyfile/*根证书私钥*/,int keylen,int serial/*序列号*/,char *enddate/*作废日期*/,
int days/*有效期*/,stuCERT * sCERT/*用户信息与密钥用法*/,int bits,char * cert/*输出证书公钥*/,int * certl/*长度*/,
char * key/*输出证书私钥*/,int * keyl/*长度*/,char * outMsg/*,int type结果类型DER,PEM*/)//直接生成公私钥
{
X509_REQ * req=NULL;
EVP_PKEY * pkey=NULL, * prkey=NULL;//证书私钥,//根私钥
X509 * x509=NULL,* x=NULL;//根公钥,证书公钥
BIO * memcert=NULL, * memkey=NULL;//输出证书公私钥
BUF_MEM *bptrcert=NULL,*bptrkey=NULL;
int ret=1;
char * md=NULL;
int i=0,j=0,ok=0;
const EVP_MD *dgst=NULL;
OpenSSL_add_all_digests();//加入签名算法
memcert= BIO_new(BIO_s_mem());
memkey= BIO_new(BIO_s_mem());
BIO_set_close(memcert, BIO_CLOSE); /* BIO_free() free BUF_MEM */
BIO_set_close(memkey, BIO_CLOSE); /* BIO_free() free BUF_MEM */
prkey=LoadKey(keyfile,keylen,NULL,outMsg);//RAND_bytes
if (prkey == NULL)
{
ret = 0;
goto err;
}
x509=LoadCert(certfile,certlen,outMsg);
if (x509 == NULL)
{
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(cha