[Overview] In Tomcat 8.5 and Tomcat 9, if we turn on FIPS mode, there are KeyStoreException which cause tomcat service could not startup successfully. [Steps to Reproduce] 1. Follow the Oracle doc to enable FIPS mode https://docs.oracle.com/javase/8/docs/technotes/guides/security/jsse/FIPS.html The cryptographic provider 2. Edit Tomcat server.xml to enable SSL Note: Provider depends on what FIPS-complinat cryptographic provider you used. <Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol" maxThreads="150" SSLEnabled="true"> <SSLHostConfig> <Certificate certificateKeystoreFile="c:\test.bcfks" type="RSA" certificateKeystorePassword="changeit" certificateKeystoreType="BCFKS" certificateKeystoreProvider="CCJ"/> </SSLHostConfig> </Connector> 3. startup Tomcat [Actual Results] KeyStoreException occurs! The log is like the following shows: Sep 19, 2017 2:59:59 PM org.apache.coyote.AbstractProtocol init INFO: Initializing ProtocolHandler ["https-jsse-nio-4119"] Sep 19, 2017 3:00:00 PM org.apache.coyote.AbstractProtocol init SEVERE: Failed to initialize end point associated with ProtocolHandler ["https-jsse-nio-4119"] java.lang.IllegalArgumentException: java.security.KeyStoreException: FIPS mode: KeyStore must be from provider CCJ at org.apache.tomcat.util.net.AbstractJsseEndpoint.createSSLContext(AbstractJsseEndpoint.java:114) at org.apache.tomcat.util.net.AbstractJsseEndpoint.initialiseSsl(AbstractJsseEndpoint.java:85) at org.apache.tomcat.util.net.NioEndpoint.bind(NioEndpoint.java:225) at org.apache.tomcat.util.net.AbstractEndpoint.init(AbstractEndpoint.java:982) at org.apache.tomcat.util.net.AbstractJsseEndpoint.init(AbstractJsseEndpoint.java:244) at org.apache.coyote.AbstractProtocol.init(AbstractProtocol.java:620) at org.apache.coyote.http11.AbstractHttp11Protocol.init(AbstractHttp11Protocol.java:66) at org.apache.catalina.connector.Connector.initInternal(Connector.java:997) at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:107) at org.apache.catalina.core.StandardService.initInternal(StandardService.java:549) at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:107) at org.apache.catalina.core.StandardServer.initInternal(StandardServer.java:875) at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:107) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:140) at org.apache.catalina.startup.Tomcat.start(Tomcat.java:367) at com.thirdbrigade.manager.service.Tomcat.startTomcat(Tomcat.java:171) at com.thirdbrigade.manager.service.DSMService$WorkerThread.run(DSMService.java:247) Caused by: java.security.KeyStoreException: FIPS mode: KeyStore must be from provider CCJ at sun.security.ssl.KeyManagerFactoryImpl$SunX509.engineInit(KeyManagerFactoryImpl.java:67) at javax.net.ssl.KeyManagerFactory.init(KeyManagerFactory.java:256) at org.apache.tomcat.util.net.jsse.JSSEUtil.getKeyManagers(JSSEUtil.java:232) at org.apache.tomcat.util.net.AbstractJsseEndpoint.createSSLContext(AbstractJsseEndpoint.java:112) ... 16 more Sep 19, 2017 3:00:00 PM org.apache.catalina.core.StandardService initInternal SEVERE: Failed to initialize connector [Connector[HTTP/1.1-4119]] org.apache.catalina.LifecycleException: Failed to initialize component [Connector[HTTP/1.1-4119]] at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:112) at org.apache.catalina.core.StandardService.initInternal(StandardService.java:549) at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:107) at org.apache.catalina.core.StandardServer.initInternal(StandardServer.java:875) at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:107) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:140) at org.apache.catalina.startup.Tomcat.start(Tomcat.java:367) at com.thirdbrigade.manager.service.Tomcat.startTomcat(Tomcat.java:171) at com.thirdbrigade.manager.service.DSMService$WorkerThread.run(DSMService.java:247) Caused by: org.apache.catalina.LifecycleException: Protocol handler initialization failed at org.apache.catalina.connector.Connector.initInternal(Connector.java:999) at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:107) ... 8 more Caused by: java.lang.IllegalArgumentException: java.security.KeyStoreException: FIPS mode: KeyStore must be from provider CCJ at org.apache.tomcat.util.net.AbstractJsseEndpoint.createSSLContext(AbstractJsseEndpoint.java:114) at org.apache.tomcat.util.net.AbstractJsseEndpoint.initialiseSsl(AbstractJsseEndpoint.java:85) at org.apache.tomcat.util.net.NioEndpoint.bind(NioEndpoint.java:225) at org.apache.tomcat.util.net.AbstractEndpoint.init(AbstractEndpoint.java:982) at org.apache.tomcat.util.net.AbstractJsseEndpoint.init(AbstractJsseEndpoint.java:244) at org.apache.coyote.AbstractProtocol.init(AbstractProtocol.java:620) at org.apache.coyote.http11.AbstractHttp11Protocol.init(AbstractHttp11Protocol.java:66) at org.apache.catalina.connector.Connector.initInternal(Connector.java:997) ... 9 more Caused by: java.security.KeyStoreException: FIPS mode: KeyStore must be from provider CCJ at sun.security.ssl.KeyManagerFactoryImpl$SunX509.engineInit(KeyManagerFactoryImpl.java:67) at javax.net.ssl.KeyManagerFactory.init(KeyManagerFactory.java:256) at org.apache.tomcat.util.net.jsse.JSSEUtil.getKeyManagers(JSSEUtil.java:232) at org.apache.tomcat.util.net.AbstractJsseEndpoint.createSSLContext(AbstractJsseEndpoint.java:112) ... 16 more [Expected Results] Tomcat should be startup successfully. [Build] the latest 8.5.20 and 9.0.0.M26 have this issue. [Additional Information] In nightly build 8.5.21, there is related fix but it doesn't solve this issue. https://github.com/apache/tomcat/commit/5fca54ea7b653403b5b12ac1d830a8a5fa5484d7#diff-a067af9186cf2818d35dbaa0828e2960 It's caused by hard code "JKS" for the in-memory keystore in JSSEUtil.java ========================= if (k != null && "PKCS#8".equalsIgnoreCase(k.getFormat())) { // Switch to in-memory key store ksUsed = KeyStore.getInstance("JKS"); ksUsed.load(null, null); ksUsed.setKeyEntry(keyAlias, k, keyPassArray, ks.getCertificateChain(keyAlias)); } ===================== The keystoretype should use what user assign in connector setting. for example, in this example, it should be BCFKS.
This was not tested with trunk, and is likely already fixed in it.
Update the correct version which the issue happens.
Created attachment 35359 [details] Proposed patch for 9.0.x Does this patch fix the issue? It is for 9.0.x but should apply to 8.5.x as well.
(In reply to Mark Thomas from comment #3) > Created attachment 35359 [details] > Proposed patch for 9.0.x > > Does this patch fix the issue? It is for 9.0.x but should apply to 8.5.x as > well. I pull 8.5 source code in local and apply the same patch. And it solved the issue! The tomcat could startup successfully. [Log] Sep 22, 2017 10:13:57 AM org.apache.coyote.AbstractProtocol init INFO: Initializing ProtocolHandler ["https-jsse-nio-8443"] Sep 22, 2017 10:13:58 AM org.apache.tomcat.util.net.SSLUtilBase getEnabled WARNING: Some of the specified [protocols] are not supported by the SSL engine and have been skipped: [[SSLv2Hello]] Sep 22, 2017 10:13:58 AM org.apache.tomcat.util.net.NioSelectorPool getSharedSelector INFO: Using a shared selector for servlet write/read Sep 22, 2017 10:13:58 AM org.apache.coyote.AbstractProtocol init INFO: Initializing ProtocolHandler ["ajp-nio-8009"] Sep 22, 2017 10:13:58 AM org.apache.tomcat.util.net.NioSelectorPool getSharedSelector INFO: Using a shared selector for servlet write/read Sep 22, 2017 10:13:58 AM org.apache.catalina.startup.Catalina load INFO: Initialization processed in 3715 ms Sep 22, 2017 10:13:58 AM org.apache.catalina.core.StandardService startInternal INFO: Starting service [Catalina] Sep 22, 2017 10:13:58 AM org.apache.catalina.core.StandardEngine startInternal INFO: Starting Servlet Engine: Apache Tomcat/8.5.22-dev
Thanks for testing and confirming the fix. Fixed in - trunk for 9.0.0 onwards - 8.5.x for 8.5.22 onwards