summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Sommerseth <dazo@users.sourceforge.net>2013-06-07 17:29:06 +0200
committerDavid Sommerseth <dazo@users.sourceforge.net>2013-06-07 17:29:06 +0200
commitf9abcda006eb71f30df14218a4a2588dbc41ceb5 (patch)
treeccf5e6cae8543a8c4ddb39c1e180a2505020018b
parent00dcadab3096549e936092b7f6485fb2077868dc (diff)
downloadeurephia-f9abcda006eb71f30df14218a4a2588dbc41ceb5.tar.gz
eurephia-f9abcda006eb71f30df14218a4a2588dbc41ceb5.tar.xz
eurephia-f9abcda006eb71f30df14218a4a2588dbc41ceb5.zip
common: Improved the certificate information extračtion
Added a function to extract the needed information from an OpenSSL X509 object. Also extended parse_tlsid() to include a pointer to the certificate digest, to have a common behaviour between parse_tlsid() and parse_x509_cert(). Signed-off-by: David Sommerseth <dazo@users.sourceforge.net>
-rw-r--r--common/certinfo.c86
-rw-r--r--common/certinfo.h4
2 files changed, 88 insertions, 2 deletions
diff --git a/common/certinfo.c b/common/certinfo.c
index 12a03fc..36a92a7 100644
--- a/common/certinfo.c
+++ b/common/certinfo.c
@@ -32,6 +32,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <openssl/x509.h>
#include <eurephia_nullsafe.h>
#include <certinfo.h>
@@ -53,7 +54,7 @@
*
* @return Pointer to a certinfo structure containing the information
*/
-certinfo *parse_tlsid(const char *input) {
+certinfo *parse_tlsid(const char *input, const char *digest) {
char tmp[130], *mainp, *origptr, *sub, *tok, *tok2;
certinfo *ret = NULL;
@@ -86,6 +87,9 @@ certinfo *parse_tlsid(const char *input) {
}
free(origptr); mainp = NULL; origptr = NULL;
+ /* Copy over the digest info */
+ ret->digest = digest;
+
/* Make sure we at least have empty NULL terminated strings */
if( ret->org == NULL ) {
ret->org = strdup("\0");
@@ -100,6 +104,86 @@ certinfo *parse_tlsid(const char *input) {
return ret;
}
+/**
+ * Parses an X.509 certificate data structure into a certinfo struct
+ * This implementation depends on OpenSSL
+ */
+certinfo *parse_x509_cert (X509 *cert)
+{
+ int i, n, objnid;
+ const int hashlen = SHA_DIGEST_LENGTH*3+2;
+ ASN1_OBJECT *asn1 = NULL;
+ ASN1_STRING *asn1val = NULL;
+ X509_NAME *x509_name = NULL;
+ X509_NAME_ENTRY *ent = NULL;
+ const char *objbuf = NULL;
+ unsigned char *buf = NULL;
+ char *ptr = NULL;
+ certinfo *ret = NULL;
+
+ ret = (certinfo *) malloc_nullsafe(NULL, sizeof(certinfo)+2);
+
+ x509_name = X509_get_subject_name(cert);
+ n = X509_NAME_entry_count(x509_name);
+ for (i = 0; i < n; i++) {
+ ent = X509_NAME_get_entry(x509_name, i);
+ if( !ent ) {
+ continue;
+ }
+
+ asn1 = X509_NAME_ENTRY_get_object(ent);
+ if( !asn1 ) {
+ continue;
+ }
+
+ asn1val = X509_NAME_ENTRY_get_data(ent);
+ if( !asn1val ) {
+ continue;
+ }
+
+ objnid = OBJ_obj2nid(asn1);
+ if( objnid == NID_undef ) {
+ continue;
+ }
+
+ objbuf = OBJ_nid2sn(objnid);
+ if( !objbuf ) {
+ continue;
+ }
+
+ if( ASN1_STRING_to_UTF8(&buf, asn1val) <= 0 ) {
+ continue;
+ }
+
+ // At this point we now have the 'field name' from the certificate
+ // available in objbuf and the 'field value' in buf.
+
+ if( (ret->org == NULL) && (strcmp(objbuf, "O") == 0) ) {
+ ret->org = strdup_nullsafe((char *) buf);
+ } else if( (ret->common_name == NULL) && (strcmp(objbuf, "CN") == 0) ) {
+ ret->common_name = strdup_nullsafe((char *) buf);
+ } else if( (ret->email == NULL) && (strcmp(objbuf, "emailAddress") == 0) ) {
+ ret->email = strdup_nullsafe((char *) buf);
+ }
+ OPENSSL_free(buf); buf = NULL;
+
+ if( ret->org && ret->common_name && ret->email ) {
+ // If we got all we need, skip the rest
+ break;
+ }
+ }
+
+ // Extract the SHA1 certificate fingerprint/digest
+ ptr = ret->digest = malloc_nullsafe(NULL, hashlen);
+ buf = cert->sha1_hash;
+ for( i = 0; i < SHA_DIGEST_LENGTH; ++i ) {
+ snprintf(ptr, 4, "%02x:", buf[i]);
+ ptr += 3;
+ }
+ *(ptr-1) = 0;
+
+ return ret;
+}
/**
* Frees up the memory used by a certinfo structure
diff --git a/common/certinfo.h b/common/certinfo.h
index 91103d8..f306e36 100644
--- a/common/certinfo.h
+++ b/common/certinfo.h
@@ -41,7 +41,9 @@ typedef struct _certinfo {
char *email; /**< Contains the emailAddress field from the X.509 certificate */
} certinfo;
-certinfo *parse_tlsid(const char *);
+certinfo *parse_tlsid(const char *, const char *);
+certinfo *parse_x509_cert (X509 *cert);
+
void free_certinfo(certinfo *);
#endif