You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mina.apache.org by gn...@apache.org on 2015/03/30 15:10:53 UTC

[1/2] mina-sshd git commit: [SSHD-442] Attach knowledge whether a signature is supported to the BuiltinSignature(s) enums

Repository: mina-sshd
Updated Branches:
  refs/heads/master b9e1401c1 -> 82b0f82ec


[SSHD-442] Attach knowledge whether a signature is supported to the BuiltinSignature(s) enums

Project: http://git-wip-us.apache.org/repos/asf/mina-sshd/repo
Commit: http://git-wip-us.apache.org/repos/asf/mina-sshd/commit/1f1b88f7
Tree: http://git-wip-us.apache.org/repos/asf/mina-sshd/tree/1f1b88f7
Diff: http://git-wip-us.apache.org/repos/asf/mina-sshd/diff/1f1b88f7

Branch: refs/heads/master
Commit: 1f1b88f706ca5341a55c8f9f88a71c8fc98cc9db
Parents: b9e1401
Author: Guillaume Nodet <gn...@apache.org>
Authored: Mon Mar 30 13:37:32 2015 +0200
Committer: Guillaume Nodet <gn...@apache.org>
Committed: Mon Mar 30 13:37:32 2015 +0200

----------------------------------------------------------------------
 .../main/java/org/apache/sshd/SshBuilder.java   | 121 +++++++++++--------
 .../org/apache/sshd/common/NamedFactory.java    |  14 ++-
 .../org/apache/sshd/common/OptionalFeature.java |  27 +++++
 .../sshd/common/cipher/BuiltinCiphers.java      |   6 +-
 .../sshd/common/kex/BuiltinDHFactories.java     |  35 ++++--
 .../org/apache/sshd/common/kex/DHFactory.java   |   4 -
 .../org/apache/sshd/common/mac/BuiltinMacs.java |  11 +-
 .../common/signature/BuiltinSignatures.java     |  24 +++-
 .../java/org/apache/sshd/SshBuilderTest.java    |  52 ++++++++
 .../sshd/common/cipher/BuiltinCiphersTest.java  |  18 +++
 .../sshd/common/kex/BuiltinDHFactoriesTest.java |  18 ++-
 .../apache/sshd/common/mac/BuiltinMacsTest.java |  60 +++++++++
 .../common/signature/BuiltinSignaturesTest.java |  42 +++++++
 13 files changed, 355 insertions(+), 77 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/1f1b88f7/sshd-core/src/main/java/org/apache/sshd/SshBuilder.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/SshBuilder.java b/sshd-core/src/main/java/org/apache/sshd/SshBuilder.java
index 38ebf63..0fc65c0 100644
--- a/sshd-core/src/main/java/org/apache/sshd/SshBuilder.java
+++ b/sshd-core/src/main/java/org/apache/sshd/SshBuilder.java
@@ -35,6 +35,7 @@ import org.apache.sshd.common.Factory;
 import org.apache.sshd.common.KeyExchange;
 import org.apache.sshd.common.Mac;
 import org.apache.sshd.common.NamedFactory;
+import org.apache.sshd.common.NamedFactory.Utils;
 import org.apache.sshd.common.Random;
 import org.apache.sshd.common.RequestHandler;
 import org.apache.sshd.common.Signature;
@@ -82,9 +83,7 @@ public class SshBuilder {
      * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
      */
     protected static class BaseBuilder<T extends AbstractFactoryManager, S extends BaseBuilder<T, S>> implements ObjectBuilder<T> {
-
         protected Factory<T> factory = null;
-
         protected List<NamedFactory<KeyExchange>> keyExchangeFactories = null;
         protected List<NamedFactory<Cipher>> cipherFactories = null;
         protected List<NamedFactory<Compression>> compressionFactories = null;
@@ -97,38 +96,14 @@ public class SshBuilder {
         protected List<RequestHandler<ConnectionService>> globalRequestHandlers = null;
 
         protected S fillWithDefaultValues() {
-            if (SecurityUtils.isBouncyCastleRegistered()) {
-                if (signatureFactories == null) {
-                    signatureFactories = Arrays.<NamedFactory<Signature>>asList(
-                            BuiltinSignatures.nistp256,
-                            BuiltinSignatures.nistp384,
-                            BuiltinSignatures.nistp521,
-                            BuiltinSignatures.dsa,
-                            BuiltinSignatures.rsa);
-                }
-                if (randomFactory == null) {
+            if (signatureFactories == null) {
+                signatureFactories = setUpDefaultSignatures(false);
+            }
+
+            if (randomFactory == null) {
+                if (SecurityUtils.isBouncyCastleRegistered()) {
                     randomFactory = new SingletonRandomFactory(new BouncyCastleRandom.Factory());
-                }
-                // EC keys are not supported until OpenJDK 7
-            } else if (SecurityUtils.hasEcc()) {
-                if (signatureFactories == null) {
-                    signatureFactories = Arrays.<NamedFactory<Signature>>asList(
-                            BuiltinSignatures.nistp256,
-                            BuiltinSignatures.nistp384,
-                            BuiltinSignatures.nistp521,
-                            BuiltinSignatures.dsa,
-                            BuiltinSignatures.rsa);
-                }
-                if (randomFactory == null) {
-                    randomFactory = new SingletonRandomFactory(new JceRandom.Factory());
-                }
-            } else {
-                if (signatureFactories == null) {
-                    signatureFactories = Arrays.<NamedFactory<Signature>>asList(
-                            BuiltinSignatures.dsa,
-                            BuiltinSignatures.rsa);
-                }
-                if (randomFactory == null) {
+                } else {
                     randomFactory = new SingletonRandomFactory(new JceRandom.Factory());
                 }
             }
@@ -149,14 +124,9 @@ public class SshBuilder {
                         new CompressionNone.Factory());
             }
             if (macFactories == null) {
-                macFactories = Arrays.<NamedFactory<Mac>>asList(
-                        BuiltinMacs.hmacsha256,
-                        BuiltinMacs.hmacsha512,
-                        BuiltinMacs.hmacsha1,
-                        BuiltinMacs.hmacmd5,
-                        BuiltinMacs.hmacsha196,
-                        BuiltinMacs.hmacmd596);
+                macFactories = setUpDefaultMacs(false);
             }
+
             if (fileSystemFactory == null) {
                 fileSystemFactory = new NativeFileSystemFactory();
             }
@@ -287,14 +257,7 @@ public class SshBuilder {
          * @see BuiltinCiphers#isSupported()
          */
         public static List<NamedFactory<Cipher>> setUpDefaultCiphers(boolean ignoreUnsupported) {
-            List<NamedFactory<Cipher>> avail = new ArrayList<NamedFactory<Cipher>>(DEFAULT_CIPHERS_PREFERENCE.size());
-            for (BuiltinCiphers c : DEFAULT_CIPHERS_PREFERENCE) {
-                if (ignoreUnsupported || c.isSupported()) {
-                    avail.add(c);
-                }
-            }
-
-            return avail;
+            return Utils.setUpBuiltinFactories(ignoreUnsupported, DEFAULT_CIPHERS_PREFERENCE);
         }
         
         /**
@@ -316,6 +279,65 @@ public class SshBuilder {
                                 BuiltinDHFactories.dhg1
                         ));
 
+        /**
+         * The default {@link BuiltinMacs} setup in order of preference
+         * as specified by <A HREF="https://www.freebsd.org/cgi/man.cgi?query=ssh_config&sektion=5">
+         * ssh_config(5)</A> 
+         */
+        public static final List<BuiltinMacs>   DEFAULT_MAC_PREFERENCE=
+                Collections.unmodifiableList(
+                        Arrays.asList(
+                                BuiltinMacs.hmacmd5,
+                                BuiltinMacs.hmacsha1,
+                                BuiltinMacs.hmacsha256,
+                                BuiltinMacs.hmacsha512,
+                                BuiltinMacs.hmacsha196,
+                                BuiltinMacs.hmacmd596
+                        ));
+        /**
+         * @param ignoreUnsupported If {@code true} all the available built-in
+         * {@link Mac} factories are added, otherwise only those that are supported
+         * by the current JDK setup
+         * @return A {@link List} of the default {@link NamedFactory}
+         * instances of the {@link Mac}s according to the preference
+         * order defined by {@link #DEFAULT_MAC_PREFERENCE}.
+         * <B>Note:</B> the list may be filtered to exclude unsupported JCE
+         * MACs according to the <tt>ignoreUnsupported</tt> parameter
+         * @see BuiltinMacs#isSupported()
+         */
+        public static final List<NamedFactory<Mac>> setUpDefaultMacs(boolean ignoreUnsupported) {
+            return Utils.setUpBuiltinFactories(ignoreUnsupported, DEFAULT_MAC_PREFERENCE);
+        }
+        
+        /**
+         * Preferred {@link BuiltinSignatures} according to
+         * <A HREF="https://www.freebsd.org/cgi/man.cgi?query=ssh_config&sektion=5>sshd_config(5)</A>
+         * {@code HostKeyAlgorithms} recommendation
+         */
+        public static final List<BuiltinSignatures> DEFAULT_SIGNATURE_PREFERENCE=
+                Collections.unmodifiableList(
+                        Arrays.asList(
+                                BuiltinSignatures.nistp256,
+                                BuiltinSignatures.nistp384,
+                                BuiltinSignatures.nistp521,
+                                BuiltinSignatures.rsa,
+                                BuiltinSignatures.dsa
+                        ));
+
+        /**
+         * @param ignoreUnsupported If {@code true} all the available built-in
+         * {@link Signature} factories are added, otherwise only those that are supported
+         * by the current JDK setup
+         * @return A {@link List} of the default {@link NamedFactory}
+         * instances of the {@link Signature}s according to the preference
+         * order defined by {@link #DEFAULT_SIGNATURE_PREFERENCE}.
+         * <B>Note:</B> the list may be filtered to exclude unsupported JCE
+         * signatures according to the <tt>ignoreUnsupported</tt> parameter
+         * @see BuiltinSignatures#isSupported()
+         */
+        public static final List<NamedFactory<Signature>> setUpDefaultSignatures(boolean ignoreUnsupported) {
+            return Utils.setUpBuiltinFactories(ignoreUnsupported, DEFAULT_SIGNATURE_PREFERENCE);
+        }
     }
 
     /**
@@ -385,7 +407,6 @@ public class SshBuilder {
                 return DHGClient.newFactory(factory);
             }
         }
-
     }
 
     /**
@@ -446,7 +467,5 @@ public class SshBuilder {
                 return DHGServer.newFactory(factory);
             }
         }
-
     }
-
 }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/1f1b88f7/sshd-core/src/main/java/org/apache/sshd/common/NamedFactory.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/NamedFactory.java b/sshd-core/src/main/java/org/apache/sshd/common/NamedFactory.java
index 9d2c164..77b8cdc 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/NamedFactory.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/NamedFactory.java
@@ -127,6 +127,18 @@ public interface NamedFactory<T> extends Factory<T>, NamedResource {
             }
             return null;
         }
+        
+        
+        public static final <T,E extends NamedFactory<T> & OptionalFeature> List<NamedFactory<T>> setUpBuiltinFactories(
+                boolean ignoreUnsupported, Collection<? extends E> preferred) {
+            List<NamedFactory<T>>   avail=new ArrayList<>(preferred.size());
+            for (E f : preferred) {
+                if (ignoreUnsupported || f.isSupported()) {
+                    avail.add(f);
+                }
+            }
+            
+            return avail;
+        }
     }
-
 }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/1f1b88f7/sshd-core/src/main/java/org/apache/sshd/common/OptionalFeature.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/OptionalFeature.java b/sshd-core/src/main/java/org/apache/sshd/common/OptionalFeature.java
new file mode 100644
index 0000000..21bee61
--- /dev/null
+++ b/sshd-core/src/main/java/org/apache/sshd/common/OptionalFeature.java
@@ -0,0 +1,27 @@
+/*
+ * 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;
+
+/**
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ */
+public interface OptionalFeature {
+    boolean isSupported();
+}

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/1f1b88f7/sshd-core/src/main/java/org/apache/sshd/common/cipher/BuiltinCiphers.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/cipher/BuiltinCiphers.java b/sshd-core/src/main/java/org/apache/sshd/common/cipher/BuiltinCiphers.java
index d6c0526..78f1749 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/cipher/BuiltinCiphers.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/cipher/BuiltinCiphers.java
@@ -26,6 +26,7 @@ import java.util.concurrent.atomic.AtomicReference;
 
 import org.apache.sshd.common.Cipher;
 import org.apache.sshd.common.NamedFactory;
+import org.apache.sshd.common.OptionalFeature;
 import org.apache.sshd.common.util.GenericUtils;
 
 /**
@@ -33,7 +34,7 @@ import org.apache.sshd.common.util.GenericUtils;
  *
  * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
  */
-public enum BuiltinCiphers implements NamedFactory<Cipher> {
+public enum BuiltinCiphers implements NamedFactory<Cipher>, OptionalFeature {
     none(Constants.NONE) {
         @Override
         public Cipher create() {
@@ -119,6 +120,7 @@ public enum BuiltinCiphers implements NamedFactory<Cipher> {
      * cipher - e.g., AES-256 requires the <A HREF="http://www.oracle.com/technetwork/java/javase/downloads/">
      * Java Cryptography Extension (JCE)</A>
      */
+    @Override
     public boolean isSupported() {
         Boolean value;
         synchronized (_supported) {
@@ -193,7 +195,7 @@ public enum BuiltinCiphers implements NamedFactory<Cipher> {
         return null;
     }
 
-    private static class Constants {
+    public static final class Constants {
         public static final String NONE = "none";
         public static final String AES128_CBC = "aes128-cbc";
         public static final String AES128_CTR = "aes128-ctr";

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/1f1b88f7/sshd-core/src/main/java/org/apache/sshd/common/kex/BuiltinDHFactories.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/kex/BuiltinDHFactories.java b/sshd-core/src/main/java/org/apache/sshd/common/kex/BuiltinDHFactories.java
index b3ba27d..7dc630d 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/kex/BuiltinDHFactories.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/kex/BuiltinDHFactories.java
@@ -24,6 +24,7 @@ import java.util.Collections;
 import java.util.EnumSet;
 import java.util.Set;
 
+import org.apache.sshd.common.OptionalFeature;
 import org.apache.sshd.common.cipher.ECCurves;
 import org.apache.sshd.common.digest.BuiltinDigests;
 import org.apache.sshd.common.util.GenericUtils;
@@ -32,12 +33,11 @@ import org.apache.sshd.common.util.SecurityUtils;
 /**
  * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
  */
-public enum BuiltinDHFactories implements DHFactory {
-
+public enum BuiltinDHFactories implements DHFactory, OptionalFeature {
     dhg1(Constants.DIFFIE_HELLMAN_GROUP1_SHA1) {
         @Override
         public DHG create(Object... params) throws Exception {
-            if (params != null && params.length > 0) {
+            if (!GenericUtils.isEmpty(params)) {
                 throw new IllegalArgumentException("No accepted parameters for " + getName());
             }
             return new DHG(BuiltinDigests.sha1, new BigInteger(DHGroupData.getP1()), new BigInteger(DHGroupData.getG()));
@@ -46,11 +46,12 @@ public enum BuiltinDHFactories implements DHFactory {
     dhg14(Constants.DIFFIE_HELLMAN_GROUP14_SHA1) {
         @Override
         public DHG create(Object... params) throws Exception {
-            if (params != null && params.length > 0) {
+            if (!GenericUtils.isEmpty(params)) {
                 throw new IllegalArgumentException("No accepted parameters for " + getName());
             }
             return new DHG(BuiltinDigests.sha1, new BigInteger(DHGroupData.getP14()), new BigInteger(DHGroupData.getG()));
         }
+
         @Override
         public boolean isSupported() {
             return SecurityUtils.isBouncyCastleRegistered();
@@ -59,12 +60,14 @@ public enum BuiltinDHFactories implements DHFactory {
     dhgex(Constants.DIFFIE_HELLMAN_GROUP_EXCHANGE_SHA1) {
         @Override
         public DHG create(Object... params) throws Exception {
-            if (params == null || params.length != 2
-                    || !(params[0] instanceof BigInteger) || !(params[1] instanceof BigInteger)) {
+            if ((GenericUtils.length(params) != 2)
+             || (!(params[0] instanceof BigInteger))
+             || (!(params[1] instanceof BigInteger))) {
                 throw new IllegalArgumentException("Bad parameters for " + getName());
             }
             return new DHG(BuiltinDigests.sha1, (BigInteger) params[0], (BigInteger) params[1]);
         }
+
         @Override
         public boolean isGroupExchange() {
             return true;
@@ -73,16 +76,19 @@ public enum BuiltinDHFactories implements DHFactory {
     dhgex256(Constants.DIFFIE_HELLMAN_GROUP_EXCHANGE_SHA256) {
         @Override
         public AbstractDH create(Object... params) throws Exception {
-            if (params == null || params.length != 2
-                    || !(params[0] instanceof BigInteger) || !(params[1] instanceof BigInteger)) {
+            if ((GenericUtils.length(params) != 2)
+             || (!(params[0] instanceof BigInteger))
+             || (!(params[1] instanceof BigInteger))) {
                 throw new IllegalArgumentException("Bad parameters for " + getName());
             }
             return new DHG(BuiltinDigests.sha256, (BigInteger) params[0], (BigInteger) params[1]);
         }
+
         @Override
         public boolean isSupported() {  // avoid "Prime size must be multiple of 64, and can only range from 512 to 2048 (inclusive)"
             return SecurityUtils.isBouncyCastleRegistered();
         }
+
         @Override
         public boolean isGroupExchange() {
             return true;
@@ -91,11 +97,12 @@ public enum BuiltinDHFactories implements DHFactory {
     ecdhp256(Constants.ECDH_SHA2_NISTP256) {
         @Override
         public ECDH create(Object... params) throws Exception {
-            if (params != null && params.length > 0) {
+            if (!GenericUtils.isEmpty(params)) {
                 throw new IllegalArgumentException("No accepted parameters for " + getName());
             }
             return new ECDH(ECCurves.EllipticCurves.nistp256);
         }
+
         @Override
         public boolean isSupported() {
             return SecurityUtils.hasEcc();
@@ -104,11 +111,12 @@ public enum BuiltinDHFactories implements DHFactory {
     ecdhp384(Constants.ECDH_SHA2_NISTP384) {
         @Override
         public ECDH create(Object... params) throws Exception {
-            if (params != null && params.length > 0) {
+            if (!GenericUtils.isEmpty(params)) {
                 throw new IllegalArgumentException("No accepted parameters for " + getName());
             }
             return new ECDH(ECCurves.EllipticCurves.nistp384);
         }
+
         @Override
         public boolean isSupported() {
             return SecurityUtils.hasEcc();
@@ -117,11 +125,12 @@ public enum BuiltinDHFactories implements DHFactory {
     ecdhp521(Constants.ECDH_SHA2_NISTP521) {
         @Override
         public ECDH create(Object... params) throws Exception {
-            if (params != null && params.length > 0) {
+            if (!GenericUtils.isEmpty(params)) {
                 throw new IllegalArgumentException("No accepted parameters for " + getName());
             }
             return new ECDH(ECCurves.EllipticCurves.nistp521);
         }
+
         @Override
         public boolean isSupported() {
             return SecurityUtils.hasEcc();
@@ -135,6 +144,7 @@ public enum BuiltinDHFactories implements DHFactory {
         return factoryName;
     }
 
+    @Override
     public boolean isSupported() {
         return true;
     }
@@ -170,7 +180,7 @@ public enum BuiltinDHFactories implements DHFactory {
         return false;
     }
 
-    public static class Constants {
+    public static final class Constants {
         public static final String DIFFIE_HELLMAN_GROUP1_SHA1 = "diffie-hellman-group1-sha1";
         public static final String DIFFIE_HELLMAN_GROUP14_SHA1 = "diffie-hellman-group14-sha1";
         public static final String DIFFIE_HELLMAN_GROUP_EXCHANGE_SHA1 = "diffie-hellman-group-exchange-sha1";
@@ -179,5 +189,4 @@ public enum BuiltinDHFactories implements DHFactory {
         public static final String ECDH_SHA2_NISTP384 = "ecdh-sha2-nistp384";
         public static final String ECDH_SHA2_NISTP521 = "ecdh-sha2-nistp521";
     }
-
 }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/1f1b88f7/sshd-core/src/main/java/org/apache/sshd/common/kex/DHFactory.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/kex/DHFactory.java b/sshd-core/src/main/java/org/apache/sshd/common/kex/DHFactory.java
index ad80eca..ad0e295 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/kex/DHFactory.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/kex/DHFactory.java
@@ -18,17 +18,13 @@
  */
 package org.apache.sshd.common.kex;
 
-import java.math.BigInteger;
-
 import org.apache.sshd.common.NamedResource;
 
 /**
  * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
  */
 public interface DHFactory extends NamedResource {
-
     boolean isGroupExchange();
 
     AbstractDH create(Object... params) throws Exception;
-
 }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/1f1b88f7/sshd-core/src/main/java/org/apache/sshd/common/mac/BuiltinMacs.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/mac/BuiltinMacs.java b/sshd-core/src/main/java/org/apache/sshd/common/mac/BuiltinMacs.java
index df8aa6d..75f6c4c 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/mac/BuiltinMacs.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/mac/BuiltinMacs.java
@@ -26,6 +26,7 @@ import java.util.Set;
 import org.apache.sshd.common.Digest;
 import org.apache.sshd.common.Mac;
 import org.apache.sshd.common.NamedFactory;
+import org.apache.sshd.common.OptionalFeature;
 import org.apache.sshd.common.util.GenericUtils;
 
 /**
@@ -33,7 +34,7 @@ import org.apache.sshd.common.util.GenericUtils;
  *
  * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
  */
-public enum BuiltinMacs implements NamedFactory<Mac> {
+public enum BuiltinMacs implements NamedFactory<Mac>, OptionalFeature {
     hmacmd5(Constants.HMAC_MD5) {
         @Override
         public Mac create() {
@@ -78,11 +79,15 @@ public enum BuiltinMacs implements NamedFactory<Mac> {
         return factoryName;
     }
 
+    @Override
+    public final boolean isSupported() {
+        return true;
+    }
+
     BuiltinMacs(String facName) {
         factoryName = facName;
     }
 
-
     public static final Set<BuiltinMacs> VALUES =
             Collections.unmodifiableSet(EnumSet.allOf(BuiltinMacs.class));
 
@@ -138,7 +143,7 @@ public enum BuiltinMacs implements NamedFactory<Mac> {
         return null;
     }
 
-    private static class Constants {
+    public static final class Constants {
         public static final String HMAC_MD5 = "hmac-md5";
         public static final String HMAC_MD5_96 = "hmac-md5-96";
         public static final String HMAC_SHA1 = "hmac-sha1";

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/1f1b88f7/sshd-core/src/main/java/org/apache/sshd/common/signature/BuiltinSignatures.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/signature/BuiltinSignatures.java b/sshd-core/src/main/java/org/apache/sshd/common/signature/BuiltinSignatures.java
index 425a47f..86c85ad 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/signature/BuiltinSignatures.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/signature/BuiltinSignatures.java
@@ -27,16 +27,18 @@ import java.util.Set;
 import org.apache.sshd.common.Digest;
 import org.apache.sshd.common.KeyPairProvider;
 import org.apache.sshd.common.NamedFactory;
+import org.apache.sshd.common.OptionalFeature;
 import org.apache.sshd.common.Signature;
 import org.apache.sshd.common.cipher.ECCurves;
 import org.apache.sshd.common.util.GenericUtils;
+import org.apache.sshd.common.util.SecurityUtils;
 
 /**
  * Provides easy access to the currently implemented macs
  *
  * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
  */
-public enum BuiltinSignatures implements NamedFactory<Signature> {
+public enum BuiltinSignatures implements NamedFactory<Signature>, OptionalFeature {
     dsa(KeyPairProvider.SSH_DSS) {
         @Override
         public Signature create() {
@@ -54,18 +56,33 @@ public enum BuiltinSignatures implements NamedFactory<Signature> {
         public Signature create() {
             return new SignatureECDSA("SHA256withECDSA");
         }
+        
+        @Override
+        public boolean isSupported() {
+            return SecurityUtils.isBouncyCastleRegistered() || SecurityUtils.hasEcc();
+        }
     },
     nistp384(KeyPairProvider.ECDSA_SHA2_NISTP384) {
         @Override
         public Signature create() {
             return new SignatureECDSA("SHA384withECDSA");
         }
+        
+        @Override
+        public boolean isSupported() {
+            return SecurityUtils.isBouncyCastleRegistered() || SecurityUtils.hasEcc();
+        }
     },
     nistp521(KeyPairProvider.ECDSA_SHA2_NISTP521) {
         @Override
         public Signature create() {
             return new SignatureECDSA("SHA512withECDSA");
         }
+        
+        @Override
+        public boolean isSupported() {
+            return SecurityUtils.isBouncyCastleRegistered() || SecurityUtils.hasEcc();
+        }
     };
 
     private final String factoryName;
@@ -90,6 +107,10 @@ public enum BuiltinSignatures implements NamedFactory<Signature> {
         factoryName = facName;
     }
 
+    @Override
+    public boolean isSupported() {
+        return true;
+    }
 
     public static final Set<BuiltinSignatures> VALUES =
             Collections.unmodifiableSet(EnumSet.allOf(BuiltinSignatures.class));
@@ -145,5 +166,4 @@ public enum BuiltinSignatures implements NamedFactory<Signature> {
 
         return null;
     }
-
 }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/1f1b88f7/sshd-core/src/test/java/org/apache/sshd/SshBuilderTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/SshBuilderTest.java b/sshd-core/src/test/java/org/apache/sshd/SshBuilderTest.java
index a1d9a39..4046d15 100644
--- a/sshd-core/src/test/java/org/apache/sshd/SshBuilderTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/SshBuilderTest.java
@@ -19,12 +19,18 @@
 
 package org.apache.sshd;
 
+import java.util.Collection;
+import java.util.EnumSet;
 import java.util.List;
+import java.util.Set;
 
 import org.apache.sshd.SshBuilder.BaseBuilder;
 import org.apache.sshd.common.Cipher;
 import org.apache.sshd.common.NamedFactory;
 import org.apache.sshd.common.cipher.BuiltinCiphers;
+import org.apache.sshd.common.kex.BuiltinDHFactories;
+import org.apache.sshd.common.mac.BuiltinMacs;
+import org.apache.sshd.common.signature.BuiltinSignatures;
 import org.apache.sshd.common.util.GenericUtils;
 import org.apache.sshd.util.BaseTest;
 import org.junit.Assert;
@@ -39,6 +45,52 @@ public class SshBuilderTest extends BaseTest {
     }
 
     /**
+     * Make sure that all values in {@link BuiltinCiphers} are
+     * listed in {@link BaseBuilder#DEFAULT_CIPHERS_PREFERENCE}
+     */
+    @Test
+    public void testAllBuiltinCiphersListed() {
+        Set<BuiltinCiphers> all=EnumSet.allOf(BuiltinCiphers.class);
+        // The 'none' cipher is not listed as preferred - it is implied
+        Assert.assertTrue("Missing " + BuiltinCiphers.Constants.NONE + " cipher in all values", all.remove(BuiltinCiphers.none));
+        testAllInstancesListed(all, BaseBuilder.DEFAULT_CIPHERS_PREFERENCE);
+    }
+
+    /**
+     * Make sure that all values in {@link BuiltinMacs} are
+     * listed in {@link BaseBuilder#DEFAULT_MAC_PREFERENCE}
+     */
+    @Test
+    public void testAllBuiltinMacsListed() {
+        testAllInstancesListed(BuiltinMacs.VALUES, BaseBuilder.DEFAULT_MAC_PREFERENCE);
+    }
+
+    /**
+     * Make sure that all values in {@link BuiltinSignatures} are
+     * listed in {@link BaseBuilder#DEFAULT_SIGNATURE_PREFERENCE}
+     */
+    @Test
+    public void testAllBuiltinSignaturesListed() {
+        testAllInstancesListed(BuiltinSignatures.VALUES, BaseBuilder.DEFAULT_SIGNATURE_PREFERENCE);
+    }
+
+    /**
+     * Make sure that all values in {@link BuiltinDHFactories} are
+     * listed in {@link BaseBuilder#DEFAULT_KEX_PREFERENCE}
+     */
+    @Test
+    public void testAllBuiltinDHFactoriesListed() {
+        testAllInstancesListed(BuiltinDHFactories.VALUES, BaseBuilder.DEFAULT_KEX_PREFERENCE);
+    }
+
+    private static <E extends Enum<E>> void testAllInstancesListed(Set<? extends E> expValues, Collection<? extends E> actValues) {
+        Assert.assertEquals("Mismatched actual values size", expValues.size(), actValues.size());
+        for (E expected : expValues) {
+            Assert.assertTrue(expected.name() + " not found in actual values", actValues.contains(expected));
+        }
+    }
+
+    /**
      * Make sure that {@link BaseBuilder#setUpDefaultCiphers(boolean)} returns
      * the correct result - i.e., according to the {@code ingoreUnsupported}
      * parameter and in the defined preference order

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/1f1b88f7/sshd-core/src/test/java/org/apache/sshd/common/cipher/BuiltinCiphersTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/common/cipher/BuiltinCiphersTest.java b/sshd-core/src/test/java/org/apache/sshd/common/cipher/BuiltinCiphersTest.java
index 357502b..70d9d34 100644
--- a/sshd-core/src/test/java/org/apache/sshd/common/cipher/BuiltinCiphersTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/common/cipher/BuiltinCiphersTest.java
@@ -19,6 +19,10 @@
 
 package org.apache.sshd.common.cipher;
 
+import java.lang.reflect.Field;
+import java.util.EnumSet;
+import java.util.Set;
+
 import org.apache.sshd.common.Cipher;
 import org.apache.sshd.common.NamedFactory;
 import org.apache.sshd.util.BaseTest;
@@ -75,6 +79,20 @@ public class BuiltinCiphersTest extends BaseTest {
         }
     }
 
+    @Test
+    public void testAllConstantsCovered() throws Exception {
+        Set<BuiltinCiphers> avail=EnumSet.noneOf(BuiltinCiphers.class);
+        Field[]             fields=BuiltinCiphers.Constants.class.getFields();
+        for (Field f : fields) {
+            String          name=(String) f.get(null);
+            BuiltinCiphers  value=BuiltinCiphers.fromFactoryName(name);
+            Assert.assertNotNull("No match found for " + name, value);
+            Assert.assertTrue(name + " re-specified", avail.add(value));
+        }
+        
+        Assert.assertEquals("Incomplete coverage", BuiltinCiphers.VALUES, avail);
+    }
+
 //    @Test
 //    public void testFromCipher() {
 //        for (BuiltinCiphers expected : BuiltinCiphers.VALUES) {

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/1f1b88f7/sshd-core/src/test/java/org/apache/sshd/common/kex/BuiltinDHFactoriesTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/common/kex/BuiltinDHFactoriesTest.java b/sshd-core/src/test/java/org/apache/sshd/common/kex/BuiltinDHFactoriesTest.java
index 6a53dd3..61ebcf6 100644
--- a/sshd-core/src/test/java/org/apache/sshd/common/kex/BuiltinDHFactoriesTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/common/kex/BuiltinDHFactoriesTest.java
@@ -19,6 +19,10 @@
 
 package org.apache.sshd.common.kex;
 
+import java.lang.reflect.Field;
+import java.util.EnumSet;
+import java.util.Set;
+
 import org.apache.sshd.util.BaseTest;
 import org.junit.Assert;
 import org.junit.Test;
@@ -27,7 +31,6 @@ import org.junit.Test;
  * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
  */
 public class BuiltinDHFactoriesTest extends BaseTest {
-
     public BuiltinDHFactoriesTest() {
         super();
     }
@@ -41,4 +44,17 @@ public class BuiltinDHFactoriesTest extends BaseTest {
         }
     }
 
+    @Test
+    public void testAllConstantsCovered() throws Exception {
+        Set<BuiltinDHFactories> avail=EnumSet.noneOf(BuiltinDHFactories.class);
+        Field[]             fields=BuiltinDHFactories.Constants.class.getFields();
+        for (Field f : fields) {
+            String          name=(String) f.get(null);
+            BuiltinDHFactories  value=BuiltinDHFactories.fromFactoryName(name);
+            Assert.assertNotNull("No match found for " + name, value);
+            Assert.assertTrue(name + " re-specified", avail.add(value));
+        }
+        
+        Assert.assertEquals("Incomplete coverage", BuiltinDHFactories.VALUES, avail);
+    }
 }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/1f1b88f7/sshd-core/src/test/java/org/apache/sshd/common/mac/BuiltinMacsTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/common/mac/BuiltinMacsTest.java b/sshd-core/src/test/java/org/apache/sshd/common/mac/BuiltinMacsTest.java
new file mode 100644
index 0000000..7867d28
--- /dev/null
+++ b/sshd-core/src/test/java/org/apache/sshd/common/mac/BuiltinMacsTest.java
@@ -0,0 +1,60 @@
+/*
+ * 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.mac;
+
+import java.lang.reflect.Field;
+import java.util.EnumSet;
+import java.util.Set;
+
+import org.apache.sshd.util.BaseTest;
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ */
+public class BuiltinMacsTest extends BaseTest {
+    public BuiltinMacsTest() {
+        super();
+    }
+
+    @Test
+    public void testFromName() {
+        for (BuiltinMacs expected : BuiltinMacs.VALUES) {
+            String name = expected.getName();
+            BuiltinMacs actual = BuiltinMacs.fromFactoryName(name);
+            Assert.assertSame(name, expected, actual);
+        }
+    }
+
+    @Test
+    public void testAllConstantsCovered() throws Exception {
+        Set<BuiltinMacs> avail=EnumSet.noneOf(BuiltinMacs.class);
+        Field[]             fields=BuiltinMacs.Constants.class.getFields();
+        for (Field f : fields) {
+            String          name=(String) f.get(null);
+            BuiltinMacs  value=BuiltinMacs.fromFactoryName(name);
+            Assert.assertNotNull("No match found for " + name, value);
+            Assert.assertTrue(name + " re-specified", avail.add(value));
+        }
+        
+        Assert.assertEquals("Incomplete coverage", BuiltinMacs.VALUES, avail);
+    }
+}

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/1f1b88f7/sshd-core/src/test/java/org/apache/sshd/common/signature/BuiltinSignaturesTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/common/signature/BuiltinSignaturesTest.java b/sshd-core/src/test/java/org/apache/sshd/common/signature/BuiltinSignaturesTest.java
new file mode 100644
index 0000000..99bd1d7
--- /dev/null
+++ b/sshd-core/src/test/java/org/apache/sshd/common/signature/BuiltinSignaturesTest.java
@@ -0,0 +1,42 @@
+/*
+ * 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.signature;
+
+import org.apache.sshd.util.BaseTest;
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ */
+public class BuiltinSignaturesTest extends BaseTest {
+    public BuiltinSignaturesTest() {
+        super();
+    }
+
+    @Test
+    public void testFromName() {
+        for (BuiltinSignatures expected : BuiltinSignatures.VALUES) {
+            String name = expected.getName();
+            BuiltinSignatures actual = BuiltinSignatures.fromFactoryName(name);
+            Assert.assertSame(name, expected, actual);
+        }
+    }
+}


[2/2] mina-sshd git commit: [SSHD-443] Improve supported cipher detection

Posted by gn...@apache.org.
[SSHD-443] Improve supported cipher detection

Project: http://git-wip-us.apache.org/repos/asf/mina-sshd/repo
Commit: http://git-wip-us.apache.org/repos/asf/mina-sshd/commit/82b0f82e
Tree: http://git-wip-us.apache.org/repos/asf/mina-sshd/tree/82b0f82e
Diff: http://git-wip-us.apache.org/repos/asf/mina-sshd/diff/82b0f82e

Branch: refs/heads/master
Commit: 82b0f82ece8deac40b48bbce69cab840a9e64f56
Parents: 1f1b88f
Author: Guillaume Nodet <gn...@apache.org>
Authored: Mon Mar 30 15:00:04 2015 +0200
Committer: Guillaume Nodet <gn...@apache.org>
Committed: Mon Mar 30 15:00:04 2015 +0200

----------------------------------------------------------------------
 .../apache/sshd/common/cipher/BaseCipher.java   |   7 +-
 .../sshd/common/cipher/BuiltinCiphers.java      | 143 +++++++++----------
 .../apache/sshd/common/cipher/CipherUtils.java  |  58 --------
 .../test/java/org/apache/sshd/CipherTest.java   |  28 ++--
 .../sshd/common/cipher/BuiltinCiphersTest.java  |  29 ++--
 5 files changed, 108 insertions(+), 157 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/82b0f82e/sshd-core/src/main/java/org/apache/sshd/common/cipher/BaseCipher.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/cipher/BaseCipher.java b/sshd-core/src/main/java/org/apache/sshd/common/cipher/BaseCipher.java
index 33c18b2..66a283c 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/cipher/BaseCipher.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/cipher/BaseCipher.java
@@ -22,6 +22,7 @@ import javax.crypto.spec.IvParameterSpec;
 import javax.crypto.spec.SecretKeySpec;
 
 import org.apache.sshd.common.Cipher;
+import org.apache.sshd.common.SshException;
 import org.apache.sshd.common.util.SecurityUtils;
 
 /**
@@ -63,7 +64,7 @@ public class BaseCipher implements Cipher {
         }
         catch (Exception e) {
             cipher = null;
-            throw e;
+            throw new SshException("Unable to initialize cipher " + this, e);
         }
     }
 
@@ -80,4 +81,8 @@ public class BaseCipher implements Cipher {
         return data;
     }
 
+    @Override
+    public String toString() {
+        return getClass().getSimpleName() + "[" + algorithm + "," + ivsize + "," + bsize + "," + transformation + "]";
+    }
 }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/82b0f82e/sshd-core/src/main/java/org/apache/sshd/common/cipher/BuiltinCiphers.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/cipher/BuiltinCiphers.java b/sshd-core/src/main/java/org/apache/sshd/common/cipher/BuiltinCiphers.java
index 78f1749..52cef83 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/cipher/BuiltinCiphers.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/cipher/BuiltinCiphers.java
@@ -22,7 +22,6 @@ package org.apache.sshd.common.cipher;
 import java.util.Collections;
 import java.util.EnumSet;
 import java.util.Set;
-import java.util.concurrent.atomic.AtomicReference;
 
 import org.apache.sshd.common.Cipher;
 import org.apache.sshd.common.NamedFactory;
@@ -35,85 +34,52 @@ import org.apache.sshd.common.util.GenericUtils;
  * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
  */
 public enum BuiltinCiphers implements NamedFactory<Cipher>, OptionalFeature {
-    none(Constants.NONE) {
+    none(Constants.NONE, 0, 0, "None", "None") {
         @Override
         public Cipher create() {
             return new CipherNone();
         }
     },
-    aes128cbc(Constants.AES128_CBC) {
+    aes128cbc(Constants.AES128_CBC, 16, 16, "AES", "AES/CBC/NoPadding"),
+    aes128ctr(Constants.AES128_CTR, 16, 16, "AES", "AES/CTR/NoPadding"),
+    aes192cbc(Constants.AES192_CBC, 16, 24, "AES", "AES/CBC/NoPadding"),
+    aes192ctr(Constants.AES192_CTR, 16, 24, "AES", "AES/CTR/NoPadding"),
+    aes256cbc(Constants.AES256_CBC, 16, 32, "AES", "AES/CBC/NoPadding"),
+    aes256ctr(Constants.AES256_CTR, 16, 32, "AES", "AES/CTR/NoPadding"),
+    arcfour128(Constants.ARCFOUR128, 8, 16, "ARCFOUR", "RC4") {
         @Override
         public Cipher create() {
-            return new BaseCipher(16, 16, "AES", "AES/CBC/NoPadding");
+            return new BaseRC4Cipher(getIVSize(), getBlockSize());
         }
     },
-    aes128ctr(Constants.AES128_CTR) {
+    arcfour256(Constants.ARCFOUR256, 8, 32, "ARCFOUR", "RC4") {
         @Override
         public Cipher create() {
-            return new BaseCipher(16, 16, "AES", "AES/CTR/NoPadding");
+            return new BaseRC4Cipher(getIVSize(), getBlockSize());
         }
     },
-    aes192cbc(Constants.AES192_CBC) {
-        @Override
-        public Cipher create() {
-            return new BaseCipher(16, 24, "AES", "AES/CBC/NoPadding");
-        }
-    },
-    aes192ctr(Constants.AES192_CTR) {
-        @Override
-        public Cipher create() {
-            return new BaseCipher(16, 24, "AES", "AES/CTR/NoPadding");
-        }
-    },
-    aes256cbc(Constants.AES256_CBC) {
-        @Override
-        public Cipher create() {
-            return new BaseCipher(16, 32, "AES", "AES/CBC/NoPadding");
-        }
-    },
-    aes256ctr(Constants.AES256_CTR) {
-        @Override
-        public Cipher create() {
-            return new BaseCipher(16, 32, "AES", "AES/CTR/NoPadding");
-        }
-    },
-    arcfour128(Constants.ARCFOUR128) {
-        @Override
-        public Cipher create() {
-            return new BaseRC4Cipher(8, 16);
-        }
-    },
-    arcfour256(Constants.ARCFOUR256) {
-        @Override
-        public Cipher create() {
-            return new BaseRC4Cipher(8, 32);
-        }
-    },
-    blowfishcbc(Constants.BLOWFISH_CBC) {
-        @Override
-        public Cipher create() {
-            return new BaseCipher(8, 16, "Blowfish", "Blowfish/CBC/NoPadding");
-        }
-    },
-    tripledescbc(Constants.DES_CBC) {
-        @Override
-        public Cipher create() {
-            return new BaseCipher(8, 24, "DESede", "DESede/CBC/NoPadding");
-        }
-    };
+    blowfishcbc(Constants.BLOWFISH_CBC, 8, 16, "Blowfish", "Blowfish/CBC/NoPadding"),
+    tripledescbc(Constants.TRIPLE_DES_CBC, 8, 24, "DESede", "DESede/CBC/NoPadding");
 
     private final String factoryName;
+    private final int ivsize;
+    private final int blocksize;
+    private final String algorithm;
+    private final String transformation;
 
     @Override
     public final String getName() {
         return factoryName;
     }
 
-    BuiltinCiphers(String facName) {
-        factoryName = facName;
-    }
+    BuiltinCiphers(String factoryName, int ivsize, int blocksize, String algorithm, String transformation) {
+        this.factoryName = factoryName;
+        this.ivsize = ivsize;
+        this.blocksize = blocksize;
+        this.algorithm = algorithm;
+        this.transformation = transformation;
 
-    private final AtomicReference<Boolean> _supported = new AtomicReference<>(null);
+    }
 
     /**
      * @return {@code true} if the current JVM configuration supports this
@@ -122,22 +88,53 @@ public enum BuiltinCiphers implements NamedFactory<Cipher>, OptionalFeature {
      */
     @Override
     public boolean isSupported() {
-        Boolean value;
-        synchronized (_supported) {
-            if ((value = _supported.get()) == null) {
-                // see BaseBuilder#fillWithDefaultValues
-                try {
-                    Exception t = CipherUtils.checkSupported(create());
-                    value = t == null;
-                } catch (Exception e) {
-                    value = Boolean.FALSE;
-                }
-
-                _supported.set(value);
-            }
+        try {
+            int maxKeyLength = javax.crypto.Cipher.getMaxAllowedKeyLength(getAlgorithm());
+            return maxKeyLength >= (1l << getBlockSize());
+        } catch (Exception e) {
+            return false;
         }
+    }
+
+    /**
+     * Retrieves the size of the initialization vector
+     *
+     * @return
+     */
+    public int getIVSize() {
+        return ivsize;
+    }
 
-        return value;
+    /**
+     * Retrieves the block size for this cipher
+     *
+     * @return
+     */
+    public int getBlockSize() {
+        return blocksize;
+    }
+
+    /**
+     * Retrieves the algorithm for this cipher
+     *
+     * @return
+     */
+    public String getAlgorithm() {
+        return algorithm;
+    }
+
+    /**
+     * Retrieves the algorithm for this cipher
+     *
+     * @return
+     */
+    public String getTransformation() {
+        return transformation;
+    }
+
+    @Override
+    public Cipher create() {
+        return new BaseCipher(getIVSize(), getBlockSize(), getAlgorithm(), getTransformation());
     }
 
     public static final Set<BuiltinCiphers> VALUES =
@@ -206,6 +203,6 @@ public enum BuiltinCiphers implements NamedFactory<Cipher>, OptionalFeature {
         public static final String ARCFOUR128 = "arcfour128";
         public static final String ARCFOUR256 = "arcfour256";
         public static final String BLOWFISH_CBC = "blowfish-cbc";
-        public static final String DES_CBC = "3des-cbc";
+        public static final String TRIPLE_DES_CBC = "3des-cbc";
     }
 }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/82b0f82e/sshd-core/src/main/java/org/apache/sshd/common/cipher/CipherUtils.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/cipher/CipherUtils.java b/sshd-core/src/main/java/org/apache/sshd/common/cipher/CipherUtils.java
deleted file mode 100644
index 45070f6..0000000
--- a/sshd-core/src/main/java/org/apache/sshd/common/cipher/CipherUtils.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * 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.cipher;
-
-import org.apache.sshd.common.Cipher;
-import org.apache.sshd.common.Factory;
-
-/**
- * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
- */
-public class CipherUtils {
-    /**
-     * Checks if the provided cipher factory instance generates a cipher
-     * that is supported by the JCE
-     * @param f The cipher factory instance
-     * @return The {@link Exception} that the {@link Cipher#init(org.apache.sshd.common.Cipher.Mode, byte[], byte[])}
-     * call has thrown - {@code null} if successful (i.e., cipher supported)
-     * @see <A HREF="http://www.oracle.com/technetwork/java/javase/downloads/">Java Cryptography Extension (JCE)</A>
-     */
-    public static Exception checkSupported(Factory<? extends Cipher> f) {
-        return checkSupported(f.create());
-    }
-
-    /**
-     * Checks if the provided cipher is supported by the JCE
-     * @param c The {@link Cipher} to be checked
-     * @return The {@link Exception} that the {@link Cipher#init(org.apache.sshd.common.Cipher.Mode, byte[], byte[])}
-     * call has thrown - {@code null} if successful (i.e., cipher supported)
-     * @see <A HREF="http://www.oracle.com/technetwork/java/javase/downloads/">Java Cryptography Extension (JCE)</A>
-     */
-    public static Exception checkSupported(Cipher c) {
-        try {
-            byte[] key=new byte[c.getBlockSize()];
-            byte[] iv=new byte[c.getIVSize()];
-            c.init(Cipher.Mode.Encrypt, key, iv);
-            return null;
-        } catch(Exception e) {
-            return e;
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/82b0f82e/sshd-core/src/test/java/org/apache/sshd/CipherTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/CipherTest.java b/sshd-core/src/test/java/org/apache/sshd/CipherTest.java
index 9f9fa74..faa2c1f 100644
--- a/sshd-core/src/test/java/org/apache/sshd/CipherTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/CipherTest.java
@@ -28,7 +28,6 @@ import org.apache.sshd.common.NamedFactory;
 import org.apache.sshd.common.Random;
 import org.apache.sshd.common.cipher.BuiltinCiphers;
 import org.apache.sshd.common.random.BouncyCastleRandom;
-import org.apache.sshd.common.util.SecurityUtils;
 import org.apache.sshd.util.BaseTest;
 import org.apache.sshd.util.BogusPasswordAuthenticator;
 import org.apache.sshd.util.EchoShellFactory;
@@ -52,13 +51,17 @@ public class CipherTest extends BaseTest {
 
     @Test
     public void testAES128CBC() throws Exception {
-        setUp(BuiltinCiphers.aes128cbc);
-        runTest();
+        if (BuiltinCiphers.aes128cbc.isSupported()
+                && checkCipher(com.jcraft.jsch.jce.AES128CBC.class.getName())) {
+            setUp(BuiltinCiphers.aes128cbc);
+            runTest();
+        }
     }
 
     @Test
     public void testAES192CBC() throws Exception {
-        if (SecurityUtils.isBouncyCastleRegistered() && checkCipher(com.jcraft.jsch.jce.AES192CBC.class.getName())) {
+        if (BuiltinCiphers.aes192cbc.isSupported()
+                && checkCipher(com.jcraft.jsch.jce.AES192CBC.class.getName())) {
             setUp(BuiltinCiphers.aes192cbc);
             runTest();
         }
@@ -66,7 +69,8 @@ public class CipherTest extends BaseTest {
 
     @Test
     public void testAES256CBC() throws Exception {
-        if (SecurityUtils.isBouncyCastleRegistered() && checkCipher(com.jcraft.jsch.jce.AES256CBC.class.getName())) {
+        if (BuiltinCiphers.aes256cbc.isSupported()
+                && checkCipher(com.jcraft.jsch.jce.AES256CBC.class.getName())) {
             setUp(BuiltinCiphers.aes256cbc);
             runTest();
         }
@@ -74,14 +78,20 @@ public class CipherTest extends BaseTest {
 
     @Test
     public void testBlowfishCBC() throws Exception {
-        setUp(BuiltinCiphers.blowfishcbc);
-        runTest();
+        if (BuiltinCiphers.blowfishcbc.isSupported()
+                && checkCipher(com.jcraft.jsch.jce.BlowfishCBC.class.getName())) {
+            setUp(BuiltinCiphers.blowfishcbc);
+            runTest();
+        }
     }
 
     @Test
     public void testTripleDESCBC() throws Exception {
-        setUp(BuiltinCiphers.tripledescbc);
-        runTest();
+        if (BuiltinCiphers.tripledescbc.isSupported()
+                && checkCipher(com.jcraft.jsch.jce.TripleDESCBC.class.getName())) {
+            setUp(BuiltinCiphers.tripledescbc);
+            runTest();
+        }
     }
 
     @Test

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/82b0f82e/sshd-core/src/test/java/org/apache/sshd/common/cipher/BuiltinCiphersTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/common/cipher/BuiltinCiphersTest.java b/sshd-core/src/test/java/org/apache/sshd/common/cipher/BuiltinCiphersTest.java
index 70d9d34..e90e64a 100644
--- a/sshd-core/src/test/java/org/apache/sshd/common/cipher/BuiltinCiphersTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/common/cipher/BuiltinCiphersTest.java
@@ -93,20 +93,17 @@ public class BuiltinCiphersTest extends BaseTest {
         Assert.assertEquals("Incomplete coverage", BuiltinCiphers.VALUES, avail);
     }
 
-//    @Test
-//    public void testFromCipher() {
-//        for (BuiltinCiphers expected : BuiltinCiphers.VALUES) {
-//            if (!expected.isSupported()) {
-//                System.out.append("Skip unsupported cipher: ").println(expected);
-//                continue;
-//            }
-//
-//            NamedFactory<Cipher>    factory=expected;
-//            Cipher                  cipher=factory.create();
-//            assertObjectInstanceOf(expected.name() + " - mismatched cipher type", expected.getCipherType(), cipher);
-//
-//            BuiltinCiphers  actual=BuiltinCiphers.fromCipher(cipher);
-//            Assert.assertSame(expected.getName() + " - mismatched enum values", expected, actual);
-//        }
-//    }
+    @Test
+    public void testSupportedCipher() throws Exception {
+        for (BuiltinCiphers expected : BuiltinCiphers.VALUES) {
+            if (!expected.isSupported()) {
+                System.out.append("Skip unsupported cipher: ").println(expected);
+                continue;
+            }
+            Cipher cipher = expected.create();
+            byte[] key = new byte[cipher.getBlockSize()];
+            byte[] iv = new byte[cipher.getIVSize()];
+            cipher.init(Cipher.Mode.Encrypt, key, iv);
+        }
+    }
 }