From 5c665fe614c9d20f54e4b88958b8ad9cb27770d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Moise=CC=81s=20Guimara=CC=83es?= Date: Thu, 30 May 2013 15:22:38 -0300 Subject: [PATCH] Added options to SNI (now it is possible to choose whether or not to abort on a SNI Host Name mismatch) Exposed SNI Type at ssl.h --- cyassl/internal.h | 18 +++++++++++------- cyassl/ssl.h | 17 +++++++++++++++++ examples/server/server.c | 9 +++++++-- src/ssl.c | 15 +++++++++++++++ src/tls.c | 35 ++++++++++++++++++++++++----------- 5 files changed, 74 insertions(+), 20 deletions(-) diff --git a/cyassl/internal.h b/cyassl/internal.h index 89f34b5a6..f53733d83 100644 --- a/cyassl/internal.h +++ b/cyassl/internal.h @@ -1151,19 +1151,23 @@ CYASSL_LOCAL int TLSX_Parse(CYASSL* ssl, byte* input, word16 length, /* Server Name Indication */ #ifdef HAVE_SNI -typedef enum { - HOST_NAME = 0 -} SNI_Type; - typedef struct SNI { - SNI_Type type; /* SNI Type */ - union { char* host_name; } data; /* SNI Data */ - struct SNI* next; /* List Behavior */ + byte type; /* SNI Type */ + union { char* host_name; } data; /* SNI Data */ + struct SNI* next; /* List Behavior */ +#ifndef NO_CYASSL_SERVER + byte options; /* Behaviour options */ +#endif } SNI; CYASSL_LOCAL int TLSX_UseSNI(TLSX** extensions, byte type, const void* data, word16 size); +#ifndef NO_CYASSL_SERVER +CYASSL_LOCAL void TLSX_SNI_SetOptions(TLSX* extensions, byte type, + byte options); +#endif + #endif /* HAVE_SNI */ #endif /* HAVE_TLS_EXTENSIONS */ diff --git a/cyassl/ssl.h b/cyassl/ssl.h index 338564950..85807ace3 100644 --- a/cyassl/ssl.h +++ b/cyassl/ssl.h @@ -931,10 +931,27 @@ CYASSL_API int CyaSSL_CTX_UseCavium(CYASSL_CTX*, int devId); /* tls extensions */ #ifdef HAVE_SNI +/* SNI types */ +enum { + CYASSL_SNI_HOST_NAME = 0 +}; + CYASSL_API int CyaSSL_UseSNI(CYASSL* ssl, unsigned char type, const void* data, unsigned short size); CYASSL_API int CyaSSL_CTX_UseSNI(CYASSL_CTX* ctx, unsigned char type, const void* data, unsigned short size); + +#ifndef NO_CYASSL_SERVER +/* SNI options */ +enum { + CYASSL_SNI_ABORT_ON_MISMATCH = 0x01 +}; + +CYASSL_API void CyaSSL_SNI_SetOptions(CYASSL* ssl, unsigned char type, + unsigned char options); +CYASSL_API void CyaSSL_CTX_SNI_SetOptions(CYASSL_CTX* ctx, unsigned char type, + unsigned char options); +#endif #endif #define CYASSL_CRL_MONITOR 0x01 /* monitor this dir flag */ diff --git a/examples/server/server.c b/examples/server/server.c index da6fccf45..ffa29bc08 100644 --- a/examples/server/server.c +++ b/examples/server/server.c @@ -408,9 +408,14 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args) #endif #ifdef HAVE_SNI - if (sniHostName) - if (CyaSSL_CTX_UseSNI(ctx, 0, sniHostName, XSTRLEN(sniHostName))) + if (sniHostName) { + if (CyaSSL_CTX_UseSNI(ctx, CYASSL_SNI_HOST_NAME, sniHostName, + XSTRLEN(sniHostName))) err_sys("UseSNI failed"); + else + CyaSSL_CTX_SNI_SetOptions(ctx, CYASSL_SNI_HOST_NAME, + CYASSL_SNI_ABORT_ON_MISMATCH); + } #endif ssl = SSL_new(ctx); diff --git a/src/ssl.c b/src/ssl.c index aaf384066..7b9cb1f64 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -529,6 +529,21 @@ int CyaSSL_CTX_UseSNI(CYASSL_CTX* ctx, unsigned char type, const void* data, return TLSX_UseSNI(&ctx->extensions, type, data, size); } +#ifndef NO_CYASSL_SERVER +void CyaSSL_SNI_SetOptions(CYASSL* ssl, unsigned char type, + unsigned char options) +{ + if (ssl && ssl->extensions) + TLSX_SNI_SetOptions(ssl->extensions, type, options); +} +void CyaSSL_CTX_SNI_SetOptions(CYASSL_CTX* ctx, unsigned char type, + unsigned char options) +{ + if (ctx && ctx->extensions) + TLSX_SNI_SetOptions(ctx->extensions, type, options); +} +#endif + #endif /* HAVE_SNI */ #ifndef CYASSL_LEANPSK diff --git a/src/tls.c b/src/tls.c index 2776b5e86..8cc4d3098 100644 --- a/src/tls.c +++ b/src/tls.c @@ -531,7 +531,7 @@ static void TLSX_SNI_Free(SNI* sni) { if (sni) { switch (sni->type) { - case HOST_NAME: + case CYASSL_SNI_HOST_NAME: XFREE(sni->data.host_name, 0, DYNAMIC_TYPE_TLSX); break; } @@ -550,8 +550,7 @@ static void TLSX_SNI_FreeAll(SNI* list) } } -static int TLSX_SNI_Append(SNI** list, SNI_Type type, const void* data, - word16 size) +static int TLSX_SNI_Append(SNI** list, byte type, const void* data, word16 size) { SNI* sni; @@ -562,7 +561,7 @@ static int TLSX_SNI_Append(SNI** list, SNI_Type type, const void* data, return MEMORY_E; switch (type) { - case HOST_NAME: { + case CYASSL_SNI_HOST_NAME: { sni->data.host_name = XMALLOC(size + 1, 0, DYNAMIC_TYPE_TLSX); if (sni->data.host_name) { @@ -583,6 +582,7 @@ static int TLSX_SNI_Append(SNI** list, SNI_Type type, const void* data, sni->type = type; sni->next = *list; + sni->options = 0; *list = sni; return 0; @@ -599,7 +599,7 @@ static word16 TLSX_SNI_GetSize(SNI* list) length += ENUM_LEN + OPAQUE16_LEN; /* sni type + sni length */ switch (sni->type) { - case HOST_NAME: + case CYASSL_SNI_HOST_NAME: length += XSTRLEN((char*) sni->data.host_name); break; } @@ -620,7 +620,7 @@ static word16 TLSX_SNI_Write(SNI* list, byte* output) output[offset++] = sni->type; /* sni type */ switch (sni->type) { - case HOST_NAME: + case CYASSL_SNI_HOST_NAME: length = XSTRLEN((char*) sni->data.host_name); c16toa(length, output + offset); /* sni length */ @@ -638,7 +638,7 @@ static word16 TLSX_SNI_Write(SNI* list, byte* output) return offset; } -static SNI* TLSX_SNI_Find(SNI *list, SNI_Type type) +static SNI* TLSX_SNI_Find(SNI *list, byte type) { SNI *sni = list; @@ -691,7 +691,7 @@ static int TLSX_SNI_Parse(CYASSL* ssl, byte* input, word16 length, for (size = 0; offset < length; offset += size) { SNI *sni; - SNI_Type type = input[offset++]; + byte type = input[offset++]; if (offset + OPAQUE16_LEN > length) return INCOMPLETE_DATA; @@ -707,9 +707,11 @@ static int TLSX_SNI_Parse(CYASSL* ssl, byte* input, word16 length, } switch(type) { - case HOST_NAME: - if (XSTRNCMP(sni->data.host_name, - (const char *) input + offset, size)) { + case CYASSL_SNI_HOST_NAME: + if ((sni->options & CYASSL_SNI_ABORT_ON_MISMATCH) + && ((XSTRLEN(sni->data.host_name) != size) + || XSTRNCMP(sni->data.host_name, + (const char *) input + offset, size))) { SendAlert(ssl, alert_fatal, unrecognized_name); return UNKNOWN_SNI_HOST_NAME_E; @@ -776,6 +778,17 @@ int TLSX_UseSNI(TLSX** extensions, byte type, const void* data, word16 size) return 0; } +#ifndef NO_CYASSL_SERVER +void TLSX_SNI_SetOptions(TLSX* extensions, byte type, byte options) +{ + TLSX* extension = TLSX_Find(extensions, SERVER_NAME_INDICATION); + SNI* sni = TLSX_SNI_Find(extension ? extension->data : NULL, type); + + if (sni) + sni->options = options; +} +#endif + #define SNI_FREE_ALL TLSX_SNI_FreeAll #define SNI_GET_SIZE TLSX_SNI_GetSize #define SNI_WRITE TLSX_SNI_Write