|
@@ -33,7 +33,9 @@ import org.apache.hadoop.conf.Configuration;
|
|
|
import org.apache.hadoop.crypto.key.KeyProviderCryptoExtension.EncryptedKeyVersion;
|
|
|
import org.junit.Assert;
|
|
|
import org.junit.BeforeClass;
|
|
|
+import org.junit.Rule;
|
|
|
import org.junit.Test;
|
|
|
+import org.junit.rules.Timeout;
|
|
|
|
|
|
import static org.apache.hadoop.crypto.key.KeyProvider.KeyVersion;
|
|
|
import static org.junit.Assert.assertArrayEquals;
|
|
@@ -52,6 +54,9 @@ public class TestKeyProviderCryptoExtension {
|
|
|
private static KeyProvider.Options options;
|
|
|
private static KeyVersion encryptionKey;
|
|
|
|
|
|
+ @Rule
|
|
|
+ public Timeout testTimeout = new Timeout(180000);
|
|
|
+
|
|
|
@BeforeClass
|
|
|
public static void setup() throws Exception {
|
|
|
conf = new Configuration();
|
|
@@ -138,6 +143,103 @@ public class TestKeyProviderCryptoExtension {
|
|
|
manualMaterial, apiMaterial);
|
|
|
}
|
|
|
|
|
|
+ @Test
|
|
|
+ public void testReencryptEncryptedKey() throws Exception {
|
|
|
+ // Generate a new EEK
|
|
|
+ final KeyProviderCryptoExtension.EncryptedKeyVersion ek1 =
|
|
|
+ kpExt.generateEncryptedKey(encryptionKey.getName());
|
|
|
+
|
|
|
+ // Decrypt EEK into an EK and check it
|
|
|
+ final KeyVersion k1 = kpExt.decryptEncryptedKey(ek1);
|
|
|
+ assertEquals(KeyProviderCryptoExtension.EK, k1.getVersionName());
|
|
|
+ assertEquals(encryptionKey.getMaterial().length, k1.getMaterial().length);
|
|
|
+ if (Arrays.equals(k1.getMaterial(), encryptionKey.getMaterial())) {
|
|
|
+ fail("Encrypted key material should not equal encryption key material");
|
|
|
+ }
|
|
|
+
|
|
|
+ // Roll the EK
|
|
|
+ kpExt.rollNewVersion(ek1.getEncryptionKeyName());
|
|
|
+
|
|
|
+ // Reencrypt ek1
|
|
|
+ final KeyProviderCryptoExtension.EncryptedKeyVersion ek2 =
|
|
|
+ kpExt.reencryptEncryptedKey(ek1);
|
|
|
+ assertEquals("Version name of EEK should be EEK",
|
|
|
+ KeyProviderCryptoExtension.EEK,
|
|
|
+ ek2.getEncryptedKeyVersion().getVersionName());
|
|
|
+ assertEquals("Name of EEK should be encryption key name",
|
|
|
+ ENCRYPTION_KEY_NAME, ek2.getEncryptionKeyName());
|
|
|
+ assertNotNull("Expected encrypted key material",
|
|
|
+ ek2.getEncryptedKeyVersion().getMaterial());
|
|
|
+ assertEquals("Length of encryption key material and EEK material should "
|
|
|
+ + "be the same", encryptionKey.getMaterial().length,
|
|
|
+ ek2.getEncryptedKeyVersion().getMaterial().length);
|
|
|
+ if (Arrays.equals(ek2.getEncryptedKeyVersion().getMaterial(),
|
|
|
+ encryptionKey.getMaterial())) {
|
|
|
+ fail("Encrypted key material should not equal decrypted key material");
|
|
|
+ }
|
|
|
+ if (Arrays.equals(ek2.getEncryptedKeyVersion().getMaterial(),
|
|
|
+ ek1.getEncryptedKeyVersion().getMaterial())) {
|
|
|
+ fail("Re-encrypted EEK should have different material");
|
|
|
+ }
|
|
|
+
|
|
|
+ // Decrypt the new EEK into an EK and check it
|
|
|
+ final KeyVersion k2 = kpExt.decryptEncryptedKey(ek2);
|
|
|
+ assertEquals(KeyProviderCryptoExtension.EK, k2.getVersionName());
|
|
|
+ assertEquals(encryptionKey.getMaterial().length, k2.getMaterial().length);
|
|
|
+ if (Arrays.equals(k2.getMaterial(), encryptionKey.getMaterial())) {
|
|
|
+ fail("Encrypted key material should not equal encryption key material");
|
|
|
+ }
|
|
|
+
|
|
|
+ // Re-encrypting the same EEK with the same EK should be deterministic
|
|
|
+ final KeyProviderCryptoExtension.EncryptedKeyVersion ek2a =
|
|
|
+ kpExt.reencryptEncryptedKey(ek1);
|
|
|
+ assertEquals("Version name of EEK should be EEK",
|
|
|
+ KeyProviderCryptoExtension.EEK,
|
|
|
+ ek2a.getEncryptedKeyVersion().getVersionName());
|
|
|
+ assertEquals("Name of EEK should be encryption key name",
|
|
|
+ ENCRYPTION_KEY_NAME, ek2a.getEncryptionKeyName());
|
|
|
+ assertNotNull("Expected encrypted key material",
|
|
|
+ ek2a.getEncryptedKeyVersion().getMaterial());
|
|
|
+ assertEquals("Length of encryption key material and EEK material should "
|
|
|
+ + "be the same", encryptionKey.getMaterial().length,
|
|
|
+ ek2a.getEncryptedKeyVersion().getMaterial().length);
|
|
|
+ if (Arrays.equals(ek2a.getEncryptedKeyVersion().getMaterial(),
|
|
|
+ encryptionKey.getMaterial())) {
|
|
|
+ fail("Encrypted key material should not equal decrypted key material");
|
|
|
+ }
|
|
|
+ if (Arrays.equals(ek2a.getEncryptedKeyVersion().getMaterial(),
|
|
|
+ ek1.getEncryptedKeyVersion().getMaterial())) {
|
|
|
+ fail("Re-encrypted EEK should have different material");
|
|
|
+ }
|
|
|
+ assertArrayEquals(ek2.getEncryptedKeyVersion().getMaterial(),
|
|
|
+ ek2a.getEncryptedKeyVersion().getMaterial());
|
|
|
+
|
|
|
+ // Re-encrypting an EEK with the same version EK should be no-op
|
|
|
+ final KeyProviderCryptoExtension.EncryptedKeyVersion ek3 =
|
|
|
+ kpExt.reencryptEncryptedKey(ek2);
|
|
|
+ assertEquals("Version name of EEK should be EEK",
|
|
|
+ KeyProviderCryptoExtension.EEK,
|
|
|
+ ek3.getEncryptedKeyVersion().getVersionName());
|
|
|
+ assertEquals("Name of EEK should be encryption key name",
|
|
|
+ ENCRYPTION_KEY_NAME, ek3.getEncryptionKeyName());
|
|
|
+ assertNotNull("Expected encrypted key material",
|
|
|
+ ek3.getEncryptedKeyVersion().getMaterial());
|
|
|
+ assertEquals("Length of encryption key material and EEK material should "
|
|
|
+ + "be the same", encryptionKey.getMaterial().length,
|
|
|
+ ek3.getEncryptedKeyVersion().getMaterial().length);
|
|
|
+ if (Arrays.equals(ek3.getEncryptedKeyVersion().getMaterial(),
|
|
|
+ encryptionKey.getMaterial())) {
|
|
|
+ fail("Encrypted key material should not equal decrypted key material");
|
|
|
+ }
|
|
|
+
|
|
|
+ if (Arrays.equals(ek3.getEncryptedKeyVersion().getMaterial(),
|
|
|
+ ek1.getEncryptedKeyVersion().getMaterial())) {
|
|
|
+ fail("Re-encrypted EEK should have different material");
|
|
|
+ }
|
|
|
+ assertArrayEquals(ek2.getEncryptedKeyVersion().getMaterial(),
|
|
|
+ ek3.getEncryptedKeyVersion().getMaterial());
|
|
|
+ }
|
|
|
+
|
|
|
@Test
|
|
|
public void testNonDefaultCryptoExtensionSelectionWithCachingKeyProvider()
|
|
|
throws Exception {
|
|
@@ -233,6 +335,12 @@ public class TestKeyProviderCryptoExtension {
|
|
|
return this.ekv;
|
|
|
}
|
|
|
|
|
|
+ @Override
|
|
|
+ public EncryptedKeyVersion reencryptEncryptedKey(EncryptedKeyVersion ekv)
|
|
|
+ throws IOException, GeneralSecurityException {
|
|
|
+ return ekv;
|
|
|
+ }
|
|
|
+
|
|
|
@Override
|
|
|
public KeyVersion decryptEncryptedKey(
|
|
|
EncryptedKeyVersion encryptedKeyVersion)
|
|
@@ -339,5 +447,11 @@ public class TestKeyProviderCryptoExtension {
|
|
|
throws IOException, GeneralSecurityException {
|
|
|
return kv;
|
|
|
}
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public EncryptedKeyVersion reencryptEncryptedKey(EncryptedKeyVersion ekv)
|
|
|
+ throws IOException, GeneralSecurityException {
|
|
|
+ return ekv;
|
|
|
+ }
|
|
|
}
|
|
|
}
|