⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 OpenSSL-Test软件包是OpenSSL使用示例
💻 C
字号:
#include <stdio.h>
#include <string.h>
#include <windows.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;
	int 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;
	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("郭靖.cer","rb");
	if(fp==NULL)
	{
		printf("open file err\n");
		return ;
	}
	usrCertificate1Len = fread(usrCertificate1,1,4096,fp);
	fclose(fp);
	//读取待验证的用户证书2
	fp=fopen("黄飞洪.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证书结构体
	unsigned char *pTmp = 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;
	int nUtf8;
	int rv;

	//打开用户证书文件
	fp=fopen("黄飞洪.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);
			
			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);
			
			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);
	pTmp=derpubkey;
	//把证书公钥专为为DER编码的数据
	derpubkeyLen=i2d_PublicKey(pubKey,&pTmp);
	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;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -