JBoss EAP 7 with FIPS 140-2 Configuration

Version History

Version

Date

Modified By

Description of Modification

1.012/19/2016Minh-Hai NguyenInitial
2.011/28/2018Minh-Hai NguyenUpdate to use standalone.xml and troubleshooting steps
2.101/07/2019Minh-Hai NguyenAdd JVM arguments

Introduction

Motivation & Scope

The typical CONNECT installation uses Java keystores, but implementers may wish to use PKCS11 stores for FIPS 140-2 compliance.  The instructions cover an example setup and deployment of CONNECT to JBoss EAP 7.0.0.GA on RedHat Enterprise Server Release 6.2 (Santiago), using Mozilla Network Security Services (NSS).

Document Audience

This document is intended for system administrators experienced with JBoss EAP 7.0.0.GA and RedHat Enterprise Server Release 6.2 (Santiago)

Prerequisites

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

NSS Configuration

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 Jboss user.  Under the config folder, create a file called pkcs11.cfg with the following content

/nhin/nss/fips/config
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

Convert JKS into p12:

  • Navigate to {JBOSS_HOME}/modules/system/layers/base/org/connectopensource/configuration/main/
  • To convert gateway.jks to PKCS12 format, execute the following: 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

Modify Java.securityby 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.

Java Policy:

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/

Module Setup - org.connectopensource.configuration

Navigate to folder ${JBOSS_HOME}/modules/system/layers/base/org/connectopensource/configuration/main.

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

org.apache.ws.security.saml.issuer.key.name=gateway
org.apache.ws.security.saml.issuer.key.password=changeit

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

org.apache.ws.security.crypto.merlin.keystore.type=PKCS11
org.apache.ws.security.crypto.merlin.keystore.provider=SunPKCS11-nss-fips
org.apache.ws.security.crypto.merlin.keystore.password=changeit
org.apache.ws.security.crypto.merlin.keystore.alias=gateway
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:

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.provider=SunPKCS11-nss-fips
org.apache.ws.security.crypto.merlin.keystore.password=changeit
org.apache.ws.security.crypto.merlin.truststore.file=

Server Configuration: JAVA_OPTS

  •  In the standalone configuration file ${JBOSS_HOME}/bin/standalone.conf, append the following:
standalone.conf
# Use standalone-full.xml instead of standalone.xml
JAVA_OPTS="$JAVA_OPTS  -Djboss.server.default.config=standalone-full.xml"
 
# Increase memory allocation
JAVA_OPTS="$JAVA_OPTS -Xmx8000m"
 
# 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 -Djdk.tls.useExtendedMasterSecret=false"
  • Edit jboss-cli file in ${JBOSS_HOME}/bin/jboss-cli.sh, append the following:

    jboss-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"

Configure SSL

Open ${JBOSS_HOME}/standalone/configuration/standalone-full.xml and do the following:

1. Replace https-listener under subsystem/undertow:

<https-listener name="https" socket-binding="connect" security-realm="ApplicationRealm" verify-client="REQUIRED"/>

with this:


<https-listener name="https" enabled-protocols="TLSv1.1" enabled-cipher-suites="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" verify-client="REQUIRED" security-realm="ApplicationRealm" socket-binding="connect"/>


2. Replace security realm under management/security-realms:


Old Security for Application Realm
<security-realm name="ApplicationRealm">
    <server-identities>
        <ssl>
            <keystore path="modules/system/layers/base/org/connectopensource/configuration/main/gateway.jks" relative-to="jboss.home.dir" keystore-password="changeit" alias="gateway"/>
        </ssl>
    </server-identities>
    <authentication>
        <truststore path="modules/system/layers/base/org/connectopensource/configuration/main/cacerts.jks" relative-to="jboss.home.dir" keystore-password="changeit"/>
        <local default-user="$local" allowed-users="*" skip-group-loading="true"/>
        <properties path="application-users.properties" relative-to="jboss.server.config.dir"/>
    </authentication>
    <authorization>
        <properties path="application-roles.properties" relative-to="jboss.server.config.dir"/>
    </authorization>
</security-realm>

with this:


New Security For Application Realm
<security-realm name="ApplicationRealm">
<server-identities>
<ssl>
<keystore provider="PKCS11" keystore-password="<nss_db_password>" alias="gateway"/>
</ssl>
</server-identities>
<authentication>
<local default-user="$local" allowed-users="*" skip-group-loading="true"/>
<properties path="application-users.properties" relative-to="jboss.server.config.dir"/>
</authentication>
<authorization>
<properties path="application-roles.properties" relative-to="jboss.server.config.dir"/>
</authorization>
</security-realm>

