diff src/ch/ethz/ssh2/crypto/dh/EcDhExchange.java @ 309:cb179051f0f2 ganymed

add ecdsa key support everywhere
author Carl Byington <carl@five-ten-sg.com>
date Wed, 30 Jul 2014 14:29:39 -0700
parents
children 1d400fd78e4a
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ch/ethz/ssh2/crypto/dh/EcDhExchange.java	Wed Jul 30 14:29:39 2014 -0700
@@ -0,0 +1,114 @@
+/**
+ *
+ */
+package ch.ethz.ssh2.crypto.dh;
+
+import java.io.IOException;
+import java.math.BigInteger;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.KeyFactory;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.NoSuchAlgorithmException;
+import java.security.interfaces.ECPrivateKey;
+import java.security.interfaces.ECPublicKey;
+import java.security.spec.ECParameterSpec;
+import java.security.spec.ECPoint;
+import java.security.spec.ECPublicKeySpec;
+import java.security.spec.InvalidKeySpecException;
+
+import javax.crypto.KeyAgreement;
+
+import ch.ethz.ssh2.signature.ECDSASHA2Verify;
+
+/**
+ * @author kenny
+ *
+ */
+public class EcDhExchange extends GenericDhExchange {
+    private ECPrivateKey clientPrivate;
+    private ECPublicKey clientPublic;
+    private ECPublicKey serverPublic;
+
+    @Override
+    public void init(String name) throws IOException {
+        final ECParameterSpec spec;
+
+        if ("ecdh-sha2-nistp256".equals(name)) {
+            spec = ECDSASHA2Verify.EllipticCurves.nistp256;
+        }
+        else if ("ecdh-sha2-nistp384".equals(name)) {
+            spec = ECDSASHA2Verify.EllipticCurves.nistp384;
+        }
+        else if ("ecdh-sha2-nistp521".equals(name)) {
+            spec = ECDSASHA2Verify.EllipticCurves.nistp521;
+        }
+        else {
+            throw new IllegalArgumentException("Unknown EC curve " + name);
+        }
+
+        KeyPairGenerator kpg;
+
+        try {
+            kpg = KeyPairGenerator.getInstance("EC");
+            kpg.initialize(spec);
+            KeyPair pair = kpg.generateKeyPair();
+            clientPrivate = (ECPrivateKey) pair.getPrivate();
+            clientPublic = (ECPublicKey) pair.getPublic();
+        }
+        catch (NoSuchAlgorithmException e) {
+            throw(IOException) new IOException("No DH keypair generator").initCause(e);
+        }
+        catch (InvalidAlgorithmParameterException e) {
+            throw(IOException) new IOException("Invalid DH parameters").initCause(e);
+        }
+    }
+
+    @Override
+    public byte[] getE() {
+        return ECDSASHA2Verify.encodeECPoint(clientPublic.getW(), clientPublic.getParams()
+                                             .getCurve());
+    }
+
+    @Override
+    protected byte[] getServerE() {
+        return ECDSASHA2Verify.encodeECPoint(serverPublic.getW(), serverPublic.getParams()
+                                             .getCurve());
+    }
+
+    @Override
+    public void setF(byte[] f) throws IOException {
+        if (clientPublic == null)
+            throw new IllegalStateException("DhDsaExchange not initialized!");
+
+        final KeyAgreement ka;
+
+        try {
+            KeyFactory kf = KeyFactory.getInstance("EC");
+            ECParameterSpec params = clientPublic.getParams();
+            ECPoint serverPoint = ECDSASHA2Verify.decodeECPoint(f, params.getCurve());
+            this.serverPublic = (ECPublicKey) kf.generatePublic(new ECPublicKeySpec(serverPoint,
+                                params));
+            ka = KeyAgreement.getInstance("ECDH");
+            ka.init(clientPrivate);
+            ka.doPhase(serverPublic, true);
+        }
+        catch (NoSuchAlgorithmException e) {
+            throw(IOException) new IOException("No ECDH key agreement method").initCause(e);
+        }
+        catch (InvalidKeyException e) {
+            throw(IOException) new IOException("Invalid ECDH key").initCause(e);
+        }
+        catch (InvalidKeySpecException e) {
+            throw(IOException) new IOException("Invalid ECDH key").initCause(e);
+        }
+
+        sharedSecret = new BigInteger(ka.generateSecret());
+    }
+
+    @Override
+    public String getHashAlgo() {
+        return ECDSASHA2Verify.getDigestAlgorithmForParams(clientPublic.getParams());
+    }
+}