src/main/java/com/amazonaws/encryptionsdk/kmssdkv2/AwsKmsMrkAwareMasterKeyProvider.java [642:717]:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  public DataKey<AwsKmsMrkAwareMasterKey> decryptDataKey(
      final CryptoAlgorithm algorithm,
      final Collection<? extends EncryptedDataKey> encryptedDataKeys,
      final Map<String, String> encryptionContext)
      throws AwsCryptoException {
    final List<Exception> exceptions = new ArrayList<>();

    return encryptedDataKeys.stream()
        // = compliance/framework/aws-kms/aws-kms-mrk-aware-master-key-provider.txt#2.9
        // # The set of encrypted data keys MUST first be filtered to match this
        // # master key's configuration.
        .filter(
            edk -> {
              // = compliance/framework/aws-kms/aws-kms-mrk-aware-master-key-provider.txt#2.9
              // # To match the encrypted data key's
              // # provider ID MUST exactly match the value "aws-kms".
              if (!canProvide(edk.getProviderId())) return false;

              final String providerInfo =
                  new String(edk.getProviderInformation(), StandardCharsets.UTF_8);
              final AwsKmsCmkArnInfo providerArnInfo = parseInfoFromKeyArn(providerInfo);

              // = compliance/framework/aws-kms/aws-kms-mrk-aware-master-key-provider.txt#2.9
              // # Additionally
              // # each provider info MUST be a valid AWS KMS ARN (aws-kms-key-arn.md#a-
              // # valid-aws-kms-arn) with a resource type of "key".
              if (providerArnInfo == null || !"key".equals(providerArnInfo.getResourceType())) {
                throw new IllegalStateException("Invalid provider info in message.");
              }
              return true;
            })
        .map(
            edk -> {
              try {
                final String keyArn =
                    new String(edk.getProviderInformation(), StandardCharsets.UTF_8);

                // = compliance/framework/aws-kms/aws-kms-mrk-aware-master-key-provider.txt#2.9
                // # For each encrypted data key in the filtered set, one at a time, the
                // # master key provider MUST call Get Master Key (aws-kms-mrk-aware-
                // # master-key-provider.md#get-master-key) with the encrypted data key's
                // # provider info as the AWS KMS key ARN.
                // This will throw if we can't use this key for whatever reason
                return getMasterKey(edk.getProviderId(), keyArn)
                    // = compliance/framework/aws-kms/aws-kms-mrk-aware-master-key-provider.txt#2.9
                    // # It MUST call Decrypt Data Key
                    // # (aws-kms-mrk-aware-master-key.md#decrypt-data-key) on this master key
                    // # with the input algorithm, this single encrypted data key, and the
                    // # input encryption context.
                    .decryptDataKey(algorithm, singletonList(edk), encryptionContext);
              } catch (final Exception ex) {
                // = compliance/framework/aws-kms/aws-kms-mrk-aware-master-key-provider.txt#2.9
                // # If this attempt results in an error, then
                // # these errors MUST be collected.
                exceptions.add(ex);
                return null;
              }
            })
        /* Need to filter null because an Optional of a null is crazy.
         * `findFirst` will throw if it sees `null`.
         */
        .filter(Objects::nonNull)
        // = compliance/framework/aws-kms/aws-kms-mrk-aware-master-key-provider.txt#2.9
        // # If the decrypt data key call is
        // # successful, then this function MUST return this result and not
        // # attempt to decrypt any more encrypted data keys.
        .findFirst()
        // = compliance/framework/aws-kms/aws-kms-mrk-aware-master-key-provider.txt#2.9
        // # If all the input encrypted data keys have been processed then this
        // # function MUST yield an error that includes all the collected errors.
        //
        // = compliance/framework/aws-kms/aws-kms-mrk-aware-master-key-provider.txt#2.9
        // # The output MUST be the same as the Master Key Provider Decrypt Data
        // # Key (../master-key-provider-interface.md#decrypt-data-key) interface.
        .orElseThrow(() -> buildCannotDecryptDksException(exceptions));
  }
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -



