Add support for Exif decoding (initial framework).
[obnox/wireshark/wip.git] / packet-ssl.c
index 650e74c21a717e73c0b05a2f9e4780f9979bbb30..7cb283b1d4cfa40fc983f766763127fdc838f16c 100644 (file)
@@ -2,7 +2,7 @@
  * Routines for ssl dissection
  * Copyright (c) 2000-2001, Scott Renfro <scott@renfro.org>
  *
- * $Id: packet-ssl.c,v 1.22 2002/04/11 09:43:22 guy Exp $
+ * $Id: packet-ssl.c,v 1.29 2004/02/05 19:08:59 obiot Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@ethereal.com>
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  *
+ * See
+ *
+ *     http://www.netscape.com/eng/security/SSL_2.html
+ *
+ * for SSL 2.0 specs.
+ * 
+ * See
+ *
+ *     http://www.netscape.com/eng/ssl3/
+ *
+ * for SSL 3.0 specs.
+ *
+ * See RFC 2246 for SSL 3.1/TLS 1.0 specs.
+ *
  * Notes:
  *
  *   - Uses conversations in a no-malloc fashion.  Since we just want to
 
 #include <glib.h>
 
-#ifdef NEED_SNPRINTF_H
-# include "snprintf.h"
-#endif
-
 #include <epan/conversation.h>
 #include "prefs.h"
 
@@ -178,16 +188,16 @@ static gchar* ssl_version_short_names[] = {
 #define SSL_ID_HANDSHAKE               0x16
 #define SSL_ID_APP_DATA                0x17
 
-#define SSL_HND_HELLO_REQUEST          0x00
-#define SSL_HND_CLIENT_HELLO           0x01
-#define SSL_HND_SERVER_HELLO           0x02
-#define SSL_HND_CERTIFICATE            0x0b
-#define SSL_HND_SERVER_KEY_EXCHG       0x0c
-#define SSL_HND_CERT_REQUEST           0x0d
-#define SSL_HND_SVR_HELLO_DONE         0x0e
-#define SSL_HND_CERT_VERIFY            0x0f
-#define SSL_HND_CLIENT_KEY_EXCHG       0x10
-#define SSL_HND_FINISHED               0x14
+#define SSL_HND_HELLO_REQUEST          0
+#define SSL_HND_CLIENT_HELLO           1
+#define SSL_HND_SERVER_HELLO           2
+#define SSL_HND_CERTIFICATE            11
+#define SSL_HND_SERVER_KEY_EXCHG       12
+#define SSL_HND_CERT_REQUEST           13
+#define SSL_HND_SVR_HELLO_DONE         14
+#define SSL_HND_CERT_VERIFY            15
+#define SSL_HND_CLIENT_KEY_EXCHG       16
+#define SSL_HND_FINISHED               20
 
 #define SSL2_HND_ERROR                 0x00
 #define SSL2_HND_CLIENT_HELLO          0x01
@@ -264,6 +274,18 @@ static const value_string ssl_20_cipher_suites[] = {
     { 0x00001c, "SSL_FORTEZZA_KEA_WITH_NULL_SHA" },
     { 0x00001d, "SSL_FORTEZZA_KEA_WITH_FORTEZZA_CBC_SHA" },
     { 0x00001e, "SSL_FORTEZZA_KEA_WITH_RC4_128_SHA" },
+    { 0x00002f, "TLS_RSA_WITH_AES_128_CBC_SHA" },
+    { 0x000030, "TLS_DH_DSS_WITH_AES_128_CBC_SHA" },
+    { 0x000031, "TLS_DH_RSA_WITH_AES_128_CBC_SHA" },
+    { 0x000032, "TLS_DHE_DSS_WITH_AES_128_CBC_SHA" },
+    { 0x000033, "TLS_DHE_RSA_WITH_AES_128_CBC_SHA" },
+    { 0x000034, "TLS_DH_anon_WITH_AES_128_CBC_SHA" },
+    { 0x000035, "TLS_RSA_WITH_AES_256_CBC_SHA" },
+    { 0x000036, "TLS_DH_DSS_WITH_AES_256_CBC_SHA" },
+    { 0x000037, "TLS_DH_RSA_WITH_AES_256_CBC_SHA" },
+    { 0x000038, "TLS_DHE_DSS_WITH_AES_256_CBC_SHA" },
+    { 0x000039, "TLS_DHE_RSA_WITH_AES_256_CBC_SHA" },
+    { 0x00003A, "TLS_DH_anon_WITH_AES_256_CBC_SHA" },
     { 0x000060, "TLS_RSA_EXPORT1024_WITH_RC4_56_MD5" },
     { 0x000061, "TLS_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5" },
     { 0x000062, "TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA" },
@@ -316,10 +338,14 @@ static const value_string ssl_versions[] = {
     { 0x00, NULL }
 };
 
+#if 0
+/* XXX - would be used if we dissected the body of a Change Cipher Spec
+   message. */
 static const value_string ssl_31_change_cipher_spec[] = {
     { 1, "Change Cipher Spec" },
     { 0x00, NULL },
 };
+#endif
 
 static const value_string ssl_31_alert_level[] = {
     { 1, "Warning" },
@@ -370,9 +396,13 @@ static const value_string ssl_31_handshake_type[] = {
 
 static const value_string ssl_31_compression_method[] = {
     { 0, "null" },
+    { 1, "ZLIB" },
     { 0x00, NULL }
 };
 
+#if 0
+/* XXX - would be used if we dissected a Signature, as would be
+   seen in a server key exchange or certificate verify message. */
 static const value_string ssl_31_key_exchange_algorithm[] = {
     { 0, "RSA" },
     { 1, "Diffie Hellman" },
@@ -385,6 +415,7 @@ static const value_string ssl_31_signature_algorithm[] = {
     { 2, "DSA" },
     { 0x00, NULL }
 };
+#endif
 
 static const value_string ssl_31_client_certificate_type[] = {
     { 1, "RSA Sign" },
@@ -394,11 +425,15 @@ static const value_string ssl_31_client_certificate_type[] = {
     { 0x00, NULL }
 };
 
+#if 0
+/* XXX - would be used if we dissected exchnage keys, as would be
+   seen in a client key exchange message. */
 static const value_string ssl_31_public_value_encoding[] = {
     { 0, "Implicit" },
     { 1, "Explicit" },
     { 0x00, NULL }
 };
+#endif
 
 static const value_string ssl_31_ciphersuite[] = {
     { 0x0000, "TLS_NULL_WITH_NULL_NULL" },
@@ -432,6 +467,20 @@ static const value_string ssl_31_ciphersuite[] = {
     { 0x001c, "SSL_FORTEZZA_KEA_WITH_NULL_SHA" },
     { 0x001d, "SSL_FORTEZZA_KEA_WITH_FORTEZZA_CBC_SHA" },
     { 0x001e, "SSL_FORTEZZA_KEA_WITH_RC4_128_SHA" },
+    { 0x002f, "TLS_RSA_WITH_AES_128_CBC_SHA" },
+    { 0x0030, "TLS_DH_DSS_WITH_AES_128_CBC_SHA" },
+    { 0x0031, "TLS_DH_RSA_WITH_AES_128_CBC_SHA" },
+    { 0x0032, "TLS_DHE_DSS_WITH_AES_128_CBC_SHA" },
+    { 0x0033, "TLS_DHE_RSA_WITH_AES_128_CBC_SHA" },
+    { 0x0034, "TLS_DH_anon_WITH_AES_128_CBC_SHA" },
+    { 0x0035, "TLS_RSA_WITH_AES_256_CBC_SHA" },
+    { 0x0036, "TLS_DH_DSS_WITH_AES_256_CBC_SHA" },
+    { 0x0037, "TLS_DH_RSA_WITH_AES_256_CBC_SHA" },
+    { 0x0038, "TLS_DHE_DSS_WITH_AES_256_CBC_SHA" },
+    { 0x0039, "TLS_DHE_RSA_WITH_AES_256_CBC_SHA" },
+    { 0x003A, "TLS_DH_anon_WITH_AES_256_CBC_SHA" },
+    { 0x0060, "TLS_RSA_EXPORT1024_WITH_RC4_56_MD5" },
+    { 0x0061, "TLS_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5" },
     { 0x0062, "TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA" },
     { 0x0063, "TLS_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA" },
     { 0x0064, "TLS_RSA_EXPORT1024_WITH_RC4_56_SHA" },
@@ -602,7 +651,7 @@ dissect_ssl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
     conv_data = conversation_get_proto_data(conversation, proto_ssl);
     if (conv_data != NULL)
     {
-        conv_version = (guint)conv_data;
+        conv_version = GPOINTER_TO_UINT(conv_data);
     }
 
     /* Initialize the protocol column; we'll set it later when we
@@ -734,7 +783,7 @@ dissect_ssl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
          * this conversation, do so. */
         if (conv_data == NULL)
         {
-            conv_data = (void *)conv_version;
+            conv_data = GINT_TO_POINTER(conv_version);
             conversation_add_proto_data(conversation, proto_ssl, conv_data);
         }
 
@@ -832,9 +881,9 @@ dissect_ssl3_record(tvbuff_t *tvb, packet_info *pinfo,
                 return offset;
             }
         }
-      
+
     } else {
-      
+
     /* if we don't have a valid content_type, there's no sense
      * continuing any further
      */
@@ -1198,6 +1247,10 @@ dissect_ssl3_handshake(tvbuff_t *tvb, packet_info *pinfo,
                 dissect_ssl3_hnd_cert(tvb, ssl_hand_tree, offset);
                 break;
 
+            case SSL_HND_SERVER_KEY_EXCHG:
+                /* unimplemented */
+                break;
+
             case SSL_HND_CERT_REQUEST:
                 dissect_ssl3_hnd_cert_req(tvb, ssl_hand_tree, offset);
                 break;
@@ -1206,16 +1259,18 @@ dissect_ssl3_handshake(tvbuff_t *tvb, packet_info *pinfo,
                 /* server_hello_done has no fields, so nothing to do! */
                 break;
 
-            case SSL_HND_FINISHED:
-                dissect_ssl3_hnd_finished(tvb, ssl_hand_tree,
-                                          offset, conv_version);
+            case SSL_HND_CERT_VERIFY:
+                /* unimplemented */
                 break;
 
-            case SSL_HND_SERVER_KEY_EXCHG:
-            case SSL_HND_CERT_VERIFY:
             case SSL_HND_CLIENT_KEY_EXCHG:
                 /* unimplemented */
                 break;
+
+            case SSL_HND_FINISHED:
+                dissect_ssl3_hnd_finished(tvb, ssl_hand_tree,
+                                          offset, conv_version);
+                break;
             }
 
         }
@@ -1287,6 +1342,7 @@ dissect_ssl3_hnd_cli_hello(tvbuff_t *tvb,
     proto_tree *cs_tree;
     guint16 cipher_suite_length = 0;
     guint8  compression_methods_length = 0;
+    guint8  compression_method;
 
     if (tree)
     {
@@ -1354,8 +1410,18 @@ dissect_ssl3_hnd_cli_hello(tvbuff_t *tvb,
 
             while (compression_methods_length > 0)
             {
-                proto_tree_add_item(cs_tree, hf_ssl_handshake_comp_method,
-                                    tvb, offset, 1, FALSE);
+                compression_method = tvb_get_guint8(tvb, offset);
+                if (compression_method < 64)
+                    proto_tree_add_uint(cs_tree, hf_ssl_handshake_comp_method,
+                                    tvb, offset, 1, compression_method);
+                else if (compression_method > 63 && compression_method < 193)
+                    proto_tree_add_text(cs_tree, tvb, offset, 1,
+                      "Compression Method: Reserved - to be assigned by IANA (%u)",
+                      compression_method);
+                else
+                    proto_tree_add_text(cs_tree, tvb, offset, 1,
+                       "Compression Method: Private use range (%u)",
+                       compression_method);
                 offset++;
                 compression_methods_length--;
             }
@@ -1718,7 +1784,7 @@ dissect_ssl2_record(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
             ssl_set_conv_version(pinfo, *conv_version);
         }
     }
-    
+
     /* if we get here, but don't have a version set for the
      * conversation, then set a version for just this frame
      * (e.g., on a client hello)
@@ -1843,7 +1909,7 @@ dissect_ssl2_record(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
     }
     else
     {
-        /* dissect the message */ 
+        /* dissect the message */
         switch (msg_type) {
         case PCT_MSG_CLIENT_HELLO:
         case PCT_MSG_SERVER_HELLO:
@@ -2123,7 +2189,7 @@ dissect_ssl2_hnd_server_hello(tvbuff_t *tvb,
     if (cipher_spec_length > 0)
     {
         /* provide a collapsing node for the cipher specs */
-        ti = proto_tree_add_none_format(tree, 
+        ti = proto_tree_add_none_format(tree,
                                         hf_ssl_handshake_cipher_suites,
                                         tvb, offset, cipher_spec_length,
                                         "Cipher Specs (%u spec%s)",
@@ -2191,7 +2257,7 @@ ssl_set_conv_version(packet_info *pinfo, guint version)
         /* get rid of the current data */
         conversation_delete_proto_data(conversation, proto_ssl);
     }
-    conversation_add_proto_data(conversation, proto_ssl, (void *)version);
+    conversation_add_proto_data(conversation, proto_ssl, GINT_TO_POINTER(version));
 }
 
 static int
@@ -2807,7 +2873,7 @@ proto_register_ssl(void)
                                      "When enabled, SSL records that span multiple TCP segments are desegmented",
                                      &ssl_desegment);
     }
-  
+
     register_dissector("ssl", dissect_ssl, proto_ssl);
 
 }