OpenSSL证书操作
(2) 基于OpenSSL库开发X509证书验证和证书信息查看程序。
(2) 在函数tGetX509Info() 中,获取证书的信息,包括证书版本号、证书序列号、证书颁发者信息、证书使用者信息、证书有效期和证书公钥。
(3) 程序输出参考下图:
(2) 实验代码:
#include
#include
#include
#include
#include
void tX509_Verify()
{
unsigned char usrCertificate1[4096];
unsigned long usrCertificate1Len;
unsigned char usrCertificate2[4096];
unsigned long usrCertificate2Len;
unsigned char derCrl[4096];
unsigned long derCrlLen;
unsigned char derRootCert[4096];
unsigned long derRootCertLen;
int rv;
X509_STORE_CTX *ctx=NULL;
X509 *usrCert1=NULL;
X509 *usrCert2=NULL;
X509 *caCert=NULL;
X509 *rootCert=NULL;
X509_CRL *Crl=NULL;
STACK_OF(X509)*caCertStack=NULL;
X509_STORE *rootCertStore =NULL;
int j=0;
const unsigned char *pTmp=NULL;
FILE *fp;
fp=fopen("root.cer","rb");
if(fp==NULL)
{
printf("open file\"root.cer\"err.\n");
return;
}
derRootCertLen=fread(derRootCert,1,4096,fp);
fclose(fp);
fp=fopen("crl.crl","rb");
if(fp==NULL)
{
printf("open file\"crl.crl\"err.\n");
return;
}
derCrlLen=fread(derCrl,1,4096,fp);
fclose(fp);
fp=fopen("guojing.cer","rb");
if(fp==NULL)
{
printf("open file\"guojing.cer\"err.\n");
return;
}
usrCertificate1Len=fread(usrCertificate1,1,4096,fp);
fclose(fp);
fp=fopen("huangfeihong.cer","rb");
if(fp==NULL)
{
printf("open file\"huangfeihong.cer\"err.\n");
return;
}
usrCertificate2Len=fread(usrCertificate2,1,4096,fp);
fclose(fp);
pTmp=derRootCert;
rootCert=d2i_X509(NULL,&pTmp,derRootCertLen);
if(rootCert==NULL)
{
printf("d2i_X509 err.\n");
return;
}
pTmp=usrCertificate1;
usrCert1=d2i_X509(NULL,&pTmp,usrCertificate1Len);
if(usrCert1==NULL)
{
printf("d2i_X509 err.\n");
return;
}
pTmp=usrCertificate2;
usrCert2=d2i_X509(NULL,&pTmp,usrCertificate2Len);
if(usrCert2==NULL)
{
printf("d2i_X509 err.\n");
return;
}
pTmp=derCrl;
Crl=d2i_X509_CRL(NULL,&pTmp,derCrlLen);
if(usrCert2==NULL)
{
printf("d2i_X509_CRL err.\n");
return;
}
printf("---------------Certificate Verify ---------------\n");
rootCertStore=X509_STORE_new();
X509_STORE_add_cert(rootCertStore,rootCert);
X509_STORE_set_flags(rootCertStore,X509_V_FLAG_CRL_CHECK);
X509_STORE_add_crl(rootCertStore,Crl);
ctx=X509_STORE_CTX_new();
rv=X509_STORE_CTX_init(ctx,rootCertStore,usrCert1,caCertStack);
if(rv!=1)
{
printf("X509_STORE_CTX_init err.\n");
X509_free(usrCert1);
X509_free(usrCert2);
X509_free(rootCert);
X509_STORE_CTX_cleanup(ctx);
X509_STORE_CTX_free(ctx);
X509_STORE_free(rootCertStore);
return;
}
rv=X509_verify_cert(ctx);
if(rv!=1)
{
printf("verify guojing.cer err. error=%d,info:%s.\n",ctx->error,X509_verify_cert_error_string(ctx->error));
}
else
{
printf("verify guojing.cer OK.\n");
}
rv=X509_STORE_CTX_init(ctx,rootCertStore,usrCert2,caCertStack);
if(rv!=1)
{
printf("X509_STORE_CTX_init err.\n");
X509_free(usrCert1);
X509_free(usrCert2);
X509_free(rootCert);
X509_STORE_CTX_cleanup(ctx);
X509_STORE_CTX_free(ctx);
X509_STORE_free(rootCertStore);
return;
}
rv=X509_verify_cert(ctx);
if(rv!=1)
{
printf("verify huangfeihong.cer err. error=%d,info:%s.\n",ctx->error,X509_verify_cert_error_string(ctx->error));
}
else
{
printf("verify huangfeihong.cer OK.\n");
}
X509_free(usrCert1);
X509_free(usrCert2);
X509_free(rootCert);
X509_STORE_CTX_cleanup(ctx);
X509_STORE_CTX_free(ctx);
X509_STORE_free(rootCertStore);
return;
}
void tGetX509Info()
{
unsigned char usrCertificate[4096];
unsigned long usrCertificateLen;
X509 *x509Cert=NULL;
const unsigned char *pTmp=NULL;
X509_NAME *issuer=NULL;
X509_NAME *subject=NULL;
int i;
int entriesNum;
X509_NAME_ENTRY *name_entry;
ASN1_INTEGER *Serial=NULL;
long Nid;
ASN1_TIME *time;
EVP_PKEY *pubKey;
long Version;
FILE *fp;
unsigned char derpubkey[1024];
int derpubkeyLen;
unsigned char msginfo[1024];
int msginfoLen;
unsigned short *pUtf8=NULL;
int nUtf8;
int rv;
fp=fopen("huangfeihong.cer","rb");
if(fp==NULL)
{
printf("open file err.\n");
return;
}
usrCertificateLen=fread(usrCertificate,1,4096,fp);
fclose(fp);
pTmp=usrCertificate;
x509Cert=d2i_X509(NULL,&pTmp,usrCertificateLen);
if(x509Cert==NULL)
{
printf("d2i_X509 err.\n");
return;
}
printf("---------------Certificate Info --------------\n");
Version=X509_get_version(x509Cert);
printf("X509 Version:%d\n",Version);
Serial =X509_get_serialNumber(x509Cert);
printf("serialNumber:");
for(i=0;ilength;i++)
{
printf("%02x",Serial->data[i]);
}
printf("\n--------------------------------------------\n");
issuer=X509_get_issuer_name(x509Cert);
entriesNum=sk_X509_NAME_ENTRY_num(issuer->entries);
for(i=0;ientries,i);
Nid=OBJ_obj2nid(name_entry->object);
if(name_entry->value->type==V_ASN1_UTF8STRING)
{
nUtf8=2*name_entry->value->length;
// pUtf8=malloc(nUtf8);
memset(pUtf8,0,nUtf8);
rv=MultiByteToWideChar(
CP_UTF8,
0,
(char*)name_entry->value->data,
name_entry->value->length,
pUtf8,
nUtf8);
rv=WideCharToMultiByte(
CP_ACP,
0,
pUtf8,
rv,
(char*)msginfo,
nUtf8,
NULL,
NULL);
free(pUtf8);
pUtf8=NULL;
msginfoLen=rv;
msginfo[msginfoLen]='\0';
}
else
{
msginfoLen=name_entry->value->length;
memcpy(msginfo,name_entry->value->data,msginfoLen);
msginfo[msginfoLen]='\0';
}
switch(Nid)
{
case NID_countryName:
printf("Issuer's countryName:%s\n",msginfo);
break;
case NID_stateOrProvinceName:
printf("Issuer's ProvinceName:%s\n",msginfo);
break;
case NID_localityName:
printf("Issuer's localityName:%s\n",msginfo);
break;
case NID_organizationName:
printf("Issuer's organizationName:%s\n",msginfo);
break;
case NID_organizationalUnitName:
printf("Issuer's organizationalUnitName:%s\n",msginfo);
break;
case NID_commonName:
printf("Issuer's commonName:%s\n",msginfo);
break;
case NID_pkcs9_emailAddress:
printf("Issuer's emailAddress:%s\n",msginfo);
break;
}
}
printf("-----------------\n");
subject=X509_get_subject_name(x509Cert);
entriesNum=sk_X509_NAME_ENTRY_num(subject->entries);
for(i=0;ientries,i);
Nid=OBJ_obj2nid(name_entry->object);
if(name_entry->value->type==V_ASN1_UTF8STRING)
{
nUtf8=2*name_entry->value->length;
//pUtf8=malloc(nUtf8);
memset(pUtf8,0,nUtf8);
rv=MultiByteToWideChar(
CP_UTF8,
0,
(char*)name_entry->value->data,
name_entry->value->length,
pUtf8,
nUtf8);
rv=WideCharToMultiByte(
CP_ACP,
0,
pUtf8,
rv,
(char*)msginfo,
nUtf8,
NULL,
NULL);
free(pUtf8);
pUtf8=NULL;
msginfoLen=rv;
msginfo[msginfoLen]='\0';
}
else
{
msginfoLen=name_entry->value->length;
memcpy(msginfo,name_entry->value->data,msginfoLen);
msginfo[msginfoLen]='\0';
}
switch(Nid)
{
case NID_countryName:
printf("Subject's countryName:%s\n",msginfo);
break;
case NID_stateOrProvinceName:
printf("Subject's ProvinceName:%s\n",msginfo);
break;
case NID_localityName:
printf("Subject's localityName:%s\n",msginfo);
break;
case NID_organizationName:
printf("Subject's organizationName:%s\n",msginfo);
break;
case NID_organizationalUnitName:
printf("Subject's organizationalUnitName:%s\n",msginfo);
break;
case NID_commonName:
printf("Subject's commonName:%s\n",msginfo);
break;
case NID_pkcs9_emailAddress:
printf("Subject's emailAddress:%s\n",msginfo);
break;
}
}
printf("-----------------\n");
time=X509_get_notBefore(x509Cert);
printf("Cert notBefore:%s\n",time->data);
time=X509_get_notAfter(x509Cert);
printf("Cert notAfter:%s\n",time->data);
printf("---------------------------\n");
pubKey=X509_get_pubkey(x509Cert);
/* pTmp=derpubkey;
derpubkeyLen=i2d_PublicKey(pubKey,&pTmp);
printf("PublicKey is:\n");
for(i=0;i
unsigned char *pTmp=NULL;
rootCert=d2i_X509(NULL, &pTmp ,derRootCertLen);
usrCert1=d2i_X509(NULL,&pTmp,usrCertificate1Len);
usrCert2=d2i_X509(NULL,&pTmp,usrCertificate2Len);
解决方法为将unsigned char *pTmp=NULL;改为const unsigned char *pTmp=NULL;
(2) 证书验证存在问题:证书与实验所要用的证书有所不同。
(3) 未打印出公钥public key: