Choosing an SSL Cipher Suite

To use extended verification, write a class that implements the HostnameVerifier interface com.sun.net.ssl.HostnameVerifier . This interface contains a single method: public boolean verifyString urlHostname, String certHostname Verify that the common name from the server certificate should be accepted when attempting to connect to the given URL hostname. Return true if you want to accept the connection; false otherwise. Hostname verifiers are installed on instances of the HttpsURLConnection class com.sun.net.ssl.HttpsURLConnection , which extends the standard HttpURLConnection class. These are returned from the openConnection method of the URL class. There are two methods by which you can install a hostname verifier: public static void setDefaultHostnameVerifierHostnameVerifier v Set the hostname verifier that will be used by default for all future instances of HTTPS connections. public void setHostnameVerifierHostnameVerifier v Set the hostname verifier that will be used for this particular instance of the HTTPS connection. This method must be called before obtaining the input or output socket of the connection. Heres an example that puts this all together: package javasec.samples.ch14; import java.io.; import java.net.; import com.sun.net.ssl.; public class HttpsClient { static class HttpClientVerifier implements HostnameVerifier { public boolean verifyString url, String cert { try { We know the strings dont match, but its conceivable that their IP addresses do. We could also ask the user here. InetAddress iaU = InetAddress.getByNameurl; InetAddress iaC = InetAddress.getByNamecert; return iaU.equalsiaC; } catch Exception e { return false; } } } public static void mainString[] args throws Exception { URL u = new URLargs[0]; Alternately, we could set a global verifier like this HttpsURLConnection.setDefaultHostnameVerifier new HttpClientVerifier ; HttpsURLConnection huc = HttpsURLConnection u.openConnection ; Instead, we set the verifier only for this instance huc.setHostnameVerifiernew HttpClientVerifier ; BufferedReader br = new BufferedReader new InputStreamReaderhuc.getInputStream ; String s = br.readLine ; while s = null { System.out.printlns; s = br.readLine ; } } }

14.6.2 HTTPS Properties

Four properties control how the HTTPS protocol handler operates. Weve already seen the first of these, the java.protocol.handler.pkgs property that defines which class should be used as the protocol handler. Additionally, you may specify any of the following properties: https.proxyHost If you must go through a proxy server to access the URL in question, set this property to the name of the proxy server. https.proxyPort If you must go through a proxy server that resides on a port other than 80, set this property to the port number. http.nonProxyHost If there are hosts on your local network that should be accessed directly rather than through the proxy host, set this property to a list of those hosts. The hosts should be separated by the pipe | symbol: www.sun.com|www.ora.com. Note that this property applies to both the HTTP and HTTPS protocols, despite its name there is no separate https.nonProxyHost property. https.cipherSuites If you want to use a particular set of SSL cipher suites, set this property to a list of comma−separated suites that you wish to use.

14.7 Debugging JSSE

Code that is involved in an SSL conversation can be tricky to debug because many of the details that youd normally handle yourself key exchange, certificate verification, and so on are hidden from you. When these operations dont work, it can be difficult to figure out what went wrong. Complicating this is the fact that setting up an SSL connection is a time−consuming operation. Both parties in the conversation must create a secure random number an instance of the SecureRandom class if they are Java programs. Then the peers must negotiate which key exchange algorithm to use and actually perform the key exchange. Only then is the socket available to send and receive data. So our first tip in working with SSL code is to be patient when you start a program. Several exceptions are thrown by the JSSE API. These are often self−explanatory. For example, if you attempt to retrieve the certificate chain of a peer from the SSLSession object, you will get an SSLPeerUnverifiedException if the peer is not verified. However, you will get a SocketException with the somewhat cryptic detail message of No SSL Sockets if you specify an incorrect password for a keystore used by an SSL context or an SSL socket factory. Exceptions are not always thrown when you might expect, however. In particular, an SSL socket will become connected at the socket level even if the SSL protocol negotiation fails. For instance, when an SSL client calls the createSocket method, it will receive a valid socket even if it is unable to verify the identity of the server to which it is connecting because, for example, the client used the incorrect truststore. If the client attempts an SSL operation on the socket such as retrieving the certificate chain in order to verify the servers hostname, an exception will be thrown. If, however, the client just uses the socket, no exception will occur: the write method will succeed. In this case, the server can read from the socket, but it will get no data. Similarly, the server can write data to the client and the client will see that data was written but be unable to read that data. In our simple test program, this manifests itself with the following output: piccolo java SSLSimpleClient localhost 9096 Who is Sylvia? null Here the client has failed to specify a truststore; it will use the default cacerts truststore. Since that truststore does not contain the root certificate that our server uses, the server verification fails. But the client doesnt really know that until it reads data from the server and receives a null string. This is another reason why its important to verify the name of the peer to which you are connecting. Finally, JSSE specifies a property−based debug facility that supplements the standard debug facility of the java.security package. We explained this facility in Chapter 1.

