You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by br...@apache.org on 2011/11/29 17:41:25 UTC

svn commit: r1207958 - in /cassandra/branches/cassandra-1.0: CHANGES.txt conf/cassandra.yaml src/java/org/apache/cassandra/config/EncryptionOptions.java src/java/org/apache/cassandra/security/SSLFactory.java

Author: brandonwilliams
Date: Tue Nov 29 16:41:23 2011
New Revision: 1207958

URL: http://svn.apache.org/viewvc?rev=1207958&view=rev
Log:
Filter out unavailable cipher suites when using encryption.
Patch by Vijay, reviewed by brandonwilliams for CASSANDRA-3278

Modified:
    cassandra/branches/cassandra-1.0/CHANGES.txt
    cassandra/branches/cassandra-1.0/conf/cassandra.yaml
    cassandra/branches/cassandra-1.0/src/java/org/apache/cassandra/config/EncryptionOptions.java
    cassandra/branches/cassandra-1.0/src/java/org/apache/cassandra/security/SSLFactory.java

Modified: cassandra/branches/cassandra-1.0/CHANGES.txt
URL: http://svn.apache.org/viewvc/cassandra/branches/cassandra-1.0/CHANGES.txt?rev=1207958&r1=1207957&r2=1207958&view=diff
==============================================================================
--- cassandra/branches/cassandra-1.0/CHANGES.txt (original)
+++ cassandra/branches/cassandra-1.0/CHANGES.txt Tue Nov 29 16:41:23 2011
@@ -1,6 +1,6 @@
 1.0.5
  * add command to stop compactions (CASSANDRA-1740)
-
+ * filter out unavailable cipher suites when using encryption (CASSANDRA-3178)
 
 1.0.4
  * fix self-hinting of timed out read repair updates and make hinted handoff

Modified: cassandra/branches/cassandra-1.0/conf/cassandra.yaml
URL: http://svn.apache.org/viewvc/cassandra/branches/cassandra-1.0/conf/cassandra.yaml?rev=1207958&r1=1207957&r2=1207958&view=diff
==============================================================================
--- cassandra/branches/cassandra-1.0/conf/cassandra.yaml (original)
+++ cassandra/branches/cassandra-1.0/conf/cassandra.yaml Tue Nov 29 16:41:23 2011
@@ -415,9 +415,15 @@ index_interval: 128
 # The passwords used in these options must match the passwords used when generating
 # the keystore and truststore.  For instructions on generating these files, see:
 # http://download.oracle.com/javase/6/docs/technotes/guides/security/jsse/JSSERefGuide.html#CreateKeystore
+#
 encryption_options:
     internode_encryption: none
     keystore: conf/.keystore
     keystore_password: cassandra
     truststore: conf/.truststore
     truststore_password: cassandra
+    # More advanced defaults below:
+    # protocol: TLS
+    # algorithm: SunX509
+    # store_type: JKS
+    # cipher_suites: [TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA]

Modified: cassandra/branches/cassandra-1.0/src/java/org/apache/cassandra/config/EncryptionOptions.java
URL: http://svn.apache.org/viewvc/cassandra/branches/cassandra-1.0/src/java/org/apache/cassandra/config/EncryptionOptions.java?rev=1207958&r1=1207957&r2=1207958&view=diff
==============================================================================
--- cassandra/branches/cassandra-1.0/src/java/org/apache/cassandra/config/EncryptionOptions.java (original)
+++ cassandra/branches/cassandra-1.0/src/java/org/apache/cassandra/config/EncryptionOptions.java Tue Nov 29 16:41:23 2011
@@ -28,7 +28,11 @@ public class EncryptionOptions
     public String keystore_password = "cassandra";
     public String truststore = "conf/.truststore";
     public String truststore_password = "cassandra";
