Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Table of Contents

Overview

The typical CONNECT installation uses Java keystores, but implementers may wish to use PKCS11 stores for FIPS 140-2 compliance.  These instructions detail a sample setup and deployment of CONNECT in multiple certificate scenario using wildfly 15 with SNI setup. 

Wildfly15 can be configured to use SNI in two ways: legacy subsystem and the Wildlfy Elytron subsystem. This guide focuses on Wildfly Elytron subsytem.

NSS Configuration

Prerequisites

  • Jdk 1.8
  • Wildfly 15 is unpackaged, and a ManagementRealm administrative user exists.  The "nss.x86_64" package is installed via the package manager.
  • CONNECT is deployed on Wildfly server.  Make sure the Connection Validation Suite runs successfully before attempting to configure FIPS.

Prepare the Database Configuration File and Directories

Create two folders designated for NSS, one to hold the configuration, and one to hold the keystore database; this document will use/nhin/nss/fips/config and /nhin/nss/fips/db respectively.  Give ownership of these folders to Wildfly user.  Under the config folder, create a file called pkcs11.cfg with the following content:

Code Block
name = nss-fips
nssLibraryDirectory = /usr/lib64
nssSecmodDirectory = /nhin/nss/fips/db
nssModule = fips

Configure FIPS mode

Create the FIPS database:

modutil -create -dbdir /nhin/nss/fips/db

Create a p12 keystore:

  • Navigate to {JBOSS_HOME}/modules/system/layers/base/org/connectopensource/configuration/main/
  • Create gateway.p12 by executing the following (important: use the gateway.jks password for the new destination keystore):
    • keytool -importkeystore -srckeystore gateway.jks -srcstoretype JKS -deststoretype PKCS12 -destkeystore gateway.p12
  • To import the cert keypair into the FIPS database, execute the following:
    • pk12util -i gateway.p12 -n gateway -d /nhin/nss/fips/db


Info
titleKeystore passwords

Under normal circumstances, the gateway.p12 password does not need to be the same as the gateway.jks password but for FIPS installations, an error will be encountered when importing the keypair into the FIPS database if they do not match.

Update Java.security option:

  • Editing ${JAVA_HOME}/jre/lib/security/java.security as follows:
    • As the first provider line, add: security.provider.1=sun.security.pkcs11.SunPKCS11 /nhin/nss/fips/config/pkcs11.cfg
    • Increment the number of every other provider by 1.

Enable FIPS mode:

modutil -fips true -dbdir /nhin/nss/fips/db

List PKCS#11 modules:

modutil -list -dbdir /nhin/nss/fips/db

List the private keys available:

keytool -list -storetype pkcs11 -v

Display certificate content:

certutil -K -d /nhin/nss/fips/db

Note: It should prompt for a password or error out. If it prompts for password enter password. If it errors then do below steps to change the NSS database password:

  • Disable nss_db first by executing the following: modutil -fips false -dbdir /nhin/nss/fips/db
  • Execute the following: modutil -changepw "NSS FIPS 140-2 Certificate DB" -dbdir /nhin/nss/fips/db/

CONNECT Configuration Updates

Navigate to ${JBOSS_HOME}/modules/system/layers/base/org/connectopensource/configuration/main and do the following inside that directory:

Edit saml.properties and modify the following lines to reflect the name and password of the key in the NSS database:

Code Block
org.apache.ws.security.saml.issuer.key.name=gateway
org.apache.ws.security.saml.issuer.key.password=changeit<nss db password>

Edit signature.properties and modify the following lines to reflect PKCS11 settings; note that some properties may need to be added, commented out, or blanked out from the default template:

Code Block
org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin
org.apache.ws.security.crypto.merlin.keystore.type=PKCS11
org.apache.ws.security.crypto.merlin.keystore.password=<nss db password>
org.apache.ws.security.crypto.merlin.keystore.provider=SunPKCS11-nss-fips
org.apache.ws.security.crypto.merlin.file=

Edit truststore.properties and modify the following lines to reflect PKCS11 settings; note that any properties here should match their counterparts in signature.properties:

Code Block
org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin
org.apache.ws.security.crypto.merlin.keystore.provider=SunPKCS11-nss-fips
org.apache.ws.security.crypto.merlin.keystore.type=PKCS11
org.apache.ws.security.crypto.merlin.keystore.password=<nss db password>
org.apache.ws.security.crypto.merlin.truststore.file=

Server Configuration

JAVA_OPTS updates in Standalone.conf

In the standalone configuration file ${JBOSS_HOME}/bin/standalone.conf, append the following:

Code Block
languagebash
titlestandalone.conf
# Increase memory allocation
JAVA_OPTS="-Xmx8000m -XX:MaxPermSize=1024m -XX:PermSize=1024m"
 
# configuration directory
JAVA_OPTS="$JAVA_OPTS -Dnhinc.properties.dir=${JBOSS_HOME}/modules/system/layers/base/org/connectopensource/configuration/main"
 
# Keystore and Truststore
JAVA_OPTS="$JAVA_OPTS -Djavax.net.ssl.keyStore=NONE"
JAVA_OPTS="$JAVA_OPTS -Djavax.net.ssl.trustStore=NONE"
JAVA_OPTS="$JAVA_OPTS -Djavax.net.ssl.keyStoreProvider=SunPKCS11-nss-fips"
JAVA_OPTS="$JAVA_OPTS -Djavax.net.ssl.trustStoreProvider=SunPKCS11-nss-fips"
JAVA_OPTS="$JAVA_OPTS -Djavax.net.ssl.keyStoreType=PKCS11"
JAVA_OPTS="$JAVA_OPTS -Djavax.net.ssl.trustStoreType=PKCS11"
JAVA_OPTS="$JAVA_OPTS -Djavax.net.ssl.keyStorePassword=<NSS DB PASSWORD>"
JAVA_OPTS="$JAVA_OPTS -Djavax.net.ssl.trustStorePassword=<NSS DB PASSWORD>"
JAVA_OPTS="$JAVA_OPTS -DCLIENT_KEY_ALIAS=gateway"
JAVA_OPTS="$JAVA_OPTS -DSERVER_KEY_ALIAS=gateway"
JAVA_OPTS="$JAVA_OPTS -Djdk.tls.useExtendedMasterSecret=false"

