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/19 23:20:02 UTC
svn commit: r1686501 - in /tomcat/trunk/java/org/apache/tomcat/util/net: ./
jsse/ jsse/openssl/
Author: markt
Date: Fri Jun 19 21:20:02 2015
New Revision: 1686501
URL: http://svn.apache.org/r1686501
Log:
First pass at an implementation that supports multiple certificate types for all connectors.
Smoke test (SNI with 2 hosts with NIO) passes.
Further testing required.
Configuration via server.xml is still TODO
Modified:
tomcat/trunk/java/org/apache/tomcat/util/net/AbstractJsseEndpoint.java
tomcat/trunk/java/org/apache/tomcat/util/net/SSLHostConfig.java
tomcat/trunk/java/org/apache/tomcat/util/net/SSLHostConfigCertificate.java
tomcat/trunk/java/org/apache/tomcat/util/net/jsse/JSSESocketFactory.java
tomcat/trunk/java/org/apache/tomcat/util/net/jsse/openssl/Authentication.java
tomcat/trunk/java/org/apache/tomcat/util/net/jsse/openssl/OpenSSLCipherConfigurationParser.java
Modified: tomcat/trunk/java/org/apache/tomcat/util/net/AbstractJsseEndpoint.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/AbstractJsseEndpoint.java?rev=1686501&r1=1686500&r2=1686501&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/AbstractJsseEndpoint.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/AbstractJsseEndpoint.java Fri Jun 19 21:20:02 2015
@@ -16,6 +16,9 @@
*/
package org.apache.tomcat.util.net;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
@@ -132,19 +135,36 @@ public abstract class AbstractJsseEndpoi
private SSLHostConfigCertificate selectCertificate(
- SSLHostConfig sslHostConfig, List<Cipher> clientRequestedCiphers) {
+ SSLHostConfig sslHostConfig, List<Cipher> clientCiphers) {
Set<SSLHostConfigCertificate> certificates = sslHostConfig.getCertificates(true);
if (certificates.size() == 1) {
return certificates.iterator().next();
}
- // TODO:
- // Need to select correct certificate based on the ciphers requested by
- // the client, the ciphers configured for the server and which is
- // configured to define the preference order
+ LinkedHashSet<Cipher> serverCiphers = sslHostConfig.getCipherList();
- // For now, just return the first certificate
+ List<Cipher> candidateCiphers = new ArrayList<>();
+ if (sslHostConfig.getHonorCipherOrder()) {
+ candidateCiphers.addAll(serverCiphers);
+ candidateCiphers.retainAll(clientCiphers);
+ } else {
+ candidateCiphers.addAll(clientCiphers);
+ candidateCiphers.retainAll(serverCiphers);
+ }
+
+ Iterator<Cipher> candidateIter = candidateCiphers.iterator();
+ while (candidateIter.hasNext()) {
+ Cipher candidate = candidateIter.next();
+ for (SSLHostConfigCertificate certificate : certificates) {
+ if (certificate.getType().isCompatibleWith(candidate.getAu())) {
+ return certificate;
+ }
+ }
+ }
+
+ // No matches. Just return the first certificate. The handshake will
+ // then fail due to no matching ciphers.
return certificates.iterator().next();
}
Modified: tomcat/trunk/java/org/apache/tomcat/util/net/SSLHostConfig.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/SSLHostConfig.java?rev=1686501&r1=1686500&r2=1686501&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/SSLHostConfig.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/SSLHostConfig.java Fri Jun 19 21:20:02 2015
@@ -19,6 +19,8 @@ package org.apache.tomcat.util.net;
import java.io.File;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -27,6 +29,7 @@ import javax.net.ssl.TrustManagerFactory
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
+import org.apache.tomcat.util.net.jsse.openssl.Cipher;
import org.apache.tomcat.util.net.jsse.openssl.OpenSSLCipherConfigurationParser;
import org.apache.tomcat.util.res.StringManager;
@@ -75,6 +78,8 @@ public class SSLHostConfig {
private CertificateVerification certificateVerification = CertificateVerification.NONE;
private int certificateVerificationDepth = 10;
private String ciphers = "HIGH:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!kRSA";
+ private LinkedHashSet<Cipher> cipherList = null;
+ private List<String> jsseCipherNames = null;
private boolean honorCipherOrder = true;
private Set<String> protocols = new HashSet<>();
// JSSE
@@ -250,6 +255,9 @@ public class SSLHostConfig {
} else {
this.ciphers = ciphersList;
}
+ this.cipherList = null;
+ this.jsseCipherNames = null;
+
}
@@ -258,6 +266,22 @@ public class SSLHostConfig {
}
+ public LinkedHashSet<Cipher> getCipherList() {
+ if (cipherList == null) {
+ cipherList = OpenSSLCipherConfigurationParser.parse(ciphers);
+ }
+ return cipherList;
+ }
+
+
+ public List<String> getJsseCipherNames() {
+ if (jsseCipherNames == null) {
+ jsseCipherNames = OpenSSLCipherConfigurationParser.convertForJSSE(getCipherList());
+ }
+ return jsseCipherNames;
+ }
+
+
public void setHonorCipherOrder(boolean honorCipherOrder) {
this.honorCipherOrder = honorCipherOrder;
}
Modified: tomcat/trunk/java/org/apache/tomcat/util/net/SSLHostConfigCertificate.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/SSLHostConfigCertificate.java?rev=1686501&r1=1686500&r2=1686501&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/SSLHostConfigCertificate.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/SSLHostConfigCertificate.java Fri Jun 19 21:20:02 2015
@@ -16,7 +16,11 @@
*/
package org.apache.tomcat.util.net;
+import java.util.HashSet;
+import java.util.Set;
+
import org.apache.tomcat.util.net.AbstractJsseEndpoint.SSLContextWrapper;
+import org.apache.tomcat.util.net.jsse.openssl.Authentication;
public class SSLHostConfigCertificate {
@@ -174,9 +178,25 @@ public class SSLHostConfigCertificate {
// Nested types
public static enum Type {
+
UNDEFINED,
- RSA,
- DSA,
- ECC
+ RSA(Authentication.RSA),
+ DSA(Authentication.DSS),
+ ECC(Authentication.ECDH, Authentication.ECDSA);
+
+ private final Set<Authentication> compatibleAuthentications;
+
+ private Type(Authentication... authentications) {
+ compatibleAuthentications = new HashSet<>();
+ if (authentications != null) {
+ for (Authentication authentication : authentications) {
+ compatibleAuthentications.add(authentication);
+ }
+ }
+ }
+
+ public boolean isCompatibleWith(Authentication au) {
+ return compatibleAuthentications.contains(au);
+ }
}
}
Modified: tomcat/trunk/java/org/apache/tomcat/util/net/jsse/JSSESocketFactory.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/jsse/JSSESocketFactory.java?rev=1686501&r1=1686500&r2=1686501&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/jsse/JSSESocketFactory.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/jsse/JSSESocketFactory.java Fri Jun 19 21:20:02 2015
@@ -58,7 +58,6 @@ import org.apache.tomcat.util.net.SSLCon
import org.apache.tomcat.util.net.SSLHostConfig;
import org.apache.tomcat.util.net.SSLHostConfigCertificate;
import org.apache.tomcat.util.net.SSLUtil;
-import org.apache.tomcat.util.net.jsse.openssl.OpenSSLCipherConfigurationParser;
import org.apache.tomcat.util.res.StringManager;
/**
@@ -142,17 +141,14 @@ public class JSSESocketFactory implement
@Override
public String[] getEnableableCiphers(SSLContext context) {
- String requestedCiphersStr = sslHostConfig.getCiphers();
-
- List<String> requestedCiphers =
- OpenSSLCipherConfigurationParser.parseExpression(requestedCiphersStr);
+ List<String> requestedCiphers = sslHostConfig.getJsseCipherNames();
List<String> ciphers = new ArrayList<>(requestedCiphers);
ciphers.retainAll(Arrays.asList(context.getSupportedSSLParameters().getCipherSuites()));
if (ciphers.isEmpty()) {
log.warn(sm.getString("jsse.requested_ciphers_not_supported",
- requestedCiphersStr));
+ sslHostConfig.getCiphers()));
}
if (log.isDebugEnabled()) {
log.debug(sm.getString("jsse.enableable_ciphers", ciphers));
Modified: tomcat/trunk/java/org/apache/tomcat/util/net/jsse/openssl/Authentication.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/jsse/openssl/Authentication.java?rev=1686501&r1=1686500&r2=1686501&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/jsse/openssl/Authentication.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/jsse/openssl/Authentication.java Fri Jun 19 21:20:02 2015
@@ -17,7 +17,7 @@
package org.apache.tomcat.util.net.jsse.openssl;
-enum Authentication {
+public enum Authentication {
RSA /* RSA auth */,
DSS /* DSS auth */,
aNULL /* no auth (i.e. use ADH or AECDH) */,
Modified: tomcat/trunk/java/org/apache/tomcat/util/net/jsse/openssl/OpenSSLCipherConfigurationParser.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/jsse/openssl/OpenSSLCipherConfigurationParser.java?rev=1686501&r1=1686500&r2=1686501&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/jsse/openssl/OpenSSLCipherConfigurationParser.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/jsse/openssl/OpenSSLCipherConfigurationParser.java Fri Jun 19 21:20:02 2015
@@ -629,7 +629,7 @@ public class OpenSSLCipherConfigurationP
return result;
}
- static LinkedHashSet<Cipher> parse(String expression) {
+ public static LinkedHashSet<Cipher> parse(String expression) {
if (!initialized) {
init();
}
@@ -676,7 +676,7 @@ public class OpenSSLCipherConfigurationP
return defaultSort(ciphers);
}
- static List<String> convertForJSSE(Collection<Cipher> ciphers) {
+ public static List<String> convertForJSSE(Collection<Cipher> ciphers) {
List<String> result = new ArrayList<>(ciphers.size());
for (Cipher cipher : ciphers) {
result.addAll(cipher.getJsseNames());
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org