From 0bcb82c407b334b6c3dd0e243cabcfa2913a2f5a Mon Sep 17 00:00:00 2001 From: Kenny Root Date: Sat, 23 Jan 2016 15:44:40 -0800 Subject: Add curve25519-sha256@libssh.org exchange method --- .../trilead/ssh2/crypto/dh/Curve25519Exchange.java | 71 ++++++++++++++++++++++ .../trilead/ssh2/crypto/dh/GenericDhExchange.java | 3 + 2 files changed, 74 insertions(+) create mode 100644 sshlib/src/main/java/com/trilead/ssh2/crypto/dh/Curve25519Exchange.java (limited to 'sshlib/src/main/java/com/trilead/ssh2/crypto') 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 { -- cgit v1.2.3