You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@airavata.apache.org by am...@apache.org on 2013/10/11 19:08:04 UTC

svn commit: r1531359 - in /airavata/trunk/modules/credential-store/src: main/java/org/apache/airavata/credential/store/store/impl/db/ test/java/org/apache/airavata/credential/store/store/impl/db/ test/resources/

Author: amilaj
Date: Fri Oct 11 17:08:03 2013
New Revision: 1531359

URL: http://svn.apache.org/r1531359
Log:
Modifyin credential store interface to take secret key dat to encrypt credentials. This is mainly used when ACS is used as a separate component.

Added:
    airavata/trunk/modules/credential-store/src/test/resources/mykeystore.jks   (with props)
Modified:
    airavata/trunk/modules/credential-store/src/main/java/org/apache/airavata/credential/store/store/impl/db/CredentialsDAO.java
    airavata/trunk/modules/credential-store/src/test/java/org/apache/airavata/credential/store/store/impl/db/CredentialsDAOTest.java

Modified: airavata/trunk/modules/credential-store/src/main/java/org/apache/airavata/credential/store/store/impl/db/CredentialsDAO.java
URL: http://svn.apache.org/viewvc/airavata/trunk/modules/credential-store/src/main/java/org/apache/airavata/credential/store/store/impl/db/CredentialsDAO.java?rev=1531359&r1=1531358&r2=1531359&view=diff
==============================================================================
--- airavata/trunk/modules/credential-store/src/main/java/org/apache/airavata/credential/store/store/impl/db/CredentialsDAO.java (original)
+++ airavata/trunk/modules/credential-store/src/main/java/org/apache/airavata/credential/store/store/impl/db/CredentialsDAO.java Fri Oct 11 17:08:03 2013
@@ -22,10 +22,13 @@
 package org.apache.airavata.credential.store.store.impl.db;
 
 import org.apache.airavata.common.utils.DBUtil;
+import org.apache.airavata.common.utils.KeyStorePasswordCallback;
+import org.apache.airavata.common.utils.SecurityUtil;
 import org.apache.airavata.credential.store.credential.Credential;
 import org.apache.airavata.credential.store.store.CredentialStoreException;
 
 import java.io.*;
+import java.security.GeneralSecurityException;
 import java.sql.*;
 import java.util.ArrayList;
 import java.util.List;
