mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-08-02 20:24:39 +02:00
Merge pull request #2310 from SparkiDev/alpn_sni_parse
ALPN and SNI Extension parsing improvements
This commit is contained in:
58
src/tls.c
58
src/tls.c
@@ -1530,6 +1530,9 @@ static int TLSX_ALPN_ParseAndSet(WOLFSSL *ssl, byte *input, word16 length,
|
|||||||
ato16(input, &size);
|
ato16(input, &size);
|
||||||
offset += OPAQUE16_LEN;
|
offset += OPAQUE16_LEN;
|
||||||
|
|
||||||
|
if (size == 0)
|
||||||
|
return BUFFER_ERROR;
|
||||||
|
|
||||||
extension = TLSX_Find(ssl->extensions, TLSX_APPLICATION_LAYER_PROTOCOL);
|
extension = TLSX_Find(ssl->extensions, TLSX_APPLICATION_LAYER_PROTOCOL);
|
||||||
if (extension == NULL)
|
if (extension == NULL)
|
||||||
extension = TLSX_Find(ssl->ctx->extensions,
|
extension = TLSX_Find(ssl->ctx->extensions,
|
||||||
@@ -1579,7 +1582,7 @@ static int TLSX_ALPN_ParseAndSet(WOLFSSL *ssl, byte *input, word16 length,
|
|||||||
for (size = 0; offset < length; offset += size) {
|
for (size = 0; offset < length; offset += size) {
|
||||||
|
|
||||||
size = input[offset++];
|
size = input[offset++];
|
||||||
if (offset + size > length)
|
if (offset + size > length || size == 0)
|
||||||
return BUFFER_ERROR;
|
return BUFFER_ERROR;
|
||||||
|
|
||||||
if (isRequest) {
|
if (isRequest) {
|
||||||
@@ -1898,6 +1901,10 @@ static int TLSX_SNI_Parse(WOLFSSL* ssl, byte* input, word16 length,
|
|||||||
word16 size = 0;
|
word16 size = 0;
|
||||||
word16 offset = 0;
|
word16 offset = 0;
|
||||||
int cacheOnly = 0;
|
int cacheOnly = 0;
|
||||||
|
SNI *sni = NULL;
|
||||||
|
byte type;
|
||||||
|
int matchStat;
|
||||||
|
byte matched;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
TLSX *extension = TLSX_Find(ssl->extensions, TLSX_SERVER_NAME);
|
TLSX *extension = TLSX_Find(ssl->extensions, TLSX_SERVER_NAME);
|
||||||
@@ -1951,56 +1958,51 @@ static int TLSX_SNI_Parse(WOLFSSL* ssl, byte* input, word16 length,
|
|||||||
offset += OPAQUE16_LEN;
|
offset += OPAQUE16_LEN;
|
||||||
|
|
||||||
/* validating sni list length */
|
/* validating sni list length */
|
||||||
if (length != OPAQUE16_LEN + size)
|
if (length != OPAQUE16_LEN + size || size == 0)
|
||||||
return BUFFER_ERROR;
|
return BUFFER_ERROR;
|
||||||
|
|
||||||
for (size = 0; offset < length; offset += size) {
|
/* SNI was badly specified and only one type is now recognized and allowed.
|
||||||
SNI *sni = NULL;
|
* Only one SNI value per type (RFC6066), so, no loop. */
|
||||||
byte type = input[offset++];
|
type = input[offset++];
|
||||||
|
if (type != WOLFSSL_SNI_HOST_NAME)
|
||||||
|
return BUFFER_ERROR;
|
||||||
|
|
||||||
if (offset + OPAQUE16_LEN > length)
|
if (offset + OPAQUE16_LEN > length)
|
||||||
return BUFFER_ERROR;
|
return BUFFER_ERROR;
|
||||||
|
|
||||||
ato16(input + offset, &size);
|
ato16(input + offset, &size);
|
||||||
offset += OPAQUE16_LEN;
|
offset += OPAQUE16_LEN;
|
||||||
|
|
||||||
if (offset + size > length)
|
if (offset + size != length || size == 0)
|
||||||
return BUFFER_ERROR;
|
return BUFFER_ERROR;
|
||||||
|
|
||||||
if (!cacheOnly && !(sni = TLSX_SNI_Find((SNI*)extension->data, type)))
|
if (!cacheOnly && !(sni = TLSX_SNI_Find((SNI*)extension->data, type)))
|
||||||
continue; /* not using this type of SNI. */
|
return 0; /* not using this type of SNI. */
|
||||||
|
|
||||||
switch(type) {
|
|
||||||
case WOLFSSL_SNI_HOST_NAME: {
|
|
||||||
int matchStat;
|
|
||||||
byte matched;
|
|
||||||
|
|
||||||
#ifdef WOLFSSL_TLS13
|
#ifdef WOLFSSL_TLS13
|
||||||
/* Don't process the second ClientHello SNI extension if there
|
/* Don't process the second ClientHello SNI extension if there
|
||||||
* was problems with the first.
|
* was problems with the first.
|
||||||
*/
|
*/
|
||||||
if (!cacheOnly && sni->status != 0)
|
if (!cacheOnly && sni->status != 0)
|
||||||
break;
|
return 0;
|
||||||
#endif
|
#endif
|
||||||
matched = cacheOnly ||
|
matched = cacheOnly || (XSTRLEN(sni->data.host_name) == size &&
|
||||||
((XSTRLEN(sni->data.host_name) == size) &&
|
XSTRNCMP(sni->data.host_name, (const char*)input + offset, size) == 0);
|
||||||
(XSTRNCMP(sni->data.host_name,
|
|
||||||
(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, type, input + offset, size,
|
||||||
type, input + offset, size, ssl->heap);
|
ssl->heap);
|
||||||
|
|
||||||
if (r != WOLFSSL_SUCCESS)
|
if (r != WOLFSSL_SUCCESS)
|
||||||
return r; /* throws error. */
|
return r; /* throws error. */
|
||||||
|
|
||||||
if(cacheOnly) {
|
if (cacheOnly) {
|
||||||
WOLFSSL_MSG("Forcing storage of SNI, Fake match");
|
WOLFSSL_MSG("Forcing storage of SNI, Fake match");
|
||||||
matchStat = WOLFSSL_SNI_FORCE_KEEP;
|
matchStat = WOLFSSL_SNI_FORCE_KEEP;
|
||||||
} else if(matched) {
|
}
|
||||||
|
else if (matched) {
|
||||||
WOLFSSL_MSG("SNI did match!");
|
WOLFSSL_MSG("SNI did match!");
|
||||||
matchStat = WOLFSSL_SNI_REAL_MATCH;
|
matchStat = WOLFSSL_SNI_REAL_MATCH;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
WOLFSSL_MSG("fake SNI match from ANSWER_ON_MISMATCH");
|
WOLFSSL_MSG("fake SNI match from ANSWER_ON_MISMATCH");
|
||||||
matchStat = WOLFSSL_SNI_FAKE_MATCH;
|
matchStat = WOLFSSL_SNI_FAKE_MATCH;
|
||||||
}
|
}
|
||||||
@@ -2009,16 +2011,12 @@ static int TLSX_SNI_Parse(WOLFSSL* ssl, byte* input, word16 length,
|
|||||||
|
|
||||||
if(!cacheOnly)
|
if(!cacheOnly)
|
||||||
TLSX_SetResponse(ssl, TLSX_SERVER_NAME);
|
TLSX_SetResponse(ssl, TLSX_SERVER_NAME);
|
||||||
|
}
|
||||||
} else if (!(sni->options & WOLFSSL_SNI_CONTINUE_ON_MISMATCH)) {
|
else if (!(sni->options & WOLFSSL_SNI_CONTINUE_ON_MISMATCH)) {
|
||||||
SendAlert(ssl, alert_fatal, unrecognized_name);
|
SendAlert(ssl, alert_fatal, unrecognized_name);
|
||||||
|
|
||||||
return UNKNOWN_SNI_HOST_NAME_E;
|
return UNKNOWN_SNI_HOST_NAME_E;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
(void)input;
|
(void)input;
|
||||||
#endif
|
#endif
|
||||||
|
Reference in New Issue
Block a user