Search in sources :

Example 6 with KeyStoreKeyChainImpl

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());
}
Also used : KeyPair(java.security.KeyPair) PrivateKey(java.security.PrivateKey) HashMap(java.util.HashMap) URIParcel(com.disney.uriparcel.URIParcel) PublicKey(java.security.PublicKey) KeyChain(com.disney.http.auth.keychain.KeyChain) KeyStore(java.security.KeyStore) KeyStoreKeyChainImpl(com.disney.http.auth.keychain.KeyStoreKeyChainImpl) KeyChainKeyLoader(com.disney.http.auth.client.keyloader.KeyChainKeyLoader) Signature(java.security.Signature) File(java.io.File) PublicKey(java.security.PublicKey) Key(java.security.Key) PrivateKey(java.security.PrivateKey) Test(org.junit.Test)

Example 7 with KeyStoreKeyChainImpl

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;
}
Also used : URIParcel(com.disney.uriparcel.URIParcel) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) KeyStore(java.security.KeyStore) URI(java.net.URI) Callable(java.util.concurrent.Callable) KeyStoreKeyChainImpl(com.disney.http.auth.keychain.KeyStoreKeyChainImpl) SecretKeySpec(javax.crypto.spec.SecretKeySpec) KeyChainKeyLoader(com.disney.http.auth.client.keyloader.KeyChainKeyLoader) HttpSignatureSigner(com.disney.http.auth.client.signer.HttpSignatureSigner) List(java.util.List) KeyObjectKeyLoader(com.disney.http.auth.client.keyloader.KeyObjectKeyLoader) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) Map(java.util.Map) Key(java.security.Key)

Example 8 with KeyStoreKeyChainImpl

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());
}
Also used : KeyPair(java.security.KeyPair) MockHttpServletRequest(org.springframework.mock.web.MockHttpServletRequest) ServletAuthorizationRequest(com.disney.http.auth.server.ServletAuthorizationRequest) KeyChain(com.disney.http.auth.keychain.KeyChain) KeyStore(java.security.KeyStore) Callable(java.util.concurrent.Callable) Date(java.util.Date) X509Certificate(java.security.cert.X509Certificate) SignatureException(java.security.SignatureException) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) InvalidKeyException(java.security.InvalidKeyException) UnsupportedEncodingException(java.io.UnsupportedEncodingException) SignatureVerifierImpl(com.disney.http.auth.server.signature.SignatureVerifierImpl) KeyStoreKeyChainImpl(com.disney.http.auth.keychain.KeyStoreKeyChainImpl) VerifierResult(com.disney.http.auth.server.VerifierResult) SignatureAuthorization(com.disney.http.auth.SignatureAuthorization) SecretKeySpec(javax.crypto.spec.SecretKeySpec) SimpleDateFormat(java.text.SimpleDateFormat) DateFormat(java.text.DateFormat) SimpleDateFormat(java.text.SimpleDateFormat) Key(java.security.Key) PrivateKey(java.security.PrivateKey) ServerAuthorizationRequest(com.disney.http.auth.server.ServerAuthorizationRequest) Test(org.junit.Test)

Aggregations

KeyStoreKeyChainImpl (com.disney.http.auth.keychain.KeyStoreKeyChainImpl)8 URIParcel (com.disney.uriparcel.URIParcel)7 HashMap (java.util.HashMap)7 KeyStore (java.security.KeyStore)6 KeyChainKeyLoader (com.disney.http.auth.client.keyloader.KeyChainKeyLoader)5 KeyChain (com.disney.http.auth.keychain.KeyChain)5 File (java.io.File)4 KeyObjectKeyLoader (com.disney.http.auth.client.keyloader.KeyObjectKeyLoader)3 HttpSignatureSigner (com.disney.http.auth.client.signer.HttpSignatureSigner)3 Key (java.security.Key)3 Callable (java.util.concurrent.Callable)3 Test (org.junit.Test)3 SignatureAuthorization (com.disney.http.auth.SignatureAuthorization)2 UnsupportedEncodingException (java.io.UnsupportedEncodingException)2 URI (java.net.URI)2 URL (java.net.URL)2 KeyPair (java.security.KeyPair)2 NoSuchAlgorithmException (java.security.NoSuchAlgorithmException)2 PrivateKey (java.security.PrivateKey)2 Map (java.util.Map)2