From: Anoop Saldanha Date: Fri, 18 May 2012 15:48:30 +0000 (+0530) Subject: ssl parser fix/updates X-Git-Tag: suricata-1.3beta2~6 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=270ea253a24f1759d9c36d6b34abd6360c5633b0;p=thirdparty%2Fsuricata.git ssl parser fix/updates --- diff --git a/src/app-layer-ssl.c b/src/app-layer-ssl.c index 722accd7b4..e555b67baa 100644 --- a/src/app-layer-ssl.c +++ b/src/app-layer-ssl.c @@ -110,8 +110,8 @@ SslConfig ssl_config; static void SSLParserReset(SSLState *ssl_state) { - ssl_state->bytes_processed = 0; - ssl_state->message_start = 0; + ssl_state->curr_connp->bytes_processed = 0; + ssl_state->curr_connp->message_start = 0; } static int SSLv3ParseHandshakeType(SSLState *ssl_state, uint8_t *input, @@ -125,35 +125,14 @@ static int SSLv3ParseHandshakeType(SSLState *ssl_state, uint8_t *input, return 0; } - switch (ssl_state->handshake_type) { + switch (ssl_state->curr_connp->handshake_type) { case SSLV3_HS_CLIENT_HELLO: ssl_state->flags |= SSL_AL_FLAG_STATE_CLIENT_HELLO; - - switch (ssl_state->bytes_processed) { - case 9: - ssl_state->bytes_processed++; - parsed++; - ssl_state->handshake_client_hello_ssl_version = *(input++) << 8; - if (--input_len == 0) - break; - case 10: - ssl_state->bytes_processed++; - parsed++; - ssl_state->handshake_client_hello_ssl_version |= *(input++); - if (--input_len == 0) - break; - } break; case SSLV3_HS_SERVER_HELLO: ssl_state->flags |= SSL_AL_FLAG_STATE_SERVER_HELLO; - rc = DecodeTLSHandshakeServerHello(ssl_state, input, input_len); - if (rc >= 0) { - ssl_state->bytes_processed += rc; - input += rc; - parsed += rc; - } break; case SSLV3_HS_SERVER_KEY_EXCHANGE: @@ -165,33 +144,33 @@ static int SSLv3ParseHandshakeType(SSLState *ssl_state, uint8_t *input, break; case SSLV3_HS_CERTIFICATE: - if (ssl_state->trec == NULL) { - ssl_state->trec_len = 2 * ssl_state->record_length + SSLV3_RECORD_LEN + 1; - ssl_state->trec = SCMalloc( ssl_state->trec_len ); + if (ssl_state->curr_connp->trec == NULL) { + ssl_state->curr_connp->trec_len = 2 * ssl_state->curr_connp->record_length + SSLV3_RECORD_LEN + 1; + ssl_state->curr_connp->trec = SCMalloc( ssl_state->curr_connp->trec_len ); } - if (ssl_state->trec_pos + input_len >= ssl_state->trec_len) { - ssl_state->trec_len = ssl_state->trec_len + 2 * input_len + 1; - ssl_state->trec = SCRealloc( ssl_state->trec, ssl_state->trec_len ); + if (ssl_state->curr_connp->trec_pos + input_len >= ssl_state->curr_connp->trec_len) { + ssl_state->curr_connp->trec_len = ssl_state->curr_connp->trec_len + 2 * input_len + 1; + ssl_state->curr_connp->trec = SCRealloc( ssl_state->curr_connp->trec, ssl_state->curr_connp->trec_len ); } - if (ssl_state->trec == NULL) { - ssl_state->trec_len = 0; + if (ssl_state->curr_connp->trec == NULL) { + ssl_state->curr_connp->trec_len = 0; /* error, skip packet */ parsed += input_len; - ssl_state->bytes_processed += input_len; + ssl_state->curr_connp->bytes_processed += input_len; break; } - memcpy(ssl_state->trec + ssl_state->trec_pos, initial_input, input_len); - ssl_state->trec_pos += input_len; + memcpy(ssl_state->curr_connp->trec + ssl_state->curr_connp->trec_pos, initial_input, input_len); + ssl_state->curr_connp->trec_pos += input_len; - rc = DecodeTLSHandshakeServerCertificate(ssl_state, ssl_state->trec, ssl_state->trec_pos); + rc = DecodeTLSHandshakeServerCertificate(ssl_state, ssl_state->curr_connp->trec, ssl_state->curr_connp->trec_pos); if (rc > 0) { /* do not return normally if the packet was fragmented: * we would return the size of the *entire* message, * while we expect only the number of bytes parsed bytes * from the *current* fragment */ - uint32_t diff = input_len - (ssl_state->trec_pos - rc); - ssl_state->bytes_processed += diff; + uint32_t diff = input_len - (ssl_state->curr_connp->trec_pos - rc); + ssl_state->curr_connp->bytes_processed += diff; return diff; } break; @@ -207,16 +186,16 @@ static int SSLv3ParseHandshakeType(SSLState *ssl_state, uint8_t *input, } /* skip the rest of the current message */ - uint32_t next_msg_offset = ssl_state->message_start + SSLV3_MESSAGE_HDR_LEN + ssl_state->message_length; - if (ssl_state->bytes_processed + input_len < next_msg_offset) { + uint32_t next_msg_offset = ssl_state->curr_connp->message_start + SSLV3_MESSAGE_HDR_LEN + ssl_state->curr_connp->message_length; + if (ssl_state->curr_connp->bytes_processed + input_len < next_msg_offset) { /* we don't have enough data */ parsed += input_len; - ssl_state->bytes_processed += input_len; + ssl_state->curr_connp->bytes_processed += input_len; return parsed; } - uint32_t diff = next_msg_offset - ssl_state->bytes_processed; + uint32_t diff = next_msg_offset - ssl_state->curr_connp->bytes_processed; parsed += diff; - ssl_state->bytes_processed += diff; + ssl_state->curr_connp->bytes_processed += diff; return parsed; } @@ -230,44 +209,48 @@ static int SSLv3ParseHandshakeProtocol(SSLState *ssl_state, uint8_t *input, return 0; } - if (ssl_state->message_start == 0) { - ssl_state->message_start = SSLV3_RECORD_LEN; + if (ssl_state->curr_connp->message_start == 0) { + ssl_state->curr_connp->message_start = SSLV3_RECORD_LEN; } - switch (ssl_state->bytes_processed - ssl_state->message_start) { + switch (ssl_state->curr_connp->bytes_processed - ssl_state->curr_connp->message_start) { case 0: - ssl_state->handshake_type = *(input++); - ssl_state->bytes_processed++; + ssl_state->curr_connp->handshake_type = *(input++); + ssl_state->curr_connp->bytes_processed++; if (--input_len == 0) break; case 1: - ssl_state->message_length = *(input++) << 16; - ssl_state->bytes_processed++; + ssl_state->curr_connp->message_length = *(input++) << 16; + ssl_state->curr_connp->bytes_processed++; if (--input_len == 0) break; case 2: - ssl_state->message_length |= *(input++) << 8; - ssl_state->bytes_processed++; + ssl_state->curr_connp->message_length |= *(input++) << 8; + ssl_state->curr_connp->bytes_processed++; if (--input_len == 0) break; case 3: - ssl_state->message_length |= *(input++); - ssl_state->bytes_processed++; + ssl_state->curr_connp->message_length |= *(input++); + ssl_state->curr_connp->bytes_processed++; if (--input_len == 0) break; } retval = SSLv3ParseHandshakeType(ssl_state, input, input_len); if (retval < 0) { - SCReturnInt(retval); - } - uint32_t next_msg_offset = ssl_state->message_start + SSLV3_MESSAGE_HDR_LEN + ssl_state->message_length; - if (ssl_state->bytes_processed >= next_msg_offset) { - ssl_state->handshake_type = 0; - ssl_state->message_length = 0; - ssl_state->message_start = next_msg_offset; + return retval; } input += retval; + + uint32_t next_msg_offset = ssl_state->curr_connp->message_start + SSLV3_MESSAGE_HDR_LEN + ssl_state->curr_connp->message_length; + if (ssl_state->curr_connp->bytes_processed == next_msg_offset) { + ssl_state->curr_connp->handshake_type = 0; + ssl_state->curr_connp->message_length = 0; + ssl_state->curr_connp->message_start = next_msg_offset; + } else if (ssl_state->curr_connp->bytes_processed > next_msg_offset) { + return -1; + } + return (input - initial_input); } @@ -280,65 +263,42 @@ static int SSLv3ParseRecord(uint8_t direction, SSLState *ssl_state, return 0; } - switch (ssl_state->bytes_processed) { + switch (ssl_state->curr_connp->bytes_processed) { case 0: if (input_len >= 5) { - /* toserver - 0 */ - ssl_state->cur_content_type = input[0]; - if (direction == 0) { - ssl_state->client_content_type = input[0]; - ssl_state->client_version = input[1] << 8; - ssl_state->client_version |= input[2]; - - /* toclient - 1 */ - } else { - ssl_state->server_content_type = input[0]; - ssl_state->server_version = input[1] << 8; - ssl_state->server_version |= input[2]; - } - ssl_state->record_length = input[3] << 8; - ssl_state->record_length |= input[4]; - ssl_state->bytes_processed += SSLV3_RECORD_LEN; + ssl_state->curr_connp->content_type = input[0]; + 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_LEN; return SSLV3_RECORD_LEN; } else { - ssl_state->cur_content_type = *input; - if (direction == 0) { - ssl_state->client_content_type = *(input++); - } else { - ssl_state->server_content_type = *(input++); - } + ssl_state->curr_connp->content_type = *(input++); if (--input_len == 0) break; } case 1: - if (direction == 0) { - ssl_state->client_version = *(input++) << 8; - } else { - ssl_state->server_version = *(input++) << 8; - } + ssl_state->curr_connp->version = *(input++) << 8; if (--input_len == 0) break; case 2: - if (direction == 0) { - ssl_state->client_version |= *(input++); - } else { - ssl_state->server_version |= *(input++); - } + ssl_state->curr_connp->version |= *(input++); if (--input_len == 0) break; case 3: - ssl_state->record_length = *(input++) << 8; + ssl_state->curr_connp->record_length = *(input++) << 8; if (--input_len == 0) break; case 4: - ssl_state->record_length |= *(input++); - if (ssl_state->record_length <= SSLV3_RECORD_LEN) + ssl_state->curr_connp->record_length |= *(input++); + if (ssl_state->curr_connp->record_length <= SSLV3_RECORD_LEN) return -1; if (--input_len == 0) break; - } /* switch (ssl_state->bytes_processed) */ + } /* switch (ssl_state->curr_connp->bytes_processed) */ - ssl_state->bytes_processed += (input - initial_input); + ssl_state->curr_connp->bytes_processed += (input - initial_input); return (input - initial_input); } @@ -352,67 +312,49 @@ static int SSLv2ParseRecord(uint8_t direction, SSLState *ssl_state, return 0; } - if (ssl_state->record_lengths_length == 2) { - switch (ssl_state->bytes_processed) { + if (ssl_state->curr_connp->record_lengths_length == 2) { + switch (ssl_state->curr_connp->bytes_processed) { case 0: - if (input_len >= ssl_state->record_lengths_length + 1) { - ssl_state->record_length = (0x7f & input[0]) << 8 | input[1]; - ssl_state->cur_content_type = input[2]; - if (direction == 0) { - ssl_state->client_content_type = input[2]; - ssl_state->client_version = SSL_VERSION_2; - } else { - ssl_state->server_content_type = input[2]; - ssl_state->server_version = SSL_VERSION_2; - } - ssl_state->bytes_processed += 3; + if (input_len >= ssl_state->curr_connp->record_lengths_length + 1) { + ssl_state->curr_connp->record_length = (0x7f & input[0]) << 8 | input[1]; + ssl_state->curr_connp->content_type = input[2]; + ssl_state->curr_connp->version = SSL_VERSION_2; + ssl_state->curr_connp->bytes_processed += 3; return 3; } else { - ssl_state->record_length = (0x7f & *(input++)) << 8; + ssl_state->curr_connp->record_length = (0x7f & *(input++)) << 8; if (--input_len == 0) break; } case 1: - ssl_state->record_length |= *(input++); + ssl_state->curr_connp->record_length |= *(input++); if (--input_len == 0) break; case 2: - ssl_state->cur_content_type = *input; - if (direction == 0) { - ssl_state->client_content_type = *(input++); - ssl_state->client_version = SSL_VERSION_2; - } else { - ssl_state->server_content_type = *(input++); - ssl_state->server_version = SSL_VERSION_2; - } + ssl_state->curr_connp->content_type = *(input++); + ssl_state->curr_connp->version = SSL_VERSION_2; if (--input_len == 0) break; - } /* switch (ssl_state->bytes_processed) */ + } /* switch (ssl_state->curr_connp->bytes_processed) */ } else { - switch (ssl_state->bytes_processed) { + switch (ssl_state->curr_connp->bytes_processed) { case 0: - if (input_len >= ssl_state->record_lengths_length + 1) { - ssl_state->record_length = (0x3f & input[0]) << 8 | input[1]; - ssl_state->cur_content_type = input[3]; - if (direction == 0) { - ssl_state->client_content_type = input[3]; - ssl_state->client_version = SSL_VERSION_2; - } else { - ssl_state->server_content_type = input[3]; - ssl_state->server_version = SSL_VERSION_2; - } - ssl_state->bytes_processed += 4; + if (input_len >= ssl_state->curr_connp->record_lengths_length + 1) { + ssl_state->curr_connp->record_length = (0x3f & input[0]) << 8 | input[1]; + ssl_state->curr_connp->content_type = input[3]; + ssl_state->curr_connp->version = SSL_VERSION_2; + ssl_state->curr_connp->bytes_processed += 4; return 4; } else { - ssl_state->record_length = (0x3f & *(input++)) << 8; + ssl_state->curr_connp->record_length = (0x3f & *(input++)) << 8; if (--input_len == 0) break; } case 1: - ssl_state->record_length |= *(input++); + ssl_state->curr_connp->record_length |= *(input++); if (--input_len == 0) break; @@ -423,20 +365,14 @@ static int SSLv2ParseRecord(uint8_t direction, SSLState *ssl_state, break; case 3: - ssl_state->cur_content_type = *input; - if (direction == 0) { - ssl_state->client_content_type = *(input++); - ssl_state->client_version = SSL_VERSION_2; - } else { - ssl_state->server_content_type = *(input++); - ssl_state->server_version = SSL_VERSION_2; - } + ssl_state->curr_connp->content_type = *(input++); + ssl_state->curr_connp->version = SSL_VERSION_2; if (--input_len == 0) break; - } /* switch (ssl_state->bytes_processed) */ + } /* switch (ssl_state->curr_connp->bytes_processed) */ } - ssl_state->bytes_processed += (input - initial_input); + ssl_state->curr_connp->bytes_processed += (input - initial_input); return (input - initial_input); } @@ -448,17 +384,17 @@ static int SSLv2Decode(uint8_t direction, SSLState *ssl_state, int retval = 0; uint8_t *initial_input = input; - if (ssl_state->bytes_processed == 0) { + if (ssl_state->curr_connp->bytes_processed == 0) { if (input[0] & 0x80) { - ssl_state->record_lengths_length = 2; + ssl_state->curr_connp->record_lengths_length = 2; } else { - ssl_state->record_lengths_length = 3; + ssl_state->curr_connp->record_lengths_length = 3; } } /* the + 1 because, we also read one extra byte inside SSLv2ParseRecord * to read the msg_type */ - if (ssl_state->bytes_processed < (ssl_state->record_lengths_length + 1)) { + if (ssl_state->curr_connp->bytes_processed < (ssl_state->curr_connp->record_lengths_length + 1)) { retval = SSLv2ParseRecord(direction, ssl_state, input, input_len); if (retval == -1) { AppLayerDecoderEventsSetEvent(ssl_state->f, TLS_DECODER_EVENT_INVALID_SSLV2_HEADER); @@ -473,7 +409,7 @@ static int SSLv2Decode(uint8_t direction, SSLState *ssl_state, return (input - initial_input); } - switch (ssl_state->cur_content_type) { + switch (ssl_state->curr_connp->content_type) { case SSLV2_MT_ERROR: SCLogWarning(SC_ERR_ALPARSER, "SSLV2_MT_ERROR msg_type received. " "Error encountered in establishing the sslv2 " @@ -486,99 +422,99 @@ static int SSLv2Decode(uint8_t direction, SSLState *ssl_state, ssl_state->flags |= SSL_AL_FLAG_STATE_CLIENT_HELLO; ssl_state->flags |= SSL_AL_FLAG_SSL_CLIENT_HS; - if (ssl_state->record_lengths_length == 3) { - switch (ssl_state->bytes_processed) { + if (ssl_state->curr_connp->record_lengths_length == 3) { + switch (ssl_state->curr_connp->bytes_processed) { case 4: if (input_len >= 6) { - ssl_state->session_id_length = input[4] << 8; - ssl_state->session_id_length |= input[5]; + ssl_state->curr_connp->session_id_length = input[4] << 8; + ssl_state->curr_connp->session_id_length |= input[5]; input += 6; input_len -= 6; - ssl_state->bytes_processed += 6; - if (ssl_state->session_id_length == 0) { + ssl_state->curr_connp->bytes_processed += 6; + if (ssl_state->curr_connp->session_id_length == 0) { ssl_state->flags |= SSL_AL_FLAG_SSL_NO_SESSION_ID; } break; } else { input++; - ssl_state->bytes_processed++; + ssl_state->curr_connp->bytes_processed++; if (--input_len == 0) break; } case 5: input++; - ssl_state->bytes_processed++; + ssl_state->curr_connp->bytes_processed++; if (--input_len == 0) break; case 6: input++; - ssl_state->bytes_processed++; + ssl_state->curr_connp->bytes_processed++; if (--input_len == 0) break; case 7: input++; - ssl_state->bytes_processed++; + ssl_state->curr_connp->bytes_processed++; if (--input_len == 0) break; case 8: - ssl_state->session_id_length = *(input++) << 8; - ssl_state->bytes_processed++; + ssl_state->curr_connp->session_id_length = *(input++) << 8; + ssl_state->curr_connp->bytes_processed++; if (--input_len == 0) break; case 9: - ssl_state->session_id_length |= *(input++); - ssl_state->bytes_processed++; + ssl_state->curr_connp->session_id_length |= *(input++); + ssl_state->curr_connp->bytes_processed++; if (--input_len == 0) break; - } /* switch (ssl_state->bytes_processed) */ + } /* switch (ssl_state->curr_connp->bytes_processed) */ - /* ssl_state->record_lengths_length is 3 */ + /* ssl_state->curr_connp->record_lengths_length is 3 */ } else { - switch (ssl_state->bytes_processed) { + switch (ssl_state->curr_connp->bytes_processed) { case 3: if (input_len >= 6) { - ssl_state->session_id_length = input[4] << 8; - ssl_state->session_id_length |= input[5]; + ssl_state->curr_connp->session_id_length = input[4] << 8; + ssl_state->curr_connp->session_id_length |= input[5]; input += 6; input_len -= 6; - ssl_state->bytes_processed += 6; - if (ssl_state->session_id_length == 0) { + ssl_state->curr_connp->bytes_processed += 6; + if (ssl_state->curr_connp->session_id_length == 0) { ssl_state->flags |= SSL_AL_FLAG_SSL_NO_SESSION_ID; } break; } else { input++; - ssl_state->bytes_processed++; + ssl_state->curr_connp->bytes_processed++; if (--input_len == 0) break; } case 4: input++; - ssl_state->bytes_processed++; + ssl_state->curr_connp->bytes_processed++; if (--input_len == 0) break; case 5: input++; - ssl_state->bytes_processed++; + ssl_state->curr_connp->bytes_processed++; if (--input_len == 0) break; case 6: input++; - ssl_state->bytes_processed++; + ssl_state->curr_connp->bytes_processed++; if (--input_len == 0) break; case 7: - ssl_state->session_id_length = *(input++) << 8; - ssl_state->bytes_processed++; + ssl_state->curr_connp->session_id_length = *(input++) << 8; + ssl_state->curr_connp->bytes_processed++; if (--input_len == 0) break; case 8: - ssl_state->session_id_length |= *(input++); - ssl_state->bytes_processed++; + ssl_state->curr_connp->session_id_length |= *(input++); + ssl_state->curr_connp->bytes_processed++; if (--input_len == 0) break; - } /* switch (ssl_state->bytes_processed) */ - } /* else - if (ssl_state->record_lengths_length == 3) */ + } /* switch (ssl_state->curr_connp->bytes_processed) */ + } /* else - if (ssl_state->curr_connp->record_lengths_length == 3) */ break; @@ -601,7 +537,7 @@ static int SSLv2Decode(uint8_t direction, SSLState *ssl_state, case SSLV2_MT_SERVER_VERIFY: case SSLV2_MT_SERVER_FINISHED: if (direction == 0 && - !(ssl_state->cur_content_type & SSLV2_MT_CLIENT_CERTIFICATE)) { + !(ssl_state->curr_connp->content_type & SSLV2_MT_CLIENT_CERTIFICATE)) { SCLogDebug("Incorrect SSL Record type sent in the toserver " "direction!"); } @@ -643,11 +579,11 @@ static int SSLv2Decode(uint8_t direction, SSLState *ssl_state, break; } - if (input_len + ssl_state->bytes_processed >= - (ssl_state->record_length + ssl_state->record_lengths_length)) { + if (input_len + ssl_state->curr_connp->bytes_processed >= + (ssl_state->curr_connp->record_length + ssl_state->curr_connp->record_lengths_length)) { /* looks like we have another record after this*/ - uint32_t diff = ssl_state->record_length + - ssl_state->record_lengths_length + - ssl_state->bytes_processed; + uint32_t diff = ssl_state->curr_connp->record_length + + ssl_state->curr_connp->record_lengths_length + - ssl_state->curr_connp->bytes_processed; input += diff; SSLParserReset(ssl_state); return (input - initial_input); @@ -656,7 +592,7 @@ static int SSLv2Decode(uint8_t direction, SSLState *ssl_state, * currently parsing */ } else { input += input_len; - ssl_state->bytes_processed += input_len; + ssl_state->curr_connp->bytes_processed += input_len; return (input - initial_input); } } @@ -668,9 +604,9 @@ static int SSLv3Decode(uint8_t direction, SSLState *ssl_state, int retval = 0; uint32_t parsed = 0; - if (ssl_state->bytes_processed < SSLV3_RECORD_LEN) { + if (ssl_state->curr_connp->bytes_processed < SSLV3_RECORD_LEN) { retval = SSLv3ParseRecord(direction, ssl_state, input, input_len); - if (retval == -1) { + if (retval < 0) { AppLayerDecoderEventsSetEvent(ssl_state->f, TLS_DECODER_EVENT_INVALID_TLS_HEADER); return -1; } else { @@ -683,7 +619,7 @@ static int SSLv3Decode(uint8_t direction, SSLState *ssl_state, return parsed; } - switch (ssl_state->cur_content_type) { + switch (ssl_state->curr_connp->content_type) { /* we don't need any data from these types */ case SSLV3_CHANGE_CIPHER_SPEC: ssl_state->flags |= SSL_AL_FLAG_CHANGE_CIPHER_SPEC; @@ -707,12 +643,14 @@ static int SSLv3Decode(uint8_t direction, SSLState *ssl_state, pstate->flags |= APP_LAYER_PARSER_NO_REASSEMBLY; } + break; + case SSLV3_HANDSHAKE_PROTOCOL: if (ssl_state->flags & SSL_AL_FLAG_CHANGE_CIPHER_SPEC) break; retval = SSLv3ParseHandshakeProtocol(ssl_state, input + parsed, input_len); - if (retval == -1) { + if (retval < 0) { AppLayerDecoderEventsSetEvent(ssl_state->f, TLS_DECODER_EVENT_INVALID_HANDSHAKE_MESSAGE); return -1; } else { @@ -724,7 +662,7 @@ static int SSLv3Decode(uint8_t direction, SSLState *ssl_state, } parsed += retval; input_len -= retval; - if (ssl_state->bytes_processed == ssl_state->record_length + SSLV3_RECORD_LEN) { + if (ssl_state->curr_connp->bytes_processed == ssl_state->curr_connp->record_length + SSLV3_RECORD_LEN) { SSLParserReset(ssl_state); } return parsed; @@ -733,13 +671,15 @@ static int SSLv3Decode(uint8_t direction, SSLState *ssl_state, break; default: + /* \todo fix the event from invalid rule to unknown rule */ AppLayerDecoderEventsSetEvent(ssl_state->f, TLS_DECODER_EVENT_INVALID_RECORD_TYPE); - return -1; + /* we still need to parse the record */ + break; } - if (input_len + ssl_state->bytes_processed >= ssl_state->record_length + SSLV3_RECORD_LEN) { + if (input_len + ssl_state->curr_connp->bytes_processed >= ssl_state->curr_connp->record_length + SSLV3_RECORD_LEN) { /* looks like we have another record */ - uint32_t diff = ssl_state->record_length + SSLV3_RECORD_LEN - ssl_state->bytes_processed; + uint32_t diff = ssl_state->curr_connp->record_length + SSLV3_RECORD_LEN - ssl_state->curr_connp->bytes_processed; parsed += diff; SSLParserReset(ssl_state); return parsed; @@ -748,7 +688,7 @@ static int SSLv3Decode(uint8_t direction, SSLState *ssl_state, * currently parsing */ } else { parsed += input_len; - ssl_state->bytes_processed += input_len; + ssl_state->curr_connp->bytes_processed += input_len; return parsed; } @@ -775,58 +715,68 @@ static int SSLv3Decode(uint8_t direction, SSLState *ssl_state, * \retval >=0 On success. */ static int SSLDecode(Flow *f, uint8_t direction, void *alstate, AppLayerParserState *pstate, - uint8_t *input, uint32_t input_len) + uint8_t *input, uint32_t ilen) { SSLState *ssl_state = (SSLState *)alstate; int retval = 0; uint8_t counter = 0; + int32_t input_len = (int32_t)ilen; + ssl_state->f = f; + if (direction == 0) + ssl_state->curr_connp = &ssl_state->client_connp; + else + ssl_state->curr_connp = &ssl_state->server_connp; + /* if we have more than one record */ - while (input_len) { + while (input_len > 0) { if (counter++ == 30) { SCLogDebug("Looks like we have looped quite a bit. Reset state " "and get out of here"); SSLParserReset(ssl_state); - return 0; + return -1; } - /* ssl_state->bytes_processed is either ways it is either 0 for a + /* ssl_state->bytes_processed is 0 for a * fresh record or positive to indicate a record currently being * parsed */ - switch (ssl_state->bytes_processed) { + switch (ssl_state->curr_connp->bytes_processed) { /* fresh record */ case 0: /* only SSLv2, has one of the top 2 bits set */ if (input[0] & 0x80 || input[0] & 0x40) { SCLogDebug("SSLv2 detected"); - ssl_state->cur_ssl_version = SSL_VERSION_2; + ssl_state->curr_connp->version = SSL_VERSION_2; retval = SSLv2Decode(direction, ssl_state, pstate, input, input_len); - if (retval == -1) { + if (retval < 0) { SCLogDebug("Error parsing SSLv2.x. Reseting parser " "state. Let's get outta here"); SSLParserReset(ssl_state); - return 0; + return -1; } else { input_len -= retval; input += retval; } } else { SCLogDebug("SSLv3.x detected"); + /* we will keep it this way till our record parser tells + * us what exact version it is */ + ssl_state->curr_connp->version = TLS_VERSION_UNKNOWN; retval = SSLv3Decode(direction, ssl_state, pstate, input, input_len); - if (retval == -1) { + if (retval < 0) { SCLogDebug("Error parsing SSLv3.x. Reseting parser " "state. Let's get outta here"); SSLParserReset(ssl_state); - return 0; + return -1; } else { input_len -= retval; input += retval; - if (ssl_state->bytes_processed == SSLV3_RECORD_LEN - && ssl_state->record_length == 0) { + if (ssl_state->curr_connp->bytes_processed == SSLV3_RECORD_LEN + && ssl_state->curr_connp->record_length == 0) { /* empty record */ SSLParserReset(ssl_state); } @@ -838,7 +788,7 @@ static int SSLDecode(Flow *f, uint8_t direction, void *alstate, AppLayerParserSt default: /* we would have established by now if we are dealing with * SSLv2 or above */ - if (ssl_state->cur_ssl_version == SSL_VERSION_2) { + if (ssl_state->curr_connp->version == SSL_VERSION_2) { SCLogDebug("Continuing parsing SSLv2 record from where we " "previously left off"); retval = SSLv2Decode(direction, ssl_state, pstate, input, @@ -863,15 +813,15 @@ static int SSLDecode(Flow *f, uint8_t direction, void *alstate, AppLayerParserSt SSLParserReset(ssl_state); return 0; } else { - if ((uint32_t)retval > input_len) { + if (retval > input_len) { SCLogDebug("Error parsing SSLv3.x. Reseting parser " "state. Let's get outta here"); SSLParserReset(ssl_state); } input_len -= retval; input += retval; - if (ssl_state->bytes_processed == SSLV3_RECORD_LEN - && ssl_state->record_length == 0) { + if (ssl_state->curr_connp->bytes_processed == SSLV3_RECORD_LEN + && ssl_state->curr_connp->record_length == 0) { /* empty record */ SSLParserReset(ssl_state); } @@ -879,7 +829,7 @@ static int SSLDecode(Flow *f, uint8_t direction, void *alstate, AppLayerParserSt } break; - } /* switch (ssl_state->bytes_processed) */ + } /* switch (ssl_state->curr_connp->bytes_processed) */ } /* while (input_len) */ return 1; @@ -921,12 +871,20 @@ void SSLStateFree(void *p) { SSLState *ssl_state = (SSLState *)p; - if (ssl_state->trec) - SCFree(ssl_state->trec); - if (ssl_state->cert0_subject) - SCFree(ssl_state->cert0_subject); - if (ssl_state->cert0_issuerdn) - SCFree(ssl_state->cert0_issuerdn); + if (ssl_state->client_connp.trec) + SCFree(ssl_state->client_connp.trec); + if (ssl_state->client_connp.cert0_subject) + SCFree(ssl_state->client_connp.cert0_subject); + if (ssl_state->client_connp.cert0_issuerdn) + SCFree(ssl_state->client_connp.cert0_issuerdn); + + if (ssl_state->server_connp.trec) + SCFree(ssl_state->server_connp.trec); + if (ssl_state->server_connp.cert0_subject) + SCFree(ssl_state->server_connp.cert0_subject); + if (ssl_state->server_connp.cert0_issuerdn) + SCFree(ssl_state->server_connp.cert0_issuerdn); + SCFree(ssl_state); return; @@ -1037,16 +995,16 @@ static int SSLParserTest01(void) goto end; } - if (ssl_state->client_content_type != 0x16) { + if (ssl_state->client_connp.content_type != 0x16) { printf("expected content_type %" PRIu8 ", got %" PRIu8 ": ", 0x16, - ssl_state->client_content_type); + ssl_state->client_connp.content_type); result = 0; goto end; } - if (ssl_state->client_version != TLS_VERSION_10) { + if (ssl_state->client_connp.version != TLS_VERSION_10) { printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ", - TLS_VERSION_10, ssl_state->client_version); + TLS_VERSION_10, ssl_state->client_connp.version); result = 0; goto end; } @@ -1093,16 +1051,16 @@ static int SSLParserTest02(void) goto end; } - if (ssl_state->client_content_type != 0x16) { + if (ssl_state->client_connp.content_type != 0x16) { printf("expected content_type %" PRIu8 ", got %" PRIu8 ": ", 0x16, - ssl_state->client_content_type); + ssl_state->client_connp.content_type); result = 0; goto end; } - if (ssl_state->client_version != TLS_VERSION_10) { + if (ssl_state->client_connp.version != TLS_VERSION_10) { printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ", - TLS_VERSION_10, ssl_state->client_version); + TLS_VERSION_10, ssl_state->client_connp.version); result = 0; goto end; } @@ -1158,16 +1116,16 @@ static int SSLParserTest03(void) goto end; } - if (ssl_state->client_content_type != 0x16) { + if (ssl_state->client_connp.content_type != 0x16) { printf("expected content_type %" PRIu8 ", got %" PRIu8 ": ", 0x16, - ssl_state->client_content_type); + ssl_state->client_connp.content_type); result = 0; goto end; } - if (ssl_state->client_version != TLS_VERSION_10) { + if (ssl_state->client_connp.version != TLS_VERSION_10) { printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ", - TLS_VERSION_10, ssl_state->client_version); + TLS_VERSION_10, ssl_state->client_connp.version); result = 0; goto end; } @@ -1232,16 +1190,16 @@ static int SSLParserTest04(void) goto end; } - if (ssl_state->client_content_type != 0x16) { + if (ssl_state->client_connp.content_type != 0x16) { printf("expected content_type %" PRIu8 ", got %" PRIu8 ": ", 0x16, - ssl_state->client_content_type); + ssl_state->client_connp.content_type); result = 0; goto end; } - if (ssl_state->client_version != TLS_VERSION_10) { + if (ssl_state->client_connp.version != TLS_VERSION_10) { printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ", - TLS_VERSION_10, ssl_state->client_version); + TLS_VERSION_10, ssl_state->client_connp.version); result = 0; goto end; } @@ -1315,16 +1273,16 @@ static int SSLParserTest05(void) goto end; } - if (ssl_state->client_content_type != 0x17) { + if (ssl_state->client_connp.content_type != 0x17) { printf("expected content_type %" PRIu8 ", got %" PRIu8 ": ", 0x17, - ssl_state->client_content_type); + ssl_state->client_connp.content_type); result = 0; goto end; } - if (ssl_state->client_version != TLS_VERSION_10) { + if (ssl_state->client_connp.version != TLS_VERSION_10) { printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ", - TLS_VERSION_10, ssl_state->client_version); + TLS_VERSION_10, ssl_state->client_connp.client_version); result = 0; goto end; } @@ -1411,16 +1369,16 @@ static int SSLParserTest06(void) goto end; } - if (ssl_state->client_content_type != 0x17) { + if (ssl_state->client_connp.content_type != 0x17) { printf("expected content_type %" PRIu8 ", got %" PRIu8 ": ", 0x17, - ssl_state->client_content_type); + ssl_state->client_connp._content_type); result = 0; goto end; } - if (ssl_state->client_version != TLS_VERSION_10) { + if (ssl_state->client_connp.version != TLS_VERSION_10) { printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ", - TLS_VERSION_10, ssl_state->client_version); + TLS_VERSION_10, ssl_state->client_connp.version); result = 0; goto end; } @@ -1531,16 +1489,16 @@ static int SSLParserMultimsgTest01(void) goto end; } - if (ssl_state->client_content_type != 0x16) { + if (ssl_state->client_connp.content_type != 0x16) { printf("expected content_type %" PRIu8 ", got %" PRIu8 ": ", 0x16, - ssl_state->client_content_type); + ssl_state->client_connp.content_type); result = 0; goto end; } - if (ssl_state->client_version != TLS_VERSION_10) { + if (ssl_state->client_connp.version != TLS_VERSION_10) { printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ", - TLS_VERSION_10, ssl_state->client_version); + TLS_VERSION_10, ssl_state->client_connp.version); result = 0; goto end; } @@ -1605,16 +1563,16 @@ static int SSLParserMultimsgTest02(void) goto end; } - if (ssl_state->server_content_type != 0x16) { + if (ssl_state->server_connp.content_type != 0x16) { printf("expected content_type %" PRIu8 ", got %" PRIu8 ": ", 0x16, - ssl_state->server_content_type); + ssl_state->server_connp.content_type); result = 0; goto end; } - if (ssl_state->server_version != 0x0301) { + if (ssl_state->server_connp.version != 0x0301) { printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ", 0x0301, - ssl_state->server_version); + ssl_state->server_connp.version); result = 0; goto end; } @@ -1668,16 +1626,16 @@ static int SSLParserTest07(void) goto end; } - if (ssl_state->client_content_type != 0x16) { + if (ssl_state->client_connp.content_type != 0x16) { printf("expected content_type %" PRIu8 ", got %" PRIu8 ": ", 0x17, - ssl_state->client_content_type); + ssl_state->client_connp.content_type); result = 0; goto end; } - if (ssl_state->client_version != SSL_VERSION_3) { + if (ssl_state->client_connp.version != SSL_VERSION_3) { printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ", - SSL_VERSION_3, ssl_state->client_version); + SSL_VERSION_3, ssl_state->client_connp.version); result = 0; goto end; } @@ -1752,16 +1710,16 @@ static int SSLParserTest08(void) goto end; } - if (ssl_state->client_content_type != 0x17) { + if (ssl_state->client_connp.content_type != 0x17) { printf("expected content_type %" PRIu8 ", got %" PRIu8 ": ", 0x17, - ssl_state->client_content_type); + ssl_state->client_connp.content_type); result = 0; goto end; } - if (ssl_state->client_version != SSL_VERSION_3) { + if (ssl_state->client_connp.version != SSL_VERSION_3) { printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ", - SSL_VERSION_3, ssl_state->client_version); + SSL_VERSION_3, ssl_state->client_connp.version); result = 0; goto end; } @@ -1850,23 +1808,16 @@ static int SSLParserTest09(void) goto end; } - if (ssl_state->client_content_type != 0x16) { + if (ssl_state->client_connp.content_type != 0x16) { printf("expected content_type %" PRIu8 ", got %" PRIu8 ": ", 0x17, - ssl_state->client_content_type); - result = 0; - goto end; - } - - if (ssl_state->client_version != SSL_VERSION_3) { - printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ", - SSL_VERSION_3, ssl_state->client_version); + ssl_state->client_connp.content_type); result = 0; goto end; } - if (ssl_state->handshake_client_hello_ssl_version != SSL_VERSION_3) { + if (ssl_state->client_connp.version != SSL_VERSION_3) { printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ", - SSL_VERSION_3, ssl_state->handshake_client_hello_ssl_version); + SSL_VERSION_3, ssl_state->client_connp.version); result = 0; goto end; } @@ -1935,23 +1886,16 @@ static int SSLParserTest10(void) goto end; } - if (ssl_state->client_content_type != 0x16) { + if (ssl_state->client_connp.content_type != 0x16) { printf("expected content_type %" PRIu8 ", got %" PRIu8 ": ", 0x17, - ssl_state->client_content_type); - result = 0; - goto end; - } - - if (ssl_state->client_version != SSL_VERSION_3) { - printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ", - SSL_VERSION_3, ssl_state->client_version); + ssl_state->client_connp.content_type); result = 0; goto end; } - if (ssl_state->handshake_client_hello_ssl_version != SSL_VERSION_3) { + if (ssl_state->client_connp.version != SSL_VERSION_3) { printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ", - SSL_VERSION_3, ssl_state->handshake_client_hello_ssl_version); + SSL_VERSION_3, ssl_state->client_connp.version); result = 0; goto end; } @@ -2019,23 +1963,16 @@ static int SSLParserTest11(void) goto end; } - if (ssl_state->client_content_type != 0x16) { + if (ssl_state->client_connp.content_type != 0x16) { printf("expected content_type %" PRIu8 ", got %" PRIu8 ": ", 0x17, - ssl_state->client_content_type); + ssl_state->client_connp.content_type); result = 0; goto end; } - if (ssl_state->client_version != SSL_VERSION_3) { + if (ssl_state->client_connp.version != SSL_VERSION_3) { printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ", - SSL_VERSION_3, ssl_state->client_version); - result = 0; - goto end; - } - - if (ssl_state->handshake_client_hello_ssl_version != SSL_VERSION_3) { - printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ", - SSL_VERSION_3, ssl_state->handshake_client_hello_ssl_version); + SSL_VERSION_3, ssl_state->client_connp.version); result = 0; goto end; } @@ -2115,23 +2052,16 @@ static int SSLParserTest12(void) goto end; } - if (ssl_state->client_content_type != 0x16) { + if (ssl_state->client_connp.content_type != 0x16) { printf("expected content_type %" PRIu8 ", got %" PRIu8 ": ", 0x17, - ssl_state->client_content_type); - result = 0; - goto end; - } - - if (ssl_state->client_version != SSL_VERSION_3) { - printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ", - SSL_VERSION_3, ssl_state->client_version); + ssl_state->client_connp.content_type); result = 0; goto end; } - if (ssl_state->handshake_client_hello_ssl_version != SSL_VERSION_3) { + if (ssl_state->client_connp.version != SSL_VERSION_3) { printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ", - SSL_VERSION_3, ssl_state->handshake_client_hello_ssl_version); + SSL_VERSION_3, ssl_state->client_connp.version); result = 0; goto end; } @@ -2223,23 +2153,16 @@ static int SSLParserTest13(void) goto end; } - if (ssl_state->client_content_type != 0x16) { + if (ssl_state->client_connp.content_type != 0x16) { printf("expected content_type %" PRIu8 ", got %" PRIu8 ": ", 0x17, - ssl_state->client_content_type); + ssl_state->client_connp.content_type); result = 0; goto end; } - if (ssl_state->client_version != SSL_VERSION_3) { + if (ssl_state->client_connp.version != SSL_VERSION_3) { printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ", - SSL_VERSION_3, ssl_state->client_version); - result = 0; - goto end; - } - - if (ssl_state->handshake_client_hello_ssl_version != SSL_VERSION_3) { - printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ", - SSL_VERSION_3, ssl_state->handshake_client_hello_ssl_version); + SSL_VERSION_3, ssl_state->client_connp.version); result = 0; goto end; } @@ -2628,15 +2551,15 @@ static int SSLParserTest21(void) goto end; } - if (app_state->client_content_type != SSLV2_MT_CLIENT_HELLO) { + if (app_state->client_connp.content_type != SSLV2_MT_CLIENT_HELLO) { printf("expected content_type %" PRIu8 ", got %" PRIu8 ": ", - SSLV2_MT_SERVER_HELLO, app_state->client_content_type); + SSLV2_MT_SERVER_HELLO, app_state->client_connp.content_type); goto end; } - if (app_state->client_version != SSL_VERSION_2) { + if (app_state->client_connp.version != SSL_VERSION_2) { printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ", - SSL_VERSION_2, app_state->client_version); + SSL_VERSION_2, app_state->client_connp.version); goto end; } @@ -2688,16 +2611,16 @@ static int SSLParserTest22(void) goto end; } - if (app_state->server_content_type != SSLV2_MT_SERVER_HELLO) { + if (app_state->server_connp.content_type != SSLV2_MT_SERVER_HELLO) { printf("expected content_type %" PRIu8 ", got %" PRIu8 ": ", - SSLV2_MT_SERVER_HELLO, app_state->server_content_type); + SSLV2_MT_SERVER_HELLO, app_state->server_connp.content_type); result = 0; goto end; } - if (app_state->server_version != SSL_VERSION_2) { + if (app_state->server_connp.version != SSL_VERSION_2) { printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ", - SSL_VERSION_2, app_state->server_version); + SSL_VERSION_2, app_state->server_connp.version); result = 0; goto end; } @@ -2985,16 +2908,16 @@ static int SSLParserTest23(void) goto end; } - if (app_state->client_content_type != SSLV2_MT_CLIENT_HELLO) { + if (app_state->client_connp.content_type != SSLV2_MT_CLIENT_HELLO) { printf("expected content_type %" PRIu8 ", got %" PRIu8 ": ", - SSLV2_MT_CLIENT_HELLO, app_state->client_content_type); + SSLV2_MT_CLIENT_HELLO, app_state->client_connp.content_type); result = 0; goto end; } - if (app_state->client_version != SSL_VERSION_2) { + if (app_state->client_connp.version != SSL_VERSION_2) { printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ", - SSL_VERSION_2, app_state->client_version); + SSL_VERSION_2, app_state->client_connp.version); result = 0; goto end; } @@ -3016,16 +2939,16 @@ static int SSLParserTest23(void) goto end; } - if (app_state->server_content_type != SSLV3_HANDSHAKE_PROTOCOL) { + if (app_state->server_connp.content_type != SSLV3_HANDSHAKE_PROTOCOL) { printf("expected content_type %" PRIu8 ", got %" PRIu8 ": ", - SSLV3_HANDSHAKE_PROTOCOL, app_state->server_content_type); + SSLV3_HANDSHAKE_PROTOCOL, app_state->server_connp.content_type); result = 0; goto end; } - if (app_state->server_version != SSL_VERSION_3) { + if (app_state->server_connp.version != SSL_VERSION_3) { printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ", - SSL_VERSION_3, app_state->server_version); + SSL_VERSION_3, app_state->server_connp.version); result = 0; goto end; } @@ -3048,16 +2971,16 @@ static int SSLParserTest23(void) /* with multiple records the client content type hold the type from the last * record */ - if (app_state->client_content_type != SSLV3_HANDSHAKE_PROTOCOL) { + if (app_state->client_connp.content_type != SSLV3_HANDSHAKE_PROTOCOL) { printf("expected content_type %" PRIu8 ", got %" PRIu8 ": ", - SSLV3_HANDSHAKE_PROTOCOL, app_state->client_content_type); + SSLV3_HANDSHAKE_PROTOCOL, app_state->client_connp.content_type); result = 0; goto end; } - if (app_state->client_version != SSL_VERSION_3) { + if (app_state->client_connp.version != SSL_VERSION_3) { printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ", - SSL_VERSION_3, app_state->client_version); + SSL_VERSION_3, app_state->client_connp.version); result = 0; goto end; } @@ -3082,16 +3005,16 @@ static int SSLParserTest23(void) /* with multiple records the serve content type hold the type from the last * record */ - if (app_state->server_content_type != SSLV3_HANDSHAKE_PROTOCOL) { + if (app_state->server_connp.content_type != SSLV3_HANDSHAKE_PROTOCOL) { printf("expected content_type %" PRIu8 ", got %" PRIu8 ": ", - SSLV3_HANDSHAKE_PROTOCOL, app_state->server_content_type); + SSLV3_HANDSHAKE_PROTOCOL, app_state->server_connp.content_type); result = 0; goto end; } - if (app_state->server_version != SSL_VERSION_3) { + if (app_state->server_connp.version != SSL_VERSION_3) { printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ", - SSL_VERSION_3, app_state->server_version); + SSL_VERSION_3, app_state->server_connp.version); result = 0; goto end; } @@ -3115,16 +3038,16 @@ static int SSLParserTest23(void) goto end; } - if (app_state->client_content_type != SSLV3_APPLICATION_PROTOCOL) { + if (app_state->client_connp.content_type != SSLV3_APPLICATION_PROTOCOL) { printf("expected content_type %" PRIu8 ", got %" PRIu8 ": ", - SSLV3_APPLICATION_PROTOCOL, app_state->client_content_type); + SSLV3_APPLICATION_PROTOCOL, app_state->client_connp.content_type); result = 0; goto end; } - if (app_state->client_version != SSL_VERSION_3) { + if (app_state->client_connp.version != SSL_VERSION_3) { printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ", - SSL_VERSION_3, app_state->client_version); + SSL_VERSION_3, app_state->client_connp.version); result = 0; goto end; } @@ -3222,23 +3145,16 @@ static int SSLParserTest24(void) goto end; } - if (ssl_state->client_content_type != 0x16) { + if (ssl_state->client_connp.content_type != 0x16) { printf("expected content_type %" PRIu8 ", got %" PRIu8 ": ", 0x16, - ssl_state->client_content_type); - result = 0; - goto end; - } - - if (ssl_state->client_version != SSL_VERSION_3) { - printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ", - SSL_VERSION_3, ssl_state->client_version); + ssl_state->client_connp.content_type); result = 0; goto end; } - if (ssl_state->handshake_client_hello_ssl_version != SSL_VERSION_3) { + if (ssl_state->client_connp.version != SSL_VERSION_3) { printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ", - SSL_VERSION_3, ssl_state->handshake_client_hello_ssl_version); + SSL_VERSION_3, ssl_state->client_connp.version); result = 0; goto end; } diff --git a/src/app-layer-ssl.h b/src/app-layer-ssl.h index b1751740fd..d50948669f 100644 --- a/src/app-layer-ssl.h +++ b/src/app-layer-ssl.h @@ -75,14 +75,7 @@ enum { TLS_VERSION_12 = 0x0303, }; -/** - * \brief SSLv[2.0|3.[0|1|2|3]] state structure. - * - * Structure to store the SSL state values. - */ -typedef struct SSLState_ { - Flow *f; - +typedef struct SSLStateConnp_ { /* record length */ uint32_t record_length; /* record length's length for SSLv2 */ @@ -92,34 +85,18 @@ typedef struct SSLState_ { uint32_t message_start; uint32_t message_length; - /* holds some state flags we need */ - uint32_t flags; - - uint16_t client_version; - uint16_t server_version; - uint8_t client_content_type; - uint8_t server_content_type; - - /* dummy var. You can replace this if you want to */ - uint8_t pad0; + uint16_t version; + uint8_t content_type; - uint8_t cur_content_type; + uint8_t handshake_type; uint32_t handshake_length; - uint16_t handshake_client_hello_ssl_version; - uint16_t handshake_server_hello_ssl_version; + /* the no of bytes processed in the currently parsed record */ uint16_t bytes_processed; - uint16_t cur_ssl_version; - uint8_t handshake_type; - /* sslv2 client hello session id length */ uint16_t session_id_length; - /* the ciphersuite, chosen by the server */ - uint16_t ciphersuite; - uint8_t compressionmethod; - char *cert0_subject; char *cert0_issuerdn; @@ -128,6 +105,23 @@ typedef struct SSLState_ { uint8_t *trec; uint16_t trec_len; uint16_t trec_pos; +} SSLStateConnp; + +/** + * \brief SSLv[2.0|3.[0|1|2|3]] state structure. + * + * Structure to store the SSL state values. + */ +typedef struct SSLState_ { + Flow *f; + + /* holds some state flags we need */ + uint32_t flags; + + SSLStateConnp *curr_connp; + + SSLStateConnp client_connp; + SSLStateConnp server_connp; } SSLState; void RegisterSSLParsers(void); diff --git a/src/app-layer-tls-handshake.c b/src/app-layer-tls-handshake.c index 5c1089f5fb..053b6d0948 100644 --- a/src/app-layer-tls-handshake.c +++ b/src/app-layer-tls-handshake.c @@ -78,44 +78,6 @@ static void TLSCertificateErrCodeToWarning(SSLState *ssl_state, uint32_t errcode }; } -int DecodeTLSHandshakeServerHello(SSLState *ssl_state, uint8_t *input, uint32_t input_len) -{ - uint32_t version, length, ciphersuite; - uint8_t compressionmethod; - - if (input_len < 40) - return -1; - - version = input[0]<<8 | input[1]; - ssl_state->handshake_server_hello_ssl_version = version; - - input += 2; - input_len -= 2; - - /* skip the random field */ - input += 32; - - /* skip the session ID */ - length = input[0]; - input += 1 + length; - - ciphersuite = input[0]<<8 | input[1]; - ssl_state->ciphersuite = ciphersuite; - - input += 2; - - compressionmethod = input[0]; - ssl_state->compressionmethod = compressionmethod; - - input += 1; - - /* extensions (like renegotiation) */ - - SCLogDebug("TLS Handshake Version %.4x Cipher %d Compression %d\n", version, ciphersuite, compressionmethod); - - return ssl_state->message_length; -} - int DecodeTLSHandshakeServerCertificate(SSLState *ssl_state, uint8_t *input, uint32_t input_len) { uint32_t certificates_length, cur_cert_length; @@ -160,8 +122,8 @@ int DecodeTLSHandshakeServerCertificate(SSLState *ssl_state, uint8_t *input, uin } else { //SCLogInfo("TLS Cert %d: %s\n", i, buffer); if (i==0) { - ssl_state->cert0_subject = SCStrdup(buffer); - if (ssl_state->cert0_subject == NULL) { + ssl_state->curr_connp->cert0_subject = SCStrdup(buffer); + if (ssl_state->curr_connp->cert0_subject == NULL) { DerFree(cert); return -1; } @@ -173,8 +135,8 @@ int DecodeTLSHandshakeServerCertificate(SSLState *ssl_state, uint8_t *input, uin } else { //SCLogInfo("TLS IssuerDN %d: %s\n", i, buffer); if (i==0) { - ssl_state->cert0_issuerdn = SCStrdup(buffer); - if (ssl_state->cert0_issuerdn == NULL) { + ssl_state->curr_connp->cert0_issuerdn = SCStrdup(buffer); + if (ssl_state->curr_connp->cert0_issuerdn == NULL) { DerFree(cert); return -1; } diff --git a/src/app-layer-tls-handshake.h b/src/app-layer-tls-handshake.h index fa91c7dbe1..6041f7fbc5 100644 --- a/src/app-layer-tls-handshake.h +++ b/src/app-layer-tls-handshake.h @@ -35,7 +35,6 @@ #ifndef __APP_LAYER_TLS_HANDSHAKE_H__ #define __APP_LAYER_TLS_HANDSHAKE_H__ -int DecodeTLSHandshakeServerHello(SSLState *ssl_state, uint8_t *input, uint32_t input_len); int DecodeTLSHandshakeServerCertificate(SSLState *ssl_state, uint8_t *input, uint32_t input_len); #endif /* __APP_LAYER_TLS_HANDSHAKE_H__ */ diff --git a/src/detect-ssl-version.c b/src/detect-ssl-version.c index 1e9dc3f63a..f2d33eb6f9 100644 --- a/src/detect-ssl-version.c +++ b/src/detect-ssl-version.c @@ -134,12 +134,12 @@ int DetectSslVersionMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx, if (flags & STREAM_TOCLIENT) { SCLogDebug("server (toclient) version is 0x%02X", - app_state->server_version); - ver = app_state->server_version; + app_state->server_connp.version); + ver = app_state->server_connp.version; } else if (flags & STREAM_TOSERVER) { SCLogDebug("client (toserver) version is 0x%02X", - app_state->client_version); - ver = app_state->client_version; + app_state->client_connp.ersion); + ver = app_state->client_connp.version; } FLOWLOCK_UNLOCK(f); @@ -482,18 +482,18 @@ static int DetectSslVersionTestDetect01(void) goto end; } - if (app_state->client_content_type != 0x16) { - printf("expected content_type %" PRIu8 ", got %" PRIu8 ": ", 0x16, app_state->client_content_type); + if (app_state->client_connp.content_type != 0x16) { + printf("expected content_type %" PRIu8 ", got %" PRIu8 ": ", 0x16, app_state->client_connp.content_type); goto end; } - if (app_state->client_version != TLS_VERSION_10) { - printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ", TLS_VERSION_10, app_state->client_version); + if (app_state->client_connp.version != TLS_VERSION_10) { + printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ", TLS_VERSION_10, app_state->client_connp.version); goto end; } - SCLogDebug("app_state is at %p, app_state->server_version 0x%02X app_state->client_version 0x%02X", - app_state, app_state->server_version, app_state->client_version); + SCLogDebug("app_state is at %p, app_state->server_connp.version 0x%02X app_state->client_connp.version 0x%02X", + app_state, app_state->server_connp.version, app_state->client_connp.version); /* do detect */ SigMatchSignatures(&th_v, de_ctx, det_ctx, p); @@ -597,13 +597,13 @@ static int DetectSslVersionTestDetect02(void) goto end; } - if (app_state->client_content_type != 0x16) { - printf("expected content_type %" PRIu8 ", got %" PRIu8 ": ", 0x16, app_state->client_content_type); + if (app_state->client_connp.content_type != 0x16) { + printf("expected content_type %" PRIu8 ", got %" PRIu8 ": ", 0x16, app_state->client_connp.content_type); goto end; } - if (app_state->client_version != TLS_VERSION_10) { - printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ", TLS_VERSION_10, app_state->client_version); + if (app_state->client_connp.version != TLS_VERSION_10) { + printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ", TLS_VERSION_10, app_state->client_connp.version); goto end; } @@ -722,13 +722,13 @@ static int DetectSslVersionTestDetect03(void) goto end; } - if (app_state->client_content_type != 0x16) { - printf("expected content_type %" PRIu8 ", got %" PRIu8 ": ", 0x16, app_state->client_content_type); + if (app_state->client_connp.content_type != 0x16) { + printf("expected content_type %" PRIu8 ", got %" PRIu8 ": ", 0x16, app_state->client_connp.content_type); goto end; } - if (app_state->client_version != TLS_VERSION_10) { - printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ", TLS_VERSION_10, app_state->client_version); + if (app_state->client_connp.version != TLS_VERSION_10) { + printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ", TLS_VERSION_10, app_state->client_connp.version); goto end; } diff --git a/src/detect-tls-version.c b/src/detect-tls-version.c index 104b9417de..b36986740b 100644 --- a/src/detect-tls-version.c +++ b/src/detect-tls-version.c @@ -127,11 +127,11 @@ int DetectTlsVersionMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Flow * if (flags & STREAM_TOCLIENT) { SCLogDebug("server (toclient) version is 0x%02X", ssl_state->server_version); - if (tls_data->ver == ssl_state->server_version) + if (tls_data->ver == ssl_state->server_connp.version) ret = 1; } else if (flags & STREAM_TOSERVER) { SCLogDebug("client (toserver) version is 0x%02X", ssl_state->client_version); - if (tls_data->ver == ssl_state->client_version) + if (tls_data->ver == ssl_state->client_connp.version) ret = 1; } FLOWLOCK_UNLOCK(f); @@ -387,18 +387,22 @@ static int DetectTlsVersionTestDetect01(void) { goto end; } - if (ssl_state->client_content_type != 0x16) { - printf("expected content_type %" PRIu8 ", got %" PRIu8 ": ", 0x16, ssl_state->client_content_type); + if (ssl_state->client_connp.content_type != 0x16) { + printf("expected content_type %" PRIu8 ", got %" PRIu8 ": ", + 0x16, ssl_state->client_connp.content_type); goto end; } - if (ssl_state->client_version != TLS_VERSION_10) { - printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ", TLS_VERSION_10, ssl_state->client_version); + if (ssl_state->client_connp.version != TLS_VERSION_10) { + printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ", + TLS_VERSION_10, ssl_state->client_connp.version); goto end; } - SCLogDebug("ssl_state is at %p, ssl_state->server_version 0x%02X ssl_state->client_version 0x%02X", - ssl_state, ssl_state->server_version, ssl_state->client_version); + SCLogDebug("ssl_state is at %p, ssl_state->server_version 0x%02X " + "ssl_state->client_version 0x%02X", + ssl_state, ssl_state->server_connp.version, + ssl_state->client_connp.version); /* do detect */ SigMatchSignatures(&th_v, de_ctx, det_ctx, p); @@ -500,13 +504,15 @@ static int DetectTlsVersionTestDetect02(void) { goto end; } - if (ssl_state->client_content_type != 0x16) { - printf("expected content_type %" PRIu8 ", got %" PRIu8 ": ", 0x16, ssl_state->client_content_type); + if (ssl_state->client_connp.content_type != 0x16) { + printf("expected content_type %" PRIu8 ", got %" PRIu8 ": ", + 0x16, ssl_state->client_connp.content_type); goto end; } - if (ssl_state->client_version != TLS_VERSION_10) { - printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ", TLS_VERSION_10, ssl_state->client_version); + if (ssl_state->client_connp.version != TLS_VERSION_10) { + printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ", + TLS_VERSION_10, ssl_state->client_connp.version); goto end; } @@ -626,13 +632,15 @@ static int DetectTlsVersionTestDetect03(void) { goto end; } - if (ssl_state->client_content_type != 0x16) { - printf("expected content_type %" PRIu8 ", got %" PRIu8 ": ", 0x16, ssl_state->client_content_type); + if (ssl_state->client_connp.content_type != 0x16) { + printf("expected content_type %" PRIu8 ", got %" PRIu8 ": ", + 0x16, ssl_state->client_connp.content_type); goto end; } - if (ssl_state->client_version != TLS_VERSION_10) { - printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ", TLS_VERSION_10, ssl_state->client_version); + if (ssl_state->client_connp.version != TLS_VERSION_10) { + printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ", + TLS_VERSION_10, ssl_state->client_connp.version); goto end; } diff --git a/src/detect-tls.c b/src/detect-tls.c index 29e5810869..b539b12512 100644 --- a/src/detect-tls.c +++ b/src/detect-tls.c @@ -168,10 +168,19 @@ static int DetectTlsSubjectMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, } else { ret = 0; } - if (ssl_state->cert0_subject != NULL) { - SCLogDebug("TLS: Subject is [%s], looking for [%s]\n", ssl_state->cert0_subject, tls_data->subject); - if (strstr(ssl_state->cert0_subject, tls_data->subject) != NULL) { + SSLStateConnp *connp = NULL; + if (flags & STREAM_TOSERVER) { + connp = &ssl_state->client_connp; + } else { + connp = &ssl_state->server_connp; + } + + if (connp->cert0_subject != NULL) { + SCLogDebug("TLS: Subject is [%s], looking for [%s]\n", + connp->cert0_subject, tls_data->subject); + + if (strstr(connp->cert0_subject, tls_data->subject) != NULL) { if (tls_data->flags & DETECT_CONTENT_NEGATED) { ret = 0; } else { @@ -362,10 +371,19 @@ static int DetectTlsIssuerDNMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx } else { ret = 0; } - if (ssl_state->cert0_issuerdn != NULL) { - SCLogDebug("TLS: IssuerDN is [%s], looking for [%s]\n", ssl_state->cert0_issuerdn, tls_data->issuerdn); - if (strstr(ssl_state->cert0_issuerdn, tls_data->issuerdn) != NULL) { + SSLStateConnp *connp = NULL; + if (flags & STREAM_TOSERVER) { + connp = &ssl_state->client_connp; + } else { + connp = &ssl_state->server_connp; + } + + if (connp->cert0_issuerdn != NULL) { + SCLogDebug("TLS: IssuerDN is [%s], looking for [%s]\n", + connp->cert0_issuerdn, tls_data->issuerdn); + + if (strstr(connp->cert0_issuerdn, tls_data->issuerdn) != NULL) { if (tls_data->flags & DETECT_CONTENT_NEGATED) { ret = 0; } else {