UNPKG

@darren-valent/cdk-ec2-key-pair

Version:
238 lines 35 kB
"use strict"; var _a; Object.defineProperty(exports, "__esModule", { value: true }); exports.KeyPair = exports.PublicKeyFormat = void 0; const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti"); const aws_cdk_lib_1 = require("aws-cdk-lib"); const constructs_1 = require("constructs"); const path = require("path"); const resourceType = 'Custom::EC2-Key-Pair'; const ID = `CFN::Resource::${resourceType}`; const createdByTag = 'CreatedByCfnCustomResource'; const cleanID = ID.replace(/:+/g, '-'); const lambdaTimeout = 3; // minutes var PublicKeyFormat; (function (PublicKeyFormat) { PublicKeyFormat["OPENSSH"] = "OPENSSH"; PublicKeyFormat["PEM"] = "PEM"; })(PublicKeyFormat || (exports.PublicKeyFormat = PublicKeyFormat = {})); /** * An EC2 Key Pair */ class KeyPair extends constructs_1.Construct { /** * Defines a new EC2 Key Pair. The private key will be stored in AWS Secrets Manager */ constructor(scope, id, props) { super(scope, id); /** * ARN of the private key in AWS Secrets Manager */ this.privateKeyArn = ''; /** * ARN of the public key in AWS Secrets Manager */ this.publicKeyArn = ''; /** * The public key. * * Only filled, when `exposePublicKey = true` */ this.publicKeyValue = ''; /** * Name of the Key Pair */ this.keyPairName = ''; /** * ID of the Key Pair */ this.keyPairID = ''; this.prefix = ''; if (props.removeKeySecretsAfterDays && (props.removeKeySecretsAfterDays < 0 || (props.removeKeySecretsAfterDays > 0 && props.removeKeySecretsAfterDays < 7) || props.removeKeySecretsAfterDays > 30)) { aws_cdk_lib_1.Annotations.of(this).addError(`Parameter removeKeySecretsAfterDays must be 0 or between 7 and 30. Got ${props.removeKeySecretsAfterDays}`); } if (props.publicKey?.length && props.publicKeyFormat !== undefined && props.publicKeyFormat !== PublicKeyFormat.OPENSSH) { aws_cdk_lib_1.Annotations.of(this).addError('When importing a key, the format has to be of type OpenSSH'); } const stack = aws_cdk_lib_1.Stack.of(this).stackName; this.lambda = this.ensureLambda(); this.tags = new aws_cdk_lib_1.TagManager(aws_cdk_lib_1.TagType.MAP, 'Custom::EC2-Key-Pair'); this.tags.setTag(createdByTag, ID); const kmsPrivate = props.kmsPrivateKey || props.kms; const kmsPublic = props.kmsPublicKey || props.kms; const key = new aws_cdk_lib_1.CustomResource(this, `EC2-Key-Pair-${props.name}`, { serviceToken: this.lambda.functionArn, resourceType: resourceType, properties: { Name: props.name, Description: props.description || '', KmsPrivate: kmsPrivate?.keyArn || 'alias/aws/secretsmanager', KmsPublic: kmsPublic?.keyArn || 'alias/aws/secretsmanager', PublicKey: props.publicKey || '', StorePublicKey: props.storePublicKey || false, ExposePublicKey: props.exposePublicKey || false, PublicKeyFormat: props.publicKeyFormat || PublicKeyFormat.OPENSSH, RemoveKeySecretsAfterDays: props.removeKeySecretsAfterDays || 0, SecretPrefix: props.secretPrefix || 'ec2-ssh-key/', StackName: stack, Tags: aws_cdk_lib_1.Lazy.any({ produce: () => this.tags.renderTags(), }), }, }); if (typeof props.kms !== 'undefined') { props.kms.grantEncryptDecrypt(this.lambda.role); key.node.addDependency(props.kms); key.node.addDependency(this.lambda.role); } if (typeof props.kmsPrivateKey !== 'undefined') { props.kmsPrivateKey.grantEncryptDecrypt(this.lambda.role); key.node.addDependency(props.kmsPrivateKey); key.node.addDependency(this.lambda.role); } if (typeof props.kmsPublicKey !== 'undefined') { props.kmsPublicKey.grantEncryptDecrypt(this.lambda.role); key.node.addDependency(props.kmsPublicKey); key.node.addDependency(this.lambda.role); } this.privateKeyArn = key.getAttString('PrivateKeyARN'); this.publicKeyArn = key.getAttString('PublicKeyARN'); this.publicKeyValue = key.getAttString('PublicKeyValue'); this.keyPairName = key.getAttString('KeyPairName'); this.keyPairID = key.getAttString('KeyPairID'); } ensureLambda() { const stack = aws_cdk_lib_1.Stack.of(this); const constructName = 'EC2-Key-Name-Manager-Lambda'; const existing = stack.node.tryFindChild(constructName); if (existing) { return existing; } const resources = [`arn:${stack.partition}:ec2:*:*:key-pair/*`]; const policy = new aws_cdk_lib_1.aws_iam.ManagedPolicy(stack, 'EC2-Key-Pair-Manager-Policy', { description: `Used by Lambda ${cleanID}, which is a custom CFN resource, managing EC2 Key Pairs`, statements: [ new aws_cdk_lib_1.aws_iam.PolicyStatement({ actions: ['ec2:DescribeKeyPairs'], resources: ['*'], }), new aws_cdk_lib_1.aws_iam.PolicyStatement({ actions: [ 'ec2:CreateKeyPair', 'ec2:CreateTags', 'ec2:ImportKeyPair', ], conditions: { StringLike: { 'aws:RequestTag/CreatedByCfnCustomResource': ID, }, }, resources, }), new aws_cdk_lib_1.aws_iam.PolicyStatement({ // allow delete/update, only if createdByTag is set actions: ['ec2:CreateTags', 'ec2:DeleteKeyPair', 'ec2:DeleteTags'], conditions: { StringLike: { 'ec2:ResourceTag/CreatedByCfnCustomResource': ID, }, }, resources, }), new aws_cdk_lib_1.aws_iam.PolicyStatement({ // we need this to check if a secret exists before attempting to delete it actions: ['secretsmanager:ListSecrets'], resources: ['*'], }), new aws_cdk_lib_1.aws_iam.PolicyStatement({ actions: [ 'secretsmanager:CreateSecret', 'secretsmanager:TagResource', ], conditions: { StringLike: { 'aws:RequestTag/CreatedByCfnCustomResource': ID, }, }, resources: ['*'], }), new aws_cdk_lib_1.aws_iam.PolicyStatement({ // allow delete/update, only if createdByTag is set actions: [ 'secretsmanager:DeleteResourcePolicy', 'secretsmanager:DeleteSecret', 'secretsmanager:DescribeSecret', 'secretsmanager:GetResourcePolicy', 'secretsmanager:GetSecretValue', 'secretsmanager:ListSecretVersionIds', 'secretsmanager:PutResourcePolicy', 'secretsmanager:PutSecretValue', 'secretsmanager:RestoreSecret', 'secretsmanager:UntagResource', 'secretsmanager:UpdateSecret', 'secretsmanager:UpdateSecretVersionStage', ], conditions: { StringLike: { 'secretsmanager:ResourceTag/CreatedByCfnCustomResource': ID, }, }, resources: ['*'], }), ], }); const role = new aws_cdk_lib_1.aws_iam.Role(stack, 'EC2-Key-Pair-Manager-Role', { description: `Used by Lambda ${cleanID}, which is a custom CFN resource, managing EC2 Key Pairs`, assumedBy: new aws_cdk_lib_1.aws_iam.ServicePrincipal('lambda.amazonaws.com'), managedPolicies: [ policy, aws_cdk_lib_1.aws_iam.ManagedPolicy.fromAwsManagedPolicyName('service-role/AWSLambdaBasicExecutionRole'), ], }); const fn = new aws_cdk_lib_1.aws_lambda.Function(stack, constructName, { role, description: `${this.prefix}-${cleanID} Custom CFN resource: Manage EC2 Key Pairs`, runtime: aws_cdk_lib_1.aws_lambda.Runtime.NODEJS_18_X, handler: 'index.handler', code: aws_cdk_lib_1.aws_lambda.Code.fromAsset(path.join(__dirname, '../lambda/code.zip')), timeout: aws_cdk_lib_1.Duration.minutes(lambdaTimeout), }); return fn; } /** * Grants read access to the private key in AWS Secrets Manager */ grantReadOnPrivateKey(grantee) { return this.grantRead(this.privateKeyArn, grantee); } /** * Grants read access to the public key in AWS Secrets Manager */ grantReadOnPublicKey(grantee) { return this.grantRead(this.publicKeyArn, grantee); } grantRead(arn, grantee) { const result = aws_cdk_lib_1.aws_iam.Grant.addToPrincipal({ grantee, actions: [ 'secretsmanager:DescribeSecret', 'secretsmanager:GetResourcePolicy', 'secretsmanager:GetSecretValue', 'secretsmanager:ListSecretVersionIds', ], resourceArns: [arn], scope: this, }); return result; } } exports.KeyPair = KeyPair; _a = JSII_RTTI_SYMBOL_1; KeyPair[_a] = { fqn: "cdk-ec2-key-pair.KeyPair", version: "0.0.0" }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJpbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLDZDQWFxQjtBQUNyQiwyQ0FBdUM7QUFDdkMsNkJBQTZCO0FBRTdCLE1BQU0sWUFBWSxHQUFHLHNCQUFzQixDQUFDO0FBQzVDLE1BQU0sRUFBRSxHQUFHLGtCQUFrQixZQUFZLEVBQUUsQ0FBQztBQUM1QyxNQUFNLFlBQVksR0FBRyw0QkFBNEIsQ0FBQztBQUNsRCxNQUFNLE9BQU8sR0FBRyxFQUFFLENBQUMsT0FBTyxDQUFDLEtBQUssRUFBRSxHQUFHLENBQUMsQ0FBQztBQUN2QyxNQUFNLGFBQWEsR0FBRyxDQUFDLENBQUMsQ0FBQyxVQUFVO0FBRW5DLElBQVksZUFHWDtBQUhELFdBQVksZUFBZTtJQUN6QixzQ0FBbUIsQ0FBQTtJQUNuQiw4QkFBVyxDQUFBO0FBQ2IsQ0FBQyxFQUhXLGVBQWUsK0JBQWYsZUFBZSxRQUcxQjtBQTRHRDs7R0FFRztBQUNILE1BQWEsT0FBUSxTQUFRLHNCQUFTO0lBd0NwQzs7T0FFRztJQUNILFlBQVksS0FBZ0IsRUFBRSxFQUFVLEVBQUUsS0FBbUI7UUFDM0QsS0FBSyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQztRQXRDbkI7O1dBRUc7UUFDYSxrQkFBYSxHQUFXLEVBQUUsQ0FBQztRQUUzQzs7V0FFRztRQUNhLGlCQUFZLEdBQVcsRUFBRSxDQUFDO1FBRTFDOzs7O1dBSUc7UUFDYSxtQkFBYyxHQUFXLEVBQUUsQ0FBQztRQUU1Qzs7V0FFRztRQUNhLGdCQUFXLEdBQVcsRUFBRSxDQUFDO1FBRXpDOztXQUVHO1FBQ2EsY0FBUyxHQUFXLEVBQUUsQ0FBQztRQU92QixXQUFNLEdBQVcsRUFBRSxDQUFDO1FBUWxDLElBQ0UsS0FBSyxDQUFDLHlCQUF5QjtZQUMvQixDQUFDLEtBQUssQ0FBQyx5QkFBeUIsR0FBRyxDQUFDO2dCQUNsQyxDQUFDLEtBQUssQ0FBQyx5QkFBeUIsR0FBRyxDQUFDO29CQUNsQyxLQUFLLENBQUMseUJBQXlCLEdBQUcsQ0FBQyxDQUFDO2dCQUN0QyxLQUFLLENBQUMseUJBQXlCLEdBQUcsRUFBRSxDQUFDLEVBQ3ZDO1lBQ0EseUJBQVcsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUMsUUFBUSxDQUMzQiwwRUFBMEUsS0FBSyxDQUFDLHlCQUF5QixFQUFFLENBQzVHLENBQUM7U0FDSDtRQUVELElBQ0UsS0FBSyxDQUFDLFNBQVMsRUFBRSxNQUFNO1lBQ3ZCLEtBQUssQ0FBQyxlQUFlLEtBQUssU0FBUztZQUNuQyxLQUFLLENBQUMsZUFBZSxLQUFLLGVBQWUsQ0FBQyxPQUFPLEVBQ2pEO1lBQ0EseUJBQVcsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUMsUUFBUSxDQUMzQiw0REFBNEQsQ0FDN0QsQ0FBQztTQUNIO1FBRUQsTUFBTSxLQUFLLEdBQUcsbUJBQUssQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUMsU0FBUyxDQUFDO1FBQ3ZDLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1FBRWxDLElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSx3QkFBVSxDQUFDLHFCQUFPLENBQUMsR0FBRyxFQUFFLHNCQUFzQixDQUFDLENBQUM7UUFDaEUsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsWUFBWSxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBRW5DLE1BQU0sVUFBVSxHQUFHLEtBQUssQ0FBQyxhQUFhLElBQUksS0FBSyxDQUFDLEdBQUcsQ0FBQztRQUNwRCxNQUFNLFNBQVMsR0FBRyxLQUFLLENBQUMsWUFBWSxJQUFJLEtBQUssQ0FBQyxHQUFHLENBQUM7UUFFbEQsTUFBTSxHQUFHLEdBQUcsSUFBSSw0QkFBYyxDQUFDLElBQUksRUFBRSxnQkFBZ0IsS0FBSyxDQUFDLElBQUksRUFBRSxFQUFFO1lBQ2pFLFlBQVksRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLFdBQVc7WUFDckMsWUFBWSxFQUFFLFlBQVk7WUFDMUIsVUFBVSxFQUFFO2dCQUNWLElBQUksRUFBRSxLQUFLLENBQUMsSUFBSTtnQkFDaEIsV0FBVyxFQUFFLEtBQUssQ0FBQyxXQUFXLElBQUksRUFBRTtnQkFDcEMsVUFBVSxFQUFFLFVBQVUsRUFBRSxNQUFNLElBQUksMEJBQTBCO2dCQUM1RCxTQUFTLEVBQUUsU0FBUyxFQUFFLE1BQU0sSUFBSSwwQkFBMEI7Z0JBQzFELFNBQVMsRUFBRSxLQUFLLENBQUMsU0FBUyxJQUFJLEVBQUU7Z0JBQ2hDLGNBQWMsRUFBRSxLQUFLLENBQUMsY0FBYyxJQUFJLEtBQUs7Z0JBQzdDLGVBQWUsRUFBRSxLQUFLLENBQUMsZUFBZSxJQUFJLEtBQUs7Z0JBQy9DLGVBQWUsRUFBRSxLQUFLLENBQUMsZUFBZSxJQUFJLGVBQWUsQ0FBQyxPQUFPO2dCQUNqRSx5QkFBeUIsRUFBRSxLQUFLLENBQUMseUJBQXlCLElBQUksQ0FBQztnQkFDL0QsWUFBWSxFQUFFLEtBQUssQ0FBQyxZQUFZLElBQUksY0FBYztnQkFDbEQsU0FBUyxFQUFFLEtBQUs7Z0JBQ2hCLElBQUksRUFBRSxrQkFBSSxDQUFDLEdBQUcsQ0FBQztvQkFDYixPQUFPLEVBQUUsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLEVBQUU7aUJBQ3RDLENBQUM7YUFDSDtTQUNGLENBQUMsQ0FBQztRQUVILElBQUksT0FBTyxLQUFLLENBQUMsR0FBRyxLQUFLLFdBQVcsRUFBRTtZQUNwQyxLQUFLLENBQUMsR0FBRyxDQUFDLG1CQUFtQixDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSyxDQUFDLENBQUM7WUFDakQsR0FBRyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ2xDLEdBQUcsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSyxDQUFDLENBQUM7U0FDM0M7UUFFRCxJQUFJLE9BQU8sS0FBSyxDQUFDLGFBQWEsS0FBSyxXQUFXLEVBQUU7WUFDOUMsS0FBSyxDQUFDLGFBQWEsQ0FBQyxtQkFBbUIsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUssQ0FBQyxDQUFDO1lBQzNELEdBQUcsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQyxhQUFhLENBQUMsQ0FBQztZQUM1QyxHQUFHLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUssQ0FBQyxDQUFDO1NBQzNDO1FBRUQsSUFBSSxPQUFPLEtBQUssQ0FBQyxZQUFZLEtBQUssV0FBVyxFQUFFO1lBQzdDLEtBQUssQ0FBQyxZQUFZLENBQUMsbUJBQW1CLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFLLENBQUMsQ0FBQztZQUMxRCxHQUFHLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLENBQUM7WUFDM0MsR0FBRyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFLLENBQUMsQ0FBQztTQUMzQztRQUVELElBQUksQ0FBQyxhQUFhLEdBQUcsR0FBRyxDQUFDLFlBQVksQ0FBQyxlQUFlLENBQUMsQ0FBQztRQUN2RCxJQUFJLENBQUMsWUFBWSxHQUFHLEdBQUcsQ0FBQyxZQUFZLENBQUMsY0FBYyxDQUFDLENBQUM7UUFDckQsSUFBSSxDQUFDLGNBQWMsR0FBRyxHQUFHLENBQUMsWUFBWSxDQUFDLGdCQUFnQixDQUFDLENBQUM7UUFDekQsSUFBSSxDQUFDLFdBQVcsR0FBRyxHQUFHLENBQUMsWUFBWSxDQUFDLGFBQWEsQ0FBQyxDQUFDO1FBQ25ELElBQUksQ0FBQyxTQUFTLEdBQUcsR0FBRyxDQUFDLFlBQVksQ0FBQyxXQUFXLENBQUMsQ0FBQztJQUNqRCxDQUFDO0lBRU8sWUFBWTtRQUNsQixNQUFNLEtBQUssR0FBRyxtQkFBSyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUM3QixNQUFNLGFBQWEsR0FBRyw2QkFBNkIsQ0FBQztRQUNwRCxNQUFNLFFBQVEsR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxhQUFhLENBQUMsQ0FBQztRQUN4RCxJQUFJLFFBQVEsRUFBRTtZQUNaLE9BQU8sUUFBK0IsQ0FBQztTQUN4QztRQUVELE1BQU0sU0FBUyxHQUFHLENBQUMsT0FBTyxLQUFLLENBQUMsU0FBUyxxQkFBcUIsQ0FBQyxDQUFDO1FBRWhFLE1BQU0sTUFBTSxHQUFHLElBQUkscUJBQU8sQ0FBQyxhQUFhLENBQ3RDLEtBQUssRUFDTCw2QkFBNkIsRUFDN0I7WUFDRSxXQUFXLEVBQUUsa0JBQWtCLE9BQU8sMERBQTBEO1lBQ2hHLFVBQVUsRUFBRTtnQkFDVixJQUFJLHFCQUFPLENBQUMsZUFBZSxDQUFDO29CQUMxQixPQUFPLEVBQUUsQ0FBQyxzQkFBc0IsQ0FBQztvQkFDakMsU0FBUyxFQUFFLENBQUMsR0FBRyxDQUFDO2lCQUNqQixDQUFDO2dCQUNGLElBQUkscUJBQU8sQ0FBQyxlQUFlLENBQUM7b0JBQzFCLE9BQU8sRUFBRTt3QkFDUCxtQkFBbUI7d0JBQ25CLGdCQUFnQjt3QkFDaEIsbUJBQW1CO3FCQUNwQjtvQkFDRCxVQUFVLEVBQUU7d0JBQ1YsVUFBVSxFQUFFOzRCQUNWLDJDQUEyQyxFQUFFLEVBQUU7eUJBQ2hEO3FCQUNGO29CQUNELFNBQVM7aUJBQ1YsQ0FBQztnQkFDRixJQUFJLHFCQUFPLENBQUMsZUFBZSxDQUFDO29CQUMxQixtREFBbUQ7b0JBQ25ELE9BQU8sRUFBRSxDQUFDLGdCQUFnQixFQUFFLG1CQUFtQixFQUFFLGdCQUFnQixDQUFDO29CQUNsRSxVQUFVLEVBQUU7d0JBQ1YsVUFBVSxFQUFFOzRCQUNWLDRDQUE0QyxFQUFFLEVBQUU7eUJBQ2pEO3FCQUNGO29CQUNELFNBQVM7aUJBQ1YsQ0FBQztnQkFFRixJQUFJLHFCQUFPLENBQUMsZUFBZSxDQUFDO29CQUMxQiwwRUFBMEU7b0JBQzFFLE9BQU8sRUFBRSxDQUFDLDRCQUE0QixDQUFDO29CQUN2QyxTQUFTLEVBQUUsQ0FBQyxHQUFHLENBQUM7aUJBQ2pCLENBQUM7Z0JBQ0YsSUFBSSxxQkFBTyxDQUFDLGVBQWUsQ0FBQztvQkFDMUIsT0FBTyxFQUFFO3dCQUNQLDZCQUE2Qjt3QkFDN0IsNEJBQTRCO3FCQUM3QjtvQkFDRCxVQUFVLEVBQUU7d0JBQ1YsVUFBVSxFQUFFOzRCQUNWLDJDQUEyQyxFQUFFLEVBQUU7eUJBQ2hEO3FCQUNGO29CQUNELFNBQVMsRUFBRSxDQUFDLEdBQUcsQ0FBQztpQkFDakIsQ0FBQztnQkFDRixJQUFJLHFCQUFPLENBQUMsZUFBZSxDQUFDO29CQUMxQixtREFBbUQ7b0JBQ25ELE9BQU8sRUFBRTt3QkFDUCxxQ0FBcUM7d0JBQ3JDLDZCQUE2Qjt3QkFDN0IsK0JBQStCO3dCQUMvQixrQ0FBa0M7d0JBQ2xDLCtCQUErQjt3QkFDL0IscUNBQXFDO3dCQUNyQyxrQ0FBa0M7d0JBQ2xDLCtCQUErQjt3QkFDL0IsOEJBQThCO3dCQUM5Qiw4QkFBOEI7d0JBQzlCLDZCQUE2Qjt3QkFDN0IseUNBQXlDO3FCQUMxQztvQkFDRCxVQUFVLEVBQUU7d0JBQ1YsVUFBVSxFQUFFOzRCQUNWLHVEQUF1RCxFQUFFLEVBQUU7eUJBQzVEO3FCQUNGO29CQUNELFNBQVMsRUFBRSxDQUFDLEdBQUcsQ0FBQztpQkFDakIsQ0FBQzthQUNIO1NBQ0YsQ0FDRixDQUFDO1FBRUYsTUFBTSxJQUFJLEdBQUcsSUFBSSxxQkFBTyxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsMkJBQTJCLEVBQUU7WUFDaEUsV0FBVyxFQUFFLGtCQUFrQixPQUFPLDBEQUEwRDtZQUNoRyxTQUFTLEVBQUUsSUFBSSxxQkFBTyxDQUFDLGdCQUFnQixDQUFDLHNCQUFzQixDQUFDO1lBQy9ELGVBQWUsRUFBRTtnQkFDZixNQUFNO2dCQUNOLHFCQUFPLENBQUMsYUFBYSxDQUFDLHdCQUF3QixDQUM1QywwQ0FBMEMsQ0FDM0M7YUFDRjtTQUNGLENBQUMsQ0FBQztRQUVILE1BQU0sRUFBRSxHQUFHLElBQUksd0JBQVUsQ0FBQyxRQUFRLENBQUMsS0FBSyxFQUFFLGFBQWEsRUFBRTtZQUN2RCxJQUFJO1lBQ0osV0FBVyxFQUFFLEdBQUcsSUFBSSxDQUFDLE1BQU0sSUFBSSxPQUFPLDRDQUE0QztZQUNsRixPQUFPLEVBQUUsd0JBQVUsQ0FBQyxPQUFPLENBQUMsV0FBVztZQUN2QyxPQUFPLEVBQUUsZUFBZTtZQUN4QixJQUFJLEVBQUUsd0JBQVUsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUM3QixJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxvQkFBb0IsQ0FBQyxDQUMzQztZQUNELE9BQU8sRUFBRSxzQkFBUSxDQUFDLE9BQU8sQ0FBQyxhQUFhLENBQUM7U0FDekMsQ0FBQyxDQUFDO1FBRUgsT0FBTyxFQUFFLENBQUM7SUFDWixDQUFDO0lBRUQ7O09BRUc7SUFDSCxxQkFBcUIsQ0FBQyxPQUEyQjtRQUMvQyxPQUFPLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLGFBQWEsRUFBRSxPQUFPLENBQUMsQ0FBQztJQUNyRCxDQUFDO0lBRUQ7O09BRUc7SUFDSCxvQkFBb0IsQ0FBQyxPQUEyQjtRQUM5QyxPQUFPLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLFlBQVksRUFBRSxPQUFPLENBQUMsQ0FBQztJQUNwRCxDQUFDO0lBRU8sU0FBUyxDQUFDLEdBQVcsRUFBRSxPQUEyQjtRQUN4RCxNQUFNLE1BQU0sR0FBRyxxQkFBTyxDQUFDLEtBQUssQ0FBQyxjQUFjLENBQUM7WUFDMUMsT0FBTztZQUNQLE9BQU8sRUFBRTtnQkFDUCwrQkFBK0I7Z0JBQy9CLGtDQUFrQztnQkFDbEMsK0JBQStCO2dCQUMvQixxQ0FBcUM7YUFDdEM7WUFDRCxZQUFZLEVBQUUsQ0FBQyxHQUFHLENBQUM7WUFDbkIsS0FBSyxFQUFFLElBQUk7U0FDWixDQUFDLENBQUM7UUFDSCxPQUFPLE1BQU0sQ0FBQztJQUNoQixDQUFDOztBQXZRSCwwQkF3UUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBBbm5vdGF0aW9ucyxcbiAgYXdzX2lhbSxcbiAgYXdzX2ttcyxcbiAgYXdzX2xhbWJkYSxcbiAgQ3VzdG9tUmVzb3VyY2UsXG4gIER1cmF0aW9uLFxuICBJVGFnZ2FibGUsXG4gIExhenksXG4gIFJlc291cmNlUHJvcHMsXG4gIFN0YWNrLFxuICBUYWdNYW5hZ2VyLFxuICBUYWdUeXBlLFxufSBmcm9tICdhd3MtY2RrLWxpYic7XG5pbXBvcnQgeyBDb25zdHJ1Y3QgfSBmcm9tICdjb25zdHJ1Y3RzJztcbmltcG9ydCAqIGFzIHBhdGggZnJvbSAncGF0aCc7XG5cbmNvbnN0IHJlc291cmNlVHlwZSA9ICdDdXN0b206OkVDMi1LZXktUGFpcic7XG5jb25zdCBJRCA9IGBDRk46OlJlc291cmNlOjoke3Jlc291cmNlVHlwZX1gO1xuY29uc3QgY3JlYXRlZEJ5VGFnID0gJ0NyZWF0ZWRCeUNmbkN1c3RvbVJlc291cmNlJztcbmNvbnN0IGNsZWFuSUQgPSBJRC5yZXBsYWNlKC86Ky9nLCAnLScpO1xuY29uc3QgbGFtYmRhVGltZW91dCA9IDM7IC8vIG1pbnV0ZXNcblxuZXhwb3J0IGVudW0gUHVibGljS2V5Rm9ybWF0IHtcbiAgT1BFTlNTSCA9ICdPUEVOU1NIJyxcbiAgUEVNID0gJ1BFTScsXG59XG5cbi8qKlxuICogRGVmaW5pdGlvbiBvZiBFQzIgS2V5IFBhaXJcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBLZXlQYWlyUHJvcHMgZXh0ZW5kcyBSZXNvdXJjZVByb3BzIHtcbiAgLyoqXG4gICAqIE5hbWUgb2YgdGhlIEtleSBQYWlyXG4gICAqXG4gICAqIEluIEFXUyBTZWNyZXRzIE1hbmFnZXIgdGhlIGtleSB3aWxsIGJlIHByZWZpeGVkIHdpdGggYGVjMi1zc2gta2V5L2AuXG4gICAqXG4gICAqIFRoZSBuYW1lIGNhbiBiZSB1cCB0byAyNTUgY2hhcmFjdGVycyBsb25nLiBWYWxpZCBjaGFyYWN0ZXJzIGluY2x1ZGUgXywgLSwgYS16LCBBLVosIGFuZCAwLTkuXG4gICAqL1xuICByZWFkb25seSBuYW1lOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBkZXNjcmlwdGlvbiBmb3IgdGhlIGtleSBpbiBBV1MgU2VjcmV0cyBNYW5hZ2VyXG4gICAqIEBkZWZhdWx0IC0gJydcbiAgICovXG4gIHJlYWRvbmx5IGRlc2NyaXB0aW9uPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgS01TIGtleSB1c2VkIHRvIGVuY3J5cHQgdGhlIFNlY3JldHMgTWFuYWdlciBzZWNyZXRzIHdpdGhcbiAgICpcbiAgICogVGhpcyBuZWVkcyB0byBiZSBhIGtleSBjcmVhdGVkIGluIHRoZSBzYW1lIHN0YWNrLiBZb3UgY2Fubm90IHVzZSBhIGtleSBpbXBvcnRlZCB2aWEgQVJOLCBiZWNhdXNlIHRoZSBrZXlzIGFjY2VzcyBwb2xpY3kgd2lsbCBuZWVkIHRvIGJlIG1vZGlmaWVkLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIGBhbGlhcy9hd3Mvc2VjcmV0c21hbmFnZXJgXG4gICAqL1xuICByZWFkb25seSBrbXM/OiBhd3Nfa21zLktleTtcblxuICAvKipcbiAgICogVGhlIEtNUyBrZXkgdG8gdXNlIHRvIGVuY3J5cHQgdGhlIHByaXZhdGUga2V5IHdpdGhcbiAgICpcbiAgICogVGhpcyBuZWVkcyB0byBiZSBhIGtleSBjcmVhdGVkIGluIHRoZSBzYW1lIHN0YWNrLiBZb3UgY2Fubm90IHVzZSBhIGtleSBpbXBvcnRlZCB2aWEgQVJOLCBiZWNhdXNlIHRoZSBrZXlzIGFjY2VzcyBwb2xpY3kgd2lsbCBuZWVkIHRvIGJlIG1vZGlmaWVkLlxuICAgKlxuICAgKiBJZiBubyB2YWx1ZSBpcyBwcm92aWRlZCwgdGhlIHByb3BlcnR5IGBrbXNgIHdpbGwgYmUgdXNlZCBpbnN0ZWFkLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIGB0aGlzLmttc2BcbiAgICovXG4gIHJlYWRvbmx5IGttc1ByaXZhdGVLZXk/OiBhd3Nfa21zLktleTtcblxuICAvKipcbiAgICogVGhlIEtNUyBrZXkgdG8gdXNlIHRvIGVuY3J5cHQgdGhlIHB1YmxpYyBrZXkgd2l0aFxuICAgKlxuICAgKiBUaGlzIG5lZWRzIHRvIGJlIGEga2V5IGNyZWF0ZWQgaW4gdGhlIHNhbWUgc3RhY2suIFlvdSBjYW5ub3QgdXNlIGEga2V5IGltcG9ydGVkIHZpYSBBUk4sIGJlY2F1c2UgdGhlIGtleXMgYWNjZXNzIHBvbGljeSB3aWxsIG5lZWQgdG8gYmUgbW9kaWZpZWQuXG4gICAqXG4gICAqIElmIG5vIHZhbHVlIGlzIHByb3ZpZGVkLCB0aGUgcHJvcGVydHkgYGttc2Agd2lsbCBiZSB1c2VkIGluc3RlYWQuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gYHRoaXMua21zYFxuICAgKi9cbiAgcmVhZG9ubHkga21zUHVibGljS2V5PzogYXdzX2ttcy5LZXk7XG5cbiAgLyoqXG4gICAqIEltcG9ydCBhIHB1YmxpYyBrZXkgaW5zdGVhZCBvZiBjcmVhdGluZyBpdFxuICAgKlxuICAgKiBJZiBubyBwdWJsaWMga2V5IGlzIHByb3ZpZGVkLCBhIG5ldyBrZXkgcGFpciB3aWxsIGJlIGNyZWF0ZWQuXG4gICAqL1xuICByZWFkb25seSBwdWJsaWNLZXk/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFN0b3JlIHRoZSBwdWJsaWMga2V5IGFzIGEgc2VjcmV0XG4gICAqXG4gICAqIEBkZWZhdWx0IC0gZmFsc2VcbiAgICovXG4gIHJlYWRvbmx5IHN0b3JlUHVibGljS2V5PzogYm9vbGVhbjtcblxuICAvKipcbiAgICogRXhwb3NlIHRoZSBwdWJsaWMga2V5IGFzIHByb3BlcnR5IGBwdWJsaWNLZXlWYWx1ZWBcbiAgICpcbiAgICogQGRlZmF1bHQgLSBmYWxzZVxuICAgKi9cbiAgcmVhZG9ubHkgZXhwb3NlUHVibGljS2V5PzogYm9vbGVhbjtcblxuICAvKipcbiAgICogRm9ybWF0IGZvciBwdWJsaWMga2V5LlxuICAgKlxuICAgKiBSZWxldmFudCBvbmx5IGlmIHRoZSBwdWJsaWMga2V5IGlzIHN0b3JlZCBhbmQvb3IgZXhwb3NlZC5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBPUEVOU1NIXG4gICAqL1xuICByZWFkb25seSBwdWJsaWNLZXlGb3JtYXQ/OiBQdWJsaWNLZXlGb3JtYXQ7XG5cbiAgLyoqXG4gICAqIFdoZW4gdGhlIHJlc291cmNlIGlzIGRlc3Ryb3llZCwgYWZ0ZXIgaG93IG1hbnkgZGF5cyB0aGUgcHJpdmF0ZSBhbmQgcHVibGljIGtleSBpbiB0aGUgQVdTIFNlY3JldHMgTWFuYWdlciBzaG91bGQgYmUgZGVsZXRlZC5cbiAgICpcbiAgICogVmFsaWQgdmFsdWVzIGFyZSAwIGFuZCA3IHRvIDMwXG4gICAqXG4gICAqIEBkZWZhdWx0IDBcbiAgICovXG4gIHJlYWRvbmx5IHJlbW92ZUtleVNlY3JldHNBZnRlckRheXM/OiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIFByZWZpeCBmb3IgdGhlIHNlY3JldCBpbiBBV1MgU2VjcmV0cyBNYW5hZ2VyLlxuICAgKlxuICAgKiBAZGVmYXVsdCBgZWMyLXNzaC1rZXkvYFxuICAgKi9cbiAgcmVhZG9ubHkgc2VjcmV0UHJlZml4Pzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBBIHByZWZpeCBmb3IgYWxsIHJlc291cmNlIG5hbWVzLlxuICAgKlxuICAgKiBCeSBkZWZhdWx0IGFsbCByZXNvdXJjZXMgYXJlIHByZWZpeGVkIHdpdGggdGhlIHN0YWNrIG5hbWUgdG8gYXZvaWQgY29sbGlzaW9ucyB3aXRoIG90aGVyIHN0YWNrcy4gVGhpcyBtaWdodCBjYXVzZSBwcm9ibGVtcyB3aGVuIHlvdSB3b3JrIHdpdGggbG9uZyBzdGFjayBuYW1lcyBhbmQgY2FuIGJlIG92ZXJyaWRkZW4gdGhyb3VnaCB0aGlzIHBhcmFtZXRlci5cbiAgICpcbiAgICogQGRlZmF1bHQgTmFtZSBvZiB0aGUgc3RhY2tcbiAgICovXG4gIHJlYWRvbmx5IHJlc291cmNlUHJlZml4Pzogc3RyaW5nO1xufVxuXG4vKipcbiAqIEFuIEVDMiBLZXkgUGFpclxuICovXG5leHBvcnQgY2xhc3MgS2V5UGFpciBleHRlbmRzIENvbnN0cnVjdCBpbXBsZW1lbnRzIElUYWdnYWJsZSB7XG4gIC8qKlxuICAgKiBUaGUgbGFtYmRhIGZ1bmN0aW9uIHRoYXQgaXMgY3JlYXRlZFxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IGxhbWJkYTogYXdzX2xhbWJkYS5JRnVuY3Rpb247XG5cbiAgLyoqXG4gICAqIEFSTiBvZiB0aGUgcHJpdmF0ZSBrZXkgaW4gQVdTIFNlY3JldHMgTWFuYWdlclxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IHByaXZhdGVLZXlBcm46IHN0cmluZyA9ICcnO1xuXG4gIC8qKlxuICAgKiBBUk4gb2YgdGhlIHB1YmxpYyBrZXkgaW4gQVdTIFNlY3JldHMgTWFuYWdlclxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IHB1YmxpY0tleUFybjogc3RyaW5nID0gJyc7XG5cbiAgLyoqXG4gICAqIFRoZSBwdWJsaWMga2V5LlxuICAgKlxuICAgKiBPbmx5IGZpbGxlZCwgd2hlbiBgZXhwb3NlUHVibGljS2V5ID0gdHJ1ZWBcbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBwdWJsaWNLZXlWYWx1ZTogc3RyaW5nID0gJyc7XG5cbiAgLyoqXG4gICAqIE5hbWUgb2YgdGhlIEtleSBQYWlyXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkga2V5UGFpck5hbWU6IHN0cmluZyA9ICcnO1xuXG4gIC8qKlxuICAgKiBJRCBvZiB0aGUgS2V5IFBhaXJcbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBrZXlQYWlySUQ6IHN0cmluZyA9ICcnO1xuXG4gIC8qKlxuICAgKiBSZXNvdXJjZSB0YWdzXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgdGFnczogVGFnTWFuYWdlcjtcblxuICBwdWJsaWMgcmVhZG9ubHkgcHJlZml4OiBzdHJpbmcgPSAnJztcblxuICAvKipcbiAgICogRGVmaW5lcyBhIG5ldyBFQzIgS2V5IFBhaXIuIFRoZSBwcml2YXRlIGtleSB3aWxsIGJlIHN0b3JlZCBpbiBBV1MgU2VjcmV0cyBNYW5hZ2VyXG4gICAqL1xuICBjb25zdHJ1Y3RvcihzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogS2V5UGFpclByb3BzKSB7XG4gICAgc3VwZXIoc2NvcGUsIGlkKTtcblxuICAgIGlmIChcbiAgICAgIHByb3BzLnJlbW92ZUtleVNlY3JldHNBZnRlckRheXMgJiZcbiAgICAgIChwcm9wcy5yZW1vdmVLZXlTZWNyZXRzQWZ0ZXJEYXlzIDwgMCB8fFxuICAgICAgICAocHJvcHMucmVtb3ZlS2V5U2VjcmV0c0FmdGVyRGF5cyA+IDAgJiZcbiAgICAgICAgICBwcm9wcy5yZW1vdmVLZXlTZWNyZXRzQWZ0ZXJEYXlzIDwgNykgfHxcbiAgICAgICAgcHJvcHMucmVtb3ZlS2V5U2VjcmV0c0FmdGVyRGF5cyA+IDMwKVxuICAgICkge1xuICAgICAgQW5ub3RhdGlvbnMub2YodGhpcykuYWRkRXJyb3IoXG4gICAgICAgIGBQYXJhbWV0ZXIgcmVtb3ZlS2V5U2VjcmV0c0FmdGVyRGF5cyBtdXN0IGJlIDAgb3IgYmV0d2VlbiA3IGFuZCAzMC4gR290ICR7cHJvcHMucmVtb3ZlS2V5U2VjcmV0c0FmdGVyRGF5c31gXG4gICAgICApO1xuICAgIH1cblxuICAgIGlmIChcbiAgICAgIHByb3BzLnB1YmxpY0tleT8ubGVuZ3RoICYmXG4gICAgICBwcm9wcy5wdWJsaWNLZXlGb3JtYXQgIT09IHVuZGVmaW5lZCAmJlxuICAgICAgcHJvcHMucHVibGljS2V5Rm9ybWF0ICE9PSBQdWJsaWNLZXlGb3JtYXQuT1BFTlNTSFxuICAgICkge1xuICAgICAgQW5ub3RhdGlvbnMub2YodGhpcykuYWRkRXJyb3IoXG4gICAgICAgICdXaGVuIGltcG9ydGluZyBhIGtleSwgdGhlIGZvcm1hdCBoYXMgdG8gYmUgb2YgdHlwZSBPcGVuU1NIJ1xuICAgICAgKTtcbiAgICB9XG5cbiAgICBjb25zdCBzdGFjayA9IFN0YWNrLm9mKHRoaXMpLnN0YWNrTmFtZTtcbiAgICB0aGlzLmxhbWJkYSA9IHRoaXMuZW5zdXJlTGFtYmRhKCk7XG5cbiAgICB0aGlzLnRhZ3MgPSBuZXcgVGFnTWFuYWdlcihUYWdUeXBlLk1BUCwgJ0N1c3RvbTo6RUMyLUtleS1QYWlyJyk7XG4gICAgdGhpcy50YWdzLnNldFRhZyhjcmVhdGVkQnlUYWcsIElEKTtcblxuICAgIGNvbnN0IGttc1ByaXZhdGUgPSBwcm9wcy5rbXNQcml2YXRlS2V5IHx8IHByb3BzLmttcztcbiAgICBjb25zdCBrbXNQdWJsaWMgPSBwcm9wcy5rbXNQdWJsaWNLZXkgfHwgcHJvcHMua21zO1xuXG4gICAgY29uc3Qga2V5ID0gbmV3IEN1c3RvbVJlc291cmNlKHRoaXMsIGBFQzItS2V5LVBhaXItJHtwcm9wcy5uYW1lfWAsIHtcbiAgICAgIHNlcnZpY2VUb2tlbjogdGhpcy5sYW1iZGEuZnVuY3Rpb25Bcm4sXG4gICAgICByZXNvdXJjZVR5cGU6IHJlc291cmNlVHlwZSxcbiAgICAgIHByb3BlcnRpZXM6IHtcbiAgICAgICAgTmFtZTogcHJvcHMubmFtZSxcbiAgICAgICAgRGVzY3JpcHRpb246IHByb3BzLmRlc2NyaXB0aW9uIHx8ICcnLFxuICAgICAgICBLbXNQcml2YXRlOiBrbXNQcml2YXRlPy5rZXlBcm4gfHwgJ2FsaWFzL2F3cy9zZWNyZXRzbWFuYWdlcicsXG4gICAgICAgIEttc1B1YmxpYzoga21zUHVibGljPy5rZXlBcm4gfHwgJ2FsaWFzL2F3cy9zZWNyZXRzbWFuYWdlcicsXG4gICAgICAgIFB1YmxpY0tleTogcHJvcHMucHVibGljS2V5IHx8ICcnLFxuICAgICAgICBTdG9yZVB1YmxpY0tleTogcHJvcHMuc3RvcmVQdWJsaWNLZXkgfHwgZmFsc2UsXG4gICAgICAgIEV4cG9zZVB1YmxpY0tleTogcHJvcHMuZXhwb3NlUHVibGljS2V5IHx8IGZhbHNlLFxuICAgICAgICBQdWJsaWNLZXlGb3JtYXQ6IHByb3BzLnB1YmxpY0tleUZvcm1hdCB8fCBQdWJsaWNLZXlGb3JtYXQuT1BFTlNTSCxcbiAgICAgICAgUmVtb3ZlS2V5U2VjcmV0c0FmdGVyRGF5czogcHJvcHMucmVtb3ZlS2V5U2VjcmV0c0FmdGVyRGF5cyB8fCAwLFxuICAgICAgICBTZWNyZXRQcmVmaXg6IHByb3BzLnNlY3JldFByZWZpeCB8fCAnZWMyLXNzaC1rZXkvJyxcbiAgICAgICAgU3RhY2tOYW1lOiBzdGFjayxcbiAgICAgICAgVGFnczogTGF6eS5hbnkoe1xuICAgICAgICAgIHByb2R1Y2U6ICgpID0+IHRoaXMudGFncy5yZW5kZXJUYWdzKCksXG4gICAgICAgIH0pLFxuICAgICAgfSxcbiAgICB9KTtcblxuICAgIGlmICh0eXBlb2YgcHJvcHMua21zICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgcHJvcHMua21zLmdyYW50RW5jcnlwdERlY3J5cHQodGhpcy5sYW1iZGEucm9sZSEpO1xuICAgICAga2V5Lm5vZGUuYWRkRGVwZW5kZW5jeShwcm9wcy5rbXMpO1xuICAgICAga2V5Lm5vZGUuYWRkRGVwZW5kZW5jeSh0aGlzLmxhbWJkYS5yb2xlISk7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBwcm9wcy5rbXNQcml2YXRlS2V5ICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgcHJvcHMua21zUHJpdmF0ZUtleS5ncmFudEVuY3J5cHREZWNyeXB0KHRoaXMubGFtYmRhLnJvbGUhKTtcbiAgICAgIGtleS5ub2RlLmFkZERlcGVuZGVuY3kocHJvcHMua21zUHJpdmF0ZUtleSk7XG4gICAgICBrZXkubm9kZS5hZGREZXBlbmRlbmN5KHRoaXMubGFtYmRhLnJvbGUhKTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIHByb3BzLmttc1B1YmxpY0tleSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHByb3BzLmttc1B1YmxpY0tleS5ncmFudEVuY3J5cHREZWNyeXB0KHRoaXMubGFtYmRhLnJvbGUhKTtcbiAgICAgIGtleS5ub2RlLmFkZERlcGVuZGVuY3kocHJvcHMua21zUHVibGljS2V5KTtcbiAgICAgIGtleS5ub2RlLmFkZERlcGVuZGVuY3kodGhpcy5sYW1iZGEucm9sZSEpO1xuICAgIH1cblxuICAgIHRoaXMucHJpdmF0ZUtleUFybiA9IGtleS5nZXRBdHRTdHJpbmcoJ1ByaXZhdGVLZXlBUk4nKTtcbiAgICB0aGlzLnB1YmxpY0tleUFybiA9IGtleS5nZXRBdHRTdHJpbmcoJ1B1YmxpY0tleUFSTicpO1xuICAgIHRoaXMucHVibGljS2V5VmFsdWUgPSBrZXkuZ2V0QXR0U3RyaW5nKCdQdWJsaWNLZXlWYWx1ZScpO1xuICAgIHRoaXMua2V5UGFpck5hbWUgPSBrZXkuZ2V0QXR0U3RyaW5nKCdLZXlQYWlyTmFtZScpO1xuICAgIHRoaXMua2V5UGFpcklEID0ga2V5LmdldEF0dFN0cmluZygnS2V5UGFpcklEJyk7XG4gIH1cblxuICBwcml2YXRlIGVuc3VyZUxhbWJkYSgpOiBhd3NfbGFtYmRhLkZ1bmN0aW9uIHtcbiAgICBjb25zdCBzdGFjayA9IFN0YWNrLm9mKHRoaXMpO1xuICAgIGNvbnN0IGNvbnN0cnVjdE5hbWUgPSAnRUMyLUtleS1OYW1lLU1hbmFnZXItTGFtYmRhJztcbiAgICBjb25zdCBleGlzdGluZyA9IHN0YWNrLm5vZGUudHJ5RmluZENoaWxkKGNvbnN0cnVjdE5hbWUpO1xuICAgIGlmIChleGlzdGluZykge1xuICAgICAgcmV0dXJuIGV4aXN0aW5nIGFzIGF3c19sYW1iZGEuRnVuY3Rpb247XG4gICAgfVxuXG4gICAgY29uc3QgcmVzb3VyY2VzID0gW2Bhcm46JHtzdGFjay5wYXJ0aXRpb259OmVjMjoqOio6a2V5LXBhaXIvKmBdO1xuXG4gICAgY29uc3QgcG9saWN5ID0gbmV3IGF3c19pYW0uTWFuYWdlZFBvbGljeShcbiAgICAgIHN0YWNrLFxuICAgICAgJ0VDMi1LZXktUGFpci1NYW5hZ2VyLVBvbGljeScsXG4gICAgICB7XG4gICAgICAgIGRlc2NyaXB0aW9uOiBgVXNlZCBieSBMYW1iZGEgJHtjbGVhbklEfSwgd2hpY2ggaXMgYSBjdXN0b20gQ0ZOIHJlc291cmNlLCBtYW5hZ2luZyBFQzIgS2V5IFBhaXJzYCxcbiAgICAgICAgc3RhdGVtZW50czogW1xuICAgICAgICAgIG5ldyBhd3NfaWFtLlBvbGljeVN0YXRlbWVudCh7XG4gICAgICAgICAgICBhY3Rpb25zOiBbJ2VjMjpEZXNjcmliZUtleVBhaXJzJ10sXG4gICAgICAgICAgICByZXNvdXJjZXM6IFsnKiddLFxuICAgICAgICAgIH0pLFxuICAgICAgICAgIG5ldyBhd3NfaWFtLlBvbGljeVN0YXRlbWVudCh7XG4gICAgICAgICAgICBhY3Rpb25zOiBbXG4gICAgICAgICAgICAgICdlYzI6Q3JlYXRlS2V5UGFpcicsXG4gICAgICAgICAgICAgICdlYzI6Q3JlYXRlVGFncycsXG4gICAgICAgICAgICAgICdlYzI6SW1wb3J0S2V5UGFpcicsXG4gICAgICAgICAgICBdLFxuICAgICAgICAgICAgY29uZGl0aW9uczoge1xuICAgICAgICAgICAgICBTdHJpbmdMaWtlOiB7XG4gICAgICAgICAgICAgICAgJ2F3czpSZXF1ZXN0VGFnL0NyZWF0ZWRCeUNmbkN1c3RvbVJlc291cmNlJzogSUQsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgcmVzb3VyY2VzLFxuICAgICAgICAgIH0pLFxuICAgICAgICAgIG5ldyBhd3NfaWFtLlBvbGljeVN0YXRlbWVudCh7XG4gICAgICAgICAgICAvLyBhbGxvdyBkZWxldGUvdXBkYXRlLCBvbmx5IGlmIGNyZWF0ZWRCeVRhZyBpcyBzZXRcbiAgICAgICAgICAgIGFjdGlvbnM6IFsnZWMyOkNyZWF0ZVRhZ3MnLCAnZWMyOkRlbGV0ZUtleVBhaXInLCAnZWMyOkRlbGV0ZVRhZ3MnXSxcbiAgICAgICAgICAgIGNvbmRpdGlvbnM6IHtcbiAgICAgICAgICAgICAgU3RyaW5nTGlrZToge1xuICAgICAgICAgICAgICAgICdlYzI6UmVzb3VyY2VUYWcvQ3JlYXRlZEJ5Q2ZuQ3VzdG9tUmVzb3VyY2UnOiBJRCxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICByZXNvdXJjZXMsXG4gICAgICAgICAgfSksXG5cbiAgICAgICAgICBuZXcgYXdzX2lhbS5Qb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgICAgICAgLy8gd2UgbmVlZCB0aGlzIHRvIGNoZWNrIGlmIGEgc2VjcmV0IGV4aXN0cyBiZWZvcmUgYXR0ZW1wdGluZyB0byBkZWxldGUgaXRcbiAgICAgICAgICAgIGFjdGlvbnM6IFsnc2VjcmV0c21hbmFnZXI6TGlzdFNlY3JldHMnXSxcbiAgICAgICAgICAgIHJlc291cmNlczogWycqJ10sXG4gICAgICAgICAgfSksXG4gICAgICAgICAgbmV3IGF3c19pYW0uUG9saWN5U3RhdGVtZW50KHtcbiAgICAgICAgICAgIGFjdGlvbnM6IFtcbiAgICAgICAgICAgICAgJ3NlY3JldHNtYW5hZ2VyOkNyZWF0ZVNlY3JldCcsXG4gICAgICAgICAgICAgICdzZWNyZXRzbWFuYWdlcjpUYWdSZXNvdXJjZScsXG4gICAgICAgICAgICBdLFxuICAgICAgICAgICAgY29uZGl0aW9uczoge1xuICAgICAgICAgICAgICBTdHJpbmdMaWtlOiB7XG4gICAgICAgICAgICAgICAgJ2F3czpSZXF1ZXN0VGFnL0NyZWF0ZWRCeUNmbkN1c3RvbVJlc291cmNlJzogSUQsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgcmVzb3VyY2VzOiBbJyonXSxcbiAgICAgICAgICB9KSxcbiAgICAgICAgICBuZXcgYXdzX2lhbS5Qb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgICAgICAgLy8gYWxsb3cgZGVsZXRlL3VwZGF0ZSwgb25seSBpZiBjcmVhdGVkQnlUYWcgaXMgc2V0XG4gICAgICAgICAgICBhY3Rpb25zOiBbXG4gICAgICAgICAgICAgICdzZWNyZXRzbWFuYWdlcjpEZWxldGVSZXNvdXJjZVBvbGljeScsXG4gICAgICAgICAgICAgICdzZWNyZXRzbWFuYWdlcjpEZWxldGVTZWNyZXQnLFxuICAgICAgICAgICAgICAnc2VjcmV0c21hbmFnZXI6RGVzY3JpYmVTZWNyZXQnLFxuICAgICAgICAgICAgICAnc2VjcmV0c21hbmFnZXI6R2V0UmVzb3VyY2VQb2xpY3knLFxuICAgICAgICAgICAgICAnc2VjcmV0c21hbmFnZXI6R2V0U2VjcmV0VmFsdWUnLFxuICAgICAgICAgICAgICAnc2VjcmV0c21hbmFnZXI6TGlzdFNlY3JldFZlcnNpb25JZHMnLFxuICAgICAgICAgICAgICAnc2VjcmV0c21hbmFnZXI6UHV0UmVzb3VyY2VQb2xpY3knLFxuICAgICAgICAgICAgICAnc2VjcmV0c21hbmFnZXI6UHV0U2VjcmV0VmFsdWUnLFxuICAgICAgICAgICAgICAnc2VjcmV0c21hbmFnZXI6UmVzdG9yZVNlY3JldCcsXG4gICAgICAgICAgICAgICdzZWNyZXRzbWFuYWdlcjpVbnRhZ1Jlc291cmNlJyxcbiAgICAgICAgICAgICAgJ3NlY3JldHNtYW5hZ2VyOlVwZGF0ZVNlY3JldCcsXG4gICAgICAgICAgICAgICdzZWNyZXRzbWFuYWdlcjpVcGRhdGVTZWNyZXRWZXJzaW9uU3RhZ2UnLFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIGNvbmRpdGlvbnM6IHtcbiAgICAgICAgICAgICAgU3RyaW5nTGlrZToge1xuICAgICAgICAgICAgICAgICdzZWNyZXRzbWFuYWdlcjpSZXNvdXJjZVRhZy9DcmVhdGVkQnlDZm5DdXN0b21SZXNvdXJjZSc6IElELFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHJlc291cmNlczogWycqJ10sXG4gICAgICAgICAgfSksXG4gICAgICAgIF0sXG4gICAgICB9XG4gICAgKTtcblxuICAgIGNvbnN0IHJvbGUgPSBuZXcgYXdzX2lhbS5Sb2xlKHN0YWNrLCAnRUMyLUtleS1QYWlyLU1hbmFnZXItUm9sZScsIHtcbiAgICAgIGRlc2NyaXB0aW9uOiBgVXNlZCBieSBMYW1iZGEgJHtjbGVhbklEfSwgd2hpY2ggaXMgYSBjdXN0b20gQ0ZOIHJlc291cmNlLCBtYW5hZ2luZyBFQzIgS2V5IFBhaXJzYCxcbiAgICAgIGFzc3VtZWRCeTogbmV3IGF3c19pYW0uU2VydmljZVByaW5jaXBhbCgnbGFtYmRhLmFtYXpvbmF3cy5jb20nKSxcbiAgICAgIG1hbmFnZWRQb2xpY2llczogW1xuICAgICAgICBwb2xpY3ksXG4gICAgICAgIGF3c19pYW0uTWFuYWdlZFBvbGljeS5mcm9tQXdzTWFuYWdlZFBvbGljeU5hbWUoXG4gICAgICAgICAgJ3NlcnZpY2Utcm9sZS9BV1NMYW1iZGFCYXNpY0V4ZWN1dGlvblJvbGUnXG4gICAgICAgICksXG4gICAgICBdLFxuICAgIH0pO1xuXG4gICAgY29uc3QgZm4gPSBuZXcgYXdzX2xhbWJkYS5GdW5jdGlvbihzdGFjaywgY29uc3RydWN0TmFtZSwge1xuICAgICAgcm9sZSxcbiAgICAgIGRlc2NyaXB0aW9uOiBgJHt0aGlzLnByZWZpeH0tJHtjbGVhbklEfSBDdXN0b20gQ0ZOIHJlc291cmNlOiBNYW5hZ2UgRUMyIEtleSBQYWlyc2AsXG4gICAgICBydW50aW1lOiBhd3NfbGFtYmRhLlJ1bnRpbWUuTk9ERUpTXzE4X1gsXG4gICAgICBoYW5kbGVyOiAnaW5kZXguaGFuZGxlcicsXG4gICAgICBjb2RlOiBhd3NfbGFtYmRhLkNvZGUuZnJvbUFzc2V0KFxuICAgICAgICBwYXRoLmpvaW4oX19kaXJuYW1lLCAnLi4vbGFtYmRhL2NvZGUuemlwJylcbiAgICAgICksXG4gICAgICB0aW1lb3V0OiBEdXJhdGlvbi5taW51dGVzKGxhbWJkYVRpbWVvdXQpLFxuICAgIH0pO1xuXG4gICAgcmV0dXJuIGZuO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyByZWFkIGFjY2VzcyB0byB0aGUgcHJpdmF0ZSBrZXkgaW4gQVdTIFNlY3JldHMgTWFuYWdlclxuICAgKi9cbiAgZ3JhbnRSZWFkT25Qcml2YXRlS2V5KGdyYW50ZWU6IGF3c19pYW0uSUdyYW50YWJsZSkge1xuICAgIHJldHVybiB0aGlzLmdyYW50UmVhZCh0aGlzLnByaXZhdGVLZXlBcm4sIGdyYW50ZWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyByZWFkIGFjY2VzcyB0byB0aGUgcHVibGljIGtleSBpbiBBV1MgU2VjcmV0cyBNYW5hZ2VyXG4gICAqL1xuICBncmFudFJlYWRPblB1YmxpY0tleShncmFudGVlOiBhd3NfaWFtLklHcmFudGFibGUpIHtcbiAgICByZXR1cm4gdGhpcy5ncmFudFJlYWQodGhpcy5wdWJsaWNLZXlBcm4sIGdyYW50ZWUpO1xuICB9XG5cbiAgcHJpdmF0ZSBncmFudFJlYWQoYXJuOiBzdHJpbmcsIGdyYW50ZWU6IGF3c19pYW0uSUdyYW50YWJsZSkge1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3c19pYW0uR3JhbnQuYWRkVG9QcmluY2lwYWwoe1xuICAgICAgZ3JhbnRlZSxcbiAgICAgIGFjdGlvbnM6IFtcbiAgICAgICAgJ3NlY3JldHNtYW5hZ2VyOkRlc2NyaWJlU2VjcmV0JyxcbiAgICAgICAgJ3NlY3JldHNtYW5hZ2VyOkdldFJlc291cmNlUG9saWN5JyxcbiAgICAgICAgJ3NlY3JldHNtYW5hZ2VyOkdldFNlY3JldFZhbHVlJyxcbiAgICAgICAgJ3NlY3JldHNtYW5hZ2VyOkxpc3RTZWNyZXRWZXJzaW9uSWRzJyxcbiAgICAgIF0sXG4gICAgICByZXNvdXJjZUFybnM6IFthcm5dLFxuICAgICAgc2NvcGU6IHRoaXMsXG4gICAgfSk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxufVxuIl19