app-layer-ssl: add support for TLSv1.3 from draft 22

Add support for draft 22 to draft 28 and for the final
version (RFC8446) of TLSv1.3.
pull/3478/head
Mats Klepsland 7 years ago
parent e0ef578c46
commit 831ddb62d2

@ -559,15 +559,17 @@ static inline int TLSDecodeHSHelloVersion(SSLState *ssl_state,
return -1;
}
ssl_state->curr_connp->version = *input << 8 | *(input + 1);
if ((ssl_state->current_flags & SSL_AL_FLAG_STATE_CLIENT_HELLO) &&
ssl_config.enable_ja3 && ssl_state->ja3_str == NULL) {
uint16_t version = *input << 8 | *(input + 1);
ssl_state->ja3_str = Ja3BufferInit();
if (ssl_state->ja3_str == NULL)
return -1;
int rc = Ja3BufferAddValue(&ssl_state->ja3_str, version);
int rc = Ja3BufferAddValue(&ssl_state->ja3_str,
ssl_state->curr_connp->version);
if (rc != 0)
return -1;
}
@ -821,6 +823,56 @@ invalid_length:
return -1;
}
static inline int TLSDecodeHSHelloExtensionSupportedVersions(SSLState *ssl_state,
const uint8_t * const initial_input,
const uint32_t input_len)
{
uint8_t *input = (uint8_t *)initial_input;
if (ssl_state->current_flags & SSL_AL_FLAG_STATE_CLIENT_HELLO) {
if (!(HAS_SPACE(1)))
goto invalid_length;
uint8_t supported_ver_len = *input;
input += 1;
if (!(HAS_SPACE(supported_ver_len)))
goto invalid_length;
/* Use the first (and prefered) version as client version */
ssl_state->curr_connp->version = *input << 8 | *(input + 1);
/* Set a flag to indicate that we have seen this extension */
ssl_state->flags |= SSL_AL_FLAG_CH_VERSION_EXTENSION;
input += supported_ver_len;
}
else if (ssl_state->current_flags & SSL_AL_FLAG_STATE_SERVER_HELLO) {
if (!(HAS_SPACE(2)))
goto invalid_length;
uint16_t ver = *input << 8 | *(input + 1);
if ((ssl_state->flags & SSL_AL_FLAG_CH_VERSION_EXTENSION) &&
((ver == TLS_VERSION_13) || (((ver >> 8) & 0xff) == 0x7f))) {
ssl_state->flags |= SSL_AL_FLAG_LOG_WITHOUT_CERT;
}
ssl_state->curr_connp->version = ver;
input += 2;
}
return (input - initial_input);
invalid_length:
SCLogDebug("TLS handshake invalid length");
SSLSetEvent(ssl_state,
TLS_DECODER_EVENT_HANDSHAKE_INVALID_LENGTH);
return -1;
}
static inline int TLSDecodeHSHelloExtensionEllipticCurves(SSLState *ssl_state,
const uint8_t * const initial_input,
const uint32_t input_len,
@ -1018,6 +1070,18 @@ static inline int TLSDecodeHSHelloExtensions(SSLState *ssl_state,
break;
}
case SSL_EXTENSION_SUPPORTED_VERSIONS:
{
ret = TLSDecodeHSHelloExtensionSupportedVersions(ssl_state, input,
input_len - parsed);
if (ret < 0)
goto end;
input += ret;
break;
}
case SSL_EXTENSION_SESSION_TICKET:
{
if ((ssl_state->current_flags & SSL_AL_FLAG_STATE_CLIENT_HELLO) &&
@ -1536,12 +1600,30 @@ static int SSLv3ParseRecord(uint8_t direction, SSLState *ssl_state,
return 0;
}
uint8_t skip_version = 0;
/* Only set SSL/TLS version here if it has not already been set in
client/server hello. */
if (direction == 0) {
if ((ssl_state->flags & SSL_AL_FLAG_STATE_CLIENT_HELLO) &&
(ssl_state->client_connp.version != TLS_VERSION_UNKNOWN)) {
skip_version = 1;
}
} else {
if ((ssl_state->flags & SSL_AL_FLAG_STATE_SERVER_HELLO) &&
(ssl_state->server_connp.version != TLS_VERSION_UNKNOWN)) {
skip_version = 1;
}
}
switch (ssl_state->curr_connp->bytes_processed) {
case 0:
if (input_len >= 5) {
ssl_state->curr_connp->content_type = input[0];
ssl_state->curr_connp->version = input[1] << 8;
ssl_state->curr_connp->version |= input[2];
if (!skip_version) {
ssl_state->curr_connp->version = input[1] << 8;
ssl_state->curr_connp->version |= input[2];
}
ssl_state->curr_connp->record_length = input[3] << 8;
ssl_state->curr_connp->record_length |= input[4];
ssl_state->curr_connp->bytes_processed += SSLV3_RECORD_HDR_LEN;
@ -1554,13 +1636,23 @@ static int SSLv3ParseRecord(uint8_t direction, SSLState *ssl_state,
/* fall through */
case 1:
ssl_state->curr_connp->version = *(input++) << 8;
if (!skip_version) {
ssl_state->curr_connp->version = *(input++) << 8;
printf("%d\n", ssl_state->curr_connp->version);
} else {
input++;
}
if (--input_len == 0)
break;
/* fall through */
case 2:
ssl_state->curr_connp->version |= *(input++);
if (!skip_version) {
ssl_state->curr_connp->version |= *(input++);
printf("%d\n", ssl_state->curr_connp->version);
} else {
input++;
}
if (--input_len == 0)
break;
@ -1965,14 +2057,6 @@ static int SSLv3Decode(uint8_t direction, SSLState *ssl_state,
return parsed;
}
/* check record version */
if (ssl_state->curr_connp->version < SSL_VERSION_3 ||
ssl_state->curr_connp->version > TLS_VERSION_12) {
SSLSetEvent(ssl_state, TLS_DECODER_EVENT_INVALID_RECORD_VERSION);
return -1;
}
/* record_length should never be zero */
if (ssl_state->curr_connp->record_length == 0) {
SCLogDebug("SSLv3 Record length is 0");
@ -2200,9 +2284,6 @@ static int SSLDecode(Flow *f, uint8_t direction, void *alstate, AppLayerParserSt
}
} else {
SCLogDebug("SSLv3.x detected");
/* we will keep it this way till our record parser tells
us what exact version this is */
ssl_state->curr_connp->version = TLS_VERSION_UNKNOWN;
retval = SSLv3Decode(direction, ssl_state, pstate, input,
input_len);
if (retval < 0) {
@ -4459,8 +4540,6 @@ static int SSLParserTest23(void)
* record */
FAIL_IF(app_state->client_connp.content_type != SSLV3_HANDSHAKE_PROTOCOL);
FAIL_IF(app_state->client_connp.version != SSL_VERSION_3);
FAIL_IF((app_state->flags & SSL_AL_FLAG_STATE_CLIENT_HELLO) == 0);
FAIL_IF((app_state->flags & SSL_AL_FLAG_SSL_CLIENT_HS) == 0);
FAIL_IF((app_state->flags & SSL_AL_FLAG_SSL_NO_SESSION_ID) == 0);
@ -4499,8 +4578,6 @@ static int SSLParserTest23(void)
FAIL_IF(app_state->client_connp.content_type != SSLV3_APPLICATION_PROTOCOL);
FAIL_IF(app_state->client_connp.version != SSL_VERSION_3);
FAIL_IF((app_state->flags & SSL_AL_FLAG_STATE_CLIENT_HELLO) == 0);
FAIL_IF((app_state->flags & SSL_AL_FLAG_SSL_CLIENT_HS) == 0);
FAIL_IF((app_state->flags & SSL_AL_FLAG_SSL_NO_SESSION_ID) == 0);

@ -103,6 +103,13 @@ enum {
/* Session resumed without a full handshake */
#define SSL_AL_FLAG_SESSION_RESUMED BIT_U32(20)
/* Encountered a supported_versions extension in client hello */
#define SSL_AL_FLAG_CH_VERSION_EXTENSION BIT_U32(21)
/* Log the session even without ever seeing a certificate. This is used
to log TLSv1.3 sessions. */
#define SSL_AL_FLAG_LOG_WITHOUT_CERT BIT_U32(22)
/* config flags */
#define SSL_TLS_LOG_PEM (1 << 0)
@ -111,6 +118,7 @@ enum {
#define SSL_EXTENSION_ELLIPTIC_CURVES 0x000a
#define SSL_EXTENSION_EC_POINT_FORMATS 0x000b
#define SSL_EXTENSION_SESSION_TICKET 0x0023
#define SSL_EXTENSION_SUPPORTED_VERSIONS 0x002b
/* SNI types */
#define SSL_SNI_TYPE_HOST_NAME 0
@ -124,6 +132,21 @@ enum {
TLS_VERSION_10 = 0x0301,
TLS_VERSION_11 = 0x0302,
TLS_VERSION_12 = 0x0303,
TLS_VERSION_13 = 0x0304,
TLS_VERSION_13_DRAFT28 = 0x7f1c,
TLS_VERSION_13_DRAFT27 = 0x7f1b,
TLS_VERSION_13_DRAFT26 = 0x7f1a,
TLS_VERSION_13_DRAFT25 = 0x7f19,
TLS_VERSION_13_DRAFT24 = 0x7f18,
TLS_VERSION_13_DRAFT23 = 0x7f17,
TLS_VERSION_13_DRAFT22 = 0x7f16,
TLS_VERSION_13_DRAFT21 = 0x7f15,
TLS_VERSION_13_DRAFT20 = 0x7f14,
TLS_VERSION_13_DRAFT19 = 0x7f13,
TLS_VERSION_13_DRAFT18 = 0x7f12,
TLS_VERSION_13_DRAFT17 = 0x7f11,
TLS_VERSION_13_DRAFT16 = 0x7f10,
TLS_VERSION_13_PRE_DRAFT16 = 0x7f01,
};
typedef struct SSLCertsChain_ {

Loading…
Cancel
Save