package com.trilead.ssh2;
import com.trilead.ssh2.signature.DSAKeyAlgorithm;
import com.trilead.ssh2.signature.ECDSAKeyAlgorithm;
import com.trilead.ssh2.signature.RSAKeyAlgorithm;
import org.junit.Test;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.interfaces.DSAPublicKey;
import java.security.interfaces.ECPublicKey;
import java.security.interfaces.RSAPublicKey;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
/**
* @author Michael Clarke
*/
public class KnownHostsTest {
@Test
public void testKnownHostsPreferredAlgorithmsSshDssOnly() throws IOException, NoSuchAlgorithmException {
KnownHosts testCase = new KnownHosts();
KeyPairGenerator dsaGenerator = KeyPairGenerator.getInstance("DSA");
testCase.addHostkey(new String[]{"localhost"}, "ssh-dss", new DSAKeyAlgorithm().encodePublicKey((DSAPublicKey) dsaGenerator.generateKeyPair().getPublic()));
assertArrayEquals(new String[]{"ssh-dss", "ssh-ed25519", "ecdsa-sha2-nistp521", "ecdsa-sha2-nistp384", "ecdsa-sha2-nistp256", "ssh-rsa"}, testCase.getPreferredServerHostkeyAlgorithmOrder("localhost"));
}
@Test
public void testKnownHostsPreferredAlgorithmsSshRsaOnly() throws IOException, NoSuchAlgorithmException {
KnownHosts testCase = new KnownHosts();
KeyPairGenerator rsaGenerator = KeyPairGenerator.getInstance("RSA");
testCase.addHostkey(new String[]{"localhost"}, "ssh-rsa", new RSAKeyAlgorithm().encodePublicKey((RSAPublicKey) rsaGenerator.generateKeyPair().getPublic()));
assertArrayEquals(new String[]{"ssh-rsa", "ssh-ed25519", "ecdsa-sha2-nistp521", "ecdsa-sha2-nistp384", "ecdsa-sha2-nistp256", "ssh-dss"}, testCase.getPreferredServerHostkeyAlgorithmOrder("localhost"));
}
@Test
public void testKnownHostsPreferredAlgorithmsEcdsaOnly() throws IOException, NoSuchAlgorithmException {
KnownHosts testCase = new KnownHosts();
KeyPairGenerator ecGenerator = KeyPairGenerator.getInstance("EC");
testCase.addHostkey(new String[]{"localhost"}, "ecdsa-sha2-nistp256", new ECDSAKeyAlgorithm.ECDSASha2Nistp256().encodePublicKey((ECPublicKey) ecGenerator.generateKeyPair().getPublic()));
assertArrayEquals(new String[]{"ecdsa-sha2-nistp256", "ssh-ed25519", "ecdsa-sha2-nistp521", "ecdsa-sha2-nistp384", "ssh-rsa", "ssh-dss"}, testCase.getPreferredServerHostkeyAlgorithmOrder("localhost"));
}
@Test
public void testKnownHostsPreferredAlgorithmsNoKnownHosts() throws IOException {
KnownHosts testCase = new KnownHosts();
assertNull(testCase.getPreferredServerHostkeyAlgorithmOrder("localhost"));
}
/**
* The Known Hosts implementation currently expects multiple known hosts entries for the same hosts to result in
* a null value being returned for the preferred algorithms, rather than a list of all those known algorithms. This
* seems an odd choice, but I'll protect that feature for now.
* @throws IOException if failing to add the test keys
*/
@Test
public void testKnownHostsPreferredAlgorithmsRsaAndDssHosts() throws IOException, GeneralSecurityException {
KnownHosts testCase = new KnownHosts();
KeyPairGenerator dsaGenerator = KeyPairGenerator.getInstance("DSA");
testCase.addHostkey(new String[]{"localhost"}, "ssh-dss", new DSAKeyAlgorithm().encodePublicKey((DSAPublicKey) dsaGenerator.generateKeyPair().getPublic()));
KeyPairGenerator rsaGenerator = KeyPairGenerator.getInstance("RSA");
testCase.addHostkey(new String[]{"localhost"}, "ssh-rsa", new RSAKeyAlgorithm().encodePublicKey((RSAPublicKey) rsaGenerator.generateKeyPair().getPublic()));
assertNull(testCase.getPreferredServerHostkeyAlgorithmOrder("localhost"));
}
@Test
public void testVerifyKnownHostKey() throws IOException, NoSuchAlgorithmException {
KnownHosts testCase = new KnownHosts();
KeyPairGenerator rsaGenerator = KeyPairGenerator.getInstance("RSA");
byte[] encodedPublicKey = new RSAKeyAlgorithm().encodePublicKey((RSAPublicKey) rsaGenerator.generateKeyPair().getPublic());
byte[] encodedPublicKey2 = new RSAKeyAlgorithm().encodePublicKey((RSAPublicKey) rsaGenerator.generateKeyPair().getPublic());
testCase.addHostkey(new String[]{"testhost"}, "ssh-rsa", encodedPublicKey);
assertEquals(KnownHosts.HOSTKEY_IS_NEW, testCase.verifyHostkey("testhost2", "ssh-rsa", encodedPublicKey));
assertEquals(KnownHosts.HOSTKEY_HAS_CHANGED, testCase.verifyHostkey("testhost", "ssh-rsa", encodedPublicKey2));
assertEquals(KnownHosts.HOSTKEY_IS_OK, testCase.verifyHostkey("testhost", "ssh-rsa", encodedPublicKey));
}
}