This is an automated email from the ASF dual-hosted git repository.
abhi 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 3f4167e26 RANGER-5267 : Add/improve Unit test cases for Key
re-encryption in KMS module (#619)
3f4167e26 is described below
commit 3f4167e2635800d01ed556d3444be848738f8f25
Author: Vikas Kumar <[email protected]>
AuthorDate: Tue Aug 12 03:17:41 2025 +0530
RANGER-5267 : Add/improve Unit test cases for Key re-encryption in KMS
module (#619)
---
.../apache/hadoop/crypto/key/RangerMasterKey.java | 30 ++
.../hadoop/crypto/key/RangerMasterKeyTest.java | 263 ++++++++++++++++++
.../hadoop/crypto/key/TestFIPSRangerKeyStore.java | 238 ++++++++++++++++
.../hadoop/crypto/key/kms/RangerMasterKeyTest.java | 305 ---------------------
.../crypto/key/kms/server/RangerMasterKeyTest.java | 113 --------
5 files changed, 531 insertions(+), 418 deletions(-)
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 24811ce39..5b4e30cd2 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
@@ -17,6 +17,7 @@
package org.apache.hadoop.crypto.key;
+import com.google.common.annotations.VisibleForTesting;
import com.sun.org.apache.xml.internal.security.utils.Base64;
import org.apache.commons.collections.CollectionUtils;
import org.apache.hadoop.thirdparty.com.google.common.base.Joiner;
@@ -621,4 +622,33 @@ private byte[] decryptKey(byte[] encrypted, PBEKeySpec
keySpec) throws Throwable
private SecretKey getMasterKeyFromBytes(byte[] keyData) {
return new SecretKeySpec(keyData, mkCipher);
}
+
+ // Following methods MUST NOT BE USED FOR PROD CODE. IT HAS BEEN EXPOSED
ONLY FOR UnitTesting.
+
+ @VisibleForTesting
+ SupportedPBECryptoAlgo getDefaultCryptoAlgorithm() {
+ return defaultCryptAlgo;
+ }
+
+ @VisibleForTesting
+ SupportedPBECryptoAlgo getSelectedCryptoAlgorithm() {
+ return encrCryptoAlgo;
+ }
+
+ @VisibleForTesting
+ SupportedPBECryptoAlgo getMKEncryptionAlgoName() {
+ List result = getEncryptedMK();
+ String encryptedPassString = null;
+ if (CollectionUtils.isNotEmpty(result) && result.size() == 2) {
+ encryptedPassString = (String) result.get(1);
+ }
+
+ return
SupportedPBECryptoAlgo.valueOf(fetchEncrAlgo(encryptedPassString));
+ }
+
+ @VisibleForTesting
+ void resetDefaultMDAlgoAndEncrAlgo() {
+ defaultMdAlgo = "MD5";
+ defaultCryptAlgo = SupportedPBECryptoAlgo.PBEWithMD5AndTripleDES;
+ }
}
diff --git
a/kms/src/test/java/org/apache/hadoop/crypto/key/RangerMasterKeyTest.java
b/kms/src/test/java/org/apache/hadoop/crypto/key/RangerMasterKeyTest.java
new file mode 100644
index 000000000..e76f2341c
--- /dev/null
+++ b/kms/src/test/java/org/apache/hadoop/crypto/key/RangerMasterKeyTest.java
@@ -0,0 +1,263 @@
+ /*
+ * 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 com.sun.jersey.core.util.Base64;
+import org.apache.hadoop.crypto.key.kms.server.DerbyTestUtils;
+import org.apache.hadoop.crypto.key.kms.server.KMSConfiguration;
+import org.apache.ranger.entity.XXRangerMasterKey;
+import org.apache.ranger.kms.dao.DaoManager;
+import org.apache.ranger.kms.dao.RangerMasterKeyDao;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import javax.crypto.Cipher;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.SecretKeySpec;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.security.Provider;
+import java.security.Security;
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+/**
+ * A test for the RangerMasterKey.
+ */
+public class RangerMasterKeyTest {
+ private static final boolean UNRESTRICTED_POLICIES_INSTALLED;
+
+ private RangerMasterKey rangerMasterKey;
+
+ private DaoManager daoManager;
+
+ @BeforeAll
+ public static void startServers() throws Exception {
+ if (!UNRESTRICTED_POLICIES_INSTALLED) {
+ return;
+ }
+ DerbyTestUtils.startDerby();
+ }
+
+ @AfterAll
+ public static void stopServers() throws Exception {
+ if (UNRESTRICTED_POLICIES_INSTALLED) {
+ DerbyTestUtils.stopDerby();
+ }
+ }
+
+ @BeforeEach
+ public void init() {
+ Path configDir = Paths.get("src/test/resources/kms");
+ System.setProperty(KMSConfiguration.KMS_CONFIG_DIR,
configDir.toFile().getAbsolutePath());
+
+ if (null == this.daoManager) {
+ RangerKMSDB rangerkmsDb = new
RangerKMSDB(RangerKeyStoreProvider.getDBKSConf());
+ this.daoManager = rangerkmsDb.getDaoManager();
+ }
+
+ Security.removeProvider("BC");
+ this.rangerMasterKey = new RangerMasterKey(daoManager);
+ }
+
+ @AfterEach
+ public void tearDown() {
+ RangerMasterKeyDao masterKeyDao = daoManager.getRangerMasterKeyDao();
+ List<XXRangerMasterKey> masterKeys = masterKeyDao.getAll();
+ if (null != masterKeys && !masterKeys.isEmpty()) {
+ XXRangerMasterKey masterKey = masterKeys.get(0);
+ masterKeyDao.remove(masterKey);
+ }
+ this.rangerMasterKey = null;
+ }
+
+ @Test
+ public void testRangerMasterKeyGenerationAndReencryption() throws
Throwable {
+ if (!UNRESTRICTED_POLICIES_INSTALLED) {
+ return;
+ }
+
+ String masterKeyPassword =
"password0password0password0password0password0password0password0password0"
+ +
"password0password0password0password0password0password0password0password0password0password0"
+ +
"password0password0password0password0password0password0password0password0password0password0";
+
+
Assertions.assertTrue(rangerMasterKey.generateMasterKey(masterKeyPassword));
+ String masterKey = rangerMasterKey.getMasterKey(masterKeyPassword);
+ Assertions.assertNotNull(masterKey);
+
+ try {
+ rangerMasterKey.getMasterKey("badpass");
+ Assertions.fail("Failure expected on retrieving a key with the
wrong password");
+ } catch (Exception ex) {
+ // expected
+ }
+
+
Assertions.assertNotNull(rangerMasterKey.getMasterSecretKey(masterKeyPassword));
+
+ try {
+ rangerMasterKey.getMasterSecretKey("badpass");
+ Assertions.fail("Failure expected on retrieving a key with the
wrong password");
+ } catch (Exception ex) {
+ // expected
+ }
+
+ /*
+ * Now prepare env with required FIPS configurations
+ Add BouncyCastleProvider at first position
+ Change keystore type to bcfks
+ */
+
+ // Before FIPS setup, default and selected crypto Algo should be
PBEWithMD5AndTripleDES
+ Assertions.assertEquals(SupportedPBECryptoAlgo.PBEWithMD5AndTripleDES,
rangerMasterKey.getDefaultCryptoAlgorithm());
+
+ Provider provider = new BouncyCastleProvider();
+ Security.insertProviderAt(provider, 1);
+ Security.setProperty("keystore.type", "bcfks");
+
+ rangerMasterKey.init();
+
+ Assertions.assertEquals(SupportedPBECryptoAlgo.PBKDF2WithHmacSHA256,
rangerMasterKey.getDefaultCryptoAlgorithm());
+ Assertions.assertEquals(SupportedPBECryptoAlgo.PBKDF2WithHmacSHA256,
rangerMasterKey.getSelectedCryptoAlgorithm());
+
+
Assertions.assertTrue(rangerMasterKey.reencryptMKWithFipsAlgo(masterKeyPassword));
+
+ // this checks the Algo name written in the DB.
+ Assertions.assertEquals(SupportedPBECryptoAlgo.PBKDF2WithHmacSHA256,
rangerMasterKey.getMKEncryptionAlgoName());
+
+ Assertions.assertEquals(masterKey,
rangerMasterKey.getMasterKey(masterKeyPassword));
+
+
Assertions.assertFalse(rangerMasterKey.reencryptMKWithFipsAlgo(masterKeyPassword));
+
+ // revert the FIPS specific changes so that other cases can execute
with default provider.
+ Security.removeProvider(provider.getName());
+ Security.setProperty("keystore.type", "jks");
+ rangerMasterKey.resetDefaultMDAlgoAndEncrAlgo();
+ }
+
+ @Test
+ public void testReencryptMKWithFipsAlgo() throws Exception {
+ if (!UNRESTRICTED_POLICIES_INSTALLED) {
+ return;
+ }
+
+ String masterKeyPassword =
"password0password0password0password0password0password0password0password0"
+ +
"password0password0password0password0password0password0password0password0password0password0"
+ +
"password0password0password0password0password0password0password0password0password0password0";
+
+
Assertions.assertFalse(rangerMasterKey.reencryptMKWithFipsAlgo(masterKeyPassword));
// or assertTrue if expecting re-encryption to happen
+ }
+
+ @Test
+ public void testGenerateMKFromHSMMK() throws Throwable {
+ if (!UNRESTRICTED_POLICIES_INSTALLED) {
+ return;
+ }
+
+ String password =
"password0password0password0password0password0password0password0password0"
+ +
"password0password0password0password0password0password0password0password0"
+ +
"password0password0password0password0password0password0password0";
+ byte[] key = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17};
+ rangerMasterKey.generateMKFromHSMMK(password, key);
+ }
+
+ @Test
+ public void testGenerateMKFromKeySecureMK() throws Throwable {
+ if (!UNRESTRICTED_POLICIES_INSTALLED) {
+ return;
+ }
+
+ String password =
"password0password0password0password0password0password0password0password0"
+ +
"password0password0password0password0password0password0password0";
+ byte[] key = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17};
+ rangerMasterKey.generateMKFromKeySecureMK(password, key);
+
+ assertNotNull(rangerMasterKey.getMasterKey(password));
+ }
+
+ @Test
+ public void testDecryptMasterKeySK() throws Exception {
+ if (!UNRESTRICTED_POLICIES_INSTALLED) {
+ return;
+ }
+
+ String password =
"password0password0password0password0password0password0password0password0"
+ +
"password0password0password0password0password0password0password0";
+
+ // Simulate a generated master key
+ byte[] rawKey = "myMockRawKey1234567890".getBytes(); //
Simulated secret key material
+ Method encryptMethod =
RangerMasterKey.class.getDeclaredMethod("encryptMasterKey", String.class,
byte[].class);
+ encryptMethod.setAccessible(true);
+ String encryptedStr = (String) encryptMethod.invoke(rangerMasterKey,
password, rawKey);
+
+ // Now decrypt using the method under test
+ Method decryptMethod = RangerMasterKey.class.getDeclaredMethod(
+ "decryptMasterKeySK", byte[].class, String.class,
String.class);
+ decryptMethod.setAccessible(true);
+
+ byte[] encryptedBytes = Base64.decode(encryptedStr);
+ SecretKey secretKey = (SecretKey)
decryptMethod.invoke(rangerMasterKey, encryptedBytes, password, encryptedStr);
+
+ assertNotNull(secretKey);
+ }
+
+ @Test
+ public void testGetIntConfig_ReturnsDefaultWhenPropertyMissing() throws
NoSuchMethodException, InvocationTargetException, IllegalAccessException {
+ if (!UNRESTRICTED_POLICIES_INSTALLED) {
+ return;
+ }
+
+ Method method =
RangerMasterKey.class.getDeclaredMethod("getIntConfig", String.class,
int.class);
+ method.setAccessible(true);
+ int defaultValue = 42;
+ int result = (int) method.invoke(rangerMasterKey,
"non.existent.property", defaultValue);
+ Assertions.assertEquals(defaultValue, result, "Expected default value
when property is missing");
+ }
+
+ static {
+ boolean ok = false;
+ try {
+ byte[] data = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
+
+ SecretKey key192 = new SecretKeySpec(
+ new byte[] {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17},
+ "AES");
+ Cipher c = Cipher.getInstance("AES");
+ c.init(Cipher.ENCRYPT_MODE, key192);
+ c.doFinal(data);
+ ok = true;
+ } catch (Exception e) {
+ //
+ }
+ UNRESTRICTED_POLICIES_INSTALLED = ok;
+ }
+}
diff --git
a/kms/src/test/java/org/apache/hadoop/crypto/key/TestFIPSRangerKeyStore.java
b/kms/src/test/java/org/apache/hadoop/crypto/key/TestFIPSRangerKeyStore.java
new file mode 100644
index 000000000..6fdd711cb
--- /dev/null
+++ b/kms/src/test/java/org/apache/hadoop/crypto/key/TestFIPSRangerKeyStore.java
@@ -0,0 +1,238 @@
+/*
+ * 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.crypto.key.kms.server.DerbyTestUtils;
+import org.apache.hadoop.crypto.key.kms.server.KMSConfiguration;
+import org.apache.ranger.kms.dao.DaoManager;
+import org.apache.ranger.plugin.util.JsonUtilsV2;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import javax.crypto.Cipher;
+import javax.crypto.KeyGenerator;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.SecretKeySpec;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.security.NoSuchAlgorithmException;
+import java.security.Security;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Map;
+
+public class TestFIPSRangerKeyStore {
+ private static final boolean UNRESTRICTED_POLICIES_INSTALLED;
+
+ private DaoManager daoManager;
+
+ private RangerKeyStore rangerKeyStore;
+
+ @BeforeAll
+ public static void startServers() throws Exception {
+ if (!UNRESTRICTED_POLICIES_INSTALLED) {
+ return;
+ }
+ DerbyTestUtils.startDerby();
+ }
+
+ @AfterAll
+ public static void stopServers() throws Exception {
+ if (UNRESTRICTED_POLICIES_INSTALLED) {
+ DerbyTestUtils.stopDerby();
+ }
+ }
+
+ @BeforeEach
+ public void init() {
+ Path configDir = Paths.get("src/test/resources/kms");
+ System.setProperty(KMSConfiguration.KMS_CONFIG_DIR,
configDir.toFile().getAbsolutePath());
+
+ if (null == this.daoManager) {
+ RangerKMSDB rangerkmsDb = new
RangerKMSDB(RangerKeyStoreProvider.getDBKSConf());
+ this.daoManager = rangerkmsDb.getDaoManager();
+ }
+
+ // This is required. AzureKeyVault Authentication code adds
BouncyCastleProvider in the provider list and creates problem if key is created
using non-fips key.
+ Security.removeProvider("BC");
+ }
+
+ @AfterEach
+ public void tearDown() {
+ this.rangerKeyStore = null;
+ }
+
+ /**
+ * This test case creates Zone key with FIPS Algorithm, provider is
BouncyCastleProvider
+ * Scenario:
+ * Simple Zone key creation using FIPS algo
+ * Assertions:
+ * Retrieved key from DB and after unseal operation, key material
should match with the original key material
+ * On FIPS enabled env, Key Attribute map should contain the
encryptionAlgo name, that is, PBKDF2WithHmacSHA256
+ * @throws Throwable
+ */
+ @Test
+ public void testZoneKeyEncryptionWithFipsAlgo() throws Throwable {
+ if (!UNRESTRICTED_POLICIES_INSTALLED) {
+ return;
+ }
+
+ BouncyCastleProvider bouncyCastleProvider = null;
+ try {
+ // Create a Zone key
+ char[] masterKey = "masterkey".toCharArray();
+ String keyName = "fipstestkey";
+ String versionName = keyName + "@0";
+ String cipher = "AES";
+ int bitLength = 192;
+ String attribute = JsonUtilsV2.mapToJson(Collections.emptyMap());
+ byte[] originalKeyMaterial = generateKey(bitLength, cipher);
+
+ bouncyCastleProvider = new BouncyCastleProvider();
+ Security.insertProviderAt(bouncyCastleProvider, 1);
+ this.rangerKeyStore = new RangerKeyStore(true, this.daoManager);
+
+ this.rangerKeyStore.addKeyEntry(versionName, new
SecretKeySpec(originalKeyMaterial, cipher), masterKey, cipher, bitLength,
"fipstestkey", 1, attribute);
+ this.rangerKeyStore.engineStore(null, masterKey);
+
+ SecretKeySpec key = (SecretKeySpec)
this.rangerKeyStore.engineGetKey(versionName, masterKey);
+ Assertions.assertNotNull(key);
+ Assertions.assertTrue(Arrays.equals(originalKeyMaterial,
key.getEncoded()));
+
Assertions.assertEquals(SupportedPBECryptoAlgo.PBKDF2WithHmacSHA256.getAlgoName(),
this.getKeyAttributeMap(this.rangerKeyStore,
versionName).get(RangerKeyStore.KEY_CRYPTO_ALGO_NAME));
+
+ this.rangerKeyStore.engineDeleteEntry(versionName);
+
Assertions.assertNull(this.rangerKeyStore.engineGetKey(versionName, masterKey));
+ } finally {
+ if (null != bouncyCastleProvider) {
+ Security.removeProvider(bouncyCastleProvider.getName());
+ }
+ }
+ }
+
+ /**
+ * This test case creates Zone key with Non-FIPS Algorithm, and then
reencrypts the key using FIPS Algorithm, provider is BouncyCastleProvider.
+ * Purpose of this test case is to verify key-reencryption logic.
+ * Scenario:
+ * Simple Zone key creation using Non-FIPS algo
+ * Re-encrypt the zone key using FIPS-Algo
+ * Assertions:
+ * Before reencryption: Retrieved key from DB and after unseal
operation, key material should match with the original key material and Key
Attribute map should be empty in this case.
+ * After reencryption: Retrieved key from DB and after unseal
operation, key material should match with the original key material
+ * And Key Attribute map should contain the
encryptionAlgo name, that is, PBKDF2WithHmacSHA256
+ * @throws Throwable
+ */
+ @Test
+ public void testZoneKeyReencryptionWithFipsAlgo() throws Throwable {
+ if (!UNRESTRICTED_POLICIES_INSTALLED) {
+ return;
+ }
+
+ BouncyCastleProvider bouncyCastleProvider = null;
+ try {
+ // Create a Zone key
+ char[] masterKey = "masterkey".toCharArray();
+ String keyName = "fipstestkey";
+ String versionName = keyName + "@0";
+ String cipher = "AES";
+ int bitLength = 192;
+
+ this.rangerKeyStore = new RangerKeyStore(this.daoManager);
+ String attribute = JsonUtilsV2.mapToJson(Collections.emptyMap());
+ byte[] originalKeyMaterial = generateKey(bitLength, cipher);
+
+ this.rangerKeyStore.addKeyEntry(versionName, new
SecretKeySpec(originalKeyMaterial, cipher), masterKey, cipher, bitLength,
"fipstestkey", 1, attribute);
+ this.rangerKeyStore.engineStore(null, masterKey);
+
+ SecretKeySpec key = (SecretKeySpec)
this.rangerKeyStore.engineGetKey(versionName, masterKey);
+ Assertions.assertNotNull(key);
+ Assertions.assertTrue(Arrays.equals(originalKeyMaterial,
key.getEncoded()));
+ Assertions.assertNull(this.getKeyAttributeMap(this.rangerKeyStore,
versionName).get(RangerKeyStore.KEY_CRYPTO_ALGO_NAME));
+
+ // Till now, ZoneKey was created using non-fips algo.
+ // Now set FIPS parameters and invoke reencrypt.
+
+ bouncyCastleProvider = new BouncyCastleProvider();
+ Security.insertProviderAt(bouncyCastleProvider, 1);
+ this.rangerKeyStore = new RangerKeyStore(true, this.daoManager);
+
+ this.rangerKeyStore.reencryptZoneKeysWithNewAlgo(null, masterKey);
+
+ key = (SecretKeySpec)
this.rangerKeyStore.engineGetKey(versionName, masterKey);
+ Assertions.assertNotNull(key);
+ Assertions.assertTrue(Arrays.equals(originalKeyMaterial,
key.getEncoded()));
+
Assertions.assertEquals(SupportedPBECryptoAlgo.PBKDF2WithHmacSHA256.getAlgoName(),
this.getKeyAttributeMap(this.rangerKeyStore,
versionName).get(RangerKeyStore.KEY_CRYPTO_ALGO_NAME));
+
+ this.rangerKeyStore.engineDeleteEntry(versionName);
+
Assertions.assertNull(this.rangerKeyStore.engineGetKey(versionName, masterKey));
+ } finally {
+ if (null != bouncyCastleProvider) {
+ Security.removeProvider(bouncyCastleProvider.getName());
+ }
+ }
+ }
+
+ private Map<String, String> getKeyAttributeMap(RangerKeyStore
rangerKeyStore, String alias) throws Exception {
+ Class<?> cls = rangerKeyStore.getClass();
+
+ Method method = cls.getDeclaredMethod("getKeyEntry", String.class);
+ method.setAccessible(true);
+ Object secretEntry = (Object) method.invoke(rangerKeyStore, alias);
+
+ Class<?> secretKeyEntryCls =
Class.forName("org.apache.hadoop.crypto.key.RangerKeyStore$SecretKeyEntry");
+ Field secretkeyAttrField =
secretKeyEntryCls.getDeclaredField("attributes");
+ secretkeyAttrField.setAccessible(true);
+ String attribute = (String) secretkeyAttrField.get(secretEntry);
+
+ return JsonUtilsV2.jsonToMap(attribute);
+ }
+
+ private byte[] generateKey(int size, String algorithm) throws
NoSuchAlgorithmException {
+ KeyGenerator keyGenerator = KeyGenerator.getInstance(algorithm);
+ keyGenerator.init(size);
+ byte[] key = keyGenerator.generateKey().getEncoded();
+ return key;
+ }
+
+ static {
+ boolean ok = false;
+ try {
+ byte[] data = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
+
+ SecretKey key192 = new SecretKeySpec(
+ new byte[] {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17},
+ "AES");
+ Cipher c = Cipher.getInstance("AES");
+ c.init(Cipher.ENCRYPT_MODE, key192);
+ c.doFinal(data);
+ ok = true;
+ } catch (Exception e) {
+ //
+ }
+ UNRESTRICTED_POLICIES_INSTALLED = ok;
+ }
+}
diff --git
a/kms/src/test/java/org/apache/hadoop/crypto/key/kms/RangerMasterKeyTest.java
b/kms/src/test/java/org/apache/hadoop/crypto/key/kms/RangerMasterKeyTest.java
deleted file mode 100644
index 6abca9f3e..000000000
---
a/kms/src/test/java/org/apache/hadoop/crypto/key/kms/RangerMasterKeyTest.java
+++ /dev/null
@@ -1,305 +0,0 @@
- /*
- * 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.kms;
-
-import com.sun.jersey.core.util.Base64;
-import org.apache.hadoop.crypto.key.RangerKMSDB;
-import org.apache.hadoop.crypto.key.RangerKeyStoreProvider;
-import org.apache.hadoop.crypto.key.RangerMasterKey;
-import org.apache.hadoop.crypto.key.kms.server.DerbyTestUtils;
-import org.apache.hadoop.crypto.key.kms.server.KMSConfiguration;
-import org.apache.ranger.kms.dao.DaoManager;
-import org.junit.jupiter.api.AfterAll;
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.Test;
-
-import javax.crypto.Cipher;
-import javax.crypto.SecretKey;
-import javax.crypto.spec.SecretKeySpec;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.Properties;
-
-import static org.junit.jupiter.api.Assertions.assertNotNull;
-
-/**
- * A test for the RangerMasterKey.
- */
-public class RangerMasterKeyTest {
- private static final boolean UNRESTRICTED_POLICIES_INSTALLED;
-
- @BeforeAll
- public static void startServers() throws Exception {
- if (!UNRESTRICTED_POLICIES_INSTALLED) {
- return;
- }
- DerbyTestUtils.startDerby();
- }
-
- @AfterAll
- public static void stopServers() throws Exception {
- if (UNRESTRICTED_POLICIES_INSTALLED) {
- DerbyTestUtils.stopDerby();
- }
- }
-
- @Test
- public void testFetchEncrAlgo_DefaultFallback() throws Exception {
- if (!UNRESTRICTED_POLICIES_INSTALLED) {
- return;
- }
-
- Path configDir = Paths.get("src/test/resources/kms");
- System.setProperty(KMSConfiguration.KMS_CONFIG_DIR,
configDir.toFile().getAbsolutePath());
-
- RangerKMSDB rangerkmsDb = new
RangerKMSDB(RangerKeyStoreProvider.getDBKSConf());
- DaoManager daoManager = rangerkmsDb.getDaoManager();
- RangerMasterKey rangerMasterKey = new RangerMasterKey(daoManager);
-
- String inputWithoutComma = "verylongstringwithoutcommapassword123";
-
- Method method =
RangerMasterKey.class.getDeclaredMethod("fetchEncrAlgo", String.class);
- method.setAccessible(true);
-
- String result = (String) method.invoke(rangerMasterKey,
inputWithoutComma);
- Assertions.assertEquals("PBEWithMD5AndTripleDES", result); // default
fallback
- }
-
- @Test
- public void testReencryptMKWithFipsAlgo() throws Exception {
- if (!UNRESTRICTED_POLICIES_INSTALLED) {
- return;
- }
-
- Path configDir = Paths.get("src/test/resources/kms");
- System.setProperty(KMSConfiguration.KMS_CONFIG_DIR,
configDir.toFile().getAbsolutePath());
-
- RangerKMSDB rangerkmsDb = new
RangerKMSDB(RangerKeyStoreProvider.getDBKSConf());
- DaoManager daoManager = rangerkmsDb.getDaoManager();
- RangerMasterKey rangerMasterKey = new RangerMasterKey(daoManager);
-
- String inputWithoutComma = "verylongstringwithoutcommapassword123";
-
- Method method =
RangerMasterKey.class.getDeclaredMethod("reencryptMKWithFipsAlgo",
String.class);
- method.setAccessible(true);
-
- boolean result = (boolean) method.invoke(rangerMasterKey,
inputWithoutComma);
- Assertions.assertFalse(result); // or assertTrue if expecting
re-encryption to happen
- }
-
- @Test
- public void testGenerateMKFromHSMMK() throws Throwable {
- if (!UNRESTRICTED_POLICIES_INSTALLED) {
- return;
- }
-
- Path configDir = Paths.get("src/test/resources/kms");
- System.setProperty(KMSConfiguration.KMS_CONFIG_DIR,
configDir.toFile().getAbsolutePath());
-
- RangerKMSDB rangerkmsDb = new
RangerKMSDB(RangerKeyStoreProvider.getDBKSConf());
- DaoManager daoManager = rangerkmsDb.getDaoManager();
- RangerMasterKey rangerMasterKey = new RangerMasterKey(daoManager);
-
- String password =
"password0password0password0password0password0password0password0password0"
- +
"password0password0password0password0password0password0password0password0"
- +
"password0password0password0password0password0password0password0";
- byte[] key = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
- 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
- 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17};
- rangerMasterKey.generateMKFromHSMMK(password, key);
- }
-
- @Test
- public void testGenerateMKFromKeySecureMK() throws Throwable {
- if (!UNRESTRICTED_POLICIES_INSTALLED) {
- return;
- }
-
- Path configDir = Paths.get("src/test/resources/kms");
- System.setProperty(KMSConfiguration.KMS_CONFIG_DIR,
configDir.toFile().getAbsolutePath());
-
- RangerKMSDB rangerkmsDb = new
RangerKMSDB(RangerKeyStoreProvider.getDBKSConf());
- DaoManager daoManager = rangerkmsDb.getDaoManager();
- RangerMasterKey rangerMasterKey = new RangerMasterKey(daoManager);
-
- String password =
"password0password0password0password0password0password0password0password0"
- +
"password0password0password0password0password0password0password0";
- byte[] key = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
- 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
- 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17};
- rangerMasterKey.generateMKFromKeySecureMK(password, key);
-
- assertNotNull(rangerMasterKey.getMasterKey(password));
- }
-
- @Test
- public void testDecryptMasterKeySK() throws Exception {
- if (!UNRESTRICTED_POLICIES_INSTALLED) {
- return;
- }
-
- Path configDir = Paths.get("src/test/resources/kms");
- System.setProperty(KMSConfiguration.KMS_CONFIG_DIR,
configDir.toFile().getAbsolutePath());
-
- RangerKMSDB rangerkmsDb = new
RangerKMSDB(RangerKeyStoreProvider.getDBKSConf());
- DaoManager daoManager = rangerkmsDb.getDaoManager();
- RangerMasterKey rangerMasterKey = new RangerMasterKey(daoManager);
-
- String password =
"password0password0password0password0password0password0password0password0"
- +
"password0password0password0password0password0password0password0";
-
- // Simulate a generated master key
- byte[] rawKey = "myMockRawKey1234567890".getBytes(); //
Simulated secret key material
- Method encryptMethod =
RangerMasterKey.class.getDeclaredMethod("encryptMasterKey", String.class,
byte[].class);
- encryptMethod.setAccessible(true);
- String encryptedStr = (String) encryptMethod.invoke(rangerMasterKey,
password, rawKey);
-
- // Now decrypt using the method under test
- Method decryptMethod = RangerMasterKey.class.getDeclaredMethod(
- "decryptMasterKeySK", byte[].class, String.class,
String.class);
- decryptMethod.setAccessible(true);
-
- byte[] encryptedBytes = Base64.decode(encryptedStr);
- SecretKey secretKey = (SecretKey)
decryptMethod.invoke(rangerMasterKey, encryptedBytes, password, encryptedStr);
-
- assertNotNull(secretKey);
- }
-
- @Test
- public void testUpdateEncryptedMK() throws Exception {
- if (!UNRESTRICTED_POLICIES_INSTALLED) {
- return;
- }
-
- Path configDir = Paths.get("src/test/resources/kms");
- RangerKMSDB rangerkmsDb = new
RangerKMSDB(RangerKeyStoreProvider.getDBKSConf());
- DaoManager daoManager = rangerkmsDb.getDaoManager();
- RangerMasterKey rangerMasterKey = new RangerMasterKey(daoManager);
-
- String password =
"password0password0password0password0password0password0password0password0"
- +
"password0password0password0password0password0password0password0";
-
- byte[] rawKey = "myMockRawKey1234567890".getBytes();
-
- Method updateEncryptedMKMethod =
RangerMasterKey.class.getDeclaredMethod(
- "updateEncryptedMK", String.class);
- updateEncryptedMKMethod.setAccessible(true);
- updateEncryptedMKMethod.invoke(rangerMasterKey, password);
- }
-
- @Test
- public void testGetFIPSCompliantPassword() throws NoSuchMethodException,
InvocationTargetException, IllegalAccessException {
- if (!UNRESTRICTED_POLICIES_INSTALLED) {
- return;
- }
-
- Path configDir = Paths.get("src/test/resources/kms");
- System.setProperty(KMSConfiguration.KMS_CONFIG_DIR,
configDir.toFile().getAbsolutePath());
-
- RangerKMSDB rangerkmsDb = new
RangerKMSDB(RangerKeyStoreProvider.getDBKSConf());
- DaoManager daoManager = rangerkmsDb.getDaoManager();
- RangerMasterKey rangerMasterKey = new RangerMasterKey(daoManager);
-
- String password =
"password0password0password0password0password0password0password0password0"
- +
"password0password0password0password0password0password0password0";
-
- Method getFIPSCompliantPasswordMethod =
RangerMasterKey.class.getDeclaredMethod(
- "getFIPSCompliantPassword", String.class);
- getFIPSCompliantPasswordMethod.setAccessible(true);
- getFIPSCompliantPasswordMethod.invoke(rangerMasterKey, password);
- }
-
- @Test
- public void testGetPasswordParam() throws NoSuchMethodException,
InvocationTargetException, IllegalAccessException {
- if (!UNRESTRICTED_POLICIES_INSTALLED) {
- return;
- }
-
- Path configDir = Paths.get("src/test/resources/kms");
- System.setProperty(KMSConfiguration.KMS_CONFIG_DIR,
configDir.toFile().getAbsolutePath());
-
- RangerKMSDB rangerkmsDb = new
RangerKMSDB(RangerKeyStoreProvider.getDBKSConf());
- DaoManager daoManager = rangerkmsDb.getDaoManager();
- RangerMasterKey rangerMasterKey = new RangerMasterKey(daoManager);
-
- String password =
"password0password0password0password0password0password0password0password0"
- +
"password0password0password0password0password0password0password0";
-
- Method getPasswordParamMethod =
RangerMasterKey.class.getDeclaredMethod(
- "getPasswordParam", String.class);
- getPasswordParamMethod.setAccessible(true);
- getPasswordParamMethod.invoke(rangerMasterKey, password);
- }
-
- @Test
- public void testGetIntConfig_ReturnsDefaultWhenPropertyMissing() throws
NoSuchMethodException, InvocationTargetException, IllegalAccessException {
- if (!UNRESTRICTED_POLICIES_INSTALLED) {
- return;
- }
-
- Path configDir = Paths.get("src/test/resources/kms");
- System.setProperty(KMSConfiguration.KMS_CONFIG_DIR,
configDir.toFile().getAbsolutePath());
-
- RangerKMSDB rangerkmsDb = new
RangerKMSDB(RangerKeyStoreProvider.getDBKSConf());
- DaoManager daoManager = rangerkmsDb.getDaoManager();
- RangerMasterKey rangerMasterKey = new RangerMasterKey(daoManager);
-
- Method method =
RangerMasterKey.class.getDeclaredMethod("getIntConfig", String.class,
int.class);
- method.setAccessible(true);
- int defaultValue = 42;
- int result = (int) method.invoke(rangerMasterKey,
"non.existent.property", defaultValue);
- Assertions.assertEquals(defaultValue, result, "Expected default value
when property is missing");
- }
-
- @Test
- public void testGetIntConfig_ParsesValidInteger() throws Exception {
- Field propField =
RangerMasterKey.class.getDeclaredField("serverConfigProperties");
- propField.setAccessible(true);
- Properties props = new Properties();
- props.setProperty("valid.int.key", "123");
-
- Method method =
RangerMasterKey.class.getDeclaredMethod("getIntConfig", String.class,
int.class);
- method.setAccessible(true);
- int invoke = (int) method.invoke(null, "valid.int.key", 42);
- }
-
- static {
- boolean ok = false;
- try {
- byte[] data = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
-
- SecretKey key192 = new SecretKeySpec(
- new byte[] {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
- 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
- 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17},
- "AES");
- Cipher c = Cipher.getInstance("AES");
- c.init(Cipher.ENCRYPT_MODE, key192);
- c.doFinal(data);
- ok = true;
- } catch (Exception e) {
- //
- }
- UNRESTRICTED_POLICIES_INSTALLED = ok;
- }
-}
diff --git
a/kms/src/test/java/org/apache/hadoop/crypto/key/kms/server/RangerMasterKeyTest.java
b/kms/src/test/java/org/apache/hadoop/crypto/key/kms/server/RangerMasterKeyTest.java
deleted file mode 100644
index 8d2b3c806..000000000
---
a/kms/src/test/java/org/apache/hadoop/crypto/key/kms/server/RangerMasterKeyTest.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * 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.kms.server;
-
-import org.apache.hadoop.crypto.key.RangerKMSDB;
-import org.apache.hadoop.crypto.key.RangerKeyStoreProvider;
-import org.apache.hadoop.crypto.key.RangerMasterKey;
-import org.apache.ranger.kms.dao.DaoManager;
-import org.junit.jupiter.api.AfterAll;
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.Test;
-
-import javax.crypto.Cipher;
-import javax.crypto.SecretKey;
-import javax.crypto.spec.SecretKeySpec;
-
-import java.nio.file.Path;
-import java.nio.file.Paths;
-
-/**
- * A test for the RangerMasterKey.
- */
-public class RangerMasterKeyTest {
- private static final boolean UNRESTRICTED_POLICIES_INSTALLED;
-
- @BeforeAll
- public static void startServers() throws Exception {
- if (!UNRESTRICTED_POLICIES_INSTALLED) {
- return;
- }
- DerbyTestUtils.startDerby();
- }
-
- @AfterAll
- public static void stopServers() throws Exception {
- if (UNRESTRICTED_POLICIES_INSTALLED) {
- DerbyTestUtils.stopDerby();
- }
- }
-
- @Test
- public void testRangerMasterKey() throws Throwable {
- if (!UNRESTRICTED_POLICIES_INSTALLED) {
- return;
- }
-
- Path configDir = Paths.get("src/test/resources/kms");
- System.setProperty(KMSConfiguration.KMS_CONFIG_DIR,
configDir.toFile().getAbsolutePath());
-
- RangerKMSDB rangerkmsDb = new
RangerKMSDB(RangerKeyStoreProvider.getDBKSConf());
- DaoManager daoManager = rangerkmsDb.getDaoManager();
-
- String masterKeyPassword =
"password0password0password0password0password0password0password0password0"
- +
"password0password0password0password0password0password0password0password0password0password0"
- +
"password0password0password0password0password0password0password0password0password0password0";
-
- RangerMasterKey rangerMasterKey = new RangerMasterKey(daoManager);
-
Assertions.assertTrue(rangerMasterKey.generateMasterKey(masterKeyPassword));
-
Assertions.assertNotNull(rangerMasterKey.getMasterKey(masterKeyPassword));
-
- try {
- rangerMasterKey.getMasterKey("badpass");
- Assertions.fail("Failure expected on retrieving a key with the
wrong password");
- } catch (Exception ex) {
- // expected
- }
-
-
Assertions.assertNotNull(rangerMasterKey.getMasterSecretKey(masterKeyPassword));
-
- try {
- rangerMasterKey.getMasterSecretKey("badpass");
- Assertions.fail("Failure expected on retrieving a key with the
wrong password");
- } catch (Exception ex) {
- // expected
- }
- }
-
- static {
- boolean ok = false;
- try {
- byte[] data = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
-
- SecretKey key192 = new SecretKeySpec(
- new byte[] {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
- 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
- 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17},
- "AES");
- Cipher c = Cipher.getInstance("AES");
- c.init(Cipher.ENCRYPT_MODE, key192);
- c.doFinal(data);
- ok = true;
- } catch (Exception e) {
- //
- }
- UNRESTRICTED_POLICIES_INSTALLED = ok;
- }
-}