Skip to content

Commit

Permalink
Support ECDSA PuTTY keys.
Browse files Browse the repository at this point in the history
  • Loading branch information
vladimirlagunov committed Jan 8, 2021
1 parent 8076fb8 commit 8bc1e71
Show file tree
Hide file tree
Showing 9 changed files with 139 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,11 @@
import net.schmizz.sshj.common.Base64;
import net.schmizz.sshj.common.Buffer;
import net.schmizz.sshj.common.KeyType;
import net.schmizz.sshj.common.SecurityUtils;
import net.schmizz.sshj.userauth.password.PasswordUtils;
import org.bouncycastle.asn1.nist.NISTNamedCurves;
import org.bouncycastle.asn1.x9.X9ECParameters;
import org.bouncycastle.jce.spec.ECNamedCurveSpec;
import org.bouncycastle.util.encoders.Hex;

import javax.crypto.Cipher;
Expand Down Expand Up @@ -165,6 +169,35 @@ protected KeyPair readKeyPair() throws IOException {
EdDSAPrivateKeySpec privateSpec = new EdDSAPrivateKeySpec(privateKeyReader.readBytes(), ed25519);
return new KeyPair(new EdDSAPublicKey(publicSpec), new EdDSAPrivateKey(privateSpec));
}
final int ecdsaCurve;
switch (this.getType()) {
case ECDSA256:
ecdsaCurve = 256;
break;
case ECDSA384:
ecdsaCurve = 384;
break;
case ECDSA521:
ecdsaCurve = 521;
break;
default:
ecdsaCurve = -1;
break;
}
if (ecdsaCurve > 0) {
BigInteger s = new BigInteger(1, privateKeyReader.readBytes());
String name = "P-" + ecdsaCurve;
X9ECParameters ecParams = NISTNamedCurves.getByName(name);
ECNamedCurveSpec ecCurveSpec =
new ECNamedCurveSpec(name, ecParams.getCurve(), ecParams.getG(), ecParams.getN());
ECPrivateKeySpec pks = new ECPrivateKeySpec(s, ecCurveSpec);
try {
PrivateKey privateKey = SecurityUtils.getKeyFactory(KeyAlgorithm.ECDSA).generatePrivate(pks);
return new KeyPair(getType().readPubKeyFromBuffer(publicKeyReader), privateKey);
} catch (GeneralSecurityException e) {
throw new IOException(e.getMessage(), e);
}
}
throw new IOException(String.format("Unknown key type %s", this.getType()));
}

Expand Down
49 changes: 49 additions & 0 deletions src/test/java/net/schmizz/sshj/keyprovider/PuTTYKeyFileTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package net.schmizz.sshj.keyprovider;

import com.hierynomus.sshj.userauth.keyprovider.OpenSSHKeyV1KeyFile;
import net.schmizz.sshj.userauth.keyprovider.PKCS8KeyFile;
import net.schmizz.sshj.userauth.keyprovider.PuTTYKeyFile;
import net.schmizz.sshj.userauth.password.PasswordFinder;
import net.schmizz.sshj.userauth.password.Resource;
Expand Down Expand Up @@ -292,6 +293,54 @@ public boolean shouldRetry(Resource<?> resource) {
assertEquals(key.getPublic(), referenceKey.getPublic());
}

@Test
public void testEcDsa256() throws Exception {
// Generated with
// puttygen src/test/resources/keytypes/test_ecdsa_nistp256 -O private \
// -o src/test/resources/keytypes/test_ecdsa_nistp256_puttygen.ppk
PuTTYKeyFile key = new PuTTYKeyFile();
key.init(new File("src/test/resources/keytypes/test_ecdsa_nistp256_puttygen.ppk"));
assertNotNull(key.getPrivate());
assertNotNull(key.getPublic());

PKCS8KeyFile referenceKey = new PKCS8KeyFile();
referenceKey.init(new File("src/test/resources/keytypes/test_ecdsa_nistp256"));
assertEquals(key.getPrivate(), referenceKey.getPrivate());
assertEquals(key.getPublic(), referenceKey.getPublic());
}

