openssl主要流程程序代码(三)

2014-11-24 00:33:28 · 作者: · 浏览: 48
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