You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2015/06/22 23:50:32 UTC
svn commit: r1686949 - in /tomcat/trunk: java/org/apache/catalina/startup/
java/org/apache/tomcat/util/net/ webapps/docs/config/
Author: markt
Date: Mon Jun 22 21:50:31 2015
New Revision: 1686949
URL: http://svn.apache.org/r1686949
Log:
Add configuration support for SSLHostConfigCertificate
Document the new configuration
Get multiple certificates working with NIO (tested with SSLLabs). Should also be working for NIO2 but untested.
Added:
tomcat/trunk/java/org/apache/catalina/startup/CertificateCreateRule.java (with props)
Modified:
tomcat/trunk/java/org/apache/catalina/startup/Catalina.java
tomcat/trunk/java/org/apache/tomcat/util/net/SecureNio2Channel.java
tomcat/trunk/java/org/apache/tomcat/util/net/SecureNioChannel.java
tomcat/trunk/java/org/apache/tomcat/util/net/TLSClientHelloExtractor.java
tomcat/trunk/webapps/docs/config/http.xml
Modified: tomcat/trunk/java/org/apache/catalina/startup/Catalina.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/startup/Catalina.java?rev=1686949&r1=1686948&r2=1686949&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/startup/Catalina.java (original)
+++ tomcat/trunk/java/org/apache/catalina/startup/Catalina.java Mon Jun 22 21:50:31 2015
@@ -340,8 +340,15 @@ public class Catalina {
"org.apache.tomcat.util.net.SSLHostConfig");
digester.addSetProperties("Server/Service/Connector/SSLHostConfig");
digester.addSetNext("Server/Service/Connector/SSLHostConfig",
- "addSslHostConfig",
- "org.apache.tomcat.util.net.SSLHostConfig");
+ "addSslHostConfig",
+ "org.apache.tomcat.util.net.SSLHostConfig");
+
+ digester.addRule("Server/Service/Connector/SSLHostConfig/Certificate",
+ new CertificateCreateRule());
+ digester.addSetProperties("Server/Service/Connector/SSLHostConfig/Certificate");
+ digester.addSetNext("Server/Service/Connector/SSLHostConfig/Certificate",
+ "addCertificate",
+ "org.apache.tomcat.util.net.SSLHostConfigCertificate");
digester.addObjectCreate("Server/Service/Connector/Listener",
null, // MUST be specified in the element
Added: tomcat/trunk/java/org/apache/catalina/startup/CertificateCreateRule.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/startup/CertificateCreateRule.java?rev=1686949&view=auto
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/startup/CertificateCreateRule.java (added)
+++ tomcat/trunk/java/org/apache/catalina/startup/CertificateCreateRule.java Mon Jun 22 21:50:31 2015
@@ -0,0 +1,61 @@
+/*
+ * 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.
+ */
+package org.apache.catalina.startup;
+
+import org.apache.tomcat.util.digester.Rule;
+import org.apache.tomcat.util.net.SSLHostConfig;
+import org.apache.tomcat.util.net.SSLHostConfigCertificate;
+import org.apache.tomcat.util.net.SSLHostConfigCertificate.Type;
+import org.xml.sax.Attributes;
+
+/**
+ * Rule implementation that creates a SSLHostConfigCertificate.
+ */
+public class CertificateCreateRule extends Rule {
+
+ @Override
+ public void begin(String namespace, String name, Attributes attributes) throws Exception {
+ SSLHostConfig sslHostConfig = (SSLHostConfig)digester.peek();
+
+ Type type;
+ String typeValue = attributes.getValue("type");
+ if (typeValue == null || typeValue.length() == 0) {
+ type = Type.UNDEFINED;
+ } else {
+ type = Type.valueOf(typeValue);
+ }
+
+ SSLHostConfigCertificate certificate = new SSLHostConfigCertificate(sslHostConfig, type);
+
+ digester.push(certificate);
+ }
+
+
+ /**
+ * Process the end of this element.
+ *
+ * @param namespace the namespace URI of the matching element, or an
+ * empty string if the parser is not namespace aware or the element has
+ * no namespace
+ * @param name the local name if the parser is namespace aware, or just
+ * the element name otherwise
+ */
+ @Override
+ public void end(String namespace, String name) throws Exception {
+ digester.pop();
+ }
+}
Propchange: tomcat/trunk/java/org/apache/catalina/startup/CertificateCreateRule.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: tomcat/trunk/java/org/apache/catalina/startup/CertificateCreateRule.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: tomcat/trunk/java/org/apache/tomcat/util/net/SecureNio2Channel.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/SecureNio2Channel.java?rev=1686949&r1=1686948&r2=1686949&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/SecureNio2Channel.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/SecureNio2Channel.java Mon Jun 22 21:50:31 2015
@@ -22,6 +22,7 @@ import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
import java.nio.channels.WritePendingException;
+import java.util.Collections;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
@@ -336,10 +337,9 @@ public class SecureNio2Channel extends N
switch (extractor.getResult()) {
case COMPLETE:
hostName = extractor.getSNIValue();
- clientRequestedCiphers = extractor.getClientRequestedCiphers();
- break;
+ //$FALL-THROUGH$ to set the client requested ciphers
case NOT_PRESENT:
- // NO-OP
+ clientRequestedCiphers = extractor.getClientRequestedCiphers();
break;
case NEED_READ:
sc.read(netInBuffer, socket, handshakeReadCompletionHandler);
@@ -350,6 +350,7 @@ public class SecureNio2Channel extends N
log.debug(sm.getString("channel.nio.ssl.sniDefault"));
}
hostName = endpoint.getDefaultSSLHostConfigName();
+ clientRequestedCiphers = Collections.emptyList();
break;
}
Modified: tomcat/trunk/java/org/apache/tomcat/util/net/SecureNioChannel.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/SecureNioChannel.java?rev=1686949&r1=1686948&r2=1686949&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/SecureNioChannel.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/SecureNioChannel.java Mon Jun 22 21:50:31 2015
@@ -23,6 +23,7 @@ import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
+import java.util.Collections;
import java.util.List;
import javax.net.ssl.SSLEngine;
@@ -274,10 +275,9 @@ public class SecureNioChannel extends Ni
switch (extractor.getResult()) {
case COMPLETE:
hostName = extractor.getSNIValue();
- clientRequestedCiphers = extractor.getClientRequestedCiphers();
- break;
+ //$FALL-THROUGH$ to set the client requested ciphers
case NOT_PRESENT:
- // NO-OP
+ clientRequestedCiphers = extractor.getClientRequestedCiphers();
break;
case NEED_READ:
return SelectionKey.OP_READ;
@@ -287,6 +287,7 @@ public class SecureNioChannel extends Ni
log.debug(sm.getString("channel.nio.ssl.sniDefault"));
}
hostName = endpoint.getDefaultSSLHostConfigName();
+ clientRequestedCiphers = Collections.emptyList();
break;
}
Modified: tomcat/trunk/java/org/apache/tomcat/util/net/TLSClientHelloExtractor.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/TLSClientHelloExtractor.java?rev=1686949&r1=1686948&r2=1686949&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/TLSClientHelloExtractor.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/TLSClientHelloExtractor.java Mon Jun 22 21:50:31 2015
@@ -58,7 +58,7 @@ public class TLSClientHelloExtractor {
int pos = netInBuffer.position();
int limit = netInBuffer.limit();
ExtractorResult result = ExtractorResult.NOT_PRESENT;
- List<Cipher> clientRequestedCiphers = null;
+ List<Cipher> clientRequestedCiphers = new ArrayList<>();
String sniValue = null;
try {
// Switch to read mode.
@@ -101,7 +101,6 @@ public class TLSClientHelloExtractor {
// Cipher Suites
// (2 bytes for length, each cipher ID is 2 bytes)
int cipherCount = netInBuffer.getChar() / 2;
- clientRequestedCiphers = new ArrayList<>(cipherCount);
for (int i = 0; i < cipherCount; i++) {
int cipherId = netInBuffer.getChar();
clientRequestedCiphers.add(Cipher.valueOf(cipherId));
@@ -150,7 +149,7 @@ public class TLSClientHelloExtractor {
public List<Cipher> getClientRequestedCiphers() {
- if (result == ExtractorResult.COMPLETE) {
+ if (result == ExtractorResult.COMPLETE || result == ExtractorResult.NOT_PRESENT) {
return clientRequestedCiphers;
} else {
throw new IllegalStateException();
Modified: tomcat/trunk/webapps/docs/config/http.xml
URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/config/http.xml?rev=1686949&r1=1686948&r2=1686949&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/config/http.xml (original)
+++ tomcat/trunk/webapps/docs/config/http.xml Mon Jun 22 21:50:31 2015
@@ -929,8 +929,12 @@
the host name requested by the client. To facilitate this, Tomcat 9 added the
<strong>SSLHostConfig</strong> element which can be used to define one of
these configurations. Any number of <strong>SSLHostConfig</strong> may be
- nested in a <strong>Connector</strong>. For further information, see the
- SSL Support section below.</p>
+ nested in a <strong>Connector</strong>. Tomcat 9 also adds support for
+ mutliple cerificates to be associated with a single
+ <strong>SSLHostConfig</strong>. Each SSL certificate is therefore configured
+ in a <strong>Certificate</strong> element with in an
+ <strong>SSLHostConfig</strong>. For further information, see the SSL Support
+ section below.</p>
</section>
@@ -998,10 +1002,14 @@
match the <code>sslDefaultHost</code> attribute of the
<strong>Connector</strong>.</p>
+ <p>Each <strong>SSLHostConfig</strong> must in turn define at least one
+ <strong>Certificate</strong>. The types of the <strong>Certificate</strong>s
+ must be unique.</p>
+
<p>As of Tomcat 9, the majority of the SSL configuration attributes in the
<strong>Connector</strong> are deprecated. If specified, they will be used to
- configure a <strong>SSLHostConfig</strong> for the
- <code>sslDefaultHost</code>. Note that if an explicit
+ configure a <strong>SSLHostConfig</strong> and <strong>Certificate</strong>for
+ the <code>sslDefaultHost</code>. Note that if an explicit
<strong>SSLHostConfig</strong> element also exists for the
<code>sslDefaultHost</code> then that will be treated as a configuration
error. It is expected that Tomcat 10 will drop support for the SSL
@@ -1018,84 +1026,6 @@
<attributes>
- <attribute name="certificateFile" required="true">
- <p>OpenSSL only.</p>
- <p>Name of the file that contains the server certificate. The format is
- PEM-encoded. Relative paths will be resolved against
- <code>$CATALINA_BASE</code>.</p>
- <p>In addition to the certificate, the file can also contain as optional
- elements DH parameters and/or an EC curve name for ephemeral keys, as
- generated by <code>openssl dhparam</code> and <code>openssl ecparam</code>,
- respectively. The output of the respective OpenSSL command can simply
- be concatenated to the certificate file.</p>
- </attribute>
-
- <attribute name="certificateKeyAlias" required="false">
- <p>JSSE only.</p>
- <p>The alias used for the server key and certificate in the keystore. If
- not specified, the first key read from the keystore will be used. The
- order in which keys are read from the keystore is implementation
- dependent. It may not be the case that keys are read from the keystore in
- the same order as they were added. If more than one key is present in the
- kesytore it is strongly recommended that a keyAlias is configured to
- ensure that the correct key is used.</p>
- </attribute>
-
- <attribute name="certificateKeyFile" required="false">
- <p>OpenSSL only.</p>
- <p>Name of the file that contains the server private key. The format is
- PEM-encoded. The default value is the value of
- <strong>certificateFile</strong> and in this case both certificate and
- private key have to be in this file (NOT RECOMMENDED). Relative paths will
- be resolved against <code>$CATALINA_BASE</code>.</p>
- </attribute>
-
- <attribute name="certificateKeyPassword" required="false">
- <p>The password used to access the private key associated with the server
- certificate from the specified file.</p>
- <p>If not specified, the default behaviour for JSSE is to use the
- <strong>certificateKeystorePassword</strong>. For OpenSSL the default
- behaviour is not to use a password.</p>
- </attribute>
-
- <attribute name="certificateKeystoreFile" required="false">
- <p>JSSE only.</p>
- <p>The pathname of the keystore file where you have stored the server
- certificate and key to be loaded. By default, the pathname is the file
- <code>.keystore</code> in the operating system home directory of the user
- that is running Tomcat. If your <code>keystoreType</code> doesn't need a
- file use <code>""</code> (empty string) or <code>NONE</code> for this
- parameter. Relative paths will be resolved against
- <code>$CATALINA_BASE</code>.</p>
- </attribute>
-
- <attribute name="certificateKeystorePassword" required="false">
- <p>JSSE only.</p>
- <p>The password to use to access the keystore containing the server's
- private key and certificate. If not specified, a default of
- <code>changeit</code> will be used.</p>
- </attribute>
-
- <attribute name="certificateKeystoreProvider" required="false">
- <p>JSSE only.</p>
- <p>The name of the keystore provider to be used for the server
- certificate. If not specified, the value of the system property
- <code>javax.net.ssl.keyStoreProvider</code> is used. If neither this
- attribute nor the system property are set, the list of registered
- providers is traversed in preference order and the first provider that
- supports the <code>keystoreType</code> is used.
- </p>
- </attribute>
-
- <attribute name="certificateKeystoreType" required="false">
- <p>JSSE only.</p>
- <p>The type of keystore file to be used for the server certificate.
- If not specified, the value of the system property
- <code>javax.net.ssl.keyStoreType</code> is used. If neither this attribute
- nor the system property are set, a default value of "<code>JKS</code>". is
- used.</p>
- </attribute>
-
<attribute name="certificateRevocationFile" required="false">
<p>Name of the file that contains the concatenated certificate revocation
lists for the certificate authorities. The format is PEM-encoded. If not
@@ -1310,6 +1240,105 @@
</attributes>
+ </subsection>
+
+ <subsection name="SSL Support - Certificate">
+
+ <p></p>
+
+ <attributes>
+
+ <attribute name="certificateFile" required="true">
+ <p>OpenSSL only.</p>
+ <p>Name of the file that contains the server certificate. The format is
+ PEM-encoded. Relative paths will be resolved against
+ <code>$CATALINA_BASE</code>.</p>
+ <p>In addition to the certificate, the file can also contain as optional
+ elements DH parameters and/or an EC curve name for ephemeral keys, as
+ generated by <code>openssl dhparam</code> and <code>openssl ecparam</code>,
+ respectively. The output of the respective OpenSSL command can simply
+ be concatenated to the certificate file.</p>
+ </attribute>
+
+ <attribute name="certificateKeyAlias" required="false">
+ <p>JSSE only.</p>
+ <p>The alias used for the server key and certificate in the keystore. If
+ not specified, the first key read from the keystore will be used. The
+ order in which keys are read from the keystore is implementation
+ dependent. It may not be the case that keys are read from the keystore in
+ the same order as they were added. If more than one key is present in the
+ kesytore it is strongly recommended that a keyAlias is configured to
+ ensure that the correct key is used.</p>
+ </attribute>
+
+ <attribute name="certificateKeyFile" required="false">
+ <p>OpenSSL only.</p>
+ <p>Name of the file that contains the server private key. The format is
+ PEM-encoded. The default value is the value of
+ <strong>certificateFile</strong> and in this case both certificate and
+ private key have to be in this file (NOT RECOMMENDED). Relative paths will
+ be resolved against <code>$CATALINA_BASE</code>.</p>
+ </attribute>
+
+ <attribute name="certificateKeyPassword" required="false">
+ <p>The password used to access the private key associated with the server
+ certificate from the specified file.</p>
+ <p>If not specified, the default behaviour for JSSE is to use the
+ <strong>certificateKeystorePassword</strong>. For OpenSSL the default
+ behaviour is not to use a password.</p>
+ </attribute>
+
+ <attribute name="certificateKeystoreFile" required="false">
+ <p>JSSE only.</p>
+ <p>The pathname of the keystore file where you have stored the server
+ certificate and key to be loaded. By default, the pathname is the file
+ <code>.keystore</code> in the operating system home directory of the user
+ that is running Tomcat. If your <code>keystoreType</code> doesn't need a
+ file use <code>""</code> (empty string) or <code>NONE</code> for this
+ parameter. Relative paths will be resolved against
+ <code>$CATALINA_BASE</code>.</p>
+ </attribute>
+
+ <attribute name="certificateKeystorePassword" required="false">
+ <p>JSSE only.</p>
+ <p>The password to use to access the keystore containing the server's
+ private key and certificate. If not specified, a default of
+ <code>changeit</code> will be used.</p>
+ </attribute>
+
+ <attribute name="certificateKeystoreProvider" required="false">
+ <p>JSSE only.</p>
+ <p>The name of the keystore provider to be used for the server
+ certificate. If not specified, the value of the system property
+ <code>javax.net.ssl.keyStoreProvider</code> is used. If neither this
+ attribute nor the system property are set, the list of registered
+ providers is traversed in preference order and the first provider that
+ supports the <code>keystoreType</code> is used.
+ </p>
+ </attribute>
+
+ <attribute name="certificateKeystoreType" required="false">
+ <p>JSSE only.</p>
+ <p>The type of keystore file to be used for the server certificate.
+ If not specified, the value of the system property
+ <code>javax.net.ssl.keyStoreType</code> is used. If neither this attribute
+ nor the system property are set, a default value of "<code>JKS</code>". is
+ used.</p>
+ </attribute>
+
+ <attribute name="type" required="false">
+ <p>The type of certificate. This is used to idenitfy the ciphers that are
+ compatible with the certificate. It must be one of <code>UNDEFINED</code>,
+ <code>RSA</code>, <code>DSS</code> or <code>EC</code>. If only one
+ <strong>Certificate</strong> is nested within a <code>SSLHostConfig</code>
+ then this attribute is not required and will default to
+ <code>UNDEFINED</code>. If multiple <strong>Certificate</strong>s are
+ nested within a <code>SSLHostConfig</code> then this attribute is required
+ and each <strong>Certificate</strong> must have a unique type.</p>
+ </attribute>
+
+ </attributes>
+
</subsection>
<subsection name="SSL Support - Connector - NIO and NIO2">
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org