JavaTM Secure Socket Extension (JSSE) 1.0.3

API User's Guide


Contents


Introduction

The Java Secure Socket Extension (JSSE) 1.0.3 provides an application programming interface (API) framework and reference implementation for security protocols similar to Netscape's Secure Sockets Layer (SSL). The framework is capable of supporting SSL versions 2 and 3 and Transport Layer Security (TLS) 1.0. These security protocols encapsulate a normal bidirectional stream socket and add transparent support for authentication, encryption, and integrity protection.

JSSE 1.0.3 is designed to allow other implementations to be plugged in seamlessly, thus providing alternate protocol and Public Key Infrastructure (PKI) implementations.

JSSE 1.0.3 supplements the Java platform by providing additional URL scheme handlers and extended networking socket classes. It also provides a socket factory framework for encapsulating socket creation behavior and provides a limited public key certificate API that is compatible with JDK1.1-based platforms.

The JSSE is provided in 2 parts. The first part is standardized under the javax package namespace and provides an API for secure sockets, socket factories, and public key certificates. The second part is a set of reference implementation classes under the com.ibm.net.ssl package. These classes are not part of the JSSE 1.0.3 standard extension API.

The architecture of the JSSE follows the same design principles found in the Java Cryptography Architecture (JCA) which is provided in Java 2 and Java Cryptography Extension (JCE). It uses the same "provider" architecture. In order to use JSSE install this provider either statically or dynamically.

 

To do this statically edit the security properties file as follows:
 

<java-home>\lib\security\java.security[Win32]

<java-home>/lib/security/java.security[UNIX]

The static text file update would look something like this:

security.provider.1=sun.security.provider.Sun

security.provider.2=com.ibm.jsse.IBMJSSEProvider

You may also add this provider dynamically in your Java application by calling the addProvider() method in the java.security.Security class.

    Security.addProvider(new com.ibm.jsse.IBMJSSEProvider());

JSSE 1.0.3 comes standard with a provider which supplies the following cryptographic services:

·         RSA support for the signature-related JCA features of the Java 2 platform

·         An implementation of the SSL 2.0, SSL 3.0 and TLS 1.0 security protocols.

·         An implementation of the most common SSL and TLS cipher suites, which encompass a unique combination of authentication, key agreement, encryption and integrity protection.

·         An implementation of an X.509-based key manager, which chooses appropriate authentication keys from a standard JCA KeyStore.

·         An implementation of an X.509-based trust manager, which implements a subset of the RFC 2459 rules for certificate chain path validation.

·         An implementation of PKCS12 as JCA keystore type "PKCS12KS".

 

JSSE encompasses many of the concepts and algorithms in the JCE but automatically applies them underneath a simple stream socket API extension.

Concepts

This section provides a high-level description of  the concepts implemented by the API, and the exact meaning of the technical terms used in the API specification.

Encryption and Decryption

Encryption is the process of taking data (called cleartext) and a short string (a key), and producing data (ciphertext) meaningless to a third-party who does not know the key. Decryption is the inverse process: that of taking ciphertext and a short key string, and producing cleartext.

Key Agreement

Key agreement is a protocol by which two or more parties can establish the same cryptographic keys, without having to exchange any secret information.

Message Authentication Code

A Message Authentication Code (MAC) provides a way to check the integrity of information transmitted over or stored in an unreliable medium, based on a secret key. Typically, message authentication codes are used between two parties that share a secret key in order to validate information transmitted between these parties.

A MAC mechanism that is based on cryptographic hash functions is referred to as HMAC. HMAC can be used with any cryptographic hash function, e.g., MD5 or SHA-1, in combination with a secret shared key. HMAC is specified in RFC 2104.


Cipher Suite

A unique combination of authentication, key agreement, encryption and integrity protection which describes the security algorithms which will be used to protect a secure socket.

Session

A named collection of state information including authenticated peer identity, cipher suite and key agreement secrets which are negotiated through a secure socket handshake protocol and which can be shared among multiple secure socket instances.

 

Handshake Protocol

The negotiation phase during which the two socket peers agree to use a new or existing session. The handshake protocol is a series of messages exchanged over the record protocol. At the end of the handshake new connection-specific encryption and integrity protection keys are generated based on the key agreement secrets in the session.

Record Protocol

The record protocol packages all data, whether application-level or as part of the handshake process, into discrete records of data much like a TCP stream socket converts an application byte stream into network packets. The individual records are then protected by the current encryption and integrity protection keys.

Packages

javax.net
javax.net.ssl
javax.security.cert
com.ibm.net.ssl

Core Classes

