package org.ovirt.engine.core.uutils.crypto.ticket;
import static org.junit.Assert.assertEquals;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.security.GeneralSecurityException;
import java.security.KeyStore;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.apache.commons.codec.binary.Base64;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.type.TypeFactory;
import org.junit.Test;
public class TicketTest {
private static KeyStore getKeyStore(String storeType, String store, String password) throws Exception {
KeyStore ks = KeyStore.getInstance(storeType);
try (InputStream is = ClassLoader.getSystemResourceAsStream(store)) {
ks.load(is, password.toCharArray());
}
return ks;
}
private static KeyStore.PrivateKeyEntry getPrivateKeyEntry(KeyStore ks, String alias, String password) throws Exception {
return (KeyStore.PrivateKeyEntry)ks.getEntry(alias, new KeyStore.PasswordProtection(password.toCharArray()));
}
@Test
public void testByCertificate() throws Exception {
final String content = "testByCertificate";
KeyStore.PrivateKeyEntry entry = getPrivateKeyEntry(getKeyStore("PKCS12", "ticket/ca1test1.p12", "test1"), "1", "test1");
String ticket = new TicketEncoder(entry.getCertificate(), entry.getPrivateKey(), 30).encode(content);
assertEquals(content, new TicketDecoder(entry.getCertificate()).decode(ticket));
assertEquals(
content,
new TicketDecoder(
getKeyStore("JKS", "ticket/ca1.jks", "changeit"),
null,
entry.getCertificate()
).decode(ticket)
);
}
@Test(expected=GeneralSecurityException.class)
public void testByCertificateFailCertificate() throws Exception {
final String content = "testByCertificate";
KeyStore.PrivateKeyEntry entry1 = getPrivateKeyEntry(getKeyStore("PKCS12", "ticket/ca1test1.p12", "test1"), "1", "test1");
KeyStore.PrivateKeyEntry entry2 = getPrivateKeyEntry(getKeyStore("PKCS12", "ticket/ca1test2.p12", "test2"), "1", "test2");
assertEquals(
content, new TicketDecoder(
entry2.getCertificate()
).decode(
new TicketEncoder(entry1.getCertificate(), entry1.getPrivateKey()).encode(content)
)
);
}
@Test(expected=GeneralSecurityException.class)
public void testByCertificateFailCA() throws Exception {
final String content = "testByCertificate";
KeyStore.PrivateKeyEntry entry = getPrivateKeyEntry(getKeyStore("PKCS12", "ticket/ca1test1.p12", "test1"), "1", "test1");
assertEquals(
content, new TicketDecoder(
getKeyStore("JKS", "ticket/ca2.jks", "changeit"),
null,
entry.getCertificate()
).decode(
new TicketEncoder(entry.getCertificate(), entry.getPrivateKey()).encode(content)
)
);
}
@Test
public void testByEKU() throws Exception {
final String content = "testByEKU";
KeyStore.PrivateKeyEntry entry = getPrivateKeyEntry(getKeyStore("PKCS12", "ticket/ca1test2.p12", "test2"), "1", "test2");
assertEquals(
content, new TicketDecoder(
getKeyStore("JKS", "ticket/ca1.jks", "changeit"),
"1.2.3.4"
).decode(
new TicketEncoder(entry.getCertificate(), entry.getPrivateKey()).encode(content)
)
);
}
@Test(expected=GeneralSecurityException.class)
public void testByEKUFailEKU() throws Exception {
final String content = "testByEKU";
KeyStore.PrivateKeyEntry entry = getPrivateKeyEntry(getKeyStore("PKCS12", "ticket/ca1test2.p12", "test2"), "1", "test2");
assertEquals(
content, new TicketDecoder(
getKeyStore("JKS", "ticket/ca1.jks", "changeit"),
"1.2.3.4.5"
).decode(
new TicketEncoder(entry.getCertificate(), entry.getPrivateKey()).encode(content)
)
);
}
@Test(expected=GeneralSecurityException.class)
public void testByEKUFailCA() throws Exception {
final String content = "testByEKU";
KeyStore.PrivateKeyEntry entry = getPrivateKeyEntry(getKeyStore("PKCS12", "ticket/ca1test2.p12", "test2"), "1", "test2");
assertEquals(
content, new TicketDecoder(
getKeyStore("JKS", "ticket/ca2.jks", "changeit"),
"1.2.3.4"
).decode(
new TicketEncoder(entry.getCertificate(), entry.getPrivateKey()).encode(content)
)
);
}
@Test
public void testSalt() throws Exception {
final String content = "testSalt";
KeyStore.PrivateKeyEntry entry = getPrivateKeyEntry(getKeyStore("PKCS12", "ticket/ca1test2.p12", "test2"), "1", "test2");
Set<String> salt = new HashSet<>();
final int n = 10;
for (int i = 0; i < n;i++) {
salt.add(
new ObjectMapper().<Map<String, String>>readValue(
Base64.decodeBase64(new TicketEncoder(entry.getCertificate(), entry.getPrivateKey()).encode(content)),
TypeFactory.defaultInstance().constructMapType(HashMap.class, String.class, String.class)
).get("salt")
);
}
assertEquals(n, salt.size());
}
@Test(expected=GeneralSecurityException.class)
public void testContentFail() throws Exception {
KeyStore.PrivateKeyEntry entry = getPrivateKeyEntry(getKeyStore("PKCS12", "ticket/ca1test2.p12", "test2"), "1", "test2");
Map<String, String> map = new ObjectMapper().readValue(
Base64.decodeBase64(new TicketEncoder(entry.getCertificate(), entry.getPrivateKey()).encode("content")),
TypeFactory.defaultInstance().constructMapType(HashMap.class, String.class, String.class)
);
map.put("data", "Content");
String modifiedTicket = new Base64(0).encodeToString(new ObjectMapper().writeValueAsString(map).getBytes(
StandardCharsets.UTF_8));
new TicketDecoder(getKeyStore("JKS", "ticket/ca1.jks", "changeit"), "1.2.3.4").decode(modifiedTicket);
}
@Test(expected=GeneralSecurityException.class)
public void testValidToFail() throws Exception {
KeyStore.PrivateKeyEntry entry = getPrivateKeyEntry(getKeyStore("PKCS12", "ticket/ca1test2.p12", "test2"), "1", "test2");
String ticket = new TicketEncoder(entry.getCertificate(), entry.getPrivateKey(), 1).encode("content");
Thread.sleep(2000);
new TicketDecoder(getKeyStore("JKS", "ticket/ca1.jks", "changeit"), "1.2.3.4").decode(ticket);
}
}