Skip Headers
Oracle® Containers for J2EE Security Guide
10g (10.1.3.5.0)

Part Number E13977-01
Go to Documentation Home
Home
Go to Book List
Book List
Go to Table of Contents
Contents
Go to Index
Index
Go to Feedback page
Contact Us

Go to previous page
Previous
Go to next page
Next
View PDF

16 Oracle Security for Client Connections

This chapter discusses features of Oracle security for clients. These features mainly provide Secure Sockets Layer (SSL) functionality to client HTTP connections in conjunction with functionality of the HTTPClient package, and support the use of the standard Java Secure Socket Extension (JSSE). In addition, a section is included that documents the HTTP Client's non-SSL authentication features. This chapter may be of interest for any Java application that is to use SSL, where either OC4J is the Web listener (such as in standalone OC4J), or OC4J is behind Oracle HTTP Server. The following topics are included:

Notes:

See Also:

Using Non-SSL Client Authentication

This chapter primarily focuses on HTTPS for client security. However, there are several HTTP Client APIs that clients can use for non-SSL authentication. The library can be used to create HTTP requests that include basic, digest, and NT LAN Manager (NTLM) authentication information in the request header. This section includes instructions for using the HTTPClient package to create these types of requests. For detailed HTTP Client API information, refer to the Oracle Application Server HTTPClient Java API Reference.

Basic-Based Client Authentication

The HTTP Client can be used to create an HTTP request to access a server resource that requires basic authentication. The following example demonstrates creating a request and using the addBasicAuthorization method to include the realm, username, and password with the request.

URL url = new URL("http://localhost:1234");

HTTPConnection client = new HTTPConnection(url);

try {
   client.addBasicAuthorization("realm_name", "user", "password");
   HTTPResponse response = client.Get(url.getFile());
   //assertEquals(200, response.getStatusCode());
}
finally {
   client.stop();
}

The realm is a server specified string which groups various URLs under a given server together and which is used to select the correct information when a server issues an authentication challenge. The realm must be the empty string ("") for schemes which don't use a realm.

Digest-Based Client Authentication

The HTTP Client can be used to create an HTTP request to access a resource that requires digest authentication. With the digest authentication mechanism, the password that a client presents to authenticate itself is encrypted through the use of an MD5 digest. This is transmitted in the request message. From a user perspective, digest authentication behaves in the same way as basic authentication. The following example demonstrates creating a request and using the addDigestAuthorization method to include the realm, username, and password with the request.

HTTPConnection client = new HTTPConnection(url);

try {
   client.addDigestAuthorization("ProxyAuthDigestSchemeTestServlet",
      validUserName,validPassword);
   HTTPResponse response = client.Get(url.getFile());
   // assertEquals(200, response.getStatusCode());
}
finally {
   client.stop();
}

The realm is a server specified string which groups various URLs under a given server together and which is used to select the correct information when a server issues an authentication challenge. The realm must be the empty string ("") for schemes which don't use a realm.

NTLM-Based Client Authentication

NTLM is a proprietary challenge/response authentication protocol used by Microsoft browsers, proxies, and servers. A client using NTLM is able to prove its identity to a server without sending a password. NTLM is a connection-oriented protocol. Once the connection is authenticated, no further credentials are required as long as the connection remains open.

In NTLM, the NT Domain name qualifies the username. The account identifier is \. The NT Domain may be specified in HTTP Client by prefixing the username with the NT Domain name followed by a backslash. For example, for the NT Domain OPERATIONS and the username jsmith, the fully qualified username is OPERATIONS\jsmith.

If no NT Domain is given, the default (if any) is assumed. The default NT Domain is set in the HTTP Client using the system property HTTPClient.ntlm.defaultDomainName. If the username is given without an NT Domain, and no default NT Domain is defined in HTTP Client, the NTLM-protected server may assume its own default NT Domain.

To connect to an NTLM-protected resource server, add the NTLM credentials to the HTTP Client AuthorizationInfo credential store. As with basic and digest authentication, HTTP Client will automatically query the credential store, when challenged by an NTLM server. Credentials may be added to the credential store either by using an HTTP Connection instance:

HTTPConnection conn = new HTTPConnection( myHost, myPort );
conn.addNtlmAuthentication( myUsername, myPassword );

Or, directly using the AuthorizationInfo class:

AuthorizationInfo.addNtlmAuthentication( myHost, myPort, myUsername, myPassword )

The following example demonstrates creating a request and using the addNtlmAuthentication method to include the username and password with the request.

HTTPConnection conn = new HTTPConnection( myHost, myPort );
conn.addNtlmAuthentication( myUsername, myPassword );
HTTPResponse response = conn.Get( "/index.htm" );
int status = response.getStatusCode();
assertEquals( 200, status );

Note:

A realm, as specified in authentication schemes such as basic authentication, does not apply to NTLM. The NTLM challenge does not have a realm directive. Therefore, all NTLM credentials are assumed to be part of the same empty ("") realm within HTTP Client.

How to Connect to an NTLM-Protected Proxy Server

Proxy servers may also use NTLM for client authentication. However, unlike request-oriented authentication, an NTLM client may only authenticate its connection with the proxy, not the resource server.

To connect to an NTLM-protected proxy server, add the NTLM credentials to the HTTP Client AuthorizationInfo credential store. As with basic and digest authentication, the HTTP Client automatically queries the credential store when challenged by an NTLM server. Credentials may only be directly added to the credential store using AuthorizationInfo. For example:

AuthorizationInfo.addNtlmAuthentication( myProxyHost, myProxyPort, myUsername,
   myPassword)

The following example demonstrates a client that uses NTML to connect to a protected proxy server:

HTTPConnection conn = new HTTPConnection( myHost, myPort );
conn.setCurrentProxy( myProxyHost, myProxyPort );
AuthorizationInfo.addNtlmAuthentication( myProxyHost, myProxyPort, myUsername,
   myPassword, conn.getContext() )
HTTPResponse response = conn.Get( "/index.htm" );
int status = response.getStatusCode();
assertEquals( 200, status );

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 a Web application that initiates 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 HTTPClient package or the Sun Microsystems java.net package can easily use HTTPS to secure client interactions with a server.

Oracle client HTTPS functionality is based on the HTTPConnection class of the HTTPClient package, which provides a complete HTTP client library. The HTTPConnection class is used to create new connections that use HTTP, with or without SSL.

Important:

The Oracle implementation of HTTPClient has diverged from the original open source version upon which it was based. The Oracle version should be considered as a distinct product. Even though there are still many similarities, the two are not necessarily compatible with each other.

See Also:

Overview of Client-Side HTTPS Features

Oracle client HTTPS extends the HTTPConnection class of the HTTPClient package to provide SSL functionality, including cipher suite selection, security credential management with Oracle Wallet Manager, support of security-aware applications, and other features that are described in the following sections. Oracle client HTTPS supports HTTP 1.0 and HTTP 1.1 connections between a client and a server.

HTTPClient supports two SSL implementations, JSSE and Oracle Java SSL. The latter is deprecated in the OC4J 10.1.3.1 implementation, however, and will be desupported in future releases. We recommend that you use JSSE.

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

In addition, the HTTPClient package is used to support:

The following sections describe some of the features:

Supported Keystore Formats

When using JSSE, you can use a PKCS12 or SSO (auto-login) Oracle wallet with the Oracle JSSE implementation (OraclePKIProvider), or a JKS-format keystore with the default Sun Microsystems JSSE implementation. (Oracle Java SSL supports only text-format Oracle wallets.)

For either PKCS12 or SSO wallets, credential information is encrypted. The main difference is that with an SSO wallet, you do not have to present a wallet password to open the wallet at time of access.

JKS and PKCS12 are standard formats; SSO wallets are Oracle-proprietary.

See Also:

  • Oracle Application Server Administrator's Guide (in the chapter for managing wallets and certificates) for details about creating and using PKCS12 and SSO/auto-login wallets

Accessing Information for Established SSL Connections

Users can access information regarding established SSL connections using the getSSLSession() method in the HTTPConnection class of the Oracle HTTPClient package. 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.

Support for java.net.URL Framework

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

Features that are supported only through system properties are:

  • 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, 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:

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.

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

As of the OC4J 10.1.3.1 release, JSSE supports the following cipher suites, listed in default preference order. In this list, "*" indicates the cipher suite is enabled by default, and "**" indicates the cipher suite requires the installation of the JCE Unlimited Strength Jurisdiction Policy Files from Sun Microsystems. Note that with null encryption, SSL is used only for authentication and data integrity purposes.

Note:

HTTPClient does not provide a way to selectively enable a subset of supported cipher suites.
SSL_RSA_WITH_RC4_128_MD5 *
SSL_RSA_WITH_RC4_128_SHA *
TLS_RSA_WITH_AES_128_CBC_SHA *
TLS_DHE_RSA_WITH_AES_128_CBC_SHA *
TLS_DHE_DSS_WITH_AES_128_CBC_SHA *
SSL_RSA_WITH_3DES_EDE_CBC_SHA *
SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA *
SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA *
SSL_RSA_WITH_DES_CBC_SHA *
SSL_DHE_RSA_WITH_DES_CBC_SHA *
SSL_DHE_DSS_WITH_DES_CBC_SHA *
SSL_RSA_EXPORT_WITH_RC4_40_MD5 *
SSL_RSA_EXPORT_WITH_DES40_CBC_SHA *
SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA *
SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA *
TLS_RSA_WITH_AES_256_CBC_SHA **
TLS_DHE_RSA_WITH_AES_256_CBC_SHA **
TLS_DHE_DSS_WITH_AES_256_CBC_SHA **
SSL_RSA_WITH_NULL_MD5
SSL_RSA_WITH_NULL_SHA
SSL_DH_anon_WITH_RC4_128_MD5
TLS_DH_anon_WITH_AES_128_CBC_SHA
TLS_DH_anon_WITH_AES_256_CBC_SHA **
SSL_DH_anon_WITH_3DES_EDE_CBC_SHA
SSL_DH_anon_WITH_DES_CBC_SHA
SSL_DH_anon_EXPORT_WITH_RC4_40_MD5
SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA

Supported Default System Properties

This section discusses standard Java system properties supported for keystores and truststores. (These properties offer the only way for users of the java.net.URL framework to set security credential information.) Oracle client HTTPS recognizes the following properties:

Note:

You can set Java system properties on the JVM command line for standalone OC4J, or in a Java property setting for the OC4J instance in the opmn.xml file in an Oracle Application Server environment. Setting system properties is described in the Oracle Containers for J2EE Configuration and Administration Guide, in the chapter on OC4J runtime configuration.

Property javax.net.ssl.keyStore

This property specifies the location and name of the keystore file or wallet file to use as the keystore.

Property javax.net.ssl.keyStorePassword

This property can be set to indicate the password that is necessary to open the keystore (keystore file or wallet file). For example:

javax.net.ssl.keyStorePassword=welcome1

Important:

Storing the keystore 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 an SSO wallet, which does not require a password.

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

Property javax.net.ssl.keyStoreType

This property specifies the type of file used for the keystore. With the Oracle JSSE implementation (OraclePKIProvider), you can specify PKCS12 or SSO. With the default Sun Microsystems JSSE implementation, you can specify JKS.

See Also:

  • The SSL overview in the Oracle Application Server Administrator's Guide for discussion of the PKCS12 type

Property javax.net.ssl.trustStore

This property is used similarly to javax.net.ssl.keyStore, but specifies the location and name of the keystore file or wallet file to use as the truststore (a file that includes the trusted certificate authorities that a client will implicitly accept).

Property javax.net.ssl.trustStorePassword

This property is used similarly to javax.net.ssl.keyStorePassword, but specifies the password that is necessary to open the truststore (keystore file or wallet file).

Property javax.net.ssl.trustStoreType

Similarly to javax.net.ssl.keyStoreType, this property specifies the type of file used for the truststore—PKCS12 or SSO for the Oracle JSSE implementation, or JKS for the default Sun Microsystems JSSE implementation.

