Bug 5377: Support configuring cipher suites to use for SSLEngine 27/35727/1 stable/lithium
authorRashmi Pujar <rpujar@inocybe.com>
Thu, 18 Feb 2016 22:30:50 +0000 (17:30 -0500)
committerThanh Ha <thanh.ha@linuxfoundation.org>
Fri, 4 Mar 2016 04:03:34 +0000 (23:03 -0500)
Change-Id: Ia8117364bd6bcbe543cb1d31dea7d27ae87c6755
Signed-off-by: Rashmi Pujar <rpujar@inocybe.com>
12 files changed:
openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/connection/TlsConfiguration.java
openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/connection/TlsConfigurationImpl.java
openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/connection/TlsConfigurationImplTest.java
openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/TcpChannelInitializer.java
openflow-protocol-impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/openflow/_switch/connection/provider/impl/rev140328/SwitchConnectionProviderModule.java
openflow-protocol-impl/src/main/yang/openflow-switch-connection-provider-impl.yang
openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/PublishingChannelInitializerFactoryTest.java
openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/PublishingChannelInitializerTest.java
openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/SslContextFactoryTest.java
openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/SwitchConnectionProviderImpl02Test.java
openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/SwitchConnectionProviderImplTest.java
openflow-protocol-it/src/test/java/org/opendaylight/openflowjava/protocol/it/integration/IntegrationTest.java

index 6676dd02426796c316b17242c9f9a633a3b25e14..f5a71a8c2c4113c1c8c967dba0fe5d29a069a8f0 100644 (file)
@@ -8,6 +8,8 @@
 
 package org.opendaylight.openflowjava.protocol.api.connection;
 
+import java.util.List;
+
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.config.rev140630.KeystoreType;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.config.rev140630.PathType;
 
@@ -62,4 +64,9 @@ public interface TlsConfiguration {
      * @return password protecting specified truststore
      */
     String getTruststorePassword();
+
+    /**
+     * @return list of cipher suites for TLS connection
+     */
+    List<String> getCipherSuites();
 }
index 78a6c6b8c1804b0132a719884bca80706961114a..2a290140ba5abe2c6b64d56622b88eaf0e31ef23 100644 (file)
@@ -8,6 +8,8 @@
 
 package org.opendaylight.openflowjava.protocol.api.connection;
 
+import java.util.List;
+
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.config.rev140630.KeystoreType;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.config.rev140630.PathType;
 