Verify FIPS Installation:

The following steps verify that CONNECT has been set up to run in FIPS mode.  Before beginning, make sure the application server is not running:

  1. Disable FIPS mode: modutil -fips false -dbdir /nhin/nss/fips/db
  2. Restart the Jboss server.  During startup, you should be given this error message and the server should not start:

    FIPS is not available
    10:48:22,845 INFO [org.jboss.modules] (main) JBoss Modules version 1.5.1.Final-redhat-1
    10:48:23,069 INFO [org.jboss.msc] (main) JBoss MSC version 1.2.6.Final-redhat-1
    10:48:23,176 INFO [org.jboss.as] (MSC service thread 1-2) WFLYSRV0049: JBoss EAP 7.0.0.GA (WildFly Core 2.1.2.Final-redhat-1) starting
    10:48:23,287 ERROR [org.jboss.msc.service.fail] (MSC service thread 1-2) MSC000001: Failed to start service jboss.as: org.jboss.msc.service.StartException in service jboss.as: Failed to start service
    at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1904)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
    Caused by: java.security.ProviderException: NSS module not available: fips
    at sun.security.pkcs11.SunPKCS11.<init>(SunPKCS11.java:272)
    at sun.security.pkcs11.SunPKCS11.<init>(SunPKCS11.java:103)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
    at sun.security.jca.ProviderConfig$2.run(ProviderConfig.java:224)
    at sun.security.jca.ProviderConfig$2.run(ProviderConfig.java:206)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.security.jca.ProviderConfig.doLoadProvider(ProviderConfig.java:206)
    at sun.security.jca.ProviderConfig.getProvider(ProviderConfig.java:187)
    at sun.security.jca.ProviderList.getProvider(ProviderList.java:233)
  3. Enable FIPS mode: modutil -fips true -dbdir /nhin/nss/fips/db
  4. Try to start the server again. It should start this time.
  5. Deploy CONNECT and make sure the validation suite can be executed successfully.

Troubleshooting

Below is an error we encountered that was related to invalid NSS DB password: 

Invalid NSS DB Password
10:53:33,300 ERROR [org.jboss.msc.service.fail] (MSC service thread 1-1) MSC000001: Failed to start service jboss.server.controller.management.security_realm.ApplicationRealm.key-manager: org.jboss.msc.service.StartException in service jboss.server.controller.management.security_realm.ApplicationRealm.key-manager: WFLYDM0018: Unable to start service
at org.jboss.as.domain.management.security.ProviderKeyManagerService.start(ProviderKeyManagerService.java:68)
at org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1948)
at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1881)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.io.IOException: load failed
at sun.security.pkcs11.P11KeyStore.engineLoad(P11KeyStore.java:763)
at java.security.KeyStore.load(KeyStore.java:1445)
at org.jboss.as.domain.management.security.ProviderKeyManagerService.start(ProviderKeyManagerService.java:58)
... 5 more
Caused by: javax.security.auth.login.FailedLoginException
at sun.security.pkcs11.SunPKCS11.login(SunPKCS11.java:1234)
at sun.security.pkcs11.P11KeyStore.login(P11KeyStore.java:849)
at sun.security.pkcs11.P11KeyStore.engineLoad(P11KeyStore.java:753)
... 7 more
Caused by: sun.security.pkcs11.wrapper.PKCS11Exception: CKR_PIN_INCORRECT
at sun.security.pkcs11.wrapper.PKCS11.C_Login(Native Method)
at sun.security.pkcs11.SunPKCS11.login(SunPKCS11.java:1222)
... 9 more

Solution: Please enter correct password in ${JBOSS_HOME}/standalone/configuration/standalone-full.xml under <ssl> section.

Issue: java.security.InvalidAlgorithmParameterException: Key format must be RAW

Solution: Try either of one of those approaches:

  1. Add the following line to $JBOSS_HOME/bin/standalone.conf
    • JAVA_OPTS="$JAVA_OPTS -Djdk.tls.useExtendedMasterSecret=false"


Future Document Enhancements

  1. Update the JBoss 7 EAP instructions to be more modular / generic, and follow a better format / layout, to make referencing that document cleaner.
  2. Update the troubleshooting section to document solutions to common errors, misconfigurations, etc.
  3. Test configuring datasource driver by copying the connector jar into the <jboss_root>/standalone/deployments directory to auto-deploy the MySQL JDBC driver, OR, using jboss cli deploy command.

Links / Additional Reading

  1. CONNECT Forums 
  2. Deploying to JBoss EAP7 
  3. JBoss Issue Tracker (jboss.org)
  4. Mozilla NSS