This is an automated email from the ASF dual-hosted git repository.

gautam pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ranger.git


The following commit(s) were added to refs/heads/master by this push:
     new fc42892  RANGER-2331 Ranger-KMS - KeySecure HSM Integration
fc42892 is described below

commit fc4289222718d0c02ba65a994299d45ea1f4d97b
Author: Gautam Borad <[email protected]>
AuthorDate: Mon Feb 25 18:23:44 2019 +0530

    RANGER-2331 Ranger-KMS - KeySecure HSM Integration
---
 kms/config/kms-webapp/dbks-site.xml                |  51 +++++++
 kms/scripts/DBMKTOKEYSECURE.sh                     |  19 +++
 kms/scripts/KEYSECUREMKTOKMSDB.sh                  |  19 +++
 kms/scripts/install.properties                     |  10 ++
 kms/scripts/setup.sh                               |  86 +++++++++++-
 .../apache/hadoop/crypto/key/DBToKeySecure.java    | 128 +++++++++++++++++
 .../apache/hadoop/crypto/key/JKS2RangerUtil.java   |  53 ++++++-
 .../crypto/key/KeySecureToRangerDBMKUtil.java      | 104 ++++++++++++++
 .../apache/hadoop/crypto/key/Ranger2JKSUtil.java   |  47 ++++++-
 .../hadoop/crypto/key/RangerKeyStoreProvider.java  |  44 ++++--
 .../apache/hadoop/crypto/key/RangerMasterKey.java  |  18 +++
 .../hadoop/crypto/key/RangerSafenetKeySecure.java  | 153 +++++++++++++++++++++
 src/main/assembly/kms.xml                          |   2 +
 13 files changed, 718 insertions(+), 16 deletions(-)

diff --git a/kms/config/kms-webapp/dbks-site.xml 
b/kms/config/kms-webapp/dbks-site.xml
index ec649a7..05a1a13 100755
--- a/kms/config/kms-webapp/dbks-site.xml
+++ b/kms/config/kms-webapp/dbks-site.xml
@@ -180,6 +180,57 @@
        <name>ranger.ks.kerberos.keytab</name>
        <value></value>
   </property>
+
+  <!-- Key-Secure Config START-->
+
+  <property>
+        <name>ranger.kms.keysecure.enabled</name>
+        <value>false</value>
+        <description></description>
+  </property>
+
+  <property>
+        <name>ranger.kms.keysecure.UserPassword.Authentication</name>
+        <value>true</value>
+        <description></description>
+  </property>
+  <property>
+        <name>ranger.kms.keysecure.masterkey.name</name>
+        <value>safenetmasterkey</value>
+        <description>Safenet key secure master key name</description>
+  </property>
+    <property>
+        <name>ranger.kms.keysecure.login.username</name>
+        <value>user1</value>
+        <description>Safenet key secure username</description>
+  </property>
+  <property>
+        <name>ranger.kms.keysecure.login.password</name>
+        <value>t1e2s3t4</value>
+        <description>Safenet key secure user password</description>
+  </property>
+  <property>
+        <name>ranger.kms.keysecure.login.password.alias</name>
+        <value>ranger.ks.login.password</value>
+        <description>Safenet key secure user password</description>
+  </property>
+  <property>
+        <name>ranger.kms.keysecure.hostname</name>
+        <value>SunPKCS11-keysecurehn</value>
+        <description>Safenet key secure hostname</description>
+  </property>
+  <property>
+        <name>ranger.kms.keysecure.masterkey.size</name>
+        <value>256</value>
+        <description>key size</description>
+  </property>
+  <property>
+        <name>ranger.kms.keysecure.sunpkcs11.cfg.filepath</name>
+        <value>/opt/safenetConf/64/8.3.1/sunpkcs11.cfg</value>
+        <description>Location of Safenet key secure library configuration 
file</description>
+  </property>
+
+  <!-- Key-Secure Config END-->
     
   <!-- HSM Config -->
   <property>
diff --git a/kms/scripts/DBMKTOKEYSECURE.sh b/kms/scripts/DBMKTOKEYSECURE.sh
new file mode 100644
index 0000000..c0aa6e5
--- /dev/null
+++ b/kms/scripts/DBMKTOKEYSECURE.sh
@@ -0,0 +1,19 @@
+#!/bin/bash
+# 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.
+# 
-------------------------------------------------------------------------------------
+RANGER_KMS_HOME=`dirname $0`
+cp="${RANGER_KMS_HOME}/cred/lib/*:${RANGER_KMS_HOME}/./ews/webapp/WEB-INF/classes/conf/:${RANGER_KMS_HOME}/ews/webapp/config:${RANGER_KMS_HOME}/ews/lib/*:${RANGER_KMS_HOME}/ews/webapp/lib/*:${RANGER_KMS_HOME}/ews/webapp/META-INF"
+java -cp "${cp}" org.apache.hadoop.crypto.key.DBToKeySecure ${1} ${2} ${3} ${4}
diff --git a/kms/scripts/KEYSECUREMKTOKMSDB.sh 
b/kms/scripts/KEYSECUREMKTOKMSDB.sh
new file mode 100644
index 0000000..340e05e
--- /dev/null
+++ b/kms/scripts/KEYSECUREMKTOKMSDB.sh
@@ -0,0 +1,19 @@
+#!/bin/bash
+# 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.
+# 
-------------------------------------------------------------------------------------
+RANGER_KMS_HOME=`dirname $0`
+cp="${RANGER_KMS_HOME}/cred/lib/*:${RANGER_KMS_HOME}/./ews/webapp/WEB-INF/classes/conf/:${RANGER_KMS_HOME}/ews/webapp/WEB-INF/classes/lib/*:${RANGER_KMS_HOME}/ews/webapp/config:${RANGER_KMS_HOME}/ews/lib/*:${RANGER_KMS_HOME}/ews/webapp/lib/*:${RANGER_KMS_HOME}/ews/webapp/META-INF"
+java -cp "${cp}" org.apache.hadoop.crypto.key.KeySecureToRangerDBMKUtil ${1}
diff --git a/kms/scripts/install.properties b/kms/scripts/install.properties
index aea0bb8..798dd8c 100755
--- a/kms/scripts/install.properties
+++ b/kms/scripts/install.properties
@@ -89,6 +89,16 @@ HSM_ENABLED=false
 HSM_PARTITION_NAME=par19
 HSM_PARTITION_PASSWORD=S@fenet123
 
+#------------------------- Ranger SAFENET KEYSECURE CONFIG 
------------------------------
+KEYSECURE_ENABLED=false
+KEYSECURE_USER_PASSWORD_AUTHENTICATION=true
+KEYSECURE_MASTERKEY_NAME=safenetkeysecure
+KEYSECURE_USERNAME=user1
+KEYSECURE_PASSWORD=t1e2s3t4
+KEYSECURE_HOSTNAME=SunPKCS11-keysecurehn
+KEYSECURE_MASTER_KEY_SIZE=256
+KEYSECURE_LIB_CONFIG_PATH=/opt/safenetConf/64/8.3.1/sunpkcs11.cfg
+
 #
 # ------- UNIX User CONFIG ----------------
 #
diff --git a/kms/scripts/setup.sh b/kms/scripts/setup.sh
index c695e74..c430ef9 100755
--- a/kms/scripts/setup.sh
+++ b/kms/scripts/setup.sh
@@ -91,6 +91,15 @@ HSM_ENABLED=$(get_prop 'HSM_ENABLED' $PROPFILE)
 HSM_PARTITION_NAME=$(get_prop 'HSM_PARTITION_NAME' $PROPFILE)
 HSM_PARTITION_PASSWORD=$(get_prop 'HSM_PARTITION_PASSWORD' $PROPFILE)
 
+KEYSECURE_ENABLED=$(get_prop 'KEYSECURE_ENABLED' $PROPFILE)
+KEYSECURE_USER_PASSWORD_AUTHENTICATION=$(get_prop 
'KEYSECURE_USER_PASSWORD_AUTHENTICATION' $PROPFILE)
+KEYSECURE_MASTERKEY_NAME=$(get_prop 'KEYSECURE_MASTERKEY_NAME' $PROPFILE)
+KEYSECURE_USERNAME=$(get_prop 'KEYSECURE_USERNAME' $PROPFILE)
+KEYSECURE_PASSWORD=$(get_prop 'KEYSECURE_PASSWORD' $PROPFILE)
+KEYSECURE_HOSTNAME=$(get_prop 'KEYSECURE_HOSTNAME' $PROPFILE)
+KEYSECURE_MASTER_KEY_SIZE=$(get_prop 'KEYSECURE_MASTER_KEY_SIZE' $PROPFILE)
+KEYSECURE_LIB_CONFIG_PATH=$(get_prop 'KEYSECURE_LIB_CONFIG_PATH' $PROPFILE)
+
 kms_principal=$(get_prop 'kms_principal' $PROPFILE)
 kms_keytab=$(get_prop 'kms_keytab' $PROPFILE)
 hadoop_conf=$(get_prop 'hadoop_conf' $PROPFILE)
@@ -204,6 +213,17 @@ password_validation(){
                 fi
         fi
 }
