The Community OpenORB - SSL

Chris Wood

Jerome Daniel

Michael Rumpf


Table of Contents

Introduction
1. Overview
2. Compilation
3. Installing
4. Configuration
5. Deployment
6. Frequently Asked Questions
A. Appendix

Introduction

This document provides installation and use instructions for the SSLIOP module for OpenORB.

The SSLIOP extension for OpenORB provides transport layer security for transmitted requests. It is a fully compliant implementation of the SSLIOP OMG specification.

The extension provides encryption of CORBA requests and responses, protection from the contents of messages being modified from a third party, and authentication of clients and servers.

Enabling security is completely transparent to a preexisting application, it is also possible to phase in secure communications by allowing incoming requests which are unsecured.

Chapter 1. Overview

Understanding the security offered by SSLIOP SSLIOP relies on SSL to provide three facets of security

  • integrity protection, to provide protection against the contents of a message being modified.
  • encryption, providing protection against the content of a message being viewed.
  • authentication, ensuring that one or both of the parties involved are who they claim to be.

All three facets need not be provided at the same time. For example, authentication may be limited to one party (normally the server) or authentication may be provided, but without encryption.

It is always necessary to authenticate at least one end of the connection to avoid a man in the middle attack. If this is not the case, any malicious attacker can masquerade as a legitimate user: The malicious attacker intercepts connection requests and sets up two secured, unauthenticated connections between itself and the two intended endpoints. With these connections in place the malicious attacker can intercept and corrupt any of the data that he relays between the two legitimate users.

There is the option of disabling authentication at both ends, however it is strongly recommended not to do this. Options are available to authenticate only the server, or both the server and the client. Currently it is not possible to authenticate only the client, although if requested we could provide this possibility.

To provide authentication it is necessary to construct a public and private key pair, which is also authenticated against a well known public key of some organization, known as a certifying authority (ca). For information about construction and authentication of keys see the documentation for the keytool application, provided by your JDK.

Encryption is required where the data being transmitted is sensitive to eavesdropping, for example credit card data. In some cases all that is required is integrity protection, preventing an attacker from modifying the data while it is in transmission. The computational overhead required is thus greatly reduced.

Chapter 2. Compilation

