From 63da8991c2878f2a7cd526667f9e23adc9dca1c9 Mon Sep 17 00:00:00 2001 From: Slavey Karadzhov Date: Fri, 19 Feb 2016 11:41:45 +0100 Subject: [PATCH 1/2] Added SNI ( https://en.wikipedia.org/wiki/Server_Name_Indication ) support. --- ssl/ssl.h | 10 ++++++++++ ssl/tls1.c | 13 +++++++++++++ ssl/tls1.h | 1 + ssl/tls1_clnt.c | 20 ++++++++++++++++++++ 4 files changed, 44 insertions(+) diff --git a/ssl/ssl.h b/ssl/ssl.h index 97e87d495..c39f921f5 100644 --- a/ssl/ssl.h +++ b/ssl/ssl.h @@ -352,6 +352,16 @@ EXP_FUNC int STDCALL ssl_handshake_status(const SSL *ssl); */ EXP_FUNC int STDCALL ssl_get_config(int offset); +/** + * @brief Sets the hostname to be used for SNI + * @see https://en.wikipedia.org/wiki/Server_Name_Indication + * @param char* hostname + * @return success from the operation + * - 1 on success + * - 0 on failure + */ +EXP_FUNC int STDCALL ssl_set_hostname(const SSL *ssl, const char* host_name); + /** * @brief Display why the handshake failed. * diff --git a/ssl/tls1.c b/ssl/tls1.c index c4a676b10..a1783bf46 100644 --- a/ssl/tls1.c +++ b/ssl/tls1.c @@ -1849,6 +1849,19 @@ EXP_FUNC int STDCALL ssl_get_config(int offset) } } +/** + * Sets the SNI hostname + */ +EXP_FUNC int STDCALL ssl_set_hostname(const SSL *ssl, const char* host_name) { + if(host_name == NULL || strlen(host_name) == 0 || strlen(host_name) > 255 ) { + return 0; + } + + strncpy((char*)&ssl->host_name, host_name, strlen(host_name)); + + return 1; +} + #ifdef CONFIG_SSL_CERT_VERIFICATION /** * Authenticate a received certificate. diff --git a/ssl/tls1.h b/ssl/tls1.h index b7cd7f36e..d5440aa6c 100644 --- a/ssl/tls1.h +++ b/ssl/tls1.h @@ -198,6 +198,7 @@ struct _SSL uint8_t read_sequence[8]; /* 64 bit sequence number */ uint8_t write_sequence[8]; /* 64 bit sequence number */ uint8_t hmac_header[SSL_RECORD_SIZE]; /* rx hmac */ + const char host_name[255]; /* Needed for the SNI support */ }; typedef struct _SSL SSL; diff --git a/ssl/tls1_clnt.c b/ssl/tls1_clnt.c index 5f2598922..5eee5713a 100644 --- a/ssl/tls1_clnt.c +++ b/ssl/tls1_clnt.c @@ -220,6 +220,26 @@ static int send_client_hello(SSL *ssl) buf[offset++] = 1; /* no compression */ buf[offset++] = 0; + + if (ssl->host_name[0] != 0) { + unsigned int host_len = strnlen((char*) ssl->host_name, 255); + + buf[offset++] = 0; + buf[offset++] = host_len+9; /* extensions length */ + + buf[offset++] = 0; + buf[offset++] = 0; /* server_name(0) (65535) */ + buf[offset++] = 0; + buf[offset++] = host_len+5; /* server_name length */ + buf[offset++] = 0; + buf[offset++] = host_len+3; /* server_list length */ + buf[offset++] = 0; /* host_name(0) (255) */ + buf[offset++] = 0; + buf[offset++] = host_len; /* host_name length */ + strncpy((char*) &buf[offset], ssl->host_name, host_len); + offset += host_len; + } + buf[3] = offset - 4; /* handshake size */ return send_packet(ssl, PT_HANDSHAKE_PROTOCOL, NULL, offset); From 1154d0a985cc442f39f5e6b3678a7d4ffca5db31 Mon Sep 17 00:00:00 2001 From: Slavey Karadzhov Date: Mon, 22 Feb 2016 10:02:40 +0100 Subject: [PATCH 2/2] Changed the code to reserve bytes for hostname only if needed. --- ssl/ssl.h | 2 +- ssl/tls1.c | 24 ++++++++++++++++++------ ssl/tls1.h | 2 +- ssl/tls1_clnt.c | 30 +++++++++++++++--------------- 4 files changed, 35 insertions(+), 23 deletions(-) diff --git a/ssl/ssl.h b/ssl/ssl.h index c39f921f5..b287d5aa8 100644 --- a/ssl/ssl.h +++ b/ssl/ssl.h @@ -360,7 +360,7 @@ EXP_FUNC int STDCALL ssl_get_config(int offset); * - 1 on success * - 0 on failure */ -EXP_FUNC int STDCALL ssl_set_hostname(const SSL *ssl, const char* host_name); +EXP_FUNC int STDCALL ssl_set_hostname(SSL *ssl, const char* host_name); /** * @brief Display why the handshake failed. diff --git a/ssl/tls1.c b/ssl/tls1.c index a1783bf46..195cb0196 100644 --- a/ssl/tls1.c +++ b/ssl/tls1.c @@ -568,6 +568,8 @@ SSL *ssl_new(SSL_CTX *ssl_ctx, int client_fd) ssl->encrypt_ctx = malloc(sizeof(AES_CTX)); ssl->decrypt_ctx = malloc(sizeof(AES_CTX)); + ssl->host_name = NULL; + SSL_CTX_UNLOCK(ssl_ctx->mutex); return ssl; } @@ -1852,14 +1854,24 @@ EXP_FUNC int STDCALL ssl_get_config(int offset) /** * Sets the SNI hostname */ -EXP_FUNC int STDCALL ssl_set_hostname(const SSL *ssl, const char* host_name) { - if(host_name == NULL || strlen(host_name) == 0 || strlen(host_name) > 255 ) { - return 0; - } +EXP_FUNC int STDCALL ssl_set_hostname(SSL *ssl, const char* host_name) { + if(host_name == NULL || strlen(host_name) == 0 || strlen(host_name) > 255 ) { + return 0; + } - strncpy((char*)&ssl->host_name, host_name, strlen(host_name)); + if(ssl->host_name != NULL) { + free(ssl->host_name); + } - return 1; + ssl->host_name = (char *)malloc(strlen(host_name)+1); + if(ssl->host_name == NULL) { + // most probably there was no memory available + return 0; + } + + strcpy(ssl->host_name, host_name); + + return 1; } #ifdef CONFIG_SSL_CERT_VERIFICATION diff --git a/ssl/tls1.h b/ssl/tls1.h index d5440aa6c..c53ce6da0 100644 --- a/ssl/tls1.h +++ b/ssl/tls1.h @@ -198,7 +198,7 @@ struct _SSL uint8_t read_sequence[8]; /* 64 bit sequence number */ uint8_t write_sequence[8]; /* 64 bit sequence number */ uint8_t hmac_header[SSL_RECORD_SIZE]; /* rx hmac */ - const char host_name[255]; /* Needed for the SNI support */ + char *host_name; /* Needed for the SNI support */ }; typedef struct _SSL SSL; diff --git a/ssl/tls1_clnt.c b/ssl/tls1_clnt.c index 5eee5713a..b84877da7 100644 --- a/ssl/tls1_clnt.c +++ b/ssl/tls1_clnt.c @@ -221,23 +221,23 @@ static int send_client_hello(SSL *ssl) buf[offset++] = 1; /* no compression */ buf[offset++] = 0; - if (ssl->host_name[0] != 0) { - unsigned int host_len = strnlen((char*) ssl->host_name, 255); + if (ssl->host_name != NULL) { + unsigned int host_len = strlen(ssl->host_name); - buf[offset++] = 0; - buf[offset++] = host_len+9; /* extensions length */ + buf[offset++] = 0; + buf[offset++] = host_len+9; /* extensions length */ - buf[offset++] = 0; - buf[offset++] = 0; /* server_name(0) (65535) */ - buf[offset++] = 0; - buf[offset++] = host_len+5; /* server_name length */ - buf[offset++] = 0; - buf[offset++] = host_len+3; /* server_list length */ - buf[offset++] = 0; /* host_name(0) (255) */ - buf[offset++] = 0; - buf[offset++] = host_len; /* host_name length */ - strncpy((char*) &buf[offset], ssl->host_name, host_len); - offset += host_len; + buf[offset++] = 0; + buf[offset++] = 0; /* server_name(0) (65535) */ + buf[offset++] = 0; + buf[offset++] = host_len+5; /* server_name length */ + buf[offset++] = 0; + buf[offset++] = host_len+3; /* server_list length */ + buf[offset++] = 0; /* host_name(0) (255) */ + buf[offset++] = 0; + buf[offset++] = host_len; /* host_name length */ + strncpy((char*) &buf[offset], ssl->host_name, host_len); + offset += host_len; } buf[3] = offset - 4; /* handshake size */