Getting Started with Secure Indications

Introduction
Keystore Configuration Properties
Configurations for secure indication listener
"No authentication" configuration
"CIMOM authentication" configuration
"Listener authentication" configuration
"Mutual authentication" configuration
Configuring client and listener keystores independently

Introduction

The following text will explain how to configure a secure indication listener for the SBLIM CIM Client for Java.

It is suggested the reader first review Getting Started with Secure Connections, as this document relies on the topics covered there.

As described in Getting Started with Indications, indication delivery reverses the role of of HTTP client and server. The indication sender (typically the CIMOM) is now the HTTP client and the indication listener is the HTTP server.

For SSL/TLS (HTTPS) connections, configuration of a keystore is optional for the HTTPS client. For a HTTPS server however, a keystore is mandatory. This is because the keystore contains the private key the server will use to initiate encryption for the connection. So we must configure a keystore to enable a secure indication listener.

The keystore also contains the certificate the HTTPS server (i.e. the indication listener) will use to assert its identity. The HTTPS client (the indication sender or CIMOM) may optionally choose to verify the server cert against the contents of its own truststore.

Similarly, the listener may choose to verify the certificate of the indication sender. To do this we need to additionally configure a truststore for the listener.

Keystore Configuration Properties

SSL/TLS authentication is X509 certificate-based. Each side provides a X509 certificate that confirms its identity. The certificates are exchanged and each side validates the received certificate against a local copy.

For the listener, just as for the client, two files are used to store the certificates: a keystore and a truststore. The process for managing the keystores is described in Getting Started with Secure Connections. The following properties allow you to configure the keystores:

  • javax.net.ssl.keyStore: The file path of the SSL keystore.
  • javax.net.ssl.keyStoreType: The type of the SSL keystore repository. Typically this is JKS or Java KeyStore type, which is the default.
  • javax.net.ssl.keyStorePassword: The password of the keystore.
  • javax.net.ssl.trustStore: The file path of the SSL truststore.
  • javax.net.ssl.trustStoreType: The type of the SSL truststore repository. Typically this is JKS, which is the default.
  • javax.net.ssl.trustStorePassword: The password of the truststore.

Whenever the keystore properties are defined for the listener -- either by global configuration via the properties file or via a call to System.setProperty(), or set for the listener directly via a call to setProperty() on an instance of a listener -- the keystore will be activated automatically and no further configuration is required.

It should be noted that, in the case where the keystore properties are configured globally, the keystore will be activated for both the client and listener simultaneously (it will in fact be enabled for all new instances of client and listener), even if this is not the intended action. This can cause the following side effect, which would be of concern only in limited circumstances:

If you activate a keystore for the listener (as is required for SSL) it will be activated for the client as well, and the client will now begin to send a certificate during its SSL handshake. This would cause a change in behavior only if the CIMOM is configured for optional peer verification. If it is, and the CIMOM is unable to verify the new client certificate, the connection would fail. To fix this you must either import the client certificate to the CIMOM's truststore, or disable peer verification at the CIMOM.

There is currently no way to control the activation of the keystore for client and listener independently when the properties are configured globally. If your application absolutely requires independent control of the keystore for client and listener, it can be done programmatically as described here. For most applications this will not be required.

For the truststore, the situation is a bit different. An additional property is provided to control truststore activation; setting the above truststore properties alone is not sufficient to enable the truststore. The reason for this difference is that it allows peer authentication (a.k.a. peer verification) to be controlled independently for the client and the listener via the global configuration. (This is done for the truststore and not the keystore simply because the side effects of enabling peer verification simultaneously are much more severe than enabling the keystore simultaneously.)

To enable the truststore for the listener you must set the following property to accept or require (the default is ignore):

  • sblim.wbem.sslListenerPeerVerification: Determines how a HTTPS listener will handle authentication of a client (i.e. indication sender). If set to ignore, no SSL authentication (peer verification) will be performed. If set to require, the listener will attempt to verify the server certificate against the contents of the truststore defined in "javax.net.ssl.trustStore" and will fail the connection if the certificate cannot be verified. If set to accept, the listener will request the sender to present a certificate, but will not fail the connection even if an untrusted certificate is presented (this setting is of little practical value).