Using HTTPClient with JSSE

This section describes Oracle Application Server support for HTTPS client connections using JSSE, covering the following topics:

See Also:

  • Oracle Application Server Administrator's Guide (in the chapter for managing wallets and certificates) for information about Oracle Wallet Manager and orapki features for creating and maintaining wallets

  • For complete information on JSSE:

    http://java.sun.com/products/jsse/
    

Prerequisites for using JSSE

Note the following requirements to use JSSE with Oracle client HTTPS:

  • You must be using Sun Microsystems JDK version 1.2 or higher. (JSSE is included as part of JDK 1.4 or higher.)

  • The file oraclepki.jar, located in directory ORACLE_HOME/network/jlib, must be in your classpath. (The file jssl-1_1.jar or jssl-1_2.jar, used by Oracle Java SSL, is no longer necessary. These files are incompatible with JSSE and are no longer included with your installation.)

Configuring HTTPClient to Use JSSE

Oracle Application Server supports HTTPS client connections using JSSE. A client can configure HTTPClient to use JSSE as the underlying SSL provider as follows:

  1. Create a truststore using the Sun Microsystems keytool.

    See Also:

  2. Set the truststore property. A client wishing to use JSSE must specify the client truststore location through the javax.net.ssl.trustStore property. The client is not required to set the javax.net.ssl.keyStore property.

  3. Obtain the JSSE SSL socket factory (javax.net.ssl.SSLSocketFactory instance) by calling the static SSLSocketFactory.getDefault() method.

  4. Create an HTTPClient connection (HTTPConnection instance).

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

    • (For each connection) The client calls the following method on the HTTPConnection instance, specifying the JSSE SSL socket factory retrieved by the getDefault() method in step 3:

      void setSSLSocketFactory(SSLSocketFactory factory)
      

      In this case, the SSL socket factory is set for only this connection instance. Example 16-1 below demonstrates this technique.

    • (Entire VM) The client calls the following static method on the HTTPConnection class:

      void HttpConnection.setDefaultSSLSocketFactory(SSLSocketFactory factory)
      

      In this case, the SSL socket factory is set for all connection instances in the Java VM, until the method is called again with a different setting. This method must be called before instantiating any HTTPConnection instances that are to be affected.

  6. There must be a call to the HTTPConnection class connect() method 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. In the Oracle implementation, this method is called implicitly during calls to HTTP methods, such as the HTTPConnection class Get() method. In addition, an explicit call to the connect() method is useful when the calling application requires SSL session information before sending data. Also see "Verifying Additional Connection Information".

  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.

Example 16-1 Using JSSE with HTTPClient

public void obtainHTTPSConnectionUsingJSSE() throws Exception
{
   // set the truststore to the location of the client's truststore 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");
   
}

Notes:

  • If no SSL socket factory is specified, JSSE would be used anyway, by default, if Oracle Java SSL is not specified as preferred or if Oracle Java SSL classes are not found in the application classpath. If no SSL socket factory is specified and Oracle Java SSL is specified as preferred, and Oracle Java SSL classes are found in the classpath, then Oracle Java SSL is used by default. Also see "Specifying Oracle Java SSL as the SSL Implementation for HTTPClient".

  • The JSSE SSL implementation is not thread-safe.

HTTPClient Support for SSL Host Name Verification

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.

A host name verifier (javax.net.ssl.HostnameVerifier implementation) is used by HTTPClient to verify that the host name in the SSL certificate matches the host name of the URI used to access the protected server. This helps detect "man-in-the-middle" attacks. HTTPClient invokes the HostnameVerifier instance immediately after establishing an SSL session, throwing a javax.net.ssl.SSLPeerUnverifiedException if a host name mismatch is detected.

Important:

You can provide your own HostnameVerifier implementation, or use one provided by Oracle (as described below). The implementation must have a no-argument constructor.

See Also:

The section discusses how to enable and use this feature, covering the following topics:

Without either the system property setting or the programmatic setting described below, host name verification will not be performed.

Enabling Host Name Verification through System Property Setting

