in modules/kms-keyring-node/src/kms_hkeyring_node.ts [367:469]
async _onDecrypt(
decryptionMaterial: NodeDecryptionMaterial,
encryptedDataKeyObjs: EncryptedDataKey[]
): Promise<NodeDecryptionMaterial> {
//= aws-encryption-sdk-specification/framework/aws-kms/aws-kms-hierarchical-keyring.md#ondecrypt
//# The `branchKeyId` used in this operation is either the configured branchKeyId, if supplied, or the result of the `branchKeySupplier`'s
//# `getBranchKeyId` operation, using the decryption material's encryption context as input.
const branchKeyId = getBranchKeyId(this, decryptionMaterial)
// filter out edk objects that don't match this keyring's configuration
const filteredEdkObjs = encryptedDataKeyObjs.filter((edkObj) =>
filterEdk(branchKeyId, edkObj)
)
/* Precondition: There must be an encrypted data key that matches this keyring configuration */
needs(
filteredEdkObjs.length > 0,
"There must be an encrypted data key that matches this keyring's configuration"
)
const errors: Catchable[] = []
for (const { encryptedDataKey: ciphertext } of filteredEdkObjs) {
let udk: Uint8Array | undefined = undefined
try {
//= aws-encryption-sdk-specification/framework/aws-kms/aws-kms-hierarchical-keyring.md#getitem-branch-keystore-ondecrypt
//# - Deserialize the UUID string representation of the `version` from the [encrypted data key](../structures.md#encrypted-data-key) [ciphertext](#ciphertext).
// get the branch key version (as compressed bytes) from the
// destructured ciphertext of the edk
const { branchKeyVersionAsBytesCompressed } = destructureCiphertext(
ciphertext,
decryptionMaterial.suite
)
//= aws-encryption-sdk-specification/framework/aws-kms/aws-kms-hierarchical-keyring.md#getitem-branch-keystore-ondecrypt
//# - The deserialized UUID string representation of the `version`
// uncompress the branch key version into regular utf8 bytes
const branchKeyVersionAsBytes = stringToUtf8Bytes(
decompressBytesToUuidv4(branchKeyVersionAsBytesCompressed)
)
//= aws-encryption-sdk-specification/framework/aws-kms/aws-kms-hierarchical-keyring.md#ondecrypt
//# The hierarchical keyring MUST use the OnDecrypt formula specified in [Appendix A](#decryption-materials)
//# in order to compute the [cache entry identifier](cryptographic-materials-cache.md#cache-identifier).
const cacheEntryId = getCacheEntryId(
this._logicalKeyStoreName,
this._partition,
//= aws-encryption-sdk-specification/framework/aws-kms/aws-kms-hierarchical-keyring.md#getitem-branch-keystore-ondecrypt
//# OnDecrypt MUST calculate the following values:
branchKeyId,
branchKeyVersionAsBytes
)
// get the string representation of the branch key version
const branchKeyVersionAsString = decompressBytesToUuidv4(
branchKeyVersionAsBytesCompressed
)
//= aws-encryption-sdk-specification/framework/aws-kms/aws-kms-hierarchical-keyring.md#ondecrypt
//# To decrypt each encrypted data key in the filtered set, the hierarchical keyring MUST attempt
//# to find the corresponding [branch key materials](../structures.md#branch-key-materials)
//# from the underlying [cryptographic materials cache](../local-cryptographic-materials-cache.md).
const branchKeyMaterials = await getBranchKeyMaterials(
this,
this._cmc,
branchKeyId,
cacheEntryId,
branchKeyVersionAsString
)
//= aws-encryption-sdk-specification/framework/aws-kms/aws-kms-hierarchical-keyring.md#ondecrypt
//# - MUST unwrap the encrypted data key with the branch key materials according to the [branch key unwrapping](#branch-key-unwrapping) section.
udk = unwrapEncryptedDataKey(
ciphertext,
branchKeyMaterials,
decryptionMaterial,
this._utf8Sorting
)
} catch (e) {
//= aws-encryption-sdk-specification/framework/aws-kms/aws-kms-hierarchical-keyring.md#ondecrypt
//# For each encrypted data key in the filtered set, one at a time, OnDecrypt MUST attempt to decrypt the encrypted data key.
//# If this attempt results in an error, then these errors MUST be collected.
errors.push({ errPlus: e })
}
//= aws-encryption-sdk-specification/framework/aws-kms/aws-kms-hierarchical-keyring.md#ondecrypt
//# If a decryption succeeds, this keyring MUST
//# add the resulting plaintext data key to the decryption materials and return the modified materials.
if (udk) {
return modifyDencryptionMaterial(decryptionMaterial, udk, branchKeyId)
}
}
//= aws-encryption-sdk-specification/framework/aws-kms/aws-kms-hierarchical-keyring.md#ondecrypt
//# If OnDecrypt fails to successfully decrypt any [encrypted data key](../structures.md#encrypted-data-key),
//# then it MUST yield an error that includes all the collected errors
//# and MUST NOT modify the [decryption materials](structures.md#decryption-materials).
throw new Error(
errors.reduce(
(m, e, i) => `${m} Error #${i + 1} \n ${e.errPlus.stack} \n`,
'Unable to decrypt data key'
)
)
}