EDB Tutorial: How to Configure for SSL with EDB JDBC on FIPS Enabled Server

June 23, 2023
Postgres Tutorial

If you're running into issues working with your java based applications with SSL enabled EPAS with respect to FIPS mode enabled, this blog post can help! Simply follow the instructions in this post and copy paste the provided commands in your environment to run your java applications to work with SSL enabled EPAS easily. 

This is the continuation of EDB SSL configuration on FIPS disabled servers. We would use the same server certificate and keys generated in the previous blog. However, separate client certificates will be generated by first creating the key pair.

Read on to get started. 

What is FIPS?

FIPS (Federal Information Processing Standards) are a set of standards that describe document processing, encryption algorithms and other information technology standards. FIPS 140-2 is a standard which handles cryptographic modules and the ones that organizations use to encrypt data-at-rest and data-in-motion.

It has 4 levels of security, with level-1 being the least secure, and level-4 being the most secure. One of the many reasons to become FIPS compliant is due to the government’s requirement that any organization working with them must be FIPS 140-2 compliant. This requirement ensures government data handled by third-party organizations is stored and encrypted securely and with the proper levels of confidentiality, integrity, and authenticity. Many organizations have developed the policy of becoming FIPS 140-2 compliant, as it makes their organization and services seem more secure and trusted.

EPAS is certified to be in full compliance with FIPS 140-2 standard.

Test Environment

  • Red hat Linux version 8
  • EPAS-14

We will use the red hat flavor of linux to configure EDB JDBC for SSL.

To Enable FIPS on red hat linux. execute below command.

# fips-mode-setup --enable

Restart the system to allow the kernel to switch to FIPS mode.

# reboot

Verify after the system is rebooted by executing below command.

# fips-mode-setup --check
FIPS mode is enabled.

Configuring OpenJDK in FIPS mode

