Novell SSL for Java
Articles and Tips: article
Senior Software Engineer
Network Security Development
Network Security Development
01 Nov 1999
Provides an overview of Novell's Java SSL implementation for NetWare. Includes key design aspects of the Java SSl interface, API details, and configuration tips.
The Secure Socket Layer (SSL) is a security layer that exists between TCP/IP and application protocols such as HTTP, LDAP, FTP and Telnet. It can provide confidentiality, integrity, server authentication and client authentication, depending on the chosen security parameters. SSL is most commonly used for transmitting sensitive information, such as credit card numbers and passwords, and as an authentication mechanism. SSL is the standard protocol in use today for secure communication over the Internet.
This Developer Note assumes that the reader has a basic understanding of SSL. You may want to refer to some of the numerous documents available on the Internet that explain how SSL works, although it is not necessary to understand the exact details in order to use Novell SSL for Java. However, it is important to understand how to properly manage certificates so that a reasonable trust decision can be made.
Encrypting a session without authenticating the server only provides protection against passive attacks, such as sniffing the wire. Authentication of the server is required to provide protection against active attacks, such as spoofing. Proper management of trusted root certificates is essential to ensure the security of the system.
Novell provides Java SSL implementations for NetWare as well as non-NetWare platforms. The NetWare version uses the underlying native SSL implementation (provided by Novell's Secure Authentication Services or SAS), while the non-NetWare version is a 100% pure Java implementation. There are significant differences in the capabilities of the NetWare and non-NetWare implementations from a management standpoint.
The NetWare implementation uses Novell Directory Services (NDS) for securing server keys, and Novell's exportable cryptography (Novell International Cryptography Infrastructure or NICI) and Public Key Infrastructure Services (PKIS) for key generation. Availability of exportable key generation mechanism and secure key management infrastructure enables SSL to work in server and client modes on NetWare. The pure Java implementation does not have exportable key generation or secure key management infrastructure, which restricts its capabilities to SSL client-mode operation only. Being a pure Java implementation it does, however, work well on all platforms that support a JVM, including web browsers. Client-mode SSL requires management of "trusted roots", (or trusted certification authorities) which is done using java.security.KeyStorefor JDK1.2 and using DER-encoded certificate files for JDK1.1.
Note: There are significant differences between JDK1.1 and JDK1.2, especially in their security model and security relevant classes, which have had direct impact on the design and implementation of pure Java SSL. Most commercial browsers and many application environments support only JDK1.1.x at this stage, and that has motivated us to support Java SSL on both JDK platforms, though not without some minor feature differences. The JDK1.1 version of our product would run on JDK1.2, but the JDK1.2 version would not run on JDK1.1. Fortunately for application developers, the APIs do not change at all, not even between the pure Java and NetWare versions. All differences are isolated in deployment time configurable properties. The differences are explained in more detail in the following sections.
Application Programming Interface (API)
Unlike most commercially available SSL interfaces, the interface for Novell SSL for Java is exportable outside the United States. The primary reason for its exportability is that it is extremely simple and benign from a cryptographic standpoint. While simplicity of interfaces implies that application developers can use them with minimal extra learning, it also implies a tradeoff with functionality. Fortunately, the tradeoff is not significant, and is far outweighed by the benefits of exportability. As indicated above, the interface is the same for both NetWare and pure Java implementations, and developers do not have to modify their code in order to use one implementation or the other. The SSL library automatically uses the appropriate implementation depending upon the operating environment. The differences in implementations however, do require that appropriate configuration files be created during deployment.
Following are some key design aspects of the Java SSL interface:
We introduced the notion of SecureSocketas an abstraction for transport layer security protocols. This has resulted in the SecureSocketfamily of classes/interfaces as a logical extension to the standard java.net.Socketfamily of classes, rather than a representation of a specific transport layer security protocol like SSL. An SSL implementation is merely one of the secure socket providers, which hides SSL specific constructs from the application developer. There could very well be other, possibly proprietary, transport layer security protocols that could be transparently plugged in as different providers, without causing the applications using them to change.
Being a logical extension, we extended the primary socket interfaces from java.netpackage, namely Socketand ServerSocketto form SecureSocketand SecureServerSocketrespectively. This allows application developers to use them as normal sockets, requiring changes only during socket instantiation. For instantiation of these secure sockets, we use the much preferred "factory" mechanism over usual constructors. The primary advantage of the "factory" based object creation is superior control over the type and number of actual objects created. Two factory classes have been introduced for secure socket creation, namely the SecureSocketFactoryand SecureServerSocketFactory.
The secure socket factories use a service provider architecture that allows third party developers to plug-in their own secure socket implementations. Novell's SSL implementation for NetWare and non-NetWare platforms are treated as default secure socket providers. The service provider interface has been packaged in an spi sub-package. The factories delegate actual socket creation to the current secure socket provider.
Client and server platforms usually have different security characteristics, which affect secure management of keys and certificates required for SSL. Each SSL provider manages keys and certificates on different platforms and defines appropriate properties that allow deployment time configuration of keys and certificates for its use. SecureSocket providers should subclass the SecureSocketPropertiesclass in the spisub-package to manage their implementation- specific properties.
An application written to plain sockets can be converted to use SecureSockets with a minimal change to the socket creation code only. Client socket creation code typically looks like:
Socket sock = new Socket(host, port);
This code would translate to the following code in order to use the default Novell SSL provider for SecureSocket:
Socket sock = SecureSocketFactory.getDefault().createSocket(host, port);
If a custom SSL provider were to be used, the sequence of steps would be:
SecureSocketFactory.setSocketFactory(new MySocketFactory()); SecureSocketFactory factory = SecureSocketFactory.newInstance(); Socket sock = factory.createSocket(host, port);
Where MySocketFactory would be the user provided SecureSocket factory.
The code for creation of server sockets is quite similar. Plain server socket creation code typically looks like:
ServerSocket servSock = new ServerSocket(port);
The equivalent SecureServerSocket creation code, using default Novell SSL provider, would be:
SecureServerSocketFactory factory = SecureServerSocketFactory.getDefault(); ServerSocket servSock = factory.createServerSocket(port);
In order to use secure sockets for RMI, LDAP or any other higher-level protocol, we recommend you don't subclass (extend) the SecureSocketFactoryor SecureServerSocketFactory. Instead, the appropriate socket factory for the protocol (such as RMIClientSocketFactory and RMIServerSocketFactory for RMI) should delegate the socket creation to an instance of SecureSocketFactoryor SecureServerSocketFactory.
The SecureSocket family of classes/interfaces are designed to support any transport layer security protocol, and hence do not have special methods to take SSL specific parameters. The parameters are communicated using provider-defined properties. Novell SSL providers for NetWare (native implementation) and non-NetWare platforms (pure Java implementation) each have a different set of properties. Each property can be broadly categorized as required or optional. The required properties reflect the information that is essential for SSL to initialize. The optional properties can be used for advanced configuration or enhanced user experience on the client machine. The following list summarizes the required properties for both providers. The list of optional properties is quite extensive, and we refer you to the product documentation for a complete, up-to-date list.
SSL Provider for NetWare
Name of the key pair to be used for Server authentication. Key pair is stored as a Key Material Object (KMO) in an NDS (Novell Directory Services) Tree in the same container as the NetWare server.
The signer (CA) of the key-pair is used as the default trusted root for server authentication (in client mode operation) or mutual authentication (in server mode operation). The capability to specify additional trusted roots would be supported in a later release.
JDK 1.2 Version of Pure Java SSL Provider for Non-NetWare Platforms
KeyStore file for trusted roots
KeyStore file for trusted site certificates
The KeyStore specified by each of these properties can be a URL, the name of a resource (i.e., a file bundled in the application jar) or a filename. If the property is a URL, it must be a fully specified URL, including the protocol, host name and full path. If the property does not specify a URL, then a resource by the specified name is searched for. If no such resource exists, the property is assumed to be a filename. The file is searched for in the same folders as the properties files (see Specifying Configurable Properties).
The trust decision is based on the certificate chain of the server. An SSL client keeps a set of trusted certificates, classified as either trusted site certificates or trusted root certificates. The point of difference between the two is that site certificates are not considered as trusted signers. A server certificate is considered trusted if it is a trusted site certificate or if any of its chain of signers are trusted root certificates. In the future, Novell SSL for Java will likely allow more flexible trust policies using a provider model.
Trusted certificates are kept in KeyStore files, which can be managed using the JDK's KeyTool utility or the java.security.KeyStore API.
If neither KeyStore property is specified, ssl.keystoreis automatically set to ".keystore". By default, the JDK KeyTool uses a KeyStore file named ".keystore" in the user's home directory. Therefore, if neither KeyStore property is specified, the system will find the KeyTool's default KeyStore and use it to obtain the trusted roots and no file will be read for trusted site certificates. If one of the properties is left unspecified, a KeyStore file will not be read for that certificate set.
Password for the KeyStore holding trusted roots
Password for the KeyStore holding trusted site certificates
Although the passwords are optional, we recommend that they be specified, since it allows an integrity check to be performed on the KeyStore and prevents unauthorized modification. The recommended approach is for the application to collect user password and set the property programmatically as described in Specifying Configuration Properties.
JDK 1.1 Version of Pure Java SSL Provider for Non-NetWare Platforms
A comma-delimited list of DER-encoded trusted root certificate files
A comma-delimited list of DER-encoded trusted site certificate files
KeyStore does not exist prior to JDK 1.2. Therefore, the pure Java client uses a list of individual DER-encoded certificate files instead. Each certificate in the list is searched for in the same way as KeyStore files are (i.e. each item in the list can be a URL, the name of a resource or a file). It is the client's responsibility to ensure that the certificates in the given list have not been substituted with malicious certificates.
Specifying Configurable Properties
The properties can be specified in one of the following ways.
In a provider specific property file: The property files for Novell SSL providers are nssl.properties and ssl.propertiesfor NetWare and non-NetWare (pure Java) providers respectively. The appropriate file can be specified as a resource, (it can be contained in the same jar as the application classes) failing which, it is searched for in the locations specified by the Java runtime variables, user.home, user.dirand java.home\lib, in that order. Specification as a resourceis particularly useful for Applets.
Via Java runtime variables: The property values can be specified on the command-line when starting the Java program, using -D<name<=<value<syntax.
Programmatically using a method in the socket factory: Both SecureSocketFactoryand SecureServerSocketFactoryclasses allow programmatic specification of the properties via setSocketPropertyand setServerSocketPropertymethods respectively.
If the same property is specified in more than one way, the programmatic specification overrides the value specified via runtime variable, which overrides the value specified in the property file. The properties specified in the property file or via runtime variables are read once during startup. Programmatic changes to property values, or specification of new properties made during runtime, affect new sockets created after the changes. Existing sockets are not affected by such property changes.
The getDefault()method always returns the singleton instance of Novell SSL providers, whereas the newInstance()method returns a new instance of either a user-specified provider if one has been specified using the setSocketFactory or setServerSocketFactory methods, or the Novell provider if none has been specified. Property changes can be applied to the singleton instance of the Novell default provider (returned by the getDefault()method), thereby affecting application wide changes. This is important if all threads in the application use the same factory to create new sockets. If different threads have different requirements of properties for socket creation, each thread must create a private copy of the factory (using the newInstance()method) and apply the property changes to its private copy. The factory returned by newInstance()starts initialized with the default properties specified via property files or runtime variables. Together, these factory creation methods provide an extremely flexible mechanism to address the needs of different applications.
Quality of Protection
In the interest of exportability, neither SecureSocket interface nor Novell SSL providers allow configuration of cipher-suites to be used for SSL. Instead, the package defines the notion of Quality of Protection(QoP) as a coarse grained abstraction of actual protection offered by SSL. Four values of QoP have been defined, namely, "No Protection", "Integrity Only", "Confidentiality Only" and "Integrity And Confidentiality." Applications can choose the QoP to be used for their SSL session or even change the QoP during an ongoing session.
For example, an application may choose "Integrity And Confidentiality" for sending sensitive data such as passwords or credit card numbers, and "Integrity Only" for the rest of the application data in order to get better throughput. The current version does not allow the applications to choose the strength of cryptography to be used for any of the available quality of protections. QoP changes during an SSL session require an SSL handshake between the client and the server, which is not only expensive, but may even fail if the other party doesn't support re-negotiation of cipher-suites. Buggy or incomplete SSL implementations on the other end may not recognize the change of QoP message, and may close the socket. Therefore, applications using this feature must be prepared to recover from a closed socket.
We haven't come across any commercial SSL implementation that supports the NULL cipher-suite, which implies that a request to set the QoP to "No Protection" would usually fail. Also, the SSL protocol does not support any cipher-suite that provides confidentiality with no integrity. Applications should therefore use the setMinimumQOP()instead of setQOP()method in SecureSocket, so that the implementation can safely upgrade to a higher available QoP.
A few tips to developers planning to use QoP extensively:
Most commercial sites usually disable "Integrity Only" mode as well, which may limit the available QoP to "Integrity And Confidentiality" only.
Switching from "Integrity And Confidentiality" to "Integrity Only", if successful, may increase overall throughput by a factor of 2 to 10, depending upon the environment and actual cipher-suites used.
Rarely, some SSL implementations would not recognize the change QoP message and would simply not respond. In order to prevent your SSL client from an eternal wait, it is best to set a timeout using the Socket.setSoTimeout()method before attempting a change of QoP.
HTTPS URL Handler
Novell SSL for Java includes a URL handler for HTTPS URLs. The URL handler automatically handles redirections and formats and parses HTTP headers. The details on installing a URL handler in different environments are elaborated in the product documentation.
Configuring Java SSL on NetWare 5
This section covers the various steps required to configure Java SSL on one or more NetWare 5 servers. NetWare 4.x servers do not support Java SSL. Some of the setup steps require administrative rights to the NDS tree to which the server belongs.
The following component versions must be installed on a NetWare 5 server to support Java SSL.
NICI (Novell International Cryptography Infrastructure) version 1.31 or later
PKIS (Novell Public Key Infrastructure Services) version 1.0.1 or later
SAS (Novell Secure Authentication Services) version 1.2 or later
SP2 (Support Pack version 2) for NetWare 5
These components are marked optional during NetWare 5 installation.
Choose a Certification Authority
The first step is to choose a Certification Authority (CA) to issue the server certificates. You can choose an external CA, or an organizational CA. For a comprehensive guide on the benefits of choosing one over the other, please refer to the Novell PKIS documentation. An external CA can be any commercial CA (such as Verisign) who accepts a CSR (Certificate Signing Request) and issues a certificate. Novell PKIS allows creation of an Organizational CA within the NDS tree using ConsoleOne or NWAdmin. The Organizational CA must be created in the security container at the root of the NDS tree to which the server belongs. The following screen-shot illustrates a step in the creation of an Organizational CA. Please refer to the PKIS document for a complete step-by-step guideline.
Figure 1: A step in the creation of an Organizational CA.
Create Server Keys and Certificates
The next step is to create a key pair (public and private keys) to be used for SSL. Novell PKIS allows creation of a Key Material Object (KMO) in the NDS tree, which stores the server key-pair and the certificates. Each server should use a different key-pair (hence, KMO) for SSL, although a given server can choose to use more than one key-pair. The Key Material Object for a given server should be created in the same container in the NDS tree to which the server object belongs. The following screen-shot illustrates a step in the creation of the Key Material Object. Note that the object is being created in the container "novell" in the tree "TWISTER". The server "TORNADO" belongs to the same container.
Note: You might need to upgrade your PKIS snap-in (use PKIS version 1.0.1 or later) and use ConsoleOne version 1.2 or later, in order to create Server Keys using ConsoleOne.
Figure 2: A step in the creation of the Key Material Object.
Choose a Trusted Root
SSL clients maintain a list of signers that they trust for validating server certificates. Self-signed certificates of trusted roots are either distributed out of band and imported by each client in its trusted roots store, or is distributed with applications that use SSL. Most commercially available web browsers, for example, ship with a list of commercial trusted roots. If you choose an external CA to sign your server certificates, the external CA (or its signer) would be the trusted root for the server certificates.
If you choose the Organizational CA instead, you have a choice of selecting the Organizational CA itself or the Novell Root Certifier as the trusted root when you create server certificates. We recommend that you select the Organizational CA as the trusted root. All NetWare 5 servers are capable of creating certificates that chain back to the Novell Root Certifier.
Choosing the Novell Root Certifier as the trusted root may therefore, give a false sense of security, unless the client can process the Novell Security Attributes specified in the certificate chain. Most commercial SSL clients do not understand the Novell Security Attributes. We refer you to the PKIS docs for details on the Novell Security Attributes. The wizard for creation of a Key Material Object offers the choice of selecting a trusted root for the server certificates.
Figure 3: Create Server Certificate.
Export the Trusted Root for the Server Certificate
To export the trusted root for the server certificate, double click on the server KMO created in the previous step to display the details. Next view the "Certificates" Tabs in the details panel, which contains a button to export the trusted root to a file on the disk. Choose the DER encoding for the exported certificate file and save it on your disk. You would need to distribute this file to all the clients so that they can import it inside their application's trusted roots store.
Runtime Configuration of Java SSL on NetWare
Here's a small list of things you need to do for configuring your application runtime to use Java SSL.
Pre-load SAS.NLM. This NLM is usually set to load in the autoexec.ncf file by the SAS install. Java SSL would try to auto-load SAS.NLM if it is not loaded, but since SAS takes a while to initialize, auto-load may fail in some situations.
Include JSAS.NLM and JSSL.NLM in the search path. Usually, you can copy them to the SYS:\SYSTEM folder during your application install, since SYS:\SYSTEM is always in the search path by default.
Include the Jar file containing Java SSL in your Java classpath, so that the Java Virtual Machine can find it. The Jar file is named nssl1.1_dom.jaror nssl1.1_exp.jardepending upon whether you have the domestic or exportable cryptography strength jar.
Specify the server key-pair name to be used by Java SSL, by specifying the nssl.keystoreproperty via one of the three methods mentioned above. The key-pair name is the name of the Key Material Object (KMO) less the server name. For example, if the KMO name appears in ConsoleOne to be "SSLKeys-MyServer" then the key pair name is "SSLKeys".
Configuring the Pure Java Client
The following steps need to be taken to properly configure the pure Java client.
Add the appropriate JAR file (for JDK 1.1 or JDK 1.2) to the classpath.
Obtain trusted roots and/or trusted site certificates for the target servers.
If you are using JDK 1.2, create KeyStore files for your trusted roots and trusted sites. To do this, you will need to run KeyTool with the -importoption. Use -keystore <filename<to specify a different KeyStore file than the default. When importing certificates, you may get a <Signature not found< error. This happens because most certificates are signed using RSA and by default the JDK does not contain an RSA signature provider. Novell SSL for Java includes an RSA signature provider that performs signature verification only. Add
to your java.securityfile to register this signature provider. Note that when you install JDK 1.2 with JRE and/or Java plug-in, you may find more than one java.securityfiles on your system. If you still get "Signature not found" errors, make sure you have added the provider to all your java.securityfiles. Sometimes it may be necessary to run "java sun.security.tools.KeyTool" instead of keytool.exeto get it to find the correct java.securityfile.
Create an ssl.propertiesfile and specify your trusted certificates.
If you are using JDK 1.2, you should specify the ssl.keystoreand ssl.sitekeystoreproperties, and optionally the ssl.keystore.passwordand ssl.sitekeystore.passwordproperties.
If you are using JDK 1.1, you should specify the ssl.certsand ssl.sitecertsproperties.
If you are using JDK 1.2, you may choose to enable the untrusted certificate dialog. This feature is unavailable for JDK 1.1. Novell SSL for Java provides a swing based dialog that appears when a server presents an untrusted certificate to the client. The dialog allows the user to interactively decide whether or not to trust the certificate. This feature is enabled by setting the ssl.client.guiproperty to true(the dialog is disabled by default).
Figure 4: Untrusted Certificate Verification.
If you enabled the untrusted certificate dialog, you can configure it as follows:
The dialog can be customized by specifying the ssl.application_interactionproperty. To use this property, an application developer should define a class that implements the com.novell.service.security.net.ssl.gui.ApplicationInteractioninterface. This property is then set to the fully-qualified class name. When the untrusted certificate dialog is going to be displayed, the pure Java client will create an instance of this class and call its getCertificateDisplayParametersmethod. This method returns customization information and a parent window for the dialog. On Win32 platforms, failure to provide a dialog with a parent window can lead to undesirable results. Therefore, it is highly recommended that any application that enables the untrusted certificate dialog also provide an ApplicationInteractionobject, even if it does nothing more than provide a parent window.
Decide whether you want to allow the pure Java client to add certificates to the site certificate keystore on the fly. For the user to be able to add the certificate to the KeyStore file, these conditions must be met:
ssl.sitekeystoremust specify a file and not a URL or resource
ssl.sitekeystore.passwordmust be specified
ssl.sitekeystore.readonlymust not be set to "true"
If these conditions are not met, the option to accept the certificate until it expires is disabled. If the conditions are met, and the user selects this option, the certificate will be added to the keystore with a unique alias that is based on the common name of the certificate. For security reasons, certificates cannot be added to the trusted roots store on the fly. They must be added offline using the KeyTool.
Specify any of the advanced properties, such as ssl.allow_overlapping_certs, ssl.cache.highor ssl.cache.low.
* Originally published in Novell AppNotes
The origin of this information may be internal or external to Novell. While Novell makes all reasonable efforts to verify this information, Novell does not make explicit or implied claims to its validity.