From 34afae2880c94ad0ac8b92dbfad5e0d892a6eff2 Mon Sep 17 00:00:00 2001
From: drkleena <jolausson@student.unimelb.edu.au>
Date: Wed, 23 May 2018 11:27:53 +1000
Subject: [PATCH] initial commit

---
 .remote-sync.json                    |  14 +
 certexample                          | Bin 0 -> 16164 bytes
 certexample.c                        | 457 ++++++++++++++++++++++++---
 makefile                             |   3 +
 output_test.csv                      |  13 +
 sample_certs/sample_input_single.csv |   1 +
 6 files changed, 440 insertions(+), 48 deletions(-)
 create mode 100644 .remote-sync.json
 create mode 100755 certexample
 create mode 100644 makefile
 create mode 100644 output_test.csv
 create mode 100644 sample_certs/sample_input_single.csv

diff --git a/.remote-sync.json b/.remote-sync.json
new file mode 100644
index 0000000..2d3e8f5
--- /dev/null
+++ b/.remote-sync.json
@@ -0,0 +1,14 @@
+{
+  "transport": "scp",
+  "uploadOnSave": true,
+  "useAtomicWrites": true,
+  "deleteLocal": false,
+  "hostname": "ubuntu@115.146.95.37",
+  "ignore": [
+    ".remote-sync.json",
+    ".git/**"
+  ],
+  "watch": [],
+  "keyfile": "~/Desktop/private.txt",
+  "passphrase": "j0nas13"
+}
\ No newline at end of file
diff --git a/certexample b/certexample
new file mode 100755
index 0000000000000000000000000000000000000000..133b4413ab264e369a804e79ee90672329bf6e0f
GIT binary patch
literal 16164
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

literal 0
HcmV?d00001

diff --git a/certexample.c b/certexample.c
index f525aba..ab7dba1 100644
--- a/certexample.c
+++ b/certexample.c
@@ -3,70 +3,173 @@
     gcc -o certexample certexample.c -lssl -lcrypto
 */
 #include <openssl/x509.h>
+#include <openssl/asn1.h>
+#include <openssl/crypto.h>
+#include <openssl/asn1t.h>
 #include <openssl/x509v3.h>
 #include <openssl/bio.h>
 #include <openssl/pem.h>
 #include <openssl/err.h>
 #include <stdio.h>
 #include <string.h>
+#include <assert.h>
+#include <time.h>
+#include <openssl/asn1_mac.h>
 
