in src/main/java/com/amazonaws/encryptionsdk/kms/AwsKmsMrkAwareMasterKey.java [149:201]
public DataKey<AwsKmsMrkAwareMasterKey> generateDataKey(
final CryptoAlgorithm algorithm, final Map<String, String> encryptionContext) {
// = compliance/framework/aws-kms/aws-kms-mrk-aware-master-key.txt#2.10
// # This
// # master key MUST use the configured AWS KMS client to make an AWS KMS
// # GenerateDatakey (https://docs.aws.amazon.com/kms/latest/APIReference/
// # API_GenerateDataKey.html) request constructed as follows:
final GenerateDataKeyResult gdkResult =
kmsClient_.generateDataKey(
updateUserAgent(
new GenerateDataKeyRequest()
.withKeyId(awsKmsIdentifier_)
.withNumberOfBytes(algorithm.getDataKeyLength())
.withEncryptionContext(encryptionContext)
.withGrantTokens(grantTokens_)));
// = compliance/framework/aws-kms/aws-kms-mrk-aware-master-key.txt#2.10
// # If the call succeeds the AWS KMS Generate Data Key response's
// # "Plaintext" MUST match the key derivation input length specified by
// # the algorithm suite included in the input.
if (gdkResult.getPlaintext().limit() != algorithm.getDataKeyLength()) {
throw new IllegalStateException("Received an unexpected number of bytes from KMS");
}
final byte[] rawKey = new byte[algorithm.getDataKeyLength()];
gdkResult.getPlaintext().get(rawKey);
// = compliance/framework/aws-kms/aws-kms-mrk-aware-master-key.txt#2.10
// # The response's "KeyId"
// # MUST be valid.
final String gdkResultKeyId = gdkResult.getKeyId();
if (parseInfoFromKeyArn(gdkResultKeyId) == null) {
throw new IllegalStateException("Received an empty or invalid keyId from KMS");
}
final byte[] encryptedKey = new byte[gdkResult.getCiphertextBlob().remaining()];
gdkResult.getCiphertextBlob().get(encryptedKey);
final SecretKeySpec key = new SecretKeySpec(rawKey, algorithm.getDataKeyAlgo());
// = compliance/framework/aws-kms/aws-kms-mrk-aware-master-key.txt#2.10
// # The output MUST be the same as the Master Key Generate Data Key
// # (../master-key-interface.md#generate-data-key) interface.
return new DataKey<>(
// = compliance/framework/aws-kms/aws-kms-mrk-aware-master-key.txt#2.10
// # The response's "Plaintext" MUST be the plaintext in
// # the output.
key,
// = compliance/framework/aws-kms/aws-kms-mrk-aware-master-key.txt#2.10
// # The response's cipher text blob MUST be used as the
// # returned as the ciphertext for the encrypted data key in the output.
encryptedKey,
gdkResultKeyId.getBytes(StandardCharsets.UTF_8),
this);
}