in modules/kms-keyring/src/kms_mrk_keyring.ts [119:254]
async _onEncrypt(
material: EncryptionMaterial<S>
): Promise<EncryptionMaterial<S>> {
const { client, keyId, grantTokens } = this
//= compliance/framework/aws-kms/aws-kms-mrk-aware-symmetric-keyring.txt#2.7
//# If the input encryption materials (structures.md#encryption-
//# materials) do not contain a plaintext data key OnEncrypt MUST attempt
//# to generate a new plaintext data key by calling AWS KMS
//# GenerateDataKey (https://docs.aws.amazon.com/kms/latest/APIReference/
//# API_GenerateDataKey.html).
if (!material.hasUnencryptedDataKey) {
//= compliance/framework/aws-kms/aws-kms-mrk-aware-symmetric-keyring.txt#2.7
//# The keyring MUST call
//# AWS KMS GenerateDataKeys with a request constructed as follows:
//
//= compliance/framework/aws-kms/aws-kms-mrk-aware-symmetric-keyring.txt#2.7
//# If the call to AWS KMS GenerateDataKey
//# (https://docs.aws.amazon.com/kms/latest/APIReference/
//# API_GenerateDataKey.html) does not succeed, OnEncrypt MUST NOT modify
//# the encryption materials (structures.md#encryption-materials) and
//# MUST fail.
const dataKey = await generateDataKey(
//= compliance/framework/aws-kms/aws-kms-mrk-aware-symmetric-keyring.txt#2.7
//# If the keyring calls AWS KMS GenerateDataKeys, it MUST use the
//# configured AWS KMS client to make the call.
client,
material.suite.keyLengthBytes,
keyId,
material.encryptionContext,
grantTokens
)
/* This should be impossible given that generateDataKey only returns false if the client supplier does. */
needs(dataKey, 'Generator KMS key did not generate a data key')
//= compliance/framework/aws-kms/aws-kms-mrk-aware-symmetric-keyring.txt#2.7
//# The Generate Data Key response's "KeyId" MUST be A valid AWS
//# KMS key ARN (aws-kms-key-arn.md#identifying-an-aws-kms-multi-region-
//# key).
needs(parseAwsKmsKeyArn(dataKey.KeyId), 'Malformed arn.')
const flags =
KeyringTraceFlag.WRAPPING_KEY_GENERATED_DATA_KEY |
KeyringTraceFlag.WRAPPING_KEY_SIGNED_ENC_CTX |
KeyringTraceFlag.WRAPPING_KEY_ENCRYPTED_DATA_KEY
const trace: KeyringTrace = {
keyNamespace: KMS_PROVIDER_ID,
keyName: dataKey.KeyId,
flags,
}
//= compliance/framework/aws-kms/aws-kms-mrk-aware-symmetric-keyring.txt#2.7
//# If verified,
//# OnEncrypt MUST do the following with the response from AWS KMS
//# GenerateDataKey (https://docs.aws.amazon.com/kms/latest/APIReference/
//# API_GenerateDataKey.html):
material
//= compliance/framework/aws-kms/aws-kms-mrk-aware-symmetric-keyring.txt#2.7
//# If the Generate Data Key call succeeds, OnEncrypt MUST verify that
//# the response "Plaintext" length matches the specification of the
//# algorithm suite (algorithm-suites.md)'s Key Derivation Input Length
//# field.
//
// setUnencryptedDataKey will throw if the plaintext does not match the algorithm suite requirements.
.setUnencryptedDataKey(dataKey.Plaintext, trace)
.addEncryptedDataKey(
kmsResponseToEncryptedDataKey(dataKey),
KeyringTraceFlag.WRAPPING_KEY_ENCRYPTED_DATA_KEY |
KeyringTraceFlag.WRAPPING_KEY_SIGNED_ENC_CTX
)
//= compliance/framework/aws-kms/aws-kms-mrk-aware-symmetric-keyring.txt#2.7
//# * OnEncrypt MUST output the modified encryption materials
//# (structures.md#encryption-materials)
return material
} else {
//= compliance/framework/aws-kms/aws-kms-mrk-aware-symmetric-keyring.txt#2.7
//# Given a plaintext data key in the encryption materials
//# (structures.md#encryption-materials), OnEncrypt MUST attempt to
//# encrypt the plaintext data key using the configured AWS KMS key
//# identifier.
const unencryptedDataKey = unwrapDataKey(
material.getUnencryptedDataKey()
)
const flags =
KeyringTraceFlag.WRAPPING_KEY_ENCRYPTED_DATA_KEY |
KeyringTraceFlag.WRAPPING_KEY_SIGNED_ENC_CTX
//= compliance/framework/aws-kms/aws-kms-mrk-aware-symmetric-keyring.txt#2.7
//# If the call to AWS KMS Encrypt
//# (https://docs.aws.amazon.com/kms/latest/APIReference/
//# API_Encrypt.html) does not succeed, OnEncrypt MUST fail.
//
//= compliance/framework/aws-kms/aws-kms-mrk-aware-symmetric-keyring.txt#2.7
//# The keyring
//# MUST AWS KMS Encrypt call with a request constructed as follows:
const kmsEDK = await encrypt(
//= compliance/framework/aws-kms/aws-kms-mrk-aware-symmetric-keyring.txt#2.7
//# The keyring MUST call AWS KMS Encrypt
//# (https://docs.aws.amazon.com/kms/latest/APIReference/
//# API_Encrypt.html) using the configured AWS KMS client.
client,
unencryptedDataKey,
keyId,
material.encryptionContext,
grantTokens
)
/* This should be impossible given that encrypt only returns false if the client supplier does. */
needs(
kmsEDK,
'AwsKmsMrkAwareSymmetricKeyring failed to encrypt data key'
)
//= compliance/framework/aws-kms/aws-kms-mrk-aware-symmetric-keyring.txt#2.7
//# If the Encrypt call succeeds The response's "KeyId" MUST be A valid
//# AWS KMS key ARN (aws-kms-key-arn.md#identifying-an-aws-kms-multi-
//# region-key).
needs(parseAwsKmsKeyArn(kmsEDK.KeyId), 'Malformed arn.')
//= compliance/framework/aws-kms/aws-kms-mrk-aware-symmetric-keyring.txt#2.7
//# If verified, OnEncrypt MUST do the following with the response from
//# AWS KMS Encrypt (https://docs.aws.amazon.com/kms/latest/APIReference/
//# API_Encrypt.html):
material.addEncryptedDataKey(
kmsResponseToEncryptedDataKey(kmsEDK),
flags
)
//= compliance/framework/aws-kms/aws-kms-mrk-aware-symmetric-keyring.txt#2.7
//# If all Encrypt calls succeed, OnEncrypt MUST output the modified
//# encryption materials (structures.md#encryption-materials).
return material
}
}