To compile and use OpenORB SSL you have to previously install and configure a SSL implementation in Java such as JSSE. For example, consult the Java Sun Web Site ( http://java.sun.com ) to get more information about JSSE.

It is assumed that OpenORB is previously installed on your system. The OpenORB ( openorb-{version}.jar ) and Tool ( openorb_tools-{version}.jar ) jar files must be added into your classpath.

Then, to build OpenORB SSLIOP :

  • set the JAVA_HOME env variable

  • start 'build.bat' ( for Windows ) or 'build.sh' ( for Unix )

OpenORB SSL is then built. The openorb_ssl-{version}.jar file is created in the 'dist' directory ( itself created by the build process ).

The SSLIOP distribution contains an Ant script that can be used to build it. If you use the build.bat ( for windows ) or build.sh ( for Unix ) all dependences and required classpath are directly included.

Thus, to compile SSLIOP for OpenORB, we advise you to enter the following command from the command line : build or build.sh

Chapter 3. Installing

This chapter explains how to install SSLIOP for OpenORB.

How to get SSLIOP for OpenORB ?

To get this OpenORB extension, please visit the Community OpenORB web site ( openorb.sf.net ). Then, go to the download section. Follow the instructions to download the SSLIOP extension.

SSLIOP dependencies.

The SSLIOP module must have a correctly installed OpenORB distribution to allow it to be used. It also requires an implementation of JSSE, a standard implementation of SSL for java as standardized by sun. Currently only the Sun reference implementation is available, it can be retrieved from the Sun website http://java.sun.com/products/JSSE/.

Please refer to your JSSE documentation for information on installation and configuration of keystore locations and passwords. The sun reference implementation of JSSE uses system properties to specify keystore locations and passwords. In general this is not secure from interception by malicious code. If untrusted code is to be run, see the section on advanced configuration.

Chapter 4. Configuration

How to configure SSLIOP for OpenORB

The first step in using SSLIOP is to add the openorb_ssl-x.y.z.jar file to your classpath.

If JSSE was configured so that the keystore location and password have been specified, or for a simple client-only application, where the server does not require client authentication, configuration of the SSLIOP module can be performed simply by adding the following line to the active profile of the user's master configuration file:

<import xlink:href="${openorb.home}config/SSLIOP.xml" />

This will rely on the JSSE implementation for all configuration, using its defaults. If the JSSE implementation is configured with a keystore location and password all requirements for secure operation will be satisfied, both at the server and client end. This configuration provides encrypted and integrity protected messaging, and authentication of servers.

If the JSSE implementation is configured using unprotected system properties any thread running in the same VM will be able to access the keystore location and password. For this reason this configuration does not provide any protection from untrusted code, which may use these properties to gain access to sensitive key information. Without providing a keystore and password to the JSSE implementation only client to server requests can be performed, and clients will not be authenticated. This may be reasonable a behavior in many cases.

A persistent server requires a constant port number to be used when it executes. To set a constant port number for ssl incoming connections use the following config fragment:

<import xlink:href="${openorb.home}config/SSLIOP.xml#SSLIOP">
		<property name="port" value="684" />
      </import>

Allowing unsecured requests and corbaloc: references.

By default whenever SSLIOP, or any other security mechanism, is activated any requests which do not use a secure mechanism will be rejected with NO_PERMISSION exceptions on both the server and client side. This default behaviour is designed to prevent any accedental transmission of sensitive data for clients, and to ensure protection for servers.

This protection can be disabled by using the following config file fragment:

<import xlink:href="${openorb.home}config/SSLIOP.xml#security">
		<property name="server.allowUnsecure" value="true" />
	<property name="client.allowUnsecure" value="true" />
      </import>

This same mechanism is shared across all security mechanisms. At the moment finer grain access over what is rejected and what is accepted is not possible.

One case where it is necessary to disable security is when using the initial references service and corbaloc: style string references. This is because IIOP is the only defined protocol for resolving initial references; IIOP is unsecured it will not be allowed. By default OpenORB uses a corbaloc: address to resolve the name service, if the name service is started with SSLIOP enabled and it's IOR is used in the following configuration fragment then this can be avoided:

<import xlink:href="${openorb.home}config/OpenORB.xml#InitRef">
			<property name="NameService" value="IOR:..." />
      </import>

Encryption type settings

All the SSLIOP specific configuration properties have 'support' and 'require' variants for both for clients and servers. This allows flexible setting of security facets for both clients and servers, for example a server which supports, but does not require, data encryption can be contacted by clients both with and without encryption in effect. Note that if both endpoints support but do not require a particular facet then the facet will be used.

In some situations, the extra overhead involved in encrypting all transferred data is in excess of what is required. It may be reasonable to authenticate the participants in the connection and transmit integrity protected data, this prevents data from being modified in transit but does not protect it's contents being viewed by eavesdroppers. Using the following import statement achieves this goal:

<import xlink:href="${openorb.home}config/SSLIOP.xml#SSLIOP">
		<property name="server.encrypt.require" value="false" />
		<property name="client.encrypt.support" value="false" />
      </import>

This disables support on the client side for encrypted communication, and allows connections on the server side to use protocol suites which are unencrypted. It is still possible to instantiate an encrypted channel to the server side, however the client side will always initiate unencrypted channels.

By default, only the server in a connection is required to authenticate itself. The client can remain unauthenticated. To require authentication of the client by the server the following configuration fragment can be used:

<import xlink:href="${openorb.home}config/SSLIOP.xml#SSLIOP">
		<property name="server.authClient" value="true" />
      </import>

The client will then require a certificate trusted by the server in order to connect. With client authentication enabled, and with all other requirements for bidirectional IIOP satisfied then bidirectional SSLIOP will be enabled. To require client authentication, but disable bidirectional access use:

<import xlink:href="${openorb.home}config/SSLIOP.xml#SSLIOP">
	  <property name="server.authClient" value="true" />
	  <property name="server.allowBiDir" value="false" />
      </import>

It is possible to disable authentication altogether for both clients and servers leaving only encryption, however this should not normally be done since unauthenticated communication is then subject to man in the middle attack:

<import xlink:href="${openorb.home}config/SSLIOP.xml#SSLIOP">
	  <property name="server.auth.support" value="false" />
      </import>

Setting up the context.

When the code being run in the same virtual machine is potentially untrusted, extra measures must be taken to ensure access is not granted to sensitive private key information. Sun's JSSE reference implementation relies on setting system properties, which if unprotected can be intercepted by malicious code and used to steal sensitive private key information. To avoid this the IOPSSL package provides a password entry dialog box option, and a replaceable class providing the dialog boxes.

To activate the dialog box for keystore location and password entry use the following config fragment:

      <import xlink:href="${openorb.home}config/SSLIOP.xml#SSLIOP">
	  <property name="context.useDefault" value="false" />
      <property name="context.keyStore.URL" 
      value="${user.home}.keystore" >
	  <property name="context.keyStore.prompt" value="password" >
      </import>
      

The first property, SSLIOP.context.useDefault=false, disables the use of the default ssl socket factories. Not using the default contexts may not be possible when using a non-sun JSSE implementation. The second property, SSLIOP.keyStore.URL, gives a URL for the keystore. The value given here will pick up the default keystore created by the keytool utility from your JDK.

The third property, SSLIOP.keyStore.prompt=password, results in a dialog box being activated to request a password. Prompting for a password is the only secure method for retrieving a password. Other options available for this field are "default" where the JSSE defaults are used, "prompt" where the location of both the keystore and its password are prompted for, and "noprompt" where the properties are used directly. When using the "noprompt" option the property SSLIOP.keyStore.password is available for setting the password, however this is not secure from malicious code which has access to the orb.

In some applications it may be required that an alternative trust store is used to the default. The default trust store, provided with all jdk installations, trusts users who have certificates registered with one of the global CAs. For some applications only specific groups of users should be granted access. In these situatations an application specific trust store can be created, and it's location specified: To activate the dialog box for keystore location and password entry use the following config fragment:

      <import xlink:href="${openorb.home}config/SSLIOP.xml#SSLIOP">
	  <property name="context.useDefault" value="false" />
	  <property name="context.trustStore.URL" value="a secure URL" />
      </import>

It should be noted that the URL used to locate the trust store should be secure from attack, an https URL is useful for remote locations, while a local file URL can be used locally.

Parts or all of this mechanism can be replaced, several protected functions are available from the org.openorb.SSLIOP.SSLContextFinder class, to use them create a subclass and modify the SSLIOP.SSLContextFinderClass property to locate the replacement. For more details see the class's api documentation.

Chapter 5. Deployment

To test SSLIOP simply run any application you would normally run. Running the ORB with the -ORBDebug=2 flag will display information about what protocols were used and when connections go up and down.

How to freeze the configuration ?

When you developed an application that uses SSL, you'll probably customized some parameters to fullfil your needs. After this customization, it's possible to replace the default configuration embedded within the SSL Jar file by your own configuration file. This section explains how to do that.

To freeze the configuration, we are going to replace the embedded configuration by the new one. The way to do that depends on the distribution that you are currently using : source code or pre built distribution. The following paragraphs describes how to proceed for each distribution kind.

Source code distribution In that case, a Ant target is provided to replace the embedded configuration file. From the command line : build config

Note

The new configuration file must be available in the src/config directory. Moreover, the Jar file where the configuration will be output must be available in the dist directory.

Pre built distribution: In that case, the config directory contains a script named setConfig ( setConfig.bat for Windows and setConfig.sh for Unix ). We have just to start this script to replace the embedded configuration file.

Note

The new configuration file must be available in the config directory. Moreover, the Jar file where the configuration will be output must be available in the lib directory.

Chapter 6. Frequently Asked Questions

6.1. I have several users in my organization who I want to allow access to my server, but noone from outside. How can i set this up?
6.2. The key store location is set so that each user has the keystore sourced from their local directory. The trust store URL should be a secure location, a file, resource or https url will work.
6.1.

I have several users in my organization who I want to allow access to my server, but noone from outside. How can i set this up?

Use the following profile in your enterprise wide configuration file:

        <profile name="name">
        <import xlink:href="${openorb.home}config/SSLIOP.xml#SSLIOP">
        <property name="server.authClient" value="true" />
  		<property name="context.useDefault" value="false" />
	  	<property name="context.keyStore.URL" value="${user.home}.keystore" />
		<property name="context.keyStore.prompt" value="password" />
	  	<property name="context.trustStore.URL" value="location" />
        </import>
        </profile>
        

6.2.

The key store location is set so that each user has the keystore sourced from their local directory. The trust store URL should be a secure location, a file, resource or https url will work.

There are two choices for how to proceed once this has been done. The first choice is to simply store self-signed certificates in the trust store from each of the users. This has the advantage of simplicity, however does require centralization of the keystore to ensure it is always kept up to date.

The second choice is to create a organization wide certification authority (CA). This can be done using software available in the public domain, openssl for example can be used. Each of the users creates a private key and has the corresponding public key signed by the CA. The truststore must then only contain the certificate of the CA, all of the certificates signed by the CA, those of the users, will then be trusted. Since this trust store is static it can be copied to local storage without need to search for updates.

A variation of the second option is to have your CA's certificate signed by a root CA, each jdk ships with a number of certificates of root CAs, if your CA's certificate is signed by one of these then the default trust store can be used. The disadvantage of this is it allows users outside of your organization access to your protected data.

Appendix A. Appendix