@@ -35,10 +38,45 @@ import java.util.List;
  */
 public class CredentialsDAO extends ParentDAO {
 
+    private String keyStorePath = null;
+    private String secretKeyAlias = null;
+    private KeyStorePasswordCallback keyStorePasswordCallback = null;
+
+
     public CredentialsDAO() {
         super();
     }
 
+    public CredentialsDAO(String keyStore, String alias, KeyStorePasswordCallback passwordCallback) {
+        this.keyStorePath = keyStore;
+        this.secretKeyAlias = alias;
+        this.keyStorePasswordCallback = passwordCallback;
+    }
+
+    public String getKeyStorePath() {
+        return keyStorePath;
+    }
+
+    public void setKeyStorePath(String keyStorePath) {
+        this.keyStorePath = keyStorePath;
+    }
+
+    public String getSecretKeyAlias() {
+        return secretKeyAlias;
+    }
+
+    public void setSecretKeyAlias(String secretKeyAlias) {
+        this.secretKeyAlias = secretKeyAlias;
+    }
+
+    public KeyStorePasswordCallback getKeyStorePasswordCallback() {
+        return keyStorePasswordCallback;
+    }
+
+    public void setKeyStorePasswordCallback(KeyStorePasswordCallback keyStorePasswordCallback) {
+        this.keyStorePasswordCallback = keyStorePasswordCallback;
+    }
+
     /**
      * String createTable = "CREATE TABLE CREDENTIALS\n" + "(\n" + "        GATEWAY_ID VARCHAR(256) NOT NULL,\n" +
      * "        TOKEN_ID VARCHAR(256) NOT NULL,\n" + // Actual token used to identify the credential
@@ -80,24 +118,6 @@ public class CredentialsDAO extends Pare
             log.error(stringBuilder.toString(), e);
 
             throw new CredentialStoreException(stringBuilder.toString(), e);
-        } catch (UnsupportedEncodingException e) {
-            StringBuilder stringBuilder = new StringBuilder(
-                    "Error persisting community credentials. Unsupported encoding.");
-            stringBuilder.append(" gateway - ").append(gatewayId);
-            stringBuilder.append(" token id - ").append(credential.getToken());
-
-            log.error(stringBuilder.toString(), e);
-
-            throw new CredentialStoreException(stringBuilder.toString(), e);
-        } catch (IOException e) {
-            StringBuilder stringBuilder = new StringBuilder(
-                    "Error persisting community credentials. Error serializing " + "credentials.");
-            stringBuilder.append(" gateway - ").append(gatewayId);
-            stringBuilder.append(" community user name - ").append(credential.getToken());
-
-            log.error(stringBuilder.toString(), e);
-
-            throw new CredentialStoreException(stringBuilder.toString(), e);
         } finally {
 
             DBUtil.cleanup(preparedStatement);
@@ -168,22 +188,6 @@ public class CredentialsDAO extends Pare
             log.error(stringBuilder.toString(), e);
 
             throw new CredentialStoreException(stringBuilder.toString(), e);
-        } catch (UnsupportedEncodingException e) {
-            StringBuilder stringBuilder = new StringBuilder("Error updating credentials. Invalid encoding for keys.");
-            stringBuilder.append(" gateway - ").append(gatewayId);
-            stringBuilder.append(" token id - ").append(credential.getToken());
-
-            log.error(stringBuilder.toString(), e);
-
-            throw new CredentialStoreException(stringBuilder.toString(), e);
-        } catch (IOException e) {
-            StringBuilder stringBuilder = new StringBuilder("Error updating credentials. Error serializing objects.");
-            stringBuilder.append(" gateway - ").append(gatewayId);
-            stringBuilder.append(" token - ").append(credential.getToken());
-
-            log.error(stringBuilder.toString(), e);
-
-            throw new CredentialStoreException(stringBuilder.toString(), e);
         } finally {
 
             DBUtil.cleanup(preparedStatement);
@@ -236,24 +240,6 @@ public class CredentialsDAO extends Pare
             log.debug(stringBuilder.toString(), e);
 
             throw new CredentialStoreException(stringBuilder.toString(), e);
-        } catch (ClassNotFoundException e) {
-            StringBuilder stringBuilder = new StringBuilder("Error retrieving credentials for community user. Error "
-                    + "de-serializing credential objects.");
-            stringBuilder.append("gateway - ").append(gatewayName);
-            stringBuilder.append("token id - ").append(tokenId);
-
-            log.debug(stringBuilder.toString(), e);
-
-            throw new CredentialStoreException(stringBuilder.toString(), e);
-        } catch (IOException e) {
-            StringBuilder stringBuilder = new StringBuilder("Error retrieving credentials for community user. Error "
-                    + "de-serializing credential objects. An IO Error.");
-            stringBuilder.append("gateway - ").append(gatewayName);
-            stringBuilder.append("tokenId - ").append(tokenId);
-
-            log.debug(stringBuilder.toString(), e);
-
-            throw new CredentialStoreException(stringBuilder.toString(), e);
         } finally {
             DBUtil.cleanup(preparedStatement, resultSet);
         }
@@ -306,20 +292,6 @@ public class CredentialsDAO extends Pare
             log.debug(stringBuilder.toString(), e);
 
             throw new CredentialStoreException(stringBuilder.toString(), e);
-        } catch (ClassNotFoundException e) {
-            StringBuilder stringBuilder = new StringBuilder("Error retrieving credential list for ");
-            stringBuilder.append("gateway - ").append(gatewayName);
-            stringBuilder.append("Error de-serializing objects.");
-            log.debug(stringBuilder.toString(), e);
-
-            throw new CredentialStoreException(stringBuilder.toString(), e);
-        } catch (IOException e) {
-            StringBuilder stringBuilder = new StringBuilder("Error retrieving credential list for ");
-            stringBuilder.append("gateway - ").append(gatewayName);
-            stringBuilder.append("Error de-serializing objects.");
-            log.debug(stringBuilder.toString(), e);
-
-            throw new CredentialStoreException(stringBuilder.toString(), e);
         } finally {
             DBUtil.cleanup(preparedStatement, resultSet);
         }
@@ -327,18 +299,39 @@ public class CredentialsDAO extends Pare
         return credentialList;
     }
 
-    public static Object convertByteArrayToObject(byte[] data) throws IOException, ClassNotFoundException {
-        ObjectInputStream objectInputStream = new ObjectInputStream(new ByteArrayInputStream(data));
+    public Object convertByteArrayToObject(byte[] data) throws CredentialStoreException {
+        ObjectInputStream objectInputStream = null;
         Object o = null;
         try {
-            o = objectInputStream.readObject();
+            try {
+                //decrypt the data first
+                if (encrypt()) {
+                    data = SecurityUtil.decrypt(this.keyStorePath, this.secretKeyAlias, this.keyStorePasswordCallback, data);
+                }
+
+                objectInputStream = new ObjectInputStream(new ByteArrayInputStream(data));
+                o = objectInputStream.readObject();
+
+            } catch (IOException e) {
+                throw new CredentialStoreException("Error de-serializing object.", e);
+            } catch (ClassNotFoundException e) {
+                throw new CredentialStoreException("Error de-serializing object.", e);
+            } catch (GeneralSecurityException e) {
+                throw new CredentialStoreException("Error decrypting data.", e);
+            }
         } finally {
-            objectInputStream.close();
+            if (objectInputStream != null) {
+                try {
+                    objectInputStream.close();
+                } catch (IOException e) {
+                    log.error("Error occurred while closing the stream", e);
+                }
+            }
         }
         return o;
     }
 
-    public static byte[] convertObjectToByteArray(Serializable o) throws IOException {
+    public byte[] convertObjectToByteArray(Serializable o) throws CredentialStoreException {
         ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
 
         ObjectOutputStream objectOutputStream = null;
@@ -346,13 +339,40 @@ public class CredentialsDAO extends Pare
             objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
             objectOutputStream.writeObject(o);
             objectOutputStream.flush();
+        } catch (IOException e) {
+            throw new CredentialStoreException("Error serializing object.", e);
         } finally {
             if (objectOutputStream != null) {
-                objectOutputStream.close();
+                try {
+                    objectOutputStream.close();
+                } catch (IOException e) {
+                    log.error("Error occurred while closing object output stream", e);
+                }
             }
         }
 
-        return byteArrayOutputStream.toByteArray();
+        // encrypt the byte array
+        if (encrypt()) {
+            byte[] array = byteArrayOutputStream.toByteArray();
+            try {
+                return SecurityUtil.encrypt(this.keyStorePath, this.secretKeyAlias, this.keyStorePasswordCallback, array);
+            } catch (GeneralSecurityException e) {
+                throw new CredentialStoreException("Error encrypting data", e);
+            } catch (IOException e) {
+                throw new CredentialStoreException("Error encrypting data. IO exception.", e);
+            }
+        } else {
+            return byteArrayOutputStream.toByteArray();
+        }
+    }
+
+    /**
+     * Says whether to encrypt data or not. if alias, keystore is set
+     * we treat encryption true.
+     * @return true if data should encrypt else false.
+     */
+    private boolean encrypt() {
+        return this.keyStorePath != null;
     }
 
 }

