ref: 272dec2602bfb557af9464d21426d195b8e8e1a5
dir: /der.c/
#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); }