EAP 6 takes long time to boot loading a CRL file
Environment
- JBoss Enterprise Application Platform (EAP)
- 6.x
- JSSE (non-native)
Issue
- The server takes several minutes to boot after configuring the
ca-revocation-urlparameter - 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)
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.