use of com.disney.http.auth.keychain.KeyStoreKeyChainImpl in project groovity by disney.
the class TestKeyUtils method TestKeyGeneration.
@Test
public void TestKeyGeneration() throws Exception {
KeyPair pair = KeyUtils.generateKeyPair(2048);
Assert.assertNotNull(pair);
PrivateKey privateKey = pair.getPrivate();
Assert.assertNotNull(privateKey);
Assert.assertEquals(privateKey.getAlgorithm(), "RSA");
PublicKey publicKey = pair.getPublic();
Assert.assertNotNull(publicKey);
Assert.assertEquals(publicKey.getAlgorithm(), "RSA");
String alias = "apiUser123";
// Store private key
File privateKeyFile = new File("target/testPrivateKey.pem");
File privateKeyStore = new File("target/testKey.store");
String privatePassword = "passwordForPrivateKey";
URIParcel.put(privateKeyFile.toURI(), pair);
writePrivateKeystoreToFile(pair, privateKeyStore.getAbsolutePath(), alias, privatePassword);
// test retrieval of KeyStore
Map<String, Object> config = new HashMap<String, Object>();
config.put(KeyStoreValueHandler.KEYSTORE_PASSWORD, privatePassword);
config.put(KeyStoreValueHandler.KEYSTORE_TYPE, "JCEKS");
URIParcel<KeyStore> parcel = new URIParcel<KeyStore>(KeyStore.class, privateKeyStore.toURI(), config);
KeyChain chain = new KeyStoreKeyChainImpl(parcel, "".toCharArray());
KeyChainKeyLoader privateKeyStoreLoader = new KeyChainKeyLoader(chain);
privateKeyStoreLoader.setAlias(alias);
PrivateKey loadedKeyFromKeyStore = (PrivateKey) privateKeyStoreLoader.call();
Assert.assertEquals(privateKey, loadedKeyFromKeyStore);
// test retrieval of Key
URIParcel<KeyPair> pkParcel = new URIParcel<KeyPair>(KeyPair.class, privateKeyFile.toURI());
KeyPair loadedPrivateKey = pkParcel.call();
Assert.assertArrayEquals(privateKey.getEncoded(), loadedPrivateKey.getPrivate().getEncoded());
// check storage and retrieval of public key
String publicKeyFileName = "testPublicKey.store";
String password = "publicPassword";
File publicKeyFile = new File("target/" + publicKeyFileName);
KeyUtils.writePublicKeyStoreToFile(publicKey, publicKeyFile.getAbsolutePath(), alias, password);
PublicKey loadedPublicKey = loadPublicKeyStore(publicKeyFile.getAbsolutePath(), alias, password);
Assert.assertArrayEquals(publicKey.getEncoded(), loadedPublicKey.getEncoded());
// check if valid key pair by trying to sign and verify a string
String testString = "This is the message to encode.";
Signature rsaSign = Signature.getInstance("MD5withRSA");
rsaSign.initSign(privateKey);
rsaSign.update(testString.getBytes("UTF-8"));
byte[] signedMessage = rsaSign.sign();
Signature rsaVerify = Signature.getInstance("MD5withRSA");
rsaVerify.initVerify(loadedPublicKey);
rsaVerify.update(testString.getBytes("UTF-8"));
boolean valid = rsaVerify.verify(signedMessage);
Assert.assertTrue(valid);
// make new key pair and save KeyStore to file.
KeyPair keyPairForFile = KeyUtils.generateKeyPair();
String location = new File("target/testKeytool.store").getAbsolutePath();
writePrivateKeystoreToFile(keyPairForFile, location, "test", "rachel");
// load from file
config = new HashMap<String, Object>();
config.put(KeyStoreValueHandler.KEYSTORE_PASSWORD, "rachel");
config.put(KeyStoreValueHandler.KEYSTORE_TYPE, "JCEKS");
URIParcel<KeyStore> ksParcel = new URIParcel<KeyStore>(KeyStore.class, new File(location).toURI(), config);
KeyChain chain2 = new KeyStoreKeyChainImpl(ksParcel, "".toCharArray());
KeyChainKeyLoader savedKeyStoreLoader = new KeyChainKeyLoader(chain2);
savedKeyStoreLoader.setAlias("test");
Key newKey = savedKeyStoreLoader.call();
Assert.assertEquals(keyPairForFile.getPrivate(), newKey);
KeyStore importedKeystore = ksParcel.call();
Assert.assertEquals(keyPairForFile.getPublic(), importedKeystore.getCertificate("test").getPublicKey());
}
use of com.disney.http.auth.keychain.KeyStoreKeyChainImpl in project groovity by disney.
the class Signature method tag.
@SuppressWarnings({ "rawtypes", "unchecked" })
public Object tag(Map attributes, Closure body) throws Exception {
Object keyId = resolve(attributes, "keyId");
if (keyId == null) {
throw new RuntimeException("<g:signature> requires a keyId for signing");
}
Callable<Key> useLoader = null;
Object key = resolve(attributes, "key");
if (key == null) {
Object keystore = resolve(attributes, "keystore");
if (keystore == null) {
throw new RuntimeException("<g:signature> requires a key or keystore for signing");
}
String password = resolve(attributes, "password", String.class);
if (password == null) {
throw new RuntimeException("<g:signature> requires a password when using a keystore");
}
String alias = resolve(attributes, "alias", String.class);
if (alias == null) {
throw new RuntimeException("<g:signature> requires an alias when using a keystore");
}
if (!(keystore instanceof KeyStore)) {
String ksl = keystore.toString();
KeyChainKeyLoader loader = keystores.get(ksl);
if (loader == null) {
URIParcel<KeyStore> keystoreParcel = new URIParcel<KeyStore>(KeyStore.class, new URI(ksl));
keystoreParcel.setRefresh(60000);
Map conf = new HashMap();
conf.put("password", password);
String type = resolve(attributes, "type", String.class);
if (type != null) {
conf.put("type", type);
}
keystoreParcel.setConfig(conf);
loader = new KeyChainKeyLoader(new KeyStoreKeyChainImpl(keystoreParcel, password.toCharArray()), alias);
keystores.put(ksl, loader);
}
useLoader = loader;
} else {
useLoader = new KeyChainKeyLoader(new KeyStoreKeyChainImpl((KeyStore) keystore, password.toCharArray()), alias);
}
}
if (key instanceof Callable<?>) {
useLoader = (Callable<Key>) key;
} else if (key instanceof Key) {
useLoader = new KeyObjectKeyLoader((Key) key);
}
String useAlgorithm = "hmac-sha256";
Object algorithm = resolve(attributes, "algorithm");
if (algorithm != null) {
useAlgorithm = algorithm.toString();
}
if (useLoader == null) {
if (useAlgorithm.startsWith("rsa")) {
// TODO load private key from object
} else {
String signingAlg = Algorithms.getSecurityAlgorithm(useAlgorithm);
// System.out.println("Generating hmac key "+signingAlg+" with "+new String(DatatypeConverter.parseBase64Binary(key.toString())));
useLoader = new KeyObjectKeyLoader(new SecretKeySpec(DatatypeConverter.parseBase64Binary(key.toString()), signingAlg));
}
}
Object headers = resolve(attributes, "headers");
HttpSignatureSigner signer = new HttpSignatureSigner();
signer.setAlgorithm(useAlgorithm);
signer.setKeyId(keyId.toString());
signer.setKeyLoader(useLoader);
if (headers != null) {
if (!(headers instanceof List)) {
throw new RuntimeException("signature tag requires that 'headers' attribut contains a List, instead found " + headers.getClass().toString());
}
signer.setHeaders((List) headers);
}
bind(body, SIGNATURE_BINDING, Optional.of(signer));
return null;
}
use of com.disney.http.auth.keychain.KeyStoreKeyChainImpl in project groovity by disney.
the class TestHttpSignature method testSigning.
@Test
public void testSigning() throws Exception {
SignatureVerifierImpl verifier = new SignatureVerifierImpl();
verifier.setMaxDateDrift(5000);
final KeyStore testStore = KeyStore.getInstance("JCEKS");
testStore.load(null);
Key hmac256key = new SecretKeySpec("hello world".getBytes(), "HmacSHA256");
testStore.setKeyEntry("hmac256key", hmac256key, new char[0], null);
verifier.setKeyChains(Arrays.asList((KeyChain) new KeyStoreKeyChainImpl(new Callable<KeyStore>() {
@Override
public KeyStore call() throws Exception {
return testStore;
}
}, new char[0])));
DateFormat headerDateFormat = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz");
verifier.setRequiredHeaders(Arrays.asList(REQUEST_TARGET, "date"));
MockHttpServletRequest request = new MockHttpServletRequest();
ServerAuthorizationRequest areq = new ServletAuthorizationRequest(request);
// FIRST TEST: missing signature
VerifierResult result = verifier.verify(areq);
Assert.assertEquals(ERROR_MISSING_SIGNATURE, result.getMessage());
SignatureAuthorization signature = new SignatureAuthorization();
signature.setAlgorithm("rsa-sha256");
signature.setKeyId("rsa256key");
signature.setHeaders(new ArrayList<String>());
signature.setSignature(new byte[0]);
request.addHeader("Authorization", "Signature " + signature.toString());
// SECOND TEST: missing REQUEST_TARGET
result = verifier.verify(areq);
Assert.assertEquals(MessageFormat.format(ERROR_MISSING_HEADER_FORMAT, REQUEST_TARGET), result.getMessage());
signature.setHeaders(Arrays.asList(REQUEST_TARGET));
request = new MockHttpServletRequest();
areq = new ServletAuthorizationRequest(request);
request.addHeader("Authorization", "Signature " + signature.toString());
// THIRD TEST: missing date
result = verifier.verify(areq);
Assert.assertEquals(MessageFormat.format(ERROR_MISSING_HEADER_FORMAT, "date"), result.getMessage());
signature.setHeaders(Arrays.asList(REQUEST_TARGET, "date"));
request = new MockHttpServletRequest();
areq = new ServletAuthorizationRequest(request);
request.addHeader("Authorization", "Signature " + signature.toString());
request.addHeader("Date", headerDateFormat.format(new Date(System.currentTimeMillis() - 6000)));
// FOURTH TEST: out-of-range date
result = verifier.verify(areq);
Assert.assertEquals(ERROR_INVALID_DATE, result.getMessage());
request = new MockHttpServletRequest();
areq = new ServletAuthorizationRequest(request);
request.addHeader("Authorization", "Signature " + signature.toString());
request.addHeader("Date", headerDateFormat.format(new Date(System.currentTimeMillis() - 3000)));
// FIFTH TEST: unknown key ID
result = verifier.verify(areq);
Assert.assertEquals(MessageFormat.format(ERROR_UNKOWN_KEY_ID_FORMAT, signature.getKeyId()), result.getMessage());
signature.setKeyId("hmac256key");
request = new MockHttpServletRequest();
areq = new ServletAuthorizationRequest(request);
request.addHeader("Authorization", "Signature " + signature.toString());
request.addHeader("Date", headerDateFormat.format(new Date(System.currentTimeMillis() - 3000)));
// SIXTH TEST: rsa mismatch
result = verifier.verify(areq);
Assert.assertEquals(MessageFormat.format(ERROR_EXPECTED_RSA_FORMAT, signature.getKeyId()), result.getMessage());
KeyPair keypair = KeyPairGenerator.getInstance("RSA").generateKeyPair();
X509Certificate certificate = generateCertificate(keypair);
testStore.setKeyEntry("rsa256key", keypair.getPrivate(), new char[0], new Certificate[] { certificate });
signature.setKeyId("rsa256key");
signature.setAlgorithm("hmac-sha256");
request = new MockHttpServletRequest();
areq = new ServletAuthorizationRequest(request);
request.addHeader("Authorization", "Signature " + signature.toString());
request.addHeader("Date", headerDateFormat.format(new Date(System.currentTimeMillis() - 3000)));
// Seventh TEST: hmac mismatch
result = verifier.verify(areq);
Assert.assertEquals(MessageFormat.format(ERROR_EXPECTED_HMAC_FORMAT, signature.getKeyId()), result.getMessage());
signature.setAlgorithm("rsa-sha256");
request = new MockHttpServletRequest();
areq = new ServletAuthorizationRequest(request);
request.addHeader("Authorization", "Signature " + signature.toString());
request.addHeader("Date", headerDateFormat.format(new Date(System.currentTimeMillis() - 3000)));
// EIGHT test: invalid signature
Exception sigEx = null;
try {
verifier.verify(areq);
} catch (Exception e) {
sigEx = e;
}
Assert.assertNotNull(sigEx);
// NINTH test: good signature
request = new MockHttpServletRequest();
areq = new ServletAuthorizationRequest(request);
request.setMethod("GET");
request.setRequestURI("/");
request.addHeader("Date", headerDateFormat.format(new Date(System.currentTimeMillis() - 3000)));
String signingString = "(request-target): get /\ndate: " + request.getHeader("date");
byte[] sigBytes = signMessage(keypair.getPrivate(), signingString, "rsa-sha256");
signature.setSignature(sigBytes);
request.addHeader("Authorization", "Signature " + signature.toString());
result = verifier.verify(areq);
Assert.assertTrue("Verification failed", result.isAuthenticated());
// TENTH test: bad signature
request = new MockHttpServletRequest();
areq = new ServletAuthorizationRequest(request);
request.setMethod("GET");
request.setRequestURI("/nogood");
request.addHeader("Date", headerDateFormat.format(new Date(System.currentTimeMillis() - 3000)));
signingString = "(request-target): get /\ndate: " + request.getHeader("date");
sigBytes = signMessage(keypair.getPrivate(), signingString, "rsa-sha256");
signature.setSignature(sigBytes);
request.addHeader("Authorization", "Signature " + signature.toString());
result = verifier.verify(areq);
Assert.assertFalse("Verification succeed when it should have failed", result.isAuthenticated());
Assert.assertEquals(ERROR_VERIFICATION_FAILED, result.getMessage());
}
Aggregations