Repository: ranger
Updated Branches:
  refs/heads/master c89b55591 -> 6e512b6ab


RANGER-1505 - Remove KeyProtector code in KMS

Signed-off-by: Colm O hEigeartaigh <cohei...@apache.org>


Project: http://git-wip-us.apache.org/repos/asf/ranger/repo
Commit: http://git-wip-us.apache.org/repos/asf/ranger/commit/6e512b6a
Tree: http://git-wip-us.apache.org/repos/asf/ranger/tree/6e512b6a
Diff: http://git-wip-us.apache.org/repos/asf/ranger/diff/6e512b6a

Branch: refs/heads/master
Commit: 6e512b6ab5c7d2008ff8e1abd2ad9f1b8b12e169
Parents: c89b555
Author: Colm O hEigeartaigh <cohei...@apache.org>
Authored: Mon Apr 10 12:23:38 2017 +0100
Committer: Colm O hEigeartaigh <cohei...@apache.org>
Committed: Tue Apr 11 15:15:48 2017 +0100

----------------------------------------------------------------------
 .../hadoop/crypto/key/RangerKeyStore.java       | 105 ++++++++++++++-----
 1 file changed, 79 insertions(+), 26 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ranger/blob/6e512b6a/kms/src/main/java/org/apache/hadoop/crypto/key/RangerKeyStore.java
----------------------------------------------------------------------
diff --git a/kms/src/main/java/org/apache/hadoop/crypto/key/RangerKeyStore.java 
b/kms/src/main/java/org/apache/hadoop/crypto/key/RangerKeyStore.java
index a001c08..c4f7267 100644
--- a/kms/src/main/java/org/apache/hadoop/crypto/key/RangerKeyStore.java
+++ b/kms/src/main/java/org/apache/hadoop/crypto/key/RangerKeyStore.java
@@ -26,11 +26,13 @@ import java.io.InputStream;
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
 import java.io.OutputStream;
+import java.io.Serializable;
 import java.io.UnsupportedEncodingException;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Field;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
+import java.security.AlgorithmParameters;
 import java.security.DigestInputStream;
 import java.security.DigestOutputStream;
 import java.security.Key;
@@ -39,16 +41,22 @@ import java.security.KeyStoreException;
 import java.security.KeyStoreSpi;
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
 import java.security.UnrecoverableKeyException;
 import java.security.cert.Certificate;
 import java.security.cert.CertificateException;
-import java.util.ArrayList;
 import java.util.Date;
 import java.util.Enumeration;
 import java.util.Hashtable;
 import java.util.List;
 
+import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
 import javax.crypto.SealedObject;
+import javax.crypto.SecretKey;
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.PBEKeySpec;
+import javax.crypto.spec.PBEParameterSpec;
 import javax.xml.bind.DatatypeConverter;
 
 import org.apache.hadoop.crypto.key.KeyProvider.Metadata;
@@ -108,17 +116,9 @@ public class RangerKeyStore extends KeyStoreSpi {
             return null;
         }
 
-        Class<?> c = null;
-       Object o = null;
                try {
-                       c = 
Class.forName("com.sun.crypto.provider.KeyProtector");
-                       Constructor<?> constructor = 
c.getDeclaredConstructor(char[].class);
-               constructor.setAccessible(true);
-               o = constructor.newInstance(password);  
-               Method m = c.getDeclaredMethod("unseal", SealedObject.class);
-            m.setAccessible(true);
-                       key = (Key) m.invoke(o, 
((SecretKeyEntry)entry).sealedKey);
-               } catch (ClassNotFoundException | NoSuchMethodException | 
SecurityException | InstantiationException | IllegalAccessException | 
IllegalArgumentException | InvocationTargetException e) {
+                       key = unsealKey(((SecretKeyEntry)entry).sealedKey, 
password);
+               } catch (Exception e) {
                        logger.error(e.getMessage());
                }
         return key;
