Wildfly 8.2.1 with FIPS 140-2 Configuration

Version

Date

Modified By

Description of Modification

1.0

 

Minh-Hai Nguyen

Initial version

2.0

 

Daniel FernandezEdits from review
2.103/28/2017Minh-Hai NguyenUpdate content

Introduction

Motivation & Scope

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 on  Wildfly 8.2.1 (Red Hat Enterprise Linux Server release 6.2) using Mozilla Network Security Services (NSS) and JDK 1.7_71-b14. Other configurations are certainly possible but have not been tested.

Document Audience

This document is intended for system administrators experienced with Wildfly 8.2.1 and Red Hat Enterprise Linux Server release 6.2

Prerequisites

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

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

Keystore 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/

Module Setup - org.connectopensource.configuration

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:

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, uncommented, or blanked out from the default template:

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:

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

  •  In the standalone configuration file ${JBOSS_HOME}/bin/standalone.conf, append the following:
standalone.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"

  • 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


Edit to ${JBOSS_HOME}/standalone/configuration/standalone.xml and do the followings:

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" socket-binding="connect" security-realm="ApplicationRealm" enabled-protocols="TLSv1" verify-client="REQUIRED" 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" />

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>

Address Bindings

By default, wildfly services and applications are bound only to localhost.  As needed, change any references of 127.0.0.1 in standalone.xml to the desired binding address.  0.0.0.0 can be used to bind to all addresses.

Alternatively, you can start the server using the follow binding flags, replacing 0.0.0.0 with the desired binding:

Public binding: -b 0.0.0.0

Management binding: -bmanagement=0.0.0.0

Verify FIPS Installation:

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

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


    FIPS is not available
    18:07:03,719 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: Failed to start service
            at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1904) [jboss-msc-1.2.2.Final.jar:1.2.2.Final]
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [rt.jar:1.7.0_71]
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [rt.jar:1.7.0_71]
            at java.lang.Thread.run(Thread.java:745) [rt.jar:1.7.0_71]
    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) [rt.jar:1.7.0_71]
            at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57) [rt.jar:1.7.0_71]
            at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) [rt.jar:1.7.0_71]
            at java.lang.reflect.Constructor.newInstance(Constructor.java:526) [rt.jar:1.7.0_71]
            at sun.security.jca.ProviderConfig$2.run(ProviderConfig.java:224) [rt.jar:1.7.0_71]
            at sun.security.jca.ProviderConfig$2.run(ProviderConfig.java:206) [rt.jar:1.7.0_71]
            at java.security.AccessController.doPrivileged(Native Method) [rt.jar:1.7.0_71]
            at sun.security.jca.ProviderConfig.doLoadProvider(ProviderConfig.java:206) [rt.jar:1.7.0_71]
            at sun.security.jca.ProviderConfig.getProvider(ProviderConfig.java:187) [rt.jar:1.7.0_71]
            at sun.security.jca.ProviderList.getProvider(ProviderList.java:232) [rt.jar:1.7.0_71]
            at sun.security.jca.ProviderList.getService(ProviderList.java:330) [rt.jar:1.7.0_71]
            at sun.security.jca.GetInstance.getInstance(GetInstance.java:157) [rt.jar:1.7.0_71]
            at java.security.Security.getImpl(Security.java:695) [rt.jar:1.7.0_71]
    
  3. Enable FIPS mode: modutil -fips true -dbdir /nhin/nss/fips/db
  4. Try to start the server.
  5. Deploy CONNECT.
  6. Make sure to run the entire validation suite in FIPS mode

Deploy AdminGUI

Background: In JSF framework, there is a viewstate associated with each component which is passed back and forth for each requests.  The view state for components can be stored in memory on server and bind into the session or pass to client as hidden value. To ensure security, CONNECT Admingui stores view states on the server and override the default encryption algorithm.  It is recommend to change the default value when deploying into Production. Below are some entry that need to be replaced:

  1. Edit admingui.properties from ${JBOSS_HOME}/modules/system/layers/base/org/connectopensource/configuration/main
# For more information about what encryption/algorithm to use, please visit
# https://docs.oracle.com/javase/8/docs/technotes/guides/security/jsse/JSSERefGuide.html
# Define the secret (Base64 encoded) used to initialize the secret key for encryption algorithm

jsf.secret=MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIz

# Define the encryption algorithm used for encrypt the view state. Default is DES
jsf.algorithm=AES

# Defines the default mode and padding used for the encryption algorithm
jsf.algorithm.padding=CBC/PKCS5Padding

# Defines the initialization vector (Base64 encoded) used for the encryption algorithm
jsf.algorithm.iv=NzY1NDMyMTA3NjU0MzIxMA==

Replace with actual algorithms and values

The values in the snippet above were used for testing on a specific CONNECT instance


Troubleshooting

Below is sample error code relate to invalid NSS DB password: 

Invalid NSS DB Password
18:44:23,473 ERROR [org.jboss.msc.service.fail] (MSC service thread 1-4) 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: JBAS015229: Unable to start service
        at org.jboss.as.domain.management.security.ProviderKeyManagerService.start(ProviderKeyManagerService.java:69)
        at org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1948) [jboss-msc-1.2.2.Final.jar:1.2.2.Final]
        at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1881) [jboss-msc-1.2.2.Final.jar:1.2.2.Final]
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [rt.jar:1.7.0_71]
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [rt.jar:1.7.0_71]
        at java.lang.Thread.run(Thread.java:745) [rt.jar:1.7.0_71]
Caused by: java.io.IOException: load failed
        at sun.security.pkcs11.P11KeyStore.engineLoad(P11KeyStore.java:774)
        at java.security.KeyStore.load(KeyStore.java:1214) [rt.jar:1.7.0_71]
        at org.jboss.as.domain.management.security.ProviderKeyManagerService.start(ProviderKeyManagerService.java:59)
        ... 5 more
Caused by: javax.security.auth.login.FailedLoginException
        at sun.security.pkcs11.SunPKCS11.login(SunPKCS11.java:1181)
        at sun.security.pkcs11.P11KeyStore.login(P11KeyStore.java:874)
        at sun.security.pkcs11.P11KeyStore.engineLoad(P11KeyStore.java:764)
        ... 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:1169)
        ... 9 more

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

Links / Additional Reading

  1. CONNECT Forums
  2. Deploying to WildFly 8.2.1 (4.6) (atlassian.net)
  3. JBoss Issue Tracker (jboss.org)
  4. Mozilla National Security Services (NSS)
  5. Validating CONNECT Installation
  6. Apache MyFaces web configuration
  7. Oracle Java Secure Socket Extension (JSSE) Reference Guide



7u9 (b03)