adds unsupported_extension behavior to SNI

This commit is contained in:
Moisés Guimarães
2017-10-24 13:19:39 -03:00
parent 8f687e9905
commit 0dd2ba2d80
4 changed files with 44 additions and 22 deletions

View File

@ -14487,6 +14487,9 @@ const char* wolfSSL_ERR_reason_error_string(unsigned long e)
case INVALID_PARAMETER: case INVALID_PARAMETER:
return "The security parameter is invalid"; return "The security parameter is invalid";
case UNSUPPORTED_EXTENSION:
return "TLS Extension not requested by the client";
case KEY_SHARE_ERROR: case KEY_SHARE_ERROR:
return "Key share extension did not contain a valid named group"; return "Key share extension did not contain a valid named group";

View File

@ -952,8 +952,9 @@ static int TLSX_Push(TLSX** list, TLSX_Type type, void* data, void* heap)
TLSX_FreeAll(next, heap); TLSX_FreeAll(next, heap);
/* there is no way to occur more than */ /* there is no way to occur more than
/* two extensions of the same type. */ * two extensions of the same type.
*/
break; break;
} }
} while ((extension = extension->next)); } while ((extension = extension->next));
@ -968,10 +969,10 @@ void TLSX_SetResponse(WOLFSSL* ssl, TLSX_Type type);
void TLSX_SetResponse(WOLFSSL* ssl, TLSX_Type type) void TLSX_SetResponse(WOLFSSL* ssl, TLSX_Type type)
{ {
TLSX *ext = TLSX_Find(ssl->extensions, type); TLSX *extension = TLSX_Find(ssl->extensions, type);
if (ext) if (extension)
ext->resp = 1; extension->resp = 1;
} }
#endif #endif
@ -1480,7 +1481,7 @@ static word16 TLSX_SNI_Write(SNI* list, byte* output)
/** Finds a SNI object in the provided list. */ /** Finds a SNI object in the provided list. */
static SNI* TLSX_SNI_Find(SNI *list, byte type) static SNI* TLSX_SNI_Find(SNI *list, byte type)
{ {
SNI *sni = list; SNI* sni = list;
while (sni && sni->type != type) while (sni && sni->type != type)
sni = sni->next; sni = sni->next;
@ -1532,16 +1533,30 @@ static int TLSX_SNI_Parse(WOLFSSL* ssl, byte* input, word16 length,
(void)input; (void)input;
if (!extension || !extension->data) { if (!extension || !extension->data) {
/* server_side */
if (isRequest) {
#if defined(WOLFSSL_ALWAYS_KEEP_SNI) && !defined(NO_WOLFSSL_SERVER) #if defined(WOLFSSL_ALWAYS_KEEP_SNI) && !defined(NO_WOLFSSL_SERVER)
/* This will keep SNI even though TLSX_UseSNI has not been called. /* This will keep SNI even though TLSX_UseSNI has not been called.
* Enable it so that the received sni is available to functions * Enable it so that the received sni is available to functions
* that use a custom callback when SNI is received */ * that use a custom callback when SNI is received.
cacheOnly = 1; */
WOLFSSL_MSG("Forcing SSL object to store SNI parameter");
cacheOnly = 1;
WOLFSSL_MSG("Forcing SSL object to store SNI parameter");
#else #else
return isRequest ? 0 /* not using SNI. */ /* Skipping, SNI not enabled at server side. */
: BUFFER_ERROR; /* unexpected SNI response. */ return 0;
#endif #endif
}
/* client_side */
else {
#ifdef WOLFSSL_SKIP_UNEXPECTED_TLSX
return 0;
#else
SendAlert(ssl, alert_fatal, unsupported_extension);
return UNSUPPORTED_EXTENSION;
#endif
}
} }
if (!isRequest) if (!isRequest)
@ -1587,9 +1602,9 @@ static int TLSX_SNI_Parse(WOLFSSL* ssl, byte* input, word16 length,
break; break;
#endif #endif
byte matched = cacheOnly || byte matched = cacheOnly ||
((XSTRLEN(sni->data.host_name) == size) ((XSTRLEN(sni->data.host_name) == size) &&
&& (XSTRNCMP(sni->data.host_name, (XSTRNCMP(sni->data.host_name,
(const char*)input + offset, size) == 0)); (const char*)input + offset, size) == 0));
if (matched || sni->options & WOLFSSL_SNI_ANSWER_ON_MISMATCH) { if (matched || sni->options & WOLFSSL_SNI_ANSWER_ON_MISMATCH) {
int r = TLSX_UseSNI(&ssl->extensions, int r = TLSX_UseSNI(&ssl->extensions,
@ -1678,7 +1693,7 @@ int TLSX_UseSNI(TLSX** extensions, byte type, const void* data, word16 size,
void* heap) void* heap)
{ {
TLSX* extension; TLSX* extension;
SNI* sni = NULL; SNI* sni = NULL;
if (extensions == NULL || data == NULL) if (extensions == NULL || data == NULL)
return BAD_FUNC_ARG; return BAD_FUNC_ARG;
@ -1689,6 +1704,7 @@ int TLSX_UseSNI(TLSX** extensions, byte type, const void* data, word16 size,
extension = TLSX_Find(*extensions, TLSX_SERVER_NAME); extension = TLSX_Find(*extensions, TLSX_SERVER_NAME);
if (!extension) { if (!extension) {
int ret = TLSX_Push(extensions, TLSX_SERVER_NAME, (void*)sni, heap); int ret = TLSX_Push(extensions, TLSX_SERVER_NAME, (void*)sni, heap);
if (ret != 0) { if (ret != 0) {
TLSX_SNI_Free(sni, heap); TLSX_SNI_Free(sni, heap);
return ret; return ret;
@ -1702,13 +1718,14 @@ int TLSX_UseSNI(TLSX** extensions, byte type, const void* data, word16 size,
/* remove duplicate SNI, there should be only one of each type. */ /* remove duplicate SNI, there should be only one of each type. */
do { do {
if (sni->next && sni->next->type == type) { if (sni->next && sni->next->type == type) {
SNI *next = sni->next; SNI* next = sni->next;
sni->next = next->next; sni->next = next->next;
TLSX_SNI_Free(next, heap); TLSX_SNI_Free(next, heap);
/* there is no way to occur more than */ /* there is no way to occur more than
/* two SNIs of the same type. */ * two SNIs of the same type.
*/
break; break;
} }
} while ((sni = sni->next)); } while ((sni = sni->next));
@ -1753,8 +1770,8 @@ int TLSX_SNI_GetFromBuffer(const byte* clientHello, word32 helloSz,
byte type, byte* sni, word32* inOutSz) byte type, byte* sni, word32* inOutSz)
{ {
word32 offset = 0; word32 offset = 0;
word32 len32 = 0; word32 len32 = 0;
word16 len16 = 0; word16 len16 = 0;
if (helloSz < RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ + CLIENT_HELLO_FIRST) if (helloSz < RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ + CLIENT_HELLO_FIRST)
return INCOMPLETE_DATA; return INCOMPLETE_DATA;

View File

@ -164,6 +164,7 @@ enum wolfSSL_ErrorCodes {
MCAST_HIGHWATER_CB_E = -426, /* Multicast highwater cb err */ MCAST_HIGHWATER_CB_E = -426, /* Multicast highwater cb err */
ALERT_COUNT_E = -427, /* Alert Count exceeded err */ ALERT_COUNT_E = -427, /* Alert Count exceeded err */
EXT_MISSING = -428, /* Required extension not found */ EXT_MISSING = -428, /* Required extension not found */
UNSUPPORTED_EXTENSION = -429, /* TLSX not requested by client */
/* add strings to wolfSSL_ERR_reason_error_string in internal.c !!!!! */ /* add strings to wolfSSL_ERR_reason_error_string in internal.c !!!!! */
/* begin negotiation parameter errors */ /* begin negotiation parameter errors */

View File

@ -301,6 +301,7 @@ enum AlertDescription {
protocol_version = 70, protocol_version = 70,
#endif #endif
no_renegotiation = 100, no_renegotiation = 100,
unsupported_extension = 110, /**< RFC 5246, section 7.2.2 */
unrecognized_name = 112, /**< RFC 6066, section 3 */ unrecognized_name = 112, /**< RFC 6066, section 3 */
bad_certificate_status_response = 113, /**< RFC 6066, section 8 */ bad_certificate_status_response = 113, /**< RFC 6066, section 8 */
no_application_protocol = 120 no_application_protocol = 120