I've been trying to setup SSL/TLS handshake in Tomcat 8. I've successfully done all the configurations but there are some problems I'm facing with CRL/OCSP.
I need solution to: this
I've a couple of questions so kindly have some patience. Any help would be really appreciated.
I've below configuration of connector in server.xml.
<Connector protocol="org.apache.coyote.http11.Http11NioProtocol" port="8443" maxThreads="2000" clientAuth="want" scheme="https" keepAliveTimeout="-1" connectionTimeout="900000" compression="on" noCompressionUserAgents="gozilla, traviata" compressableMimeType="text/html,text/xml,text/css,text/javascript,image/jpg,image/ico,image/png,image/jpeg,image/tiff,image/tif" secure="true" SSLEnabled="true" sslProtocol="TLS" sessionTimeout="30" truststoreFile="D:\\Certs\\server.truststore" truststorePass="123456" keystoreFile="D:\\Certs\\keystore.pkcs12" keystorePass="password" keystoreType="PKCS12" crlFile="http://127.0.0.1:8600/getCRLFile/" maxKeepAliveRequests="200" sslEnabledProtocols= "TLSv1,TLSv1.1,TLSv1.2" maxHttpHeaderSize="65536" maxPostSize="4194304" ciphers="TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,TLS_RSA_WITH_AES_128_CBC_SHA256,TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA256,TLS_RSA_WITH_AES_256_CBC_SHA"/>
Can I achieve this using any of the tomcat configuration ?
Problem with this is that I'll have to send the certificates of client while handshaking to this java code and accept/reject the certificate based on reply from this code. I don't know how to do that. Any help will be of great use. The second reason is I would prefer to achieve task 1 using tomcat configurations rather than custom code because custom code might miss out on some aspects.
Can I dynamically pick an updated CRL from the CRL distribution URL without restarting the tomcat server ? The current scenario with above configuration picks the CRL file once when server is turned On and then it uses that copy only even if CRL list available on the URL has changed.
Can we have multiple CRL end-points configured in the connector ? Tomcat will check them all and accept/reject a client certificate based on combined list from all the URLs.
Thanks in advance. Please feel free to ask any details I might have missed.
Answering my own question.
I could find a way to cache CRL. What I did was to make crlFile of connector in server.xml to point to a CRL file on local machine. I updates this file using a CRON job time to time.
Starting with Tomcat v8.5.24, a new API has been added to refresh the whole SSL config without restarting Tomcat server. I called those APIs time to time too to pick the updated CRL file from the local machine.
They introduced 2 methods named:
They 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:
Find 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");
}
}
}
}
}
Connector in server.xml should mention this as the protocol:
<Connector protocol="com.myown.connector.ReloadProtocol"
..........
Hope this helps someone.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.