Author: aadamchik
Date: Fri Mar 28 14:56:46 2014
New Revision: 1582771

URL: http://svn.apache.org/r1582771
Log:
CAY-1916 cayenne-crypto module that enables data encryption for certain model 
attributes

CipherFactory

Added:
    
cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/CayenneCryptoException.java
    
cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/CryptoConstants.java
    
cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/cipher/
    
cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/cipher/CipherFactory.java
    
cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/cipher/DefaultCipherFactory.java
    
cayenne/main/trunk/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/cipher/
    
cayenne/main/trunk/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/cipher/DefaultCipherFactoryTest.java
Modified:
    
cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/CryptoModuleBuilder.java
    
cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/DefaultTransformerFactory.java

Added: 
cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/CayenneCryptoException.java
URL: 
http://svn.apache.org/viewvc/cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/CayenneCryptoException.java?rev=1582771&view=auto
==============================================================================
--- 
cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/CayenneCryptoException.java
 (added)
+++ 
cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/CayenneCryptoException.java
 Fri Mar 28 14:56:46 2014
@@ -0,0 +1,45 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+package org.apache.cayenne.crypto;
+
+import org.apache.cayenne.CayenneRuntimeException;
+
+/**
+ * @since 3.2
+ */
+public class CayenneCryptoException extends CayenneRuntimeException {
+
+    private static final long serialVersionUID = -281186275324369949L;
+
+    public CayenneCryptoException() {
+    }
+
+    public CayenneCryptoException(String messageFormat, Object... messageArgs) 
{
+        super(messageFormat, messageArgs);
+    }
+
+    public CayenneCryptoException(Throwable cause) {
+        super(cause);
+    }
+
+    public CayenneCryptoException(String messageFormat, Throwable cause, 
Object... messageArgs) {
+        super(messageFormat, cause, messageArgs);
+    }
+
+}

Added: 
cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/CryptoConstants.java
URL: 
http://svn.apache.org/viewvc/cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/CryptoConstants.java?rev=1582771&view=auto
==============================================================================
--- 
cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/CryptoConstants.java
 (added)
+++ 
cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/CryptoConstants.java
 Fri Mar 28 14:56:46 2014
@@ -0,0 +1,37 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+package org.apache.cayenne.crypto;
+
+/**
+ * @since 3.2
+ */
+public interface CryptoConstants {
+
+    /**
+     * An injection key for the map of the crypto properties.
+     */
+    public static final String PROPERTIES_MAP = "cayenne.crypto.properties";
+
+    public static final String CIPHER_ALGORITHM = 
"cayenne.crypto.cipher.algorithm";
+
+    public static final String CIPHER_MODE = "cayenne.crypto.cipher.mode";
+
+    public static final String CIPHER_PADDING = 
"cayenne.crypto.cipher.padding";
+
+}

Modified: 
cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/CryptoModuleBuilder.java
URL: 
http://svn.apache.org/viewvc/cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/CryptoModuleBuilder.java?rev=1582771&r1=1582770&r2=1582771&view=diff
==============================================================================
--- 
cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/CryptoModuleBuilder.java
 (original)
+++ 
cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/CryptoModuleBuilder.java
 Fri Mar 28 14:56:46 2014
@@ -21,10 +21,12 @@ package org.apache.cayenne.crypto;
 import org.apache.cayenne.access.jdbc.reader.RowReaderFactory;
 import org.apache.cayenne.access.translator.batch.BatchTranslatorFactory;
 import org.apache.cayenne.crypto.batch.CryptoBatchTranslatorFactoryDecorator;
+import org.apache.cayenne.crypto.cipher.CipherFactory;
+import org.apache.cayenne.crypto.cipher.DefaultCipherFactory;
 import org.apache.cayenne.crypto.map.ColumnMapper;
 import org.apache.cayenne.crypto.reader.CryptoRowReaderFactoryDecorator;