src/main/java/com/amazonaws/encryptionsdk/kms/AwsKmsMrkAwareMasterKeyProvider.java [662:737]:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  public DataKey<AwsKmsMrkAwareMasterKey> decryptDataKey(
      final CryptoAlgorithm algorithm,
      final Collection<? extends EncryptedDataKey> encryptedDataKeys,
      final Map<String, String> encryptionContext)
      throws AwsCryptoException {
    final List<Exception> exceptions = new ArrayList<>();

    return encryptedDataKeys.stream()
        // = compliance/framework/aws-kms/aws-kms-mrk-aware-master-key-provider.txt#2.9
        // # The set of encrypted data keys MUST first be filtered to match this
        // # master key's configuration.
        .filter(
            edk -> {
              // = compliance/framework/aws-kms/aws-kms-mrk-aware-master-key-provider.txt#2.9
              // # To match the encrypted data key's
              // # provider ID MUST exactly match the value "aws-kms".
              if (!canProvide(edk.getProviderId())) return false;

              final String providerInfo =
                  new String(edk.getProviderInformation(), StandardCharsets.UTF_8);
              final AwsKmsCmkArnInfo providerArnInfo = parseInfoFromKeyArn(providerInfo);

              // = compliance/framework/aws-kms/aws-kms-mrk-aware-master-key-provider.txt#2.9
              // # Additionally
              // # each provider info MUST be a valid AWS KMS ARN (aws-kms-key-arn.md#a-
              // # valid-aws-kms-arn) with a resource type of "key".
              if (providerArnInfo == null || !"key".equals(providerArnInfo.getResourceType())) {
                throw new IllegalStateException("Invalid provider info in message.");
              }
              return true;
            })
        .map(
            edk -> {
              try {
                final String keyArn =
                    new String(edk.getProviderInformation(), StandardCharsets.UTF_8);

                // = compliance/framework/aws-kms/aws-kms-mrk-aware-master-key-provider.txt#2.9
                // # For each encrypted data key in the filtered set, one at a time, the
                // # master key provider MUST call Get Master Key (aws-kms-mrk-aware-
                // # master-key-provider.md#get-master-key) with the encrypted data key's
                // # provider info as the AWS KMS key ARN.
                // This will throw if we can't use this key for whatever reason
                return getMasterKey(edk.getProviderId(), keyArn)
                    // = compliance/framework/aws-kms/aws-kms-mrk-aware-master-key-provider.txt#2.9
                    // # It MUST call Decrypt Data Key
                    // # (aws-kms-mrk-aware-master-key.md#decrypt-data-key) on this master key
                    // # with the input algorithm, this single encrypted data key, and the
                    // # input encryption context.
                    .decryptDataKey(algorithm, singletonList(edk), encryptionContext);
              } catch (final Exception ex) {
                // = compliance/framework/aws-kms/aws-kms-mrk-aware-master-key-provider.txt#2.9
                // # If this attempt results in an error, then
                // # these errors MUST be collected.
                exceptions.add(ex);
                return null;
              }
            })
        /* Need to filter null because an Optional of a null is crazy.
         * `findFirst` will throw if it sees `null`.
         */
        .filter(Objects::nonNull)
        // = compliance/framework/aws-kms/aws-kms-mrk-aware-master-key-provider.txt#2.9
        // # If the decrypt data key call is
        // # successful, then this function MUST return this result and not
        // # attempt to decrypt any more encrypted data keys.
        .findFirst()
        // = compliance/framework/aws-kms/aws-kms-mrk-aware-master-key-provider.txt#2.9
        // # If all the input encrypted data keys have been processed then this
        // # function MUST yield an error that includes all the collected errors.
        //
        // = compliance/framework/aws-kms/aws-kms-mrk-aware-master-key-provider.txt#2.9
        // # The output MUST be the same as the Master Key Provider Decrypt Data
        // # Key (../master-key-provider-interface.md#decrypt-data-key) interface.
        .orElseThrow(() -> buildCannotDecryptDksException(exceptions));
  }
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -



