app-layer-ssl: decode server hello record

Decoding server hello is needed to do a better implementation of
session resumption.
pull/3478/head
Mats Klepsland 7 years ago
parent 0f1c8711ce
commit f22bd5a75b

@ -635,50 +635,54 @@ static inline int TLSDecodeHSHelloCipherSuites(SSLState *ssl_state,
if (!(HAS_SPACE(2))) if (!(HAS_SPACE(2)))
goto invalid_length; goto invalid_length;
uint16_t cipher_suites_length = *input << 8 | *(input + 1); if (ssl_state->current_flags & SSL_AL_FLAG_STATE_SERVER_HELLO) {
input += 2; /* Skip cipher suite */
input += 2;
} else {
uint16_t cipher_suites_length = *input << 8 | *(input + 1);
input += 2;
if (!(HAS_SPACE(cipher_suites_length))) if (!(HAS_SPACE(cipher_suites_length)))
goto invalid_length; goto invalid_length;
if ((ssl_state->current_flags & SSL_AL_FLAG_STATE_CLIENT_HELLO) && if (ssl_config.enable_ja3) {
ssl_config.enable_ja3) { int rc;
int rc;
JA3Buffer *ja3_cipher_suites = Ja3BufferInit(); JA3Buffer *ja3_cipher_suites = Ja3BufferInit();
if (ja3_cipher_suites == NULL) if (ja3_cipher_suites == NULL)
return -1; return -1;
uint16_t processed_len = 0; uint16_t processed_len = 0;
/* coverity[tainted_data] */ /* coverity[tainted_data] */
while (processed_len < cipher_suites_length) while (processed_len < cipher_suites_length)
{ {
if (!(HAS_SPACE(2))) { if (!(HAS_SPACE(2))) {
Ja3BufferFree(&ja3_cipher_suites); Ja3BufferFree(&ja3_cipher_suites);
goto invalid_length; goto invalid_length;
} }
uint16_t cipher_suite = *input << 8 | *(input + 1); uint16_t cipher_suite = *input << 8 | *(input + 1);
input += 2; input += 2;
if (TLSDecodeValueIsGREASE(cipher_suite) != 1) { if (TLSDecodeValueIsGREASE(cipher_suite) != 1) {
rc = Ja3BufferAddValue(&ja3_cipher_suites, cipher_suite); rc = Ja3BufferAddValue(&ja3_cipher_suites, cipher_suite);
if (rc != 0) { if (rc != 0) {
return -1; return -1;
}
} }
processed_len += 2;
} }
processed_len += 2; rc = Ja3BufferAppendBuffer(&ssl_state->ja3_str, &ja3_cipher_suites);
} if (rc == -1) {
return -1;
}
rc = Ja3BufferAppendBuffer(&ssl_state->ja3_str, &ja3_cipher_suites); } else {
if (rc == -1) { /* Skip cipher suites */
return -1; input += cipher_suites_length;
} }
} else {
/* Skip cipher suites */
input += cipher_suites_length;
} }
return (input - initial_input); return (input - initial_input);
@ -700,13 +704,17 @@ static inline int TLSDecodeHSHelloCompressionMethods(SSLState *ssl_state,
goto invalid_length; goto invalid_length;
/* Skip compression methods */ /* Skip compression methods */
uint8_t compression_methods_length = *input; if (ssl_state->current_flags & SSL_AL_FLAG_STATE_SERVER_HELLO) {
input += 1; input += 1;
} else {
uint8_t compression_methods_length = *input;
input += 1;
if (!(HAS_SPACE(compression_methods_length))) if (!(HAS_SPACE(compression_methods_length)))
goto invalid_length; goto invalid_length;
input += compression_methods_length; input += compression_methods_length;
}
return (input - initial_input); return (input - initial_input);
@ -1053,10 +1061,6 @@ static int TLSDecodeHandshakeHello(SSLState *ssl_state,
int ret; int ret;
uint32_t parsed = 0; uint32_t parsed = 0;
/* Only parse the message if it is complete */
if (input_len < ssl_state->curr_connp->message_length || input_len < 40)
goto end;
ret = TLSDecodeHSHelloVersion(ssl_state, input, input_len); ret = TLSDecodeHSHelloVersion(ssl_state, input, input_len);
if (ret < 0) if (ret < 0)
goto end; goto end;
@ -1121,15 +1125,30 @@ static int SSLv3ParseHandshakeType(SSLState *ssl_state, uint8_t *input,
case SSLV3_HS_CLIENT_HELLO: case SSLV3_HS_CLIENT_HELLO:
ssl_state->current_flags = SSL_AL_FLAG_STATE_CLIENT_HELLO; ssl_state->current_flags = SSL_AL_FLAG_STATE_CLIENT_HELLO;
rc = TLSDecodeHandshakeHello(ssl_state, input, input_len); /* Only parse the message if it is complete */
if (input_len >= ssl_state->curr_connp->message_length &&
input_len >= 40) {
rc = TLSDecodeHandshakeHello(ssl_state, input, input_len);
if (rc < 0) if (rc < 0)
return rc; return rc;
}
break; break;
case SSLV3_HS_SERVER_HELLO: case SSLV3_HS_SERVER_HELLO:
ssl_state->current_flags = SSL_AL_FLAG_STATE_SERVER_HELLO; ssl_state->current_flags = SSL_AL_FLAG_STATE_SERVER_HELLO;
/* Only parse the message if it is complete */
if (input_len >= ssl_state->curr_connp->message_length &&
input_len >= 40) {
rc = TLSDecodeHandshakeHello(ssl_state, input,
ssl_state->curr_connp->message_length);
if (rc < 0)
return rc;
}
break; break;
case SSLV3_HS_SERVER_KEY_EXCHANGE: case SSLV3_HS_SERVER_KEY_EXCHANGE:

Loading…
Cancel
Save