Skip to content

Commit

Permalink
Add support for other keytypes to openssh-key-v1 keyfiles (#485)
Browse files Browse the repository at this point in the history
* Added support for RSA to openssh-key-v1 keyfile

* Fixed exception

* Added ECDSA support to openssh-key-v1

* Added integration tests for different keytypes
  • Loading branch information
hierynomus authored Jan 17, 2019
1 parent 00cd335 commit cac340d
Show file tree
Hide file tree
Showing 20 changed files with 288 additions and 23 deletions.
2 changes: 1 addition & 1 deletion src/itest/docker-image/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
FROM sickp/alpine-sshd:7.5-r2

ADD id_rsa.pub /home/sshj/.ssh/authorized_keys
ADD authorized_keys /home/sshj/.ssh/authorized_keys

ADD test-container/ssh_host_ecdsa_key /etc/ssh/ssh_host_ecdsa_key
ADD test-container/ssh_host_ecdsa_key.pub /etc/ssh/ssh_host_ecdsa_key.pub
Expand Down
7 changes: 7 additions & 0 deletions src/itest/docker-image/authorized_keys
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBOEQcvowiV3igdRO7rKPrZrao1hCQrnC4tgsxqSJdQCbABI+vHrdbJRfWZNuSk48aAtARJzJVmkn/r63EPJgkh8= root@itgcpkerberosstack-cbgateway-0-20151117031915
ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBHQiZm0wBbmI8gohA/N9ir1O+egikL6S9FjZS8GHbx4rTHI1V+vbXxx2O9bFWtep1PFb4iowtZkxf6gvRjGkL6M= [email protected]
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDAdJiRkkBM8yC8seTEoAn2PfwbLKrkcahZ0xxPoWICJ root@sshj
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJ8ww4hJG/gHJYdkjTTBDF1GNz+228nuWprPV+NbQauA [email protected]
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOaWrwt3drIOjeBq2LSHRavxAT7ja2f+5soOUJl/zKSI [email protected]
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAoZ9l6Tkm2aL1tSBy2yw4xU5s8BE9MfqS/4J7DzvsYJxF6oQmTIjmStuhH/CT7UjuDtKXdXZUsIhKtafiizxGO8kHSzKDeitpth2RSr8ddMzZKyD6RNs7MfsgjA3UTtrrSrCXEY6O43S2cnuJrWzkPxtwxaQ3zOvDbS2tiulzyq0VzYmuhA/a4CyuQtJBuu+P2oqmu6pU/VB6IzONpvBvYbNPsH1WDmP7zko5wHPihXPCliztspKxS4DRtOZ7BGXyvg44UmIy0Kf4jOkaBV/eCCA4qH7ZHz71/5ceMOpszPcNOEmLGGYhwI+P3OuGMpkrSAv1f8IY6R8spZNncP6UaQ== no-passphrase
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDKRyZAtOJJfAhPU6xE6ZXY564vwErAI3n3Yn4lTHL9bxev9Ily6eCqPLcV0WbSV04pztngFn9MjT7yb8mcXheHpIaWEH569sMpmpOtyfn4p68SceuXBGyyPGMIcfOTknkASd1JYSD4EPkd9rZmCzcx3vEnLu8ChnA/G221xSVQ5VC/jD/c/CgNUayhQ+xbn57qHKKtZwfTa21QmwIabGYJNwlVjlKTCdddeVnZfKqKrG7cxHQApsxd21rhM9IT/C/f4Y/Tx3WUUVeam0iZ265oiPHoPALqJIWSQIUheRYAxYAQqJwSQ0Or9MM8XXun2Iy3RUSGk6eIvrCsFbNURsHNs7Pu0UnpYv6FZ3vCkFep/1pAT6fQvY7pDOOWDHKXArD4watc9gIWaQBH73wDW/KgBcnMRSoGWgQjsYqIamP4oV1+HqUI3lRAsXZaX+eiBGt3+3A5KebP27UJ1YUwhwlzs7wzTKaCu0OaL+hOsP1F2AxAa995bgFksMd23645ux3YCJKXG4sGpJ1Z/Hs49K72gv+QjLZVxXqY623c8+3OUhlixqoEFd4iG7UMc5a552ch/VA+jaspmLZoFhPz99aBRVb1oCSPxSwLw+Q/wxv6pZmT+14rqTzY2farjU53hM+CsUPh7dnWXhGG7RuA5wCdeOXOYjuksfzAoHIZhPqTgQ== [email protected]
1 change: 0 additions & 1 deletion src/itest/docker-image/id_rsa.pub

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import spock.lang.Specification
class IntegrationBaseSpec extends Specification {
protected static final int DOCKER_PORT = 2222
protected static final String USERNAME = "sshj"
protected static final String KEYFILE = "src/test/resources/id_rsa"
protected static final String KEYFILE = "src/itest/resources/keyfiles/id_rsa"
protected final static String SERVER_IP = System.getProperty("serverIP", "127.0.0.1")

protected static SSHClient getConnectedClient(Config config) {
Expand Down
18 changes: 15 additions & 3 deletions src/itest/groovy/com/hierynomus/sshj/IntegrationSpec.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -57,23 +57,35 @@ class IntegrationSpec extends IntegrationBaseSpec {
thrown(TransportException.class)
}

def "should authenticate"() {
@Unroll
def "should authenticate with key #key"() {
given:
SSHClient client = getConnectedClient()

when:
client.authPublickey(USERNAME, KEYFILE)
def keyProvider = passphrase != null ? client.loadKeys("src/itest/resources/keyfiles/$key", passphrase) : client.loadKeys("src/itest/resources/keyfiles/$key")
client.authPublickey(USERNAME, keyProvider)

then:
client.isAuthenticated()

where:
key | passphrase
// "id_ecdsa_nistp256" | null // TODO: Need to improve PKCS8 key support.
"id_ecdsa_opensshv1" | null
"id_ed25519_opensshv1" | null
"id_ed25519_opensshv1_aes256cbc.pem" | "foobar"
"id_ed25519_opensshv1_protected" | "sshjtest"
"id_rsa" | null
"id_rsa_opensshv1" | null
}

def "should not authenticate with wrong key"() {
given:
SSHClient client = getConnectedClient()

when:
client.authPublickey("sshj", "src/test/resources/id_dsa")
client.authPublickey("sshj", "src/itest/resources/keyfiles/id_unknown_key")

then:
thrown(UserAuthException.class)
Expand Down
5 changes: 5 additions & 0 deletions src/itest/resources/keyfiles/id_ecdsa_nistp256
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIJUMlsSlXqCZmCjlN4kV7hzP+p9pu0fwJ8r4m1qle58SoAoGCCqGSM49
AwEHoUQDQgAE4RBy+jCJXeKB1E7uso+tmtqjWEJCucLi2CzGpIl1AJsAEj68et1s
lF9Zk25KTjxoC0BEnMlWaSf+vrcQ8mCSHw==
-----END EC PRIVATE KEY-----
9 changes: 9 additions & 0 deletions src/itest/resources/keyfiles/id_ecdsa_opensshv1
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAaAAAABNlY2RzYS
1zaGEyLW5pc3RwMjU2AAAACG5pc3RwMjU2AAAAQQR0ImZtMAW5iPIKIQPzfYq9TvnoIpC+
kvRY2UvBh28eK0xyNVfr218cdjvWxVrXqdTxW+IqMLWZMX+oL0YxpC+jAAAAsD+6Oow/uj
qMAAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBHQiZm0wBbmI8goh
A/N9ir1O+egikL6S9FjZS8GHbx4rTHI1V+vbXxx2O9bFWtep1PFb4iowtZkxf6gvRjGkL6
MAAAAgXNC11pInVAOd3xNphiHMoISeitf6h1IKbDM+niLrL5kAAAAXYWp2YW5lcnBASGVp
bWRhbGwubG9jYWwB
-----END OPENSSH PRIVATE KEY-----
7 changes: 7 additions & 0 deletions src/itest/resources/keyfiles/id_ed25519_opensshv1
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
QyNTUxOQAAACAwHSYkZJATPMgvLHkxKAJ9j38Gyyq5HGoWdMcT6FiAiQAAAJDimgR84poE
fAAAAAtzc2gtZWQyNTUxOQAAACAwHSYkZJATPMgvLHkxKAJ9j38Gyyq5HGoWdMcT6FiAiQ
AAAECmsckQycWnfGQK6XtQpaMGODbAkMQOdJNK6XJSipB7dDAdJiRkkBM8yC8seTEoAn2P
fwbLKrkcahZ0xxPoWICJAAAACXJvb3RAc3NoagECAwQ=
-----END OPENSSH PRIVATE KEY-----
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jYmMAAAAGYmNyeXB0AAAAGAAAABBLQVXV9f
Wpw8AL9RTpAr//AAAAEAAAAAEAAAAzAAAAC3NzaC1lZDI1NTE5AAAAIJ8ww4hJG/gHJYdk
jTTBDF1GNz+228nuWprPV+NbQauAAAAAoGHEO7x3fSRBohvrIR52U4XD3uqRnhrPYm01k1
f4HHNNv46m92Zw6JKIB9Trrvp0sdMI8MVb79bN45rbn6mvpABtWl6T5TOTyMnKzDfAOx9c
FTaasWFmgtgkXOsu5pLrYBAQgCHWbzjjz6KoV1DmD4SAn9Ojf9Oh+YdAEKZcsvklgpu+Kj
nzN/DR0jt7Nzep2kNCLAS24QEkvQeATVSDiL8=
-----END OPENSSH PRIVATE KEY-----
8 changes: 8 additions & 0 deletions src/itest/resources/keyfiles/id_ed25519_opensshv1_protected
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jdHIAAAAGYmNyeXB0AAAAGAAAABB/aWL0WG
iYPOTxGlFwvaCNAAAAEAAAAAEAAAAzAAAAC3NzaC1lZDI1NTE5AAAAIOaWrwt3drIOjeBq
2LSHRavxAT7ja2f+5soOUJl/zKSIAAAAsKplAiFbOhzcOJYFYBYm8sqYbvhPF8jKdQFkbo
LAOeq+vQ0YBV9XUWQQM2tmL+RPjykPJZ2thcHLpVp3PfUEgo4bImCt939b3Ji3cEwD3QuK
MIhjhx1KvSJNF/uhjwPJnttwHG+ld8F5Gv7LpTOUmOzXKGLIgYRuwonhs5ezdNv5ERs+Cq
M9p/SW5ehL5KPJhGa5a+ZQXRojwEH7J4Q5xztH1gviTdIEpFWWQBH8rX6y
-----END OPENSSH PRIVATE KEY-----
27 changes: 27 additions & 0 deletions src/itest/resources/keyfiles/id_rsa
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEoAIBAAKCAQEAoZ9l6Tkm2aL1tSBy2yw4xU5s8BE9MfqS/4J7DzvsYJxF6oQm
TIjmStuhH/CT7UjuDtKXdXZUsIhKtafiizxGO8kHSzKDeitpth2RSr8ddMzZKyD6
RNs7MfsgjA3UTtrrSrCXEY6O43S2cnuJrWzkPxtwxaQ3zOvDbS2tiulzyq0VzYmu
hA/a4CyuQtJBuu+P2oqmu6pU/VB6IzONpvBvYbNPsH1WDmP7zko5wHPihXPClizt
spKxS4DRtOZ7BGXyvg44UmIy0Kf4jOkaBV/eCCA4qH7ZHz71/5ceMOpszPcNOEmL
GGYhwI+P3OuGMpkrSAv1f8IY6R8spZNncP6UaQIBIwKCAQBXvO4uJlbrLJQDPYAt
1i1ybGcF+rrR/Q34a2dgCpZDEwFiDTlcv1hxx689OXTf5cMPXGDZXX5udd9p7Wxa
NqnIrvVUtQWLdqcZuEeO+gitHr8IyMJf5Lm8C/u5vl1PYOYhO0qxwmrTP1u6fZPh
zWX2X1p5626/sy+TCisCRDeLRyes+Dtfs3bDjUq+zF3D/DmeYY55LUx0XS27uXNS
QuUDMSnymFyj4o+jPK0q/j5w4bB+0rbsij+EP7S//jOFrSEcZgBhhIj0rHA5fo6w
NrgtgRKD3HKFBM3b4VM8TdMbHsmf+nT9DjiDqcs+IxXMGlb1XTjtQFIN2eyRtNLd
eQ0bAoGBAMwgv3rGytRjVbR4TT77eF81svzitOJWRdfXuKB5gqM3jsPR08f1MEtZ
44kaI5ByJ3mBDt/EwNgLRdmBddPrLu3so9VLdRmWKI+KNGxwkcxzJv1xXdicgw+w
S5WgigJryuUbtdylXQTlRArLUKsXULk/MndhGiD+a4fZ3dUtktF9AoGBAMqxh6tr
S0ao0rN4hc9I92gwPubD1+XQr9TJQEEqGv3g5O3BdfDrTvizfaeNArahrIqyO5SK
7iDg0xcHqdxmVmmCJ8CkIWBPXLU6erQ1QNlBJmnzYn5lR0Ksx2h/myjeXztvJKEM
q4xUjAEzWjmwxxU3Y6l3FokvgIU4kOVoE4JdAoGARfyZa+xizHnUPeAae/5yaclE
rnmdGma43En2KGQsyj7vHpEVaSDdW6nKWuRj9wKRMPkMafpQvxnOzjsD06EXZ4RV
bbN4mw7pVcj8B+wUuyAqoAmchMfya8dqXy+6SfkSXS4Sd4knNODkIPVAOqjoegcJ
/QtZamXbuYyGkjuCy3sCgYBLSUEFJ9ohjymwX/cvvAQfYmCBmTLu9b2mzmhSt94j
yI+Lgl8BtnxrANbmdjQ1NLxuB6+61IRVWtIP3kZnzj1aY4sbqq1PqHLkOkrVOFnq
S2YKGJJMND8KIur67ZFm84J1KUgej61uow9uKQRBUEnx8AByJOsdAwPZteys+sVq
7wKBgAc3BL6ttDVYlL8U8fgvTCGuIajItvOQQj1n8RKyRLblYXBKAtY+pbULzmF+
HscRgJMcwEIosEbTzzBNEVQm6dS6R/Q534C00Fpsw1z/PFTI8AOdUzTROGjuN8Fg
YZoqMQLhk/PB8V4l7yJmPrE971RmJBBDlLDt6hZwOYEI2yF4
-----END RSA PRIVATE KEY-----
49 changes: 49 additions & 0 deletions src/itest/resources/keyfiles/id_rsa_opensshv1
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
-----BEGIN OPENSSH PRIVATE KEY-----
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
-----END OPENSSH PRIVATE KEY-----
15 changes: 15 additions & 0 deletions src/itest/resources/keyfiles/id_unknown_key
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
-----BEGIN DSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,9B6744BB12A8EA8F

pzZw5s3zDVHYdejZxdTpaRx00Yd1grbJe6mIJGvZRB0Jm0hKXoOX71PUI814mc5+
a5pzbyO98aciL/Eat5m3P692WQ0yOPMuphRnklsM3s4qrCjp2aRRbWvbyV/QV9bp
Xz2yYvNqU3WJC3UJIaFFMvRo/lC/Wsz9OvHSSl3LnsXXhiOCeaE32etoOYdlk9ro
N9NqDdaw28t9//iiHhuQK4afK6TZkU6DatFljJHILCC416Xh9+DDK9E+CDKzmlcw
jSwtzgFKEhgrT0XKoZR9LJZDolT1YpFy7M3cFRYIuYvJfuLcjxVEldJE900QlaJS
ybb6RxV6SRVwQYXTbIClcXes+oNJMv59DivAfajxECQC5sAynW/FnY1sz0igmz6D
scclJuJIbawqiuV/Lv6bvgzMa/ZXL4b9JeJPuQELa7tCpvj4fpNk1IiftYISlwoT
iG5pL8yLhPL4/fxGnKJzUPCA9mbwiloW2cAZZxTd+Utqmhemcl9gF0JGNR2XeYwS
3obEjbkqMF0WR3AcVZU9B5d9SKUaAzTp4vu5yZtNVEIaiVlnI3hMwWMs2Jgahswo
QF9MCPsRYsxLs7/u4a4qoQ==
-----END DSA PRIVATE KEY-----
Original file line number Diff line number Diff line change
Expand Up @@ -21,23 +21,27 @@
import net.i2p.crypto.eddsa.spec.EdDSAPrivateKeySpec;
import net.schmizz.sshj.common.*;
import net.schmizz.sshj.common.Buffer.PlainBuffer;
import net.schmizz.sshj.transport.cipher.BlockCipher;
import net.schmizz.sshj.transport.cipher.Cipher;
import net.schmizz.sshj.userauth.keyprovider.BaseFileKeyProvider;
import net.schmizz.sshj.userauth.keyprovider.FileKeyProvider;
import net.schmizz.sshj.userauth.keyprovider.KeyFormat;
import org.bouncycastle.asn1.nist.NISTNamedCurves;
import org.bouncycastle.asn1.x9.X9ECParameters;
import org.bouncycastle.jce.spec.ECNamedCurveSpec;
import org.mindrot.jbcrypt.BCrypt;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.BufferedReader;
import java.io.IOException;
import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.security.GeneralSecurityException;
import java.security.KeyPair;
import java.security.PublicKey;
import java.security.*;
import java.security.spec.ECPrivateKeySpec;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.RSAPrivateKeySpec;
import java.util.Arrays;

/**
Expand Down Expand Up @@ -125,10 +129,12 @@ private PlainBuffer decryptBuffer(PlainBuffer privateKeyBuffer, String cipherNam
private void initializeCipher(String kdfName, byte[] kdfOptions, Cipher cipher) throws Buffer.BufferException {
if (kdfName.equals(BCRYPT)) {
PlainBuffer opts = new PlainBuffer(kdfOptions);
CharBuffer charBuffer = CharBuffer.wrap(pwdf.reqPassword(null));
ByteBuffer byteBuffer = Charset.forName("UTF-8").encode(charBuffer);
byte[] passphrase = Arrays.copyOfRange(byteBuffer.array(),
byteBuffer.position(), byteBuffer.limit());
byte[] passphrase = new byte[0];
if (pwdf != null) {
CharBuffer charBuffer = CharBuffer.wrap(pwdf.reqPassword(null));
ByteBuffer byteBuffer = Charset.forName("UTF-8").encode(charBuffer);
passphrase = Arrays.copyOfRange(byteBuffer.array(), byteBuffer.position(), byteBuffer.limit());
}
byte[] keyiv = new byte[48];
new BCrypt().pbkdf(passphrase, opts.readBytes(), opts.readUInt32AsInt(), keyiv);
byte[] key = Arrays.copyOfRange(keyiv, 0, 32);
Expand Down Expand Up @@ -183,13 +189,40 @@ private KeyPair readUnencrypted(final PlainBuffer keyBuffer, final PublicKey pub
}
// The private key section contains both the public key and the private key
String keyType = keyBuffer.readString(); // string keytype
logger.info("Read key type: {}", keyType);

byte[] pubKey = keyBuffer.readBytes(); // string publickey (again...)
keyBuffer.readUInt32();
byte[] privKey = new byte[32];
keyBuffer.readRawBytes(privKey); // string privatekey
keyBuffer.readRawBytes(new byte[32]); // string publickey (again...)
KeyType kt = KeyType.fromString(keyType);
logger.info("Read key type: {}", keyType, kt);
KeyPair kp;
switch (kt) {
case ED25519:
byte[] pubKey = keyBuffer.readBytes(); // string publickey (again...)
keyBuffer.readUInt32(); // length of privatekey+publickey
byte[] privKey = new byte[32];
keyBuffer.readRawBytes(privKey); // string privatekey
keyBuffer.readRawBytes(new byte[32]); // string publickey (again...)
kp = new KeyPair(publicKey, new EdDSAPrivateKey(new EdDSAPrivateKeySpec(privKey, EdDSANamedCurveTable.getByName("Ed25519"))));
break;
case RSA:
BigInteger n = keyBuffer.readMPInt(); // Modulus
BigInteger e = keyBuffer.readMPInt(); // Public Exponent
BigInteger d = keyBuffer.readMPInt(); // Private Exponent
keyBuffer.readMPInt(); // iqmp (q^-1 mod p)
keyBuffer.readMPInt(); // p (Prime 1)
keyBuffer.readMPInt(); // q (Prime 2)
kp = new KeyPair(publicKey, SecurityUtils.getKeyFactory("RSA").generatePrivate(new RSAPrivateKeySpec(n, d)));
break;
case ECDSA256:
kp = new KeyPair(publicKey, createECDSAPrivateKey(kt, keyBuffer, "P-256"));
break;
case ECDSA384:
kp = new KeyPair(publicKey, createECDSAPrivateKey(kt, keyBuffer, "P-384"));
break;
case ECDSA521:
kp = new KeyPair(publicKey, createECDSAPrivateKey(kt, keyBuffer, "P-521"));
break;

default:
throw new IOException("Cannot decode keytype " + keyType + " in openssh-key-v1 files (yet).");
}
String comment = keyBuffer.readString(); // string comment
byte[] padding = new byte[keyBuffer.available()];
keyBuffer.readRawBytes(padding); // char[] padding
Expand All @@ -198,6 +231,16 @@ private KeyPair readUnencrypted(final PlainBuffer keyBuffer, final PublicKey pub
throw new IOException("Padding of key format contained wrong byte at position: " + i);
}
}
return new KeyPair(publicKey, new EdDSAPrivateKey(new EdDSAPrivateKeySpec(privKey, EdDSANamedCurveTable.getByName("Ed25519"))));
return kp;
}

private PrivateKey createECDSAPrivateKey(KeyType kt, PlainBuffer buffer, String name) throws GeneralSecurityException, Buffer.BufferException {
PublicKey pk = kt.readPubKeyFromBuffer(buffer); // Public key
BigInteger s = new BigInteger(1, buffer.readBytes());
X9ECParameters ecParams = NISTNamedCurves.getByName(name);
ECNamedCurveSpec ecCurveSpec = new ECNamedCurveSpec(name, ecParams.getCurve(), ecParams.getG(), ecParams.getN());
ECPrivateKeySpec pks = new ECPrivateKeySpec(s, ecCurveSpec);
return SecurityUtils.getKeyFactory("ECDSA").generatePrivate(pks);

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ private static String readHeader(Reader privateKey) throws IOException {

private static KeyFormat keyFormatFromHeader(String header, boolean separatePubKey) {
if (header.startsWith("-----BEGIN") && header.endsWith("PRIVATE KEY-----")) {
if (separatePubKey && header.contains(OpenSSHKeyV1KeyFile.OPENSSH_PRIVATE_KEY)) {
if (header.contains(OpenSSHKeyV1KeyFile.OPENSSH_PRIVATE_KEY)) {
return KeyFormat.OpenSSHv1;
} else if (separatePubKey) {
// Can delay asking for password since have unencrypted pubkey
Expand Down
16 changes: 16 additions & 0 deletions src/test/java/net/schmizz/sshj/keyprovider/OpenSSHKeyFileTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,22 @@ public void shouldLoadProtectedED25519PrivateKeyAes256CBC() throws IOException {
checkOpenSSHKeyV1("src/test/resources/keytypes/ed25519_aes256cbc.pem", "foobar");
}

@Test
public void shouldLoadRSAPrivateKeyAsOpenSSHV1() throws IOException {
OpenSSHKeyV1KeyFile keyFile = new OpenSSHKeyV1KeyFile();
keyFile.init(new File("src/test/resources/keyformats/rsa_opensshv1"));
PrivateKey aPrivate = keyFile.getPrivate();
assertThat(aPrivate.getAlgorithm(), equalTo("RSA"));
}

@Test
public void shouldLoadECDSAPrivateKeyAsOpenSSHV1() throws IOException {
OpenSSHKeyV1KeyFile keyFile = new OpenSSHKeyV1KeyFile();
keyFile.init(new File("src/test/resources/keyformats/ecdsa_opensshv1"));
PrivateKey aPrivate = keyFile.getPrivate();
assertThat(aPrivate.getAlgorithm(), equalTo("ECDSA"));
}

private void checkOpenSSHKeyV1(String key, final String password) throws IOException {
OpenSSHKeyV1KeyFile keyFile = new OpenSSHKeyV1KeyFile();
keyFile.init(new File(key), new PasswordFinder() {
Expand Down
Loading

0 comments on commit cac340d

Please sign in to comment.