]> git.ipfire.org Git - people/ms/suricata.git/commitdiff
ssl parser fix/updates
authorAnoop Saldanha <poonaatsoc@gmail.com>
Fri, 18 May 2012 15:48:30 +0000 (21:18 +0530)
committerVictor Julien <victor@inliniac.net>
Thu, 7 Jun 2012 15:07:18 +0000 (17:07 +0200)
src/app-layer-ssl.c
src/app-layer-ssl.h
src/app-layer-tls-handshake.c
src/app-layer-tls-handshake.h
src/detect-ssl-version.c
src/detect-tls-version.c
src/detect-tls.c

index 722accd7b4fe98b11707ab37ffac12c3e96ed6a3..e555b67baafd4534c9c366598c5e73470ee6bed4 100644 (file)
@@ -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;
     }
index b1751740fdeed1fbb2700f1b3f509c8c7aeb6644..d50948669fc6af0220501cf352542344a3a6be01 100644 (file)
@@ -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);
index 5c1089f5fb28f2c593bf28e471fa17891e60d981..053b6d09481bc25925bbf5e76c993e2779e2d684 100644 (file)
@@ -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;
                     }
index fa91c7dbe11312b94603bfed98be61835dea8dc2..6041f7fbc5ca8f9c5b1c3de2d3511199b6e772b1 100644 (file)
@@ -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__ */
index 1e9dc3f63af18a35a0267bf70a5768e6e57ba05c..f2d33eb6f949b8458fec0f017016d6f2cb2c70a8 100644 (file)
@@ -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;
     }
 
index 104b9417de65f112550cd07cc78d7480a19ad56b..b36986740bb730b2716f843fd6d2ff901ef124da 100644 (file)
@@ -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;
     }
 
index 29e58108698d3568c7a4191f74e4b12d573aed42..b539b12512337b730f7647ae4c5a57d49998fb84 100644 (file)
@@ -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 {