@bitgo/sdk-core 38.20.0 → 38.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/dist/src/bitgo/environments.d.ts +5 -0
  2. package/dist/src/bitgo/environments.d.ts.map +1 -1
  3. package/dist/src/bitgo/environments.js +2 -1
  4. package/dist/src/bitgo/tss/redpallas/redpallasMPCv2.d.ts +33 -4
  5. package/dist/src/bitgo/tss/redpallas/redpallasMPCv2.d.ts.map +1 -1
  6. package/dist/src/bitgo/tss/redpallas/redpallasMPCv2.js +71 -4
  7. package/dist/src/bitgo/utils/index.d.ts +1 -0
  8. package/dist/src/bitgo/utils/index.d.ts.map +1 -1
  9. package/dist/src/bitgo/utils/index.js +2 -1
  10. package/dist/src/bitgo/utils/mpcUtils.d.ts.map +1 -1
  11. package/dist/src/bitgo/utils/mpcUtils.js +2 -1
  12. package/dist/src/bitgo/utils/siws.d.ts +17 -0
  13. package/dist/src/bitgo/utils/siws.d.ts.map +1 -0
  14. package/dist/src/bitgo/utils/siws.js +171 -0
  15. package/dist/src/bitgo/utils/tss/baseTSSUtils.d.ts +5 -0
  16. package/dist/src/bitgo/utils/tss/baseTSSUtils.d.ts.map +1 -1
  17. package/dist/src/bitgo/utils/tss/baseTSSUtils.js +12 -1
  18. package/dist/src/bitgo/utils/tss/baseTypes.d.ts +7 -0
  19. package/dist/src/bitgo/utils/tss/baseTypes.d.ts.map +1 -1
  20. package/dist/src/bitgo/utils/tss/baseTypes.js +1 -1
  21. package/dist/src/bitgo/utils/tss/eddsa/eddsa.d.ts +5 -0
  22. package/dist/src/bitgo/utils/tss/eddsa/eddsa.d.ts.map +1 -1
  23. package/dist/src/bitgo/utils/tss/eddsa/eddsa.js +8 -1
  24. package/dist/src/bitgo/utils/tss/index.d.ts +1 -0
  25. package/dist/src/bitgo/utils/tss/index.d.ts.map +1 -1
  26. package/dist/src/bitgo/utils/tss/index.js +2 -1
  27. package/dist/src/bitgo/utils/tss/keyVerification.d.ts +45 -0
  28. package/dist/src/bitgo/utils/tss/keyVerification.d.ts.map +1 -0
  29. package/dist/src/bitgo/utils/tss/keyVerification.js +192 -0
  30. package/dist/src/bitgo/wallet/iWallet.d.ts +16 -0
  31. package/dist/src/bitgo/wallet/iWallet.d.ts.map +1 -1
  32. package/dist/src/bitgo/wallet/iWallet.js +1 -1
  33. package/dist/src/bitgo/wallet/wallet.d.ts +21 -1
  34. package/dist/src/bitgo/wallet/wallet.d.ts.map +1 -1
  35. package/dist/src/bitgo/wallet/wallet.js +39 -1
  36. package/dist/test/unit/bitgo/safe/rootCoin.d.ts +2 -0
  37. package/dist/test/unit/bitgo/safe/rootCoin.d.ts.map +1 -0
  38. package/dist/test/unit/bitgo/safe/rootCoin.js +13 -0
  39. package/dist/test/unit/bitgo/tss/redpallas/redpallasMPCv2.js +69 -1
  40. package/dist/test/unit/bitgo/utils/siws.d.ts +2 -0
  41. package/dist/test/unit/bitgo/utils/siws.d.ts.map +1 -0
  42. package/dist/test/unit/bitgo/utils/siws.js +206 -0
  43. package/dist/test/unit/bitgo/utils/tss/keyVerification.d.ts +2 -0
  44. package/dist/test/unit/bitgo/utils/tss/keyVerification.d.ts.map +1 -0
  45. package/dist/test/unit/bitgo/utils/tss/keyVerification.js +229 -0
  46. package/dist/test/unit/bitgo/wallet/walletVerifyKey.d.ts +2 -0
  47. package/dist/test/unit/bitgo/wallet/walletVerifyKey.d.ts.map +1 -0
  48. package/dist/test/unit/bitgo/wallet/walletVerifyKey.js +160 -0
  49. package/dist/tsconfig.tsbuildinfo +1 -1
  50. package/package.json +6 -6
