Skip Headers

Oracle® Application Server Containers for J2EE Security Guide
10g Release 2 (10.1.2)
Part No. B14013-01
  Go To Documentation Library
Home
Go To Product List
Solution Area
Go To Table Of Contents
Contents
Go To Index
Index

Previous
Previous
Next
Next
 

13 Oracle HTTPS for Client Connections

This chapter describes the Oracle Application Server Containers for J2EE (Oracle Application Server Containers for J2EE) implementation of HTTPS that provides SSL functionality to client HTTP connections. The following topics are included:


Note:

For a general overview of configuring OC4J to use the Secure Sockets Layer, see Chapter 11, "Configuring OC4J and SSL". This chapter assumes that you have already obtained keys and certificates.

Introduction

This chapter discusses how to use the Secure Sockets Layer protocol to communicate securely between networked applications. It discusses using Oracle HTTPS and JSSE.


Note:

Secure communication between a client and Oracle HTTP Server is independent of secure communication between Oracle HTTP Server and OC4J. (Also note that the secure AJP protocol used between Oracle HTTP Server and OC4J is not visible to the end user.) This section covers only secure communication between OC4J and the client.

OC4J standalone supports SSL communication directly between a client and OC4J, using HTTPS. This is discussed in"Configuring OC4J in STANDALONE MODE" [MUST FIX THIS MANUALLY] .


Requesting Client Authentication

OC4J supports a client authentication mode in which the server explicitly requests authentication from the client before the server will communicate with the client. In an Oracle Application Server environment, Oracle HTTP Server acts as the client to OC4J.

For client authentication, Oracle HTTP Server must have its own certificate and authenticate itself by sending a certificate and a certificate chain that ends with a root certificate. OC4J can be configured to accept only root certificates from a specified list in establishing a chain of trust back to a client.

A certificate that OC4J trusts is called a trust point. In the certificate chain from Oracle HTTP Server, the trust point is the first certificate that OC4J encounters that matches one in its own keystore. There are three ways to establish trust:

OC4J verifies that the entire certificate chain up to and including the trust point is valid to prevent any forged certificates.

If you request client authentication with the needs-client-auth attribute, perform the following steps. See "Requesting Client Authentication" for how to configure this attribute.

  1. Decide which of the certificates in the chain from Oracle HTTP Server is to be your trust point. Ensure that you either have control over the issuance of certificates using this trust point or that you trust the certificate authority as an issuer.

  2. Import the intermediate or root certificate in the server keystore as a trust point for authentication of the client certificate.


    Note:

    If you do not want OC4J to accept certain trust points, make sure these trust points are not in the keystore.

  3. Execute the steps to create the client certificate (documented in Chapter 11, "Configuring OC4J and SSL"). The client certificate includes the intermediate or root certificate that is installed in the server. If you wish to trust another certificate authority, obtain a certificate from that authority.

  4. Save the certificate in a file on Oracle HTTP Server.

  5. Provide the certificate for the Oracle HTTP Server initiation of the secure AJP connection.

During secure communication between the client and OC4J, the following functionality is executed:

Oracle HTTPS And Clients

HTTPS is vital to securing client-server interactions. For many server applications, HTTPS is handled by the Web server. However, any application that acts as a client, such as servlets that initiate connections to other Web servers, needs its own HTTPS implementation to make requests and to receive information securely from the server. Java application developers who are familiar with either the HTTP package, HTTPClient, or who are familiar with the Sun Microsystems, Inc., java.net package can easily use Oracle HTTPS to secure client interactions with a server.

Oracle HTTPS extends the HTTPConnection class of the HTTPClient package, which provides a complete HTTP client library. To support client HTTPS connections, several methods have been added to the HTTPConnection class that use the OracleSSL class, OracleSSLCredential.


Note:

Oracle HTTPClient supports two different SSL implementations: the Java Secure Socket Extension (JSSE) and OracleSSL. This documentation discusses the two implementations separately.

HTTPConnection Class

The HTTPConnection class is used to create new connections that use HTTP, with or without SSL. To provide support for PKI (Public Key Infrastructure) digital certificates and wallets, the methods described in "Oracle HTTPS Example" have been added to this class.


See Also:

The HTTPClient Javadoc.

OracleSSLCredential Class (OracleSSL Only)

