欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

openssl——解析ssl通信过程的x509证书

程序员文章站 2022-07-12 21:59:17
...

首先当然得是想办法把通信过程中(例如libpcap抓包)的x509证书所在的内存起始地址,长度拿下来咯,下面代码可以直接贴上去用。注意如果是libpcap捕获的证书,必须要保证传入的证书必须是完整的(需要考虑证书是否跨IP数据包,是否乱序,如果证书跨包则需要手动重组)

#include <openssl\x509.h>
#include <openssl\x509v3.h>
#include <openssl\bio.h>
#include <openssl\bn.h>
#include <openssl\x509_vfy.h>
#include <openssl\pem.h>

struct certificate
{
	char *subj;
	char *issuer;
	char *not_before;
	char *not_after;
};


int x509cert_parse(const  unsigned char * data, unsigned int len, struct certificate * incert)
//从内存中解析x509证书。
//其中data是一个证书的起始地址,
//len是这个证书的长度
//certificate是自定义的结构,主要保存证书的subject,issuer和有效期。
{
	X509 * cert = d2i_X509(NULL, &data, len);
	char not_after_str[256] = { 0 }, not_before_str[256] = { 0 };
	if (cert == NULL)
	{
		//printf("UNABLE to parse this certificate in memory.\n");
		return -1;
	}
	char * subj = X509_NAME_oneline(X509_get_subject_name(cert), NULL, 0);
	incert->subj = (char *)malloc(sizeof(char)* (1+strlen(subj)));
	memset(incert->subj, 0, 1+strlen(subj));
	memcpy(incert->subj, subj, strlen(subj));

	char *issuer = X509_NAME_oneline(X509_get_issuer_name(cert), NULL, 0);
	incert->issuer = (char *)malloc(sizeof(char)* (1+strlen(issuer)));
	memset(incert->issuer, 0,1+ strlen(issuer));
	memcpy(incert->issuer, issuer, strlen(issuer));

	ASN1_TIME * not_before = X509_get_notBefore(cert);
	ASN1_TIME * not_after = X509_get_notAfter(cert);

	BIO * b = BIO_new(BIO_s_mem());
	ASN1_TIME_print(b, not_after);
	BIO_gets(b, not_after_str, 256);
	incert->not_after = (char *)malloc(sizeof(char)* (1+strlen(not_after_str)));
	memset(incert->not_after, 0, 1+strlen(not_after_str));
	memcpy(incert->not_after, not_after_str, strlen(not_after_str));

	ASN1_TIME_print(b, not_before);
	BIO_gets(b, not_before_str, 256);
	incert->not_before = (char *)malloc(sizeof(char)* (1+strlen(not_before_str)));
	memset(incert->not_before, 0, 1+ strlen(not_before_str));
	memcpy(incert->not_before, not_before_str, strlen(not_before_str));

	BIO_free(b);
	X509_free(cert);
	return 0;
}