// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
/*
 * This file contains information about particular algorithm suites used
 * within the encryption SDK.  In most cases, end-users don't need to
 * manipulate this structure, but it can occasionally be needed for more
 * advanced use cases, such as writing keyrings.
 *
 * Here we describe the overall shape of the Algorithm Suites used by the AWS Encryption
 * SDK for JavaScript.  Specific details for Node.js and WebCrypto can be found
 * in the respective files
 */
import { immutableClass, readOnlyProperty } from './immutable_class';
import { needs } from './needs';
/* References to https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/algorithms-reference.html
 * These define the possible parameters for algorithm specifications that correspond
 * to the Node.js or WebCrypto environment.
 * These parameters are composed into an algorithm suite specification for each
 * environment in the respective files.
 */
export var AlgorithmSuiteIdentifier;
(function (AlgorithmSuiteIdentifier) {
    AlgorithmSuiteIdentifier[AlgorithmSuiteIdentifier["ALG_AES128_GCM_IV12_TAG16"] = 20] = "ALG_AES128_GCM_IV12_TAG16";
    AlgorithmSuiteIdentifier[AlgorithmSuiteIdentifier["ALG_AES192_GCM_IV12_TAG16"] = 70] = "ALG_AES192_GCM_IV12_TAG16";
    AlgorithmSuiteIdentifier[AlgorithmSuiteIdentifier["ALG_AES256_GCM_IV12_TAG16"] = 120] = "ALG_AES256_GCM_IV12_TAG16";
    AlgorithmSuiteIdentifier[AlgorithmSuiteIdentifier["ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256"] = 276] = "ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256";
    AlgorithmSuiteIdentifier[AlgorithmSuiteIdentifier["ALG_AES192_GCM_IV12_TAG16_HKDF_SHA256"] = 326] = "ALG_AES192_GCM_IV12_TAG16_HKDF_SHA256";
    AlgorithmSuiteIdentifier[AlgorithmSuiteIdentifier["ALG_AES256_GCM_IV12_TAG16_HKDF_SHA256"] = 376] = "ALG_AES256_GCM_IV12_TAG16_HKDF_SHA256";
    AlgorithmSuiteIdentifier[AlgorithmSuiteIdentifier["ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256"] = 532] = "ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256";
    AlgorithmSuiteIdentifier[AlgorithmSuiteIdentifier["ALG_AES192_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384"] = 838] = "ALG_AES192_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384";
    AlgorithmSuiteIdentifier[AlgorithmSuiteIdentifier["ALG_AES256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384"] = 888] = "ALG_AES256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384";
    AlgorithmSuiteIdentifier[AlgorithmSuiteIdentifier["ALG_AES256_GCM_IV12_TAG16_HKDF_SHA512_COMMIT_KEY"] = 1144] = "ALG_AES256_GCM_IV12_TAG16_HKDF_SHA512_COMMIT_KEY";
    AlgorithmSuiteIdentifier[AlgorithmSuiteIdentifier["ALG_AES256_GCM_IV12_TAG16_HKDF_SHA512_COMMIT_KEY_ECDSA_P384"] = 1400] = "ALG_AES256_GCM_IV12_TAG16_HKDF_SHA512_COMMIT_KEY_ECDSA_P384";
})(AlgorithmSuiteIdentifier || (AlgorithmSuiteIdentifier = {}));
Object.freeze(AlgorithmSuiteIdentifier);
export var CommitmentPolicy;
(function (CommitmentPolicy) {
    CommitmentPolicy["FORBID_ENCRYPT_ALLOW_DECRYPT"] = "FORBID_ENCRYPT_ALLOW_DECRYPT";
    CommitmentPolicy["REQUIRE_ENCRYPT_ALLOW_DECRYPT"] = "REQUIRE_ENCRYPT_ALLOW_DECRYPT";
    CommitmentPolicy["REQUIRE_ENCRYPT_REQUIRE_DECRYPT"] = "REQUIRE_ENCRYPT_REQUIRE_DECRYPT";
})(CommitmentPolicy || (CommitmentPolicy = {}));
Object.freeze(CommitmentPolicy);
export var SignaturePolicy;
(function (SignaturePolicy) {
    SignaturePolicy["ALLOW_ENCRYPT_ALLOW_DECRYPT"] = "ALLOW_ENCRYPT_ALLOW_DECRYPT";
    SignaturePolicy["ALLOW_ENCRYPT_FORBID_DECRYPT"] = "ALLOW_ENCRYPT_FORBID_DECRYPT";
})(SignaturePolicy || (SignaturePolicy = {}));
Object.freeze(SignaturePolicy);
export const NonSigningAlgorithmSuiteIdentifier = (() => {
    const { ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256, ALG_AES192_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384, ALG_AES256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384, ALG_AES256_GCM_IV12_TAG16_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, 
    // Both the name side above, and the id side below
    [0x0214]: NAME_ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256, [0x0346]: NAME_ALG_AES192_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384, [0x0378]: NAME_ALG_AES256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384, [0x0578]: NAME_AES256_GCM_IV12_TAG16_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, ...NonSigningAlgorithmSuiteIdentifier } = AlgorithmSuiteIdentifier;
    return NonSigningAlgorithmSuiteIdentifier;
})();
export const SignaturePolicySuites = Object.freeze({
    isDecryptEnabled(signaturePolicy, suite, messageId) {
        const id = suite.id || suite;
        const name = suite.name || AlgorithmSuiteIdentifier[id];
        let decryption_client_name = 'decryptStream';
        let signature_description = 'signed';
        if (signaturePolicy === SignaturePolicy.ALLOW_ENCRYPT_FORBID_DECRYPT) {
            decryption_client_name = 'decryptUnsignedMessageStream';
            signature_description = 'un-signed';
        }
        /* Precondition: Only handle DecryptionMaterial for algorithm suites supported in signaturePolicy. */
        needs(this[signaturePolicy].decryptEnabledSuites[id], `Configuration conflict. ` +
            `Cannot process message with ID ${messageId} ` +
            `due to client method ${decryption_client_name} ` +
            `requiring only ${signature_description} messages. ` +
            `Algorithm ID was ${name}. ` +
            `See: https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/concepts.html#digital-sigs`);
    },
    [SignaturePolicy.ALLOW_ENCRYPT_ALLOW_DECRYPT]: Object.freeze({
        decryptEnabledSuites: AlgorithmSuiteIdentifier,
        defaultAlgorithmSuite: AlgorithmSuiteIdentifier.ALG_AES256_GCM_IV12_TAG16_HKDF_SHA512_COMMIT_KEY_ECDSA_P384,
    }),
    [SignaturePolicy.ALLOW_ENCRYPT_FORBID_DECRYPT]: Object.freeze({
        decryptEnabledSuites: NonSigningAlgorithmSuiteIdentifier,
        defaultAlgorithmSuite: AlgorithmSuiteIdentifier.ALG_AES256_GCM_IV12_TAG16_HKDF_SHA512_COMMIT_KEY,
    }),
});
export const NonCommittingAlgorithmSuiteIdentifier = (() => {
    const { ALG_AES256_GCM_IV12_TAG16_HKDF_SHA512_COMMIT_KEY, ALG_AES256_GCM_IV12_TAG16_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, 
    // Both the name side above, and the id side below
    [0x0478]: NAME_ALG_AES256_GCM_IV12_TAG16_HKDF_SHA512_COMMIT_KEY, [0x0578]: NAME_ALG_AES256_GCM_IV12_TAG16_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, ...NonCommittingAlgorithmSuiteIdentifier } = AlgorithmSuiteIdentifier;
    return NonCommittingAlgorithmSuiteIdentifier;
})();
export const CommittingAlgorithmSuiteIdentifier = (() => {
    const { ALG_AES128_GCM_IV12_TAG16, ALG_AES192_GCM_IV12_TAG16, ALG_AES256_GCM_IV12_TAG16, ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256, ALG_AES192_GCM_IV12_TAG16_HKDF_SHA256, ALG_AES256_GCM_IV12_TAG16_HKDF_SHA256, ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256, ALG_AES192_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384, ALG_AES256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384, 
    // Both the name side above, and the id side below
    [0x0014]: NAME_ALG_AES128_GCM_IV12_TAG16, [0x0046]: NAME_ALG_AES192_GCM_IV12_TAG16, [0x0078]: NAME_ALG_AES256_GCM_IV12_TAG16, [0x0114]: NAME_ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256, [0x0146]: NAME_ALG_AES192_GCM_IV12_TAG16_HKDF_SHA256, [0x0178]: NAME_ALG_AES256_GCM_IV12_TAG16_HKDF_SHA256, [0x0214]: NAME_ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256, [0x0346]: NAME_ALG_AES192_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384, [0x0378]: NAME_ALG_AES256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384, ...CommittingAlgorithmSuiteIdentifier } = AlgorithmSuiteIdentifier;
    return CommittingAlgorithmSuiteIdentifier;
})();
export const CommitmentPolicySuites = Object.freeze({
    isEncryptEnabled(commitmentPolicy, suite) {
        if (!suite)
            return;
        const id = suite.id || suite;
        const name = suite.name || AlgorithmSuiteIdentifier[id];
        /* Precondition: Only handle EncryptionMaterial for algorithm suites supported in commitmentPolicy. */
        needs(this[commitmentPolicy].encryptEnabledSuites[id], `Configuration conflict. ` +
            `Cannot encrypt due to CommitmentPolicy ${commitmentPolicy} ` +
            `requiring only non-committed messages. ` +
            `Algorithm ID was ${name}. ` +
            `See: https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/troubleshooting-migration.html`);
    },
    isDecryptEnabled(commitmentPolicy, suite, messageId) {
        const id = suite.id || suite;
        const name = suite.name || AlgorithmSuiteIdentifier[id];
        /* Precondition: Only handle DecryptionMaterial for algorithm suites supported in commitmentPolicy. */
        needs(this[commitmentPolicy].decryptEnabledSuites[id], `Configuration conflict. ` +
            `Cannot process message with ID ${messageId} ` +
            `due to CommitmentPolicy ${commitmentPolicy} ` +
            `requiring only committed messages. ` +
            `Algorithm ID was ${name}. ` +
            `See: https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/troubleshooting-migration.html`);
    },
    [CommitmentPolicy.FORBID_ENCRYPT_ALLOW_DECRYPT]: Object.freeze({
        encryptEnabledSuites: NonCommittingAlgorithmSuiteIdentifier,
        decryptEnabledSuites: AlgorithmSuiteIdentifier,
        defaultAlgorithmSuite: NonCommittingAlgorithmSuiteIdentifier.ALG_AES256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384,
    }),
    [CommitmentPolicy.REQUIRE_ENCRYPT_ALLOW_DECRYPT]: Object.freeze({
        encryptEnabledSuites: CommittingAlgorithmSuiteIdentifier,
        decryptEnabledSuites: AlgorithmSuiteIdentifier,
        defaultAlgorithmSuite: CommittingAlgorithmSuiteIdentifier.ALG_AES256_GCM_IV12_TAG16_HKDF_SHA512_COMMIT_KEY_ECDSA_P384,
    }),
    [CommitmentPolicy.REQUIRE_ENCRYPT_REQUIRE_DECRYPT]: Object.freeze({
        encryptEnabledSuites: CommittingAlgorithmSuiteIdentifier,
        decryptEnabledSuites: CommittingAlgorithmSuiteIdentifier,
        defaultAlgorithmSuite: CommittingAlgorithmSuiteIdentifier.ALG_AES256_GCM_IV12_TAG16_HKDF_SHA512_COMMIT_KEY_ECDSA_P384,
    }),
});
export function getCompatibleCommitmentPolicy(suiteId) {
    // If it is a algorithm suite with no key commitment
    // we use FORBID_ENCRYPT_ALLOW_DECRYPT
    // otherwise we use REQUIRE_ENCRYPT_REQUIRE_DECRYPT
    if (CommittingAlgorithmSuiteIdentifier[suiteId]) {
        return CommitmentPolicy.REQUIRE_ENCRYPT_REQUIRE_DECRYPT;
    }
    else {
        return CommitmentPolicy.FORBID_ENCRYPT_ALLOW_DECRYPT;
    }
}
export var MessageFormat;
(function (MessageFormat) {
    MessageFormat[MessageFormat["V1"] = 1] = "V1";
    MessageFormat[MessageFormat["V2"] = 2] = "V2";
})(MessageFormat || (MessageFormat = {}));
Object.freeze(MessageFormat);
export class AlgorithmSuite {
    constructor(suiteValues) {
        needs(this.constructor !== AlgorithmSuite, 'new AlgorithmSuite is not allowed');
        /* Precondition: A algorithm suite specification must be passed. */
        needs(suiteValues, 'Algorithm specification not set.');
        /* Precondition: The Algorithm Suite Identifier must exist. */
        needs(AlgorithmSuiteIdentifier[suiteValues.id], 'No suite by that identifier exists.');
        Object.assign(this, suiteValues);
        readOnlyProperty(this, 'keyLengthBytes', this.keyLength / 8);
        readOnlyProperty(this, 'name', AlgorithmSuiteIdentifier[this.id]);
    }
}
immutableClass(AlgorithmSuite);
//# sourceMappingURL=data:application/json;base64, 