Ethereal-dev: [Ethereal-dev] [PATCH] ssl decrypt debug code

Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.

From: Paolo Abeni <paolo.abeni@xxxxxxxx>
Date: Thu, 09 Feb 2006 10:58:40 +0100
Hi all,

I worked a bit trying to handling better the debug messages generated by
the ssl decrypt code. The attached patch add a preference to
disable/enable to stderr/file the debug messages. The whole debug
infrastructure can be disabled at compile time undefining the macro
SSL_DECRYPT_DEBUG. 

I find it very useful to get detailed information on the ongoing
decryption process, to track subtle key-related issue, but I don't know
if this is the preferred way to fix the thing, so any suggestion is
really appreciated :-)

Best Regards, 
Paolo

 
 
 --
 Email.it, the professional e-mail, gratis per te: http://www.email.it/f
 
 Sponsor:
 Prestiti e Finanziamenti con un semplice click, scopri subito se sei finanziabile cliccando qui
 Clicca qui: http://adv.email.it/cgi-bin/foclick.cgi?mid=2910&d=9-2
Index: gtk/ssl-dlg.c
===================================================================
--- gtk/ssl-dlg.c	(revision 17224)
+++ gtk/ssl-dlg.c	(working copy)
@@ -141,8 +141,6 @@
     SslDecryptedRecord* rec;
     int proto_ssl = (int) ssl;
     StringInfo* data = p_get_proto_data(pinfo->fd, proto_ssl);
-    /*ssl_debug_printf("ssl_queue_packet_data: pinfo %p proto_ssl %d data %p\n",
-        pinfo, proto_ssl, data);*/
 
     /* skip packet without decrypted data payload*/    
     if (!data)
@@ -169,8 +167,6 @@
     rec->data = data;
     follow_info->ssl_decrypted_data = g_list_append(
         follow_info->ssl_decrypted_data,rec);
-    /*ssl_debug_printf("ssl_queue_packet_data: ssl_decrypted_data %p data len %d\n",
-        follow_info->ssl_decrypted_data, data->data_len);*/
 
     return 0;
 }
@@ -482,7 +478,6 @@
     for (cur = follow_info->ssl_decrypted_data; cur; cur = g_list_next(cur))
         if (cur->data)
         {
-            /*ssl_debug_printf("follow_destroy_cb: freeing chunk %p\n", cur->data);*/
             g_free(cur->data);
             cur->data = NULL;
         }
@@ -588,9 +583,6 @@
 
     iplen = (follow_info->is_ipv6) ? 16 : 4;
     
-    /*ssl_debug_printf("follow_read_stream: iplen %d list %p\n", iplen,
-        follow_info->ssl_decrypted_data);*/
-
     for (cur = follow_info->ssl_decrypted_data; cur; cur = g_list_next(cur)) {
         SslDecryptedRecord* rec = cur->data;
 	skip = FALSE;
@@ -611,9 +603,6 @@
             size_t nchars = rec->data->data_len;
             char* buffer = (char*) rec->data->data;
             
-            /*ssl_debug_printf("follow_read_stream: chunk len %d is_server %d\n", 
-                nchars, rec->is_server);*/
-            
             switch (follow_info->show_type) {
     
             case SHOW_ASCII:
Index: epan/dissectors/packet-ssl-utils.c
===================================================================
--- epan/dissectors/packet-ssl-utils.c	(revision 17224)
+++ epan/dissectors/packet-ssl-utils.c	(working copy)
@@ -201,8 +201,9 @@
     /* build up a mpi rappresentation for encrypted data */
     rc = gcry_mpi_scan(&encr_mpi, GCRYMPI_FMT_USG,encr_data, encr_len, &encr_len); 
     if (rc != 0 ) {
-        ssl_debug_printf("pcry_private_decrypt: can't convert encr_data to mpi (size %d):%s\n", 
-            len, gcry_strerror(rc));
+        if (ssl_debug_enabled()) 
+            ssl_debug_printf("pcry_private_decrypt: can't convert encr_data to mpi (size %d):%s\n", 
+                len, gcry_strerror(rc));
         return 0;
     }
 
@@ -210,8 +211,9 @@
     /* put the data into a simple list */
     rc = gcry_sexp_build(&s_data, NULL, "(enc-val(rsa(a%m)))", encr_mpi);
     if (rc != 0) {
-        ssl_debug_printf("pcry_private_decrypt: can't build encr_sexp:%s \n",
-             gcry_strerror(rc));
+        if (ssl_debug_enabled()) 
+            ssl_debug_printf("pcry_private_decrypt: can't build encr_sexp:%s \n",
+                gcry_strerror(rc));
         return 0;
     }
 
@@ -220,8 +222,9 @@
     gcry_sexp_release(s_data);
     if (rc != 0)
     {
-        ssl_debug_printf("pcry_private_decrypt: can't decrypt key:%s\n", 
-            gcry_strerror(rc));
+        if (ssl_debug_enabled()) 
+            ssl_debug_printf("pcry_private_decrypt: can't decrypt key:%s\n", 
+                gcry_strerror(rc));
         goto out;
     }    
     
@@ -231,16 +234,18 @@
     /* compute size requested for plaintext buffer */
     decr_len = len;
     if (gcry_mpi_print(GCRYMPI_FMT_USG, NULL, decr_len, &decr_len, text) != 0) {
-        ssl_debug_printf("pcry_private_decrypt: can't compute decr size:%s\n",
-            gcry_strerror(rc));
+        if (ssl_debug_enabled()) 
+            ssl_debug_printf("pcry_private_decrypt: can't compute decr size:%s\n",
+                gcry_strerror(rc));
         decr_len = 0;
         goto out;
     }
     
     /* sanity check on out buffer */
     if (decr_len > len) {
-        ssl_debug_printf("pcry_private_decrypt: decrypted data is too long ?!? (%d max %d)\n",
-            decr_len, len);
+        if (ssl_debug_enabled()) 
+            ssl_debug_printf("pcry_private_decrypt: decrypted data is too long ?!? (%d max %d)\n",
+                decr_len, len);
         return 0;
     }
 
@@ -248,8 +253,9 @@
     decr_data_ptr = encr_data;
     if (gcry_mpi_print( GCRYMPI_FMT_USG, decr_data_ptr, decr_len, &decr_len, 
             text) != 0) {
-        ssl_debug_printf("pcry_private_decrypt: can't print decr data to mpi (size %d):%s\n", 
-            decr_len, gcry_strerror(rc));
+        if (ssl_debug_enabled()) 
+            ssl_debug_printf("pcry_private_decrypt: can't print decr data to mpi (size %d):%s\n", 
+                decr_len, gcry_strerror(rc));
         g_free(decr_data_ptr);
         decr_len = 0;
         goto out;
@@ -264,9 +270,12 @@
         }
     }
     
-    ssl_debug_printf("pcry_private_decrypt: stripping %d bytes, decr_len %d\n", 
-        rc, decr_len);
-    ssl_print_data("decypted_unstrip_pre_master", decr_data_ptr, decr_len);
+    if (ssl_debug_enabled()) 
+    {
+        ssl_debug_printf("pcry_private_decrypt: stripping %d bytes, decr_len %d\n", 
+            rc, decr_len);
+        ssl_print_data("decypted_unstrip_pre_master", decr_data_ptr, decr_len);
+    }
     g_memmove(decr_data_ptr, &decr_data_ptr[rc], decr_len - rc);
     decr_len -= rc;
 
@@ -278,8 +287,9 @@
     
     /* sanity check on out buffer */
     if (decr_len > len) {
-        ssl_debug_printf("pcry_private_decrypt: decrypted data is too long ?!? (%d max %d)\n",
-            decr_len, len);
+        if (ssl_debug_enabled()) 
+            ssl_debug_printf("pcry_private_decrypt: decrypted data is too long ?!? (%d max %d)\n",
+                decr_len, len);
         return 0;
     }
     
@@ -287,8 +297,9 @@
     decr_data_ptr = encr_data;
     if (gcry_mpi_print( GCRYMPI_FMT_USG, decr_data_ptr, decr_len, &decr_len, 
             text) != 0) {
-        ssl_debug_printf("pcry_private_decrypt: can't print decr data to mpi (size %d):%s\n", 
-            decr_len, gcry_strerror(rc));
+        if (ssl_debug_enabled()) 
+            ssl_debug_printf("pcry_private_decrypt: can't print decr data to mpi (size %d):%s\n", 
+                decr_len, gcry_strerror(rc));
         return 0;
     }
     
@@ -301,9 +312,12 @@
         }
     }
     
-    ssl_debug_printf("pcry_private_decrypt: stripping %d bytes, decr_len %d\n", 
-        rc, decr_len);
-    ssl_print_data("decypted_unstrip_pre_master", decr_data_ptr, decr_len);
+    if (ssl_debug_enabled()) 
+    {
+        ssl_debug_printf("pcry_private_decrypt: stripping %d bytes, decr_len %d\n", 
+            rc, decr_len);
+        ssl_print_data("decypted_unstrip_pre_master", decr_data_ptr, decr_len);
+    }
     g_memmove(decr_data_ptr, &decr_data_ptr[rc], decr_len - rc);
     decr_len -= rc;
 #endif /* SSL_FAST */
