UNPKG

aws-delivlib

Version:

A fabulous library for defining continuous pipelines for building, testing and releasing code libraries.

178 lines • 24.1 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; Object.defineProperty(exports, "__esModule", { value: true }); const crypto = __importStar(require("crypto")); const fs = __importStar(require("fs")); const os = __importStar(require("os")); const path = __importStar(require("path")); const util = __importStar(require("util")); // eslint-disable-next-line import/no-extraneous-dependencies const client_secrets_manager_1 = require("@aws-sdk/client-secrets-manager"); // eslint-disable-next-line import/no-extraneous-dependencies const client_ssm_1 = require("@aws-sdk/client-ssm"); const cfn = __importStar(require("./_cloud-formation")); // eslint-disable-next-line @typescript-eslint/no-require-imports const _exec = require("./_exec"); // eslint-disable-next-line @typescript-eslint/no-require-imports const _rmrf = require("./_rmrf"); const mkdtemp = util.promisify(fs.mkdtemp); const writeFile = util.promisify(fs.writeFile); const secretsManager = new client_secrets_manager_1.SecretsManager(); const ssm = new client_ssm_1.SSM(); exports.handler = cfn.customResourceHandler(handleEvent); const GPG_BIN = 'gpg'; async function handleEvent(event, context) { const props = event.ResourceProperties; if (event.RequestType !== cfn.RequestType.DELETE) { cfn.validateProperties(props, { Description: false, Email: true, Expiry: true, Identity: true, KeyArn: false, KeySizeBits: true, SecretName: true, Version: false, DeleteImmediately: false, }); } let newKey = event.RequestType === cfn.RequestType.CREATE; if (event.RequestType === cfn.RequestType.UPDATE) { const oldProps = event.OldResourceProperties; const immutableFields = ['Email', 'Expiry', 'Identity', 'KeySizeBits', 'SecretName', 'Version']; for (const key of immutableFields) { if (props[key] !== oldProps[key]) { // eslint-disable-next-line no-console console.log(`New key required: ${key} changed from ${oldProps[key]} to ${props[key]}`); newKey = true; } } } switch (event.RequestType) { case cfn.RequestType.CREATE: case cfn.RequestType.UPDATE: // If we're UPDATE and get a new key, we'll issue a new Physical ID. return newKey ? _createNewKey(event, context) : _updateExistingKey(event, context); case cfn.RequestType.DELETE: return _deleteSecret(event); } } async function _createNewKey(event, context) { const passPhrase = crypto.randomBytes(32).toString('base64'); const tempDir = await mkdtemp(path.join(os.tmpdir(), 'OpenPGP-')); try { process.env.GNUPGHOME = tempDir; const keyConfig = path.join(tempDir, 'key.config'); await writeFile(keyConfig, [ 'Key-Type: RSA', `Key-Length: ${event.ResourceProperties.KeySizeBits}`, `Name-Real: ${event.ResourceProperties.Identity}`, `Name-Email: ${event.ResourceProperties.Email}`, `Expire-Date: ${event.ResourceProperties.Expiry}`, `Passphrase: ${passPhrase}`, '%commit', '%echo done', ].join('\n'), { encoding: 'utf8' }); const gpgCommonArgs = [`--homedir=${tempDir}`, '--agent-program=/bin/gpg-agent']; await _exec(GPG_BIN, ...gpgCommonArgs, '--batch', '--gen-key', keyConfig); // Need the passphrase to export the private key const keyMaterial = await _exec(GPG_BIN, ...gpgCommonArgs, '--batch', '--yes', '--export-secret-keys', '--armor', '--pinentry-mode=loopback', `--passphrase=${passPhrase}`); const publicKey = await _exec(GPG_BIN, ...gpgCommonArgs, '--batch', '--yes', '--export', '--armor'); const secretOpts = { ClientRequestToken: context.awsRequestId, Description: event.ResourceProperties.Description, KmsKeyId: event.ResourceProperties.KeyArn, SecretString: JSON.stringify({ PrivateKey: keyMaterial, Passphrase: passPhrase, }), }; const secret = event.RequestType === cfn.RequestType.CREATE ? await secretsManager.createSecret({ ...secretOpts, Name: event.ResourceProperties.SecretName }) : await secretsManager.updateSecret({ ...secretOpts, SecretId: event.PhysicalResourceId }); return { Ref: secret.ARN, SecretArn: secret.ARN, PublicKey: publicKey, }; } finally { await _rmrf(tempDir); } } async function _updateExistingKey(event, context) { const publicKey = await _getPublicKey(event.PhysicalResourceId); const result = await secretsManager.updateSecret({ ClientRequestToken: context.awsRequestId, Description: event.ResourceProperties.Description, KmsKeyId: event.ResourceProperties.KeyArn, SecretId: event.PhysicalResourceId, }); if (event.OldResourceProperties.ParameterName) { // Migrating from a version that did create the SSM Parameter from the Custom Resource, so we'll delete that now in // order to allow the "external" creation to happen without problems... try { await ssm.deleteParameter({ Name: event.OldResourceProperties.ParameterName }); } catch (e) { // Allow the parameter to already not exist, just in case! if (e.name !== 'ParameterNotFound') { throw e; } } } return { Ref: result.ARN, SecretArn: result.ARN, PublicKey: publicKey, }; } async function _getPublicKey(secretArn) { const secretValue = await secretsManager.getSecretValue({ SecretId: secretArn }); const keyData = JSON.parse(secretValue.SecretString); const tempDir = await mkdtemp(path.join(os.tmpdir(), 'OpenPGP-')); try { process.env.GNUPGHOME = tempDir; const privateKeyFile = path.join(tempDir, 'private.key'); await writeFile(privateKeyFile, keyData.PrivateKey, { encoding: 'utf-8' }); const gpgCommonArgs = [`--homedir=${tempDir}`, '--agent-program=/bin/gpg-agent']; // Note: importing a private key does NOT require entering it's passphrase! await _exec(GPG_BIN, ...gpgCommonArgs, '--batch', '--yes', '--import', privateKeyFile); return await _exec(GPG_BIN, ...gpgCommonArgs, '--batch', '--yes', '--export', '--armor'); } finally { await _rmrf(tempDir); } } async function _deleteSecret(event) { await secretsManager.deleteSecret({ SecretId: event.PhysicalResourceId, ForceDeleteWithoutRecovery: !!event.ResourceProperties.DeleteImmediately, }); return { Ref: event.PhysicalResourceId }; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGdwLXNlY3JldC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInBncC1zZWNyZXQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLCtDQUFpQztBQUNqQyx1Q0FBeUI7QUFDekIsdUNBQXlCO0FBQ3pCLDJDQUE2QjtBQUM3QiwyQ0FBNkI7QUFDN0IsNkRBQTZEO0FBQzdELDRFQUFpRTtBQUNqRSw2REFBNkQ7QUFDN0Qsb0RBQTBDO0FBRTFDLHdEQUEwQztBQUMxQyxpRUFBaUU7QUFDakUsaUNBQWtDO0FBRWxDLGlFQUFpRTtBQUNqRSxpQ0FBa0M7QUFFbEMsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUMsT0FBTyxDQUFDLENBQUM7QUFDM0MsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUMsU0FBUyxDQUFDLENBQUM7QUFFL0MsTUFBTSxjQUFjLEdBQUcsSUFBSSx1Q0FBYyxFQUFFLENBQUM7QUFDNUMsTUFBTSxHQUFHLEdBQUcsSUFBSSxnQkFBRyxFQUFFLENBQUM7QUFFdEIsT0FBTyxDQUFDLE9BQU8sR0FBRyxHQUFHLENBQUMscUJBQXFCLENBQUMsV0FBVyxDQUFDLENBQUM7QUFFekQsTUFBTSxPQUFPLEdBQUcsS0FBSyxDQUFDO0FBUXRCLEtBQUssVUFBVSxXQUFXLENBQUMsS0FBZ0IsRUFBRSxPQUF1QjtJQUNsRSxNQUFNLEtBQUssR0FBRyxLQUFLLENBQUMsa0JBQWtCLENBQUM7SUFFdkMsSUFBSSxLQUFLLENBQUMsV0FBVyxLQUFLLEdBQUcsQ0FBQyxXQUFXLENBQUMsTUFBTSxFQUFFO1FBQ2hELEdBQUcsQ0FBQyxrQkFBa0IsQ0FBQyxLQUFLLEVBQUU7WUFDNUIsV0FBVyxFQUFFLEtBQUs7WUFDbEIsS0FBSyxFQUFFLElBQUk7WUFDWCxNQUFNLEVBQUUsSUFBSTtZQUNaLFFBQVEsRUFBRSxJQUFJO1lBQ2QsTUFBTSxFQUFF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ImltcG9ydCAqIGFzIGNyeXB0byBmcm9tICdjcnlwdG8nO1xuaW1wb3J0ICogYXMgZnMgZnJvbSAnZnMnO1xuaW1wb3J0ICogYXMgb3MgZnJvbSAnb3MnO1xuaW1wb3J0ICogYXMgcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCAqIGFzIHV0aWwgZnJvbSAndXRpbCc7XG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgaW1wb3J0L25vLWV4dHJhbmVvdXMtZGVwZW5kZW5jaWVzXG5pbXBvcnQgeyBTZWNyZXRzTWFuYWdlciB9IGZyb20gJ0Bhd3Mtc2RrL2NsaWVudC1zZWNyZXRzLW1hbmFnZXInO1xuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGltcG9ydC9uby1leHRyYW5lb3VzLWRlcGVuZGVuY2llc1xuaW1wb3J0IHsgU1NNIH0gZnJvbSAnQGF3cy1zZGsvY2xpZW50LXNzbSc7XG5cbmltcG9ydCAqIGFzIGNmbiBmcm9tICcuL19jbG91ZC1mb3JtYXRpb24nO1xuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1yZXF1aXJlLWltcG9ydHNcbmltcG9ydCBfZXhlYyA9IHJlcXVpcmUoJy4vX2V4ZWMnKTtcbmltcG9ydCAqIGFzIGxhbWJkYSBmcm9tICcuL19sYW1iZGEnO1xuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1yZXF1aXJlLWltcG9ydHNcbmltcG9ydCBfcm1yZiA9IHJlcXVpcmUoJy4vX3JtcmYnKTtcblxuY29uc3QgbWtkdGVtcCA9IHV0aWwucHJvbWlzaWZ5KGZzLm1rZHRlbXApO1xuY29uc3Qgd3JpdGVGaWxlID0gdXRpbC5wcm9taXNpZnkoZnMud3JpdGVGaWxlKTtcblxuY29uc3Qgc2VjcmV0c01hbmFnZXIgPSBuZXcgU2VjcmV0c01hbmFnZXIoKTtcbmNvbnN0IHNzbSA9IG5ldyBTU00oKTtcblxuZXhwb3J0cy5oYW5kbGVyID0gY2ZuLmN1c3RvbVJlc291cmNlSGFuZGxlcihoYW5kbGVFdmVudCk7XG5cbmNvbnN0IEdQR19CSU4gPSAnZ3BnJztcblxuXG5pbnRlcmZhY2UgUmVzb3VyY2VBdHRyaWJ1dGVzIGV4dGVuZHMgY2ZuLlJlc291cmNlQXR0cmlidXRlcyB7XG4gIFNlY3JldEFybjogc3RyaW5nO1xuICBQdWJsaWNLZXk6IHN0cmluZztcbn1cblxuYXN5bmMgZnVuY3Rpb24gaGFuZGxlRXZlbnQoZXZlbnQ6IGNmbi5FdmVudCwgY29udGV4dDogbGFtYmRhLkNvbnRleHQpOiBQcm9taXNlPGNmbi5SZXNvdXJjZUF0dHJpYnV0ZXM+IHtcbiAgY29uc3QgcHJvcHMgPSBldmVudC5SZXNvdXJjZVByb3BlcnRpZXM7XG5cbiAgaWYgKGV2ZW50LlJlcXVlc3RUeXBlICE9PSBjZm4uUmVxdWVzdFR5cGUuREVMRVRFKSB7XG4gICAgY2ZuLnZhbGlkYXRlUHJvcGVydGllcyhwcm9wcywge1xuICAgICAgRGVzY3JpcHRpb246IGZhbHNlLFxuICAgICAgRW1haWw6IHRydWUsXG4gICAgICBFeHBpcnk6IHRydWUsXG4gICAgICBJZGVudGl0eTogdHJ1ZSxcbiAgICAgIEtleUFybjogZmFsc2UsXG4gICAgICBLZXlTaXplQml0czogdHJ1ZSxcbiAgICAgIFNlY3JldE5hbWU6IHRydWUsXG4gICAgICBWZXJzaW9uOiBmYWxzZSxcbiAgICAgIERlbGV0ZUltbWVkaWF0ZWx5OiBmYWxzZSxcbiAgICB9KTtcbiAgfVxuXG4gIGxldCBuZXdLZXkgPSBldmVudC5SZXF1ZXN0VHlwZSA9PT0gY2ZuLlJlcXVlc3RUeXBlLkNSRUFURTtcblxuICBpZiAoZXZlbnQuUmVxdWVzdFR5cGUgPT09IGNmbi5SZXF1ZXN0VHlwZS5VUERBVEUpIHtcbiAgICBjb25zdCBvbGRQcm9wcyA9IGV2ZW50Lk9sZFJlc291cmNlUHJvcGVydGllcztcbiAgICBjb25zdCBpbW11dGFibGVGaWVsZHMgPSBbJ0VtYWlsJywgJ0V4cGlyeScsICdJZGVudGl0eScsICdLZXlTaXplQml0cycsICdTZWNyZXROYW1lJywgJ1ZlcnNpb24nXTtcbiAgICBmb3IgKGNvbnN0IGtleSBvZiBpbW11dGFibGVGaWVsZHMpIHtcbiAgICAgIGlmIChwcm9wc1trZXldICE9PSBvbGRQcm9wc1trZXldKSB7XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlXG4gICAgICAgIGNvbnNvbGUubG9nKGBOZXcga2V5IHJlcXVpcmVkOiAke2tleX0gY2hhbmdlZCBmcm9tICR7b2xkUHJvcHNba2V5XX0gdG8gJHtwcm9wc1trZXldfWApO1xuICAgICAgICBuZXdLZXkgPSB0cnVlO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHN3aXRjaCAoZXZlbnQuUmVxdWVzdFR5cGUpIHtcbiAgICBjYXNlIGNmbi5SZXF1ZXN0VHlwZS5DUkVBVEU6XG4gICAgY2FzZSBjZm4uUmVxdWVzdFR5cGUuVVBEQVRFOlxuICAgIC8vIElmIHdlJ3JlIFVQREFURSBhbmQgZ2V0IGEgbmV3IGtleSwgd2UnbGwgaXNzdWUgYSBuZXcgUGh5c2ljYWwgSUQuXG4gICAgICByZXR1cm4gbmV3S2V5XG4gICAgICAgID8gX2NyZWF0ZU5ld0tleShldmVudCwgY29udGV4dClcbiAgICAgICAgOiBfdXBkYXRlRXhpc3RpbmdLZXkoZXZlbnQgYXMgY2ZuLlVwZGF0ZUV2ZW50LCBjb250ZXh0KTtcbiAgICBjYXNlIGNmbi5SZXF1ZXN0VHlwZS5ERUxFVEU6XG4gICAgICByZXR1cm4gX2RlbGV0ZVNlY3JldChldmVudCk7XG4gIH1cbn1cblxuYXN5bmMgZnVuY3Rpb24gX2NyZWF0ZU5ld0tleShldmVudDogY2ZuLkNyZWF0ZUV2ZW50IHwgY2ZuLlVwZGF0ZUV2ZW50LCBjb250ZXh0OiBsYW1iZGEuQ29udGV4dCk6IFByb21pc2U8UmVzb3VyY2VBdHRyaWJ1dGVzPiB7XG4gIGNvbnN0IHBhc3NQaHJhc2UgPSBjcnlwdG8ucmFuZG9tQnl0ZXMoMzIpLnRvU3RyaW5nKCdiYXNlNjQnKTtcbiAgY29uc3QgdGVtcERpciA9IGF3YWl0IG1rZHRlbXAocGF0aC5qb2luKG9zLnRtcGRpcigpLCAnT3BlblBHUC0nKSk7XG4gIHRyeSB7XG4gICAgcHJvY2Vzcy5lbnYuR05VUEdIT01FID0gdGVtcERpcjtcblxuICAgIGNvbnN0IGtleUNvbmZpZyA9IHBhdGguam9pbih0ZW1wRGlyLCAna2V5LmNvbmZpZycpO1xuICAgIGF3YWl0IHdyaXRlRmlsZShrZXlDb25maWcsIFtcbiAgICAgICdLZXktVHlwZTogUlNBJyxcbiAgICAgIGBLZXktTGVuZ3RoOiAke2V2ZW50LlJlc291cmNlUHJvcGVydGllcy5LZXlTaXplQml0c31gLFxuICAgICAgYE5hbWUtUmVhbDogJHtldmVudC5SZXNvdXJjZVByb3BlcnRpZXMuSWRlbnRpdHl9YCxcbiAgICAgIGBOYW1lLUVtYWlsOiAke2V2ZW50LlJlc291cmNlUHJvcGVydGllcy5FbWFpbH1gLFxuICAgICAgYEV4cGlyZS1EYXRlOiAke2V2ZW50LlJlc291cmNlUHJvcGVydGllcy5FeHBpcnl9YCxcbiAgICAgIGBQYXNzcGhyYXNlOiAke3Bhc3NQaHJhc2V9YCxcbiAgICAgICclY29tbWl0JyxcbiAgICAgICclZWNobyBkb25lJyxcbiAgICBdLmpvaW4oJ1xcbicpLCB7IGVuY29kaW5nOiAndXRmOCcgfSk7XG5cbiAgICBjb25zdCBncGdDb21tb25BcmdzID0gW2AtLWhvbWVkaXI9JHt0ZW1wRGlyfWAsICctLWFnZW50LXByb2dyYW09L2Jpbi9ncGctYWdlbnQnXTtcbiAgICBhd2FpdCBfZXhlYyhHUEdfQklOLCAuLi5ncGdDb21tb25BcmdzLCAnLS1iYXRjaCcsICctLWdlbi1rZXknLCBrZXlDb25maWcpO1xuICAgIC8vIE5lZWQgdGhlIHBhc3NwaHJhc2UgdG8gZXhwb3J0IHRoZSBwcml2YXRlIGtleVxuICAgIGNvbnN0IGtleU1hdGVyaWFsID0gYXdhaXQgX2V4ZWMoR1BHX0JJTiwgLi4uZ3BnQ29tbW9uQXJncywgJy0tYmF0Y2gnLCAnLS15ZXMnLCAnLS1leHBvcnQtc2VjcmV0LWtleXMnLCAnLS1hcm1vcicsICctLXBpbmVudHJ5LW1vZGU9bG9vcGJhY2snLCBgLS1wYXNzcGhyYXNlPSR7cGFzc1BocmFzZX1gKTtcbiAgICBjb25zdCBwdWJsaWNLZXkgPSBhd2FpdCBfZXhlYyhHUEdfQklOLCAuLi5ncGdDb21tb25BcmdzLCAnLS1iYXRjaCcsICctLXllcycsICctLWV4cG9ydCcsICctLWFybW9yJyk7XG4gICAgY29uc3Qgc2VjcmV0T3B0cyA9IHtcbiAgICAgIENsaWVudFJlcXVlc3RUb2tlbjogY29udGV4dC5hd3NSZXF1ZXN0SWQsXG4gICAgICBEZXNjcmlwdGlvbjogZXZlbnQuUmVzb3VyY2VQcm9wZXJ0aWVzLkRlc2NyaXB0aW9uLFxuICAgICAgS21zS2V5SWQ6IGV2ZW50LlJlc291cmNlUHJvcGVydGllcy5LZXlBcm4sXG4gICAgICBTZWNyZXRTdHJpbmc6IEpTT04uc3RyaW5naWZ5KHtcbiAgICAgICAgUHJpdmF0ZUtleToga2V5TWF0ZXJpYWwsXG4gICAgICAgIFBhc3NwaHJhc2U6IHBhc3NQaHJhc2UsXG4gICAgICB9KSxcbiAgICB9O1xuICAgIGNvbnN0IHNlY3JldCA9IGV2ZW50LlJlcXVlc3RUeXBlID09PSBjZm4uUmVxdWVzdFR5cGUuQ1JFQVRFXG4gICAgICA/IGF3YWl0IHNlY3JldHNNYW5hZ2VyLmNyZWF0ZVNlY3JldCh7IC4uLnNlY3JldE9wdHMsIE5hbWU6IGV2ZW50LlJlc291cmNlUHJvcGVydGllcy5TZWNyZXROYW1lIH0pXG4gICAgICA6IGF3YWl0IHNlY3JldHNNYW5hZ2VyLnVwZGF0ZVNlY3JldCh7IC4uLnNlY3JldE9wdHMsIFNlY3JldElkOiBldmVudC5QaHlzaWNhbFJlc291cmNlSWQgfSk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgUmVmOiBzZWNyZXQuQVJOISxcbiAgICAgIFNlY3JldEFybjogc2VjcmV0LkFSTiEsXG4gICAgICBQdWJsaWNLZXk6IHB1YmxpY0tleSxcbiAgICB9O1xuICB9IGZpbmFsbHkge1xuICAgIGF3YWl0IF9ybXJmKHRlbXBEaXIpO1xuICB9XG59XG5cbmFzeW5jIGZ1bmN0aW9uIF91cGRhdGVFeGlzdGluZ0tleShldmVudDogY2ZuLlVwZGF0ZUV2ZW50LCBjb250ZXh0OiBsYW1iZGEuQ29udGV4dCk6IFByb21pc2U8UmVzb3VyY2VBdHRyaWJ1dGVzPiB7XG4gIGNvbnN0IHB1YmxpY0tleSA9IGF3YWl0IF9nZXRQdWJsaWNLZXkoZXZlbnQuUGh5c2ljYWxSZXNvdXJjZUlkKTtcbiAgY29uc3QgcmVzdWx0ID0gYXdhaXQgc2VjcmV0c01hbmFnZXIudXBkYXRlU2VjcmV0KHtcbiAgICBDbGllbnRSZXF1ZXN0VG9rZW46IGNvbnRleHQuYXdzUmVxdWVzdElkLFxuICAgIERlc2NyaXB0aW9uOiBldmVudC5SZXNvdXJjZVByb3BlcnRpZXMuRGVzY3JpcHRpb24sXG4gICAgS21zS2V5SWQ6IGV2ZW50LlJlc291cmNlUHJvcGVydGllcy5LZXlBcm4sXG4gICAgU2VjcmV0SWQ6IGV2ZW50LlBoeXNpY2FsUmVzb3VyY2VJZCxcbiAgfSk7XG5cbiAgaWYgKGV2ZW50Lk9sZFJlc291cmNlUHJvcGVydGllcy5QYXJhbWV0ZXJOYW1lKSB7XG4gICAgLy8gTWlncmF0aW5nIGZyb20gYSB2ZXJzaW9uIHRoYXQgZGlkIGNyZWF0ZSB0aGUgU1NNIFBhcmFtZXRlciBmcm9tIHRoZSBDdXN0b20gUmVzb3VyY2UsIHNvIHdlJ2xsIGRlbGV0ZSB0aGF0IG5vdyBpblxuICAgIC8vIG9yZGVyIHRvIGFsbG93IHRoZSBcImV4dGVybmFsXCIgY3JlYXRpb24gdG8gaGFwcGVuIHdpdGhvdXQgcHJvYmxlbXMuLi5cbiAgICB0cnkge1xuICAgICAgYXdhaXQgc3NtLmRlbGV0ZVBhcmFtZXRlcih7IE5hbWU6IGV2ZW50Lk9sZFJlc291cmNlUHJvcGVydGllcy5QYXJhbWV0ZXJOYW1lIH0pO1xuICAgIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgICAgLy8gQWxsb3cgdGhlIHBhcmFtZXRlciB0byBhbHJlYWR5IG5vdCBleGlzdCwganVzdCBpbiBjYXNlIVxuICAgICAgaWYgKGUubmFtZSAhPT0gJ1BhcmFtZXRlck5vdEZvdW5kJykge1xuICAgICAgICB0aHJvdyBlO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiB7XG4gICAgUmVmOiByZXN1bHQuQVJOISxcbiAgICBTZWNyZXRBcm46IHJlc3VsdC5BUk4hLFxuICAgIFB1YmxpY0tleTogcHVibGljS2V5LFxuICB9O1xufVxuXG5hc3luYyBmdW5jdGlvbiBfZ2V0UHVibGljS2V5KHNlY3JldEFybjogc3RyaW5nKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgY29uc3Qgc2VjcmV0VmFsdWUgPSBhd2FpdCBzZWNyZXRzTWFuYWdlci5nZXRTZWNyZXRWYWx1ZSh7IFNlY3JldElkOiBzZWNyZXRBcm4gfSk7XG4gIGNvbnN0IGtleURhdGEgPSBKU09OLnBhcnNlKHNlY3JldFZhbHVlLlNlY3JldFN0cmluZyEpO1xuICBjb25zdCB0ZW1wRGlyID0gYXdhaXQgbWtkdGVtcChwYXRoLmpvaW4ob3MudG1wZGlyKCksICdPcGVuUEdQLScpKTtcbiAgdHJ5IHtcbiAgICBwcm9jZXNzLmVudi5HTlVQR0hPTUUgPSB0ZW1wRGlyO1xuICAgIGNvbnN0IHByaXZhdGVLZXlGaWxlID0gcGF0aC5qb2luKHRlbXBEaXIsICdwcml2YXRlLmtleScpO1xuICAgIGF3YWl0IHdyaXRlRmlsZShwcml2YXRlS2V5RmlsZSwga2V5RGF0YS5Qcml2YXRlS2V5LCB7IGVuY29kaW5nOiAndXRmLTgnIH0pO1xuICAgIGNvbnN0IGdwZ0NvbW1vbkFyZ3MgPSBbYC0taG9tZWRpcj0ke3RlbXBEaXJ9YCwgJy0tYWdlbnQtcHJvZ3JhbT0vYmluL2dwZy1hZ2VudCddO1xuICAgIC8vIE5vdGU6IGltcG9ydGluZyBhIHByaXZhdGUga2V5IGRvZXMgTk9UIHJlcXVpcmUgZW50ZXJpbmcgaXQncyBwYXNzcGhyYXNlIVxuICAgIGF3YWl0IF9leGVjKEdQR19CSU4sIC4uLmdwZ0NvbW1vbkFyZ3MsICctLWJhdGNoJywgJy0teWVzJywgJy0taW1wb3J0JywgcHJpdmF0ZUtleUZpbGUpO1xuICAgIHJldHVybiBhd2FpdCBfZXhlYyhHUEdfQklOLCAuLi5ncGdDb21tb25BcmdzLCAnLS1iYXRjaCcsICctLXllcycsICctLWV4cG9ydCcsICctLWFybW9yJyk7XG4gIH0gZmluYWxseSB7XG4gICAgYXdhaXQgX3JtcmYodGVtcERpcik7XG4gIH1cbn1cblxuYXN5bmMgZnVuY3Rpb24gX2RlbGV0ZVNlY3JldChldmVudDogY2ZuLkRlbGV0ZUV2ZW50KTogUHJvbWlzZTxjZm4uUmVzb3VyY2VBdHRyaWJ1dGVzPiB7XG4gIGF3YWl0IHNlY3JldHNNYW5hZ2VyLmRlbGV0ZVNlY3JldCh7XG4gICAgU2VjcmV0SWQ6IGV2ZW50LlBoeXNpY2FsUmVzb3VyY2VJZCxcbiAgICBGb3JjZURlbGV0ZVdpdGhvdXRSZWNvdmVyeTogISFldmVudC5SZXNvdXJjZVByb3BlcnRpZXMuRGVsZXRlSW1tZWRpYXRlbHksXG4gIH0pO1xuICByZXR1cm4geyBSZWY6IGV2ZW50LlBoeXNpY2FsUmVzb3VyY2VJZCB9O1xufVxuIl19