async _onDecrypt()

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'
      )
    )
  }