@@ -413,8 +427,11 @@
     SSL_HMAC hm;
     
     memset(&hm, 0, sizeof(hm));
-    ssl_print_string("tls_hash: hash secret", secret);
-    ssl_print_string("tls_hash: hash seed", seed);
+    if (ssl_debug_enabled()) 
+    {
+        ssl_print_string("tls_hash: hash secret", secret);
+        ssl_print_string("tls_hash: hash seed", seed);
+    }
     A=seed->data;
     A_l=seed->data_len;
     
@@ -436,7 +453,8 @@
     }
     
     ssl_hmac_cleanup(&hm);
-    ssl_print_string("hash out", out);
+    if (ssl_debug_enabled()) 
+        ssl_print_string("hash out", out);
     return (0);
 }    
 
@@ -473,10 +491,13 @@
     memcpy(s1.data,secret->data,s_l);
     memcpy(s2.data,secret->data + (secret->data_len - s_l),s_l);
 
-    ssl_debug_printf("tls_prf: tls_hash(md5 secret_len %d seed_len %d )\n", s1.data_len, seed.data_len);
+    if (ssl_debug_enabled()) 
+        ssl_debug_printf("tls_prf: tls_hash(md5 secret_len %d seed_len %d )\n", 
+            s1.data_len, seed.data_len);
     if(tls_hash(&s1,&seed,ssl_get_digest_by_name("MD5"),&md5_out) != 0)
         goto free_all;
-    ssl_debug_printf("tls_prf: tls_hash(sha)\n");
+    if (ssl_debug_enabled()) 
+        ssl_debug_printf("tls_prf: tls_hash(sha)\n");
     if(tls_hash(&s2,&seed,ssl_get_digest_by_name("SHA1"),&sha_out) != 0)
         goto free_all;
     
@@ -484,7 +505,8 @@
       out->data[i]=md5_out.data[i] ^ sha_out.data[i];
     r =0;
     
-    ssl_print_string("PRF out",out);
+    if (ssl_debug_enabled()) 
+        ssl_print_string("PRF out",out);
 free_all:    
     free(s2.data);
 free_s1:    
@@ -511,7 +533,8 @@
     ssl_md5_final(tmp,&md5);
     
     memcpy(out->data,tmp,out->data_len);
-    ssl_print_string("export iv", out);
+    if (ssl_debug_enabled()) 
+        ssl_print_string("export iv", out);
     
     return(0);
 }
@@ -539,7 +562,8 @@
         int tocpy;
         i++;
         
-        ssl_debug_printf("ssl3_prf: sha1_update(%d)\n",i);
+        if (ssl_debug_enabled()) 
+            ssl_debug_printf("ssl3_prf: sha1_update(%d)\n",i);
         /* A, BB, CCC,  ... */
         for(j=0;j<i;j++){
             buf[j]=64+i;
@@ -562,7 +586,8 @@
         
         ssl_sha_init(&sha);
         
-        ssl_debug_printf("ssl3_prf: md5_update(%d)\n",i);
+        if (ssl_debug_enabled()) 
+            ssl_debug_printf("ssl3_prf: md5_update(%d)\n",i);
         ssl_md5_update(&md5,secret->data,secret->data_len);
         ssl_md5_update(&md5,buf,20);
         ssl_md5_final(outbuf,&md5);
@@ -583,12 +608,15 @@
 
     /* Find the SSLeay cipher */
     if(cipher_suite->enc!=ENC_NULL) {
-        ssl_debug_printf("ssl_create_decoder CIPHER: %s\n", ciphers[cipher_suite->enc-0x30]);
+        if (ssl_debug_enabled()) 
+            ssl_debug_printf("ssl_create_decoder CIPHER: %s\n", 
+                ciphers[cipher_suite->enc-0x30]);
         ciph=ssl_get_cipher_by_name(ciphers[cipher_suite->enc-0x30]);
     }
     if (ciph == 0) {
-        ssl_debug_printf("ssl_create_decoder can't find cipher %s\n", 
-            ciphers[cipher_suite->enc-0x30]);
+        if (ssl_debug_enabled()) 
+            ssl_debug_printf("ssl_create_decoder can't find cipher %s\n", 
+                ciphers[cipher_suite->enc-0x30]);
         return -1;
     }
     
@@ -599,12 +627,14 @@
     ssl_data_set(&dec->mac_key, mk, cipher_suite->dig_len);
 
     if (ssl_cipher_init(&dec->evp,ciph,sk,iv,cipher_suite->mode) < 0) {
-        ssl_debug_printf("ssl_create_decoder: can't create cipher id:%d mode:%d\n",
-            ciph, cipher_suite->mode);
+        if (ssl_debug_enabled()) 
+            ssl_debug_printf("ssl_create_decoder: can't create cipher id:%d mode:%d\n",
+                ciph, cipher_suite->mode);
         return -1;
     }
 
-    ssl_debug_printf("decoder initialized (digest len %d)\n", cipher_suite->dig_len);
+    if (ssl_debug_enabled()) 
+        ssl_debug_printf("decoder initialized (digest len %d)\n", cipher_suite->dig_len);
     return 0;    
 }
 
@@ -619,14 +649,17 @@
     
     /* if master_key is not yet generate, create it now*/    
     if (!(ssl_session->state & SSL_MASTER_SECRET)) {
-        ssl_debug_printf("ssl_generate_keyring_material:PRF(pre_master_secret)\n");
+        if (ssl_debug_enabled()) 
+            ssl_debug_printf("ssl_generate_keyring_material:PRF(pre_master_secret)\n");
         if (PRF(ssl_session,&ssl_session->pre_master_secret,"master secret",
                 &ssl_session->client_random,
                 &ssl_session->server_random, &ssl_session->master_secret)) {
-            ssl_debug_printf("ssl_generate_keyring_material can't generate master_secret\n");
+            if (ssl_debug_enabled()) 
+                ssl_debug_printf("ssl_generate_keyring_material can't generate master_secret\n");
             return -1;
         }
-        ssl_print_string("master secret",&ssl_session->master_secret);
+        if (ssl_debug_enabled()) 
+            ssl_print_string("master secret",&ssl_session->master_secret);
     }
     
     /* Compute the key block. First figure out how much data we need*/
@@ -638,17 +671,21 @@
     key_block.data_len = needed;
     key_block.data = g_malloc(needed);
     if (!key_block.data) {
-        ssl_debug_printf("ssl_generate_keyring_material can't allacate key_block\n");
+        if (ssl_debug_enabled()) 
+            ssl_debug_printf("ssl_generate_keyring_material can't allacate key_block\n");
         return -1;
     }
-    ssl_debug_printf("ssl_generate_keyring_material sess key generation\n");
+    if (ssl_debug_enabled()) 
+        ssl_debug_printf("ssl_generate_keyring_material sess key generation\n");
     if (PRF(ssl_session,&ssl_session->master_secret,"key expansion",
             &ssl_session->server_random,&ssl_session->client_random,
             &key_block)) {
-        ssl_debug_printf("ssl_generate_keyring_material can't generate key_block\n");
+        if (ssl_debug_enabled()) 
+            ssl_debug_printf("ssl_generate_keyring_material can't generate key_block\n");
         goto fail;
     }
-    ssl_print_string("key expansion", &key_block);
+    if (ssl_debug_enabled()) 
+        ssl_print_string("key expansion", &key_block);
     
     ptr=key_block.data;
     c_mk=ptr; ptr+=ssl_session->cipher_suite.dig_len;
@@ -672,8 +709,10 @@
             /* We only have room for MAX_BLOCK_SIZE bytes IVs, but that's
              all we should need. This is a sanity check */
             if(ssl_session->cipher_suite.block>MAX_BLOCK_SIZE) {
-                ssl_debug_printf("ssl_generate_keyring_material cipher suite block must be at most %d nut is %d\n", 
-                    MAX_BLOCK_SIZE, ssl_session->cipher_suite.block);
+                if (ssl_debug_enabled()) 
+                    ssl_debug_printf("ssl_generate_keyring_material cipher "
+                        "suite block must be at most %d nut is %d\n", 
+                        MAX_BLOCK_SIZE, ssl_session->cipher_suite.block);
                 goto fail;
             }
         
@@ -683,16 +722,20 @@
             iv_s.data_len = ssl_session->cipher_suite.block;
             
             if(ssl_session->version_netorder==SSLV3_VERSION){
-                ssl_debug_printf("ssl_generate_keyring_material ssl3_generate_export_iv\n");
+                if (ssl_debug_enabled()) 
+                    ssl_debug_printf("ssl_generate_keyring_material ssl3_generate_export_iv\n");
                 if (ssl3_generate_export_iv(&ssl_session->client_random,
                         &ssl_session->server_random,&iv_c)) {
-                    ssl_debug_printf("ssl_generate_keyring_material can't generate sslv3 client iv\n");
+                    if (ssl_debug_enabled()) 
+                        ssl_debug_printf("ssl_generate_keyring_material can't generate sslv3 client iv\n");
                     goto fail;
                 }
-                ssl_debug_printf("ssl_generate_keyring_material ssl3_generate_export_iv(2)\n");
+                if (ssl_debug_enabled()) 
+                    ssl_debug_printf("ssl_generate_keyring_material ssl3_generate_export_iv(2)\n");
                 if (ssl3_generate_export_iv(&ssl_session->server_random,
                         &ssl_session->client_random,&iv_s)) {
-                    ssl_debug_printf("ssl_generate_keyring_material can't generate sslv3 server iv\n");
+                    if (ssl_debug_enabled()) 
+                        ssl_debug_printf("ssl_generate_keyring_material can't generate sslv3 server iv\n");
                     goto fail;
                 }            
             }