OpenJDK installed on red hat linux checks if the system is configured in FIPS mode at startup.The OpenJDK security policy is controlled by the global java security policy file, found at $JRE_HOME/lib/security/java.security. That file contains several parameters that define the list of Java Cryptography Architecture/Java Cryptography Extension (JCA/JCE) providers, configure random number generation, enable user-level overrides of the global policy, etc. When FIPS mode is enabled, OpenJDK replaces the installed security providers list with the following ones:

  • SunPKCS11-NSS-FIPS
    • Initialized with a Network Security Services (NSS) Software Token (PKCS#11 backend). The NSS Software Token is configured as follows:
      • name = NSS-FIPS
      • nssLibraryDirectory = /usr/lib64
      • nssSecmodDirectory = /etc/pki/nssdb
      • nssDbMode = readOnly
      • nssModule = fips
        *The NSS library implementing the Software Token is FIPS compliant and FIPS-policy aware in RHEL 8.
  • SUN
    • For X.509 certificates support only. Make sure that your application is not using other cryptographic algorithms from this provider. For example, a MessageDigest.getInstance("SHA-256", Security.getProvider("SUN")) call would work but lead to a non-FIPS compliant MessageDigest service.
  • SunEC
    • For SunPKCS11 auxiliary helpers only. Make sure that your application is not explicitly using this provider.
  • SunJSSE
    • Initialized with the SunPKCS11-NSS-FIPS provider for all cryptographic primitives required by the TLS engine, including key derivation.

 Custom Stores

Java applications using edb jdbc on a fips enabled server have to use com.edb.ssl.DefaultJavaSSLFactory as com.edb.ssl.LibPQFactory is not supported by Sun JSSE(Java Secure Socket Extension) key managers. In case LibPQFactory is used following error is encountered when trying to connect with SSL enabled EPAS-14.

java.security.KeyManagementException: FIPS mode: only SunJSSE KeyManagers may be used

To overcome this error, com.edb.ssl.DefaultJavaSSLFactory is used as an ssl factory in EDB jdbc connection string. 

As discussed in the previous blog, server and client certificates need to be imported in the trust store and key store when using DefaultJavaSSLFactory. However, in the case of FIPS enabled servers there is a difference while creating and importing certificates in these stores. 

Both of these stores(Trust and Key) needs to be of PKCS#12 type as that is the only type which can be imported into the NSS database.

Create below directory to hold files generated as result of executing commands in this blog.

mkdir /home/enterprisedb/
cd /home/enterprisedb/

Trust Store

Execute below command to create a trust store and import the server certificate into it.

keytool -keystore mystore.p12 -alias postgres -import -file /var/lib/edb/as14/data/server.crt.der -storeType pkcs12 -storepass changeit -J-Dcom.redhat.fips=false

Please note the usage of -J-Dcom.redhat.fips=false. keytool utility has issues in FIPS mode, therefore to let this utility complete its work this option disables the FIPS alignment while still applying global crypto-policies. The generated file mystore.p12 contains a trusted CA certificate. We would use this java option in subsequent usage of keytool while creating the key store as well.

Key Store

Execute below command to generate key pairs to use in the subsequent process.

keytool -genkeypair -dname "cn=enterprisedb,ou=DEV,o=EDB,L=Islamabad,st=Federal,c=PK" -alias client -keyalg rsa -keypass changeit -keystore clientkeystore.p12 -storepass changeit -storeType pkcs12 -keysize 2048 -J-Dcom.redhat.fips=false

Execute below command to create a key store with key pair and generate the certificate signing request(CSR).

keytool -keystore clientkeystore.p12 -certreq -alias client -keyalg rsa -file client.csr -storepass changeit -J-Dcom.redhat.fips=false

Execute below command to sign the CSR.

openssl x509 -req -in client.csr -CA root.crt -CAkey /var/lib/edb/as14/data/server.key -out  client.crt -CAcreateserial

Execute below command to import the CA’s certificate into the Key store for chaining with the client certificate.

keytool -import -keystore clientkeystore.p12 -file root.crt -alias theCARoot -storepass changeit -J-Dcom.redhat.fips=false

Execute below command to import the client certificate signed by CA in the previous step using openssl.

keytool -import -keystore clientkeystore.p12 -file client.crt -alias client -storepass changeit -J-Dcom.redhat.fips=false

The generated file clientkeystore.p12 contains the client private key and associated certificate chain used for client authentication and signing.

Keys and Certificates in FIPS Mode

When in FIPS mode, OpenJDK uses the NSS DB as a read-only PKCS#11 store for keys. As a result, the keystore.type security property is internally set to PKCS11. The NSS DB repository is located at /etc/pki/nssdb. NSS DB keys are managed by RHEL tooling known as modutil.

File-based key stores such as JKS and PKCS#12 are not yet supported in FIPS mode. Since we have generated key store and trust store of PKCS#12 types therefore we have to import it into the NSS database before they could be used with the EDB JDBC application as JVM options.

To do that, execute the below command to install NSS tools.

dnf -y install nss-tools

Execute below commands to import both stores into the NSS database.

pk12util -i mystore.p12 -W changeit -d /etc/pki/nssdb
pk12util -i clientkeystore.p12 -W changeit -d /etc/pki/nssdb

Execute below command to mark trusted certificate as trusted CA by setting -t or trustargs attribute to CT.

certutil -L -d /etc/pki/nssdb | grep ",," | sed 's/ ,,.*//' | sed 's/ *$//' | while read line; do certutil -M -n "$line" -t "CT,CT,CT" -d /etc/pki/nssdb; done

Execute below command to confirm that key stores are imported successfully.

[root@ip-172-31-7-134 enterprisedb]# certutil -L -d /etc/pki/nssdb		


Certificate Nickname       			Trust Attributes
							SSL,S/MIME,JAR/XPI
postgres                                  CT,C,C                   
client                                    u,u,u       

The flag “u” in above output means that there is a private key associated with the certificate.

JDBC Example

import java.io.File;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.sql.*;
import java.util.Properties;
public class JdbcTest
{
  public static void main(String[] args) throws Exception
  {
System.out.println("Setting up SSL Connection: ");
        Class.forName("com.edb.Driver");
        Properties props = new Properties();
        props.setProperty("user","enterprisedb");
        props.setProperty("ssl","true");
        props.setProperty("sslmode","verify-ca");      
           props.setProperty("sslfactory","com.edb.ssl.DefaultJavaSSLFactory");    
       Connection con = DriverManager.getConnection("jdbc:edb://localhost:5444/postgres", props);
       System.out.println("Connection opened:");
       System.out.println(con.isClosed());
        try {
                con.close();
                System.out.println("Connection closed:");
                System.out.println(con.isClosed());
            }catch(Exception ex) {
              ex.printStackTrace();
       }
    }
  }

Running the Example

JDBC example can be run from the terminal as below.

-bash-4.2$ $JAVA_HOME/bin/javac JdbcTest.java
-bash-4.2$ $JAVA_HOME/bin/java -cp .:edb-jdbc-18.jar 	-Djavax.net.ssl.trustStore=NONE -Djavax.net.ssl.trustStoreType=PKCS11 JdbcTest

NOTE: Please install edb-jdbc driver as described here. Also note the usage of below JVM options:

-Djavax.net.ssl.trustStore=NONE -Djavax.net.ssl.trustStoreType=PKCS11

Stay tuned for an upcoming blog discussing the troubleshooting of common SSL related errors.

Share this

More Blogs