You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cayenne.apache.org by aa...@apache.org on 2014/04/04 14:04:31 UTC

svn commit: r1584631 - in /cayenne/main/trunk/cayenne-crypto/src: main/java/org/apache/cayenne/crypto/ main/java/org/apache/cayenne/crypto/cipher/ main/java/org/apache/cayenne/crypto/key/ main/java/org/apache/cayenne/crypto/transformer/ main/java/org/a...

Author: aadamchik
Date: Fri Apr  4 12:04:30 2014
New Revision: 1584631

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

* switching the framework to BytesDecryptor/ByteEncryptor
* a concept of default Key

Added:
    cayenne/main/trunk/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/unit/SwapBytesTransformer.java
    cayenne/main/trunk/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/unit/SwapBytesTransformerTest.java
      - copied, changed from r1584630, cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/key/KeySource.java
Modified:
    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/CryptoModuleBuilder.java
    cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/cipher/DefaultCipherFactory.java
    cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/key/JceksKeySource.java
    cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/key/KeySource.java
    cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/DefaultBindingsTransformer.java
    cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/DefaultMapTransformer.java
    cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/DefaultTransformerFactory.java
    cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/bytes/CbcBytesTransformerFactory.java
    cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/bytes/CbcDecryptor.java
    cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/bytes/DefaultBytesTransformerFactory.java
    cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/value/DefaultDecryptor.java
    cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/value/DefaultEncryptor.java
    cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/value/DefaultValueTransformerFactory.java
    cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/value/ValueDecryptor.java
    cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/value/ValueEncryptor.java
    cayenne/main/trunk/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/CryptoModuleBuilderTest.java
    cayenne/main/trunk/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/Runtime_Rot13_Test.java
    cayenne/main/trunk/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/key/JceksKeySourceTest.java
    cayenne/main/trunk/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/transformer/value/DefaultEncryptorTest.java
    cayenne/main/trunk/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/transformer/value/DefaultValueTransformerFactoryTest.java
    cayenne/main/trunk/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/unit/Rot13TransformerFactory.java

Modified: 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=1584631&r1=1584630&r2=1584631&view=diff
==============================================================================
--- cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/CryptoConstants.java (original)
+++ cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/CryptoConstants.java Fri Apr  4 12:04:30 2014
@@ -56,6 +56,6 @@ public interface CryptoConstants {
     /**
      * A symbolic name of the default encryption key in the keystore.
      */
-    public static final String DEFAULT_KEY_ALIAS = "cayenne.crypto.key.alias";
+    public static final String DEFAULT_KEY_ALIAS = "cayenne.crypto.key.defaultalias";
 
 }

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=1584631&r1=1584630&r2=1584631&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 Apr  4 12:04:30 2014
@@ -27,8 +27,8 @@ import org.apache.cayenne.access.transla
 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.key.KeySource;
 import org.apache.cayenne.crypto.key.JceksKeySource;
+import org.apache.cayenne.crypto.key.KeySource;
 import org.apache.cayenne.crypto.map.ColumnMapper;
 import org.apache.cayenne.crypto.map.PatternColumnMapper;
 import org.apache.cayenne.crypto.reader.CryptoRowReaderFactoryDecorator;