@@ -708,11 +751,13 @@
                 iv_block.data = _iv_block;
                 iv_block.data_len = ssl_session->cipher_suite.block*2;
                 
-                ssl_debug_printf("ssl_generate_keyring_material prf(iv_block)\n");
+                if (ssl_debug_enabled()) 
+                    ssl_debug_printf("ssl_generate_keyring_material prf(iv_block)\n");
                 if(PRF(ssl_session,&key_null, "IV block",
                         &ssl_session->client_random,
                         &ssl_session->server_random,&iv_block)) {
-                    ssl_debug_printf("ssl_generate_keyring_material can't generate tls31 iv block\n");
+                    if (ssl_debug_enabled()) 
+                        ssl_debug_printf("ssl_generate_keyring_material can't generate tls31 iv block\n");
                     goto fail;
                 }
                 
@@ -728,7 +773,8 @@
         if (ssl_session->version_netorder==SSLV3_VERSION){
             
             SSL_MD5_CTX md5;
-            ssl_debug_printf("ssl_generate_keyring_material MD5(client_random)\n");
+            if (ssl_debug_enabled()) 
+                ssl_debug_printf("ssl_generate_keyring_material MD5(client_random)\n");
             ssl_md5_init(&md5);
             ssl_md5_update(&md5,c_wk,ssl_session->cipher_suite.eff_bits/8);
             ssl_md5_update(&md5,ssl_session->client_random.data,
@@ -739,7 +785,8 @@
             c_wk=_key_c;
             
             ssl_md5_init(&md5);
-            ssl_debug_printf("ssl_generate_keyring_material MD5(server_random)\n");
+            if (ssl_debug_enabled()) 
+                ssl_debug_printf("ssl_generate_keyring_material MD5(server_random)\n");
             ssl_md5_update(&md5,s_wk,ssl_session->cipher_suite.eff_bits/8);
             ssl_md5_update(&md5,ssl_session->server_random.data,
                 ssl_session->server_random.data_len);
@@ -756,22 +803,26 @@
             
             k.data = c_wk;
             k.data_len = ssl_session->cipher_suite.eff_bits/8;
-            ssl_debug_printf("ssl_generate_keyring_material PRF(key_c)\n");
+            if (ssl_debug_enabled()) 
+                ssl_debug_printf("ssl_generate_keyring_material PRF(key_c)\n");
             if (PRF(ssl_session,&k,"client write key",
                     &ssl_session->client_random,
                     &ssl_session->server_random, &key_c)) {
-                ssl_debug_printf("ssl_generate_keyring_material can't generate tll31 server key \n");        
+                if (ssl_debug_enabled()) 
+                    ssl_debug_printf("ssl_generate_keyring_material can't generate tll31 server key \n");        
                 goto fail;
             }
             c_wk=_key_c;
             
             k.data = s_wk;
             k.data_len = ssl_session->cipher_suite.eff_bits/8;
-            ssl_debug_printf("ssl_generate_keyring_material PRF(key_s)\n");
+            if (ssl_debug_enabled()) 
+                ssl_debug_printf("ssl_generate_keyring_material PRF(key_s)\n");
             if(PRF(ssl_session,&k,"server write key",
                     &ssl_session->client_random,
                     &ssl_session->server_random, &key_s)) {
-                ssl_debug_printf("ssl_generate_keyring_material can't generate tll31 client key \n");
+                if (ssl_debug_enabled()) 
+                    ssl_debug_printf("ssl_generate_keyring_material can't generate tll31 client key \n");
                 goto fail;
             }
             s_wk=_key_s;
@@ -779,31 +830,37 @@
     }
     
     /* show key material info */
-    ssl_print_data("Client MAC key",c_mk,ssl_session->cipher_suite.dig_len);
-    ssl_print_data("Server MAC key",s_mk,ssl_session->cipher_suite.dig_len);    
-    ssl_print_data("Client Write key",c_wk,ssl_session->cipher_suite.bits/8);
-    ssl_print_data("Server Write key",s_wk,ssl_session->cipher_suite.bits/8);    
-        
-    if(ssl_session->cipher_suite.block>1) {
-        ssl_print_data("Client Write IV",c_iv,ssl_session->cipher_suite.block);
-        ssl_print_data("Server Write IV",s_iv,ssl_session->cipher_suite.block);
+    if (ssl_debug_enabled()) 
+    {
+        ssl_print_data("Client MAC key",c_mk,ssl_session->cipher_suite.dig_len);
+        ssl_print_data("Server MAC key",s_mk,ssl_session->cipher_suite.dig_len);    
+        ssl_print_data("Client Write key",c_wk,ssl_session->cipher_suite.bits/8);
+        ssl_print_data("Server Write key",s_wk,ssl_session->cipher_suite.bits/8);    
+        if(ssl_session->cipher_suite.block>1) {
+            ssl_print_data("Client Write IV",c_iv,ssl_session->cipher_suite.block);
+            ssl_print_data("Server Write IV",s_iv,ssl_session->cipher_suite.block);
+        }
+        else {
+            ssl_print_data("Client Write IV",c_iv,8);
+            ssl_print_data("Server Write IV",s_iv,8);
+        }
+        ssl_debug_printf("ssl_generate_keyring_material ssl_create_decoder(client)\n");
     }
-    else {
-        ssl_print_data("Client Write IV",c_iv,8);
-        ssl_print_data("Server Write IV",s_iv,8);
-    }
     
+    
     /* create both client and server ciphers*/
-    ssl_debug_printf("ssl_generate_keyring_material ssl_create_decoder(client)\n");
     if (ssl_create_decoder(&ssl_session->client,
             &ssl_session->cipher_suite,c_mk,c_wk,c_iv)) {
-        ssl_debug_printf("ssl_generate_keyring_material can't init client decoder\n");        
+        if (ssl_debug_enabled()) 
+            ssl_debug_printf("ssl_generate_keyring_material can't init client decoder\n");        
         goto fail;
     }
-    ssl_debug_printf("ssl_generate_keyring_material ssl_create_decoder(server)\n");
+    if (ssl_debug_enabled()) 
+        ssl_debug_printf("ssl_generate_keyring_material ssl_create_decoder(server)\n");
     if (ssl_create_decoder(&ssl_session->server,
             &ssl_session->cipher_suite,s_mk,s_wk,s_iv)) {
-        ssl_debug_printf("ssl_generate_keyring_material can't init client decoder\n");        
+        if (ssl_debug_enabled()) 
+            ssl_debug_printf("ssl_generate_keyring_material can't init client decoder\n");        
         goto fail;
     }
         
@@ -822,35 +879,42 @@
     int i;
         
     if(ssl_session->cipher_suite.kex!=KEX_RSA) {
-        ssl_debug_printf("ssl_decrypt_pre_master_secret key %d diferent from KEX_RSA(%d)\n",
-            ssl_session->cipher_suite.kex, KEX_RSA);
+        if (ssl_debug_enabled()) 
+            ssl_debug_printf("ssl_decrypt_pre_master_secret key %d diferent from KEX_RSA(%d)\n",
+                ssl_session->cipher_suite.kex, KEX_RSA);
         return(-1);
     }
 
 #if 0 
     /* can't find any place where ephemeral_rsa is set ...*/
     if(d->ephemeral_rsa) {
-        ssl_debug_printf("ssl_decrypt_pre_master_secret ephimeral RSA\n");
+        if (ssl_debug_enabled()) 
+            ssl_debug_printf("ssl_decrypt_pre_master_secret ephimeral RSA\n");
         return(-1);
     }
 #endif    
  
     /* with tls key loading will fail if not rsa type, so no need to check*/
-    ssl_print_string("pre master encrypted",entrypted_pre_master);
-    ssl_debug_printf("ssl_decrypt_pre_master_secret:RSA_private_decrypt\n");
+    if (ssl_debug_enabled()) 
+    {
+        ssl_print_string("pre master encrypted",entrypted_pre_master);
+        ssl_debug_printf("ssl_decrypt_pre_master_secret:RSA_private_decrypt\n");
+    }
     i=ssl_private_decrypt(entrypted_pre_master->data_len,
         entrypted_pre_master->data, pk);
 
     if (i!=48) {
-        ssl_debug_printf("ssl_decrypt_pre_master_secret wrong "
-            "pre_master_secret lenght (%d, expected %d)\n", i, 48);
+        if (ssl_debug_enabled()) 
+            ssl_debug_printf("ssl_decrypt_pre_master_secret wrong "
+                "pre_master_secret lenght (%d, expected %d)\n", i, 48);
         return -1;
     }
 
     /* the decrypted data has been written into the pre_master key buffer */
     ssl_session->pre_master_secret.data = entrypted_pre_master->data;
     ssl_session->pre_master_secret.data_len=48;  
-    ssl_print_string("pre master secret",&ssl_session->pre_master_secret);
+    if (ssl_debug_enabled()) 
+        ssl_print_string("pre master secret",&ssl_session->pre_master_secret);
 
     /* Remove the master secret if it was there.
        This force keying material regeneration in
@@ -886,8 +950,9 @@
 
     memset(&hm, 0, sizeof(hm));
     md=ssl_get_digest_by_name(digests[decoder->cipher_suite->dig-0x40]);
-    ssl_debug_printf("tls_check_mac mac type:%s md %d\n",
-        digests[decoder->cipher_suite->dig-0x40], md);
+    if (ssl_debug_enabled()) 
+        ssl_debug_printf("tls_check_mac mac type:%s md %d\n",
+            digests[decoder->cipher_suite->dig-0x40], md);
     
     ssl_hmac_init(&hm,decoder->mac_key.data,decoder->mac_key.data_len,md);
     
@@ -909,7 +974,8 @@
     ssl_hmac_update(&hm,data,datalen);
 
     ssl_hmac_final(&hm,buf,&l);
-    ssl_print_data("Mac", buf, l);
+    if (ssl_debug_enabled()) 
+        ssl_print_data("Mac", buf, l);
     if(memcmp(mac,buf,l))
         return -1;
 
@@ -931,11 +997,13 @@
 
     /* get cipher used for digest comptuation */
     md=ssl_get_digest_by_name(digests[decoder->cipher_suite->dig-0x40]);
-    ssl_debug_printf("ssl3_check_mac digest%s md %d\n",
-        digests[decoder->cipher_suite->dig-0x40], md);
+    if (ssl_debug_enabled()) 
+        ssl_debug_printf("ssl3_check_mac digest%s md %d\n",
+            digests[decoder->cipher_suite->dig-0x40], md);
     memset(&mc, 0, sizeof(mc));
     ssl_md_init(&mc,md);
-    ssl_debug_printf("ssl3_check_mac memory digest %p\n",mc);
+    if (ssl_debug_enabled()) 
+        ssl_debug_printf("ssl3_check_mac memory digest %p\n",mc);
 
     /* do hash computation on data && padding */
     ssl_md_update(&mc,decoder->mac_key.data,decoder->mac_key.data_len);
@@ -980,50 +1048,62 @@
     int pad, worklen;
     guint8 *mac;
     
-    ssl_debug_printf("ssl_decrypt_record ciphertext len %d\n", inl);
-    ssl_print_data("Ciphertext",in, inl);
+    if (ssl_debug_enabled()) 
+    {
+        ssl_debug_printf("ssl_decrypt_record ciphertext len %d\n", inl);
+        ssl_print_data("Ciphertext",in, inl);
+    }
     
     /* First decrypt*/
     if ((pad = ssl_cipher_decrypt(&decoder->evp,out,*outl,in,inl))!= 0)
-        ssl_debug_printf("ssl_decrypt_record: %s %s\n", gcry_strsource (pad),
-                    gcry_strerror (pad));
+        if (ssl_debug_enabled()) 
+            ssl_debug_printf("ssl_decrypt_record: %s %s\n", gcry_strsource (pad),
+                gcry_strerror (pad));
 
-    ssl_print_data("Plaintext",out,inl);
+    if (ssl_debug_enabled()) 
+        ssl_print_data("Plaintext",out,inl);
     worklen=inl;
 
     /* Now strip off the padding*/
     if(decoder->cipher_suite->block!=1){
         pad=out[inl-1];
         worklen-=(pad+1);
-        ssl_debug_printf("ssl_decrypt_record found padding %d final len %d\n", 
-            pad, *outl);
+        if (ssl_debug_enabled()) 
+            ssl_debug_printf("ssl_decrypt_record found padding %d final len %d\n", 
+                pad, *outl);
     }
 
     /* And the MAC */
     worklen-=decoder->cipher_suite->dig_len;
     if (worklen < 0)
     {
-        ssl_debug_printf("ssl_decrypt_record wrong record len/padding outlen %d\n work %d\n",*outl, worklen);
+        if (ssl_debug_enabled()) 
+            ssl_debug_printf("ssl_decrypt_record wrong record len/padding outlen %d\n work %d\n",
+                *outl, worklen);
         return -1;
     }
     mac=out+worklen;
-    /*ssl_print_data("Record data",out,*outl);*/
 
     /* Now check the MAC */
-    ssl_debug_printf("checking mac (len %d, version %X, ct %d)\n", worklen,ssl->version_netorder, ct);
+    if (ssl_debug_enabled()) 
+        ssl_debug_printf("checking mac (len %d, version %X, ct %d)\n", 
+            worklen,ssl->version_netorder, ct);
     if(ssl->version_netorder==0x300){
         if(ssl3_check_mac(decoder,ct,out,worklen,mac) < 0) {
-            ssl_debug_printf("ssl_decrypt_record: mac falied\n");
+            if (ssl_debug_enabled()) 
+                ssl_debug_printf("ssl_decrypt_record: mac falied\n");
             return -1;
         }
     }
     else{
         if(tls_check_mac(decoder,ct,ssl->version_netorder,out,worklen,mac)< 0) {
-            ssl_debug_printf("ssl_decrypt_record: mac falied\n");
+            if (ssl_debug_enabled()) 
+                ssl_debug_printf("ssl_decrypt_record: mac falied\n");
             return -1;
         }
     }
-    ssl_debug_printf("ssl_decrypt_record: mac ok\n");
+    if (ssl_debug_enabled()) 
+        ssl_debug_printf("ssl_decrypt_record: mac ok\n");
     *outl = worklen;
     return(0);
 }
@@ -1035,7 +1115,8 @@
 {
     const char* str = gnutls_check_version(NULL);
     
-    ssl_debug_printf("ssl_get_version: %s\n", str);
+    if (ssl_debug_enabled()) 
+        ssl_debug_printf("ssl_get_version: %s\n", str);
     sscanf(str, "%d.%d.%d", major, minor, patch);
 }
 
@@ -1065,47 +1146,55 @@
     
     /* compute file size and load all file contents into a datum buffer*/
     if (fseek(fp, 0, SEEK_END) < 0) {
-        ssl_debug_printf("ssl_load_key: can't fseek file\n");
+        if (ssl_debug_enabled()) 
+            ssl_debug_printf("ssl_load_key: can't fseek file\n");
         return NULL;
     }
     if ((size = ftell(fp)) < 0) {
-        ssl_debug_printf("ssl_load_key: can't ftell file\n");
+        if (ssl_debug_enabled()) 
+            ssl_debug_printf("ssl_load_key: can't ftell file\n");
         return NULL;
     }
     if (fseek(fp, 0, SEEK_SET) < 0) {
-        ssl_debug_printf("ssl_load_key: can't refseek file\n");
+        if (ssl_debug_enabled()) 
+            ssl_debug_printf("ssl_load_key: can't refseek file\n");
         return NULL;
     }
     key.data = g_malloc(size);
     key.size = size;
     bytes = fread(key.data, 1, key.size, fp);
     if (bytes < key.size) {
-        ssl_debug_printf("ssl_load_key: can't read from file %d bytes, got %d\n", 
-            key.size, bytes);
+        if (ssl_debug_enabled()) 
+            ssl_debug_printf("ssl_load_key: can't read from file %d bytes, got %d\n", 
+                key.size, bytes);
         return NULL;
     }
     
     /* import PEM data*/
     if (gnutls_x509_privkey_import(priv_key, &key, GNUTLS_X509_FMT_PEM)!=0) {
-        ssl_debug_printf("ssl_load_key: can't import pem data\n");
+        if (ssl_debug_enabled()) 
+            ssl_debug_printf("ssl_load_key: can't import pem data\n");
         return NULL;
     }
-    free(key.data);
+    g_free(key.data);
     
     /* RSA get parameter */
     if (gnutls_x509_privkey_export_rsa_raw(priv_key, &m, &e, &d, &p, &q, &u) != 0) {
-        ssl_debug_printf("ssl_load_key: can't export rsa param (is a rsa private key file ?!?)\n");
+        if (ssl_debug_enabled()) 
+            ssl_debug_printf("ssl_load_key: can't export rsa param (is a rsa private key file ?!?)\n");
         return NULL;
     }
     
     /* convert each rsa parameter to mpi format*/
     if (gcry_mpi_scan( &rsa_params[0], GCRYMPI_FMT_USG, m.data,  m.size, &tmp_size) !=0) {
-        ssl_debug_printf("ssl_load_key: can't convert m rsa param to int (size %d)\n", m.size);
+        if (ssl_debug_enabled()) 
+            ssl_debug_printf("ssl_load_key: can't convert m rsa param to int (size %d)\n", m.size);
         return NULL;
     }
     
     if (gcry_mpi_scan( &rsa_params[1], GCRYMPI_FMT_USG, e.data,  e.size, &tmp_size) != 0) {
-        ssl_debug_printf("ssl_load_key: can't convert e rsa param to int (size %d)\n", e.size);
+        if (ssl_debug_enabled()) 
+            ssl_debug_printf("ssl_load_key: can't convert e rsa param to int (size %d)\n", e.size);
         return NULL;
     }
 
@@ -1114,22 +1203,26 @@
      * our 'p' must be equal to 'q' as provided from openssl and viceversa
      */
     if (gcry_mpi_scan( &rsa_params[2], GCRYMPI_FMT_USG, d.data,  d.size, &tmp_size) !=0) {
-        ssl_debug_printf("ssl_load_key: can't convert d rsa param to int (size %d)\n", d.size);
+        if (ssl_debug_enabled()) 
+            ssl_debug_printf("ssl_load_key: can't convert d rsa param to int (size %d)\n", d.size);
         return NULL;
     }
     
     if (gcry_mpi_scan( &rsa_params[3], GCRYMPI_FMT_USG, q.data,  q.size, &tmp_size) !=0) {
-        ssl_debug_printf("ssl_load_key: can't convert q rsa param to int (size %d)\n", q.size);
+        if (ssl_debug_enabled()) 
+            ssl_debug_printf("ssl_load_key: can't convert q rsa param to int (size %d)\n", q.size);
         return NULL;
     }
 
     if (gcry_mpi_scan( &rsa_params[4], GCRYMPI_FMT_USG, p.data,  p.size, &tmp_size) !=0) {
-        ssl_debug_printf("ssl_load_key: can't convert p rsa param to int (size %d)\n", p.size);
+        if (ssl_debug_enabled()) 
+            ssl_debug_printf("ssl_load_key: can't convert p rsa param to int (size %d)\n", p.size);
         return NULL;
     }
         
     if (gcry_mpi_scan( &rsa_params[5], GCRYMPI_FMT_USG, u.data,  u.size, &tmp_size) !=0) {
-        ssl_debug_printf("ssl_load_key: can't convert u rsa param to int (size %d)\n", m.size);
+        if (ssl_debug_enabled()) 
+            ssl_debug_printf("ssl_load_key: can't convert u rsa param to int (size %d)\n", m.size);
         return NULL; 
     }
     
@@ -1139,7 +1232,8 @@
     if ((major <= 1) && (minor <= 0) && (patch <=13))
     {
         gcry_mpi_t tmp;
-        ssl_debug_printf("ssl_load_key: swapping p and q parametes\n");
+        if (ssl_debug_enabled()) 
+            ssl_debug_printf("ssl_load_key: swapping p and q parametes\n");
         tmp = rsa_params[4];
         rsa_params[4] = rsa_params[3];
         rsa_params[3] = tmp;
@@ -1149,7 +1243,8 @@
             "(private-key(rsa((n%m)(e%m)(d%m)(p%m)(q%m)(u%m))))", rsa_params[0], 
             rsa_params[1], rsa_params[2], rsa_params[3], rsa_params[4], 
             rsa_params[5]) != 0) {
-        ssl_debug_printf("ssl_load_key: can't built rsa private key s-exp\n");
+        if (ssl_debug_enabled()) 
+            ssl_debug_printf("ssl_load_key: can't built rsa private key s-exp\n");
         return NULL;
     }
 
