Revisiting Our Web Browser

Once youve installed a provider on the client side, the next step is to create and configure an instance of SSLSocket . This process is analogous to how an instance of SSLServerSocket is created on the server side. In particular, the following code gets the default SSLSocketFactory and proceeds to create an instance of SSLSocket : public static String ANON_CIPHER = SSL_DH_anon_WITH_RC4_128_MD5; public static String[] CIPHERS = {ANON_CIPHER}; public Socket createSocketString host, int port { try { java.security.Security.addProvidernew com.sun.net.ssl.internal.ssl. Provider ; SSLSocketFactory socketFactory = SSLSocketFactory SSLSocketFactory. getDefault ; SSLSocket returnValue = SSLSocket socketFactory.createSockethost, port; returnValue.setEnabledCipherSuitesCIPHERS; return returnValue; } .. }

2.6.2.4 Sending data

Its important to note that at this point, weve created and configured two sockets: an SSLServerSocket on the server side and an ordinary SSLSocket on the client side. There has not, however, been any communication between them. The SSL handshake has not yet occurred, and no information, of any type, has been sent over the wire. This is because we need time, once weve created the sockets, to configure them. The SSL handshake occurs the first time we attempt to send or receive data on the client side. That is, the first time code such as the following is executed, the SSL sockets will attempt to complete a handshake: InputStream inputStream = sslsocket.getInputStream ; inputStream.read ;

2.6.3 Revisiting Our Web Browser

With the discussion of SSL under our belt, we can almost reimplement our web server as a secure web server. In our original web server, we created an instance of ServerSocket in the startListening method: public void startListening { ServerSocket serverSocket; try { serverSocket = new ServerSocket80; } .... } We can replace this with the following code: public void startListening { ServerSocket serverSocket; try { serverSocket = getSSLServerSocket443; } .... } private static String ANON_CIPHER_1 = SSL_DH_anon_WITH_DES_CBC_SHA; private static String ANON_CIPHER_2 = SSL_DH_anon_WITH_3DES_EDE_CBC_SHA; private static String ANON_CIPHER_ 3 = SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA; private static String ANON_CIPHER_4 = SSL_DH_anon_WITH_RC4_128_MD5; private static String ANON_CIPHER_5 = SSL_DH_anon_EXPORT_WITH_RC4_40_MD5; private static String[] CIPHERS = {ANON_CIPHER_1, ANON_CIPHER_ 2, ANON_CIPHER_3, ANON_CIPHER_4, ANON_CIPHER_5}; static { java.security.Security.addProvidernew com.sun.net.ssl.internal.ssl. Provider ; } private ServerSocket getSSLServerSocketint port throws IOException { SSLServerSocketFactory socketFactory = SSLServerSocketFactory SSLServerSocketFactory.getDefault ; SSLServerSocket returnValue = SSLServerSocket socketFactory. createServerSocketport; returnValue.setEnabledCipherSuitesCIPHER S; returnValue.setNeedClientAuthfalse; returnValue.setEnableSessionCreationtrue; return returnValue; } This code creates an instance of SSLServerSocket that will work with five different anonymous ciphersuites and listen on port 443, which is the default port for https: requests. And this almost works. Sadly, if you attempt to connect to a running instance of SSLWebServer using Netscape Navigator 4.6, youll get the error dialog shown in Figur e 2- 4 . Figure 2-4. SSL error dialog for Netscape Navigator 4.6 Actually, this is pretty impressive; a legacy application written in C and released in 1998 communicated with our SSL server, engaged in an SSL handshake, and realized that there was no way to establish a common ciphersuite web browsers require servers to authenticate themselves. This cross-language compatibility is one of the strongest reasons to adopt SSL as an encryption and authentication layer.

Chapter 3. A Socket-Based Printer Server