This is an automated email from the ASF dual-hosted git repository.

albumenj pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/dubbo.git


The following commit(s) were added to refs/heads/master by this push:
     new 75cda93  ssl support ciphers&protocols (#7740)
75cda93 is described below

commit 75cda93e8598abf7801603ee41b1e16d8a302838
Author: Owen.Cai <[email protected]>
AuthorDate: Mon May 31 10:42:51 2021 +0800

    ssl support ciphers&protocols (#7740)
    
    * ssl support ciphers&protocals
    
    * fix spell bug
    
    * spell error
    
    * add test
    
    * fix import *
    
    * add ASF license
    
    * delete no need
---
 .../java/org/apache/dubbo/config/SslConfig.java    | 29 ++++++++
 dubbo-dependencies-bom/pom.xml                     |  7 ++
 dubbo-remoting/dubbo-remoting-netty4/pom.xml       |  5 ++
 .../remoting/transport/netty4/SslContexts.java     | 13 ++++
 .../remoting/transport/netty4/SslContextsTest.java | 83 ++++++++++++++++++++++
 pom.xml                                            |  6 ++
 6 files changed, 143 insertions(+)

diff --git a/dubbo-common/src/main/java/org/apache/dubbo/config/SslConfig.java 
b/dubbo-common/src/main/java/org/apache/dubbo/config/SslConfig.java
index 83f8659..b861e5e 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/config/SslConfig.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/config/SslConfig.java
@@ -23,6 +23,7 @@ import org.apache.dubbo.config.support.Parameter;
 
 import java.io.IOException;
 import java.io.InputStream;
+import java.util.List;
 import java.util.concurrent.atomic.AtomicBoolean;
 
 public class SslConfig extends AbstractConfig {
@@ -40,6 +41,16 @@ public class SslConfig extends AbstractConfig {
     private String clientKeyPassword;
     private String clientTrustCertCollectionPath;
 
+    /**
+     * set support cipher
+     */
+    private List<String> ciphers;
+
+    /**
+     * set support protocols
+     */
+    private List<String> protocols;
+
     private InputStream serverKeyCertChainPathStream;
     private InputStream serverPrivateKeyPathStream;
     private InputStream serverTrustCertCollectionPathStream;
@@ -120,6 +131,24 @@ public class SslConfig extends AbstractConfig {
         this.clientTrustCertCollectionPath = clientTrustCertCollectionPath;
     }
 
+    @Parameter(key = "ciphers")
+    public List<String> getCiphers() {
+        return ciphers;
+    }
+
+    public void setCiphers(List<String> ciphers) {
+        this.ciphers = ciphers;
+    }
+
+    @Parameter(key = "protocols")
+    public List<String> getProtocols() {
+        return protocols;
+    }
+
+    public void setProtocols(List<String> protocols) {
+        this.protocols = protocols;
+    }
+
     public InputStream getServerKeyCertChainPathStream() throws IOException {
         if (serverKeyCertChainPath != null) {
             serverKeyCertChainPathStream = 
IOUtils.getURL(serverKeyCertChainPath).openStream();
diff --git a/dubbo-dependencies-bom/pom.xml b/dubbo-dependencies-bom/pom.xml
index 84442a3..77d2e6b 100644
--- a/dubbo-dependencies-bom/pom.xml
+++ b/dubbo-dependencies-bom/pom.xml
@@ -93,6 +93,7 @@
         <javassist_version>3.23.1-GA</javassist_version>
         <netty_version>3.2.5.Final</netty_version>
         <netty4_version>4.1.51.Final</netty4_version>
+        <netty4_ssl_version>2.0.39.Final</netty4_ssl_version>
         <mina_version>1.1.7</mina_version>
         <grizzly_version>2.4.4</grizzly_version>
         <httpclient_version>4.5.3</httpclient_version>
@@ -196,6 +197,12 @@
                 <version>${netty4_version}</version>
             </dependency>
             <dependency>
+                <groupId>io.netty</groupId>
+                <artifactId>netty-tcnative-boringssl-static</artifactId>
+                <version>${netty4_ssl_version}</version>
+                <scope>test</scope>
+            </dependency>
+            <dependency>
                 <groupId>org.apache.mina</groupId>
                 <artifactId>mina-core</artifactId>
                 <version>${mina_version}</version>
diff --git a/dubbo-remoting/dubbo-remoting-netty4/pom.xml 
b/dubbo-remoting/dubbo-remoting-netty4/pom.xml
index 99dd144..41da6bc 100644
--- a/dubbo-remoting/dubbo-remoting-netty4/pom.xml
+++ b/dubbo-remoting/dubbo-remoting-netty4/pom.xml
@@ -50,5 +50,10 @@
             <version>${project.parent.version}</version>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>io.netty</groupId>
+            <artifactId>netty-tcnative-boringssl-static</artifactId>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 </project>
diff --git 
a/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/SslContexts.java
 
b/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/SslContexts.java
index 94feda6..c4d3598 100644
--- 
a/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/SslContexts.java
+++ 
b/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/SslContexts.java
@@ -57,6 +57,13 @@ public class SslContexts {
                 
sslClientContextBuilder.trustManager(sslConfig.getServerTrustCertCollectionPathStream());
                 sslClientContextBuilder.clientAuth(ClientAuth.REQUIRE);
             }
+            if (sslConfig.getCiphers() != null) {
+                sslClientContextBuilder.ciphers(sslConfig.getCiphers());
+            }
+            if (sslConfig.getProtocols() != null) {
+                sslClientContextBuilder.protocols(sslConfig.getProtocols());
+            }
+
         } catch (Exception e) {
             throw new IllegalArgumentException("Could not find certificate 
file or the certificate is invalid.", e);
         }
@@ -87,6 +94,12 @@ public class SslContexts {
                     builder.keyManager(clientCertChainFilePath, 
clientPrivateKeyFilePath);
                 }
             }
+            if (sslConfig.getCiphers() != null) {
+                builder.ciphers(sslConfig.getCiphers());
+            }
+            if (sslConfig.getProtocols() != null) {
+                builder.protocols(sslConfig.getProtocols());
+            }
         } catch (Exception e) {
             throw new IllegalArgumentException("Could not find certificate 
file or find invalid certificate.", e);
         }
diff --git 
a/dubbo-remoting/dubbo-remoting-netty4/src/test/java/org/apache/dubbo/remoting/transport/netty4/SslContextsTest.java
 
b/dubbo-remoting/dubbo-remoting-netty4/src/test/java/org/apache/dubbo/remoting/transport/netty4/SslContextsTest.java
new file mode 100644
index 0000000..496fd66
--- /dev/null
+++ 
b/dubbo-remoting/dubbo-remoting-netty4/src/test/java/org/apache/dubbo/remoting/transport/netty4/SslContextsTest.java
@@ -0,0 +1,83 @@
+/*
+ * 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.dubbo.remoting.transport.netty4;
+
+import io.netty.handler.ssl.JdkSslContext;
+import io.netty.handler.ssl.OpenSsl;
+import io.netty.handler.ssl.OpenSslContext;
+import io.netty.handler.ssl.SslContext;
+import io.netty.handler.ssl.ReferenceCountedOpenSslContext;
+import org.apache.dubbo.config.SslConfig;
+import org.apache.dubbo.config.context.ConfigManager;
+import org.apache.dubbo.rpc.model.ApplicationModel;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import java.lang.reflect.Field;
+import java.util.Arrays;
+import java.util.List;
+
+import org.mockito.MockedStatic;
+import org.mockito.Mockito;
+
+/**
+ * ssl contexts test
+ */
+public class SslContextsTest {
+    @Test
+    public void testSslContexts() throws NoSuchFieldException, 
IllegalAccessException {
+        //test openssl
+        testSslContextsItem();
+
+        MockedStatic<OpenSsl> openSslMockedStatic = 
Mockito.mockStatic(OpenSsl.class);
+        openSslMockedStatic.when(OpenSsl::isAvailable).thenReturn(false);
+
+        //test jdk
+        testSslContextsItem();
+    }
+
+    protected void testSslContextsItem() throws NoSuchFieldException, 
IllegalAccessException {
+        String cipher = "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256";
+        String protocol = "TLSv1.3";
+
+        ConfigManager globalConfigManager = 
ApplicationModel.getConfigManager();
+        SslConfig sslConfig = new SslConfig();
+        sslConfig.setCiphers(Arrays.asList(cipher));
+        sslConfig.setProtocols(Arrays.asList(protocol));
+        globalConfigManager.setSsl(sslConfig);
+
+        SslContext sslContext = SslContexts.buildClientSslContext(null);
+        if(sslContext instanceof JdkSslContext){
+            JdkSslContext jdkSslContext = (JdkSslContext) sslContext;
+            List<String> cipherSuites = jdkSslContext.cipherSuites();
+            Assertions.assertTrue(cipherSuites.size() == 1 && 
cipherSuites.get(0).equals(cipher));
+            Field protocols = 
JdkSslContext.class.getDeclaredField("protocols");
+            protocols.setAccessible(true);
+            String[] item = (String[])protocols.get(jdkSslContext);
+            Assertions.assertTrue(item.length == 1 && 
item[0].equals(protocol));
+        }
+        else if(sslContext instanceof OpenSslContext){
+            OpenSslContext openSslContext = (OpenSslContext) sslContext;
+            Assertions.assertTrue(openSslContext instanceof 
ReferenceCountedOpenSslContext);
+            List<String> cipherSuites = openSslContext.cipherSuites();
+            Assertions.assertTrue(cipherSuites.size() == 1 && 
cipherSuites.get(0).equals(cipher));
+            Field protocols = 
ReferenceCountedOpenSslContext.class.getDeclaredField("protocols");
+            protocols.setAccessible(true);
+            final String[] item = (String[]) protocols.get(openSslContext);
+            Assertions.assertTrue(item.length == 1 && 
item[0].equals(protocol));
+        }
+    }
+}
diff --git a/pom.xml b/pom.xml
index 3fd0bf7..f3aca25 100644
--- a/pom.xml
+++ b/pom.xml
@@ -192,6 +192,12 @@
             <scope>test</scope>
         </dependency>
         <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-inline</artifactId>
+            <version>${mockito_version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
             <groupId>cglib</groupId>
             <artifactId>cglib-nodep</artifactId>
             <version>${cglib_version}</version>

Reply via email to