@Test
public void testEcDsa384() throws Exception {
// Generated with
// puttygen src/test/resources/keytypes/test_ecdsa_nistp384_2 -O private \
// -o src/test/resources/keytypes/test_ecdsa_nistp384_2_puttygen.ppk
PuTTYKeyFile key = new PuTTYKeyFile();
key.init(new File("src/test/resources/keytypes/test_ecdsa_nistp384_2_puttygen.ppk"));
assertNotNull(key.getPrivate());
assertNotNull(key.getPublic());

OpenSSHKeyV1KeyFile referenceKey = new OpenSSHKeyV1KeyFile();
referenceKey.init(new File("src/test/resources/keytypes/test_ecdsa_nistp384_2"));
assertEquals(key.getPrivate(), referenceKey.getPrivate());
assertEquals(key.getPublic(), referenceKey.getPublic());
}

@Test
public void testEcDsa521() throws Exception {
// Generated with
// puttygen src/test/resources/keytypes/test_ecdsa_nistp521_2 -O private \
// -o src/test/resources/keytypes/test_ecdsa_nistp521_2_puttygen.ppk
PuTTYKeyFile key = new PuTTYKeyFile();
key.init(new File("src/test/resources/keytypes/test_ecdsa_nistp521_2_puttygen.ppk"));
assertNotNull(key.getPrivate());
assertNotNull(key.getPublic());

OpenSSHKeyV1KeyFile referenceKey = new OpenSSHKeyV1KeyFile();
referenceKey.init(new File("src/test/resources/keytypes/test_ecdsa_nistp521_2"));
assertEquals(key.getPrivate(), referenceKey.getPrivate());
assertEquals(key.getPublic(), referenceKey.getPublic());
}

