You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mina.apache.org by lg...@apache.org on 2015/06/15 13:56:33 UTC

mina-sshd git commit: [SSHD-492] Use DERParser/DERWriter to correctly sign/verify hashes

Repository: mina-sshd
Updated Branches:
  refs/heads/master 168c5054b -> 4b86f6377


[SSHD-492] Use DERParser/DERWriter to correctly sign/verify hashes


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

Branch: refs/heads/master
Commit: 4b86f63774416cc86273c9b2c6b38d145ad55f3c
Parents: 168c505
Author: Lyor Goldstein <lg...@vmware.com>
Authored: Mon Jun 15 14:53:29 2015 +0300
Committer: Lyor Goldstein <lg...@vmware.com>
Committed: Mon Jun 15 14:55:59 2015 +0300

----------------------------------------------------------------------
 .../java/org/apache/sshd/agent/SshAgent.java    |  22 +--
 .../sshd/agent/common/AbstractAgentClient.java  |   5 +-
 .../sshd/agent/common/AbstractAgentProxy.java   |   1 +
 .../apache/sshd/agent/common/AgentDelegate.java |   1 +
 .../org/apache/sshd/agent/local/AgentImpl.java  |  72 +++-----
 .../sshd/client/auth/UserAuthPublicKey.java     |  12 +-
 .../org/apache/sshd/client/kex/DHGClient.java   |  15 +-
 .../org/apache/sshd/client/kex/DHGEXClient.java |  14 +-
 .../org/apache/sshd/common/cipher/ECCurves.java |   5 +-
 .../common/signature/AbstractSignature.java     |  70 +++++---
 .../common/signature/BuiltinSignatures.java     |   2 +-
 .../apache/sshd/common/signature/Signature.java |  13 +-
 .../sshd/common/signature/SignatureDSA.java     | 148 ++++++++++------
 .../sshd/common/signature/SignatureECDSA.java   |  19 ++-
 .../sshd/common/signature/SignatureRSA.java     |  16 +-
 .../java/org/apache/sshd/common/util/Pair.java  |  41 +++++
 .../apache/sshd/common/util/buffer/Buffer.java  |   6 +-
 .../apache/sshd/common/util/io/DERWriter.java   |  10 +-
 .../sshd/server/auth/UserAuthPublicKey.java     |  22 +--
 .../org/apache/sshd/server/kex/DHGEXServer.java |  10 +-
 .../org/apache/sshd/server/kex/DHGServer.java   |  10 +-
 .../test/java/org/apache/sshd/EcdsaTest.java    | 167 -------------------
 .../java/org/apache/sshd/agent/AgentTest.java   |   3 +-
 .../sshd/common/config/keys/KeyUtilsTest.java   |   9 +-
 .../AbstractSignatureFactoryTestSupport.java    | 134 +++++++++++++++
 .../signature/SignatureDSSFactoryTest.java      |  58 +++++++
 .../signature/SignatureECDSAFactoryTest.java    |  67 ++++++++
 .../signature/SignatureRSAFactoryTest.java      |  58 +++++++
 .../apache/sshd/deprecated/UserAuthAgent.java   |   3 +-
 .../sshd/deprecated/UserAuthPublicKey.java      |  10 +-
 .../org/apache/sshd/util/BaseTestSupport.java   |  25 +++
 31 files changed, 672 insertions(+), 376 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/4b86f637/sshd-core/src/main/java/org/apache/sshd/agent/SshAgent.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/agent/SshAgent.java b/sshd-core/src/main/java/org/apache/sshd/agent/SshAgent.java
index 4303721..188b73c 100644
--- a/sshd-core/src/main/java/org/apache/sshd/agent/SshAgent.java
+++ b/sshd-core/src/main/java/org/apache/sshd/agent/SshAgent.java
@@ -23,30 +23,14 @@ import java.security.KeyPair;
 import java.security.PublicKey;
 import java.util.List;
 
