Author: aadamchik
Date: Sun Apr 13 19:48:30 2014
New Revision: 1587083
URL: http://svn.apache.org/r1587083
Log:
CAY-1925 cayenne-crypto: add optional compression to the encryption pipeline
API to enable compression
Added:
cayenne/main/trunk/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/transformer/bytes/DefaultBytesTransformerFactoryTest.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/transformer/bytes/DefaultBytesTransformerFactory.java
cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/bytes/Header.java
cayenne/main/trunk/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/transformer/bytes/HeaderEncryptorTest.java
cayenne/main/trunk/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/transformer/bytes/HeaderTest.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=1587083&r1=1587082&r2=1587083&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
Sun Apr 13 19:48:30 2014
@@ -58,4 +58,10 @@ public interface CryptoConstants {
*/
public static final String ENCRYPTION_KEY_ALIAS =
"cayenne.crypto.key.enc.alias";
+ /**
+ * A property that defines whether compression is enabled. Should be "true"
+ * or "false". "False" is the default.
+ */
+ public static final String COMPRESSION = "cayenne.crypto.compression";
+
}
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=1587083&r1=1587082&r2=1587083&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
Sun Apr 13 19:48:30 2014
@@ -77,6 +77,8 @@ public class CryptoModuleBuilder {
private String encryptionKeyAlias;
private char[] keyPassword;
+ private boolean compress;
+
public CryptoModuleBuilder() {
// init some sensible defaults that work in JVM without extra
@@ -218,6 +220,11 @@ public class CryptoModuleBuilder {
return this;
}
+ public CryptoModuleBuilder compress() {
+ this.compress = true;
+ return this;
+ }
+
/**
* Produces a module that can be used to start Cayenne runtime.
*/
@@ -267,6 +274,10 @@ public class CryptoModuleBuilder {
props.put(CryptoConstants.ENCRYPTION_KEY_ALIAS,
encryptionKeyAlias);
}
+ if (compress) {
+ props.put(CryptoConstants.COMPRESSION, "true");
+ }
+
// char[] credentials... stored as char[] to potentially allow
// wiping them clean in memory...
MapBuilder<char[]> creds = binder.<char[]>
bindMap(CryptoConstants.CREDENTIALS_MAP);
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=1587083&r1=1587082&r2=1587083&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
Sun Apr 13 19:48:30 2014
@@ -36,17 +36,23 @@ public class DefaultBytesTransformerFact
private BytesTransformerFactory delegate;
+ static Header createEncryptionHeader(Map<String, String> properties,
KeySource keySource) {
+ boolean compressed =
"true".equals(properties.get(CryptoConstants.COMPRESSION));
+ return Header.create(keySource.getDefaultKeyAlias(), compressed);
+ }
+
public
DefaultBytesTransformerFactory(@Inject(CryptoConstants.PROPERTIES_MAP)
Map<String, String> properties,
@Inject CipherFactory cipherFactory, @Inject KeySource keySource) {
+ Header encryptionHeader = createEncryptionHeader(properties,
keySource);
+
String mode = properties.get(CryptoConstants.CIPHER_MODE);
if (mode == null) {
throw new CayenneCryptoException("Cipher mode is not set. Property
name: " + CryptoConstants.CIPHER_MODE);
}
if ("CBC".equals(mode)) {
- this.delegate = new CbcBytesTransformerFactory(cipherFactory,
keySource, Header.create(keySource
- .getDefaultKeyAlias()));
+ this.delegate = new CbcBytesTransformerFactory(cipherFactory,
keySource, encryptionHeader);
}
// TODO: ECB and other modes...
else {
@@ -55,10 +61,12 @@ public class DefaultBytesTransformerFact
}
}
+ @Override
public BytesEncryptor encryptor() {
return delegate.encryptor();
}
+ @Override
public BytesDecryptor decryptor() {
return delegate.decryptor();
}
Modified:
cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/bytes/Header.java
URL:
http://svn.apache.org/viewvc/cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/bytes/Header.java?rev=1587083&r1=1587082&r2=1587083&view=diff
==============================================================================
---
cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/bytes/Header.java
(original)
+++
cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/bytes/Header.java
Sun Apr 13 19:48:30 2014
@@ -69,10 +69,15 @@ public class Header {
*/
private static final int KEY_NAME_MAX_SIZE = Byte.MAX_VALUE -
KEY_NAME_OFFSET;
+ /**
+ * A position of the compress bit.
+ */
+ private static final int COMPRESS_BIT = 0;
+
private byte[] data;
private int offset;
- public static Header create(String keyName) {
+ public static Header create(String keyName, boolean compessed) {
byte[] keyNameBytes;
try {
keyNameBytes = keyName.getBytes(KEY_NAME_CHARSET);
@@ -94,7 +99,9 @@ public class Header {
data[SIZE_POSITION] = (byte) n;
// flags
- data[FLAGS_POSITION] = 0;
+ if (compessed) {
+ data[FLAGS_POSITION] = bitOn(data[FLAGS_POSITION], COMPRESS_BIT);
+ }
// key name
System.arraycopy(keyNameBytes, 0, data, KEY_NAME_OFFSET,
keyNameBytes.length);
@@ -106,6 +113,14 @@ public class Header {
return new Header(data, offset);
}
+ private static byte bitOn(byte bits, int position) {
+ return (byte) (bits | (1 << position));
+ }
+
+ private static boolean isBitOn(byte bits, int position) {
+ return ((bits >> position) & 1) == 1;
+ }
+
// private constructor... construction is done via factory methods...
private Header(byte[] data, int offset) {
this.data = data;
@@ -116,6 +131,10 @@ public class Header {
return data[offset + SIZE_POSITION];
}
+ public boolean isCompressed() {
+ return isBitOn(data[offset + FLAGS_POSITION], COMPRESS_BIT);
+ }
+
/**
* Saves the header bytes in the provided buffer at specified offset.
*/
Added:
cayenne/main/trunk/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/transformer/bytes/DefaultBytesTransformerFactoryTest.java
URL:
http://svn.apache.org/viewvc/cayenne/main/trunk/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/transformer/bytes/DefaultBytesTransformerFactoryTest.java?rev=1587083&view=auto
==============================================================================
---
cayenne/main/trunk/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/transformer/bytes/DefaultBytesTransformerFactoryTest.java
(added)
+++
cayenne/main/trunk/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/transformer/bytes/DefaultBytesTransformerFactoryTest.java
Sun Apr 13 19:48:30 2014
@@ -0,0 +1,60 @@
+/*****************************************************************
+ * 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.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.cayenne.crypto.CryptoConstants;
+import org.apache.cayenne.crypto.key.KeySource;
+import org.junit.Test;
+
+public class DefaultBytesTransformerFactoryTest {
+
+ @Test
+ public void testCreateEncryptionHeader() {
+
+ Map<String, String> properties = new HashMap<String, String>();
+ KeySource keySource = mock(KeySource.class);
+ when(keySource.getDefaultKeyAlias()).thenReturn("bla");
+
+ Header h1 =
DefaultBytesTransformerFactory.createEncryptionHeader(properties, keySource);
+ assertNotNull(h1);
+ assertFalse(h1.isCompressed());
+ assertEquals("bla", h1.getKeyName());
+
+ properties.put(CryptoConstants.COMPRESSION, "false");
+ Header h2 =
DefaultBytesTransformerFactory.createEncryptionHeader(properties, keySource);
+ assertFalse(h2.isCompressed());
+ assertEquals("bla", h2.getKeyName());
+
+ properties.put(CryptoConstants.COMPRESSION, "true");
+ Header h3 =
DefaultBytesTransformerFactory.createEncryptionHeader(properties, keySource);
+ assertTrue(h3.isCompressed());
+ assertEquals("bla", h3.getKeyName());
+ }
+
+}
Modified:
cayenne/main/trunk/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/transformer/bytes/HeaderEncryptorTest.java
URL:
http://svn.apache.org/viewvc/cayenne/main/trunk/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/transformer/bytes/HeaderEncryptorTest.java?rev=1587083&r1=1587082&r2=1587083&view=diff
==============================================================================
---
cayenne/main/trunk/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/transformer/bytes/HeaderEncryptorTest.java
(original)
+++
cayenne/main/trunk/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/transformer/bytes/HeaderEncryptorTest.java
Sun Apr 13 19:48:30 2014
@@ -30,7 +30,7 @@ public class HeaderEncryptorTest {
@Test
public void testTransform() throws UnsupportedEncodingException {
- Header encryptionHeader = Header.create("mykey");
+ Header encryptionHeader = Header.create("mykey", false);
BytesEncryptor delegate = SwapBytesTransformer.encryptor();
Modified:
cayenne/main/trunk/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/transformer/bytes/HeaderTest.java
URL:
http://svn.apache.org/viewvc/cayenne/main/trunk/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/transformer/bytes/HeaderTest.java?rev=1587083&r1=1587082&r2=1587083&view=diff
==============================================================================
---
cayenne/main/trunk/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/transformer/bytes/HeaderTest.java
(original)
+++
cayenne/main/trunk/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/transformer/bytes/HeaderTest.java
Sun Apr 13 19:48:30 2014
@@ -19,6 +19,8 @@
package org.apache.cayenne.crypto.transformer.bytes;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
import org.apache.cayenne.crypto.CayenneCryptoException;
import org.junit.Test;
@@ -28,9 +30,18 @@ public class HeaderTest {
@Test
public void testCreate_WithKeyName() {
- assertEquals("bcd", Header.create("bcd").getKeyName());
- assertEquals("bc", Header.create("bc").getKeyName());
- assertEquals("b", Header.create("b").getKeyName());
+ Header h1 = Header.create("bcd", false);
+ Header h2 = Header.create("bc", true);
+ Header h3 = Header.create("b", false);
+
+ assertEquals("bcd", h1.getKeyName());
+ assertFalse(h1.isCompressed());
+
+ assertEquals("bc", h2.getKeyName());
+ assertTrue(h2.isCompressed());
+
+ assertEquals("b", h3.getKeyName());
+ assertFalse(h3.isCompressed());
}
@Test(expected = CayenneCryptoException.class)
@@ -41,15 +52,19 @@ public class HeaderTest {
buf.append("a");
}
- Header.create(buf.toString());
+ Header.create(buf.toString(), false);
}
@Test
public void testCreate_WithData() {
byte[] input1 = { 'C', 'C', '1', 9, 0, 'a', 'b', 'c', 'd', 'e' };
- assertEquals("abcd", Header.create(input1, 0).getKeyName());
-
- byte[] input2 = { 0, 'C', 'C', '1', 9, 0, 'a', 'b', 'c', 'd', 'e' };
- assertEquals("abcd", Header.create(input2, 1).getKeyName());
+ Header h1 = Header.create(input1, 0);
+ assertEquals("abcd", h1.getKeyName());
+ assertFalse(h1.isCompressed());
+
+ byte[] input2 = { 0, 'C', 'C', '1', 9, 1, 'a', 'b', 'c', 'd', 'e' };
+ Header h2 = Header.create(input2, 1);
+ assertEquals("abcd", h2.getKeyName());
+ assertTrue(h2.isCompressed());
}
}