To enable host name verification without having to alter your code, set the system property HTTPClient.defaultHostnameVerifier to the fully-qualified class name of a host name verifier implementation in the classpath.

The setting must specify the name of an appropriate class (a javax.net.ssl.HostnameVerifier implementation with a no-argument constructor).

Enabling Host Name Verification Programmatically

You can use the following methods of the HTTPConnection class to enable host name verification programmatically, by specifying the javax.net.ssl.HostnameVerifier instance to use for verification:

  • static HostnameVerifier setDefaultHostnameVerifier (HostnameVerifier defaultHostnameVerifier)

    Use this static method to assign the specified HostnameVerifier instance as the JVM default. This method returns the previously set default host name verifier, or null if host name verification was previously disabled by default.

  • HostnameVerifier setHostnameVerifier (HostnameVerifier hostnameVerifier)

    Use this instance method to override the default host name verifier and assign the specified HostnameVerifier instance for use by the connection. You can also specify null, in order to disable host name verification for the connection.

    This method returns the previous host name verifier for the connection, or null if host name verification was previously disabled for the connection.

Using the Oracle Standard Host Name Verifier

Oracle supplies the host name verifier implementation StandardHostnameVerifier, in the HTTPClient package.

StandardHostnameVerifier implements standard host name matching rules for site identity checking, providing the following features:

  • It verifies the SSL session host name by checking whether the given host name is the same as the common name (CN) of the distinguished name (DN) from the first certificate in the SSL certificate chain. The comparison is not case-sensitive.

  • If wildcard matching is enabled, it will recognize and match the given host name with a wildcard CN in the SSL certificate (for example, *.oracle.com), if present.

StandardHostnameVerifier has the following methods:

  • boolean setRecognizeWildcardCNs(boolean recognizeWildcardCNs)

    Specify whether to recognize wildcard CNs. This method returns the previously set value.

  • boolean isRecognizeWildcardCNs()

    This method tells you whether wildcard CNs are recognized.

  • boolean verify(java.lang.String hostname, javax.net.ssl.SSLSession sslSession)

    Call this method to verify that the host name is an acceptable match with the authentication scheme of the server. (This is standard functionality specified in the javax.net.ssl.HostnameVerifier interface.)

You can specify StandardHostnameVerifier as your host name verifier either programmatically or through the system property setting, as discussed previously. To set it as the default host name verifier, for example, use the following system property setting:

HTTPClient.defaultHostnameVerifier=HTTPClient.StandardHostnameVerifier;

Verifying Additional Connection Information

Further validation (beyond host name verification) may be performed using any data found in the javax.net.ssl.SSLSession object returned from the HTTPConnection class getSSLSession() method, after the HTTPConnection class connect() is called.

To perform this validation, establish a connection to the server without transferring any data, as follows:

httpsConnection.connect();

After the connection is established, the connection information, in this example the server certificate chain, is obtained as follows:

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

Finally the server certificate common name is obtained as follows.

String peerCertDN = peerCerts[0].getSubjectDN().getName();
peerCertDN = peerCertDN.toLowerCase();

(The user's certificate is first in the array; the root CA's certificate is last.)

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

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

Note:

The preferred mechanism is to use the host name verification facility described in the preceding sections.

Migrating from Oracle Java SSL to JSSE

As noted earlier, in the OC4J 10.1.3.1 implementation and beyond, we recommend that you use JSSE rather than Oracle Java SSL. The latter is deprecated in the 10.1.3.1 implementation and will be desupported in future releases. This section discusses how to modify your client code to use JSSE instead of Oracle Java SSL for your SSL functionality.

Code Samples for Migration to JSSE

This section provides code samples to show the steps for creating a new SSL socket factory using JSSE, compared to equivalent code you would have used previously for Oracle Java SSL. The java.security.Keystore class and various javax.net.ssl classes are used to open the keystore or wallet and apply Oracle-specific security policies for verifying peer certificates.

See Also:

