Openssl 简介
构成部分
用途
openssl生成csr的程序方法
将openssl如何生成CSR写了一上DEMO,支持扩展属性,同时增加了通过DN字符串转X509_NAME的方法。
[cpp]
#include<string.h>
#include<openssl/x509.h>
#include<openssl/rsa.h>
#pragmacomment(lib,“libeay32.lib”)
/*
*subjectisexpectedtobeintheformat/type0=value0/type1=value1/type2=…
*wherecharactersmaybeescapedby\
*/
X509_NAME*parse_name(char*subject,longchtype,intmultirdn)
{
size_tbuflen=strlen(subject)+1;/*tocopythetypesandvaluesinto.duetoescaping,thecopycanonlybecomeshorter*/
char*buf=OPENSSL_malloc(buflen);
size_tmax_ne=buflen/2+1;/*maximumnumberofnameelements*/
char**ne_types=OPENSSL_malloc(max_ne*sizeof(char*));
char**ne_values=OPENSSL_malloc(max_ne*sizeof(char*));
int*mval=OPENSSL_malloc(max_ne*sizeof(int));
char*sp=subject,*bp=buf;
inti,ne_num=0;
X509_NAME*n=NULL;
intnid;
if(!buf||!ne_types||!ne_values||!mval)
{
//BIO_printf(bio_err,“mallocerror\n”);
gotoerror;
}
if(*subject!=‘/’)
{
//BIO_printf(bio_err,“Subjectdoesnotstartwith‘/’.\n”);
gotoerror;
}
sp++;/*skipleading/*/
/*nomultivaluedRDNbydefault*/
mval[ne_num]=0;
while(*sp)
{
/*collecttype*/
ne_types[ne_num]=bp;
while(*sp)
{
if(*sp==‘\\’)/*isthereanythingtoescapeinthetype…?*/
{
if(*++sp)
*bp++=*sp++;
else
{
//BIO_printf(bio_err,“escapecharacteratendofstring\n”);
gotoerror;
}
}
elseif(*sp==‘=’)
{
sp++;
*bp++=‘\0’;
break;
}
else
*bp++=*sp++;
}
if(!*sp)
{
//BIO_printf(bio_err,“endofstringencounteredwhileprocessingtypeofsubjectnameelement#%d\n”,ne_num);
gotoerror;
}
ne_values[ne_num]=bp;
while(*sp)
{
if(*sp==‘\\’)
{
if(*++sp)
*bp++=*sp++;
else
{
//BIO_printf(bio_err,“escapecharacteratendofstring\n”);
gotoerror;
}
}
elseif(*sp==‘/’)
{
sp++;
/*nomultivaluedRDNbydefault*/
mval[ne_num+1]=0;
break;
}
elseif(*sp==‘+’&&multirdn)
{
/*anotescaped+signalsamutlivaluedRDN*/
sp++;
mval[ne_num+1]=-1;
break;
}
else
*bp++=*sp++;
}
*bp++=‘\0’;
ne_num++;
}
if(!(n=X509_NAME_new()))
gotoerror;
for(i=0;i<ne_num;i++)
{
if((nid=OBJ_txt2nid(ne_types[i]))==NID_undef)
{
//BIO_printf(bio_err,“SubjectAttribute%shasnoknownNID,skipped\n”,ne_types[i]);
continue;
}
if(!*ne_values[i])
{
//BIO_printf(bio_err,“NovalueprovidedforSubjectAttribute%s,skipped\n”,ne_types[i]);
continue;
}
if(!X509_NAME_add_entry_by_NID(n,nid,chtype,(unsignedchar*)ne_values[i],-1,-1,mval[i]))
gotoerror;
}
OPENSSL_free(ne_values);
OPENSSL_free(ne_types);
OPENSSL_free(buf);
OPENSSL_free(mval);
returnn;
error:
X509_NAME_free(n);
if(ne_values)
OPENSSL_free(ne_values);
if(ne_types)
OPENSSL_free(ne_types);
if(mval)
OPENSSL_free(mval);
if(buf)
OPENSSL_free(buf);
returnNULL;
}
X509_NAME*CreateDN(char*pbEmail,char*pbCN,char*pbOU,char*pbO,char*pbL,char*pbST,char*pbC)
{
X509_NAME*pX509Name=NULL;
if(pbCN==NULL)
{
returnNULL;
}
if(!(pX509Name=X509_NAME_new()))
{
returnNULL;
}
X509_NAME_add_entry_by_txt(pX509Name,“emailAddress”,V_ASN1_UTF8STRING,pbEmail,-1,-1,0);
X509_NAME_add_entry_by_txt(pX509Name,“CN”,V_ASN1_UTF8STRING,pbCN,-1,-1,0);
X509_NAME_add_entry_by_txt(pX509Name,“OU”,V_ASN1_UTF8STRING,pbOU,-1,-1,0);
X509_NAME_add_entry_by_txt(pX509Name,“O”,V_ASN1_UTF8STRING,pbO,-1,-1,0);
X509_NAME_add_entry_by_txt(pX509Name,“L”,V_ASN1_UTF8STRING,pbL,-1,-1,0);
X509_NAME_add_entry_by_txt(pX509Name,“ST”,V_ASN1_UTF8STRING,pbST,-1,-1,0);
X509_NAME_add_entry_by_txt(pX509Name,“C”,V_ASN1_UTF8STRING,pbC,-1,-1,0);
returnpX509Name;
}
intGenCSR(char*pbDN,intnDNLen,char*pCSR,size_tnCSRSize)
{
charszAltName[]=“DNS:www.”;
charszComment[]=“CreatebyJinhill”;
charszKeyUsage[]=“digitalSignature,nonRepudiation”;
charszExKeyUsage[]=“serverAuth,clientAuth”;
X509_REQ*pX509Req=NULL;
intiRV=0;
longlVer=3;
X509_NAME*pX509DN=NULL;
EVP_PKEY*pEVPKey=NULL;
RSA*pRSA=NULL;
X509_NAME_ENTRY*pX509Entry=NULL;
charszBuf[255]={0};
charmdout[20];
intnLen,nModLen;
intbits=2048;
unsignedlongE=RSA_3;
unsignedchar*pDer=NULL;
unsignedchar*p=NULL;
FILE*fp=NULL;
constEVP_MD*md=NULL;
X509*pX509=NULL;
BIO*pBIO=NULL;
BIO*pPemBIO=NULL;
BUF_MEM*pBMem=NULL;
//STACK_OF(X509_EXTENSION)*pX509Ext;
if(pbDN==NULL)
{
return-1;
}
pX509DN=parse_name(pbDN,V_ASN1_UTF8STRING,0);
pX509Req=X509_REQ_new();
iRV=X509_REQ_set_version(pX509Req,lVer);
//subjectpX509Name
iRV=X509_REQ_set_subject_name(pX509Req,pX509DN);
/*pubkey*/
pEVPKey=EVP_PKEY_new();
pRSA=RSA_generate_key(bits,E,NULL,NULL);
EVP_PKEY_assign_RSA(pEVPKey,pRSA);
iRV=X509_REQ_set_pubkey(pX509Req,pEVPKey);
/*attribute*/
strcpy(szBuf,szAltName);
nLen=strlen(szBuf);
iRV=X509_REQ_add1_attr_by_txt(pX509Req,“subjectAltName”,V_ASN1_UTF8STRING,szBuf,nLen);
strcpy(szBuf,szKeyUsage);
nLen=strlen(szBuf);
iRV=X509_REQ_add1_attr_by_txt(pX509Req,“keyUsage”,V_ASN1_UTF8STRING,szBuf,nLen);
strcpy(szBuf,szExKeyUsage);
nLen=strlen(szBuf);
iRV=X509_REQ_add1_attr_by_txt(pX509Req,“extendedKeyUsage”,V_ASN1_UTF8STRING,szBuf,nLen);
strcpy(szBuf,szComment);
nLen=strlen(szBuf);
iRV=X509_REQ_add1_attr_by_txt(pX509Req,“nsComment”,V_ASN1_UTF8STRING,szBuf,nLen);
md=EVP_sha1();
iRV=X509_REQ_digest(pX509Req,md,mdout,&nModLen);
iRV=X509_REQ_sign(pX509Req,pEVPKey,md);
if(!iRV)
{
printf(“signerr!\n”);
X509_REQ_free(pX509Req);
return-1;
}
//写入文件PEM格式
//pBIO=BIO_new_file(“certreq.txt”,“w”);
//PEM_write_bio_X509_REQ(pBIO,pX509Req,NULL,NULL);
//BIO_free(pBIO);
//返回PEM字符
pPemBIO=BIO_new(BIO_s_mem());
PEM_write_bio_X509_REQ(pPemBIO,pX509Req,NULL,NULL);
BIO_get_mem_ptr(pPemBIO,&pBMem);
if(pBMem->length<=nCSRSize)
{
memcpy(pCSR,pBMem->data,pBMem->length);
}
BIO_free(pPemBIO);
/*DER编码*/
//nLen=i2d_X509_REQ(pX509Req,NULL);
//pDer=(unsignedchar*)malloc(nLen);
//p=pDer;
//nLen=i2d_X509_REQ(pX509Req,&p);
//free(pDer);
//验证CSR
OpenSSL_add_all_algorithms();
iRV=X509_REQ_verify(pX509Req,pEVPKey);
if(iRV<0)
{
printf(“verifyerr.\n”);
}
X509_REQ_free(pX509Req);
returnnCSRSize;
}
intmain()
{
charchDN[255]=“/CN=www./O=BeijingJinhillInc./C=CN”;
charchCSR[2048]={0};
intrv=GenCSR(chDN,strlen(chDN),chCSR,sizeof(chCSR));
printf(“CSR:\n%s”,chCSR);
}
GDCA()拥有国内自主签发的SSL证书以及是国际知名品牌:GlobalSign、Symantec、GeoTrust SSL证书国内金牌代理商,满足各种用户对SSL的各种要求,广大用户可根据自身的需求向GDCA申请合适的SSL证书,GDCA的专业团队将会为您提供最佳的HTTPS解决方案。
猜你喜欢