"use strict";
// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
Object.defineProperty(exports, "__esModule", { value: true });
exports.KeyringWebCrypto = exports.KeyringNode = exports.Keyring = void 0;
const encrypted_data_key_1 = require("./encrypted_data_key");
const immutable_class_1 = require("./immutable_class");
const cryptographic_material_1 = require("./cryptographic_material");
const needs_1 = require("./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.
 */
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
         */
        (0, needs_1.needs)((0, cryptographic_material_1.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.
         */
        (0, needs_1.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. */
        (0, needs_1.needs)((0, cryptographic_material_1.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. */
        (0, needs_1.needs)(encryptedDataKeys.every((edk) => edk instanceof encrypted_data_key_1.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.
         */
        (0, needs_1.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;
    }
}
exports.Keyring = Keyring;
(0, immutable_class_1.immutableBaseClass)(Keyring);
class KeyringNode extends Keyring {
}
exports.KeyringNode = KeyringNode;
(0, immutable_class_1.immutableClass)(KeyringNode);
class KeyringWebCrypto extends Keyring {
}
exports.KeyringWebCrypto = KeyringWebCrypto;
(0, immutable_class_1.immutableClass)(KeyringWebCrypto);
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoia2V5cmluZy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9rZXlyaW5nLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxvRUFBb0U7QUFDcEUsc0NBQXNDOzs7QUFFdEMsNkRBQXVEO0FBQ3ZELHVEQUFzRTtBQUV0RSxxRUFHaUM7QUFNakMsbUNBQStCO0FBSS9COzs7OztHQUtHO0FBRUgsTUFBc0IsT0FBTztJQUMzQixLQUFLLENBQUMsU0FBUyxDQUNiLFFBQStCO1FBRS9COzs7Ozs7V0FNRztRQUNILElBQUEsYUFBSyxFQUFDLElBQUEsNkNBQW9CLEVBQUMsUUFBUSxDQUFDLEVBQUUsK0JBQStCLENBQUMsQ0FBQTtRQUV0RSxNQUFNLFNBQVMsR0FBRyxNQUFNLElBQUksQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLENBQUE7UUFFakQ7Ozs7O1dBS0c7UUFDSCxJQUFBLGFBQUssRUFDSCxRQUFRLEtBQUssU0FBUyxFQUN0QixzREFBc0QsQ0FDdkQsQ0FBQTtRQUVEOzs7V0FHRztRQUVILE9BQU8sUUFBUSxDQUFBO0lBQ2pCLENBQUM7SUFNRDs7Ozs7Ozs7OztPQVVHO0lBQ0gsS0FBSyxDQUFDLFNBQVMsQ0FDYixRQUErQixFQUMvQixpQkFBcUM7UUFFckMsd0RBQXdEO1FBQ3hELElBQUEsYUFBSyxFQUFDLElBQUEsNkNBQW9CLEVBQUMsUUFBUSxDQUFDLEVBQUUsNEJBQTRCLENBQUMsQ0FBQTtRQUVuRSwwRkFBMEY7UUFDMUYsSUFBSSxRQUFRLENBQUMsV0FBVyxFQUFFO1lBQUUsT0FBTyxRQUFRLENBQUE7UUFFM0MsbUVBQW1FO1FBQ25FLElBQUEsYUFBSyxFQUNILGlCQUFpQixDQUFDLEtBQUssQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsR0FBRyxZQUFZLHFDQUFnQixDQUFDLEVBQ2pFLG1DQUFtQyxDQUNwQyxDQUFBO1FBRUQsTUFBTSxTQUFTLEdBQUcsTUFBTSxJQUFJLENBQUMsVUFBVSxDQUFDLFFBQVEsRUFBRSxpQkFBaUIsQ0FBQyxDQUFBO1FBRXBFOzs7OztXQUtHO1FBQ0gsSUFBQSxhQUFLLEVBQ0gsUUFBUSxLQUFLLFNBQVMsRUFDdEIsc0RBQXNELENBQ3ZELENBQUE7UUFFRDs7Ozs7V0FLRztRQUVILE9BQU8sUUFBUSxDQUFBO0lBQ2pCLENBQUM7Q0FNRjtBQTVGRCwwQkE0RkM7QUFFRCxJQUFBLG9DQUFrQixFQUFDLE9BQU8sQ0FBQyxDQUFBO0FBRTNCLE1BQXNCLFdBQVksU0FBUSxPQUEyQjtDQUFHO0FBQXhFLGtDQUF3RTtBQUN4RSxJQUFBLGdDQUFjLEVBQUMsV0FBVyxDQUFDLENBQUE7QUFDM0IsTUFBc0IsZ0JBQWlCLFNBQVEsT0FBZ0M7Q0FBRztBQUFsRiw0Q0FBa0Y7QUFDbEYsSUFBQSxnQ0FBYyxFQUFDLGdCQUFnQixDQUFDLENBQUEifQ==