aboutsummaryrefslogtreecommitdiffstats
path: root/sshlib/src/main/java/com/trilead/ssh2/crypto/dh/Curve25519Exchange.java
blob: d28393bffea1f10b653575d0982566bbb7520c6b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
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";
	}
}