package org.limewire.security; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.Signature; import java.security.SignatureException; import java.util.Random; import junit.framework.Test; import org.limewire.security.SecureMessage.Status; import org.limewire.util.BaseTestCase; public class SecureMessageVerifierTest extends BaseTestCase { private static PublicKey PUBLIC_KEY; private static PrivateKey PRIVATE_KEY; public SecureMessageVerifierTest(String name) { super(name); } public static Test suite() { return buildTestSuite(SecureMessageVerifierTest.class); } public static void main(String argv[]) { junit.textui.TestRunner.run(suite()); } /** gen some fake private/public keys so we can create messages easily. */ public static void globalSetUp() throws Exception { KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DSA"); SecureRandom random = SecureRandom.getInstance("SHA1PRNG", "SUN"); keyGen.initialize(512, random); KeyPair pair = keyGen.generateKeyPair(); PUBLIC_KEY = pair.getPublic(); PRIVATE_KEY = pair.getPrivate(); } /** Tests a secure message we create ourselves. */ public void testSecuring() throws Exception { SecureMessage m1 = new StubSecureMessage(); SecureMessageVerifier vf = new SimpleVerifier(); StubSecureMessageCallback cb = new StubSecureMessageCallback(); vf.verify(m1, cb); cb.waitForReply(); assertEquals(m1, cb.getSecureMessage()); assertEquals(true, cb.getPassed()); assertEquals(Status.SECURE, m1.getSecureStatus()); } /** Tests a bad message doesn't secure. */ public void testFails() throws Exception { SecureMessage m1 = new StubSecureMessage() { @Override public void updateSignatureWithSecuredBytes(Signature signature) throws SignatureException { super.updateSignatureWithSecuredBytes(signature); signature.update(new byte[100]); } }; SecureMessageVerifier vf = new SimpleVerifier(); StubSecureMessageCallback cb = new StubSecureMessageCallback(); vf.verify(m1, cb); cb.waitForReply(); assertEquals(m1, cb.getSecureMessage()); assertEquals(false, cb.getPassed()); assertEquals(Status.FAILED, m1.getSecureStatus()); } /** Tests a message with no signature. */ public void testNoSignature() throws Exception { SecureMessage m1 = new SecureMessageAdapter(); SecureMessageVerifier vf = new SimpleVerifier(); StubSecureMessageCallback cb = new StubSecureMessageCallback(); vf.verify(m1, cb); cb.waitForReply(); assertEquals(m1, cb.getSecureMessage()); assertEquals(false, cb.getPassed()); assertEquals(Status.INSECURE, m1.getSecureStatus()); } /** Tests attempting to secure with no public key. */ public void testNoPublicKey() throws Exception { SecureMessage m1 = new StubSecureMessage(); SecureMessageVerifier vf = new SecureMessageVerifierImpl("","") { @Override protected PublicKey createPublicKey() { return null; } }; StubSecureMessageCallback cb = new StubSecureMessageCallback(); vf.verify(m1, cb); cb.waitForReply(); assertEquals(m1, cb.getSecureMessage()); assertEquals(false, cb.getPassed()); assertEquals(Status.INSECURE, m1.getSecureStatus()); } /** Tests attempting to secure with a different signature. */ public void testWrongSignature() throws Exception { SecureMessage m1 = new StubSecureMessage() { @Override public byte[] getSecureSignature() { byte[] sig = super.getSecureSignature(); sig[0]++; return sig; } }; SecureMessageVerifier vf = new SimpleVerifier(); StubSecureMessageCallback cb = new StubSecureMessageCallback(); vf.verify(m1, cb); cb.waitForReply(); assertEquals(m1, cb.getSecureMessage()); assertEquals(false, cb.getPassed()); assertEquals(Status.FAILED, m1.getSecureStatus()); } /** Verifier that'll use our fake public key. */ private static class SimpleVerifier extends SecureMessageVerifierImpl { SimpleVerifier() { super(PUBLIC_KEY, "Simple Verifier"); } } /** Simple SecureMessage. */ private static class StubSecureMessage extends SecureMessageAdapter { private byte[] data; private static Random random = new Random(); private byte[] signature; StubSecureMessage() throws Exception { data = new byte[1024]; random.nextBytes(data); Signature sig = Signature.getInstance("SHA1withDSA"); sig.initSign(PRIVATE_KEY); sig.update(data); signature = sig.sign(); } @Override public byte[] getSecureSignature() { return signature; } @Override public void updateSignatureWithSecuredBytes(Signature signature) throws SignatureException { signature.update(data); } } /** An Adapter so we can do different stuff easily if we want. */ private static class SecureMessageAdapter implements SecureMessage { private Status secureStatus = null; public byte[] getSecureSignature() { return null; } public Status getSecureStatus() { return secureStatus; } public void setSecureStatus(Status secureStatus) { this.secureStatus = secureStatus; } public void updateSignatureWithSecuredBytes(Signature signature) throws SignatureException { } } }