-
Notifications
You must be signed in to change notification settings - Fork 603
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added support for curve25519-sha256@libssh.org (Fixes #171)
- Loading branch information
1 parent
eece80c
commit 29a6cf6
Showing
8 changed files
with
188 additions
and
65 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
54 changes: 54 additions & 0 deletions
54
src/main/java/net/schmizz/sshj/transport/kex/Curve25519DH.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
package net.schmizz.sshj.transport.kex; | ||
|
||
import net.schmizz.sshj.common.SecurityUtils; | ||
import org.bouncycastle.asn1.x9.X9ECParameters; | ||
import org.bouncycastle.crypto.ec.CustomNamedCurves; | ||
import org.bouncycastle.jce.spec.ECParameterSpec; | ||
import org.bouncycastle.math.ec.ECFieldElement; | ||
import org.bouncycastle.math.ec.custom.djb.Curve25519; | ||
|
||
import java.math.BigInteger; | ||
import java.security.*; | ||
import java.security.interfaces.ECPublicKey; | ||
import java.security.spec.AlgorithmParameterSpec; | ||
import java.security.spec.ECPoint; | ||
import java.security.spec.ECPublicKeySpec; | ||
import java.util.Arrays; | ||
import java.util.BitSet; | ||
|
||
public class Curve25519DH extends DHBase { | ||
|
||
|
||
private byte[] secretKey; | ||
|
||
public Curve25519DH() { | ||
super("ECDSA", "ECDH"); | ||
} | ||
|
||
@Override | ||
void computeK(byte[] f) throws GeneralSecurityException { | ||
byte[] k = new byte[32]; | ||
djb.Curve25519.curve(k, secretKey, f); | ||
setK(new BigInteger(1, k)); | ||
} | ||
|
||
@Override | ||
public void init(AlgorithmParameterSpec params) throws GeneralSecurityException { | ||
SecureRandom secureRandom = new SecureRandom(); | ||
byte[] secretBytes = new byte[32]; | ||
secureRandom.nextBytes(secretBytes); | ||
byte[] publicBytes = new byte[32]; | ||
djb.Curve25519.keygen(publicBytes, null, secretBytes); | ||
this.secretKey = Arrays.copyOf(secretBytes, secretBytes.length); | ||
setE(publicBytes); | ||
} | ||
|
||
/** | ||
* TODO want to figure out why BouncyCastle does not work. | ||
* @return | ||
*/ | ||
public static AlgorithmParameterSpec getCurve25519Params() { | ||
X9ECParameters ecP = CustomNamedCurves.getByName("curve25519"); | ||
return new ECParameterSpec(ecP.getCurve(), ecP.getG(), ecP.getN(), ecP.getH(), ecP.getSeed()); | ||
} | ||
} |
38 changes: 38 additions & 0 deletions
38
src/main/java/net/schmizz/sshj/transport/kex/Curve25519SHA256.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
package net.schmizz.sshj.transport.kex; | ||
|
||
import net.schmizz.sshj.common.*; | ||
import net.schmizz.sshj.signature.Signature; | ||
import net.schmizz.sshj.transport.TransportException; | ||
import net.schmizz.sshj.transport.digest.SHA256; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
||
import java.security.GeneralSecurityException; | ||
|
||
public class Curve25519SHA256 extends AbstractDHG { | ||
private static final Logger logger = LoggerFactory.getLogger(Curve25519SHA256.class); | ||
|
||
/** Named factory for Curve25519SHA256 key exchange */ | ||
public static class Factory | ||
implements net.schmizz.sshj.common.Factory.Named<KeyExchange> { | ||
|
||
@Override | ||
public KeyExchange create() { | ||
return new Curve25519SHA256(); | ||
} | ||
|
||
@Override | ||
public String getName() { | ||
return "curve25519-sha256@libssh.org"; | ||
} | ||
} | ||
|
||
public Curve25519SHA256() { | ||
super(new Curve25519DH(), new SHA256()); | ||
} | ||
|
||
@Override | ||
protected void initDH(DHBase dh) throws GeneralSecurityException { | ||
dh.init(Curve25519DH.getCurve25519Params()); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
55 changes: 55 additions & 0 deletions
55
src/main/java/net/schmizz/sshj/transport/kex/SecgUtils.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
package net.schmizz.sshj.transport.kex; | ||
|
||
import net.schmizz.sshj.common.SSHRuntimeException; | ||
|
||
import java.math.BigInteger; | ||
import java.security.spec.ECPoint; | ||
import java.security.spec.EllipticCurve; | ||
import java.util.Arrays; | ||
|
||
class SecgUtils { | ||
/** | ||
* SECG 2.3.4 Octet String to ECPoint | ||
*/ | ||
static ECPoint getDecoded(byte[] M, EllipticCurve curve) { | ||
int elementSize = getElementSize(curve); | ||
if (M.length != 2 * elementSize + 1 || M[0] != 0x04) { | ||
throw new SSHRuntimeException("Invalid 'f' for Elliptic Curve " + curve.toString()); | ||
} | ||
byte[] xBytes = new byte[elementSize]; | ||
byte[] yBytes = new byte[elementSize]; | ||
System.arraycopy(M, 1, xBytes, 0, elementSize); | ||
System.arraycopy(M, 1 + elementSize, yBytes, 0, elementSize); | ||
return new ECPoint(new BigInteger(1, xBytes), new BigInteger(1, yBytes)); | ||
} | ||
|
||
/** | ||
* SECG 2.3.3 ECPoint to Octet String | ||
*/ | ||
static byte[] getEncoded(ECPoint point, EllipticCurve curve) { | ||
int elementSize = getElementSize(curve); | ||
byte[] M = new byte[2 * elementSize + 1]; | ||
M[0] = 0x04; | ||
|
||
byte[] xBytes = stripLeadingZeroes(point.getAffineX().toByteArray()); | ||
byte[] yBytes = stripLeadingZeroes(point.getAffineY().toByteArray()); | ||
System.arraycopy(xBytes, 0, M, 1 + elementSize - xBytes.length, xBytes.length); | ||
System.arraycopy(yBytes, 0, M, 1 + 2 * elementSize - yBytes.length, yBytes.length); | ||
return M; | ||
} | ||
|
||
private static byte[] stripLeadingZeroes(byte[] bytes) { | ||
int start = 0; | ||
while (bytes[start] == 0x0) { | ||
start++; | ||
} | ||
|
||
return Arrays.copyOfRange(bytes, start, bytes.length); | ||
} | ||
|
||
private static int getElementSize(EllipticCurve curve) { | ||
int fieldSize = curve.getField().getFieldSize(); | ||
return (fieldSize + 7) / 8; | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters