]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
bug #955 - Fix SSL parsing issue.
authorAnoop Saldanha <anoopsaldanha@gmail.com>
Fri, 13 Sep 2013 14:27:29 +0000 (19:57 +0530)
committerVictor Julien <victor@inliniac.net>
Tue, 24 Sep 2013 13:22:18 +0000 (15:22 +0200)
The parser wasn't carrying out a bounds check on record length while
in the middle of parsing a handshake.  As a result we would step onto the
next record header and consider it a part of the current handshake.

- Contains an unittest to test the issue.
- Disable the duplicate parser unittest registration.

The issue came to light through an irregular ssl record, which was
reported by Sebastian Roschke, via CVE-2013-5919.

Thanks to Sebastian Roschke for reporting this issue.

src/app-layer-ssl.c
src/app-layer-ssl.h
src/runmode-unittests.c

index 74bc993b3b05ee44a54437c1cc02739ee1bf7ad2..542070e9f75c5ffd806571f196fc69d8543e4ce9 100644 (file)
@@ -66,6 +66,8 @@ SCEnumCharMap tls_decoder_event_table[ ] = {
     { "CERTIFICATE_INVALID_LENGTH",  TLS_DECODER_EVENT_CERTIFICATE_INVALID_LENGTH },
     { "CERTIFICATE_INVALID_STRING",  TLS_DECODER_EVENT_CERTIFICATE_INVALID_STRING },
     { "ERROR_MESSAGE_ENCOUNTERED",   TLS_DECODER_EVENT_ERROR_MSG_ENCOUNTERED },
+    /* used as a generic error event */
+    { "INVALID_SSL_RECORD",          TLS_DECODER_EVENT_INVALID_SSL_RECORD },
     { NULL,                          -1 },
 };
 
