From 2213f304490e059d72fd511cd6548b23a685ee8f Mon Sep 17 00:00:00 2001 From: cameronrich Date: Mon, 19 Dec 2016 20:20:01 +0000 Subject: [PATCH] * X509 State, country and location are now used for verification and display. * SNI hostname memory is now managed by the calling application * X509 version number is checked before processing v3 extensions. git-svn-id: svn://svn.code.sf.net/p/axtls/code/trunk@272 9a5d90b5-6617-0410-8a86-bb477d3ed2e3 --- samples/c/axssl.c | 10 -------- ssl/asn1.c | 20 ++++++++++------ ssl/crypto_misc.h | 5 +++- ssl/ssl.h | 18 +++++++++++--- ssl/tls1.c | 35 +++++++++++++++++++-------- ssl/x509.c | 60 +++++++++++++++++++++++++++++++++++++++-------- 6 files changed, 107 insertions(+), 41 deletions(-) diff --git a/samples/c/axssl.c b/samples/c/axssl.c index aaf803440..2bc872a5e 100644 --- a/samples/c/axssl.c +++ b/samples/c/axssl.c @@ -650,7 +650,6 @@ static void do_client(int argc, char *argv[]) } ssl_free(ssl); - ssl_ext_free(extensions); exit(1); } @@ -660,7 +659,6 @@ static void do_client(int argc, char *argv[]) if (reconnect) { ssl_free(ssl); - ssl_ext_free(extensions); SOCKET_CLOSE(client_fd); client_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); @@ -687,13 +685,6 @@ static void do_client(int argc, char *argv[]) if (!quiet) { - const char *common_name = ssl_get_cert_dn(ssl, - SSL_X509_CERT_COMMON_NAME); - if (common_name) - { - printf("Common Name:\t\t\t%s\n", common_name); - } - display_session_id(ssl); display_cipher(ssl); } @@ -766,7 +757,6 @@ static void do_client(int argc, char *argv[]) } ssl_ctx_free(ssl_ctx); - ssl_ext_free(extensions); SOCKET_CLOSE(client_fd); #else print_client_options(argv[1]); diff --git a/ssl/asn1.c b/ssl/asn1.c index 8faefe23a..d2bd88980 100644 --- a/ssl/asn1.c +++ b/ssl/asn1.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007-2015, Cameron Rich + * Copyright (c) 2007-2016, Cameron Rich * * All rights reserved. * @@ -80,8 +80,8 @@ static const uint8_t sig_subject_alt_name[] = 0x55, 0x1d, 0x11 }; -/* CN, O, OU */ -static const uint8_t g_dn_types[] = { 3, 10, 11 }; +/* CN, O, OU, L, C, ST */ +static const uint8_t g_dn_types[] = { 3, 10, 11, 7, 6, 8 }; uint32_t get_asn1_length(const uint8_t *buf, int *offset) { @@ -300,13 +300,19 @@ static int asn1_get_utc_time(const uint8_t *buf, int *offset, time_t *t) int asn1_version(const uint8_t *cert, int *offset, X509_CTX *x509_ctx) { int ret = X509_NOT_OK; + int len; (*offset) += 2; /* get past explicit tag */ - if (asn1_skip_obj(cert, offset, ASN1_INTEGER)) - goto end_version; + if (cert[(*offset)++] != ASN1_INTEGER) + return X509_NOT_OK; - ret = X509_OK; -end_version: + len = get_asn1_length(cert, offset); + if (len == 1) + { + ret = cert[*offset]; + } + + *offset += len; return ret; } diff --git a/ssl/crypto_misc.h b/ssl/crypto_misc.h index d66839755..34593fdae 100644 --- a/ssl/crypto_misc.h +++ b/ssl/crypto_misc.h @@ -60,10 +60,13 @@ extern "C" { /* * The Distinguished Name */ -#define X509_NUM_DN_TYPES 3 +#define X509_NUM_DN_TYPES 6 #define X509_COMMON_NAME 0 #define X509_ORGANIZATION 1 #define X509_ORGANIZATIONAL_UNIT 2 +#define X509_LOCATION 3 +#define X509_COUNTRY 4 +#define X509_STATE 5 struct _x509_ctx { diff --git a/ssl/ssl.h b/ssl/ssl.h index 71f92f0f5..df4fed9bc 100644 --- a/ssl/ssl.h +++ b/ssl/ssl.h @@ -159,9 +159,15 @@ extern "C" { #define SSL_X509_CERT_COMMON_NAME 0 #define SSL_X509_CERT_ORGANIZATION 1 #define SSL_X509_CERT_ORGANIZATIONAL_NAME 2 -#define SSL_X509_CA_CERT_COMMON_NAME 3 -#define SSL_X509_CA_CERT_ORGANIZATION 4 -#define SSL_X509_CA_CERT_ORGANIZATIONAL_NAME 5 +#define SSL_X509_CERT_LOCATION 3 +#define SSL_X509_CERT_COUNTRY 4 +#define SSL_X509_CERT_STATE 5 +#define SSL_X509_CA_CERT_COMMON_NAME 6 +#define SSL_X509_CA_CERT_ORGANIZATION 7 +#define SSL_X509_CA_CERT_ORGANIZATIONAL_NAME 8 +#define SSL_X509_CA_CERT_LOCATION 9 +#define SSL_X509_CA_CERT_COUNTRY 10 +#define SSL_X509_CA_CERT_STATE 11 /* SSL object loader types */ #define SSL_OBJ_X509_CERT 1 @@ -454,9 +460,15 @@ EXP_FUNC int STDCALL ssl_match_spki_sha256(const SSL *ssl, const uint8_t* hash); * - SSL_X509_CERT_COMMON_NAME * - SSL_X509_CERT_ORGANIZATION * - SSL_X509_CERT_ORGANIZATIONAL_NAME + * - SSL_X509_CERT_LOCATION + * - SSL_X509_CERT_COUNTRY + * - SSL_X509_CERT_STATE * - SSL_X509_CA_CERT_COMMON_NAME * - SSL_X509_CA_CERT_ORGANIZATION * - SSL_X509_CA_CERT_ORGANIZATIONAL_NAME + * - SSL_X509_CA_CERT_LOCATION + * - SSL_X509_CA_CERT_COUNTRY + * - SSL_X509_CA_CERT_STATE * @return The appropriate string (or null if not defined) * @note Verification build mode must be enabled. */ diff --git a/ssl/tls1.c b/ssl/tls1.c index b8a813bc5..5257cbda6 100644 --- a/ssl/tls1.c +++ b/ssl/tls1.c @@ -145,11 +145,7 @@ void DISPLAY_BYTES(SSL *ssl, const char *format, */ EXP_FUNC SSL_EXTENSIONS * STDCALL ssl_ext_new() { - SSL_EXTENSIONS *ssl_ext = (SSL_EXTENSIONS *)malloc(sizeof(SSL_EXTENSIONS)); - ssl_ext->max_fragment_size = 0; - ssl_ext->host_name = NULL; - - return ssl_ext; + return (SSL_EXTENSIONS *)calloc(1, sizeof(SSL_EXTENSIONS)); } /** @@ -163,10 +159,6 @@ EXP_FUNC void STDCALL ssl_ext_free(SSL_EXTENSIONS *ssl_ext) return; } - if (ssl_ext->host_name != NULL) - { - free(ssl_ext->host_name); - } free(ssl_ext); } @@ -530,6 +522,15 @@ EXP_FUNC const char * STDCALL ssl_get_cert_dn(const SSL *ssl, int component) case SSL_X509_CERT_ORGANIZATIONAL_NAME: return ssl->x509_ctx->cert_dn[X509_ORGANIZATIONAL_UNIT]; + case SSL_X509_CERT_LOCATION: + return ssl->x509_ctx->cert_dn[X509_LOCATION]; + + case SSL_X509_CERT_COUNTRY: + return ssl->x509_ctx->cert_dn[X509_COUNTRY]; + + case SSL_X509_CERT_STATE: + return ssl->x509_ctx->cert_dn[X509_STATE]; + case SSL_X509_CA_CERT_COMMON_NAME: return ssl->x509_ctx->ca_cert_dn[X509_COMMON_NAME]; @@ -539,6 +540,15 @@ EXP_FUNC const char * STDCALL ssl_get_cert_dn(const SSL *ssl, int component) case SSL_X509_CA_CERT_ORGANIZATIONAL_NAME: return ssl->x509_ctx->ca_cert_dn[X509_ORGANIZATIONAL_UNIT]; + case SSL_X509_CA_CERT_LOCATION: + return ssl->x509_ctx->ca_cert_dn[X509_LOCATION]; + + case SSL_X509_CA_CERT_COUNTRY: + return ssl->x509_ctx->ca_cert_dn[X509_COUNTRY]; + + case SSL_X509_CA_CERT_STATE: + return ssl->x509_ctx->ca_cert_dn[X509_STATE]; + default: return NULL; } @@ -1393,7 +1403,7 @@ int basic_read(SSL *ssl, uint8_t **in_data) if (IS_SET_SSL_FLAG(SSL_NEED_RECORD)) { /* check for sslv2 "client hello" */ - if (buf[0] & 0x80 && buf[2] == 1) + if ((buf[0] & 0x80) && buf[2] == 1) { #ifdef CONFIG_SSL_FULL_MODE printf("Error: no SSLv23 handshaking allowed\n"); @@ -2149,6 +2159,10 @@ int process_certificate(SSL *ssl, X509_CTX **x509_ctx) goto error; } +#if defined (CONFIG_SSL_FULL_MODE) + if (ssl->ssl_ctx->options & SSL_DISPLAY_CERTS) + x509_print(certs[num_certs], NULL); +#endif num_certs++; offset += cert_size; } @@ -2168,6 +2182,7 @@ int process_certificate(SSL *ssl, X509_CTX **x509_ctx) { if (certs[i] == chain) continue; + if (cert_used[i]) continue; // don't allow loops diff --git a/ssl/x509.c b/ssl/x509.c index 35bd7281e..3d1541461 100644 --- a/ssl/x509.c +++ b/ssl/x509.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007-2015, Cameron Rich + * Copyright (c) 2007-2016, Cameron Rich * * All rights reserved. * @@ -73,6 +73,7 @@ int x509_new(const uint8_t *cert, int *len, X509_CTX **ctx) { int begin_tbs, end_tbs, begin_spki, end_spki; int ret = X509_NOT_OK, offset = 0, cert_size = 0; + int version = 0; X509_CTX *x509_ctx; #ifdef CONFIG_SSL_CERT_VERIFICATION /* only care if doing verification */ BI_CTX *bi_ctx; @@ -96,7 +97,7 @@ int x509_new(const uint8_t *cert, int *len, X509_CTX **ctx) if (cert[offset] == ASN1_EXPLICIT_TAG) /* optional version */ { - if (asn1_version(cert, &offset, x509_ctx)) + if ((version = asn1_version(cert, &offset, x509_ctx)) == X509_NOT_OK) goto end_cert; } @@ -122,7 +123,6 @@ int x509_new(const uint8_t *cert, int *len, X509_CTX **ctx) goto end_cert; end_spki = offset; - x509_ctx->fingerprint = malloc(SHA1_SIZE); SHA1_CTX sha_fp_ctx; SHA1_Init(&sha_fp_ctx); @@ -197,7 +197,7 @@ int x509_new(const uint8_t *cert, int *len, X509_CTX **ctx) break; } - if (cert[offset] == ASN1_V3_DATA) + if (version == 2 && cert[offset] == ASN1_V3_DATA) { int suboffset; @@ -518,9 +518,29 @@ void x509_print(const X509_CTX *cert, CA_CERT_CTX *ca_cert_ctx) printf("%s\n", cert->cert_dn[X509_ORGANIZATION] ? cert->cert_dn[X509_ORGANIZATION] : not_part_of_cert); - printf("Organizational Unit (OU):\t"); - printf("%s\n", cert->cert_dn[X509_ORGANIZATIONAL_UNIT] ? - cert->cert_dn[X509_ORGANIZATIONAL_UNIT] : not_part_of_cert); + if (cert->cert_dn[X509_ORGANIZATIONAL_UNIT]) + { + printf("Organizational Unit (OU):\t"); + printf("%s\n", cert->cert_dn[X509_ORGANIZATIONAL_UNIT]); + } + + if (cert->cert_dn[X509_LOCATION]) + { + printf("Location (L):\t\t\t"); + printf("%s\n", cert->cert_dn[X509_LOCATION]); + } + + if (cert->cert_dn[X509_COUNTRY]) + { + printf("Country (C):\t\t\t"); + printf("%s\n", cert->cert_dn[X509_COUNTRY]); + } + + if (cert->cert_dn[X509_STATE]) + { + printf("State (ST):\t\t\t"); + printf("%s\n", cert->cert_dn[X509_STATE]); + } printf("=== CERTIFICATE ISSUED BY ===\n"); printf("Common Name (CN):\t\t"); @@ -531,9 +551,29 @@ void x509_print(const X509_CTX *cert, CA_CERT_CTX *ca_cert_ctx) printf("%s\n", cert->ca_cert_dn[X509_ORGANIZATION] ? cert->ca_cert_dn[X509_ORGANIZATION] : not_part_of_cert); - printf("Organizational Unit (OU):\t"); - printf("%s\n", cert->ca_cert_dn[X509_ORGANIZATIONAL_UNIT] ? - cert->ca_cert_dn[X509_ORGANIZATIONAL_UNIT] : not_part_of_cert); + if (cert->ca_cert_dn[X509_ORGANIZATIONAL_UNIT]) + { + printf("Organizational Unit (OU):\t"); + printf("%s\n", cert->ca_cert_dn[X509_ORGANIZATIONAL_UNIT]); + } + + if (cert->ca_cert_dn[X509_LOCATION]) + { + printf("Location (L):\t\t\t"); + printf("%s\n", cert->ca_cert_dn[X509_LOCATION]); + } + + if (cert->ca_cert_dn[X509_COUNTRY]) + { + printf("Country (C):\t\t\t"); + printf("%s\n", cert->ca_cert_dn[X509_COUNTRY]); + } + + if (cert->ca_cert_dn[X509_STATE]) + { + printf("State (ST):\t\t\t"); + printf("%s\n", cert->ca_cert_dn[X509_STATE]); + } printf("Not Before:\t\t\t%s", ctime(&cert->not_before)); printf("Not After:\t\t\t%s", ctime(&cert->not_after));