@@ -0,0 +1,229 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ const assert = __importStar(require("assert"));
40
+ require("should");
41
+ const sdk_lib_mpc_1 = require("@bitgo/sdk-lib-mpc");
42
+ const tss_1 = __importDefault(require("../../../../../src/account-lib/mpc/tss"));
43
+ const keyVerification_1 = require("../../../../../src/bitgo/utils/tss/keyVerification");
44
+ describe('TSS EdDSA key verification', function () {
45
+ let matchingPrv;
46
+ let commonKeychain;
47
+ let otherPrv;
48
+ let backupStylePrv;
49
+ before(async function () {
50
+ const hdTree = await sdk_lib_mpc_1.Ed25519Bip32HdTree.initialize();
51
+ const MPC = await tss_1.default.initialize(hdTree);
52
+ const userKeyShare = MPC.keyShare(1, 2, 3);
53
+ const backupKeyShare = MPC.keyShare(2, 2, 3);
54
+ const bitgoKeyShare = MPC.keyShare(3, 2, 3);
55
+ const combined = MPC.keyCombine(userKeyShare.uShare, [backupKeyShare.yShares[1], bitgoKeyShare.yShares[1]]);
56
+ commonKeychain = combined.pShare.y + combined.pShare.chaincode;
57
+ matchingPrv = JSON.stringify({
58
+ uShare: userKeyShare.uShare,
59
+ bitgoYShare: bitgoKeyShare.yShares[1],
60
+ backupYShare: backupKeyShare.yShares[1],
61
+ });
62
+ // an independent key generation for the negative case
63
+ const otherUserKeyShare = MPC.keyShare(1, 2, 3);
64
+ const otherBackupKeyShare = MPC.keyShare(2, 2, 3);
65
+ const otherBitgoKeyShare = MPC.keyShare(3, 2, 3);
66
+ otherPrv = JSON.stringify({
67
+ uShare: otherUserKeyShare.uShare,
68
+ bitgoYShare: otherBitgoKeyShare.yShares[1],
69
+ backupYShare: otherBackupKeyShare.yShares[1],
70
+ });
71
+ // backup-style signing material: the holder is the backup party (i=2), so it carries
72
+ // userYShare instead of backupYShare
73
+ backupStylePrv = JSON.stringify({
74
+ uShare: backupKeyShare.uShare,
75
+ bitgoYShare: bitgoKeyShare.yShares[2],
76
+ userYShare: userKeyShare.yShares[2],
77
+ });
78
+ });
79
+ describe('parseEddsaUserSigningMaterial', function () {
80
+ it('parses well-formed user signing material', function () {
81
+ const parsed = (0, keyVerification_1.parseEddsaUserSigningMaterial)(matchingPrv);
82
+ parsed.should.have.property('uShare');
83
+ parsed.should.have.property('bitgoYShare');
84
+ parsed.should.have.property('backupYShare');
85
+ });
86
+ it('rejects input that is not valid JSON without echoing the input', function () {
87
+ const prv = 'not json';
88
+ assert.throws(() => (0, keyVerification_1.parseEddsaUserSigningMaterial)(prv), (err) => {
89
+ assert.ok(err instanceof Error);
90
+ assert.ok(!err.message.includes(prv), 'error message must not echo the input');
91
+ return true;
92
+ });
93
+ });
94
+ it('rejects input that parses to a non-object', function () {
95
+ assert.throws(() => (0, keyVerification_1.parseEddsaUserSigningMaterial)('123'), /signing material is not an object/);
96
+ });
97
+ it('rejects material missing any of the three required shares', function () {
98
+ const { uShare, bitgoYShare, backupYShare } = (0, keyVerification_1.parseEddsaUserSigningMaterial)(matchingPrv);
99
+ assert.throws(() => (0, keyVerification_1.parseEddsaUserSigningMaterial)(JSON.stringify({ bitgoYShare, backupYShare })), /missing uShare/);
100
+ assert.throws(() => (0, keyVerification_1.parseEddsaUserSigningMaterial)(JSON.stringify({ uShare, backupYShare })), /missing bitgoYShare/);
101
+ assert.throws(() => (0, keyVerification_1.parseEddsaUserSigningMaterial)(JSON.stringify({ uShare, bitgoYShare })), /missing backupYShare/);
102
+ });
103
+ it('rejects backup-style material; only user signing material is accepted', function () {
104
+ assert.throws(() => (0, keyVerification_1.parseEddsaUserSigningMaterial)(backupStylePrv), /missing backupYShare/);
105
+ });
106
+ it('rejects shares that are not share-shaped objects', function () {
107
+ const { uShare, bitgoYShare, backupYShare } = (0, keyVerification_1.parseEddsaUserSigningMaterial)(matchingPrv);
108
+ // array shares are malformed; null shares count as missing
109
+ assert.throws(() => (0, keyVerification_1.parseEddsaUserSigningMaterial)(JSON.stringify({ uShare, bitgoYShare: [], backupYShare })), /bitgoYShare is not a valid share/);
110
+ assert.throws(() => (0, keyVerification_1.parseEddsaUserSigningMaterial)(JSON.stringify({ uShare, bitgoYShare: null, backupYShare })), /missing bitgoYShare/);
111
+ assert.throws(() => (0, keyVerification_1.parseEddsaUserSigningMaterial)(JSON.stringify({ uShare: {}, bitgoYShare, backupYShare })), /uShare is not a valid share/);
112
+ });
113
+ it('rejects shares with malformed fields', function () {
114
+ const malformed = JSON.stringify({
115
+ uShare: { i: 1, t: 2, n: 3, y: 'not-hex', seed: 'ab', chaincode: 'cd' },
116
+ bitgoYShare: { i: 1, j: 3, y: 'ab', u: 'cd', chaincode: 'ef', v: '01' },
117
+ backupYShare: { i: 1, j: 2, y: 'ab', u: 'cd', chaincode: 'ef' },
118
+ });
119
+ assert.throws(() => (0, keyVerification_1.parseEddsaUserSigningMaterial)(malformed), /uShare is not a valid share/);
120
+ });
121
+ it('rejects hex fields of the wrong length', function () {
122
+ const { uShare, bitgoYShare, backupYShare } = (0, keyVerification_1.parseEddsaUserSigningMaterial)(matchingPrv);
123
+ const truncatedChaincode = JSON.stringify({
124
+ uShare: { ...uShare, chaincode: uShare.chaincode.slice(0, 62) },
125
+ bitgoYShare,
126
+ backupYShare,
127
+ });
128
+ assert.throws(() => (0, keyVerification_1.parseEddsaUserSigningMaterial)(truncatedChaincode), /uShare is not a valid share/);
129
+ });
130
+ it('rejects a non-hex v field on a Y share when present', function () {
131
+ const { uShare, bitgoYShare, backupYShare } = (0, keyVerification_1.parseEddsaUserSigningMaterial)(matchingPrv);
132
+ const tampered = JSON.stringify({
133
+ uShare,
134
+ backupYShare,
135
+ bitgoYShare: { ...bitgoYShare, v: 'zz' },
136
+ });
137
+ assert.throws(() => (0, keyVerification_1.parseEddsaUserSigningMaterial)(tampered), /bitgoYShare is not a valid share/);
138
+ });
139
+ it('accepts a Y share without the optional v field', function () {
140
+ // v is optional on the YShare type, so parsing must allow it; verification separately
141
+ // rejects material without it with a distinct unable-to-verify error (see below)
142
+ const { uShare, bitgoYShare, backupYShare } = (0, keyVerification_1.parseEddsaUserSigningMaterial)(matchingPrv);
143
+ const withoutV = { ...bitgoYShare };
144
+ delete withoutV.v;
145
+ const vlessPrv = JSON.stringify({ uShare, bitgoYShare: withoutV, backupYShare });
146
+ const parsed = (0, keyVerification_1.parseEddsaUserSigningMaterial)(vlessPrv);
147
+ parsed.bitgoYShare.should.not.have.property('v');
148
+ });
149
+ });
150
+ describe('eddsaUserSigningMaterialMatchesCommonKeychain', function () {
151
+ it('returns true when the combined key equals the commonKeychain', async function () {
152
+ const match = await (0, keyVerification_1.eddsaUserSigningMaterialMatchesCommonKeychain)({ prv: matchingPrv, commonKeychain });
153
+ match.should.equal(true);
154
+ });
155
+ it('returns false for material from a different key generation', async function () {
156
+ const match = await (0, keyVerification_1.eddsaUserSigningMaterialMatchesCommonKeychain)({ prv: otherPrv, commonKeychain });
157
+ match.should.equal(false);
158
+ });
159
+ it('rejects malformed material without echoing the input', async function () {
160
+ await assert.rejects((0, keyVerification_1.eddsaUserSigningMaterialMatchesCommonKeychain)({ prv: 'not json', commonKeychain }), {
161
+ message: 'Invalid user key - could not parse signing material',
162
+ });
163
+ });
164
+ it('rejects inconsistent shares with a constant error instead of the raw combine failure', async function () {
165
+ const { uShare, bitgoYShare, backupYShare } = (0, keyVerification_1.parseEddsaUserSigningMaterial)(matchingPrv);
166
+ const tampered = JSON.stringify({
167
+ uShare,
168
+ bitgoYShare,
169
+ backupYShare: { ...backupYShare, v: '00'.repeat(32) },
170
+ });
171
+ await assert.rejects((0, keyVerification_1.eddsaUserSigningMaterialMatchesCommonKeychain)({ prv: tampered, commonKeychain }), {
172
+ message: 'Invalid user key - could not combine signing material',
173
+ });
174
+ });
175
+ it('returns false for a wrong seed behind otherwise genuine public fields', async function () {
176
+ // keyCombine derives the private scalar from the seed but rebuilds the common keychain from
177
+ // the declared y fields, so without an explicit seed/y binding a caller who knows only the
178
+ // public commonKeychain could verify against a seed they do not hold
179
+ const { uShare, bitgoYShare, backupYShare } = (0, keyVerification_1.parseEddsaUserSigningMaterial)(matchingPrv);
180
+ const forged = JSON.stringify({
181
+ uShare: { ...uShare, seed: 'ab'.repeat(32) },
182
+ bitgoYShare,
183
+ backupYShare,
184
+ });
185
+ const match = await (0, keyVerification_1.eddsaUserSigningMaterialMatchesCommonKeychain)({ prv: forged, commonKeychain });
186
+ match.should.equal(false);
187
+ });
188
+ it('rejects material that omits a VSS commitment instead of judging it a non-match', async function () {
189
+ // keyCombine only verifies a Y share's secret u when v is present, so material that drops
190
+ // v would otherwise pass combine with an arbitrary u; it cannot be verified at all and
191
+ // must not be reported as a clean non-match
192
+ const { uShare, bitgoYShare, backupYShare } = (0, keyVerification_1.parseEddsaUserSigningMaterial)(matchingPrv);
193
+ const bitgoWithoutV = { ...bitgoYShare, u: 'cd'.repeat(32) };
194
+ delete bitgoWithoutV.v;
195
+ const forged = JSON.stringify({
196
+ uShare,
197
+ bitgoYShare: bitgoWithoutV,
198
+ backupYShare,
199
+ });
200
+ await assert.rejects((0, keyVerification_1.eddsaUserSigningMaterialMatchesCommonKeychain)({ prv: forged, commonKeychain }), {
201
+ message: 'Unable to verify key - signing material has no VSS commitment',
202
+ });
203
+ });
204
+ it('rejects otherwise-genuine material without a VSS commitment as unverifiable', async function () {
205
+ // shares without v may be genuine (the server did not always return vssProof), so the
206
+ // answer must be "cannot verify", never "not this wallet's key"
207
+ const { uShare, bitgoYShare, backupYShare } = (0, keyVerification_1.parseEddsaUserSigningMaterial)(matchingPrv);
208
+ const bitgoWithoutV = { ...bitgoYShare };
209
+ delete bitgoWithoutV.v;
210
+ const vless = JSON.stringify({ uShare, bitgoYShare: bitgoWithoutV, backupYShare });
211
+ await assert.rejects((0, keyVerification_1.eddsaUserSigningMaterialMatchesCommonKeychain)({ prv: vless, commonKeychain }), {
212
+ message: 'Unable to verify key - signing material has no VSS commitment',
213
+ });
214
+ });
215
+ it('returns false when a Y share carries a mismatched secret with its commitment present', async function () {
216
+ const { uShare, bitgoYShare, backupYShare } = (0, keyVerification_1.parseEddsaUserSigningMaterial)(matchingPrv);
217
+ const forged = JSON.stringify({
218
+ uShare,
219
+ bitgoYShare: { ...bitgoYShare, u: 'cd'.repeat(32) },
220
+ backupYShare,
221
+ });
222
+ // a present-but-failing commitment is a combine failure, surfaced as the constant error
223
+ await assert.rejects((0, keyVerification_1.eddsaUserSigningMaterialMatchesCommonKeychain)({ prv: forged, commonKeychain }), {
224
+ message: 'Invalid user key - could not combine signing material',
225
+ });
226
+ });
227
+ });
228
+ });
229
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoia2V5VmVyaWZpY2F0aW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vdGVzdC91bml0L2JpdGdvL3V0aWxzL3Rzcy9rZXlWZXJpZmljYXRpb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSwrQ0FBaUM7QUFDakMsa0JBQWdCO0FBQ2hCLG9EQUF3RDtBQUN4RCxpRkFBMkQ7QUFDM0Qsd0ZBRzREO0FBRTVELFFBQVEsQ0FBQyw0QkFBNEIsRUFBRTtJQUNyQyxJQUFJLFdBQW1CLENBQUM7SUFDeEIsSUFBSSxjQUFzQixDQUFDO0lBQzNCLElBQUksUUFBZ0IsQ0FBQztJQUNyQixJQUFJLGNBQXNCLENBQUM7SUFFM0IsTUFBTSxDQUFDLEtBQUs7UUFDVixNQUFNLE1BQU0sR0FBRyxNQUFNLGdDQUFrQixDQUFDLFVBQVUsRUFBRSxDQUFDO1FBQ3JELE1BQU0sR0FBRyxHQUFHLE1BQU0sYUFBSyxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUUzQyxNQUFNLFlBQVksR0FBRyxHQUFHLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDM0MsTUFBTSxjQUFjLEdBQUcsR0FBRyxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQzdDLE1BQU0sYUFBYSxHQUFHLEdBQUcsQ0FBQyxRQUFRLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUM1QyxNQUFNLFFBQVEsR0FBRyxHQUFHLENBQUMsVUFBVSxDQUFDLFlBQVksQ0FBQyxNQUFNLEVBQUUsQ0FBQyxjQUFjLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLGFBQWEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzVHLGNBQWMsR0FBRyxR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QSwrREFBNkMsRUFBQyxFQUFFLEdBQUcsRUFBRSxLQUFLLEVBQUUsY0FBYyxFQUFFLENBQUMsRUFBRTtnQkFDbEcsT0FBTyxFQUFFLCtEQUErRDthQUN6RSxDQUFDLENBQUM7UUFDTCxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyxzRkFBc0YsRUFBRSxLQUFLO1lBQzlGLE1BQU0sRUFBRSxNQUFNLEVBQUUsV0FBVyxFQUFFLFlBQVksRUFBRSxHQUFHLElBQUEsK0NBQTZCLEVBQUMsV0FBVyxDQUFDLENBQUM7WUFDekYsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQztnQkFDNUIsTUFBTTtnQkFDTixXQUFXLEVBQUUsRUFBRSxHQUFHLFdBQVcsRUFBRSxDQUFDLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsRUFBRTtnQkFDbkQsWUFBWTthQUNiLENBQUMsQ0FBQztZQUNILHdGQUF3RjtZQUN4RixNQUFNLE1BQU0sQ0FBQyxPQUFPLENBQUMsSUFBQSwrREFBNkMsRUFBQyxFQUFFLEdBQUcsRUFBRSxNQUFNLEVBQUUsY0FBYyxFQUFFLENBQUMsRUFBRTtnQkFDbkcsT0FBTyxFQUFFLHVEQUF1RDthQUNqRSxDQUFDLENBQUM7UUFDTCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBhc3NlcnQgZnJvbSAnYXNzZXJ0JztcbmltcG9ydCAnc2hvdWxkJztcbmltcG9ydCB7IEVkMjU1MTlCaXAzMkhkVHJlZSB9IGZyb20gJ0BiaXRnby9zZGstbGliLW1wYyc7XG5pbXBvcnQgRWRkc2EgZnJvbSAnLi4vLi4vLi4vLi4vLi4vc3JjL2FjY291bnQtbGliL21wYy90c3MnO1xuaW1wb3J0IHtcbiAgZWRkc2FVc2VyU2lnbmluZ01hdGVyaWFsTWF0Y2hlc0NvbW1vbktleWNoYWluLFxuICBwYXJzZUVkZHNhVXNlclNpZ25pbmdNYXRlcmlhbCxcbn0gZnJvbSAnLi4vLi4vLi4vLi4vLi4vc3JjL2JpdGdvL3V0aWxzL3Rzcy9rZXlWZXJpZmljYXRpb24nO1xuXG5kZXNjcmliZSgnVFNTIEVkRFNBIGtleSB2ZXJpZmljYXRpb24nLCBmdW5jdGlvbiAoKSB7XG4gIGxldCBtYXRjaGluZ1Bydjogc3RyaW5nO1xuICBsZXQgY29tbW9uS2V5Y2hhaW46IHN0cmluZztcbiAgbGV0IG90aGVyUHJ2OiBzdHJpbmc7XG4gIGxldCBiYWNrdXBTdHlsZVBydjogc3RyaW5nO1xuXG4gIGJlZm9yZShhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3QgaGRUcmVlID0gYXdhaXQgRWQyNTUxOUJpcDMySGRUcmVlLmluaXRpYWxpemUoKTtcbiAgICBjb25zdCBNUEMgPSBhd2FpdCBFZGRzYS5pbml0aWFsaXplKGhkVHJlZSk7XG5cbiAgICBjb25zdCB1c2VyS2V5U2hhcmUgPSBNUEMua2V5U2hhcmUoMSwgMiwgMyk7XG4gICAgY29uc3QgYmFja3VwS2V5U2hhcmUgPSBNUEMua2V5U2hhcmUoMiwgMiwgMyk7XG4gICAgY29uc3QgYml0Z29LZXlTaGFyZSA9IE1QQy5rZXlTaGFyZSgzLCAyLCAzKTtcbiAgICBjb25zdCBjb21iaW5lZCA9IE1QQy5rZXlDb21iaW5lKHVzZXJLZXlTaGFyZS51U2hhcmUsIFtiYWNrdXBLZXlTaGFyZS55U2hhcmVzWzFdLCBiaXRnb0tleVNoYXJlLnlTaGFyZXNbMV1dKTtcbiAgICBjb21tb25LZXljaGFpbiA9IGNvbWJpbmVkLnBTaGFyZS55ICsgY29tYmluZWQucFNoYXJlLmNoYWluY29kZTtcbiAgICBtYXRjaGluZ1BydiA9IEpTT04uc3RyaW5naWZ5KHtcbiAgICAgIHVTaGFyZTogdXNlcktleVNoYXJlLnVTaGFyZSxcbiAgICAgIGJpdGdvWVNoYXJlOiBiaXRnb0tleVNoYXJlLnlTaGFyZXNbMV0sXG4gICAgICBiYWNrdXBZU2hhcmU6IGJhY2t1cEtleVNoYXJlLnlTaGFyZXNbMV0sXG4gICAgfSk7XG5cbiAgICAvLyBhbiBpbmRlcGVuZGVudCBrZXkgZ2VuZXJhdGlvbiBmb3IgdGhlIG5lZ2F0aXZlIGNhc2VcbiAgICBjb25zdCBvdGhlclVzZXJLZXlTaGFyZSA9IE1QQy5rZXlTaGFyZSgxLCAyLCAzKTtcbiAgICBjb25zdCBvdGhlckJhY2t1cEtleVNoYXJlID0gTVBDLmtleVNoYXJlKDIsIDIsIDMpO1xuICAgIGNvbnN0IG90aGVyQml0Z29LZXlTaGFyZSA9IE1QQy5rZXlTaGFyZSgzLCAyLCAzKTtcbiAgICBvdGhlclBydiA9IEpTT04uc3RyaW5naWZ5KHtcbiAgICAgIHVTaGFyZTogb3RoZXJVc2VyS2V5U2hhcmUudVNoYXJlLFxuICAgICAgYml0Z29ZU2hhcmU6IG90aGVyQml0Z29LZXlTaGFyZS55U2hhcmVzWzFdLFxuICAgICAgYmFja3VwWVNoYXJlOiBvdGhlckJhY2t1cEtleVNoYXJlLnlTaGFyZXNbMV0sXG4gICAgfSk7XG5cbiAgICAvLyBiYWNrdXAtc3R5bGUgc2lnbmluZyBtYXRlcmlhbDogdGhlIGhvbGRlciBpcyB0aGUgYmFja3VwIHBhcnR5IChpPTIpLCBzbyBpdCBjYXJyaWVzXG4gICAgLy8gdXNlcllTaGFyZSBpbnN0ZWFkIG9mIGJhY2t1cFlTaGFyZVxuICAgIGJhY2t1cFN0eWxlUHJ2ID0gSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgdVNoYXJlOiBiYWNrdXBLZXlTaGFyZS51U2hhcmUsXG4gICAgICBiaXRnb1lTaGFyZTogYml0Z29LZXlTaGFyZS55U2hhcmVzWzJdLFxuICAgICAgdXNlcllTaGFyZTogdXNlcktleVNoYXJlLnlTaGFyZXNbMl0sXG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdwYXJzZUVkZHNhVXNlclNpZ25pbmdNYXRlcmlhbCcsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgncGFyc2VzIHdlbGwtZm9ybWVkIHVzZXIgc2lnbmluZyBtYXRlcmlhbCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHBhcnNlZCA9IHBhcnNlRWRkc2FVc2VyU2lnbmluZ01hdGVyaWFsKG1hdGNoaW5nUHJ2KTtcbiAgICAgIHBhcnNlZC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgndVNoYXJlJyk7XG4gICAgICBwYXJzZWQuc2hvdWxkLmhhdmUucHJvcGVydHkoJ2JpdGdvWVNoYXJlJyk7XG4gICAgICBwYXJzZWQuc2hvdWxkLmhhdmUucHJvcGVydHkoJ2JhY2t1cFlTaGFyZScpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3JlamVjdHMgaW5wdXQgdGhhdCBpcyBub3QgdmFsaWQgSlNPTiB3aXRob3V0IGVjaG9pbmcgdGhlIGlucHV0JywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgcHJ2ID0gJ25vdCBqc29uJztcbiAgICAgIGFzc2VydC50aHJvd3MoXG4gICAgICAgICgpID0+IHBhcnNlRWRkc2FVc2VyU2lnbmluZ01hdGVyaWFsKHBydiksXG4gICAgICAgIChlcnI6IHVua25vd24pID0+IHtcbiAgICAgICAgICBhc3NlcnQub2soZXJyIGluc3RhbmNlb2YgRXJyb3IpO1xuICAgICAgICAgIGFzc2VydC5vayghZXJyLm1lc3NhZ2UuaW5jbHVkZXMocHJ2KSwgJ2Vycm9yIG1lc3NhZ2UgbXVzdCBub3QgZWNobyB0aGUgaW5wdXQnKTtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgKTtcbiAgICB9KTtcblxuICAgIGl0KCdyZWplY3RzIGlucHV0IHRoYXQgcGFyc2VzIHRvIGEgbm9uLW9iamVjdCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGFzc2VydC50aHJvd3MoKCkgPT4gcGFyc2VFZGRzYVVzZXJTaWduaW5nTWF0ZXJpYWwoJzEyMycpLCAvc2lnbmluZyBtYXRlcmlhbCBpcyBub3QgYW4gb2JqZWN0Lyk7XG4gICAgfSk7XG5cbiAgICBpdCgncmVqZWN0cyBtYXRlcmlhbCBtaXNzaW5nIGFueSBvZiB0aGUgdGhyZWUgcmVxdWlyZWQgc2hhcmVzJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgeyB1U2hhcmUsIGJpdGdvWVNoYXJlLCBiYWNrdXBZU2hhcmUgfSA9IHBhcnNlRWRkc2FVc2VyU2lnbmluZ01hdGVyaWFsKG1hdGNoaW5nUHJ2KTtcbiAgICAgIGFzc2VydC50aHJvd3MoXG4gICAgICAgICgpID0+IHBhcnNlRWRkc2FVc2VyU2lnbmluZ01hdGVyaWFsKEpTT04uc3RyaW5naWZ5KHsgYml0Z29ZU2hhcmUsIGJhY2t1cFlTaGFyZSB9KSksXG4gICAgICAgIC9taXNzaW5nIHVTaGFyZS9cbiAgICAgICk7XG4gICAgICBhc3NlcnQudGhyb3dzKFxuICAgICAgICAoKSA9PiBwYXJzZUVkZHNhVXNlclNpZ25pbmdNYXRlcmlhbChKU09OLnN0cmluZ2lmeSh7IHVTaGFyZSwgYmFja3VwWVNoYXJlIH0pKSxcbiAgICAgICAgL21pc3NpbmcgYml0Z29ZU2hhcmUvXG4gICAgICApO1xuICAgICAgYXNzZXJ0LnRocm93cyhcbiAgICAgICAgKCkgPT4gcGFyc2VFZGRzYVVzZXJTaWduaW5nTWF0ZXJpYWwoSlNPTi5zdHJpbmdpZnkoeyB1U2hhcmUsIGJpdGdvWVNoYXJlIH0pKSxcbiAgICAgICAgL21pc3NpbmcgYmFja3VwWVNoYXJlL1xuICAgICAgKTtcbiAgICB9KTtcblxuICAgIGl0KCdyZWplY3RzIGJhY2t1cC1zdHlsZSBtYXRlcmlhbDsgb25seSB1c2VyIHNpZ25pbmcgbWF0ZXJpYWwgaXMgYWNjZXB0ZWQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBhc3NlcnQudGhyb3dzKCgpID0+IHBhcnNlRWRkc2FVc2VyU2lnbmluZ01hdGVyaWFsKGJhY2t1cFN0eWxlUHJ2KSwgL21pc3NpbmcgYmFja3VwWVNoYXJlLyk7XG4gICAgfSk7XG5cbiAgICBpdCgncmVqZWN0cyBzaGFyZXMgdGhhdCBhcmUgbm90IHNoYXJlLXNoYXBlZCBvYmplY3RzJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgeyB1U2hhcmUsIGJpdGdvWVNoYXJlLCBiYWNrdXBZU2hhcmUgfSA9IHBhcnNlRWRkc2FVc2VyU2lnbmluZ01hdGVyaWFsKG1hdGNoaW5nUHJ2KTtcbiAgICAgIC8vIGFycmF5IHNoYXJlcyBhcmUgbWFsZm9ybWVkOyBudWxsIHNoYXJlcyBjb3VudCBhcyBtaXNzaW5nXG4gICAgICBhc3NlcnQudGhyb3dzKFxuICAgICAgICAoKSA9PiBwYXJzZUVkZHNhVXNlclNpZ25pbmdNYXRlcmlhbChKU09OLnN0cmluZ2lmeSh7IHVTaGFyZSwgYml0Z29ZU2hhcmU6IFtdLCBiYWNrdXBZU2hhcmUgfSkpLFxuICAgICAgICAvYml0Z29ZU2hhcmUgaXMgbm90IGEgdmFsaWQgc2hhcmUvXG4gICAgICApO1xuICAgICAgYXNzZXJ0LnRocm93cyhcbiAgICAgICAgKCkgPT4gcGFyc2VFZGRzYVVzZXJTaWduaW5nTWF0ZXJpYWwoSlNPTi5zdHJpbmdpZnkoeyB1U2hhcmUsIGJpdGdvWVNoYXJlOiBudWxsLCBiYWNrdXBZU2hhcmUgfSkpLFxuICAgICAgICAvbWlzc2luZyBiaXRnb1lTaGFyZS9cbiAgICAgICk7XG4gICAgICBhc3NlcnQudGhyb3dzKFxuICAgICAgICAoKSA9PiBwYXJzZUVkZHNhVXNlclNpZ25pbmdNYXRlcmlhbChKU09OLnN0cmluZ2lmeSh7IHVTaGFyZToge30sIGJpdGdvWVNoYXJlLCBiYWNrdXBZU2hhcmUgfSkpLFxuICAgICAgICAvdVNoYXJlIGlzIG5vdCBhIHZhbGlkIHNoYXJlL1xuICAgICAgKTtcbiAgICB9KTtcblxuICAgIGl0KCdyZWplY3RzIHNoYXJlcyB3aXRoIG1hbGZvcm1lZCBmaWVsZHMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBtYWxmb3JtZWQgPSBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgIHVTaGFyZTogeyBpOiAxLCB0OiAyLCBuOiAzLCB5OiAnbm90LWhleCcsIHNlZWQ6ICdhYicsIGNoYWluY29kZTogJ2NkJyB9LFxuICAgICAgICBiaXRnb1lTaGFyZTogeyBpOiAxLCBqOiAzLCB5OiAnYWInLCB1OiAnY2QnLCBjaGFpbmNvZGU6ICdlZicsIHY6ICcwMScgfSxcbiAgICAgICAgYmFja3VwWVNoYXJlOiB7IGk6IDEsIGo6IDIsIHk6ICdhYicsIHU6ICdjZCcsIGNoYWluY29kZTogJ2VmJyB9LFxuICAgICAgfSk7XG4gICAgICBhc3NlcnQudGhyb3dzKCgpID0+IHBhcnNlRWRkc2FVc2VyU2lnbmluZ01hdGVyaWFsKG1hbGZvcm1lZCksIC91U2hhcmUgaXMgbm90IGEgdmFsaWQgc2hhcmUvKTtcbiAgICB9KTtcblxuICAgIGl0KCdyZWplY3RzIGhleCBmaWVsZHMgb2YgdGhlIHdyb25nIGxlbmd0aCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHsgdVNoYXJlLCBiaXRnb1lTaGFyZSwgYmFja3VwWVNoYXJlIH0gPSBwYXJzZUVkZHNhVXNlclNpZ25pbmdNYXRlcmlhbChtYXRjaGluZ1Bydik7XG4gICAgICBjb25zdCB0cnVuY2F0ZWRDaGFpbmNvZGUgPSBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgIHVTaGFyZTogeyAuLi51U2hhcmUsIGNoYWluY29kZTogdVNoYXJlLmNoYWluY29kZS5zbGljZSgwLCA2MikgfSxcbiAgICAgICAgYml0Z29ZU2hhcmUsXG4gICAgICAgIGJhY2t1cFlTaGFyZSxcbiAgICAgIH0pO1xuICAgICAgYXNzZXJ0LnRocm93cygoKSA9PiBwYXJzZUVkZHNhVXNlclNpZ25pbmdNYXRlcmlhbCh0cnVuY2F0ZWRDaGFpbmNvZGUpLCAvdVNoYXJlIGlzIG5vdCBhIHZhbGlkIHNoYXJlLyk7XG4gICAgfSk7XG5cbiAgICBpdCgncmVqZWN0cyBhIG5vbi1oZXggdiBmaWVsZCBvbiBhIFkgc2hhcmUgd2hlbiBwcmVzZW50JywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgeyB1U2hhcmUsIGJpdGdvWVNoYXJlLCBiYWNrdXBZU2hhcmUgfSA9IHBhcnNlRWRkc2FVc2VyU2lnbmluZ01hdGVyaWFsKG1hdGNoaW5nUHJ2KTtcbiAgICAgIGNvbnN0IHRhbXBlcmVkID0gSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICB1U2hhcmUsXG4gICAgICAgIGJhY2t1cFlTaGFyZSxcbiAgICAgICAgYml0Z29ZU2hhcmU6IHsgLi4uYml0Z29ZU2hhcmUsIHY6ICd6eicgfSxcbiAgICAgIH0pO1xuICAgICAgYXNzZXJ0LnRocm93cygoKSA9PiBwYXJzZUVkZHNhVXNlclNpZ25pbmdNYXRlcmlhbCh0YW1wZXJlZCksIC9iaXRnb1lTaGFyZSBpcyBub3QgYSB2YWxpZCBzaGFyZS8pO1xuICAgIH0pO1xuXG4gICAgaXQoJ2FjY2VwdHMgYSBZIHNoYXJlIHdpdGhvdXQgdGhlIG9wdGlvbmFsIHYgZmllbGQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAvLyB2IGlzIG9wdGlvbmFsIG9uIHRoZSBZU2hhcmUgdHlwZSwgc28gcGFyc2luZyBtdXN0IGFsbG93IGl0OyB2ZXJpZmljYXRpb24gc2VwYXJhdGVseVxuICAgICAgLy8gcmVqZWN0cyBtYXRlcmlhbCB3aXRob3V0IGl0IHdpdGggYSBkaXN0aW5jdCB1bmFibGUtdG8tdmVyaWZ5IGVycm9yIChzZWUgYmVsb3cpXG4gICAgICBjb25zdCB7IHVTaGFyZSwgYml0Z29ZU2hhcmUsIGJhY2t1cFlTaGFyZSB9ID0gcGFyc2VFZGRzYVVzZXJTaWduaW5nTWF0ZXJpYWwobWF0Y2hpbmdQcnYpO1xuICAgICAgY29uc3Qgd2l0aG91dFYgPSB7IC4uLmJpdGdvWVNoYXJlIH07XG4gICAgICBkZWxldGUgd2l0aG91dFYudjtcbiAgICAgIGNvbnN0IHZsZXNzUHJ2ID0gSlNPTi5zdHJpbmdpZnkoeyB1U2hhcmUsIGJpdGdvWVNoYXJlOiB3aXRob3V0ViwgYmFja3VwWVNoYXJlIH0pO1xuICAgICAgY29uc3QgcGFyc2VkID0gcGFyc2VFZGRzYVVzZXJTaWduaW5nTWF0ZXJpYWwodmxlc3NQcnYpO1xuICAgICAgcGFyc2VkLmJpdGdvWVNoYXJlLnNob3VsZC5ub3QuaGF2ZS5wcm9wZXJ0eSgndicpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnZWRkc2FVc2VyU2lnbmluZ01hdGVyaWFsTWF0Y2hlc0NvbW1vbktleWNoYWluJywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdyZXR1cm5zIHRydWUgd2hlbiB0aGUgY29tYmluZWQga2V5IGVxdWFscyB0aGUgY29tbW9uS2V5Y2hhaW4nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBtYXRjaCA9IGF3YWl0IGVkZHNhVXNlclNpZ25pbmdNYXRlcmlhbE1hdGNoZXNDb21tb25LZXljaGFpbih7IHBydjogbWF0Y2hpbmdQcnYsIGNvbW1vbktleWNoYWluIH0pO1xuICAgICAgbWF0Y2guc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3JldHVybnMgZmFsc2UgZm9yIG1hdGVyaWFsIGZyb20gYSBkaWZmZXJlbnQga2V5IGdlbmVyYXRpb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBtYXRjaCA9IGF3YWl0IGVkZHNhVXNlclNpZ25pbmdNYXRlcmlhbE1hdGNoZXNDb21tb25LZXljaGFpbih7IHBydjogb3RoZXJQcnYsIGNvbW1vbktleWNoYWluIH0pO1xuICAgICAgbWF0Y2guc2hvdWxkLmVxdWFsKGZhbHNlKTtcbiAgICB9KTtcblxuICAgIGl0KCdyZWplY3RzIG1hbGZvcm1lZCBtYXRlcmlhbCB3aXRob3V0IGVjaG9pbmcgdGhlIGlucHV0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoZWRkc2FVc2VyU2lnbmluZ01hdGVyaWFsTWF0Y2hlc0NvbW1vbktleWNoYWluKHsgcHJ2OiAnbm90IGpzb24nLCBjb21tb25LZXljaGFpbiB9KSwge1xuICAgICAgICBtZXNzYWdlOiAnSW52YWxpZCB1c2VyIGtleSAtIGNvdWxkIG5vdCBwYXJzZSBzaWduaW5nIG1hdGVyaWFsJyxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3JlamVjdHMgaW5jb25zaXN0ZW50IHNoYXJlcyB3aXRoIGEgY29uc3RhbnQgZXJyb3IgaW5zdGVhZCBvZiB0aGUgcmF3IGNvbWJpbmUgZmFpbHVyZScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHsgdVNoYXJlLCBiaXRnb1lTaGFyZSwgYmFja3VwWVNoYXJlIH0gPSBwYXJzZUVkZHNhVXNlclNpZ25pbmdNYXRlcmlhbChtYXRjaGluZ1Bydik7XG4gICAgICBjb25zdCB0YW1wZXJlZCA9IEpTT04uc3RyaW5naWZ5KHtcbiAgICAgICAgdVNoYXJlLFxuICAgICAgICBiaXRnb1lTaGFyZSxcbiAgICAgICAgYmFja3VwWVNoYXJlOiB7IC4uLmJhY2t1cFlTaGFyZSwgdjogJzAwJy5yZXBlYXQoMzIpIH0sXG4gICAgICB9KTtcbiAgICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKGVkZHNhVXNlclNpZ25pbmdNYXRlcmlhbE1hdGNoZXNDb21tb25LZXljaGFpbih7IHBydjogdGFtcGVyZWQsIGNvbW1vbktleWNoYWluIH0pLCB7XG4gICAgICAgIG1lc3NhZ2U6ICdJbnZhbGlkIHVzZXIga2V5IC0gY291bGQgbm90IGNvbWJpbmUgc2lnbmluZyBtYXRlcmlhbCcsXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdyZXR1cm5zIGZhbHNlIGZvciBhIHdyb25nIHNlZWQgYmVoaW5kIG90aGVyd2lzZSBnZW51aW5lIHB1YmxpYyBmaWVsZHMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAvLyBrZXlDb21iaW5lIGRlcml2ZXMgdGhlIHByaXZhdGUgc2NhbGFyIGZyb20gdGhlIHNlZWQgYnV0IHJlYnVpbGRzIHRoZSBjb21tb24ga2V5Y2hhaW4gZnJvbVxuICAgICAgLy8gdGhlIGRlY2xhcmVkIHkgZmllbGRzLCBzbyB3aXRob3V0IGFuIGV4cGxpY2l0IHNlZWQveSBiaW5kaW5nIGEgY2FsbGVyIHdobyBrbm93cyBvbmx5IHRoZVxuICAgICAgLy8gcHVibGljIGNvbW1vbktleWNoYWluIGNvdWxkIHZlcmlmeSBhZ2FpbnN0IGEgc2VlZCB0aGV5IGRvIG5vdCBob2xkXG4gICAgICBjb25zdCB7IHVTaGFyZSwgYml0Z29ZU2hhcmUsIGJhY2t1cFlTaGFyZSB9ID0gcGFyc2VFZGRzYVVzZXJTaWduaW5nTWF0ZXJpYWwobWF0Y2hpbmdQcnYpO1xuICAgICAgY29uc3QgZm9yZ2VkID0gSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICB1U2hhcmU6IHsgLi4udVNoYXJlLCBzZWVkOiAnYWInLnJlcGVhdCgzMikgfSxcbiAgICAgICAgYml0Z29ZU2hhcmUsXG4gICAgICAgIGJhY2t1cFlTaGFyZSxcbiAgICAgIH0pO1xuICAgICAgY29uc3QgbWF0Y2ggPSBhd2FpdCBlZGRzYVVzZXJTaWduaW5nTWF0ZXJpYWxNYXRjaGVzQ29tbW9uS2V5Y2hhaW4oeyBwcnY6IGZvcmdlZCwgY29tbW9uS2V5Y2hhaW4gfSk7XG4gICAgICBtYXRjaC5zaG91bGQuZXF1YWwoZmFsc2UpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3JlamVjdHMgbWF0ZXJpYWwgdGhhdCBvbWl0cyBhIFZTUyBjb21taXRtZW50IGluc3RlYWQgb2YganVkZ2luZyBpdCBhIG5vbi1tYXRjaCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIC8vIGtleUNvbWJpbmUgb25seSB2ZXJpZmllcyBhIFkgc2hhcmUncyBzZWNyZXQgdSB3aGVuIHYgaXMgcHJlc2VudCwgc28gbWF0ZXJpYWwgdGhhdCBkcm9wc1xuICAgICAgLy8gdiB3b3VsZCBvdGhlcndpc2UgcGFzcyBjb21iaW5lIHdpdGggYW4gYXJiaXRyYXJ5IHU7IGl0IGNhbm5vdCBiZSB2ZXJpZmllZCBhdCBhbGwgYW5kXG4gICAgICAvLyBtdXN0IG5vdCBiZSByZXBvcnRlZCBhcyBhIGNsZWFuIG5vbi1tYXRjaFxuICAgICAgY29uc3QgeyB1U2hhcmUsIGJpdGdvWVNoYXJlLCBiYWNrdXBZU2hhcmUgfSA9IHBhcnNlRWRkc2FVc2VyU2lnbmluZ01hdGVyaWFsKG1hdGNoaW5nUHJ2KTtcbiAgICAgIGNvbnN0IGJpdGdvV2l0aG91dFYgPSB7IC4uLmJpdGdvWVNoYXJlLCB1OiAnY2QnLnJlcGVhdCgzMikgfTtcbiAgICAgIGRlbGV0ZSBiaXRnb1dpdGhvdXRWLnY7XG4gICAgICBjb25zdCBmb3JnZWQgPSBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgIHVTaGFyZSxcbiAgICAgICAgYml0Z29ZU2hhcmU6IGJpdGdvV2l0aG91dFYsXG4gICAgICAgIGJhY2t1cFlTaGFyZSxcbiAgICAgIH0pO1xuICAgICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoZWRkc2FVc2VyU2lnbmluZ01hdGVyaWFsTWF0Y2hlc0NvbW1vbktleWNoYWluKHsgcHJ2OiBmb3JnZWQsIGNvbW1vbktleWNoYWluIH0pLCB7XG4gICAgICAgIG1lc3NhZ2U6ICdVbmFibGUgdG8gdmVyaWZ5IGtleSAtIHNpZ25pbmcgbWF0ZXJpYWwgaGFzIG5vIFZTUyBjb21taXRtZW50JyxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3JlamVjdHMgb3RoZXJ3aXNlLWdlbnVpbmUgbWF0ZXJpYWwgd2l0aG91dCBhIFZTUyBjb21taXRtZW50IGFzIHVudmVyaWZpYWJsZScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIC8vIHNoYXJlcyB3aXRob3V0IHYgbWF5IGJlIGdlbnVpbmUgKHRoZSBzZXJ2ZXIgZGlkIG5vdCBhbHdheXMgcmV0dXJuIHZzc1Byb29mKSwgc28gdGhlXG4gICAgICAvLyBhbnN3ZXIgbXVzdCBiZSBcImNhbm5vdCB2ZXJpZnlcIiwgbmV2ZXIgXCJub3QgdGhpcyB3YWxsZXQncyBrZXlcIlxuICAgICAgY29uc3QgeyB1U2hhcmUsIGJpdGdvWVNoYXJlLCBiYWNrdXBZU2hhcmUgfSA9IHBhcnNlRWRkc2FVc2VyU2lnbmluZ01hdGVyaWFsKG1hdGNoaW5nUHJ2KTtcbiAgICAgIGNvbnN0IGJpdGdvV2l0aG91dFYgPSB7IC4uLmJpdGdvWVNoYXJlIH07XG4gICAgICBkZWxldGUgYml0Z29XaXRob3V0Vi52O1xuICAgICAgY29uc3Qgdmxlc3MgPSBKU09OLnN0cmluZ2lmeSh7IHVTaGFyZSwgYml0Z29ZU2hhcmU6IGJpdGdvV2l0aG91dFYsIGJhY2t1cFlTaGFyZSB9KTtcbiAgICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKGVkZHNhVXNlclNpZ25pbmdNYXRlcmlhbE1hdGNoZXNDb21tb25LZXljaGFpbih7IHBydjogdmxlc3MsIGNvbW1vbktleWNoYWluIH0pLCB7XG4gICAgICAgIG1lc3NhZ2U6ICdVbmFibGUgdG8gdmVyaWZ5IGtleSAtIHNpZ25pbmcgbWF0ZXJpYWwgaGFzIG5vIFZTUyBjb21taXRtZW50JyxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3JldHVybnMgZmFsc2Ugd2hlbiBhIFkgc2hhcmUgY2FycmllcyBhIG1pc21hdGNoZWQgc2VjcmV0IHdpdGggaXRzIGNvbW1pdG1lbnQgcHJlc2VudCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHsgdVNoYXJlLCBiaXRnb1lTaGFyZSwgYmFja3VwWVNoYXJlIH0gPSBwYXJzZUVkZHNhVXNlclNpZ25pbmdNYXRlcmlhbChtYXRjaGluZ1Bydik7XG4gICAgICBjb25zdCBmb3JnZWQgPSBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgIHVTaGFyZSxcbiAgICAgICAgYml0Z29ZU2hhcmU6IHsgLi4uYml0Z29ZU2hhcmUsIHU6ICdjZCcucmVwZWF0KDMyKSB9LFxuICAgICAgICBiYWNrdXBZU2hhcmUsXG4gICAgICB9KTtcbiAgICAgIC8vIGEgcHJlc2VudC1idXQtZmFpbGluZyBjb21taXRtZW50IGlzIGEgY29tYmluZSBmYWlsdXJlLCBzdXJmYWNlZCBhcyB0aGUgY29uc3RhbnQgZXJyb3JcbiAgICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKGVkZHNhVXNlclNpZ25pbmdNYXRlcmlhbE1hdGNoZXNDb21tb25LZXljaGFpbih7IHBydjogZm9yZ2VkLCBjb21tb25LZXljaGFpbiB9KSwge1xuICAgICAgICBtZXNzYWdlOiAnSW52YWxpZCB1c2VyIGtleSAtIGNvdWxkIG5vdCBjb21iaW5lIHNpZ25pbmcgbWF0ZXJpYWwnLFxuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xufSk7XG4iXX0=
@@ -0,0 +1,2 @@
1
+ import 'should';
2
+ //# sourceMappingURL=walletVerifyKey.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"walletVerifyKey.d.ts","sourceRoot":"","sources":["../../../../../test/unit/bitgo/wallet/walletVerifyKey.ts"],"names":[],"mappings":"AAEA,OAAO,QAAQ,CAAC"}
@@ -0,0 +1,160 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ const assert = __importStar(require("assert"));
40
+ const sinon = __importStar(require("sinon"));
41
+ require("should");
42
+ const wallet_1 = require("../../../../src/bitgo/wallet/wallet");
43
+ const sdk_lib_mpc_1 = require("@bitgo/sdk-lib-mpc");
44
+ const tss_1 = __importDefault(require("../../../../src/account-lib/mpc/tss"));
45
+ const bitgoPubKeys_1 = require("../../../../src/bitgo/tss/bitgoPubKeys");
46
+ const util_1 = require("../../../../src/bitgo/utils/util");
47
+ const UNSUPPORTED_WALLET_MESSAGE = 'Key verification is not supported for this wallet type';
48
+ describe('Wallet.verifyKey', function () {
49
+ let commonKeychain;
50
+ let matchingPrv;
51
+ let otherPrv;
52
+ before(async function () {
53
+ const hdTree = await sdk_lib_mpc_1.Ed25519Bip32HdTree.initialize();
54
+ const MPC = await tss_1.default.initialize(hdTree);
55
+ const userKeyShare = MPC.keyShare(1, 2, 3);
56
+ const backupKeyShare = MPC.keyShare(2, 2, 3);
57
+ const bitgoKeyShare = MPC.keyShare(3, 2, 3);
58
+ const combined = MPC.keyCombine(userKeyShare.uShare, [backupKeyShare.yShares[1], bitgoKeyShare.yShares[1]]);
59
+ commonKeychain = combined.pShare.y + combined.pShare.chaincode;
60
+ matchingPrv = JSON.stringify({
61
+ uShare: userKeyShare.uShare,
62
+ bitgoYShare: bitgoKeyShare.yShares[1],
63
+ backupYShare: backupKeyShare.yShares[1],
64
+ });
65
+ // an independent key generation for the negative case
66
+ const otherUserKeyShare = MPC.keyShare(1, 2, 3);
67
+ const otherBackupKeyShare = MPC.keyShare(2, 2, 3);
68
+ const otherBitgoKeyShare = MPC.keyShare(3, 2, 3);
69
+ otherPrv = JSON.stringify({
70
+ uShare: otherUserKeyShare.uShare,
71
+ bitgoYShare: otherBitgoKeyShare.yShares[1],
72
+ backupYShare: otherBackupKeyShare.yShares[1],
73
+ });
74
+ });
75
+ let mockBitGo;
76
+ let mockBaseCoin;
77
+ let walletData;
78
+ let getKeychainStub;
79
+ beforeEach(function () {
80
+ mockBitGo = {
81
+ post: sinon.stub(),
82
+ setRequestTracer: sinon.stub(),
83
+ // the MPCv2/ECDSA utils constructors call setBitgoGpgPubKey, which fetches constants;
84
+ // stubbing it avoids a swallowed unhandled rejection in those tests
85
+ fetchConstants: sinon.stub().resolves({
86
+ mpc: { bitgoPublicKey: (0, bitgoPubKeys_1.getBitgoMpcGpgPubKey)('test', 'nitro', 'mpcv1') },
87
+ }),
88
+ };
89
+ getKeychainStub = sinon.stub().resolves({ id: 'user-key-id', type: 'tss', commonKeychain });
90
+ mockBaseCoin = {
91
+ supportsTss: sinon.stub().returns(true),
92
+ getFamily: sinon.stub().returns('sol'),
93
+ getMPCAlgorithm: sinon.stub().returns('eddsa'),
94
+ keychains: sinon.stub().returns({ get: getKeychainStub }),
95
+ url: sinon.stub().returns('/api/v2/sol/wallet/test-wallet-id'),
96
+ };
97
+ walletData = {
98
+ id: 'test-wallet-id',
99
+ keys: ['user-key-id', 'backup-key-id', 'bitgo-key-id'],
100
+ multisigType: 'tss',
101
+ };
102
+ });
103
+ afterEach(function () {
104
+ sinon.restore();
105
+ });
106
+ /**
107
+ * Builds the wallet under test from the sinon stand-ins. The casts are safe because the
108
+ * Wallet constructor and verifyKey only touch the members stubbed above.
109
+ */
110
+ function buildWallet() {
111
+ return new wallet_1.Wallet(mockBitGo, mockBaseCoin, walletData);
112
+ }
113
+ it('returns match true for user signing material that belongs to the wallet', async function () {
114
+ const wallet = buildWallet();
115
+ const result = await wallet.verifyKey({ prv: matchingPrv });
116
+ assert.deepStrictEqual(result, { match: true });
117
+ sinon.assert.calledOnce(getKeychainStub);
118
+ assert.strictEqual(getKeychainStub.firstCall.args[0].id, walletData.keys[0]);
119
+ });
120
+ it('forwards the request tracer to the keychain fetch', async function () {
121
+ const wallet = buildWallet();
122
+ const reqId = new util_1.RequestTracer();
123
+ const result = await wallet.verifyKey({ prv: matchingPrv, reqId });
124
+ assert.deepStrictEqual(result, { match: true });
125
+ sinon.assert.calledOnce(getKeychainStub);
126
+ assert.strictEqual(getKeychainStub.firstCall.args[0].reqId, reqId);
127
+ });
128
+ it('returns match false for user signing material from a different key generation', async function () {
129
+ const wallet = buildWallet();
130
+ const result = await wallet.verifyKey({ prv: otherPrv });
131
+ assert.deepStrictEqual(result, { match: false });
132
+ sinon.assert.calledOnce(getKeychainStub);
133
+ });
134
+ it('rejects on-chain multisig wallets without fetching the keychain', async function () {
135
+ walletData.multisigType = 'onchain';
136
+ const wallet = buildWallet();
137
+ await assert.rejects(wallet.verifyKey({ prv: matchingPrv }), { message: UNSUPPORTED_WALLET_MESSAGE });
138
+ sinon.assert.notCalled(getKeychainStub);
139
+ });
140
+ it('rejects TSS EdDSA MPCv2 wallets without fetching the keychain', async function () {
141
+ walletData.multisigTypeVersion = 'MPCv2';
142
+ const wallet = buildWallet();
143
+ await assert.rejects(wallet.verifyKey({ prv: matchingPrv }), { message: UNSUPPORTED_WALLET_MESSAGE });
144
+ sinon.assert.notCalled(getKeychainStub);
145
+ });
146
+ it('rejects TSS ECDSA wallets without fetching the keychain', async function () {
147
+ mockBaseCoin.getMPCAlgorithm.returns('ecdsa');
148
+ const wallet = buildWallet();
149
+ await assert.rejects(wallet.verifyKey({ prv: matchingPrv }), { message: UNSUPPORTED_WALLET_MESSAGE });
150
+ sinon.assert.notCalled(getKeychainStub);
151
+ });
152
+ it('rejects when the user keychain has no commonKeychain', async function () {
153
+ getKeychainStub.resolves({ id: 'user-key-id', type: 'tss' });
154
+ const wallet = buildWallet();
155
+ await assert.rejects(wallet.verifyKey({ prv: matchingPrv }), {
156
+ message: 'wallet keychain is missing commonKeychain',
157
+ });
158
+ });
159
+ });
160
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2FsbGV0VmVyaWZ5S2V5LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vdGVzdC91bml0L2JpdGdvL3dhbGxldC93YWxsZXRWZXJpZnlLZXkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSwrQ0FBaUM7QUFDakMsNkNBQStCO0FBQy9CLGtCQUFnQjtBQUNoQixnRUFBNkQ7QUFDN0Qsb0RBQXdEO0FBQ3hELDhFQUF3RDtBQUd4RCx5RUFBOEU7QUFDOUUsMkRBQWlFO0FBRWpFLE1BQU0sMEJBQTBCLEdBQUcsd0RBQXdELENBQUM7QUFFNUYsUUFBUSxDQUFDLGtCQUFrQixFQUFFO0lBQzNCLElBQUksY0FBc0IsQ0FBQztJQUMzQixJQUFJLFdBQW1CLENBQUM7SUFDeEIsSUFBSSxRQUFnQixDQUFDO0lBRXJCLE1BQU0sQ0FBQyxLQUFLO1FBQ1YsTUFBTSxNQUFNLEdBQUcsTUFBTSxnQ0FBa0IsQ0FBQyxVQUFVLEVBQUUsQ0FBQztRQUNyRCxNQUFNLEdBQUcsR0FBRyxNQUFNLGFBQUssQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLENBQUM7UUFFM0MsTUFBTSxZQUFZLEdBQUcsR0FBRyxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQzNDLE1BQU0sY0FBYyxHQUFHLEdBQUcsQ0FBQyxRQUFRLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUM3QyxNQUFNLGFBQWEsR0FBRyxHQUFHLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDNUMsTUFBTSxRQUFRLEdBQUcsR0FBRyxDQUFDLFVBQVUsQ0FBQyxZQUFZLENBQUMsTUFBTSxFQUFFLENBQUMsY0FBYyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRSxhQUFhLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUM1RyxjQUFjLEdBQUcsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsUUFBUSxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUM7UUFDL0QsV0FBVyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUM7WUFDM0IsTUFBTSxFQUFFLFlBQVksQ0FBQyxNQUFNO1lBQzNCLFdBQVcsRUFBRSxhQUFhLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQztZQUNyQyxZQUFZLEVBQUUsY0FBYyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7U0FDeEMsQ0FBQyxDQUFDO1FBRUgsc0RBQXNEO1FBQ3RELE1BQU0saUJBQWlCLEdBQUcsR0FBRyxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQ2hELE1BQU0sbUJBQW1CLEdBQUcsR0FBRyxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQ2xELE1BQU0sa0JBQWtCLEdBQUcsR0FBRyxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQ2pELFFBQVEsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDO1lBQ3hCLE1BQU0sRUFBRSxpQkFBaUIsQ0FBQyxNQUFNO1lBQ2hDLFdBQVcsRUFBRSxrQkFBa0IsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDO1lBQzFDLFlBQVksRUFBRSxtQkFBbUIsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDO1NBQzdDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0lBRUgsSUFBSSxTQUF3RyxDQUFDO0lBQzdHLElBQUksWUFNSCxDQUFDO0lBQ0YsSUFBSSxVQUE4RixDQUFDO0lBQ25HLElBQUksZUFBZ0MsQ0FBQztJQUVyQyxVQUFVLENBQUM7UUFDVCxTQUFTLEdBQUc7WUFDVixJQUFJLEVBQUUsS0FBSyxDQUFDLElBQUksRUFBRTtZQUNsQixnQkFBZ0IsRUFBRSxLQUFLLENBQUMsSUFBSSxFQUFFO1lBQzlCLHNGQUFzRjtZQUN0RixvRUFBb0U7WUFDcEUsY0FBYyxFQUFFLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQyxRQUFRLENBQUM7Z0JBQ3BDLEdBQUcsRUFBRSxFQUFFLGNBQWMsRUFBRSxJQUFBLG1DQUFvQixFQUFDLE1BQU0sRUFBRSxPQUFPLEVBQUUsT0FBTyxDQUFDLEVBQUU7YUFDeEUsQ0FBQztTQUNILENBQUM7UUFFRixlQUFlLEdBQUcsS0FBSyxDQUFDLElBQUksRUFBRSxDQUFDLFFBQVEsQ0FBQyxFQUFFLEVBQUUsRUFBRSxhQUFhLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxjQUFjLEVBQUUsQ0FBQyxDQUFDO1FBRTVGLFlBQVksR0FBRztZQUNiLFdBQVcsRUFBRSxLQUFLLENBQUMsSUFBSSxFQUFFLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQztZQUN2QyxTQUFTLEVBQUUsS0FBSyxDQUFDLElBQUksRUFBRSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUM7WUFDdEMsZUFBZSxFQUFFLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDO1lBQzlDLFNBQVMsRUFBRSxLQUFLLENBQUMsSUFBSSxFQUFFLENBQUMsT0FBTyxDQUFDLEVBQUUsR0FBRyxFQUFFLGVBQWUsRUFBRSxDQUFDO1lBQ3pELEdBQUcsRUFBRSxLQUFLLENBQUMsSUFBSSxFQUFFLENBQUMsT0FBTyxDQUFDLG1DQUFtQyxDQUFDO1NBQy9ELENBQUM7UUFFRixVQUFVLEdBQUc7WUFDWCxFQUFFLEVBQUUsZ0JBQWdCO1lBQ3BCLElBQUksRUFBRSxDQUFDLGFBQWEsRUFBRSxlQUFlLEVBQUUsY0FBYyxDQUFDO1lBQ3RELFlBQVksRUFBRSxLQUFLO1NBQ3BCLENBQUM7SUFDSixDQUFDLENBQUMsQ0FBQztJQUVILFNBQVMsQ0FBQztRQUNSLEtBQUssQ0FBQyxPQUFPLEVBQUUsQ0FBQztJQUNsQixDQUFDLENBQUMsQ0FBQztJQUVIOzs7T0FHRztJQUNILFNBQVMsV0FBVztRQUNsQixPQUFPLElBQUksZUFBTSxDQUFDLFNBQWlDLEVBQUUsWUFBb0MsRUFBRSxVQUFVLENBQUMsQ0FBQztJQUN6RyxDQUFDO0lBRUQsRUFBRSxDQUFDLHlFQUF5RSxFQUFFLEtBQUs7UUFDakYsTUFBTSxNQUFNLEdBQUcsV0FBVyxFQUFFLENBQUM7UUFFN0IsTUFBTSxNQUFNLEdBQUcsTUFBTSxNQUFNLENBQUMsU0FBUyxDQUFDLEVBQUUsR0FBRyxFQUFFLFdBQVcsRUFBRSxDQUFDLENBQUM7UUFFNUQsTUFBTSxDQUFDLGVBQWUsQ0FBQyxNQUFNLEVBQUUsRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztRQUNoRCxLQUFLLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxlQUFlLENBQUMsQ0FBQztRQUN6QyxNQUFNLENBQUMsV0FBVyxDQUFDLGVBQWUsQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDL0UsQ0FBQyxDQUFDLENBQUM7SUFFSCxFQUFFLENBQUMsbURBQW1ELEVBQUUsS0FBSztRQUMzRCxNQUFNLE1BQU0sR0FBRyxXQUFXLEVBQUUsQ0FBQztRQUM3QixNQUFNLEtBQUssR0FBRyxJQUFJLG9CQUFhLEVBQUUsQ0FBQztRQUVsQyxNQUFNLE1BQU0sR0FBRyxNQUFNLE1BQU0sQ0FBQyxTQUFTLENBQUMsRUFBRSxHQUFHLEVBQUUsV0FBVyxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUM7UUFFbkUsTUFBTSxDQUFDLGVBQWUsQ0FBQyxNQUFNLEVBQUUsRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztRQUNoRCxLQUFLLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxlQUFlLENBQUMsQ0FBQztRQUN6QyxNQUFNLENBQUMsV0FBVyxDQUFDLGVBQWUsQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQztJQUNyRSxDQUFDLENBQUMsQ0FBQztJQUVILEVBQUUsQ0FBQywrRUFBK0UsRUFBRSxLQUFLO1FBQ3ZGLE1BQU0sTUFBTSxHQUFHLFdBQVcsRUFBRSxDQUFDO1FBRTdCLE1BQU0sTUFBTSxHQUFHLE1BQU0sTUFBTSxDQUFDLFNBQVMsQ0FBQyxFQUFFLEdBQUcsRUFBRSxRQUFRLEVBQUUsQ0FBQyxDQUFDO1FBRXpELE1BQU0sQ0FBQyxlQUFlLENBQUMsTUFBTSxFQUFFLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUM7UUFDakQsS0FBSyxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsZUFBZSxDQUFDLENBQUM7SUFDM0MsQ0FBQyxDQUFDLENBQUM7SUFFSCxFQUFFLENBQUMsaUVBQWlFLEVBQUUsS0FBSztRQUN6RSxVQUFVLENBQUMsWUFBWSxHQUFHLFNBQVMsQ0FBQztRQUNwQyxNQUFNLE1BQU0sR0FBRyxXQUFXLEVBQUUsQ0FBQztRQUU3QixNQUFNLE1BQU0sQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxFQUFFLEdBQUcsRUFBRSxXQUFXLEVBQUUsQ0FBQyxFQUFFLEVBQUUsT0FBTyxFQUFFLDBCQUEwQixFQUFFLENBQUMsQ0FBQztRQUN0RyxLQUFLLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxlQUFlLENBQUMsQ0FBQztJQUMxQyxDQUFDLENBQUMsQ0FBQztJQUVILEVBQUUsQ0FBQywrREFBK0QsRUFBRSxLQUFLO1FBQ3ZFLFVBQVUsQ0FBQyxtQkFBbUIsR0FBRyxPQUFPLENBQUM7UUFDekMsTUFBTSxNQUFNLEdBQUcsV0FBVyxFQUFFLENBQUM7UUFFN0IsTUFBTSxNQUFNLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsRUFBRSxHQUFHLEVBQUUsV0FBVyxFQUFFLENBQUMsRUFBRSxFQUFFLE9BQU8sRUFBRSwwQkFBMEIsRUFBRSxDQUFDLENBQUM7UUFDdEcsS0FBSyxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsZUFBZSxDQUFDLENBQUM7SUFDMUMsQ0FBQyxDQUFDLENBQUM7SUFFSCxFQUFFLENBQUMseURBQXlELEVBQUUsS0FBSztRQUNqRSxZQUFZLENBQUMsZUFBZSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUM5QyxNQUFNLE1BQU0sR0FBRyxXQUFXLEVBQUUsQ0FBQztRQUU3QixNQUFNLE1BQU0sQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxFQUFFLEdBQUcsRUFBRSxXQUFXLEVBQUUsQ0FBQyxFQUFFLEVBQUUsT0FBTyxFQUFFLDBCQUEwQixFQUFFLENBQUMsQ0FBQztRQUN0RyxLQUFLLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxlQUFlLENBQUMsQ0FBQztJQUMxQyxDQUFDLENBQUMsQ0FBQztJQUVILEVBQUUsQ0FBQyxzREFBc0QsRUFBRSxLQUFLO1FBQzlELGVBQWUsQ0FBQyxRQUFRLENBQUMsRUFBRSxFQUFFLEVBQUUsYUFBYSxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDO1FBQzdELE1BQU0sTUFBTSxHQUFHLFdBQVcsRUFBRSxDQUFDO1FBRTdCLE1BQU0sTUFBTSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLEVBQUUsR0FBRyxFQUFFLFdBQVcsRUFBRSxDQUFDLEVBQUU7WUFDM0QsT0FBTyxFQUFFLDJDQUEyQztTQUNyRCxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgYXNzZXJ0IGZyb20gJ2Fzc2VydCc7XG5pbXBvcnQgKiBhcyBzaW5vbiBmcm9tICdzaW5vbic7XG5pbXBvcnQgJ3Nob3VsZCc7XG5pbXBvcnQgeyBXYWxsZXQgfSBmcm9tICcuLi8uLi8uLi8uLi9zcmMvYml0Z28vd2FsbGV0L3dhbGxldCc7XG5pbXBvcnQgeyBFZDI1NTE5QmlwMzJIZFRyZWUgfSBmcm9tICdAYml0Z28vc2RrLWxpYi1tcGMnO1xuaW1wb3J0IEVkZHNhIGZyb20gJy4uLy4uLy4uLy4uL3NyYy9hY2NvdW50LWxpYi9tcGMvdHNzJztcbmltcG9ydCB7IEJpdEdvQmFzZSB9IGZyb20gJy4uLy4uLy4uLy4uL3NyYy9iaXRnby9iaXRnb0Jhc2UnO1xuaW1wb3J0IHsgSUJhc2VDb2luIH0gZnJvbSAnLi4vLi4vLi4vLi4vc3JjL2JpdGdvL2Jhc2VDb2luJztcbmltcG9ydCB7IGdldEJpdGdvTXBjR3BnUHViS2V5IH0gZnJvbSAnLi4vLi4vLi4vLi4vc3JjL2JpdGdvL3Rzcy9iaXRnb1B1YktleXMnO1xuaW1wb3J0IHsgUmVxdWVzdFRyYWNlciB9IGZyb20gJy4uLy4uLy4uLy4uL3NyYy9iaXRnby91dGlscy91dGlsJztcblxuY29uc3QgVU5TVVBQT1JURURfV0FMTEVUX01FU1NBR0UgPSAnS2V5IHZlcmlmaWNhdGlvbiBpcyBub3Qgc3VwcG9ydGVkIGZvciB0aGlzIHdhbGxldCB0eXBlJztcblxuZGVzY3JpYmUoJ1dhbGxldC52ZXJpZnlLZXknLCBmdW5jdGlvbiAoKSB7XG4gIGxldCBjb21tb25LZXljaGFpbjogc3RyaW5nO1xuICBsZXQgbWF0Y2hpbmdQcnY6IHN0cmluZztcbiAgbGV0IG90aGVyUHJ2OiBzdHJpbmc7XG5cbiAgYmVmb3JlKGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCBoZFRyZWUgPSBhd2FpdCBFZDI1NTE5QmlwMzJIZFRyZWUuaW5pdGlhbGl6ZSgpO1xuICAgIGNvbnN0IE1QQyA9IGF3YWl0IEVkZHNhLmluaXRpYWxpemUoaGRUcmVlKTtcblxuICAgIGNvbnN0IHVzZXJLZXlTaGFyZSA9IE1QQy5rZXlTaGFyZSgxLCAyLCAzKTtcbiAgICBjb25zdCBiYWNrdXBLZXlTaGFyZSA9IE1QQy5rZXlTaGFyZSgyLCAyLCAzKTtcbiAgICBjb25zdCBiaXRnb0tleVNoYXJlID0gTVBDLmtleVNoYXJlKDMsIDIsIDMpO1xuICAgIGNvbnN0IGNvbWJpbmVkID0gTVBDLmtleUNvbWJpbmUodXNlcktleVNoYXJlLnVTaGFyZSwgW2JhY2t1cEtleVNoYXJlLnlTaGFyZXNbMV0sIGJpdGdvS2V5U2hhcmUueVNoYXJlc1sxXV0pO1xuICAgIGNvbW1vbktleWNoYWluID0gY29tYmluZWQucFNoYXJlLnkgKyBjb21iaW5lZC5wU2hhcmUuY2hhaW5jb2RlO1xuICAgIG1hdGNoaW5nUHJ2ID0gSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgdVNoYXJlOiB1c2VyS2V5U2hhcmUudVNoYXJlLFxuICAgICAgYml0Z29ZU2hhcmU6IGJpdGdvS2V5U2hhcmUueVNoYXJlc1sxXSxcbiAgICAgIGJhY2t1cFlTaGFyZTogYmFja3VwS2V5U2hhcmUueVNoYXJlc1sxXSxcbiAgICB9KTtcblxuICAgIC8vIGFuIGluZGVwZW5kZW50IGtleSBnZW5lcmF0aW9uIGZvciB0aGUgbmVnYXRpdmUgY2FzZVxuICAgIGNvbnN0IG90aGVyVXNlcktleVNoYXJlID0gTVBDLmtleVNoYXJlKDEsIDIsIDMpO1xuICAgIGNvbnN0IG90aGVyQmFja3VwS2V5U2hhcmUgPSBNUEMua2V5U2hhcmUoMiwgMiwgMyk7XG4gICAgY29uc3Qgb3RoZXJCaXRnb0tleVNoYXJlID0gTVBDLmtleVNoYXJlKDMsIDIsIDMpO1xuICAgIG90aGVyUHJ2ID0gSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgdVNoYXJlOiBvdGhlclVzZXJLZXlTaGFyZS51U2hhcmUsXG4gICAgICBiaXRnb1lTaGFyZTogb3RoZXJCaXRnb0tleVNoYXJlLnlTaGFyZXNbMV0sXG4gICAgICBiYWNrdXBZU2hhcmU6IG90aGVyQmFja3VwS2V5U2hhcmUueVNoYXJlc1sxXSxcbiAgICB9KTtcbiAgfSk7XG5cbiAgbGV0IG1vY2tCaXRHbzogeyBwb3N0OiBzaW5vbi5TaW5vblN0dWI7IHNldFJlcXVlc3RUcmFjZXI6IHNpbm9uLlNpbm9uU3R1YjsgZmV0Y2hDb25zdGFudHM6IHNpbm9uLlNpbm9uU3R1YiB9O1xuICBsZXQgbW9ja0Jhc2VDb2luOiB7XG4gICAgc3VwcG9ydHNUc3M6IHNpbm9uLlNpbm9uU3R1YjtcbiAgICBnZXRGYW1pbHk6IHNpbm9uLlNpbm9uU3R1YjtcbiAgICBnZXRNUENBbGdvcml0aG06IHNpbm9uLlNpbm9uU3R1YjtcbiAgICBrZXljaGFpbnM6IHNpbm9uLlNpbm9uU3R1YjtcbiAgICB1cmw6IHNpbm9uLlNpbm9uU3R1YjtcbiAgfTtcbiAgbGV0IHdhbGxldERhdGE6IHsgaWQ6IHN0cmluZzsga2V5czogc3RyaW5nW107IG11bHRpc2lnVHlwZTogc3RyaW5nOyBtdWx0aXNpZ1R5cGVWZXJzaW9uPzogc3RyaW5nIH07XG4gIGxldCBnZXRLZXljaGFpblN0dWI6IHNpbm9uLlNpbm9uU3R1YjtcblxuICBiZWZvcmVFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICBtb2NrQml0R28gPSB7XG4gICAgICBwb3N0OiBzaW5vbi5zdHViKCksXG4gICAgICBzZXRSZXF1ZXN0VHJhY2VyOiBzaW5vbi5zdHViKCksXG4gICAgICAvLyB0aGUgTVBDdjIvRUNEU0EgdXRpbHMgY29uc3RydWN0b3JzIGNhbGwgc2V0Qml0Z29HcGdQdWJLZXksIHdoaWNoIGZldGNoZXMgY29uc3RhbnRzO1xuICAgICAgLy8gc3R1YmJpbmcgaXQgYXZvaWRzIGEgc3dhbGxvd2VkIHVuaGFuZGxlZCByZWplY3Rpb24gaW4gdGhvc2UgdGVzdHNcbiAgICAgIGZldGNoQ29uc3RhbnRzOiBzaW5vbi5zdHViKCkucmVzb2x2ZXMoe1xuICAgICAgICBtcGM6IHsgYml0Z29QdWJsaWNLZXk6IGdldEJpdGdvTXBjR3BnUHViS2V5KCd0ZXN0JywgJ25pdHJvJywgJ21wY3YxJykgfSxcbiAgICAgIH0pLFxuICAgIH07XG5cbiAgICBnZXRLZXljaGFpblN0dWIgPSBzaW5vbi5zdHViKCkucmVzb2x2ZXMoeyBpZDogJ3VzZXIta2V5LWlkJywgdHlwZTogJ3RzcycsIGNvbW1vbktleWNoYWluIH0pO1xuXG4gICAgbW9ja0Jhc2VDb2luID0ge1xuICAgICAgc3VwcG9ydHNUc3M6IHNpbm9uLnN0dWIoKS5yZXR1cm5zKHRydWUpLFxuICAgICAgZ2V0RmFtaWx5OiBzaW5vbi5zdHViKCkucmV0dXJucygnc29sJyksXG4gICAgICBnZXRNUENBbGdvcml0aG06IHNpbm9uLnN0dWIoKS5yZXR1cm5zKCdlZGRzYScpLFxuICAgICAga2V5Y2hhaW5zOiBzaW5vbi5zdHViKCkucmV0dXJucyh7IGdldDogZ2V0S2V5Y2hhaW5TdHViIH0pLFxuICAgICAgdXJsOiBzaW5vbi5zdHViKCkucmV0dXJucygnL2FwaS92Mi9zb2wvd2FsbGV0L3Rlc3Qtd2FsbGV0LWlkJyksXG4gICAgfTtcblxuICAgIHdhbGxldERhdGEgPSB7XG4gICAgICBpZDogJ3Rlc3Qtd2FsbGV0LWlkJyxcbiAgICAgIGtleXM6IFsndXNlci1rZXktaWQnLCAnYmFja3VwLWtleS1pZCcsICdiaXRnby1rZXktaWQnXSxcbiAgICAgIG11bHRpc2lnVHlwZTogJ3RzcycsXG4gICAgfTtcbiAgfSk7XG5cbiAgYWZ0ZXJFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICBzaW5vbi5yZXN0b3JlKCk7XG4gIH0pO1xuXG4gIC8qKlxuICAgKiBCdWlsZHMgdGhlIHdhbGxldCB1bmRlciB0ZXN0IGZyb20gdGhlIHNpbm9uIHN0YW5kLWlucy4gVGhlIGNhc3RzIGFyZSBzYWZlIGJlY2F1c2UgdGhlXG4gICAqIFdhbGxldCBjb25zdHJ1Y3RvciBhbmQgdmVyaWZ5S2V5IG9ubHkgdG91Y2ggdGhlIG1lbWJlcnMgc3R1YmJlZCBhYm92ZS5cbiAgICovXG4gIGZ1bmN0aW9uIGJ1aWxkV2FsbGV0KCk6IFdhbGxldCB7XG4gICAgcmV0dXJuIG5ldyBXYWxsZXQobW9ja0JpdEdvIGFzIHVua25vd24gYXMgQml0R29CYXNlLCBtb2NrQmFzZUNvaW4gYXMgdW5rbm93biBhcyBJQmFzZUNvaW4sIHdhbGxldERhdGEpO1xuICB9XG5cbiAgaXQoJ3JldHVybnMgbWF0Y2ggdHJ1ZSBmb3IgdXNlciBzaWduaW5nIG1hdGVyaWFsIHRoYXQgYmVsb25ncyB0byB0aGUgd2FsbGV0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IHdhbGxldCA9IGJ1aWxkV2FsbGV0KCk7XG5cbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB3YWxsZXQudmVyaWZ5S2V5KHsgcHJ2OiBtYXRjaGluZ1BydiB9KTtcblxuICAgIGFzc2VydC5kZWVwU3RyaWN0RXF1YWwocmVzdWx0LCB7IG1hdGNoOiB0cnVlIH0pO1xuICAgIHNpbm9uLmFzc2VydC5jYWxsZWRPbmNlKGdldEtleWNoYWluU3R1Yik7XG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKGdldEtleWNoYWluU3R1Yi5maXJzdENhbGwuYXJnc1swXS5pZCwgd2FsbGV0RGF0YS5rZXlzWzBdKTtcbiAgfSk7XG5cbiAgaXQoJ2ZvcndhcmRzIHRoZSByZXF1ZXN0IHRyYWNlciB0byB0aGUga2V5Y2hhaW4gZmV0Y2gnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3Qgd2FsbGV0ID0gYnVpbGRXYWxsZXQoKTtcbiAgICBjb25zdCByZXFJZCA9IG5ldyBSZXF1ZXN0VHJhY2VyKCk7XG5cbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB3YWxsZXQudmVyaWZ5S2V5KHsgcHJ2OiBtYXRjaGluZ1BydiwgcmVxSWQgfSk7XG5cbiAgICBhc3NlcnQuZGVlcFN0cmljdEVxdWFsKHJlc3VsdCwgeyBtYXRjaDogdHJ1ZSB9KTtcbiAgICBzaW5vbi5hc3NlcnQuY2FsbGVkT25jZShnZXRLZXljaGFpblN0dWIpO1xuICAgIGFzc2VydC5zdHJpY3RFcXVhbChnZXRLZXljaGFpblN0dWIuZmlyc3RDYWxsLmFyZ3NbMF0ucmVxSWQsIHJlcUlkKTtcbiAgfSk7XG5cbiAgaXQoJ3JldHVybnMgbWF0Y2ggZmFsc2UgZm9yIHVzZXIgc2lnbmluZyBtYXRlcmlhbCBmcm9tIGEgZGlmZmVyZW50IGtleSBnZW5lcmF0aW9uJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IHdhbGxldCA9IGJ1aWxkV2FsbGV0KCk7XG5cbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB3YWxsZXQudmVyaWZ5S2V5KHsgcHJ2OiBvdGhlclBydiB9KTtcblxuICAgIGFzc2VydC5kZWVwU3RyaWN0RXF1YWwocmVzdWx0LCB7IG1hdGNoOiBmYWxzZSB9KTtcbiAgICBzaW5vbi5hc3NlcnQuY2FsbGVkT25jZShnZXRLZXljaGFpblN0dWIpO1xuICB9KTtcblxuICBpdCgncmVqZWN0cyBvbi1jaGFpbiBtdWx0aXNpZyB3YWxsZXRzIHdpdGhvdXQgZmV0Y2hpbmcgdGhlIGtleWNoYWluJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgIHdhbGxldERhdGEubXVsdGlzaWdUeXBlID0gJ29uY2hhaW4nO1xuICAgIGNvbnN0IHdhbGxldCA9IGJ1aWxkV2FsbGV0KCk7XG5cbiAgICBhd2FpdCBhc3NlcnQucmVqZWN0cyh3YWxsZXQudmVyaWZ5S2V5KHsgcHJ2OiBtYXRjaGluZ1BydiB9KSwgeyBtZXNzYWdlOiBVTlNVUFBPUlRFRF9XQUxMRVRfTUVTU0FHRSB9KTtcbiAgICBzaW5vbi5hc3NlcnQubm90Q2FsbGVkKGdldEtleWNoYWluU3R1Yik7XG4gIH0pO1xuXG4gIGl0KCdyZWplY3RzIFRTUyBFZERTQSBNUEN2MiB3YWxsZXRzIHdpdGhvdXQgZmV0Y2hpbmcgdGhlIGtleWNoYWluJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgIHdhbGxldERhdGEubXVsdGlzaWdUeXBlVmVyc2lvbiA9ICdNUEN2Mic7XG4gICAgY29uc3Qgd2FsbGV0ID0gYnVpbGRXYWxsZXQoKTtcblxuICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKHdhbGxldC52ZXJpZnlLZXkoeyBwcnY6IG1hdGNoaW5nUHJ2IH0pLCB7IG1lc3NhZ2U6IFVOU1VQUE9SVEVEX1dBTExFVF9NRVNTQUdFIH0pO1xuICAgIHNpbm9uLmFzc2VydC5ub3RDYWxsZWQoZ2V0S2V5Y2hhaW5TdHViKTtcbiAgfSk7XG5cbiAgaXQoJ3JlamVjdHMgVFNTIEVDRFNBIHdhbGxldHMgd2l0aG91dCBmZXRjaGluZyB0aGUga2V5Y2hhaW4nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgbW9ja0Jhc2VDb2luLmdldE1QQ0FsZ29yaXRobS5yZXR1cm5zKCdlY2RzYScpO1xuICAgIGNvbnN0IHdhbGxldCA9IGJ1aWxkV2FsbGV0KCk7XG5cbiAgICBhd2FpdCBhc3NlcnQucmVqZWN0cyh3YWxsZXQudmVyaWZ5S2V5KHsgcHJ2OiBtYXRjaGluZ1BydiB9KSwgeyBtZXNzYWdlOiBVTlNVUFBPUlRFRF9XQUxMRVRfTUVTU0FHRSB9KTtcbiAgICBzaW5vbi5hc3NlcnQubm90Q2FsbGVkKGdldEtleWNoYWluU3R1Yik7XG4gIH0pO1xuXG4gIGl0KCdyZWplY3RzIHdoZW4gdGhlIHVzZXIga2V5Y2hhaW4gaGFzIG5vIGNvbW1vbktleWNoYWluJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgIGdldEtleWNoYWluU3R1Yi5yZXNvbHZlcyh7IGlkOiAndXNlci1rZXktaWQnLCB0eXBlOiAndHNzJyB9KTtcbiAgICBjb25zdCB3YWxsZXQgPSBidWlsZFdhbGxldCgpO1xuXG4gICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMod2FsbGV0LnZlcmlmeUtleSh7IHBydjogbWF0Y2hpbmdQcnYgfSksIHtcbiAgICAgIG1lc3NhZ2U6ICd3YWxsZXQga2V5Y2hhaW4gaXMgbWlzc2luZyBjb21tb25LZXljaGFpbicsXG4gICAgfSk7XG4gIH0pO1xufSk7XG4iXX0=