@@ -1176,22 +1271,10 @@
 #endif
 }
 
-#ifdef SSL_DECRYPT_DEBUG
-static FILE* myout=NULL;
-#endif
 void 
 ssl_lib_init(void)
 {
     gnutls_global_init();
-
-#ifdef SSL_DECRYPT_DEBUG    
-#ifdef _WIN32
-    /* we don't have standard I/O file available, open a log */
-    myout = fopen("ssl-decrypt.txt","w");
-    if (!myout)
-#endif /* _WIN32 */
-        myout = stderr;
-#endif /* SSL_DECRYPT_DEBUG */
 }
 
 #else /* HAVE_LIBGNUTLS */
@@ -1204,7 +1287,8 @@
 SSL_PRIVATE_KEY* 
 ssl_load_key(FILE* fp) 
 {
-    ssl_debug_printf("ssl_load_key: impossible without glutls. fp %p\n",fp);
+    if (ssl_debug_enabled()) 
+        ssl_debug_printf("ssl_load_key: impossible without glutls. fp %p\n",fp);
     return NULL;
 }
 
@@ -1216,23 +1300,26 @@
 int 
 ssl_find_cipher(int num,SslCipherSuite* cs) 
 {
-    ssl_debug_printf("ssl_find_cipher: dummy without glutls. num %d cs %p\n",
-        num,cs);
+    if (ssl_debug_enabled()) 
+        ssl_debug_printf("ssl_find_cipher: dummy without glutls. num %d cs %p\n",
+            num,cs);
     return 0; 
 }
 int 
 ssl_generate_keyring_material(SslDecryptSession*ssl) 
 {
-    ssl_debug_printf("ssl_generate_keyring_material: impossible without glutls. ssl %p\n",
-        ssl);
+    if (ssl_debug_enabled()) 
+        ssl_debug_printf("ssl_generate_keyring_material: impossible without glutls. ssl %p\n",
+            ssl);
     return 0; 
 }
 int 
 ssl_decrypt_pre_master_secret(SslDecryptSession* ssl_session, 
     StringInfo* entrypted_pre_master, SSL_PRIVATE_KEY *pk)
 {
-    ssl_debug_printf("ssl_decrypt_pre_master_secret: impossible without glutls."
-        " ssl %p entrypted_pre_master %p pk %p\n", ssl_session,
+    if (ssl_debug_enabled()) 
+        ssl_debug_printf("ssl_decrypt_pre_master_secret: impossible without glutls."
+            " ssl %p entrypted_pre_master %p pk %p\n", ssl_session,
         entrypted_pre_master, pk);
     return 0;
 }
@@ -1241,9 +1328,10 @@
 ssl_decrypt_record(SslDecryptSession*ssl,SslDecoder* decoder, int ct, 
         const unsigned char* in, int inl,unsigned char*out,int* outl)
 {
-    ssl_debug_printf("ssl_decrypt_record: impossible without gnutls. ssl %p"
-        "decoder %p ct %d, in %p inl %d out %p outl %p\n", ssl, decoder, ct,
-        in, inl, out, outl);
+    if (ssl_debug_enabled()) 
+        ssl_debug_printf("ssl_decrypt_record: impossible without gnutls. ssl %p"
+            "decoder %p ct %d, in %p inl %d out %p outl %p\n", ssl, decoder, ct,
+            in, inl, out, outl);
     return 0;
 }
 
@@ -1253,8 +1341,9 @@
 void 
 ssl_session_init(SslDecryptSession* ssl_session)
 {
-    ssl_debug_printf("ssl_session_init: initializing ptr %p size %lu\n", 
-        ssl_session, (unsigned long)sizeof(SslDecryptSession));
+    if (ssl_debug_enabled()) 
+        ssl_debug_printf("ssl_session_init: initializing ptr %p size %lu\n", 
+            ssl_session, (unsigned long)sizeof(SslDecryptSession));
 
     ssl_session->master_secret.data = ssl_session->_master_secret;
     ssl_session->session_id.data = ssl_session->_session_id;
@@ -1263,42 +1352,62 @@
     ssl_session->master_secret.data_len = 48;
 }
 
-#ifdef SSL_DECRYPT_DEBUG
+FILE* ssl_debug_file=NULL;
+
 void 
+ssl_set_debug(char* name)
+{
+#ifdef SSL_DECRYPT_DEBUG    
+    int use_stderr = (strcmp(name, SSL_DEBUG_USE_STDERR) == 0);
+    static int debug_file_must_be_closed = 0;
+    if (debug_file_must_be_closed)
+        fclose(ssl_debug_file);
+    if (use_stderr)    
+        ssl_debug_file = stderr;    
+    else if (strcmp(name, "") ==0)
+        ssl_debug_file = NULL;
+    else
+        ssl_debug_file = fopen(name, "w");    
+    if (!use_stderr && ssl_debug_file)
+        debug_file_must_be_closed = 1;
+#endif /* SSL_DECRYPT_DEBUG */
+}
+
+void 
 ssl_debug_printf(const char* fmt, ...)
 {
   va_list ap;
   int ret=0;
   va_start(ap, fmt);
-  ret += vfprintf(myout, fmt, ap);
+  ret += vfprintf(ssl_debug_file, fmt, ap);
   va_end(ap);
-  fflush(myout);
+  fflush(ssl_debug_file);
 }
 
 void 
 ssl_print_text_data(const char* name, const unsigned char* data, int len)
 {
     int i;
-    fprintf(myout,"%s: ",name);
+    fprintf(ssl_debug_file,"%s: ",name);
     for (i=0; i< len; i++) {
-      fprintf(myout,"%c",data[i]);
+      fprintf(ssl_debug_file,"%c",data[i]);
     }
-    fprintf(myout,"\n");
-    fflush(myout);
+    fprintf(ssl_debug_file,"\n");
+    fflush(ssl_debug_file);
 }
 
 void 
 ssl_print_data(const char* name, const unsigned char* data, int len)
 {
     int i;
-    fprintf(myout,"%s[%d]:\n",name, len);
+    fprintf(ssl_debug_file,"%s[%d]:\n",name, len);
     for (i=0; i< len; i++) {
         if ((i>0) && (i%16 == 0))
-            fprintf(myout,"\n");
-        fprintf(myout,"%.2x ",data[i]&255);
+            fprintf(ssl_debug_file,"\n");
+        fprintf(ssl_debug_file,"%.2x ",data[i]&255);
     }
-    fprintf(myout,"\n");
-    fflush(myout);
+    fprintf(ssl_debug_file,"\n");
+    fflush(ssl_debug_file);
 }
 
 void 
@@ -1306,4 +1415,3 @@
 {
     ssl_print_data(name, data->data, data->data_len);
 }
-#endif /* SSL_DECRYPT_DEBUG */
Index: epan/dissectors/packet-ssl-utils.h
===================================================================
--- epan/dissectors/packet-ssl-utils.h	(revision 17224)
+++ epan/dissectors/packet-ssl-utils.h	(working copy)
@@ -38,6 +38,7 @@
 
 /* #define SSL_FAST 1 */
 #define SSL_DECRYPT_DEBUG
+#define SSL_DEBUG_USE_STDERR "-"
 
 #define SSL_CIPHER_CTX gcry_cipher_hd_t
 #ifdef SSL_FAST
@@ -201,8 +202,24 @@
 extern int 
 ssl_decrypt_record(SslDecryptSession*ssl,SslDecoder* decoder, int ct, 
         const unsigned char* in, int inl,unsigned char*out,int* outl);
+        
 
+/* Controll ssl debug outout
+ @param name file name where debug is log to, an empty file name disable debug
+        and SSL_DEBUG_USE_STDERR cause to log to stderr */
+void 
+ssl_set_debug(char* name);        
+        
 #ifdef SSL_DECRYPT_DEBUG
+static inline int ssl_debug_enabled(void)
+{
+    extern FILE* ssl_debug_file;
+    return ssl_debug_file != NULL;
+}
+#else 
+static inline int ssl_debug_enabled(void)  { return 0;}
+#endif /* SSL_DECRYPT_DEBUG */        
+        
 extern void 
 ssl_debug_printf(const char* fmt,...) GNUC_FORMAT_CHECK(printf,1,2);
 extern void 
@@ -211,16 +228,5 @@
 ssl_print_string(const char* name, const StringInfo* data);
 extern void 
 ssl_print_text_data(const char* name, const unsigned char* data, int len);
-#else
 
-/* No debug: nullify debug operation*/
-static inline void GNUC_FORMAT_CHECK(printf,1,2)
-ssl_debug_printf(const char* fmt _U_,...)
-{ 
-}
-#define ssl_print_data(a, b, c)
-#define ssl_print_string(a, b)
-#define ssl_print_text_data(a, b, c)
 #endif
-
-#endif
Index: epan/dissectors/packet-ssl.c
===================================================================
--- epan/dissectors/packet-ssl.c	(revision 17224)
+++ epan/dissectors/packet-ssl.c	(working copy)
@@ -219,6 +219,7 @@
 
 static char* ssl_keys_list = NULL;
 static char* ssl_ports_list = NULL;
+static char* ssl_debug_file_name = NULL;
 
 typedef struct _SslService {
     address addr;
@@ -306,8 +307,9 @@
     assoc->decrypted_port = ctport;
     assoc->handle = dissector_get_port_handle(tcp_dissectors, ctport);
     
-    ssl_debug_printf("ssl_association_add port %d ctport %d info %s handle %p\n",
-        port, ctport, info, assoc->handle);
+    if (ssl_debug_enabled()) 
+        ssl_debug_printf("ssl_association_add port %d ctport %d info %s handle %p\n",
+            port, ctport, info, assoc->handle);
 
     dissector_add("tcp.port", port, ssl_handle);    
     g_tree_insert(ssl_associations, (gpointer)port, assoc);
@@ -323,7 +325,8 @@
 SslAssociation* ssl_association_find(unsigned int port)
 {
     register SslAssociation* ret = g_tree_lookup(ssl_associations, (gpointer)port);
-    ssl_debug_printf("ssl_association_find: port %d found %p\n", port, ret);
+    if (ssl_debug_enabled()) 
+        ssl_debug_printf("ssl_association_find: port %d found %p\n", port, ret);
     return ret;
 }
 
@@ -332,8 +335,9 @@
     gpointer  data, gpointer  user_data _U_)
 {
     SslAssociation* assoc = (SslAssociation*) data;
-    ssl_debug_printf("ssl_association_remove_handle removing ptr %p handle %p\n",
-        data, assoc->handle);
+    if (ssl_debug_enabled()) 
+        ssl_debug_printf("ssl_association_remove_handle removing ptr %p handle %p\n",
+            data, assoc->handle);
     if (assoc->handle)
         dissector_delete("tcp.port", assoc->ssl_port, assoc->handle);
     g_free(data);
@@ -343,7 +347,8 @@
 static inline int ssl_packet_from_server(unsigned int port)
 {
     register int ret = ssl_association_find(port) != 0;
-    ssl_debug_printf("ssl_packet_from_server: is from server %d\n", ret);    
+    if (ssl_debug_enabled()) 
+        ssl_debug_printf("ssl_packet_from_server: is from server %d\n", ret);    
     return ret;
 }    
 
@@ -383,7 +388,8 @@
         char* start = strdup(ssl_keys_list);
         char* tmp = start;
         
-        ssl_debug_printf("ssl_init keys string %s\n", start);
+        if (ssl_debug_enabled()) 
+            ssl_debug_printf("ssl_init keys string %s\n", start);
         do {
             char* addr, *port, *filename;
             unsigned char* ip;
@@ -400,11 +406,13 @@
             }
             
             /* for each entry split ip, port, filename with ':' separator */
-            ssl_debug_printf("ssl_init found host entry %s\n", addr);
+            if (ssl_debug_enabled()) 
+                ssl_debug_printf("ssl_init found host entry %s\n", addr);
             port = strchr(addr, ':');
             if (!port)
             {
-                ssl_debug_printf("ssl_init entry malformed can't find port in %s\n", addr);
+                if (ssl_debug_enabled()) 
+                    ssl_debug_printf("ssl_init entry malformed can't find port in %s\n", addr);
                 break;
             }
             *port = 0;
@@ -413,7 +421,8 @@
             filename = strchr(port,':');
             if (!filename)
             {
-                ssl_debug_printf("ssl_init entry malformed can't find filename in %s\n", port);
+                if (ssl_debug_enabled()) 
+                    ssl_debug_printf("ssl_init entry malformed can't find filename in %s\n", port);
                 break;
             }
             *filename=0;
@@ -426,8 +435,9 @@
             service->addr.data = ip = ((unsigned char*)service) + sizeof(SslService);
             sscanf(addr, "%hhu.%hhu.%hhu.%hhu", &ip[0], &ip[1], &ip[2], &ip[3]);
             service->port = atoi(port);
-            ssl_debug_printf("ssl_init addr %hhu.%hhu.%hhu.%hhu port %d filename %s\n", 
-                ip[0], ip[1], ip[2], ip[3], service->port, filename);
+            if (ssl_debug_enabled()) 
+                ssl_debug_printf("ssl_init addr %hhu.%hhu.%hhu.%hhu port %d filename %s\n", 
+                    ip[0], ip[1], ip[2], ip[3], service->port, filename);
     
             /* try to load pen file*/
             fp = fopen(filename, "rb");
@@ -444,8 +454,9 @@
             }
             fclose(fp);
             
-            ssl_debug_printf("ssl_init private key file %s successfully loaded\n", 
-                filename);
+            if (ssl_debug_enabled()) 
+                ssl_debug_printf("ssl_init private key file %s successfully loaded\n", 
+                    filename);
             g_hash_table_insert(ssl_key_hash, service, private_key);
                
         } while (end != NULL);
