openssl主要流程程序代码(六)
*位数*/,char * reqFile/*证书请求文件*/,
char * priFile/*私钥文件*/,char * outMsg/*操作结果*/,int type)
{
X509_REQ *req=NULL;
EVP_PKEY *pkey=NULL;
BIO * breq=NULL,* bkey=NULL;
int i=0,j=0;
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(type==PEM)
{
i=PEM_write_bio_X509_REQ(breq,req);
j=PEM_write_bio_PrivateKey(bkey,pkey,NULL,NULL,0,NULL, NULL);
}
else if(type==DER)
{
i=i2d_X509_REQ_bio(breq,req);
j=i2d_PrivateKey_bio(bkey,pkey);
}
BIO_free(breq);
BIO_free(bkey);
X509_REQ_free(req);
EVP_PKEY_free(pkey);
if(!i||!j)
{
strcpy(outMsg,"Save Cert or Key File Error");
return false;
}
return true;
}
////////////////////////// end //////////////////////////////////////
////////////////////////////////////////////////////////////////////
/////////////////////////// begin ////////////////////////////////////////
int copy_extensions(X509 *x, X509_REQ *req, int copy_type)//在证书中加入req自带扩展信息
{
STACK_OF(X509_EXTENSION) *exts = NULL;
X509_EXTENSION *ext, *tmpext;
ASN1_OBJECT *obj;
int i, idx, 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 *x509, const EVP_MD *dgst,int serial,
char *startdate, char *enddate, int days,X509_REQ * req,stuKEYUSAGE * KUSAGE,
stuEKEYUSAGE * EKUSAGE,char * outMsg)
{
X509_NAME *name=NULL,*CAname=NULL;
X509 *ret=NULL;
X509_CINF *ci;
EVP_PKEY *pktmp;
int ok= -1,i=0;
// STACK_OF (X509_EXTENSION) * req_exts;//如何释放
char kusage[160]={0};
char ekusage[360]={0};
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(x509)))//发行者
{
ok=0;
goto err;
}
if (strcmp(startdate,"today") == 0)
X509_gmtime_adj(X509_get_notBefore(ret),0);//开始日期
else ASN1_UTCTIME_set_string(X509_get_notBefore(ret),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),enddate);
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;
}
/* Lets add the extensions, if there are any 加入标准扩展*/
//基本限制Note if the CA option is false the pathlen option should be omitted.
Add_ExtCert(ret,ret,NID_basic_constraints, "critical,CA:FALSE,pathlen:1");
//主题密钥标示符--------区分拥有者多对密钥
Add_ExtCert(ret,ret,NID_subject_key_identifier, "hash");
//Authority密钥标示符----区分发行者有多个签名密钥时
Add_ExtCert(ret,x509, NID_authority_key_identifier, "keyid,issuer:always");
//密钥用法 ----数字签名、不可否认性、密钥加密、数据加密、密钥协商、证书签名、
//CRL签名、仅仅加密、仅仅解密
if(KUSAGE->DS)
strcpy(kusage,"digitalSignature");
if(KUSAGE->NR)
if(strlen(kusage))//添加
strcat(kusage, ",nonRepudiation");
else
strcpy(kusage,"nonRepudiation");
if(KUSAGE->KE)
if(strlen(kusage))//添加
strcat(kusage, ",keyEncipherment");
else
strcpy(kusage,"keyEncipherment");
if(KUSAGE->DE)
if(strlen(kusage))//添加
strcat(kusage, ",dataEncipherment");
else
strcpy(kusage,"dataEnc