+
+password_validation_safenet_keysecure(){
+        if [ -z "$1" ]
+        then
+                log "[I] Blank password is not allowed for" $2". Please enter 
valid password."
+                exit 1
+        else
+                log "[I]" $2 "password validated."
+        fi
+}
+
 init_variables(){
        curDt=`date '+%Y%m%d%H%M%S'`
 
@@ -546,9 +566,14 @@ update_properties() {
        DB_CREDENTIAL_ALIAS="ranger.ks.jpa.jdbc.credential.alias"
 
        HSM_PARTITION_PASSWD="ranger.ks.hsm.partition.password"
-       HSM_PARTITION_PASSWORD_ALIAS="ranger.kms.hsm.partition.password"
+        HSM_PARTITION_PASSWORD_ALIAS="ranger.kms.hsm.partition.password"
+
+        KEYSECURE_PASSWD="ranger.kms.keysecure.login.password"
+        KEYSECURE_PASSWORD_ALIAS="ranger.ks.login.password"
+
 
         HSM_ENABLED=`echo $HSM_ENABLED | tr '[:lower:]' '[:upper:]'`
+        KEYSECURE_ENABLED=`echo $KEYSECURE_ENABLED | tr '[:lower:]' 
'[:upper:]'`
 
        if [ "${keystore}" != "" ]
        then
@@ -574,6 +599,21 @@ update_properties() {
                         updatePropertyToFilePy $propertyName $newPropertyValue 
$to_file
                 fi
 
+                if [ "${KEYSECURE_ENABLED}" == "TRUE" ]
+                then
+                        password_validation_safenet_keysecure 
"$KEYSECURE_PASSWORD" "KEYSECURE User Password"
+                        $PYTHON_COMMAND_INVOKER ranger_credential_helper.py -l 
"cred/lib/*" -f "$keystore" -k "${KEYSECURE_PASSWORD_ALIAS}" -v 
"${KEYSECURE_PASSWORD}" -c 1
+
+                        propertyName=ranger.kms.keysecure.login.password.alias
+                        newPropertyValue="${KEYSECURE_PASSWORD_ALIAS}"
+                        updatePropertyToFilePy $propertyName $newPropertyValue 
$to_file
+
+                        propertyName=ranger.kms.keysecure.login.password
+                        newPropertyValue="_"
+                        updatePropertyToFilePy $propertyName $newPropertyValue 
$to_file
+                fi
+
+
                propertyName=ranger.ks.jpa.jdbc.credential.alias
                newPropertyValue="${DB_CREDENTIAL_ALIAS}"
                updatePropertyToFilePy $propertyName $newPropertyValue $to_file
@@ -605,6 +645,11 @@ update_properties() {
                propertyName="${HSM_PARTITION_PASSWD}"
                 newPropertyValue="${HSM_PARTITION_PASSWORD}"
                 updatePropertyToFilePy $propertyName $newPropertyValue $to_file
+
+                propertyName="${KEYSECURE_PASSWD}"
+                newPropertyValue="${KEYSECURE_PASSWORD}"
+                updatePropertyToFilePy $propertyName $newPropertyValue $to_file
+
        fi
 
        if test -f $keystore; then
@@ -669,6 +714,45 @@ update_properties() {
                 updatePropertyToFilePy $propertyName $newPropertyValue 
$to_file         
         fi
 
+                ########### SAFENET KEYSECURE CONFIG #################
+
+
+        if [ "${KEYSECURE_ENABLED}" != "TRUE" ]
+        then
+                propertyName=ranger.kms.keysecure.enabled
+                newPropertyValue="false"
+                updatePropertyToFilePy $propertyName $newPropertyValue $to_file
+        else
+                propertyName=ranger.kms.keysecure.enabled
+                newPropertyValue="true"
+                updatePropertyToFilePy $propertyName $newPropertyValue $to_file
+
+                propertyName=ranger.kms.keysecure.UserPassword.Authentication
+                newPropertyValue="${KEYSECURE_USER_PASSWORD_AUTHENTICATION}"
+                updatePropertyToFilePy $propertyName $newPropertyValue $to_file
+
+                propertyName=ranger.kms.keysecure.masterkey.name
+                newPropertyValue="${KEYSECURE_MASTERKEY_NAME}"
+                updatePropertyToFilePy $propertyName $newPropertyValue $to_file
+
+                propertyName=ranger.kms.keysecure.login.username
+                newPropertyValue="${KEYSECURE_USERNAME}"
+                updatePropertyToFilePy $propertyName $newPropertyValue $to_file
+
+                propertyName=ranger.kms.keysecure.hostname
+                newPropertyValue="${KEYSECURE_HOSTNAME}"
+                updatePropertyToFilePy $propertyName $newPropertyValue $to_file
+
+                propertyName=ranger.kms.keysecure.masterkey.size
+                newPropertyValue="${KEYSECURE_MASTER_KEY_SIZE}"
+                updatePropertyToFilePy $propertyName $newPropertyValue $to_file
+
+                propertyName=ranger.kms.keysecure.sunpkcs11.cfg.filepath
+                newPropertyValue="${KEYSECURE_LIB_CONFIG_PATH}"
+                updatePropertyToFilePy $propertyName $newPropertyValue $to_file
+
+        fi
+
        
to_file_kms_site=$PWD/ews/webapp/WEB-INF/classes/conf/ranger-kms-site.xml
     if test -f $to_file_kms_site; then
                log "[I] $to_file_kms_site file found"
diff --git a/kms/src/main/java/org/apache/hadoop/crypto/key/DBToKeySecure.java 
b/kms/src/main/java/org/apache/hadoop/crypto/key/DBToKeySecure.java
new file mode 100644
index 0000000..2740e45
--- /dev/null
+++ b/kms/src/main/java/org/apache/hadoop/crypto/key/DBToKeySecure.java
@@ -0,0 +1,128 @@
+/*
+ * 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.hadoop.crypto.key;
+
+import java.io.IOException;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.ranger.kms.dao.DaoManager;
+
+import com.sun.org.apache.xml.internal.security.utils.Base64;
+
+public class DBToKeySecure {
+
+        private static final String ENCRYPTION_KEY = 
"ranger.db.encrypt.key.password";
+        private static final String KEYSECURE_MASTERKEY_NAME = 
"ranger.kms.keysecure.masterkey.name";
+//     private static final String KEYSECURE_PROTOCOL = 
"ranger.kms.keysecure.protocol";
+        private static final String KEYSECURE_LOGIN = 
"ranger.kms.keysecure.login";
+        private static final String CFGFILEPATH = 
"ranger.kms.keysecure.sunpkcs11.cfg.filepath";
+
+        public static void showUsage() {
+                System.err
+                                .println("USAGE: java "
+                                                + DBToKeySecure.class.getName()
+                                                + " <keySecureMasterKeyName> 
<keySecureUsername> <keySecurePassword> <sunpkcs11CfgFilePath>");
+        }
+
+        public static void main(String[] args) {
+
+                if (args.length < 4) {
+                        System.err.println("Invalid number of parameters 
found.");
+                        showUsage();
+                        System.exit(1);
+                } else {
+
+                        Configuration conf = 
RangerKeyStoreProvider.getDBKSConf();
+
+                        String keyName = args[0];
+                        if (keyName == null || keyName.trim().isEmpty()) {
+                                System.err.println("Key Secure master key name 
not provided.");
+                                showUsage();
+                                System.exit(1);
+                        }
+
+                        String username = args[1];
+                        if (username == null || username.trim().isEmpty()) {
+                                System.err.println("Key Secure username not 
provided.");
+                                showUsage();
+                                System.exit(1);
+                        }
+                        String password = args[2];
+                        if (password == null || password.trim().isEmpty()) {
+                                System.err.println("Key Secure password not 
provided.");
+                                showUsage();
+                                System.exit(1);
+                        }
+
+                        String cfgFilePath = args[3];
+                        if (cfgFilePath == null || 
cfgFilePath.trim().isEmpty()) {
+                                System.err.println("sunpkcs11 Configuration 
File Path not provided");
+                                showUsage();
+                                System.exit(1);
+                        }
+
+                        boolean result = new 
DBToKeySecure().doExportMKToKeySecure(keyName, username, password, cfgFilePath, 
 conf);
+                        if (result) {
+                                System.out
+                                                .println("Master Key from 
Ranger KMS DB has been successfully imported into Key Secure.");
+                        } else {
+                                System.out
+                                                .println("Import of Master Key 
from DB has been unsuccessful.");
+                                System.exit(1);
+                        }
+                        System.exit(0);
+                }
+        }
+
+        private boolean doExportMKToKeySecure(String keyName, String username, 
String password, String cfgFilePath, Configuration conf) {
+                try {
+                        String keySecureMKPassword = conf.get(ENCRYPTION_KEY);
+                        if (keySecureMKPassword == null
+                                        || 
keySecureMKPassword.trim().equals("")
+                                        || 
keySecureMKPassword.trim().equals("_")
+                                        || 
keySecureMKPassword.trim().equals("crypted")) {
+                                throw new IOException("Master Key Jceks does 
not exists");
+                        }
+
+                        conf.set(CFGFILEPATH, cfgFilePath);
+                        conf.set(KEYSECURE_MASTERKEY_NAME, keyName);
+                        conf.set(KEYSECURE_LOGIN,username + ":" + password);
+
+                        RangerKMSDB rangerkmsDb = new RangerKMSDB(conf);
+                        DaoManager daoManager = rangerkmsDb.getDaoManager();
+                        String mkPassword = conf.get(ENCRYPTION_KEY);
+
+                        // Get Master Key from Ranger DB
+                        RangerMasterKey rangerMasterKey = new 
RangerMasterKey(daoManager);
+                        String mkey = rangerMasterKey.getMasterKey(mkPassword);
+                        byte[] key = Base64.decode(mkey);
+
+                        if (conf != null) {
+                                RangerSafenetKeySecure rangerSafenetKeySecure 
= new RangerSafenetKeySecure(
+                                                conf);
+                                return 
rangerSafenetKeySecure.setMasterKey(password, key,conf);
+                        }
+
+                        return false;
+                } catch (Throwable t) {
+                        throw new RuntimeException(
+                                        "Unable to import Master key from 
Ranger DB to KeySecure ",
+                                        t);
+                }
+
+        }
+
+}
diff --git a/kms/src/main/java/org/apache/hadoop/crypto/key/JKS2RangerUtil.java 
b/kms/src/main/java/org/apache/hadoop/crypto/key/JKS2RangerUtil.java
index dd4408f..5e394de 100644
--- a/kms/src/main/java/org/apache/hadoop/crypto/key/JKS2RangerUtil.java
+++ b/kms/src/main/java/org/apache/hadoop/crypto/key/JKS2RangerUtil.java
@@ -23,14 +23,21 @@ import java.io.InputStream;
 import java.security.KeyStore;
 import java.security.KeyStoreException;
 import java.util.Arrays;
-
+import org.apache.commons.lang.StringUtils;
 import org.apache.hadoop.conf.Configuration;
+import org.apache.ranger.credentialapi.CredentialReader;
 import org.apache.ranger.kms.dao.DaoManager;
 
 public class JKS2RangerUtil {
        
        private static final String DEFAULT_KEYSTORE_TYPE = "jceks";
        private static final String ENCRYPTION_KEY = 
"ranger.db.encrypt.key.password";
+        private static final String KEYSECURE_ENABLED = 
"ranger.kms.keysecure.enabled";
+        private static final String KEYSECURE_USERNAME = 
"ranger.kms.keysecure.login.username";
+    private static final String KEYSECURE_PASSWORD = 
"ranger.kms.keysecure.login.password";
+    private static final String KEYSECURE_PASSWORD_ALIAS = 
"ranger.kms.keysecure.login.password.alias";
+    private static final String KEYSECURE_LOGIN = "ranger.kms.keysecure.login";
+    private static final String CREDENTIAL_PATH = 
"ranger.ks.jpa.jdbc.credential.provider.path";
        
        public static void showUsage() {
                System.err.println("USAGE: java " + 
JKS2RangerUtil.class.getName() + " <KMS_FileName> [KeyStoreType]");
@@ -71,6 +78,22 @@ public class JKS2RangerUtil {
                        }
        }
        
+        private static void getFromJceks(Configuration conf, String path, 
String alias, String key) {
+
+        //update credential from keystore
+        if (conf != null) {
+            String pathValue = conf.get(path);
+            String aliasValue = conf.get(alias);
+            if (pathValue != null && aliasValue != null) {
+                String xaDBPassword = 
CredentialReader.getDecryptedString(pathValue.trim(), aliasValue.trim());
+                if (xaDBPassword != null && !xaDBPassword.trim().isEmpty() &&
+                        !xaDBPassword.trim().equalsIgnoreCase("none")) {
+                    conf.set(key, xaDBPassword);
+                }
+            }
+        }
+    }
+
        private void doImportKeysFromJKS(String keyStoreFileName, String 
keyStoreType) {
                char[] keyStorePassword = null;
                char[] keyPassword = null;
@@ -81,11 +104,33 @@ public class JKS2RangerUtil {
                        RangerKMSDB rangerkmsDb = new RangerKMSDB(conf);        
        
                        DaoManager daoManager = rangerkmsDb.getDaoManager();
                        RangerKeyStore dbStore = new RangerKeyStore(daoManager);
+                        char[] masterKey;
                        String password = conf.get(ENCRYPTION_KEY);
-                       RangerMasterKey rangerMasterKey = new 
RangerMasterKey(daoManager);
-                       rangerMasterKey.generateMasterKey(password);            
-                       char[] masterKey = 
rangerMasterKey.getMasterKey(password).toCharArray();
                        InputStream in = null;
+
+
+                        if (conf != null
+                                        && 
StringUtils.isNotEmpty(conf.get(KEYSECURE_ENABLED))
+                                        && 
conf.get(KEYSECURE_ENABLED).equalsIgnoreCase("true")) {
+
+                                getFromJceks(conf, CREDENTIAL_PATH, 
KEYSECURE_PASSWORD_ALIAS, KEYSECURE_PASSWORD);
+                                String keySecureLoginCred = 
conf.get(KEYSECURE_USERNAME).trim() + ":" + conf.get(KEYSECURE_PASSWORD);
+                                conf.set(KEYSECURE_LOGIN, keySecureLoginCred);
+
+                                RangerSafenetKeySecure rangerSafenetKeySecure 
= new RangerSafenetKeySecure(
+                                                conf);
+                                
rangerSafenetKeySecure.generateMasterKey(password);
+                                masterKey = 
rangerSafenetKeySecure.getMasterKey(password).toCharArray();
+                        } else {
+                                RangerMasterKey rangerMasterKey = new 
RangerMasterKey(
+                                                daoManager);
+                                rangerMasterKey.generateMasterKey(password);
+                                masterKey = 
rangerMasterKey.getMasterKey(password)
+                                                .toCharArray();
+                        }
+
+
+
                        try {
                                in = new FileInputStream(new 
File(keyStoreFileName));
                                dbStore.engineLoadKeyStoreFile(in, 
keyStorePassword, keyPassword, masterKey, keyStoreType);
diff --git 
a/kms/src/main/java/org/apache/hadoop/crypto/key/KeySecureToRangerDBMKUtil.java 
b/kms/src/main/java/org/apache/hadoop/crypto/key/KeySecureToRangerDBMKUtil.java
new file mode 100644
index 0000000..538fde9
--- /dev/null
+++ 
b/kms/src/main/java/org/apache/hadoop/crypto/key/KeySecureToRangerDBMKUtil.java
@@ -0,0 +1,104 @@
+/*
+ * 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.hadoop.crypto.key;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.ranger.credentialapi.CredentialReader;
+import org.apache.ranger.kms.dao.DaoManager;
+
+import com.sun.org.apache.xml.internal.security.utils.Base64;
+
+public class KeySecureToRangerDBMKUtil {
+        private static final String ENCRYPTION_KEY = 
"ranger.db.encrypt.key.password";
+        private static final String KEYSECURE_USERNAME = 
"ranger.kms.keysecure.login.username";
+    private static final String KEYSECURE_PASSWORD = 
"ranger.kms.keysecure.login.password";
+    private static final String KEYSECURE_PASSWORD_ALIAS = 
"ranger.kms.keysecure.login.password.alias";
+    private static final String KEYSECURE_LOGIN = "ranger.kms.keysecure.login";
+    private static final String CREDENTIAL_PATH = 
"ranger.ks.jpa.jdbc.credential.provider.path";
+
+        public static void showUsage() {
+                System.err.println("USAGE: java " + 
KeySecureToRangerDBMKUtil.class.getName() + " <KMS master key password>");
+        }
+
+        public static void main(String[] args) {
+
+                                if (args.length != 1) {
+                                        System.err.println("Invalid number of 
parameters found.");
+                                        showUsage();
+                                        System.exit(1);
+                                }
+                                else {
+                                        String kmsMKPassword = args[0];
+                                        if (kmsMKPassword == null || 
kmsMKPassword.trim().isEmpty()) {
+                                                System.err.println("KMS master 
key password not provided");
+                                                showUsage();
+                                                System.exit(1);
+                                        }
+
+                                        new 
KeySecureToRangerDBMKUtil().doImportMKFromKeySecure(kmsMKPassword);
+                                                System.out.println("Master Key 
from Key Secure has been successfully imported into Ranger KMS DB.");
+                                }
+                        }
+
+        private void doImportMKFromKeySecure(String kmsMKPassword) {
+                try {
+                        Configuration conf = 
RangerKeyStoreProvider.getDBKSConf();
+                        conf.set(ENCRYPTION_KEY, kmsMKPassword);
+                        getFromJceks(conf, CREDENTIAL_PATH, 
KEYSECURE_PASSWORD_ALIAS, KEYSECURE_PASSWORD);
+                        String keySecureLoginCred = 
conf.get(KEYSECURE_USERNAME).trim() + ":" + conf.get(KEYSECURE_PASSWORD);
+                        conf.set(KEYSECURE_LOGIN, keySecureLoginCred);
+
+                        RangerKMSDB rangerkmsDb = new RangerKMSDB(conf);
+                        DaoManager daoManager = rangerkmsDb.getDaoManager();
+                        String password = conf.get(ENCRYPTION_KEY);
+
+                        RangerSafenetKeySecure rangerSafenetKeySecure = new 
RangerSafenetKeySecure(
+                                        conf);
+                        String mKey = 
rangerSafenetKeySecure.getMasterKey(password);
+
+                        byte[] key = Base64.decode(mKey);
+
+                        // Put Master Key in Ranger DB
+                        RangerMasterKey rangerMasterKey = new 
RangerMasterKey(daoManager);
+                        rangerMasterKey.generateMKFromKeySecureMK(password, 
key);
+
+                } catch (Throwable t) {
+                        throw new RuntimeException(
+                                        "Unable to migrate Master key from 
KeySecure to Ranger DB",
+                                        t);
+
+                }
+        }
+
+        private static void getFromJceks(Configuration conf, String path, 
String alias, String key) {
+
+        //update credential from keystore
+        if (conf != null) {
+            String pathValue = conf.get(path);
+            String aliasValue = conf.get(alias);
+            if (pathValue != null && aliasValue != null) {
+                String xaDBPassword = 
CredentialReader.getDecryptedString(pathValue.trim(), aliasValue.trim());
+                if (xaDBPassword != null && !xaDBPassword.trim().isEmpty() &&
+                        !xaDBPassword.trim().equalsIgnoreCase("none")) {
+                    conf.set(key, xaDBPassword);
+                }
+            }
+        }
+    }
+
+
+}
diff --git a/kms/src/main/java/org/apache/hadoop/crypto/key/Ranger2JKSUtil.java 
b/kms/src/main/java/org/apache/hadoop/crypto/key/Ranger2JKSUtil.java
index 4f337bb..f542364 100644
--- a/kms/src/main/java/org/apache/hadoop/crypto/key/Ranger2JKSUtil.java
+++ b/kms/src/main/java/org/apache/hadoop/crypto/key/Ranger2JKSUtil.java
@@ -23,14 +23,21 @@ import java.io.OutputStream;
 import java.security.KeyStore;
 import java.security.KeyStoreException;
 import java.util.Arrays;
-
+import org.apache.commons.lang.StringUtils;
 import org.apache.hadoop.conf.Configuration;
+import org.apache.ranger.credentialapi.CredentialReader;
 import org.apache.ranger.kms.dao.DaoManager;
 
 public class Ranger2JKSUtil {
 
        private static final String DEFAULT_KEYSTORE_TYPE = "jceks";
        private static final String ENCRYPTION_KEY = 
"ranger.db.encrypt.key.password";
+        private static final String KEYSECURE_ENABLED = 
"ranger.kms.keysecure.enabled";
+        private static final String KEYSECURE_USERNAME = 
"ranger.kms.keysecure.login.username";
+    private static final String KEYSECURE_PASSWORD = 
"ranger.kms.keysecure.login.password";
+    private static final String KEYSECURE_PASSWORD_ALIAS = 
"ranger.kms.keysecure.login.password.alias";
+    private static final String KEYSECURE_LOGIN = "ranger.kms.keysecure.login";
+    private static final String CREDENTIAL_PATH = 
"ranger.ks.jpa.jdbc.credential.provider.path";
        
        public static void showUsage() {
                System.err.println("USAGE: java " + 
Ranger2JKSUtil.class.getName() + " <KMS_FileName> [KeyStoreType]");
@@ -82,9 +89,27 @@ public class Ranger2JKSUtil {
                        RangerKMSDB rangerkmsDb = new RangerKMSDB(conf);        
        
                        DaoManager daoManager = rangerkmsDb.getDaoManager();
                        RangerKeyStore dbStore = new RangerKeyStore(daoManager);
+                        char[] masterKey;
                        String password = conf.get(ENCRYPTION_KEY);
-                       RangerMasterKey rangerMasterKey = new 
RangerMasterKey(daoManager);
-                       char[] masterKey = 
rangerMasterKey.getMasterKey(password).toCharArray();
+                        if (conf != null
+                                        && 
StringUtils.isNotEmpty(conf.get(KEYSECURE_ENABLED))
+                                        && 
conf.get(KEYSECURE_ENABLED).equalsIgnoreCase("true")) {
+
+                                getFromJceks(conf, CREDENTIAL_PATH, 
KEYSECURE_PASSWORD_ALIAS, KEYSECURE_PASSWORD);
+                                String keySecureLoginCred = 
conf.get(KEYSECURE_USERNAME).trim() + ":" + conf.get(KEYSECURE_PASSWORD);
+                                conf.set(KEYSECURE_LOGIN, keySecureLoginCred);
+
+                                RangerSafenetKeySecure rangerSafenetKeySecure 
= new RangerSafenetKeySecure(
+                                                conf);
+                                masterKey = 
rangerSafenetKeySecure.getMasterKey(password)
+                                                .toCharArray();
+
+                        } else {
+                                RangerMasterKey rangerMasterKey = new 
RangerMasterKey(
+                                                daoManager);
+                                masterKey = 
rangerMasterKey.getMasterKey(password)
+                                                .toCharArray();
+                        }
                        OutputStream out = null;
                        try {
                                out = new FileOutputStream(new 
File(keyStoreFileName));
@@ -109,5 +134,21 @@ public class Ranger2JKSUtil {
                }
        }
        
+        private static void getFromJceks(Configuration conf, String path, 
String alias, String key) {
+
+        //update credential from keystore
+        if (conf != null) {
+            String pathValue = conf.get(path);
+            String aliasValue = conf.get(alias);
+            if (pathValue != null && aliasValue != null) {
+                String xaDBPassword = 
CredentialReader.getDecryptedString(pathValue.trim(), aliasValue.trim());
+                if (xaDBPassword != null && !xaDBPassword.trim().isEmpty() &&
+                        !xaDBPassword.trim().equalsIgnoreCase("none")) {
+                    conf.set(key, xaDBPassword);
+                }
+            }
+        }
+    }
+
 
 }
diff --git 
a/kms/src/main/java/org/apache/hadoop/crypto/key/RangerKeyStoreProvider.java 
b/kms/src/main/java/org/apache/hadoop/crypto/key/RangerKeyStoreProvider.java
index 88a545e..bc69293 100755
--- a/kms/src/main/java/org/apache/hadoop/crypto/key/RangerKeyStoreProvider.java
+++ b/kms/src/main/java/org/apache/hadoop/crypto/key/RangerKeyStoreProvider.java
@@ -68,6 +68,12 @@ public class RangerKeyStoreProvider extends KeyProvider {
     private static final String HSM_ENABLED = "ranger.ks.hsm.enabled";
     private static final String HSM_PARTITION_PASSWORD_ALIAS = 
"ranger.ks.hsm.partition.password.alias";
     private static final String HSM_PARTITION_PASSWORD = 
"ranger.ks.hsm.partition.password";
+    private static final String KEYSECURE_ENABLED = 
"ranger.kms.keysecure.enabled";
+
+        private static final String KEYSECURE_USERNAME = 
"ranger.kms.keysecure.login.username";
+        private static final String KEYSECURE_PASSWORD_ALIAS = 
"ranger.kms.keysecure.login.password.alias";
+    private static final String KEYSECURE_PASSWORD = 
"ranger.kms.keysecure.login.password";
+    private static final String KEYSECURE_LOGIN = "ranger.kms.keysecure.login";
 
     private final RangerKeyStore dbStore;
     private char[] masterKey;
@@ -105,14 +111,36 @@ public class RangerKeyStoreProvider extends KeyProvider {
                 throw new IOException("Partition Password doesn't exists");
             }
         }
-        dbStore = new RangerKeyStore(daoManager);
-        rangerMasterKey.generateMasterKey(password);
-        //code to retrieve rangerMasterKey password
-        masterKey = rangerMasterKey.getMasterKey(password).toCharArray();
-        if (masterKey == null) {
-            // Master Key does not exists
-            throw new IOException("Ranger MasterKey does not exists");
-        }
+
+                if (conf != null && 
StringUtils.isNotEmpty(conf.get(KEYSECURE_ENABLED))
+                                && 
conf.get(KEYSECURE_ENABLED).equalsIgnoreCase("true")) {
+                        getFromJceks(conf, CREDENTIAL_PATH, 
KEYSECURE_PASSWORD_ALIAS, KEYSECURE_PASSWORD);
+                        String keySecureLoginCred = 
conf.get(KEYSECURE_USERNAME).trim() + ":" + conf.get(KEYSECURE_PASSWORD);
+                        conf.set(KEYSECURE_LOGIN, keySecureLoginCred);
+
+                        rangerMasterKey = new RangerSafenetKeySecure(conf);
+
+                        dbStore = new RangerKeyStore(daoManager);
+                        // generate master key on key secure server
+                        rangerMasterKey.generateMasterKey(password);
+                        try {
+                                masterKey = 
rangerMasterKey.getMasterKey(password)
+                                                .toCharArray();
+                        } catch (Exception ex) {
+                                throw new Exception("Error while getting 
Safenet KeySecure master key " + ex);
+                        }
+
+                } else {
+                        dbStore = new RangerKeyStore(daoManager);
+                        rangerMasterKey.generateMasterKey(password);
+                        // code to retrieve rangerMasterKey password
+                        try {
+                                masterKey = 
rangerMasterKey.getMasterKey(password)
+                                                .toCharArray();
+                        } catch (Exception ex) {
+                                throw new Exception("Error while getting 
Ranger Master key " + ex);
+                        }
+                }
         reloadKeys();
         ReadWriteLock lock = new ReentrantReadWriteLock(true);
         readLock = lock.readLock();
diff --git 
a/kms/src/main/java/org/apache/hadoop/crypto/key/RangerMasterKey.java 
b/kms/src/main/java/org/apache/hadoop/crypto/key/RangerMasterKey.java
index eb4f75a..2b4eb80 100755
--- a/kms/src/main/java/org/apache/hadoop/crypto/key/RangerMasterKey.java
+++ b/kms/src/main/java/org/apache/hadoop/crypto/key/RangerMasterKey.java
@@ -277,6 +277,24 @@ public class RangerMasterKey implements RangerKMSMKI {
         }
     }
 
+        public boolean generateMKFromKeySecureMK(String password, byte[] key)
+                        throws Throwable {
+                if (logger.isDebugEnabled()) {
+            logger.debug("==> RangerMasterKey.generateMKFromKeySecureMK()");
+        }
+                init();
+                String encryptedMasterKey = encryptMasterKey(password, key);
+                String savedKey = saveEncryptedMK(paddingString + "," + 
encryptedMasterKey, daoManager);
+                if (savedKey != null && !savedKey.trim().equals("")) {
+                        logger.debug("Master Key Created with id = " + 
savedKey);
+                        return true;
+                }
+                if (logger.isDebugEnabled()) {
+            logger.debug("<== RangerMasterKey.generateMKFromKeySecureMK()");
+        }
+                return false;
+        }
+
     private SecretKey decryptMasterKeySK(byte masterKey[], String password, 
String encryptedPassString)
             throws Throwable {
         if (logger.isDebugEnabled()) {
diff --git 
a/kms/src/main/java/org/apache/hadoop/crypto/key/RangerSafenetKeySecure.java 
b/kms/src/main/java/org/apache/hadoop/crypto/key/RangerSafenetKeySecure.java
new file mode 100644
index 0000000..12afe33
--- /dev/null
+++ b/kms/src/main/java/org/apache/hadoop/crypto/key/RangerSafenetKeySecure.java
@@ -0,0 +1,153 @@
+/*
+ * 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.hadoop.crypto.key;
+
+import javax.crypto.KeyGenerator;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.SecretKeySpec;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.log4j.Logger;
+
+import com.sun.org.apache.xml.internal.security.utils.Base64;
+
+import java.io.IOException;
+import java.security.Key;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.Provider;
+import java.security.Security;
+import java.security.cert.CertificateException;
+
+/**
+ * This Class is for HSM Keystore
+ */
+public class RangerSafenetKeySecure implements RangerKMSMKI {
+
+        static final Logger logger = 
Logger.getLogger(RangerSafenetKeySecure.class);
+
+        private final String alias;
+        private final KeyStore myStore;
+        private final String adp;
+        private final Provider provider;
+        private static final String MK_ALGO = "AES";
+        private final int mkSize;
+        private static final int MK_KeySize = 256;
+        private String pkcs11CfgFilePath = null;
+        private static final String CFGFILEPATH = 
"ranger.kms.keysecure.sunpkcs11.cfg.filepath";
+        private static final String MK_KEYSIZE = 
"ranger.kms.keysecure.masterkey.size";
+        private static final String ALIAS = 
"ranger.kms.keysecure.masterkey.name";
+
+        private static final String KEYSECURE_LOGIN = 
"ranger.kms.keysecure.login";
+
+        public RangerSafenetKeySecure(Configuration conf) throws 
KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException {
+                mkSize = conf.getInt(MK_KEYSIZE, MK_KeySize);
+                alias = conf.get(ALIAS, "RANGERMK");
+                adp = conf.get(KEYSECURE_LOGIN);
+                pkcs11CfgFilePath = conf.get(CFGFILEPATH);
+
+                try {
+                        // Create a PKCS#11 session and initialize it
+                        // using the sunPKCS11 config file
+                        provider = new 
sun.security.pkcs11.SunPKCS11(pkcs11CfgFilePath);
+                        Security.addProvider(provider);
+                        myStore = KeyStore.getInstance("PKCS11", provider);
+                        if(myStore != null){
+                                myStore.load(null, adp.toCharArray());
+                        }else{
+                                logger.error("Safenet Keysecure not found. 
Please verify the Ranger KMS Safenet Keysecure configuration setup.");
+                        }
+
+                } catch (NoSuchAlgorithmException nsae) {
+                        throw new NoSuchAlgorithmException("Unexpected 
NoSuchAlgorithmException while loading keystore : "
+                                        + nsae.getMessage());
+                } catch (CertificateException e) {
+                        throw new CertificateException("Unexpected 
CertificateException while loading keystore : "
+                                        + e.getMessage());
+                } catch (IOException e) {
+                        throw new IOException("Unexpected IOException while 
loading keystore : "
+                                        + e.getMessage());
+                }
+        }
+
+        @Override
+        public boolean generateMasterKey(String password){
+                if (myStore != null) {
+                        KeyGenerator keyGen = null;
+                        SecretKey aesKey = null;
+                        try {
+                                boolean result = myStore.containsAlias(alias);
+
+                                if (!result) {
+                                        keyGen = 
KeyGenerator.getInstance(MK_ALGO, provider);
+                                        keyGen.init(mkSize);
+                                        aesKey = keyGen.generateKey();
+                                        myStore.setKeyEntry(alias, aesKey, 
password.toCharArray(),
+                                                        
(java.security.cert.Certificate[]) null);
+                                        return true;
+                                } else {
+                                        return true;
+                                }
+
+                        } catch (Exception e) {
+                                logger.error("generateMasterKey : Exception 
during Ranger Master Key Generation - "
+                                                + e);
+                                return false;
+                        }
+                }
+                return false;
+        }
+
+        @Override
+        public String getMasterKey(String password) throws Throwable {
+                if (myStore != null) {
+                        try {
+                                boolean result = myStore.containsAlias(alias);
+                                if (result) {
+                                        SecretKey key = (SecretKey) 
myStore.getKey(alias,
+                                                        
password.toCharArray());
+                                        if (key != null) {
+                                                return 
Base64.encode(key.getEncoded());
+                                        }
+
+                                }
+                        } catch (Exception e) {
+                                logger.error("getMasterKey : Exception 
searching for Ranger Master Key - "
+                                                + e.getMessage());
+                        }
+                }
+                return null;
+        }
+
+        public boolean setMasterKey(String password, byte[] key, Configuration 
conf) {
+                if (myStore != null) {
+                        try {
+                                Key aesKey = new SecretKeySpec(key, MK_ALGO);
+                                myStore.setKeyEntry(alias, aesKey, 
password.toCharArray(),
+                                                
(java.security.cert.Certificate[]) null);
+                                return true;
+                        } catch (Exception e) {
+                                logger.error("setMasterKey : Exception while 
setting Master Key - "
+                                                + e.getMessage());
+                        }
+                }
+                return false;
+        }
+
+}
\ No newline at end of file
diff --git a/src/main/assembly/kms.xml b/src/main/assembly/kms.xml
index 3adc55c..fd28b0d 100755
--- a/src/main/assembly/kms.xml
+++ b/src/main/assembly/kms.xml
@@ -320,6 +320,8 @@
                 <include>DBMK2HSM.sh</include>
                 <include>VerifyIsDBMasterkeyCorrect.sh</include>
                 <include>VerifyIsHSMMasterkeyCorrect.sh</include>
+                <include>DBMKTOKEYSECURE.sh</include>
+                                <include>KEYSECUREMKTOKMSDB.sh</include>
             </includes>
             <fileMode>544</fileMode>
         </fileSet>

Reply via email to