Why does my SSL certificate not work with the Tomcat Native Library?

Solution Verified - Updated

Environment

  • Red Hat JBoss Enterprise Application Platform (EAP)
    • 4.x
    • 5.x
    • 6.x
  • Tomcat

Issue

  • SSL was working with existing certificate before the Tomcat Native library was installed.  However, now I have installed the Tomcat Native library and I am not able to get the APR connector to use my existing PKCS12 keystore.  I get the following exception:
ERROR [Http11AprProtocol] Error initializing endpoint java.lang.Exception: No Certificate file specified or invalid file format
                at org.apache.tomcat.jni.SSLContext.setCertificate(Native Method)
                at org.apache.tomcat.util.net.AprEndpoint.init(AprEndpoint.java:660)
                at org.apache.coyote.http11.Http11AprProtocol.init(Http11AprProtocol.java:106)
                at org.apache.catalina.connector.Connector.initialize(Connector.java:1029)
ERROR [org.apache.coyote.http11] (MSC service thread 1-4) [] [] [] JBWEB003043: Error initializing endpoint: java.lang.Exception: No Certificate file specified or invalid file format
  • Not able to use Native connectors, due to above SSL exception

Resolution

The APR/Native connector does not support PKCS12 keystores.  The openssl command line utility can be used convert PKCS12 keystore to PEM-encoded public/private key pair.

openssl pkcs12 -in jboss.cert.p12 -out priv_pub.pem -nodes

This will output a file (priv_pub.pem) that contains the both the private and public key pair.  The public key and private key will need to be copied into separate files.

The public key (certificate) is denoted by the following lines:

-----BEGIN CERTIFICATE-----
-----END CERTIFICATE-----

The private key is denoted by the following lines:

-----BEGIN PRIVATE KEY-----
-----END PRIVATE KEY-----

Then it will need to replace the following Connector attributes:

keystoreFile="/jboss51/keys/mykestore.p12"
keystorePass="123456" 
keystoreType="pkcs12"

with:

SSLCertificateFile="/opt/jboss51/keys/pub_key.pem"
SSLCertificateKeyFile="/opt/jboss51/keys/priv_key.pem"

Note: If the keystore is in JKS format (e.g. using keytool), it must first be converted to PKCS12 format via

keytool -importkeystore -srckeystore server.keystore -destkeystore jboss.cert.p12 -srcstoretype JKS -deststoretype PKCS12

Diagnostic Steps

EAP 5

To check if Tomcat native is being used, look for the following entry in the console or server log

INFO  [org.apache.catalina.core.AprLifecycleListener] (main) Loaded Apache Tomcat Native library 1.1.20.

EAP 6
To confirm that JBoss EAP 6 is using Apache Portable Runtime, in logging subsystem enable org.apache.catalina.core category to DEBUG as below:

<logger category="org.apache.catalina.core">
    <level name="DEBUG"/>
</logger>

Now restart your JBoss EAP 6 server and check the server.log for below entries.

DEBUG [org.apache.catalina.core.AprLifecycleListener] (MSC service thread 1-7) Loaded: apr-1
DEBUG [org.apache.catalina.core.AprLifecycleListener] (MSC service thread 1-7) Loaded: ssl
DEBUG [org.apache.catalina.core.AprLifecycleListener] (MSC service thread 1-7) Loaded: tcnative-1
DEBUG [org.apache.catalina.core.AprLifecycleListener] (MSC service thread 1-7) Loaded Apache Tomcat Native library 1.1.23.
Components
Category

This solution is part of Red Hat’s fast-track publication program, providing a huge library of solutions that Red Hat engineers have created while supporting our customers. To give you the knowledge you need the instant it becomes available, these articles may be presented in a raw and unedited form.