@@ -23,6 +25,7 @@ public class TlsConfigurationImpl implements TlsConfiguration {
     private String keyStore;
     private PathType keystorePathType;
     private PathType truststorePathType;
+    private List<String> cipherSuites;
 
     /**
      * Default constructor
@@ -35,13 +38,15 @@ public class TlsConfigurationImpl implements TlsConfiguration {
      */
     public TlsConfigurationImpl(KeystoreType trustStoreType, String trustStore,
             PathType trustStorePathType, KeystoreType keyStoreType,
-            String keyStore, PathType keyStorePathType) {
+            String keyStore, PathType keyStorePathType,
+            List<String> cipherSuites) {
         this.trustStoreType = trustStoreType;
         this.trustStore = trustStore;
         this.truststorePathType = trustStorePathType;
         this.keyStoreType = keyStoreType;
         this.keyStore = keyStore;
         this.keystorePathType = keyStorePathType;
+        this.cipherSuites = cipherSuites;
     }
 
     @Override
@@ -88,4 +93,9 @@ public class TlsConfigurationImpl implements TlsConfiguration {
     public String getTruststorePassword() {
         return "opendaylight";
     }
+
+    @Override
+    public List<String> getCipherSuites() {
+        return cipherSuites;
+    }
 }
index f71d23022c8ea3e0d6b63980a3971f69df6d06e7..be52a18890fee87dc2ac33ece16d42f8efad2ed2 100644 (file)
@@ -10,10 +10,14 @@ package org.opendaylight.openflowjava.protocol.api.connection;
 
 import static org.junit.Assert.*;
 
+import java.util.List;
+
 import org.junit.Test;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.config.rev140630.KeystoreType;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.config.rev140630.PathType;
 
+import com.google.common.collect.Lists;
+
 /**
  * @author michal.polkorab
  *
@@ -25,8 +29,9 @@ public class TlsConfigurationImplTest {
      */
     @Test
     public void test() {
+        List<String> cipherSuites = Lists.newArrayList("TLS_RSA_WITH_AES_128_CBC_SHA", "TLS_RSA_WITH_AES_128_CBC_SHA256");
         TlsConfigurationImpl config = new TlsConfigurationImpl(KeystoreType.JKS,
-                "user/dir", PathType.CLASSPATH, KeystoreType.PKCS12, "/var/lib", PathType.PATH);
+                "user/dir", PathType.CLASSPATH, KeystoreType.PKCS12, "/var/lib", PathType.PATH, cipherSuites);
         assertEquals("Wrong keystore location", "/var/lib", config.getTlsKeystore());
         assertEquals("Wrong truststore location", "user/dir", config.getTlsTruststore());
         assertEquals("Wrong keystore type", KeystoreType.PKCS12, config.getTlsKeystoreType());
@@ -36,5 +41,6 @@ public class TlsConfigurationImplTest {
         assertEquals("Wrong certificate password", "opendaylight", config.getCertificatePassword());
         assertEquals("Wrong keystore password", "opendaylight", config.getKeystorePassword());
         assertEquals("Wrong truststore password", "opendaylight", config.getTruststorePassword());
+        assertEquals("Wrong cipher suites", cipherSuites, config.getCipherSuites());
     }
 }
\ No newline at end of file
index 18566eb29e086898d68fbfbfb9bbc957649b5719..881f697adf85d0f8cdf50ec12844723688c9af46 100644 (file)
@@ -16,6 +16,7 @@ import io.netty.util.concurrent.Future;
 import io.netty.util.concurrent.GenericFutureListener;
 import java.net.InetAddress;
 import java.util.Iterator;
+import java.util.List;
 import java.util.concurrent.TimeUnit;
 import javax.net.ssl.SSLEngine;
 import org.opendaylight.openflowjava.protocol.impl.core.connection.ConnectionAdapterFactory;
@@ -84,6 +85,13 @@ public class TcpChannelInitializer extends ProtocolChannelInitializer<SocketChan
                 final SSLEngine engine = sslFactory.getServerContext().createSSLEngine();
                 engine.setNeedClientAuth(true);
                 engine.setUseClientMode(false);
+                List<String> suitesList = getTlsConfiguration().getCipherSuites();
+                if (suitesList != null && !suitesList.isEmpty()) {
+                    LOGGER.debug("Requested Cipher Suites are: {}", suitesList);
+                    String[] suites = suitesList.toArray(new String[suitesList.size()]);
+                    engine.setEnabledCipherSuites(suites);
+                    LOGGER.debug("Cipher suites enabled in SSLEngine are: {}", engine.getEnabledCipherSuites().toString());
+                }
                 final SslHandler ssl = new SslHandler(engine);
                 final Future<Channel> handshakeFuture = ssl.handshakeFuture();
                 final ConnectionFacade finalConnectionFacade = connectionFacade;
index 6077c787017ae0e26376fea066764f7641c3cb0f..6ded9bfbb2cb33100225070873ecf4e76efc0a2f 100644 (file)
@@ -12,6 +12,8 @@ package org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflo
 import com.google.common.base.MoreObjects;
 import java.net.InetAddress;
 import java.net.UnknownHostException;
+import java.util.List;
+
 import org.opendaylight.openflowjava.protocol.api.connection.ConnectionConfiguration;
 import org.opendaylight.openflowjava.protocol.api.connection.ThreadConfiguration;
 import org.opendaylight.openflowjava.protocol.api.connection.TlsConfiguration;
