package com.trilead.ssh2.signature;
import com.trilead.ssh2.crypto.PEMDecoder;
import org.apache.commons.io.IOUtils;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.GeneralSecurityException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.SecureRandom;
import java.security.interfaces.ECPrivateKey;
import java.security.interfaces.ECPublicKey;
import java.util.Arrays;
import java.util.Collection;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
/**
* @author Michael Clarke
*/
@RunWith(Parameterized.class)
public class ECDSAKeyAlgorithmTest {
private final ECDSAKeyAlgorithm testCase;
public ECDSAKeyAlgorithmTest(ECDSAKeyAlgorithm testCase) {
super();
this.testCase = testCase;
}
@Parameterized.Parameters
public static Collection<ECDSAKeyAlgorithm[]> getAlgorithms() {
return Arrays.asList(new ECDSAKeyAlgorithm[]{new ECDSAKeyAlgorithm.ECDSASha2Nistp256()},
new ECDSAKeyAlgorithm[]{new ECDSAKeyAlgorithm.ECDSASha2Nistp384()},
new ECDSAKeyAlgorithm[]{new ECDSAKeyAlgorithm.ECDSASha2Nistp521()});
}
@Test
public void testEncodeDecodePublicKey() throws GeneralSecurityException, IOException {
KeyPairGenerator factory = KeyPairGenerator.getInstance("EC");
factory.initialize(testCase.getEcParameterSpec().getCurve().getField().getFieldSize());
ECPublicKey publicKey = (ECPublicKey) factory.generateKeyPair().getPublic();
byte[] encoded = testCase.encodePublicKey(publicKey);
ECPublicKey decoded = testCase.decodePublicKey(encoded);
assertEquals(publicKey, decoded);
}
@Test
public void testEncodeDecodeSignature() throws GeneralSecurityException, IOException {
KeyPairGenerator factory = KeyPairGenerator.getInstance("EC");
factory.initialize(testCase.getEcParameterSpec().getCurve().getField().getFieldSize());
ECPrivateKey privateKey = (ECPrivateKey) factory.generateKeyPair().getPrivate();
byte[] signature = testCase.generateSignature("Sign Me".getBytes(StandardCharsets.UTF_8), privateKey, new SecureRandom());
byte[] encoded = testCase.encodeSignature(signature);
byte[] decoded = testCase.decodeSignature(encoded);
assertArrayEquals(signature, decoded);
}
@Test
public void testSignAndVerify() throws GeneralSecurityException, IOException {
byte[] message = "Signature Test".getBytes(StandardCharsets.UTF_8);
KeyPairGenerator factory = KeyPairGenerator.getInstance("EC");
KeyPair keyPair = factory.generateKeyPair();
ECPrivateKey privateKey = (ECPrivateKey) keyPair.getPrivate();
ECPublicKey publicKey = (ECPublicKey) keyPair.getPublic();
byte[] signature = testCase.generateSignature(message, privateKey, new SecureRandom());
assertTrue(testCase.verifySignature(message, signature, publicKey));
}
@Test
public void testSignAndVerifyFailure() throws GeneralSecurityException, IOException {
byte[] message = "Signature Test 2".getBytes(StandardCharsets.UTF_8);
KeyPairGenerator factory = KeyPairGenerator.getInstance("EC");
factory.initialize(testCase.getEcParameterSpec().getCurve().getField().getFieldSize());
KeyPair keyPair = factory.generateKeyPair();
ECPrivateKey privateKey = (ECPrivateKey) keyPair.getPrivate();
ECPublicKey publicKey = (ECPublicKey) keyPair.getPublic();
byte[] signature = testCase.generateSignature("Other Message".getBytes(StandardCharsets.UTF_8), privateKey, new SecureRandom());
assertFalse(testCase.verifySignature(message, signature, publicKey));
}
@Test
public void testParsePrivateKey() throws IOException {
KeyPair oldFormat = PEMDecoder.decodeKeyPair(IOUtils.toCharArray(getClass().getResourceAsStream(testCase.getKeyFormat() + "-testkey-unprotected.txt")), null);
KeyPair newFormat = PEMDecoder.decodeKeyPair(IOUtils.toCharArray(getClass().getResourceAsStream(testCase.getKeyFormat() + "-testkey-unprotected-newformat.txt")), null);
assertEquals(oldFormat.getPublic(), newFormat.getPublic());
assertEquals(oldFormat.getPrivate(), newFormat.getPrivate());
}
}