Skip Headers
Oracle® Fusion Middleware Security Guide
11g Release 1 (11.1.1)
E10043-04
  Go To Table Of Contents
Contents
Go To Index
Index

Previous
Previous
 
Next
Next
 

20 Developing with Oracle HTTPClient Security

Oracle HTTPClient security supports the Secure Sockets Layer (SSL) on client HTTP connections with the package HTTPClient.This chapter describes the basic features of HTTPClient, how to configure it with system properties, and how to use it with the standard Java Secure Socket Extension (JSSE) or with NTLM authentication.

This chapter is divided in the following sections:

For general information about JSSE, see http://java.sun.com/javase/6/docs/technotes/guides/security/jsse/JSSERefGuide.html.

20.1 Overview of Oracle HTTPClient Security

Oracle HTTPClient security implements the package HTTPClient.HTTPConnection and provides a comprehensive set of functions that allows the creation of HTTP connections (secured or otherwise) between a source and a target. The Oracle implementation of the class HTTPClient diverges from the original open source version upon which it is based, and even though many similarities between them remain, the two implementations are not necessarily compatible with each other.

For further details about JSSE and java.net, see information in the following links:

20.2 Oracle HTTPClient Security Features

Oracle HTTPClient provides the following major features for security-aware applications:

Oracle HTTPClient supports the use of the protocols HTTP 1.0 and HTTP 1.1 for communication between client and server, and the JSSE SSL implementation. Note that without adding OraclePKIProvider to the JVM, Oracle Wallets cannot be used. See Prerequisites for using JSSE.

The following four sections describe in detail the major features supported by Oracle HTTPClient security.

20.2.1 Keystore Formats

Starting with this release, an application should use only a JKS keystore with Oracle HTTPClient. The JKS keystore is the default keystore in Java and no JVM settings are required to use this keystore. Applications that want to migrate the content of their existing Oracle Wallets to JKS can use orapki command.

The choice of data format in a keystore depends on the choice of the security provider configured in the JVM. If you choose the default Sun Microsystems security provider, then you must use a JKS-formatted keystore. If you choose the oracle.security.pki.OraclePKIProvider, which should be registered with the JVM, then you must use the keystore formats PKCS12 or SSO (auto-login) Oracle wallet.

PKCS12 and JKS are standard keystore formats; SSO Oracle wallet is an Oracle proprietary format.

Wallets formatted with PKCS12 or SSO contain all their credentials encrypted; the main difference between these two keystores is that, in case of an SSO wallet, a password to open the wallet to access information in it is not required.

For details about using the orapki command to migrate an Oracle Wallet to JKS, see section H.1.6 Converting Between Oracle Wallet and JSK Store in Oracle Fusion Middleware Administrator's Guide.

For further details about Oracle Wallets, see chapter Oracle Wallet Manager and orapki in Oracle Fusion Middleware Administrator's Guide.

20.2.2 SSL Connection Information

Applications can access information about an established SSL connection using the method getSSLSession in the class HTTPConnection in the Oracle package HTTPClient. After a connection has been established, applications can retrieve connection information such as the cipher suite used for the connection and the peer certificate chain.

20.2.3 Support for java.net.URL

A user of the java.net.URL framework may configure JSSE according to the system properties listed in the following document (JSSE Reference Guide): http://java.sun.com/javase/6/docs/technotes/guides/security/jsse/JSSERefGuide.html

20.2.4 Cipher Suites

A cipher is an algorithm that performs encryption and decryption, and a cipher suite is a set of such algorithms. Before data can flow through an SSL connection, both sides of the connection must negotiate and agree on the various connection parameters, including the common cipher to use for data transmission. Selecting a particular cipher and related SSL connection parameters allows the communicating participants to establish the appropriate security level on the transmission channel.

The following choice of parameters of a secure transmission are recommended:

  • Key exchange - choose the public-key cryptographic algorithm RSA rather than the cryptographic protocol Diffie-Hellman.

  • Symmetric cipher - choose Triple DES or RC4 128 rather than any other encryption method, because they use strong keys.

  • Hash function - choose SHA1 digest rather than MD5, because SHA1 produces a stronger digest.

When null encryption is chosen, SSL performs only authentication and data integrity checks. The system property https.cipherSuites specifies the subset of available cipher suites (comma-delimited list of cipher suite names).

20.3 JSSE System Properties

This section describes some standard JSSE system keystore properties used to set security credential information.

javax.net.ssl.keyStore

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

javax.net.ssl.keyStorePassword

This property indicates the password necessary to open the keystore (keystore or wallet file). Specifying the keystore password in Java system property may pose a security risk in some environments.

To avoid this risk, if a password is necessary, do not store it in a clear text. Alternatively, use the method System.setProperty to set it dynamically (before starting the HTTPConnection) and then unset it after the handshake is completed. Note, however, that this still may present the security risk since another application running in the server may read the password by polling this property.

javax.net.ssl.keyStoreType

This property indicates the type of file used for the keystore. When using the OraclePKIProvider, the value can be PKCS12 or SSO; when using the default Sun Microsystems JSSE implementation, the value must be JKS.

javax.net.ssl.trustStore

This property, similar to javax.net.ssl.keyStore, indicates the location and name of the keystore or wallet file to use as the truststore.

javax.net.ssl.trustStorePassword

This property, similar to javax.net.ssl.keyStorePassword, indicates the password necessary to open the truststore file (keystore or wallet).

javax.net.ssl.trustStoreType

This property, identical in function to the property javax.net.ssl.keyStoreType, indicates the type of file used for the truststore.

20.4 Using HTTPClient with JSSE

This section describes the requirements for using and configuring Oracle HTTPClient with JSSE. The information applies only to scenarios where Oracle HTTPClient is used with Oracle Wallet.

By default, HTTPClient uses the JSSE implementations available in the JVM.

20.4.1 Prerequisites for using JSSE

To use HTTPClient with JSSE:

  • Use Sun Microsystems JDK version 1.2 or higher (JSSE is included as part of JDK 1.4 or higher).

  • If Oracle wallet support is required, include the file oraclepki.jar in your classpath. Note that the files jssl-1_1.jar and jssl-1_2.jar (used by Oracle Java SSL) are no longer required.


    Note:

    Starting with this release, an application should use only a JKS keystore with Oracle HTTPClient. The JKS keystore is the default keystore in Java and no JVM settings are required to use this keystore. Application wanting to migrate the content of their existing oracle Wallets to JKS can use orapki command.

  • This step is necessary only if you are using Oracle Wallet. Register the OraclePKIProvider with the JVM, by using either of the following steps:

    • Edit the file jre/lib/security/java.security, by adding an entry similar to security.provider.n=oracle.security.pki.OraclePKIProvider, where n is replaced with the appropriate index number.

    • Call the method Security.addProvider(new OraclePKIProvider())

20.4.2 Configuring HTTPClient


Note:

By default, HTTPClient uses the JVM JSSE SSLSocketFactory, which recognizes the SSL-related system properties. An application can, however, construct its own JSSE SSLSocketFactory for HTTPClient to use. This custom SSLSocketFactory could be designed to support multiple keystores or truststores and to ignore SSL-related system properties.

Also, by default, HTTPClient uses the JVM JSSE implementation. If, however, the Sun SSL provider is configured, the cacerts file is used as a truststore based on the rules defined in http://java.sun.com/javase/6/docs/technotes/guides/security/jsse/JSSERefGuide.html.


To configure HTTPClient to use JSSE as the underlying SSL provider, proceed as follows:

  1. This step is necessary only if not using the JDK infrastructure.

    Create a truststore using the Sun Microsystems utility keytool. For details about this tool usage, see http://java.sun.com/javase/6/docs/technotes/tools/index.html#security.

    Assign the truststore to the underlying SSL provider. For the Sun JSSE provider, set the system properties javax.net.ssl.trustStore, javax.net.ssl.trustStoreType, and javax.net.ssl.trustStorePassword. Oracle discourages setting passwords in system properties, and some truststore types may not require password for read access.

  2. Create an instance of HTTPClient.HTTPConnection, as illustrated in the following code sample:

    HTTPConnection conn = new HTTPConnection( "https", "my.bank.com", -1 );
    
  3. Optionally, call connect to establish the SSL connection and get SSL session info, as illustrated in the following code sample:

    conn.connect();
    SSLSession sessionInfo = conn.getSSLSession();
    

20.5 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 risk requires that HTTPS servers have certificates issued to their host name. Then, it is the responsibility of the client to perform the validation after the SSL connection is established.

Oracle HTTP Client Security uses a host name verifier (an implementation of the interface javax.net.ssl.HostnameVerifier) to attest that the host name in an SSL certificate matches the host name in the URI used to access the protected server. HTTPClient invokes the HostnameVerifier instance immediately after establishing an SSL session and throws the exception javax.net.ssl.SSLPeerUnverifiedException if it detects a host name mismatch.


Important:

You can use your own implementation of the host name verifier or the one provided by Oracle (as described below). Any such implementation must contain a constructor with no arguments.

For further details about the class HostnameVerifier, see http://java.sun.com/j2se/1.4.2/docs/api/javax/net/ssl/HostnameVerifier.html

Host name verification is performed only if it is enabled by a system property or programmatically, as described in the following two sections.

20.5.1 Enabling Host Name Verification with a System Property

