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

lgoldstein pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mina-sshd.git

commit 5fc2eff001684626601b6855a609076ab22cd0a7
Author: Lyor Goldstein <lgoldst...@apache.org>
AuthorDate: Tue Dec 1 19:10:34 2020 +0200

    [SSHD-1107] Allow configuration of minimum DH group exchange key size via 
property or programmatically
---
 CHANGES.md                                         |   3 +-
 docs/security-providers.md                         |  23 +++++
 .../sshd/common/util/security/SecurityUtils.java   |  79 +++++++++++----
 .../SecurityProviderRegistrarTestSupport.java      |   3 -
 .../SecurityUtilsDHGEXGroupKeySizeTest.java        | 111 +++++++++++++++++++++
 .../common/util/security/SecurityUtilsTest.java    |  22 +---
 .../util/security/SecurityUtilsTestSupport.java    |  48 +++++++++
 .../eddsa/EdDSASecurityProviderRegistrarTest.java  |   3 +
 .../org/apache/sshd/client/kex/DHGEXClient.java    |   2 +-
 .../org/apache/sshd/server/kex/DHGEXServer.java    |   8 +-
 10 files changed, 254 insertions(+), 48 deletions(-)

diff --git a/CHANGES.md b/CHANGES.md
index 4375d17..333f354 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -61,4 +61,5 @@ or `-key-file` command line option.
 * [SSHD-1070](https://issues.apache.org/jira/browse/SSHD-1070) 
OutOfMemoryError when use async port forwarding
 * [SSHD-1100](https://issues.apache.org/jira/browse/SSHD-1100) Updated used 
moduli for DH group KEX
 * [SSHD-1102](https://issues.apache.org/jira/browse/SSHD-1102) Provide filter 
support for SftpDirectoryStream
-* [SSHD-1104](https://issues.apache.org/jira/browse/SSHD-1104) Take into 
account possible key type aliases when using public key authentication
\ No newline at end of file
+* [SSHD-1104](https://issues.apache.org/jira/browse/SSHD-1104) Take into 
account possible key type aliases when using public key authentication
+* [SSHD-1107](https://issues.apache.org/jira/browse/SSHD-1107) Allow 
configuration of minimum DH group exchange key size via property or 
programmatically
\ No newline at end of file
diff --git a/docs/security-providers.md b/docs/security-providers.md
index 71f9d52..e9ed66d 100644
--- a/docs/security-providers.md
+++ b/docs/security-providers.md
@@ -82,3 +82,26 @@ with the `Cipher` class as its argument.
 * Specifically for **ciphers** the argument to the support query contains a 
**transformation** (e.g., `AES/CBC/NoPadding`)
 so one should take that into account when parsing the input argument to decide 
which cipher is referenced - see
 `SecurityProviderRegistrar.getEffectiveSecurityEntityName(Class<?>, String)` 
helper method
+
+## Diff-Hellman group exchange configuration
+
+The [RFC 4419 - Diffie-Hellman Group Exchange for the Secure Shell (SSH) 
Transport Layer Protocol](https://tools.ietf.org/html/rfc4419)
+specifies in section 3:
+
+>> Servers and clients SHOULD support groups with a modulus length of k bits, 
where 1024 <= k <= 8192.
+>> The recommended values for min and max are 1024 and 8192, respectively.
+
+This was subsequently amended in [RFC 8270 - Increase the Secure Shell Minimum 
Recommended Diffie-Hellman Modulus Size to 2048 
Bits](https://tools.ietf.org/html/rfc8270).
+
+In any case, the values are auto-detected by the code but the user can 
intervene in 2 ways:
+
+1. Programmatically - by invoking 
`SecurityUtils#setMin/MaxDHGroupExchangeKeySize` respectively
+2. Via system property - by setting `org.apache.sshd.min/maxDHGexKeySize` 
system property respectively
+
+**Note(s)**
+
+* The value should be a multiple of 1024 (not enforced)
+* The value should be between 1024 and 8192 (not enforced)
+* The minimum must be less or equal to the maximum (enforced - if reversed 
then group exchange is **disabled**)
+* If a **negative** value is set in either one then group exchange is 
**disabled**
+* Setting a value of zero indicates a **lazy** auto-detection of the supported 
range the next time these values are needed.
\ No newline at end of file
diff --git 
a/sshd-common/src/main/java/org/apache/sshd/common/util/security/SecurityUtils.java
 
b/sshd-common/src/main/java/org/apache/sshd/common/util/security/SecurityUtils.java
index a538f8e..c300213 100644
--- 
a/sshd-common/src/main/java/org/apache/sshd/common/util/security/SecurityUtils.java
+++ 
b/sshd-common/src/main/java/org/apache/sshd/common/util/security/SecurityUtils.java
@@ -102,6 +102,13 @@ public final class SecurityUtils {
     public static final String CURVE_ED25519_SHA512 = "NONEwithEdDSA";
 
     /**
+     * System property used to configure the value for the minimum supported 
Diffie-Hellman Group Exchange key size. If
+     * not set, then an internal auto-discovery mechanism is employed. If set 
to negative value then Diffie-Hellman
+     * Group Exchange is disabled. If set to a negative value then 
Diffie-Hellman Group Exchange is disabled
+     */
+    public static final String MIN_DHGEX_KEY_SIZE_PROP = 
"org.apache.sshd.minDHGexKeySize";
+
+    /**
      * System property used to configure the value for the maximum supported 
Diffie-Hellman Group Exchange key size. If
      * not set, then an internal auto-discovery mechanism is employed. If set 
to negative value then Diffie-Hellman
      * Group Exchange is disabled. If set to a negative value then 
Diffie-Hellman Group Exchange is disabled
@@ -155,6 +162,7 @@ public final class SecurityUtils {
 
     public static final String PROP_DEFAULT_SECURITY_PROVIDER = 
"org.apache.sshd.security.defaultProvider";
 
+    private static final AtomicInteger MIN_DHG_KEY_SIZE_HOLDER = new 
AtomicInteger(0);
     private static final AtomicInteger MAX_DHG_KEY_SIZE_HOLDER = new 
AtomicInteger(0);
 
     /*
@@ -244,37 +252,78 @@ public final class SecurityUtils {
 
     /**
      * @return {@code true} if Diffie-Hellman Group Exchange is supported
+     * @see    #getMinDHGroupExchangeKeySize()
      * @see    #getMaxDHGroupExchangeKeySize()
      */
     public static boolean isDHGroupExchangeSupported() {
-        return getMaxDHGroupExchangeKeySize() > 0;
+        int maxSize = getMaxDHGroupExchangeKeySize();
+        int minSize = getMinDHGroupExchangeKeySize();
+        return (minSize > 0) && (maxSize > 0) && (minSize <= maxSize);
     }
 
     /**
      * @param  keySize The expected key size
      * @return         {@code true} if Oakely Diffie-Hellman Group Exchange is 
supported for the specified key size
+     * @see            #isDHGroupExchangeSupported()
      * @see            #getMaxDHGroupExchangeKeySize()
      */
     public static boolean isDHOakelyGroupSupported(int keySize) {
-        return getMaxDHGroupExchangeKeySize() >= keySize;
+        return isDHGroupExchangeSupported()
+                && (getMaxDHGroupExchangeKeySize() >= keySize);
+    }
+
+    /**
+     * @return The minimum supported Diffie-Hellman Group Exchange key size, 
or non-positive if not supported
+     */
+    public static int getMinDHGroupExchangeKeySize() {
+        return resolveDHGEXKeySizeValue(MIN_DHG_KEY_SIZE_HOLDER, 
MIN_DHGEX_KEY_SIZE_PROP, MIN_DHGEX_KEY_SIZE);
+    }
+
+    /**
+     * Set programmatically the reported value for {@link 
#getMinDHGroupExchangeKeySize()}
+     *
+     * @param keySize The reported key size - if zero, then it will be 
auto-detected, if negative then DH group exchange
+     *                will be disabled
+     */
+    public static void setMinDHGroupExchangeKeySize(int keySize) {
+        synchronized (MIN_DHG_KEY_SIZE_HOLDER) {
+            MIN_DHG_KEY_SIZE_HOLDER.set(keySize);
+        }
     }
 
     /**
      * @return The maximum supported Diffie-Hellman Group Exchange key size, 
or non-positive if not supported
      */
     public static int getMaxDHGroupExchangeKeySize() {
-        int maxSupportedKeySize;
+        return resolveDHGEXKeySizeValue(MAX_DHG_KEY_SIZE_HOLDER, 
MAX_DHGEX_KEY_SIZE_PROP, MAX_DHGEX_KEY_SIZE);
+    }
+
+    /**
+     * Set programmatically the reported value for {@link 
#getMaxDHGroupExchangeKeySize()}
+     *
+     * @param keySize The reported key size - if zero, then it will be 
auto-detected, if negative then DH group exchange
+     *                will be disabled
+     */
+    public static void setMaxDHGroupExchangeKeySize(int keySize) {
         synchronized (MAX_DHG_KEY_SIZE_HOLDER) {
-            maxSupportedKeySize = MAX_DHG_KEY_SIZE_HOLDER.get();
+            MAX_DHG_KEY_SIZE_HOLDER.set(keySize);
+        }
+    }
+
+    private static int resolveDHGEXKeySizeValue(
+            AtomicInteger holder, String propName, int maxKeySize) {
+        int maxSupportedKeySize;
+        synchronized (holder) {
+            maxSupportedKeySize = holder.get();
             if (maxSupportedKeySize != 0) { // 1st time we are called ?
                 return maxSupportedKeySize;
             }
 
-            String propValue = System.getProperty(MAX_DHGEX_KEY_SIZE_PROP);
+            String propValue = System.getProperty(propName);
             if (GenericUtils.isEmpty(propValue)) {
                 maxSupportedKeySize = -1;
                 // Go down from max. to min. to ensure we stop at 1st maximum 
value success
-                for (int testKeySize = MAX_DHGEX_KEY_SIZE; testKeySize >= 
MIN_DHGEX_KEY_SIZE; testKeySize -= 1024) {
+                for (int testKeySize = maxKeySize; testKeySize >= 
MIN_DHGEX_KEY_SIZE; testKeySize -= 1024) {
                     if (isDHGroupExchangeSupported(testKeySize)) {
                         maxSupportedKeySize = testKeySize;
                         break;
@@ -282,31 +331,19 @@ public final class SecurityUtils {
                 }
             } else {
                 Logger logger = LoggerFactory.getLogger(SecurityUtils.class);
-                logger.info("Override max. DH group exchange key size: " + 
propValue);
+                logger.info("Override DH group exchange key size via {}: {}", 
propName, propValue);
                 maxSupportedKeySize = Integer.parseInt(propValue);
                 // negative is OK - means user wants to disable DH group 
exchange
                 ValidateUtils.checkTrue(maxSupportedKeySize != 0,
-                        "Configured " + MAX_DHGEX_KEY_SIZE_PROP + " value must 
be non-zero: %d", maxSupportedKeySize);
+                        "Configured " + propName + " value must be non-zero: 
%d", maxSupportedKeySize);
             }
 
-            MAX_DHG_KEY_SIZE_HOLDER.set(maxSupportedKeySize);
+            holder.set(maxSupportedKeySize);
         }
 
         return maxSupportedKeySize;
     }
 
-    /**
-     * Set programmatically the reported value for {@link 
#getMaxDHGroupExchangeKeySize()}
-     *
-     * @param keySize The reported key size - if zero, then it will be 
auto-detected, if negative then DH group exchange
-     *                will be disabled
-     */
-    public static void setMaxDHGroupExchangeKeySize(int keySize) {
-        synchronized (MAX_DHG_KEY_SIZE_HOLDER) {
-            MAX_DHG_KEY_SIZE_HOLDER.set(keySize);
-        }
-    }
-
     public static boolean isDHGroupExchangeSupported(int maxKeySize) {
         ValidateUtils.checkTrue(maxKeySize > Byte.SIZE, "Invalid max. key 
size: %d", maxKeySize);
 
diff --git 
a/sshd-common/src/test/java/org/apache/sshd/common/util/security/SecurityProviderRegistrarTestSupport.java
 
b/sshd-common/src/test/java/org/apache/sshd/common/util/security/SecurityProviderRegistrarTestSupport.java
index 4eeaafe..6f20183 100644
--- 
a/sshd-common/src/test/java/org/apache/sshd/common/util/security/SecurityProviderRegistrarTestSupport.java
+++ 
b/sshd-common/src/test/java/org/apache/sshd/common/util/security/SecurityProviderRegistrarTestSupport.java
@@ -23,13 +23,10 @@ import java.util.Arrays;
 import java.util.Collection;
 
 import org.apache.sshd.util.test.JUnitTestSupport;
-import org.apache.sshd.util.test.NoIoTestCase;
-import org.junit.experimental.categories.Category;
 
 /**
  * @author <a href="mailto:d...@mina.apache.org";>Apache MINA SSHD Project</a>
  */
-@Category({ NoIoTestCase.class })
 public abstract class SecurityProviderRegistrarTestSupport extends 
JUnitTestSupport {
     protected SecurityProviderRegistrarTestSupport() {
         super();
diff --git 
a/sshd-common/src/test/java/org/apache/sshd/common/util/security/SecurityUtilsDHGEXGroupKeySizeTest.java
 
b/sshd-common/src/test/java/org/apache/sshd/common/util/security/SecurityUtilsDHGEXGroupKeySizeTest.java
new file mode 100644
index 0000000..c2ff548
--- /dev/null
+++ 
b/sshd-common/src/test/java/org/apache/sshd/common/util/security/SecurityUtilsDHGEXGroupKeySizeTest.java
@@ -0,0 +1,111 @@
+/*
+ * 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.sshd.common.util.security;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.sshd.util.test.JUnit4ClassRunnerWithParametersFactory;
+import org.apache.sshd.util.test.NoIoTestCase;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.runner.RunWith;
+import org.junit.runners.MethodSorters;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+import org.junit.runners.Parameterized.UseParametersRunnerFactory;
+
+/**
+ * @author <a href="mailto:d...@mina.apache.org";>Apache MINA SSHD Project</a>
+ */
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+@RunWith(Parameterized.class) // see 
https://github.com/junit-team/junit/wiki/Parameterized-tests
+@UseParametersRunnerFactory(JUnit4ClassRunnerWithParametersFactory.class)
+@Category({ NoIoTestCase.class })
+public class SecurityUtilsDHGEXGroupKeySizeTest extends 
SecurityUtilsTestSupport {
+    private final int expected;
+
+    public SecurityUtilsDHGEXGroupKeySizeTest(int expected) {
+        this.expected = expected;
+    }
+
+    @Before
+    @After
+    public void resetDHGEXGroupKeySizes() {
+        System.clearProperty(SecurityUtils.MIN_DHGEX_KEY_SIZE_PROP);
+        SecurityUtils.setMinDHGroupExchangeKeySize(0); // force detection
+        System.clearProperty(SecurityUtils.MAX_DHGEX_KEY_SIZE_PROP);
+        SecurityUtils.setMaxDHGroupExchangeKeySize(0); // force detection
+    }
+
+    @Parameters(name = "keySize={0}")
+    public static List<Object[]> parameters() {
+        System.clearProperty(SecurityUtils.MAX_DHGEX_KEY_SIZE_PROP);
+        SecurityUtils.setMaxDHGroupExchangeKeySize(0); // force detection
+        try {
+            List<Object[]> values = new ArrayList<>();
+            int maxSupported = SecurityUtils.getMaxDHGroupExchangeKeySize();
+            for (int expected = SecurityUtils.MIN_DHGEX_KEY_SIZE;
+                 expected <= maxSupported;
+                 expected += 1024) {
+                values.add(new Object[] { expected });
+            }
+            return values;
+        } finally {
+            SecurityUtils.setMaxDHGroupExchangeKeySize(0); // force detection
+        }
+    }
+
+    @Test
+    public void testSetMaxDHGroupExchangeKeySizeByProperty() {
+        System.setProperty(SecurityUtils.MAX_DHGEX_KEY_SIZE_PROP, 
Integer.toString(expected));
+        assertTrue("DH group not supported for key size=" + expected, 
SecurityUtils.isDHGroupExchangeSupported());
+        assertEquals("Mismatched values", expected, 
SecurityUtils.getMaxDHGroupExchangeKeySize());
+    }
+
+    @Test
+    public void testSetMaxDHGroupExchangeKeySizeProgrammatically() {
+        SecurityUtils.setMaxDHGroupExchangeKeySize(expected);
+        assertTrue("DH group not supported for key size=" + expected, 
SecurityUtils.isDHGroupExchangeSupported());
+        assertEquals("Mismatched values", expected, 
SecurityUtils.getMaxDHGroupExchangeKeySize());
+    }
+
+    @Test
+    public void testSetMinDHGroupExchangeKeySizeByProperty() {
+        System.setProperty(SecurityUtils.MIN_DHGEX_KEY_SIZE_PROP, 
Integer.toString(expected));
+        assertTrue("DH group not supported for key size=" + expected, 
SecurityUtils.isDHGroupExchangeSupported());
+        assertEquals("Mismatched values", expected, 
SecurityUtils.getMinDHGroupExchangeKeySize());
+    }
+
+    @Test
+    public void testSetMinDHGroupExchangeKeySizeProgrammatically() {
+        SecurityUtils.setMinDHGroupExchangeKeySize(expected);
+        assertTrue("DH group not supported for key size=" + expected, 
SecurityUtils.isDHGroupExchangeSupported());
+        assertEquals("Mismatched values", expected, 
SecurityUtils.getMinDHGroupExchangeKeySize());
+    }
+
+    @Override
+    public String toString() {
+        return getClass().getSimpleName() + "[keySize=" + expected + "]";
+    }
+}
diff --git 
a/sshd-common/src/test/java/org/apache/sshd/common/util/security/SecurityUtilsTest.java
 
b/sshd-common/src/test/java/org/apache/sshd/common/util/security/SecurityUtilsTest.java
index ecf7ac8..0dba74f 100644
--- 
a/sshd-common/src/test/java/org/apache/sshd/common/util/security/SecurityUtilsTest.java
+++ 
b/sshd-common/src/test/java/org/apache/sshd/common/util/security/SecurityUtilsTest.java
@@ -46,11 +46,8 @@ import 
org.apache.sshd.common.keyprovider.ClassLoadableResourceKeyPairProvider;
 import org.apache.sshd.common.keyprovider.FileKeyPairProvider;
 import org.apache.sshd.common.util.GenericUtils;
 import org.apache.sshd.common.util.io.resource.PathResource;
-import org.apache.sshd.util.test.JUnitTestSupport;
 import org.apache.sshd.util.test.NoIoTestCase;
-import org.junit.AfterClass;
 import org.junit.Assume;
-import org.junit.BeforeClass;
 import org.junit.FixMethodOrder;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
@@ -62,11 +59,7 @@ import org.junit.runners.MethodSorters;
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
 @Category({ NoIoTestCase.class })
 @SuppressWarnings("checkstyle:MethodCount")
-public class SecurityUtilsTest extends JUnitTestSupport {
-    public static final String BC_NAMED_USAGE_PROP = 
SecurityProviderRegistrar.CONFIG_PROP_BASE
-                                                     + "." + 
SecurityUtils.BOUNCY_CASTLE
-                                                     + "." + 
SecurityProviderRegistrar.NAMED_PROVIDER_PROPERTY;
-
+public class SecurityUtilsTest extends SecurityUtilsTestSupport {
     private static final String DEFAULT_PASSWORD = "super secret passphrase";
     private static final FilePasswordProvider TEST_PASSWORD_PROVIDER = 
(session, file, index) -> DEFAULT_PASSWORD;
 
@@ -74,17 +67,6 @@ public class SecurityUtilsTest extends JUnitTestSupport {
         super();
     }
 
-    // NOTE: Using the BouncyCastle provider instead of the name does not work 
as expected so we take no chances
-    @BeforeClass
-    public static void useNamedBouncyCastleProvider() {
-        System.setProperty(BC_NAMED_USAGE_PROP, Boolean.TRUE.toString());
-    }
-
-    @AfterClass
-    public static void unsetBouncyCastleProviderUsagePreference() {
-        System.clearProperty(BC_NAMED_USAGE_PROP);
-    }
-
     @Test
     public void testLoadEncryptedDESPrivateKey() throws Exception {
         testLoadEncryptedRSAPrivateKey("DES-EDE3");
@@ -227,6 +209,7 @@ public class SecurityUtilsTest extends JUnitTestSupport {
                 }
             }
         } finally {
+            SecurityUtils.setMinDHGroupExchangeKeySize(0); // force detection
             SecurityUtils.setMaxDHGroupExchangeKeySize(0); // force detection
         }
     }
@@ -242,6 +225,7 @@ public class SecurityUtilsTest extends JUnitTestSupport {
                 assertEquals("Mismatched values", expected, 
SecurityUtils.getMaxDHGroupExchangeKeySize());
             }
         } finally {
+            SecurityUtils.setMinDHGroupExchangeKeySize(0); // force detection
             SecurityUtils.setMaxDHGroupExchangeKeySize(0); // force detection
         }
     }
diff --git 
a/sshd-common/src/test/java/org/apache/sshd/common/util/security/SecurityUtilsTestSupport.java
 
b/sshd-common/src/test/java/org/apache/sshd/common/util/security/SecurityUtilsTestSupport.java
new file mode 100644
index 0000000..84a6c04
--- /dev/null
+++ 
b/sshd-common/src/test/java/org/apache/sshd/common/util/security/SecurityUtilsTestSupport.java
@@ -0,0 +1,48 @@
+/*
+ * 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.sshd.common.util.security;
+
+import org.apache.sshd.util.test.JUnitTestSupport;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+
+/**
+ * @author <a href="mailto:d...@mina.apache.org";>Apache MINA SSHD Project</a>
+ */
+public abstract class SecurityUtilsTestSupport extends JUnitTestSupport {
+    public static final String BC_NAMED_USAGE_PROP = 
SecurityProviderRegistrar.CONFIG_PROP_BASE
+                                                     + "." + 
SecurityUtils.BOUNCY_CASTLE
+                                                     + "." + 
SecurityProviderRegistrar.NAMED_PROVIDER_PROPERTY;
+
+    protected SecurityUtilsTestSupport() {
+        super();
+    }
+
+    // NOTE: Using the BouncyCastle provider instead of the name does not work 
as expected so we take no chances
+    @BeforeClass
+    public static void useNamedBouncyCastleProvider() {
+        System.setProperty(BC_NAMED_USAGE_PROP, Boolean.TRUE.toString());
+    }
+
+    @AfterClass
+    public static void unsetBouncyCastleProviderUsagePreference() {
+        System.clearProperty(BC_NAMED_USAGE_PROP);
+    }
+}
diff --git 
a/sshd-common/src/test/java/org/apache/sshd/common/util/security/eddsa/EdDSASecurityProviderRegistrarTest.java
 
b/sshd-common/src/test/java/org/apache/sshd/common/util/security/eddsa/EdDSASecurityProviderRegistrarTest.java
index 4365dbf..075127b 100644
--- 
a/sshd-common/src/test/java/org/apache/sshd/common/util/security/eddsa/EdDSASecurityProviderRegistrarTest.java
+++ 
b/sshd-common/src/test/java/org/apache/sshd/common/util/security/eddsa/EdDSASecurityProviderRegistrarTest.java
@@ -30,16 +30,19 @@ import net.i2p.crypto.eddsa.EdDSASecurityProvider;
 import org.apache.sshd.common.util.security.SecurityProviderRegistrar;
 import 
org.apache.sshd.common.util.security.SecurityProviderRegistrarTestSupport;
 import org.apache.sshd.common.util.security.SecurityUtils;
+import org.apache.sshd.util.test.NoIoTestCase;
 import org.junit.Assume;
 import org.junit.BeforeClass;
 import org.junit.FixMethodOrder;
 import org.junit.Test;
+import org.junit.experimental.categories.Category;
 import org.junit.runners.MethodSorters;
 
 /**
  * @author <a href="mailto:d...@mina.apache.org";>Apache MINA SSHD Project</a>
  */
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
+@Category({ NoIoTestCase.class })
 public class EdDSASecurityProviderRegistrarTest extends 
SecurityProviderRegistrarTestSupport {
     private static SecurityProviderRegistrar registrarInstance;
 
diff --git 
a/sshd-core/src/main/java/org/apache/sshd/client/kex/DHGEXClient.java 
b/sshd-core/src/main/java/org/apache/sshd/client/kex/DHGEXClient.java
index 6c7923c..e689982 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/kex/DHGEXClient.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/kex/DHGEXClient.java
@@ -64,7 +64,7 @@ public class DHGEXClient extends AbstractDHClientKeyExchange {
 
         // SSHD-941 give the user a chance to intervene in the choice
         min = CoreModuleProperties.PROP_DHGEX_CLIENT_MIN_KEY.get(session)
-                .orElse(SecurityUtils.MIN_DHGEX_KEY_SIZE);
+                .orElse(SecurityUtils.getMinDHGroupExchangeKeySize());
         max = CoreModuleProperties.PROP_DHGEX_CLIENT_MAX_KEY.get(session)
                 .orElse(SecurityUtils.getMaxDHGroupExchangeKeySize());
         prf = CoreModuleProperties.PROP_DHGEX_CLIENT_PRF_KEY.get(session)
diff --git 
a/sshd-core/src/main/java/org/apache/sshd/server/kex/DHGEXServer.java 
b/sshd-core/src/main/java/org/apache/sshd/server/kex/DHGEXServer.java
index 3e23da2..3403c1d 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/kex/DHGEXServer.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/kex/DHGEXServer.java
@@ -114,7 +114,8 @@ public class DHGEXServer extends 
AbstractDHServerKeyExchange {
         if ((cmd == SshConstants.SSH_MSG_KEX_DH_GEX_REQUEST_OLD)
                 && (expected == SshConstants.SSH_MSG_KEX_DH_GEX_REQUEST)) {
             oldRequest = true;
-            min = 
CoreModuleProperties.PROP_DHGEX_SERVER_MIN_KEY.get(session).orElse(SecurityUtils.MIN_DHGEX_KEY_SIZE);
+            min = CoreModuleProperties.PROP_DHGEX_SERVER_MIN_KEY.get(session)
+                    .orElse(SecurityUtils.getMinDHGroupExchangeKeySize());
             prf = buffer.getInt();
             max = CoreModuleProperties.PROP_DHGEX_SERVER_MAX_KEY.get(session)
                     .orElse(SecurityUtils.getMaxDHGroupExchangeKeySize());
@@ -295,8 +296,9 @@ public class DHGEXServer extends 
AbstractDHServerKeyExchange {
             ServerSession session, int min, int prf, int max, 
List<Moduli.DhGroup> groups)
             throws Exception {
         int maxDHGroupExchangeKeySize = 
SecurityUtils.getMaxDHGroupExchangeKeySize();
-        min = Math.max(min, SecurityUtils.MIN_DHGEX_KEY_SIZE);
-        prf = Math.max(prf, SecurityUtils.MIN_DHGEX_KEY_SIZE);
+        int minDHGroupExchangeKeySize = 
SecurityUtils.getMinDHGroupExchangeKeySize();
+        min = Math.max(min, minDHGroupExchangeKeySize);
+        prf = Math.max(prf, minDHGroupExchangeKeySize);
         prf = Math.min(prf, maxDHGroupExchangeKeySize);
         max = Math.min(max, maxDHGroupExchangeKeySize);
 

Reply via email to