If the truststore properties are set but sslListenerPeerVerification is ignore, the truststore is not activated and all connections will be allowed (i.e. every sender is trusted). The only real use of this configuration is to temporarily disable the truststore for testing. Conversely, if sslListenerPeerVerification is require but the truststore properties are not set (or the truststore file is missing or otherwise unreadable), no connections will be allowed (i.e. no sender is trusted), as this is considered to be a misconfiguration. In both cases, a WARNING message is sent to the logger. (Note: sslListenerPeerVerification=accept behaves like require but the connection will not actually fail in this case.)

As mentioned above, there is a way to set the keystore or truststore properties independently for client and listener, and in this manner it is possible to configure a separate set of keystores for each. However, this cannot be done via the properties file; it can only be done programmatically. This is described here.

Configurations for secure indication listener

The table below shows the possible keystore configurations for the listener. Note we refer to the CIMOM in its capacity as indication sender, not server.

ConfigurationEncryption/HashingCIMOM authenticatedListener authenticatedSide effect if configured globally
No authenticationyesnonoclient now sends cert
CIMOM authenticationyesyesnonone
Listener authenticationyesnoyesclient now sends cert
Mutual authenticationyesyesyesclient now sends cert

"No authentication" configuration

  • Confidentiality: given
  • Integrity: given
  • Authentication: no
  • Keystore: always required
  • Truststore: No

As previously stated we must always configure a keystore to enable a secure listener. Follow the procedure here to create a keystore and set the appropriate configuration properties. Once this is done the keystore will be activated and the listener will be capable of receiving secure indications.

The process for creating a new indication listener is described here. The sample code supports either a http or https listener. Don't forget to change "http" to "https" in the CIM_ListenerDestinationCIMXML instance when creating a secure subscription.

Note: The indication sender CIMOM (i.e. the indication sender) may be configured to send its own X509 certificate. In this scenario we decided not to evaluate this certificate..

Note: Because the listener acts as a HTTPS server it will always present its certificate to the client (the indication sender or CIMOM). The CIMOM is free to verify the listener cert if desired. See your CIMOM documentation to determine if this feature is available. If so, the configuration will likely involve importing the listener certificate into the CIMOM truststore. See exporting a certificate for a description on how to export a certificate from your keystore so that you can import it into the CIMOM's truststore.

Note also: if the keystore properties are configured globally the keystore will be activated for (Java CIM) client as well as the listener. This can cause the side effect described in configuration properties above, which in most cases it is not of concern. If your application absolutely requires an independent keystore configuration this can be done programmatically as described below

"CIMOM authentication" configuration

  • Confidentiality: given
  • Integrity: given
  • Authentication: CIMOM only
  • Keystore: always required
  • Truststore: required

In this scenario we configure the listener to check the identity of the CIMOM (i.e. the indication sender). To do this we need to create a truststore and the appropriate configuration properties described above. When sslListenerPeerVerification is set to accept or require, the truststore will be activated and the listener will automatically check the CIMOM certificate against the contents. Everything else is equal to the "no authorization" configuration

Note: In this scenario we will check the CIMOM's X509 certificate. In order to do that we have to import the CIMOM's certificate into our truststore. See importing a certificate for details.

Note: Because the listener acts as a HTTPS server it will always present its certificate to the client (the indication sender or CIMOM). The CIMOM is free to verify the listener cert if desired.

Note also: even when the truststore properties are configured globally they are activated separately for client and listener via the sslClientPeerVerification and sslListenerPeerVerification properties. This is done to prevent any side effect from enabling them simultaneously.

"Listener authentication" configuration

  • Confidentiality: given
  • Integrity: given
  • Authentication: listener only
  • Keystore: always required
  • Truststore: no

In this scenario we configure the CIMOM (i.e. the indication sender) to check the identity of the listener. As previously stated, the listener will always present its certificate to the indication sender, so there is no further configuration required on the listener side. All that is required is to enable listener verification at your CIMOM. See your CIMOM documentation to determine if this feature is available. If so, the configuration will likely involve importing the listener certificate into the CIMOM truststore. See exporting a certificate for a description on how to export a certificate from your keystore so that you can import it into the CIMOM's truststore.

