mirror of
https://github.com/hierynomus/sshj.git
synced 2025-12-06 15:20:54 +03:00
Skip blank lines when detecting key formats
Some private keys found in the wild start with a blank line, which breaks SSHJ. OpenSSH utilities worked as expected with these key files. Also add some basic tests for key formats.
This commit is contained in:
committed by
Jeroen van Erp
parent
1c749da957
commit
c98ad22a7a
@@ -51,8 +51,7 @@ public class KeyProviderUtil {
|
||||
* @return name of the key file format
|
||||
* @throws java.io.IOException
|
||||
*/
|
||||
public static KeyFormat detectKeyFileFormat(String privateKey,
|
||||
boolean separatePubKey)
|
||||
public static KeyFormat detectKeyFileFormat(String privateKey, boolean separatePubKey)
|
||||
throws IOException {
|
||||
return detectKeyFileFormat(new StringReader(privateKey), separatePubKey);
|
||||
}
|
||||
@@ -67,35 +66,44 @@ public class KeyProviderUtil {
|
||||
* @return name of the key file format
|
||||
* @throws java.io.IOException
|
||||
*/
|
||||
public static KeyFormat detectKeyFileFormat(Reader privateKey,
|
||||
boolean separatePubKey)
|
||||
public static KeyFormat detectKeyFileFormat(Reader privateKey, boolean separatePubKey)
|
||||
throws IOException {
|
||||
BufferedReader br = new BufferedReader(privateKey);
|
||||
final String firstLine;
|
||||
try {
|
||||
firstLine = br.readLine();
|
||||
}
|
||||
finally {
|
||||
IOUtils.closeQuietly(br);
|
||||
}
|
||||
if(firstLine == null) {
|
||||
String header = readHeader(privateKey);
|
||||
if (header == null) {
|
||||
throw new IOException("Empty file");
|
||||
}
|
||||
if(firstLine.startsWith("-----BEGIN") && firstLine.endsWith("PRIVATE KEY-----")) {
|
||||
if(separatePubKey)
|
||||
// Can delay asking for password since have unencrypted pubkey
|
||||
{
|
||||
return KeyFormat.OpenSSH;
|
||||
return keyFormatFromHeader(header, separatePubKey);
|
||||
}
|
||||
else
|
||||
|
||||
private static String readHeader(Reader privateKey) throws IOException {
|
||||
BufferedReader br = new BufferedReader(privateKey);
|
||||
try {
|
||||
String header;
|
||||
while ((header = br.readLine()) != null) {
|
||||
header = header.trim();
|
||||
if (!header.isEmpty()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return header;
|
||||
} finally {
|
||||
IOUtils.closeQuietly(br);
|
||||
}
|
||||
}
|
||||
|
||||
private static KeyFormat keyFormatFromHeader(String header, boolean separatePubKey) {
|
||||
if (header.startsWith("-----BEGIN") && header.endsWith("PRIVATE KEY-----")) {
|
||||
if (separatePubKey) {
|
||||
// Can delay asking for password since have unencrypted pubkey
|
||||
return KeyFormat.OpenSSH;
|
||||
} else {
|
||||
// More general
|
||||
{
|
||||
return KeyFormat.PKCS8;
|
||||
}
|
||||
}
|
||||
if(firstLine.startsWith("PuTTY-User-Key-File-")) {
|
||||
} else if (header.startsWith("PuTTY-User-Key-File-")) {
|
||||
return KeyFormat.PuTTY;
|
||||
}
|
||||
} else {
|
||||
return KeyFormat.Unknown;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
package net.schmizz.sshj.keyprovider;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import net.schmizz.sshj.userauth.keyprovider.KeyFormat;
|
||||
import net.schmizz.sshj.userauth.keyprovider.KeyProviderUtil;
|
||||
|
||||
public class KeyProviderUtilTest {
|
||||
|
||||
private static final File ROOT = new File("src/test/resources/keyformats");
|
||||
|
||||
@Test
|
||||
public void testOpenSsh() throws IOException {
|
||||
KeyFormat format = KeyProviderUtil.detectKeyFileFormat(new File(ROOT, "openssh"));
|
||||
assertEquals(KeyFormat.OpenSSH, format);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPkcs8() throws IOException {
|
||||
KeyFormat format = KeyProviderUtil.detectKeyFileFormat(new File(ROOT, "pkcs8"));
|
||||
assertEquals(KeyFormat.PKCS8, format);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPutty() throws IOException {
|
||||
KeyFormat format = KeyProviderUtil.detectKeyFileFormat(new File(ROOT, "putty"));
|
||||
assertEquals(KeyFormat.PuTTY, format);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSkipsBlankLines() throws IOException {
|
||||
KeyFormat format = KeyProviderUtil.detectKeyFileFormat(new File(ROOT, "pkcs8-blanks"));
|
||||
assertEquals(KeyFormat.PKCS8, format);
|
||||
}
|
||||
}
|
||||
15
src/test/resources/keyformats/openssh
Normal file
15
src/test/resources/keyformats/openssh
Normal file
@@ -0,0 +1,15 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIICXQIBAAKBgQCm2IJ9gWDkPTlQ37NNUB0za5mCsQ8bi++8fyEqw7wl8ZNBh3qt
|
||||
TcnL+m+NZfQjUC0BXic7PcMLVm4A3ID2IAZQM+axfq9aL4huWerm4ua6tvdt4gQK
|
||||
oL1+8JFmdFvFw5pWW/NZHtkIprbVf7KtYrU27WmMhXruN071UzqLsw08cwIDAQAB
|
||||
AoGAHQ7cOyuLSnT3RISRX8eyLkBxLffUX8HRcQzbI+2PGTSnpuQHk6NWn/Xv87pr
|
||||
+LKABBr3zjOFgrX81p2QwEz3jDxNXzbOeZzhuvGXCX5GocuEO4n5EhDvXRDF4uht
|
||||
uvVV5FsQv/sTOR0PNo1nELiAA8k3NYDxraB83q7wtsmErtECQQDYWMnq8mwRe49d
|
||||
jIXNKJeNiuLUYxO3CLI/vx279gDKlKrt677trr1e7JZqm/DapEWG511tw3cW63gQ
|
||||
+qxtgkw1AkEAxW0UeaNaJd7DApqwGAcS1JkygCKwzQ4ns/Co15qUgMkqCkmQU9AU
|
||||
/zQpt2+BjdYVe50r/nr8K1KYwrBsyndrBwJBALe90N+FvFqswfoFmq2/R9eimTsg
|
||||
WmIdNKYHPs2gBNQIp5MhoSpkOdkgvi8U+d33nkUQwryyQbZpjbN98mufOfECQEML
|
||||
eBiW0NZrf+4yefqu7EYmgG/jWAdK91C0OaJ+bFAQAKbdtJXB5F+GZ2RUCbsRKNqB
|
||||
1Z7mRRyxQA9dupRHWaECQQCM9bbCtfGesgvZlhBavlWavu8iCvJlAbGdf5QMlFQE
|
||||
kABmZg84Fy3NUFCD+RXCuatb4Oo9P/WPIbjYiC4p0hLJ
|
||||
-----END RSA PRIVATE KEY-----
|
||||
1
src/test/resources/keyformats/openssh.pub
Normal file
1
src/test/resources/keyformats/openssh.pub
Normal file
@@ -0,0 +1 @@
|
||||
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQCm2IJ9gWDkPTlQ37NNUB0za5mCsQ8bi++8fyEqw7wl8ZNBh3qtTcnL+m+NZfQjUC0BXic7PcMLVm4A3ID2IAZQM+axfq9aL4huWerm4ua6tvdt4gQKoL1+8JFmdFvFw5pWW/NZHtkIprbVf7KtYrU27WmMhXruN071UzqLsw08cw==
|
||||
15
src/test/resources/keyformats/pkcs8
Normal file
15
src/test/resources/keyformats/pkcs8
Normal file
@@ -0,0 +1,15 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIICXQIBAAKBgQCm2IJ9gWDkPTlQ37NNUB0za5mCsQ8bi++8fyEqw7wl8ZNBh3qt
|
||||
TcnL+m+NZfQjUC0BXic7PcMLVm4A3ID2IAZQM+axfq9aL4huWerm4ua6tvdt4gQK
|
||||
oL1+8JFmdFvFw5pWW/NZHtkIprbVf7KtYrU27WmMhXruN071UzqLsw08cwIDAQAB
|
||||
AoGAHQ7cOyuLSnT3RISRX8eyLkBxLffUX8HRcQzbI+2PGTSnpuQHk6NWn/Xv87pr
|
||||
+LKABBr3zjOFgrX81p2QwEz3jDxNXzbOeZzhuvGXCX5GocuEO4n5EhDvXRDF4uht
|
||||
uvVV5FsQv/sTOR0PNo1nELiAA8k3NYDxraB83q7wtsmErtECQQDYWMnq8mwRe49d
|
||||
jIXNKJeNiuLUYxO3CLI/vx279gDKlKrt677trr1e7JZqm/DapEWG511tw3cW63gQ
|
||||
+qxtgkw1AkEAxW0UeaNaJd7DApqwGAcS1JkygCKwzQ4ns/Co15qUgMkqCkmQU9AU
|
||||
/zQpt2+BjdYVe50r/nr8K1KYwrBsyndrBwJBALe90N+FvFqswfoFmq2/R9eimTsg
|
||||
WmIdNKYHPs2gBNQIp5MhoSpkOdkgvi8U+d33nkUQwryyQbZpjbN98mufOfECQEML
|
||||
eBiW0NZrf+4yefqu7EYmgG/jWAdK91C0OaJ+bFAQAKbdtJXB5F+GZ2RUCbsRKNqB
|
||||
1Z7mRRyxQA9dupRHWaECQQCM9bbCtfGesgvZlhBavlWavu8iCvJlAbGdf5QMlFQE
|
||||
kABmZg84Fy3NUFCD+RXCuatb4Oo9P/WPIbjYiC4p0hLJ
|
||||
-----END RSA PRIVATE KEY-----
|
||||
18
src/test/resources/keyformats/pkcs8-blanks
Normal file
18
src/test/resources/keyformats/pkcs8-blanks
Normal file
@@ -0,0 +1,18 @@
|
||||
|
||||
|
||||
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIICXQIBAAKBgQCm2IJ9gWDkPTlQ37NNUB0za5mCsQ8bi++8fyEqw7wl8ZNBh3qt
|
||||
TcnL+m+NZfQjUC0BXic7PcMLVm4A3ID2IAZQM+axfq9aL4huWerm4ua6tvdt4gQK
|
||||
oL1+8JFmdFvFw5pWW/NZHtkIprbVf7KtYrU27WmMhXruN071UzqLsw08cwIDAQAB
|
||||
AoGAHQ7cOyuLSnT3RISRX8eyLkBxLffUX8HRcQzbI+2PGTSnpuQHk6NWn/Xv87pr
|
||||
+LKABBr3zjOFgrX81p2QwEz3jDxNXzbOeZzhuvGXCX5GocuEO4n5EhDvXRDF4uht
|
||||
uvVV5FsQv/sTOR0PNo1nELiAA8k3NYDxraB83q7wtsmErtECQQDYWMnq8mwRe49d
|
||||
jIXNKJeNiuLUYxO3CLI/vx279gDKlKrt677trr1e7JZqm/DapEWG511tw3cW63gQ
|
||||
+qxtgkw1AkEAxW0UeaNaJd7DApqwGAcS1JkygCKwzQ4ns/Co15qUgMkqCkmQU9AU
|
||||
/zQpt2+BjdYVe50r/nr8K1KYwrBsyndrBwJBALe90N+FvFqswfoFmq2/R9eimTsg
|
||||
WmIdNKYHPs2gBNQIp5MhoSpkOdkgvi8U+d33nkUQwryyQbZpjbN98mufOfECQEML
|
||||
eBiW0NZrf+4yefqu7EYmgG/jWAdK91C0OaJ+bFAQAKbdtJXB5F+GZ2RUCbsRKNqB
|
||||
1Z7mRRyxQA9dupRHWaECQQCM9bbCtfGesgvZlhBavlWavu8iCvJlAbGdf5QMlFQE
|
||||
kABmZg84Fy3NUFCD+RXCuatb4Oo9P/WPIbjYiC4p0hLJ
|
||||
-----END RSA PRIVATE KEY-----
|
||||
19
src/test/resources/keyformats/putty
Normal file
19
src/test/resources/keyformats/putty
Normal file
@@ -0,0 +1,19 @@
|
||||
PuTTY-User-Key-File-2: ssh-rsa
|
||||
Encryption: none
|
||||
Comment: rsa-key-20150817
|
||||
Public-Lines: 4
|
||||
AAAAB3NzaC1yc2EAAAABJQAAAIEAhoCAakZdrCNrHNpJHRIED4movsposAlk4ZPz
|
||||
n/IFGkiIZOWRF/p4Sq+CaLigamwpe3f2/vYxCwtF3oCcJMQdn6CLYytHgrC2pRWa
|
||||
bNBBClSO4jzWMlBRBZnzXBHKJ04kviqIybEvrN2weg5ArSOK7297DU2id+kDxSJz
|
||||
QleZ+9c=
|
||||
Private-Lines: 8
|
||||
AAAAgBItCm858PuWFWTDjVb0mMPUVRLdFRDerMSJnXZ6pr5c1ClPdHjcqHjLnABQ
|
||||
TQd2Znh3/siCIk2ZvVVrU17qEdcZyivntbi8NuehqcVQr2ny8pc+sXvxXv2inoA3
|
||||
4mIVqjhIoljYf1VWgDXUxUsGU6QZdMfkDCEuoxL9QM7RdFXNAAAAQQDk01miHj3M
|
||||
LozpMovCU2oKDFLsmOrXe7jroff2sM4BX5Iwym4N197O7ZIs5E52K0bWIDH9SouX
|
||||
RTseqiHsPxexAAAAQQCWeZFwG7qm8cyAGSzsDsN35cmzgkvlFl4uIuJ9jh0S2Yt5
|
||||
2couD/AoQVmHqGaxwYPc+q24yvbFbjCxtlkqMTYHAAAAQQCcpItltKrhNW2svG2P
|
||||
NuOi0TQmMZQigMOYQx4wd/8G2n+nr0Qsi4wuq/qccgKViVRyobB7nxQqoJdGAI90
|
||||
ECNG
|
||||
Private-MAC: 4f200e5f5b766351b996d92f3b733b671b9ff957
|
||||
|
||||
Reference in New Issue
Block a user