·SSLSocketFactory

An SSLSocketFactory acts as a factory for creating secure sockets. This class is a subclass of the generic SocketFactory class provided with JSSE. Socket factories encapsulate the details of creating and initially configuring sockets. For example, this could include interacting with firewall proxies to tunnel connections. In the case of secure sockets, this includes authentication keys, peer certificate validation, enabled cipher suites and the like.

 

Obtaining an SSLSocketFactory

 

There are three primary ways of obtaining an SSLSocketFactory:

·get the default factory by calling the getDefault() static method.

·receive a factory as an API parameter to code which needs to create sockets but doesn't care about the details of how the sockets are configured.

·construct a new factory with specifically configured behavior.

The default factory is typically configured to support server authentication only so that sockets created by the default factory do not leak any more information about the client than a normal TCP socket would.

Many classes which create and use sockets do not need to know the details of socket creation behavior. Creating sockets through a socket factory passed in as a parameter is a good way of isolating the details of socket configuration, and increases the reusability of classes which create and use sockets.

You can create new socket factory instances either by implementing your own socket factory subclass or by using another class which acts as a factory for socket factories. One example of such a class is SSLContext, which is provided as a non-standard provider-based configuration class with the JSSE reference implementation.

·SSLSocket

This class is a subclass of the standard Java Socket class. It supports all of the standard socket methods and then adds additional methods specific to secure sockets. Instances of this class encapsulate the SSLContext under which they were created. There are APIs to control the creation of secure socket sessions for a socket instance but trust and key management are not directly exposed.

Obtaining an SSLSocket

Instances of SSLSocket can be obtained in two ways. First, an SSLSocket can be created by an instance of SSLSocketFactory via one of the several createSocket() methods on that class. The second way to obtain SSLSockets is through the accept() method on the SSLServerSocket class.

·SSLSession

An SSLSession represents a security context negotiated between the two peers of an SSLSocket connection. Once a session has been arranged it can be shared by future SSLSockets connected between the same two peers. The session contains the cipher suite which will be used for communications over a secure socket as well as a non-authoritative hint as to the identity of the remote peer and management information such the time of creation and last use. A session also contains a shared "master secret" negotiated between the peers that is used to create cryptographic keys for encrypting and guaranteeing the integrity of the communications over an SSLSocket. However, the value of this master secret is known only to the underlying secure socket implementation and is not exposed through the SSLSession API.

Support Classes

Several classes are provided as part of the JSSE API which support the creation, use, and management of secure sockets but which might not be commonly accessed by secure socket applications.

·SSLSessionContext

 

This class can optionally be obtained from an instance of SSLSession. Some implementations may return session contexts while others may simply return null from the getSessionContext() method. SSLSessionContexts are used to manage the cache of SSLSessions available for use by SSLSockets when negotiating a security context. The methods on this class enable the enumeration of all sessions in a context and allow lookup of specific sessions using the session id.

 

·SSLSessionBindingEvent

You may register a listener for session binding events on an SSLSocket. This allows notification of any changes to the name/value properties which can be associated with an SSLSession through the getValue() and putValue() methods.
 

·HandshakeCompletedEvent

You may register a listener for handshake completion events on an SSLSocket. This allows notification whenever a new session is negotiated for use on the SSLSocket instance.
 

·X509Certificate

Many secure socket protocols perform authentication using public key certificates. This is the default authentication mechanism for the SSL and TLS protocols.

Configuration Classes

These classes are provided with the JSSE reference implementation but they are not part of the JSSE 1.0.3 standard extension API.

 

·SSLContext

An SSLContext instance represents an implementation of a secure socket protocol. Instances of this class act as a factory for socket factories. An SSLContext holds all of the state information shared across all sockets created under that context. For instance, session state is associated with the SSLContext when it is negotiated through the handshake protocol by sockets created by socket factories provided by the context. These cached sessions can then be reused and shared by other sockets created under the same context.

Each instance is configured through its init() method with the keys, certificate chains, and trusted root CA certificates that it needs to perform authentication. This configuration is provided in the form of  key and trust managers. These managers provide support for the authentication and key agreement aspects of the cipher suites supported by the context.

 

Currently, only X.509-based managers are supported.

 

Creating an SSLContext Object

Like other JCA provider-based "engine" classes, SSLContext objects are created using the getInstance factory methods on the SSLContext class. This is a static method which returns an instance which implements a requested secure socket protocol.

To create an SSLContext object, specify the protocol name. You may also specify which provider you want to supply the implementation of the requested protocol:
 

public static Cipher getInstance(String protocol);

