|
@@ -188,8 +188,8 @@ public class KeyProviderCryptoExtension extends
|
|
public void drain(String keyName);
|
|
public void drain(String keyName);
|
|
|
|
|
|
/**
|
|
/**
|
|
- * Generates a key material and encrypts it using the given key version name
|
|
|
|
- * and initialization vector. The generated key material is of the same
|
|
|
|
|
|
+ * Generates a key material and encrypts it using the given key name.
|
|
|
|
+ * The generated key material is of the same
|
|
* length as the <code>KeyVersion</code> material of the latest key version
|
|
* length as the <code>KeyVersion</code> material of the latest key version
|
|
* of the key and is encrypted using the same cipher.
|
|
* of the key and is encrypted using the same cipher.
|
|
* <p/>
|
|
* <p/>
|
|
@@ -210,7 +210,7 @@ public class KeyProviderCryptoExtension extends
|
|
GeneralSecurityException;
|
|
GeneralSecurityException;
|
|
|
|
|
|
/**
|
|
/**
|
|
- * Decrypts an encrypted byte[] key material using the given a key version
|
|
|
|
|
|
+ * Decrypts an encrypted byte[] key material using the given key version
|
|
* name and initialization vector.
|
|
* name and initialization vector.
|
|
*
|
|
*
|
|
* @param encryptedKeyVersion
|
|
* @param encryptedKeyVersion
|
|
@@ -227,6 +227,26 @@ public class KeyProviderCryptoExtension extends
|
|
public KeyVersion decryptEncryptedKey(
|
|
public KeyVersion decryptEncryptedKey(
|
|
EncryptedKeyVersion encryptedKeyVersion) throws IOException,
|
|
EncryptedKeyVersion encryptedKeyVersion) throws IOException,
|
|
GeneralSecurityException;
|
|
GeneralSecurityException;
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Re-encrypts an encrypted key version, using its initialization vector
|
|
|
|
+ * and key material, but with the latest key version name of its key name
|
|
|
|
+ * in the key provider.
|
|
|
|
+ * <p>
|
|
|
|
+ * If the latest key version name in the provider is the
|
|
|
|
+ * same as the one encrypted the passed-in encrypted key version, the same
|
|
|
|
+ * encrypted key version is returned.
|
|
|
|
+ * <p>
|
|
|
|
+ * NOTE: The generated key is not stored by the <code>KeyProvider</code>
|
|
|
|
+ *
|
|
|
|
+ * @param ekv The EncryptedKeyVersion containing keyVersionName and IV.
|
|
|
|
+ * @return The re-encrypted EncryptedKeyVersion.
|
|
|
|
+ * @throws IOException If the key material could not be re-encrypted.
|
|
|
|
+ * @throws GeneralSecurityException If the key material could not be
|
|
|
|
+ * re-encrypted because of a cryptographic issue.
|
|
|
|
+ */
|
|
|
|
+ EncryptedKeyVersion reencryptEncryptedKey(EncryptedKeyVersion ekv)
|
|
|
|
+ throws IOException, GeneralSecurityException;
|
|
}
|
|
}
|
|
|
|
|
|
private static class DefaultCryptoExtension implements CryptoExtension {
|
|
private static class DefaultCryptoExtension implements CryptoExtension {
|
|
@@ -258,24 +278,55 @@ public class KeyProviderCryptoExtension extends
|
|
cc.generateSecureRandom(newKey);
|
|
cc.generateSecureRandom(newKey);
|
|
final byte[] iv = new byte[cc.getCipherSuite().getAlgorithmBlockSize()];
|
|
final byte[] iv = new byte[cc.getCipherSuite().getAlgorithmBlockSize()];
|
|
cc.generateSecureRandom(iv);
|
|
cc.generateSecureRandom(iv);
|
|
|
|
+ Encryptor encryptor = cc.createEncryptor();
|
|
|
|
+ return generateEncryptedKey(encryptor, encryptionKey, newKey, iv);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private EncryptedKeyVersion generateEncryptedKey(final Encryptor encryptor,
|
|
|
|
+ final KeyVersion encryptionKey, final byte[] key, final byte[] iv)
|
|
|
|
+ throws IOException, GeneralSecurityException {
|
|
// Encryption key IV is derived from new key's IV
|
|
// Encryption key IV is derived from new key's IV
|
|
final byte[] encryptionIV = EncryptedKeyVersion.deriveIV(iv);
|
|
final byte[] encryptionIV = EncryptedKeyVersion.deriveIV(iv);
|
|
- Encryptor encryptor = cc.createEncryptor();
|
|
|
|
encryptor.init(encryptionKey.getMaterial(), encryptionIV);
|
|
encryptor.init(encryptionKey.getMaterial(), encryptionIV);
|
|
- int keyLen = newKey.length;
|
|
|
|
|
|
+ final int keyLen = key.length;
|
|
ByteBuffer bbIn = ByteBuffer.allocateDirect(keyLen);
|
|
ByteBuffer bbIn = ByteBuffer.allocateDirect(keyLen);
|
|
ByteBuffer bbOut = ByteBuffer.allocateDirect(keyLen);
|
|
ByteBuffer bbOut = ByteBuffer.allocateDirect(keyLen);
|
|
- bbIn.put(newKey);
|
|
|
|
|
|
+ bbIn.put(key);
|
|
bbIn.flip();
|
|
bbIn.flip();
|
|
encryptor.encrypt(bbIn, bbOut);
|
|
encryptor.encrypt(bbIn, bbOut);
|
|
bbOut.flip();
|
|
bbOut.flip();
|
|
byte[] encryptedKey = new byte[keyLen];
|
|
byte[] encryptedKey = new byte[keyLen];
|
|
- bbOut.get(encryptedKey);
|
|
|
|
- return new EncryptedKeyVersion(encryptionKeyName,
|
|
|
|
|
|
+ bbOut.get(encryptedKey);
|
|
|
|
+ return new EncryptedKeyVersion(encryptionKey.getName(),
|
|
encryptionKey.getVersionName(), iv,
|
|
encryptionKey.getVersionName(), iv,
|
|
new KeyVersion(encryptionKey.getName(), EEK, encryptedKey));
|
|
new KeyVersion(encryptionKey.getName(), EEK, encryptedKey));
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ @Override
|
|
|
|
+ public EncryptedKeyVersion reencryptEncryptedKey(EncryptedKeyVersion ekv)
|
|
|
|
+ throws IOException, GeneralSecurityException {
|
|
|
|
+ final String ekName = ekv.getEncryptionKeyName();
|
|
|
|
+ final KeyVersion ekNow = keyProvider.getCurrentKey(ekName);
|
|
|
|
+ Preconditions
|
|
|
|
+ .checkNotNull(ekNow, "KeyVersion name '%s' does not exist", ekName);
|
|
|
|
+ Preconditions.checkArgument(ekv.getEncryptedKeyVersion().getVersionName()
|
|
|
|
+ .equals(KeyProviderCryptoExtension.EEK),
|
|
|
|
+ "encryptedKey version name must be '%s', is '%s'",
|
|
|
|
+ KeyProviderCryptoExtension.EEK,
|
|
|
|
+ ekv.getEncryptedKeyVersion().getVersionName());
|
|
|
|
+
|
|
|
|
+ if (ekv.getEncryptedKeyVersion().equals(ekNow)) {
|
|
|
|
+ // no-op if same key version
|
|
|
|
+ return ekv;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ final KeyVersion dek = decryptEncryptedKey(ekv);
|
|
|
|
+ final CryptoCodec cc = CryptoCodec.getInstance(keyProvider.getConf());
|
|
|
|
+ final Encryptor encryptor = cc.createEncryptor();
|
|
|
|
+ return generateEncryptedKey(encryptor, ekNow, dek.getMaterial(),
|
|
|
|
+ ekv.getEncryptedKeyIv());
|
|
|
|
+ }
|
|
|
|
+
|
|
@Override
|
|
@Override
|
|
public KeyVersion decryptEncryptedKey(
|
|
public KeyVersion decryptEncryptedKey(
|
|
EncryptedKeyVersion encryptedKeyVersion) throws IOException,
|
|
EncryptedKeyVersion encryptedKeyVersion) throws IOException,
|
|
@@ -388,6 +439,28 @@ public class KeyProviderCryptoExtension extends
|
|
return getExtension().decryptEncryptedKey(encryptedKey);
|
|
return getExtension().decryptEncryptedKey(encryptedKey);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
+ * Re-encrypts an encrypted key version, using its initialization vector
|
|
|
|
+ * and key material, but with the latest key version name of its key name
|
|
|
|
+ * in the key provider.
|
|
|
|
+ * <p>
|
|
|
|
+ * If the latest key version name in the provider is the
|
|
|
|
+ * same as the one encrypted the passed-in encrypted key version, the same
|
|
|
|
+ * encrypted key version is returned.
|
|
|
|
+ * <p>
|
|
|
|
+ * NOTE: The generated key is not stored by the <code>KeyProvider</code>
|
|
|
|
+ *
|
|
|
|
+ * @param ekv The EncryptedKeyVersion containing keyVersionName and IV.
|
|
|
|
+ * @return The re-encrypted EncryptedKeyVersion.
|
|
|
|
+ * @throws IOException If the key material could not be re-encrypted
|
|
|
|
+ * @throws GeneralSecurityException If the key material could not be
|
|
|
|
+ * re-encrypted because of a cryptographic issue.
|
|
|
|
+ */
|
|
|
|
+ public EncryptedKeyVersion reencryptEncryptedKey(EncryptedKeyVersion ekv)
|
|
|
|
+ throws IOException, GeneralSecurityException {
|
|
|
|
+ return getExtension().reencryptEncryptedKey(ekv);
|
|
|
|
+ }
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* Creates a <code>KeyProviderCryptoExtension</code> using a given
|
|
* Creates a <code>KeyProviderCryptoExtension</code> using a given
|
|
* {@link KeyProvider}.
|
|
* {@link KeyProvider}.
|