package co.codewizards.cloudstore.core.auth;
import static java.lang.System.*;
import static org.assertj.core.api.Assertions.*;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import co.codewizards.cloudstore.core.auth.AuthToken;
import co.codewizards.cloudstore.core.auth.AuthTokenIO;
import co.codewizards.cloudstore.core.auth.AuthTokenSigner;
import co.codewizards.cloudstore.core.auth.AuthTokenVerifier;
import co.codewizards.cloudstore.core.auth.SignatureException;
import co.codewizards.cloudstore.core.auth.SignedAuthToken;
public class AuthTokenSignAndVerifyTest {
private static SecureRandom random = new SecureRandom();
private static final Logger logger = LoggerFactory.getLogger(AuthTokenSignAndVerifyTest.class);
{
logger.debug("[{}]<init>", Integer.toHexString(identityHashCode(this)));
}
@Test
public void signAndVerifyWithValidPublicKey() throws Exception {
logger.debug("[{}]signAndVerifyWithValidPublicKey: entered.", Integer.toHexString(identityHashCode(this)));
final AuthToken authToken = AuthTokenIOTest.createAuthToken();
final byte[] authTokenData = new AuthTokenIO().serialise(authToken);
final KeyPair keyPair = createKeyPair();
final SignedAuthToken signedAuthToken = new AuthTokenSigner(keyPair.getPrivate().getEncoded()).sign(authTokenData);
assertThat(signedAuthToken).isNotNull();
assertThat(signedAuthToken.getAuthTokenData()).isNotNull();
assertThat(signedAuthToken.getSignature()).isNotNull();
final AuthTokenVerifier verifier = new AuthTokenVerifier(keyPair.getPublic().getEncoded());
verifier.verify(signedAuthToken);
}
@Test(expected=SignatureException.class)
public void signAndVerifyWithDifferentPublicKey() throws Exception {
logger.debug("[{}]signAndVerifyWithDifferentPublicKey: entered.", Integer.toHexString(identityHashCode(this)));
final AuthToken authToken = AuthTokenIOTest.createAuthToken();
final byte[] authTokenData = new AuthTokenIO().serialise(authToken);
final KeyPair keyPair = createKeyPair();
final KeyPair keyPair2 = createKeyPair();
final SignedAuthToken signedAuthToken = new AuthTokenSigner(keyPair.getPrivate().getEncoded()).sign(authTokenData);
assertThat(signedAuthToken).isNotNull();
assertThat(signedAuthToken.getAuthTokenData()).isNotNull();
assertThat(signedAuthToken.getSignature()).isNotNull();
final AuthTokenVerifier verifier = new AuthTokenVerifier(keyPair2.getPublic().getEncoded());
verifier.verify(signedAuthToken);
}
@Test(expected=SignatureException.class)
public void signAndVerifyCorruptData() throws Exception {
logger.debug("[{}]signAndVerifyCorruptData: entered.", Integer.toHexString(identityHashCode(this)));
final AuthToken authToken = AuthTokenIOTest.createAuthToken();
final byte[] authTokenData = new AuthTokenIO().serialise(authToken);
final KeyPair keyPair = createKeyPair();
final SignedAuthToken signedAuthToken = new AuthTokenSigner(keyPair.getPrivate().getEncoded()).sign(authTokenData);
assertThat(signedAuthToken).isNotNull();
assertThat(signedAuthToken.getAuthTokenData()).isNotNull();
assertThat(signedAuthToken.getSignature()).isNotNull();
final int index = random.nextInt(signedAuthToken.getAuthTokenData().length);
final byte oldValue = signedAuthToken.getAuthTokenData()[index];
do {
signedAuthToken.getAuthTokenData()[index] = (byte) random.nextInt();
} while (oldValue == signedAuthToken.getAuthTokenData()[index]);
final AuthTokenVerifier verifier = new AuthTokenVerifier(keyPair.getPublic().getEncoded());
verifier.verify(signedAuthToken);
}
private KeyPair createKeyPair() throws NoSuchAlgorithmException {
final KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
// keyGen.initialize(4096, random);
keyGen.initialize(1024, random); // much faster - we don't need high security for testing only!
final KeyPair pair = keyGen.generateKeyPair();
return pair;
}
}