You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@karaf.apache.org by gn...@apache.org on 2016/06/14 09:28:12 UTC

karaf git commit: [KARAF-4062][KARAF-4502] Check elliptic curves using SecurityUtils.hasEcc() and compute the maximum length for DHGEX factories

Repository: karaf
Updated Branches:
  refs/heads/karaf-4.0.x de5253446 -> 78f539e97


[KARAF-4062][KARAF-4502] Check elliptic curves using SecurityUtils.hasEcc() and compute the maximum length for DHGEX factories

Project: http://git-wip-us.apache.org/repos/asf/karaf/repo
Commit: http://git-wip-us.apache.org/repos/asf/karaf/commit/78f539e9
Tree: http://git-wip-us.apache.org/repos/asf/karaf/tree/78f539e9
Diff: http://git-wip-us.apache.org/repos/asf/karaf/diff/78f539e9

Branch: refs/heads/karaf-4.0.x
Commit: 78f539e970eb6775551d491acc67be775013a2cb
Parents: de52534
Author: Guillaume Nodet <gn...@apache.org>
Authored: Tue Jun 14 11:27:55 2016 +0200
Committer: Guillaume Nodet <gn...@apache.org>
Committed: Tue Jun 14 11:27:55 2016 +0200

----------------------------------------------------------------------
 .../main/java/org/apache/karaf/client/Main.java |  31 +++---
 .../org/apache/sshd/client/kex/FixedDHGEX.java  | 100 +++++++++++++++++++
 .../apache/sshd/client/kex/FixedDHGEX256.java   |  45 +++++++++
 3 files changed, 163 insertions(+), 13 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/karaf/blob/78f539e9/client/src/main/java/org/apache/karaf/client/Main.java
----------------------------------------------------------------------
diff --git a/client/src/main/java/org/apache/karaf/client/Main.java b/client/src/main/java/org/apache/karaf/client/Main.java
index 7a01299..acf1e9b 100644
--- a/client/src/main/java/org/apache/karaf/client/Main.java
+++ b/client/src/main/java/org/apache/karaf/client/Main.java
@@ -25,9 +25,10 @@ import java.lang.reflect.Proxy;
 import java.net.URL;
 import java.security.KeyPair;
 import java.nio.charset.Charset;
-import java.util.Arrays;
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Locale;
+import java.util.List;
 import java.util.Map;
 import java.util.concurrent.ArrayBlockingQueue;
 import java.util.concurrent.BlockingQueue;
@@ -49,12 +50,10 @@ import org.apache.sshd.client.UserInteraction;
 import org.apache.sshd.client.channel.ChannelShell;
 import org.apache.sshd.client.channel.PtyCapableChannelSession;
 import org.apache.sshd.client.future.ConnectFuture;
-import org.apache.sshd.client.kex.ECDHP256;
-import org.apache.sshd.client.kex.ECDHP384;
-import org.apache.sshd.client.kex.ECDHP521;
 import org.apache.sshd.common.*;
 import org.apache.sshd.common.keyprovider.FileKeyPairProvider;
 import org.apache.sshd.common.util.Buffer;
+import org.apache.sshd.common.util.SecurityUtils;
 import org.fusesource.jansi.AnsiConsole;
 import org.slf4j.impl.SimpleLogger;
 
