// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
import { EncryptedDataKey } from './encrypted_data_key';
import { immutableBaseClass, immutableClass } from './immutable_class';
import { isEncryptionMaterial, isDecryptionMaterial, } from './cryptographic_material';
import { needs } from './needs';
/*
 * This public interface to the Keyring object is provided for
 * developers of CMMs and keyrings only. If you are a user of the AWS Encryption
 * SDK and you are not developing your own CMMs and/or keyrings, you do not
 * need to use it and you should not do so.
 */
export class Keyring {
    async onEncrypt(material) {
        /* Precondition: material must be a type of isEncryptionMaterial.
         * There are several security properties that NodeEncryptionMaterial and WebCryptoEncryptionMaterial
         * posses.
         * The unencryptedDataKey can only be written once.
         * If a data key has not already been generated, there must be no EDKs.
         * See cryptographic_materials.ts
         */
        needs(isEncryptionMaterial(material), 'Unsupported type of material.');
        const _material = await this._onEncrypt(material);
        /* Postcondition: The EncryptionMaterial objects must be the same.
         * See cryptographic_materials.ts.  The CryptographicMaterial objects
         * provide several security properties, including immutability of
         * the unencrypted data key and the ability to zero the data key.
         * This is insured by returning the same material.
         */
        needs(material === _material, 'New EncryptionMaterial instances can not be created.');
        /* Postcondition UNTESTED: If this keyring generated data key, it must be the right length.
         * See cryptographic_materials.ts This is handled in setUnencryptedDataKey
         * this condition is listed here to keep help keep track of important conditions
         */
        return material;
    }
    /* NOTE: The order of EDK's passed to the onDecrypt function is a clear
     * intent on the part of the person who did the encryption.
     * The EDK's should always correspond to the order serialized.
     * It is the Keyrings responsibility to maintain this order.
     * The most clear example is from KMS.  KMS is a regional service.
     * This means that a call to decrypt an EDK must go to the
     * region that "owns" this EDK.  If the decryption is done
     * in a different region. To control this behavior the person
     * who called encrypt can control the order of EDK and in the
     * configuration of the KMS Keyring.
     */
    async onDecrypt(material, encryptedDataKeys) {
        /* Precondition: material must be DecryptionMaterial. */
        needs(isDecryptionMaterial(material), 'Unsupported material type.');
        /* Precondition: Attempt to decrypt iif material does not have an unencrypted data key. */
        if (material.hasValidKey())
            return material;
        /* Precondition: encryptedDataKeys must all be EncryptedDataKey. */
        needs(encryptedDataKeys.every((edk) => edk instanceof EncryptedDataKey), 'Unsupported EncryptedDataKey type');
        const _material = await this._onDecrypt(material, encryptedDataKeys);
        /* Postcondition: The DecryptionMaterial objects must be the same.
         * See cryptographic_materials.ts.  The CryptographicMaterial objects
         * provide several security properties, including immutability of
         * the unencrypted data key and the ability to zero the data key.
         * This is insured by returning the same material.
         */
        needs(material === _material, 'New DecryptionMaterial instances can not be created.');
        /* See cryptographic_materials.ts The length condition is handled there.
         * But the condition is important and so repeated here.
         * The postcondition is "If an EDK was decrypted, its length must agree with algorithm specification."
         * If this is not the case, it either means ciphertext was tampered
         * with or the keyring implementation is not setting the length properly.
         */
        return material;
    }
}
immutableBaseClass(Keyring);
export class KeyringNode extends Keyring {
}
immutableClass(KeyringNode);
export class KeyringWebCrypto extends Keyring {
}
immutableClass(KeyringWebCrypto);
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoia2V5cmluZy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9rZXlyaW5nLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLG9FQUFvRTtBQUNwRSxzQ0FBc0M7QUFFdEMsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sc0JBQXNCLENBQUE7QUFDdkQsT0FBTyxFQUFFLGtCQUFrQixFQUFFLGNBQWMsRUFBRSxNQUFNLG1CQUFtQixDQUFBO0FBRXRFLE9BQU8sRUFDTCxvQkFBb0IsRUFDcEIsb0JBQW9CLEdBQ3JCLE1BQU0sMEJBQTBCLENBQUE7QUFNakMsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLFNBQVMsQ0FBQTtBQUkvQjs7Ozs7R0FLRztBQUVILE1BQU0sT0FBZ0IsT0FBTztJQUMzQixLQUFLLENBQUMsU0FBUyxDQUNiLFFBQStCO1FBRS9COzs7Ozs7V0FNRztRQUNILEtBQUssQ0FBQyxvQkFBb0IsQ0FBQyxRQUFRLENBQUMsRUFBRSwrQkFBK0IsQ0FBQyxDQUFBO1FBRXRFLE1BQU0sU0FBUyxHQUFHLE1BQU0sSUFBSSxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsQ0FBQTtRQUVqRDs7Ozs7V0FLRztRQUNILEtBQUssQ0FDSCxRQUFRLEtBQUssU0FBUyxFQUN0QixzREFBc0QsQ0FDdkQsQ0FBQTtRQUVEOzs7V0FHRztRQUVILE9BQU8sUUFBUSxDQUFBO0lBQ2pCLENBQUM7SUFNRDs7Ozs7Ozs7OztPQVVHO0lBQ0gsS0FBSyxDQUFDLFNBQVMsQ0FDYixRQUErQixFQUMvQixpQkFBcUM7UUFFckMsd0RBQXdEO1FBQ3hELEtBQUssQ0FBQyxvQkFBb0IsQ0FBQyxRQUFRLENBQUMsRUFBRSw0QkFBNEIsQ0FBQyxDQUFBO1FBRW5FLDBGQUEwRjtRQUMxRixJQUFJLFFBQVEsQ0FBQyxXQUFXLEVBQUU7WUFBRSxPQUFPLFFBQVEsQ0FBQTtRQUUzQyxtRUFBbUU7UUFDbkUsS0FBSyxDQUNILGlCQUFpQixDQUFDLEtBQUssQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsR0FBRyxZQUFZLGdCQUFnQixDQUFDLEVBQ2pFLG1DQUFtQyxDQUNwQyxDQUFBO1FBRUQsTUFBTSxTQUFTLEdBQUcsTUFBTSxJQUFJLENBQUMsVUFBVSxDQUFDLFFBQVEsRUFBRSxpQkFBaUIsQ0FBQyxDQUFBO1FBRXBFOzs7OztXQUtHO1FBQ0gsS0FBSyxDQUNILFFBQVEsS0FBSyxTQUFTLEVBQ3RCLHNEQUFzRCxDQUN2RCxDQUFBO1FBRUQ7Ozs7O1dBS0c7UUFFSCxPQUFPLFFBQVEsQ0FBQTtJQUNqQixDQUFDO0NBTUY7QUFFRCxrQkFBa0IsQ0FBQyxPQUFPLENBQUMsQ0FBQTtBQUUzQixNQUFNLE9BQWdCLFdBQVksU0FBUSxPQUEyQjtDQUFHO0FBQ3hFLGNBQWMsQ0FBQyxXQUFXLENBQUMsQ0FBQTtBQUMzQixNQUFNLE9BQWdCLGdCQUFpQixTQUFRLE9BQWdDO0NBQUc7QUFDbEYsY0FBYyxDQUFDLGdCQUFnQixDQUFDLENBQUEifQ==