@@ -57,6 +57,7 @@ public class CryptoModuleBuilder {
     private static final String DEFAULT_CIPHER_PADDING = "PKCS5Padding";
 
     private Class<? extends ValueTransformerFactory> valueTransformerFactoryType;
+    private Class<? extends BytesTransformerFactory> bytesTransformerFactoryType;
 
     private String columnMapperPattern;
     private ColumnMapper columnMapper;
@@ -71,6 +72,9 @@ public class CryptoModuleBuilder {
     private String keyStoreUrlString;
     private File keyStoreFile;
     private Class<? extends KeySource> keySourceType;
+    private KeySource keySource;
+
+    private String defaultKeyAlias;
 
     private char[] keyPassword;
 
@@ -86,8 +90,9 @@ public class CryptoModuleBuilder {
         this.keySourceType = JceksKeySource.class;
 
         this.columnMapperPattern = "^CRYPTO_";
-        
+
         this.valueTransformerFactoryType = DefaultValueTransformerFactory.class;
+        this.bytesTransformerFactoryType = DefaultBytesTransformerFactory.class;
     }
 
     public CryptoModuleBuilder cipherAlgorithm(String algorithm) {
@@ -109,6 +114,11 @@ public class CryptoModuleBuilder {
         this.valueTransformerFactoryType = factoryType;
         return this;
     }
+    
+    public CryptoModuleBuilder bytesTransformer(Class<? extends BytesTransformerFactory> factoryType) {
+        this.bytesTransformerFactoryType = factoryType;
+        return this;
+    }
 
     public CryptoModuleBuilder columnMapper(Class<? extends ColumnMapper> columnMapperType) {
         this.columnMapperPattern = null;
@@ -177,6 +187,18 @@ public class CryptoModuleBuilder {
 
     public CryptoModuleBuilder keySource(Class<? extends KeySource> type) {
         this.keySourceType = type;
+        this.keySource = null;
+        return this;
+    }
+
+    public CryptoModuleBuilder keySource(KeySource keySource) {
+        this.keySourceType = null;
+        this.keySource = keySource;
+        return this;
+    }
+
+    public CryptoModuleBuilder defaultKeyAlias(String defaultKeyAlias) {
+        this.defaultKeyAlias = defaultKeyAlias;
         return this;
     }
 
@@ -225,6 +247,10 @@ public class CryptoModuleBuilder {
                     props.put(CryptoConstants.KEYSTORE_URL, keyStoreUrl);
                 }
 
+                if (defaultKeyAlias != null) {
+                    props.put(CryptoConstants.DEFAULT_KEY_ALIAS, defaultKeyAlias);
+                }
+
                 // char[] credentials... stored as char[] to potentially allow
                 // wiping them clean in memory...
                 MapBuilder<char[]> creds = binder.<char[]> bindMap(CryptoConstants.CREDENTIALS_MAP);
@@ -236,8 +262,13 @@ public class CryptoModuleBuilder {
                 binder.bind(CipherFactory.class).to(cipherFactoryType);
                 binder.bind(TransformerFactory.class).to(DefaultTransformerFactory.class);
                 binder.bind(ValueTransformerFactory.class).to(valueTransformerFactoryType);
-                binder.bind(BytesTransformerFactory.class).to(DefaultBytesTransformerFactory.class);
-                binder.bind(KeySource.class).to(keySourceType);
+                binder.bind(BytesTransformerFactory.class).to(bytesTransformerFactoryType);
+
+                if (keySource != null) {
+                    binder.bind(KeySource.class).toInstance(keySource);
+                } else {
+                    binder.bind(KeySource.class).to(keySourceType);
+                }
 
                 if (columnMapperPattern != null) {
                     binder.bind(ColumnMapper.class).toInstance(new PatternColumnMapper(columnMapperPattern));

Modified: 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=1584631&r1=1584630&r2=1584631&view=diff
==============================================================================
--- cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/cipher/DefaultCipherFactory.java (original)
+++ cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/cipher/DefaultCipherFactory.java Fri Apr  4 12:04:30 2014
@@ -59,7 +59,6 @@ public class DefaultCipherFactory implem
         }
 
         this.transformation = algorithm + "/" + mode + "/" + padding;
-        this.blockSize = cipher().getBlockSize();
     }
 
     @Override
@@ -72,9 +71,17 @@ public class DefaultCipherFactory implem
             throw new CayenneCryptoException("Error instantiating a cipher - no such padding: " + transformation, e);
         }
     }
-    
+
     @Override
     public int blockSize() {
+
+        // lazy init to prevent Cipher initialization in constructor.
+        // synchronization is not required - if we do it multiple times ,
+        // shouldn't be a big deal...
+        if (blockSize == 0) {
+            this.blockSize = cipher().getBlockSize();
+        }
+
         return blockSize;
     }
 }

Modified: cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/key/JceksKeySource.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/key/JceksKeySource.java?rev=1584631&r1=1584630&r2=1584631&view=diff
==============================================================================
--- cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/key/JceksKeySource.java (original)
+++ cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/key/JceksKeySource.java Fri Apr  4 12:04:30 2014
@@ -46,14 +46,14 @@ public class JceksKeySource implements K
 
     private KeyStore keyStore;
     private char[] keyPassword;
+    private String defaultKeyAlias;
 
     public JceksKeySource(@Inject(CryptoConstants.PROPERTIES_MAP) Map<String, String> properties,
             @Inject(CryptoConstants.CREDENTIALS_MAP) Map<String, char[]> credentials) {
 
         String keyStoreUrl = properties.get(CryptoConstants.KEYSTORE_URL);
         if (keyStoreUrl == null) {
-            throw new CayenneCryptoException("KeyStore URL is not set. Property name: "
-                    + CryptoConstants.KEYSTORE_URL);
+            throw new CayenneCryptoException("KeyStore URL is not set. Property name: " + CryptoConstants.KEYSTORE_URL);
         }
 
         this.keyPassword = credentials.get(CryptoConstants.KEY_PASSWORD);
@@ -64,6 +64,12 @@ public class JceksKeySource implements K
         } catch (Exception e) {
             throw new CayenneCryptoException("Error loading keystore at " + keyStoreUrl, e);
         }
+
+        this.defaultKeyAlias = properties.get(CryptoConstants.DEFAULT_KEY_ALIAS);
+        if (defaultKeyAlias == null) {
+            throw new CayenneCryptoException("Default key alias is not set. Property name: "
+                    + CryptoConstants.DEFAULT_KEY_ALIAS);
+        }
     }
 
     private KeyStore createKeyStore(String keyStoreUrl) throws KeyStoreException, IOException,
@@ -91,4 +97,9 @@ public class JceksKeySource implements K
             throw new CayenneCryptoException("Error accessing key for alias: " + alias, e);
         }
     }
+
+    @Override
+    public String getDefaultKeyAlias() {
+        return defaultKeyAlias;
+    }
 }

Modified: cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/key/KeySource.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/key/KeySource.java?rev=1584631&r1=1584630&r2=1584631&view=diff
==============================================================================
--- cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/key/KeySource.java (original)
+++ cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/key/KeySource.java Fri Apr  4 12:04:30 2014
@@ -28,4 +28,9 @@ public interface KeySource {
      */
     Key getKey(String alias);
 
+    /**
+     * Returns an alias of the default key.
+     */
+    String getDefaultKeyAlias();
+
 }

Modified: cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/DefaultBindingsTransformer.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/DefaultBindingsTransformer.java?rev=1584631&r1=1584630&r2=1584631&view=diff
==============================================================================
--- cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/DefaultBindingsTransformer.java (original)
+++ cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/DefaultBindingsTransformer.java Fri Apr  4 12:04:30 2014
@@ -18,9 +18,8 @@
  ****************************************************************/
 package org.apache.cayenne.crypto.transformer;
 
-import javax.crypto.Cipher;
-
 import org.apache.cayenne.access.translator.batch.BatchParameterBinding;
