diff --git a/.DS_Store b/.DS_Store deleted file mode 100644 index d5e0a6428dc8765cd85a6dbeeffa32ba01fd23f1..0000000000000000000000000000000000000000 Binary files a/.DS_Store and /dev/null differ diff --git a/certexample b/certexample index 846f93a4a6f291f1bcb633c3917453db801a64b4..2ea29dbca7ad1eaeebd9e98a82c350f58bed7196 100755 Binary files a/certexample and b/certexample differ diff --git a/certexample.c b/certexample.c index fdda0bfba537bc82b0557c9ed5b9bf36165e8180..c3299381a7895c96a8dec26d5e0ca457642d4c61 100644 --- a/certexample.c +++ b/certexample.c @@ -2,234 +2,32 @@ Example certifcate code gcc -o certexample certexample.c -lssl -lcrypto */ -#include <openssl/x509.h> -#include <openssl/x509v3.h> -#include <openssl/bio.h> -#include <openssl/pem.h> -#include <openssl/err.h> -#include <openssl/rsa.h> -#include <openssl/evp.h> -#include <stdio.h> -#include <string.h> -int check_san_valid(X509* cert, char* URL, int in_host); -int check_if_url_valid(char* URL, char* domain); -int check_name_valid(X509* cert, char* URL); -void printTime(X509* cert); -int check_public_key(X509 *cert); +#include "headers.h" + int main() { + char* filename = "./sample_certs/testseven.crt"; + char* url = "www.example.com"; - char* URL = "mega.google.com"; - - const char test_cert_example[] = "./sample_certs/testtwo.crt"; - BIO *certificate_bio = NULL; - X509 *cert = NULL; - X509_CINF *cert_inf = NULL; - STACK_OF(X509_EXTENSION) * ext_list; - - //initialise openSSL - 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()); - - //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); - } - - //cert contains the x509 certificate and can be used to analyse the certificate - int in_host = check_name_valid(cert, URL); - + if (validate_certificate(filename, url)) + { + printf("VALID\n"); + } - //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 - if (check_san_valid(cert,URL, in_host)) - { - printf("valid\n"); - } - - else{ - printf("invalid\n"); - } - - printTime(cert); - check_public_key(cert); - - //********************* - // End of Example code - //********************* - - X509_free(cert); - BIO_free_all(certificate_bio); - exit(0); + else{ + printf("INVALID\n"); + } + } -void printTime(X509* cert){ - ASN1_TIME *after = X509_get_notBefore(cert); - - int day; - int sec; - - ASN1_TIME_diff(&day, &sec, after, NULL); - - printf("%d -- %d\n", day, sec); - - BUF_MEM *bptr = NULL; - char *buf = NULL; - - BIO *bio = BIO_new(BIO_s_mem()); - if (!ASN1_TIME_print(bio, after)) - { - fprintf(stderr, "Error in reading extensions"); - } - 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'; - - printf("%s\n", buf); - - BIO_free_all(bio); - free(buf); - - - ASN1_TIME *tm; - time_t t; - BIO *b; - t = time(NULL); - tm = ASN1_TIME_adj(NULL, t, 0, 0); - b = BIO_new_fp(stdout, BIO_NOCLOSE); - ASN1_TIME_print(b, tm); - ASN1_STRING_free(tm); - BIO_free(b); - -} - -int check_name_valid(X509* cert, char* URL){ - X509_NAME *cert_issuer = X509_get_subject_name(cert); - char subj_cn[256] = "Issuer CN NOT FOUND"; - X509_NAME_get_text_by_NID(cert_issuer, NID_commonName, subj_cn, 256); - if (check_if_url_valid(URL, subj_cn)) - { - return 1; - } - - return 0; -} - -int check_san_valid(X509* cert, char* URL, int in_host){ - if (in_host){ - return 1; - } - X509_EXTENSION *ex = X509_get_ext(cert, X509_get_ext_by_NID(cert, NID_subject_alt_name, -1)); - if (ex == NULL) - { - return 0; - } - ASN1_OBJECT *obj = X509_EXTENSION_get_object(ex); - char buff[2048]; - OBJ_obj2txt(buff, 2048, obj, 0); - printf("Extension:%s\n", 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"); - } - 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'; - - //Can print or parse value - char *tok = strtok(buf, ", "); - while (tok !=NULL){ - printf("%s\n", tok); - if (check_if_url_valid(URL, tok+4)){ - BIO_free_all(bio); - free(buf); - return 1; - } - tok = strtok(NULL, ", "); - - } - - BIO_free_all(bio); - free(buf); - - return 0; -} - - - - - - -int check_if_url_valid(char* URL, char* domain){ -if (domain[0] == '*'){ - char* domain_1 = domain+1; - char *sub_url = strstr(URL, domain_1); - - if (sub_url == NULL) - { - return 0; - } - - else{ - return (strcmp(sub_url, domain_1) == 0); - } - -} -else -{ - return (strcmp(URL, domain) == 0); - - -} - -return 0; - - -} -int check_public_key(X509 *cert){ - EVP_PKEY *key = X509_get_pubkey(cert); - RSA *rsa = NULL; - if ((rsa = EVP_PKEY_get1_RSA(key)) == NULL) - { - return 0; - } - if(8*RSA_size(rsa)==2048){ - return 1; - } - return 1; -} \ No newline at end of file diff --git a/headers.h b/headers.h new file mode 100644 index 0000000000000000000000000000000000000000..41777a0ec63460ec64978b2024e4f3bc0b26a757 --- /dev/null +++ b/headers.h @@ -0,0 +1,29 @@ + +#ifndef HEADER +#define HEADER + + +#include <openssl/x509.h> +#include <openssl/x509v3.h> +#include <openssl/bio.h> +#include <openssl/pem.h> +#include <openssl/err.h> +#include <openssl/rsa.h> +#include <openssl/evp.h> +#include <stdio.h> +#include <string.h> + + + +X509 *load_cert(char * filename); +int check_san_valid(X509* cert, char* URL, int in_host); +int check_if_url_valid(char* URL, char* domain); +int check_name_valid(X509* cert, char* URL); +int check_time(X509* cert); +int check_public_key(X509 *cert); +int check_constraint(X509 *cert); +int check_ext_key(X509 *cert); +int validate_certificate(char* filename, char* URL); + + +#endif \ No newline at end of file diff --git a/helper_checker.c b/helper_checker.c index a9d6b9834fb37d894a732906a1a548c3d78c72c4..1e1d09f5c8b89a82861ca387d747ce35f6907a94 100644 --- a/helper_checker.c +++ b/helper_checker.c @@ -1,14 +1,294 @@ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> +#include "headers.h" -int check_if_url_valid(char* URL, char* domain); +int validate_certificate(char* filename, char* URL){ + X509* cert = load_cert(filename); + int in_host = check_name_valid(cert, URL); + if (!check_san_valid(cert, URL, in_host)) + { + printf("SAN \n"); + X509_free(cert); + return 0; + } -int main(int argc, char const *argv[]) + if (!check_time(cert)) + { + printf("time\n"); + X509_free(cert); + return 0; + } + + if (!check_public_key(cert)) + { + printf("PKEY\n"); + X509_free(cert); + return 0; + } + + if (!check_constraint(cert)) + { + printf("CONSTRAINTS\n"); + X509_free(cert); + return 0; + } + + if (!check_ext_key(cert)) + { + printf("ext key\n"); + X509_free(cert); + return 0; + } + + X509_free(cert); + return 1; + +} + +X509 *load_cert(char * filename){ + BIO *certificate_bio = NULL; + X509 *cert = NULL; + X509_CINF *cert_inf = NULL; + STACK_OF(X509_EXTENSION) * ext_list; + + //initialise openSSL + 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()); + + //Read certificate into BIO + if (!(BIO_read_filename(certificate_bio, filename))) + { + fprintf(stderr, "Error in reading cert BIO filename"); + return NULL; + } + if (!(cert = PEM_read_bio_X509(certificate_bio, NULL, 0, NULL))) + { + fprintf(stderr, "Error in loading certificate"); + return NULL; + } + + + BIO_free_all(certificate_bio); + return cert; +} + + + + + +int check_name_valid(X509* cert, char* URL){ + X509_NAME *cert_issuer = X509_get_subject_name(cert); + char subj_cn[256] = "Issuer CN NOT FOUND"; + X509_NAME_get_text_by_NID(cert_issuer, NID_commonName, subj_cn, 256); + if (check_if_url_valid(URL, subj_cn)) + { + return 1; + } + + return 0; +} + + + + + +int check_san_valid(X509* cert, char* URL, int in_host){ + if (in_host){ + return 1; + } + X509_EXTENSION *ex = X509_get_ext(cert, X509_get_ext_by_NID(cert, NID_subject_alt_name, -1)); + if (ex == NULL) + { + return 0; + } + 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"); + } + 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'; + printf("%s\n", buf); + + //Can print or parse value + char *tok = strtok(buf, ", "); + while (tok !=NULL){ + if (check_if_url_valid(URL, tok+4)){ + BIO_free_all(bio); + free(buf); + return 1; + } + tok = strtok(NULL, ", "); + + } + + BIO_free_all(bio); + free(buf); + + return 0; +} + + +int check_if_url_valid(char* URL, char* domain){ +if (domain[0] == '*'){ + char* domain_1 = domain+1; + char *sub_url = strstr(URL, domain_1); + + if (sub_url == NULL) + { + return 0; + } + + else{ + return (strcmp(sub_url, domain_1) == 0); + } + +} +else { - int m = check_if_url_valid("www.google.com.au", "google.com"); - printf("%d\n", m); - return 0; + return (strcmp(URL, domain) == 0); + + +} + +return 0; + + +} + + + + + + + + +int check_time(X509* cert){ + ASN1_TIME *after = X509_get_notAfter(cert); + if (after == NULL) + { + return 0; + } + + int day; + int sec; + + ASN1_TIME_diff(&day, &sec, NULL, after); + + if (day < 0 || sec <0) + { + return 0; + } + + ASN1_TIME *before = X509_get_notBefore(cert); + if (before == NULL) + { + return 0; + } + + + ASN1_TIME_diff(&day, &sec, before, NULL); + + if (day < 0 || sec <0) + { + return 0; + } + + return 1; + + +} + + + + + + +int check_public_key(X509 *cert){ + EVP_PKEY *key = X509_get_pubkey(cert); + RSA *rsa = NULL; + + if ((rsa = EVP_PKEY_get1_RSA(key)) == NULL) + { + return 0; + } + if(8*RSA_size(rsa)==2048){ + return 1; + } + + return 0; +} + + +int check_constraint(X509 *cert){ + X509_EXTENSION *ex = X509_get_ext(cert, X509_get_ext_by_NID(cert, NID_basic_constraints, -1)); + if (ex == NULL) + { + return 0; + } + + 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"); + } + 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'; + + int cond = strcmp(buf, "CA:FALSE"); + BIO_free_all(bio); + free(buf); + + return cond == 0; +} + + +int check_ext_key(X509 *cert){ + X509_EXTENSION *ex = X509_get_ext(cert, X509_get_ext_by_NID(cert, NID_ext_key_usage, -1)); + if (ex == NULL) + { + return 0; + } + 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"); + } + 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'; + + int cond = strcmp(buf, "TLS Web Server Authentication"); + + BIO_free_all(bio); + free(buf); + + return cond == 0; }