From 142d8cdeb47ed1b717353d418efea8b05fd9a37f Mon Sep 17 00:00:00 2001 From: Jarl Gullberg Date: Sun, 24 Mar 2024 20:23:32 +0100 Subject: [PATCH 1/2] Implement support for Tomcat 10. --- .classpath | 2 +- build.xml | 2 +- core/pom.xml | 4 +- .../dogtagpki/tomcat/Http11NioProtocol.java | 22 --- main/pom.xml | 2 +- pom.xml | 2 +- tomcat-10.0/pom.xml | 52 +++++++ .../java/org/dogtagpki/tomcat/JSSContext.java | 124 +++++++++++++++++ .../dogtagpki/tomcat/JSSImplementation.java | 63 +++++++++ .../java/org/dogtagpki/tomcat/JSSUtil.java | 130 ++++++++++++++++++ tomcatjss.spec | 2 +- 11 files changed, 376 insertions(+), 29 deletions(-) create mode 100644 tomcat-10.0/pom.xml create mode 100644 tomcat-10.0/src/main/java/org/dogtagpki/tomcat/JSSContext.java create mode 100644 tomcat-10.0/src/main/java/org/dogtagpki/tomcat/JSSImplementation.java create mode 100644 tomcat-10.0/src/main/java/org/dogtagpki/tomcat/JSSUtil.java diff --git a/.classpath b/.classpath index 2fd05fe..d849bda 100644 --- a/.classpath +++ b/.classpath @@ -1,7 +1,7 @@ - + diff --git a/build.xml b/build.xml index 2ea7ed5..ac0d8a4 100644 --- a/build.xml +++ b/build.xml @@ -58,7 +58,7 @@ Set the properties related to the source tree --> - + diff --git a/core/pom.xml b/core/pom.xml index aa0b63e..1365424 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -31,13 +31,13 @@ org.apache.tomcat tomcat-catalina - 9.0.50 + 10.1.6 org.apache.tomcat tomcat-coyote - 9.0.50 + 10.1.6 diff --git a/core/src/main/java/org/dogtagpki/tomcat/Http11NioProtocol.java b/core/src/main/java/org/dogtagpki/tomcat/Http11NioProtocol.java index 974e607..7989da3 100644 --- a/core/src/main/java/org/dogtagpki/tomcat/Http11NioProtocol.java +++ b/core/src/main/java/org/dogtagpki/tomcat/Http11NioProtocol.java @@ -102,26 +102,4 @@ public int getOcspTimeout() { public void setOcspTimeout(int ocspTimeout) { tomcatjss.setOcspTimeout(ocspTimeout); } - - public void setKeystorePassFile(String keystorePassFile) { - try { - Path path = Paths.get(keystorePassFile); - String password = new String(Files.readAllBytes(path)).trim(); - setKeystorePass(password); - - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - public void setTruststorePassFile(String truststorePassFile) { - try { - Path path = Paths.get(truststorePassFile); - String password = new String(Files.readAllBytes(path)).trim(); - setTruststorePass(password); - - } catch (IOException e) { - throw new RuntimeException(e); - } - } } diff --git a/main/pom.xml b/main/pom.xml index 267b1bf..844bc73 100644 --- a/main/pom.xml +++ b/main/pom.xml @@ -24,7 +24,7 @@ ${project.groupId} - tomcatjss-tomcat-9.0 + tomcatjss-tomcat-10.0 ${project.version} diff --git a/pom.xml b/pom.xml index a515791..fe6901d 100644 --- a/pom.xml +++ b/pom.xml @@ -15,7 +15,7 @@ core - tomcat-9.0 + tomcat-10.0 main diff --git a/tomcat-10.0/pom.xml b/tomcat-10.0/pom.xml new file mode 100644 index 0000000..673b1ff --- /dev/null +++ b/tomcat-10.0/pom.xml @@ -0,0 +1,52 @@ + + + + 4.0.0 + + + org.dogtagpki.tomcatjss + tomcatjss-parent + 8.5.0-SNAPSHOT + + + tomcatjss-tomcat-10.0 + jar + + + + + org.apache.tomcat + tomcat-juli + 10.1.6 + + + + org.dogtagpki.jss + jss-base + 5.5.0-SNAPSHOT + + + + ${project.groupId} + tomcatjss-core + ${project.version} + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + 17 + + + + + + diff --git a/tomcat-10.0/src/main/java/org/dogtagpki/tomcat/JSSContext.java b/tomcat-10.0/src/main/java/org/dogtagpki/tomcat/JSSContext.java new file mode 100644 index 0000000..ec1b1df --- /dev/null +++ b/tomcat-10.0/src/main/java/org/dogtagpki/tomcat/JSSContext.java @@ -0,0 +1,124 @@ +package org.dogtagpki.tomcat; + +import java.security.KeyManagementException; +import java.security.SecureRandom; + +import javax.net.ssl.KeyManager; +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.TrustManager; +import javax.net.ssl.TrustManagerFactory; + +import org.apache.tomcat.util.net.jss.TomcatJSS; +import org.mozilla.jss.JSSProvider; +import org.mozilla.jss.provider.javax.crypto.JSSKeyManager; +import org.mozilla.jss.provider.javax.crypto.JSSTrustManager; +import org.mozilla.jss.ssl.javax.JSSEngine; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class JSSContext implements org.apache.tomcat.util.net.SSLContext { + public static Logger logger = LoggerFactory.getLogger(JSSContext.class); + + private javax.net.ssl.SSLContext ctx; + private String alias; + + private JSSKeyManager jkm; + private JSSTrustManager jtm; + + public JSSContext(String alias) { + logger.debug("JSSContext(" + alias + ")"); + this.alias = alias; + + /* These KeyManagers and TrustManagers aren't used with the SSLEngine; + * they're only used to implement certain function calls below. */ + try { + KeyManagerFactory kmf = KeyManagerFactory.getInstance("NssX509", "Mozilla-JSS"); + jkm = (JSSKeyManager) kmf.getKeyManagers()[0]; + + TrustManagerFactory tmf = TrustManagerFactory.getInstance("NssX509", "Mozilla-JSS"); + jtm = (JSSTrustManager) tmf.getTrustManagers()[0]; + } catch (Exception e) { + throw new RuntimeException(e.getMessage(), e); + } + } + + @Override + public void init(KeyManager[] kms, TrustManager[] tms, SecureRandom sr) throws KeyManagementException { + logger.debug("JSSContext.init(...)"); + + try { + String provider = "SunJSSE"; + if (JSSProvider.ENABLE_JSSENGINE) { + provider = "Mozilla-JSS"; + } + + ctx = javax.net.ssl.SSLContext.getInstance("TLS", provider); + ctx.init(kms, tms, sr); + } catch (Exception e) { + throw new KeyManagementException(e.getMessage(), e); + } + } + + @Override + public javax.net.ssl.SSLEngine createSSLEngine() { + logger.debug("JSSContext.createSSLEngine()"); + javax.net.ssl.SSLEngine eng = ctx.createSSLEngine(); + + TomcatJSS instance = TomcatJSS.getInstance(); + + if (eng instanceof JSSEngine) { + JSSEngine j_eng = (JSSEngine) eng; + j_eng.setCertFromAlias(alias); + if(instance != null) { + j_eng.setListeners(instance.getSocketListeners()); + } + } + + return eng; + } + + @Override + public javax.net.ssl.SSLSessionContext getServerSessionContext() { + logger.debug("JSSContext.getServerSessionContext()"); + return ctx.getServerSessionContext(); + } + + @Override + public javax.net.ssl.SSLServerSocketFactory getServerSocketFactory() { + logger.debug("JSSContext.getServerSocketFactory()"); + return ctx.getServerSocketFactory(); + } + + @Override + public javax.net.ssl.SSLParameters getSupportedSSLParameters() { + logger.debug("JSSContext.getSupportedSSLParameters()"); + return ctx.getSupportedSSLParameters(); + } + + @Override + public java.security.cert.X509Certificate[] getCertificateChain(java.lang.String alias) { + logger.debug("JSSContext.getCertificateChain(" + alias + ")"); + + try { + return jkm.getCertificateChain(alias); + } catch (Exception e) { + throw new RuntimeException(e.getMessage(), e); + } + } + + @Override + public java.security.cert.X509Certificate[] getAcceptedIssuers() { + logger.debug("JSSContext.getAcceptedIssuers()"); + + try { + return jtm.getAcceptedIssuers(); + } catch (Exception e) { + throw new RuntimeException(e.getMessage(), e); + } + } + + @Override + public void destroy() { + logger.debug("JSSContext.destroy()"); + } +} diff --git a/tomcat-10.0/src/main/java/org/dogtagpki/tomcat/JSSImplementation.java b/tomcat-10.0/src/main/java/org/dogtagpki/tomcat/JSSImplementation.java new file mode 100644 index 0000000..d1e5f10 --- /dev/null +++ b/tomcat-10.0/src/main/java/org/dogtagpki/tomcat/JSSImplementation.java @@ -0,0 +1,63 @@ +/* BEGIN COPYRIGHT BLOCK + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Copyright (C) 2007 Red Hat, Inc. + * All rights reserved. + * END COPYRIGHT BLOCK */ + +package org.dogtagpki.tomcat; + +import javax.net.ssl.SSLSession; + +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.SSLSupport; +import org.apache.tomcat.util.net.SSLUtil; +import org.apache.tomcat.util.net.jsse.JSSESupport; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.List; +import java.util.Map; + +public class JSSImplementation extends SSLImplementation { + + public static final Logger logger = LoggerFactory.getLogger(JSSImplementation.class); + + public JSSImplementation() { + logger.debug("JSSImplementation: instance created"); + } + + @Override + public SSLSupport getSSLSupport(SSLSession sslSession, Map> map) { + logger.debug("JSSImplementation.getSSLSupport()"); + return new JSSESupport(sslSession, map); + } + + @Override + public SSLUtil getSSLUtil(SSLHostConfigCertificate cert) { + logger.debug("JSSImplementation: getSSLUtil()"); + logger.debug("JSSImplementation: key alias: {}", cert.getCertificateKeyAlias()); + logger.debug("JSSImplementation: keystore provider: {}", cert.getCertificateKeystoreProvider()); + + SSLHostConfig hostConfig = cert.getSSLHostConfig(); + logger.debug("JSSImplementation: key manager alg: {}", hostConfig.getKeyManagerAlgorithm()); + logger.debug("JSSImplementation: truststore alg: {}", hostConfig.getTruststoreAlgorithm()); + logger.debug("JSSImplementation: truststore provider: {}", hostConfig.getTruststoreProvider()); + + return new JSSUtil(cert); + } +} diff --git a/tomcat-10.0/src/main/java/org/dogtagpki/tomcat/JSSUtil.java b/tomcat-10.0/src/main/java/org/dogtagpki/tomcat/JSSUtil.java new file mode 100644 index 0000000..8370370 --- /dev/null +++ b/tomcat-10.0/src/main/java/org/dogtagpki/tomcat/JSSUtil.java @@ -0,0 +1,130 @@ +/* BEGIN COPYRIGHT BLOCK + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Copyright (C) 2018 Red Hat, Inc. + * All rights reserved. + * END COPYRIGHT BLOCK */ + +package org.dogtagpki.tomcat; + +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import javax.net.ssl.KeyManager; +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.SSLEngine; +import javax.net.ssl.TrustManager; +import javax.net.ssl.TrustManagerFactory; + +import org.apache.juli.logging.Log; +import org.apache.juli.logging.LogFactory; +import org.apache.tomcat.util.net.SSLContext; +import org.apache.tomcat.util.net.SSLHostConfigCertificate; +import org.apache.tomcat.util.net.SSLUtilBase; +import org.mozilla.jss.JSSProvider; +import org.mozilla.jss.provider.javax.crypto.JSSNativeTrustManager; + +public class JSSUtil extends SSLUtilBase { + public static Log logger = LogFactory.getLog(JSSUtil.class); + + private String keyAlias; + + private SSLEngine engine; + private Set protocols; + private Set ciphers; + + public JSSUtil(SSLHostConfigCertificate cert) { + super(cert); + + keyAlias = certificate.getCertificateKeyAlias(); + logger.debug("JSSUtil: instance created"); + } + + private void init() { + if (engine != null) { + return; + } + + try { + JSSContext ctx = new JSSContext(null); + ctx.init(null, null, null); + engine = ctx.createSSLEngine(); + } catch (Exception e) { + throw new RuntimeException(e.getMessage(), e); + } + + protocols = Collections.unmodifiableSet( + new HashSet<>(Arrays.asList(engine.getSupportedProtocols())) + ); + + ciphers = Collections.unmodifiableSet( + new HashSet<>(Arrays.asList(engine.getSupportedCipherSuites())) + ); + } + + @Override + public KeyManager[] getKeyManagers() throws Exception { + logger.debug("JSSUtil: getKeyManagers()"); + KeyManagerFactory jkm = KeyManagerFactory.getInstance("NssX509", "Mozilla-JSS"); + return jkm.getKeyManagers(); + } + + @Override + public TrustManager[] getTrustManagers() throws Exception { + logger.debug("JSSUtil: getTrustManagers()"); + if (!JSSProvider.ENABLE_JSSENGINE) { + TrustManagerFactory tmf = TrustManagerFactory.getInstance("NssX509"); + return tmf.getTrustManagers(); + } + + return new TrustManager[] { new JSSNativeTrustManager() }; + } + + @Override + public SSLContext createSSLContextInternal(List negotiableProtocols) throws Exception { + logger.debug("JSSUtil createSSLContextInternal(...) keyAlias=" + keyAlias); + return new JSSContext(keyAlias); + } + + @Override + public boolean isTls13RenegAuthAvailable() { + logger.debug("JSSUtil: isTls13RenegAuthAvailable()"); + return true; + } + + @Override + public Log getLog() { + logger.debug("JSSUtil: getLog()"); + return logger; + } + + @Override + protected Set getImplementedProtocols() { + logger.debug("JSSUtil: getImplementedProtocols()"); + init(); + return protocols; + } + + @Override + protected Set getImplementedCiphers() { + logger.debug("JSSUtil: getImplementedCiphers()"); + init(); + + return ciphers; + } +} diff --git a/tomcatjss.spec b/tomcatjss.spec index be00c24..5371e9d 100644 --- a/tomcatjss.spec +++ b/tomcatjss.spec @@ -163,7 +163,7 @@ mkdir -p main/target/classes pushd main/target/classes jar xvf ../../../core/target/tomcatjss-core-%{version}-SNAPSHOT.jar -jar xvf ../../../tomcat-9.0/target/tomcatjss-tomcat-9.0-%{version}-SNAPSHOT.jar +jar xvf ../../../tomcat-10.0/target/tomcatjss-tomcat-10.0-%{version}-SNAPSHOT.jar popd jar cvf main/target/tomcatjss.jar -C main/target/classes . From e11829d41e82cef559c728a744864ae40d5859fb Mon Sep 17 00:00:00 2001 From: Jarl Gullberg Date: Tue, 26 Mar 2024 13:10:03 +0100 Subject: [PATCH 2/2] Enable building for both Tomcat 9 and Tomcat 10. --- .classpath | 2 +- build.xml | 3 +- core/pom.xml | 4 +- main/pom.xml | 2 +- pom.xml | 4 +- .../dogtagpki/tomcat/Http11NioProtocol.java | 0 .../dogtagpki/tomcat/Http11NioProtocol.java | 127 ++++++++++++++++++ tomcatjss.spec | 2 +- 8 files changed, 137 insertions(+), 7 deletions(-) rename {core => tomcat-10.0}/src/main/java/org/dogtagpki/tomcat/Http11NioProtocol.java (100%) create mode 100644 tomcat-9.0/src/main/java/org/dogtagpki/tomcat/Http11NioProtocol.java diff --git a/.classpath b/.classpath index d849bda..2fd05fe 100644 --- a/.classpath +++ b/.classpath @@ -1,7 +1,7 @@ - + diff --git a/build.xml b/build.xml index ac0d8a4..a69b174 100644 --- a/build.xml +++ b/build.xml @@ -39,6 +39,7 @@ + - + diff --git a/core/pom.xml b/core/pom.xml index 1365424..0acaba0 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -31,13 +31,13 @@ org.apache.tomcat tomcat-catalina - 10.1.6 + ${project.tomcat.version} org.apache.tomcat tomcat-coyote - 10.1.6 + ${project.tomcat.version} diff --git a/main/pom.xml b/main/pom.xml index 844bc73..6d62abe 100644 --- a/main/pom.xml +++ b/main/pom.xml @@ -24,7 +24,7 @@ ${project.groupId} - tomcatjss-tomcat-10.0 + tomcatjss-tomcat-${project.tomcat.majorVersion}.0 ${project.version} diff --git a/pom.xml b/pom.xml index fe6901d..3a5cc34 100644 --- a/pom.xml +++ b/pom.xml @@ -11,11 +11,13 @@ UTF-8 + 9 + 9.0.50 core - tomcat-10.0 + tomcat-${project.tomcat.majorVersion}.0 main diff --git a/core/src/main/java/org/dogtagpki/tomcat/Http11NioProtocol.java b/tomcat-10.0/src/main/java/org/dogtagpki/tomcat/Http11NioProtocol.java similarity index 100% rename from core/src/main/java/org/dogtagpki/tomcat/Http11NioProtocol.java rename to tomcat-10.0/src/main/java/org/dogtagpki/tomcat/Http11NioProtocol.java diff --git a/tomcat-9.0/src/main/java/org/dogtagpki/tomcat/Http11NioProtocol.java b/tomcat-9.0/src/main/java/org/dogtagpki/tomcat/Http11NioProtocol.java new file mode 100644 index 0000000..974e607 --- /dev/null +++ b/tomcat-9.0/src/main/java/org/dogtagpki/tomcat/Http11NioProtocol.java @@ -0,0 +1,127 @@ +package org.dogtagpki.tomcat; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; + +import org.apache.tomcat.util.net.jss.TomcatJSS; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class Http11NioProtocol extends org.apache.coyote.http11.Http11NioProtocol { + + public static Logger logger = LoggerFactory.getLogger(Http11NioProtocol.class); + + TomcatJSS tomcatjss = TomcatJSS.getInstance(); + + public String getCertdbDir() { + return tomcatjss.getCertdbDir(); + } + + public void setCertdbDir(String certdbDir) { + tomcatjss.setCertdbDir(certdbDir); + } + + public String getPasswordClass() { + return tomcatjss.getPasswordClass(); + } + + public void setPasswordClass(String passwordClass) { + tomcatjss.setPasswordClass(passwordClass); + } + + public String getPasswordFile() { + return tomcatjss.getPasswordFile(); + } + + public void setPasswordFile(String passwordFile) { + tomcatjss.setPasswordFile(passwordFile); + } + + public String getServerCertNickFile() { + return tomcatjss.getServerCertNickFile(); + } + + public void setServerCertNickFile(String serverCertNickFile) { + tomcatjss.setServerCertNickFile(serverCertNickFile); + } + + public boolean getEnabledOCSP() { + return tomcatjss.getEnableOCSP(); + } + + public void setEnableOCSP(boolean enableOCSP) { + tomcatjss.setEnableOCSP(enableOCSP); + } + + public String getOcspResponderURL() { + return tomcatjss.getOcspResponderURL(); + } + + public void setOcspResponderURL(String ocspResponderURL) { + tomcatjss.setOcspResponderURL(ocspResponderURL); + } + + public String getOcspResponderCertNickname() { + return tomcatjss.getOcspResponderCertNickname(); + } + + public void setOcspResponderCertNickname(String ocspResponderCertNickname) { + tomcatjss.setOcspResponderCertNickname(ocspResponderCertNickname); + } + + public int getOcspCacheSize() { + return tomcatjss.getOcspCacheSize(); + } + + public void setOcspCacheSize(int ocspCacheSize) { + tomcatjss.setOcspCacheSize(ocspCacheSize); + } + + public int getOcspMinCacheEntryDuration() { + return tomcatjss.getOcspMinCacheEntryDuration(); + } + + public void setOcspMinCacheEntryDuration(int ocspMinCacheEntryDuration) { + tomcatjss.setOcspMinCacheEntryDuration(ocspMinCacheEntryDuration); + } + + public int getOcspMaxCacheEntryDuration() { + return tomcatjss.getOcspMaxCacheEntryDuration(); + } + + public void setOcspMaxCacheEntryDuration(int ocspMaxCacheEntryDuration) { + tomcatjss.setOcspMaxCacheEntryDuration(ocspMaxCacheEntryDuration); + } + + public int getOcspTimeout() { + return tomcatjss.getOcspTimeout(); + } + + public void setOcspTimeout(int ocspTimeout) { + tomcatjss.setOcspTimeout(ocspTimeout); + } + + public void setKeystorePassFile(String keystorePassFile) { + try { + Path path = Paths.get(keystorePassFile); + String password = new String(Files.readAllBytes(path)).trim(); + setKeystorePass(password); + + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + public void setTruststorePassFile(String truststorePassFile) { + try { + Path path = Paths.get(truststorePassFile); + String password = new String(Files.readAllBytes(path)).trim(); + setTruststorePass(password); + + } catch (IOException e) { + throw new RuntimeException(e); + } + } +} diff --git a/tomcatjss.spec b/tomcatjss.spec index 5371e9d..be00c24 100644 --- a/tomcatjss.spec +++ b/tomcatjss.spec @@ -163,7 +163,7 @@ mkdir -p main/target/classes pushd main/target/classes jar xvf ../../../core/target/tomcatjss-core-%{version}-SNAPSHOT.jar -jar xvf ../../../tomcat-10.0/target/tomcatjss-tomcat-10.0-%{version}-SNAPSHOT.jar +jar xvf ../../../tomcat-9.0/target/tomcatjss-tomcat-9.0-%{version}-SNAPSHOT.jar popd jar cvf main/target/tomcatjss.jar -C main/target/classes .