RANGER-2331 Ranger-KMS - KeySecure HSM Integration
diff --git a/kms/config/kms-webapp/dbks-site.xml b/kms/config/kms-webapp/dbks-site.xml
index 0e0f2ec..2248032 100755
--- a/kms/config/kms-webapp/dbks-site.xml
+++ b/kms/config/kms-webapp/dbks-site.xml
@@ -123,6 +123,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..ba0a8a9
--- /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/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 ddc779d..a4fda7e 100755
--- a/kms/scripts/install.properties
+++ b/kms/scripts/install.properties
@@ -89,6 +89,16 @@
 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 2db05b8..39afa5a 100755
--- a/kms/scripts/setup.sh
+++ b/kms/scripts/setup.sh
@@ -98,6 +98,15 @@
 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)
@@ -210,6 +219,17 @@
                 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'`
 
@@ -574,7 +594,11 @@
 	HSM_PARTITION_PASSWD="ranger.ks.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
@@ -600,6 +624,20 @@
                         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
@@ -631,6 +669,10 @@
 		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
@@ -695,6 +737,45 @@
                 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..ab0baa1
--- /dev/null
+++ b/kms/src/main/java/org/apache/hadoop/crypto/key/DBToKeySecure.java
@@ -0,0 +1,127 @@
+/*
+ * 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_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 22dce0f..ee0913f 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
@@ -26,13 +26,22 @@
 import java.security.KeyStore;
 import java.security.KeyStoreException;
 
+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]");
@@ -80,12 +89,31 @@
 			Configuration conf = RangerKeyStoreProvider.getDBKSConf();
 			RangerKMSDB rangerkmsDb = new RangerKMSDB(conf);		
 			DaoManager daoManager = rangerkmsDb.getDaoManager();
-			RangerKeyStore dbStore = new RangerKeyStore(daoManager);
+                        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);
@@ -105,6 +133,21 @@
 			throw new RuntimeException("Unable to import keys from [" + keyStoreFileName + "] due to exception.", 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);
+                }
+            }
+        }
+    }
 	
 	
 	private char[] getPasswordFromConsole(String prompt) throws IOException {
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 1abbf8e..3a54041 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
@@ -26,13 +26,21 @@
 import java.security.KeyStore;
 import java.security.KeyStoreException;
 
+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]");
@@ -79,23 +87,43 @@
 			char[] keyStorePassword = getPasswordFromConsole("Enter Password for the keystore FILE :");
 			char[] keyPassword = getPasswordFromConsole("Enter Password for the KEY(s) stored in the keystore:");
 			Configuration conf = RangerKeyStoreProvider.getDBKSConf();
-			RangerKMSDB rangerkmsDb = new RangerKMSDB(conf);		
+                        RangerKMSDB rangerkmsDb = new RangerKMSDB(conf);
 			DaoManager daoManager = rangerkmsDb.getDaoManager();
-			RangerKeyStore dbStore = new RangerKeyStore(daoManager);
+                        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));
-				dbStore.engineLoadToKeyStoreFile(out, keyStorePassword, keyPassword, masterKey, keyStoreType);
-			}
-			finally {
+                                dbStore.engineLoadToKeyStoreFile(out, keyStorePassword,
+                                                keyPassword, masterKey, keyStoreType);
+                        } finally {
 				if (out != null) {
 					try {
 						out.close();
 					} catch (Exception e) {
-						throw new RuntimeException("ERROR:  Unable to close file stream for [" + keyStoreFileName + "]", e);
+                                                throw new RuntimeException(
+                                                                "ERROR:  Unable to close file stream for ["
+                                                                                + keyStoreFileName + "]", e);
 					}
 				}
 			}
@@ -134,4 +162,20 @@
 	    }
 	    return ret.toCharArray();
 	}
+
+        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 267fcf0..448469b 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,13 @@
 	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;
@@ -80,37 +87,68 @@
 	public RangerKeyStoreProvider(Configuration conf) throws Throwable {
 		super(conf);
 		conf = getDBKSConf();
-		getFromJceks(conf,CREDENTIAL_PATH, MK_CREDENTIAL_ALIAS, ENCRYPTION_KEY);
-		getFromJceks(conf,CREDENTIAL_PATH, DB_CREDENTIAL_ALIAS, DB_PASSWORD);
-		getFromJceks(conf,CREDENTIAL_PATH, HSM_PARTITION_PASSWORD_ALIAS, HSM_PARTITION_PASSWORD);
+                getFromJceks(conf, CREDENTIAL_PATH, MK_CREDENTIAL_ALIAS, ENCRYPTION_KEY);
+                getFromJceks(conf, CREDENTIAL_PATH, DB_CREDENTIAL_ALIAS, DB_PASSWORD);
+                getFromJceks(conf, CREDENTIAL_PATH, HSM_PARTITION_PASSWORD_ALIAS,
+                                HSM_PARTITION_PASSWORD);
 		RangerKMSDB rangerKMSDB = new RangerKMSDB(conf);
 		daoManager = rangerKMSDB.getDaoManager();
-		
+
 		RangerKMSMKI rangerMasterKey = null;
 		String password = conf.get(ENCRYPTION_KEY);
-		if(password == null || password.trim().equals("") || password.trim().equals("_") || password.trim().equals("crypted")){
+                if (password == null || password.trim().equals("")
+                                || password.trim().equals("_")
+                                || password.trim().equals("crypted")) {
 			throw new IOException("Master Key Jceks does not exists");
 		}
-		if(StringUtils.isEmpty(conf.get(HSM_ENABLED)) || conf.get(HSM_ENABLED).equalsIgnoreCase("false")){
+                if (StringUtils.isEmpty(conf.get(HSM_ENABLED))
+                                || conf.get(HSM_ENABLED).equalsIgnoreCase("false")) {
 			rangerMasterKey = new RangerMasterKey(daoManager);
-		}else{
+                } else {
 			rangerMasterKey = new RangerHSM(conf);
 			String partitionPasswd = conf.get(HSM_PARTITION_PASSWORD);
-			if(partitionPasswd == null || partitionPasswd.trim().equals("") || partitionPasswd.trim().equals("_") || partitionPasswd.trim().equals("crypted")){
+                        if (partitionPasswd == null || partitionPasswd.trim().equals("")
+                                        || partitionPasswd.trim().equals("_")
+                                        || partitionPasswd.trim().equals("crypted")) {
 				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();
+
+                reloadKeys();
 		ReadWriteLock lock = new ReentrantReadWriteLock(true);
-	    readLock = lock.readLock();
+                readLock = lock.readLock();
+
 	}
 
 	public static Configuration getDBKSConf() {
@@ -164,7 +202,7 @@
 	        throw new IOException("Wrong key length. Required " +
 	            options.getBitLength() + ", but got " + (8 * material.length));
 	      }
-	      cache.put(name, meta);
+		  cache.put(name, meta);
 	      String versionName = buildVersionName(name, 0);
 	      return innerSetKeyVersion(name, versionName, material, meta.getCipher(), meta.getBitLength(), meta.getDescription(), meta.getVersions(), meta.getAttributes());
 	}
@@ -205,7 +243,8 @@
 	      } catch (KeyStoreException e) {
 	        throw new IOException("Problem removing " + name + " from " + this, e);
 	      }
-	      cache.remove(name);
+		  cache.remove(name);
+
 	      changed = true;	
 	}
 
@@ -236,7 +275,8 @@
 	        }	
 	      changed = false;
 		 }catch (IOException ioe) {
-			  cache.clear();
+                                 cache.clear();
+
 			  reloadKeys();
 	          throw ioe;
 	     }		
@@ -245,37 +285,40 @@
 	@Override
 	public KeyVersion getKeyVersion(String versionName) throws IOException {
 		readLock.lock();
-	    try {
-	    	SecretKeySpec key = null;
-	    	try {
-	    		if (!dbStore.engineContainsAlias(versionName)) {
-  	    		        dbStore.engineLoad(null, masterKey);
-	    			if (!dbStore.engineContainsAlias(versionName)) {
-	    				return null;
-	    			}
+                try {
+                        SecretKeySpec key = null;
+                        try {
+                                if (!dbStore.engineContainsAlias(versionName)) {
+                                        dbStore.engineLoad(null, masterKey);
+                                        if (!dbStore.engineContainsAlias(versionName)) {
+                                                return null;
+                                        }
+                                }
+                                key = (SecretKeySpec) dbStore.engineGetKey(versionName,
+                                                masterKey);
+                        } catch (NoSuchAlgorithmException e) {
+
+                                throw new IOException("Can't get algorithm for key " + key, e);
+                        } catch (UnrecoverableKeyException e) {
+                                throw new IOException("Can't recover key " + key, e);
+                        } catch (CertificateException e) {
+                                throw new IOException("Certificate exception storing key", e);
 			}
-	    		key = (SecretKeySpec) dbStore.engineGetKey(versionName, masterKey);
-	    	} catch (NoSuchAlgorithmException e) {
-	    		throw new IOException("Can't get algorithm for key " + key, e);
-	    	} catch (UnrecoverableKeyException e) {
-	    		throw new IOException("Can't recover key " + key, e);
-	    	}
-		catch (CertificateException e) {
-	    		throw new IOException("Certificate exception storing key", e);
+                        if (key == null) {
+                                return null;
+                        } else {
+                                return new KeyVersion(getBaseName(versionName), versionName,
+                                                key.getEncoded());
+                        }
+                } finally {
+                        readLock.unlock();
 		}
-	    	if (key == null) {
-	    		return null;
-	    	} else {
-	    		return new KeyVersion(getBaseName(versionName), versionName, key.getEncoded());
-	    	}
-	    } finally {
-	        readLock.unlock();
-	    }
 	}
 
 	@Override
 	public List<KeyVersion> getKeyVersions(String name) throws IOException {
 		List<KeyVersion> list = new ArrayList<KeyVersion>();
+
 	    Metadata km = getMetadata(name);
 	    if (km != null) {
 	       int latestVersion = km.getVersions();
@@ -294,18 +337,18 @@
 
 	@Override
 	public List<String> getKeys() throws IOException {
-		ArrayList<String> list = new ArrayList<String>();
-		String alias = null;
-		reloadKeys();
-	    Enumeration<String> e = dbStore.engineAliases();
-		while (e.hasMoreElements()) {
-		   alias = e.nextElement();
-		   // only include the metadata key names in the list of names
-		   if (!alias.contains("@")) {
-		       list.add(alias);
-		   }
-		}
-	    return list;
+                        ArrayList<String> list = new ArrayList<String>();
+                        String alias = null;
+                        reloadKeys();
+                        Enumeration<String> e = dbStore.engineAliases();
+                        while (e.hasMoreElements()) {
+                                alias = e.nextElement();
+                                // only include the metadata key names in the list of names
+                                if (!alias.contains("@")) {
+                                        list.add(alias);
+                                }
+                        }
+                        return list;
 	}
 
 	@Override
@@ -326,7 +369,7 @@
 	    		Key key = dbStore.engineGetKey(name, masterKey);
 	    		if(key != null){
 	    			Metadata meta = ((KeyMetadata) key).metadata;
-	    			cache.put(name, meta);
+					cache.put(name, meta);
 	    			return meta;
 	    		}
 	    	} catch (NoSuchAlgorithmException e) {
@@ -347,6 +390,7 @@
 	@Override
 	public KeyVersion rollNewVersion(String name, byte[] material)throws IOException {
 		reloadKeys();
+
 		Metadata meta = getMetadata(name);
         if (meta == null) {
 	        throw new IOException("Key " + name + " not found");
@@ -378,8 +422,8 @@
 
     private void reloadKeys() throws IOException {
         try {
-        	cache.clear();
-            loadKeys(masterKey);
+                                cache.clear();
+                                loadKeys(masterKey);
         } catch (NoSuchAlgorithmException e) {
             throw new IOException("Can't load Keys");
         }catch(CertificateException e){
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 5614c16..c0910a4 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
@@ -131,6 +131,17 @@
 		return getMasterKeyFromBytes(masterKeyFromDBDecrypted);		
 	}
 
+        public boolean generateMKFromKeySecureMK(String password, byte[] key) throws Throwable{
+                logger.info("Generating Master Key");
+                String encryptedMasterKey = encryptMasterKey(password, key);
+                String savedKey = saveEncryptedMK(encryptedMasterKey, daoManager);
+                if(savedKey != null && !savedKey.trim().equals("")){
+                        logger.debug("Master Key Created with id = "+savedKey);
+                        return true;
+                }
+                return false;
+        }
+
 	private byte[] getEncryptedMK() throws Base64DecodingException {
 		logger.debug("Retrieving Encrypted Master Key from database");
 		try{
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..70ec504
--- /dev/null
+++ b/kms/src/main/java/org/apache/hadoop/crypto/key/RangerSafenetKeySecure.java
@@ -0,0 +1,156 @@
+/*
+ * 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) {
+                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 fca6a32..c156fe3 100755
--- a/src/main/assembly/kms.xml
+++ b/src/main/assembly/kms.xml
@@ -317,6 +317,8 @@
 			<include>exportKeysToJCEKS.sh</include>
 			<include>HSMMK2DB.sh</include>
 			<include>DBMK2HSM.sh</include>
+                        <include>DBMKTOKEYSECURE.sh</include>
+                        <include>KEYSECUREMKTOKMSDB.sh</include>
 		</includes>
 		<fileMode>544</fileMode>
 	</fileSet>