Here are the steps, with explanations and comparisons:

  1. Register the SSL provider. This step is not necessary if providers are set statically in the jre/lib/security/java.security properties file for your JDK.

    Old code for Oracle Java SSL: not applicable

    New code for JSSE:

    Security.insertProviderAt(new oracle.security.ssl.OraclePKIProvider(), 1);
    

    The static insertProviderAt() method of the java.security.Security class adds a new provider, at a specified preference position. The position refers to the preference order in which providers are searched for requested algorithms, with 1 being most preferred. Use OraclePKIProvider for enforcement of Oracle security policies. Once you set the provider, you can use standard JSSE classes for your SSL functionality.

  2. Load your keystore, wallet, or trusted certificates.

    Old code for Oracle Java SSL:

    OracleSSLCredential cred = new OracleSSLCredential();
    cred.loadWallet("walletpath", "password");
    

    New code for JSSE:

    KeyStore myWallet = KeyStore.getInstance("keystoretype","OraclePKI");
    FileInputStream istr = new FileInputStream("pathtowallet");
    myWallet.load(istr, password);
    

    The static getInstance() method of the Keystore class creates a keystore object for the specified keystore type from the specified provider. Use OraclePKI as the provider.

    In this sample: keystoretype is PKCS12 or SSO; pathtowallet is the path and file name of the keystore or wallet file; and password is a char[] array for the password, or null if you use an SSO wallet.

    Note that the OracleSSLCredential class, used for Oracle Java SSL, is not used for JSSE.

  3. Create the SSL socket factory.

    Old code for Oracle Java SSL:

    OracleSSLSocketFactory socketFactory = new OracleSSLSocketFactoryImpl();
    SocketFactory.setSSLCredentials(cred);
    

    New code for JSSE:

    TrustManagerFactory tmf = TrustManagerFactory.getInstance("OracleX509");
    tmf.init(trustCerts);
    TrustManager[] tmA = tmf.getTrustManagers();
    
    KeyManagerFactory kmf = KeyManagerFactory.getInstance("OracleX509");
    kmf.init(trustCerts, password);
    KeyManager[] kmA = kmf.getKeyManagers();
    
    SSLContext ctx = SSLContext.getInstance("SSL");
    ctx.init(kmA, tmA, null);
    SSLSocketFactory factory = ctx.getSocketFactory();
    

    Create and set trust managers so the SSL connection can verify the peer certificate chain. Create and set key managers so the SSL connection can access the user certificate and private key. Then use key managers and trust managers to configure the SSL context, which is used to create new SSL socket factories. Once an SSLSocketFactory instance is created, you can use it to create SSL sockets.

Additional Changes Relevant for Migration to JSSE

Note the following additional changes between Oracle Java SSL and JSSE that may affect your application:

  • There is a different signature for the createSocket() method of the SSL socket factory. (This is an OracleSSLSocketFactory instance for Oracle Java SSL, and an SSLSocketFactory instance for JSSE.) Note, however, that users of HTTPClient are not required to call createSocket() directly.

    Old signature for Oracle Java SSL:

    createSocket(Socket sock)
    

    New signature for JSSE:

    createSocket(Socket sock, String host, int port, boolean autoClose)
    

    This method creates a new socket layered over an existing socket. Specify the existing socket, server host, server port, and whether to close the underlying socket when the created socket is closed.

  • There is a difference in the peer certificate chain returned by the SSL session object.

    For Oracle Java SSL: The getPeerCertificateChain() method of OracleSSLSession returns a certificate chain with the root CA certificate first and the peer certificate last.

    For JSSE: The getPeerCertificates() method (preferred) or getPeerCertificateChain() method (maintained for backward compatibility) of SSLSession returns a certificate chain with the peer certificate first and the root CA certificate last.

Features for Oracle Java SSL (Deprecated)

Oracle Java SSL is deprecated in the OC4J 10.1.3.1 implementation but not yet desupported. (It will be desupported in future releases.)

For completeness, this section documents features specific to Oracle Java SSL, but we strongly recommend that you migrate to JSSE, as discussed in "Migrating from Oracle Java SSL to JSSE".

The following topics are covered here:

Note:

Depending on the JDK you use, Oracle Java SSL requires the file jssl-1_1.jar or jssl-1_2.jar to be in the classpath.

