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: "Servers and clients SHOULD support groups with a modulus length of k
+ * bits, where 1024 <= k <= 8192".
+ * </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;
+ }
+
+}