This is an automated email from the ASF dual-hosted git repository. markt pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/tomcat.git
The following commit(s) were added to refs/heads/main by this push: new 43df99e Log a warning for CLIENT-CERT + JSSE TLS 1.3 as PHA is not supported 43df99e is described below commit 43df99e05cfa4d0eaed30cb03f65ee687ff0ce54 Author: Mark Thomas <ma...@apache.org> AuthorDate: Thu Mar 24 16:19:09 2022 +0000 Log a warning for CLIENT-CERT + JSSE TLS 1.3 as PHA is not supported CLIENT-CERT requires post-handshake authentication (PHA) to work with TLS 1.3 but the JSSE TLS 1.3 implementation does not support PHA. --- .../catalina/authenticator/LocalStrings.properties | 3 + .../catalina/authenticator/SSLAuthenticator.java | 70 ++++++++++++++++++++++ java/org/apache/tomcat/util/net/SSLHostConfig.java | 12 ++++ java/org/apache/tomcat/util/net/SSLUtilBase.java | 6 +- webapps/docs/changelog.xml | 10 +++- 5 files changed, 98 insertions(+), 3 deletions(-) diff --git a/java/org/apache/catalina/authenticator/LocalStrings.properties b/java/org/apache/catalina/authenticator/LocalStrings.properties index 0030ce3..81acc29 100644 --- a/java/org/apache/catalina/authenticator/LocalStrings.properties +++ b/java/org/apache/catalina/authenticator/LocalStrings.properties @@ -70,3 +70,6 @@ spnegoAuthenticator.authHeaderNoToken=The Negotiate authorization header sent by spnegoAuthenticator.authHeaderNotNego=The authorization header sent by the client did not start with Negotiate spnegoAuthenticator.serviceLoginFail=Unable to login as the service principal spnegoAuthenticator.ticketValidateFail=Failed to validate client supplied ticket + +sslAuthenticatorValve.http2=The context [{0}] in virtual host [{1}] is configured to use CLIENT-CERT authentication and [{2}] is configured to support HTTP/2. Use of CLIENT-CERT authentication is not compatible with the use of HTTP/2. +sslAuthenticatorValve.tls13=The context [{0}] in virtual host [{1}] is configured to use CLIENT-CERT authentication and [{2}] is configured to support TLS 1.3 using JSSE. Use of CLIENT-CERT authentication is not compatible with the use of TLS 1.3 and JSSE. diff --git a/java/org/apache/catalina/authenticator/SSLAuthenticator.java b/java/org/apache/catalina/authenticator/SSLAuthenticator.java index 9844b22..30344b9 100644 --- a/java/org/apache/catalina/authenticator/SSLAuthenticator.java +++ b/java/org/apache/catalina/authenticator/SSLAuthenticator.java @@ -23,9 +23,20 @@ import java.security.cert.X509Certificate; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; +import org.apache.catalina.Container; +import org.apache.catalina.Context; +import org.apache.catalina.Engine; import org.apache.catalina.Globals; +import org.apache.catalina.Host; +import org.apache.catalina.LifecycleException; +import org.apache.catalina.connector.Connector; import org.apache.catalina.connector.Request; import org.apache.coyote.ActionCode; +import org.apache.coyote.UpgradeProtocol; +import org.apache.juli.logging.Log; +import org.apache.juli.logging.LogFactory; +import org.apache.tomcat.util.net.Constants; +import org.apache.tomcat.util.net.SSLHostConfig; /** * An <b>Authenticator</b> and <b>Valve</b> implementation of authentication @@ -35,6 +46,8 @@ import org.apache.coyote.ActionCode; */ public class SSLAuthenticator extends AuthenticatorBase { + private final Log log = LogFactory.getLog(SSLAuthenticator.class); // must not be static + /** * Authenticate the user by checking for the existence of a certificate * chain, validating it against the trust manager for the connector and then @@ -137,4 +150,61 @@ public class SSLAuthenticator extends AuthenticatorBase { return certs; } + + + @Override + protected synchronized void startInternal() throws LifecycleException { + + super.startInternal(); + + /* + * This Valve should only ever be added to a Context and if the Context + * is started there should always be a Host and an Engine but test at + * each stage to be safe. + */ + Container container = getContainer(); + if (!(container instanceof Context)) { + return; + } + Context context = (Context) container; + + container = context.getParent(); + if (!(container instanceof Host)) { + return; + } + Host host = (Host) container; + + container = host.getParent(); + if (!(container instanceof Engine)) { + return; + } + Engine engine = (Engine) container; + + + Connector[] connectors = engine.getService().findConnectors(); + + for (Connector connector : connectors) { + // First check for upgrade + UpgradeProtocol[] upgradeProtocols = connector.findUpgradeProtocols(); + for (UpgradeProtocol upgradeProtocol : upgradeProtocols) { + if ("h2".equals(upgradeProtocol.getAlpnName())) { + log.warn(sm.getString("sslAuthenticatorValve.http2", context.getName(), host.getName(), connector)); + break; + } + } + + // Then check for TLS 1.3 + SSLHostConfig[] sslHostConfigs = connector.findSslHostConfigs(); + for (SSLHostConfig sslHostConfig : sslHostConfigs) { + if (!sslHostConfig.isTls13RenegotiationAvailable()) { + String[] enabledProtocols = sslHostConfig.getEnabledProtocols(); + for (String enbabledProtocol : enabledProtocols) { + if (Constants.SSL_PROTO_TLSv1_3.equals(enbabledProtocol)) { + log.warn(sm.getString("sslAuthenticatorValve.tls13", context.getName(), host.getName(), connector)); + } + } + } + } + } + } } diff --git a/java/org/apache/tomcat/util/net/SSLHostConfig.java b/java/org/apache/tomcat/util/net/SSLHostConfig.java index 81552f4..9a06c52 100644 --- a/java/org/apache/tomcat/util/net/SSLHostConfig.java +++ b/java/org/apache/tomcat/util/net/SSLHostConfig.java @@ -77,6 +77,8 @@ public class SSLHostConfig implements Serializable { // reference is held on the certificate. private transient Long openSslContext = Long.valueOf(0); + private boolean tls13RenegotiationAvailable = false; + // Configuration properties // Internal @@ -130,6 +132,16 @@ public class SSLHostConfig implements Serializable { } + public boolean isTls13RenegotiationAvailable() { + return tls13RenegotiationAvailable; + } + + + public void setTls13RenegotiationAvailable(boolean tls13RenegotiationAvailable) { + this.tls13RenegotiationAvailable = tls13RenegotiationAvailable; + } + + public Long getOpenSslConfContext() { return openSslConfContext; } diff --git a/java/org/apache/tomcat/util/net/SSLUtilBase.java b/java/org/apache/tomcat/util/net/SSLUtilBase.java index 0cac954..0c73006 100644 --- a/java/org/apache/tomcat/util/net/SSLUtilBase.java +++ b/java/org/apache/tomcat/util/net/SSLUtilBase.java @@ -58,7 +58,6 @@ import javax.net.ssl.X509KeyManager; import org.apache.juli.logging.Log; import org.apache.juli.logging.LogFactory; import org.apache.tomcat.util.file.ConfigFileLoader; -import org.apache.tomcat.util.net.SSLHostConfig.CertificateVerification; import org.apache.tomcat.util.net.jsse.JSSEKeyManager; import org.apache.tomcat.util.net.jsse.PEMFile; import org.apache.tomcat.util.res.StringManager; @@ -113,11 +112,14 @@ public abstract class SSLUtilBase implements SSLUtil { this.enabledProtocols = enabledProtocols.toArray(new String[0]); if (enabledProtocols.contains(Constants.SSL_PROTO_TLSv1_3) && - sslHostConfig.getCertificateVerification() == CertificateVerification.OPTIONAL && + sslHostConfig.getCertificateVerification().isOptional() && !isTls13RenegAuthAvailable() && warnTls13) { log.warn(sm.getString("sslUtilBase.tls13.auth")); } + // Make TLS 1.3 renegotiation status visible further up the stack + sslHostConfig.setTls13RenegotiationAvailable(isTls13RenegAuthAvailable()); + // Calculate the enabled ciphers List<String> configuredCiphers = sslHostConfig.getJsseCipherNames(); Set<String> implementedCiphers = getImplementedCiphers(); diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml index 4a3a260..aff1aa1 100644 --- a/webapps/docs/changelog.xml +++ b/webapps/docs/changelog.xml @@ -130,11 +130,19 @@ by Thomas Hoffmann. (remm) </fix> <add> - <bug>65975</bug>: Add a warning if a TLS vitual host is configured with + <bug>65975</bug>: Add a warning if a TLS virtual host is configured with optional certificate authentication and the containing connector is also configured to support HTTP/2 as HTTP/2 does not permit optional certificate authentication. (markt) </add> + <add> + <bug>65975</bug>: Add a warning if a TLS virtual host is configured for + TLS 1.3 with a JSSE implementation and a web application is configured + for <code>CLIENT-CERT</code> authentication. <code>CLIENT-CERT</code> + authentication requires post-handshake authentication (PHA) when used + with TLS 1.3 but the JSSE TLS 1.3 implementation does not support PHA. + (markt) + </add> </changelog> </subsection> <subsection name="Jasper"> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org