To enable host name verification without having to alter your code, set the system property HTTPClient.defaultHostnameVerifier to the full name of the class implementing the interface javax.net.ssl.HostnameVerifier.

20.5.2 Enabling Host Name Verification Programmatically

To enable host name verification programmatically, use:

  • static HostnameVerifier setDefaultHostnameVerifier (HostnameVerifier myHNVerifier)

    This method sets the host name verifier for all connections in the entire Java VM to the passed instance. It returns the host name verifier previously set as default (if there was one) or null (if the host name verification was disabled for the Java VM).

  • HostnameVerifier setHostnameVerifier (HostnameVerifier myHNVerifier)

    This method sets the verifier for the connection to the passed instance and overrides any default setting; if the passed argument is null, it disables the host name verification for the connection. It returns the host name verifier previously set for the connection (if there was one) or null (if the host name verification was disabled for the connection).

20.5.3 Oracle Standard Host Name Verifier

Oracle HTTP Client Security includes the class StandardHostnameVerifier, an implementation of the host name verifier that provides standard host name matching rules for site identity checking.

StandardHostnameVerifier compares (case-insensitive) the SSL session host name and the common name (CN) of the distinguished name (DN) from the first certificate in the SSL certificate chain; moreover, it allows the use of wildcard characters while attempting to match both names during the comparison. For example, if wildcard is enabled, the strings “*.oracle.com” and “www.oracle.com” match.

StandardHostnameVerifier exposes the following methods:

  • boolean setRecognizeWildcardCNs(boolean recognizeWildcardCNs)

    This method sets the comparison to recognize or not to recognize wildcard characters; it returns the value previously set.

  • boolean isRecognizeWildcardCNs()

    This method returns true is the comparison uses wildcards, or false otherwise.

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

    This method returns true, if the passed hostname matches the authentication scheme of the server in the passed session, or false otherwise.

The following line illustrates how to set the Oracle host name verifier as the default host name verifier with a system property:

HTTPClient.defaultHostnameVerifier=HTTPClient.StandardHostnameVerifier;

20.5.4 Additional Verification

To perform further validation (beyond host name verification) by using the data in the object returned by the method getSSLSession, proceed as follows. First, establish a connection to the server without transferring any data:

httpsConnection.connect();

Next, obtain a session info:

SSLSession sessionInfo = httpsConnection.getSSLSession();

The object SSLSession exposes many attributes of the SSL connection which may be used to verify the connection. For details, see http://java.sun.com/j2se/1.5.0/docs/api/javax/net/ssl/SSLSession.html

20.6 Using NTLM Authentication with Oracle HTTPClient

NT LAN Manager (NTLM) is a Microsoft authentication protocol supported by Oracle HTTPClient that clients, proxies, and servers can use.

NTLM is a connection-oriented protocol because after a connection is authenticated no further credentials are required for transmission while the connection remains open. Thus, a client using NTLM proves its identity to establish the connection and need not send its password thereafter.

Proxy servers may also use NTLM for client authentication, but, unlike some request-oriented authentication schemes (such as Basic and Digest authentication), an NTLM client authenticates its connection with only the proxy server, not the resource server.

HTTPClient also supports Basic and Digest Authentication. This support equals that provided in the open source version of HTTPClient.

20.6.1 NTLM Domain Name and Realm

An NTLM account identifier has the format NTDname\userName, where the optional string NTDname identifies the NT Domain name; if not present, the domain name is assumed to be the default NT Domain name, which is set with the system property HTTPClient.ntlm.defaultDomainName. Furthermore, if the account identifier contains no NT Domain name and there is no default set, then the NTLM-protected server uses its own NT Domain name.

A realm, as specified in some authentication schemes (such as Basic authentication), does not apply to NTLM since the challenge does not have a realm directive; thus, all NTLM credentials are assumed to be part of the same empty realm within an HTTPClient connection.

20.6.2 Connecting to NTLM-Protected Servers

To connect to an NTLM-protected resource or proxy server, credentials must be added to the HTTPClient AuthorizationInfo credential store. This is accomplished in one of two ways according to the type of server to which the client is connecting. In any case, HTTPClient automatically queries the credential store when challenged by an NTLM server.

To connect to an NTLM-protected resource server, add NTLM credentials using the HTTPConnection instance as illustrated in the following code snippet:

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

Note that the example above adds NTLM credentials for the resource server represented in myHost.

Alternatively, add NTLM credentials using the object AuthorizationInfo directly as illustrated in the following code snippet:

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 );

Note that the example above adds NTLM credentials for the proxy server represented in myProxyHost.

To connect to an NTLM-protected proxy server, add NTLM credentials using HTTPConnection.addNtlmAuthentication directly, as illustrated above, since the method addNtlmAuthentication adds credentials for the associated resource server, not the proxy server.