See Also:

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

Specifying Oracle Java SSL as the SSL Implementation for HTTPClient

In the OC4J 10.1.3.1 implementation, the JDK-default JSSE implementation is now the default SSL implementation for HTTPClient. (This is a step toward deprecating Oracle Java SSL, the previous default SSL implementation for HTTPClient.)

You can, however, explicitly specify Oracle Java SSL as the default SSL implementation for HTTPClient by completing the following steps:

  1. Specify the following system property setting:

    HTTPClient.preferOracleSSL=true
    
  2. Ensure that the Oracle Java SSL classes (for example, oracle.security.ssl.OracleSSLSocketFactory) are in your classpath.

Important:

If an SSL socket factory (javax.net.ssl.SSLSocketFactory implementation) is explicitly specified through the setSSLSocketFactory() method of HTTPConnection, the SSL implementation associated with the specified factory will be used, regardless of the setting of the HTTPClient.preferOracleSSL property.

OracleSSLCredential Class for Oracle Java SSL

To support client HTTPS connections for use with Oracle Java SSL, several methods were added to the HTTPConnection class that use the Oracle Java SSL class, OracleSSLCredential.

For Oracle Java SSL, security credentials are used to authenticate the server and the client to each other. OracleSSLCredential is used to load user certificates and trust points 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 setSSLCredential() method of the HTTPConnection class.

Security-Aware Applications Support in Oracle Java SSL

Oracle client HTTPS uses SSL to provide security-aware applications support. When security-aware applications do not set trust points, 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 trust point level, they are responsible for authenticating individual certificates below the trust point.

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 require the trust point check must ensure that trust points are set in the HTTPS infrastructure.

Using HTTPClient with Oracle Java SSL

This section shows an application that uses HTTPClient and Oracle Java SSL to connect to a Web server, send a GET request, and fetch a Web page.

Sample Code (Oracle Java SSL)

This section contains the sample code using HTTPClient and Oracle Java SSL.

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 Oracle Java SSL

This example uses a wallet created by Oracle Wallet Manager to set up credential information.

  1. First, create the credentials and load the wallet:

    mycredential = new OracleSSLCredential();
    mycredential.setWallet(wallet_path, password);
    
  2. After the credentials are created, pass them to your HTTPConnection instance (here called httpsConnection) through its setSSLCredential() method. This method takes the OracleSSLCredential instance, created in the first step, as input:

    httpsConnection.setSSLCredential(mycredential);
    

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

System Property Features with Oracle Java SSL

"Supported Default System Properties" discusses the Java system properties keyStore, keyStorePassword, keyStoreType, trustStore, trustStorePassword, and trustStoreType. This section discusses features relating to javax.net.ssl.keyStore that are specific to Oracle Java SSL:

  • 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.

  • 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 as this file is read, then the connection fails and an IOException is thrown.

  • If this property has no setting, the application is responsible for verifying that the certificate chain contains a certificate that can be trusted.

Specifying Cipher Suites for Oracle Java SSL

This section discusses how to specify cipher suites for Oracle Java SSL.

Property Oracle.ssl.defaultCipherSuites

For Oracle Java SSL, Oracle.ssl.defaultCipherSuites 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

You can set this property before establishing an SSL connection using Oracle Java SSL. The cipher suites that you specify in this property setting are used as the enabled cipher suites for new HTTPS connections.

Method setSSLEnabledCipherSuites()

For Oracle Java SSL, you can also set cipher suites per connection by using the following method of the HTTPConnection class in package HTTPClient:

  • boolean setSSLEnabledCipherSuites(String[] cipherSuites)

This takes a Java string array, with each array element specifying a cipher suite. It returns a boolean indicating whether the current SSL implementation supports this method.

Note:

There is no way to specify cipher suites per HTTP connection in JSSE.

See Also:

  • Oracle Application Server HTTPClient Java API Reference (Javadoc) for additional information

SSL Cipher Suites Supported by Oracle Java SSL

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

Table 16-1 Cipher Suites Supported by Oracle Java SSL

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