Security credentials are used to authenticate the server and the client to each other. Oracle HTTPS uses the Oracle Java SSL package, OracleSSLCredential, to load user certificates and trustpoints from base64 or DER-encoded certificates. (DER, part of the X.690 ASN.1 standard, stands for Distinguished Encoding Rules.)

The API for Oracle Java SSL requires that security credentials be passed to the HTTP connection before the connection is established. The OracleSSLCredential class is used to store these security credentials. Typically, a wallet generated by Oracle Wallet Manager is used to populate the OracleSSLCredential object. Alternatively, individual certificates can be added by using an OracleSSLCredential class API. After the credentials are complete, they are passed to the connection with the setCredentials method.

Overview of Oracle HTTPS Features

Oracle HTTPS supports HTTP 1.0 and HTTP 1.1 connections between a client and a server. To provide SSL functionality, new methods have been added to the HTTPConnection class of this package. These methods are used in conjunction with Oracle Java SSL to support cipher suite selection, security credential management with Oracle Wallet Manager, security-aware applications, and other features that are described in the following sections. Oracle HTTPS uses the Oracle Java SSL class, OracleSSLCredential, and it extends the HTTPConnection class of the HTTPClient package. HTTPClient supports two SSL implementations, OracleSSL and JSSE.

In addition to the functionality included in the HTTPClient package, Oracle HTTPS supports the following:

In addition, Oracle HTTPS uses the HTTPClient package to support

The following sections describe Oracle HTTPS features in detail:

SSL Cipher Suites

Before data can flow through an SSL connection, both sides of the connection must negotiate common algorithms to be used for data transmission. A set of such algorithms combined to provide a mix of security features is called a cipher suite. Selecting a particular cipher suite lets the participants in an SSL connection establish the appropriate level for their communications.

HTTPClient supports two different SSL implementations, each of which supports different cipher suites. These are discussed in this section.

Choosing a Cipher Suite

In general, you should prefer:

  • RSA to Diffie-Hellman, because RSA defeats many security attacks.

  • 3DES or RC4 128 to other encryption methods, because 3DES and RC4 128 have strong keys

  • SHA1 digest to MD5, because SHA1 produces a stronger digest.

SSL Cipher Suites Supported by OracleSSL

OracleSSL supports the cipher suites listed in Table 13-1. Note that with NULL encryption, SSL is only used for authentication and data integrity purposes.

Table 13-1 Cipher Suites Supported By OracleSSL

Cipher Suite Authentication Encryption Hash Function (Digest)
SSL_RSA_WITH_3DES_EDE_CBC_SHA RSA 3DES EDE CBC SHA1
SSL_RSA_WITH_RC4_128_SHA RSA RC4 128 SHA1
SSL_RSA_WITH_RC4_128_MD5 RSA RC4 128 MD5
SSL_RSA_WITH_DES_CBC_SHA RSA DES CBC SHA1
SSL_RSA_EXPORT_WITH_RC4_40_MD5 RSA RC4 40 MD5
SSL_RSA_EXPORT_WITH_DES40_CBC_SHA RSA DES40 CBC SHA1
SSL_DH_anon_WITH_3DES_EDE_CBC_SHA DH anon 3DES EDE CBC SHA1
SSL_DH_anon_WITH_RC4_128_MD5 DH anon RC4 128 MD5
SSL_DH_anon_WITH_DES_CBC_SHA DH anon DES CBC SHA1
SSL_DH_anon_EXPORT_WITH_RC4_40_MD5 DH anon RC4 40 MD5
SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA DH anon DES40 CBC SHA1
SSL_RSA_WITH_NULL_SHA RSA NULL SHA1
SSL_RSA_WITH_NULL_MD5 RSA NULL MD5

SSL Cipher Suites Supported by JSSE

JSSE supports the cipher suites listed in Table 13-2. Note that with NULL encryption, SSL is only used for authentication and data integrity purposes.

Table 13-2 Cipher Suites Supported By JSSE

