Skip to content

Commit

Permalink
PuTTYKeyFile: Use net.schmizz.sshj.common.Buffer instead of own KeyRe…
Browse files Browse the repository at this point in the history
…ader.

A tiny refactoring made in order to allow usage of other utility methods which require Buffer.
  • Loading branch information
vladimirlagunov committed Jan 8, 2021
1 parent e173c07 commit 8076fb8
Showing 1 changed file with 15 additions and 58 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import net.i2p.crypto.eddsa.spec.EdDSAPrivateKeySpec;
import net.i2p.crypto.eddsa.spec.EdDSAPublicKeySpec;
import net.schmizz.sshj.common.Base64;
import net.schmizz.sshj.common.Buffer;
import net.schmizz.sshj.common.KeyType;
import net.schmizz.sshj.userauth.password.PasswordUtils;
import org.bouncycastle.util.encoders.Hex;
Expand Down Expand Up @@ -107,17 +108,17 @@ public boolean isEncrypted() {

protected KeyPair readKeyPair() throws IOException {
this.parseKeyPair();
final Buffer.PlainBuffer publicKeyReader = new Buffer.PlainBuffer(publicKey);
final Buffer.PlainBuffer privateKeyReader = new Buffer.PlainBuffer(privateKey);
publicKeyReader.readBytes(); // The first part of the payload is a human-readable key format name.
if (KeyType.RSA.equals(this.getType())) {
final KeyReader publicKeyReader = new KeyReader(publicKey);
publicKeyReader.skip(); // skip this
// public key exponent
BigInteger e = publicKeyReader.readInt();
BigInteger e = new BigInteger(publicKeyReader.readBytes());
// modulus
BigInteger n = publicKeyReader.readInt();
BigInteger n = new BigInteger(publicKeyReader.readBytes());

final KeyReader privateKeyReader = new KeyReader(privateKey);
// private key exponent
BigInteger d = privateKeyReader.readInt();
BigInteger d = new BigInteger(privateKeyReader.readBytes());

final KeyFactory factory;
try {
Expand All @@ -135,16 +136,13 @@ protected KeyPair readKeyPair() throws IOException {
}
}
if (KeyType.DSA.equals(this.getType())) {
final KeyReader publicKeyReader = new KeyReader(publicKey);
publicKeyReader.skip(); // skip this
BigInteger p = publicKeyReader.readInt();
BigInteger q = publicKeyReader.readInt();
BigInteger g = publicKeyReader.readInt();
BigInteger y = publicKeyReader.readInt();

final KeyReader privateKeyReader = new KeyReader(privateKey);
BigInteger p = new BigInteger(publicKeyReader.readBytes());
BigInteger q = new BigInteger(publicKeyReader.readBytes());
BigInteger g = new BigInteger(publicKeyReader.readBytes());
BigInteger y = new BigInteger(publicKeyReader.readBytes());

// Private exponent from the private key
BigInteger x = privateKeyReader.readInt();
BigInteger x = new BigInteger(privateKeyReader.readBytes());

final KeyFactory factory;
try {
Expand All @@ -163,13 +161,8 @@ protected KeyPair readKeyPair() throws IOException {
}
if (KeyType.ED25519.equals(this.getType())) {
EdDSANamedCurveSpec ed25519 = EdDSANamedCurveTable.getByName("Ed25519");

final KeyReader publicKeyReader = new KeyReader(publicKey);
publicKeyReader.skip(); // The first part of the payload is "ssh-ed25519" string.
EdDSAPublicKeySpec publicSpec = new EdDSAPublicKeySpec(publicKeyReader.read(), ed25519);

final KeyReader privateKeyReader = new KeyReader(privateKey);
EdDSAPrivateKeySpec privateSpec = new EdDSAPrivateKeySpec(privateKeyReader.read(), ed25519);
EdDSAPublicKeySpec publicSpec = new EdDSAPublicKeySpec(publicKeyReader.readBytes(), ed25519);
EdDSAPrivateKeySpec privateSpec = new EdDSAPrivateKeySpec(privateKeyReader.readBytes(), ed25519);
return new KeyPair(new EdDSAPublicKey(publicSpec), new EdDSAPrivateKey(privateSpec));
}
throw new IOException(String.format("Unknown key type %s", this.getType()));
Expand Down Expand Up @@ -313,40 +306,4 @@ private byte[] decrypt(final byte[] key, final String passphrase) throws IOExcep
throw new IOException(e.getMessage(), e);
}
}

/**
* Parses the putty key bit vector, which is an encoded sequence
* of {@link java.math.BigInteger}s.
*/
private final static class KeyReader {
private final DataInput di;

public KeyReader(byte[] key) {
this.di = new DataInputStream(new ByteArrayInputStream(key));
}

/**
* Skips an integer without reading it.
*/
public void skip() throws IOException {
final int read = di.readInt();
if (read != di.skipBytes(read)) {
throw new IOException(String.format("Failed to skip %d bytes", read));
}
}

private byte[] read() throws IOException {
int len = di.readInt();
byte[] r = new byte[len];
di.readFully(r);
return r;
}

/**
* Reads the next integer.
*/
public BigInteger readInt() throws IOException {
return new BigInteger(read());
}
}
}

0 comments on commit 8076fb8

Please sign in to comment.