EAP 6 takes long time to boot loading a CRL file

Solution Verified - Updated

Environment

  • JBoss Enterprise Application Platform (EAP)
    • 6.x
    • JSSE (non-native)

Issue

  • The server takes several minutes to boot after configuring the ca-revocation-url parameter
  • Very long startup using a big CRL file

Resolution

The ca-revocation-url final file should be encoded in DER format and not using PEM format, specially if the CRL is big.

The parameter ca-revocation-url can be configured in an HTTPS connector to specify a list of CRLs (Certificate Revocation List) that the server will use to validate the client certificates. It can be encoded in two formats:

  • DER = The DER format is a binary (ASN.1) format for different X.509v3 files.
  • PEM = The PEM format contains ASCII (Base64) armored data prefixed with a "----- BEGIN ..." line and suffixed by a "----- END ..." line. The base64 data contains the same DER CRL data.

So the PEM format is the same as DER but adding the complexity of decoding the base64.

Root Cause

The main problem is a poor implementation inside the JVM for parsing big PEM CRLs. See the following bug for more information:

Nevertheless the DER format is always more direct, therefore it generates a smaller file and it is parsed faster. So the DER format is always preferred over the PEM format (even if the BUG is fixed).

This issue affects the JSSE (java) connector implementation and not the native (openssl) one.

Diagnostic Steps

The EAP server takes long time to boot and the thread parsing the CRL file is stuck inside the generateCRLs method:

"MSC service thread 1-6" #18 prio=5 os_prio=0 tid=0x00000000251c6000 nid=0x16d4 runnable [0x00000000276be000]
   java.lang.Thread.State: RUNNABLE
	at java.io.FileInputStream.read0(Native Method)
	at java.io.FileInputStream.read(FileInputStream.java:207)
	at java.io.FilterInputStream.read(FilterInputStream.java:83)
	at java.io.PushbackInputStream.read(PushbackInputStream.java:139)
	at sun.security.provider.X509Factory.readOneBlock(X509Factory.java:610)
	at sun.security.provider.X509Factory.parseX509orPKCS7CRL(X509Factory.java:524)
	at sun.security.provider.X509Factory.engineGenerateCRLs(X509Factory.java:420)
	at java.security.cert.CertificateFactory.generateCRLs(CertificateFactory.java:535)
	at org.apache.tomcat.util.net.jsse.JSSESocketFactory.getCRLs(JSSESocketFactory.java:584)
	at org.apache.tomcat.util.net.jsse.JSSESocketFactory.getParameters(JSSESocketFactory.java:546)
	at org.apache.tomcat.util.net.jsse.JSSESocketFactory.getTrustManagers(JSSESocketFactory.java:519)
	at org.apache.tomcat.util.net.jsse.JSSESocketFactory.init(JSSESocketFactory.java:417)
	at org.apache.tomcat.util.net.jsse.JSSESocketFactory.createSocket(JSSESocketFactory.java:180)
	at org.apache.tomcat.util.net.JIoEndpoint.init(JIoEndpoint.java:973)
	at org.apache.coyote.http11.Http11Protocol.init(Http11Protocol.java:175)
	at org.apache.catalina.connector.Connector.init(Connector.java:986)
	- locked <0x00000004c1626638> (a java.lang.Class for org.apache.catalina.connector.Connector)
	at org.jboss.as.web.WebConnectorService.start(WebConnectorService.java:318)
	- locked <0x00000004c19c15a8> (a org.jboss.as.web.WebConnectorService)
	at org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1980)
	at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1913)
	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)
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.