public void reencryptEncryptedKeys(List<EncryptedKeyVersion> ekvs)
      throws IOException, GeneralSecurityException {
    getExtension().reencryptEncryptedKeys(ekvs);
  }
@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()));
    }
  }