public static Cipher getInstance(String protocol,
                                 String provider);

If just a protocol name is specified, the system will determine if there is an implementation of the requested protocol available in the environment, and if there is more than one, if there is a preferred one.

If both a protocol name and a provider are specified, the system will determine if there is an implementation of the requested protocol in the provider requested, and throw an exception if there is not.

A protocol is a string that describes the secure socket protocol desired.

For example:

"SSL"

Common protocol  names for SSLContext objects are defined in Appendix A.

 

·TrustManagerFactory

In order to support authenticating the remote identity of a secure socket peer you need to initialize an SSLContext object with one or more TrustManagers. You need to pass one TrustManager for each different authentication mechanism that will be supported. Typically, there is only one trust manager that supports verifying authentication based on X.509 public key certificates. Some secure socket implementations may also support authentication based on shared secret keys, Kerberos, or other mechanisms.

The TrustManagerFactory is a provider-based service which acts as a factory for one or more types of TrustManager objects. The JSSE reference provider implements a factory which can return a basic X.509 trust manager. Because it is provider-based, additional factories can be implemented and configured that provide additional or alternate trust managers that provide more sophisticated services or that implement installation-specific authentication policies.

Creating a TrustManagerFactory

You create an instance of this class in a similar manner to SSLContext. However, instead of passing a protocol name to the getInstance() method, you instead pass an algorithm name string.

For example:

"IbmX509"

The above example will create an instance of the JSSE default factory which provides basic X.509-based certification path validity checking. In the 1.0.3 release, this performs a subset of the rules specified in RFC 2459.

A newly created factory should be initialized by calling the init() method. You may pass a KeyStore object which the factory will query for information on which remote certificates should be trusted during authorization checks.

Some factories are capable of  making trust decisions without having to be initialized with a KeyStore object. For example, they may access trust material from a local directory service via Lightweight Directory Access Protocol (LDAP), may use a remote online certificate status checking server, or may access default trust material from a standard local location.

For instance, the IbmX509 factory will access the KeyStore file in the "jre/lib/security/cacerts" subdirectory of the directory where Java is installed if a null object is passed to the KeyStore parameter.

It will first check for "jre/lib/security/jssecacerts" before falling back on the cacerts file so that you can provide a JSSE-specific set of trusted root certificates separate from ones that might be present in cacerts for code signing purposes.
 

·X509TrustManager

This is the interface that must be implemented by a trust manager for X.509-based authentication. This is a subinterface of the general TrustManager interface. In order to support X.509 authentication of remote socket peers through JSSE, an instance of this interface must be passed to the init() method of an SSLContext object.

Creating an X509TrustManager

You can either implement this interface directly yourself or obtain one from a provider-based TrustManagerFactory.  You could also implement your own that delegates to a factory-generated trust manager. For example, you might do this in order to filter the resulting trust decisions and query an end-user through a graphical user interface.

·KeyManagerFactory

In order to support authenticating yourself to a remote secure socket peer you need to initialize an SSLContext object with one or more KeyManagers. You need to pass one KeyManager for each different authentication mechanism that will be supported. Typically, there is only one key manager and it supports authenticating based on X.509 public key certificates. Some secure socket implementations may also support authentication based on shared secret keys, Kerberos, or other mechanisms.

The KeyManagerFactory is a provider-based service which acts as a factory for one or more types of KeyManager objects. The JSSE reference provider implements a factory which can return a basic X.509 key manager. Because it is provider-based, additional factories can be implemented and configured that provide additional or alternate trust managers.

Creating a KeyManagerFactory

You create an instance of this class in a similar manner to SSLContext. However, instead of passing a protocol name to the getInstance() method, you instead pass an algorithm name string.

For example:

"IbmX509"

The above example will create an instance of the JSSE default factory which provides basic X.509-based authentication keys.

A newly created factory should be initialized by calling the init() method. You may pass a KeyStore object which the factory will query for information on which private key and matching public key certificates should be used for authenticating to a remote socket peer. In addition to the KeyStore object, you must also provide a second parameter which gives the password that will be used with the methods for accessing keys from the KeyStore. All keys in the KeyStore must be protected by the same password.

Some factories are capable of  providing access to authentication material without having to be initialized with a KeyStore object. For example, they may access key material as part of a login mechanism such as one based on JAAS, the Java Authentication and Authorization Service.

The JSSE provider supports a "IbmX509" factory which must be initialized with a KeyStore parameter.

·X509KeyManager

This is the interface that must be implemented by a key manager for X.509-based authentication. This is a subinterface of the general KeyManager interface. In order to support X.509 authentication to remote socket peers through JSSE, an instance of this interface must be passed to the init() method of an SSLContext object.

