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) {