void read_digital_certificate()
{
CString filename;
unsigned char Cert[4099];
unsigned long Certlen;
unsigned char *pTmp = NULL;
X509 *usrCert = NULL; //X509证书结构体,保存用户证书
FILE *fp;
CFileDialog dlg(TRUE,NULL,NULL,OFN_HIDEREADONLY| OFN_OVERWRITEPROMPT,0,this);
if (IDOK == dlg.DoModal())
{
filename = dlg.GetPathName() ;
GetDlgItem(IDC_EDIT1)->SetWindowText(filename);
}
fp=fopen(filename.GetBuffer(0),"rb");
if(fp==NULL)
{
MessageBox("读取证书错误");
return ;
}
Certlen=fread(Cert,1,4096,fp);
fclose(fp);
//判断是否为DER编码的用户证书,并转化为X509结构体
pTmp=Cert;
usrCert = d2i_X509(NULL,(const unsigned char ** )&pTmp,Certlen);
if(usrCert==NULL)
{
BIO *b;
/* 判断是否为PEM格式的数字证书 */
b=BIO_new_file(filename.GetBuffer(0),"r");
usrCert=PEM_read_bio_X509(b,NULL,NULL,NULL);
BIO_free(b);
if(usrCert==NULL)
{
MessageBox("转化格式错误!");
return;
}
}
//解析证书
X509_NAME *issuer = NULL; //X509_NAME结构体,保存证书颁发者信息
X509_NAME *subject = NULL; //X509_NAME结构体,保存证书拥有者信息
int i;
int entriesNum;
X509_NAME_ENTRY *name_entry; //
ASN1_INTEGER *Serial = NULL; //保存证书序列号
long Nid;
ASN1_TIME *time; //保存证书有效期时间
EVP_PKEY *pubKey; //保存证书公钥
long Version; //保存证书版本
unsigned char derpubkey[1024];
int derpubkeyLen;
unsigned char msginfo[1024];
int msginfoLen;
unsigned short *pUtf8 = NULL;
int nUtf8;
int rv;
CString tmp;
//获取证书版本
Version = X509_get_version(usrCert);
tmp.Format("X509 Version:%ld\n",Version);
m_list.InsertString(-1,tmp);
tmp.Empty();
//获取证书颁发者信息,X509_NAME结构体保存了多项信息,包括国家、组织、部门、通用名、mail等。
issuer = X509_get_issuer_name(usrCert);
//获取X509_NAME条目个数
entriesNum = sk_X509_NAME_ENTRY_num(issuer->entries);
//循环读取各条目信息
for(i=0;ientries,i);
//获取对象ID
Nid = OBJ_obj2nid(name_entry->object);
//判断条目编码的类型
if(name_entry->value->type==V_ASN1_UTF8STRING)//把UTF8编码数据转化成可见字符
{
nUtf8 = 2*name_entry->value->length;
pUtf8 = (unsigned short *)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';
}
//根据NID打印出信息
switch(Nid)
{
case NID_countryName://国家
tmp.Format("issuer 's countryName:%s\n",msginfo);
m_list.InsertString(-1,tmp);
tmp.Empty();
break;
case NID_stateOrProvinceName://省
tmp.Format("issuer 's ProvinceName:%s\n",msginfo);
m_list.InsertString(-1,tmp);
tmp.Empty();
break;
case NID_localityName://地区
tmp.Format("issuer 's localityName:%s\n",msginfo);
m_list.InsertString(-1,tmp);
tmp.Empty();
break;
case NID_organizationName://组织
tmp.Format("issuer 's organizationName:%s\n",msginfo);
m_list.InsertString(-1,tmp);
tmp.Empty();
break;
case NID_organizationalUnitName://单位
tmp.Format("issuer 's organizationalUnitName:%s\n",msginfo);
m_list.InsertString(-1,tmp);
tmp.Empty();
break;
case NID_commonName://通用名
tmp.Format("issuer 's commonName:%s\n",msginfo);
m_list.InsertString(-1,tmp);
tmp.Empty();
break;
case NID_pkcs9_emailAddress://Mail
tmp.Format("issuer 's emailAddress:%s\n",msginfo);
m_list.InsertString(-1,tmp);
tmp.Empty();
break;
}//end switch
}
//获取证书主题信息
subject = X509_get_subject_name(usrCert);
//获得证书主题信息条目个数
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)//把UTF8编码数据转化成可见字符
{
nUtf8 = 2*name_entry->value->length;
pUtf8 = (unsigned short *)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://国家
tmp.Format("subject 's countryName:%s\n",msginfo);
m_list.InsertString(-1,tmp);
tmp.Empty();
break;
case NID_stateOrProvinceName://省
tmp.Format("subject 's ProvinceName:%s\n",msginfo);
m_list.InsertString(-1,tmp);
tmp.Empty();
break;
case NID_localityName://地区
tmp.Format("subject 's localityName:%s\n",msginfo);
m_list.InsertString(-1,tmp);
tmp.Empty();
break;
case NID_organizationName://组织
tmp.Format("subject 's organizationName:%s\n",msginfo);
m_list.InsertString(-1,tmp);
tmp.Empty();
break;
case NID_organizationalUnitName://单位
tmp.Format("subject 's organizationalUnitName:%s\n",msginfo);
m_list.InsertString(-1,tmp);
tmp.Empty();
break;
case NID_commonName://通用名
tmp.Format("subject 's commonName:%s\n",msginfo);
m_list.InsertString(-1,tmp);
tmp.Empty();
break;
case NID_pkcs9_emailAddress://Mail
tmp.Format("subject 's emailAddress:%s\n",msginfo);
m_list.InsertString(-1,tmp);
tmp.Empty();
break;
}//end switch
}
//获取证书生效日期
time = X509_get_notBefore(usrCert);
tmp.Format("Cert notBefore:%s\n",time->data);
m_list.InsertString(-1,tmp);
tmp.Empty();
//获取证书过期日期
time = X509_get_notAfter(usrCert);
tmp.Format("Cert notAfter:%s\n",time->data);
m_list.InsertString(-1,tmp);
tmp.Empty();
//获取证书公钥
pubKey = X509_get_pubkey(usrCert);
pTmp=derpubkey;
//把证书公钥转为DER编码的数据
derpubkeyLen=i2d_PublicKey(pubKey,&pTmp);
printf("PublicKey is: \n");
tmp.Format("PublicKey is: \n");
for(i = 0; i < derpubkeyLen; i++)
{
CString tmpp;
tmpp.Format("%02x", derpubkey[i]);
tmp=tmp+tmpp;
}
m_list.InsertString(-1,tmp);
X509_free(usrCert);
}