"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.kmsResponseToEncryptedDataKey = exports.decrypt = exports.encrypt = exports.generateDataKey = exports.KMS_PROVIDER_ID = void 0;
const arn_parsing_1 = require("./arn_parsing");
const material_management_1 = require("@aws-crypto/material-management");
exports.KMS_PROVIDER_ID = 'aws-kms';
async function generateDataKey(clientProvider, NumberOfBytes, KeyId, EncryptionContext, GrantTokens) {
    const client = typeof clientProvider === 'function'
        ? clientProvider((0, arn_parsing_1.getRegionFromIdentifier)(KeyId))
        : clientProvider;
    /* Check for early return (Postcondition): clientProvider did not return a client for generateDataKey. */
    if (!client)
        return false;
    const v2vsV3Response = client.generateDataKey({
        KeyId,
        GrantTokens,
        NumberOfBytes,
        EncryptionContext,
    });
    const v2vsV3Promise = 'promise' in v2vsV3Response ? v2vsV3Response.promise() : v2vsV3Response;
    const dataKey = await v2vsV3Promise;
    return safeGenerateDataKey(dataKey);
}
exports.generateDataKey = generateDataKey;
async function encrypt(clientProvider, Plaintext, KeyId, EncryptionContext, GrantTokens) {
    const client = typeof clientProvider === 'function'
        ? clientProvider((0, arn_parsing_1.getRegionFromIdentifier)(KeyId))
        : clientProvider;
    /* Check for early return (Postcondition): clientProvider did not return a client for encrypt. */
    if (!client)
        return false;
    const v2vsV3Response = client.encrypt({
        KeyId,
        Plaintext,
        EncryptionContext,
        GrantTokens,
    });
    const v2vsV3Promise = 'promise' in v2vsV3Response ? v2vsV3Response.promise() : v2vsV3Response;
    const kmsEDK = await v2vsV3Promise;
    return safeEncryptOutput(kmsEDK);
}
exports.encrypt = encrypt;
async function decrypt(clientProvider, { providerId, providerInfo, encryptedDataKey }, EncryptionContext, GrantTokens) {
    /* Precondition:  The EDK must be a KMS edk. */
    (0, material_management_1.needs)(providerId === exports.KMS_PROVIDER_ID, 'Unsupported providerId');
    const client = typeof clientProvider === 'function'
        ? clientProvider((0, arn_parsing_1.getRegionFromIdentifier)(providerInfo))
        : clientProvider;
    /* Check for early return (Postcondition): clientProvider did not return a client for decrypt. */
    if (!client)
        return false;
    /* The AWS KMS KeyId *must* be set. */
    const v2vsV3Response = client.decrypt({
        KeyId: providerInfo,
        CiphertextBlob: encryptedDataKey,
        EncryptionContext,
        GrantTokens,
    });
    const v2vsV3Promise = 'promise' in v2vsV3Response ? v2vsV3Response.promise() : v2vsV3Response;
    const dataKey = await v2vsV3Promise;
    return safeDecryptOutput(dataKey);
}
exports.decrypt = decrypt;
function kmsResponseToEncryptedDataKey({ KeyId: providerInfo, CiphertextBlob: encryptedDataKey, }) {
    return new material_management_1.EncryptedDataKey({
        providerId: exports.KMS_PROVIDER_ID,
        providerInfo,
        encryptedDataKey,
    });
}
exports.kmsResponseToEncryptedDataKey = kmsResponseToEncryptedDataKey;
function safeGenerateDataKey(dataKey) {
    /* Postcondition: KMS must return serializable generate data key. */
    (0, material_management_1.needs)(typeof dataKey.KeyId === 'string' &&
        dataKey.Plaintext instanceof Uint8Array &&
        dataKey.CiphertextBlob instanceof Uint8Array, 'Malformed KMS response.');
    return safePlaintext(dataKey);
}
function safeEncryptOutput(dataKey) {
    /* Postcondition: KMS must return serializable encrypted data key. */
    (0, material_management_1.needs)(typeof dataKey.KeyId === 'string' &&
        dataKey.CiphertextBlob instanceof Uint8Array, 'Malformed KMS response.');
    return dataKey;
}
function safeDecryptOutput(dataKey) {
    /* Postcondition: KMS must return usable decrypted key. */
    (0, material_management_1.needs)(typeof dataKey.KeyId === 'string' &&
        dataKey.Plaintext instanceof Uint8Array, 'Malformed KMS response.');
    return safePlaintext(dataKey);
}
function safePlaintext(dataKey) {
    /* The KMS Client *may* return a Buffer that is not isolated.
     * i.e. the byteOffset !== 0.
     * This means that the unencrypted data key is possibly accessible to someone else.
     * If this is the node shared Buffer, then other code within this process _could_ find this secret.
     * Copy Plaintext to an isolated ArrayBuffer and zero the Plaintext.
     * This means that this function will *always* zero out the value returned to it from the KMS client.
     * While this is safe to do here, copying this code somewhere else may produce unexpected results.
     */
    const { Plaintext } = dataKey;
    dataKey.Plaintext = new Uint8Array(Plaintext);
    Plaintext.fill(0);
    return dataKey;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaGVscGVycy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9oZWxwZXJzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxvRUFBb0U7QUFDcEUsc0NBQXNDOzs7QUFZdEMsK0NBQXVEO0FBQ3ZELHlFQUl3QztBQUUzQixRQUFBLGVBQWUsR0FBRyxTQUFTLENBQUE7QUFFakMsS0FBSyxVQUFVLGVBQWUsQ0FDbkMsY0FBa0QsRUFDbEQsYUFBcUIsRUFDckIsS0FBYSxFQUNiLGlCQUFvQyxFQUNwQyxXQUFzQjtJQUV0QixNQUFNLE1BQU0sR0FDVixPQUFPLGNBQWMsS0FBSyxVQUFVO1FBQ2xDLENBQUMsQ0FBQyxjQUFjLENBQUMsSUFBQSxxQ0FBdUIsRUFBQyxLQUFLLENBQUMsQ0FBQztRQUNoRCxDQUFDLENBQUMsY0FBYyxDQUFBO0lBRXBCLHlHQUF5RztJQUN6RyxJQUFJLENBQUMsTUFBTTtRQUFFLE9BQU8sS0FBSyxDQUFBO0lBQ3pCLE1BQU0sY0FBYyxHQUFHLE1BQU0sQ0FBQyxlQUFlLENBQUM7UUFDNUMsS0FBSztRQUNMLFdBQVc7UUFDWCxhQUFhO1FBQ2IsaUJBQWlCO0tBQ2xCLENBQUMsQ0FBQTtJQUNGLE1BQU0sYUFBYSxHQUNqQixTQUFTLElBQUksY0FBYyxDQUFDLENBQUMsQ0FBQyxjQUFjLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUFDLGNBQWMsQ0FBQTtJQUN6RSxNQUFNLE9BQU8sR0FBRyxNQUFNLGFBQWEsQ0FBQTtJQUVuQyxPQUFPLG1CQUFtQixDQUFDLE9BQU8sQ0FBQyxDQUFBO0FBQ3JDLENBQUM7QUF6QkQsMENBeUJDO0FBRU0sS0FBSyxVQUFVLE9BQU8sQ0FDM0IsY0FBa0QsRUFDbEQsU0FBcUIsRUFDckIsS0FBYSxFQUNiLGlCQUFvQyxFQUNwQyxXQUFzQjtJQUV0QixNQUFNLE1BQU0sR0FDVixPQUFPLGNBQWMsS0FBSyxVQUFVO1FBQ2xDLENBQUMsQ0FBQyxjQUFjLENBQUMsSUFBQSxx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