UNPKG

aws-delivlib

Version:

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

142 lines • 23.4 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 }); exports.CodeSigningCertificate = void 0; const aws_cdk_lib_1 = require("aws-cdk-lib"); const constructs_1 = require("constructs"); const private_key_1 = require("./private-key"); const permissions = __importStar(require("../permissions")); /** * A Code-Signing certificate, that will use a private key that is generated by a Lambda function. The Certificate will * not be usable until the ``pemCertificate`` value has been provided. A typical workflow to use this Construct would be: * * 1. Add an instance of the construct to your app, without providing the ``pemCertificate`` property * 2. Deploy the stack to provision a Private Key and obtain the CSR (you can surface it using a Output, for example) * 3. Submit the CSR to your Certificate Authority of choice. * 4. Populate the ``pemCertificate`` property with the PEM-encoded certificate provided by your CA of coice. * 5. Re-deploy the stack so make the certificate usable * * In order to renew the certificate, if you do not wish to retain the same private key (your clients do not rely on * public key pinning), simply add a new instance of the construct to your app and follow the process listed above. If * you wish to retain the private key, you can set ``forceCertificateSigningRequest`` to ``true`` in order to obtain a * new CSR document. */ class CodeSigningCertificate extends constructs_1.Construct { constructor(parent, id, props) { super(parent, id); // The construct path of this construct with respect to the containing stack, without any leading / const stack = aws_cdk_lib_1.Stack.of(this); const baseName = props.baseName ?? `${stack.stackName}${this.node.path.substr(stack.node.path.length)}`; const privateKey = new private_key_1.RsaPrivateKeySecret(this, 'RSAPrivateKey', { removalPolicy: props.retainPrivateKey === false ? aws_cdk_lib_1.RemovalPolicy.DESTROY : aws_cdk_lib_1.RemovalPolicy.RETAIN, description: 'The PEM-encoded private key of the x509 Code-Signing Certificate', keySize: props.rsaKeySize || 2048, secretEncryptionKey: props.secretEncryptionKey, // rename the secret name, as since this resource will be deleted and create a new resource, // so the new resource will be created before the old one got deleted, and so we will not be able // to create a new secrete with the same name, and even we could not reuse it, as it will be deleted once // the old resource got deleted. secretName: `${baseName}/RSAPrivateKeyV2`, }); // this change to keep the permissions to access the old secret for the custom resource Lambda function role, so it can // delete the old secret. const oldSecretArnLike = aws_cdk_lib_1.Stack.of(this).formatArn({ service: 'secretsmanager', resource: 'secret', arnFormat: aws_cdk_lib_1.ArnFormat.COLON_RESOURCE_NAME, // The ARN of a secret has "-" followed by 6 random characters appended at the end resourceName: `${baseName}/RSAPrivateKey-??????`, }); privateKey.customResource.addToRolePolicy(new aws_cdk_lib_1.aws_iam.PolicyStatement({ actions: [ 'secretsmanager:CreateSecret', 'secretsmanager:DeleteSecret', 'secretsmanager:UpdateSecret', ], resources: [oldSecretArnLike], })); if (props.secretEncryptionKey) { props.secretEncryptionKey.addToResourcePolicy(new aws_cdk_lib_1.aws_iam.PolicyStatement({ // description: `Allow use via AWS Secrets Manager by CustomResource handler ${customResource.functionName}`, principals: [new aws_cdk_lib_1.aws_iam.ArnPrincipal(privateKey.customResource.role.roleArn)], actions: ['kms:Decrypt', 'kms:GenerateDataKey'], resources: ['*'], conditions: { StringEquals: { 'kms:ViaService': `secretsmanager.${aws_cdk_lib_1.Stack.of(this).region}.amazonaws.com`, }, ArnLike: { 'kms:EncryptionContext:SecretARN': oldSecretArnLike, }, }, })); } this.credential = aws_cdk_lib_1.aws_secretsmanager.Secret.fromSecretAttributes(this, 'Credential', { encryptionKey: props.secretEncryptionKey, secretCompleteArn: privateKey.secretArn, }); let certificate = props.pemCertificate; if (!certificate || props.forceCertificateSigningRequest) { const csr = privateKey.newCertificateSigningRequest('CertificateSigningRequest', props.distinguishedName, 'critical,digitalSignature', 'critical,codeSigning'); this.certificateBucket = csr.outputBucket; new aws_cdk_lib_1.CfnOutput(this, 'CSR', { description: 'A PEM-encoded Certificate Signing Request for a Code-Signing Certificate', value: csr.pemRequest, }); if (!certificate) { certificate = csr.selfSignedPemCertificate; } } this.principal = new aws_cdk_lib_1.aws_ssm.StringParameter(this, 'Resource', { description: `A PEM-encoded Code-Signing Certificate (private key in ${privateKey.secretArn})`, parameterName: `/${baseName}/Certificate`, stringValue: certificate, }); } /** * Grant the IAM principal permissions to read the private key and * certificate. */ grantDecrypt(principal) { if (!principal) { return; } permissions.grantSecretRead({ keyArn: this.credential.encryptionKey && this.credential.encryptionKey.keyArn, secretArn: this.credential.secretArn, }, principal); principal.addToPrincipalPolicy(new aws_cdk_lib_1.aws_iam.PolicyStatement({ actions: ['ssm:GetParameter'], resources: [aws_cdk_lib_1.Stack.of(this).formatArn({ // TODO: This is a workaround until https://github.com/awslabs/aws-cdk/pull/1726 is released service: 'ssm', resource: `parameter${this.principal.parameterName}`, })], })); this.certificateBucket?.grantRead(principal); } } exports.CodeSigningCertificate = CodeSigningCertificate; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29kZS1zaWduaW5nLWNlcnRpZmljYXRlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiY29kZS1zaWduaW5nLWNlcnRpZmljYXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsNkNBUXFCO0FBQ3JCLDJDQUFtRDtBQUVuRCwrQ0FBb0Q7QUFFcEQsNERBQThDO0FBd0U5Qzs7Ozs7Ozs7Ozs7Ozs7R0FjRztBQUNILE1BQWEsc0JBQXVCLFNBQVEsc0JBQVM7SUFnQm5ELFlBQVksTUFBaUIsRUFBRSxFQUFVLEVBQUUsS0FBa0M7UUFDM0UsS0FBSyxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsQ0FBQztRQUVsQixtR0FBbUc7UUFDbkcsTUFBTSxLQUFLLEdBQUcsbUJBQUssQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDN0IsTUFBTSxRQUFRLEdBQUcsS0FBSyxDQUFDLFFBQVEsSUFBSSxHQUFHLEtBQUssQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUM7UUFFeEcsTUFBTSxVQUFVLEdBQUcsSUFBSSxpQ0FBbUIsQ0FBQyxJQUFJLEVBQUUsZUFBZSxFQUFFO1lBQ2hFLGFBQWEsRUFBRSxLQUFLLENBQUMsZ0JBQWdCLEtBQUssS0FBSyxDQUFDLENBQUMsQ0FBQywyQkFBYSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsMkJBQWEsQ0FBQyxNQUFNO1lBQzlGLFdBQVcsRUFBRSxrRUFBa0U7WUFDL0UsT0FBTyxFQUFFLEtBQUssQ0FBQyxVQUFVLElBQUksSUFBSTtZQUNqQyxtQkFBbUIsRUFBRSxLQUFLLENBQUMsbUJBQW1CO1lBQzlDLDRGQUE0RjtZQUM1RixpR0FBaUc7WUFDakcseUdBQXlHO1lBQ3pHLGdDQUFnQztZQUNoQyxVQUFVLEVBQUUsR0FB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O1lBQzFCLE1BQU0sRUFBRSxJQUFJLENBQUMsVUFBVSxDQUFDLGFBQWEsSUFBSSxJQUFJLENBQUMsVUFBVSxDQUFDLGFBQWEsQ0FBQyxNQUFNO1lBQzdFLFNBQVMsRUFBRSxJQUFJLENBQUMsVUFBVSxDQUFDLFNBQVM7U0FDckMsRUFBRSxTQUFTLENBQUMsQ0FBQztRQUVkLFNBQVMsQ0FBQyxvQkFBb0IsQ0FBQyxJQUFJLHFCQUFHLENBQUMsZUFBZSxDQUFDO1lBQ3JELE9BQU8sRUFBRSxDQUFDLGtCQUFrQixDQUFDO1lBQzdCLFNBQVMsRUFBRSxDQUFDLG1CQUFLLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDLFNBQVMsQ0FBQztvQkFDbkMsNEZBQTRGO29CQUM1RixPQUFPLEVBQUUsS0FBSztvQkFDZCxRQUFRLEVBQUUsWUFBWSxJQUFJLENBQUMsU0FBUyxDQUFDLGFBQWEsRUFBRTtpQkFDckQsQ0FBQyxDQUFDO1NBQ0osQ0FBQyxDQUFDLENBQUM7UUFFSixJQUFJLENBQUMsaUJBQWlCLEVBQUUsU0FBUyxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQy9DLENBQUM7Q0FDRjtBQTdIRCx3REE2SEMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBDZm5PdXRwdXQsIFJlbW92YWxQb2xpY3ksIFN0YWNrLFxuICBhd3NfaWFtIGFzIGlhbSxcbiAgYXdzX2ttcyBhcyBrbXMsXG4gIGF3c19zMyBhcyBzMyxcbiAgYXdzX3NlY3JldHNtYW5hZ2VyIGFzIHNlY3JldHNNYW5hZ2VyLFxuICBhd3Nfc3NtIGFzIHNzbSxcbiAgQXJuRm9ybWF0LFxufSBmcm9tICdhd3MtY2RrLWxpYic7XG5pbXBvcnQgeyBDb25zdHJ1Y3QsIElDb25zdHJ1Y3QgfSBmcm9tICdjb25zdHJ1Y3RzJztcbmltcG9ydCB7IENlcnRpZmljYXRlU2lnbmluZ1JlcXVlc3QsIERpc3Rpbmd1aXNoZWROYW1lIH0gZnJvbSAnLi9jZXJ0aWZpY2F0ZS1zaWduaW5nLXJlcXVlc3QnO1xuaW1wb3J0IHsgUnNhUHJpdmF0ZUtleVNlY3JldCB9IGZyb20gJy4vcHJpdmF0ZS1rZXknO1xuaW1wb3J0IHsgSUNyZWRlbnRpYWxQYWlyIH0gZnJvbSAnLi4vY3JlZGVudGlhbC1wYWlyJztcbmltcG9ydCAqIGFzIHBlcm1pc3Npb25zIGZyb20gJy4uL3Blcm1pc3Npb25zJztcblxuXG5leHBvcnQgeyBEaXN0aW5ndWlzaGVkTmFtZSB9IGZyb20gJy4vY2VydGlmaWNhdGUtc2lnbmluZy1yZXF1ZXN0JztcblxuaW50ZXJmYWNlIENvZGVTaWduaW5nQ2VydGlmaWNhdGVQcm9wcyB7XG4gIC8qKlxuICAgKiBUaGUgbnVtYmVyIG9mIGJpdHMgdG8gY29tcG9zZSB0aGUgbW9kdWx1cyBvZiB0aGUgZ2VuZXJhdGVkIHByaXZhdGUga2V5IGZvciB0aGlzIGNlcnRpZmljYXRlLlxuICAgKlxuICAgKiBAZGVmYXVsdCAyMDQ4XG4gICAqL1xuICByc2FLZXlTaXplPzogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBUaGUgS01TIENNSyB0byB1c2UgZm9yIGVuY3J5cHRpbmcgdGhlIFByaXZhdGUgS2V5IHNlY3JldC5cbiAgICogQGRlZmF1bHQgQSBuZXcgS01TIGtleSB3aWxsIGJlIGFsbG9jYXRlZCBmb3IgeW91XG4gICAqL1xuICBzZWNyZXRFbmNyeXB0aW9uS2V5Pzoga21zLklLZXk7XG5cbiAgLyoqXG4gICAqIFRoZSBQRU0tZW5jb2RlZCBjZXJ0aWZpY2F0ZSB0aGF0IHdhcyBzaWduZWQgYnkgdGhlIHJlbGV2YW50IGF1dGhvcml0eS5cbiAgICpcbiAgICogQGRlZmF1bHQgSWYgYSBjZXJ0aWZpY2F0ZSBpcyBub3QgcHJvdmlkZWQsIGEgc2VsZi1zaWduZWQgY2VydGlmaWNhdGUgd2lsbFxuICAgKiBiZSBnZW5lcmF0ZWQgYW5kIGEgQ1NSIChjZXJ0aWZpY2F0ZSBzaWduaW5nIHJlcXVlc3QpIHdpbGwgYnkgYXZhaWxhYmxlIGluXG4gICAqIHRoZSBzdGFjayBvdXRwdXQuXG4gICAqL1xuICBwZW1DZXJ0aWZpY2F0ZT86IHN0cmluZztcblxuICAvKipcbiAgICogV2hldGhlciBhIENTUiBzaG91bGQgYmUgZ2VuZXJhdGVkLCBldmVuIGlmIHRoZSBjZXJ0aWZpY2F0ZSBpcyBwcm92aWRlZC5cbiAgICogVGhpcyBjYW4gYmUgdXNlZnVsIGlmIG9uZSB3YW50cyB0byByZW5ldyBhIGNlcnRpZmljYXRlIHRoYXQgaXMgY2xvc2UgdG9cbiAgICogZXhwaXJ5IHdpdGhvdXQgZ2VuZXJhdGluZyBhIG5ldyBwcml2YXRlIGtleSAoZm9yIGV4YW1wbGUsIHRvIGF2b2lkIGJyZWFraW5nXG4gICAqIGNsaWVudHMgdGhhdCBtYWtlIHVzZSBvZiBjZXJ0aWZpY2F0ZSBwaW5uaW5nKS5cbiAgICpcbiAgICogQGRlZmF1bHQgZmFsc2VcbiAgICovXG4gIGZvcmNlQ2VydGlmaWNhdGVTaWduaW5nUmVxdWVzdD86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIFdoZW4gZW5hYmxlZCwgdGhlIFByaXZhdGUgS2V5IHNlY3JldCB3aWxsIGhhdmUgYSBEZWxldGlvblBvbGljeSBvZlxuICAgKiBcIlJFVEFJTlwiLCBtYWtpbmcgc3VyZSB0aGUgUHJpdmF0ZSBLZXkgaXMgbm90IGluYWR2ZXJ0ZW50bHkgZGVzdHJveWVkLlxuICAgKlxuICAgKiBAZGVmYXVsdCB0cnVlXG4gICAqL1xuICByZXRhaW5Qcml2YXRlS2V5PzogYm9vbGVhbjtcblxuICAvKipcbiAgICogVGhlIERpc3Rpbmd1aXNoZWQgTmFtZSBmb3IgdGhpcyBDU1IuXG4gICAqL1xuICBkaXN0aW5ndWlzaGVkTmFtZTogRGlzdGluZ3Vpc2hlZE5hbWU7XG5cbiAgLyoqXG4gICAqIEJhc2UgbmFtZXMgZm9yIHRoZSBwcml2YXRlIGtleSBhbmQgb3V0cHV0IFNTTSBwYXJhbWV0ZXJcbiAgICpcbiAgICogQGRlZmF1bHQgLSBBdXRvbWF0aWNhbGx5IGdlbmVyYXRlZFxuICAgKi9cbiAgcmVhZG9ubHkgYmFzZU5hbWU/OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSUNvZGVTaWduaW5nQ2VydGlmaWNhdGUgZXh0ZW5kcyBJQ29uc3RydWN0LCBJQ3JlZGVudGlhbFBhaXIge1xuICAvKipcbiAgICogVGhlIFMzIGJ1Y2tldCB3aGVyZSB0aGUgc2VsZi1zaWduZWQgY2VydGlmaWNhdGUgaXMgc3RvcmVkLlxuICAgKi9cbiAgcmVhZG9ubHkgY2VydGlmaWNhdGVCdWNrZXQ/OiBzMy5JQnVja2V0O1xuXG4gIC8qKlxuICAgKiBHcmFudCB0aGUgSUFNIHByaW5jaXBhbCBwZXJtaXNzaW9ucyB0byByZWFkIHRoZSBwcml2YXRlIGtleSBhbmRcbiAgICogY2VydGlmaWNhdGUuXG4gICAqL1xuICBncmFudERlY3J5cHQocHJpbmNpcGFsPzogaWFtLklQcmluY2lwYWwpOiB2b2lkO1xufVxuXG4vKipcbiAqIEEgQ29kZS1TaWduaW5nIGNlcnRpZmljYXRlLCB0aGF0IHdpbGwgdXNlIGEgcHJpdmF0ZSBrZXkgdGhhdCBpcyBnZW5lcmF0ZWQgYnkgYSBMYW1iZGEgZnVuY3Rpb24uIFRoZSBDZXJ0aWZpY2F0ZSB3aWxsXG4gKiBub3QgYmUgdXNhYmxlIHVudGlsIHRoZSBgYHBlbUNlcnRpZmljYXRlYGAgdmFsdWUgaGFzIGJlZW4gcHJvdmlkZWQuIEEgdHlwaWNhbCB3b3JrZmxvdyB0byB1c2UgdGhpcyBDb25zdHJ1Y3Qgd291bGQgYmU6XG4gKlxuICogMS4gQWRkIGFuIGluc3RhbmNlIG9mIHRoZSBjb25zdHJ1Y3QgdG8geW91ciBhcHAsIHdpdGhvdXQgcHJvdmlkaW5nIHRoZSBgYHBlbUNlcnRpZmljYXRlYGAgcHJvcGVydHlcbiAqIDIuIERlcGxveSB0aGUgc3RhY2sgdG8gcHJvdmlzaW9uIGEgUHJpdmF0ZSBLZXkgYW5kIG9idGFpbiB0aGUgQ1NSICh5b3UgY2FuIHN1cmZhY2UgaXQgdXNpbmcgYSBPdXRwdXQsIGZvciBleGFtcGxlKVxuICogMy4gU3VibWl0IHRoZSBDU1IgdG8geW91ciBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgb2YgY2hvaWNlLlxuICogNC4gUG9wdWxhdGUgdGhlIGBgcGVtQ2VydGlmaWNhdGVgYCBwcm9wZXJ0eSB3aXRoIHRoZSBQRU0tZW5jb2RlZCBjZXJ0aWZpY2F0ZSBwcm92aWRlZCBieSB5b3VyIENBIG9mIGNvaWNlLlxuICogNS4gUmUtZGVwbG95IHRoZSBzdGFjayBzbyBtYWtlIHRoZSBjZXJ0aWZpY2F0ZSB1c2FibGVcbiAqXG4gKiBJbiBvcmRlciB0byByZW5ldyB0aGUgY2VydGlmaWNhdGUsIGlmIHlvdSBkbyBub3Qgd2lzaCB0byByZXRhaW4gdGhlIHNhbWUgcHJpdmF0ZSBrZXkgKHlvdXIgY2xpZW50cyBkbyBub3QgcmVseSBvblxuICogcHVibGljIGtleSBwaW5uaW5nKSwgc2ltcGx5IGFkZCBhIG5ldyBpbnN0YW5jZSBvZiB0aGUgY29uc3RydWN0IHRvIHlvdXIgYXBwIGFuZCBmb2xsb3cgdGhlIHByb2Nlc3MgbGlzdGVkIGFib3ZlLiBJZlxuICogeW91IHdpc2ggdG8gcmV0YWluIHRoZSBwcml2YXRlIGtleSwgeW91IGNhbiBzZXQgYGBmb3JjZUNlcnRpZmljYXRlU2lnbmluZ1JlcXVlc3RgYCB0byBgYHRydWVgYCBpbiBvcmRlciB0byBvYnRhaW4gYVxuICogbmV3IENTUiBkb2N1bWVudC5cbiAqL1xuZXhwb3J0IGNsYXNzIENvZGVTaWduaW5nQ2VydGlmaWNhdGUgZXh0ZW5kcyBDb25zdHJ1Y3QgaW1wbGVtZW50cyBJQ29kZVNpZ25pbmdDZXJ0aWZpY2F0ZSB7XG4gIC8qKlxuICAgKiBUaGUgQVdTIFNlY3JldHMgTWFuYWdlciBzZWNyZXQgdGhhdCBob2xkcyB0aGUgcHJpdmF0ZSBrZXkgZm9yIHRoaXMgQ1NDXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgY3JlZGVudGlhbDogc2VjcmV0c01hbmFnZXIuSVNlY3JldDtcblxuICAvKipcbiAgICogVGhlIEFXUyBTU00gUGFyYW1ldGVyIHRoYXQgaG9sZHMgdGhlIGNlcnRpZmljYXRlIGZvciB0aGlzIENTQy5cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBwcmluY2lwYWw6IHNzbS5JU3RyaW5nUGFyYW1ldGVyO1xuXG4gIC8qKlxuICAgKiBUaGUgUzMgYnVja2V0IHdoZXJlIHRoZSBzZWxmLXNpZ25lZCBjZXJ0aWZpY2F0ZSBpcyBzdG9yZWQuXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgY2VydGlmaWNhdGVCdWNrZXQ/OiBzMy5JQnVja2V0O1xuXG4gIGNvbnN0cnVjdG9yKHBhcmVudDogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogQ29kZVNpZ25pbmdDZXJ0aWZpY2F0ZVByb3BzKSB7XG4gICAgc3VwZXIocGFyZW50LCBpZCk7XG5cbiAgICAvLyBUaGUgY29uc3RydWN0IHBhdGggb2YgdGhpcyBjb25zdHJ1Y3Qgd2l0aCByZXNwZWN0IHRvIHRoZSBjb250YWluaW5nIHN0YWNrLCB3aXRob3V0IGFueSBsZWFkaW5nIC9cbiAgICBjb25zdCBzdGFjayA9IFN0YWNrLm9mKHRoaXMpO1xuICAgIGNvbnN0IGJhc2VOYW1lID0gcHJvcHMuYmFzZU5hbWUgPz8gYCR7c3RhY2suc3RhY2tOYW1lfSR7dGhpcy5ub2RlLnBhdGguc3Vic3RyKHN0YWNrLm5vZGUucGF0aC5sZW5ndGgpfWA7XG5cbiAgICBjb25zdCBwcml2YXRlS2V5ID0gbmV3IFJzYVByaXZhdGVLZXlTZWNyZXQodGhpcywgJ1JTQVByaXZhdGVLZXknLCB7XG4gICAgICByZW1vdmFsUG9saWN5OiBwcm9wcy5yZXRhaW5Qcml2YXRlS2V5ID09PSBmYWxzZSA/IFJlbW92YWxQb2xpY3kuREVTVFJPWSA6IFJlbW92YWxQb2xpY3kuUkVUQUlOLFxuICAgICAgZGVzY3JpcHRpb246ICdUaGUgUEVNLWVuY29kZWQgcHJpdmF0ZSBrZXkgb2YgdGhlIHg1MDkgQ29kZS1TaWduaW5nIENlcnRpZmljYXRlJyxcbiAgICAgIGtleVNpemU6IHByb3BzLnJzYUtleVNpemUgfHwgMjA0OCxcbiAgICAgIHNlY3JldEVuY3J5cHRpb25LZXk6IHByb3BzLnNlY3JldEVuY3J5cHRpb25LZXksXG4gICAgICAvLyByZW5hbWUgdGhlIHNlY3JldCBuYW1lLCBhcyBzaW5jZSB0aGlzIHJlc291cmNlIHdpbGwgYmUgZGVsZXRlZCBhbmQgY3JlYXRlIGEgbmV3IHJlc291cmNlLFxuICAgICAgLy8gc28gdGhlIG5ldyByZXNvdXJjZSB3aWxsIGJlIGNyZWF0ZWQgYmVmb3JlIHRoZSBvbGQgb25lIGdvdCBkZWxldGVkLCBhbmQgc28gd2Ugd2lsbCBub3QgYmUgYWJsZVxuICAgICAgLy8gdG8gY3JlYXRlIGEgbmV3IHNlY3JldGUgd2l0aCB0aGUgc2FtZSBuYW1lLCBhbmQgZXZlbiB3ZSBjb3VsZCBub3QgcmV1c2UgaXQsIGFzIGl0IHdpbGwgYmUgZGVsZXRlZCBvbmNlXG4gICAgICAvLyB0aGUgb2xkIHJlc291cmNlIGdvdCBkZWxldGVkLlxuICAgICAgc2VjcmV0TmFtZTogYCR7YmFzZU5hbWV9L1JTQVByaXZhdGVLZXlWMmAsXG4gICAgfSk7XG5cbiAgICAvLyB0aGlzIGNoYW5nZSB0byBrZWVwIHRoZSBwZXJtaXNzaW9ucyB0byBhY2Nlc3MgdGhlIG9sZCBzZWNyZXQgZm9yIHRoZSBjdXN0b20gcmVzb3VyY2UgTGFtYmRhIGZ1bmN0aW9uIHJvbGUsIHNvIGl0IGNhblxuICAgIC8vIGRlbGV0ZSB0aGUgb2xkIHNlY3JldC5cbiAgICBjb25zdCBvbGRTZWNyZXRBcm5MaWtlID0gU3RhY2sub2YodGhpcykuZm9ybWF0QXJuKHtcbiAgICAgIHNlcnZpY2U6ICdzZWNyZXRzbWFuYWdlcicsXG4gICAgICByZXNvdXJjZTogJ3NlY3JldCcsXG4gICAgICBhcm5Gb3JtYXQ6IEFybkZvcm1hdC5DT0xPTl9SRVNPVVJDRV9OQU1FLFxuICAgICAgLy8gVGhlIEFSTiBvZiBhIHNlY3JldCBoYXMgXCItXCIgZm9sbG93ZWQgYnkgNiByYW5kb20gY2hhcmFjdGVycyBhcHBlbmRlZCBhdCB0aGUgZW5kXG4gICAgICByZXNvdXJjZU5hbWU6IGAke2Jhc2VOYW1lfS9SU0FQcml2YXRlS2V5LT8/Pz8/P2AsXG4gICAgfSk7XG4gICAgcHJpdmF0ZUtleS5jdXN0b21SZXNvdXJjZS5hZGRUb1JvbGVQb2xpY3kobmV3IGlhbS5Qb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgYWN0aW9uczogW1xuICAgICAgICAnc2VjcmV0c21hbmFnZXI6Q3JlYXRlU2VjcmV0JyxcbiAgICAgICAgJ3NlY3JldHNtYW5hZ2VyOkRlbGV0ZVNlY3JldCcsXG4gICAgICAgICdzZWNyZXRzbWFuYWdlcjpVcGRhdGVTZWNyZXQnLFxuICAgICAgXSxcbiAgICAgIHJlc291cmNlczogW29sZFNlY3JldEFybkxpa2VdLFxuICAgIH0pKTtcblxuICAgIGlmIChwcm9wcy5zZWNyZXRFbmNyeXB0aW9uS2V5KSB7XG4gICAgICBwcm9wcy5zZWNyZXRFbmNyeXB0aW9uS2V5LmFkZFRvUmVzb3VyY2VQb2xpY3kobmV3IGlhbS5Qb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgICAvLyBkZXNjcmlwdGlvbjogYEFsbG93IHVzZSB2aWEgQVdTIFNlY3JldHMgTWFuYWdlciBieSBDdXN0b21SZXNvdXJjZSBoYW5kbGVyICR7Y3VzdG9tUmVzb3VyY2UuZnVuY3Rpb25OYW1lfWAsXG4gICAgICAgIHByaW5jaXBhbHM6IFtuZXcgaWFtLkFyblByaW5jaXBhbChwcml2YXRlS2V5LmN1c3RvbVJlc291cmNlLnJvbGUhLnJvbGVBcm4pXSxcbiAgICAgICAgYWN0aW9uczogWydrbXM6RGVjcnlwdCcsICdrbXM6R2VuZXJhdGVEYXRhS2V5J10sXG4gICAgICAgIHJlc291cmNlczogWycqJ10sXG4gICAgICAgIGNvbmRpdGlvbnM6IHtcbiAgICAgICAgICBTdHJpbmdFcXVhbHM6IHtcbiAgICAgICAgICAgICdrbXM6VmlhU2VydmljZSc6IGBzZWNyZXRzbWFuYWdlci4ke1N0YWNrLm9mKHRoaXMpLnJlZ2lvbn0uYW1hem9uYXdzLmNvbWAsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBBcm5MaWtlOiB7XG4gICAgICAgICAgICAna21zOkVuY3J5cHRpb25Db250ZXh0OlNlY3JldEFSTic6IG9sZFNlY3JldEFybkxpa2UsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgIH0pKTtcbiAgICB9XG5cbiAgICB0aGlzLmNyZWRlbnRpYWwgPSBzZWNyZXRzTWFuYWdlci5TZWNyZXQuZnJvbVNlY3JldEF0dHJpYnV0ZXModGhpcywgJ0NyZWRlbnRpYWwnLCB7XG4gICAgICBlbmNyeXB0aW9uS2V5OiBwcm9wcy5zZWNyZXRFbmNyeXB0aW9uS2V5LFxuICAgICAgc2VjcmV0Q29tcGxldGVBcm46IHByaXZhdGVLZXkuc2VjcmV0QXJuLFxuICAgIH0pO1xuXG4gICAgbGV0IGNlcnRpZmljYXRlID0gcHJvcHMucGVtQ2VydGlmaWNhdGU7XG5cbiAgICBpZiAoIWNlcnRpZmljYXRlIHx8IHByb3BzLmZvcmNlQ2VydGlmaWNhdGVTaWduaW5nUmVxdWVzdCkge1xuICAgICAgY29uc3QgY3NyOiBDZXJ0aWZpY2F0ZVNpZ25pbmdSZXF1ZXN0ID0gcHJpdmF0ZUtleS5uZXdDZXJ0aWZpY2F0ZVNpZ25pbmdSZXF1ZXN0KCdDZXJ0aWZpY2F0ZVNpZ25pbmdSZXF1ZXN0JyxcbiAgICAgICAgcHJvcHMuZGlzdGluZ3Vpc2hlZE5hbWUsXG4gICAgICAgICdjcml0aWNhbCxkaWdpdGFsU2lnbmF0dXJlJyxcbiAgICAgICAgJ2NyaXRpY2FsLGNvZGVTaWduaW5nJyk7XG5cbiAgICAgIHRoaXMuY2VydGlmaWNhdGVCdWNrZXQgPSBjc3Iub3V0cHV0QnVja2V0O1xuXG4gICAgICBuZXcgQ2ZuT3V0cHV0KHRoaXMsICdDU1InLCB7XG4gICAgICAgIGRlc2NyaXB0aW9uOiAnQSBQRU0tZW5jb2RlZCBDZXJ0aWZpY2F0ZSBTaWduaW5nIFJlcXVlc3QgZm9yIGEgQ29kZS1TaWduaW5nIENlcnRpZmljYXRlJyxcbiAgICAgICAgdmFsdWU6IGNzci5wZW1SZXF1ZXN0LFxuICAgICAgfSk7XG5cbiAgICAgIGlmICghY2VydGlmaWNhdGUpIHtcbiAgICAgICAgY2VydGlmaWNhdGUgPSBjc3Iuc2VsZlNpZ25lZFBlbUNlcnRpZmljYXRlO1xuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMucHJpbmNpcGFsID0gbmV3IHNzbS5TdHJpbmdQYXJhbWV0ZXIodGhpcywgJ1Jlc291cmNlJywge1xuICAgICAgZGVzY3JpcHRpb246IGBBIFBFTS1lbmNvZGVkIENvZGUtU2lnbmluZyBDZXJ0aWZpY2F0ZSAocHJpdmF0ZSBrZXkgaW4gJHtwcml2YXRlS2V5LnNlY3JldEFybn0pYCxcbiAgICAgIHBhcmFtZXRlck5hbWU6IGAvJHtiYXNlTmFtZX0vQ2VydGlmaWNhdGVgLFxuICAgICAgc3RyaW5nVmFsdWU6IGNlcnRpZmljYXRlISxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudCB0aGUgSUFNIHByaW5jaXBhbCBwZXJtaXNzaW9ucyB0byByZWFkIHRoZSBwcml2YXRlIGtleSBhbmRcbiAgICogY2VydGlmaWNhdGUuXG4gICAqL1xuICBwdWJsaWMgZ3JhbnREZWNyeXB0KHByaW5jaXBhbD86IGlhbS5JUHJpbmNpcGFsKSB7XG4gICAgaWYgKCFwcmluY2lwYWwpIHsgcmV0dXJuOyB9XG5cbiAgICBwZXJtaXNzaW9ucy5ncmFudFNlY3JldFJlYWQoe1xuICAgICAga2V5QXJuOiB0aGlzLmNyZWRlbnRpYWwuZW5jcnlwdGlvbktleSAmJiB0aGlzLmNyZWRlbnRpYWwuZW5jcnlwdGlvbktleS5rZXlBcm4sXG4gICAgICBzZWNyZXRBcm46IHRoaXMuY3JlZGVudGlhbC5zZWNyZXRBcm4sXG4gICAgfSwgcHJpbmNpcGFsKTtcblxuICAgIHByaW5jaXBhbC5hZGRUb1ByaW5jaXBhbFBvbGljeShuZXcgaWFtLlBvbGljeVN0YXRlbWVudCh7XG4gICAgICBhY3Rpb25zOiBbJ3NzbTpHZXRQYXJhbWV0ZXInXSxcbiAgICAgIHJlc291cmNlczogW1N0YWNrLm9mKHRoaXMpLmZvcm1hdEFybih7XG4gICAgICAgIC8vIFRPRE86IFRoaXMgaXMgYSB3b3JrYXJvdW5kIHVudGlsIGh0dHBzOi8vZ2l0aHViLmNvbS9hd3NsYWJzL2F3cy1jZGsvcHVsbC8xNzI2IGlzIHJlbGVhc2VkXG4gICAgICAgIHNlcnZpY2U6ICdzc20nLFxuICAgICAgICByZXNvdXJjZTogYHBhcmFtZXRlciR7dGhpcy5wcmluY2lwYWwucGFyYW1ldGVyTmFtZX1gLFxuICAgICAgfSldLFxuICAgIH0pKTtcblxuICAgIHRoaXMuY2VydGlmaWNhdGVCdWNrZXQ/LmdyYW50UmVhZChwcmluY2lwYWwpO1xuICB9XG59XG4iXX0=