aws-delivlib
Version:
A fabulous library for defining continuous pipelines for building, testing and releasing code libraries.
178 lines • 24.1 kB
JavaScript
;
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