JAVA_OPTS updates in jboss-cli

Edit jboss-cli file in ${JBOSS_HOME}/bin/jboss-cli.sh, append the following:

Code Block
titlejboss-cli.sh
#JAVA_OPTS="$JAVA_OPTS -agentlib:jdwp=transport=dt_socket,address=8787,server=y,suspend=n"
JAVA_OPTS="$JAVA_OPTS -Djavax.net.ssl.keyStore=NONE"
JAVA_OPTS="$JAVA_OPTS -Djavax.net.ssl.trustStore=NONE"
JAVA_OPTS="$JAVA_OPTS -Djavax.net.ssl.keyStoreProvider=SunPKCS11-nss-fips"
JAVA_OPTS="$JAVA_OPTS -Djavax.net.ssl.trustStoreProvider=SunPKCS11-nss-fips"
JAVA_OPTS="$JAVA_OPTS -Djavax.net.ssl.keyStoreType=PKCS11"
JAVA_OPTS="$JAVA_OPTS -Djavax.net.ssl.trustStoreType=PKCS11"
JAVA_OPTS="$JAVA_OPTS -Djavax.net.ssl.keyStorePassword=<NSS DB PASSWORD>"
JAVA_OPTS="$JAVA_OPTS -Djavax.net.ssl.trustStorePassword=<NSS DB PASSWORD>"


Standalone.xml Updates

Note: The stanalone.xml configuration for FIPs mode include SNI configuration as well.

Key-Stores

Code Block
languagexml
titlekey-stores configuration in Elytron subsystem for FIPs mode
                <key-stores>
                    <key-store name="keyStore1">
                        <credential-reference clear-text="<NSS Password>"/>
                        <implementation type="PKCS11"/>
                    </key-store>
					..
                    <key-store name="keyStoreN">
                        <credential-reference clear-text="<NSS Password>"/>
                        <implementation type="PKCS11"/>
                    </key-store>
                </key-stores>

Key-Managers

Code Block
languagexml
titlekey-managers configuration in Elytron susbstem for FIPs mode
                <key-managers>
                    <key-manager name="keyManager1" key-store="keyStore1" alias-filter="gateway" algorithm="SunX509">
                        <credential-reference clear-text="<NSS Password>"/>
                    </key-manager>
                    ..
                    <key-manager name="keyManagerN" key-store="keyStoreN" alias-filter="carequality" algorithm="SunX509">
                        <credential-reference clear-text="<NSS Password>"/>
                    </key-manager>
                </key-managers>

Server-SSL-Contexts

Code Block
languagexml
titleserver-ssl-contexts configuration in Elytron subsystem for FIPs mode
<server-ssl-contexts>
  <server-ssl-context name="sslContext1" cipher-suite-filter="SSL_RSA_WITH_3DES_EDE_CBC_SHA,SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA,TLS_DHE_DSS_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_DSS_WITH_AES_256_CBC_SHA,TLS_DHE_RSA_WITH_AES_256_CBC_SHA, TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA,TLS_ECDH_anon_WITH_AES_128_CBC_SHA, TLS_ECDH_anon_WITH_AES_256_CBC_SHA" protocols="TLSv1 TLSv1.1" need-client-auth="true" key-manager="keyManager1"/>
..
  <server-ssl-context name="sslContextN" cipher-suite-filter="SSL_RSA_WITH_3DES_EDE_CBC_SHA,SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA,TLS_DHE_DSS_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_DSS_WITH_AES_256_CBC_SHA,TLS_DHE_RSA_WITH_AES_256_CBC_SHA, TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA,TLS_ECDH_anon_WITH_AES_128_CBC_SHA, TLS_ECDH_anon_WITH_AES_256_CBC_SHA" protocols="TLSv1 TLSv1.1" need-client-auth="true" key-manager="keyManagerN"/>
</server-ssl-contexts>


Server-SSL-SNI-Contexts

This is optional. If application does not require SNI setup, we can omit the <server-ssl-sni-contexts> element.

Code Block
languagexml
titleserver-ssl-sni-contexts configuration in Elytron subsystem for FIPs mode
<server-ssl-sni-contexts>
  <server-ssl-sni-context name="applicationSNI" default-ssl-context="sslContext1">
    <sni-mapping host="ssi1" ssl-context="sslContext1"/>
     ..
    <sni-mapping host="ssiN" ssl-context="sslContextN"/>
  </server-ssl-sni-context>
</server-ssl-sni-contexts>


Https-Listener

Code Block
languagexml
titleHttps-listener configuration for FIPs mode
<subsystem xmlns="urn:jboss:domain:undertow:8.0" default-server="default-server" default-virtual-host="default-host" default-servlet-container="default" default-security-domain="other">
            <buffer-cache name="default"/>
            <server name="default-server">
                <http-listener name="default" socket-binding="http" redirect-socket="https" enable-http2="false"/>
                <https-listener name="https" socket-binding="connect" ssl-context="<applicationSNI or appropriate ssl-context name>" enable-http2="false"/>
                <host name="default-host" alias="localhost">
                    <location name="/" handler="welcome-content"/>
                    <http-invoker security-realm="ApplicationRealm"/>
                </host>
            </server>
  ..
</subsystem>