+import org.apache.cayenne.crypto.transformer.bytes.BytesEncryptor;
 import org.apache.cayenne.crypto.transformer.value.ValueEncryptor;
 
 /**
@@ -30,12 +29,12 @@ public class DefaultBindingsTransformer 
 
     private int[] positions;
     private ValueEncryptor[] transformers;
-    private Cipher cipher;
+    private BytesEncryptor encryptor;
 
-    public DefaultBindingsTransformer(int[] positions, ValueEncryptor[] transformers, Cipher cipher) {
+    public DefaultBindingsTransformer(int[] positions, ValueEncryptor[] transformers, BytesEncryptor encryptor) {
         this.positions = positions;
         this.transformers = transformers;
-        this.cipher = cipher;
+        this.encryptor = encryptor;
     }
 
     @Override
@@ -45,7 +44,7 @@ public class DefaultBindingsTransformer 
 
         for (int i = 0; i < len; i++) {
             BatchParameterBinding b = bindings[positions[i]];
-            Object transformed = transformers[i].encrypt(cipher, b.getValue());
+            Object transformed = transformers[i].encrypt(encryptor, b.getValue());
             b.setValue(transformed);
         }
     }

Modified: cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/DefaultMapTransformer.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/DefaultMapTransformer.java?rev=1584631&r1=1584630&r2=1584631&view=diff
==============================================================================
--- cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/DefaultMapTransformer.java (original)
+++ cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/DefaultMapTransformer.java Fri Apr  4 12:04:30 2014
@@ -20,8 +20,7 @@ package org.apache.cayenne.crypto.transf
 
 import java.util.Map;
 
-import javax.crypto.Cipher;
-
+import org.apache.cayenne.crypto.transformer.bytes.BytesDecryptor;
 import org.apache.cayenne.crypto.transformer.value.ValueDecryptor;
 
 /**
@@ -31,12 +30,12 @@ public class DefaultMapTransformer imple
 
     private String[] mapKeys;
     private ValueDecryptor[] transformers;
-    private Cipher cipher;
+    private BytesDecryptor bytesDecryptor;
 
-    public DefaultMapTransformer(String[] mapKeys, ValueDecryptor[] transformers, Cipher cipher) {
+    public DefaultMapTransformer(String[] mapKeys, ValueDecryptor[] transformers, BytesDecryptor bytesDecryptor) {
         this.mapKeys = mapKeys;
         this.transformers = transformers;
-        this.cipher = cipher;
+        this.bytesDecryptor = bytesDecryptor;
     }
 
     @Override
@@ -48,7 +47,7 @@ public class DefaultMapTransformer imple
             Object value = map.get(mapKeys[i]);
 
             if (value != null) {
-                Object transformed = transformers[i].decrypt(cipher, value);
+                Object transformed = transformers[i].decrypt(bytesDecryptor, value);
                 map.put(mapKeys[i], transformed);
             }
         }

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=1584631&r1=1584630&r2=1584631&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 Apr  4 12:04:30 2014
@@ -24,8 +24,8 @@ 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.crypto.transformer.bytes.BytesTransformerFactory;
 import org.apache.cayenne.crypto.transformer.value.ValueDecryptor;
 import org.apache.cayenne.crypto.transformer.value.ValueEncryptor;
 import org.apache.cayenne.crypto.transformer.value.ValueTransformerFactory;
@@ -37,15 +37,15 @@ import org.apache.cayenne.map.DbAttribut
  */
 public class DefaultTransformerFactory implements TransformerFactory {
 
-    private CipherFactory cipherFactory;
+    private BytesTransformerFactory bytesTransformerFactory;
     private ColumnMapper columnMapper;
     private ValueTransformerFactory transformerFactory;
 
     public DefaultTransformerFactory(@Inject ColumnMapper columnMapper,
-            @Inject ValueTransformerFactory transformerFactory, @Inject CipherFactory cipherFactory) {
+            @Inject ValueTransformerFactory transformerFactory, @Inject BytesTransformerFactory bytesTransformerFactory) {
         this.columnMapper = columnMapper;
         this.transformerFactory = transformerFactory;
-        this.cipherFactory = cipherFactory;
+        this.bytesTransformerFactory = bytesTransformerFactory;
     }
 
     @Override
@@ -83,7 +83,7 @@ public class DefaultTransformerFactory i
                 transformers[i] = transformerFactory.decryptor(cd.getAttribute());
             }
 
-            return new DefaultMapTransformer(mapKeys, transformers, cipherFactory.cipher());
+            return new DefaultMapTransformer(mapKeys, transformers, bytesTransformerFactory.decryptor());
         }
 
         return null;
@@ -120,7 +120,7 @@ public class DefaultTransformerFactory i
                 transformers[i] = transformerFactory.encryptor(b.getAttribute());
             }
 
-            return new DefaultBindingsTransformer(positions, transformers, cipherFactory.cipher());
+            return new DefaultBindingsTransformer(positions, transformers, bytesTransformerFactory.encryptor());
         }
 
         return null;

Modified: cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/bytes/CbcBytesTransformerFactory.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/bytes/CbcBytesTransformerFactory.java?rev=1584631&r1=1584630&r2=1584631&view=diff
==============================================================================
--- cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/bytes/CbcBytesTransformerFactory.java (original)
+++ cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/bytes/CbcBytesTransformerFactory.java Fri Apr  4 12:04:30 2014
@@ -44,10 +44,13 @@ class CbcBytesTransformerFactory impleme
     private KeySource keySource;
     private Queue<SecureRandom> randoms;
 