Modified: airavata/trunk/modules/credential-store/src/test/java/org/apache/airavata/credential/store/store/impl/db/CredentialsDAOTest.java
URL: http://svn.apache.org/viewvc/airavata/trunk/modules/credential-store/src/test/java/org/apache/airavata/credential/store/store/impl/db/CredentialsDAOTest.java?rev=1531359&r1=1531358&r2=1531359&view=diff
==============================================================================
--- airavata/trunk/modules/credential-store/src/test/java/org/apache/airavata/credential/store/store/impl/db/CredentialsDAOTest.java (original)
+++ airavata/trunk/modules/credential-store/src/test/java/org/apache/airavata/credential/store/store/impl/db/CredentialsDAOTest.java Fri Oct 11 17:08:03 2013
@@ -25,9 +25,11 @@ import junit.framework.Assert;
 import org.apache.airavata.common.utils.DBUtil;
 import org.apache.airavata.common.utils.DatabaseTestCases;
 import org.apache.airavata.common.utils.DerbyUtil;
+import org.apache.airavata.common.utils.KeyStorePasswordCallback;
 import org.apache.airavata.credential.store.credential.CommunityUser;
 import org.apache.airavata.credential.store.credential.Credential;
 import org.apache.airavata.credential.store.credential.impl.certificate.CertificateCredential;
+import org.apache.airavata.credential.store.store.CredentialStoreException;
 import org.junit.AfterClass;
 import org.junit.Before;
 import org.junit.BeforeClass;
@@ -36,7 +38,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import java.io.File;
-import java.io.IOException;
+import java.net.URL;
 import java.security.*;
 import java.security.cert.X509Certificate;
 import java.sql.Connection;
