Fix for sniffer using HAVE_MAX_FRAGMENT in "certificate" type message. ZD 10903

This commit is contained in:
David Garske
2020-09-15 10:01:05 -07:00
parent 1668f6f626
commit ce1c1fe0a6

View File

@ -452,6 +452,11 @@ typedef struct SnifferSession {
word32 srvReassemblyMemory; /* server packet memory used */ word32 srvReassemblyMemory; /* server packet memory used */
struct SnifferSession* next; /* for hash table list */ struct SnifferSession* next; /* for hash table list */
byte* ticketID; /* mac ID of session ticket */ byte* ticketID; /* mac ID of session ticket */
#ifdef HAVE_MAX_FRAGMENT
byte* tlsFragBuf;
word32 tlsFragOffset;
word32 tlsFragSize;
#endif
#ifdef HAVE_SNI #ifdef HAVE_SNI
const char* sni; /* server name indication */ const char* sni; /* server name indication */
#endif #endif
@ -648,6 +653,12 @@ static void FreeSnifferSession(SnifferSession* session)
#ifdef WOLFSSL_TLS13 #ifdef WOLFSSL_TLS13
if (session->cliKeyShare) if (session->cliKeyShare)
XFREE(session->cliKeyShare, NULL, DYNAMIC_TYPE_TMP_BUFFER); XFREE(session->cliKeyShare, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif
#ifdef HAVE_MAX_FRAGMENT
if (session->tlsFragBuf) {
XFREE(session->tlsFragBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
session->tlsFragBuf = NULL;
}
#endif #endif
} }
XFREE(session, NULL, DYNAMIC_TYPE_SNIFFER_SESSION); XFREE(session, NULL, DYNAMIC_TYPE_SNIFFER_SESSION);
@ -2743,6 +2754,24 @@ static int ProcessServerHello(int msgSz, const byte* input, int* sslBytes,
session->sslClient->session.ticketNonce.len = 1; session->sslClient->session.ticketNonce.len = 1;
session->sslClient->session.ticketNonce.data[0] = 0; session->sslClient->session.ticketNonce.data[0] = 0;
break; break;
#endif
#ifdef HAVE_MAX_FRAGMENT
case EXT_MAX_FRAGMENT_LENGTH:
{
word16 max_fragment = MAX_RECORD_SIZE;
switch (input[0]) {
case WOLFSSL_MFL_2_8 : max_fragment = 256; break;
case WOLFSSL_MFL_2_9 : max_fragment = 512; break;
case WOLFSSL_MFL_2_10: max_fragment = 1024; break;
case WOLFSSL_MFL_2_11: max_fragment = 2048; break;
case WOLFSSL_MFL_2_12: max_fragment = 4096; break;
case WOLFSSL_MFL_2_13: max_fragment = 8192; break;
default: break;
}
session->sslServer->max_fragment = max_fragment;
session->sslClient->max_fragment = max_fragment;
break;
}
#endif #endif
case EXT_SUPPORTED_VERSIONS: case EXT_SUPPORTED_VERSIONS:
session->sslServer->version.major = input[0]; session->sslServer->version.major = input[0];
@ -3407,14 +3436,30 @@ static int ProcessFinished(const byte* input, int size, int* sslBytes,
/* Process HandShake input */ /* Process HandShake input */
static int DoHandShake(const byte* input, int* sslBytes, static int DoHandShake(const byte* input, int* sslBytes,
SnifferSession* session, char* error) SnifferSession* session, char* error, word16 rhSize)
{ {
byte type; byte type;
int size; int size;
int ret = 0; int ret = 0;
int startBytes;
WOLFSSL* ssl; WOLFSSL* ssl;
#ifdef HAVE_MAX_FRAGMENT
if (session->tlsFragBuf) {
XMEMCPY(session->tlsFragBuf + session->tlsFragOffset, input, rhSize);
session->tlsFragOffset += rhSize;
*sslBytes -= rhSize;
if (session->tlsFragOffset < session->tlsFragSize) {
return 0;
}
/* reassembled complete fragment */
input = session->tlsFragBuf;
*sslBytes = session->tlsFragSize;
rhSize = session->tlsFragSize;
}
#endif
if (*sslBytes < HANDSHAKE_HEADER_SZ) { if (*sslBytes < HANDSHAKE_HEADER_SZ) {
SetError(HANDSHAKE_INPUT_STR, error, session, FATAL_ERROR_STATE); SetError(HANDSHAKE_INPUT_STR, error, session, FATAL_ERROR_STATE);
return -1; return -1;
@ -3424,7 +3469,6 @@ static int DoHandShake(const byte* input, int* sslBytes,
input += HANDSHAKE_HEADER_SZ; input += HANDSHAKE_HEADER_SZ;
*sslBytes -= HANDSHAKE_HEADER_SZ; *sslBytes -= HANDSHAKE_HEADER_SZ;
startBytes = *sslBytes;
if (*sslBytes < size) { if (*sslBytes < size) {
Trace(SPLIT_HANDSHAKE_MSG_STR); Trace(SPLIT_HANDSHAKE_MSG_STR);
@ -3449,6 +3493,30 @@ static int DoHandShake(const byte* input, int* sslBytes,
} }
#endif #endif
#ifdef HAVE_MAX_FRAGMENT
if (rhSize < size) {
/* partial fragment, let's reassemble */
if (session->tlsFragBuf == NULL) {
session->tlsFragOffset = 0;
session->tlsFragSize = size + HANDSHAKE_HEADER_SZ;
session->tlsFragBuf = (byte*)XMALLOC(session->tlsFragSize, NULL, DYNAMIC_TYPE_TMP_BUFFER);
if (session->tlsFragBuf == NULL) {
SetError(MEMORY_STR, error, NULL, 0);
return 0;
}
/* include the handshake header */
input -= HANDSHAKE_HEADER_SZ;
*sslBytes += HANDSHAKE_HEADER_SZ;
}
XMEMCPY(session->tlsFragBuf + session->tlsFragOffset, input, rhSize);
session->tlsFragOffset += rhSize;
*sslBytes -= rhSize;
return 0;
}
#endif
#ifdef WOLFSSL_TLS13 #ifdef WOLFSSL_TLS13
if (type != client_hello) { if (type != client_hello) {
/* For resumption the hash is before / after client_hello PSK binder */ /* For resumption the hash is before / after client_hello PSK binder */
@ -3465,7 +3533,8 @@ static int DoHandShake(const byte* input, int* sslBytes,
if (HashUpdate(session->hash, input, size) != 0) { if (HashUpdate(session->hash, input, size) != 0) {
SetError(EXTENDED_MASTER_HASH_STR, error, SetError(EXTENDED_MASTER_HASH_STR, error,
session, FATAL_ERROR_STATE); session, FATAL_ERROR_STATE);
return -1; ret = -1;
goto exit;
} }
} }
#endif #endif
@ -3560,10 +3629,17 @@ static int DoHandShake(const byte* input, int* sslBytes,
break; break;
default: default:
SetError(GOT_UNKNOWN_HANDSHAKE_STR, error, session, 0); SetError(GOT_UNKNOWN_HANDSHAKE_STR, error, session, 0);
return -1; ret = -1;
break;
} }
*sslBytes = startBytes - size; /* actual bytes of full process */ exit:
#ifdef HAVE_MAX_FRAGMENT
if (session->tlsFragBuf) {
XFREE(session->tlsFragBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
session->tlsFragBuf = NULL;
}
#endif
return ret; return ret;
} }
@ -4818,11 +4894,9 @@ doPart:
switch ((enum ContentType)rh.type) { switch ((enum ContentType)rh.type) {
case handshake: case handshake:
{ {
int startIdx = sslBytes; int inOutIdx = sslBytes;
int used;
Trace(GOT_HANDSHAKE_STR); Trace(GOT_HANDSHAKE_STR);
ret = DoHandShake(sslFrame, &sslBytes, session, error); ret = DoHandShake(sslFrame, &inOutIdx, session, error, rhSize);
if (ret != 0) { if (ret != 0) {
if (session->flags.fatalError == 0) if (session->flags.fatalError == 0)
SetError(BAD_HANDSHAKE_STR, error, session, SetError(BAD_HANDSHAKE_STR, error, session,
@ -4830,9 +4904,8 @@ doPart:
return -1; return -1;
} }
/* DoHandShake now fully decrements sslBytes to remaining */ sslFrame += rhSize;
used = startIdx - sslBytes; sslBytes -= rhSize;
sslFrame += used;
if (decrypted) if (decrypted)
sslFrame += ssl->keys.padSz; sslFrame += ssl->keys.padSz;
} }