Stuck in my basement with no real domain I'm having trouble setting up
SSL/TLS on an embedded tomcat instance. And I'm very lost, having tried
more dead ends than I can remember.
I used this to generate cert and key
openssl req -out localhost.crt -key localhost.key \
-newkey rsa:2048 -nodes -sha256 \
-subj '/CN=localhost' -extensions EXT -config <( \
printf "[dn]\nCN=localhost\n[req]\ndistinguished_name =
dn\n[EXT]\nsubjectAltName=DNS:localhost\nkeyUsage=digitalSignature,
nonRepudiation, keyEncipherment,
dataEncipherment\nextendedKeyUsage=serverAuth")
and try to apply those with
-Djavax.net.ssl.trustStore=/tmp/key/localhost.crt
-Djavax.net.ssl.trustStorePassword=changeit
-Djavax.net.ssl.trustStoreType=PKCS12
-Djavax.net.ssl.keyStore=/tmp/key/localhost.key
-Djavax.net.ssl.keyStorePassword=changeit
-Dhttps.protocols=TLSv1.2,TLSv1.3
-Djdk.tls.client.protocols=TLSv1.2,TLSv1.3
I get "toDerInputStream rejects tag type 45".
That error rears its ugly head in several places such when adding those
same two localhost files to a pkcs12 rendition of the OS's cacerts file
using below. The crt goes in quietly. (I'm couldn't convince my self of
the openssl equivalent of this command)
root@gitanmax:/tmp/key# keytool -importkeystore -srckeystore
localhost.key -srckeypass changeit -srcstoretype pkcs12 -destkeystore
cacerts.pkcs12 -deststoretype pkcs12 -srcalias localhost -destalias
tomcatlocal
Importing keystore localhost.key to cacerts.pkcs12...
Enter destination keystore password: changeit
Enter source keystore password: changeit
keytool error: java.io.IOException: toDerInputStream rejects tag type 45
My actual first attempt was to just use keytool to generate a cert
interactively, filling in my own bogus values but that hit the domain
name mismatch gotcha.
Then, there's confusion on the java side as well.
My plan was to add a connector for my webapp
embeddedTomcat = new Tomcat();
logger.debug("handing in CATALINA_HOME as " +
System.getenv("CATALINA_HOME"));
embeddedTomcat.setPort(tomcatPort-1);
embeddedTomcat.enableNaming();
Connector defaultConnector = embeddedTomcat.getConnector(); // an init,
really
defaultConnector.setSecure(true); // force https?
Service service = embeddedTomcat.getService();
service.addConnector(addTLSConnector(tomcatPort));
logger.info("tomcatd listening on port " + tomcatPort);
String contextRootPath = System.getenv("CATALINA_HOME");
logger.debug("contextRootPath is {}", contextRootPath);
Context contextTomcat = embeddedTomcat.addContext("", new
File(contextRootPath + "/sgs").getAbsolutePath());
logger.debug("host: {}, general context basename {}",
embeddedTomcat.getHost(), contextTomcat.getBaseName());
//TODO: cut from here ...
java.time.LocalDateTime bootDT = java.time.LocalDateTime.now();
Tomcat.addServlet(contextTomcat, "monitor", new HttpServlet() {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
ServletOutputStream out = resp.getOutputStream();
out.write("SGS Agent monitor: SGS_OK\n".getBytes());
out.write(("Up since " + bootDT.toString()).getBytes());
out.write(("\nTime now " +
java.time.LocalDateTime.now().toString()).getBytes());
out.flush();
out.close();
}
});
contextTomcat.addServletMappingDecoded("/monitor", "monitor");
// My webapp
Context sgsContext = embeddedTomcat.addWebapp("/sgs", contextRootPath +
"/sgs"); // /sgs.war
embeddedTomcat.start();
embeddedTomcat.getServer().await();
private Connector addTLSConnector(Connector connector, int tcport) {
File keyFile = new File (System.getProperty("SGSSRVR_keystoreFile"));
if (! keyFile.exists()) throw new RuntimeException("where's the
keystore?");
connector.setPort(tcport);
connector.setSecure(true);
connector.setScheme("https");
connector.setProperty("protocol", "HTTP/1.1");
connector.setProperty("sslProtocol", "TLS");
connector.setProperty("address","127.0.0.1");
connector.setProperty("clientAuth", "false");
connector.setProperty("maxThreads", "200");
connector.setProperty("protocol",
"org.apache.coyote.http11.Http11NioProtocol");
connector.setProperty("SSLEnabled", "true");
return connector;
}
private Connector addTLSConnector(int tcport) {
Connector connector = new Connector();
addTLSConnector(connector, tcport);
return connector;
}
That "monitor" works, on a separate port, on either http or https as per
defaultConnector.setSecure(isHttps);
but possibly because I've diddle with chrome's security settings.
I have a similar "monitor" as a servlet which I use as my
is-anybody-home call to start my analyses. And of course can also use
it via the browser at /seg/webmonitor.
All these behave when SSL is not in play, but I'm forced, very much
against my will, to use SSL so here I am bother the good folks on this
list for more help.