@@ -459,7 +470,8 @@
         char* start = strdup(ssl_ports_list);
         char* tmp = start;
         
-        ssl_debug_printf("ssl_init ports string %s\n", start);
+        if (ssl_debug_enabled()) 
+            ssl_debug_printf("ssl_init ports string %s\n", start);
         do {
             char* port, *ctport, *info;
             unsigned int portn, ctportn;
@@ -473,7 +485,8 @@
             }
             
             /* for each entry split ip, port, filename with ':' separator */
-            ssl_debug_printf("ssl_init found port entry %s\n", port);
+            if (ssl_debug_enabled()) 
+                ssl_debug_printf("ssl_init found port entry %s\n", port);
             ctport = strchr(port, ':');
             if (!ctport)
                 break;
@@ -492,11 +505,14 @@
             if (!portn || !ctportn)
                 break;
             
-            ssl_debug_printf("ssl_init adding dissector to port %d (ct port %d)\n", portn, ctportn);
+            if (ssl_debug_enabled()) 
+                ssl_debug_printf("ssl_init adding dissector to port %d (ct port %d)\n", portn, ctportn);
             ssl_association_add(portn, ctportn, info);
         } while (end != NULL);
         free(tmp);
     }
+    
+    ssl_set_debug(ssl_debug_file_name);
 
     /* [re] add ssl dissection to defaults ports */
     ssl_association_add(443, 80, "Hypertext transfer protocol");
@@ -518,20 +534,25 @@
     ssl_data_set(session_id, ssl->session_id.data, ssl->session_id.data_len);
     ssl_data_set(master_secret, ssl->master_secret.data, ssl->master_secret.data_len);
     g_hash_table_insert(ssl_session_hash, session_id, master_secret);
-    ssl_print_string("ssl_save_session stored session id", session_id);
-    ssl_print_string("ssl_save_session stored master secret", master_secret);
+    if (ssl_debug_enabled()) 
+    {
+        ssl_print_string("ssl_save_session stored session id", session_id);
+        ssl_print_string("ssl_save_session stored master secret", master_secret);
+    }
 }
 
 static void ssl_restore_session(SslDecryptSession* ssl)
 {
     StringInfo* ms = g_hash_table_lookup(ssl_session_hash, &ssl->session_id);
     if (!ms) {
-        ssl_debug_printf("ssl_restore_session can't find stored session\n");
+        if (ssl_debug_enabled()) 
+            ssl_debug_printf("ssl_restore_session can't find stored session\n");
         return;
     }
     ssl_data_set(&ssl->master_secret, ms->data, ms->data_len);
     ssl->state |= SSL_MASTER_SECRET;    
-    ssl_debug_printf("ssl_restore_session master key retrived\n");
+    if (ssl_debug_enabled()) 
+        ssl_debug_printf("ssl_restore_session master key retrived\n");
 }
 
 /* The TCP port to associate with by default */
