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/03 13:03:51 UTC
svn commit: r1584340 - 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/transformer/bytes/
test/java/org/apache/cayenne/crypto/transformer/by...
Author: aadamchik
Date: Thu Apr 3 11:03:51 2014
New Revision: 1584340
URL: http://svn.apache.org/r1584340
Log:
CAY-1916 cayenne-crypto module that enables data encryption for certain model attributes
BytesTransformer to encapsulate crypto protocol .. IN PROGRESS
Added:
cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/bytes/
cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/bytes/BytesTransformer.java
- copied, changed from r1584339, 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/transformer/bytes/BytesTransformerFactory.java
- copied, changed from r1584339, 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/transformer/bytes/CbcBytesTransformerFactory.java
cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/bytes/CbcEncryptor.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/bytes/EncryptorWithKeyName.java
- copied, changed from r1584339, cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/cipher/CipherFactory.java
cayenne/main/trunk/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/transformer/bytes/
cayenne/main/trunk/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/transformer/bytes/CbcEncryptorTest.java
cayenne/main/trunk/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/transformer/bytes/EncryptorWithKeyNameTest.java
- copied, changed from r1584339, cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/cipher/CipherFactory.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/CipherFactory.java
cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/cipher/DefaultCipherFactory.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=1584340&r1=1584339&r2=1584340&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 Thu Apr 3 11:03:51 2014
@@ -53,4 +53,9 @@ public interface CryptoConstants {
*/
public static final String KEY_PASSWORD = "cayenne.crypto.key.password";
+ /**
+ * A symbolic name of the default encryption key in the keystore.
+ */
+ public static final String DEFAULT_KEY_ALIAS = "cayenne.crypto.key.alias";
+
}
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=1584340&r1=1584339&r2=1584340&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 Thu Apr 3 11:03:51 2014
@@ -34,6 +34,8 @@ import org.apache.cayenne.crypto.map.Pat
import org.apache.cayenne.crypto.reader.CryptoRowReaderFactoryDecorator;
import org.apache.cayenne.crypto.transformer.DefaultTransformerFactory;
import org.apache.cayenne.crypto.transformer.TransformerFactory;
+import org.apache.cayenne.crypto.transformer.bytes.BytesTransformerFactory;
+import org.apache.cayenne.crypto.transformer.bytes.DefaultBytesTransformerFactory;
import org.apache.cayenne.crypto.transformer.value.ValueTransformerFactory;
import org.apache.cayenne.di.Binder;
import org.apache.cayenne.di.MapBuilder;
@@ -231,6 +233,7 @@ 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);
if (columnMapperPattern != null) {
Modified: 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=1584340&r1=1584339&r2=1584340&view=diff
==============================================================================
--- cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/cipher/CipherFactory.java (original)
+++ cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/cipher/CipherFactory.java Thu Apr 3 11:03:51 2014
@@ -33,4 +33,11 @@ public interface CipherFactory {
* null if the factory does not support cipher-based encryption.
*/
Cipher cipher();
+
+ /**
+ * Returns the block size for the ciphers created by this factory. This
+ * information is needed for the callers to presize they various arrays
+ * before a cipher is available.
+ */
+ int blockSize();
}
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=1584340&r1=1584339&r2=1584340&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 Thu Apr 3 11:03:51 2014
@@ -37,6 +37,7 @@ import org.apache.cayenne.di.Inject;
public class DefaultCipherFactory implements CipherFactory {
protected String transformation;
+ protected int blockSize;
public DefaultCipherFactory(@Inject(CryptoConstants.PROPERTIES_MAP) Map<String, String> properties) {
String algorithm = properties.get(CryptoConstants.CIPHER_ALGORITHM);
@@ -58,6 +59,7 @@ public class DefaultCipherFactory implem
}
this.transformation = algorithm + "/" + mode + "/" + padding;
+ this.blockSize = cipher().getBlockSize();
}
@Override
@@ -70,4 +72,9 @@ public class DefaultCipherFactory implem
throw new CayenneCryptoException("Error instantiating a cipher - no such padding: " + transformation, e);
}
}
+
+ @Override
+ public int blockSize() {
+ return blockSize;
+ }
}
Copied: cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/bytes/BytesTransformer.java (from r1584339, 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/transformer/bytes/BytesTransformer.java?p2=cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/bytes/BytesTransformer.java&p1=cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/cipher/CipherFactory.java&r1=1584339&r2=1584340&rev=1584340&view=diff
==============================================================================
--- cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/cipher/CipherFactory.java (original)
+++ cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/bytes/BytesTransformer.java Thu Apr 3 11:03:51 2014
@@ -16,21 +16,18 @@
* specific language governing permissions and limitations
* under the License.
****************************************************************/
-package org.apache.cayenne.crypto.cipher;
-
-import javax.crypto.Cipher;
+package org.apache.cayenne.crypto.transformer.bytes;
/**
* @since 3.2
*/
-public interface CipherFactory {
+public interface BytesTransformer {
/**
- * 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.
+ * Returns the size of the transformed data in bytes. This information
+ * allows the caller to pre-size the output array.
*/
- Cipher cipher();
+ int getOutputSize(int inputLength);
+
+ void transform(byte[] input, byte[] output, int outputOffset);
}
Copied: cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/bytes/BytesTransformerFactory.java (from r1584339, 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/transformer/bytes/BytesTransformerFactory.java?p2=cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/bytes/BytesTransformerFactory.java&p1=cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/cipher/CipherFactory.java&r1=1584339&r2=1584340&rev=1584340&view=diff
==============================================================================
--- cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/cipher/CipherFactory.java (original)
+++ cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/bytes/BytesTransformerFactory.java Thu Apr 3 11:03:51 2014
@@ -16,21 +16,17 @@
* specific language governing permissions and limitations
* under the License.
****************************************************************/
-package org.apache.cayenne.crypto.cipher;
-
-import javax.crypto.Cipher;
+package org.apache.cayenne.crypto.transformer.bytes;
/**
+ * A class that encapsulates Cayenne cryptography protocol, which is usually
+ * dependent on the encryption mode.
+ *
* @since 3.2
*/
-public interface CipherFactory {
+public interface BytesTransformerFactory {
+
+ BytesTransformer encryptor();
- /**
- * 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();
+ BytesTransformer decryptor();
}
Added: 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=1584340&view=auto
==============================================================================
--- cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/bytes/CbcBytesTransformerFactory.java (added)
+++ cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/bytes/CbcBytesTransformerFactory.java Thu Apr 3 11:03:51 2014
@@ -0,0 +1,114 @@
+/*****************************************************************
+ * 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.transformer.bytes;
+
+import java.io.UnsupportedEncodingException;
+import java.security.Key;
+import java.security.SecureRandom;
+import java.util.Queue;
+import java.util.concurrent.ConcurrentLinkedQueue;
+
+import javax.crypto.Cipher;
+
+import org.apache.cayenne.crypto.CayenneCryptoException;
+import org.apache.cayenne.crypto.cipher.CipherFactory;
+import org.apache.cayenne.crypto.key.KeySource;
+
+public class CbcBytesTransformerFactory implements BytesTransformerFactory {
+
+ private static final String KEY_NAME_CHARSET = "UTF-8";
+
+ private CipherFactory cipherFactory;
+ private Key key;
+ private byte[] keyName;
+ private int blockSize;
+ private Queue<SecureRandom> randoms;
+
+ public CbcBytesTransformerFactory(CipherFactory cipherFactory, KeySource keySource, String keyName) {
+
+ this.randoms = new ConcurrentLinkedQueue<SecureRandom>();
+ this.cipherFactory = cipherFactory;
+ this.blockSize = cipherFactory.blockSize();
+
+ byte[] keyNameBytes;
+ try {
+ keyNameBytes = keyName.getBytes(KEY_NAME_CHARSET);
+ } catch (UnsupportedEncodingException e) {
+ throw new CayenneCryptoException("Can't encode in " + KEY_NAME_CHARSET, e);
+ }
+
+ if (keyNameBytes.length == blockSize) {
+ this.keyName = keyNameBytes;
+ } else if (keyNameBytes.length < blockSize) {
+ this.keyName = new byte[blockSize];
+ System.arraycopy(keyNameBytes, 0, this.keyName, 0, keyNameBytes.length);
+ } else {
+ throw new CayenneCryptoException("Key name '" + keyName + "' is too long. Its byte form should not exceed "
+ + blockSize + " bytes");
+ }
+ }
+
+ protected byte[] generateSeedIv() {
+
+ byte[] iv = new byte[blockSize];
+
+ // the idea of a queue of SecureRandoms for concurrency is taken from
+ // Tomcat's SessionIdGenerator. Also some code...
+
+ SecureRandom random = randoms.poll();
+ if (random == null) {
+ random = createSecureRandom();
+ }
+
+ random.nextBytes(iv);
+ randoms.add(random);
+
+ return iv;
+ }
+
+ /**
+ * Create a new random number generator instance we should use for
+ * generating session identifiers.
+ */
+ private SecureRandom createSecureRandom() {
+
+ // TODO: allow to customize provider?
+ SecureRandom result = new SecureRandom();
+
+ // Force seeding to take place
+ result.nextInt();
+ return result;
+ }
+
+ @Override
+ public BytesTransformer encryptor() {
+ Cipher cipher = cipherFactory.cipher();
+
+ BytesTransformer cbcEncryptor = new CbcEncryptor(cipher, key, generateSeedIv());
+
+ // TODO: make adding key name for versioning an optional property
+ return new EncryptorWithKeyName(cbcEncryptor, keyName, blockSize);
+ }
+
+ @Override
+ public BytesTransformer decryptor() {
+ throw new UnsupportedOperationException("TODO");
+ }
+
+}
Added: cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/bytes/CbcEncryptor.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/bytes/CbcEncryptor.java?rev=1584340&view=auto
==============================================================================
--- cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/bytes/CbcEncryptor.java (added)
+++ cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/bytes/CbcEncryptor.java Thu Apr 3 11:03:51 2014
@@ -0,0 +1,89 @@
+/*****************************************************************
+ * 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.transformer.bytes;
+
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.Key;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.ShortBufferException;
+import javax.crypto.spec.IvParameterSpec;
+
+import org.apache.cayenne.crypto.CayenneCryptoException;
+
+/**
+ * A {@link BytesTransformer} that encrypts the provided bytes. The first block
+ * in the encrypted bytes is the value of IV used to seed the CBC
+ * transformation. It will be needed for decryption. The object is stateful and
+ * is not thread-safe.
+ *
+ * @since 3.2
+ */
+public class CbcEncryptor implements BytesTransformer {
+
+ private Cipher cipher;
+ private byte[] iv;
+ private Key key;
+ private int blockSize;
+
+ public CbcEncryptor(Cipher cipher, Key key, byte[] seedIv) {
+ this.key = key;
+ this.cipher = cipher;
+ this.iv = seedIv;
+ this.blockSize = cipher.getBlockSize();
+
+ if (iv.length != blockSize) {
+ throw new CayenneCryptoException("IV size is expected to be the same as block size. Was " + iv.length
+ + "; block size was: " + blockSize);
+ }
+ }
+
+ @Override
+ public int getOutputSize(int inputLength) {
+ // add one block for IV storage
+ return blockSize + cipher.getOutputSize(inputLength);
+ }
+
+ @Override
+ public void transform(byte[] input, byte[] output, int outputOffset) {
+ try {
+ encrypt(input, output, outputOffset);
+ } catch (Exception e) {
+ throw new CayenneCryptoException("Error on encryption", e);
+ }
+ }
+
+ protected void encrypt(byte[] plain, byte[] encrypted, int outputOffset) throws InvalidKeyException,
+ InvalidAlgorithmParameterException, ShortBufferException, IllegalBlockSizeException, BadPaddingException {
+
+ // copy IV in the first block
+ System.arraycopy(iv, 0, encrypted, outputOffset, blockSize);
+
+ cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(iv));
+ int encBytes = cipher.doFinal(plain, 0, plain.length, encrypted, outputOffset + blockSize);
+
+ // store the last block of ciphertext to use as an IV for the next round
+ // of encryption...
+ System.arraycopy(encrypted, outputOffset + encBytes, iv, 0, blockSize);
+ }
+
+}
Added: 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=1584340&view=auto
==============================================================================
--- cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/bytes/DefaultBytesTransformerFactory.java (added)
+++ cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/bytes/DefaultBytesTransformerFactory.java Thu Apr 3 11:03:51 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.transformer.bytes;
+
+import java.util.Map;
+
+import org.apache.cayenne.crypto.CayenneCryptoException;
+import org.apache.cayenne.crypto.CryptoConstants;
+import org.apache.cayenne.crypto.cipher.CipherFactory;
+import org.apache.cayenne.crypto.key.KeySource;
+import org.apache.cayenne.di.Inject;
+
+/**
+ * A {@link BytesTransformerFactory} that creates transformers depending on the
+ * encryption mode specified via properties.
+ *
+ * @since 3.2
+ */
+public class DefaultBytesTransformerFactory implements BytesTransformerFactory {
+
+ private BytesTransformerFactory delegate;
+
+ public DefaultBytesTransformerFactory(@Inject(CryptoConstants.PROPERTIES_MAP) Map<String, String> properties,
+ @Inject CipherFactory cipherFactory, @Inject KeySource keySource) {
+
+ String mode = properties.get(CryptoConstants.CIPHER_MODE);
+ if (mode == null) {
+ 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);
+ }
+ // TODO: ECB and other modes...
+ else {
+ throw new CayenneCryptoException("Unsupported mode: " + mode
+ + ". The following modes are currently supported: CBC");
+ }
+ }
+
+ public BytesTransformer encryptor() {
+ return delegate.encryptor();
+ }
+
+ public BytesTransformer decryptor() {
+ return delegate.decryptor();
+ }
+}
Copied: cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/bytes/EncryptorWithKeyName.java (from r1584339, 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/transformer/bytes/EncryptorWithKeyName.java?p2=cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/bytes/EncryptorWithKeyName.java&p1=cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/cipher/CipherFactory.java&r1=1584339&r2=1584340&rev=1584340&view=diff
==============================================================================
--- cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/cipher/CipherFactory.java (original)
+++ cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/bytes/EncryptorWithKeyName.java Thu Apr 3 11:03:51 2014
@@ -16,21 +16,30 @@
* specific language governing permissions and limitations
* under the License.
****************************************************************/
-package org.apache.cayenne.crypto.cipher;
+package org.apache.cayenne.crypto.transformer.bytes;
-import javax.crypto.Cipher;
+public class EncryptorWithKeyName implements BytesTransformer {
+
+ private BytesTransformer delegate;
+ private int blockSize;
+ private byte[] keyName;
+
+ public EncryptorWithKeyName(BytesTransformer delegate, byte[] keyName, int blockSize) {
+ this.delegate = delegate;
+ this.blockSize = blockSize;
+ this.keyName = keyName;
+ }
+
+ @Override
+ public int getOutputSize(int inputLength) {
+ // add one block for key name storage
+ return blockSize + delegate.getOutputSize(inputLength);
+ }
+
+ @Override
+ public void transform(byte[] input, byte[] output, int outputOffset) {
+ System.arraycopy(keyName, 0, output, outputOffset, blockSize);
+ delegate.transform(input, output, outputOffset + blockSize);
+ }
-/**
- * @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/test/java/org/apache/cayenne/crypto/transformer/bytes/CbcEncryptorTest.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/transformer/bytes/CbcEncryptorTest.java?rev=1584340&view=auto
==============================================================================
--- cayenne/main/trunk/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/transformer/bytes/CbcEncryptorTest.java (added)
+++ cayenne/main/trunk/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/transformer/bytes/CbcEncryptorTest.java Thu Apr 3 11:03:51 2014
@@ -0,0 +1,67 @@
+/*****************************************************************
+ * 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.transformer.bytes;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.mock;
+
+import java.io.UnsupportedEncodingException;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.NoSuchAlgorithmException;
+
+import javax.crypto.Cipher;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.spec.SecretKeySpec;
+
+import org.apache.cayenne.crypto.CayenneCryptoException;
+import org.junit.Test;
+
+public class CbcEncryptorTest {
+
+ @Test(expected = CayenneCryptoException.class)
+ public void testConstructor() throws UnsupportedEncodingException, NoSuchAlgorithmException, NoSuchPaddingException {
+
+ byte[] iv = { 1, 2, 3, 4, 5, 6 };
+ Key key = mock(Key.class);
+ Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
+ assertEquals(8, cipher.getBlockSize());
+
+ // must throw as IV sie and block size are different
+ new CbcEncryptor(cipher, key, iv);
+ }
+
+ @Test
+ public void testGetOutputSize() throws UnsupportedEncodingException, NoSuchAlgorithmException,
+ NoSuchPaddingException, InvalidKeyException {
+
+ byte[] iv = { 1, 2, 3, 4, 5, 6, 7, 8 };
+ byte[] keyBytes = { 1, 2, 3, 4, 5, 6, 7, 8 };
+ Key key = new SecretKeySpec(keyBytes, "DES");
+
+ Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
+ cipher.init(Cipher.ENCRYPT_MODE, key);
+ assertEquals(8, cipher.getBlockSize());
+
+ // try with non-standard block size too...
+ CbcEncryptor encryptor = new CbcEncryptor(cipher, key, iv);
+ assertEquals(24, encryptor.getOutputSize(11));
+ }
+
+}
Copied: cayenne/main/trunk/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/transformer/bytes/EncryptorWithKeyNameTest.java (from r1584339, 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/test/java/org/apache/cayenne/crypto/transformer/bytes/EncryptorWithKeyNameTest.java?p2=cayenne/main/trunk/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/transformer/bytes/EncryptorWithKeyNameTest.java&p1=cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/cipher/CipherFactory.java&r1=1584339&r2=1584340&rev=1584340&view=diff
==============================================================================
--- cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/cipher/CipherFactory.java (original)
+++ cayenne/main/trunk/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/transformer/bytes/EncryptorWithKeyNameTest.java Thu Apr 3 11:03:51 2014
@@ -16,21 +16,28 @@
* specific language governing permissions and limitations
* under the License.
****************************************************************/
-package org.apache.cayenne.crypto.cipher;
+package org.apache.cayenne.crypto.transformer.bytes;
-import javax.crypto.Cipher;
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.io.UnsupportedEncodingException;
+
+import org.junit.Test;
+
+public class EncryptorWithKeyNameTest {
+
+ @Test
+ public void testGetOutputSize() throws UnsupportedEncodingException {
+
+ byte[] keyName = "mykey".getBytes("UTF-8");
+ BytesTransformer delegate = mock(BytesTransformer.class);
+ when(delegate.getOutputSize(8)).thenReturn(8);
+
+ // try with non-standard block size..
+ EncryptorWithKeyName encryptor = new EncryptorWithKeyName(delegate, keyName, 17);
+ assertEquals(25, encryptor.getOutputSize(8));
+ }
-/**
- * @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();
}