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());
+ }
+
+}