On 19/01/2021 04:02, Rob Sargent wrote:
> 
> 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")

That isn't a certificate and key. It is a certificate signing request
(csr) and a key.

You might want to take a look at:
http://tomcat.apache.org/presentations.html

search for "TLS key/certificate generation". That creates a private CA
and then uses it to issue a cert for localhost. Having a private CA lets
you test stuff things client certificate authentication.

Note that this dates from before the subjectAltName requirements so it
will need some tweaks (-ext san=dns:localhost)

Alternatively, grab the (and I can't emphasis this enough) *TEST* keys
and certs from the Tomcat unit tests and use those:

https://github.com/apache/tomcat/tree/master/test/org/apache/tomcat/util/net

> 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

As a general rule it is always better to configure a Tomcat connector
explicitly rather than relay on the fallback to the system properties.

> 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.

"-ext san=dns:localhost" should help

> 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?

Nope. That simply tells Tomcat to treat connections as secure. You don't
want that except in some proxy scenarios.

> 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");

This the line the enables TLS.

> 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.

My recommendation would be:
- start with the test certs from the Tomcat unit tests as they are known
  to work
- get your code working so you know the code is good
- they try with your own keys certificates

Mark

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org

Reply via email to