aboutsummaryrefslogtreecommitdiffstats
path: root/sshlib/src/main/java/com/trilead/ssh2
diff options
context:
space:
mode:
authorKenny Root <kenny@the-b.org>2016-01-23 15:44:40 -0800
committerKenny Root <kenny@the-b.org>2016-01-24 11:09:00 -0800
commit0bcb82c407b334b6c3dd0e243cabcfa2913a2f5a (patch)
tree0917dd41541f03cb604933d4504a6f87302d0a15 /sshlib/src/main/java/com/trilead/ssh2
parenta905a351a1480f121e75e065549ad7b1b5b4c862 (diff)
downloadsshlib-0bcb82c407b334b6c3dd0e243cabcfa2913a2f5a.tar.gz
sshlib-0bcb82c407b334b6c3dd0e243cabcfa2913a2f5a.tar.bz2
sshlib-0bcb82c407b334b6c3dd0e243cabcfa2913a2f5a.zip
Add curve25519-sha256@libssh.org exchange method
Diffstat (limited to 'sshlib/src/main/java/com/trilead/ssh2')
-rw-r--r--sshlib/src/main/java/com/trilead/ssh2/crypto/dh/Curve25519Exchange.java71
-rw-r--r--sshlib/src/main/java/com/trilead/ssh2/crypto/dh/GenericDhExchange.java3
-rw-r--r--sshlib/src/main/java/com/trilead/ssh2/transport/KexManager.java8
3 files changed, 80 insertions, 2 deletions
diff --git a/sshlib/src/main/java/com/trilead/ssh2/crypto/dh/Curve25519Exchange.java b/sshlib/src/main/java/com/trilead/ssh2/crypto/dh/Curve25519Exchange.java
new file mode 100644
index 0000000..d28393b
--- /dev/null
+++ b/sshlib/src/main/java/com/trilead/ssh2/crypto/dh/Curve25519Exchange.java
@@ -0,0 +1,71 @@
+package com.trilead.ssh2.crypto.dh;
+
+import djb.Curve25519;
+
+import java.io.IOException;
+import java.math.BigInteger;
+import java.security.SecureRandom;
+
+/**
+ * Created by Kenny Root on 1/23/16.
+ */
+public class Curve25519Exchange extends GenericDhExchange {
+ public static final String NAME = "curve25519-sha256@libssh.org";
+
+ private final byte[] clientPublic = new byte[Curve25519.KEY_SIZE];
+ private final byte[] clientPrivate = new byte[Curve25519.KEY_SIZE];
+ private final byte[] serverPublic = new byte[Curve25519.KEY_SIZE];
+
+ public Curve25519Exchange() {
+ super();
+ }
+
+ /*
+ * Used to test known vectors.
+ */
+ public Curve25519Exchange(byte[] secret) {
+ if (secret.length != Curve25519.KEY_SIZE) {
+ throw new AssertionError("secret must be key size");
+ }
+ System.arraycopy(secret, 0, clientPrivate, 0, secret.length);
+ Curve25519.keygen(clientPublic, null, clientPrivate);
+ }
+
+ @Override
+ public void init(String name) throws IOException {
+ if (!NAME.equals(name)) {
+ throw new IOException("Invalid name " + name);
+ }
+
+ SecureRandom sr = new SecureRandom();
+ sr.nextBytes(clientPrivate);
+ Curve25519.keygen(clientPublic, null, clientPrivate);
+ }
+
+ @Override
+ public byte[] getE() {
+ return clientPublic.clone();
+ }
+
+ @Override
+ protected byte[] getServerE() {
+ return serverPublic.clone();
+ }
+
+ @Override
+ public void setF(byte[] f) throws IOException {
+ if (f.length != serverPublic.length) {
+ throw new IOException("Server sent invalid key length " + f.length + " (expected " +
+ serverPublic.length + ")");
+ }
+ System.arraycopy(f, 0, serverPublic, 0, f.length);
+ byte[] sharedSecretBytes = new byte[Curve25519.KEY_SIZE];
+ Curve25519.curve(sharedSecretBytes, clientPrivate, serverPublic);
+ sharedSecret = new BigInteger(1, sharedSecretBytes);
+ }
+
+ @Override
+ public String getHashAlgo() {
+ return "SHA-256";
+ }
+}
diff --git a/sshlib/src/main/java/com/trilead/ssh2/crypto/dh/GenericDhExchange.java b/sshlib/src/main/java/com/trilead/ssh2/crypto/dh/GenericDhExchange.java
index 039ff75..1ad2554 100644
--- a/sshlib/src/main/java/com/trilead/ssh2/crypto/dh/GenericDhExchange.java
+++ b/sshlib/src/main/java/com/trilead/ssh2/crypto/dh/GenericDhExchange.java
@@ -28,6 +28,9 @@ public abstract class GenericDhExchange
}
public static GenericDhExchange getInstance(String algo) {
+ if (algo.startsWith("curve25519-sha256@libssh.org")) {
+ return new Curve25519Exchange();
+ }
if (algo.startsWith("ecdh-sha2-")) {
return new EcDhExchange();
} else {
diff --git a/sshlib/src/main/java/com/trilead/ssh2/transport/KexManager.java b/sshlib/src/main/java/com/trilead/ssh2/transport/KexManager.java
index ee0784a..741268b 100644
--- a/sshlib/src/main/java/com/trilead/ssh2/transport/KexManager.java
+++ b/sshlib/src/main/java/com/trilead/ssh2/transport/KexManager.java
@@ -21,6 +21,7 @@ import com.trilead.ssh2.crypto.CryptoWishList;
import com.trilead.ssh2.crypto.KeyMaterial;
import com.trilead.ssh2.crypto.cipher.BlockCipher;
import com.trilead.ssh2.crypto.cipher.BlockCipherFactory;
+import com.trilead.ssh2.crypto.dh.Curve25519Exchange;
import com.trilead.ssh2.crypto.dh.DhGroupExchange;
import com.trilead.ssh2.crypto.dh.GenericDhExchange;
import com.trilead.ssh2.crypto.digest.MAC;
@@ -75,6 +76,7 @@ public class KexManager
private static final Set<String> KEX_ALGS = new LinkedHashSet<String>();
static {
+ KEX_ALGS.add(Curve25519Exchange.NAME);
if (supportsEc) {
KEX_ALGS.add("ecdh-sha2-nistp256");
KEX_ALGS.add("ecdh-sha2-nistp384");
@@ -495,7 +497,8 @@ public class KexManager
|| kxs.np.kex_algo.equals("diffie-hellman-group14-sha1")
|| kxs.np.kex_algo.equals("ecdh-sha2-nistp256")
|| kxs.np.kex_algo.equals("ecdh-sha2-nistp384")
- || kxs.np.kex_algo.equals("ecdh-sha2-nistp521")) {
+ || kxs.np.kex_algo.equals("ecdh-sha2-nistp521")
+ || kxs.np.kex_algo.equals(Curve25519Exchange.NAME)) {
kxs.dhx = GenericDhExchange.getInstance(kxs.np.kex_algo);
kxs.dhx.init(kxs.np.kex_algo);
@@ -633,7 +636,8 @@ public class KexManager
|| kxs.np.kex_algo.equals("diffie-hellman-group14-sha1")
|| kxs.np.kex_algo.equals("ecdh-sha2-nistp256")
|| kxs.np.kex_algo.equals("ecdh-sha2-nistp384")
- || kxs.np.kex_algo.equals("ecdh-sha2-nistp521"))
+ || kxs.np.kex_algo.equals("ecdh-sha2-nistp521")
+ || kxs.np.kex_algo.equals(Curve25519Exchange.NAME))
{
if (kxs.state == 1)
{