Bug 63650 - Unable to use own JSSE cipher implementation
Summary: Unable to use own JSSE cipher implementation
Status: RESOLVED FIXED
Alias: None
Product: Tomcat 9
Classification: Unclassified
Component: Connectors (show other bugs)
Version: 9.0.21
Hardware: PC All
: P2 normal (vote)
Target Milestone: -----
Assignee: Tomcat Developers Mailing List
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2019-08-08 10:56 UTC by Arne Stahlbock
Modified: 2019-08-08 13:40 UTC (History)
0 users



Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Arne Stahlbock 2019-08-08 10:56:19 UTC
Due to our need to use certain TLS cipher suites which are not supported by the SunJSSE provider by Oracle, we have created an own implementation of a JSSE provider.
In Tomcat 7, we are able to use it easily by registering our provider in the JRE and configuring

<Connector port="..." protocol="HTTP/1.1" SSLEnabled="true" maxThreads="150" scheme="https" secure="true" keystoreFile="..." keystorePass="..." sslProtocol="TLSPSK" ciphers="TLS_RSA_PSK_WITH_AES_256_GCM_SHA384" clientAuth="false" />

where "TLSPSK" is the name of our SSLContext implementation.

However we are unable to use it in Tomcat 9 (or 8.5).
Startup of Tomcat 9 (with same connector configuration) results in following exception:

Caused by: java.lang.IllegalArgumentException: Keine der spezifizierten [ciphers] wird von der SSL Engine unterstützt: [[TLS_RSA_PSK_WITH_AES_256_GCM_SHA384]]
at org.apache.tomcat.util.net.SSLUtilBase.getEnabled(SSLUtilBase.java:151)
at org.apache.tomcat.util.net.SSLUtilBase.<init>(SSLUtilBase.java:125)
at org.apache.tomcat.util.net.jsse.JSSEUtil.<init>(JSSEUtil.java:113)
at org.apache.tomcat.util.net.jsse.JSSEUtil.<init>(JSSEUtil.java:108)
at org.apache.tomcat.util.net.jsse.JSSEImplementation.getSSLUtil(JSSEImplementation.java:50)
at org.apache.tomcat.util.net.AbstractJsseEndpoint.createSSLContext(AbstractJsseEndpoint.java:88)
at org.apache.tomcat.util.net.AbstractJsseEndpoint.initialiseSsl(AbstractJsseEndpoint.java:71)
at org.apache.tomcat.util.net.NioEndpoint.bind(NioEndpoint.java:218)
at org.apache.tomcat.util.net.AbstractEndpoint.bindWithCleanup(AbstractEndpoint.java:1124)
at org.apache.tomcat.util.net.AbstractEndpoint.init(AbstractEndpoint.java:1137)
at org.apache.coyote.AbstractProtocol.init(AbstractProtocol.java:574)
at org.apache.coyote.http11.AbstractHttp11Protocol.init(AbstractHttp11Protocol.java:74)
at org.apache.catalina.connector.Connector.initInternal(Connector.java:980)

meaning given ciphers not supported.
An investigation showed us that SSLUtilBase.getEnabled always produces an empty list with operations

enabled.addAll(configured);
enabled.retainAll(implemented);

where "configured" holds exactly the ciphers we give in the config, and "implemented" holds a number of ciphers but not ours.
Tracking down where "implemented" comes from led us to JSSEUtil static initializer

SSLContext context;
try {
    context = new JSSESSLContext(Constants.SSL_PROTO_TLS);

... and later

    String[] implementedCipherSuiteArray = context.getSupportedSSLParameters().getCipherSuites();

So, the "implemented" ciphers are always taken from the SSLContext one receives from SSLContext.getInstance("TLS") which is usually the SunJSSE implementation, essentially locking out all other ciphers.
A workaround by naming our SSLContext "TLS" and assigning it higher priority than SunJSSE, so JSSEUtil would then always use ours, is not feasible as we also need SunJSSE (on other connectors).
Comment 1 Mark Thomas 2019-08-08 13:40:37 UTC
Fixed in:
- master for 9.0.23 onwards
- 8.5.x for 8.5.44 onwards

I have refactored the initialisation so it uses the sslProtocol value from the SSLHostContext.