When configured with FIPS with NSS The connector gives the following exception: 20-Jul-2020 09:11:03.863 SEVERE [main] org.apache.catalina.util.LifecycleBase.handleSubClassException Failed to initialize component [Connector[HTTP/1.1-8443]] org.apache.catalina.LifecycleException: Protocol handler initialization failed at org.apache.catalina.connector.Connector.initInternal(Connector.java:1042) at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:136) at org.apache.catalina.core.StandardService.initInternal(StandardService.java:533) at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:136) at org.apache.catalina.core.StandardServer.initInternal(StandardServer.java:1057) at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:136) at org.apache.catalina.startup.Catalina.load(Catalina.java:690) at org.apache.catalina.startup.Catalina.load(Catalina.java:712) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.apache.catalina.startup.Bootstrap.load(Bootstrap.java:302) at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:472) Caused by: java.lang.IllegalArgumentException: FIPS mode: only SunJSSE KeyManagers may be used at org.apache.tomcat.util.net.AbstractJsseEndpoint.createSSLContext(AbstractJsseEndpoint.java:99) at org.apache.tomcat.util.net.AbstractJsseEndpoint.initialiseSsl(AbstractJsseEndpoint.java:71) at org.apache.tomcat.util.net.NioEndpoint.bind(NioEndpoint.java:216) at org.apache.tomcat.util.net.AbstractEndpoint.bindWithCleanup(AbstractEndpoint.java:1141) at org.apache.tomcat.util.net.AbstractEndpoint.init(AbstractEndpoint.java:1154) at org.apache.coyote.AbstractProtocol.init(AbstractProtocol.java:581) at org.apache.coyote.http11.AbstractHttp11Protocol.init(AbstractHttp11Protocol.java:74) at org.apache.catalina.connector.Connector.initInternal(Connector.java:1039) ... 13 more Caused by: java.security.KeyManagementException: FIPS mode: only SunJSSE KeyManagers may be used at sun.security.ssl.SSLContextImpl.chooseKeyManager(SSLContextImpl.java:154) at sun.security.ssl.SSLContextImpl.engineInit(SSLContextImpl.java:71) at javax.net.ssl.SSLContext.init(SSLContext.java:282) at org.apache.tomcat.util.net.jsse.JSSESSLContext.init(JSSESSLContext.java:61) at org.apache.tomcat.util.net.SSLUtilBase.createSSLContext(SSLUtilBase.java:246) at org.apache.tomcat.util.net.AbstractJsseEndpoint.createSSLContext(AbstractJsseEndpoint.java:97) ... 20 more
To configure I did the following: modutil -create -dbdir /home/jfclere/db touch /home/jfclere/db/secmod.db (for what?). modutil -fips true -dbdir /home/jfclere/db modutil -list -dbdir /home/jfclere/db (looks OK) modutil -changepw "NSS FIPS 140-2 Certificate DB" -dbdir /home/jfclere/db (-list to get the tokens) modutil -changepw "NSS Certificate DB" -dbdir /home/jfclere/db (when no fips!). certutil -S -k rsa -n jbossweb -t "u,u,u" -x -s "CN=localhost, OU=MYOU, O=MYORG, L=MYCITY, ST=MYSTATE, C=MY" -d /home/jfclere/db Add the providers in jre/lib/security/java.security security.provider.4=com.sun.net.ssl.internal.ssl.Provider SunPKCS11-NSSfips security.provider.10=sun.security.pkcs11.SunPKCS11 /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.252.b09-1.fc32.x86_64/jre/lib/security/nss.cfg I have in jre/lib/security/nss.cfg: +++ name = NSSfips nssLibraryDirectory = /usr/lib64 nssSecmodDirectory = /home/jfclere/db nssDbMode = readWrite nssModule = fips attributes = compatibility handleStartupErrors = ignoreMultipleInitialisation +++ I have in server.xml +++ <Connector port="8443" protocol="HTTP/1.1" maxThreads="150" SSLEnabled="true" > <UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" /> <SSLHostConfig> <Certificate certificateKeystorePassword="Adelina2020!" certificateKeystoreType="PKCS11" certificateKeystoreProvider="SunPKCS11-NSSfips" /> </SSLHostConfig> </Connector> +++
Created attachment 37364 [details] Possible patch for the issue. Patch that fixes the issue.
Doesn't the patch defeat the point of using Tomcat's JSSEKeyManager thereby breaking the use cases that required it in the first place?
Yes, it would prevent using a key alias, which was the only reason for the wrapper. So I get FIPS mode prevents creative key manager uses then ? Idea: maybe don't use a wrapper if there's no key alias set ? This is still pretty bad overall since some configurations becomes broken :(
I need to investigate a little I will come with a better patch later this week.
<Connector port="8443" protocol="HTTP/1.1" maxThreads="150" SSLEnabled="true" sslImplementationName="org.apache.tomcat.util.net.jsse.JSSEImplementation" > <UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" /> <SSLHostConfig ciphers="SSL_RSA_WITH_3DES_EDE_CBC_SHA,SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA,TLS_RSA_WITH_AES_128_CBC_SHA,TLS_DHE_DSS_WITH_AES_128_CBC_SHA,TLS_DHE_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA,TLS_DHE_DSS_WITH_AES_256_CBC_SHA,TLS_DHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA,TLS_ECDH_anon_WITH_AES_128_CBC_SHA,TLS_ECDH_anon_WITH_AES_256_CBC_SHA"> <Certificate certificateKeystorePassword="Adelina2020!" certificateKeystoreType="PKCS11" certificateKeystoreProvider="SunPKCS11-NSSfips" /> </SSLHostConfig> </Connector> Note the ciphers list is needed for FIPS.
Created attachment 37367 [details] improved? patch. Check for FIPS to prevent regressions...
Seems like an awful hack. Perhaps instead we should have a configuration attribute like dontWrapKeyManager="true|false" and them simply do not wrap in the first place. Or is the wrapping required for other things?
(In reply to Christopher Schultz from comment #8) > Seems like an awful hack. > > Perhaps instead we should have a configuration attribute like > dontWrapKeyManager="true|false" and them simply do not wrap in the first > place. Or is the wrapping required for other things? If there's really a need to avoid wrapping when FIPS is used, then it should be done here: https://github.com/apache/tomcat/blob/master/java/org/apache/tomcat/util/net/SSLUtilBase.java#L369 (using a new abstract method to detect FIPS JSSE) But there's probably no need for new explicit configuration, if it won't work. And log something if wrapping was desired but cannot be done due to FIPS. So context.getProvider().getInfo().indexOf("FIPS") != -1 is a 100% correct way to test for FIPS ?
kmf.getProvider().getInfo() also gives "Sun JSSE provider (FIPS mode, crypto provider SunPKCS11-NSSfips" so indexOf("FIPS") != -1 would also work there.
Created attachment 37368 [details] patch for the issue.
Aren't we just "always wrapping" because it was simpler than only wrapping when necessary? Why don't we "only" wrap when we must? I think the wrapper is only for certain scenarios. Why not detect THOSE instead of trying to detect the cases where un-wrapping is necessary?
Something like no alias no wrapping and alias and FIPS warning and no wrapping?
https://github.com/apache/tomcat/pull/334 as the best I can get ;-)
PR applied.