#include <stdio.h>
#include <string.h>
#include <locale.h>
#include <openssl/evp.h>
#include <openssl/x509.h>
void tX509_Verify()
{
unsigned char usrCertificate1[4096]; //DER证书缓冲区数组
unsigned long usrCertificate1Len; //证书长度
unsigned char usrCertificate2[4096];
unsigned long usrCertificate2Len;
unsigned char derCrl[4096]; //CRL缓冲区数组
unsigned long derCrlLen; //CRL长度
unsigned char derRootCert[4096]; //根证书缓冲区数组
unsigned long derRootCertLen; //根证书长度
int i,rv;
X509_STORE_CTX *ctx = NULL; //证书存储区句柄
X509 *usrCert1 = NULL; //X509证书结构体,保存用户证书
X509 *usrCert2 = NULL;
X509 *caCert = NULL; //X509证书结构体,保存CA证书
X509 *rootCert = NULL; //X509证书结构体,保存根证书
X509_CRL *Crl = NULL; //X509_CRL结构体,保存CRL
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 err\n");
return ;
}
derRootCertLen = fread(derRootCert,1,4096,fp);
fclose(fp);
//读取CRL文件
fp=fopen("crl.crl","rb");
if(fp==NULL)
{
printf("open file err\n");
return ;
}
derCrlLen = fread(derCrl,1,4096,fp);
fclose(fp);
//读取待验证的用户证书1
fp=fopen("gj.cer","rb");
if(fp==NULL)
{
printf("open file err\n");
return ;
}
usrCertificate1Len = fread(usrCertificate1,1,4096,fp);
fclose(fp);
//读取待验证的用户证书2
fp=fopen("hfh.cer","rb");
if(fp==NULL)
{
printf("open file err\n");
return ;
}
usrCertificate2Len = fread(usrCertificate2,1,4096,fp);
fclose(fp);
//把DER编码的根证书转化为X509结构体
pTmp=derRootCert;
rootCert = d2i_X509(NULL,&pTmp,derRootCertLen);
if(rootCert==NULL)
{
printf("d2i_X509 err.\n");
return;
}
//把DER编码的用户证书转化为X509结构体
pTmp=usrCertificate1;
usrCert1 = d2i_X509(NULL,&pTmp,usrCertificate1Len);
if(usrCert1==NULL)
{
printf("d2i_X509 err.\n");
return;
}
//把DER编码的用户证书转化为X509结构体
pTmp=usrCertificate2;
usrCert2 = d2i_X509(NULL,&pTmp,usrCertificate2Len);
if(usrCert2==NULL)
{
printf("d2i_X509 err.\n");
return;
}
//把DER编码的CRL转化为X509_CRL结构体
pTmp=derCrl;
Crl = d2i_X509_CRL(NULL,&pTmp,derCrlLen);
if(usrCert2==NULL)
{
printf("d2i_X509_CRL err.\n");
return;
}
//新建X509证书存储区
rootCertStore = X509_STORE_new();
//添加根证书到证书存储区
X509_STORE_add_cert(rootCertStore,rootCert);
//设置检查CRL标志位,如果设置此标志位,则检查CRL,否则不检查CRL。
X509_STORE_set_flags(rootCertStore,X509_V_FLAG_CRL_CHECK);
//添加CRL到证书存储区
X509_STORE_add_crl(rootCertStore,Crl);
//新建证书存储区句柄
ctx = X509_STORE_CTX_new();
//初始化根证书存储区、用户证书1
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;
}
//验证用户证书1
rv = X509_verify_cert(ctx);
if(rv != 1)
{
printf("verify 郭靖.cer err.error= %d,info:%s\n",ctx->error,X509_verify_cert_error_string(ctx->error));
}
else
{
printf("verify 郭靖.cer OK\n");
}
//初始化根证书存储区、用户证书2
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;
}
//验证用户证书2
rv = X509_verify_cert(ctx);
if(rv != 1)
{
printf("verify 黄飞洪.cer err.error= %d,info:%s\n",ctx->error,X509_verify_cert_error_string(ctx->error));
}
else
{
printf("verify 黄飞洪.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]; //DER证书缓冲区数组
unsigned long usrCertificateLen; //证书长度
X509 *x509Cert = NULL; //X509证书结构体
const unsigned char *pTmp = NULL;
unsigned char *pTmp1 = NULL;
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; //保存证书版本
FILE *fp;
unsigned char derpubkey[1024];
int derpubkeyLen;
unsigned char msginfo[1024];
int msginfoLen;
// unsigned short *pUtf8 = NULL;
wchar_t *pUtf8 = NULL;
int nUtf8;
int rv;
//打开用户证书文件
//fp=fopen("hfh.cer","rb");
fp=fopen("testmy.cer","rb");
//fp=fopen("ABC.cer","rb");
//fp=fopen("root.cer","rb");
if(fp==NULL)
{
printf("open file err\n");
return ;
}
usrCertificateLen = fread(usrCertificate,1,4096,fp);
fclose(fp);
//把DER证书转化为X509结构体
pTmp=usrCertificate;
x509Cert = d2i_X509(NULL,&pTmp,usrCertificateLen);
if(x509Cert==NULL)
{
printf("d2i_X509 err.\n");
return;
}
//获取证书版本
Version = X509_get_version(x509Cert);
printf("X509 Version:%ld\n",Version);
//获取证书序列号
Serial = X509_get_serialNumber(x509Cert);
//打印证书序列号
printf("serialNumber is: \n");
for(i = 0; i < Serial->length; i++)
{
printf("%02x", Serial->data[i]);
}
printf("\n");
//获取证书颁发者信息,X509_NAME结构体保存了多项信息,包括国家、组织、部门、通用名、mail等。
issuer = X509_get_issuer_name(x509Cert);
//获取X509_NAME条目个数
entriesNum = sk_X509_NAME_ENTRY_num(issuer->entries);
//循环读取各条目信息
for(i=0;i<entriesNum;i++)
{
//获取第I个条目值
name_entry = sk_X509_NAME_ENTRY_value(issuer->entries,i);
//获取对象ID
Nid = OBJ_obj2nid(name_entry->object);
//判断条目编码的类型
if(name_entry->value->type==V_ASN1_UTF8STRING)//把UTF8编码数据转化成可见字符
{
nUtf8 = 2*name_entry->value->length;
pUtf8 = malloc(nUtf8);
memset(pUtf8,0,nUtf8);
//linux
setlocale(LC_ALL,"zh_CN.UTF-8");//设置转换前的编码
rv=mbstowcs(pUtf8,(char*)name_entry->value->data,nUtf8);
rv=wcstombs((char*)msginfo,pUtf8,nUtf8);
/* //windows.h
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://国家
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://Mail
printf("issuer 's emailAddress:%s\n",msginfo);
break;
}//end switch
}
//获取证书主题信息
subject = X509_get_subject_name(x509Cert);
//获得证书主题信息条目个数
entriesNum = sk_X509_NAME_ENTRY_num(subject->entries);
//循环读取个条目信息
for(i=0;i<entriesNum;i++)
{
//获取第I个条目值
name_entry = sk_X509_NAME_ENTRY_value(subject->entries,i);
Nid = OBJ_obj2nid(name_entry->object);
//判断条目编码的类型
if(name_entry->value->type==V_ASN1_UTF8STRING)//把UTF8编码数据转化成可见字符
{
nUtf8 = 2*name_entry->value->length;
pUtf8 = malloc(nUtf8);
memset(pUtf8,0,nUtf8);
//linux
setlocale(LC_ALL,"zh_CN.UTF-8");//设置转换前的编码
rv=mbstowcs(pUtf8,(char*)name_entry->value->data,nUtf8);
rv=wcstombs((char*)msginfo,pUtf8,nUtf8);
/* //windows.h
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://Mail
printf("subject 's emailAddress:%s\n",msginfo);
break;
}//end switch
}
//获取证书生效日期
time = X509_get_notBefore(x509Cert);
printf("Cert notBefore:%s\n",time->data);
//获取证书过期日期
time = X509_get_notAfter(x509Cert);
printf("Cert notAfter:%s\n",time->data);
//获取证书公钥
pubKey = X509_get_pubkey(x509Cert);
pTmp1=derpubkey;
//把证书公钥专为为DER编码的数据
derpubkeyLen=i2d_PublicKey(pubKey,&pTmp1);
printf("PublicKey is: \n");
for(i = 0; i < derpubkeyLen; i++)
{
printf("%02x", derpubkey[i]);
}
printf("\n");
X509_free(x509Cert);
return;
}
int main()
{
OpenSSL_add_all_algorithms();
tX509_Verify();
tGetX509Info();
return 0;
}
OpenSSL linux 证书操作
最新推荐文章于 2024-08-12 15:56:16 发布