mirror of
https://github.com/hierynomus/sshj.git
synced 2025-12-06 23:30:55 +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
|
* @return name of the key file format
|
||||||
* @throws java.io.IOException
|
* @throws java.io.IOException
|
||||||
*/
|
*/
|
||||||
public static KeyFormat detectKeyFileFormat(String privateKey,
|
public static KeyFormat detectKeyFileFormat(String privateKey, boolean separatePubKey)
|
||||||
boolean separatePubKey)
|
|
||||||
throws IOException {
|
throws IOException {
|
||||||
return detectKeyFileFormat(new StringReader(privateKey), separatePubKey);
|
return detectKeyFileFormat(new StringReader(privateKey), separatePubKey);
|
||||||
}
|
}
|
||||||
@@ -67,35 +66,44 @@ public class KeyProviderUtil {
|
|||||||
* @return name of the key file format
|
* @return name of the key file format
|
||||||
* @throws java.io.IOException
|
* @throws java.io.IOException
|
||||||
*/
|
*/
|
||||||
public static KeyFormat detectKeyFileFormat(Reader privateKey,
|
public static KeyFormat detectKeyFileFormat(Reader privateKey, boolean separatePubKey)
|
||||||
boolean separatePubKey)
|
|
||||||
throws IOException {
|
throws IOException {
|
||||||
BufferedReader br = new BufferedReader(privateKey);
|
String header = readHeader(privateKey);
|
||||||
final String firstLine;
|
if (header == null) {
|
||||||
try {
|
|
||||||
firstLine = br.readLine();
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
IOUtils.closeQuietly(br);
|
|
||||||
}
|
|
||||||
if(firstLine == null) {
|
|
||||||
throw new IOException("Empty file");
|
throw new IOException("Empty file");
|
||||||
}
|
}
|
||||||
if(firstLine.startsWith("-----BEGIN") && firstLine.endsWith("PRIVATE KEY-----")) {
|
return keyFormatFromHeader(header, separatePubKey);
|
||||||
if(separatePubKey)
|
|
||||||
// Can delay asking for password since have unencrypted pubkey
|
|
||||||
{
|
|
||||||
return KeyFormat.OpenSSH;
|
|
||||||
}
|
}
|
||||||
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
|
// More general
|
||||||
{
|
|
||||||
return KeyFormat.PKCS8;
|
return KeyFormat.PKCS8;
|
||||||
}
|
}
|
||||||
}
|
} else if (header.startsWith("PuTTY-User-Key-File-")) {
|
||||||
if(firstLine.startsWith("PuTTY-User-Key-File-")) {
|
|
||||||
return KeyFormat.PuTTY;
|
return KeyFormat.PuTTY;
|
||||||
}
|
} else {
|
||||||
return KeyFormat.Unknown;
|
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