-int main()
-{
+const ASN1_TIME *X509_get0_notBefore(const X509 *x);
+char** str_split(const char* a_str, const char a_delim);
+char* concat(char *s1, char *s2);
+char* get_basic_constraints(X509 *cert);
+char* get_key_usage(X509 *cert);
+char* compare_not_before(X509 *cert);
+char* compare_not_after(X509 *cert);
+char* get_SAN(X509 *cert);
+char *get_domain_name(X509 *cert);
+int matches_subject_alternative_name(const char *hostname, X509 *server_cert);
+int get_public_key_length(X509 *cert);
+int validate_basic_constraints(char* basic_constraints);
+int validate_key_usage(char* key_usage);
+int validate_key_length(int length);
+int validate_CN(const char* hostname, char*cn);
+int validate_wildcard_string(const char *hostname, char*hostname_with_wildcard);
+int validate_CN_and_SAN(const char *url, X509 *cert);
+int validate_not_before(X509 *cert);
+int validate_not_after(X509 *cert);
+int validate_certificate(const char *url, X509 *cert);
 
-    const char test_cert_example[] = "./cert-file2.pem";
-    BIO *certificate_bio = NULL;
-    X509 *cert = NULL;
-    X509_NAME *cert_issuer = NULL;
-    X509_CINF *cert_inf = NULL;
-    STACK_OF(X509_EXTENSION) * ext_list;
+int main(int argc, char **argv){
+    int LINE_BUFFER=100;
+    char line[LINE_BUFFER];
 
-    //initialise openSSL
+    FILE *csv_input = fopen(concat("./sample_certs/",argv[1]), "r");
+    FILE *csv_output = fopen("output_test.csv" ,"w");
+
+    //for each line in the csv file, process each certificate
     OpenSSL_add_all_algorithms();
     ERR_load_BIO_strings();
     ERR_load_crypto_strings();
 
-    //create BIO object to read certificate
-    certificate_bio = BIO_new(BIO_s_file());
+    int n = 0;
+    while (fgets(line, LINE_BUFFER, csv_input) != NULL){
+
+        printf("CSV LINE # %d\n", n);
+        BIO *certificate_bio = NULL;
+        X509 *cert = NULL;
+        X509_NAME *cert_issuer = NULL;
+        X509_CINF *cert_inf = NULL;
+        STACK_OF(X509_EXTENSION) * ext_list;
+        certificate_bio = BIO_new(BIO_s_file());
+        //here we are able to access each line
+        line[strlen(line)-1] = '\0';
+
+
+        char **csv_row_elements = str_split(line, ',');
+
+        printf("\tFILE: %s\n",csv_row_elements[0]);
+        printf("\tURL: %s\n",csv_row_elements[1]);
+
+
+        char *certificate_file = concat("./sample_certs/", csv_row_elements[0]);
+
+        const char *url = csv_row_elements[1];
+        //for some reason splitting keeps mututating the original string
+        char *unchanged_url = csv_row_elements[1];
+
+        FILE *fp = fopen(certificate_file, "r");
+
+        if (!(BIO_read_filename(certificate_bio, certificate_file))){
+            fprintf(stderr, "Error in reading cert BIO filename");
+            exit(EXIT_FAILURE);
+        }
+
+        //load certiifcate
+        if (!(cert = PEM_read_bio_X509(certificate_bio, NULL, 0, NULL))){
+            fprintf(stderr, "Error in loading certificate");
+            exit(EXIT_FAILURE);
+        }
+        // printf ("\tBASIC CONSTRAINT: %s\n",get_basic_constraints(cert));
+        // printf ("\tBASIC CONSTRAINT VALIDATION: %d\n",validate_basic_constraints(get_basic_constraints(cert)));
+        //
+        // // printf ("\tKEY USAGE: %s\n",get_key_usage(cert));
+        // printf ("\tKEY USAGE VALIDATION: %d\n",validate_key_usage(get_key_usage(cert)));
+        //
+        // // printf ("\tKEY LENGTH BITS: %d\n",get_public_key_length(cert));
+        //
+        // printf ("\tKEY LENGTH VALIDATION: %d\n",validate_key_length(get_public_key_length(cert)));
+        //
+        // // printf ("\tNot Before compared to Current:  %s\n",compare_not_before(cert));
+        // // printf ("\tNot After compared to Current:  %s\n",compare_not_after(cert));
+        // printf("\tNOT BEFORE VALIDATION %d\n", validate_not_before(cert));
+        // printf("\tNOT AFTER VALIDATION %d\n", validate_not_after(cert));
+        // // printf ("\tCommon Name:  %s\n",get_domain_name(cert));
+        //
+        // printf("\tCOMMON NAME AND SAN VALIDATION %d\n", validate_CN_and_SAN(url, cert));
+        // printf ("%d", 0 || 1);
+        // printf("FINAL VALIDATION %d\n", validate_certificate(url, cert));
+        // printf("\t%s\n", unchanged_url);
+        fprintf(csv_output,"%s,", csv_row_elements[0]);
+        fprintf(csv_output,"%s,", unchanged_url);
+        fprintf(csv_output,"%d\n", validate_certificate(url, cert));
+
+        // printf ("\tCOMMON NAME VALIDATION:  %d\n",);
+        // printf ("\tMatches Subject Alternative Name Result:  %d\n",);
+        // printf("URL: %s\n",url);
+
+        //
+        // printf("URL: %s\n",url);
+        n++;
 
-    //Read certificate into BIO
-    if (!(BIO_read_filename(certificate_bio, test_cert_example)))
-    {
-        fprintf(stderr, "Error in reading cert BIO filename");
-        exit(EXIT_FAILURE);
-    }
-    if (!(cert = PEM_read_bio_X509(certificate_bio, NULL, 0, NULL)))
-    {
-        fprintf(stderr, "Error in loading certificate");
-        exit(EXIT_FAILURE);
     }
+    exit(0);
+}
+char* get_basic_constraints(X509 *cert){
 
-    //cert contains the x509 certificate and can be used to analyse the certificate
-    
-    //*********************
-    // Example code of accessing certificate values
-    //*********************
+    X509_EXTENSION *ex = X509_get_ext(cert, X509_get_ext_by_NID(cert, NID_basic_constraints, -1));
 
-    cert_issuer = X509_get_issuer_name(cert);
-    char issuer_cn[256] = "Issuer CN NOT FOUND";
-    X509_NAME_get_text_by_NID(cert_issuer, NID_commonName, issuer_cn, 256);
-    printf("Issuer CommonName:%s\n", issuer_cn);
+    ASN1_OBJECT *obj = X509_EXTENSION_get_object(ex);
+
+    char buff[1024];
+    OBJ_obj2txt(buff, 1024, obj, 0);
+    //printf("Extension: %s, ", buff);
+
+    BUF_MEM *bptr = NULL;
+    char *buf = NULL;
+
+    BIO *bio = BIO_new(BIO_s_mem());
+
+    X509V3_EXT_print(bio, ex, 0, 0);
+
+
+    BIO_flush(bio);
+    BIO_get_mem_ptr(bio, &bptr);
+
+    //bptr->data is not NULL terminated - add null character
+    buf = (char *)malloc((bptr->length + 1) * sizeof(char));
+    memcpy(buf, bptr->data, bptr->length);
+    buf[bptr->length] = '\0';
+    BIO_flush(bio);
+    //Can print or parse value
+
+    return buf;
+}
+char* get_key_usage(X509 *cert){
+
+    X509_EXTENSION *ex = X509_get_ext(cert, X509_get_ext_by_NID(cert, NID_ext_key_usage, -1));
 
-    //List of extensions available at https://www.openssl.org/docs/man1.1.0/crypto/X509_REVOKED_get0_extensions.html
-    //Need to check extension exists and is not null
-    X509_EXTENSION *ex = X509_get_ext(cert, X509_get_ext_by_NID(cert, NID_subject_key_identifier, -1));
     ASN1_OBJECT *obj = X509_EXTENSION_get_object(ex);
+
     char buff[1024];
     OBJ_obj2txt(buff, 1024, obj, 0);
-    printf("Extension:%s\n", buff);
+    //printf("Extension: %s, ", buff);
 
     BUF_MEM *bptr = NULL;
     char *buf = NULL;
 
     BIO *bio = BIO_new(BIO_s_mem());
-    if (!X509V3_EXT_print(bio, ex, 0, 0))
-    {
-        fprintf(stderr, "Error in reading extensions");
-    }
+
+    X509V3_EXT_print(bio, ex, 0, 0);
+
+
     BIO_flush(bio);
     BIO_get_mem_ptr(bio, &bptr);
 
@@ -76,15 +179,273 @@ int main()
     buf[bptr->length] = '\0';
 
     //Can print or parse value
-    printf("%s\n", buf);
 
-    //*********************
-    // End of Example code
-    //*********************
+    return buf;
+}
+int get_public_key_length(X509 *cert){
 
-    X509_free(cert);
-    BIO_free_all(certificate_bio);
-    BIO_free_all(bio);
-    free(buf);
-    exit(0);
-}
\ No newline at end of file
+    EVP_PKEY *public_key = X509_get_pubkey(cert);
+
+    RSA *rsa_key = EVP_PKEY_get1_RSA(public_key);
+
+    int key_length_bytes = RSA_size(rsa_key);
+
+    return (key_length_bytes*8);
+
+}
+char* get_domain_name(X509 *cert){
+    X509_NAME *x509_name = X509_get_subject_name(cert);
+    char *cert_cn = X509_NAME_oneline(x509_name, 0, 0);
+    cert_cn =(cert_cn+1);
+    char **chain = str_split(cert_cn, '/');
+    char *domain = chain[5];
+
+    char **domain_clean = str_split(domain, '=');
+
+    return domain_clean[1];
+}
+char* compare_not_before(X509 *cert){
+    int day, sec;
+    const ASN1_TIME *not_before = X509_get_notBefore(cert);
+
+    if (!ASN1_TIME_diff(&day, &sec, NULL, not_before)){
+        /* Invalid time format */
+        printf("what the fuck do now\n");
+    }
+
+    if (day > 0 || sec > 0){
+        return "Later";
+    }
+    else if (day < 0 || sec < 0){
+        return "Sooner";
+    }
+    else{
+        return "Same";
+    }
+    return "invalid?";
+}
+char* compare_not_after(X509 *cert){
+    int day, sec;
+    const ASN1_TIME *not_after = X509_get_notAfter(cert);
+
+    if (!ASN1_TIME_diff(&day, &sec, NULL, not_after)){
+        /* Invalid time format */
+        printf("what the fuck do now\n");
+    }
+
+    if (day > 0 || sec > 0){
+        return "Later";
+    }
+    else if (day < 0 || sec < 0){
+        return "Sooner";
+    }
+    else{
+        return "Same";
+    }
+
+    return "invalid?";
+}
+char* concat(char *s1, char *s2){
+	//concats two strings
+    char *result = malloc(strlen(s1)+strlen(s2)+1);
+    strcpy(result, s1);
+    strcat(result, s2);
+    return result;
+
+}
+char** str_split(const char* a_str, const char a_delim){
+    char** result = 0;
+    size_t count = 0;
+    char* tmp = (char *)a_str;
+    char* copy = (char *)a_str;
+    char* last_comma = 0;
+    char delim[2];
+    delim[0] = a_delim;
+    delim[1] = 0;
+
+    /* Count how many elements will be extracted. */
+    while (*tmp){
+        if (a_delim == *tmp){
+            count++;
+            last_comma = tmp;
+        }
+        tmp++;
+    }
+    /* Add space for trailing token. */
+    count += last_comma < (a_str + strlen(a_str) - 1);
+    /* Add space for terminating null string so caller
+       knows where the list of returned strings ends. */
+    count++;
+    result = malloc(sizeof(char*) * count);
+    if (result){
+        size_t idx  = 0;
+        char* token = strtok(copy, delim);
+
+        while (token){
+            assert(idx < count);
+            *(result + idx++) = strdup(token);
+            token = strtok(0, delim);
+        }
+        assert(idx == count - 1);
+        *(result + idx) = 0;
+    }
+    return result;
+}
+int matches_subject_alternative_name(const char *hostname, X509 *server_cert) {
+
+
+    int i;
+    int san_names_nb = -1;
+    STACK_OF(GENERAL_NAME) *san_names = NULL;
+
+    // Try to extract the names within the SAN extension from the certificate
+    san_names = X509_get_ext_d2i(server_cert, NID_subject_alt_name, NULL, NULL);
+
+
+    if (san_names == NULL) {
+
+        return 0;
+    }
+
+    san_names_nb = sk_GENERAL_NAME_num(san_names);
+
+    // Check each name within the extension
+    for (i=0; i<san_names_nb; i++) {
+        const GENERAL_NAME *current_name = sk_GENERAL_NAME_value(san_names, i);
+
+        if (current_name->type == GEN_DNS) {
+            // Current name is a DNS name, let's check it
+            char *dns_name = (char *) ASN1_STRING_data(current_name->d.dNSName);
+            printf ("\t%s\n", dns_name);
+            // Make sure there isn't an embedded NUL character in the DNS name
+            if (ASN1_STRING_length(current_name->d.dNSName) != strlen(dns_name)) {
+
+                return 0;
+                break;
+            }
+            else { // Compare expected hostname with the DNS name
+
+
+
+                if (validate_wildcard_string(hostname, dns_name) == 1) {
+
+                    return 1;
+
+                    break;
+                }
+            }
+        }
+    }
+    sk_GENERAL_NAME_pop_free(san_names, GENERAL_NAME_free);
+    return 0;
+}
+int validate_key_usage(char* key_usage){
+
+    //key usage may be a bunch of strings, need to get first one if this is the case
+
+    if(strlen("TLS Web Server Authentication")!=strlen(key_usage)){
+        char **key_usage_clean = str_split(key_usage, ',');
+        if(strcmp(key_usage_clean[0], "TLS Web Server Authentication") == 0){
+            return 1;
+        }
+
+        return 0;
+
+
+    }
+
+    else{
+        if(strcmp(key_usage, "TLS Web Server Authentication") == 0){
+            return 1;
+        }
+        return 0;
+    }
+
+}
+int validate_basic_constraints(char* basic_constraints){
+
+    if(strcmp(basic_constraints, "CA:FALSE")==0){
+        // printf("\tBASIC CONSTRAINT PASS\n");
+        return 1;
+    }
+    return 0;
+}
+
+int validate_wildcard_string(const char *hostname, char*hostname_with_wildcard){
+    char **hostname_with_wildcard_split = str_split(hostname_with_wildcard, '.');
+
+    char **hostname_split = str_split(hostname, '.');
+
+    const char *hostname_with_wildcard_right = hostname_with_wildcard_split[1];
+    const char *hostname_split_right = hostname_split[1];
+
+    if(strcasecmp(hostname_split_right, hostname_with_wildcard_right)==0){
+        printf("\t\tWILDCARD FUNCTION\t\t%s == %s\n", hostname_split_right, hostname_with_wildcard_right);
+        return 1;
+    }
+    return 0;
+}
+int validate_key_length(int length){
+    if (length==2048){
+        return 1;
+    }
+    return 0;
+}
+int validate_CN(const char* hostname, char*cn){
+    if(cn[0]=='*'){
+        return (validate_wildcard_string(hostname, cn));
+    }
+    else{
+        if(strcasecmp(cn, hostname)==0){
+            return 1;
+        }
+        else{
+            return 0;
+        }
+    }
+    return 0;
+}
+int validate_CN_and_SAN(const char *url, X509 *cert){
+
+    if(validate_CN(url, get_domain_name(cert)) || matches_subject_alternative_name(url, cert)){
+        return 1;
+    }
+    else{return 0;}
+}
+int validate_not_before(X509 *cert){
+
+    if(strcmp(compare_not_before(cert), "Sooner")==0){
+        return 1;
+    }
+    return 0;
+}
+int validate_not_after(X509 *cert){
+
+    if(strcmp(compare_not_after(cert), "Later")==0){
+        return 1;
+    }
+    return 0;
+}
+int validate_certificate(const char *url, X509 *cert){
+    // printf ("\tBASIC CONSTRAINT VALIDATION: %d\n",validate_basic_constraints(get_basic_constraints(cert)));
+    // printf ("\tKEY USAGE VALIDATION: %d\n",validate_key_usage(get_key_usage(cert)));
+    // printf ("\tKEY LENGTH VALIDATION: %d\n",validate_key_length(get_public_key_length(cert)));
+    // printf("\tNOT BEFORE VALIDATION %d\n", validate_not_before(cert));
+    // printf("\tNOT AFTER VALIDATION %d\n", validate_not_after(cert));
+    // printf("\tCOMMON NAME AND SAN VALIDATION %d\n", validate_CN_and_SAN(url, cert));
+
+    int a =  validate_basic_constraints(get_basic_constraints(cert));
+    int b = validate_key_usage(get_key_usage(cert));
+    int c = validate_key_length(get_public_key_length(cert));
+    int d = validate_not_before(cert);
+    int e = validate_not_after(cert);
+    // printf("%s\n", url);
+    int f = validate_CN_and_SAN(url, cert);
+    // & b & c & d & e & f
+    if(a&b & c & d & e& f){
+        return 1;
+    }
+    else{
+        return 0;
+    }
+}
diff --git a/makefile b/makefile
new file mode 100644
index 0000000..f62ae4a
--- /dev/null
+++ b/makefile
@@ -0,0 +1,3 @@
+#!/bin/bash
+all: certexample.c
+	gcc -I /usr/local/opt/openssl/include -L /usr/local/opt/openssl/lib -o certexample certexample.c -lssl -lcrypto
diff --git a/output_test.csv b/output_test.csv
new file mode 100644
index 0000000..7b25d86
--- /dev/null
+++ b/output_test.csv
@@ -0,0 +1,13 @@
+testone.crt,www.example.com,0
+testtwo.crt,www.mydomain.com,1
+testthree.crt,www.test.com,0
+testfour.crt,www.oldsite.com,0
+testfive.crt,www.unimelb.com,0
+testsix.crt,www.codetest.com,0
+testseven.crt,www.example.com,1
+testeight.crt,www.comp30023.com,1
+testnine.crt,www.certtest.com,1
+testten.crt,www.victoria.com,1
+testeleven.crt,freeca.com,0
+testtwo.crt,www.example.com,0
+testseven.crt,example.com,0
diff --git a/sample_certs/sample_input_single.csv b/sample_certs/sample_input_single.csv
new file mode 100644
index 0000000..9239412
--- /dev/null
+++ b/sample_certs/sample_input_single.csv
@@ -0,0 +1 @@
+testeight.crt,www.comp30023.com
-- 
GitLab