blob: 67dab34ef877c52d43903b4827dd630f5d174fb7 [file] [log] [blame]
package org.apache.harmony.security.tests.java.security;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetClass;
import dalvik.annotation.TestTargetNew;
import junit.framework.TestCase;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyFactorySpi;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PrivateKey;
import java.security.Provider;
import java.security.PublicKey;
import java.security.Security;
import java.security.spec.DSAPublicKeySpec;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import java.util.Arrays;
@TestTargetClass(KeyFactory.class)
public class KeyFactoryTest extends TestCase {
Provider provider;
boolean exceptionThrown;
Provider existingProvider;
@Override
protected void setUp() throws Exception {
super.setUp();
exceptionThrown = false;
Provider[] providers = Security.getProviders();
if (providers.length == 0) {
fail("no providers found");
}
existingProvider = providers[0];
provider = new TestKeyFactoryProvider();
Security.addProvider(provider);
}
@Override
protected void tearDown() throws Exception {
super.tearDown();
Security.removeProvider(provider.getName());
}
@SuppressWarnings("unchecked")
@TestTargetNew(
level=TestLevel.COMPLETE,
method="getInstance",
args={String.class}
)
public void testGetInstanceString() {
try {
KeyFactory factory = KeyFactory.getInstance(TEST_KEYFACTORY_NAME);
assertNotNull(factory);
} catch (NoSuchAlgorithmException e) {
fail("unexpected exception: " + e);
}
String[] parameters = {
"UnknownKeyFactory",
null
};
Class[] exceptions = {
NoSuchAlgorithmException.class,
NullPointerException.class
};
for (int i = 0; i < parameters.length; i++) {
String algorithm = parameters[i];
exceptionThrown = false;
String message = "getInstance(" + (algorithm == null ? "null" : "\"" + algorithm + "\"") + ")";
try {
KeyFactory.getInstance(algorithm);
} catch (Exception e) {
checkException(message, e, exceptions[i]);
} finally {
checkException(message, null, exceptions[i]);
}
}
}
@SuppressWarnings("unchecked")
@TestTargetNew(
level=TestLevel.COMPLETE,
method="getInstance",
args={String.class, String.class}
)
public void testGetInstanceStringString() {
try {
KeyFactory factory = KeyFactory.getInstance(TEST_KEYFACTORY_NAME, TEST_PROVIDER_NAME);
assertNotNull(factory);
} catch (NoSuchAlgorithmException e) {
fail("unexpected exception: " + e);
} catch (NoSuchProviderException e) {
fail("unexpected exception: " + e);
}
String[][] combinations = {
{ "UnknownKeyFactory", TEST_PROVIDER_NAME},
{ TEST_KEYFACTORY_NAME, "UnknownProvider"},
{ TEST_KEYFACTORY_NAME, existingProvider.getName() },
{ null, TEST_PROVIDER_NAME },
{ TEST_KEYFACTORY_NAME, null },
{ null, null}
};
Class[] exceptions = {
NoSuchAlgorithmException.class,
NoSuchProviderException.class,
NoSuchAlgorithmException.class,
NullPointerException.class,
IllegalArgumentException.class,
IllegalArgumentException.class
};
for (int i = 0; i < combinations.length; i++) {
String[] combination = combinations[i];
String message = "getInstance(\"" + combination[0] + "\", \"" + combination[1] + "\")";
exceptionThrown = false;
try {
KeyFactory.getInstance(combination[0], combination[1]);
} catch (Exception e) {
checkException(message, e, exceptions[i]);
} finally {
checkException(message, null, exceptions[i]);
}
}
}
@SuppressWarnings("unchecked")
@TestTargetNew(
level=TestLevel.COMPLETE,
method="getInstance",
args={String.class, Provider.class}
)
public void testGetInstanceStringProvider() {
try {
KeyFactory factory = KeyFactory.getInstance(TEST_KEYFACTORY_NAME, provider);
assertNotNull(factory);
} catch (NoSuchAlgorithmException e) {
fail("unexpected exception: " + e);
}
String[] algorithms = {
"UnknownKeyFactory",
null,
TEST_KEYFACTORY_NAME,
TEST_KEYFACTORY_NAME
};
Provider[] providers = {
provider,
provider,
existingProvider,
null
};
Class[] exceptions = {
NoSuchAlgorithmException.class,
NullPointerException.class,
NoSuchAlgorithmException.class,
IllegalArgumentException.class
};
for (int i = 0; i < algorithms.length; i++) {
String algorithm = algorithms[i];
Provider provider = providers[i];
String message = "getInstance(" +
(algorithm == null ? "null" : "\"" + algorithm + "\"") +
", " +
(provider == null ? "null" : "provider");
exceptionThrown = false;
try {
KeyFactory.getInstance(algorithm, provider);
} catch (Exception e) {
checkException(message, e, exceptions[i]);
} finally {
checkException(message, null, exceptions[i]);
}
}
}
@SuppressWarnings("unchecked")
@TestTargetNew(
level=TestLevel.COMPLETE,
method="generatePublic",
args={KeySpec.class}
)
public void testGeneratePublic() {
KeyFactory factory = null;
try {
factory = KeyFactory.getInstance(TEST_KEYFACTORY_NAME);
} catch (NoSuchAlgorithmException e) {
fail("unexpected exception: " + e);
}
assertNotNull(factory);
try {
TestPublicKey key = new TestPublicKey();
TestPublicKeySpec keySpec = new TestPublicKeySpec(key);
PublicKey publicKey = factory.generatePublic(keySpec);
assertNotNull(publicKey);
assertTrue(Arrays.equals(key.encoded, publicKey.getEncoded()));
} catch (InvalidKeySpecException e) {
fail("unexpected exception: " + e);
}
KeySpec[] keySpecs = {
new TestPrivateKeySpec(new TestPrivateKey()),
null,
new DSAPublicKeySpec(null, null, null, null)
};
Class[] exceptions = {
InvalidKeySpecException.class,
NullPointerException.class,
InvalidKeySpecException.class
};
for (int i = 0; i < keySpecs.length; i++) {
KeySpec keySpec = keySpecs[i];
String message = "generatePublic(" +
(keySpec == null ? "null" : keySpec.toString()) + ")";
try {
PublicKey generatePublic = factory.generatePublic(keySpec);
assertNotNull(generatePublic);
} catch (Exception e) {
checkException(message, e, exceptions[i]);
} finally {
checkException(message, null, exceptions[i]);
}
}
}
@SuppressWarnings("unchecked")
@TestTargetNew(
level=TestLevel.COMPLETE,
method="generatePrivate",
args={KeySpec.class}
)
public void testGeneratePrivate() {
KeyFactory factory = null;
try {
factory = KeyFactory.getInstance(TEST_KEYFACTORY_NAME);
} catch (NoSuchAlgorithmException e) {
fail("unexpected exception: " + e);
}
assertNotNull(factory);
try {
TestPrivateKey key = new TestPrivateKey();
TestPrivateKeySpec keySpec = new TestPrivateKeySpec(key);
PrivateKey privateKey = factory.generatePrivate(keySpec);
assertNotNull(privateKey);
assertTrue(Arrays.equals(key.getEncoded(), privateKey.getEncoded()));
} catch (InvalidKeySpecException e) {
fail("unexpected exception: " + e);
}
KeySpec[] keySpecs = {
new TestPublicKeySpec(new TestPublicKey()),
null,
new DSAPublicKeySpec(null, null, null, null)
};
Class[] exceptions = {
InvalidKeySpecException.class,
NullPointerException.class,
InvalidKeySpecException.class
};
for (int i = 0; i < keySpecs.length; i++) {
KeySpec keySpec = keySpecs[i];
exceptionThrown = false;
String message = "generatePrivate(" +
(keySpec == null ? "null" : keySpec.toString()) + ")";
try {
factory.generatePrivate(keySpec);
} catch (Exception e) {
checkException(message, e, exceptions[i]);
} finally {
checkException(message, null, exceptions[i]);
}
}
}
@SuppressWarnings("unchecked")
@TestTargetNew(
level=TestLevel.COMPLETE,
method="getKeySpec",
args={Key.class, Class.class}
)
public void testGetKeySpec() {
KeyFactory factory = null;
try {
factory = KeyFactory.getInstance(TEST_KEYFACTORY_NAME);
} catch (NoSuchAlgorithmException e) {
fail("unexpected exception: " + e);
}
assertNotNull(factory);
{
Key[] keys = {
new TestPrivateKey(),
new TestPublicKey(),
new TestPrivateKey(new byte[] { 42, 41, 40 }),
new TestPublicKey(new byte[] { 40, 41, 42 })
};
Class[] keySpecs = {
TestPrivateKeySpec.class,
TestPublicKeySpec.class,
TestPrivateKeySpec.class,
TestPublicKeySpec.class,
};
for (int i = 0; i < keys.length; i++) {
Key key = keys[i];
Class keySpec = keySpecs[i];
String message = "getKeySpec(" + key.toString() + ", " + keySpec.toString() + ")";
try {
KeySpec spec = factory.getKeySpec(key, keySpec);
assertNotNull(spec);
assertTrue(spec.getClass() == keySpec);
} catch (InvalidKeySpecException e) {
fail("unexpected exception: " + e);
}
}
}
{
Key[] keys = {
new AnotherKey(),
null,
new TestPrivateKey(),
null,
};
Class[] keySpecs = {
KeySpec.class,
TestPrivateKeySpec.class,
null,
null,
};
Class[] exceptions = {
InvalidKeySpecException.class,
NullPointerException.class,
InvalidKeySpecException.class,
NullPointerException.class
};
for (int i = 0; i < keys.length; i++) {
Key key = keys[i];
Class keySpec = keySpecs[i];
exceptionThrown = false;
String message = "getKeySpec(" +
(key == null ? "null" : key.toString()) +
", " +
(keySpec == null ? "null" : keySpec.toString()) + ")";
try {
factory.getKeySpec(key, keySpec);
} catch (Exception e) {
checkException(message, e, exceptions[i]);
} finally {
checkException(message, null, exceptions[i]);
}
}
}
}
@SuppressWarnings("unchecked")
@TestTargetNew(
level=TestLevel.COMPLETE,
method="translateKey",
args={Key.class}
)
public void testTranslateKey() {
KeyFactory factory = null;
try {
factory = KeyFactory.getInstance(TEST_KEYFACTORY_NAME);
} catch (NoSuchAlgorithmException e) {
fail("unexpected exception: " + e);
}
assertNotNull(factory);
{
Key[] keys = {
new TestPrivateKey(),
new TestPublicKey()
};
Class[] translated = {
TestPublicKey.class,
TestPrivateKey.class
};
for (int i = 0; i < keys.length; i++) {
Key key = keys[i];
Class translate = translated[i];
try {
Key translateKey = factory.translateKey(key);
assertNotNull(translateKey);
assertEquals(translate, translateKey.getClass());
} catch (InvalidKeyException e) {
fail("unexpected exception: " + e);
}
}
}
{
Key[] keys = {
new AnotherKey(),
null
};
Class[] exceptions = {
InvalidKeyException.class,
NullPointerException.class
};
for (int i = 0; i < keys.length; i++) {
Key key = keys[i];
String message = "translateKey(" +
(key == null ? "null" : key.toString()) + ")";
exceptionThrown = false;
try {
factory.translateKey(key);
} catch (Exception e) {
checkException(message, e, exceptions[i]);
} finally {
checkException(message, null, exceptions[i]);
}
}
}
}
private static final String TEST_PROVIDER_NAME = "TestKeyFactoryProvider";
private static final String TEST_KEYFACTORY_NAME = "TestKeyFactory";
static class TestKeyFactoryProvider extends Provider {
protected TestKeyFactoryProvider() {
super(TEST_PROVIDER_NAME, 1.1, "Test KeyFactory Provider");
put("KeyFactory." + TEST_KEYFACTORY_NAME, TestKeyFactorySpi.class.getName());
}
}
public static class TestKeyFactorySpi extends KeyFactorySpi {
@Override
protected PrivateKey engineGeneratePrivate(KeySpec keySpec)
throws InvalidKeySpecException {
if (TestPrivateKeySpec.class == keySpec.getClass()) {
return new TestPrivateKey(((TestPrivateKeySpec)keySpec).encoded);
}
throw new InvalidKeySpecException();
}
@Override
protected PublicKey engineGeneratePublic(KeySpec keySpec)
throws InvalidKeySpecException {
if (TestPublicKeySpec.class == keySpec.getClass()) {
return new TestPublicKey(((TestPublicKeySpec)keySpec).encoded);
}
throw new InvalidKeySpecException();
}
@Override
protected <T extends KeySpec> T engineGetKeySpec(Key key,
Class<T> keySpec) throws InvalidKeySpecException {
if (key == null) {
throw new NullPointerException();
}
Constructor<T> constructor = null;
if (TestPrivateKeySpec.class == keySpec) {
try {
constructor = keySpec.getConstructor(TestPrivateKey.class);
} catch (SecurityException e) {
throw new InvalidKeySpecException(e);
} catch (NoSuchMethodException e) {
throw new InvalidKeySpecException(e);
}
} else if (TestPublicKeySpec.class == keySpec) {
try {
constructor = keySpec.getConstructor(TestPublicKey.class);
} catch (SecurityException e) {
throw new InvalidKeySpecException(e);
} catch (NoSuchMethodException e) {
throw new InvalidKeySpecException(e);
}
}
if (constructor == null) {
throw new InvalidKeySpecException();
}
try {
return constructor.newInstance(key);
} catch (IllegalArgumentException e) {
throw new InvalidKeySpecException(e);
} catch (InstantiationException e) {
throw new InvalidKeySpecException(e);
} catch (IllegalAccessException e) {
throw new InvalidKeySpecException(e);
} catch (InvocationTargetException e) {
throw new InvalidKeySpecException(e);
}
}
@Override
protected Key engineTranslateKey(Key key) throws InvalidKeyException {
if (TestPrivateKey.class == key.getClass()) {
return new TestPublicKey();
} else if (TestPublicKey.class == key.getClass()) {
return new TestPrivateKey();
}
throw new InvalidKeyException();
}
}
static class TestPrivateKeySpec implements KeySpec {
@SuppressWarnings("unused")
private final byte[] encoded;
public TestPrivateKeySpec(TestPrivateKey key) {
this.encoded = key.getEncoded();
}
}
static class TestPublicKeySpec implements KeySpec {
@SuppressWarnings("unused")
private final byte[] encoded;
public TestPublicKeySpec(TestPublicKey key) {
this.encoded = key.getEncoded();
}
}
static class TestPrivateKey implements PrivateKey {
private final byte[] encoded;
public TestPrivateKey() {
encoded = new byte[] {3, 4, 5};
}
public TestPrivateKey(byte[] encoded) {
this.encoded = encoded;
}
public String getAlgorithm() {
return "TestPrivateKey";
}
public byte[] getEncoded() {
return encoded;
}
public String getFormat() {
return "TestFormat";
}
}
static class TestPublicKey implements PublicKey {
private final byte[] encoded;
public TestPublicKey() {
encoded = new byte[] {3, 4, 5};
}
public TestPublicKey(byte[] encoded) {
this.encoded = encoded;
}
public String getAlgorithm() {
return "TestPublicKey";
}
public byte[] getEncoded() {
return encoded;
}
public String getFormat() {
return "TestFormat";
}
}
static class AnotherKey implements Key {
public String getAlgorithm() {
return "AnotherKey";
}
public byte[] getEncoded() {
return null;
}
public String getFormat() {
return "AnotherFormat";
}
}
private void checkException(String message, Exception thrown, Class<? extends Exception> expected) {
if (thrown == null) {
if (!exceptionThrown) {
fail(message + ", expected " + expected.getName());
}
} else if (expected == thrown.getClass()) {
exceptionThrown = true;
// ok
} else {
exceptionThrown = true;
fail(message + ", unexpected exception: " + thrown + ", expected: " + expected.getName());
}
}
}