Cipher Suite Authentication Encryption Hash Function (Digest)
SSL_RSA_WITH_3DES_EDE_CBC_SHA RSA 3DES EDE CBC SHA1
SSL_RSA_WITH_RC4_128_SHA RSA RC4 128 SHA1
SSL_RSA_WITH_RC4_128_MD5 RSA RC4 128 MD5
SSL_RSA_WITH_DES_CBC_SHA RSA DES CBC SHA1
SSL_RSA_EXPORT_WITH_RC4_40_MD5 RSA RC4 40 MD5
SSL_DH_anon_WITH_3DES_EDE_CBC_SHA DH anon 3DES EDE CBC SHA1
SSL_DH_anon_WITH_RC4_128_MD5 DH anon RC4 128 MD5
SSL_DH_anon_WITH_DES_CBC_SHA DH anon DES CBC SHA1
SSL_DH_anon_EXPORT_WITH_RC4_40_MD5 DH anon RC4 40 MD5
SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA DH anon DES40 CBC SHA1
SSL_RSA_WITH_NULL_SHA RSA NULL SHA1
SSL_RSA_WITH_NULL_MD5 RSA NULL MD5
SSL_DHE_DSS_WITH_DES_CBC_SHA DH DES CBC SHA1
SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA DH 3DES EDE CBC SHA1
SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA DH DES40 CBC SHA1

Access Information About Established SSL Connections

Users can access information about established SSL connections using the getSSLSession method of Oracle HTTPS. After a connection is established, users can retrieve the cipher suite used for the connection, the peer certificate chain, and other information about the current connection.

Security-Aware Applications Support

Oracle HTTPS uses Oracle Java SSL to provide security-aware applications support. When security-aware applications do not set trust points, Oracle Java SSL allows them to perform their own validation letting the handshake complete successfully only if a complete certificate chain is sent by the peer. When applications authenticate to the trustpoint level, they are responsible for authenticating individual certificates below the trustpoint.

After the handshake is complete, the application must obtain the SSL session information and perform any additional validation for the connection.

Security-unaware applications that need the trust point check must ensure that trust points are set in the HTTPS infrastructure.


See Also:

Oracle Advanced Security Administrator's Guide for information about Oracle Java SSL.

java.net.URL Framework Support

The HTTPClient package provides basic support for the java.net.URL framework with the HTTPClient.HttpUrlConnection class. However, many of the Oracle HTTPS features are supported through system properties only.

Features that are only supported through system properties are

  • cipher suites selection option

  • confidentiality only option

  • server authentication option

  • mutual authentication option

  • security credential management with Oracle Wallet Manager


    Note:

    If the java.net.URL framework is used, then set the java.protocol.handler.pkgs system property to select the HTTPClient package as a replacement for the JDK client as follows:
    java.protocol.handler.pkgs=HTTPClient
    


    See Also:


Specifying Default System Properties

For many users of HTTPS it is desirable to specify some default properties in a non-programmatic way. The best way to accomplish this is through Java system properties which are accessible through the java.lang.System class. These properties are the only way for users of the java.net.URL framework to set security credential information. Oracle HTTPS recognizes the following properties:

The following sections describe how to set these properties.

javax.net.ssl.KeyStore

This property can be set to point to the text wallet file exported from Oracle Wallet Manager that contains the credentials that are to be used for a specific connection. For example:

javax.net.ssl.KeyStore=/etc/ORACLE/WALLETS/Default/default.txt

where default.txt is the name of the text wallet file that contains the credentials.

If no other credentials have been set for the HTTPS connection, then the file indicated by this property is opened when a handshake first occurs. If any errors occur while reading this file, then the connection fails and an IOException is thrown.

If you do not set this property, the application is responsible for verifying that the certificate chain contains a certificate that can be trusted. However, HTTPClient using Oracle SSL does verify that all of the certificates in the certificate chain, from the user certificate to the root CA, have been sent by the server and that all of these certificates contain valid signatures.

javax.net.ssl.KeyStorePassword

This property can be set to the password that is necessary to open the wallet file. For example:

javax.net.ssl.KeyStorePassword=welcome1

where welcome1 is the password that is necessary to open the wallet file.

Potential Security Risk with Storing Passwords in System Properties

Storing the wallet file password as a Java system property can result in a security risk in some environments. To avoid this risk, use one of the following alternatives:

  • If mutual authentication is not required for the application, use a text wallet that contains no private key. No password is needed to open these wallets.

  • If a password is necessary, then do not store it in a clear text file. Instead, load the property dynamically before the HTTPConnection is started by using System.setProperty(). Unset the property after the handshake is completed.