@Test
public void testCorrectPassphraseRsa() throws Exception {
PuTTYKeyFile key = new PuTTYKeyFile();
Expand Down
10 changes: 10 additions & 0 deletions src/test/resources/keytypes/test_ecdsa_nistp256_puttygen.ppk
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
PuTTY-User-Key-File-2: ecdsa-sha2-nistp256
Encryption: none
Comment: imported-openssh-key
Public-Lines: 3
AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBOEQcvowiV3i
gdRO7rKPrZrao1hCQrnC4tgsxqSJdQCbABI+vHrdbJRfWZNuSk48aAtARJzJVmkn
/r63EPJgkh8=
Private-Lines: 1
AAAAIQCVDJbEpV6gmZgo5TeJFe4cz/qfabtH8CfK+JtapXufEg==
Private-MAC: 48f3a17cf5f65f4f225e7a21f007d8270d7c8c8f
10 changes: 10 additions & 0 deletions src/test/resources/keytypes/test_ecdsa_nistp384_2
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAiAAAABNlY2RzYS
1zaGEyLW5pc3RwMzg0AAAACG5pc3RwMzg0AAAAYQRNKNXuAS/Um8JmbTAWnMf5l/JaXLPb
GWIuXwcZeDd/bnrFeAkMRALkKfGLHmD3Sw+1A/qk+mOIYyYbYINN4jqQxVuDzpMD0q/pkt
dSx6H7GOxVN4W4BMDY23jGLpVWPgYAAADgeuV2SXrldkkAAAATZWNkc2Etc2hhMi1uaXN0
cDM4NAAAAAhuaXN0cDM4NAAAAGEETSjV7gEv1JvCZm0wFpzH+ZfyWlyz2xliLl8HGXg3f2
56xXgJDEQC5Cnxix5g90sPtQP6pPpjiGMmG2CDTeI6kMVbg86TA9Kv6ZLXUseh+xjsVTeF
uATA2Nt4xi6VVj4GAAAAMQDmxzsgvtP2GuzXgIuqtUVEIEMil6XD3oacqj7Ew9MLJ9641X
SOf6mmKKV2d5QHzC0AAAARbGFndW5vdkB1bml0LTEzODEBAgMEBQY=
-----END OPENSSH PRIVATE KEY-----
1 change: 1 addition & 0 deletions src/test/resources/keytypes/test_ecdsa_nistp384_2.pub
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBE0o1e4BL9SbwmZtMBacx/mX8lpcs9sZYi5fBxl4N39uesV4CQxEAuQp8YseYPdLD7UD+qT6Y4hjJhtgg03iOpDFW4POkwPSr+mS11LHofsY7FU3hbgEwNjbeMYulVY+Bg== lagunov@unit-1381
11 changes: 11 additions & 0 deletions src/test/resources/keytypes/test_ecdsa_nistp384_2_puttygen.ppk
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
PuTTY-User-Key-File-2: ecdsa-sha2-nistp384
Encryption: none
Comment: lagunov@unit-1381
Public-Lines: 3
AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBE0o1e4BL9Sb
wmZtMBacx/mX8lpcs9sZYi5fBxl4N39uesV4CQxEAuQp8YseYPdLD7UD+qT6Y4hj
Jhtgg03iOpDFW4POkwPSr+mS11LHofsY7FU3hbgEwNjbeMYulVY+Bg==
Private-Lines: 2
AAAAMQDmxzsgvtP2GuzXgIuqtUVEIEMil6XD3oacqj7Ew9MLJ9641XSOf6mmKKV2
d5QHzC0=
Private-MAC: 1a403879b840e06c2004b7901eca9f80c3faad76
12 changes: 12 additions & 0 deletions src/test/resources/keytypes/test_ecdsa_nistp521_2
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAArAAAABNlY2RzYS
1zaGEyLW5pc3RwNTIxAAAACG5pc3RwNTIxAAAAhQQB61HvD2TptgQbzdLCU5sltq+k2Dha
UQK6OQl7FCZe5RuIeokwZj8F04e7WwuUjaP2QhNeIigprJSksh54uwkQtbgAhHP67q3r+Q
3wrVpfXb8pnGlzvbJSD8eMt8rL7uFgKxIm5ohi/1yLxVAjDTBB8MP7gRK2ZxlktytgZW9p
2FyZvOYAAAEQMgc5wDIHOcAAAAATZWNkc2Etc2hhMi1uaXN0cDUyMQAAAAhuaXN0cDUyMQ
AAAIUEAetR7w9k6bYEG83SwlObJbavpNg4WlECujkJexQmXuUbiHqJMGY/BdOHu1sLlI2j
9kITXiIoKayUpLIeeLsJELW4AIRz+u6t6/kN8K1aX12/KZxpc72yUg/HjLfKy+7hYCsSJu
aIYv9ci8VQIw0wQfDD+4EStmcZZLcrYGVvadhcmbzmAAAAQgFrcwyNJrHD5D6YRwkZe5D2
jYwZt9hB+prBiCyU0lQ7wUDI0SOlewp3x6IVMPG0cAVGWPBSvgmkpd3OVH0LcTibnwAAAB
FsYWd1bm92QHVuaXQtMTM4MQE=
-----END OPENSSH PRIVATE KEY-----
1 change: 1 addition & 0 deletions src/test/resources/keytypes/test_ecdsa_nistp521_2.pub
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAHrUe8PZOm2BBvN0sJTmyW2r6TYOFpRAro5CXsUJl7lG4h6iTBmPwXTh7tbC5SNo/ZCE14iKCmslKSyHni7CRC1uACEc/rurev5DfCtWl9dvymcaXO9slIPx4y3ysvu4WArEibmiGL/XIvFUCMNMEHww/uBErZnGWS3K2Blb2nYXJm85g== lagunov@unit-1381
12 changes: 12 additions & 0 deletions src/test/resources/keytypes/test_ecdsa_nistp521_2_puttygen.ppk
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
PuTTY-User-Key-File-2: ecdsa-sha2-nistp521
Encryption: none
Comment: lagunov@unit-1381
Public-Lines: 4
AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAHrUe8PZOm2
BBvN0sJTmyW2r6TYOFpRAro5CXsUJl7lG4h6iTBmPwXTh7tbC5SNo/ZCE14iKCms
lKSyHni7CRC1uACEc/rurev5DfCtWl9dvymcaXO9slIPx4y3ysvu4WArEibmiGL/
XIvFUCMNMEHww/uBErZnGWS3K2Blb2nYXJm85g==
Private-Lines: 2
AAAAQgFrcwyNJrHD5D6YRwkZe5D2jYwZt9hB+prBiCyU0lQ7wUDI0SOlewp3x6IV
MPG0cAVGWPBSvgmkpd3OVH0LcTibnw==
Private-MAC: 7ec9ca86c1c5e99076259f90cb82f77bbdbc4d7f

0 comments on commit 8bc1e71

Please sign in to comment.