@@ -198,12 +200,55 @@ public class CredentialsDAOTest extends 
     }
 
     @Test
-    public void testSerialization() throws IOException, ClassNotFoundException {
+    public void testSerialization() throws CredentialStoreException {
 
         CertificateCredential certificateCredential = getTestCredentialObject();
 
-        byte[] array = CredentialsDAO.convertObjectToByteArray(certificateCredential);
-        CertificateCredential readCertificateCredential = (CertificateCredential) CredentialsDAO
+        CredentialsDAO credentialsDAO1 = new CredentialsDAO();
+
+        byte[] array = credentialsDAO1.convertObjectToByteArray(certificateCredential);
+        CertificateCredential readCertificateCredential = (CertificateCredential) credentialsDAO1
+                .convertByteArrayToObject(array);
+
+        checkEquality(certificateCredential.getCertificates(), readCertificateCredential.getCertificates());
+        Assert.assertEquals(certificateCredential.getCertificateRequestedTime(),
+                readCertificateCredential.getCertificateRequestedTime());
+        Assert.assertEquals(certificateCredential.getCommunityUser().getGatewayName(), readCertificateCredential
+                .getCommunityUser().getGatewayName());
+        Assert.assertEquals(certificateCredential.getCommunityUser().getUserEmail(), readCertificateCredential
+                .getCommunityUser().getUserEmail());
+        Assert.assertEquals(certificateCredential.getCommunityUser().getUserName(), readCertificateCredential
+                .getCommunityUser().getUserName());
+        Assert.assertEquals(certificateCredential.getLifeTime(), readCertificateCredential.getLifeTime());
+        Assert.assertEquals(certificateCredential.getNotAfter(), readCertificateCredential.getNotAfter());
+        Assert.assertEquals(certificateCredential.getNotBefore(), readCertificateCredential.getNotBefore());
+        Assert.assertEquals(certificateCredential.getPortalUserName(), readCertificateCredential.getPortalUserName());
+
+        PrivateKey newKey = readCertificateCredential.getPrivateKey();
+
+        Assert.assertNotNull(newKey);
+        Assert.assertEquals(privateKey.getClass(), newKey.getClass());
+
+        Assert.assertEquals(privateKey.getFormat(), newKey.getFormat());
+        Assert.assertEquals(privateKey.getAlgorithm(), newKey.getAlgorithm());
+        Assert.assertTrue(Arrays.equals(privateKey.getEncoded(), newKey.getEncoded()));
+    }
+
+    @Test
+    public void testSerializationWithEncryption() throws CredentialStoreException {
+
+        URL url = this.getClass().getClassLoader().getResource("mykeystore.jks");
+        String secretKeyAlias = "mykey";
+
+        assert url != null;
+
+        CertificateCredential certificateCredential = getTestCredentialObject();
+
+        CredentialsDAO credentialsDAO1 = new CredentialsDAO(url.getPath(), secretKeyAlias,
+                new TestACSKeyStoreCallback());
+
+        byte[] array = credentialsDAO1.convertObjectToByteArray(certificateCredential);
+        CertificateCredential readCertificateCredential = (CertificateCredential) credentialsDAO1
                 .convertByteArrayToObject(array);
 
         checkEquality(certificateCredential.getCertificates(), readCertificateCredential.getCertificates());
@@ -230,6 +275,23 @@ public class CredentialsDAOTest extends 
         Assert.assertTrue(Arrays.equals(privateKey.getEncoded(), newKey.getEncoded()));
     }
 
+    private class TestACSKeyStoreCallback implements KeyStorePasswordCallback {
+
+        @Override
+        public char[] getStorePassword() {
+            return "airavata".toCharArray();
+        }
+
+        @Override
+        public char[] getSecretKeyPassPhrase(String keyAlias) {
+            if (keyAlias.equals("mykey")) {
+                return "airavatasecretkey".toCharArray();
+            }
+
+            return null;
+        }
+    }
+
     private void checkEquality(X509Certificate[] certificates1, X509Certificate[] certificates2) {
 
         int i = 0;

Added: airavata/trunk/modules/credential-store/src/test/resources/mykeystore.jks
URL: http://svn.apache.org/viewvc/airavata/trunk/modules/credential-store/src/test/resources/mykeystore.jks?rev=1531359&view=auto
==============================================================================
Binary file - no diff available.

Propchange: airavata/trunk/modules/credential-store/src/test/resources/mykeystore.jks
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream