OpenSSL linux 证书操作

#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;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值