@@ -1215,10 +1236,10 @@
             dummy.addr = pinfo->net_dst;
             dummy.port = pinfo->destport;
         }
-        ssl_debug_printf("dissect_ssl server %hhd.%hhd.%hhd.%hhd:%d\n", 
-            dummy.addr.data[0],
-            dummy.addr.data[1],dummy.addr.data[2],
-            dummy.addr.data[3],dummy.port);
+        if (ssl_debug_enabled()) 
+            ssl_debug_printf("dissect_ssl server %hhd.%hhd.%hhd.%hhd:%d\n", 
+                dummy.addr.data[0],dummy.addr.data[1],dummy.addr.data[2],
+                dummy.addr.data[3],dummy.port);
 
         /* try to retrive private key for this service. Do it now 'cause pinfo
          * is not always available 
@@ -1226,7 +1247,8 @@
          * and thus decryption never engaged*/
         ssl_session->private_key = g_hash_table_lookup(ssl_key_hash, &dummy);
         if (!ssl_session->private_key) 
-            ssl_debug_printf("dissect_ssl can't find private key for this server!\n");
+            if (ssl_debug_enabled()) 
+                ssl_debug_printf("dissect_ssl can't find private key for this server!\n");
     }
     conv_version= & ssl_session->version;
 
@@ -1381,27 +1403,32 @@
     
     /* if we can decrypt and decryption have success
     * add decrypted data to this packet info*/
-    ssl_debug_printf("decrypt_ssl3_record: app_data len %d ssl state %X\n", 
-        record_length, ssl->state);
+    if (ssl_debug_enabled()) 
+        ssl_debug_printf("decrypt_ssl3_record: app_data len %d ssl state %X\n", 
+            record_length, ssl->state);
     if (!(ssl->state & SSL_HAVE_SESSION_KEY)) {
-        ssl_debug_printf("decrypt_ssl3_record: no session key\n");
+        if (ssl_debug_enabled()) 
+            ssl_debug_printf("decrypt_ssl3_record: no session key\n");
         return ;
     }
     
     /* retrive decoder for this packet direction*/    
     if ((direction = ssl_packet_from_server(pinfo->srcport)) != 0) {
-        ssl_debug_printf("decrypt_ssl3_record: using server decoder\n");
+        if (ssl_debug_enabled()) 
+            ssl_debug_printf("decrypt_ssl3_record: using server decoder\n");
         decoder = &ssl->server;
     }
     else { 
-        ssl_debug_printf("decrypt_ssl3_record: using client decoder\n");
+        if (ssl_debug_enabled()) 
+            ssl_debug_printf("decrypt_ssl3_record: using client decoder\n");
         decoder = &ssl->client;
     }
     
     /* ensure we have enough storage space for decrypted data */
     if (record_length > ssl_decrypted_data.data_len)
     {
-        ssl_debug_printf("decrypt_ssl3_record: allocating %d bytes"
+        if (ssl_debug_enabled()) 
+            ssl_debug_printf("decrypt_ssl3_record: allocating %d bytes"
                 " for decrypt data (old len %d)\n", 
                 record_length + 32, ssl_decrypted_data.data_len);
         ssl_decrypted_data.data = g_realloc(ssl_decrypted_data.data, 
@@ -1420,8 +1447,9 @@
         StringInfo* data = p_get_proto_data(pinfo->fd, proto_ssl);
         if (!data) 
         {
-            ssl_debug_printf("decrypt_ssl3_record: allocating app_data %d "
-                "bytes for app data\n", len);
+            if (ssl_debug_enabled()) 
+                ssl_debug_printf("decrypt_ssl3_record: allocating app_data %d "
+                    "bytes for app data\n", len);
             /* first app data record: allocate and put packet data*/
             data = se_alloc(sizeof(StringInfo));
             data->data = se_alloc(len);
@@ -1431,9 +1459,10 @@
         else { 
             unsigned char* store;
             /* update previus record*/
-            ssl_debug_printf("decrypt_ssl3_record: reallocating app_data "
-                "%d bytes for app data (total %d appdata bytes)\n", 
-                len, data->data_len + len);
+            if (ssl_debug_enabled()) 
+                ssl_debug_printf("decrypt_ssl3_record: reallocating app_data "
+                    "%d bytes for app data (total %d appdata bytes)\n", 
+                    len, data->data_len + len);
             store = se_alloc(data->data_len + len);
             memcpy(store, data->data, data->data_len);
             memcpy(&store[data->data_len], ssl_decrypted_data.data, len);
@@ -1444,11 +1473,13 @@
             data->data = store;
             
             /* data ptr is changed, so remove old one and re-add the new one*/
-            ssl_debug_printf("decrypt_ssl3_record: removing old app_data ptr\n");
+            if (ssl_debug_enabled()) 
+                ssl_debug_printf("decrypt_ssl3_record: removing old app_data ptr\n");
             p_remove_proto_data(pinfo->fd, proto_ssl);
         }
      
-        ssl_debug_printf("decrypt_ssl3_record: setting decrypted app_data ptr %p\n",data);
+        if (ssl_debug_enabled()) 
+            ssl_debug_printf("decrypt_ssl3_record: setting decrypted app_data ptr %p\n",data);
         p_add_proto_data(pinfo->fd, proto_ssl, data);
     }
 }
@@ -1652,7 +1683,8 @@
     /*
      * now dissect the next layer
      */
-    ssl_debug_printf("dissect_ssl3_record: content_type %d\n",content_type);
+    if (ssl_debug_enabled()) 
+        ssl_debug_printf("dissect_ssl3_record: content_type %d\n",content_type);
     
     /* PAOLO try to decrypt each record (we must keep ciphers "in sync") 
      * store plain text only for app data */
@@ -1709,7 +1741,8 @@
             tvbuff_t* new_tvb;
             
             /* try to dissect decrypted data*/
-            ssl_debug_printf("dissect_ssl3_record decrypted len %d\n", decrypted->data_len);
+            if (ssl_debug_enabled()) 
+                ssl_debug_printf("dissect_ssl3_record decrypted len %d\n", decrypted->data_len);
             
              /* create new tvbuff for the decrypted data */
             new_tvb = tvb_new_real_data(decrypted->data, 
@@ -1719,9 +1752,12 @@
             
             /* find out a dissector using server port*/
             if (association && association->handle) {
-                ssl_debug_printf("dissect_ssl3_record found association %p\n", association);
-                ssl_print_text_data("decrypted app data",decrypted->data, 
-                    decrypted->data_len);
+                if (ssl_debug_enabled()) 
+                {
+                    ssl_debug_printf("dissect_ssl3_record found association %p\n", association);
+                    ssl_print_text_data("decrypted app data",decrypted->data, 
+                        decrypted->data_len);
+                }
                 
                 call_dissector(association->handle, new_tvb, pinfo, ssl_record_tree);
             }
@@ -1893,8 +1929,9 @@
         msg_type_str = match_strval(msg_type, ssl_31_handshake_type);
         length   = tvb_get_ntoh24(tvb, offset + 1);
 
-        ssl_debug_printf("dissect_ssl3_handshake iteration %d type %d offset %d lenght %d "
-            "bytes, remaning %d \n", first_iteration, msg_type, offset, length, record_length);
+        if (ssl_debug_enabled()) 
+            ssl_debug_printf("dissect_ssl3_handshake iteration %d type %d offset %d lenght %d "
+                "bytes, remaning %d \n", first_iteration, msg_type, offset, length, record_length);
         if (!msg_type_str && !first_iteration)
         {
             /* only dissect / report messages if they're
@@ -2012,12 +2049,14 @@
                         break;
                     
                     /* check for required session data */
-                    ssl_debug_printf("dissect_ssl3_handshake found SSL_HND_CLIENT_KEY_EXCHG state %X\n",
-                        ssl->state);
+                    if (ssl_debug_enabled()) 
+                        ssl_debug_printf("dissect_ssl3_handshake found SSL_HND_CLIENT_KEY_EXCHG state %X\n",
+                            ssl->state);
                     if ((ssl->state & (SSL_CIPHER|SSL_CLIENT_RANDOM|SSL_SERVER_RANDOM|SSL_VERSION)) !=
                             (SSL_CIPHER|SSL_CLIENT_RANDOM|SSL_SERVER_RANDOM|SSL_VERSION)) {
-                        ssl_debug_printf("dissect_ssl3_handshake not enough data to generate key (required %X)\n",
-                            (SSL_CIPHER|SSL_CLIENT_RANDOM|SSL_SERVER_RANDOM|SSL_VERSION));
+                        if (ssl_debug_enabled()) 
+                            ssl_debug_printf("dissect_ssl3_handshake not enough data to generate key (required %X)\n",
+                                (SSL_CIPHER|SSL_CLIENT_RANDOM|SSL_SERVER_RANDOM|SSL_VERSION));
                         break;
                     }
                                 
@@ -2028,7 +2067,8 @@
                     tvb_memcpy(tvb, encrypted_pre_master.data, offset+2, length-2);
                     
                     if (!ssl->private_key) {
-                        ssl_debug_printf("dissect_ssl3_handshake can't find private key\n");
+                        if (ssl_debug_enabled()) 
+                            ssl_debug_printf("dissect_ssl3_handshake can't find private key\n");
                         break;
                     }
                                 
@@ -2036,16 +2076,19 @@
                      * will be used for master secret store*/
                     ret = ssl_decrypt_pre_master_secret(ssl, &encrypted_pre_master, ssl->private_key);
                     if (ret < 0) {
-                        ssl_debug_printf("dissect_ssl3_handshake can't decrypt pre master secret\n");
+                        if (ssl_debug_enabled()) 
+                            ssl_debug_printf("dissect_ssl3_handshake can't decrypt pre master secret\n");
                         break;
                     }
                     if (ssl_generate_keyring_material(ssl)<0) {
-                        ssl_debug_printf("dissect_ssl3_handshake can't generate keyring material\n");
+                        if (ssl_debug_enabled()) 
+                            ssl_debug_printf("dissect_ssl3_handshake can't generate keyring material\n");
                         break;
                     }
                     ssl->state |= SSL_HAVE_SESSION_KEY;
                     ssl_save_session(ssl);
-                    ssl_debug_printf("dissect_ssl3_handshake session keys succesfully generated\n");
+                    if (ssl_debug_enabled()) 
+                        ssl_debug_printf("dissect_ssl3_handshake session keys succesfully generated\n");
                 }
                 break;
 
@@ -2088,8 +2131,9 @@
             ssl->state |= SSL_SERVER_RANDOM;
         else
             ssl->state |= SSL_CLIENT_RANDOM;
-        ssl_debug_printf("dissect_ssl3_hnd_hello_common found random state %X\n", 
-            ssl->state);
+        if (ssl_debug_enabled()) 
+            ssl_debug_printf("dissect_ssl3_hnd_hello_common found random state %X\n", 
+                ssl->state);
         
         session_id_length = tvb_get_guint8(tvb, offset + 32);
         /* check stored session id info */
@@ -2351,27 +2395,33 @@
             /* store selected cipher suite for decryption */
             ssl->cipher = tvb_get_ntohs(tvb, offset);
             if (ssl_find_cipher(ssl->cipher,&ssl->cipher_suite) < 0) {
-                ssl_debug_printf("dissect_ssl3_hnd_srv_hello can't find cipher suite %X\n", ssl->cipher);
+                if (ssl_debug_enabled()) 
+                    ssl_debug_printf("dissect_ssl3_hnd_srv_hello can't find cipher suite %X\n", 
+                        ssl->cipher);
                 goto no_cipher;
             }
 
             ssl->state |= SSL_CIPHER;
-            ssl_debug_printf("dissect_ssl3_hnd_srv_hello found cipher %X, state %X\n", 
-                ssl->cipher, ssl->state);
+            if (ssl_debug_enabled()) 
+                ssl_debug_printf("dissect_ssl3_hnd_srv_hello found cipher %X, state %X\n", 
+                    ssl->cipher, ssl->state);
 
             /* if we have restored a session now we can have enought material 
              * to build session key, check it out*/
             if ((ssl->state & 
                     (SSL_CIPHER|SSL_CLIENT_RANDOM|SSL_SERVER_RANDOM|SSL_VERSION|SSL_MASTER_SECRET)) !=
                     (SSL_CIPHER|SSL_CLIENT_RANDOM|SSL_SERVER_RANDOM|SSL_VERSION|SSL_MASTER_SECRET)) {
-                ssl_debug_printf("dissect_ssl3_hnd_srv_hello not enough data to generate key (required %X)\n",
-                    (SSL_CIPHER|SSL_CLIENT_RANDOM|SSL_SERVER_RANDOM|SSL_VERSION|SSL_MASTER_SECRET));
+                if (ssl_debug_enabled()) 
+                    ssl_debug_printf("dissect_ssl3_hnd_srv_hello not enough data to generate key (required %X)\n",
+                        (SSL_CIPHER|SSL_CLIENT_RANDOM|SSL_SERVER_RANDOM|SSL_VERSION|SSL_MASTER_SECRET));
                 goto no_cipher;
             }
             
-            ssl_debug_printf("dissect_ssl3_hnd_srv_hello trying to generate keys\n");
+            if (ssl_debug_enabled()) 
+                ssl_debug_printf("dissect_ssl3_hnd_srv_hello trying to generate keys\n");
             if (ssl_generate_keyring_material(ssl)<0) {
-                ssl_debug_printf("dissect_ssl3_hnd_srv_hello can't generate keyring material\n");
+                if (ssl_debug_enabled()) 
+                    ssl_debug_printf("dissect_ssl3_hnd_srv_hello can't generate keyring material\n");
                 goto no_cipher;
             }
             ssl->state |= SSL_HAVE_SESSION_KEY;
@@ -2994,8 +3044,9 @@
                  challenge */
                 int max = challenge_length > 32? 32: challenge_length;
                 
-                ssl_debug_printf("client random len: %d padded to 32\n",
-                    challenge_length);
+                if (ssl_debug_enabled()) 
+                    ssl_debug_printf("client random len: %d padded to 32\n",
+                        challenge_length);
                 
                 /* client random is padded with zero and 'right' aligned */
                 memset(ssl->client_random.data, 0, 32 - max);
@@ -4277,14 +4328,14 @@
     proto_register_subtree_array(ett, array_length(ett));
 
     {
-      module_t *ssl_module = prefs_register_protocol(proto_ssl, ssl_parse);
-      prefs_register_bool_preference(ssl_module,
+        module_t *ssl_module = prefs_register_protocol(proto_ssl, ssl_parse);
+        prefs_register_bool_preference(ssl_module,
              "desegment_ssl_records",
              "Reassemble SSL records spanning multiple TCP segments",
              "Whether the SSL dissector should reassemble SSL records spanning multiple TCP segments. "
              "To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
              &ssl_desegment);
-       prefs_register_string_preference(ssl_module, "keys_list", "RSA keys list",
+        prefs_register_string_preference(ssl_module, "keys_list", "RSA keys list",
              "comma separated list of private RSA keys used for SSL decryption; "
              "each list entry must be in the form of <ip>:<port>:<key_file_name>"
              "<key_file_name>   is the local file name of the RSA private key used by the specified server\n",
@@ -4294,6 +4345,11 @@
              "each list entry must be in the form of <port>:<clear-text-port>"
              "<clear-text-port>   is the port numbert associated with the protocol tunneled over SSL for this port\n",
              (const char **)&ssl_ports_list);
+        prefs_register_string_preference(ssl_module, "debug", "debug file",
+             "file name where verbose debug is log into; use no file name to"
+             "disable debug, or '-' to log onto standard error. Enabling debug"
+             "will show down dissection. Debug file will be rewritten\n",
+             (const char **)&ssl_debug_file_name);
     }
 
     register_dissector("ssl", dissect_ssl, proto_ssl);
@@ -4301,8 +4357,9 @@
     register_init_routine(ssl_init);
     ssl_lib_init();
     ssl_tap = register_tap("ssl");
-    ssl_debug_printf("proto_register_ssl: registered tap %s:%d\n",
-        "ssl", ssl_tap);
+    if (ssl_debug_enabled()) 
+        ssl_debug_printf("proto_register_ssl: registered tap %s:%d\n",
+            "ssl", ssl_tap);
 }
 
 /* If this dissector uses sub-dissector registration add a registration