Creating an X509KeyManager

You can either implement this interface directly yourself or obtain one from a provider-based KeyManagerFactory.  You could also implement your own that delegates to a factory-generated trust manager. For example, you might do this in order to filter the resulting keys and query an end-user through a graphical user interface.

Using HTTPS

There are two primary APIs for accessing secure communications through JSSE. One way is through a socket-level API which can be used for arbitrary secure communications. A second, and often simpler way, is through the URL API.

You can communicate securely with an SSL-enabled web server by using the "https" URL protocol or scheme using the java.net.URL class.

Support for "https" URL schemes is implemented in many of the common browsers which allows access to secured communications without requiring the socket-level API provided with JSSE.

An example URL might be:

"https://www.ibm.com"

 

The trust and key management for the "https" URL implementation is environment specific. The JSSE reference implementation provided an "https" URLStreamHandler implementation. In order to use this handler, add the handler's implementation package name to the list of packages which are searched by the Java URL class. This is configured via the "java.protocol.handler.pkgs" system property. See the java.net.URL class documentation for details.

 

The handler uses the cacerts, which is the system-wide keystore that comes with Java runtime environment, as the default trusted CA certificates database. The cacerts file stores five VeriSign root CA certificates in JKS format. You can create your own trusted CA certificates database file via iKeyman tool, and use the file for HTTPS connection by setting system properties "javax.net.ssl.trustStore" and "javax.net.ssl.trustStorePassword" to point to it.

In some cases, the secure Web server requires mutual authentication, provide client-side certificate by setting system properties "javax.net.ssl.keyStore" and "javax.net.ssl.keyStorePassword" properly. A sample keystore file (testkeys, password is "passphrase") with a personal certificate and ten trusted signer certificates is included in:

<java-home>\docs\ikeyman\samples directory[Win32]

<java-home>/demo/ikeyman/SampleIKEYMAN.jar jar file[UNIX]

 

 Personal certificates could be requested and generated using iKeyman tool.

In the case when there is a firewall between the secure Web server and the client application, set the socks hostname and port number in system properties "socksProxyHost" and "socksProxyPort".

System properties can be set via the command line or at runtime through the java.lang.System class. For example, all the system properties described above can be set on the command line as follows:

java -Djava.protocol.handler.pkgs=com.ibm.net.ssl.internal.www.protocol -Djavax.net.ssl.trustStore=trustStorePath -Djavax.net.ssl.trustStorePassword=changeit -Djavax.net.ssl.keyStore=keyStorePath -Djavax.net.ssl.keyStorePassword=passphrase -DsocksProxyHost=socks.ibm.com -DsocksProxyPort=80

where trustStorePath represents the fully qualified path where to find the TrustStore and keyStorePath represents the fully qualified path where to find the KeyStore.

Additional Keystore Formats

The JSSE reference implementation provider supplies its own implementation of the Java 2 KeyStore API that supports the PKCS12 file format. This format is also supported by other toolkits and applications for importing and exporting keys and certificates. For example, Netscape 4.x (versions 4.04 and later) can export client certificates and keys into a file using the ".p12" filename extension in PKCS12 format.

With the JSSE provider installed, you can access these keys through the KeyStore API with a keystore type of "pkcs12ks" (or "PKCS12KS", the name is case-insensitive). In addition, you can list the supported keys using the keytool command with the -storetype option set to pkcs12ks.

See the README file for the release you are using. The 1.0.3 release of JSSE has limitations on its implementation but can read and use PKCS12 keystore files exported by Netscape. Future releases will also support and be tested with Internet Explorer and other applications.

How to Get Debug Information

One can use the dynamic debug tracing support to get debug information. This is similar to that used for debugging access control failures in Java 2. You can configure this via the javax.net.debug system property. A value of "true" will turn on the trace facility given you have installed the debug version of JSSE.

Appendix A: Standard Names

The protocol name parameter field passed to the getInstance() method of SSLContext supports a named secure socket protocol and optionally a named purpose separated from the protocol name by a '/' character. The table below names some common standard protocol names.


 

Protocol

Comment

SSL

Supports some version of SSL; may support other versions

SSLv2

Supports SSL version 2 or higher

SSLv3

Supports SSL version 3; may support other versions

TLS

Supports some version of TLS; may support other versions

TLSv1

Supports TLS version 1; may support other versions

SSL_TLS

Supports some version of SSL and TLS; may support other versions

 

 

IBM is a trademark of the IBM Corporation in the United States, other countries, or both.