@@ -94,15 +93,7 @@ public class Main {
         int exitStatus = 0;
         try {
             SshBuilder.ClientBuilder clientBuilder = SshBuilder.client();
-            clientBuilder.keyExchangeFactories(Arrays.<NamedFactory<KeyExchange>>asList(
-                     new ECDHP256.Factory(),
-                     new ECDHP256.Factory(),
-                     new ECDHP384.Factory(),
-                     new ECDHP384.Factory(),
-                     new ECDHP521.Factory(),
-                     new ECDHP521.Factory()
-                     )
-                );
+            clientBuilder.keyExchangeFactories(getKexFactories());
 
             client = clientBuilder.build();
             setupAgent(config.getUser(), config.getKeyFile(), client);
@@ -252,6 +243,20 @@ public class Main {
         System.exit(exitStatus);
     }
 
+    private static List<NamedFactory<KeyExchange>> getKexFactories() {
+        List<NamedFactory<KeyExchange>> list = new ArrayList<>();
+        if (SecurityUtils.hasEcc()) {
+            list.add(new org.apache.sshd.client.kex.ECDHP521.Factory());
+            list.add(new org.apache.sshd.client.kex.ECDHP384.Factory());
+            list.add(new org.apache.sshd.client.kex.ECDHP256.Factory());
+        }
+        list.add(new org.apache.sshd.client.kex.FixedDHGEX256.Factory());
+        list.add(new org.apache.sshd.client.kex.FixedDHGEX.Factory());
+        list.add(new org.apache.sshd.client.kex.DHG14.Factory());
+        list.add(new org.apache.sshd.client.kex.DHG1.Factory());
+        return list;
+    }
+
     private static int getFlag(TerminalLineSettings settings, PtyMode mode) {
         String name = mode.toString().toLowerCase();
         return (settings.getPropertyAsString(name) != null) ? 1 : 0;

http://git-wip-us.apache.org/repos/asf/karaf/blob/78f539e9/client/src/main/java/org/apache/sshd/client/kex/FixedDHGEX.java
----------------------------------------------------------------------
diff --git a/client/src/main/java/org/apache/sshd/client/kex/FixedDHGEX.java b/client/src/main/java/org/apache/sshd/client/kex/FixedDHGEX.java
new file mode 100644
index 0000000..ef921f9
--- /dev/null
+++ b/client/src/main/java/org/apache/sshd/client/kex/FixedDHGEX.java
@@ -0,0 +1,100 @@
+package org.apache.sshd.client.kex;
+
+import javax.crypto.spec.DHParameterSpec;
+import java.math.BigInteger;
+import java.security.GeneralSecurityException;
+import java.security.KeyPairGenerator;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.sshd.common.KeyExchange;
+import org.apache.sshd.common.NamedFactory;
+import org.apache.sshd.common.util.SecurityUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class FixedDHGEX extends DHGEX {
+
+    /**
+     * Named factory for DHGEX key exchange
+     */
+    public static class Factory implements NamedFactory<KeyExchange> {
+
+        public String getName() {
+            return "diffie-hellman-group-exchange-sha1";
+        }
+
+        public KeyExchange create() {
+            return new FixedDHGEX();
+        }
+
+    }
+
+    public FixedDHGEX() {
+        min = MIN_DHGEX_KEY_SIZE;
+        max = getMaxDHGroupExchangeKeySize();
+        prf = Math.min(PREFERRED_DHGEX_KEY_SIZE, max);
+    }
+
+    /**
+     * 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
+     */
+    public static final String MAX_DHGEX_KEY_SIZE_PROP = "org.apache.sshd.maxDHGexKeySize";
+
+    /**
+     * The min. key size value used for testing whether Diffie-Hellman Group Exchange
+     * is supported or not. According to <A HREF="https://tools.ietf.org/html/rfc4419">RFC 4419</A>
+     * section 3: &quot;Servers and clients SHOULD support groups with a modulus length of k
+     * bits, where 1024 <= k <= 8192&quot;.
+     * </code>
+     */
+    public static final int MIN_DHGEX_KEY_SIZE = 1024;
+    // Keys of size > 1024 are not support by default with JCE
+    public static final int DEFAULT_DHGEX_KEY_SIZE = MIN_DHGEX_KEY_SIZE;
+    public static final int PREFERRED_DHGEX_KEY_SIZE = 4096;
+    public static final int MAX_DHGEX_KEY_SIZE = 8192;
+
+    private static final AtomicInteger MAX_DHG_KEY_SIZE_HOLDER = new AtomicInteger(0);
+
+    static int getMaxDHGroupExchangeKeySize() {
+        int maxSupportedKeySize;
+        synchronized (MAX_DHG_KEY_SIZE_HOLDER) {
+            maxSupportedKeySize = MAX_DHG_KEY_SIZE_HOLDER.get();
+            if (maxSupportedKeySize != 0) { // 1st time we are called ?
+                return maxSupportedKeySize;
+            }
+            String propValue = System.getProperty(MAX_DHGEX_KEY_SIZE_PROP);
+            if (propValue == null || propValue.isEmpty()) {
+                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) {
+                    if (isDHGroupExchangeSupported(testKeySize)) {
+                        maxSupportedKeySize = testKeySize;
+                        break;
+                    }
+                }
+            } else {
+                Logger logger = LoggerFactory.getLogger(SecurityUtils.class);
+                logger.info("Override max. DH group exchange key size: " + propValue);
+                maxSupportedKeySize = Integer.parseInt(propValue);
+            }
+            MAX_DHG_KEY_SIZE_HOLDER.set(maxSupportedKeySize);
+        }
+        return maxSupportedKeySize;
+    }
+
+    static boolean isDHGroupExchangeSupported(int maxKeySize) {
+        try {
+            BigInteger r = new BigInteger("0").setBit(maxKeySize - 1);
+            DHParameterSpec dhSkipParamSpec = new DHParameterSpec(r, r);
+            KeyPairGenerator kpg = SecurityUtils.getKeyPairGenerator("DH");
+            kpg.initialize(dhSkipParamSpec);
+            return true;
+        } catch (GeneralSecurityException t) {
+            return false;
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/karaf/blob/78f539e9/client/src/main/java/org/apache/sshd/client/kex/FixedDHGEX256.java
----------------------------------------------------------------------
diff --git a/client/src/main/java/org/apache/sshd/client/kex/FixedDHGEX256.java b/client/src/main/java/org/apache/sshd/client/kex/FixedDHGEX256.java
new file mode 100644
index 0000000..b8f86b5
--- /dev/null
+++ b/client/src/main/java/org/apache/sshd/client/kex/FixedDHGEX256.java
@@ -0,0 +1,45 @@
+package org.apache.sshd.client.kex;
+
+import javax.crypto.spec.DHParameterSpec;
+import java.math.BigInteger;
+import java.security.GeneralSecurityException;
+import java.security.KeyPairGenerator;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.sshd.common.KeyExchange;
+import org.apache.sshd.common.NamedFactory;
+import org.apache.sshd.common.digest.SHA256;
+import org.apache.sshd.common.kex.DH;
+import org.apache.sshd.common.util.SecurityUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class FixedDHGEX256 extends FixedDHGEX {
+
+    /**
+     * Named factory for DHGEX key exchange
+     */
+    public static class Factory implements NamedFactory<KeyExchange> {
+
+        public String getName() {
+            return "diffie-hellman-group-exchange-sha256";
+        }
+
+        public KeyExchange create() {
+            return new FixedDHGEX256();
+        }
+
+    }
+
+    public FixedDHGEX256() {
+    }
+
+    @Override
+    protected DH getDH(BigInteger p, BigInteger g) throws Exception {
+        DH dh = new DH(new SHA256.Factory());
+        dh.setP(p);
+        dh.setG(g);
+        return dh;
+    }
+
+}