-    public String[] cipherSuites = {"TLS_RSA_WITH_AES_128_CBC_SHA", "TLS_RSA_WITH_AES_256_CBC_SHA"};
+    public String[] cipher_suites = {"TLS_RSA_WITH_AES_128_CBC_SHA", "TLS_RSA_WITH_AES_256_CBC_SHA"};
+    public String protocol = "TLS";
+    public String algorithm = "SunX509";
+    public String store_type = "JKS";
+
 
     public static enum InternodeEncryption
     {

Modified: cassandra/branches/cassandra-1.0/src/java/org/apache/cassandra/security/SSLFactory.java
URL: http://svn.apache.org/viewvc/cassandra/branches/cassandra-1.0/src/java/org/apache/cassandra/security/SSLFactory.java?rev=1207958&r1=1207957&r2=1207958&view=diff
==============================================================================
--- cassandra/branches/cassandra-1.0/src/java/org/apache/cassandra/security/SSLFactory.java (original)
+++ cassandra/branches/cassandra-1.0/src/java/org/apache/cassandra/security/SSLFactory.java Tue Nov 29 16:41:23 2011
@@ -26,6 +26,7 @@ import java.io.IOException;
 import java.net.InetAddress;
 import java.net.InetSocketAddress;
 import java.security.KeyStore;
+import java.util.Set;
 
 import javax.net.ssl.KeyManagerFactory;
 import javax.net.ssl.SSLContext;
@@ -35,6 +36,11 @@ import javax.net.ssl.TrustManagerFactory
 
 import org.apache.cassandra.config.EncryptionOptions;
 import org.apache.cassandra.io.util.FileUtils;
+import org.apache.commons.lang.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.Sets;
 
 /**
  * A Factory for providing and setting up Client and Server SSL wrapped
@@ -42,16 +48,15 @@ import org.apache.cassandra.io.util.File
  */
 public final class SSLFactory
 {
-    private static final String PROTOCOL = "TLS";
-    private static final String ALGORITHM = "SunX509";
-    private static final String STORE_TYPE = "JKS";
+    private static final Logger logger_ = LoggerFactory.getLogger(SSLFactory.class);
 
     public static SSLServerSocket getServerSocket(EncryptionOptions options, InetAddress address, int port) throws IOException
     {
         SSLContext ctx = createSSLContext(options);
         SSLServerSocket serverSocket = (SSLServerSocket)ctx.getServerSocketFactory().createServerSocket();
         serverSocket.setReuseAddress(true);
-        serverSocket.setEnabledCipherSuites(options.cipherSuites);
+        String[] suits = filterCipherSuites(serverSocket.getSupportedCipherSuites(), options.cipher_suites);
+        serverSocket.setEnabledCipherSuites(suits);
         serverSocket.bind(new InetSocketAddress(address, port), 100);
         return serverSocket;
     }
@@ -61,7 +66,8 @@ public final class SSLFactory
     {
         SSLContext ctx = createSSLContext(options);
         SSLSocket socket = (SSLSocket) ctx.getSocketFactory().createSocket(address, port, localAddress, localPort);
-        socket.setEnabledCipherSuites(options.cipherSuites);
+        String[] suits = filterCipherSuites(socket.getSupportedCipherSuites(), options.cipher_suites);
+        socket.setEnabledCipherSuites(suits);
         return socket;
     }
 
@@ -70,7 +76,8 @@ public final class SSLFactory
     {
         SSLContext ctx = createSSLContext(options);
         SSLSocket socket = (SSLSocket) ctx.getSocketFactory().createSocket();
-        socket.setEnabledCipherSuites(options.cipherSuites);
+        String[] suits = filterCipherSuites(socket.getSupportedCipherSuites(), options.cipher_suites);
+        socket.setEnabledCipherSuites(suits);
         return socket;
     }
 
@@ -81,17 +88,17 @@ public final class SSLFactory
         SSLContext ctx;
         try
         {
-            ctx = SSLContext.getInstance(PROTOCOL);
+            ctx = SSLContext.getInstance(options.protocol);
             TrustManagerFactory tmf;
             KeyManagerFactory kmf;
 
-            tmf = TrustManagerFactory.getInstance(ALGORITHM);
-            KeyStore ts = KeyStore.getInstance(STORE_TYPE);
+            tmf = TrustManagerFactory.getInstance(options.algorithm);
+            KeyStore ts = KeyStore.getInstance(options.store_type);
             ts.load(tsf, options.truststore_password.toCharArray());
             tmf.init(ts);
 
-            kmf = KeyManagerFactory.getInstance(ALGORITHM);
-            KeyStore ks = KeyStore.getInstance(STORE_TYPE);
+            kmf = KeyManagerFactory.getInstance(options.algorithm);
+            KeyStore ks = KeyStore.getInstance(options.store_type);
             ks.load(ksf, options.keystore_password.toCharArray());
             kmf.init(ks, options.keystore_password.toCharArray());
 
@@ -109,4 +116,13 @@ public final class SSLFactory
         }
         return ctx;
     }
+    
+    private static String[] filterCipherSuites(String[] supported, String[] desired)
+    {
+        Set<String> des = Sets.newHashSet(desired);
+        Set<String> return_ = Sets.intersection(Sets.newHashSet(supported), des);
+        if (des.size() > return_.size())
+            logger_.warn("Filtering out {} as it isnt supported by the socket", StringUtils.join(Sets.difference(des, return_), ","));
+        return return_.toArray(new String[return_.size()]);
+    }
 }