From Yaniv Kaul:
authorAnders Broman <anders.broman@ericsson.com>
Thu, 22 Mar 2012 08:58:19 +0000 (08:58 -0000)
committerAnders Broman <anders.broman@ericsson.com>
Thu, 22 Mar 2012 08:58:19 +0000 (08:58 -0000)
Enhance the SSL dissector to dissect some Hello extensions.

https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=6979

svn path=/trunk/; revision=41736

epan/dissectors/packet-ssl-utils.c
epan/dissectors/packet-ssl-utils.h
epan/dissectors/packet-ssl.c

index a13e66a340d1fe9eb99de6e73b4f6effde32cfb1..d6c20f400e0f636d06c3f382f55702d897044a09 100644 (file)
@@ -898,7 +898,7 @@ const value_string pct_error_code[] = {
 
 /* RFC 4366 */
 const value_string tls_hello_extension_types[] = {
-    { 0, "server_name" },
+    { SSL_HND_HELLO_EXT_SERVER_NAME, "server_name" }, /* RFC 3546 */
     { 1, "max_fragment_length" },
     { 2, "client_certificate_url" },
     { 3, "trusted_ca_keys" },
@@ -915,7 +915,13 @@ const value_string tls_hello_extension_types[] = {
     { 14, "use_srtp" },
     { SSL_HND_HELLO_EXT_HEARTBEAT, "Heartbeat" },  /* RFC 6520 */
     { 35, "SessionTicket TLS" },  /* RFC 4507 */
-    { 65281, "renegotiation_info" },
+    { SSL_HND_HELLO_EXT_NPN, "next_protocol_negotiation"}, /* http://technotes.googlecode.com/git/nextprotoneg.html */
+    { SSL_HND_HELLO_EXT_RENEG_INFO, "renegotiation_info" }, /* RFC 5746 */
+    { 0, NULL }
+};
+
+const value_string tls_hello_ext_server_name_type_vs[] = {
+    { 0, "host_name" },
     { 0, NULL }
 };
 
index 59565b1ef54c40a02033f2fda7f4ed08725e908a..70d37448053dd2fd7a4679cc47b2994c9b5f1698 100644 (file)
 #define PCT_ERR_SERVER_AUTH_FAILED     0x05
 #define PCT_ERR_SPECS_MISMATCH         0x06
 
+#define SSL_HND_HELLO_EXT_SERVER_NAME        0x0
 #define SSL_HND_HELLO_EXT_ELLIPTIC_CURVES    0x000a
 #define SSL_HND_HELLO_EXT_EC_POINT_FORMATS   0x000b
 #define SSL_HND_HELLO_EXT_HEARTBEAT          0x000f
-
+#define SSL_HND_HELLO_EXT_RENEG_INFO         0xff01
+#define SSL_HND_HELLO_EXT_NPN                0x3374
 #define SSL_HND_CERT_STATUS_TYPE_OCSP  1
 
 /*
@@ -188,6 +190,7 @@ extern const value_string tls_cert_status_type[];
 extern const value_string ssl_extension_curves[];
 extern const value_string ssl_extension_ec_point_formats[];
 extern const value_string ssl_curve_types[];
+extern const value_string tls_hello_ext_server_name_type_vs[];
 
 /* XXX Should we use GByteArray instead? */
 typedef struct _StringInfo {
index ba2acae0f990b7f9b147dba8641772095a98af1c..f866c01cb22fe1d4bb7ca435c53eca14cbe6d1a7 100644 (file)
@@ -172,6 +172,14 @@ static gint hf_ssl_handshake_extension_elliptic_curves      = -1;
 static gint hf_ssl_handshake_extension_elliptic_curve       = -1;
 static gint hf_ssl_handshake_extension_ec_point_formats_len = -1;
 static gint hf_ssl_handshake_extension_ec_point_format      = -1;
+static gint hf_ssl_handshake_extension_npn_len = -1;
+static gint hf_ssl_handshake_extension_npn_str_len = -1;
+static gint hf_ssl_handshake_extension_npn_str = -1;
+static gint hf_ssl_handshake_extension_reneg_info_len = -1;
+static gint hf_ssl_handshake_extension_server_name_len = -1;
+static gint hf_ssl_handshake_extension_server_name_list_len = -1;
+static gint hf_ssl_handshake_extension_server_name_type = -1;
+static gint hf_ssl_handshake_extension_server_name = -1;
 static gint hf_ssl_handshake_certificates_len = -1;
 static gint hf_ssl_handshake_certificates     = -1;
 static gint hf_ssl_handshake_certificate      = -1;
@@ -272,6 +280,9 @@ static gint ett_ssl_comp_methods      = -1;
 static gint ett_ssl_extension         = -1;
 static gint ett_ssl_extension_curves  = -1;
 static gint ett_ssl_extension_curves_point_formats = -1;
+static gint ett_ssl_extension_npn     = -1;
+static gint ett_ssl_extension_reneg_info = -1;
+static gint ett_ssl_extension_server_name = -1;
 static gint ett_ssl_certs             = -1;
 static gint ett_ssl_cert_types        = -1;
 static gint ett_ssl_sig_hash_algs     = -1;
@@ -475,6 +486,15 @@ static gint dissect_ssl3_hnd_hello_ext_elliptic_curves(tvbuff_t *tvb,
 static gint dissect_ssl3_hnd_hello_ext_ec_point_formats(tvbuff_t *tvb,
                                                         proto_tree *tree, guint32 offset);
 
+static gint dissect_ssl3_hnd_hello_ext_npn(tvbuff_t *tvb,
+                                           proto_tree *tree, guint32 offset, guint32 ext_len);
+
+static gint dissect_ssl3_hnd_hello_ext_reneg_info(tvbuff_t *tvb,
+                                           proto_tree *tree, guint32 offset, guint32 ext_len);
+
+static gint dissect_ssl3_hnd_hello_ext_server_name(tvbuff_t *tvb,
+                                           proto_tree *tree, guint32 offset, guint32 ext_len);
+
 static void dissect_ssl3_hnd_cli_hello(tvbuff_t *tvb, packet_info *pinfo,
                                        proto_tree *tree,
                                        guint32 offset, guint32 length,
@@ -2349,6 +2369,15 @@ dissect_ssl3_hnd_hello_ext(tvbuff_t *tvb,
         case SSL_HND_HELLO_EXT_EC_POINT_FORMATS:
             offset = dissect_ssl3_hnd_hello_ext_ec_point_formats(tvb, ext_tree, offset);
             break;
+        case SSL_HND_HELLO_EXT_NPN:
+             offset = dissect_ssl3_hnd_hello_ext_npn(tvb, ext_tree, offset, ext_len);
+             break;
+        case SSL_HND_HELLO_EXT_RENEG_INFO:
+             offset = dissect_ssl3_hnd_hello_ext_reneg_info(tvb, ext_tree, offset, ext_len);
+             break;
+        case SSL_HND_HELLO_EXT_SERVER_NAME:
+             offset = dissect_ssl3_hnd_hello_ext_server_name(tvb, ext_tree, offset, ext_len);
+             break;
         case SSL_HND_HELLO_EXT_HEARTBEAT:
             proto_tree_add_item(ext_tree, hf_ssl_heartbeat_extension_mode,
                                 tvb, offset, 1, ENC_BIG_ENDIAN);
@@ -2368,6 +2397,110 @@ dissect_ssl3_hnd_hello_ext(tvbuff_t *tvb,
     return offset;
 }
 
+static gint
+dissect_ssl3_hnd_hello_ext_npn(tvbuff_t *tvb,
+                               proto_tree *tree, guint32 offset, guint32 ext_len)
+{
+    guint8 npn_length;
+    proto_tree *npn_tree, *ti;
+
+    if (ext_len == 0) {
+       return offset;
+    }
+
+    ti = proto_tree_add_text(tree, tvb, offset, ext_len, "Next Protocol Negotiation");
+    npn_tree = proto_item_add_subtree(ti, ett_ssl_extension_npn); 
+
+    while (ext_len > 0) {
+          npn_length = tvb_get_guint8(tvb, offset);
+          proto_tree_add_item(npn_tree, hf_ssl_handshake_extension_npn_str_len,
+              tvb, offset, 1, ENC_NA);
+          offset++;
+          ext_len--;
+
+          if (npn_length > 0) {
+             tvb_ensure_bytes_exist(tvb, offset, npn_length);
+             proto_tree_add_item(npn_tree, hf_ssl_handshake_extension_npn_str,
+                 tvb, offset, npn_length, ENC_NA);
+             offset += npn_length;
+             ext_len -= npn_length;
+          }
+    }
+
+    return offset;
+}
+
+static gint
+dissect_ssl3_hnd_hello_ext_reneg_info(tvbuff_t *tvb,
+                               proto_tree *tree, guint32 offset, guint32 ext_len)
+{
+    guint8 reneg_info_length;
+    proto_tree *reneg_info_tree, *ti;
+
+    if (ext_len == 0) {
+       return offset;
+    }
+
+    ti = proto_tree_add_text(tree, tvb, offset, ext_len, "Renegotiation Info extension");
+    reneg_info_tree = proto_item_add_subtree(ti, ett_ssl_extension_reneg_info);
+
+    reneg_info_length = tvb_get_guint8(tvb, offset);
+    proto_tree_add_item(reneg_info_tree, hf_ssl_handshake_extension_reneg_info_len,
+              tvb, offset, 1, ENC_NA);
+    offset++;
+
+    if (reneg_info_length > 0) {
+       tvb_ensure_bytes_exist(tvb, offset, reneg_info_length);
+       proto_tree_add_text(reneg_info_tree, tvb, offset, reneg_info_length, "Renegotiation Info"); 
+       offset += reneg_info_length;
+    }
+
+    return offset;
+}
+
+static gint
+dissect_ssl3_hnd_hello_ext_server_name(tvbuff_t *tvb,
+                               proto_tree *tree, guint32 offset, guint32 ext_len)
+{
+    guint8 server_name_length;
+    proto_tree *server_name_tree, *ti;
+
+
+   if (ext_len == 0) {
+      return offset;
+   }
+
+    ti = proto_tree_add_text(tree, tvb, offset, ext_len, "Server Name Indication extension");
+    server_name_tree = proto_item_add_subtree(ti, ett_ssl_extension_server_name);
+
+    proto_tree_add_item(server_name_tree, hf_ssl_handshake_extension_server_name_list_len,
+         tvb, offset, 2, ENC_BIG_ENDIAN);
+    offset += 2;
+    ext_len -= 2;
+
+    while (ext_len > 0) {
+          proto_tree_add_item(server_name_tree, hf_ssl_handshake_extension_server_name_type,
+              tvb, offset, 2, ENC_BIG_ENDIAN);
+          offset += 2;
+          ext_len -= 2;
+
+          server_name_length = tvb_get_guint8(tvb, offset);
+          proto_tree_add_item(server_name_tree, hf_ssl_handshake_extension_server_name_len,
+              tvb, offset, 1, ENC_NA);
+          offset++;
+          ext_len--;
+
+          if (server_name_length > 0) {
+             tvb_ensure_bytes_exist(tvb, offset, server_name_length);
+             proto_tree_add_item(server_name_tree, hf_ssl_handshake_extension_server_name,
+                   tvb, offset, server_name_length, ENC_NA);
+             offset += server_name_length;
+             ext_len -= server_name_length;
+          }
+    }
+    return offset;
+}
+
 static gint
 dissect_ssl3_hnd_hello_ext_elliptic_curves(tvbuff_t *tvb,
                                            proto_tree *tree, guint32 offset)
@@ -4962,6 +5095,46 @@ proto_register_ssl(void)
             FT_UINT8, BASE_DEC, VALS(ssl_extension_ec_point_formats), 0x0,
             "Elliptic curves point format", HFILL }
         },
+        { &hf_ssl_handshake_extension_npn_len,
+          { "NPN extension length", "ssl.handshake.extensions_npn_length",
+            FT_UINT16, BASE_DEC, NULL, 0x0,
+            "Length of NPN extension", HFILL }
+        },
+        { &hf_ssl_handshake_extension_npn_str_len,
+          { "Protocol string length", "ssl.handshake.extensions_npn_str_len",
+            FT_UINT8, BASE_DEC, NULL, 0x0,
+            "Length of next protocol string", HFILL }
+        },
+        { &hf_ssl_handshake_extension_npn_str,
+          { "Next Protocol", "ssl.handshake.extensions_npn",
+            FT_STRING, BASE_NONE, NULL, 0x0,
+            "Next Protocol", HFILL }
+        },
+        { &hf_ssl_handshake_extension_reneg_info_len,
+          { "Renegotiation info extension length", "ssl.handshake.extensions_reneg_info_len",
+            FT_UINT8, BASE_DEC, NULL, 0x0,
+            "Renegotiation info extension length", HFILL }
+        },
+        { &hf_ssl_handshake_extension_server_name_list_len,
+          { "Server Name list length", "ssl.handshake.extensions_server_name_list_len",
+            FT_UINT16, BASE_DEC, NULL, 0x0,
+            "Length of server name list", HFILL }
+        },
+        { &hf_ssl_handshake_extension_server_name_len,
+          { "Server Name length", "ssl.handshake.extensions_server_name_len",
+            FT_UINT16, BASE_DEC, NULL, 0x0,
+            "Length of server name string", HFILL }
+        },
+        { &hf_ssl_handshake_extension_server_name_type,
+          { "Server Name Type", "ssl.handshake.extensions_server_name_type",
+            FT_UINT16, BASE_DEC, VALS(tls_hello_ext_server_name_type_vs), 0x0,
+            "Server name type", HFILL }
+        },
+        { &hf_ssl_handshake_extension_server_name,
+          { "Server Name", "ssl.handshake.extensions_server_name",
+            FT_STRING, BASE_NONE, NULL, 0x0,
+            "Server name", HFILL }
+        },
         { &hf_ssl_handshake_certificates_len,
           { "Certificates Length", "ssl.handshake.certificates_length",
             FT_UINT24, BASE_DEC, NULL, 0x0,
@@ -5402,6 +5575,9 @@ proto_register_ssl(void)
         &ett_ssl_extension,
         &ett_ssl_extension_curves,
         &ett_ssl_extension_curves_point_formats,
+        &ett_ssl_extension_npn,
+        &ett_ssl_extension_reneg_info,
+        &ett_ssl_extension_server_name,
         &ett_ssl_certs,
         &ett_ssl_cert_types,
         &ett_ssl_sig_hash_algs,