-    public CbcBytesTransformerFactory(CipherFactory cipherFactory, KeySource keySource, String keyName) {
+    public CbcBytesTransformerFactory(CipherFactory cipherFactory, KeySource keySource) {
+
+        String keyName = keySource.getDefaultKeyAlias();
 
         this.randoms = new ConcurrentLinkedQueue<SecureRandom>();
         this.keySource = keySource;
+        this.key = keySource.getKey(keyName);
         this.cipherFactory = cipherFactory;
         this.blockSize = cipherFactory.blockSize();
 

Modified: cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/bytes/CbcDecryptor.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/bytes/CbcDecryptor.java?rev=1584631&r1=1584630&r2=1584631&view=diff
==============================================================================
--- cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/bytes/CbcDecryptor.java (original)
+++ cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/bytes/CbcDecryptor.java Fri Apr  4 12:04:30 2014
@@ -31,6 +31,10 @@ import javax.crypto.spec.IvParameterSpec
 import org.apache.cayenne.crypto.CayenneCryptoException;
 
 /**
+ * A {@link BytesDecryptor} that decrypts the provided bytes that were encrypted
+ * by the complimentary {@link CbcEncryptor}. The object is stateful and is not
+ * thread-safe.
+ * 
  * @since 3.2
  */
 class CbcDecryptor implements BytesDecryptor {

Modified: cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/bytes/DefaultBytesTransformerFactory.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/bytes/DefaultBytesTransformerFactory.java?rev=1584631&r1=1584630&r2=1584631&view=diff
==============================================================================
--- cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/bytes/DefaultBytesTransformerFactory.java (original)
+++ cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/bytes/DefaultBytesTransformerFactory.java Fri Apr  4 12:04:30 2014
@@ -44,14 +44,8 @@ public class DefaultBytesTransformerFact
             throw new CayenneCryptoException("Cipher mode is not set. Property name: " + CryptoConstants.CIPHER_MODE);
         }
 
-        String keyName = properties.get(CryptoConstants.DEFAULT_KEY_ALIAS);
-        if (keyName == null) {
-            throw new CayenneCryptoException("Default key alias is not set. Property name: "
-                    + CryptoConstants.DEFAULT_KEY_ALIAS);
-        }
-
         if ("CBC".equals(mode)) {
-            this.delegate = new CbcBytesTransformerFactory(cipherFactory, keySource, keyName);
+            this.delegate = new CbcBytesTransformerFactory(cipherFactory, keySource);
         }
         // TODO: ECB and other modes...
         else {

Modified: cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/value/DefaultDecryptor.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/value/DefaultDecryptor.java?rev=1584631&r1=1584630&r2=1584631&view=diff
==============================================================================
--- cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/value/DefaultDecryptor.java (original)
+++ cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/value/DefaultDecryptor.java Fri Apr  4 12:04:30 2014
@@ -18,21 +18,20 @@
  ****************************************************************/
 package org.apache.cayenne.crypto.transformer.value;
 
-import javax.crypto.BadPaddingException;
-import javax.crypto.Cipher;
-import javax.crypto.IllegalBlockSizeException;
+import java.security.Key;
 
-import org.apache.cayenne.crypto.CayenneCryptoException;
+import org.apache.cayenne.crypto.transformer.bytes.BytesDecryptor;
 
 /**
  * @since 3.2
  */
 class DefaultDecryptor implements ValueDecryptor {
 
+    private Key defaultKey;
     private BytesConverter preConverter;
     private BytesConverter postConverter;
 
-    public DefaultDecryptor(BytesConverter preConverter, BytesConverter postConverter) {
+    public DefaultDecryptor(BytesConverter preConverter, BytesConverter postConverter, Key defaultKey) {
         this.preConverter = preConverter;
         this.postConverter = postConverter;
     }
@@ -46,19 +45,13 @@ class DefaultDecryptor implements ValueD
     }
 
     @Override
-    public Object decrypt(Cipher cipher, Object value) {
+    public Object decrypt(BytesDecryptor bytesDecryptor, Object value) {
 
         byte[] bytes = preConverter.toBytes(value);
-        byte[] transformed;
-
-        try {
-            transformed = cipher.doFinal(bytes);
-        } catch (IllegalBlockSizeException e) {
-            throw new CayenneCryptoException("Illegal block size", e);
-        } catch (BadPaddingException e) {
-            throw new CayenneCryptoException("Bad padding", e);
-        }
 
+        // 'defaultKey' is likely to be ignored by the BytesDecryptor, as the
+        // key name is obtained from the record itself
+        byte[] transformed = bytesDecryptor.decrypt(bytes, 0, defaultKey);
         return postConverter.fromBytes(transformed);
     }
 

Modified: cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/value/DefaultEncryptor.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/value/DefaultEncryptor.java?rev=1584631&r1=1584630&r2=1584631&view=diff
==============================================================================
--- cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/value/DefaultEncryptor.java (original)
+++ cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/value/DefaultEncryptor.java Fri Apr  4 12:04:30 2014
@@ -18,11 +18,7 @@
  ****************************************************************/
 package org.apache.cayenne.crypto.transformer.value;
 
-import javax.crypto.BadPaddingException;
-import javax.crypto.Cipher;
-import javax.crypto.IllegalBlockSizeException;
-
-import org.apache.cayenne.crypto.CayenneCryptoException;
+import org.apache.cayenne.crypto.transformer.bytes.BytesEncryptor;
 
 /**
  * @since 3.2
@@ -46,18 +42,12 @@ class DefaultEncryptor implements ValueE
     }
 
     @Override
-    public Object encrypt(Cipher cipher, Object value) {
+    public Object encrypt(BytesEncryptor encryptor, Object value) {
 
         byte[] bytes = preConverter.toBytes(value);
-        byte[] transformed;
+        byte[] transformed = new byte[encryptor.getOutputSize(bytes.length)];
 
-        try {
-            transformed = cipher.doFinal(bytes);
-        } catch (IllegalBlockSizeException e) {
-            throw new CayenneCryptoException("Illegal block size", e);
-        } catch (BadPaddingException e) {
-            throw new CayenneCryptoException("Bad padding", e);
-        }
+        encryptor.encrypt(bytes, transformed, 0);
 
         return postConverter.fromBytes(transformed);
     }

Modified: cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/value/DefaultValueTransformerFactory.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/value/DefaultValueTransformerFactory.java?rev=1584631&r1=1584630&r2=1584631&view=diff
==============================================================================
--- cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/value/DefaultValueTransformerFactory.java (original)
+++ cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/value/DefaultValueTransformerFactory.java Fri Apr  4 12:04:30 2014
@@ -18,6 +18,7 @@
  ****************************************************************/
 package org.apache.cayenne.crypto.transformer.value;
 
+import java.security.Key;
 import java.sql.Types;
 import java.util.Collection;
 import java.util.HashMap;
@@ -26,7 +27,9 @@ import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 
+import org.apache.cayenne.crypto.key.KeySource;
 import org.apache.cayenne.dba.TypesMapping;
+import org.apache.cayenne.di.Inject;
 import org.apache.cayenne.map.DataMap;
 import org.apache.cayenne.map.DbAttribute;
 import org.apache.cayenne.map.DbEntity;
@@ -41,6 +44,8 @@ import org.apache.cayenne.map.ObjEntity;
  */
 public class DefaultValueTransformerFactory implements ValueTransformerFactory {
 
+    private Key defaultKey;
+
     private Map<String, BytesConverter> objectToBytes;
     private Map<Integer, BytesConverter> dbToBytes;
 
@@ -50,7 +55,9 @@ public class DefaultValueTransformerFact
     private ConcurrentMap<DbAttribute, ValueEncryptor> encryptors;
     private ConcurrentMap<DbAttribute, ValueDecryptor> decryptors;
 
-    public DefaultValueTransformerFactory() {
+    public DefaultValueTransformerFactory(@Inject KeySource keySource) {
+        this.defaultKey = keySource.getKey(keySource.getDefaultKeyAlias());
+
         this.encryptors = new ConcurrentHashMap<DbAttribute, ValueEncryptor>();
         this.decryptors = new ConcurrentHashMap<DbAttribute, ValueDecryptor>();
 
@@ -175,7 +182,7 @@ public class DefaultValueTransformerFact
                     + " has no bytes-to-object conversion");
         }
 
-        return new DefaultDecryptor(toBytes, fromBytes);
+        return new DefaultDecryptor(toBytes, fromBytes, defaultKey);
     }
 
     // TODO: calculating Java type of ObjAttribute may become unneeded per

Modified: cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/value/ValueDecryptor.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/value/ValueDecryptor.java?rev=1584631&r1=1584630&r2=1584631&view=diff
==============================================================================
--- cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/value/ValueDecryptor.java (original)
+++ cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/value/ValueDecryptor.java Fri Apr  4 12:04:30 2014
@@ -18,16 +18,17 @@
  ****************************************************************/
 package org.apache.cayenne.crypto.transformer.value;
 
-import javax.crypto.Cipher;
+import org.apache.cayenne.crypto.transformer.bytes.BytesDecryptor;
 
 /**
  * @since 3.2
  */
 public interface ValueDecryptor {
+
     /**
      * Transforms a value using the provided Cipher. Cipher is assumed to be
      * fully initialized for the right operation (encryption or decryption) and
      * its state reset from any previous operations.
      */
-    Object decrypt(Cipher cipher, Object value);
+    Object decrypt(BytesDecryptor bytesDecryptor, Object value);
 }

Modified: cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/value/ValueEncryptor.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/value/ValueEncryptor.java?rev=1584631&r1=1584630&r2=1584631&view=diff
==============================================================================
--- cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/value/ValueEncryptor.java (original)
+++ cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/value/ValueEncryptor.java Fri Apr  4 12:04:30 2014
@@ -18,7 +18,7 @@
  ****************************************************************/
 package org.apache.cayenne.crypto.transformer.value;
 
-import javax.crypto.Cipher;
+import org.apache.cayenne.crypto.transformer.bytes.BytesEncryptor;
 
 /**
  * An encryptor or decryptor of a single value.
@@ -28,9 +28,7 @@ import javax.crypto.Cipher;
 public interface ValueEncryptor {
 
     /**
-     * Transforms a value using the provided Cipher. Cipher is assumed to be
-     * fully initialized for the right operation (encryption or decryption) and
-     * its state reset from any previous operations.
+     * Transforms a value using the provided BytesEncryptor.
      */
-    Object encrypt(Cipher cipher, Object value);
+    Object encrypt(BytesEncryptor bytesEncryptor, Object value);
 }

Modified: cayenne/main/trunk/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/CryptoModuleBuilderTest.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/CryptoModuleBuilderTest.java?rev=1584631&r1=1584630&r2=1584631&view=diff
==============================================================================
--- cayenne/main/trunk/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/CryptoModuleBuilderTest.java (original)
+++ cayenne/main/trunk/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/CryptoModuleBuilderTest.java Fri Apr  4 12:04:30 2014
@@ -23,8 +23,8 @@ import static org.junit.Assert.assertNot
 
 import java.security.Key;
 
-import org.apache.cayenne.crypto.key.KeySource;
 import org.apache.cayenne.crypto.key.JceksKeySourceTest;
+import org.apache.cayenne.crypto.key.KeySource;
 import org.apache.cayenne.crypto.transformer.value.DefaultValueTransformerFactory;
 import org.apache.cayenne.di.DIBootstrap;
 import org.apache.cayenne.di.Injector;
@@ -37,7 +37,7 @@ public class CryptoModuleBuilderTest {
     public void testBuild_KeySource() {
         Module m = new CryptoModuleBuilder().keyPassword(JceksKeySourceTest.TEST_KEY_PASS)
                 .keyStore(JceksKeySourceTest.class.getResource(JceksKeySourceTest.KS1_JCEKS))
-                .valueTransformer(DefaultValueTransformerFactory.class).build();
+                .valueTransformer(DefaultValueTransformerFactory.class).defaultKeyAlias("k1").build();
 
         Injector injector = DIBootstrap.createInjector(m);
 
@@ -45,6 +45,10 @@ public class CryptoModuleBuilderTest {
         Key k1 = ks.getKey("k1");
         assertNotNull(k1);
         assertEquals("DES", k1.getAlgorithm());
+
+        String dkName = ks.getDefaultKeyAlias();
+
+        assertEquals("k1", dkName);
     }
 
 }

Modified: cayenne/main/trunk/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/Runtime_Rot13_Test.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/Runtime_Rot13_Test.java?rev=1584631&r1=1584630&r2=1584631&view=diff
==============================================================================
--- cayenne/main/trunk/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/Runtime_Rot13_Test.java (original)
+++ cayenne/main/trunk/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/Runtime_Rot13_Test.java Fri Apr  4 12:04:30 2014
@@ -19,6 +19,7 @@
 package org.apache.cayenne.crypto;
 
 import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.mock;
 
 import java.sql.SQLException;
 import java.util.HashMap;
@@ -28,6 +29,7 @@ import java.util.Map;
 import org.apache.cayenne.ObjectContext;
 import org.apache.cayenne.configuration.server.ServerRuntime;
 import org.apache.cayenne.crypto.db.Table1;
+import org.apache.cayenne.crypto.key.KeySource;
 import org.apache.cayenne.crypto.unit.Rot13TransformerFactory;
 import org.apache.cayenne.di.Module;
 import org.apache.cayenne.query.SelectQuery;
@@ -45,7 +47,8 @@ public class Runtime_Rot13_Test {
     @Before
     public void setUp() throws Exception {
 
-        Module crypto = new CryptoModuleBuilder().valueTransformer(Rot13TransformerFactory.class).build();
+        Module crypto = new CryptoModuleBuilder().valueTransformer(Rot13TransformerFactory.class)
+                .keySource(mock(KeySource.class)).cipherMode("dummy").build();
 
         this.runtime = new ServerRuntime("cayenne-crypto.xml", crypto);
 

Modified: cayenne/main/trunk/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/key/JceksKeySourceTest.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/key/JceksKeySourceTest.java?rev=1584631&r1=1584630&r2=1584631&view=diff
==============================================================================
--- cayenne/main/trunk/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/key/JceksKeySourceTest.java (original)
+++ cayenne/main/trunk/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/key/JceksKeySourceTest.java Fri Apr  4 12:04:30 2014
@@ -51,6 +51,7 @@ public class JceksKeySourceTest {
 
         Map<String, String> props = new HashMap<String, String>();
         props.put(CryptoConstants.KEYSTORE_URL, url.toExternalForm());
+        props.put(CryptoConstants.DEFAULT_KEY_ALIAS, "k2");
 
         Map<String, char[]> creds = new HashMap<String, char[]>();
         creds.put(CryptoConstants.KEY_PASSWORD, TEST_KEY_PASS);

Modified: cayenne/main/trunk/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/transformer/value/DefaultEncryptorTest.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/transformer/value/DefaultEncryptorTest.java?rev=1584631&r1=1584630&r2=1584631&view=diff
==============================================================================
--- cayenne/main/trunk/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/transformer/value/DefaultEncryptorTest.java (original)
+++ cayenne/main/trunk/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/transformer/value/DefaultEncryptorTest.java Fri Apr  4 12:04:30 2014
@@ -28,35 +28,25 @@ import java.security.InvalidKeyException
 import java.security.NoSuchAlgorithmException;
 
 import javax.crypto.BadPaddingException;
-import javax.crypto.Cipher;
 import javax.crypto.IllegalBlockSizeException;
-import javax.crypto.KeyGenerator;
 import javax.crypto.NoSuchPaddingException;
-import javax.crypto.SecretKey;
 import javax.xml.bind.DatatypeConverter;
 
+import org.apache.cayenne.crypto.transformer.bytes.BytesDecryptor;
+import org.apache.cayenne.crypto.transformer.bytes.BytesEncryptor;
+import org.apache.cayenne.crypto.unit.SwapBytesTransformer;
 import org.junit.Before;
 import org.junit.Test;
 
 public class DefaultEncryptorTest {
 
-    private Cipher encCipher;
-    private Cipher decCipher;
-    private SecretKey key;
+    private BytesEncryptor encryptor;
+    private BytesDecryptor decryptor;
 
     @Before
     public void before() throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException {
-
-        KeyGenerator keyGen = KeyGenerator.getInstance("AES");
-        keyGen.init(128);
-
-        this.key = keyGen.generateKey();
-
-        this.encCipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
-        this.encCipher.init(Cipher.ENCRYPT_MODE, key);
-
-        this.decCipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
-        this.decCipher.init(Cipher.DECRYPT_MODE, key);
+        this.encryptor = SwapBytesTransformer.encryptor();
+        this.decryptor = SwapBytesTransformer.decryptor();
     }
 
     @Test
@@ -67,54 +57,15 @@ public class DefaultEncryptorTest {
         byte[] b1 = new byte[] { 1, 2 };
         byte[] b2 = new byte[] { 2, 3 };
 
-        byte[] b1_t = (byte[]) e.encrypt(encCipher, b1);
+        byte[] b1_t = (byte[]) e.encrypt(encryptor, b1);
 
         assertNotNull(b1_t);
-        assertEquals(encCipher.getBlockSize(), b1_t.length);
-        assertArrayEquals(b1, decCipher.doFinal(b1_t));
+        assertArrayEquals(b1, decryptor.decrypt(b1_t, 0, null));
 
-        byte[] b2_t = (byte[]) e.encrypt(encCipher, b2);
+        byte[] b2_t = (byte[]) e.encrypt(encryptor, b2);
 
         assertNotNull(b2_t);
-        assertEquals(encCipher.getBlockSize(), b2_t.length);
-        assertArrayEquals(b2, decCipher.doFinal(b2_t));
-    }
-
-    @Test
-    public void testTransform_BytesToBytes_DifferentSizes() {
-
-        DefaultEncryptor e = new DefaultEncryptor(BytesToBytesConverter.INSTANCE, BytesToBytesConverter.INSTANCE);
-
-        int blockSize = encCipher.getBlockSize();
-
-        byte[] b1 = new byte[] {};
-        byte[] b2 = new byte[] { 1 };
-        byte[] b3 = new byte[] { 1, 2 };
-
-        byte[] b4 = new byte[blockSize];
-        for (int i = 0; i < blockSize; i++) {
-            b4[i] = (byte) i;
-        }
-
-        byte[] b5 = new byte[blockSize + 5];
-        for (int i = 0; i < blockSize + 5; i++) {
-            b5[i] = (byte) i;
-        }
-
-        byte[] b1_t = (byte[]) e.encrypt(encCipher, b1);
-        assertEquals(encCipher.getBlockSize(), b1_t.length);
-
-        byte[] b2_t = (byte[]) e.encrypt(encCipher, b2);
-        assertEquals(encCipher.getBlockSize(), b2_t.length);
-
-        byte[] b3_t = (byte[]) e.encrypt(encCipher, b3);
-        assertEquals(encCipher.getBlockSize(), b3_t.length);
-
-        byte[] b4_t = (byte[]) e.encrypt(encCipher, b4);
-        assertEquals(encCipher.getBlockSize() * 2, b4_t.length);
-
-        byte[] b5_t = (byte[]) e.encrypt(encCipher, b5);
-        assertEquals(encCipher.getBlockSize() * 2, b5_t.length);
+        assertArrayEquals(b2, decryptor.decrypt(b2_t, 0, null));
     }
 
     @Test
@@ -126,17 +77,15 @@ public class DefaultEncryptorTest {
         String s1 = "ab";
         String s2 = "cd";
 
-        byte[] b1_t = (byte[]) e.encrypt(encCipher, s1);
+        byte[] b1_t = (byte[]) e.encrypt(encryptor, s1);
 
         assertNotNull(b1_t);
-        assertEquals(encCipher.getBlockSize(), b1_t.length);
-        assertEquals(s1, new String(decCipher.doFinal(b1_t), Utf8StringConverter.DEFAULT_CHARSET));
+        assertEquals(s1, new String(decryptor.decrypt(b1_t, 0, null), Utf8StringConverter.DEFAULT_CHARSET));
 
-        byte[] b2_t = (byte[]) e.encrypt(encCipher, s2);
+        byte[] b2_t = (byte[]) e.encrypt(encryptor, s2);
 
         assertNotNull(b2_t);
-        assertEquals(encCipher.getBlockSize(), b2_t.length);
-        assertEquals(s2, new String(decCipher.doFinal(b2_t), Utf8StringConverter.DEFAULT_CHARSET));
+        assertEquals(s2, new String(decryptor.decrypt(b2_t, 0, null), Utf8StringConverter.DEFAULT_CHARSET));
     }
 
     @Test
@@ -154,20 +103,20 @@ public class DefaultEncryptorTest {
                 + "Donec convallis mi vitae luctus rutrum. Sed ut imperdiet ante. Praesent condimentum velit eget "
                 + "felis pretium blandit. Praesent lacus tortor, facilisis eget sapien quis, hendrerit iaculis tellus.";
 
-        String s1_t = (String) e.encrypt(encCipher, s1);
+        String s1_t = (String) e.encrypt(encryptor, s1);
 
         assertNotNull(s1_t);
         assertNotEquals(s1_t, s1);
 
         byte[] b1_t = DatatypeConverter.parseBase64Binary(s1_t);
-        assertEquals(s1, new String(decCipher.doFinal(b1_t), Utf8StringConverter.DEFAULT_CHARSET));
+        assertEquals(s1, new String(decryptor.decrypt(b1_t, 0, null), Utf8StringConverter.DEFAULT_CHARSET));
 
-        String s2_t = (String) e.encrypt(encCipher, s2);
+        String s2_t = (String) e.encrypt(encryptor, s2);
 
         assertNotNull(s2_t);
         assertNotEquals(s2_t, s2);
 
         byte[] b2_t = DatatypeConverter.parseBase64Binary(s2_t);
-        assertEquals(s2, new String(decCipher.doFinal(b2_t), Utf8StringConverter.DEFAULT_CHARSET));
+        assertEquals(s2, new String(decryptor.decrypt(b2_t, 0, null), Utf8StringConverter.DEFAULT_CHARSET));
     }
 }

Modified: cayenne/main/trunk/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/transformer/value/DefaultValueTransformerFactoryTest.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/transformer/value/DefaultValueTransformerFactoryTest.java?rev=1584631&r1=1584630&r2=1584631&view=diff
==============================================================================
--- cayenne/main/trunk/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/transformer/value/DefaultValueTransformerFactoryTest.java (original)
+++ cayenne/main/trunk/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/transformer/value/DefaultValueTransformerFactoryTest.java Fri Apr  4 12:04:30 2014
@@ -28,6 +28,7 @@ import static org.mockito.Mockito.when;
 import java.sql.Types;
 
 import org.apache.cayenne.configuration.server.ServerRuntime;
+import org.apache.cayenne.crypto.key.KeySource;
 import org.apache.cayenne.map.DbAttribute;
 import org.apache.cayenne.map.DbEntity;
 import org.junit.Before;
@@ -50,7 +51,7 @@ public class DefaultValueTransformerFact
     @Test
     public void testGetJavaType() {
 
-        DefaultValueTransformerFactory f = new DefaultValueTransformerFactory();
+        DefaultValueTransformerFactory f = new DefaultValueTransformerFactory(mock(KeySource.class));
 
         DbAttribute t1_ct = t1.getAttribute("CRYPTO_STRING");
         assertEquals("java.lang.String", f.getJavaType(t1_ct));
@@ -78,7 +79,7 @@ public class DefaultValueTransformerFact
 
     @Test
     public void testCreateEncryptor() {
-        DefaultValueTransformerFactory f = new DefaultValueTransformerFactory();
+        DefaultValueTransformerFactory f = new DefaultValueTransformerFactory(mock(KeySource.class));
 
         DbAttribute t1_ct = t1.getAttribute("CRYPTO_STRING");
 
@@ -99,7 +100,7 @@ public class DefaultValueTransformerFact
 
     @Test
     public void testCreateDecryptor() {
-        DefaultValueTransformerFactory f = new DefaultValueTransformerFactory();
+        DefaultValueTransformerFactory f = new DefaultValueTransformerFactory(mock(KeySource.class));
 
         DbAttribute t1_ct = t1.getAttribute("CRYPTO_STRING");
 
@@ -128,7 +129,7 @@ public class DefaultValueTransformerFact
 
     @Test
     public void testEncryptor() {
-        DefaultValueTransformerFactory f = new DefaultValueTransformerFactory();
+        DefaultValueTransformerFactory f = new DefaultValueTransformerFactory(mock(KeySource.class));
 
         DbAttribute t1_ct = t1.getAttribute("CRYPTO_STRING");
 
@@ -144,10 +145,10 @@ public class DefaultValueTransformerFact
         assertSame(t2, f.encryptor(t2_cb));
         assertSame(t2, f.encryptor(t2_cb));
     }
-    
+
     @Test
     public void testDecryptor() {
-        DefaultValueTransformerFactory f = new DefaultValueTransformerFactory();
+        DefaultValueTransformerFactory f = new DefaultValueTransformerFactory(mock(KeySource.class));
 
         DbAttribute t1_ct = t1.getAttribute("CRYPTO_STRING");
 

Modified: cayenne/main/trunk/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/unit/Rot13TransformerFactory.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/unit/Rot13TransformerFactory.java?rev=1584631&r1=1584630&r2=1584631&view=diff
==============================================================================
--- cayenne/main/trunk/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/unit/Rot13TransformerFactory.java (original)
+++ cayenne/main/trunk/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/unit/Rot13TransformerFactory.java Fri Apr  4 12:04:30 2014
@@ -20,8 +20,8 @@ package org.apache.cayenne.crypto.unit;
 
 import java.io.UnsupportedEncodingException;
 
-import javax.crypto.Cipher;
-
+import org.apache.cayenne.crypto.transformer.bytes.BytesDecryptor;
+import org.apache.cayenne.crypto.transformer.bytes.BytesEncryptor;
 import org.apache.cayenne.crypto.transformer.value.ValueDecryptor;
 import org.apache.cayenne.crypto.transformer.value.ValueEncryptor;
 import org.apache.cayenne.crypto.transformer.value.ValueTransformerFactory;
@@ -70,15 +70,15 @@ public class Rot13TransformerFactory imp
         this.stringEncryptor = new ValueEncryptor() {
 
             @Override
-            public Object encrypt(Cipher cipher, Object value) {
+            public Object encrypt(BytesEncryptor bytesEncryptor, Object value) {
                 return value != null ? rotate(value.toString()) : null;
             }
         };
-        
+
         this.stringDecryptor = new ValueDecryptor() {
 
             @Override
-            public Object decrypt(Cipher cipher, Object value) {
+            public Object decrypt(BytesDecryptor bytesDecryptor, Object value) {
                 return value != null ? rotate(value.toString()) : null;
             }
         };

Added: cayenne/main/trunk/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/unit/SwapBytesTransformer.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/unit/SwapBytesTransformer.java?rev=1584631&view=auto
==============================================================================
--- cayenne/main/trunk/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/unit/SwapBytesTransformer.java (added)
+++ cayenne/main/trunk/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/unit/SwapBytesTransformer.java Fri Apr  4 12:04:30 2014
@@ -0,0 +1,79 @@
+/*****************************************************************
+ *   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.unit;
+
+import java.security.Key;
+
+import org.apache.cayenne.crypto.transformer.bytes.BytesDecryptor;
+import org.apache.cayenne.crypto.transformer.bytes.BytesEncryptor;
+
+/**
+ * A fake "cipher" used for unit tests that does simple bytes swapping.
+ */
+public class SwapBytesTransformer implements BytesEncryptor, BytesDecryptor {
+
+    private static final SwapBytesTransformer instance = new SwapBytesTransformer();
+
+    public static BytesEncryptor encryptor() {
+        return instance;
+    }
+
+    public static BytesDecryptor decryptor() {
+        return instance;
+    }
+
+    private SwapBytesTransformer() {
+    }
+
+    @Override
+    public byte[] decrypt(byte[] input, int inputOffset, Key key) {
+
+        byte[] output = new byte[input.length];
+        System.arraycopy(input, inputOffset, output, 0, input.length);
+
+        swap(output, 0, output.length - 1);
+        return output;
+    }
+
+    @Override
+    public void encrypt(byte[] input, byte[] output, int outputOffset) {
+        System.arraycopy(input, 0, output, outputOffset, input.length);
+
+        swap(output, outputOffset, outputOffset + input.length - 1);
+    }
+
+    private void swap(byte[] buffer, int start, int end) {
+
+        if (start >= end) {
+            return;
+        }
+
+        byte b = buffer[end];
+        buffer[end] = buffer[start];
+        buffer[start] = b;
+
+        swap(buffer, ++start, --end);
+    }
+
+    @Override
+    public int getOutputSize(int inputLength) {
+        return inputLength;
+    }
+
+}

Copied: cayenne/main/trunk/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/unit/SwapBytesTransformerTest.java (from r1584630, cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/key/KeySource.java)
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/unit/SwapBytesTransformerTest.java?p2=cayenne/main/trunk/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/unit/SwapBytesTransformerTest.java&p1=cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/key/KeySource.java&r1=1584630&r2=1584631&rev=1584631&view=diff
==============================================================================
--- cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/key/KeySource.java (original)
+++ cayenne/main/trunk/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/unit/SwapBytesTransformerTest.java Fri Apr  4 12:04:30 2014
@@ -16,16 +16,38 @@
  *  specific language governing permissions and limitations
  *  under the License.
  ****************************************************************/
-package org.apache.cayenne.crypto.key;
+package org.apache.cayenne.crypto.unit;
 
-import java.security.Key;
+import static org.junit.Assert.assertArrayEquals;
 
-public interface KeySource {
+import org.apache.cayenne.crypto.transformer.bytes.BytesEncryptor;
+import org.junit.Test;
 
-    /**
-     * Returns a named secret key that can be used for data
-     * encryption/decryption.
-     */
-    Key getKey(String alias);
+public class SwapBytesTransformerTest {
 
+    @Test
+    public void testEncrypt_Odd() {
+
+        BytesEncryptor instance = SwapBytesTransformer.encryptor();
+
+        byte[] input = { 1, 3, 5 };
+        byte[] output = { 8, 11, 13, 0, 0, 0, 5, 6 };
+
+        instance.encrypt(input, output, 3);
+
+        assertArrayEquals(new byte[] { 8, 11, 13, 5, 3, 1, 5, 6 }, output);
+    }
+    
+    @Test
+    public void testEncrypt_Even() {
+
+        BytesEncryptor instance = SwapBytesTransformer.encryptor();
+
+        byte[] input = { 1, 3, 5, 8 };
+        byte[] output = { 8, 11, 13, 0, 0, 0, 0};
+
+        instance.encrypt(input, output, 3);
+
+        assertArrayEquals(new byte[] { 8, 11, 13, 8, 5, 3, 1}, output);
+    }
 }