wm: dnsparser

ref: 272dec2602bfb557af9464d21426d195b8e8e1a5
dir: /der.c/

View raw version
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include <openssl/bn.h>
#include <openssl/asn1.h>
#include <openssl/x509.h>
#include <openssl/x509_vfy.h>
#include <openssl/pem.h>
#include <openssl/bio.h>
#include "common.h"

int
duplicateCN(u_char *cn, Der *der)
{
	for(int i = 0 ; i < der->nCommonName ; i++)
	{
		if(!strcmp(cn, der->commonName[i]))
			return 1;
	}
	return 0;
}

int
parseDerManual(const u_char *pkt, Der *der)
{
	u_char subjectlen;
	u_char cnlen;
	u_char *cn;
	
	//	for(u_char *p = PKTHEAD ; p < PKTHEAD + der->len + 5 ; p++)
	der->nCommonName = 0;
	for(u_char *p = PKTHEAD ; der->nCommonName < DER_CN_MAX && p != NULL ; p = (u_char*)memchr(p+1, 30, der->len))
	{
		p++;
		subjectlen = *p;
		
		for(u_char *s = p ; s != NULL && s - p < subjectlen ; s = (u_char*)memchr(s+1, 0x55, der->len))
		{
			if(s[0] == 0x55 && s[1] == 0x4 && s[2] == 0x3)
			{
				s += 4;
				cnlen = *p;
				s += 1;
				cn = memdup(s, cnlen+1);
				cn[cnlen] = '\0';
				
				if(duplicateCN(cn, der))
				{
						free(cn);
						continue;
				}
				der->commonName[der->nCommonName] = cn;
				der->nCommonName++;
				s += cnlen;
			}
		}	
	}
	pos += der->len;
	return 1;
}


int
parseDerOpenSSL(const u_char *pkt, Der *der)
{
	const u_char *head = pkt + pos;
	der->cert = d2i_X509(NULL, &head, der->len);
	if(!der->cert)
	{
		err(0, "parseDer(): failure to parse cert: pos: %d (%#x)", pos, pos);
		return 0;
	}
	
	der->subject = X509_NAME_oneline(X509_get_subject_name(der->cert), NULL, 0);
	der->issuer = X509_NAME_oneline(X509_get_issuer_name(der->cert), NULL, 0);
	
	if (X509_check_issued(der->cert, der->cert) == X509_V_OK)
		der->selfsigned = 1;
	else
		der->selfsigned = 0;
	
	der->commonName[0] = strstr(der->subject, "CN=");
	der->commonName[0] += 3; // "CN=", skip it.
	der->nCommonName++;
	
	pos += der->len;
	return 1;
}

int
parseDer(const u_char *pkt, Der *der)
{
	return parseDerOpenSSL(pkt, der);
}

void
printDer(Der der)
{
	if(debug)
	{
		printf("Der:\n"
		"\t\tsubject: %s\n"
		"\t\tissuer: %s\n"
		"\t\tselfsigned: %d\n",
		
		der.subject, der.issuer, der.selfsigned);
		
		for(int i = 0 ; i < der.nCommonName ; i++)
			printf("\t\tCN: %s\n",
			der.commonName[i]);
	}
	else
	{
		for(int i = 0 ; i < der.nCommonName ; i++)
			printf("\t\tCN: %s\n",
			der.commonName[i]);
	}
}

void
freeDer(Der *der)
{
	X509_free(der->cert);
	free(der);
}