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/05 17:34:12 UTC
svn commit: r1585107 -
/cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/key/JceksKeySource.java
Author: aadamchik
Date: Sat Apr 5 15:34:11 2014
New Revision: 1585107
URL: http://svn.apache.org/r1585107
Log:
CAY-1916 cayenne-crypto module that enables data encryption for certain model attributes
caching keys - reading it every time from the keystore is really expensive
Modified:
cayenne/main/trunk/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/key/JceksKeySource.java
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=1585107&r1=1585106&r2=1585107&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 Sat Apr 5 15:34:11 2014
@@ -27,6 +27,8 @@ import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
import org.apache.cayenne.crypto.CayenneCryptoException;
import org.apache.cayenne.crypto.CryptoConstants;
@@ -43,11 +45,36 @@ public class JceksKeySource implements K
// this is the only standard keystore type that supports storing secret keys
private static final String JCEKS_KEYSTORE_TYPE = "jceks";
+ private static final Key NULL_KEY = new Key() {
+
+ private static final long serialVersionUID = 4755682444381893880L;
+
+ @Override
+ public String getFormat() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public byte[] getEncoded() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public String getAlgorithm() {
+ throw new UnsupportedOperationException();
+ }
+ };
private KeyStore keyStore;
private char[] keyPassword;
private String defaultKeyAlias;
+ // caching the keys may not be a good idea for security reasons, but
+ // re-reading the key from KeyStore for every select row creates a huge
+ // bottleneck... And considering we are caching keystore password, it
+ // probably doesn't make things that much worse
+ private ConcurrentMap<String, Key> keyCache;
+
public JceksKeySource(@Inject(CryptoConstants.PROPERTIES_MAP) Map<String, String> properties,
@Inject(CryptoConstants.CREDENTIALS_MAP) Map<String, char[]> credentials) {
@@ -70,6 +97,8 @@ public class JceksKeySource implements K
throw new CayenneCryptoException("Default key alias is not set. Property name: "
+ CryptoConstants.ENCRYPTION_KEY_ALIAS);
}
+
+ this.keyCache = new ConcurrentHashMap<String, Key>();
}
private KeyStore createKeyStore(String keyStoreUrl) throws KeyStoreException, IOException,
@@ -91,8 +120,22 @@ public class JceksKeySource implements K
@Override
public Key getKey(String alias) {
+
+ Key key = keyCache.get(alias);
+ if (key == null) {
+
+ Key newKey = createKey(alias);
+ Key oldKey = keyCache.putIfAbsent(alias, newKey);
+ key = oldKey != null ? oldKey : newKey;
+ }
+
+ return key == NULL_KEY ? null : key;
+ }
+
+ protected Key createKey(String alias) {
try {
- return keyStore.getKey(alias, keyPassword);
+ Key key = keyStore.getKey(alias, keyPassword);
+ return key != null ? key : NULL_KEY;
} catch (Exception e) {
throw new CayenneCryptoException("Error accessing key for alias: " + alias, e);
}