@Test
public void testReencryptEncryptedKeys() throws Exception {

  List<EncryptedKeyVersion> ekvs = new ArrayList<>(4);
  // Generate 2 new EEKs @v0 and add to the list
  ekvs.add(kpExt.generateEncryptedKey(encryptionKey.getName()));
  ekvs.add(kpExt.generateEncryptedKey(encryptionKey.getName()));
  // Roll the EK
  kpExt.rollNewVersion(ekvs.get(0).getEncryptionKeyName());
  // Generate 1 new EEK @v1 add to the list.
  ekvs.add(kpExt.generateEncryptedKey(encryptionKey.getName()));
  // Roll the EK again
  kpExt.rollNewVersion(ekvs.get(0).getEncryptionKeyName());
  // Generate 1 new EEK @v2 add to the list.
  ekvs.add(kpExt.generateEncryptedKey(encryptionKey.getName()));
  // leave a deep copy of the original, for verification purpose.
  List<EncryptedKeyVersion> ekvsOrig = new ArrayList<>(ekvs.size());
  for (EncryptedKeyVersion ekv : ekvs) {
    ekvsOrig.add(new EncryptedKeyVersion(ekv.getEncryptionKeyName(),
        ekv.getEncryptionKeyVersionName(), ekv.getEncryptedKeyIv(),
        ekv.getEncryptedKeyVersion()));
  }
  // Reencrypt ekvs
  kpExt.reencryptEncryptedKeys(ekvs);
  // Verify each ekv
  for (int i = 0; i < ekvs.size(); ++i) {
    final EncryptedKeyVersion ekv = ekvs.get(i);
    final EncryptedKeyVersion orig = ekvsOrig.get(i);
    assertEquals("Version name should be EEK",
        KeyProviderCryptoExtension.EEK,
        ekv.getEncryptedKeyVersion().getVersionName());
    assertEquals("Encryption key name should be " + ENCRYPTION_KEY_NAME,
        ENCRYPTION_KEY_NAME, ekv.getEncryptionKeyName());
    assertNotNull("Expected encrypted key material",
        ekv.getEncryptedKeyVersion().getMaterial());
    assertEquals("Length of encryption key material and EEK material should "
            + "be the same", encryptionKey.getMaterial().length,
        ekv.getEncryptedKeyVersion().getMaterial().length);
    assertFalse(
        "Encrypted key material should not equal encryption key material",
        Arrays.equals(ekv.getEncryptedKeyVersion().getMaterial(),
            encryptionKey.getMaterial()));
    if (i < 3) {
      assertFalse("Re-encrypted EEK should have different material",
          Arrays.equals(ekv.getEncryptedKeyVersion().getMaterial(),
              orig.getEncryptedKeyVersion().getMaterial()));
    } else {
      assertTrue("Re-encrypted EEK should have same material",
          Arrays.equals(ekv.getEncryptedKeyVersion().getMaterial(),
              orig.getEncryptedKeyVersion().getMaterial()));
    }
    // Decrypt the new EEK into an EK and check it
    final KeyVersion kv = kpExt.decryptEncryptedKey(ekv);
    assertEquals(KeyProviderCryptoExtension.EK, kv.getVersionName());
    // Decrypt it again and it should be the same
    KeyVersion kv1 = kpExt.decryptEncryptedKey(ekv);
    assertArrayEquals(kv.getMaterial(), kv1.getMaterial());
    // Verify decrypting the new EEK and orig EEK gives the same material.
    final KeyVersion origKv = kpExt.decryptEncryptedKey(orig);
    assertTrue("Returned EEK and original EEK should both decrypt to the "
        + "same kv.", Arrays.equals(origKv.getMaterial(), kv.getMaterial()));
  }
}