Author: markt
Date: Wed Dec 13 11:17:04 2017
New Revision: 1817999
URL: http://svn.apache.org/viewvc?rev=1817999&view=rev
Log:
Partial fix for https://bz.apache.org/bugzilla/show_bug.cgi?id=61566
Trusted certs are now exposed for virtual hosts configured using a Java key
store.
Added:
tomcat/trunk/webapps/manager/WEB-INF/jsp/connectorTrustedCerts.jsp (with
props)
Modified:
tomcat/trunk/java/org/apache/catalina/manager/HTMLManagerServlet.java
tomcat/trunk/java/org/apache/catalina/manager/LocalStrings.properties
tomcat/trunk/java/org/apache/catalina/manager/ManagerServlet.java
tomcat/trunk/java/org/apache/tomcat/util/net/SSLContext.java
tomcat/trunk/java/org/apache/tomcat/util/net/jsse/JSSESSLContext.java
tomcat/trunk/java/org/apache/tomcat/util/net/openssl/OpenSSLContext.java
tomcat/trunk/webapps/docs/changelog.xml
tomcat/trunk/webapps/manager/WEB-INF/jsp/connectorCerts.jsp
Modified: tomcat/trunk/java/org/apache/catalina/manager/HTMLManagerServlet.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/manager/HTMLManagerServlet.java?rev=1817999&r1=1817998&r2=1817999&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/manager/HTMLManagerServlet.java
(original)
+++ tomcat/trunk/java/org/apache/catalina/manager/HTMLManagerServlet.java Wed
Dec 13 11:17:04 2017
@@ -86,6 +86,7 @@ public final class HTMLManagerServlet ex
static final String sessionDetailJspPath =
"/WEB-INF/jsp/sessionDetail.jsp";
static final String connectorCiphersJspPath =
"/WEB-INF/jsp/connectorCiphers.jsp";
static final String connectorCertsJspPath =
"/WEB-INF/jsp/connectorCerts.jsp";
+ static final String connectorTrustedCertsJspPath =
"/WEB-INF/jsp/connectorTrustedCerts.jsp";
private boolean showProxySessions = false;
@@ -140,7 +141,9 @@ public final class HTMLManagerServlet ex
} else if (command.equals("/sslConnectorCiphers")) {
sslConnectorCiphers(request, response);
} else if (command.equals("/sslConnectorCerts")) {
- sslConnectorHostCerts(request, response);
+ sslConnectorCerts(request, response);
+ } else if (command.equals("/sslConnectorTrustedCerts")) {
+ sslConnectorTrustedCerts(request, response);
} else if (command.equals("/upload") || command.equals("/deploy") ||
command.equals("/reload") || command.equals("/undeploy") ||
command.equals("/expire") || command.equals("/start") ||
@@ -538,7 +541,7 @@ public final class HTMLManagerServlet ex
writer.print(MessageFormat.format(UPLOAD_SECTION, args));
// Diagnostics section
- args = new Object[12];
+ args = new Object[15];
args[0] = smClient.getString("htmlManagerServlet.diagnosticsTitle");
args[1] = smClient.getString("htmlManagerServlet.diagnosticsLeak");
args[2] = response.encodeURL(
@@ -554,6 +557,10 @@ public final class HTMLManagerServlet ex
request.getContextPath() + "/html/sslConnectorCerts");
args[10] =
smClient.getString("htmlManagerServlet.diagnosticsSslConnectorCertsButton");
args[11] =
smClient.getString("htmlManagerServlet.diagnosticsSslConnectorCertsText");
+ args[12] = response.encodeURL(
+ request.getContextPath() + "/html/sslConnectorTrustedCerts");
+ args[13] =
smClient.getString("htmlManagerServlet.diagnosticsSslConnectorTrustedCertsButton");
+ args[14] =
smClient.getString("htmlManagerServlet.diagnosticsSslConnectorTrustedCertsText");
writer.print(MessageFormat.format(DIAGNOSTICS_SECTION, args));
// Server Header Section
@@ -735,7 +742,7 @@ public final class HTMLManagerServlet ex
}
- protected void sslConnectorHostCerts(HttpServletRequest request,
+ protected void sslConnectorCerts(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException
{
request.setAttribute("certList", getConnectorCerts());
getServletContext().getRequestDispatcher(
@@ -743,6 +750,14 @@ public final class HTMLManagerServlet ex
}
+ protected void sslConnectorTrustedCerts(HttpServletRequest request,
+ HttpServletResponse response) throws ServletException, IOException
{
+ request.setAttribute("trustedCertList", getConnectorTrustedCerts());
+ getServletContext().getRequestDispatcher(
+ connectorTrustedCertsJspPath).forward(request, response);
+ }
+
+
/**
* @see javax.servlet.Servlet#getServletInfo()
*/
@@ -1365,11 +1380,24 @@ public final class HTMLManagerServlet ex
"</form>\n" +
"</td>\n" +
"</tr>\n" +
+
+ "<tr>\n" +
+ " <td colspan=\"2\">\n" +
+ "<form method=\"post\" action=\"{12}\">\n" +
+ "<table cellspacing=\"0\" cellpadding=\"3\">\n" +
+ "<tr>\n" +
+ " <td class=\"row-left\">\n" +
+ " <input type=\"submit\" value=\"{13}\">\n" +
+ " </td>\n" +
+ " <td class=\"row-left\">\n" +
+ " <small>{14}</small>\n" +
+ " </td>\n" +
+ "</tr>\n" +
"</table>\n" +
"</form>\n" +
-
"</td>\n" +
"</tr>\n" +
+
"</table>\n" +
"<br>";
}
Modified: tomcat/trunk/java/org/apache/catalina/manager/LocalStrings.properties
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/manager/LocalStrings.properties?rev=1817999&r1=1817998&r2=1817999&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/manager/LocalStrings.properties
(original)
+++ tomcat/trunk/java/org/apache/catalina/manager/LocalStrings.properties Wed
Dec 13 11:17:04 2017
@@ -53,6 +53,8 @@ htmlManagerServlet.diagnosticsSslConnect
htmlManagerServlet.diagnosticsSslConnectorCipherText=List the configured TLS
virtual hosts and the ciphers for each
htmlManagerServlet.diagnosticsSslConnectorCertsButton=Certificates
htmlManagerServlet.diagnosticsSslConnectorCertsText=List the configured TLS
virtual hosts and the certificate chain for each
+htmlManagerServlet.diagnosticsSslConnectorTrustedCertsButton=Trusted
Certificates
+htmlManagerServlet.diagnosticsSslConnectorTrustedCertsText=List the configured
TLS virtual hosts and the trusted certificates for each
htmlManagerServlet.diagnosticsTitle=Diagnostics
htmlManagerServlet.findleaksList=\
The following web applications were stopped (reloaded, undeployed), but
their\n\
@@ -118,6 +120,7 @@ managerServlet.stopped=OK - Stopped appl
managerServlet.storeConfig.invalidMBean=FAIL - Unable to find the StoreConfig
Mbean. [{0}] is not a valid name for an MBean.
managerServlet.storeConfig.noMBean=FAIL - No StoreConfig MBean registered at
[{0}]. Registration is typically performed by the StoreConfigLifecycleListener.
managerServlet.threaddump=OK - JVM thread dump
+managerServlet.trustedCertsNotConfigured=No trusted certificates are
configured for this virtual host
managerServlet.undeployed=OK - Undeployed application at context path [{0}]
managerServlet.unknownCommand=FAIL - Unknown command [{0}]
managerServlet.vminfo=OK - VM info
Modified: tomcat/trunk/java/org/apache/catalina/manager/ManagerServlet.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/manager/ManagerServlet.java?rev=1817999&r1=1817998&r2=1817999&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/manager/ManagerServlet.java (original)
+++ tomcat/trunk/java/org/apache/catalina/manager/ManagerServlet.java Wed Dec
13 11:17:04 2017
@@ -1761,4 +1761,40 @@ public class ManagerServlet extends Http
return result;
}
+
+ protected Map<String,List<String>> getConnectorTrustedCerts() {
+ Map<String,List<String>> result = new HashMap<>();
+
+ Engine e = (Engine) host.getParent();
+ Service s = e.getService();
+ Connector connectors[] = s.findConnectors();
+ for (Connector connector : connectors) {
+ if (Boolean.TRUE.equals(connector.getProperty("SSLEnabled"))) {
+ SSLHostConfig[] sslHostConfigs =
connector.getProtocolHandler().findSslHostConfigs();
+ for (SSLHostConfig sslHostConfig : sslHostConfigs) {
+ String name = connector.toString() + "-" +
sslHostConfig.getHostName();
+ List<String> certList = new ArrayList<>();
+ SSLContext sslContext =
+
sslHostConfig.getCertificates().iterator().next().getSslContext();
+ X509Certificate[] certs = sslContext.getAcceptedIssuers();
+ if (certs == null) {
+
certList.add(sm.getString("managerServlet.certsNotAvailable"));
+ } else if (certs.length == 0) {
+
certList.add(sm.getString("managerServlet.trustedCertsNotConfigured"));
+ } else {
+ for (Certificate cert : certs) {
+ certList.add(cert.toString());
+ }
+ }
+ result.put(name, certList);
+ }
+ } else {
+ List<String> certList = new ArrayList<>(1);
+ certList.add(sm.getString("managerServlet.notSslConnector"));
+ result.put(connector.toString(), certList);
+ }
+ }
+
+ return result;
+ }
}
Modified: tomcat/trunk/java/org/apache/tomcat/util/net/SSLContext.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/SSLContext.java?rev=1817999&r1=1817998&r2=1817999&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/SSLContext.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/SSLContext.java Wed Dec 13
11:17:04 2017
@@ -49,4 +49,6 @@ public interface SSLContext {
public SSLParameters getSupportedSSLParameters();
public X509Certificate[] getCertificateChain(String alias);
+
+ public X509Certificate[] getAcceptedIssuers();
}
Modified: tomcat/trunk/java/org/apache/tomcat/util/net/jsse/JSSESSLContext.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/jsse/JSSESSLContext.java?rev=1817999&r1=1817998&r2=1817999&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/jsse/JSSESSLContext.java
(original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/jsse/JSSESSLContext.java Wed
Dec 13 11:17:04 2017
@@ -21,6 +21,8 @@ import java.security.KeyManagementExcept
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;
+import java.util.HashSet;
+import java.util.Set;
import javax.net.ssl.KeyManager;
import javax.net.ssl.SSLEngine;
@@ -29,6 +31,7 @@ import javax.net.ssl.SSLServerSocketFact
import javax.net.ssl.SSLSessionContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509KeyManager;
+import javax.net.ssl.X509TrustManager;
import org.apache.tomcat.util.net.SSLContext;
@@ -36,6 +39,7 @@ class JSSESSLContext implements SSLConte
private javax.net.ssl.SSLContext context;
private KeyManager[] kms;
+ private TrustManager[] tms;
JSSESSLContext(String protocol) throws NoSuchAlgorithmException {
context = javax.net.ssl.SSLContext.getInstance(protocol);
@@ -45,6 +49,7 @@ class JSSESSLContext implements SSLConte
public void init(KeyManager[] kms, TrustManager[] tms, SecureRandom sr)
throws KeyManagementException {
this.kms = kms;
+ this.tms = tms;
context.init(kms, tms, sr);
}
@@ -84,4 +89,22 @@ class JSSESSLContext implements SSLConte
}
return result;
}
+
+ @Override
+ public X509Certificate[] getAcceptedIssuers() {
+ Set<X509Certificate> certs = new HashSet<>();
+ if (tms != null) {
+ for (TrustManager tm : tms) {
+ if (tm instanceof X509TrustManager) {
+ X509Certificate[] accepted = ((X509TrustManager)
tm).getAcceptedIssuers();
+ if (accepted != null) {
+ for (X509Certificate c : accepted) {
+ certs.add(c);
+ }
+ }
+ }
+ }
+ }
+ return certs.toArray(new X509Certificate[certs.size()]);
+ }
}
Modified:
tomcat/trunk/java/org/apache/tomcat/util/net/openssl/OpenSSLContext.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/openssl/OpenSSLContext.java?rev=1817999&r1=1817998&r2=1817999&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/openssl/OpenSSLContext.java
(original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/openssl/OpenSSLContext.java
Wed Dec 13 11:17:04 2017
@@ -69,6 +69,7 @@ public class OpenSSLContext implements o
private final SSLHostConfigCertificate certificate;
private OpenSSLSessionContext sessionContext;
private X509KeyManager x509KeyManager;
+ private X509TrustManager x509TrustManager;
private final List<String> negotiableProtocols;
@@ -326,13 +327,13 @@ public class OpenSSLContext implements o
if (tms != null) {
// Client certificate verification based on custom trust
managers
- final X509TrustManager manager = chooseTrustManager(tms);
+ x509TrustManager = chooseTrustManager(tms);
SSLContext.setCertVerifyCallback(ctx, new
CertificateVerifier() {
@Override
public boolean verify(long ssl, byte[][] chain, String
auth) {
X509Certificate[] peerCerts = certificates(chain);
try {
- manager.checkClientTrusted(peerCerts, auth);
+ x509TrustManager.checkClientTrusted(peerCerts,
auth);
return true;
} catch (Exception e) {
log.debug(sm.getString("openssl.certificateVerificationFailed"), e);
@@ -344,7 +345,7 @@ public class OpenSSLContext implements o
// certificate issuers, so that their subjects can be presented
// by the server during the handshake to allow the client
choosing
// an acceptable certificate
- for (X509Certificate caCert : manager.getAcceptedIssuers()) {
+ for (X509Certificate caCert :
x509TrustManager.getAcceptedIssuers()) {
SSLContext.addClientCACertificateRaw(ctx,
caCert.getEncoded());
if (log.isDebugEnabled())
log.debug(sm.getString("openssl.addedClientCaCert",
caCert.toString()));
@@ -516,19 +517,31 @@ public class OpenSSLContext implements o
@Override
public X509Certificate[] getCertificateChain(String alias) {
- if (alias == null) {
- alias = "tomcat";
- }
- X509Certificate[] chain = x509KeyManager.getCertificateChain(alias);
- if (chain == null) {
- alias = findAlias(x509KeyManager, certificate);
+ X509Certificate[] chain = null;
+ if (x509KeyManager != null) {
+ if (alias == null) {
+ alias = "tomcat";
+ }
chain = x509KeyManager.getCertificateChain(alias);
+ if (chain == null) {
+ alias = findAlias(x509KeyManager, certificate);
+ chain = x509KeyManager.getCertificateChain(alias);
+ }
}
return chain;
}
@Override
+ public X509Certificate[] getAcceptedIssuers() {
+ X509Certificate[] acceptedCerts = null;
+ if (x509TrustManager != null) {
+ acceptedCerts = x509TrustManager.getAcceptedIssuers();
+ }
+ return acceptedCerts;
+ }
+
+ @Override
protected void finalize() throws Throwable {
/*
* When an SSLHostConfig is replaced at runtime, it is not possible to
Modified: tomcat/trunk/webapps/docs/changelog.xml
URL:
http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/changelog.xml?rev=1817999&r1=1817998&r2=1817999&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/changelog.xml (original)
+++ tomcat/trunk/webapps/docs/changelog.xml Wed Dec 13 11:17:04 2017
@@ -92,9 +92,9 @@
</add>
<add>
<bug>61566</bug>: Provide a partial fix for this issue. The fix exposes
- the currently in use certificate chain for all virtual hosts configured
- using the JSSE style (keystore) TLS configuration via the Manager web
- application.
+ the currently in use certificate chain and list of trusted certificates
+ for all virtual hosts configured using the JSSE style (keystore) TLS
+ configuration via the Manager web application.
</add>
</changelog>
</subsection>
Modified: tomcat/trunk/webapps/manager/WEB-INF/jsp/connectorCerts.jsp
URL:
http://svn.apache.org/viewvc/tomcat/trunk/webapps/manager/WEB-INF/jsp/connectorCerts.jsp?rev=1817999&r1=1817998&r2=1817999&view=diff
==============================================================================
--- tomcat/trunk/webapps/manager/WEB-INF/jsp/connectorCerts.jsp (original)
+++ tomcat/trunk/webapps/manager/WEB-INF/jsp/connectorCerts.jsp Wed Dec 13
11:17:04 2017
@@ -37,7 +37,7 @@
<title>Configured certificate chains per Connector</title>
</head>
<body>
-<h1>Configured ciphers per Connector</h1>
+<h1>Configured certificate chains per Connector</h1>
<table border="1" cellpadding="2" cellspacing="2" width="100%">
<thead>
Added: tomcat/trunk/webapps/manager/WEB-INF/jsp/connectorTrustedCerts.jsp
URL:
http://svn.apache.org/viewvc/tomcat/trunk/webapps/manager/WEB-INF/jsp/connectorTrustedCerts.jsp?rev=1817999&view=auto
==============================================================================
--- tomcat/trunk/webapps/manager/WEB-INF/jsp/connectorTrustedCerts.jsp (added)
+++ tomcat/trunk/webapps/manager/WEB-INF/jsp/connectorTrustedCerts.jsp Wed Dec
13 11:17:04 2017
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<%--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+--%>
+<%@page session="false" contentType="text/html; charset=ISO-8859-1" %>
+<%@page import="java.util.Map" %>
+<%@page import="java.util.Map.Entry" %>
+<%@page import="java.util.List" %>
+<!DOCTYPE html
+ PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
+<% Map<String,List<String>> trustedCertList = (Map<String,List<String>>)
request.getAttribute("trustedCertList");
+%>
+<head>
+ <meta http-equiv="content-type" content="text/html; charset=iso-8859-1"/>
+ <meta http-equiv="pragma" content="no-cache"/><!-- HTTP 1.0 -->
+ <meta http-equiv="cache-control" content="no-cache,must-revalidate"/><!--
HTTP 1.1 -->
+ <meta http-equiv="expires" content="0"/><!-- 0 is an invalid value and
should be treated as 'now' -->
+ <meta http-equiv="content-language" content="en"/>
+ <meta name="copyright" content="copyright 2005-2017 the Apache Software
Foundation"/>
+ <meta name="robots" content="noindex,nofollow,noarchive"/>
+ <title>Trusted certificates per Connector</title>
+</head>
+<body>
+<h1>Trusted certificates per Connector</h1>
+
+<table border="1" cellpadding="2" cellspacing="2" width="100%">
+ <thead>
+ <tr>
+ <th>Connector / TLS Virtual Host</th>
+ <th>Trusted Certificates</th>
+ </tr>
+ </thead>
+ <tbody>
+ <%
+ for (Map.Entry<String, List<String>> entry :
trustedCertList.entrySet()) {
+ %>
+ <tr>
+ <td><%=entry.getKey()%></td>
+ <td>
+ <%
+ for (String cert : entry.getValue()) {
+ %>
+ <pre><%=cert%></pre>
+ <%
+ }
+ %>
+ </td>
+ </tr>
+ <%
+ }
+ %>
+ </tbody>
+</table>
+
+<form method="get" action="<%=request.getContextPath()%>/html">
+ <p style="text-align: center;">
+ <input type="submit" value="Return to main page" />
+ </p>
+</form>
+
+<%--div style="display: none;">
+<p>
+ <a href="http://validator.w3.org/check?uri=referer"><img
+ src="http://www.w3.org/Icons/valid-html401"
+ alt="Valid HTML 4.01!" height="31" width="88"></a>
+ <a href="http://validator.w3.org/check?uri=referer"><img
+ src="http://www.w3.org/Icons/valid-xhtml10"
+ alt="Valid XHTML 1.0!" height="31" width="88" /></a>
+ <a href="http://validator.w3.org/check?uri=referer"><img
+ src="http://www.w3.org/Icons/valid-xhtml11"
+ alt="Valid XHTML 1.1!" height="31" width="88" /></a>
+</p>
+</div--%>
+
+</body>
+</html>
Propchange: tomcat/trunk/webapps/manager/WEB-INF/jsp/connectorTrustedCerts.jsp
------------------------------------------------------------------------------
svn:eol-style = native
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]