Note: In this scenario we decided not to evaluate the CIMOM's X509 certificate. The listener can be configured to do that as described above.

Note also: if the keystore properties are configured globally the keystore will be activated for (Java CIM) client as well as the listener. This can cause the side effect described in configuration properties above, which in most cases it is not of concern. If your application absolutely requires an independent keystore configuration this can be done programmatically as described below

"Mutual authentication" configuration

  • Confidentiality: given
  • Integrity: given
  • Authentication: listener and CIMOM
  • Keystore: always required
  • Truststore: required

In this scenario we configure certificate validation in both directions simultaneously.

In short, this configuration comprises the "CIMOM authentication" and "Listener authentication" together.

Remember, if the keystore or truststore properties are configured globally, the keystore or truststore will be activated for the client as well as the listener. If this is not your intent you must set the keystore configurations independently.

Configuring client and listener keystores independently

While it is not possible to configure client and listener keystores independently via the global configuration, it is possible to do so programmatically, by setting the desired property on the client or listener object directly, using the object's setProperty() method. In the case of the client this must be done after obtaining a reference to the client object but before the call to initialize(). For the listener it is done after obtaining the listener object but before the call to addlistener().

The ability to configure client and listener keystores independently has two basic applications:

  1. It allows the use of separate keystore/truststore files for client and listener. For most applications this should not be necessary. Understand that sharing a truststore between client and listener does not mean you are limited to a single CA certificate for both, since a truststore can contain more than one certificate. The same is not exactly true for the keystore: While a keystore can contain more than one key pair, the Java CIM Client's KeyManager will use the first acceptable key pair it finds in the keystore in order to complete the SSL handshake. So there is no simple way to make the client use one key pair and the listener use another. If your application requires this you must separate the client and listener keystores. The circumstances where this is required would be unusual, since it is most common in a public key infrastructure to assign a single indentity to an endpoint, and this technique would actually assign two identities to the endpoint. Nevertheless it is supported.
  2. It allows the keystore to be enabled separately for client and listener. When the keystore is configured globally it is automatically enabled for both client and listener even if this is not the intent. Configuring the keystore independently allows its activation to be controlled independently as well, since any property set on the client or listener directly will override the global value of that property. So there are two strategies here: you can either forego setting the keystore properties globally and set them only on the client or listener as required; or, you can force keystore activation off for client or listener by setting the keystore path to an empty string. The latter is recommended as it ensures it will not be inadvertently enabled if the global configuration is later modified. The circumstances where this required would be unusual, e.g. it is necessary to hide the identity of the client even when a SSL listener is enabled.

For the client, using the code snippet in First Steps as a reference: to configure a keystore for use solely by the client, insert the following lines after the call to getClient() but before the call to client.initialize():

client.setProperty(WBEMConfigurationProperties.KEYSTORE_PATH, "/path/to/client/keystore.pks");
client.setProperty(WBEMConfigurationProperties.KEYSTORE_PASSWORD, "password");

To disable the keystore for the client:

client.setProperty(WBEMConfigurationProperties.KEYSTORE_PATH, "");

For the listener, using the code snippet in Setting up an indication listener as a reference: to configure a keystore for use solely by the listener, insert the following lines after the call to getListener() but before the call to listener.addListener():

listener.setProperty(WBEMConfigurationProperties.KEYSTORE_PATH, "/path/to/listener/keystore.pks");
listener.setProperty(WBEMConfigurationProperties.KEYSTORE_PASSWORD, "password");

To disable the keystore for the listener (preventing the use SSL indications):

listener.setProperty(WBEMConfigurationProperties.KEYSTORE_PATH, "");

Finally, note it is also possible to control the listener configuration by creating a new java.lang.Properties object and passing it to addListener(), as shown in the example here. The result will be the same as the example above. If for some reason both methods are used, the properties passed to addListener() will take precedence.