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>