@@ -144,22 +144,9 @@ public class RangerKeyStore extends KeyStoreSpi {
        SecretKeyEntry entry = new SecretKeyEntry();
         synchronized(deltaEntries) {
             try {              
-               Class<?> c = null;
-               Object o = null;
-                       try {
-                               c = 
Class.forName("com.sun.crypto.provider.KeyProtector");
-                               Constructor<?> constructor = 
c.getDeclaredConstructor(char[].class);
-                       constructor.setAccessible(true);
-                       o = constructor.newInstance(password);          
-                       } catch (ClassNotFoundException | NoSuchMethodException 
| SecurityException | InstantiationException | IllegalAccessException | 
IllegalArgumentException | InvocationTargetException e) {
-                               logger.error(e.getMessage());
-                               throw new KeyStoreException(e.getMessage());
-                       }
                 entry.date = new Date();
                 // seal and store the key
-                Method m = c.getDeclaredMethod("seal", Key.class);
-                m.setAccessible(true);
-                entry.sealedKey = (SealedObject) m.invoke(o, key);
+                entry.sealedKey = sealKey(key, password);
 
                 entry.cipher_field = cipher;
                 entry.bit_length = bitLength;
@@ -182,6 +169,47 @@ public class RangerKeyStore extends KeyStoreSpi {
         }
     }
 
+    private SealedObject sealKey(Key key, char[] password) throws Exception {
+        // Create SecretKey
+        SecretKeyFactory secretKeyFactory = 
SecretKeyFactory.getInstance("PBEWithMD5AndTripleDES");
+        PBEKeySpec pbeKeySpec = new PBEKeySpec(password);
+        SecretKey secretKey = secretKeyFactory.generateSecret(pbeKeySpec);
+        pbeKeySpec.clearPassword();
+
+        // Generate random bytes + set up the PBEParameterSpec
+        SecureRandom random = new SecureRandom();
+        byte[] salt = new byte[8];
+        random.nextBytes(salt);
+        PBEParameterSpec pbeSpec = new PBEParameterSpec(salt, 20);
+
+        // Seal the Key
+        Cipher cipher = Cipher.getInstance("PBEWithMD5AndTripleDES");
+        cipher.init(Cipher.ENCRYPT_MODE, secretKey, pbeSpec);
+        return new RangerSealedObject(key, cipher);
+    }
+
+    private Key unsealKey(SealedObject sealedKey, char[] password) throws 
Exception {
+        // Create SecretKey
+        SecretKeyFactory secretKeyFactory = 
SecretKeyFactory.getInstance("PBEWithMD5AndTripleDES");
+        PBEKeySpec pbeKeySpec = new PBEKeySpec(password);
+        SecretKey secretKey = secretKeyFactory.generateSecret(pbeKeySpec);
+        pbeKeySpec.clearPassword();
+
+        // Get the AlgorithmParameters from RangerSealedObject
+        AlgorithmParameters algorithmParameters = null;
+        if (sealedKey instanceof RangerSealedObject) {
+            algorithmParameters = 
((RangerSealedObject)sealedKey).getParameters();
+        } else {
+            algorithmParameters = new 
RangerSealedObject(sealedKey).getParameters();
+        }
+
+        // Unseal the Key
+        Cipher cipher = Cipher.getInstance("PBEWithMD5AndTripleDES");
+        cipher.init(Cipher.DECRYPT_MODE, secretKey, algorithmParameters);
+
+        return (Key)sealedKey.getObject(cipher);
+    }
+
     @Override
     public void engineDeleteEntry(String alias)
         throws KeyStoreException
@@ -585,5 +613,30 @@ public class RangerKeyStore extends KeyStoreSpi {
        public void clearDeltaEntires(){
                deltaEntries.clear();
        }
-       
+
+       /**
+        * Encapsulate the encrypted key, so that we can retrieve the 
AlgorithmParameters object on the decryption side
+        */
+       private static class RangerSealedObject extends SealedObject {
+
+           /**
+            *
+            */
+           private static final long serialVersionUID = -7551578543434362070L;
+
+           protected RangerSealedObject(SealedObject so) {
+               super(so);
+           }
+
+           protected RangerSealedObject(Serializable object, Cipher cipher) 
throws IllegalBlockSizeException, IOException {
+               super(object, cipher);
+           }
+
+           public AlgorithmParameters getParameters() throws 
NoSuchAlgorithmException, IOException {
+               AlgorithmParameters algorithmParameters = 
AlgorithmParameters.getInstance("PBEWithMD5AndTripleDES");
+               algorithmParameters.init(super.encodedParams);
+               return algorithmParameters;
+           }
+
+       }
 }

Reply via email to