+import org.apache.sshd.common.util.Pair;
+
 /**
  * SSH key agent server
  */
 public interface SshAgent extends java.nio.channels.Channel {
 
-    public static final String SSH_AUTHSOCKET_ENV_NAME = "SSH_AUTH_SOCK";
-
-    public static class Pair<U,V> {
-        private final U first;
-        private final V second;
-
-        public Pair(U first, V second) {
-            this.first = first;
-            this.second = second;
-        }
-
-        public U getFirst() {
-            return first;
-        }
-
-        public V getSecond() {
-            return second;
-        }
-    }
+    String SSH_AUTHSOCKET_ENV_NAME = "SSH_AUTH_SOCK";
 
     List<Pair<PublicKey, String>> getIdentities() throws IOException;
 

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/4b86f637/sshd-core/src/main/java/org/apache/sshd/agent/common/AbstractAgentClient.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/agent/common/AbstractAgentClient.java b/sshd-core/src/main/java/org/apache/sshd/agent/common/AbstractAgentClient.java
index c99977b..548b411 100644
--- a/sshd-core/src/main/java/org/apache/sshd/agent/common/AbstractAgentClient.java
+++ b/sshd-core/src/main/java/org/apache/sshd/agent/common/AbstractAgentClient.java
@@ -34,6 +34,7 @@ import java.util.List;
 
 import org.apache.sshd.agent.SshAgent;
 import org.apache.sshd.common.config.keys.KeyUtils;
+import org.apache.sshd.common.util.Pair;
 import org.apache.sshd.common.util.buffer.Buffer;
 import org.apache.sshd.common.util.buffer.BufferUtils;
 import org.apache.sshd.common.util.buffer.ByteArrayBuffer;
@@ -78,10 +79,10 @@ public abstract class AbstractAgentClient extends AbstractLoggingBean {
         int cmd = req.getByte();
         switch (cmd) {
             case SSH2_AGENTC_REQUEST_IDENTITIES: {
-                List<SshAgent.Pair<PublicKey,String>> keys = agent.getIdentities();
+                List<Pair<PublicKey,String>> keys = agent.getIdentities();
                 rep.putByte(SSH2_AGENT_IDENTITIES_ANSWER);
                 rep.putInt(keys.size());
-                for (SshAgent.Pair<PublicKey,String> key : keys) {
+                for (Pair<PublicKey,String> key : keys) {
                     rep.putPublicKey(key.getFirst());
                     rep.putString(key.getSecond());
                 }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/4b86f637/sshd-core/src/main/java/org/apache/sshd/agent/common/AbstractAgentProxy.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/agent/common/AbstractAgentProxy.java b/sshd-core/src/main/java/org/apache/sshd/agent/common/AbstractAgentProxy.java
index 9ec0adf..a5a7304 100644
--- a/sshd-core/src/main/java/org/apache/sshd/agent/common/AbstractAgentProxy.java
+++ b/sshd-core/src/main/java/org/apache/sshd/agent/common/AbstractAgentProxy.java
@@ -38,6 +38,7 @@ import java.util.concurrent.ExecutorService;
 import org.apache.sshd.agent.SshAgent;
 import org.apache.sshd.common.SshException;
 import org.apache.sshd.common.util.GenericUtils;
+import org.apache.sshd.common.util.Pair;
 import org.apache.sshd.common.util.buffer.Buffer;
 import org.apache.sshd.common.util.buffer.BufferUtils;
 import org.apache.sshd.common.util.buffer.ByteArrayBuffer;

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/4b86f637/sshd-core/src/main/java/org/apache/sshd/agent/common/AgentDelegate.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/agent/common/AgentDelegate.java b/sshd-core/src/main/java/org/apache/sshd/agent/common/AgentDelegate.java
index ed74fb6..3474c72 100644
--- a/sshd-core/src/main/java/org/apache/sshd/agent/common/AgentDelegate.java
+++ b/sshd-core/src/main/java/org/apache/sshd/agent/common/AgentDelegate.java
@@ -24,6 +24,7 @@ import java.security.PublicKey;
 import java.util.List;
 
 import org.apache.sshd.agent.SshAgent;
+import org.apache.sshd.common.util.Pair;
 
 public class AgentDelegate implements SshAgent {
 

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/4b86f637/sshd-core/src/main/java/org/apache/sshd/agent/local/AgentImpl.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/agent/local/AgentImpl.java b/sshd-core/src/main/java/org/apache/sshd/agent/local/AgentImpl.java
index fffad42..5ddbd81 100644
--- a/sshd-core/src/main/java/org/apache/sshd/agent/local/AgentImpl.java
+++ b/sshd-core/src/main/java/org/apache/sshd/agent/local/AgentImpl.java
@@ -21,19 +21,21 @@ package org.apache.sshd.agent.local;
 import java.io.IOException;
 import java.security.KeyPair;
 import java.security.PublicKey;
-import java.security.interfaces.DSAParams;
 import java.security.interfaces.DSAPublicKey;
 import java.security.interfaces.ECPublicKey;
 import java.security.interfaces.RSAPublicKey;
-import java.security.spec.ECParameterSpec;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.concurrent.atomic.AtomicBoolean;
 
 import org.apache.sshd.agent.SshAgent;
 import org.apache.sshd.common.SshException;
+import org.apache.sshd.common.config.keys.KeyUtils;
 import org.apache.sshd.common.signature.BuiltinSignatures;
 import org.apache.sshd.common.signature.Signature;
+import org.apache.sshd.common.util.GenericUtils;
+import org.apache.sshd.common.util.Pair;
+import org.apache.sshd.common.util.ValidateUtils;
 
 /**
  * A local SSH agent implementation
@@ -71,24 +73,23 @@ public class AgentImpl implements SshAgent {
             throw new SshException("Agent closed");
         }
 
-        Pair<KeyPair, String> kp = getKeyPair(keys, key);
-        if (kp == null) {
-            throw new SshException("Key not found");
-        }
-
         try {
+            Pair<KeyPair, String> pp = ValidateUtils.checkNotNull(getKeyPair(keys, key), "Key not found", GenericUtils.EMPTY_OBJECT_ARRAY);
+            KeyPair kp = ValidateUtils.checkNotNull(pp.getFirst(), "No key pair for agent=%s", pp.getSecond());
+            PublicKey pubKey = ValidateUtils.checkNotNull(kp.getPublic(), "No public key for agent=%s", pp.getSecond());
+
             final Signature verif;
-            if (kp.getFirst().getPublic() instanceof DSAPublicKey) {
+            if (pubKey instanceof DSAPublicKey) {
                 verif = BuiltinSignatures.dsa.create();
-            } else if (kp.getFirst().getPublic() instanceof ECPublicKey) {
-                ECPublicKey pubKey = (ECPublicKey) kp.getFirst().getPublic();
-                verif = BuiltinSignatures.getByCurveSize(pubKey.getParams());
-            } else if (kp.getFirst().getPublic() instanceof RSAPublicKey) {
+            } else if (pubKey instanceof ECPublicKey) {
+                ECPublicKey ecKey = (ECPublicKey) pubKey;
+                verif = BuiltinSignatures.getByCurveSize(ecKey.getParams());
+            } else if (pubKey instanceof RSAPublicKey) {
                 verif = BuiltinSignatures.rsa.create();
             } else {
-                throw new SshException("Unsupported key type");
+                throw new SshException("Unsupported key type: " + pubKey.getClass().getSimpleName());
             }
-            verif.init(kp.getFirst().getPublic(), kp.getFirst().getPrivate());
+            verif.initSigner(kp.getPrivate());
             verif.update(data, 0, data.length);
             return verif.sign();
         } catch (IOException e) {
@@ -133,45 +134,14 @@ public class AgentImpl implements SshAgent {
         }
     }
 
-    protected static SshAgent.Pair<KeyPair, String> getKeyPair(List<SshAgent.Pair<KeyPair, String>> keys, PublicKey key) {
-        SshAgent.Pair<KeyPair, String> kp = null;
-        for (SshAgent.Pair<KeyPair, String> k : keys) {
-            if (areKeyEquals(key, k.getFirst().getPublic())) {
-                kp = k;
-                break;
+    protected static Pair<KeyPair, String> getKeyPair(List<Pair<KeyPair, String>> keys, PublicKey key) {
+        for (Pair<KeyPair, String> k : keys) {
+            KeyPair kp = k.getFirst();
+            if (KeyUtils.compareKeys(key, kp.getPublic())) {
+                return k;
             }
         }
-        return kp;
-    }
 
-    protected static boolean areKeyEquals(PublicKey k1, PublicKey k2) {
-        if (k1 instanceof DSAPublicKey && k2 instanceof DSAPublicKey) {
-            DSAPublicKey d1 = (DSAPublicKey) k1;
-            DSAPublicKey d2 = (DSAPublicKey) k2;
-            DSAParams p1 = d1.getParams();
-            DSAParams p2 = d2.getParams();
-            return d1.getY().equals(d2.getY())
-                        && p1.getG().equals(p2.getG())
-                        && p1.getP().equals(p2.getP())
-                        && p1.getQ().equals(p2.getQ());
-        } else if (k1 instanceof ECPublicKey && k2 instanceof ECPublicKey) {
-            ECPublicKey e1 = (ECPublicKey) k1;
-            ECPublicKey e2 = (ECPublicKey) k2;
-            ECParameterSpec p1 = e1.getParams();
-            ECParameterSpec p2 = e2.getParams();
-            return p1.getCofactor() == p2.getCofactor()
-                        && p1.getOrder().equals(p2.getOrder())
-                        && e1.getW().equals(e2.getW())
-                        && p1.getGenerator().equals(p2.getGenerator())
-                        && p1.getCurve().equals(p2.getCurve());
-        } else if (k1 instanceof RSAPublicKey && k2 instanceof RSAPublicKey) {
-            RSAPublicKey r1 = (RSAPublicKey) k1;
-            RSAPublicKey r2 = (RSAPublicKey) k2;
-            return r1.getModulus().equals(r2.getModulus())
-                        && r1.getPublicExponent().equals(r2.getPublicExponent());
-        } else {
-            return false;
-        }
+        return null;
     }
-
 }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/4b86f637/sshd-core/src/main/java/org/apache/sshd/client/auth/UserAuthPublicKey.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/auth/UserAuthPublicKey.java b/sshd-core/src/main/java/org/apache/sshd/client/auth/UserAuthPublicKey.java
index 2d2c95a..e691825 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/auth/UserAuthPublicKey.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/auth/UserAuthPublicKey.java
@@ -38,6 +38,8 @@ import org.apache.sshd.common.SshConstants;
 import org.apache.sshd.common.keyprovider.KeyPairProvider;
 import org.apache.sshd.common.session.AbstractSession;
 import org.apache.sshd.common.signature.Signature;
+import org.apache.sshd.common.util.Pair;
+import org.apache.sshd.common.util.ValidateUtils;
 import org.apache.sshd.common.util.buffer.Buffer;
 import org.apache.sshd.common.util.buffer.ByteArrayBuffer;
 import org.apache.sshd.common.util.logging.AbstractLoggingBean;
@@ -92,7 +94,7 @@ public class UserAuthPublicKey extends AbstractLoggingBean implements UserAuth {
         SshAgentFactory factory = manager.getAgentFactory();
         if (factory != null) {
             this.agent = factory.createClient(manager);
-            for (SshAgent.Pair<PublicKey, String> pair : agent.getIdentities()) {
+            for (Pair<PublicKey, String> pair : agent.getIdentities()) {
                 ids.add(new KeyAgentIdentity(agent, pair.getFirst()));
             }
         } else {
@@ -217,8 +219,12 @@ public class UserAuthPublicKey extends AbstractLoggingBean implements UserAuth {
 
         @Override
         public byte[] sign(byte[] data) throws Exception {
-            Signature verif = NamedFactory.Utils.create(manager.getSignatureFactories(), getKeyType(pair));
-            verif.init(pair.getPublic(), pair.getPrivate());
+            String keyType = getKeyType(pair);
+            Signature verif = ValidateUtils.checkNotNull(
+                    NamedFactory.Utils.create(manager.getSignatureFactories(), keyType),
+                    "No signer could be located for key type=%s",
+                    keyType);
+            verif.initSigner(pair.getPrivate());
             verif.update(data, 0, data.length);
             return verif.sign();
         }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/4b86f637/sshd-core/src/main/java/org/apache/sshd/client/kex/DHGClient.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/kex/DHGClient.java b/sshd-core/src/main/java/org/apache/sshd/client/kex/DHGClient.java
index 1893a4b..f4a21f9 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/kex/DHGClient.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/kex/DHGClient.java
@@ -18,6 +18,7 @@
  */
 package org.apache.sshd.client.kex;
 
+import org.apache.sshd.common.FactoryManager;
 import org.apache.sshd.common.NamedFactory;
 import org.apache.sshd.common.SshConstants;
 import org.apache.sshd.common.SshException;
@@ -27,6 +28,8 @@ import org.apache.sshd.common.kex.DHFactory;
 import org.apache.sshd.common.kex.KeyExchange;
 import org.apache.sshd.common.session.AbstractSession;
 import org.apache.sshd.common.signature.Signature;
+import org.apache.sshd.common.util.GenericUtils;
+import org.apache.sshd.common.util.ValidateUtils;
 import org.apache.sshd.common.util.buffer.Buffer;
 import org.apache.sshd.common.util.buffer.ByteArrayBuffer;
 
@@ -64,8 +67,7 @@ public class DHGClient extends AbstractDHClientKeyExchange {
     }
 
     protected DHGClient(DHFactory factory) {
-        super();
-        this.factory = factory;
+        this.factory = ValidateUtils.checkNotNull(factory, "No factory", GenericUtils.EMPTY_OBJECT_ARRAY);
     }
 
     @Override
@@ -121,9 +123,12 @@ public class DHGClient extends AbstractDHClientKeyExchange {
         hash.update(buffer.array(), 0, buffer.available());
         H = hash.digest();
 
-        Signature verif = NamedFactory.Utils.create(session.getFactoryManager().getSignatureFactories(), keyAlg);
-        verif.init(serverKey, null);
-        verif.update(H, 0, H.length);
+        FactoryManager manager = session.getFactoryManager();
+        Signature verif = ValidateUtils.checkNotNull(NamedFactory.Utils.create(manager.getSignatureFactories(), keyAlg),
+                            "No verifier located for algorithm=%s",
+                            keyAlg);
+        verif.initVerifier(serverKey);
+        verif.update(H);
         if (!verif.verify(sig)) {
             throw new SshException(SshConstants.SSH2_DISCONNECT_KEY_EXCHANGE_FAILED,
                                    "KeyExchange signature verification failed");

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/4b86f637/sshd-core/src/main/java/org/apache/sshd/client/kex/DHGEXClient.java
----------------------------------------------------------------------
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 12d4f08..bcf4ba9 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
@@ -30,6 +30,8 @@ import org.apache.sshd.common.kex.DHFactory;
 import org.apache.sshd.common.kex.KeyExchange;
 import org.apache.sshd.common.session.AbstractSession;
 import org.apache.sshd.common.signature.Signature;
+import org.apache.sshd.common.util.GenericUtils;
+import org.apache.sshd.common.util.ValidateUtils;
 import org.apache.sshd.common.util.buffer.Buffer;
 import org.apache.sshd.common.util.buffer.ByteArrayBuffer;
 
@@ -69,8 +71,7 @@ public class DHGEXClient extends AbstractDHClientKeyExchange {
         };
     }
     protected DHGEXClient(DHFactory factory) {
-        super();
-        this.factory = factory;
+        this.factory = ValidateUtils.checkNotNull(factory, "No factory", GenericUtils.EMPTY_OBJECT_ARRAY);
     }
 
     @Override
@@ -144,9 +145,12 @@ public class DHGEXClient extends AbstractDHClientKeyExchange {
             hash.update(buffer.array(), 0, buffer.available());
             H = hash.digest();
 
-            Signature verif = NamedFactory.Utils.create(session.getFactoryManager().getSignatureFactories(), keyAlg);
-            verif.init(serverKey, null);
-            verif.update(H, 0, H.length);
+            Signature verif = ValidateUtils.checkNotNull(
+                    NamedFactory.Utils.create(session.getFactoryManager().getSignatureFactories(), keyAlg),
+                    "No verifier located for algorithm=%s",
+                    keyAlg);
+            verif.initVerifier(serverKey);
+            verif.update(H);
             if (!verif.verify(sig)) {
                 throw new SshException(SshConstants.SSH2_DISCONNECT_KEY_EXCHANGE_FAILED,
                         "KeyExchange signature verification failed");

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/4b86f637/sshd-core/src/main/java/org/apache/sshd/common/cipher/ECCurves.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/cipher/ECCurves.java b/sshd-core/src/main/java/org/apache/sshd/common/cipher/ECCurves.java
index d3f0b34..6f0c46e 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/cipher/ECCurves.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/cipher/ECCurves.java
@@ -41,12 +41,13 @@ import org.apache.sshd.common.util.ValidateUtils;
  * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
  */
 public class ECCurves {
+    /**
+     * Standard prefix of NISTP key types when encoded
+     */
     public static final String ECDSA_SHA2_PREFIX = "ecdsa-sha2-";
 
     public static final String NISTP256 = "nistp256";
-
     public static final String NISTP384 = "nistp384";
-
     public static final String NISTP521 = "nistp521";
 
 

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/4b86f637/sshd-core/src/main/java/org/apache/sshd/common/signature/AbstractSignature.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/signature/AbstractSignature.java b/sshd-core/src/main/java/org/apache/sshd/common/signature/AbstractSignature.java
index 65f434c..57e9840 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/signature/AbstractSignature.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/signature/AbstractSignature.java
@@ -18,12 +18,15 @@
  */
 package org.apache.sshd.common.signature;
 
+import java.nio.charset.StandardCharsets;
 import java.security.PrivateKey;
 import java.security.PublicKey;
 
 import org.apache.sshd.common.util.GenericUtils;
+import org.apache.sshd.common.util.Pair;
 import org.apache.sshd.common.util.SecurityUtils;
 import org.apache.sshd.common.util.ValidateUtils;
+import org.apache.sshd.common.util.buffer.BufferUtils;
 
 /**
  * TODO Add javadoc
@@ -43,16 +46,18 @@ public abstract class AbstractSignature implements Signature {
     public final String getAlgorithm() {
         return algorithm;
     }
+    
 
     @Override
-    public void init(PublicKey pubkey, PrivateKey prvkey) throws Exception {
+    public void initVerifier(PublicKey key) throws Exception {
         signature = SecurityUtils.getSignature(getAlgorithm());
-        if (pubkey != null) {
-            signature.initVerify(pubkey);
-        }
-        if (prvkey != null) {
-            signature.initSign(prvkey);
-        }
+        signature.initVerify(ValidateUtils.checkNotNull(key, "No public key provided", GenericUtils.EMPTY_OBJECT_ARRAY));
+    }
+
+    @Override
+    public void initSigner(PrivateKey key) throws Exception {
+        signature = SecurityUtils.getSignature(getAlgorithm());
+        signature.initSign(ValidateUtils.checkNotNull(key, "No private key provided", GenericUtils.EMPTY_OBJECT_ARRAY));
     }
 
     @Override
@@ -65,24 +70,43 @@ public abstract class AbstractSignature implements Signature {
         signature.update(hash, off, len);
     }
 
-    protected byte[] extractSig(byte[] sig) {
-        if ((sig[0] == 0) && (sig[1] == 0) && (sig[2] == 0)) {
-            int i = 0, j;
-            j = ((sig[i++] << 24) & 0xff000000) |
-                ((sig[i++] << 16) & 0x00ff0000) |
-                ((sig[i++] <<  8) & 0x0000ff00) |
-                ((sig[i++]      ) & 0x000000ff);
-            i += j;
-            j = ((sig[i++] << 24) & 0xff000000) |
-                ((sig[i++] << 16) & 0x00ff0000) |
-                ((sig[i++] << 8 ) & 0x0000ff00) |
-                ((sig[i++]      ) & 0x000000ff);
-            byte[] tmp = new byte[j];
-            System.arraycopy(sig, i, tmp, 0, j);
-            sig = tmp;
+    /**
+     *  Makes an attempt to detect if the signature is encoded or pure data
+     * @param sig The original signature
+     * @return A {@link Pair} where first value is the key type and second
+     * value is the data - {@code null} if not encoded
+     */
+    protected Pair<String,byte[]> extractEncodedSignature(byte[] sig) {
+        final int dataLen = GenericUtils.length(sig);
+        // if it is encoded then we must have at least 2 UINT32 values
+        if (dataLen < (2 * (Integer.SIZE / Byte.SIZE))) {
+            return null;
+        }
+        
+        long keyTypeLen = BufferUtils.getUInt(sig, 0, dataLen);
+        // after the key type we MUST have data bytes
+        if (keyTypeLen >= (dataLen - (Integer.SIZE / Byte.SIZE))) {
+            return null;
+        }
+        
+        int keyTypeStartPos = Integer.SIZE / Byte.SIZE;
+        int keyTypeEndPos = keyTypeStartPos + (int) keyTypeLen;
+        int remainLen = dataLen - keyTypeEndPos;
+        // must have UINT32 with the data bytes length
+        if (remainLen < (Integer.SIZE / Byte.SIZE)) {
+            return null;
+        }
+        
+        long dataBytesLen = BufferUtils.getUInt(sig, keyTypeEndPos, remainLen);
+        // make sure reported number of bytes does not exceed available
+        if (dataBytesLen > (remainLen - (Integer.SIZE / Byte.SIZE))) {
+            return null;
         }
 
-        return sig;
+        String keyType = new String(sig, keyTypeStartPos, (int) keyTypeLen, StandardCharsets.UTF_8);
+        byte[] data = new byte[(int) dataBytesLen];
+        System.arraycopy(sig, keyTypeEndPos + (Integer.SIZE / Byte.SIZE), data, 0, (int) dataBytesLen);
+        return new Pair<String,byte[]>(keyType, data);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/4b86f637/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 e77ec12..c79f56a 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
@@ -142,7 +142,7 @@ public enum BuiltinSignatures implements SignatureFactory {
         ValidateUtils.checkTrue(fromFactoryName(name) == null, "Extension overrides built-in: %s", name);
 
         synchronized(extensions) {
-            ValidateUtils.checkTrue(!extensions.containsKey(name), "Extension overrides existinh: %s", name);
+            ValidateUtils.checkTrue(!extensions.containsKey(name), "Extension overrides existing: %s", name);
             extensions.put(name, extension);
         }
     }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/4b86f637/sshd-core/src/main/java/org/apache/sshd/common/signature/Signature.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/signature/Signature.java b/sshd-core/src/main/java/org/apache/sshd/common/signature/Signature.java
index dad946c..30b448d 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/signature/Signature.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/signature/Signature.java
@@ -34,17 +34,22 @@ public interface Signature {
     String getAlgorithm();
 
     /**
-     * @param pubkey The {@link PublicKey} to be used for verifying signatures
-     * @param prvkey The {@link PrivateKey} to be used for signing - if {@code null}
-     * then only verification can be performed
+     * @param key The {@link PublicKey} to be used for verifying signatures
      * @throws Exception If failed to initialize
      */
-    void init(PublicKey pubkey, PrivateKey prvkey) throws Exception;
+    void initVerifier(PublicKey key) throws Exception;
+
+    /**
+     * @param prvkey The {@link PrivateKey} to be used for signing
+     * @throws Exception If failed to initialize
+     */
+    void initSigner(PrivateKey key) throws Exception;
 
     /**
      * Update the computed signature with the given data
      * @param hash The hash data buffer
      * @throws Exception If failed to update
+     * @see #update(byte[], int, int)
      */
     void update(byte[] hash) throws Exception;
 

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/4b86f637/sshd-core/src/main/java/org/apache/sshd/common/signature/SignatureDSA.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/signature/SignatureDSA.java b/sshd-core/src/main/java/org/apache/sshd/common/signature/SignatureDSA.java
index b6ec18c..1a32274 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/signature/SignatureDSA.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/signature/SignatureDSA.java
@@ -18,13 +18,28 @@
  */
 package org.apache.sshd.common.signature;
 
+import java.io.IOException;
+import java.math.BigInteger;
+import java.security.SignatureException;
+
+import org.apache.sshd.common.keyprovider.KeyPairProvider;
+import org.apache.sshd.common.util.GenericUtils;
+import org.apache.sshd.common.util.Pair;
+import org.apache.sshd.common.util.ValidateUtils;
+import org.apache.sshd.common.util.buffer.BufferUtils;
+import org.apache.sshd.common.util.io.DERParser;
+import org.apache.sshd.common.util.io.DERWriter;
+
 
 /**
  * DSA <code>Signature</code>
- *
  * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ * @see <A HREF="https://tools.ietf.org/html/rfc4253#section-6.6">RFC4253 section 6.6</A>
  */
 public class SignatureDSA extends AbstractSignature {
+    public static final int DSA_SIGNATURE_LENGTH = 40;
+    // result must be 40 bytes, but length of r and s may not exceed 20 bytes
+    public static final int MAX_SIGNATURE_VALUE_LENGTH = DSA_SIGNATURE_LENGTH / 2;
 
     protected SignatureDSA(String algorithm) {
 	    super(algorithm);
@@ -34,61 +49,88 @@ public class SignatureDSA extends AbstractSignature {
     public byte[] sign() throws Exception {
         byte[] sig = signature.sign();
 
-        // sig is in ASN.1
-        // SEQUENCE::={ r INTEGER, s INTEGER }
-        int len = 0;
-        int index = 3;
-        len = sig[index++] & 0xff;
-        byte[] r = new byte[len];
-        System.arraycopy(sig, index, r, 0, r.length);
-        index = index + len + 1;
-        len = sig[index++] & 0xff;
-        byte[] s = new byte[len];
-        System.arraycopy(sig, index, s, 0, s.length);
-
-        byte[] result = new byte[40];
-
-        // result must be 40 bytes, but length of r and s may not be 20 bytes
-
-        System.arraycopy(r,
-                         (r.length > 20) ? 1 : 0,
-                         result,
-                         (r.length > 20) ? 0 : 20 - r.length,
-                         (r.length > 20) ? 20 : r.length);
-        System.arraycopy(s,
-                         (s.length > 20) ? 1 : 0,
-                         result,
-                         (s.length > 20) ? 20 : 40 - s.length,
-                         (s.length > 20) ? 20 : s.length);
-
-        return result;
+        try(DERParser parser = new DERParser(sig)) {
+            int type = parser.read();
+            if (type != 0x30) {
+                throw new IOException("Invalid signature format - not a DER SEQUENCE: 0x" + Integer.toHexString(type));
+            }
+    
+            // length of remaining encoding of the 2 integers
+            int remainLen = parser.readLength();
+            /*
+             * There are supposed to be 2 INTEGERs, each encoded with:
+             * 
+             *  - one byte representing the fact that it is an INTEGER
+             *  - one byte of the integer encoding length
+             *  - at least one byte of integer data (zero length is not an option)
+             */
+            if (remainLen < (2 * 3)) {
+                throw new IOException("Invalid signature format - not enough encoded data length: " + remainLen);
+            }
+
+            BigInteger r = parser.readBigInteger();
+            BigInteger s = parser.readBigInteger();
+
+            byte[] result = new byte[DSA_SIGNATURE_LENGTH];
+            putBigInteger(r, result, 0);
+            putBigInteger(s, result, MAX_SIGNATURE_VALUE_LENGTH);
+            return result;
+        }
+    }
+
+    public static void putBigInteger(BigInteger value, byte[] result, int offset) {
+        byte[] data = value.toByteArray();
+        boolean maxExceeded = data.length > MAX_SIGNATURE_VALUE_LENGTH;
+        int dstOffset = maxExceeded ? 0 : (MAX_SIGNATURE_VALUE_LENGTH - data.length);
+        System.arraycopy(data, maxExceeded ? 1 : 0,
+                         result, offset + dstOffset,
+                         Math.min(MAX_SIGNATURE_VALUE_LENGTH, data.length));
     }
 
     @Override
     public boolean verify(byte[] sig) throws Exception {
-        sig = extractSig(sig);
-
-        // ASN.1
-        int frst = ((sig[0] & 0x80) != 0 ? 1 : 0);
-        int scnd = ((sig[20] & 0x80) != 0 ? 1 : 0);
-
-        int length = sig.length + 6 + frst + scnd;
-        byte[] tmp = new byte[length];
-        tmp[0] = (byte) 0x30;
-        tmp[1] = (byte) 0x2c;
-        tmp[1] += frst;
-        tmp[1] += scnd;
-        tmp[2] = (byte) 0x02;
-        tmp[3] = (byte) 0x14;
-        tmp[3] += frst;
-        System.arraycopy(sig, 0, tmp, 4 + frst, 20);
-        tmp[4 + tmp[3]] = (byte) 0x02;
-        tmp[5 + tmp[3]] = (byte) 0x14;
-        tmp[5 + tmp[3]] += scnd;
-        System.arraycopy(sig, 20, tmp, 6 + tmp[3] + scnd, 20);
-        sig = tmp;
-
-        return signature.verify(sig);
-    }
+        int sigLen = GenericUtils.length(sig);
+        byte[] data = sig;
 
+        if (sigLen != DSA_SIGNATURE_LENGTH) {
+            // probably some encoded data
+            Pair<String,byte[]> encoding = extractEncodedSignature(sig);
+            if (encoding != null) {
+                String keyType = encoding.getFirst();
+                ValidateUtils.checkTrue(KeyPairProvider.SSH_DSS.equals(keyType), "Mismatched key type: %s", keyType);
+                data = encoding.getSecond();
+                sigLen = GenericUtils.length(data);
+            }
+        }
+
+        if (sigLen != DSA_SIGNATURE_LENGTH) {
+            throw new SignatureException("Bad signature length (" + sigLen + " instead of " + DSA_SIGNATURE_LENGTH + ")"
+                                      + " for " + BufferUtils.printHex(':', data));
+        }
+
+        byte[] rEncoding;
+        try(DERWriter w = new DERWriter(MAX_SIGNATURE_VALUE_LENGTH + 4)) {     // in case length > 0x7F
+            w.writeBigInteger(data, 0, MAX_SIGNATURE_VALUE_LENGTH);
+            rEncoding = w.toByteArray();
+        }
+
+        byte[] sEncoding;
+        try(DERWriter w = new DERWriter(MAX_SIGNATURE_VALUE_LENGTH + 4)) {     // in case length > 0x7F
+            w.writeBigInteger(data, MAX_SIGNATURE_VALUE_LENGTH, MAX_SIGNATURE_VALUE_LENGTH);
+            sEncoding = w.toByteArray();
+        }
+
+
+        int length = rEncoding.length + sEncoding.length;
+        byte[] encoded;
+        try(DERWriter w = new DERWriter(1 + length + 4)) {  // in case length > 0x7F
+            w.write(0x30); // SEQUENCE
+            w.writeLength(length);
+            w.write(rEncoding);
+            w.write(sEncoding);
+            encoded = w.toByteArray();
+        }
+
+        return signature.verify(encoded);
+    }
 }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/4b86f637/sshd-core/src/main/java/org/apache/sshd/common/signature/SignatureECDSA.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/signature/SignatureECDSA.java b/sshd-core/src/main/java/org/apache/sshd/common/signature/SignatureECDSA.java
index 4aa3ec9..67c01d1 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/signature/SignatureECDSA.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/signature/SignatureECDSA.java
@@ -21,6 +21,9 @@ package org.apache.sshd.common.signature;
 import java.io.IOException;
 import java.math.BigInteger;
 
+import org.apache.sshd.common.cipher.ECCurves;
+import org.apache.sshd.common.util.Pair;
+import org.apache.sshd.common.util.ValidateUtils;
 import org.apache.sshd.common.util.buffer.Buffer;
 import org.apache.sshd.common.util.buffer.ByteArrayBuffer;
 import org.apache.sshd.common.util.io.DERParser;
@@ -29,6 +32,7 @@ import org.apache.sshd.common.util.io.DERWriter;
 /**
  * Signature algorithm for EC keys using ECDSA. 
  * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ * @see <A HREF="http://tools.ietf.org/html/rfc3278#section-8.2">RFC3278 section 8.2</A>
  */
 public class SignatureECDSA extends AbstractSignature {
 
@@ -39,8 +43,7 @@ public class SignatureECDSA extends AbstractSignature {
     @Override
     public byte[] sign() throws Exception {
         byte[] sig = signature.sign();
-        
-        // see http://tools.ietf.org/html/rfc3278#section-8.2
+
         try(DERParser parser = new DERParser(sig)) {
             int type = parser.read();
             if (type != 0x30) {
@@ -62,8 +65,7 @@ public class SignatureECDSA extends AbstractSignature {
 
             BigInteger r = parser.readBigInteger();
             BigInteger s = parser.readBigInteger();
-
-            // see https://tools.ietf.org/html/rfc5656#page-5
+            // Write the <r,s> to its own types writer.
             Buffer rsBuf = new ByteArrayBuffer();
             rsBuf.putMPInt(r);
             rsBuf.putMPInt(s);
@@ -74,7 +76,14 @@ public class SignatureECDSA extends AbstractSignature {
 
     @Override
     public boolean verify(byte[] sig) throws Exception {
-        byte[] data = extractSig(sig);
+        byte[] data = sig;
+        Pair<String,byte[]> encoding = extractEncodedSignature(data);
+        if (encoding != null) {
+            String keyType = encoding.getFirst();
+            ValidateUtils.checkTrue(ECCurves.TYPES.contains(keyType), "Unknown curve type: %s", keyType);
+            data = encoding.getSecond();
+        }
+
         Buffer rsBuf = new ByteArrayBuffer(data);
 
         byte[] rArray = rsBuf.getMPIntAsBytes(), rEncoding;

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/4b86f637/sshd-core/src/main/java/org/apache/sshd/common/signature/SignatureRSA.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/signature/SignatureRSA.java b/sshd-core/src/main/java/org/apache/sshd/common/signature/SignatureRSA.java
index 1cb117e..6970420 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/signature/SignatureRSA.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/signature/SignatureRSA.java
@@ -18,13 +18,16 @@
  */
 package org.apache.sshd.common.signature;
 
+import org.apache.sshd.common.keyprovider.KeyPairProvider;
+import org.apache.sshd.common.util.Pair;
+import org.apache.sshd.common.util.ValidateUtils;
+
 /**
  * RSA <code>Signature</code>
  *
  * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
  */
 public class SignatureRSA extends AbstractSignature {
-
     public SignatureRSA() {
         super("SHA1withRSA");
     }
@@ -36,8 +39,15 @@ public class SignatureRSA extends AbstractSignature {
 
     @Override
     public boolean verify(byte[] sig) throws Exception {
-        sig = extractSig(sig);
-        return signature.verify(sig);
+        byte[] data = sig;
+        Pair<String,byte[]> encoding = extractEncodedSignature(data);
+        if (encoding != null) {
+            String keyType = encoding.getFirst();
+            ValidateUtils.checkTrue(KeyPairProvider.SSH_RSA.equals(keyType), "Mismatched key type: %s", keyType);
+            data = encoding.getSecond();
+        }
+
+        return signature.verify(data);
     }
 
 }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/4b86f637/sshd-core/src/main/java/org/apache/sshd/common/util/Pair.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/util/Pair.java b/sshd-core/src/main/java/org/apache/sshd/common/util/Pair.java
new file mode 100644
index 0000000..d885b14
--- /dev/null
+++ b/sshd-core/src/main/java/org/apache/sshd/common/util/Pair.java
@@ -0,0 +1,41 @@
+/*
+ * 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;
+
+/**
+ * Represents a pair of values
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ */
+public class Pair<U,V> {
+    private final U first;
+    private final V second;
+
+    public Pair(U first, V second) {
+        this.first = first;
+        this.second = second;
+    }
+
+    public U getFirst() {
+        return first;
+    }
+
+    public V getSecond() {
+        return second;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/4b86f637/sshd-core/src/main/java/org/apache/sshd/common/util/buffer/Buffer.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/util/buffer/Buffer.java b/sshd-core/src/main/java/org/apache/sshd/common/util/buffer/Buffer.java
index 233766a..fe3c0e3 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/util/buffer/Buffer.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/util/buffer/Buffer.java
@@ -379,13 +379,11 @@ public abstract class Buffer implements Readable {
     }
 
     public void putMPInt(byte[] foo) {
-        int i = foo.length;
         if ((foo[0] & 0x80) != 0) {
-            i++;
-            putInt(i);
+            putInt(foo.length + 1 /* padding */);
             putByte((byte)0);
         } else {
-            putInt(i);
+            putInt(foo.length);
         }
         putRawBytes(foo);
     }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/4b86f637/sshd-core/src/main/java/org/apache/sshd/common/util/io/DERWriter.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/util/io/DERWriter.java b/sshd-core/src/main/java/org/apache/sshd/common/util/io/DERWriter.java
index 1e0098e..6d4dd51 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/util/io/DERWriter.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/util/io/DERWriter.java
@@ -57,17 +57,21 @@ public class DERWriter extends FilterOutputStream {
     }
 
     public void writeBigInteger(byte ... bytes) throws IOException {
+        writeBigInteger(bytes, 0, GenericUtils.length(bytes));
+    }
+
+    public void writeBigInteger(byte[] bytes, int off, int len) throws IOException {
         // ASN.1 - zero padding if 1st byte is > 0x7F
-        int padLen = ((bytes[0] & 0x80) != 0) ? 1 : 0;
+        int padLen = ((len > 0) && ((bytes[off] & 0x80) != 0)) ? 1 : 0;
 
         write(0x02);    // indicate it is an INTEGER
-        writeLength(bytes.length + padLen);
+        writeLength(len + padLen);
 
         for (int index = 0; index < padLen; index++) {
             write(0);
         }
 
-        write(bytes);
+        write(bytes, off, len);
     }
 
     public void writeObject(byte tag, int len, byte ... data) throws IOException {

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/4b86f637/sshd-core/src/main/java/org/apache/sshd/server/auth/UserAuthPublicKey.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/auth/UserAuthPublicKey.java b/sshd-core/src/main/java/org/apache/sshd/server/auth/UserAuthPublicKey.java
index 913543a..9e7d269 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/auth/UserAuthPublicKey.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/auth/UserAuthPublicKey.java
@@ -23,9 +23,12 @@ import java.security.PublicKey;
 import org.apache.sshd.common.NamedFactory;
 import org.apache.sshd.common.SshConstants;
 import org.apache.sshd.common.signature.Signature;
+import org.apache.sshd.common.util.GenericUtils;
+import org.apache.sshd.common.util.ValidateUtils;
 import org.apache.sshd.common.util.buffer.Buffer;
 import org.apache.sshd.common.util.buffer.ByteArrayBuffer;
 import org.apache.sshd.server.PublickeyAuthenticator;
+import org.apache.sshd.server.ServerFactoryManager;
 import org.apache.sshd.server.UserAuth;
 
 /**
@@ -67,23 +70,22 @@ public class UserAuthPublicKey extends AbstractUserAuth {
         int len = buffer.getInt();
         buffer.wpos(buffer.rpos() + len);
         PublicKey key = buffer.getRawPublicKey();
-        Signature verif = NamedFactory.Utils.create(session.getFactoryManager().getSignatureFactories(), alg);
-        if (verif == null) {
-            throw new Exception("No Signature available for: " + alg);
-        }
-        verif.init(key, null);
+        ServerFactoryManager manager = session.getFactoryManager();
+        Signature verif = ValidateUtils.checkNotNull(
+                NamedFactory.Utils.create(manager.getSignatureFactories(), alg),
+                "No verifier located for algorithm=%s",
+                alg);
+        verif.initVerifier(key);
         buffer.wpos(oldLim);
 
         byte[] sig = hasSig ? buffer.getBytes() : null;
 
-        PublickeyAuthenticator authenticator = session.getFactoryManager().getPublickeyAuthenticator();
-        if (authenticator == null) {
-            throw new Exception("No PublickeyAuthenticator configured");
-        }
-
+        PublickeyAuthenticator authenticator = 
+                ValidateUtils.checkNotNull(manager.getPublickeyAuthenticator(), "No PublickeyAuthenticator configured", GenericUtils.EMPTY_OBJECT_ARRAY);
         if (!authenticator.authenticate(username, key, session)) {
             return Boolean.FALSE;
         }
+
         if (!hasSig) {
             Buffer buf = session.createBuffer(SshConstants.SSH_MSG_USERAUTH_PK_OK);
             buf.putString(alg);

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/4b86f637/sshd-core/src/main/java/org/apache/sshd/server/kex/DHGEXServer.java
----------------------------------------------------------------------
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 85375bd..7cc569e 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
@@ -83,8 +83,7 @@ public class DHGEXServer extends AbstractDHServerKeyExchange {
     }
 
     protected DHGEXServer(DHFactory factory) {
-        super();
-        this.factory = factory;
+        this.factory = ValidateUtils.checkNotNull(factory, "No factory", GenericUtils.EMPTY_OBJECT_ARRAY);
     }
 
     @Override
@@ -161,8 +160,11 @@ public class DHGEXServer extends AbstractDHServerKeyExchange {
             KeyPair kp = session.getHostKey();
             String algo = session.getNegotiatedKexParameter(KexProposalOption.SERVERKEYS);
             FactoryManager manager = session.getFactoryManager();
-            Signature sig = ValidateUtils.checkNotNull(NamedFactory.Utils.create(manager.getSignatureFactories(), algo), "Unknown negotiated server keys: %s", algo);
-            sig.init(kp.getPublic(), kp.getPrivate());
+            Signature sig = ValidateUtils.checkNotNull(
+                    NamedFactory.Utils.create(manager.getSignatureFactories(), algo),
+                    "Unknown negotiated server keys: %s",
+                    algo);
+            sig.initSigner(kp.getPrivate());
 
             buffer = new ByteArrayBuffer();
             buffer.putRawPublicKey(kp.getPublic());

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/4b86f637/sshd-core/src/main/java/org/apache/sshd/server/kex/DHGServer.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/kex/DHGServer.java b/sshd-core/src/main/java/org/apache/sshd/server/kex/DHGServer.java
index 61f1a41..c88f902 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/kex/DHGServer.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/kex/DHGServer.java
@@ -30,6 +30,7 @@ import org.apache.sshd.common.kex.KexProposalOption;
 import org.apache.sshd.common.kex.KeyExchange;
 import org.apache.sshd.common.session.AbstractSession;
 import org.apache.sshd.common.signature.Signature;
+import org.apache.sshd.common.util.GenericUtils;
 import org.apache.sshd.common.util.ValidateUtils;
 import org.apache.sshd.common.util.buffer.Buffer;
 import org.apache.sshd.common.util.buffer.BufferUtils;
@@ -65,7 +66,7 @@ public class DHGServer extends AbstractDHServerKeyExchange {
     }
 
     protected DHGServer(DHFactory factory) {
-        this.factory = factory;
+        this.factory = ValidateUtils.checkNotNull(factory, "No factory", GenericUtils.EMPTY_OBJECT_ARRAY);
     }
 
     @Override
@@ -93,8 +94,11 @@ public class DHGServer extends AbstractDHServerKeyExchange {
         KeyPair kp = session.getHostKey();
         String algo = session.getNegotiatedKexParameter(KexProposalOption.SERVERKEYS);
         FactoryManager manager = session.getFactoryManager();
-        Signature sig = ValidateUtils.checkNotNull(NamedFactory.Utils.create(manager.getSignatureFactories(), algo), "Unknown negotiated server keys: %s", algo);
-        sig.init(kp.getPublic(), kp.getPrivate());
+        Signature sig = ValidateUtils.checkNotNull(
+                NamedFactory.Utils.create(manager.getSignatureFactories(), algo),
+                "Unknown negotiated server keys: %s",
+                algo);
+        sig.initSigner(kp.getPrivate());
 
         buffer = new ByteArrayBuffer();
         buffer.putRawPublicKey(kp.getPublic());

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/4b86f637/sshd-core/src/test/java/org/apache/sshd/EcdsaTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/EcdsaTest.java b/sshd-core/src/test/java/org/apache/sshd/EcdsaTest.java
deleted file mode 100644
index 629c238..0000000
--- a/sshd-core/src/test/java/org/apache/sshd/EcdsaTest.java
+++ /dev/null
@@ -1,167 +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;
-
-import java.security.KeyPair;
-import java.security.KeyPairGenerator;
-import java.security.SecureRandom;
-import java.security.spec.ECGenParameterSpec;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicReference;
-
-import org.apache.sshd.client.SshClient;
-import org.apache.sshd.client.session.ClientSession;
-import org.apache.sshd.common.NamedFactory;
-import org.apache.sshd.common.RuntimeSshException;
-import org.apache.sshd.common.cipher.ECCurves;
-import org.apache.sshd.common.config.keys.ECDSAPublicKeyEntryDecoder;
-import org.apache.sshd.common.keyprovider.AbstractKeyPairProvider;
-import org.apache.sshd.common.signature.BuiltinSignatures;
-import org.apache.sshd.common.signature.Signature;
-import org.apache.sshd.common.util.SecurityUtils;
-import org.apache.sshd.server.PublickeyAuthenticator.AcceptAllPublickeyAuthenticator;
-import org.apache.sshd.server.SshServer;
-import org.apache.sshd.util.BaseTestSupport;
-import org.apache.sshd.util.BogusPasswordAuthenticator;
-import org.apache.sshd.util.Utils;
-import org.junit.After;
-import org.junit.Assume;
-import org.junit.Before;
-import org.junit.FixMethodOrder;
-import org.junit.Test;
-import org.junit.runners.MethodSorters;
-
-/**
- * TODO Add javadoc
- *
- * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
- */
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-public class EcdsaTest extends BaseTestSupport {
-
-    private SshServer sshd;
-    private SshClient client;
-    private int port;
-
-    public EcdsaTest() {
-        super();
-    }
-
-    @Before
-    public void setUp() throws Exception {
-        sshd = SshServer.setUpDefaultServer();
-        sshd.setPasswordAuthenticator(BogusPasswordAuthenticator.INSTANCE);
-        sshd.setSessionFactory(new org.apache.sshd.server.session.SessionFactory());
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        if (sshd != null) {
-            sshd.stop(true);
-        }
-        if (client != null) {
-            client.stop();
-        }
-    }
-
-    @Test
-    public void testECDSA_SHA2_NISTP256() throws Exception {
-        testECDSA_SHA2_NISTP_Curve(ECCurves.NISTP256);
-    }
-
-    @Test
-    public void testECDSA_SHA2_NISTP384() throws Exception {
-        testECDSA_SHA2_NISTP_Curve(ECCurves.NISTP384);
-    }
-
-    @Test
-    public void testECDSA_SHA2_NISTP521() throws Exception {
-        testECDSA_SHA2_NISTP_Curve(ECCurves.NISTP521);
-    }
-
-    private void testECDSA_SHA2_NISTP_Curve(final String curvName) throws Exception {
-        Assume.assumeTrue("ECC not supported", SecurityUtils.hasEcc() || SecurityUtils.isBouncyCastleRegistered());
-        sshd.setKeyPairProvider(new AbstractKeyPairProvider() {
-                private final AtomicReference<Iterable<KeyPair>> keys=new AtomicReference<Iterable<KeyPair>>(null);
-    
-                @Override
-                public Iterable<KeyPair> loadKeys() {
-                    Iterable<KeyPair>   iter;
-                    synchronized(keys) {
-                        if ((iter=keys.get()) != null) {
-                            return iter;
-                        }
-    
-                        try {
-                            Integer keySize = ECCurves.getCurveSize(curvName);
-                            assertNotNull("No key size for curve=" + curvName, keySize);
-                            KeyPair kp = ECDSAPublicKeyEntryDecoder.INSTANCE.generateKeyPair(keySize.intValue());
-                            iter = Collections.singleton(kp);
-                            keys.set(iter);
-                        } catch (Exception e) {
-                            throw new RuntimeSshException(e);
-                        }
-                    }
-                    
-                    return iter;
-                }
-            });
-        sshd.start();
-        port = sshd.getPort();
-
-        client = SshClient.setUpDefaultClient();
-        client.setSignatureFactories(Arrays.<NamedFactory<Signature>>asList(
-                BuiltinSignatures.nistp256,
-                BuiltinSignatures.nistp384,
-                BuiltinSignatures.nistp521));
-        client.start();
-        try(ClientSession s = client.connect(getCurrentTestName(), "localhost", port).await().getSession()) {
-            s.addPasswordIdentity(getCurrentTestName());
-            s.auth().verify(15L, TimeUnit.SECONDS);
-        } finally {
-            client.stop();
-        }
-    }
-
-    @Test
-    public void testEcdsaPublicKeyAuth() throws Exception {
-        Assume.assumeTrue("BouncyCastle not registered", SecurityUtils.isBouncyCastleRegistered());
-        ECGenParameterSpec ecGenSpec = new ECGenParameterSpec("secp256r1");
-        KeyPairGenerator generator = SecurityUtils.getKeyPairGenerator("ECDSA");
-        generator.initialize(ecGenSpec, new SecureRandom());
-        KeyPair kp = generator.generateKeyPair();
-
-        sshd.setKeyPairProvider(Utils.createTestHostKeyProvider());
-        sshd.setPublickeyAuthenticator(AcceptAllPublickeyAuthenticator.INSTANCE);
-        sshd.start();
-        port  = sshd.getPort();
-
-        client = SshClient.setUpDefaultClient();
-        client.start();
-        
-        try(ClientSession s = client.connect(getCurrentTestName(), "localhost", port).await().getSession()) {
-            s.addPublicKeyIdentity(kp);
-            s.auth().verify(5L, TimeUnit.SECONDS);
-        } finally {
-            client.stop();
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/4b86f637/sshd-core/src/test/java/org/apache/sshd/agent/AgentTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/agent/AgentTest.java b/sshd-core/src/test/java/org/apache/sshd/agent/AgentTest.java
index dc7d958..e6224b4 100644
--- a/sshd-core/src/test/java/org/apache/sshd/agent/AgentTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/agent/AgentTest.java
@@ -37,6 +37,7 @@ import org.apache.sshd.client.SshClient;
 import org.apache.sshd.client.channel.ChannelShell;
 import org.apache.sshd.client.session.ClientSession;
 import org.apache.sshd.common.keyprovider.KeyPairProvider;
+import org.apache.sshd.common.util.Pair;
 import org.apache.sshd.common.util.SecurityUtils;
 import org.apache.sshd.server.Command;
 import org.apache.sshd.server.Environment;
@@ -74,7 +75,7 @@ public class AgentTest extends BaseTestSupport {
             Assume.assumeTrue("Native library N/A", authSocket != null);
     
             try(SshAgent client = new AgentClient(authSocket)) {
-                List<SshAgent.Pair<PublicKey, String>> keys = client.getIdentities();
+                List<Pair<PublicKey, String>> keys = client.getIdentities();
                 assertNotNull("No initial identities", keys);
                 assertEquals("Unexpected initial identities size", 0, keys.size());
         

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/4b86f637/sshd-core/src/test/java/org/apache/sshd/common/config/keys/KeyUtilsTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/common/config/keys/KeyUtilsTest.java b/sshd-core/src/test/java/org/apache/sshd/common/config/keys/KeyUtilsTest.java
index 680eec8..36613dc 100644
--- a/sshd-core/src/test/java/org/apache/sshd/common/config/keys/KeyUtilsTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/common/config/keys/KeyUtilsTest.java
@@ -39,9 +39,6 @@ import org.junit.runners.MethodSorters;
  */
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
 public class KeyUtilsTest extends BaseTestSupport {
-    private static int[] DSS_SIZES = { 512, 768, 1024 };
-    private static int[] RSA_SIZES = { 1024, 2048, 3072, 4096 };
-
     public KeyUtilsTest() {
         super();
     }
@@ -49,7 +46,8 @@ public class KeyUtilsTest extends BaseTestSupport {
     @Test
     public void testGenerateRSAKeyPairs() throws GeneralSecurityException {
         GeneralSecurityException err = null;
-        for (int keySize : RSA_SIZES) {
+        for (Integer size : RSA_SIZES) {
+            int keySize = size.intValue();
             try {
                 KeyPair kp = generateKeyPair(KeyPairProvider.SSH_RSA, keySize);
                 testKeyPairCloning(KeyPairProvider.SSH_RSA, keySize, kp);
@@ -66,7 +64,8 @@ public class KeyUtilsTest extends BaseTestSupport {
     @Test
     public void testGenerateDSSKeyPairs() throws GeneralSecurityException {
         GeneralSecurityException err = null;
-        for (int keySize : DSS_SIZES) {
+        for (Integer size : DSS_SIZES) {
+            int keySize = size.intValue();
             try {
                 KeyPair kp = generateKeyPair(KeyPairProvider.SSH_DSS, keySize);
                 testKeyPairCloning(KeyPairProvider.SSH_DSS, keySize, kp);

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/4b86f637/sshd-core/src/test/java/org/apache/sshd/common/signature/AbstractSignatureFactoryTestSupport.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/common/signature/AbstractSignatureFactoryTestSupport.java b/sshd-core/src/test/java/org/apache/sshd/common/signature/AbstractSignatureFactoryTestSupport.java
new file mode 100644
index 0000000..3267e76
--- /dev/null
+++ b/sshd-core/src/test/java/org/apache/sshd/common/signature/AbstractSignatureFactoryTestSupport.java
@@ -0,0 +1,134 @@
+/*
+ * 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 java.security.KeyPair;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.sshd.client.SshClient;
+import org.apache.sshd.client.session.ClientSession;
+import org.apache.sshd.common.Factory;
+import org.apache.sshd.common.NamedFactory;
+import org.apache.sshd.common.RuntimeSshException;
+import org.apache.sshd.common.config.keys.PublicKeyEntryDecoder;
+import org.apache.sshd.common.keyprovider.AbstractKeyPairProvider;
+import org.apache.sshd.common.keyprovider.KeyPairProvider;
+import org.apache.sshd.common.util.GenericUtils;
+import org.apache.sshd.common.util.ValidateUtils;
+import org.apache.sshd.server.SshServer;
+import org.apache.sshd.util.BaseTestSupport;
+import org.apache.sshd.util.BogusPasswordAuthenticator;
+import org.junit.After;
+import org.junit.Before;
+
+/**
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ */
+public abstract class AbstractSignatureFactoryTestSupport extends BaseTestSupport {
+    private SshServer sshd;
+    private SshClient client;
+    private int port;
+
+    private final String keyType;
+    private final int keySize;
+
+    protected AbstractSignatureFactoryTestSupport(String keyType, int keySize) {
+        this.keyType = ValidateUtils.checkNotNullAndNotEmpty(keyType, "No key type specified", GenericUtils.EMPTY_OBJECT_ARRAY);
+        ValidateUtils.checkTrue(keySize > 0, "Invalid key size: %d", keySize);
+        this.keySize = keySize;
+    }
+
+    public final int getKeySize() {
+        return keySize;
+    }
+
+    public final String getKeyType() {
+        return keyType;
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        sshd = SshServer.setUpDefaultServer();
+        sshd.setPasswordAuthenticator(BogusPasswordAuthenticator.INSTANCE);
+        sshd.setSessionFactory(new org.apache.sshd.server.session.SessionFactory());
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        if (sshd != null) {
+            sshd.stop(true);
+        }
+        if (client != null) {
+            client.stop();
+        }
+    }
+
+    protected void testKeyPairProvider(PublicKeyEntryDecoder<?,?> decoder, List<NamedFactory<Signature>> signatures) throws Exception {
+        testKeyPairProvider(getKeyType(), getKeySize(), decoder, signatures);
+    }
+
+    protected void testKeyPairProvider(
+            final String keyName, final int keySize, final PublicKeyEntryDecoder<?,?> decoder, List<NamedFactory<Signature>> signatures)
+                    throws Exception {
+        testKeyPairProvider(keyName, new Factory<Iterable<KeyPair>>() {
+            @Override
+            public Iterable<KeyPair> create() {
+                try {
+                    KeyPair kp = decoder.generateKeyPair(keySize);
+                    System.out.println("Generated key pair for " + keyName + "[" + keySize + "]");
+                    return Collections.singletonList(kp);
+                } catch (Exception e) {
+                    throw new RuntimeSshException(e);
+                }
+            }
+        }, signatures);
+    }
+
+    protected void testKeyPairProvider(
+            final String keyName, final Factory<Iterable<KeyPair>> factory, List<NamedFactory<Signature>> signatures)
+                    throws Exception {
+        final Iterable<KeyPair> iter = factory.create();
+        testKeyPairProvider(new AbstractKeyPairProvider() {
+            @Override
+            public Iterable<KeyPair> loadKeys() {
+                return iter;
+            }
+        }, signatures);
+    }
+
+    protected void testKeyPairProvider(KeyPairProvider provider, List<NamedFactory<Signature>> signatures) throws Exception {
+        sshd.setKeyPairProvider(provider);
+        sshd.start();
+        port = sshd.getPort();
+
+        client = SshClient.setUpDefaultClient();
+        client.setSignatureFactories(signatures);
+        client.start();
+        try(ClientSession s = client.connect(getCurrentTestName(), "localhost", port).await().getSession()) {
+            s.addPasswordIdentity(getCurrentTestName());
+            // allow a rather long timeout since generating some keys may take some time
+            s.auth().verify(30L, TimeUnit.SECONDS);
+        } finally {
+            client.stop();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/4b86f637/sshd-core/src/test/java/org/apache/sshd/common/signature/SignatureDSSFactoryTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/common/signature/SignatureDSSFactoryTest.java b/sshd-core/src/test/java/org/apache/sshd/common/signature/SignatureDSSFactoryTest.java
new file mode 100644
index 0000000..0e434e9
--- /dev/null
+++ b/sshd-core/src/test/java/org/apache/sshd/common/signature/SignatureDSSFactoryTest.java
@@ -0,0 +1,58 @@
+/*
+ * 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 java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.sshd.common.NamedFactory;
+import org.apache.sshd.common.config.keys.DSSPublicKeyEntryDecoder;
+import org.apache.sshd.common.keyprovider.KeyPairProvider;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.MethodSorters;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+/**
+ * @author <a href="mailto:dev@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
+public class SignatureDSSFactoryTest extends AbstractSignatureFactoryTestSupport {
+    private static final List<NamedFactory<Signature>> FACTORIES =
+            Collections.unmodifiableList(Collections.<NamedFactory<Signature>>singletonList(BuiltinSignatures.dsa));
+
+    @Parameters(name = "keySize={0}")
+    public static Collection<Object[]> parameters() {
+        return parameterize(DSS_SIZES);
+    }
+
+    public SignatureDSSFactoryTest(int keySize) {
+        super(KeyPairProvider.SSH_DSS, keySize);
+    }
+    
+    @Test
+    public void testDSSPublicKeyAuth() throws Exception {
+        testKeyPairProvider(DSSPublicKeyEntryDecoder.INSTANCE, FACTORIES);
+    }
+}

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/4b86f637/sshd-core/src/test/java/org/apache/sshd/common/signature/SignatureECDSAFactoryTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/common/signature/SignatureECDSAFactoryTest.java b/sshd-core/src/test/java/org/apache/sshd/common/signature/SignatureECDSAFactoryTest.java
new file mode 100644
index 0000000..abbdf8d
--- /dev/null
+++ b/sshd-core/src/test/java/org/apache/sshd/common/signature/SignatureECDSAFactoryTest.java
@@ -0,0 +1,67 @@
+/*
+ * 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 java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.sshd.common.NamedFactory;
+import org.apache.sshd.common.cipher.ECCurves;
+import org.apache.sshd.common.config.keys.ECDSAPublicKeyEntryDecoder;
+import org.apache.sshd.common.util.SecurityUtils;
+import org.junit.Assume;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.MethodSorters;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+/**
+ * Makes sure that all the available {@link Signature} implementations are tested
+ * @author <a href="mailto:dev@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
+public class SignatureECDSAFactoryTest extends AbstractSignatureFactoryTestSupport {
+    private static final List<NamedFactory<Signature>> FACTORIES =
+            Collections.unmodifiableList(
+                    Arrays.<NamedFactory<Signature>>asList(
+                            BuiltinSignatures.nistp256,
+                            BuiltinSignatures.nistp384,
+                            BuiltinSignatures.nistp521
+                        ));
+
+    @Parameters(name = "keySize={0}")
+    public static Collection<Object[]> parameters() {
+        return parameterize(ECCurves.SIZES);
+    }
+    
+    public SignatureECDSAFactoryTest(int keySize) {
+        super(ECCurves.getCurveName(keySize), keySize);
+    }
+
+    @Test
+    public void testECDSAPublicKeyAuth() throws Exception {
+        Assume.assumeTrue("ECC not supported", SecurityUtils.hasEcc() || SecurityUtils.isBouncyCastleRegistered());
+        testKeyPairProvider(ECDSAPublicKeyEntryDecoder.INSTANCE, FACTORIES);
+    }
+}

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/4b86f637/sshd-core/src/test/java/org/apache/sshd/common/signature/SignatureRSAFactoryTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/common/signature/SignatureRSAFactoryTest.java b/sshd-core/src/test/java/org/apache/sshd/common/signature/SignatureRSAFactoryTest.java
new file mode 100644
index 0000000..573f0ce
--- /dev/null
+++ b/sshd-core/src/test/java/org/apache/sshd/common/signature/SignatureRSAFactoryTest.java
@@ -0,0 +1,58 @@
+/*
+ * 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 java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.sshd.common.NamedFactory;
+import org.apache.sshd.common.config.keys.RSAPublicKeyDecoder;
+import org.apache.sshd.common.keyprovider.KeyPairProvider;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.MethodSorters;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+/**
+ * @author <a href="mailto:dev@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
+public class SignatureRSAFactoryTest extends AbstractSignatureFactoryTestSupport {
+    private static final List<NamedFactory<Signature>> FACTORIES =
+            Collections.unmodifiableList(Collections.<NamedFactory<Signature>>singletonList(BuiltinSignatures.rsa));
+
+    @Parameters(name = "keySize={0}")
+    public static Collection<Object[]> parameters() {
+        return parameterize(RSA_SIZES);
+    }
+
+    public SignatureRSAFactoryTest(int keySize) {
+        super(KeyPairProvider.SSH_RSA, keySize);
+    }
+    
+    @Test
+    public void testRSAPublicKeyAuth() throws Exception {
+        testKeyPairProvider(RSAPublicKeyDecoder.INSTANCE, FACTORIES);
+    }
+}

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/4b86f637/sshd-core/src/test/java/org/apache/sshd/deprecated/UserAuthAgent.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/deprecated/UserAuthAgent.java b/sshd-core/src/test/java/org/apache/sshd/deprecated/UserAuthAgent.java
index 96c956c..f656fdb 100644
--- a/sshd-core/src/test/java/org/apache/sshd/deprecated/UserAuthAgent.java
+++ b/sshd-core/src/test/java/org/apache/sshd/deprecated/UserAuthAgent.java
@@ -27,6 +27,7 @@ import org.apache.sshd.client.auth.UserAuthPublicKey.UserAuthPublicKeyFactory;
 import org.apache.sshd.client.session.ClientSessionImpl;
 import org.apache.sshd.common.SshConstants;
 import org.apache.sshd.common.config.keys.KeyUtils;
+import org.apache.sshd.common.util.Pair;
 import org.apache.sshd.common.util.buffer.Buffer;
 import org.apache.sshd.common.util.buffer.ByteArrayBuffer;
 
@@ -36,7 +37,7 @@ import org.apache.sshd.common.util.buffer.ByteArrayBuffer;
 public class UserAuthAgent extends AbstractUserAuth {
 
     private final SshAgent agent;
-    private final Iterator<SshAgent.Pair<PublicKey, String>> keys;
+    private final Iterator<Pair<PublicKey, String>> keys;
 
     public UserAuthAgent(ClientSessionImpl session, String service) throws IOException {
         super(session, service);

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/4b86f637/sshd-core/src/test/java/org/apache/sshd/deprecated/UserAuthPublicKey.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/deprecated/UserAuthPublicKey.java b/sshd-core/src/test/java/org/apache/sshd/deprecated/UserAuthPublicKey.java
index 76296a7..f4d1a96 100644
--- a/sshd-core/src/test/java/org/apache/sshd/deprecated/UserAuthPublicKey.java
+++ b/sshd-core/src/test/java/org/apache/sshd/deprecated/UserAuthPublicKey.java
@@ -23,10 +23,12 @@ import java.security.KeyPair;
 
 import org.apache.sshd.client.auth.UserAuthPublicKey.UserAuthPublicKeyFactory;
 import org.apache.sshd.client.session.ClientSessionImpl;
+import org.apache.sshd.common.FactoryManager;
 import org.apache.sshd.common.NamedFactory;
 import org.apache.sshd.common.SshConstants;
 import org.apache.sshd.common.config.keys.KeyUtils;
 import org.apache.sshd.common.signature.Signature;
+import org.apache.sshd.common.util.ValidateUtils;
 import org.apache.sshd.common.util.buffer.Buffer;
 import org.apache.sshd.common.util.buffer.ByteArrayBuffer;
 
@@ -59,8 +61,12 @@ public class UserAuthPublicKey extends AbstractUserAuth {
                 int pos2 = buffer.wpos();
                 buffer.putPublicKey(key.getPublic());
 
-                Signature verif = NamedFactory.Utils.create(session.getFactoryManager().getSignatureFactories(), alg);
-                verif.init(key.getPublic(), key.getPrivate());
+                FactoryManager manager = session.getFactoryManager();
+                Signature verif =
+                        ValidateUtils.checkNotNull(NamedFactory.Utils.create(manager.getSignatureFactories(), alg),
+                                "No signature factory located for algorithm=%s",
+                                alg);
+                verif.initSigner(key.getPrivate());
 
                 Buffer bs = new ByteArrayBuffer();
                 bs.putBytes(session.getKex().getH());

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/4b86f637/sshd-core/src/test/java/org/apache/sshd/util/BaseTestSupport.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/util/BaseTestSupport.java b/sshd-core/src/test/java/org/apache/sshd/util/BaseTestSupport.java
index c6ec293..c6cd954 100644
--- a/sshd-core/src/test/java/org/apache/sshd/util/BaseTestSupport.java
+++ b/sshd-core/src/test/java/org/apache/sshd/util/BaseTestSupport.java
@@ -37,6 +37,10 @@ import java.security.spec.ECField;
 import java.security.spec.ECParameterSpec;
 import java.security.spec.ECPoint;
 import java.security.spec.EllipticCurve;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
 
@@ -54,6 +58,15 @@ import org.junit.runner.Description;
  */
 public abstract class BaseTestSupport extends Assert {
     public static final String TEMP_SUBFOLDER_NAME="temp";
+
+    // useful test sizes for keys
+    @SuppressWarnings("boxing")
+    public static final List<Integer> DSS_SIZES =
+        Collections.unmodifiableList(Arrays.asList(512, 768, 1024));
+    @SuppressWarnings("boxing")
+    public static final List<Integer> RSA_SIZES =
+            Collections.unmodifiableList(Arrays.asList(1024, 2048, 3072, 4096));
+
     @Rule public final TestWatcher rule = new TestWatcher() {
             // TODO consider using a ThreadLocal storage for the start time - provided
             //      the code is assured to call starting/finished on the same thread
@@ -123,6 +136,18 @@ public abstract class BaseTestSupport extends Assert {
         return sb.toString();
     }
 
+    public static List<Object[]> parameterize(Collection<?> params) {
+        if (GenericUtils.isEmpty(params)) {
+            return Collections.emptyList();
+        }
+        
+        List<Object[]> result = new ArrayList<Object[]>(params.size());
+        for (Object p : params) {
+            result.add(new Object[] { p });
+        }
+
+        return result;
+    }
     /* ----------------------- Useful extra assertions --------------------- */
 
     public static void assertEquals(String message, boolean expected, boolean actual) {