14.8 Summary

In this chapter, weve looked at JSSE and how it provides support for SSL and TLS. SSL is an important protocol because it is so ubiquitous. Since it requires only one participant in a conversation to possess a valid certificate, SSL makes it easy to send and receive secure, encrypted data in an environment with relatively few servers and many clients. SSL is also the basis of the HTTPS protocol, the secure HTTP protocol. From an application perspective, the HTTPS protocol handler that comes with JSSE makes it simple to talk to HTTPS servers using the same code youd use to talk to a standard HTTP server. 290

Chapter 15. Authentication and Authorization

So far, weve examined security mainly from the perspective of how it protects the end user from the outside world. The default sandbox protects end users from writers of malicious Java programs; digital signatures protect the integrity of end user data while encryption protects the confidentiality of end user data. But how do we protect the rest of the world from end users? Thats the topic of this chapter, which focuses on the Java Authentication and Authorization Service JAAS. JAAS provides a framework through which developers can require users who execute their code to have explicit permission to perform certain operations. JAAS provides a set of classes that authenticate a user. This typically means that a JAAS−enabled application requires a user to log into it, much like the user logs into his computer in fact, JAAS often uses the operating system to authenticate the user directly. JAAS also provides a set of classes that authorize users to perform certain operations; this authorization is very similar to the permissions−based authorization that the default sandbox grants to code loaded from particular locations or signed by particular entities. Like the default sandbox, permissions granted to particular users by JAAS are administered by a system administrator; the system administrator also sets up the default parameters that JAAS uses. However, applications must be modified in order to use JAAS; by default, Java applications do not use the JAAS framework. In this chapter, well look into all aspects of JAAS: Administrative steps to enable JAAS • Programmatic steps to enable JAAS • Programmatic extensions to JAAS • See Chapter 1, for information on installing JAAS.

15.1 JAAS Overview

JAAS provides a framework based on a pluggable architecture. Like the engines we looked at earlier, JAAS provides a set of abstract classes, and at runtime each program finds the appropriate provider of the necessary class. However, the pluggable architecture is not built into the standard security framework, so we will refrain from referring to the major JAAS classes as engines. A JAAS−enabled application works like this: The program asks the user to log in, obtaining a user login object. Programmatically, this is a simple operation, involving the instantiation of a LoginContext object and the invocation of a single method on that object. What happens when that method is invoked can be quite complex and is determined by a system administrator. The system administrator is responsible for setting up a file that contains one or more directives indicating what happens when a particular application attempts to log in a user. These directives take the form of login modules that are called to authenticate the user and a series of options that govern how those classes can be used. The classes themselves typically interact with the operating system, using system calls to authenticate the user via Solaris NIS or NIS+, the Windows NT login service, an LDAP server, or whatever other authentication system is available on the platform. 1. The system administrator also determines the parameters of the authentication. For example, the user may be required to enter a valid Solaris password. Alternately, she may be required to enter a valid LDAP password, a valid NT password, or a valid password held in a custom database and either a valid Solaris or NT password. One or more of these passwords may be deemed optional. The administrator can set up as few or as many login modules as desired, and any or all of them may be optional or required. The program executes a method call the doAs or doAsPrivileged method, passing in the user login object and the code that should be executed on behalf of that user. Programatically, this method is very similar to the doPrivileged method of the access controller. As well see, it accomplishes a similar purpose. 2. Within the context just created, the program executes code that requires a specific permission e.g., it attempts to count the files in a directory. Like all such requests, this code results in a call to the security manager and hence the access controller to see if the appropriate permission is granted. As usual, if all the classes on the stack are granted that permission via the standard policy files or whatever Policy class is in effect, the permission will be granted and the call will succeed. However, because the call was executed within the context of the doAs method, the JAAS framework comes into play. JAAS provides a second set of policy files that allow permissions to be granted to code loaded from particular locations andor signed by particular entities, but only if that code is being executed by a specific authenticated user. Figure 15−1 shows how the stack might look when a call is made to the access controller from within the JAAS framework. The application code was initially loaded from file:filesjaas. That code authenticated the user and passed the authenticated user and an object loaded from file:filesjaasactionsto the doAs method. To call the File.listFiles method, the protection domain file:filesjaas must have the relevant permissions in the standard Java policy file. The protection domain file:filesjaasactions must have those same permissions, but they may be loaded from the standard Java policy file in which case they apply to all users. Alternately, the permissions may be loaded from a JAAS policy file, in which case they apply only to the user named in that file. Figure 15−1. The stack and protection domains of a JAAS−enabled application 3. 292