What is common way of client certificate validation against CRL in Tomcat?
One possible solution:
Update server.xml
, set up connector
, set up key and trust store, and there is crlList
parameter.
There are 2 issues with that approach:
Maintenance of the list - have to be done outside of Tomcat, Tomcat needs restart in order to pick up latest one
There is no (or at least the one I could find) way to support CR Lists for multiple CA bodies, or just say - multiple CR Lists at the same time.
I was not able to find "good" solution back few years ago with Tomcat 5. Any news on this with 7?
Is there common/elegant way to override connector handler and current functionality and provide custom certificate validation?
In a way that JBoss AS let you do it, by just extending existing class and giving you possibility to define own login-module and own verifier.
There is now a way to pick the latest CRL file without restarting the server.
They introduced 2 methods named:
reloadSslHostConfig(String hostName)
- to reload a specific hostreloadSslHostConfigs()
- reload allThey can be called in various ways:
Details of way 1 and way 2 are easily available online.
Details of how to go about using way 3:
Http11NioProtocol
reloadSslHostConfigs
method time to timeFind sample code below:
Main protocol class:
package com.myown.connector;
import java.io.File;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.net.URL;
import java.net.URLConnection;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentMap;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import javax.net.ssl.SSLSessionContext;
import org.apache.coyote.http11.Http11NioProtocol;
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
import org.apache.tomcat.util.modeler.Registry;
import org.apache.tomcat.util.net.AbstractEndpoint;
import org.apache.tomcat.util.net.AbstractJsseEndpoint;
import org.apache.tomcat.util.net.GetSslConfig;
import org.apache.tomcat.util.net.SSLContext;
import org.apache.tomcat.util.net.SSLHostConfig;
import org.apache.tomcat.util.net.SSLHostConfigCertificate;
import org.apache.tomcat.util.net.SSLImplementation;
import org.apache.tomcat.util.net.SSLUtil;
public class ReloadProtocol extends Http11NioProtocol {
private static final Log log = LogFactory.getLog(Http12ProtocolSSL.class);
public ReloadProtocol() {
super();
RefreshSslConfigThread refresher = new
RefreshSslConfigThread(this.getEndpoint(), this);
refresher.start();
}
@Override
public void setKeystorePass(String s) {
super.setKeystorePass(s);
}
@Override
public void setKeyPass(String s) {
super.setKeyPass(s);
}
@Override
public void setTruststorePass(String p) {
super.setTruststorePass(p);
}
class RefreshSslConfigThread extends Thread {
AbstractJsseEndpoint<?> abstractJsseEndpoint = null;
Http11NioProtocol protocol = null;
public RefreshSslConfigThread(AbstractJsseEndpoint<?> abstractJsseEndpoint, Http11NioProtocol protocol) {
this.abstractJsseEndpoint = abstractJsseEndpoint;
this.protocol = protocol;
}
public void run() {
int timeBetweenRefreshesInt = 1000000; // time in milli-seconds
while (true) {
try {
abstractJsseEndpoint.reloadSslHostConfigs();
System.out.println("Config Updated");
} catch (Exception e) {
System.out.println("Problem while reloading.");
}
try {
Thread.sleep(timeBetweenRefreshesInt);
} catch (InterruptedException e) {
System.out.println("Error while sleeping");
}
}
}
}
}
The Connector
in server.xml
should mention this as the protocol:
<Connector protocol="com.myown.connector.ReloadProtocol"
...
Hope this helps.