UNPKG

bitgo

Version:
164 lines • 28.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const sdk_core_1 = require("@bitgo/sdk-core"); const sdk_test_1 = require("@bitgo/sdk-test"); const src_1 = require("../../../../../src"); const openpgp = require("openpgp"); const nock = require("nock"); const assert = require("assert"); class TestEcdsaMpcv2Utils extends sdk_core_1.ECDSAUtils.EcdsaMPCv2Utils { async testPickBitgoPubGpgKeyForSigning(isMpcv2, reqId, enterpriseId) { return this.pickBitgoPubGpgKeyForSigning(isMpcv2, reqId, enterpriseId); } } class TestEddsaMpcv1Utils extends sdk_core_1.EddsaUtils { async testPickBitgoPubGpgKeyForSigning(isMpcv2, reqId, enterpriseId) { return this.pickBitgoPubGpgKeyForSigning(isMpcv2, reqId, enterpriseId); } } describe('TSS MPC Pick BitGo GPG Pub Key Utils:', function () { const walletId = '5b34252f1bf349930e34020a00000000'; const enterpriseId = '6449153a6f6bc20006d66771cdbe15d3'; const ecdsaCoinName = 'hteth'; const eddsaCoinName = 'tsol'; const ecdsaWalletData = { id: walletId, enterprise: enterpriseId, coin: ecdsaCoinName, coinSpecific: {}, multisigType: 'tss', keys: ['key1', 'key2', 'key3'], }; const eddsaWalletData = { id: walletId, enterprise: enterpriseId, coin: eddsaCoinName, coinSpecific: {}, multisigType: 'tss', keys: ['key1', 'key2', 'key3'], }; const envs = ['test', 'staging', 'prod']; const ecdsaMpcv2Utils = []; const eddsaMpcv1Utils = []; before(async function () { nock.cleanAll(); for (const env of envs) { const bitgoInstance = sdk_test_1.TestBitGo.decorate(src_1.BitGo, { env }); bitgoInstance.initializeTestVars(); let coinInstance = bitgoInstance.coin(ecdsaCoinName); ecdsaMpcv2Utils.push(new TestEcdsaMpcv2Utils(bitgoInstance, coinInstance, new sdk_core_1.Wallet(bitgoInstance, coinInstance, ecdsaWalletData))); coinInstance = bitgoInstance.coin(eddsaCoinName); eddsaMpcv1Utils.push(new TestEddsaMpcv1Utils(bitgoInstance, coinInstance, new sdk_core_1.Wallet(bitgoInstance, coinInstance, eddsaWalletData))); } }); beforeEach(async function () { for (const env of envs) { const bgUrl = sdk_core_1.common.Environments[env].uri; nock(bgUrl).get(`/api/v2/${ecdsaCoinName}/key/key3`).times(envs.length).reply(200, { hsmType: 'onprem' }); nock(bgUrl).get(`/api/v2/${eddsaCoinName}/key/key3`).times(envs.length).reply(200, { hsmType: 'nitro' }); } }); envs.forEach(async function (env, index) { it(`should pick correct Mpcv2 BitGo GPG Pub Key for ${env} env`, async function () { const bitgoGpgPubKey = await ecdsaMpcv2Utils[index].testPickBitgoPubGpgKeyForSigning(true); bitgoGpgPubKey .armor() .should.equal(sdk_core_1.BitgoMpcGpgPubKeys.bitgoMpcGpgPubKeys['mpcv2']['onprem'][env === 'staging' ? 'test' : env]); }); }); envs.forEach(async function (env, index) { it(`should pick correct Mpcv1 BitGo GPG Pub Key for ${env} env`, async function () { const bitgoGpgPubKey = await eddsaMpcv1Utils[index].testPickBitgoPubGpgKeyForSigning(false); bitgoGpgPubKey .armor() .should.equal(sdk_core_1.BitgoMpcGpgPubKeys.bitgoMpcGpgPubKeys['mpcv1']['nitro'][env === 'staging' ? 'test' : env]); }); }); it(`should pick BitGo GPG Pub Key based on enterprise flag for mock env`, async function () { const bgUrl = sdk_core_1.common.Environments['mock'].uri; const testBitgo = sdk_test_1.TestBitGo.decorate(src_1.BitGo, { env: 'mock' }); const testCoin = testBitgo.coin(ecdsaCoinName); const bitgoGPGKey = await openpgp.generateKey({ userIDs: [ { name: 'bitgo', email: 'bitgo@test.com', }, ], }); nock(bgUrl) .get(`/api/v2/${ecdsaCoinName}/tss/pubkey`) .query({ enterpriseId }) .reply(200, { mpcv2PublicKey: bitgoGPGKey.publicKey }); const ecdsaMpcv2Util = new TestEcdsaMpcv2Utils(testBitgo, testCoin, new sdk_core_1.Wallet(testBitgo, testCoin, ecdsaWalletData)); const bitgoGpgPubKey = await ecdsaMpcv2Util.testPickBitgoPubGpgKeyForSigning(true, undefined, enterpriseId); bitgoGpgPubKey.armor().should.equal(bitgoGPGKey.publicKey); }); it(`should pick BitGo GPG Pub Key based on constants api for mock env if enterprise flag based fetch fails`, async function () { nock.cleanAll(); const bgUrl = sdk_core_1.common.Environments['mock'].uri; const testBitgo = sdk_test_1.TestBitGo.decorate(src_1.BitGo, { env: 'mock' }); const testCoin = testBitgo.coin(ecdsaCoinName); const bitgoGPGKey = await openpgp.generateKey({ userIDs: [ { name: 'bitgo', email: 'bitgo@test.com', }, ], }); const constants = { mpc: { bitgoMPCv2PublicKey: bitgoGPGKey.publicKey, bitgoPublicKey: bitgoGPGKey.publicKey, }, }; nock(bgUrl).get('/api/v1/client/constants').times(2).reply(200, { ttl: 3600, constants }); const ecdsaMpcv2Util = new TestEcdsaMpcv2Utils(testBitgo, testCoin, new sdk_core_1.Wallet(testBitgo, testCoin, ecdsaWalletData)); const bitgoGpgPubKey = await ecdsaMpcv2Util.testPickBitgoPubGpgKeyForSigning(true, undefined, enterpriseId); bitgoGpgPubKey.armor().should.equal(bitgoGPGKey.publicKey); }); it(`should throw an error if config is not available in one of test, staging, or prod`, async function () { nock.cleanAll(); const testBitgo = sdk_test_1.TestBitGo.decorate(src_1.BitGo, { env: 'test' }); const testCoin = testBitgo.coin(ecdsaCoinName); const ecdsaMpcv2Util = new TestEcdsaMpcv2Utils(testBitgo, testCoin, new sdk_core_1.Wallet(testBitgo, testCoin, ecdsaWalletData)); await assert.rejects(async () => await ecdsaMpcv2Util.testPickBitgoPubGpgKeyForSigning(true)); }); it('should select the correct GPG key for verifyWalletSignatures with hardcoded options', async function () { // Test environment setup const env = 'test'; const bitgoInstance = sdk_test_1.TestBitGo.decorate(src_1.BitGo, { env }); bitgoInstance.initializeTestVars(); const coinInstance = bitgoInstance.coin(eddsaCoinName); const eddsaMpcv1Util = new TestEddsaMpcv1Utils(bitgoInstance, coinInstance, new sdk_core_1.Wallet(bitgoInstance, coinInstance, eddsaWalletData)); // Get the key that would be selected when using hardcoded BitGo keys // mpcv1 and nitro are passed as options const gpgKey = await eddsaMpcv1Util.testPickBitgoPubGpgKeyForSigning(false, undefined, undefined); // Mock implementation of verifyWalletSignatures to capture the bitgoGpgKey that gets used let capturedKey; eddsaMpcv1Util.verifyWalletSignatures = async function (userGpgPub, backupGpgPub, bitgoKeychain, decryptedShare, verifierIndex, useHardcodedBitGoKeys) { // Save the key that would be used when specifying hardcoded options if (useHardcodedBitGoKeys) { const hardcodedKey = await openpgp.readKey({ armoredKey: sdk_core_1.BitgoMpcGpgPubKeys.bitgoMpcGpgPubKeys['mpcv1']['nitro']['test'], }); capturedKey = hardcodedKey.armor(); } // Not actually verifying in this test return; }; // Call with hardcoded key options await eddsaMpcv1Util.verifyWalletSignatures('mock-user-key', 'mock-backup-key', { commonKeychain: 'mock-keychain', walletHSMGPGPublicKeySigs: '', id: '', type: 'tss', }, 'decrypted-share', 1, { env: 'test', pubKeyType: 'nitro' }); // Verify the hardcoded key matches what we expect capturedKey.should.equal(sdk_core_1.BitgoMpcGpgPubKeys.bitgoMpcGpgPubKeys['mpcv1']['nitro']['test']); // Also verify it's the same as what's returned by testPickBitgoPubGpgKeyForSigning gpgKey.armor().should.equal(capturedKey); }); }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYml0Z29NcGNHcGdQdWJLZXlzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vdGVzdC92Mi91bml0L2ludGVybmFsL3Rzc1V0aWxzL2JpdGdvTXBjR3BnUHViS2V5cy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLDhDQVF5QjtBQUN6Qiw4Q0FBNEM7QUFFNUMsNENBQTJDO0FBQzNDLG1DQUFtQztBQUNuQyw2QkFBOEI7QUFDOUIsaUNBQWtDO0FBRWxDLE1BQU0sbUJBQW9CLFNBQVEscUJBQVUsQ0FBQyxlQUFlO0lBQ25ELEtBQUssQ0FBQyxnQ0FBZ0MsQ0FDM0MsT0FBZ0IsRUFDaEIsS0FBc0IsRUFDdEIsWUFBcUI7UUFFckIsT0FBTyxJQUFJLENBQUMsNEJBQTRCLENBQUMsT0FBTyxFQUFFLEtBQUssRUFBRSxZQUFZLENBQUMsQ0FBQztJQUN6RSxDQUFDO0NBQ0Y7QUFFRCxNQUFNLG1CQUFvQixTQUFRLHFCQUFVO0lBQ25DLEtBQUssQ0FBQyxnQ0FBZ0MsQ0FDM0MsT0FBZ0IsRUFDaEIsS0FBc0IsRUFDdEIsWUFBcUI7UUFFckIsT0FBTyxJQUFJLENBQUMsNEJBQTRCLENBQUMsT0FBTyxFQUFFLEtBQUssRUFBRSxZQUFZLENBQUMsQ0FBQztJQUN6RSxDQUFDO0NBQ0Y7QUFFRCxRQUFRLENBQUMsdUNBQXVDLEVBQUU7SUFDaEQsTUFBTSxRQUFRLEdBQUcsa0NBQWtDLENBQUM7SUFDcEQsTUFBTSxZQUFZLEdBQUcsa0NBQWtDLENBQUM7SUFDeEQsTUFBTSxhQUFhLEdBQUcsT0FBTyxDQUFDO0lBQzlCLE1BQU0sYUFBYSxHQUFHLE1BQU0sQ0FBQztJQUM3QixNQUFNLGVBQWUsR0FBRztRQUN0QixFQUFFLEVBQUUsUUFBUTtRQUNaLFVBQVUsRUFBRSxZQUFZO1FBQ3hCLElBQUksRUFBRSxhQUFhO1FBQ25CLFlBQVksRUFBRSxFQUFFO1FBQ2hCLFlBQVksRUFBRSxLQUFLO1FBQ25CLElBQUksRUFBRSxDQUFD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LGVBQWU7WUFDL0IseUJBQXlCLEVBQUUsRUFBRTtZQUM3QixFQUFFLEVBQUUsRUFBRTtZQUNOLElBQUksRUFBRSxLQUFLO1NBQ1osRUFDRCxpQkFBaUIsRUFDakIsQ0FBQyxFQUNELEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUUsT0FBTyxFQUFFLENBQ3JDLENBQUM7UUFFRixrREFBa0Q7UUFDbEQsV0FBVyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsNkJBQWtCLENBQUMsa0JBQWtCLENBQUMsT0FBTyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztRQUMxRixtRkFBbUY7UUFDbkYsTUFBTSxDQUFDLEtBQUssRUFBRSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLENBQUM7SUFDM0MsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIEJpdGdvTXBjR3BnUHViS2V5cyxcbiAgY29tbW9uLFxuICBFQ0RTQVV0aWxzLFxuICBFZGRzYVV0aWxzLFxuICBFbnZpcm9ubWVudE5hbWUsXG4gIElSZXF1ZXN0VHJhY2VyLFxuICBXYWxsZXQsXG59IGZyb20gJ0BiaXRnby9zZGstY29yZSc7XG5pbXBvcnQgeyBUZXN0Qml0R28gfSBmcm9tICdAYml0Z28vc2RrLXRlc3QnO1xuXG5pbXBvcnQgeyBCaXRHbyB9IGZyb20gJy4uLy4uLy4uLy4uLy4uL3NyYyc7XG5pbXBvcnQgKiBhcyBvcGVucGdwIGZyb20gJ29wZW5wZ3AnO1xuaW1wb3J0IG5vY2sgPSByZXF1aXJlKCdub2NrJyk7XG5pbXBvcnQgYXNzZXJ0ID0gcmVxdWlyZSgnYXNzZXJ0Jyk7XG5cbmNsYXNzIFRlc3RFY2RzYU1wY3YyVXRpbHMgZXh0ZW5kcyBFQ0RTQVV0aWxzLkVjZHNhTVBDdjJVdGlscyB7XG4gIHB1YmxpYyBhc3luYyB0ZXN0UGlja0JpdGdvUHViR3BnS2V5Rm9yU2lnbmluZyhcbiAgICBpc01wY3YyOiBib29sZWFuLFxuICAgIHJlcUlkPzogSVJlcXVlc3RUcmFjZXIsXG4gICAgZW50ZXJwcmlzZUlkPzogc3RyaW5nXG4gICk6IFByb21pc2U8b3BlbnBncC5LZXk+IHtcbiAgICByZXR1cm4gdGhpcy5waWNrQml0Z29QdWJHcGdLZXlGb3JTaWduaW5nKGlzTXBjdjIsIHJlcUlkLCBlbnRlcnByaXNlSWQpO1xuICB9XG59XG5cbmNsYXNzIFRlc3RFZGRzYU1wY3YxVXRpbHMgZXh0ZW5kcyBFZGRzYVV0aWxzIHtcbiAgcHVibGljIGFzeW5jIHRlc3RQaWNrQml0Z29QdWJHcGdLZXlGb3JTaWduaW5nKFxuICAgIGlzTXBjdjI6IGJvb2xlYW4sXG4gICAgcmVxSWQ/OiBJUmVxdWVzdFRyYWNlcixcbiAgICBlbnRlcnByaXNlSWQ/OiBzdHJpbmdcbiAgKTogUHJvbWlzZTxvcGVucGdwLktleT4ge1xuICAgIHJldHVybiB0aGlzLnBpY2tCaXRnb1B1YkdwZ0tleUZvclNpZ25pbmcoaXNNcGN2MiwgcmVxSWQsIGVudGVycHJpc2VJZCk7XG4gIH1cbn1cblxuZGVzY3JpYmUoJ1RTUyBNUEMgUGljayBCaXRHbyBHUEcgUHViIEtleSBVdGlsczonLCBmdW5jdGlvbiAoKSB7XG4gIGNvbnN0IHdhbGxldElkID0gJzViMzQyNTJmMWJmMzQ5OTMwZTM0MDIwYTAwMDAwMDAwJztcbiAgY29uc3QgZW50ZXJwcmlzZUlkID0gJzY0NDkxNTNhNmY2YmMyMDAwNmQ2Njc3MWNkYmUxNWQzJztcbiAgY29uc3QgZWNkc2FDb2luTmFtZSA9ICdodGV0aCc7XG4gIGNvbnN0IGVkZHNhQ29pbk5hbWUgPSAndHNvbCc7XG4gIGNvbnN0IGVjZHNhV2FsbGV0RGF0YSA9IHtcbiAgICBpZDogd2FsbGV0SWQsXG4gICAgZW50ZXJwcmlzZTogZW50ZXJwcmlzZUlkLFxuICAgIGNvaW46IGVjZHNhQ29pbk5hbWUsXG4gICAgY29pblNwZWNpZmljOiB7fSxcbiAgICBtdWx0aXNpZ1R5cGU6ICd0c3MnLFxuICAgIGtleXM6IFsna2V5MScsICdrZXkyJywgJ2tleTMnXSxcbiAgfTtcbiAgY29uc3QgZWRkc2FXYWxsZXREYXRhID0ge1xuICAgIGlkOiB3YWxsZXRJZCxcbiAgICBlbnRlcnByaXNlOiBlbnRlcnByaXNlSWQsXG4gICAgY29pbjogZWRkc2FDb2luTmFtZSxcbiAgICBjb2luU3BlY2lmaWM6IHt9LFxuICAgIG11bHRpc2lnVHlwZTogJ3RzcycsXG4gICAga2V5czogWydrZXkxJywgJ2tleTInLCAna2V5MyddLFxuICB9O1xuICBjb25zdCBlbnZzOiBFbnZpcm9ubWVudE5hbWVbXSA9IFsndGVzdCcsICdzdGFnaW5nJywgJ3Byb2QnXTtcbiAgY29uc3QgZWNkc2FNcGN2MlV0aWxzOiBUZXN0RWNkc2FNcGN2MlV0aWxzW10gPSBbXTtcbiAgY29uc3QgZWRkc2FNcGN2MVV0aWxzOiBUZXN0RWRkc2FNcGN2MVV0aWxzW10gPSBbXTtcblxuICBiZWZvcmUoYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgIG5vY2suY2xlYW5BbGwoKTtcbiAgICBmb3IgKGNvbnN0IGVudiBvZiBlbnZzKSB7XG4gICAgICBjb25zdCBiaXRnb0luc3RhbmNlID0gVGVzdEJpdEdvLmRlY29yYXRlKEJpdEdvLCB7IGVudiB9KTtcbiAgICAgIGJpdGdvSW5zdGFuY2UuaW5pdGlhbGl6ZVRlc3RWYXJzKCk7XG4gICAgICBsZXQgY29pbkluc3RhbmNlID0gYml0Z29JbnN0YW5jZS5jb2luKGVjZHNhQ29pbk5hbWUpO1xuICAgICAgZWNkc2FNcGN2MlV0aWxzLnB1c2goXG4gICAgICAgIG5ldyBUZXN0RWNkc2FNcGN2MlV0aWxzKGJpdGdvSW5zdGFuY2UsIGNvaW5JbnN0YW5jZSwgbmV3IFdhbGxldChiaXRnb0luc3RhbmNlLCBjb2luSW5zdGFuY2UsIGVjZHNhV2FsbGV0RGF0YSkpXG4gICAgICApO1xuICAgICAgY29pbkluc3RhbmNlID0gYml0Z29JbnN0YW5jZS5jb2luKGVkZHNhQ29pbk5hbWUpO1xuICAgICAgZWRkc2FNcGN2MVV0aWxzLnB1c2goXG4gICAgICAgIG5ldyBUZXN0RWRkc2FNcGN2MVV0aWxzKGJpdGdvSW5zdGFuY2UsIGNvaW5JbnN0YW5jZSwgbmV3IFdhbGxldChiaXRnb0luc3RhbmNlLCBjb2luSW5zdGFuY2UsIGVkZHNhV2FsbGV0RGF0YSkpXG4gICAgICApO1xuICAgIH1cbiAgfSk7XG5cbiAgYmVmb3JlRWFjaChhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgZm9yIChjb25zdCBlbnYgb2YgZW52cykge1xuICAgICAgY29uc3QgYmdVcmwgPSBjb21tb24uRW52aXJvbm1lbnRzW2Vudl0udXJpO1xuICAgICAgbm9jayhiZ1VybCkuZ2V0KGAvYXBpL3YyLyR7ZWNkc2FDb2luTmFtZX0va2V5L2tleTNgKS50aW1lcyhlbnZzLmxlbmd0aCkucmVwbHkoMjAwLCB7IGhzbVR5cGU6ICdvbnByZW0nIH0pO1xuICAgICAgbm9jayhiZ1VybCkuZ2V0KGAvYXBpL3YyLyR7ZWRkc2FDb2luTmFtZX0va2V5L2tleTNgKS50aW1lcyhlbnZzLmxlbmd0aCkucmVwbHkoMjAwLCB7IGhzbVR5cGU6ICduaXRybycgfSk7XG4gICAgfVxuICB9KTtcblxuICBlbnZzLmZvckVhY2goYXN5bmMgZnVuY3Rpb24gKGVudiwgaW5kZXgpIHtcbiAgICBpdChgc2hvdWxkIHBpY2sgY29ycmVjdCBNcGN2MiBCaXRHbyBHUEcgUHViIEtleSBmb3IgJHtlbnZ9IGVudmAsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGJpdGdvR3BnUHViS2V5ID0gYXdhaXQgZWNkc2FNcGN2MlV0aWxzW2luZGV4XS50ZXN0UGlja0JpdGdvUHViR3BnS2V5Rm9yU2lnbmluZyh0cnVlKTtcbiAgICAgIGJpdGdvR3BnUHViS2V5XG4gICAgICAgIC5hcm1vcigpXG4gICAgICAgIC5zaG91bGQuZXF1YWwoQml0Z29NcGNHcGdQdWJLZXlzLmJpdGdvTXBjR3BnUHViS2V5c1snbXBjdjInXVsnb25wcmVtJ11bZW52ID09PSAnc3RhZ2luZycgPyAndGVzdCcgOiBlbnZdKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZW52cy5mb3JFYWNoKGFzeW5jIGZ1bmN0aW9uIChlbnYsIGluZGV4KSB7XG4gICAgaXQoYHNob3VsZCBwaWNrIGNvcnJlY3QgTXBjdjEgQml0R28gR1BHIFB1YiBLZXkgZm9yICR7ZW52fSBlbnZgLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBiaXRnb0dwZ1B1YktleSA9IGF3YWl0IGVkZHNhTXBjdjFVdGlsc1tpbmRleF0udGVzdFBpY2tCaXRnb1B1YkdwZ0tleUZvclNpZ25pbmcoZmFsc2UpO1xuICAgICAgYml0Z29HcGdQdWJLZXlcbiAgICAgICAgLmFybW9yKClcbiAgICAgICAgLnNob3VsZC5lcXVhbChCaXRnb01wY0dwZ1B1YktleXMuYml0Z29NcGNHcGdQdWJLZXlzWydtcGN2MSddWyduaXRybyddW2VudiA9PT0gJ3N0YWdpbmcnID8gJ3Rlc3QnIDogZW52XSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGl0KGBzaG91bGQgcGljayBCaXRHbyBHUEcgUHViIEtleSBiYXNlZCBvbiBlbnRlcnByaXNlIGZsYWcgZm9yIG1vY2sgZW52YCwgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IGJnVXJsID0gY29tbW9uLkVudmlyb25tZW50c1snbW9jayddLnVyaTtcbiAgICBjb25zdCB0ZXN0Qml0Z28gPSBUZXN0Qml0R28uZGVjb3JhdGUoQml0R28sIHsgZW52OiAnbW9jaycgfSk7XG4gICAgY29uc3QgdGVzdENvaW4gPSB0ZXN0Qml0Z28uY29pbihlY2RzYUNvaW5OYW1lKTtcbiAgICBjb25zdCBiaXRnb0dQR0tleSA9IGF3YWl0IG9wZW5wZ3AuZ2VuZXJhdGVLZXkoe1xuICAgICAgdXNlcklEczogW1xuICAgICAgICB7XG4gICAgICAgICAgbmFtZTogJ2JpdGdvJyxcbiAgICAgICAgICBlbWFpbDogJ2JpdGdvQHRlc3QuY29tJyxcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgfSk7XG4gICAgbm9jayhiZ1VybClcbiAgICAgIC5nZXQoYC9hcGkvdjIvJHtlY2RzYUNvaW5OYW1lfS90c3MvcHVia2V5YClcbiAgICAgIC5xdWVyeSh7IGVudGVycHJpc2VJZCB9KVxuICAgICAgLnJlcGx5KDIwMCwgeyBtcGN2MlB1YmxpY0tleTogYml0Z29HUEdLZXkucHVibGljS2V5IH0pO1xuICAgIGNvbnN0IGVjZHNhTXBjdjJVdGlsID0gbmV3IFRlc3RFY2RzYU1wY3YyVXRpbHMoXG4gICAgICB0ZXN0Qml0Z28sXG4gICAgICB0ZXN0Q29pbixcbiAgICAgIG5ldyBXYWxsZXQodGVzdEJpdGdvLCB0ZXN0Q29pbiwgZWNkc2FXYWxsZXREYXRhKVxuICAgICk7XG4gICAgY29uc3QgYml0Z29HcGdQdWJLZXkgPSBhd2FpdCBlY2RzYU1wY3YyVXRpbC50ZXN0UGlja0JpdGdvUHViR3BnS2V5Rm9yU2lnbmluZyh0cnVlLCB1bmRlZmluZWQsIGVudGVycHJpc2VJZCk7XG4gICAgYml0Z29HcGdQdWJLZXkuYXJtb3IoKS5zaG91bGQuZXF1YWwoYml0Z29HUEdLZXkucHVibGljS2V5KTtcbiAgfSk7XG5cbiAgaXQoYHNob3VsZCBwaWNrIEJpdEdvIEdQRyBQdWIgS2V5IGJhc2VkIG9uIGNvbnN0YW50cyBhcGkgZm9yIG1vY2sgZW52IGlmIGVudGVycHJpc2UgZmxhZyBiYXNlZCBmZXRjaCBmYWlsc2AsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICBub2NrLmNsZWFuQWxsKCk7XG4gICAgY29uc3QgYmdVcmwgPSBjb21tb24uRW52aXJvbm1lbnRzWydtb2NrJ10udXJpO1xuICAgIGNvbnN0IHRlc3RCaXRnbyA9IFRlc3RCaXRHby5kZWNvcmF0ZShCaXRHbywgeyBlbnY6ICdtb2NrJyB9KTtcbiAgICBjb25zdCB0ZXN0Q29pbiA9IHRlc3RCaXRnby5jb2luKGVjZHNhQ29pbk5hbWUpO1xuICAgIGNvbnN0IGJpdGdvR1BHS2V5ID0gYXdhaXQgb3BlbnBncC5nZW5lcmF0ZUtleSh7XG4gICAgICB1c2VySURzOiBbXG4gICAgICAgIHtcbiAgICAgICAgICBuYW1lOiAnYml0Z28nLFxuICAgICAgICAgIGVtYWlsOiAnYml0Z29AdGVzdC5jb20nLFxuICAgICAgICB9LFxuICAgICAgXSxcbiAgICB9KTtcbiAgICBjb25zdCBjb25zdGFudHMgPSB7XG4gICAgICBtcGM6IHtcbiAgICAgICAgYml0Z29NUEN2MlB1YmxpY0tleTogYml0Z29HUEdLZXkucHVibGljS2V5LFxuICAgICAgICBiaXRnb1B1YmxpY0tleTogYml0Z29HUEdLZXkucHVibGljS2V5LFxuICAgICAgfSxcbiAgICB9O1xuICAgIG5vY2soYmdVcmwpLmdldCgnL2FwaS92MS9jbGllbnQvY29uc3RhbnRzJykudGltZXMoMikucmVwbHkoMjAwLCB7IHR0bDogMzYwMCwgY29uc3RhbnRzIH0pO1xuICAgIGNvbnN0IGVjZHNhTXBjdjJVdGlsID0gbmV3IFRlc3RFY2RzYU1wY3YyVXRpbHMoXG4gICAgICB0ZXN0Qml0Z28sXG4gICAgICB0ZXN0Q29pbixcbiAgICAgIG5ldyBXYWxsZXQodGVzdEJpdGdvLCB0ZXN0Q29pbiwgZWNkc2FXYWxsZXREYXRhKVxuICAgICk7XG4gICAgY29uc3QgYml0Z29HcGdQdWJLZXkgPSBhd2FpdCBlY2RzYU1wY3YyVXRpbC50ZXN0UGlja0JpdGdvUHViR3BnS2V5Rm9yU2lnbmluZyh0cnVlLCB1bmRlZmluZWQsIGVudGVycHJpc2VJZCk7XG4gICAgYml0Z29HcGdQdWJLZXkuYXJtb3IoKS5zaG91bGQuZXF1YWwoYml0Z29HUEdLZXkucHVibGljS2V5KTtcbiAgfSk7XG5cbiAgaXQoYHNob3VsZCB0aHJvdyBhbiBlcnJvciBpZiBjb25maWcgaXMgbm90IGF2YWlsYWJsZSBpbiBvbmUgb2YgdGVzdCwgc3RhZ2luZywgb3IgcHJvZGAsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICBub2NrLmNsZWFuQWxsKCk7XG4gICAgY29uc3QgdGVzdEJpdGdvID0gVGVzdEJpdEdvLmRlY29yYXRlKEJpdEdvLCB7IGVudjogJ3Rlc3QnIH0pO1xuICAgIGNvbnN0IHRlc3RDb2luID0gdGVzdEJpdGdvLmNvaW4oZWNkc2FDb2luTmFtZSk7XG4gICAgY29uc3QgZWNkc2FNcGN2MlV0aWwgPSBuZXcgVGVzdEVjZHNhTXBjdjJVdGlscyhcbiAgICAgIHRlc3RCaXRnbyxcbiAgICAgIHRlc3RDb2luLFxuICAgICAgbmV3IFdhbGxldCh0ZXN0Qml0Z28sIHRlc3RDb2luLCBlY2RzYVdhbGxldERhdGEpXG4gICAgKTtcbiAgICBhd2FpdCBhc3NlcnQucmVqZWN0cyhhc3luYyAoKSA9PiBhd2FpdCBlY2RzYU1wY3YyVXRpbC50ZXN0UGlja0JpdGdvUHViR3BnS2V5Rm9yU2lnbmluZyh0cnVlKSk7XG4gIH0pO1xuXG4gIGl0KCdzaG91bGQgc2VsZWN0IHRoZSBjb3JyZWN0IEdQRyBrZXkgZm9yIHZlcmlmeVdhbGxldFNpZ25hdHVyZXMgd2l0aCBoYXJkY29kZWQgb3B0aW9ucycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAvLyBUZXN0IGVudmlyb25tZW50IHNldHVwXG4gICAgY29uc3QgZW52ID0gJ3Rlc3QnO1xuICAgIGNvbnN0IGJpdGdvSW5zdGFuY2UgPSBUZXN0Qml0R28uZGVjb3JhdGUoQml0R28sIHsgZW52IH0pO1xuICAgIGJpdGdvSW5zdGFuY2UuaW5pdGlhbGl6ZVRlc3RWYXJzKCk7XG4gICAgY29uc3QgY29pbkluc3RhbmNlID0gYml0Z29JbnN0YW5jZS5jb2luKGVkZHNhQ29pbk5hbWUpO1xuICAgIGNvbnN0IGVkZHNhTXBjdjFVdGlsID0gbmV3IFRlc3RFZGRzYU1wY3YxVXRpbHMoXG4gICAgICBiaXRnb0luc3RhbmNlLFxuICAgICAgY29pbkluc3RhbmNlLFxuICAgICAgbmV3IFdhbGxldChiaXRnb0luc3RhbmNlLCBjb2luSW5zdGFuY2UsIGVkZHNhV2FsbGV0RGF0YSlcbiAgICApO1xuXG4gICAgLy8gR2V0IHRoZSBrZXkgdGhhdCB3b3VsZCBiZSBzZWxlY3RlZCB3aGVuIHVzaW5nIGhhcmRjb2RlZCBCaXRHbyBrZXlzXG4gICAgLy8gbXBjdjEgYW5kIG5pdHJvIGFyZSBwYXNzZWQgYXMgb3B0aW9uc1xuICAgIGNvbnN0IGdwZ0tleSA9IGF3YWl0IGVkZHNhTXBjdjFVdGlsLnRlc3RQaWNrQml0Z29QdWJHcGdLZXlGb3JTaWduaW5nKGZhbHNlLCB1bmRlZmluZWQsIHVuZGVmaW5lZCk7XG5cbiAgICAvLyBNb2NrIGltcGxlbWVudGF0aW9uIG9mIHZlcmlmeVdhbGxldFNpZ25hdHVyZXMgdG8gY2FwdHVyZSB0aGUgYml0Z29HcGdLZXkgdGhhdCBnZXRzIHVzZWRcbiAgICBsZXQgY2FwdHVyZWRLZXk7XG4gICAgZWRkc2FNcGN2MVV0aWwudmVyaWZ5V2FsbGV0U2lnbmF0dXJlcyA9IGFzeW5jIGZ1bmN0aW9uIChcbiAgICAgIHVzZXJHcGdQdWIsXG4gICAgICBiYWNrdXBHcGdQdWIsXG4gICAgICBiaXRnb0tleWNoYWluLFxuICAgICAgZGVjcnlwdGVkU2hhcmUsXG4gICAgICB2ZXJpZmllckluZGV4LFxuICAgICAgdXNlSGFyZGNvZGVkQml0R29LZXlzXG4gICAgKSB7XG4gICAgICAvLyBTYXZlIHRoZSBrZXkgdGhhdCB3b3VsZCBiZSB1c2VkIHdoZW4gc3BlY2lmeWluZyBoYXJkY29kZWQgb3B0aW9uc1xuICAgICAgaWYgKHVzZUhhcmRjb2RlZEJpdEdvS2V5cykge1xuICAgICAgICBjb25zdCBoYXJkY29kZWRLZXkgPSBhd2FpdCBvcGVucGdwLnJlYWRLZXkoe1xuICAgICAgICAgIGFybW9yZWRLZXk6IEJpdGdvTXBjR3BnUHViS2V5cy5iaXRnb01wY0dwZ1B1YktleXNbJ21wY3YxJ11bJ25pdHJvJ11bJ3Rlc3QnXSxcbiAgICAgICAgfSk7XG4gICAgICAgIGNhcHR1cmVkS2V5ID0gaGFyZGNvZGVkS2V5LmFybW9yKCk7XG4gICAgICB9XG4gICAgICAvLyBOb3QgYWN0dWFsbHkgdmVyaWZ5aW5nIGluIHRoaXMgdGVzdFxuICAgICAgcmV0dXJuO1xuICAgIH07XG5cbiAgICAvLyBDYWxsIHdpdGggaGFyZGNvZGVkIGtleSBvcHRpb25zXG4gICAgYXdhaXQgZWRkc2FNcGN2MVV0aWwudmVyaWZ5V2FsbGV0U2lnbmF0dXJlcyhcbiAgICAgICdtb2NrLXVzZXIta2V5JyxcbiAgICAgICdtb2NrLWJhY2t1cC1rZXknLFxuICAgICAge1xuICAgICAgICBjb21tb25LZXljaGFpbjogJ21vY2sta2V5Y2hhaW4nLFxuICAgICAgICB3YWxsZXRIU01HUEdQdWJsaWNLZXlTaWdzOiAnJyxcbiAgICAgICAgaWQ6ICcnLFxuICAgICAgICB0eXBlOiAndHNzJyxcbiAgICAgIH0sXG4gICAgICAnZGVjcnlwdGVkLXNoYXJlJyxcbiAgICAgIDEsXG4gICAgICB7IGVudjogJ3Rlc3QnLCBwdWJLZXlUeXBlOiAnbml0cm8nIH1cbiAgICApO1xuXG4gICAgLy8gVmVyaWZ5IHRoZSBoYXJkY29kZWQga2V5IG1hdGNoZXMgd2hhdCB3ZSBleHBlY3RcbiAgICBjYXB0dXJlZEtleS5zaG91bGQuZXF1YWwoQml0Z29NcGNHcGdQdWJLZXlzLmJpdGdvTXBjR3BnUHViS2V5c1snbXBjdjEnXVsnbml0cm8nXVsndGVzdCddKTtcbiAgICAvLyBBbHNvIHZlcmlmeSBpdCdzIHRoZSBzYW1lIGFzIHdoYXQncyByZXR1cm5lZCBieSB0ZXN0UGlja0JpdGdvUHViR3BnS2V5Rm9yU2lnbmluZ1xuICAgIGdwZ0tleS5hcm1vcigpLnNob3VsZC5lcXVhbChjYXB0dXJlZEtleSk7XG4gIH0pO1xufSk7XG4iXX0=