You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@karaf.apache.org by jb...@apache.org on 2016/06/14 13:08:37 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-3.0.x c9d7be1b7 -> b1b554d3a


[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/b1b554d3
Tree: http://git-wip-us.apache.org/repos/asf/karaf/tree/b1b554d3
Diff: http://git-wip-us.apache.org/repos/asf/karaf/diff/b1b554d3

Branch: refs/heads/karaf-3.0.x
Commit: b1b554d3a0cfc405dd51de272afaad87d5c50d80
Parents: c9d7be1
Author: Jean-Baptiste Onofr� <jb...@apache.org>
Authored: Tue Jun 14 15:07:47 2016 +0200
Committer: Jean-Baptiste Onofr� <jb...@apache.org>
Committed: Tue Jun 14 15:07:47 2016 +0200

----------------------------------------------------------------------
 client/pom.xml                                  |   1 +
 .../main/java/org/apache/karaf/client/Main.java |  27 +++--
 .../org/apache/sshd/client/kex/FixedDHGEX.java  | 116 +++++++++++++++++++
 .../apache/sshd/client/kex/FixedDHGEX256.java   |  54 +++++++++
 4 files changed, 189 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/karaf/blob/b1b554d3/client/pom.xml
----------------------------------------------------------------------
diff --git a/client/pom.xml b/client/pom.xml
index 95ade64..8919789 100644
--- a/client/pom.xml
+++ b/client/pom.xml
@@ -72,6 +72,7 @@
                         <Private-Package>
                             org.apache.karaf.client;
                             org.slf4j.impl;
+                            org.apache.sshd.client.kex;
                             META-INF;-split-package:=merge-first
                         </Private-Package>
                         <Include-Resource>

http://git-wip-us.apache.org/repos/asf/karaf/blob/b1b554d3/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 50071af..5acec9e 100644
--- a/client/src/main/java/org/apache/karaf/client/Main.java
+++ b/client/src/main/java/org/apache/karaf/client/Main.java
@@ -20,7 +20,9 @@ import java.io.*;
 import java.net.URL;
 import java.security.KeyPair;
 import java.nio.charset.Charset;
+import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.List;
 import java.util.Locale;
 import java.util.concurrent.ArrayBlockingQueue;
 import java.util.concurrent.BlockingQueue;
@@ -47,6 +49,7 @@ import org.apache.sshd.common.KeyExchange;
 import org.apache.sshd.common.NamedFactory;
 import org.apache.sshd.common.RuntimeSshException;
 import org.apache.sshd.common.keyprovider.FileKeyPairProvider;
+import org.apache.sshd.common.util.SecurityUtils;
 import org.fusesource.jansi.AnsiConsole;
 import org.slf4j.impl.SimpleLogger;
 
@@ -86,15 +89,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 = (SshClient)clientBuilder.build();
             setupAgent(config.getUser(), config.getKeyFile(), client);
@@ -186,6 +181,20 @@ public class Main {
         System.exit(exitStatus);
     }
 
+    private static List<NamedFactory<KeyExchange>> getKexFactories() {
+        List<NamedFactory<KeyExchange>> list = new ArrayList<NamedFactory<KeyExchange>>();
+        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 void setupAgent(String user, String keyFile, SshClient client) {
         SshAgent agent;
         URL builtInPrivateKey = Main.class.getClassLoader().getResource("karaf.key");

http://git-wip-us.apache.org/repos/asf/karaf/blob/b1b554d3/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..c481f49
--- /dev/null
+++ b/client/src/main/java/org/apache/sshd/client/kex/FixedDHGEX.java
@@ -0,0 +1,116 @@
+/*
+ * 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.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;
+        }
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/karaf/blob/b1b554d3/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..5dcaacc
--- /dev/null
+++ b/client/src/main/java/org/apache/sshd/client/kex/FixedDHGEX256.java
@@ -0,0 +1,54 @@
+/*
+ * 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.client.kex;
+
+import java.math.BigInteger;
+
+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;
+
+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;
+    }
+
+}
\ No newline at end of file