Setting up and using FIPS
Federal Information Processing Standards (FIPS) provides standards for information processing for use within the Federal government.
Many government and financial organizations require their software to be FIPS 140-2 compliant, which follows the current standards and guidelines for cryptographic information processing.
In Universal Messaging, FIPS capabilities can be enabled through the use of Mozilla NSS. NSS is an open source security library that has received FIPS validation/certification for both its FIPS and cryptographic modes. Further information can be found at the Mozilla website.
Note:
Universal Messaging itself is not FIPS 140 certified.
The NSS library is not bundled in the Universal Messaging product. Details of how to download and build your own copy of NSS for your respective platform can be found at the Mozilla website.
Once you have built the library, the JVM will need to know where to load this library from via environment variable (for example, LD_LIBRARY_PATH, or equivalent). Only the Oracle® JVM is supported at this time.
To enable FIPS in Universal Messaging, the property enableFIPS must be set on either the client and/or server before either one is started. For example:
-DenableFIPS=<NSS mode>
where <NSS mode> can be one of the following:
nssfips nsscrypto The biggest difference between these modes is that nssfips uses an NSS database for all key management purposes, while nsscrypto uses just the cryptographic algorithms and functions of NSS, while maintaining native JKS support. And, at the time of this writing, nssfips does not yet support TLS 1.2.
Storing certificates into an NSS database requires you to use certain NSS tools; documenting these tools is beyond the scope of this document (see the Mozilla website for details). However, an example shell script is provided below to get you started:
#!/bin/csh
setenv DYLD_LIBRARY_PATH /Users/test/Downloads/nss-3.20/dist/Darwin13.4.0_64_OPT.OBJ/lib
setenv PATH /Users/test/test/nss-3.20/dist/Darwin13.4.0_64_OPT.OBJ/bin:$PATH
echo Make nssdb directory
mkdir ~/nssdb
modutil -create -dbdir ~/nssdb
echo Enable FIPS mode on nssdb
modutil -fips true -dbdir ~/nssdb
# Password12345!
echo Set password for nssdb
modutil -changepw "NSS FIPS 140-2 Certificate DB" -dbdir ~/nssdb
# DER format/PKCS#7
echo Export alias from CA JKS to CRT
# Export only public keys
keytool -export -alias "localhost,127.0.0.1" -keystore ./nirvanacacerts.jks \
-file public.crt
echo Import CRT into nssdb
certutil -A -d ~/nssdb -t "TCu,,TCu" -n "Test CA 1" -i ./public.crt
echo Convert client JKS to PKCS12
keytool -importkeystore -srckeystore ./client.jks -destkeystore ./client.p12 \
-deststoretype PKCS12
echo Convert server JKS to PKCS12
keytool -importkeystore -srckeystore ./server.jks -destkeystore ./server.p12 \
-deststoretype PKCS12
echo Import client PKCS12 into nssdb
pk12util -i ./client.p12 -n client -d ~/nssdb
echo Import server PKCS12 into nssdb
pk12util -i ./server.p12 -n CA -d ~/nssdb
The above example assumes self signed certificates. Certificate aliases are NOT supported when NSS is run in FIPS mode, so only 1 certificate/trusted certificate pair should be imported into an NSS database. It is recommended that you create both a client and server NSS database to separate certificates from one another. Each NSS instance/library has a single NSS database available for key management (i.e., the relationship is 1:1).
Both modes use the Oracle JVM support for NSS; specifically, this means using the Oracle PKCS11 provider to access functionality within the NSS library. Again, no other JVM is currently supported. Only 1 NSS instance/library can be loaded per JVM via the PKCS11 provider. Universal Messaging automatically manages the loading of the PKCS11 provider and NSS library for you, so you do not have to do this yourself (assuming that the LD_LIBRARY_PATH is set properly for the NSS library).
NSS uses separate configuration files to determine the mode that it should run in (among other things). For example, to run NSS in FIPS mode, create the following configuration file as a text file:
name = <unique name>
nssLibraryDirectory = <path to location of NSS library>
nssSecmodDirectory = <path to location of NSS database>
nssModule = fips
Example:
name = CNSS
nssLibraryDirectory = /Users/test/Downloads/nss-3.20/dist/Darwin13.4.0_64_OPT.OBJ/lib
nssSecmodDirectory = /Users/test/nssdb
nssModule = fips
The key "name" is important, as it signifies the NSS name which uniquely identifies the NSS instance. The rest should be self explanatory. If you set up an NSS configuration file for FIPS mode, then -DenableFIPS should be set to nssfips.
To run NSS in crypto mode, create a configuration file as follows:
name = <unique name>
nssLibraryDirectory = <path to location of NSS library>
nssModule = crypto
attributes = compatibility
nssDbMode = noDb
Example:
name = CNSS
nssLibraryDirectory = /Users/test/Downloads/nss-3.20/dist/Darwin13.4.0_64_OPT.OBJ/lib
nssModule = crypto
attributes = compatibility
nssDbMode = noDb
If you set up an NSS configuration file for crypto mode, then -DenableFIPS should be set to nsscrypto.
Note that NSS configuration files can only have 1 set of configuration parameters in them; in other words, you cannot have multiple configurations within a single file.
Once the configuration file and name have been set up, you'll need to specify them either via the Universal Messaging APIs, or via the Enterprise Manager (if configuring a Universal Messaging server NHPS or NSPS interface). For the Universal Messaging APIs, see the appropriate Java documentation for:
com.pcbsys.nirvana.client.nSessionAttributes.getPKCS11NSSConfigFile
com.pcbsys.nirvana.client.nSessionAttributes.setPKCS11NSSConfigFile
com.pcbsys.nirvana.client.nSessionAttributes.getPKCS11NSSName
com.pcbsys.nirvana.client.nSessionAttributes.setPKCS11NSSName
com.pcbsys.nirvana.nAdminAPI.nSSLInterface.getPKCS11NSSConfigFile
com.pcbsys.nirvana.nAdminAPI.nSSLInterface.setPKCS11NSSConfigFile
com.pcbsys.nirvana.nAdminAPI.nSSLInterface.getPKCS11NSSName
com.pcbsys.nirvana.nAdminAPI.nSSLInterface.setPKCS11NSSName
com.pcbsys.nirvana.nAdminAPI.nHTTPSInterface.getPKCS11NSSConfigFile
com.pcbsys.nirvana.nAdminAPI.nHTTPSInterface.setPKCS11NSSConfigFile
com.pcbsys.nirvana.nAdminAPI.nHTTPSInterface.getPKCS11NSSName
com.pcbsys.nirvana.nAdminAPI.nHTTPSInterface.setPKCS11NSSName
com.pcbsys.foundation.drivers.configuration.fSSLConfig
com.pcbsys.foundation.drivers.configuration.fHTTPSConfig
While running NSS in FIPS mode, the password to the NSS database must be specified via nSessionAttributes.setKeystore (keystore/alias would be set to null or is unused), or via nSSLInterface/nHTTPSInterface.setKeyStorePassword. While running NSS in crypto mode, use the APIs as you normally would for JKS keystores/truststores. Set the PKCS11 NSS configuration file and name using the appropriate nSessionAttributes/nSSLInterface/nHTTPSInterface.setPKCS11NSS* methods.
For configuring an SSL/HTTPS interface in the Enterprise Manager, specify a key store password, PKCS11 NSS configuration file and name for NSS FIPS mode; all other fields can be left blank. Any combination of SSL and/or HTTPS interfaces configured while in NSS FIPS mode will share the same NSS database (since only 1 NSS instance/database is available per JVM). For NSS crypto, configure the interfaces as you normally would for JKS keystores/truststores.
To recap, refer to the following NSS checklist when enabling FIPS for UM:
1. Shut down any Universal Messaging servers and/or clients that you want to configure for FIPS.
2. Download the Mozilla NSS open source library, and build it for your respective platform (see the Mozilla website for details).
3. Determine whether you want to run in NSS FIPS or crypto mode.
4. If you'll be running in FIPS mode, create an NSS FIPS configuration file. If you'll be running in crypto mode, create an NSS crypto configuration file.
5. If you'll be running in FIPS mode, create an NSS database, and store the appropriate certificates in it (both client and server). If you'll be running in crypto mode, create/use normal JKS keystores/truststores.
6. Set up LD_LIBRARY_PATH (or equivalent, depending on your platform) to point to the location of the NSS binary distribution. This can be done in either a shell, command line, shell/batch script or configuration file.
7. Write any API programs that are FIPS enabled (if applicable).
8. For client and/or server, set -DenableFIPS=nssfips in a command line, shell/batch script or configuration file if you'll be running in FIPS mode. Set -DenableFIPS=nsscrypto if you'll be running in crypto mode (again, for client and/or server).
9. Restart the Universal Messaging server(s), and configure SSL/HTTPS interfaces with FIPS as needed. Restart the Universal Messaging client(s).