|Summary:||Allow the crlFile to be reloaded|
|Product:||Tomcat 8||Reporter:||Daniel Mikusa <dmikusa>|
|Component:||Connectors||Assignee:||Tomcat Developers Mailing List <dev>|
Description Daniel Mikusa 2013-11-12 19:33:03 UTC
There have been a few recent requests on the users list for the ability to reload the crlFile. http://tomcat.markmail.org/message/fa7rqbjmqadzxxok http://tomcat.markmail.org/message/kid5zlnlznsflhkz Would it be possible to reload the file if it changes? If that's not possible, how about exposing the ability to reload it through JMX? Thanks
Comment 1 Christopher Schultz 2013-11-12 20:21:19 UTC
For the JSSE connector, it appears that changing the TrustManager itself is non-trivial: it would require that the SSLServerSocketFactory be re-built from scratch, the connector would have to detach from the port and re-bind to it. That's obviously not a good solution. However, the TrustManager itself could be rigged to re-load the CRL at an interval. I'd have to look to see how the stock TrustManagers work... if they do any kind of trust-caching things might not go well. Assuming there's no problem with a TrustManager that changes behavior over time, this should be doable... for JSSE anyway.
Comment 2 Christopher Schultz 2014-05-02 16:33:18 UTC
It turns out this is something of a mess. During initialization, the connector (really o.a.t.util.net.jsse.JSSESocketFactory) sets-up a set of TrustManager objects in an array, which are passed-into SSLContext.init. After that, who knows. We can wrap a TrustManager in another object, but TrustManager itself doesn't have any methods. Instead, there is a subinterface called X509TrustManager that does have actual methods. Unfortunately, the standard way of getting TrustManagers that work off of a trust store and a CRL ultimately returns an array of ... TrustManagers. So, you either have to assume that the only useful implementation of a TrustManager is an X509TrustManager (which isn't a bad assumption, really, but could end up biting us in the future) or that the only thing that will come out of that standard setup procedure (an array of TrustManagers) will have exactly one TrustManager in it -- and we can replace one with the other in the existing array being used by the SSLContext. This will all fall apart if the SSLContext does something sensible like making a defensive copy of the array it gets from the calling code. I think perhaps the only way to do this would be to make a few assumptions and hope for the best. That seems to be what Hadoop does (see below). References: http://jcalcote.wordpress.com/2010/06/22/managing-a-dynamic-java-trust-store/ http://svn.apache.org/repos/asf/hadoop/common/trunk/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/ssl/ReloadingX509TrustManager.java
Comment 3 Mark Thomas 2016-08-30 21:03:12 UTC
The solution is to replace the SSLContext. That should be fairly simple for JSSE. It is a little more 'interesting' for OpenSSL since you need to destroy the SSLContext and you can't do that while it is in use but that should be a solvable problem. The advantage of this approach is you can reload the entire TLS config so it can beused to update server certs, trust stores etc as well as CRL.
Comment 4 Christopher Schultz 2016-08-31 00:31:06 UTC
SSLServerSocketFactory doesn't have any methods that allow us to replace the SSLContext, and neither does JSSESocketFactory. I think we have to re-bind to the port in order to actually change anything... unless there is some technique that I don't know about. I honestly don't know about the underpinnings of how Tomcat takes an incoming request and hands it off to whatever component picks-up after the socket accept(). But the SocketFactory is used to configure and bind to the port, producing a ServerSocket. I see no way in the API to replace the SSLContext in an existing ServerSocket. BTW, what happened to JSSESocketFactory after 8.0.x?