/*! @azure/msal-browser v2.35.0 2023-04-03 */
'use strict';
import { __awaiter, __generator } from '../_virtual/_tslib.js';
import { BrowserStringUtils } from '../utils/BrowserStringUtils.js';
import { BrowserAuthError } from '../error/BrowserAuthError.js';
import { ModernBrowserCrypto } from './ModernBrowserCrypto.js';
import { MsrBrowserCrypto } from './MsrBrowserCrypto.js';
import { MsBrowserCrypto } from './MsBrowserCrypto.js';
import { BrowserConfigurationAuthError } from '../error/BrowserConfigurationAuthError.js';

/*
 * Copyright (c) Microsoft Corporation. All rights reserved.
 * Licensed under the MIT License.
 */
/**
 * See here for more info on RsaHashedKeyGenParams: https://developer.mozilla.org/en-US/docs/Web/API/RsaHashedKeyGenParams
 */
// RSA KeyGen Algorithm
var PKCS1_V15_KEYGEN_ALG = "RSASSA-PKCS1-v1_5";
// SHA-256 hashing algorithm
var S256_HASH_ALG = "SHA-256";
// MOD length for PoP tokens
var MODULUS_LENGTH = 2048;
// Public Exponent
var PUBLIC_EXPONENT = new Uint8Array([0x01, 0x00, 0x01]);
/**
 * This class implements functions used by the browser library to perform cryptography operations such as
 * hashing and encoding. It also has helper functions to validate the availability of specific APIs.
 */
var BrowserCrypto = /** @class */ (function () {
    function BrowserCrypto(logger, cryptoOptions) {
        var _a, _b;
        this.logger = logger;
        this.cryptoOptions = cryptoOptions;
        if (this.hasBrowserCrypto()) {
            // Use standard modern web crypto if available
            this.logger.verbose("BrowserCrypto: modern crypto interface available");
            this.subtleCrypto = new ModernBrowserCrypto();
        }
        else if (this.hasIECrypto()) {
            // For IE11, use msCrypto interface
            this.logger.verbose("BrowserCrypto: MS crypto interface available");
            this.subtleCrypto = new MsBrowserCrypto();
        }
        else if (this.hasMsrCrypto() && ((_a = this.cryptoOptions) === null || _a === void 0 ? void 0 : _a.useMsrCrypto)) {
            // For other browsers, use MSR Crypto if found
            this.logger.verbose("BrowserCrypto: MSR crypto interface available");
            this.subtleCrypto = new MsrBrowserCrypto();
        }
        else {
            if (this.hasMsrCrypto()) {
                this.logger.info("BrowserCrypto: MSR Crypto interface available but system.cryptoOptions.useMsrCrypto not enabled");
            }
            this.logger.error("BrowserCrypto: No crypto interfaces available.");
            throw BrowserAuthError.createCryptoNotAvailableError("Browser crypto, msCrypto, or msrCrypto interfaces not available.");
        }
        // Mainly needed for MSR Crypto: https://github.com/microsoft/MSR-JavaScript-Crypto#random-number-generator-prng
        if (this.subtleCrypto.initPrng) {
            this.logger.verbose("BrowserCrypto: Interface requires entropy");
            if (!((_b = this.cryptoOptions) === null || _b === void 0 ? void 0 : _b.entropy)) {
                this.logger.error("BrowserCrypto: Interface requires entropy but none provided.");
                throw BrowserConfigurationAuthError.createEntropyNotProvided();
            }
            this.logger.verbose("BrowserCrypto: Entropy provided");
            this.subtleCrypto.initPrng(this.cryptoOptions.entropy);
        }
        this.keygenAlgorithmOptions = {
            name: PKCS1_V15_KEYGEN_ALG,
            hash: S256_HASH_ALG,
            modulusLength: MODULUS_LENGTH,
            publicExponent: PUBLIC_EXPONENT
        };
    }
    /**
     * Check whether IE crypto or other browser cryptography is available.
     */
    BrowserCrypto.prototype.hasIECrypto = function () {
        return "msCrypto" in window;
    };
    /**
     * Check whether browser crypto is available.
     */
    BrowserCrypto.prototype.hasBrowserCrypto = function () {
        return "crypto" in window;
    };
    /**
     * Check whether MSR crypto polyfill is available
     */
    BrowserCrypto.prototype.hasMsrCrypto = function () {
        return "msrCrypto" in window;
    };
    /**
     * Returns a sha-256 hash of the given dataString as an ArrayBuffer.
     * @param dataString
     */
    BrowserCrypto.prototype.sha256Digest = function (dataString) {
        return __awaiter(this, void 0, void 0, function () {
            var data;
            return __generator(this, function (_a) {
                data = BrowserStringUtils.stringToUtf8Arr(dataString);
                // MSR Crypto wants object with name property, instead of string
                return [2 /*return*/, this.subtleCrypto.digest({ name: S256_HASH_ALG }, data)];
            });
        });
    };
    /**
     * Populates buffer with cryptographically random values.
     * @param dataBuffer
     */
    BrowserCrypto.prototype.getRandomValues = function (dataBuffer) {
        return this.subtleCrypto.getRandomValues(dataBuffer);
    };
    /**
     * Generates a keypair based on current keygen algorithm config.
     * @param extractable
     * @param usages
     */
    BrowserCrypto.prototype.generateKeyPair = function (extractable, usages) {
        return __awaiter(this, void 0, void 0, function () {
            return __generator(this, function (_a) {
                return [2 /*return*/, this.subtleCrypto.generateKey(this.keygenAlgorithmOptions, extractable, usages)];
            });
        });
    };
    /**
     * Export key as Json Web Key (JWK)
     * @param key
     * @param format
     */
    BrowserCrypto.prototype.exportJwk = function (key) {
        return __awaiter(this, void 0, void 0, function () {
            return __generator(this, function (_a) {
                return [2 /*return*/, this.subtleCrypto.exportKey(key)];
            });
        });
    };
    /**
     * Imports key as Json Web Key (JWK), can set extractable and usages.
     * @param key
     * @param format
     * @param extractable
     * @param usages
     */
    BrowserCrypto.prototype.importJwk = function (key, extractable, usages) {
        return __awaiter(this, void 0, void 0, function () {
            return __generator(this, function (_a) {
                return [2 /*return*/, this.subtleCrypto.importKey(key, this.keygenAlgorithmOptions, extractable, usages)];
            });
        });
    };
    /**
     * Signs given data with given key
     * @param key
     * @param data
     */
    BrowserCrypto.prototype.sign = function (key, data) {
        return __awaiter(this, void 0, void 0, function () {
            return __generator(this, function (_a) {
                return [2 /*return*/, this.subtleCrypto.sign(this.keygenAlgorithmOptions, key, data)];
            });
        });
    };
    return BrowserCrypto;
}());

export { BrowserCrypto };
//# sourceMappingURL=BrowserCrypto.js.map
