diff --git a/src/main/java/net/schmizz/sshj/transport/kex/SecgUtils.java b/src/main/java/com/hierynomus/sshj/secg/SecgUtils.java similarity index 89% rename from src/main/java/net/schmizz/sshj/transport/kex/SecgUtils.java rename to src/main/java/com/hierynomus/sshj/secg/SecgUtils.java index 776edcf8..0e5be51f 100644 --- a/src/main/java/net/schmizz/sshj/transport/kex/SecgUtils.java +++ b/src/main/java/com/hierynomus/sshj/secg/SecgUtils.java @@ -1,4 +1,4 @@ -package net.schmizz.sshj.transport.kex; +package com.hierynomus.sshj.secg; import net.schmizz.sshj.common.SSHRuntimeException; @@ -7,11 +7,11 @@ import java.security.spec.ECPoint; import java.security.spec.EllipticCurve; import java.util.Arrays; -class SecgUtils { +public class SecgUtils { /** * SECG 2.3.4 Octet String to ECPoint */ - static ECPoint getDecoded(byte[] M, EllipticCurve curve) { + public 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()); @@ -26,7 +26,7 @@ class SecgUtils { /** * SECG 2.3.3 ECPoint to Octet String */ - static byte[] getEncoded(ECPoint point, EllipticCurve curve) { + public static byte[] getEncoded(ECPoint point, EllipticCurve curve) { int elementSize = getElementSize(curve); byte[] M = new byte[2 * elementSize + 1]; M[0] = 0x04; diff --git a/src/main/java/net/schmizz/sshj/common/KeyType.java b/src/main/java/net/schmizz/sshj/common/KeyType.java index a5ace6b1..046d1ed9 100644 --- a/src/main/java/net/schmizz/sshj/common/KeyType.java +++ b/src/main/java/net/schmizz/sshj/common/KeyType.java @@ -15,6 +15,7 @@ */ package net.schmizz.sshj.common; +import com.hierynomus.sshj.secg.SecgUtils; import org.bouncycastle.asn1.nist.NISTNamedCurves; import org.bouncycastle.asn1.x9.X9ECParameters; import org.bouncycastle.jce.spec.ECParameterSpec; @@ -151,17 +152,11 @@ public enum KeyType { @Override public void putPubKeyIntoBuffer(PublicKey pk, Buffer buf) { final ECPublicKey ecdsa = (ECPublicKey) pk; - final java.security.spec.ECPoint point = ecdsa.getW(); - final byte[] x = trimStartingZeros(point.getAffineX().toByteArray()); - final byte[] y = trimStartingZeros(point.getAffineY().toByteArray()); + byte[] encoded = SecgUtils.getEncoded(ecdsa.getW(), ecdsa.getParams().getCurve()); buf.putString(sType) .putString(NISTP_CURVE) - .putUInt32(1 + x.length + y.length) - .putRawBytes(new byte[] { (byte) 0x04 }) - .putRawBytes(x) - .putRawBytes(y) - ; + .putBytes(encoded); } @Override diff --git a/src/main/java/net/schmizz/sshj/transport/kex/ECDH.java b/src/main/java/net/schmizz/sshj/transport/kex/ECDH.java index d9c972ba..419e071f 100644 --- a/src/main/java/net/schmizz/sshj/transport/kex/ECDH.java +++ b/src/main/java/net/schmizz/sshj/transport/kex/ECDH.java @@ -1,6 +1,5 @@ package net.schmizz.sshj.transport.kex; -import net.schmizz.sshj.common.SSHRuntimeException; import net.schmizz.sshj.common.SecurityUtils; import java.math.BigInteger; @@ -10,10 +9,9 @@ import java.security.KeyPair; import java.security.PublicKey; import java.security.interfaces.ECPublicKey; import java.security.spec.*; -import java.util.Arrays; -import static net.schmizz.sshj.transport.kex.SecgUtils.getDecoded; -import static net.schmizz.sshj.transport.kex.SecgUtils.getEncoded; +import static com.hierynomus.sshj.secg.SecgUtils.getDecoded; +import static com.hierynomus.sshj.secg.SecgUtils.getEncoded; public class ECDH extends DHBase { diff --git a/src/main/java/net/schmizz/sshj/userauth/keyprovider/OpenSSHKeyFile.java b/src/main/java/net/schmizz/sshj/userauth/keyprovider/OpenSSHKeyFile.java index 46cd8a97..bee86433 100644 --- a/src/main/java/net/schmizz/sshj/userauth/keyprovider/OpenSSHKeyFile.java +++ b/src/main/java/net/schmizz/sshj/userauth/keyprovider/OpenSSHKeyFile.java @@ -92,7 +92,7 @@ public class OpenSSHKeyFile try { final String keydata = br.readLine(); if (keydata != null) { - String[] parts = keydata.split(" "); + String[] parts = keydata.trim().split(" "); assert parts.length >= 2; type = KeyType.fromString(parts[0]); pubKey = new Buffer.PlainBuffer(Base64.decode(parts[1])).readPublicKey(); diff --git a/src/test/java/net/schmizz/sshj/keyprovider/OpenSSHKeyFileTest.java b/src/test/java/net/schmizz/sshj/keyprovider/OpenSSHKeyFileTest.java index 4fdb4bcf..33d88d1c 100644 --- a/src/test/java/net/schmizz/sshj/keyprovider/OpenSSHKeyFileTest.java +++ b/src/test/java/net/schmizz/sshj/keyprovider/OpenSSHKeyFileTest.java @@ -30,9 +30,12 @@ import java.io.File; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.security.GeneralSecurityException; +import java.security.PublicKey; import java.util.Arrays; import java.util.Scanner; +import static org.hamcrest.CoreMatchers.containsString; +import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; @@ -127,6 +130,16 @@ public class OpenSSHKeyFileTest { assertEquals(KeyUtil.newDSAPrivateKey(x, p, q, g), dsa.getPrivate()); } + @Test + public void shouldHaveCorrectFingerprintForECDSA() throws IOException, GeneralSecurityException { + OpenSSHKeyFile keyFile = new OpenSSHKeyFile(); + keyFile.init(new File("src/test/resources/test_ecdsa_nistp256")); + String expected = "256 MD5:53:ae:db:ed:8f:2d:02:d4:d5:6c:24:bc:a4:66:88:79 root@itgcpkerberosstack-cbgateway-0-20151117031915 (ECDSA)\n"; + PublicKey aPublic = keyFile.getPublic(); + String sshjFingerprintSshjKey = net.schmizz.sshj.common.SecurityUtils.getFingerprint(aPublic); + assertThat(expected, containsString(sshjFingerprintSshjKey)); + } + @Before public void setup() throws UnsupportedEncodingException, GeneralSecurityException { diff --git a/src/test/resources/test_ecdsa_nistp256 b/src/test/resources/test_ecdsa_nistp256 new file mode 100644 index 00000000..720e7fc0 --- /dev/null +++ b/src/test/resources/test_ecdsa_nistp256 @@ -0,0 +1,5 @@ +-----BEGIN EC PRIVATE KEY----- +MHcCAQEEIJUMlsSlXqCZmCjlN4kV7hzP+p9pu0fwJ8r4m1qle58SoAoGCCqGSM49 +AwEHoUQDQgAE4RBy+jCJXeKB1E7uso+tmtqjWEJCucLi2CzGpIl1AJsAEj68et1s +lF9Zk25KTjxoC0BEnMlWaSf+vrcQ8mCSHw== +-----END EC PRIVATE KEY----- diff --git a/src/test/resources/test_ecdsa_nistp256.pub b/src/test/resources/test_ecdsa_nistp256.pub new file mode 100644 index 00000000..feb6314a --- /dev/null +++ b/src/test/resources/test_ecdsa_nistp256.pub @@ -0,0 +1 @@ +ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBOEQcvowiV3igdRO7rKPrZrao1hCQrnC4tgsxqSJdQCbABI+vHrdbJRfWZNuSk48aAtARJzJVmkn/r63EPJgkh8= root@itgcpkerberosstack-cbgateway-0-20151117031915