@@ -161,6 +163,10 @@ static int SSLv3ParseHandshakeType(SSLState *ssl_state, uint8_t *input,
             }
             uint32_t write_len = 0;
             if ((ssl_state->curr_connp->bytes_processed + input_len) > ssl_state->curr_connp->record_length + (SSLV3_RECORD_HDR_LEN)) {
+                if ((ssl_state->curr_connp->record_length + SSLV3_RECORD_HDR_LEN) < ssl_state->curr_connp->bytes_processed) {
+                    AppLayerDecoderEventsSetEvent(ssl_state->f, TLS_DECODER_EVENT_INVALID_SSL_RECORD);
+                    return -1;
+                }
                 write_len = (ssl_state->curr_connp->record_length + SSLV3_RECORD_HDR_LEN) - ssl_state->curr_connp->bytes_processed;
             } else {
                 write_len = input_len;
@@ -175,6 +181,10 @@ static int SSLv3ParseHandshakeType(SSLState *ssl_state, uint8_t *input,
                  * while we expect only the number of bytes parsed bytes
                  * from the *current* fragment
                  */
+                if (write_len < (ssl_state->curr_connp->trec_pos - rc)) {
+                    AppLayerDecoderEventsSetEvent(ssl_state->f, TLS_DECODER_EVENT_INVALID_SSL_RECORD);
+                    return -1;
+                }
                 uint32_t diff = write_len - (ssl_state->curr_connp->trec_pos - rc);
                 ssl_state->curr_connp->bytes_processed += diff;
 
@@ -199,16 +209,25 @@ static int SSLv3ParseHandshakeType(SSLState *ssl_state, uint8_t *input,
         case SSLV3_HS_CERTIFICATE_STATUS:
             break;
         default:
-            break;
+            AppLayerDecoderEventsSetEvent(ssl_state->f, TLS_DECODER_EVENT_INVALID_SSL_RECORD);
+            return -1;
     }
 
     uint32_t write_len = 0;
     if ((ssl_state->curr_connp->bytes_processed + input_len) >= ssl_state->curr_connp->record_length + (SSLV3_RECORD_HDR_LEN)) {
+        if ((ssl_state->curr_connp->record_length + SSLV3_RECORD_HDR_LEN) < ssl_state->curr_connp->bytes_processed) {
+            AppLayerDecoderEventsSetEvent(ssl_state->f, TLS_DECODER_EVENT_INVALID_SSL_RECORD);
+            return -1;
+        }
         write_len = (ssl_state->curr_connp->record_length + SSLV3_RECORD_HDR_LEN) - ssl_state->curr_connp->bytes_processed;
     } else {
         write_len = input_len;
     }
     if ((ssl_state->curr_connp->trec_pos + write_len) >= ssl_state->curr_connp->message_length) {
+        if (ssl_state->curr_connp->message_length < ssl_state->curr_connp->trec_pos) {
+            AppLayerDecoderEventsSetEvent(ssl_state->f, TLS_DECODER_EVENT_INVALID_SSL_RECORD);
+            return -1;
+        }
         parsed += ssl_state->curr_connp->message_length - ssl_state->curr_connp->trec_pos;
 
         ssl_state->curr_connp->bytes_processed += ssl_state->curr_connp->message_length - ssl_state->curr_connp->trec_pos;
@@ -233,7 +252,10 @@ static int SSLv3ParseHandshakeProtocol(SSLState *ssl_state, uint8_t *input,
     uint8_t *initial_input = input;
     int retval;
 
-    if (input_len == 0) {
+    if (input_len == 0 ||
+        ssl_state->curr_connp->bytes_processed ==
+        (ssl_state->curr_connp->record_length + SSLV3_RECORD_HDR_LEN))
+    {
         return 0;
     }
 
@@ -242,26 +264,37 @@ static int SSLv3ParseHandshakeProtocol(SSLState *ssl_state, uint8_t *input,
             ssl_state->curr_connp->handshake_type = *(input++);
             ssl_state->curr_connp->bytes_processed++;
             ssl_state->curr_connp->hs_bytes_processed++;
-            if (--input_len == 0)
-                break;
+            if (--input_len == 0 ||
+                ssl_state->curr_connp->bytes_processed ==
+                (ssl_state->curr_connp->record_length + SSLV3_RECORD_HDR_LEN))
+            {
+                return (input - initial_input);
+            }
         case 1:
             ssl_state->curr_connp->message_length = *(input++) << 16;
             ssl_state->curr_connp->bytes_processed++;
             ssl_state->curr_connp->hs_bytes_processed++;
-            if (--input_len == 0)
-                break;
+            if (--input_len == 0 ||
+                ssl_state->curr_connp->bytes_processed ==
+                (ssl_state->curr_connp->record_length + SSLV3_RECORD_HDR_LEN))
+            {
+                return (input - initial_input);
+            }
         case 2:
             ssl_state->curr_connp->message_length |= *(input++) << 8;
             ssl_state->curr_connp->bytes_processed++;
             ssl_state->curr_connp->hs_bytes_processed++;
-            if (--input_len == 0)
-                break;
+            if (--input_len == 0 ||
+                ssl_state->curr_connp->bytes_processed ==
+                (ssl_state->curr_connp->record_length + SSLV3_RECORD_HDR_LEN))
+            {
+                return (input - initial_input);
+            }
         case 3:
             ssl_state->curr_connp->message_length |= *(input++);
             ssl_state->curr_connp->bytes_processed++;
             ssl_state->curr_connp->hs_bytes_processed++;
-            if (--input_len == 0)
-                break;
+            --input_len;
     }
 
     retval = SSLv3ParseHandshakeType(ssl_state, input, input_len);
@@ -668,18 +701,21 @@ static int SSLv3Decode(uint8_t direction, SSLState *ssl_state,
 
             if (ssl_state->curr_connp->record_length < 4) {
                 SSLParserReset(ssl_state);
+                AppLayerDecoderEventsSetEvent(ssl_state->f, TLS_DECODER_EVENT_INVALID_SSL_RECORD);
                 return -1;
             }
 
             retval = SSLv3ParseHandshakeProtocol(ssl_state, input + parsed, input_len);
             if (retval < 0) {
                 AppLayerDecoderEventsSetEvent(ssl_state->f, TLS_DECODER_EVENT_INVALID_HANDSHAKE_MESSAGE);
+                AppLayerDecoderEventsSetEvent(ssl_state->f, TLS_DECODER_EVENT_INVALID_SSL_RECORD);
                 return -1;
             } else {
                 if ((uint32_t)retval > input_len) {
                     SCLogDebug("Error parsing SSLv3.x.  Reseting parser "
                             "state.  Let's get outta here");
                     SSLParserReset(ssl_state);
+                    AppLayerDecoderEventsSetEvent(ssl_state->f, TLS_DECODER_EVENT_INVALID_SSL_RECORD);
                     return -1;
                 }
                 parsed += retval;
@@ -695,11 +731,16 @@ static int SSLv3Decode(uint8_t direction, SSLState *ssl_state,
         default:
             /* \todo fix the event from invalid rule to unknown rule */
             AppLayerDecoderEventsSetEvent(ssl_state->f, TLS_DECODER_EVENT_INVALID_RECORD_TYPE);
-            /* we still need to parse the record */
-            break;
+            AppLayerDecoderEventsSetEvent(ssl_state->f, TLS_DECODER_EVENT_INVALID_SSL_RECORD);
+            return -1;
     }
 
     if (input_len + ssl_state->curr_connp->bytes_processed >= ssl_state->curr_connp->record_length + SSLV3_RECORD_HDR_LEN) {
+        if ((ssl_state->curr_connp->record_length + SSLV3_RECORD_HDR_LEN) < ssl_state->curr_connp->bytes_processed) {
+            /* defensive checks.  Something's wrong. */
+            AppLayerDecoderEventsSetEvent(ssl_state->f, TLS_DECODER_EVENT_INVALID_SSL_RECORD);
+            return -1;
+        }
         /* looks like we have another record */
         uint32_t diff = ssl_state->curr_connp->record_length + SSLV3_RECORD_HDR_LEN - ssl_state->curr_connp->bytes_processed;
         parsed += diff;
@@ -758,6 +799,7 @@ static int SSLDecode(Flow *f, uint8_t direction, void *alstate, AppLayerParserSt
             SCLogDebug("Looks like we have looped quite a bit.  Reset state "
                        "and get out of here");
             SSLParserReset(ssl_state);
+            AppLayerDecoderEventsSetEvent(ssl_state->f, TLS_DECODER_EVENT_INVALID_SSL_RECORD);
             return -1;
         }
 
@@ -777,6 +819,7 @@ static int SSLDecode(Flow *f, uint8_t direction, void *alstate, AppLayerParserSt
                         SCLogDebug("Error parsing SSLv2.x.  Reseting parser "
                                    "state.  Let's get outta here");
                         SSLParserReset(ssl_state);
+                        AppLayerDecoderEventsSetEvent(ssl_state->f, TLS_DECODER_EVENT_INVALID_SSL_RECORD);
                         return -1;
                     } else {
                         input_len -= retval;
@@ -793,6 +836,7 @@ static int SSLDecode(Flow *f, uint8_t direction, void *alstate, AppLayerParserSt
                         SCLogDebug("Error parsing SSLv3.x.  Reseting parser "
                                    "state.  Let's get outta here");
                         SSLParserReset(ssl_state);
+                        AppLayerDecoderEventsSetEvent(ssl_state->f, TLS_DECODER_EVENT_INVALID_SSL_RECORD);
                         return -1;
                     } else {
                         input_len -= retval;
@@ -3273,6 +3317,406 @@ end:
     return result;
 }
 
+/**
+ * \test Test for bug #955 and CVE-2013-5919.  The data is from the
+ *       pcap that was used to report this issue.
+ */
+static int SSLParserTest25(void)
+{
+    int result = 0;
+    Flow f;
+    uint8_t client_hello[] = {
+        0x16, 0x03, 0x01, 0x00, 0xd3, 0x01, 0x00, 0x00,
+        0xcf, 0x03, 0x01, 0x51, 0x60, 0xc2, 0x15, 0x36,
+        0x73, 0xf5, 0xb8, 0x58, 0x55, 0x3b, 0x68, 0x12,
+        0x7d, 0xe3, 0x28, 0xa3, 0xe1, 0x02, 0x79, 0x2d,
+        0x12, 0xe1, 0xf4, 0x24, 0x12, 0xa2, 0x9e, 0xf1,
+        0x08, 0x49, 0x68, 0x20, 0x0e, 0x96, 0x46, 0x3d,
+        0x84, 0x5a, 0xc6, 0x55, 0xeb, 0x3b, 0x53, 0x77,
+        0xf4, 0x8e, 0xf4, 0xd2, 0x8b, 0xec, 0xd6, 0x99,
+        0x63, 0x64, 0x62, 0xf8, 0x3f, 0x3b, 0xd5, 0x35,
+        0x45, 0x1b, 0x16, 0xac, 0x00, 0x46, 0x00, 0x04,
+        0x00, 0x05, 0x00, 0x2f, 0x00, 0x35, 0xc0, 0x02,
+        0xc0, 0x04, 0xc0, 0x05, 0xc0, 0x0c, 0xc0, 0x0e,
+        0xc0, 0x0f, 0xc0, 0x07, 0xc0, 0x09, 0xc0, 0x0a,
+        0xc0, 0x11, 0xc0, 0x13, 0xc0, 0x14, 0x00, 0x33,
+        0x00, 0x39, 0x00, 0x32, 0x00, 0x38, 0x00, 0x0a,
+        0xc0, 0x03, 0xc0, 0x0d, 0xc0, 0x08, 0xc0, 0x12,
+        0x00, 0x16, 0x00, 0x13, 0x00, 0x09, 0x00, 0x15,
+        0x00, 0x12, 0x00, 0x03, 0x00, 0x08, 0x00, 0x14,
+        0x00, 0x11, 0x00, 0xff, 0x01, 0x00, 0x00, 0x40,
+        0x00, 0x0b, 0x00, 0x04, 0x03, 0x00, 0x01, 0x02,
+        0x00, 0x0a, 0x00, 0x34, 0x00, 0x32, 0x00, 0x0e,
+        0x00, 0x0d, 0x00, 0x19, 0x00, 0x0b, 0x00, 0x0c,
+        0x00, 0x18, 0x00, 0x09, 0x00, 0x0a, 0x00, 0x16,
+        0x00, 0x17, 0x00, 0x08, 0x00, 0x06, 0x00, 0x07,
+        0x00, 0x14, 0x00, 0x15, 0x00, 0x04, 0x00, 0x05,
+        0x00, 0x12, 0x00, 0x13, 0x00, 0x01, 0x00, 0x02,
+        0x00, 0x03, 0x00, 0x0f, 0x00, 0x10, 0x00, 0x11
+    };
+    uint32_t client_hello_len = sizeof(client_hello);
+
+    uint8_t server_hello_certificate_done[] = {
+        0x16, 0x03, 0x01, 0x00, 0x51, 0x02, 0x00, 0x00,
+        0x4d, 0x03, 0x01, 0x51, 0x60, 0xc2, 0x17, 0xb7,
+        0x81, 0xaa, 0x27, 0xa1, 0xd5, 0xfa, 0x14, 0xc1,
+        0xe0, 0x05, 0xab, 0x75, 0xf2, 0x51, 0xe7, 0x6e,
+        0xe6, 0xf9, 0xc4, 0x8f, 0x16, 0x08, 0x26, 0x6c,
+        0x1b, 0x86, 0x90, 0x20, 0x0a, 0x38, 0x90, 0x2d,
+        0x17, 0x7d, 0xb7, 0x6b, 0x6b, 0xe5, 0xeb, 0x61,
+        0x90, 0x35, 0xf8, 0xcd, 0xb1, 0x2a, 0x69, 0x6e,
+        0x0e, 0x3e, 0x5f, 0x90, 0xdc, 0x2f, 0x51, 0x45,
+        0x68, 0x63, 0xe3, 0xb3, 0x00, 0x05, 0x00, 0x00,
+        0x05, 0xff, 0x01, 0x00, 0x01, 0x00, 0x16, 0x03,
+        0x01, 0x07, 0x60, 0x0b, 0x00, 0x07, 0x5c, 0x00,
+        0x07, 0x59, 0x00, 0x03, 0xcc, 0x30, 0x82, 0x03,
+        0xc8, 0x30, 0x82, 0x03, 0x31, 0xa0, 0x03, 0x02,
+        0x01, 0x02, 0x02, 0x10, 0x01, 0x7f, 0x77, 0xde,
+        0xb3, 0xbc, 0xbb, 0x23, 0x5d, 0x44, 0xcc, 0xc7,
+        0xdb, 0xa6, 0x2e, 0x72, 0x30, 0x0d, 0x06, 0x09,
+        0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
+        0x05, 0x05, 0x00, 0x30, 0x81, 0xba, 0x31, 0x1f,
+        0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
+        0x16, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67,
+        0x6e, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20,
+        0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x31,
+        0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0b,
+        0x13, 0x0e, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69,
+        0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e,
+        0x31, 0x33, 0x30, 0x31, 0x06, 0x03, 0x55, 0x04,
+        0x0b, 0x13, 0x2a, 0x56, 0x65, 0x72, 0x69, 0x53,
+        0x69, 0x67, 0x6e, 0x20, 0x49, 0x6e, 0x74, 0x65,
+        0x72, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61,
+        0x6c, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72,
+        0x20, 0x43, 0x41, 0x20, 0x2d, 0x20, 0x43, 0x6c,
+        0x61, 0x73, 0x73, 0x20, 0x33, 0x31, 0x49, 0x30,
+        0x47, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x40,
+        0x77, 0x77, 0x77, 0x2e, 0x76, 0x65, 0x72, 0x69,
+        0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d,
+        0x2f, 0x43, 0x50, 0x53, 0x20, 0x49, 0x6e, 0x63,
+        0x6f, 0x72, 0x70, 0x2e, 0x62, 0x79, 0x20, 0x52,
+        0x65, 0x66, 0x2e, 0x20, 0x4c, 0x49, 0x41, 0x42,
+        0x49, 0x4c, 0x49, 0x54, 0x59, 0x20, 0x4c, 0x54,
+        0x44, 0x2e, 0x28, 0x63, 0x29, 0x39, 0x37, 0x20,
+        0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e,
+        0x30, 0x1e, 0x17, 0x0d, 0x31, 0x32, 0x30, 0x36,
+        0x32, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
+        0x5a, 0x17, 0x0d, 0x31, 0x33, 0x31, 0x32, 0x33,
+        0x31, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a,
+        0x30, 0x68, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03,
+        0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31,
+        0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08,
+        0x13, 0x0a, 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f,
+        0x72, 0x6e, 0x69, 0x61, 0x31, 0x12, 0x30, 0x10,
+        0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x09, 0x50,
+        0x61, 0x6c, 0x6f, 0x20, 0x41, 0x6c, 0x74, 0x6f,
+        0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04,
+        0x0a, 0x13, 0x0e, 0x46, 0x61, 0x63, 0x65, 0x62,
+        0x6f, 0x6f, 0x6b, 0x2c, 0x20, 0x49, 0x6e, 0x63,
+        0x2e, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55,
+        0x04, 0x02, 0x14, 0x0e, 0x2a, 0x2e, 0x66, 0x61,
+        0x63, 0x65, 0x62, 0x6f, 0x6f, 0x6b, 0x2e, 0x63,
+        0x6f, 0x6d, 0x30, 0x81, 0x9f, 0x30, 0x0d, 0x06,
+        0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
+        0x01, 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d, 0x00,
+        0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xae,
+        0x94, 0xb1, 0x71, 0xe2, 0xde, 0xcc, 0xc1, 0x69,
+        0x3e, 0x05, 0x10, 0x63, 0x24, 0x01, 0x02, 0xe0,
+        0x68, 0x9a, 0xe8, 0x3c, 0x39, 0xb6, 0xb3, 0xe7,
+        0x4b, 0x97, 0xd4, 0x8d, 0x7b, 0x23, 0x68, 0x91,
+        0x00, 0xb0, 0xb4, 0x96, 0xee, 0x62, 0xf0, 0xe6,
+        0xd3, 0x56, 0xbc, 0xf4, 0xaa, 0x0f, 0x50, 0x64,
+        0x34, 0x02, 0xf5, 0xd1, 0x76, 0x6a, 0xa9, 0x72,
+        0x83, 0x5a, 0x75, 0x64, 0x72, 0x3f, 0x39, 0xbb,
+        0xef, 0x52, 0x90, 0xde, 0xd9, 0xbc, 0xdb, 0xf9,
+        0xd3, 0xd5, 0x5d, 0xfa, 0xd2, 0x3a, 0xa0, 0x3d,
+        0xc6, 0x04, 0xc5, 0x4d, 0x29, 0xcf, 0x1d, 0x4b,
+        0x3b, 0xdb, 0xd1, 0xa8, 0x09, 0xcf, 0xae, 0x47,
+        0xb4, 0x4c, 0x7e, 0xae, 0x17, 0xc5, 0x10, 0x9b,
+        0xee, 0x24, 0xa9, 0xcf, 0x4a, 0x8d, 0x91, 0x1b,
+        0xb0, 0xfd, 0x04, 0x15, 0xae, 0x4c, 0x3f, 0x43,
+        0x0a, 0xa1, 0x2a, 0x55, 0x7e, 0x2a, 0xe1, 0x02,
+        0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x1e,
+        0x30, 0x82, 0x01, 0x1a, 0x30, 0x09, 0x06, 0x03,
+        0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30,
+        0x44, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x3d,
+        0x30, 0x3b, 0x30, 0x39, 0x06, 0x0b, 0x60, 0x86,
+        0x48, 0x01, 0x86, 0xf8, 0x45, 0x01, 0x07, 0x17,
+        0x03, 0x30, 0x2a, 0x30, 0x28, 0x06, 0x08, 0x2b,
+        0x06, 0x01, 0x05, 0x05, 0x07, 0x00, 0x01, 0x16,
+        0x1c, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f,
+        0x2f, 0x77, 0x77, 0x77, 0x2e, 0x76, 0x65, 0x72,
+        0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f,
+        0x6d, 0x2f, 0x72, 0x70, 0x61, 0x30, 0x3c, 0x06,
+        0x03, 0x55, 0x1d, 0x1f, 0x04, 0x35, 0x30, 0x33,
+        0x30, 0x31, 0xa0, 0x2f, 0xa0, 0x2d, 0x86, 0x2b,
+        0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x53,
+        0x56, 0x52, 0x49, 0x6e, 0x74, 0x6c, 0x2d, 0x63,
+        0x72, 0x6c, 0x2e, 0x76, 0x65, 0x72, 0x69, 0x73,
+        0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
+        0x53, 0x56, 0x52, 0x49, 0x6e, 0x74, 0x6c, 0x2e,
+        0x63, 0x72, 0x6c, 0x30, 0x1d, 0x06, 0x03, 0x55,
+        0x1d, 0x25, 0x04, 0x16, 0x30, 0x14, 0x06, 0x08,
+        0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01,
+        0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
+        0x03, 0x02, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d,
+        0x0f, 0x04, 0x04, 0x03, 0x02, 0x05, 0xa0, 0x30,
+        0x34, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
+        0x07, 0x01, 0x01, 0x04, 0x28, 0x30, 0x26, 0x30,
+        0x24, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
+        0x07, 0x30, 0x01, 0x86, 0x18, 0x68, 0x74, 0x74,
+        0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70,
+        0x2e, 0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67,
+        0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x27, 0x06,
+        0x03, 0x55, 0x1d, 0x11, 0x04, 0x20, 0x30, 0x1e,
+        0x82, 0x0e, 0x2a, 0x2e, 0x66, 0x61, 0x63, 0x65,
+        0x62, 0x6f, 0x6f, 0x6b, 0x2e, 0x63, 0x6f, 0x6d,
+        0x82, 0x0c, 0x66, 0x61, 0x63, 0x65, 0x62, 0x6f,
+        0x6f, 0x6b, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x0d,
+        0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+        0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x81, 0x81,
+        0x00, 0x5b, 0x6c, 0x2b, 0x75, 0xf8, 0xed, 0x30,
+        0xaa, 0x51, 0xaa, 0xd3, 0x6a, 0xba, 0x59, 0x5e,
+        0x55, 0x51, 0x41, 0x95, 0x1f, 0x81, 0xa5, 0x3b,
+        0x44, 0x79, 0x10, 0xac, 0x1f, 0x76, 0xff, 0x78,
+        0xfc, 0x27, 0x81, 0x61, 0x6b, 0x58, 0xf3, 0x12,
+        0x2a, 0xfc, 0x1c, 0x87, 0x01, 0x04, 0x25, 0xe9,
+        0xed, 0x43, 0xdf, 0x1a, 0x7b, 0xa6, 0x49, 0x80,
+        0x60, 0x67, 0xe2, 0x68, 0x8a, 0xf0, 0x3d, 0xb5,
+        0x8c, 0x7d, 0xf4, 0xee, 0x03, 0x30, 0x9a, 0x6a,
+        0xfc, 0x24, 0x7c, 0xcb, 0x13, 0x4d, 0xc3, 0x3e,
+        0x54, 0xc6, 0xbc, 0x1d, 0x51, 0x33, 0xa5, 0x32,
+        0xa7, 0x32, 0x73, 0xb1, 0xd7, 0x9c, 0xad, 0xc0,
+        0x8e, 0x7e, 0x1a, 0x83, 0x11, 0x6d, 0x34, 0x52,
+        0x33, 0x40, 0xb0, 0x30, 0x54, 0x27, 0xa2, 0x17,
+        0x42, 0x82, 0x7c, 0x98, 0x91, 0x66, 0x98, 0xee,
+        0x7e, 0xaf, 0x8c, 0x3b, 0xdd, 0x71, 0x70, 0x08,
+        0x17, 0x00, 0x03, 0x87, 0x30, 0x82, 0x03, 0x83,
+        0x30, 0x82, 0x02, 0xec, 0xa0, 0x03, 0x02, 0x01,
+        0x02, 0x02, 0x10, 0x46, 0xfc, 0xeb, 0xba, 0xb4,
+        0xd0, 0x2f, 0x0f, 0x92, 0x60, 0x98, 0x23, 0x3f,
+        0x93, 0x07, 0x8f, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+        0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05,
+        0x05, 0x00, 0x30, 0x5f, 0x31, 0x0b, 0x30, 0x09,
+        0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55,
+        0x53, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55,
+        0x04, 0x0a, 0x13, 0x0e, 0x56, 0x65, 0x72, 0x69,
+        0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e,
+        0x63, 0x2e, 0x31, 0x37, 0x30, 0x35, 0x06, 0x03,
+        0x55, 0x04, 0x0b, 0x13, 0x2e, 0x43, 0x6c, 0x61,
+        0x73, 0x73, 0x20, 0x33, 0x20, 0x50, 0x75, 0x62,
+        0x6c, 0x69, 0x63, 0x20, 0x50, 0x72, 0x69, 0x6d,
+        0x61, 0x72, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74,
+        0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
+        0x6e, 0x20, 0x41, 0x75, 0x64, 0x68, 0x6f, 0x72,
+        0x69, 0x74, 0x79, 0x30, 0x1e, 0x17, 0x0d, 0x39,
+        0x37, 0x30, 0x34, 0x31, 0x37, 0x30, 0x30, 0x30,
+        0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x31, 0x36,
+        0x31, 0x30, 0x32, 0x34, 0x32, 0x33, 0x35, 0x39,
+        0x35, 0x39, 0x5a, 0x30, 0x81, 0xba, 0x31, 0x1f,
+        0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
+        0x16, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67,
+        0x6e, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20,
+        0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x31,
+        0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0b,
+        0x13, 0x0e, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69,
+        0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e,
+        0x31, 0x33, 0x30, 0x31, 0x06, 0x03, 0x55, 0x04,
+        0x0b, 0x13, 0x2a, 0x56, 0x65, 0x72, 0x69, 0x53,
+        0x69, 0x67, 0x6e, 0x20, 0x49, 0x6e, 0x74, 0x65,
+        0x72, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61,
+        0x6c, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72,
+        0x20, 0x43, 0x41, 0x20, 0x2d, 0x20, 0x43, 0x6c,
+        0x61, 0x73, 0x73, 0x20, 0x33, 0x31, 0x49, 0x30,
+        0x47, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x40,
+        0x77, 0x77, 0x77, 0x2e, 0x76, 0x65, 0x72, 0x69,
+        0x73, 0x69,
+        0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x43,
+        0x50, 0x53, 0x20, 0x49, 0x6e, 0x63, 0x6f, 0x72,
+        0x70, 0x2e, 0x62, 0x79, 0x20, 0x52, 0x65, 0x66,
+        0x2e, 0x20, 0x4c, 0x49, 0x41, 0x42, 0x49, 0x4c,
+        0x49, 0x54, 0x59, 0x20, 0x4c, 0x54, 0x44, 0x2e,
+        0x28, 0x63, 0x29, 0x39, 0x37, 0x20, 0x56, 0x65,
+        0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x30, 0x81,
+        0x9f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
+        0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00,
+        0x03, 0x81, 0x8d, 0x00, 0x30, 0x81, 0x89, 0x02,
+        0x81, 0x81, 0x00, 0xd8, 0x82, 0x80, 0xe8, 0xd6,
+        0x19, 0x02, 0x7d, 0x1f, 0x85, 0x18, 0x39, 0x25,
+        0xa2, 0x65, 0x2b, 0xe1, 0xbf, 0xd4, 0x05, 0xd3,
+        0xbc, 0xe6, 0x36, 0x3b, 0xaa, 0xf0, 0x4c, 0x6c,
+        0x5b, 0xb6, 0xe7, 0xaa, 0x3c, 0x73, 0x45, 0x55,
+        0xb2, 0xf1, 0xbd, 0xea, 0x97, 0x42, 0xed, 0x9a,
+        0x34, 0x0a, 0x15, 0xd4, 0xa9, 0x5c, 0xf5, 0x40,
+        0x25, 0xdd, 0xd9, 0x07, 0xc1, 0x32, 0xb2, 0x75,
+        0x6c, 0xc4, 0xca, 0xbb, 0xa3, 0xfe, 0x56, 0x27,
+        0x71, 0x43, 0xaa, 0x63, 0xf5, 0x30, 0x3e, 0x93,
+        0x28, 0xe5, 0xfa, 0xf1, 0x09, 0x3b, 0xf3, 0xb7,
+        0x4d, 0x4e, 0x39, 0xf7, 0x5c, 0x49, 0x5a, 0xb8,
+        0xc1, 0x1d, 0xd3, 0xb2, 0x8a, 0xfe, 0x70, 0x30,
+        0x95, 0x42, 0xcb, 0xfe, 0x2b, 0x51, 0x8b, 0x5a,
+        0x3c, 0x3a, 0xf9, 0x22, 0x4f, 0x90, 0xb2, 0x02,
+        0xa7, 0x53, 0x9c, 0x4f, 0x34, 0xe7, 0xab, 0x04,
+        0xb2, 0x7b, 0x6f, 0x02, 0x03, 0x01, 0x00, 0x01,
+        0xa3, 0x81, 0xe3, 0x30, 0x81, 0xe0, 0x30, 0x0f,
+        0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x08, 0x30,
+        0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30,
+        0x44, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x3d,
+        0x30, 0x3b, 0x30, 0x39, 0x06, 0x0b, 0x60, 0x86,
+        0x48, 0x01, 0x86, 0xf8, 0x45, 0x01, 0x07, 0x01,
+        0x01, 0x30, 0x2a, 0x30, 0x28, 0x06, 0x08, 0x2b,
+        0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16,
+        0x1c, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f,
+        0x2f, 0x77, 0x77, 0x77, 0x2e, 0x76, 0x65, 0x72,
+        0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f,
+        0x6d, 0x2f, 0x43, 0x50, 0x53, 0x30, 0x34, 0x06,
+        0x03, 0x55, 0x1d, 0x25, 0x04, 0x2d, 0x30, 0x2b,
+        0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
+        0x03, 0x01, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
+        0x05, 0x07, 0x03, 0x02, 0x06, 0x09, 0x60, 0x86,
+        0x48, 0x01, 0x86, 0xf8, 0x42, 0x04, 0x01, 0x06,
+        0x0a, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x45,
+        0x01, 0x08, 0x01, 0x30, 0x0b, 0x06, 0x03, 0x55,
+        0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06,
+        0x30, 0x11, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
+        0x86, 0xf8, 0x42, 0x01, 0x01, 0x04, 0x04, 0x03,
+        0x02, 0x01, 0x06, 0x30, 0x31, 0x06, 0x03, 0x55,
+        0x1d, 0x1f, 0x04, 0x2a, 0x30, 0x28, 0x30, 0x26,
+        0xa0, 0x24, 0xa0, 0x22, 0x86, 0x20, 0x68, 0x74,
+        0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c,
+        0x2e, 0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67,
+        0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x63,
+        0x61, 0x33, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x0d,
+        0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+        0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x81, 0x81,
+        0x00, 0x40, 0x8e, 0x49, 0x97, 0x96, 0x8a, 0x73,
+        0xdd, 0x8e, 0x4d, 0xef, 0x3e, 0x61, 0xb7, 0xca,
+        0xa0, 0x62, 0xad, 0xf4, 0x0e, 0x0a, 0xbb, 0x75,
+        0x3d, 0xe2, 0x6e, 0xd8, 0x2c, 0xc7, 0xbf, 0xf4,
+        0xb9, 0x8c, 0x36, 0x9b, 0xca, 0xa2, 0xd0, 0x9c,
+        0x72, 0x46, 0x39, 0xf6, 0xa6, 0x82, 0x03, 0x65,
+        0x11, 0xc4, 0xbc, 0xbf, 0x2d, 0xa6, 0xf5, 0xd9,
+        0x3b, 0x0a, 0xb5, 0x98, 0xfa, 0xb3, 0x78, 0xb9,
+        0x1e, 0xf2, 0x2b, 0x4c, 0x62, 0xd5, 0xfd, 0xb2,
+        0x7a, 0x1d, 0xdf, 0x33, 0xfd, 0x73, 0xf9, 0xa5,
+        0xd8, 0x2d, 0x8c, 0x2a, 0xea, 0xd1, 0xfc, 0xb0,
+        0x28, 0xb6, 0xe9, 0x49, 0x48, 0x13, 0x4b, 0x83,
+        0x8a, 0x1b, 0x48, 0x7b, 0x24, 0xf7, 0x38, 0xde,
+        0x6f, 0x41, 0x54, 0xb8, 0xab, 0x57, 0x6b, 0x06,
+        0xdf, 0xc7, 0xa2, 0xd4, 0xa9, 0xf6, 0xf1, 0x36,
+        0x62, 0x80, 0x88, 0xf2, 0x8b, 0x75, 0xd6, 0x80,
+        0x75, 0x16, 0x03, 0x01, 0x00, 0x04, 0x0e, 0x00,
+        0x00, 0x00
+    };
+    uint32_t server_hello_certificate_done_len = sizeof(server_hello_certificate_done);
+
+    uint8_t client_key_exchange_cipher_enc_hs[] = {
+        0x16, 0x03, 0x01, 0x00, 0x86, 0x10, 0x00, 0x00,
+        0x80, 0x00, 0x80, 0x14, 0x2b, 0x2f, 0x9f, 0x02,
+        0x1d, 0x4e, 0x0d, 0xa7, 0x41, 0x0f, 0x99, 0xc5,
+        0xe9, 0x49, 0x22, 0x14, 0xa0, 0x42, 0x7b, 0xb4,
+        0x6d, 0x4f, 0x82, 0x3c, 0x3a, 0x6e, 0xed, 0xd5,
+        0x6e, 0x72, 0x71, 0xae, 0x00, 0x4a, 0x9a, 0xc9,
+        0x0e, 0x2d, 0x08, 0xa2, 0xd3, 0x3a, 0xb0, 0xb2,
+        0x1a, 0x56, 0x01, 0x7c, 0x9a, 0xfa, 0xfb, 0x1a,
+        0xd7, 0x7e, 0x20, 0x68, 0x51, 0xd0, 0xfe, 0xd9,
+        0xdc, 0xa7, 0x0b, 0xeb, 0x1a, 0xb6, 0xd3, 0xc7,
+        0x17, 0x1f, 0xf3, 0x6e, 0x91, 0xdd, 0x06, 0x0d,
+        0x48, 0xde, 0xcd, 0x0c, 0x36, 0x8c, 0x83, 0x29,
+        0x9a, 0x40, 0x03, 0xcd, 0xf3, 0x1b, 0xdb, 0xd8,
+        0x44, 0x6b, 0x75, 0xf3, 0x5a, 0x9f, 0x26, 0x1a,
+        0xc4, 0x16, 0x35, 0x8f, 0xc1, 0x15, 0x19, 0xa9,
+        0xdf, 0x07, 0xa9, 0xe5, 0x56, 0x45, 0x6d, 0xca,
+        0x20, 0x3c, 0xcf, 0x8e, 0xbe, 0x44, 0x68, 0x73,
+        0xc8, 0x0b, 0xc7, 0x14, 0x03, 0x01, 0x00, 0x01,
+        0x01, 0x16, 0x03, 0x01, 0x00, 0x24, 0xf9, 0x7e,
+        0x28, 0x77, 0xa9, 0x9a, 0x08, 0x0c, 0x2e, 0xa9,
+        0x09, 0x15, 0x27, 0xcd, 0x93, 0x5f, 0xc0, 0x32,
+        0x0a, 0x8d, 0x62, 0xd3, 0x54, 0x79, 0x6b, 0x51,
+        0xd7, 0xba, 0x02, 0xd6, 0xdb, 0x66, 0xe8, 0x97,
+        0x5d, 0x7a
+    };
+    uint32_t client_key_exchange_cipher_enc_hs_len = sizeof(client_key_exchange_cipher_enc_hs);
+
+    TcpSession ssn;
+
+    memset(&f, 0, sizeof(f));
+    memset(&ssn, 0, sizeof(ssn));
+    f.protoctx = (void *)&ssn;
+
+    StreamTcpInitConfig(TRUE);
+
+    SCMutexLock(&f.m);
+    int r = AppLayerParse(NULL, &f, ALPROTO_TLS, STREAM_TOSERVER, client_hello, client_hello_len);
+    if (r != 0) {
+        printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
+        SCMutexUnlock(&f.m);
+        goto end;
+    }
+    SCMutexUnlock(&f.m);
+
+    SSLState *ssl_state = f.alstate;
+    if (ssl_state == NULL) {
+        printf("no tls state: ");
+        goto end;
+    }
+
+    if (ssl_state->client_connp.bytes_processed != 0 ||
+        ssl_state->client_connp.hs_bytes_processed != 0)
+    {
+        printf("client_hello error\n");
+        goto end;
+    }
+
+    SCMutexLock(&f.m);
+    r = AppLayerParse(NULL, &f, ALPROTO_TLS, STREAM_TOCLIENT,
+                      server_hello_certificate_done,
+                      server_hello_certificate_done_len);
+    if (r != 0) {
+        printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
+        SCMutexUnlock(&f.m);
+        goto end;
+    }
+    SCMutexUnlock(&f.m);
+
+    if (ssl_state->client_connp.bytes_processed != 0 ||
+        ssl_state->client_connp.hs_bytes_processed != 0)
+    {
+        printf("server_hello_certificate_done error\n");
+        goto end;
+    }
+
+    SCMutexLock(&f.m);
+    r = AppLayerParse(NULL, &f, ALPROTO_TLS, STREAM_TOSERVER,
+                      client_key_exchange_cipher_enc_hs,
+                      client_key_exchange_cipher_enc_hs_len);
+    if (r != 0) {
+        printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
+        SCMutexUnlock(&f.m);
+        goto end;
+    }
+    SCMutexUnlock(&f.m);
+
+    /* The reason hs_bytes_processed is 2 is because, the record
+     * immediately after the client key exchange is 2 bytes long,
+     * and next time we see a new handshake, it is after we have
+     * seen a change cipher spec.  Hence when we process the
+     * handshake, we immediately break and don't parse the pdu from
+     * where we left off, and leave the hs_bytes_processed var
+     * isn't reset. */
+    if (ssl_state->client_connp.bytes_processed != 0 ||
+        ssl_state->client_connp.hs_bytes_processed != 2)
+    {
+        printf("client_key_exchange_cipher_enc_hs error\n");
+        goto end;
+    }
+
+    result = 1;
+end:
+    StreamTcpFreeConfig(TRUE);
+    return result;
+}
+
 #endif /* UNITTESTS */
 
 void SSLParserRegisterTests(void)
@@ -3304,6 +3748,7 @@ void SSLParserRegisterTests(void)
     UtRegisterTest("SSLParserTest22", SSLParserTest22, 1);
     UtRegisterTest("SSLParserTest23", SSLParserTest23, 1);
     UtRegisterTest("SSLParserTest24", SSLParserTest24, 1);
+    UtRegisterTest("SSLParserTest25", SSLParserTest25, 1);
 
     UtRegisterTest("SSLParserMultimsgTest01", SSLParserMultimsgTest01, 1);
     UtRegisterTest("SSLParserMultimsgTest02", SSLParserMultimsgTest02, 1);
index 51efb91efedf64b03d59d4985b896e4b9472581b..55a85ae4d7693d78249b52804c194482ceb8c008 100644 (file)
@@ -42,6 +42,7 @@ enum {
     TLS_DECODER_EVENT_CERTIFICATE_INVALID_LENGTH,
     TLS_DECODER_EVENT_CERTIFICATE_INVALID_STRING,
     TLS_DECODER_EVENT_ERROR_MSG_ENCOUNTERED,
+    TLS_DECODER_EVENT_INVALID_SSL_RECORD,
 };
 
 /* Flag to indicate that server will now on send encrypted msgs */
index a3190306e6178acb5472e7e4553bf9d2a0ca144c..8113da5c0a7584e5d907af5b5c1dd92d71947153 100644 (file)
@@ -187,7 +187,6 @@ int RunUnittests(int list_unittests, char *regex_arg)
     DecodePPPRegisterTests();
     DecodeVLANRegisterTests();
     HTPParserRegisterTests();
-    SSLParserRegisterTests();
     SSHParserRegisterTests();
     SMBParserRegisterTests();
     DCERPCParserRegisterTests();