-import org.apache.cayenne.crypto.transformer.TransformerFactory;
 import org.apache.cayenne.crypto.transformer.DefaultTransformerFactory;
+import org.apache.cayenne.crypto.transformer.TransformerFactory;
 import org.apache.cayenne.crypto.transformer.ValueTransformerFactory;
 import org.apache.cayenne.di.Binder;
 import org.apache.cayenne.di.Module;
@@ -39,13 +41,48 @@ import org.apache.cayenne.di.Module;
  */
 public class CryptoModuleBuilder {
 
+    private static final String DEFAULT_CIPHER_ALGORITHM = "AES";
+    private static final String DEFAULT_CIPHER_MODE = "CBC";
+    private static final String DEFAULT_CIPHER_PADDING = "PKCS5Padding";
+
     private Class<? extends ValueTransformerFactory> 
valueTransformerFactoryType;
 
     private ColumnMapper columnMapper;
     private Class<? extends ColumnMapper> columnMapperType;
 
-    public CryptoModuleBuilder valueTransformer(Class<? extends 
ValueTransformerFactory> valueTransformerFactoryType) {
-        this.valueTransformerFactoryType = valueTransformerFactoryType;
+    private String cipherAlgoritm;
+    private String cipherMode;
+    private String cipherPadding;
+    private Class<? extends CipherFactory> cipherFactoryType;
+
+    public CryptoModuleBuilder() {
+
+        // init some sensible defaults that work in JVM without extra
+        // packages...
+        this.cipherAlgoritm = DEFAULT_CIPHER_ALGORITHM;
+        this.cipherMode = DEFAULT_CIPHER_MODE;
+        this.cipherPadding = DEFAULT_CIPHER_PADDING;
+
+        this.cipherFactoryType = DefaultCipherFactory.class;
+    }
+
+    public CryptoModuleBuilder cipherAlgorithm(String algorithm) {
+        this.cipherAlgoritm = algorithm;
+        return this;
+    }
+
+    public CryptoModuleBuilder cipherMode(String mode) {
+        this.cipherMode = mode;
+        return this;
+    }
+
+    public CryptoModuleBuilder cipherFactory(Class<? extends CipherFactory> 
factoryType) {
+        this.cipherFactoryType = factoryType;
+        return this;
+    }
+
+    public CryptoModuleBuilder valueTransformer(Class<? extends 
ValueTransformerFactory> factoryType) {
+        this.valueTransformerFactoryType = factoryType;
         return this;
     }
 
@@ -74,11 +111,21 @@ public class CryptoModuleBuilder {
             throw new IllegalStateException("'ColumnMapper' is not 
initialized");
         }
 
+        if (cipherFactoryType == null) {
+            throw new IllegalStateException("'CipherFactory' is not 
initialized");
+        }
+
         return new Module() {
 
             @Override
             public void configure(Binder binder) {
 
+                // init default cipher settings
+                
binder.bindMap(CryptoConstants.PROPERTIES_MAP).put(CryptoConstants.CIPHER_ALGORITHM,
 cipherAlgoritm)
+                        .put(CryptoConstants.CIPHER_MODE, cipherMode)
+                        .put(CryptoConstants.CIPHER_PADDING, cipherPadding);
+
+                binder.bind(CipherFactory.class).to(cipherFactoryType);
                 
binder.bind(TransformerFactory.class).to(DefaultTransformerFactory.class);
                 
binder.bind(ValueTransformerFactory.class).to(valueTransformerFactoryType);
 
@@ -93,5 +140,4 @@ public class CryptoModuleBuilder {
             }
         };
     }
-
 }

Added: 
cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/cipher/CipherFactory.java
URL: 
http://svn.apache.org/viewvc/cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/cipher/CipherFactory.java?rev=1582771&view=auto
==============================================================================
--- 
cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/cipher/CipherFactory.java
 (added)
+++ 
cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/cipher/CipherFactory.java
 Fri Mar 28 14:56:46 2014
@@ -0,0 +1,36 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+package org.apache.cayenne.crypto.cipher;
+
+import javax.crypto.Cipher;
+
+/**
+ * @since 3.2
+ */
+public interface CipherFactory {
+
+    /**
+     * Creates and returns a new {@link Cipher} configured using settings known
+     * to the factory implementation.
+     * 
+     * @return a new Cipher that is guaranteed to be unused by other callers or
+     *         null if the factory does not support cipher-based encryption.
+     */
+    Cipher cipher();
+}

Added: 
cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/cipher/DefaultCipherFactory.java
URL: 
http://svn.apache.org/viewvc/cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/cipher/DefaultCipherFactory.java?rev=1582771&view=auto
==============================================================================
--- 
cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/cipher/DefaultCipherFactory.java
 (added)
+++ 
cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/cipher/DefaultCipherFactory.java
 Fri Mar 28 14:56:46 2014
@@ -0,0 +1,70 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+package org.apache.cayenne.crypto.cipher;
+
+import java.security.NoSuchAlgorithmException;
+import java.util.Map;
+
+import javax.crypto.Cipher;
+import javax.crypto.NoSuchPaddingException;
+
+import org.apache.cayenne.crypto.CayenneCryptoException;
+import org.apache.cayenne.crypto.CryptoConstants;
+import org.apache.cayenne.di.Inject;
+
+/**
+ * @since 3.2
+ */
+public class DefaultCipherFactory implements CipherFactory {
+
+    protected String transformation;
+
+    public DefaultCipherFactory(@Inject(CryptoConstants.PROPERTIES_MAP) 
Map<String, String> properties) {
+        String algorithm = properties.get(CryptoConstants.CIPHER_ALGORITHM);
+
+        if (algorithm == null) {
+            throw new CayenneCryptoException("Cipher algorithm is not set. 
Property name: "
+                    + CryptoConstants.CIPHER_ALGORITHM);
+        }
+
+        String mode = properties.get(CryptoConstants.CIPHER_MODE);
+        if (mode == null) {
+            throw new CayenneCryptoException("Cipher mode is not set. Property 
name: " + CryptoConstants.CIPHER_MODE);
+        }
+
+        String padding = properties.get(CryptoConstants.CIPHER_PADDING);
+        if (padding == null) {
+            throw new CayenneCryptoException("Cipher padding is not set. 
Property name: "
+                    + CryptoConstants.CIPHER_PADDING);
+        }
+
+        this.transformation = algorithm + "/" + mode + "/" + padding;
+    }
+
+    @Override
+    public Cipher cipher() {
+        try {
+            return Cipher.getInstance(transformation);
+        } catch (NoSuchAlgorithmException e) {
+            throw new CayenneCryptoException("Error instantiating a cipher - 
no such algorithm: " + transformation, e);
+        } catch (NoSuchPaddingException e) {
+            throw new CayenneCryptoException("Error instantiating a cipher - 
no such padding: " + transformation, e);
+        }
+    }
+}

Modified: 
cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/DefaultTransformerFactory.java
URL: 
http://svn.apache.org/viewvc/cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/DefaultTransformerFactory.java?rev=1582771&r1=1582770&r2=1582771&view=diff
==============================================================================
--- 
cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/DefaultTransformerFactory.java
 (original)
+++ 
cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/DefaultTransformerFactory.java
 Fri Mar 28 14:56:46 2014
@@ -24,18 +24,22 @@ import java.util.Map;
 
 import org.apache.cayenne.access.jdbc.ColumnDescriptor;
 import org.apache.cayenne.access.translator.batch.BatchParameterBinding;
+import org.apache.cayenne.crypto.cipher.CipherFactory;
 import org.apache.cayenne.crypto.map.ColumnMapper;
 import org.apache.cayenne.di.Inject;
 import org.apache.cayenne.map.DbAttribute;
 
 public class DefaultTransformerFactory implements TransformerFactory {
 
+    private CipherFactory cipherFactory;
     private ColumnMapper columnMapper;
     private ValueTransformerFactory transformerFactory;
 
-    public DefaultTransformerFactory(@Inject ColumnMapper columnMapper, 
@Inject ValueTransformerFactory transformerFactory) {
+    public DefaultTransformerFactory(@Inject ColumnMapper columnMapper,
+            @Inject ValueTransformerFactory transformerFactory, @Inject 
CipherFactory cipherFactory) {
         this.columnMapper = columnMapper;
         this.transformerFactory = transformerFactory;
+        this.cipherFactory = cipherFactory;
     }
 
     @Override
@@ -73,8 +77,7 @@ public class DefaultTransformerFactory i
                 transformers[i] = 
transformerFactory.decryptor(cd.getAttribute().getType());
             }
 
-            // TODO: use real cipher
-            return new DefaultMapTransformer(keys, transformers, null);
+            return new DefaultMapTransformer(keys, transformers, 
cipherFactory.cipher());
         }
 
         return null;
@@ -111,8 +114,7 @@ public class DefaultTransformerFactory i
                 transformers[i] = 
transformerFactory.encryptor(b.getAttribute().getType());
             }
 
-            // TODO: use real cipher
-            return new DefaultBindingsTransformer(positions, transformers, 
null);
+            return new DefaultBindingsTransformer(positions, transformers, 
cipherFactory.cipher());
         }
 
         return null;

Added: 
cayenne/main/trunk/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/cipher/DefaultCipherFactoryTest.java
URL: 
http://svn.apache.org/viewvc/cayenne/main/trunk/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/cipher/DefaultCipherFactoryTest.java?rev=1582771&view=auto
==============================================================================
--- 
cayenne/main/trunk/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/cipher/DefaultCipherFactoryTest.java
 (added)
+++ 
cayenne/main/trunk/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/cipher/DefaultCipherFactoryTest.java
 Fri Mar 28 14:56:46 2014
@@ -0,0 +1,77 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+package org.apache.cayenne.crypto.cipher;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.crypto.Cipher;
+
+import junit.framework.TestCase;
+
+import org.apache.cayenne.crypto.CayenneCryptoException;
+import org.apache.cayenne.crypto.CryptoConstants;
+
+public class DefaultCipherFactoryTest extends TestCase {
+
+    public void testConstructor() {
+
+        Map<String, String> properties = new HashMap<String, String>();
+
+        try {
+            new DefaultCipherFactory(properties);
+            fail("Must have thrown");
+        } catch (CayenneCryptoException e) {
+            // expected
+        }
+
+        properties.put(CryptoConstants.CIPHER_ALGORITHM, "AES");
+        try {
+            new DefaultCipherFactory(properties);
+            fail("Must have thrown");
+        } catch (CayenneCryptoException e) {
+            // expected
+        }
+
+        properties.put(CryptoConstants.CIPHER_MODE, "CBC");
+        try {
+            new DefaultCipherFactory(properties);
+            fail("Must have thrown");
+        } catch (CayenneCryptoException e) {
+            // expected
+        }
+
+        properties.put(CryptoConstants.CIPHER_PADDING, "PKCS5Padding");
+        DefaultCipherFactory f = new DefaultCipherFactory(properties);
+        assertEquals("AES/CBC/PKCS5Padding", f.transformation);
+    }
+
+    public void testGetCipher() {
+        Map<String, String> properties = new HashMap<String, String>();
+        properties.put(CryptoConstants.CIPHER_ALGORITHM, "AES");
+        properties.put(CryptoConstants.CIPHER_MODE, "CBC");
+        properties.put(CryptoConstants.CIPHER_PADDING, "PKCS5Padding");
+
+        DefaultCipherFactory f = new DefaultCipherFactory(properties);
+        Cipher c = f.cipher();
+        assertNotNull(c);
+        assertEquals("AES/CBC/PKCS5Padding", c.getAlgorithm());
+    }
+
+}


Reply via email to