Sun Java System Web Server 7.0 Update 1 Troubleshooting Guide

Chapter 6 Security

Issuing Test Request to an SSL Server

While diagnosing problems between Web Server 7.0 and web browsers, it is useful to analyze the requests and responses. When SSL/TLS is not used, for capturing requests and responses between web browser and the server you can use any network capture tool such as ethereal.

But when SSL/TLS is used for communication, you can use the OpensSSL's s_client application for tapping the communication.

Execute the following command (after successful SSL connection) and enter the test HTTP request as desired.


$openssl s_client -host localhost -port 8080 -quiet

By using the same command without the -quiet flag, you can see information about the connection, such as the server DN, Certificate name and negotiated cipher suite.

For testing particular cipher suites, check the -cipher option. For example:


$openssl s_client -host localhost -port 8080  -cipher DES-CBC-SHA

For more information, see the s_client man page at http://www.openssl.org/docs/apps/s_client.html.

Analyzing SSL Requests

Earlier method of issuing test request works well as long as you can recreate the request content manually. But sometimes you need to diagnose a connection that is being used by a web browser.

There are a number of tools available to observe such request and response data. One such tool is ssltap. ssltap takes the proxy approach-it serves as a simple proxy between the client and the Web Server and displays information about the connections it forwards (you can also use ssltap for observing plain HTTP requests or even requests based on other protocols).

Assume that Web Server is running with an SSL-enabled listener on port 8088 on a machine. Now issue the following command:


$ssltap -l -s localhost:8088
Looking up "localhost"...
Proxy socket ready and listening

Note –

Use the -l option so ssltap doesn't exit after a single request.


By default ssltap listens on port 1924. Now connect to https://localhost:1924 with your browser. You will get an output like the following snippet:


Connection #1 [Mon Dec 10 15:49:49 2006]
Connected to localhost:8088
--> [
alloclen = 87 bytes
(87 bytes of 87)
 [Mon Apr 10 15:49:49 2006] [ssl2]  ClientHelloV2 {
           version = {0x03, 0x01}
           cipher-specs-length = 60 (0x3c)
           sid-length = 0 (0x00)
           challenge-length = 16 (0x10)
           cipher-suites = {
                (0x000039) TLS/DHE-RSA/AES256-CBC/SHA
                (0x000038) TLS/DHE-DSS/AES256-CBC/SHA
                (0x000035) TLS/RSA/AES256-CBC/SHA
                (0x000033) TLS/DHE-RSA/AES128-CBC/SHA
                (0x000032) TLS/DHE-DSS/AES128-CBC/SHA
                (0x000004) SSL3/RSA/RC4-128/MD5
                (0x000005) SSL3/RSA/RC4-128/SHA
                (0x00002f) TLS/RSA/AES128-CBC/SHA
                (0x000016) SSL3/DHE-RSA/3DES192EDE-CBC/SHA
                (0x000013) SSL3/DHE-DSS/DES192EDE3CBC/SHA
                (0x00feff) SSL3/RSA-FIPS/3DESEDE-CBC/SHA
                (0x00000a) SSL3/RSA/3DES192EDE-CBC/SHA
                (0x000015) SSL3/DHE-RSA/DES56-CBC/SHA
                (0x000012) SSL3/DHE-DSS/DES56-CBC/SHA
                (0x00fefe) SSL3/RSA-FIPS/DES-CBC/SHA
                (0x000009) SSL3/RSA/DES56-CBC/SHA
                (0x000064) TLS/RSA-EXPORT1024/RC4-56/SHA
                (0x000062) TLS/RSA-EXPORT1024/DES56-CBC/SHA
                (0x000003) SSL3/RSA/RC4-40/MD5
                (0x000006) SSL3/RSA/RC2CBC40/MD5
                }
           session-id = { }
           challenge = { 0xdfb5 0x1d22 0x6562 0x34f6 0x95b9 0x668a 0x234e 0x38ea }
}
]

This is the SSL client hello being sent from the browser to the server. Note the list of cipher suites the browser has sent. This is the set of cipher suites the browser is configured to handle (note that they are sorted in order of preference). The server will pick one of those for the handshake (if the server is not set up to handle any of these, the connection will then immediately fail). In the above snippet, the session-id is empty, which tells you the browser does not have any cached SSL session with this particular server.

For the above request, the Web Server's response is shown below:


<-- [
(1015 bytes of 1010)
SSLRecord { [Mon Apr 10 15:49:49 2006]
   type    = 22 (handshake)
   version = { 3,1 }
   length  = 1010 (0x3f2)
   handshake {
      type = 2 (server_hello)
      length = 70 (0x000046)
         ServerHello {
            server_version = {3, 1}
            random = {...}
            session ID = {
                length = 32
                contents = {..}
            }
            cipher_suite = (0x0035) TLS/RSA/AES256-CBC/SHA
         }
      type = 11 (certificate)
      length = 928 (0x0003a0)
         CertificateChain {
            chainlength = 925 (0x039d)
            Certificate {
               size = 485 (0x01e5)
               data = { saved in file 'cert.001' }
            }
            Certificate {
               size = 434 (0x01b2)
               data = { saved in file 'cert.002' }
            }
         }
      type = 14 (server_hello_done)
      length = 0 (0x000000)
   }
}
]

The server picked TLS/RSA/AES256-CBC/SHA as the cipher suite to use. A session ID was sent, which this client will include in subsequent requests. The server also sent its certificate chain for the browser to verify. ssltap saved these certificates in the files noted cert.001 and cert.002. You can examine these certificates with any tool that can parse X.509 certificates. For example, execute the following command:


$openssl x509 -in cert.001 -text -inform DER

Note –

ssltap is a single threaded proxy server. So if you issue multiple requests through it, the requests will get serialized. If you need to analyze a specific problem with your application that only occurs on concurrent requests through SSL, try running multiple ssltap instances.