@@ -136,6 +138,10 @@ public final class SwitchConnectionProviderModule extends org.opendaylight.yang.
                     public String getTruststorePassword() {
                         return MoreObjects.firstNonNull(tlsConfig.getTruststorePassword(), null);
                     }
+                    @Override
+                    public List<String> getCipherSuites() {
+                        return tlsConfig.getCipherSuites();
+                    }
                 };
             }
             @Override
index aead17584718b7698f4a9aeb83396a85d97783c8..1610ff1badea324d976253423731eae6fecbf3fe 100644 (file)
@@ -97,6 +97,10 @@ module openflow-switch-connection-provider-impl {
                     description "password protecting truststore";
                     type string;
                 }
+                leaf-list cipher-suites {
+                    description "combination of cryptographic algorithms used by TLS connection";
+                    type string;
+                }
             }
             container threads {
                 leaf boss-threads {
index 6001e7f84c52e36e03f28e6addef98b056ced20b..486972401b3d23d2356bc5897d0b1e5856a02f47 100644 (file)
@@ -22,6 +22,8 @@ import org.opendaylight.openflowjava.protocol.impl.serialization.SerializationFa
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.config.rev140630.KeystoreType;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.config.rev140630.PathType;
 
+import com.google.common.collect.Lists;
+
 /**
  *
  * @author jameshall
@@ -43,7 +45,8 @@ public class PublishingChannelInitializerFactoryTest {
         MockitoAnnotations.initMocks(this);
         factory = new ChannelInitializerFactory();
         tlsConfiguration = new TlsConfigurationImpl(KeystoreType.JKS, "/exemplary-ctlTrustStore",
-                PathType.CLASSPATH, KeystoreType.JKS, "/exemplary-ctlKeystore", PathType.CLASSPATH);
+                PathType.CLASSPATH, KeystoreType.JKS, "/exemplary-ctlKeystore", PathType.CLASSPATH,
+                Lists.newArrayList("TLS_RSA_WITH_AES_128_CBC_SHA", "TLS_RSA_WITH_AES_128_CBC_SHA256"));
         factory.setDeserializationFactory(deserializationFactory);
         factory.setSerializationFactory(serializationFactory);
         factory.setSwitchConnectionHandler(switchConnectionHandler);
index bcd2ebb9b1b36813bae8664ea1fd30d5e50d8da0..b855cc917ec3f11e48bcc5637577e9f6fb007b11 100644 (file)
@@ -39,6 +39,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.config.rev140630.K
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.config.rev140630.PathType;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflow._switch.connection.provider.impl.rev140328.Tls;
 
+import com.google.common.collect.Lists;
+
 /**
  *
  * @author james.hall
@@ -89,7 +91,8 @@ public class PublishingChannelInitializerTest {
         when(mockSocketCh.pipeline()).thenReturn(mockChPipeline) ;
 
         tlsConfiguration = new TlsConfigurationImpl(KeystoreType.JKS, "/selfSignedSwitch", PathType.CLASSPATH,
-                KeystoreType.JKS, "/selfSignedController", PathType.CLASSPATH);
+                KeystoreType.JKS, "/selfSignedController", PathType.CLASSPATH,
+                Lists.newArrayList("TLS_RSA_WITH_AES_128_CBC_SHA", "TLS_RSA_WITH_AES_128_CBC_SHA256"));
     }
 
 
index a52f44c673b2a82274a1fb253047f9b460447695..c73f6c638ba6ff771efa3e110f8cb53eedd4bea3 100644 (file)
@@ -20,6 +20,8 @@ import org.opendaylight.openflowjava.protocol.api.connection.TlsConfigurationImp
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.config.rev140630.KeystoreType;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.config.rev140630.PathType;
 
+import com.google.common.collect.Lists;
+
 /**
  *
  * @author jameshall
@@ -36,7 +38,8 @@ public class SslContextFactoryTest {
     public void setUp() {
         MockitoAnnotations.initMocks(this);
         tlsConfiguration = new TlsConfigurationImpl(KeystoreType.JKS, "/exemplary-ctlTrustStore",
-                PathType.CLASSPATH, KeystoreType.JKS, "/exemplary-ctlKeystore", PathType.CLASSPATH) ;
+                PathType.CLASSPATH, KeystoreType.JKS, "/exemplary-ctlKeystore", PathType.CLASSPATH,
+                Lists.newArrayList("TLS_RSA_WITH_AES_128_CBC_SHA", "TLS_RSA_WITH_AES_128_CBC_SHA256")) ;
         sslContextFactory = new SslContextFactory(tlsConfiguration);
     }
 
index 78b243256ca0f57299c02ed898b7930a4dc2c92e..e9b36307f188a4cc6d1f3ee159e4b83945838866 100644 (file)
@@ -7,6 +7,7 @@
  */
 package org.opendaylight.openflowjava.protocol.impl.core.connection;
 
+import com.google.common.collect.Lists;
 import com.google.common.util.concurrent.ListenableFuture;
 import java.net.InetAddress;
 import java.net.UnknownHostException;
@@ -93,7 +94,8 @@ public class SwitchConnectionProviderImpl02Test {
         if (protocol.equals(TransportProtocol.TLS)) {
             tlsConfiguration = new TlsConfigurationImpl(KeystoreType.JKS,
                     "/selfSignedSwitch", PathType.CLASSPATH, KeystoreType.JKS,
-                    "/selfSignedController", PathType.CLASSPATH) ;
+                    "/selfSignedController", PathType.CLASSPATH,
+                    Lists.newArrayList("TLS_RSA_WITH_AES_128_CBC_SHA", "TLS_RSA_WITH_AES_128_CBC_SHA256")) ;
         }
         config = new ConnectionConfigurationImpl(startupAddress, 0, tlsConfiguration, SWITCH_IDLE_TIMEOUT, true);
         config.setTransferProtocol(protocol);
index 3b53eed6e5d9c0c5365866a8524a7bfbb41318fd..491e18de5237718df257af844d20ae4248540296 100644 (file)
@@ -8,6 +8,7 @@
 
 package org.opendaylight.openflowjava.protocol.impl.core.connection;
 
+import com.google.common.collect.Lists;
 import com.google.common.util.concurrent.ListenableFuture;
 import java.net.InetAddress;
 import java.net.UnknownHostException;
@@ -65,7 +66,8 @@ public class SwitchConnectionProviderImplTest {
         if (protocol.equals(TransportProtocol.TLS)) {
             tlsConfiguration = new TlsConfigurationImpl(KeystoreType.JKS,
                     "/selfSignedSwitch", PathType.CLASSPATH, KeystoreType.JKS,
-                    "/selfSignedController", PathType.CLASSPATH) ;
+                    "/selfSignedController", PathType.CLASSPATH,
+                    Lists.newArrayList("TLS_RSA_WITH_AES_128_CBC_SHA", "TLS_RSA_WITH_AES_128_CBC_SHA256")) ;
         }
         config = new ConnectionConfigurationImpl(startupAddress, 0, tlsConfiguration, SWITCH_IDLE_TIMEOUT, true);
         config.setTransferProtocol(protocol);
index e10d12de10a9fa6fa981626c169f7b7630346b0b..77e747a96279f793715e110399c08d9e07969e65 100644 (file)
@@ -74,7 +74,8 @@ public class IntegrationTest {
         if (protocol.equals(TransportProtocol.TLS)) {
             tlsConfiguration = new TlsConfigurationImpl(KeystoreType.JKS,
                     "/selfSignedSwitch", PathType.CLASSPATH, KeystoreType.JKS,
-                    "/selfSignedController", PathType.CLASSPATH) ;
+                    "/selfSignedController", PathType.CLASSPATH,
+                    new ArrayList<String>());
         }
         connConfig = new ConnectionConfigurationImpl(startupAddress, 0, tlsConfiguration, SWITCH_IDLE_TIMEOUT, true);
         connConfig.setTransferProtocol(protocol);