Oracle.ssl.defaultCipherSuites (OracleSSL only)

This property can be set to a comma-delimited list of cipher suites. For example:

Oracle.ssl.defaultCipherSuites=
            SSL_RSA_WITH_DES_CBC_SHA,\
            SSL_RSA_EXPORT_WITH_RC4_40_MD5,\
            SSL_RSA_WITH_RC4_128_MD5

The cipher suites that you set this property to are used as the default cipher suites for new HTTPS connections.


See Also:

Table 13-1 for a complete list of the cipher suites that are supported by OracleSSL.

Oracle HTTPS Example

The following is a simple program that uses Oracle HTTPS, HTTPClient, and OracleSSL to connect to a Web server, send a GET request, and fetch a Web page. The complete code for this program is presented here followed by sections that explain how Oracle HTTPS is used to set up secure connections.

import HTTPClient.HTTPConnection;
import HTTPClient.HTTPResponse;
import oracle.security.ssl.OracleSSLCredential;
import java.io.IOException;

public class HTTPSConnectionExample
{
    public static void main(String[] args)
    {
        if(args.length < 4)
        {
            System.out.println(
            "Usage: java HTTPSConnectionTest [host] [port] " +
            "[wallet] [password]");
            System.exit(-1);
        }

        String hostname = args[0].toLowerCase();
        int port = Integer.decode(args[1]).intValue();
        String walletPath = args[2];
        String password = args[3];

        HTTPConnection httpsConnection = null; 
        OracleSSLCredential credential = null;

        try
        {
            httpsConnection = new HTTPConnection("https", hostname, port);
        }
        catch(IOException e)
        {
            System.out.println("HTTPS Protocol not supported");
            System.exit(-1);
        }

        try
        {
            credential = new OracleSSLCredential();
            credential.setWallet(walletPath, password);
        }
        catch(IOException e)
        {
            System.out.println("Could not open wallet");
            System.exit(-1);
        }
        httpsConnection.setSSLCredential(credential);

        try
        {
            httpsConnection.connect();
        }
        catch (IOException e)
        { 
            System.out.println("Could not establish connection");
            e.printStackTrace();
            System.exit(-1);
        }

        javax.servlet.request.X509Certificate[] peerCerts = null;
        try
        {
            peerCerts =               (httpsConnection.getSSLSession()).getPeerCertificateChain();
        }
        catch(javax.net.ssl.SSLPeerUnverifiedException e)
        { 
            System.err.println("Unable to obtain peer credentials");
            System.exit(-1);
        }

        String peerCertDN =            peerCerts[peerCerts.length -1].getSubjectDN().getName();
        peerCertDN = peerCertDN.toLowerCase();
        if(peerCertDN.lastIndexOf("cn="+hostname) == -1)
        {
            System.out.println("Certificate for " + hostname + " is issued to "               + peerCertDN); 
            System.out.println("Aborting connection");
            System.exit(-1);
        }

        try
        {
            HTTPResponse rsp = httpsConnection.Get("/");
            System.out.println("Server Response: ");
            System.out.println(rsp); 
        }
        catch(Exception e)
        {
            System.out.println("Exception occured during Get");
            e.printStackTrace();
            System.exit(-1);
        }
    }
}

Initializing SSL Credentials In OracleSSL

This program example uses a wallet created by Oracle Wallet Manager to set up credential information. First the credentials are created and the wallet is loaded using

credential = new OracleSSLCredential();
credential.setWallet(walletPath, password);

After the credentials are created, they are passed to HTTPSConnection using

httpsConnection.setSSLCredential(credential);

The private key, user certificate, and trust points located in the wallet can now be used for the connection.

Verifying Connection Information

Although SSL verifies that the certificate chain presented by the server is valid and contains at least one certificate trusted by the client, that does not prevent impersonation by malicious third parties. An HTTPS standard that addresses this problem requires that HTTPS servers have certificates issued to their host name. Then it is the responsibility of the client to perform this validation after the SSL connection is established.

To perform this validation in this sample program, HTTPSConnectionExample establishes a connection to the server without transferring any data using the following:

httpsConnection.connect();

After the connection is established, the connection information, in this case the server certificate chain, is obtained with the following:

peerCerts = (httpsConnection.getSSLSession()).getPeerCertificateChain();

Finally the server certificate's common name is obtained with the following:

String peerCertDN = peerCerts[peerCerts.length -1].getSubjectDN().getName();
peerCertDN = peerCertDN.toLowerCase();

If the certificate name is not the same as the host name used to connect to the server, then the connection is aborted with the following:

if(peerCertDN.lastIndexOf("cn="+hostname) == -1)
{
    System.out.println("Certificate for " + hostname + " is issued to " +
        peerCertDN);
    System.out.println("Aborting connection");
        System.exit(-1);
}

Transferring Data Using HTTPS

It is important to verify the connection information before data is transferred from the client or from the server. The data transfer is performed in the same way for HTTPS as it is for HTTP. In this sample program a GET request is made to the server using the following:

HTTPResponse rsp = httpsConnection.Get("/");

Using HTTPClient with JSSE

Oracle Application Server supports HTTPS client connections using the Java Secure Socket Extension (JSSE). A client can configure HTTPClient to use JSSE as the underlying SSL provider.


Notes:

  • The JSSE SSL implementation is not thread-safe; if you need to use SSL in a threaded application, use OracleSSL.
  • For full information on JSSE, see the Sun documentation at http://java.sun.com/products/jsse/


HTTPClient still uses OracleSSL as the default provider, but the developer can easily change this by setting the SSLSocketFactory on the HTTPConnection class. Example 13-1 demonstrates how a client could configure HTTPClient to use JSSE for SSL communication.

Example 13-1 Using JSSE with HTTPClient

public void obtainHTTPSConnectionUsingJSSE() throws Exception
{
// set the trust store to the location of the client's trust store file
      // this value specifies the certificate authorities the client accepts
   System.setProperty("javax.net.ssl.trustStore", KEYSTORE_FILE);
   // creates the HTTPS URL
   URL testURL = new URL("https://" + HOSTNAME + ":" + HTTPS_PORTNUM);
   // call SSLSocketFactory.getDefault() to obtain the default JSSE implementation
  // of an SSLSocketFactory
   SSLSocketFactory socketFactory = (SSLSocketFactory)SSLSocketFactory.getDefault();
   HTTPConnection connection = new HTTPConnection(testURL);

   // configure HTTPClient to use JSSE as the underlying
   // SSL provider
   connection.setSSLSocketFactory(socketFactory);
   // call connect to setup SSL handshake
   try
   {
       connection.connect();
   }
   catch (IOException e)
   {
       e.printStackTrace();    }

   HTTPResponse response = connection.Get("/index.html");
   
       }

Configuring HTTPClient To Use JSSE

The steps required to use JSSE with HTTPClient are as follows:

  1. Create a truststore using the keytool.


    Notes:

    • For details of using the keytool, see http://java.sun.com/j2se/1.3/docs/tooldocs/win32/keytool.html
    • JSSE's implementation of SSL has some subtle differences from Oracle's implementation. Unlike in OracleSSL, if no truststore is set, the JDK default truststore will be used. This default will accept known certificate authorities, such as Verisign and Thawte. Many self-signed certificates will be rejected by this default.


  2. Set the truststore property. A client wishing to use JSSE must specify the client truststore location in javax.net.ssl.trustStore. Unlike OracleSSL, the client does not need to set the javax.net.ssl.keyStore property.

  3. Obtain the JSSE SSLSocketFactory by calling SSLSocketFactory.getDefault().

  4. Create an HTTPClient connection.

  5. Configure the HTTPClient connection to use the JSSE implementation of SSL. HTTPClient can be configured to use JSSE in one of two ways:

    1. (For each connection) The client calls HTTPConnection.setSSLSocketFactory(SSLSocketFactory factory)

    2. (Entire VM) The client calls the static method: HttpConnection.setDefaultSSLSocketFactory(SSLSocketFactory factory). This static method must be called before instantiating any HTTPConnection instances.

  6. Call HTTPConnection.connect() before sending any HTTPS data. This allows the connection to verify the SSL handshaking that must occur between client and server before any data can be encrypted and sent.

  7. Use the HTTPConnection instance normally. At this point, the client is set up to use HTTPClient with JSSE. There is no additional configuration necessary and basic usage is the same.