@lifeready/core 1.0.2 → 1.0.4

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 (225) hide show
  1. package/README.md +62 -62
  2. package/bundles/lifeready-core.umd.js +15445 -15445
  3. package/bundles/lifeready-core.umd.js.map +1 -1
  4. package/bundles/lifeready-core.umd.min.js.map +1 -1
  5. package/esm2015/lib/_common/ast.js +40 -40
  6. package/esm2015/lib/_common/deferred-promise.js +24 -24
  7. package/esm2015/lib/_common/exceptions.js +157 -157
  8. package/esm2015/lib/_common/queries.gql.js +190 -190
  9. package/esm2015/lib/_common/run-outside-angular.js +79 -79
  10. package/esm2015/lib/_common/types.js +1 -1
  11. package/esm2015/lib/_common/utils.js +44 -44
  12. package/esm2015/lib/api/contact-card.gql.js +79 -79
  13. package/esm2015/lib/api/contact-card.service.js +154 -154
  14. package/esm2015/lib/api/contact-card2.gql.js +60 -60
  15. package/esm2015/lib/api/contact-card2.service.js +103 -103
  16. package/esm2015/lib/api/file.service.js +74 -74
  17. package/esm2015/lib/api/item2.gql.js +110 -110
  18. package/esm2015/lib/api/item2.service.js +311 -311
  19. package/esm2015/lib/api/key-exchange.gql.js +188 -188
  20. package/esm2015/lib/api/key-exchange.service.js +442 -442
  21. package/esm2015/lib/api/key-exchange.types.js +18 -18
  22. package/esm2015/lib/api/key-exchange2.gql.js +171 -171
  23. package/esm2015/lib/api/key-exchange2.service.js +479 -479
  24. package/esm2015/lib/api/lock.gql.js +40 -40
  25. package/esm2015/lib/api/lock.service.js +64 -64
  26. package/esm2015/lib/api/lr-apollo.service.js +46 -46
  27. package/esm2015/lib/api/lr-graphql/index.js +6 -6
  28. package/esm2015/lib/api/lr-graphql/lr-graphql.service.js +155 -155
  29. package/esm2015/lib/api/lr-graphql/lr-merged-mutation.js +213 -213
  30. package/esm2015/lib/api/lr-graphql/lr-mutation-base.js +51 -51
  31. package/esm2015/lib/api/lr-graphql/lr-mutation.js +48 -48
  32. package/esm2015/lib/api/lr-graphql/lr.service.js +18 -18
  33. package/esm2015/lib/api/message.service.js +138 -138
  34. package/esm2015/lib/api/persist.service.js +181 -181
  35. package/esm2015/lib/api/query-processor/common-processors.service.js +93 -93
  36. package/esm2015/lib/api/query-processor/index.js +3 -3
  37. package/esm2015/lib/api/query-processor/query-processor.service.js +192 -192
  38. package/esm2015/lib/api/query-processor/tp-password-reset-processor.service.js +109 -109
  39. package/esm2015/lib/api/shared-contact-card.service.js +119 -119
  40. package/esm2015/lib/api/shared-contact-card2.gql.js +41 -41
  41. package/esm2015/lib/api/shared-contact-card2.service.js +117 -117
  42. package/esm2015/lib/api/time.service.js +146 -146
  43. package/esm2015/lib/api/types/graphql.types.js +7 -7
  44. package/esm2015/lib/api/types/index.js +3 -3
  45. package/esm2015/lib/api/types/lr-graphql.types.js +71 -71
  46. package/esm2015/lib/auth/auth.config.js +57 -57
  47. package/esm2015/lib/auth/auth.gql.js +48 -48
  48. package/esm2015/lib/auth/auth.types.js +27 -27
  49. package/esm2015/lib/auth/idle.service.js +168 -168
  50. package/esm2015/lib/auth/idle.types.js +7 -7
  51. package/esm2015/lib/auth/lbop.service.js +355 -355
  52. package/esm2015/lib/auth/life-ready-auth.service.js +500 -500
  53. package/esm2015/lib/auth/password.service.js +320 -320
  54. package/esm2015/lib/auth/register.service.js +172 -172
  55. package/esm2015/lib/auth/two-factor.service.js +74 -74
  56. package/esm2015/lib/category/category-meta.service.js +99 -99
  57. package/esm2015/lib/category/category.gql.js +406 -406
  58. package/esm2015/lib/category/category.service.js +390 -390
  59. package/esm2015/lib/category/category.types.js +29 -29
  60. package/esm2015/lib/cryptography/cryptography.types.js +11 -11
  61. package/esm2015/lib/cryptography/encryption.service.js +189 -189
  62. package/esm2015/lib/cryptography/key-factory.service.js +237 -237
  63. package/esm2015/lib/cryptography/key-graph.service.js +280 -280
  64. package/esm2015/lib/cryptography/key-meta.service.js +200 -200
  65. package/esm2015/lib/cryptography/key.service.js +124 -124
  66. package/esm2015/lib/cryptography/slip39.service.js +169 -169
  67. package/esm2015/lib/cryptography/web-crypto.service.js +29 -29
  68. package/esm2015/lib/life-ready.config.js +84 -84
  69. package/esm2015/lib/life-ready.module.js +74 -74
  70. package/esm2015/lib/plan/plan.gql.js +123 -123
  71. package/esm2015/lib/plan/plan.service.js +149 -149
  72. package/esm2015/lib/plan/plan.types.js +11 -11
  73. package/esm2015/lib/record/record-attachment.service.js +101 -101
  74. package/esm2015/lib/record/record.gql.js +179 -179
  75. package/esm2015/lib/record/record.service.js +206 -206
  76. package/esm2015/lib/record/record.types.js +15 -15
  77. package/esm2015/lib/record-type/record-type.service.js +75 -75
  78. package/esm2015/lib/record-type/record-type.types.js +28 -28
  79. package/esm2015/lib/scenario/approvals/scenario-approval.gql.js +105 -105
  80. package/esm2015/lib/scenario/approvals/scenario-approval.types.js +1 -1
  81. package/esm2015/lib/scenario/approvals/scenario-approver.service.js +300 -300
  82. package/esm2015/lib/scenario/claimants/scenario-claimant.gql.js +52 -52
  83. package/esm2015/lib/scenario/claimants/scenario-claimant.service.js +97 -97
  84. package/esm2015/lib/scenario/claimants/scenario-claimant.types.js +1 -1
  85. package/esm2015/lib/scenario/receivers/scenario-receiver.gql.js +150 -150
  86. package/esm2015/lib/scenario/receivers/scenario-receiver.service.js +229 -229
  87. package/esm2015/lib/scenario/receivers/scenario-receiver.types.js +1 -1
  88. package/esm2015/lib/scenario/scenario-setup.service.js +269 -269
  89. package/esm2015/lib/scenario/scenario.gql.js +368 -368
  90. package/esm2015/lib/scenario/scenario.service.js +611 -611
  91. package/esm2015/lib/scenario/scenario.types.js +64 -64
  92. package/esm2015/lib/search/search.gql.js +62 -62
  93. package/esm2015/lib/search/search.service.js +156 -156
  94. package/esm2015/lib/search/search.types.js +6 -6
  95. package/esm2015/lib/trusted-parties/tp-password-reset-request.service.js +112 -112
  96. package/esm2015/lib/trusted-parties/tp-password-reset-user.service.js +129 -129
  97. package/esm2015/lib/trusted-parties/tp-password-reset.constants.js +4 -4
  98. package/esm2015/lib/trusted-parties/tp-password-reset.gql.js +232 -232
  99. package/esm2015/lib/trusted-parties/tp-password-reset.service.js +299 -299
  100. package/esm2015/lib/trusted-parties/trusted-party.gql.js +148 -148
  101. package/esm2015/lib/trusted-parties/trusted-party.service.js +326 -326
  102. package/esm2015/lib/trusted-parties/trusted-party.types.js +41 -41
  103. package/esm2015/lib/trusted-parties/trusted-party2.gql.js +87 -87
  104. package/esm2015/lib/trusted-parties/trusted-party2.service.js +215 -215
  105. package/esm2015/lib/users/profile-details.service.js +214 -214
  106. package/esm2015/lib/users/profile.gql.js +97 -97
  107. package/esm2015/lib/users/profile.service.js +169 -169
  108. package/esm2015/lib/users/profile.types.js +34 -34
  109. package/esm2015/lib/users/user.gql.js +60 -60
  110. package/esm2015/lib/users/user.service.js +79 -79
  111. package/esm2015/lib/users/user.types.js +5 -5
  112. package/esm2015/lifeready-core.js +10 -10
  113. package/esm2015/public-api.js +81 -81
  114. package/fesm2015/lifeready-core.js +13088 -13088
  115. package/fesm2015/lifeready-core.js.map +1 -1
  116. package/lib/_common/ast.d.ts +11 -11
  117. package/lib/_common/deferred-promise.d.ts +12 -12
  118. package/lib/_common/exceptions.d.ts +109 -109
  119. package/lib/_common/queries.gql.d.ts +10 -10
  120. package/lib/_common/run-outside-angular.d.ts +14 -14
  121. package/lib/_common/types.d.ts +10 -10
  122. package/lib/_common/utils.d.ts +3 -3
  123. package/lib/api/contact-card.gql.d.ts +7 -7
  124. package/lib/api/contact-card.service.d.ts +52 -52
  125. package/lib/api/contact-card2.gql.d.ts +34 -34
  126. package/lib/api/contact-card2.service.d.ts +49 -49
  127. package/lib/api/file.service.d.ts +18 -18
  128. package/lib/api/item2.gql.d.ts +96 -96
  129. package/lib/api/item2.service.d.ts +177 -177
  130. package/lib/api/key-exchange.gql.d.ts +9 -9
  131. package/lib/api/key-exchange.service.d.ts +39 -39
  132. package/lib/api/key-exchange.types.d.ts +196 -196
  133. package/lib/api/key-exchange2.gql.d.ts +125 -125
  134. package/lib/api/key-exchange2.service.d.ts +187 -187
  135. package/lib/api/lock.gql.d.ts +27 -27
  136. package/lib/api/lock.service.d.ts +25 -25
  137. package/lib/api/lr-apollo.service.d.ts +15 -15
  138. package/lib/api/lr-graphql/index.d.ts +5 -5
  139. package/lib/api/lr-graphql/lr-graphql.service.d.ts +60 -60
  140. package/lib/api/lr-graphql/lr-merged-mutation.d.ts +27 -27
  141. package/lib/api/lr-graphql/lr-mutation-base.d.ts +28 -28
  142. package/lib/api/lr-graphql/lr-mutation.d.ts +8 -8
  143. package/lib/api/lr-graphql/lr.service.d.ts +9 -9
  144. package/lib/api/message.service.d.ts +58 -58
  145. package/lib/api/persist.service.d.ts +31 -31
  146. package/lib/api/query-processor/common-processors.service.d.ts +36 -36
  147. package/lib/api/query-processor/index.d.ts +2 -2
  148. package/lib/api/query-processor/query-processor.service.d.ts +18 -18
  149. package/lib/api/query-processor/tp-password-reset-processor.service.d.ts +15 -15
  150. package/lib/api/shared-contact-card.service.d.ts +33 -33
  151. package/lib/api/shared-contact-card2.gql.d.ts +36 -36
  152. package/lib/api/shared-contact-card2.service.d.ts +45 -45
  153. package/lib/api/time.service.d.ts +16 -16
  154. package/lib/api/types/graphql.types.d.ts +29 -29
  155. package/lib/api/types/index.d.ts +2 -2
  156. package/lib/api/types/lr-graphql.types.d.ts +385 -385
  157. package/lib/auth/auth.config.d.ts +5 -5
  158. package/lib/auth/auth.gql.d.ts +15 -15
  159. package/lib/auth/auth.types.d.ts +66 -66
  160. package/lib/auth/idle.service.d.ts +40 -40
  161. package/lib/auth/idle.types.d.ts +10 -10
  162. package/lib/auth/lbop.service.d.ts +91 -91
  163. package/lib/auth/life-ready-auth.service.d.ts +59 -59
  164. package/lib/auth/password.service.d.ts +78 -78
  165. package/lib/auth/register.service.d.ts +25 -25
  166. package/lib/auth/two-factor.service.d.ts +15 -15
  167. package/lib/category/category-meta.service.d.ts +23 -23
  168. package/lib/category/category.gql.d.ts +45 -45
  169. package/lib/category/category.service.d.ts +67 -67
  170. package/lib/category/category.types.d.ts +79 -79
  171. package/lib/cryptography/cryptography.types.d.ts +83 -83
  172. package/lib/cryptography/encryption.service.d.ts +41 -41
  173. package/lib/cryptography/key-factory.service.d.ts +38 -38
  174. package/lib/cryptography/key-graph.service.d.ts +33 -33
  175. package/lib/cryptography/key-meta.service.d.ts +44 -44
  176. package/lib/cryptography/key.service.d.ts +36 -36
  177. package/lib/cryptography/slip39.service.d.ts +43 -43
  178. package/lib/cryptography/web-crypto.service.d.ts +5 -5
  179. package/lib/life-ready.config.d.ts +14 -14
  180. package/lib/life-ready.module.d.ts +5 -5
  181. package/lib/plan/plan.gql.d.ts +11 -11
  182. package/lib/plan/plan.service.d.ts +33 -33
  183. package/lib/plan/plan.types.d.ts +31 -31
  184. package/lib/record/record-attachment.service.d.ts +16 -16
  185. package/lib/record/record.gql.d.ts +14 -14
  186. package/lib/record/record.service.d.ts +25 -25
  187. package/lib/record/record.types.d.ts +57 -57
  188. package/lib/record-type/record-type.service.d.ts +11 -11
  189. package/lib/record-type/record-type.types.d.ts +50 -50
  190. package/lib/scenario/approvals/scenario-approval.gql.d.ts +7 -7
  191. package/lib/scenario/approvals/scenario-approval.types.d.ts +63 -63
  192. package/lib/scenario/approvals/scenario-approver.service.d.ts +32 -32
  193. package/lib/scenario/claimants/scenario-claimant.gql.d.ts +5 -5
  194. package/lib/scenario/claimants/scenario-claimant.service.d.ts +17 -17
  195. package/lib/scenario/claimants/scenario-claimant.types.d.ts +18 -18
  196. package/lib/scenario/receivers/scenario-receiver.gql.d.ts +8 -8
  197. package/lib/scenario/receivers/scenario-receiver.service.d.ts +30 -30
  198. package/lib/scenario/receivers/scenario-receiver.types.d.ts +54 -54
  199. package/lib/scenario/scenario-setup.service.d.ts +22 -22
  200. package/lib/scenario/scenario.gql.d.ts +34 -34
  201. package/lib/scenario/scenario.service.d.ts +58 -58
  202. package/lib/scenario/scenario.types.d.ts +217 -217
  203. package/lib/search/search.gql.d.ts +1 -1
  204. package/lib/search/search.service.d.ts +25 -25
  205. package/lib/search/search.types.d.ts +20 -20
  206. package/lib/trusted-parties/tp-password-reset-request.service.d.ts +20 -20
  207. package/lib/trusted-parties/tp-password-reset-user.service.d.ts +35 -35
  208. package/lib/trusted-parties/tp-password-reset.constants.d.ts +3 -3
  209. package/lib/trusted-parties/tp-password-reset.gql.d.ts +218 -218
  210. package/lib/trusted-parties/tp-password-reset.service.d.ts +130 -130
  211. package/lib/trusted-parties/trusted-party.gql.d.ts +9 -9
  212. package/lib/trusted-parties/trusted-party.service.d.ts +44 -44
  213. package/lib/trusted-parties/trusted-party.types.d.ts +102 -102
  214. package/lib/trusted-parties/trusted-party2.gql.d.ts +79 -79
  215. package/lib/trusted-parties/trusted-party2.service.d.ts +114 -114
  216. package/lib/users/profile-details.service.d.ts +21 -21
  217. package/lib/users/profile.gql.d.ts +11 -11
  218. package/lib/users/profile.service.d.ts +35 -35
  219. package/lib/users/profile.types.d.ts +96 -96
  220. package/lib/users/user.gql.d.ts +9 -9
  221. package/lib/users/user.service.d.ts +12 -12
  222. package/lib/users/user.types.d.ts +23 -23
  223. package/lifeready-core.d.ts +9 -9
  224. package/package.json +1 -1
  225. package/public-api.d.ts +77 -77
@@ -1,479 +1,479 @@
1
- import { __awaiter, __decorate } from "tslib";
2
- import { Injectable, NgZone } from '@angular/core';
3
- import { EncryptionService, JoseSerialization, } from '../cryptography/encryption.service';
4
- import { KeyFactoryService } from '../cryptography/key-factory.service';
5
- import { KeyGraphService } from '../cryptography/key-graph.service';
6
- import { KeyService } from '../cryptography/key.service';
7
- import { LrCodeMismatchException } from '../_common/exceptions';
8
- import { RunOutsideAngular } from '../_common/run-outside-angular';
9
- import { UserService } from './../users/user.service';
10
- import { CancelKeyExchangeMutation, CompleteKeyExchangeOtkMutation, CurrentUserSharedKeyQuery2, DeclineKeyExchangeMutation, InitiateKeyExchangeOtkMutation, KeyExchangeQuery2, KeyExchangesQuery2, KeyExchangeTokenQuery2, RespondKeyExchangeOtkMutation, } from './key-exchange2.gql';
11
- import { LrGraphQLService, LrMutation } from './lr-graphql';
12
- import * as i0 from "@angular/core";
13
- import * as i1 from "../cryptography/key-factory.service";
14
- import * as i2 from "../cryptography/key.service";
15
- import * as i3 from "../cryptography/encryption.service";
16
- import * as i4 from "../users/user.service";
17
- import * as i5 from "../cryptography/key-graph.service";
18
- import * as i6 from "./lr-graphql/lr-graphql.service";
19
- let KeyExchange2Service = class KeyExchange2Service {
20
- constructor(ngZone, keyFactory, keyService, encryptionService, userService, keyGraph, lrGraphQL) {
21
- this.ngZone = ngZone;
22
- this.keyFactory = keyFactory;
23
- this.keyService = keyService;
24
- this.encryptionService = encryptionService;
25
- this.userService = userService;
26
- this.keyGraph = keyGraph;
27
- this.lrGraphQL = lrGraphQL;
28
- this.CLIENT_NONCE_LENGTH = 32;
29
- }
30
- getOtKey(keyExchange, otKeyK) {
31
- return __awaiter(this, void 0, void 0, function* () {
32
- if (otKeyK) {
33
- return yield KeyFactoryService.asKey(Object.assign(Object.assign({}, JSON.parse(keyExchange.otk.otKeyParams)), { k: otKeyK }));
34
- }
35
- else if (keyExchange.otk.state === 'OTK_INITIATED' &&
36
- !keyExchange.isInitiator &&
37
- keyExchange.otk.responderPbkCipher) {
38
- // Assuming existing user getting invited where OTK is wrapped in responder's public key.
39
- const prk = yield this.keyService.getCurrentPxk();
40
- const decryptedCipher = yield this.encryptionService.decrypt(prk.jwk, JSON.parse(keyExchange.otk.responderPbkCipher), {
41
- serializations: [JoseSerialization.COMPACT],
42
- });
43
- if (decryptedCipher.otKey) {
44
- return yield KeyFactoryService.asKey(decryptedCipher.otKey);
45
- }
46
- }
47
- return null;
48
- });
49
- }
50
- decryptOtk(keyExchange, otKeyK) {
51
- return __awaiter(this, void 0, void 0, function* () {
52
- const otKey = yield this.getOtKey(keyExchange, otKeyK);
53
- let otk = keyExchange.otk;
54
- if (otKey && otk.otKeyCipher) {
55
- otk = Object.assign(Object.assign({}, otk), { otKey, otKeyCipherClearJson: yield this.encryptionService.decrypt(otKey, keyExchange.otk.otKeyCipher) });
56
- }
57
- return Object.assign(Object.assign({}, keyExchange), { otk });
58
- });
59
- }
60
- decryptResponseCipher(otKey, otPrk, content) {
61
- return __awaiter(this, void 0, void 0, function* () {
62
- // The response could be wrapped by the OtK in addition to the OtPbk
63
- try {
64
- content = yield this.encryptionService.decrypt(otKey, content);
65
- }
66
- catch (error) {
67
- if (error.message !== 'no key found') {
68
- throw error;
69
- }
70
- // Do nothing to support older versions where message is not wrapped with otk.
71
- }
72
- // The Prk is single-use and only used to send information from the responder back to the initiator.
73
- return yield this.encryptionService.decrypt(otPrk, content);
74
- });
75
- }
76
- decryptKeyExchangeAsInitiator(keyExchange) {
77
- return __awaiter(this, void 0, void 0, function* () {
78
- const rootKey = yield this.keyService.getCurrentRootKey();
79
- // Decrypt using the root key to get the Prk
80
- const initiatorRootKeyCipherClearJson = (yield this.encryptionService.decrypt(rootKey.jwk, keyExchange.initiatorRootKeyCipher));
81
- const otKey = yield KeyFactoryService.asKey(initiatorRootKeyCipherClearJson.otKey);
82
- keyExchange = Object.assign(Object.assign({}, keyExchange), { initiatorRootKeyCipherClearJson });
83
- let otk = keyExchange.otk;
84
- if (otk.initiatorOneTimePbkCipher) {
85
- otk = Object.assign(Object.assign({}, otk), { initiatorOneTimePbkCipherClearJson: yield this.decryptResponseCipher(otKey, yield KeyFactoryService.asKey(initiatorRootKeyCipherClearJson.oneTimePrk), otk.initiatorOneTimePbkCipher) });
86
- }
87
- if (otk.otKeyCipher) {
88
- otk.otKeyCipherClearJson = yield this.encryptionService.decrypt(otKey, otk.otKeyCipher);
89
- }
90
- return Object.assign(Object.assign({}, keyExchange), { otk });
91
- });
92
- }
93
- decryptKeyExchangeAsResponder(keyExchange, otKeyK) {
94
- return __awaiter(this, void 0, void 0, function* () {
95
- return this.decryptOtk(keyExchange, otKeyK);
96
- });
97
- }
98
- decryptKeyExchange(keyExchange, otKeyK) {
99
- return __awaiter(this, void 0, void 0, function* () {
100
- if (keyExchange.isInitiator) {
101
- return this.decryptKeyExchangeAsInitiator(keyExchange);
102
- }
103
- else {
104
- return this.decryptKeyExchangeAsResponder(keyExchange, otKeyK);
105
- }
106
- });
107
- }
108
- getKeyExchanges({ state } = {}) {
109
- return __awaiter(this, void 0, void 0, function* () {
110
- const { keyExchanges } = yield this.lrGraphQL.query({
111
- query: KeyExchangesQuery2,
112
- variables: {
113
- state,
114
- },
115
- });
116
- return Promise.all(keyExchanges.edges.map((edge) => this.decryptKeyExchange(edge.node)));
117
- });
118
- }
119
- /**
120
- * @param id If the current user can responder the key exchange if they are either the initiator or the receiver.
121
- * @param token If not signed in, or not the initiator or responder, 'token' must be given.
122
- * @param otKeyK Is the raw one-time key (string). If the responder is explicitly specified at time of initiation, then
123
- * it's possible to have the otKey wrapped by the public key of the responder. In which case, the otKeyK is not needed.
124
- */
125
- getKeyExchange(id, { otKeyK, token } = {}) {
126
- return __awaiter(this, void 0, void 0, function* () {
127
- const res = yield this.lrGraphQL.query({
128
- query: token ? KeyExchangeTokenQuery2 : KeyExchangeQuery2,
129
- variables: {
130
- id,
131
- token,
132
- },
133
- includeKeyGraph: !token,
134
- });
135
- return this.decryptKeyExchange(res.keyExchange, otKeyK);
136
- });
137
- }
138
- getCurrentUserSharedKey(input) {
139
- return __awaiter(this, void 0, void 0, function* () {
140
- return this.lrGraphQL.query({
141
- query: CurrentUserSharedKeyQuery2,
142
- variables: {
143
- username: input.username,
144
- userId: input.userId,
145
- },
146
- });
147
- });
148
- }
149
- // TODO: deprecate this
150
- cancelKeyExchange(id) {
151
- return __awaiter(this, void 0, void 0, function* () {
152
- return this.cancelKeyExchangeMutation(id);
153
- });
154
- }
155
- cancelKeyExchangeMutation(id) {
156
- return new LrMutation({
157
- mutation: CancelKeyExchangeMutation,
158
- variables: {
159
- input: {
160
- id,
161
- },
162
- },
163
- });
164
- }
165
- // TODO: deprecate this
166
- declineKeyExchange(id, token) {
167
- return __awaiter(this, void 0, void 0, function* () {
168
- return this.declineKeyExchangeMutation(id, token);
169
- });
170
- }
171
- declineKeyExchangeMutation(id, token) {
172
- return new LrMutation({
173
- mutation: DeclineKeyExchangeMutation,
174
- variables: {
175
- input: {
176
- id,
177
- token,
178
- },
179
- },
180
- });
181
- }
182
- initiateOtk({ message, email, contactCard, upgrade, } = {}) {
183
- return __awaiter(this, void 0, void 0, function* () {
184
- const otKey = yield this.keyFactory.createKey();
185
- const nonce = this.keyFactory.randomString(this.CLIENT_NONCE_LENGTH);
186
- // New PKC key for encryption. This key is used only once when the responder sends
187
- // back their signing public key.
188
- const initiatorOneTimePrk = yield this.keyFactory.createPkcKey();
189
- // Option 1: New PKC key for signing
190
- // const initiatorSigPrk = await this.keyService.createPkcSignKey();
191
- // Option 2: Use the user's global signing key.
192
- // This key is used to prove the initiator's identity.
193
- const initiatorPrk = yield this.keyService.getCurrentPxk();
194
- const initiatorSigPrk = yield this.keyService.getCurrentSigPxk();
195
- let initiatorPlainDataSig = null;
196
- if (contactCard && contactCard.ownerPlainDataJson) {
197
- initiatorPlainDataSig = yield this.encryptionService.signToString(initiatorSigPrk.jwk, contactCard.ownerPlainDataJson);
198
- }
199
- const initiator = {
200
- message,
201
- contactCard: contactCard && {
202
- sharedCipherDataClearJson: contactCard.sharedCipherDataClearJson,
203
- },
204
- };
205
- // Content to be encrypted using the OTK.
206
- const plainOtKeyCipher = {
207
- // TODO Make sure we also put the OOB code in here as well since the OOB code is the
208
- // _only_ information the KC server does not have access to. The server may have
209
- // access to OTK and hence the nonce here. It's good to have both the nonce and OOB code
210
- // since the user may not be using the OOB code. And it's simple to always include
211
- // the nonce, so why not.
212
- nonce,
213
- initiator: Object.assign(Object.assign({}, initiator), { oneTimePbk: initiatorOneTimePrk.toJSON(), pbk: initiatorPrk.jwk.toJSON(), sigPbk: initiatorSigPrk.jwk.toJSON() }),
214
- };
215
- const otKeyCipher = yield this.keyGraph.encryptToString(otKey, plainOtKeyCipher);
216
- // Content to be encrypted using the initiator's root key.
217
- const initiatorRootKeyCipherClearJson = {
218
- nonce,
219
- oneTimePrk: initiatorOneTimePrk.toJSON(true),
220
- // Should not need to keep this encrypted since we are using the global signing key.
221
- // sigPrk: initiatorSigPrk.toJSON(true),
222
- // Save it in case the initiator want to decode the otKeyCipher.
223
- // Since the otKey is only used once, and that otKeyCipher contains only
224
- // the public key of the initiator, it's safe just leave the otKey stored here.
225
- otKey: otKey.toJSON(true),
226
- // These should be storing information such as how the fields of the shared contact card is
227
- // derived from the master contact card.
228
- initiatorContactCard: contactCard,
229
- initiator,
230
- };
231
- const rootKey = yield this.keyService.getCurrentRootKey();
232
- const initiatorRootKeyCipher = yield this.keyGraph.encryptToString(rootKey.jwk, initiatorRootKeyCipherClearJson);
233
- // The raw OTK
234
- const otKeyK = otKey.toJSON(true).k;
235
- // API call
236
- const lrMutation = new LrMutation({
237
- mutation: InitiateKeyExchangeOtkMutation,
238
- variables: {
239
- input: {
240
- // These will be stored on the server
241
- initiatorRootKeyCipher,
242
- initiatorPxkId: initiatorPrk.id,
243
- initiatorSigPxkId: initiatorSigPrk.id,
244
- // These will be sent to the responder
245
- otKeyParams: JSON.stringify(otKey.toJSON()),
246
- otKeyCipher,
247
- sendEmail: email && {
248
- email,
249
- rawOtKey: otKeyK,
250
- },
251
- createTp: true,
252
- initiatorPlainDataSig,
253
- upgrade,
254
- },
255
- },
256
- });
257
- return { lrMutation, otKeyK };
258
- });
259
- }
260
- respondOtk({ keyExchangeId, token, decryptedOtk, message, initiatorContactCard, responderContactCard, }) {
261
- return __awaiter(this, void 0, void 0, function* () {
262
- const rootKey = yield this.keyService.getCurrentRootKey();
263
- const masterKeyId = this.keyService.getCurrentMasterKey().id;
264
- const masterKey = yield this.keyService.getCurrentMasterKey();
265
- const sharedKey = yield this.keyFactory.createKey();
266
- const mkSharedKey = yield this.keyFactory.createKey();
267
- const rkWrappedSharedKey = yield this.encryptionService.encrypt(rootKey.jwk, sharedKey.toJSON(true));
268
- const mkWrappedMkSharedKey = yield this.encryptionService.encrypt(masterKey.jwk, mkSharedKey.toJSON(true));
269
- const initiatorOneTimePbk = yield KeyFactoryService.asKey(decryptedOtk.otKeyCipherClearJson.initiator.oneTimePbk);
270
- const initiatorPbk = yield KeyFactoryService.asKey(decryptedOtk.otKeyCipherClearJson.initiator.pbk);
271
- const initiatorSigPbk = yield KeyFactoryService.asKey(decryptedOtk.otKeyCipherClearJson.initiator.sigPbk);
272
- // Option 1: Using new Prk for each TP pair
273
- // Create a new public signing key for the responder.
274
- // const responderSigPrk = await this.keyService.createPkcSignKey()
275
- // const rkWrappedResponderSigPrk = await this.encrypt(rootKey, responderSigPrk.toJSON(true));
276
- // Option 2: Responder already has a signing Prk
277
- const responderPrk = yield this.keyService.getCurrentPxk();
278
- const responderSigPrk = yield this.keyService.getCurrentSigPxk();
279
- const signedInitiatorPbk = yield this.encryptionService.sign(responderSigPrk.jwk, initiatorPbk.toJSON());
280
- const signedInitiatorSigPbk = yield this.encryptionService.sign(responderSigPrk.jwk, initiatorSigPbk.toJSON());
281
- const initiatorOneTimePbkCipherClearJson = {
282
- nonce: decryptedOtk.otKeyCipherClearJson.nonce,
283
- sharedKey: sharedKey.toJSON(true),
284
- mkSharedKey: mkSharedKey.toJSON(true),
285
- responder: {
286
- pbk: responderPrk.jwk.toJSON(),
287
- sigPbk: responderSigPrk.jwk.toJSON(),
288
- message,
289
- },
290
- };
291
- let receivedCardInput;
292
- if (decryptedOtk.otKeyCipherClearJson.initiator.contactCard) {
293
- // Set the info about the initiator to be the ones sent by the initiator. We need th responder to do the encryption here
294
- // because the initiator does not have the shared key yet, and we want the responder to have a functional contact card after
295
- // this exchange. The initiator can double check the contact details are correct and sign it when it completes the exchange.
296
- const sharedCipherDataClearJson = decryptedOtk.otKeyCipherClearJson.initiator.contactCard
297
- .sharedCipherDataClearJson;
298
- // Create keys
299
- const receiverKey = yield this.keyFactory.createKey();
300
- const ccSharedKey = yield this.keyFactory.createKey();
301
- const sigPxk = yield this.keyService.getCurrentSigPxk();
302
- receivedCardInput = {
303
- receiverWrappedKey: JSON.stringify(yield this.encryptionService.encrypt(rootKey.jwk, receiverKey.toJSON(true))),
304
- receiverWrappingKeyId: rootKey.id,
305
- receiverCipherData: initiatorContactCard
306
- ? JSON.stringify(yield this.encryptionService.encrypt(receiverKey, initiatorContactCard.receiverCipherDataClearJson))
307
- : '',
308
- sharedWrappedKey: JSON.stringify(yield this.encryptionService.encrypt(sharedKey, ccSharedKey.toJSON(true))),
309
- };
310
- const sharedCipherData = yield this.encryptionService.encrypt(ccSharedKey, sharedCipherDataClearJson);
311
- receivedCardInput.sharedCipherDataSig = JSON.stringify(yield this.encryptionService.sign(sigPxk.jwk, sharedCipherData));
312
- receivedCardInput.sigPxkId = sigPxk.id;
313
- initiatorOneTimePbkCipherClearJson.responder.contactCard = Object.assign(Object.assign({}, initiatorOneTimePbkCipherClearJson.responder.contactCard), { sharedCipherKey: ccSharedKey.toJSON(true) });
314
- }
315
- let responderCardInput;
316
- if (responderContactCard) {
317
- // Create keys
318
- const ownerKey = yield this.keyFactory.createKey();
319
- const ccSharedKey = yield this.keyFactory.createKey();
320
- const sigPxk = yield this.keyService.getCurrentSigPxk();
321
- responderCardInput = {
322
- ownerWrappedKey: JSON.stringify(yield this.encryptionService.encrypt(rootKey.jwk, ownerKey.toJSON(true))),
323
- ownerWrappingKeyId: rootKey.id,
324
- ownerCipherData: responderContactCard.ownerCipherDataClearJson
325
- ? JSON.stringify(yield this.encryptionService.encrypt(ownerKey, responderContactCard.ownerCipherDataClearJson))
326
- : '',
327
- sharedWrappedKey: JSON.stringify(yield this.encryptionService.encrypt(sharedKey, ccSharedKey.toJSON(true))),
328
- };
329
- const sharedCipherData = yield this.encryptionService.encrypt(ccSharedKey, responderContactCard.sharedCipherDataClearJson);
330
- responderCardInput.sharedCipherDataSig = JSON.stringify(yield this.encryptionService.sign(sigPxk.jwk, sharedCipherData));
331
- responderCardInput.sigPxkId = sigPxk.id;
332
- if (responderContactCard.ownerPlainDataJson) {
333
- responderCardInput.ownerPlainDataSig = JSON.stringify(yield this.encryptionService.sign(responderSigPrk.jwk, responderContactCard.ownerPlainDataJson));
334
- }
335
- // Contact card info readable by the initiator
336
- initiatorOneTimePbkCipherClearJson.responder.contactCard = Object.assign(Object.assign({}, initiatorOneTimePbkCipherClearJson.responder.contactCard), { sharedCipherDataClearJson: responderContactCard.sharedCipherDataClearJson });
337
- }
338
- // Encrypt with one-time public key
339
- let initiatorOneTimePbkCipher = yield this.encryptionService.encrypt(initiatorOneTimePbk, initiatorOneTimePbkCipherClearJson);
340
- // Encrypt with the otk again to keep use of asymmetric keys to a minimum.
341
- initiatorOneTimePbkCipher = yield this.encryptionService.encrypt(decryptedOtk.otKey, initiatorOneTimePbkCipher);
342
- return new LrMutation({
343
- mutation: RespondKeyExchangeOtkMutation,
344
- variables: {
345
- input: {
346
- keyExchangeId,
347
- keyExchangeToken: token,
348
- rootKeyId: rootKey.id,
349
- masterKeyId,
350
- // These will be stored on the server
351
- responderPxkId: responderPrk.id,
352
- responderSigPxkId: responderSigPrk.id,
353
- signedInitiatorPbk: JSON.stringify(signedInitiatorPbk),
354
- signedInitiatorSigPbk: JSON.stringify(signedInitiatorSigPbk),
355
- // rkWrappedInitiatorSigPbk: JSON.stringify(rkWrappedInitiatorSigPbk),
356
- // Option 1: Using new Prk for each TP pair
357
- // rkWrappedResponderSigPrk: JSON.stringify(rkWrappedResponderSigPrk),
358
- rkWrappedSharedKey: JSON.stringify(rkWrappedSharedKey),
359
- mkWrappedMkSharedKey: JSON.stringify(mkWrappedMkSharedKey),
360
- // These will be sent to the initiator
361
- initiatorOneTimePbkCipher: JSON.stringify(initiatorOneTimePbkCipher),
362
- initiatorContactCard: receivedCardInput,
363
- responderContactCard: responderCardInput,
364
- },
365
- },
366
- });
367
- });
368
- }
369
- completeOtk({ keyExchangeId, initiatorRootKeyCipher, initiatorOneTimePbkCipher, responderContactCard, initiatorContactCard, }) {
370
- return __awaiter(this, void 0, void 0, function* () {
371
- const rootKey = yield this.keyService.getCurrentRootKey();
372
- const masterKey = yield this.keyService.getCurrentMasterKey();
373
- // Decrypt using the root key to get the Prk
374
- const initiatorRootKeyCipherClearJson = (yield this.encryptionService.decrypt(rootKey.jwk, initiatorRootKeyCipher));
375
- // The Prk is single-use and only used to send information from the responder back to the initiator.
376
- const plainInitiatorOneTimePbkCipher = yield this.decryptResponseCipher(yield KeyFactoryService.asKey(initiatorRootKeyCipherClearJson.otKey), yield KeyFactoryService.asKey(initiatorRootKeyCipherClearJson.oneTimePrk), initiatorOneTimePbkCipher);
377
- // Check the nonce match to ensure the responder was the one holding the OTK
378
- if (initiatorRootKeyCipherClearJson.nonce !==
379
- plainInitiatorOneTimePbkCipher.nonce) {
380
- throw new LrCodeMismatchException('The nonce returned by responder does not match with the one created by the initiator.');
381
- }
382
- // Option 1: Assuming the signing key is unique between users.
383
- // const initiatorSigPrk = await KFS.asKey(ke.plainInitiatorRootKeyCipher.sigPrk);
384
- // const rkWrappedInitiatorSigPrk = await this.encrypt(rootKey, initiatorSigPrk.toJSON(true));
385
- // Option 2: Use the user's global signing key.
386
- // In this case the initiatorSigPrk is already a part of the key graph.
387
- // So there's nothing to do here.
388
- // Protected the signing public key of the responder.
389
- const initiatorSigPrk = yield this.keyService.getCurrentSigPxk();
390
- const responderSigPbk = yield KeyFactoryService.asKey(plainInitiatorOneTimePbkCipher.responder.sigPbk);
391
- const responderPbk = yield KeyFactoryService.asKey(plainInitiatorOneTimePbkCipher.responder.pbk);
392
- const signedResponderPbk = yield this.encryptionService.sign(initiatorSigPrk.jwk, responderPbk.toJSON());
393
- const signedResponderSigPbk = yield this.encryptionService.sign(initiatorSigPrk.jwk, responderSigPbk.toJSON());
394
- const sharedKey = yield KeyFactoryService.asKey(plainInitiatorOneTimePbkCipher.sharedKey);
395
- const rkWrappedSharedKey = yield this.encryptionService.encrypt(rootKey.jwk, sharedKey.toJSON(true));
396
- const mkSharedKey = yield KeyFactoryService.asKey(plainInitiatorOneTimePbkCipher.mkSharedKey);
397
- const mkWrappedMkSharedKey = yield this.encryptionService.encrypt(masterKey.jwk, mkSharedKey.toJSON(true));
398
- let responderContactCardCipherInput;
399
- if (responderContactCard) {
400
- // Create key
401
- const receiverKey = yield this.keyFactory.createKey();
402
- responderContactCardCipherInput = {
403
- receiverWrappedKey: JSON.stringify(yield this.encryptionService.encrypt(rootKey.jwk, receiverKey.toJSON(true))),
404
- receiverWrappingKeyId: rootKey.id,
405
- receiverCipherData: JSON.stringify(yield this.encryptionService.encrypt(receiverKey, responderContactCard.receiverCipherDataClearJson)),
406
- };
407
- }
408
- // Get the data needed from the initiator's cipher data.
409
- let initiatorContactCardCipherInput;
410
- let initiatorContactCardSharedCipherInput;
411
- if (initiatorRootKeyCipherClearJson.initiatorContactCard) {
412
- // The initiatorContactCard created during the creation of the invite and encrypted using the initiator's
413
- // root key
414
- const initiatorContactCardFromInit = initiatorRootKeyCipherClearJson.initiatorContactCard;
415
- const ownerKey = yield this.keyFactory.createKey();
416
- const sharedCipherKey = yield KeyFactoryService.asKey(plainInitiatorOneTimePbkCipher.responder.contactCard.sharedCipherKey);
417
- const ownerWrappedKey = JSON.stringify(yield this.encryptionService.encrypt(rootKey.jwk, ownerKey.toJSON(true)));
418
- // Allow the initiatorContactCard parameter to override
419
- const ownerCipherDataClearJson = (initiatorContactCard === null || initiatorContactCard === void 0 ? void 0 : initiatorContactCard.ownerCipherDataClearJson) ||
420
- initiatorContactCardFromInit.ownerCipherDataClearJson;
421
- const ownerCipherData = ownerCipherDataClearJson
422
- ? yield this.keyGraph.encryptToString(ownerKey, ownerCipherDataClearJson)
423
- : '';
424
- initiatorContactCardCipherInput = {
425
- ownerWrappedKey,
426
- ownerWrappingKeyId: rootKey.id,
427
- ownerCipherData,
428
- };
429
- initiatorContactCardSharedCipherInput = {
430
- sigPxkId: initiatorSigPrk.id,
431
- };
432
- const sharedCipherData = yield this.encryptionService.encrypt(sharedCipherKey, initiatorContactCardFromInit.sharedCipherDataClearJson);
433
- initiatorContactCardSharedCipherInput.sharedCipherDataSig = JSON.stringify(yield this.encryptionService.sign(initiatorSigPrk.jwk, sharedCipherData));
434
- }
435
- // TODO ideally we update the shared data in the contact card sent to the responder as well since that
436
- // CC was created by the responder.
437
- return new LrMutation({
438
- mutation: CompleteKeyExchangeOtkMutation,
439
- variables: {
440
- input: {
441
- keyExchangeId,
442
- rootKeyId: rootKey.id,
443
- masterKeyId: masterKey.id,
444
- initiatorSigPxkId: initiatorSigPrk.id,
445
- signedResponderPbk: JSON.stringify(signedResponderPbk),
446
- signedResponderSigPbk: JSON.stringify(signedResponderSigPbk),
447
- rkWrappedSharedKey: JSON.stringify(rkWrappedSharedKey),
448
- mkWrappedMkSharedKey: JSON.stringify(mkWrappedMkSharedKey),
449
- responderContactCardCipher: responderContactCardCipherInput,
450
- initiatorContactCardCipher: initiatorContactCardCipherInput,
451
- initiatorContactCardSharedCipher: initiatorContactCardSharedCipherInput,
452
- },
453
- },
454
- });
455
- });
456
- }
457
- };
458
- KeyExchange2Service.ɵprov = i0.ɵɵdefineInjectable({ factory: function KeyExchange2Service_Factory() { return new KeyExchange2Service(i0.ɵɵinject(i0.NgZone), i0.ɵɵinject(i1.KeyFactoryService), i0.ɵɵinject(i2.KeyService), i0.ɵɵinject(i3.EncryptionService), i0.ɵɵinject(i4.UserService), i0.ɵɵinject(i5.KeyGraphService), i0.ɵɵinject(i6.LrGraphQLService)); }, token: KeyExchange2Service, providedIn: "root" });
459
- KeyExchange2Service.decorators = [
460
- { type: Injectable, args: [{
461
- providedIn: 'root',
462
- },] }
463
- ];
464
- KeyExchange2Service.ctorParameters = () => [
465
- { type: NgZone },
466
- { type: KeyFactoryService },
467
- { type: KeyService },
468
- { type: EncryptionService },
469
- { type: UserService },
470
- { type: KeyGraphService },
471
- { type: LrGraphQLService }
472
- ];
473
- KeyExchange2Service = __decorate([
474
- RunOutsideAngular({
475
- ngZoneName: 'ngZone',
476
- })
477
- ], KeyExchange2Service);
478
- export { KeyExchange2Service };
479
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoia2V5LWV4Y2hhbmdlMi5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6Ii9vcHQvYXRsYXNzaWFuL3BpcGVsaW5lcy9hZ2VudC9idWlsZC9wcm9qZWN0cy9jb3JlL3NyYy8iLCJzb3VyY2VzIjpbImxpYi9hcGkva2V5LWV4Y2hhbmdlMi5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUVuRCxPQUFPLEVBQ0wsaUJBQWlCLEVBQ2pCLGlCQUFpQixHQUNsQixNQUFNLG9DQUFvQyxDQUFDO0FBQzVDLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLHFDQUFxQyxDQUFDO0FBQ3hFLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxtQ0FBbUMsQ0FBQztBQUNwRSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFDekQsT0FBTyxFQUFFLHVCQUF1QixFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDaEUsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFDbkUsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBRXRELE9BQU8sRUFDTCx5QkFBeUIsRUFDekIsOEJBQThCLEVBQzlCLDBCQUEwQixFQUMxQiwwQkFBMEIsRUFDMUIsOEJBQThCLEVBRTlCLGlCQUFpQixFQUNqQixrQkFBa0IsRUFFbEIsc0JBQXNCLEVBQ3RCLDZCQUE2QixHQUM5QixNQUFNLHFCQUFxQixDQUFDO0FBQzdCLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxVQUFVLEVBQUUsTUFBTSxjQUFjLENBQUM7Ozs7Ozs7O0lBNkgvQyxtQkFBbUIsU0FBbkIsbUJBQW1CO0lBRzlCLFlBQ1UsTUFBYyxFQUNkLFVBQTZCLEVBQzdCLFVBQXNCLEVBQ3RCLGlCQUFvQyxFQUNwQyxXQUF3QixFQUN4QixRQUF5QixFQUN6QixTQUEyQjtRQU4zQixXQUFNLEdB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O0lBTi9CLGlCQUFpQixDQUFDO1FBQ2pCLFVBQVUsRUFBRSxRQUFRO0tBQ3JCLENBQUM7R0FJVyxtQkFBbUIsQ0FtdEIvQjtTQW50QlksbUJBQW1CIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSwgTmdab25lIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBKV0sgfSBmcm9tICdub2RlLWpvc2UnO1xuaW1wb3J0IHtcbiAgRW5jcnlwdGlvblNlcnZpY2UsXG4gIEpvc2VTZXJpYWxpemF0aW9uLFxufSBmcm9tICcuLi9jcnlwdG9ncmFwaHkvZW5jcnlwdGlvbi5zZXJ2aWNlJztcbmltcG9ydCB7IEtleUZhY3RvcnlTZXJ2aWNlIH0gZnJvbSAnLi4vY3J5cHRvZ3JhcGh5L2tleS1mYWN0b3J5LnNlcnZpY2UnO1xuaW1wb3J0IHsgS2V5R3JhcGhTZXJ2aWNlIH0gZnJvbSAnLi4vY3J5cHRvZ3JhcGh5L2tleS1ncmFwaC5zZXJ2aWNlJztcbmltcG9ydCB7IEtleVNlcnZpY2UgfSBmcm9tICcuLi9jcnlwdG9ncmFwaHkva2V5LnNlcnZpY2UnO1xuaW1wb3J0IHsgTHJDb2RlTWlzbWF0Y2hFeGNlcHRpb24gfSBmcm9tICcuLi9fY29tbW9uL2V4Y2VwdGlvbnMnO1xuaW1wb3J0IHsgUnVuT3V0c2lkZUFuZ3VsYXIgfSBmcm9tICcuLi9fY29tbW9uL3J1bi1vdXRzaWRlLWFuZ3VsYXInO1xuaW1wb3J0IHsgVXNlclNlcnZpY2UgfSBmcm9tICcuLy4uL3VzZXJzL3VzZXIuc2VydmljZSc7XG5pbXBvcnQgeyBPd25lclBsYWluRGF0YUpzb24gfSBmcm9tICcuL2NvbnRhY3QtY2FyZDIuc2VydmljZSc7XG5pbXBvcnQge1xuICBDYW5jZWxLZXlFeGNoYW5nZU11dGF0aW9uLFxuICBDb21wbGV0ZUtleUV4Y2hhbmdlT3RrTXV0YXRpb24sXG4gIEN1cnJlbnRVc2VyU2hhcmVkS2V5UXVlcnkyLFxuICBEZWNsaW5lS2V5RXhjaGFuZ2VNdXRhdGlvbixcbiAgSW5pdGlhdGVLZXlFeGNoYW5nZU90a011dGF0aW9uLFxuICBLZXlFeGNoYW5nZUZyYWdtZW50LFxuICBLZXlFeGNoYW5nZVF1ZXJ5MixcbiAgS2V5RXhjaGFuZ2VzUXVlcnkyLFxuICBLZXlFeGNoYW5nZVN0YXRlMixcbiAgS2V5RXhjaGFuZ2VUb2tlblF1ZXJ5MixcbiAgUmVzcG9uZEtleUV4Y2hhbmdlT3RrTXV0YXRpb24sXG59IGZyb20gJy4va2V5LWV4Y2hhbmdlMi5ncWwnO1xuaW1wb3J0IHsgTHJHcmFwaFFMU2VydmljZSwgTHJNdXRhdGlvbiB9IGZyb20gJy4vbHItZ3JhcGhxbCc7XG5pbXBvcnQgeyBDb250YWN0Q2FyZFNoYXJlZENpcGhlckRhdGEsIE90S2V5Q2lwaGVyQ2xlYXJKc29uMiB9IGZyb20gJy4vdHlwZXMnO1xuXG4vKipcbiAqIFRoZSBkZWNyeXB0ZWQgY29udGVudCBvZiB0aGUgb25lLXRpbWUga2V5IGNpcGhlcjtcbiAqIFdoZW4gdXNlciBzdXBwbGllcyB0aGlzIGluZm9ybWF0aW9uIHRoZSBsaWIgZG9lc24ndCBuZWVkIHRvIGRvIGFub3RoZXIgQVBJIGNhbGxcbiAqIHRvIGZldGNoIHRoZSBrZXkgZXhjaGFuZ2Ugbm9kZS4gQW5kIHNpbmNlIHRoZSB0eXBpY2FsIHVzZSBjYXNlIGlzIHRvIGRpc3BsYXlcbiAqIHNvbWUgaW5mb3JtYXRpb24gdG8gdGhlIHVzZXIsIHRoZSBrZXkgZXhjaGFuZ2Ugbm9kZSB3b3VsZCBhbHJlYWR5IGhhdmUgYmVlblxuICogZmV0Y2hlZCBhbmQgZGVjcnlwdGVkLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIERlY3J5cHRlZE90azIge1xuICBvdEtleUNpcGhlckNsZWFySnNvbjogT3RLZXlDaXBoZXJDbGVhckpzb24yO1xuICBvdEtleTogSldLLktleTsgLy8gVGhlIG9uZS10aW1lIGtleVxufVxuXG5leHBvcnQgaW50ZXJmYWNlIENvbnRhY3RDYXJkUmVjZWl2ZXJDaXBoZXJEYXRhIHtcbiAgLy8gVGhlIHJlY2VpdmVyIG9mIHRoZSBjb250YWN0IGNhcmQga2VlcHMgYSBjb3B5XG4gIC8vIG9mIHRoZSBvd25lcidzIGNvbnRhY3QgY2FyZCBpbmZvcm1hdGlvbiwgZW5jcnlwdGVkIHVzaW5nIHRoZSByZWNlaXZlcidzIGtleXMuIFNvIHRoYXQgd2hlblxuICAvLyB0aGUgb3duZXIgZGVjaWRlcyB0byB1cGRhdGUgdGhlaXIgc2hhcmVkIGNvbnRhY3QgY2FyZCBhdCBhIGxhdGVyIGRhdGUsIHRoZSByZWNlaXZlciBjYW5cbiAgLy8gY29tcGFyZSBhZ2FpbnN0IHRoZSBvcmlnaW5hbCBjb250YWN0IGNhcmQgc2VudCBkdXJpbmcga2V5IGV4Y2hhbmdlLiBUaGlzIHdheSwgdGhlIG93bmVyXG4gIC8vIGNhbid0IHVuaWxhdGVyYWxseSB1cGRhdGUgdGhlaXIgc2hhcmVkIGNvbnRhY3QgY2FyZCB3aXRob3V0IHRoZSByZWNlaXZlciBrbm93aW5nIGFib3V0IGl0LlxuICByZWNlaXZlckNpcGhlckRhdGFDbGVhckpzb246IGFueTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBDb250YWN0Q2FyZE93bmVyUGxhaW5EYXRhIHtcbiAgLy8gQWNjZXNzaWJsZSBieSB0aGUgc2VydmVyIGFuZCB0aGUgb3duZXIuIFNlcnZlciBzaWRlIG5vdGlmaWNhdGlvbiBlbWFpbHMgbmVlZCB0byBrbm93IHNvbWVcbiAgLy8gaW5mb3JtYXRpb24gYWJvdXQgdGhlIG93bmVyLlxuICAvLyBUaGUgb3duZXIgY291bGQgZWl0aGVyIGJlIHRoZSBpbml0aWF0b3Igb3IgdGhlIHJlc3BvbmRlci5cbiAgb3duZXJQbGFpbkRhdGFKc29uOiBPd25lclBsYWluRGF0YUpzb247XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ29udGFjdENhcmRPd25lckNpcGhlckRhdGEge1xuICAvLyBPd25lciBvbmx5IGFjY2VzcyB0byB0aGlzIGRhdGFcbiAgb3duZXJDaXBoZXJEYXRhQ2xlYXJKc29uOiBhbnk7XG59XG5cbi8qKlxuICogU2VuZGluZyBjb250YWN0IGNhcmQgaW5mb3JtYXRpb24gZnJvbSB0aGUgb3duZXIgdG8gdGhlIHJlY2VpdmVyLlxuICovXG5leHBvcnQgdHlwZSBTZW5kQ29udGFjdENhcmRJbnB1dCA9IENvbnRhY3RDYXJkT3duZXJQbGFpbkRhdGEgJlxuICBDb250YWN0Q2FyZE93bmVyQ2lwaGVyRGF0YSAmXG4gIENvbnRhY3RDYXJkU2hhcmVkQ2lwaGVyRGF0YTtcblxuZXhwb3J0IGludGVyZmFjZSBJbml0aWF0ZU90a0lucHV0MiB7XG4gIC8vIE5vdGUgdGhhdCBpZiBuZWl0aGVyIGVtYWlsIG5vciByZXNwb25kZXJVc2VybmFtZSBhcmUgZ2l2ZW4sIHRoZSBvbmUtdGltZSBrZXlcbiAgLy8gY2FuIHN0aWxsIGJlIHNlbnQgdG8gdGhlIHJlc3BvbmRlciB2aWEgT09CXG4gIGVtYWlsPzogc3RyaW5nO1xuICBtZXNzYWdlPzogYW55O1xuICBjb250YWN0Q2FyZD86IFNlbmRDb250YWN0Q2FyZElucHV0O1xuICAvLyBJZiBUcnVlLCB0byB1cGdyYWRlIGFuIGVtYWlsIGludml0ZSB0byBhbiBleGlzdGluZyB1c2VyIGludml0ZSBpZiB0aGUgZW1haWxcbiAgLy8gaXMgYWxyZWFkeSBhc3NvY2lhdGVkIHdpdGggYW4gZXhpc3RpbmcgdXNlci5cbiAgdXBncmFkZT86IGJvb2xlYW47XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUmVzcG9uZE90a0lucHV0MiB7XG4gIGtleUV4Y2hhbmdlSWQ6IHN0cmluZztcbiAgdG9rZW46IHN0cmluZztcbiAgZGVjcnlwdGVkT3RrOiBEZWNyeXB0ZWRPdGsyO1xuICBtZXNzYWdlPzogYW55O1xuICAvLyBUaGUgaW5pdGlhdG9yIGlzIHRoZSBvd25lciBmbyB0aGUgaW5pdGlhdG9yQ29udGFjdENhcmQsIHRoZSByZXNwb25kZXJcbiAgLy8gaXMgdGhlIHJlY2VpdmVyLlxuICBpbml0aWF0b3JDb250YWN0Q2FyZD86IENvbnRhY3RDYXJkUmVjZWl2ZXJDaXBoZXJEYXRhO1xuICByZXNwb25kZXJDb250YWN0Q2FyZD86IFNlbmRDb250YWN0Q2FyZElucHV0O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIENvbXBsZXRlT3RrSW5wdXQyIHtcbiAga2V5RXhjaGFuZ2VJZDogc3RyaW5nO1xuICAvLyBUaGlzIGlzIGEgcGFydCBvZiB0aGUga2V5IGV4Y2hhbmdlIGRhdGEuIEl0J3MgZW5jcnlwdGVkIHVzaW5nIHRoZSByb290IGtleVxuICBpbml0aWF0b3JSb290S2V5Q2lwaGVyOiBzdHJpbmc7XG4gIC8vIFRoaXMgaXMgYSBwYXJ0IG9mIHRoZSBrZXkgZXhjaGFuZ2UgZGF0YS4gSXQncyBlbmNyeXB0ZWQgdXNpbmcgdGhlIG9uZS10aW1lIGtleS5cbiAgaW5pdGlhdG9yT25lVGltZVBia0NpcGhlcjogc3RyaW5nO1xuICAvLyBUaGUgcmVzcG9uZGVyIGlzIHRoZSBvd25lciBmbyB0aGUgcmVzcG9uZGVyQ29udGFjdENhcmQsIHRoZSBpbml0aWF0b3JcbiAgLy8gaXMgdGhlIHJlY2VpdmVyLlxuICByZXNwb25kZXJDb250YWN0Q2FyZD86IENvbnRhY3RDYXJkUmVjZWl2ZXJDaXBoZXJEYXRhO1xuICAvLyBUaGUgaW5pdGlhdG9yIGNhbiB1cGRhdGUgdGhlIGNpcGhlciBkYXRhIHRoYXQgYXJlIG9ubHkgdmlzaWJsZSB0byB0aGVtLiBJdCBtYWtlc1xuICAvLyBsZXNzIHNlbnNlIHRvIHVwZGF0ZSB0aGUgc2hhcmVkIGRhdGEgYmVjYXVzZSB0aGUgcmVzcG9uZGVyIHdvdWxkIGhhdmUgYWxyZWFkeSBzZWVuXG4gIC8vIHRoZSBzaGFyZWQgZGF0YSBhbmQgYWNjZXB0ZWQgdGhhdCBpdCdzIGxlZ2l0LlxuICAvLyBCdXQgaW4gYW55IGNhc2UsIHRoZSBpbml0aWF0b3IgY2FuIHVwZGF0ZSB0aGUgc2hhcmVkIGNvbnRhY3QgY2FyZCBpbmZvIGF0IGFueSB0aW1lLlxuICBpbml0aWF0b3JDb250YWN0Q2FyZD86IENvbnRhY3RDYXJkT3duZXJDaXBoZXJEYXRhO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEluaXRpYXRvclJvb3RLZXlDaXBoZXJDbGVhckpzb24yIHtcbiAgbm9uY2U6IHN0cmluZztcbiAgb25lVGltZVByazogb2JqZWN0OyAvLyBvbmUtdGltZSBwdWJsaWMgZW5jcnlwdGlvbiBrZXkgcmVzcG9uZGVyIHVzZSB0byBzZW5kIGRhdGEgYmFjayB0byBpbml0aWF0b3JcbiAgb3RLZXk6IG9iamVjdDsgLy8gb25lLXRpbWUgc3ltbWV0cmljIGtleSB0aGF0IG5lZWRzIHRvIGJlIHNoYXJlZCBPT0JcbiAgaW5pdGlhdG9yQ29udGFjdENhcmQ/OiBDb250YWN0Q2FyZE93bmVyQ2lwaGVyRGF0YSAmXG4gICAgQ29udGFjdENhcmRTaGFyZWRDaXBoZXJEYXRhO1xuICBpbml0aWF0b3I6IHtcbiAgICBtZXNzYWdlPzogYW55O1xuICAgIGNvbnRhY3RDYXJkPzogQ29udGFjdENhcmRTaGFyZWRDaXBoZXJEYXRhO1xuICB9O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEluaXRpYXRvck9uZVRpbWVQYmtDaXBoZXJDbGVhckpzb24ge1xuICBub25jZTogc3RyaW5nO1xuICBzaGFyZWRLZXk6IG9iamVjdDtcbiAgbWtTaGFyZWRLZXk6IG9iamVjdDtcbiAgcmVzcG9uZGVyOiB7XG4gICAgcGJrOiBvYmplY3Q7XG4gICAgc2lnUGJrOiBvYmplY3Q7XG4gICAgbWVzc2FnZT86IGFueTtcbiAgICBjb250YWN0Q2FyZD86IENvbnRhY3RDYXJkU2hhcmVkQ2lwaGVyRGF0YSAmIHtcbiAgICAgIC8vIE5vdGUgdGhhdCB0aGlzIGlzIF9ub3RfIHRoZSBzYW1lIGtleSBhcyB0aGUgc2hhcmVkS2V5LiBUaGUgc2hhcmVkS2V5IHdyYXBzXG4gICAgICAvLyB0aGlzIGtleSBpbiB0aGUga2V5IGdyYXBoLiBCdXQgYmVjYXVzZSB0aGlzIGtleSBoYXMgbm90IGJlZW4gZW50ZXJlZCBpbnRvXG4gICAgICAvLyB0aGUga2V5IGdyYXBoIHdoZW4gdGhlIHJlc3BvbmRlciBjYWxscyB0aGUgQVBJLCB3ZSBwYXNzIHRoZSBKV0sgZGlyZWN0bHkgaGVyZS5cbiAgICAgIHNoYXJlZENpcGhlcktleTogb2JqZWN0O1xuICAgIH07XG4gIH07XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgR2V0S2V5RXhjaGFuZ2VPcHRpb25zMiB7XG4gIC8vIFRoZSBvdEtleSBhcyBhIHJhdyBzdHJpbmcuIGkuZS4ga2V5LnRvSlNPTih0cnVlKS5rXG4gIG90S2V5Sz86IHN0cmluZztcbiAgLy8gVXNlciBuZWVkIHRoZSB0b2tlbiBpZiB0aGV5IGhhdmUgbm90IHJlc3BvbmRlZCB0byB0aGUga2V5IGV4Y2hhbmdlIHlldC5cbiAgLy8gT25jZSB0aGV5J3ZlIHJlc3BvbmRlZCAoaGVuY2UgcHJvdmVuIHRoZXkgaGF2ZSB0aGUgT09CIEtleSkgdGhleSBiZWNvbWVcbiAgLy8gdGhlIFwicmVzcG9uZGVyXCIgb2YgdGhpcyBleGNoYW5nZSwgYW5kIGNhbiBhY2Nlc3MgaXQgd2hlbiBzaWduZWQgaW4uXG4gIHRva2VuPzogc3RyaW5nO1xufVxuXG5AUnVuT3V0c2lkZUFuZ3VsYXIoe1xuICBuZ1pvbmVOYW1lOiAnbmdab25lJyxcbn0pXG5ASW5qZWN0YWJsZSh7XG4gIHByb3ZpZGVkSW46ICdyb290Jyxcbn0pXG5leHBvcnQgY2xhc3MgS2V5RXhjaGFuZ2UyU2VydmljZSB7XG4gIHByaXZhdGUgcmVhZG9ubHkgQ0xJRU5UX05PTkNFX0xFTkdUSCA9IDMyO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgbmdab25lOiBOZ1pvbmUsXG4gICAgcHJpdmF0ZSBrZXlGYWN0b3J5OiBLZXlGYWN0b3J5U2VydmljZSxcbiAgICBwcml2YXRlIGtleVNlcnZpY2U6IEtleVNlcnZpY2UsXG4gICAgcHJpdmF0ZSBlbmNyeXB0aW9uU2VydmljZTogRW5jcnlwdGlvblNlcnZpY2UsXG4gICAgcHJpdmF0ZSB1c2VyU2VydmljZTogVXNlclNlcnZpY2UsXG4gICAgcHJpdmF0ZSBrZXlHcmFwaDogS2V5R3JhcGhTZXJ2aWNlLFxuICAgIHByaXZhdGUgbHJHcmFwaFFMOiBMckdyYXBoUUxTZXJ2aWNlXG4gICkge31cblxuICBwcml2YXRlIGFzeW5jIGdldE90S2V5KFxuICAgIGtleUV4Y2hhbmdlOiBLZXlFeGNoYW5nZUZyYWdtZW50LFxuICAgIG90S2V5Sz86IHN0cmluZ1xuICApOiBQcm9taXNlPEpXSy5LZXk+IHtcbiAgICBpZiAob3RLZXlLKSB7XG4gICAgICByZXR1cm4gYXdhaXQgS2V5RmFjdG9yeVNlcnZpY2UuYXNLZXkoe1xuICAgICAgICAuLi5KU09OLnBhcnNlKGtleUV4Y2hhbmdlLm90ay5vdEtleVBhcmFtcyksXG4gICAgICAgIGs6IG90S2V5SyxcbiAgICAgIH0pO1xuICAgIH0gZWxzZSBpZiAoXG4gICAgICBrZXlFeGNoYW5nZS5vdGsuc3RhdGUgPT09ICdPVEtfSU5JVElBVEVEJyAmJlxuICAgICAgIWtleUV4Y2hhbmdlLmlzSW5pdGlhdG9yICYmXG4gICAgICBrZXlFeGNoYW5nZS5vdGsucmVzcG9uZGVyUGJrQ2lwaGVyXG4gICAgKSB7XG4gICAgICAvLyBBc3N1bWluZyBleGlzdGluZyB1c2VyIGdldHRpbmcgaW52aXRlZCB3aGVyZSBPVEsgaXMgd3JhcHBlZCBpbiByZXNwb25kZXIncyBwdWJsaWMga2V5LlxuICAgICAgY29uc3QgcHJrID0gYXdhaXQgdGhpcy5rZXlTZXJ2aWNlLmdldEN1cnJlbnRQeGsoKTtcbiAgICAgIGNvbnN0IGRlY3J5cHRlZENpcGhlcjogYW55ID0gYXdhaXQgdGhpcy5lbmNyeXB0aW9uU2VydmljZS5kZWNyeXB0KFxuICAgICAgICBwcmsuandrLFxuICAgICAgICBKU09OLnBhcnNlKGtleUV4Y2hhbmdlLm90ay5yZXNwb25kZXJQYmtDaXBoZXIpLFxuICAgICAgICB7XG4gICAgICAgICAgc2VyaWFsaXphdGlvbnM6IFtKb3NlU2VyaWFsaXphdGlvbi5DT01QQUNUXSxcbiAgICAgICAgfVxuICAgICAgKTtcbiAgICAgIGlmIChkZWNyeXB0ZWRDaXBoZXIub3RLZXkpIHtcbiAgICAgICAgcmV0dXJuIGF3YWl0IEtleUZhY3RvcnlTZXJ2aWNlLmFzS2V5KGRlY3J5cHRlZENpcGhlci5vdEtleSk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBkZWNyeXB0T3RrKFxuICAgIGtleUV4Y2hhbmdlOiBLZXlFeGNoYW5nZUZyYWdtZW50LFxuICAgIG90S2V5Sz86IHN0cmluZ1xuICApOiBQcm9taXNlPEtleUV4Y2hhbmdlRnJhZ21lbnQ+IHtcbiAgICBjb25zdCBvdEtleSA9IGF3YWl0IHRoaXMuZ2V0T3RLZXkoa2V5RXhjaGFuZ2UsIG90S2V5Syk7XG5cbiAgICBsZXQgb3RrID0ga2V5RXhjaGFuZ2Uub3RrO1xuXG4gICAgaWYgKG90S2V5ICYmIG90ay5vdEtleUNpcGhlcikge1xuICAgICAgb3RrID0ge1xuICAgICAgICAuLi5vdGssXG4gICAgICAgIG90S2V5LFxuICAgICAgICBvdEtleUNpcGhlckNsZWFySnNvbjogYXdhaXQgdGhpcy5lbmNyeXB0aW9uU2VydmljZS5kZWNyeXB0KFxuICAgICAgICAgIG90S2V5LFxuICAgICAgICAgIGtleUV4Y2hhbmdlLm90ay5vdEtleUNpcGhlclxuICAgICAgICApLFxuICAgICAgfTtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgLi4ua2V5RXhjaGFuZ2UsXG4gICAgICBvdGssXG4gICAgfTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgZGVjcnlwdFJlc3BvbnNlQ2lwaGVyKFxuICAgIG90S2V5OiBKV0suS2V5LFxuICAgIG90UHJrOiBKV0suS2V5LFxuICAgIGNvbnRlbnQ6IGFueVxuICApOiBQcm9taXNlPEluaXRpYXRvck9uZVRpbWVQYmtDaXBoZXJDbGVhckpzb24+IHtcbiAgICAvLyBUaGUgcmVzcG9uc2UgY291bGQgYmUgd3JhcHBlZCBieSB0aGUgT3RLIGluIGFkZGl0aW9uIHRvIHRoZSBPdFBia1xuICAgIHRyeSB7XG4gICAgICBjb250ZW50ID0gYXdhaXQgdGhpcy5lbmNyeXB0aW9uU2VydmljZS5kZWNyeXB0KG90S2V5LCBjb250ZW50KTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgaWYgKGVycm9yLm1lc3NhZ2UgIT09ICdubyBrZXkgZm91bmQnKSB7XG4gICAgICAgIHRocm93IGVycm9yO1xuICAgICAgfVxuICAgICAgLy8gRG8gbm90aGluZyB0byBzdXBwb3J0IG9sZGVyIHZlcnNpb25zIHdoZXJlIG1lc3NhZ2UgaXMgbm90IHdyYXBwZWQgd2l0aCBvdGsuXG4gICAgfVxuXG4gICAgLy8gVGhlIFByayBpcyBzaW5nbGUtdXNlIGFuZCBvbmx5IHVzZWQgdG8gc2VuZCBpbmZvcm1hdGlvbiBmcm9tIHRoZSByZXNwb25kZXIgYmFjayB0byB0aGUgaW5pdGlhdG9yLlxuICAgIHJldHVybiBhd2FpdCB0aGlzLmVuY3J5cHRpb25TZXJ2aWNlLmRlY3J5cHQob3RQcmssIGNvbnRlbnQpO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBkZWNyeXB0S2V5RXhjaGFuZ2VBc0luaXRpYXRvcihcbiAgICBrZXlFeGNoYW5nZTogS2V5RXhjaGFuZ2VGcmFnbWVudFxuICApOiBQcm9taXNlPEtleUV4Y2hhbmdlRnJhZ21lbnQ+IHtcbiAgICBjb25zdCByb290S2V5ID0gYXdhaXQgdGhpcy5rZXlTZXJ2aWNlLmdldEN1cnJlbnRSb290S2V5KCk7XG5cbiAgICAvLyBEZWNyeXB0IHVzaW5nIHRoZSByb290IGtleSB0byBnZXQgdGhlIFBya1xuICAgIGNvbnN0IGluaXRpYXRvclJvb3RLZXlDaXBoZXJDbGVhckpzb24gPSAoYXdhaXQgdGhpcy5lbmNyeXB0aW9uU2VydmljZS5kZWNyeXB0KFxuICAgICAgcm9vdEtleS5qd2ssXG4gICAgICBrZXlFeGNoYW5nZS5pbml0aWF0b3JSb290S2V5Q2lwaGVyXG4gICAgKSkgYXMgSW5pdGlhdG9yUm9vdEtleUNpcGhlckNsZWFySnNvbjI7XG5cbiAgICBjb25zdCBvdEtleSA9IGF3YWl0IEtleUZhY3RvcnlTZXJ2aWNlLmFzS2V5KFxuICAgICAgaW5pdGlhdG9yUm9vdEtleUNpcGhlckNsZWFySnNvbi5vdEtleVxuICAgICk7XG5cbiAgICBrZXlFeGNoYW5nZSA9IHtcbiAgICAgIC4uLmtleUV4Y2hhbmdlLFxuICAgICAgaW5pdGlhdG9yUm9vdEtleUNpcGhlckNsZWFySnNvbixcbiAgICB9O1xuXG4gICAgbGV0IG90ayA9IGtleUV4Y2hhbmdlLm90aztcblxuICAgIGlmIChvdGsuaW5pdGlhdG9yT25lVGltZVBia0NpcGhlcikge1xuICAgICAgb3RrID0ge1xuICAgICAgICAuLi5vdGssXG4gICAgICAgIGluaXRpYXRvck9uZVRpbWVQYmtDaXBoZXJDbGVhckpzb246IGF3YWl0IHRoaXMuZGVjcnlwdFJlc3BvbnNlQ2lwaGVyKFxuICAgICAgICAgIG90S2V5LFxuICAgICAgICAgIGF3YWl0IEtleUZhY3RvcnlTZXJ2aWNlLmFzS2V5KFxuICAgICAgICAgICAgaW5pdGlhdG9yUm9vdEtleUNpcGhlckNsZWFySnNvbi5vbmVUaW1lUHJrXG4gICAgICAgICAgKSxcbiAgICAgICAgICBvdGsuaW5pdGlhdG9yT25lVGltZVBia0NpcGhlclxuICAgICAgICApLFxuICAgICAgfTtcbiAgICB9XG5cbiAgICBpZiAob3RrLm90S2V5Q2lwaGVyKSB7XG4gICAgICBvdGsub3RLZXlDaXBoZXJDbGVhckpzb24gPSBhd2FpdCB0aGlzLmVuY3J5cHRpb25TZXJ2aWNlLmRlY3J5cHQoXG4gICAgICAgIG90S2V5LFxuICAgICAgICBvdGsub3RLZXlDaXBoZXJcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLmtleUV4Y2hhbmdlLFxuICAgICAgb3RrLFxuICAgIH07XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGRlY3J5cHRLZXlFeGNoYW5nZUFzUmVzcG9uZGVyKFxuICAgIGtleUV4Y2hhbmdlOiBLZXlFeGNoYW5nZUZyYWdtZW50LFxuICAgIG90S2V5Sz86IHN0cmluZ1xuICApIHtcbiAgICByZXR1cm4gdGhpcy5kZWNyeXB0T3RrKGtleUV4Y2hhbmdlLCBvdEtleUspO1xuICB9XG5cbiAgYXN5bmMgZGVjcnlwdEtleUV4Y2hhbmdlKGtleUV4Y2hhbmdlOiBLZXlFeGNoYW5nZUZyYWdtZW50LCBvdEtleUs/OiBzdHJpbmcpIHtcbiAgICBpZiAoa2V5RXhjaGFuZ2UuaXNJbml0aWF0b3IpIHtcbiAgICAgIHJldHVybiB0aGlzLmRlY3J5cHRLZXlFeGNoYW5nZUFzSW5pdGlhdG9yKGtleUV4Y2hhbmdlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHRoaXMuZGVjcnlwdEtleUV4Y2hhbmdlQXNSZXNwb25kZXIoa2V5RXhjaGFuZ2UsIG90S2V5Syk7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgZ2V0S2V5RXhjaGFuZ2VzKHsgc3RhdGUgfTogeyBzdGF0ZT86IEtleUV4Y2hhbmdlU3RhdGUyIH0gPSB7fSkge1xuICAgIGNvbnN0IHsga2V5RXhjaGFuZ2VzIH0gPSBhd2FpdCB0aGlzLmxyR3JhcGhRTC5xdWVyeSh7XG4gICAgICBxdWVyeTogS2V5RXhjaGFuZ2VzUXVlcnkyLFxuICAgICAgdmFyaWFibGVzOiB7XG4gICAgICAgIHN0YXRlLFxuICAgICAgfSxcbiAgICB9KTtcblxuICAgIHJldHVybiBQcm9taXNlLmFsbChcbiAgICAgIGtleUV4Y2hhbmdlcy5lZGdlcy5tYXAoKGVkZ2UpID0+IHRoaXMuZGVjcnlwdEtleUV4Y2hhbmdlKGVkZ2Uubm9kZSkpXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0gaWQgSWYgdGhlIGN1cnJlbnQgdXNlciBjYW4gcmVzcG9uZGVyIHRoZSBrZXkgZXhjaGFuZ2UgaWYgdGhleSBhcmUgZWl0aGVyIHRoZSBpbml0aWF0b3Igb3IgdGhlIHJlY2VpdmVyLlxuICAgKiBAcGFyYW0gdG9rZW4gSWYgbm90IHNpZ25lZCBpbiwgb3Igbm90IHRoZSBpbml0aWF0b3Igb3IgcmVzcG9uZGVyLCAndG9rZW4nIG11c3QgYmUgZ2l2ZW4uXG4gICAqIEBwYXJhbSBvdEtleUsgSXMgdGhlIHJhdyBvbmUtdGltZSBrZXkgKHN0cmluZykuIElmIHRoZSByZXNwb25kZXIgaXMgZXhwbGljaXRseSBzcGVjaWZpZWQgYXQgdGltZSBvZiBpbml0aWF0aW9uLCB0aGVuXG4gICAqICAgaXQncyBwb3NzaWJsZSB0byBoYXZlIHRoZSBvdEtleSB3cmFwcGVkIGJ5IHRoZSBwdWJsaWMga2V5IG9mIHRoZSByZXNwb25kZXIuIEluIHdoaWNoIGNhc2UsIHRoZSBvdEtleUsgaXMgbm90IG5lZWRlZC5cbiAgICovXG4gIGFzeW5jIGdldEtleUV4Y2hhbmdlKFxuICAgIGlkOiBzdHJpbmcsXG4gICAgeyBvdEtleUssIHRva2VuIH06IEdldEtleUV4Y2hhbmdlT3B0aW9uczIgPSB7fVxuICApIHtcbiAgICBjb25zdCByZXMgPSBhd2FpdCB0aGlzLmxyR3JhcGhRTC5xdWVyeSh7XG4gICAgICBxdWVyeTogdG9rZW4gPyBLZXlFeGNoYW5nZVRva2VuUXVlcnkyIDogS2V5RXhjaGFuZ2VRdWVyeTIsXG4gICAgICB2YXJpYWJsZXM6IHtcbiAgICAgICAgaWQsXG4gICAgICAgIHRva2VuLFxuICAgICAgfSxcbiAgICAgIGluY2x1ZGVLZXlHcmFwaDogIXRva2VuLCAvLyBpZiAhdG9rZW4gdGhlbiB3ZSBhcmUgcG9zdCBhdXRoLCBzbyBjYW4gZmV0Y2gga2V5R3JhcGhcbiAgICB9KTtcbiAgICByZXR1cm4gdGhpcy5kZWNyeXB0S2V5RXhjaGFuZ2UocmVzLmtleUV4Y2hhbmdlLCBvdEtleUspO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIGdldEN1cnJlbnRVc2VyU2hhcmVkS2V5KGlucHV0OiB7XG4gICAgdXNlcm5hbWU/OiBzdHJpbmc7XG4gICAgdXNlcklkPzogc3RyaW5nO1xuICB9KSB7XG4gICAgcmV0dXJuIHRoaXMubHJHcmFwaFFMLnF1ZXJ5KHtcbiAgICAgIHF1ZXJ5OiBDdXJyZW50VXNlclNoYXJlZEtleVF1ZXJ5MixcbiAgICAgIHZhcmlhYmxlczoge1xuICAgICAgICB1c2VybmFtZTogaW5wdXQudXNlcm5hbWUsXG4gICAgICAgIHVzZXJJZDogaW5wdXQudXNlcklkLFxuICAgICAgfSxcbiAgICB9KTtcbiAgfVxuXG4gIC8vIFRPRE86IGRlcHJlY2F0ZSB0aGlzXG4gIGFzeW5jIGNhbmNlbEtleUV4Y2hhbmdlKGlkOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5jYW5jZWxLZXlFeGNoYW5nZU11dGF0aW9uKGlkKTtcbiAgfVxuXG4gIGNhbmNlbEtleUV4Y2hhbmdlTXV0YXRpb24oaWQ6IHN0cmluZykge1xuICAgIHJldHVybiBuZXcgTHJNdXRhdGlvbih7XG4gICAgICBtdXRhdGlvbjogQ2FuY2VsS2V5RXhjaGFuZ2VNdXRhdGlvbixcbiAgICAgIHZhcmlhYmxlczoge1xuICAgICAgICBpbnB1dDoge1xuICAgICAgICAgIGlkLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9KTtcbiAgfVxuXG4gIC8vIFRPRE86IGRlcHJlY2F0ZSB0aGlzXG4gIGFzeW5jIGRlY2xpbmVLZXlFeGNoYW5nZShpZDogc3RyaW5nLCB0b2tlbjogc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMuZGVjbGluZUtleUV4Y2hhbmdlTXV0YXRpb24oaWQsIHRva2VuKTtcbiAgfVxuXG4gIGRlY2xpbmVLZXlFeGNoYW5nZU11dGF0aW9uKGlkOiBzdHJpbmcsIHRva2VuOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gbmV3IExyTXV0YXRpb24oe1xuICAgICAgbXV0YXRpb246IERlY2xpbmVLZXlFeGNoYW5nZU11dGF0aW9uLFxuICAgICAgdmFyaWFibGVzOiB7XG4gICAgICAgIGlucHV0OiB7XG4gICAgICAgICAgaWQsXG4gICAgICAgICAgdG9rZW4sXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIH0pO1xuICB9XG5cbiAgYXN5bmMgaW5pdGlhdGVPdGsoe1xuICAgIG1lc3NhZ2UsXG4gICAgZW1haWwsXG4gICAgY29udGFjdENhcmQsXG4gICAgdXBncmFkZSxcbiAgfTogSW5pdGlhdGVPdGtJbnB1dDIgPSB7fSkge1xuICAgIGNvbnN0IG90S2V5ID0gYXdhaXQgdGhpcy5rZXlGYWN0b3J5LmNyZWF0ZUtleSgpO1xuICAgIGNvbnN0IG5vbmNlID0gdGhpcy5rZXlGYWN0b3J5LnJhbmRvbVN0cmluZyh0aGlzLkNMSUVOVF9OT05DRV9MRU5HVEgpO1xuXG4gICAgLy8gTmV3IFBLQyBrZXkgZm9yIGVuY3J5cHRpb24uIFRoaXMga2V5IGlzIHVzZWQgb25seSBvbmNlIHdoZW4gdGhlIHJlc3BvbmRlciBzZW5kc1xuICAgIC8vIGJhY2sgdGhlaXIgc2lnbmluZyBwdWJsaWMga2V5LlxuICAgIGNvbnN0IGluaXRpYXRvck9uZVRpbWVQcmsgPSBhd2FpdCB0aGlzLmtleUZhY3RvcnkuY3JlYXRlUGtjS2V5KCk7XG5cbiAgICAvLyBPcHRpb24gMTogTmV3IFBLQyBrZXkgZm9yIHNpZ25pbmdcbiAgICAvLyBjb25zdCBpbml0aWF0b3JTaWdQcmsgPSBhd2FpdCB0aGlzLmtleVNlcnZpY2UuY3JlYXRlUGtjU2lnbktleSgpO1xuXG4gICAgLy8gT3B0aW9uIDI6IFVzZSB0aGUgdXNlcidzIGdsb2JhbCBzaWduaW5nIGtleS5cbiAgICAvLyBUaGlzIGtleSBpcyB1c2VkIHRvIHByb3ZlIHRoZSBpbml0aWF0b3IncyBpZGVudGl0eS5cbiAgICBjb25zdCBpbml0aWF0b3JQcmsgPSBhd2FpdCB0aGlzLmtleVNlcnZpY2UuZ2V0Q3VycmVudFB4aygpO1xuICAgIGNvbnN0IGluaXRpYXRvclNpZ1ByayA9IGF3YWl0IHRoaXMua2V5U2VydmljZS5nZXRDdXJyZW50U2lnUHhrKCk7XG5cbiAgICBsZXQgaW5pdGlhdG9yUGxhaW5EYXRhU2lnOiBzdHJpbmcgPSBudWxsO1xuXG4gICAgaWYgKGNvbnRhY3RDYXJkICYmIGNvbnRhY3RDYXJkLm93bmVyUGxhaW5EYXRhSnNvbikge1xuICAgICAgaW5pdGlhdG9yUGxhaW5EYXRhU2lnID0gYXdhaXQgdGhpcy5lbmNyeXB0aW9uU2VydmljZS5zaWduVG9TdHJpbmcoXG4gICAgICAgIGluaXRpYXRvclNpZ1Byay5qd2ssXG4gICAgICAgIGNvbnRhY3RDYXJkLm93bmVyUGxhaW5EYXRhSnNvblxuICAgICAgKTtcbiAgICB9XG5cbiAgICBjb25zdCBpbml0aWF0b3IgPSB7XG4gICAgICBtZXNzYWdlLFxuICAgICAgY29udGFjdENhcmQ6IGNvbnRhY3RDYXJkICYmIHtcbiAgICAgICAgc2hhcmVkQ2lwaGVyRGF0YUNsZWFySnNvbjogY29udGFjdENhcmQuc2hhcmVkQ2lwaGVyRGF0YUNsZWFySnNvbixcbiAgICAgIH0sXG4gICAgfTtcblxuICAgIC8vIENvbnRlbnQgdG8gYmUgZW5jcnlwdGVkIHVzaW5nIHRoZSBPVEsuXG4gICAgY29uc3QgcGxhaW5PdEtleUNpcGhlcjogT3RLZXlDaXBoZXJDbGVhckpzb24yID0ge1xuICAgICAgLy8gVE9ETyBNYWtlIHN1cmUgd2UgYWxzbyBwdXQgdGhlIE9PQiBjb2RlIGluIGhlcmUgYXMgd2VsbCBzaW5jZSB0aGUgT09CIGNvZGUgaXMgdGhlXG4gICAgICAvLyBfb25seV8gaW5mb3JtYXRpb24gdGhlIEtDIHNlcnZlciBkb2VzIG5vdCBoYXZlIGFjY2VzcyB0by4gVGhlIHNlcnZlciBtYXkgaGF2ZVxuICAgICAgLy8gYWNjZXNzIHRvIE9USyBhbmQgaGVuY2UgdGhlIG5vbmNlIGhlcmUuIEl0J3MgZ29vZCB0byBoYXZlIGJvdGggdGhlIG5vbmNlIGFuZCBPT0IgY29kZVxuICAgICAgLy8gc2luY2UgdGhlIHVzZXIgbWF5IG5vdCBiZSB1c2luZyB0aGUgT09CIGNvZGUuIEFuZCBpdCdzIHNpbXBsZSB0byBhbHdheXMgaW5jbHVkZVxuICAgICAgLy8gdGhlIG5vbmNlLCBzbyB3aHkgbm90LlxuICAgICAgbm9uY2UsXG4gICAgICBpbml0aWF0b3I6IHtcbiAgICAgICAgLi4uaW5pdGlhdG9yLFxuICAgICAgICBvbmVUaW1lUGJrOiBpbml0aWF0b3JPbmVUaW1lUHJrLnRvSlNPTigpLCAvLyBvbmUtdGltZSBwdWJsaWMgZW5jcnlwdGlvbiBrZXkgcmVzcG9uZGVyIHVzZSB0byBzZW5kIGRhdGEgYmFjayB0byBpbml0aWF0b3JcbiAgICAgICAgcGJrOiBpbml0aWF0b3JQcmsuandrLnRvSlNPTigpLCAvLyBwdWJsaWMgZW5jcnlwdGlvbiBrZXlcbiAgICAgICAgc2lnUGJrOiBpbml0aWF0b3JTaWdQcmsuandrLnRvSlNPTigpLCAvLyBwdWJsaWMgc2lnbmluZyBrZXlcbiAgICAgIH0sXG4gICAgfTtcblxuICAgIGNvbnN0IG90S2V5Q2lwaGVyID0gYXdhaXQgdGhpcy5rZXlHcmFwaC5lbmNyeXB0VG9TdHJpbmcoXG4gICAgICBvdEtleSxcbiAgICAgIHBsYWluT3RLZXlDaXBoZXJcbiAgICApO1xuXG4gICAgLy8gQ29udGVudCB0byBiZSBlbmNyeXB0ZWQgdXNpbmcgdGhlIGluaXRpYXRvcidzIHJvb3Qga2V5LlxuICAgIGNvbnN0IGluaXRpYXRvclJvb3RLZXlDaXBoZXJDbGVhckpzb246IEluaXRpYXRvclJvb3RLZXlDaXBoZXJDbGVhckpzb24yID0ge1xuICAgICAgbm9uY2UsXG4gICAgICBvbmVUaW1lUHJrOiBpbml0aWF0b3JPbmVUaW1lUHJrLnRvSlNPTih0cnVlKSxcbiAgICAgIC8vIFNob3VsZCBub3QgbmVlZCB0byBrZWVwIHRoaXMgZW5jcnlwdGVkIHNpbmNlIHdlIGFyZSB1c2luZyB0aGUgZ2xvYmFsIHNpZ25pbmcga2V5LlxuICAgICAgLy8gc2lnUHJrOiBpbml0aWF0b3JTaWdQcmsudG9KU09OKHRydWUpLFxuXG4gICAgICAvLyBTYXZlIGl0IGluIGNhc2UgdGhlIGluaXRpYXRvciB3YW50IHRvIGRlY29kZSB0aGUgb3RLZXlDaXBoZXIuXG4gICAgICAvLyBTaW5jZSB0aGUgb3RLZXkgaXMgb25seSB1c2VkIG9uY2UsIGFuZCB0aGF0IG90S2V5Q2lwaGVyIGNvbnRhaW5zIG9ubHlcbiAgICAgIC8vIHRoZSBwdWJsaWMga2V5IG9mIHRoZSBpbml0aWF0b3IsIGl0J3Mgc2FmZSBqdXN0IGxlYXZlIHRoZSBvdEtleSBzdG9yZWQgaGVyZS5cbiAgICAgIG90S2V5OiBvdEtleS50b0pTT04odHJ1ZSksXG4gICAgICAvLyBUaGVzZSBzaG91bGQgYmUgc3RvcmluZyBpbmZvcm1hdGlvbiBzdWNoIGFzIGhvdyB0aGUgZmllbGRzIG9mIHRoZSBzaGFyZWQgY29udGFjdCBjYXJkIGlzXG4gICAgICAvLyBkZXJpdmVkIGZyb20gdGhlIG1hc3RlciBjb250YWN0IGNhcmQuXG4gICAgICBpbml0aWF0b3JDb250YWN0Q2FyZDogY29udGFjdENhcmQsXG4gICAgICBpbml0aWF0b3IsXG4gICAgfTtcblxuICAgIGNvbnN0IHJvb3RLZXkgPSBhd2FpdCB0aGlzLmtleVNlcnZpY2UuZ2V0Q3VycmVudFJvb3RLZXkoKTtcbiAgICBjb25zdCBpbml0aWF0b3JSb290S2V5Q2lwaGVyID0gYXdhaXQgdGhpcy5rZXlHcmFwaC5lbmNyeXB0VG9TdHJpbmcoXG4gICAgICByb290S2V5Lmp3ayxcbiAgICAgIGluaXRpYXRvclJvb3RLZXlDaXBoZXJDbGVhckpzb25cbiAgICApO1xuXG4gICAgLy8gVGhlIHJhdyBPVEtcbiAgICBjb25zdCBvdEtleUs6IHN0cmluZyA9IChvdEtleS50b0pTT04odHJ1ZSkgYXMgYW55KS5rO1xuXG4gICAgLy8gQVBJIGNhbGxcbiAgICBjb25zdCBsck11dGF0aW9uID0gbmV3IExyTXV0YXRpb24oe1xuICAgICAgbXV0YXRpb246IEluaXRpYXRlS2V5RXhjaGFuZ2VPdGtNdXRhdGlvbixcbiAgICAgIHZhcmlhYmxlczoge1xuICAgICAgICBpbnB1dDoge1xuICAgICAgICAgIC8vIFRoZXNlIHdpbGwgYmUgc3RvcmVkIG9uIHRoZSBzZXJ2ZXJcbiAgICAgICAgICBpbml0aWF0b3JSb290S2V5Q2lwaGVyLFxuICAgICAgICAgIGluaXRpYXRvclB4a0lkOiBpbml0aWF0b3JQcmsuaWQsXG4gICAgICAgICAgaW5pdGlhdG9yU2lnUHhrSWQ6IGluaXRpYXRvclNpZ1Byay5pZCxcbiAgICAgICAgICAvLyBUaGVzZSB3aWxsIGJlIHNlbnQgdG8gdGhlIHJlc3BvbmRlclxuICAgICAgICAgIG90S2V5UGFyYW1zOiBKU09OLnN0cmluZ2lmeShvdEtleS50b0pTT04oKSksXG4gICAgICAgICAgb3RLZXlDaXBoZXIsXG4gICAgICAgICAgc2VuZEVtYWlsOiBlbWFpbCAmJiB7XG4gICAgICAgICAgICBlbWFpbCxcbiAgICAgICAgICAgIHJhd090S2V5OiBvdEtleUssXG4gICAgICAgICAgfSxcbiAgICAgICAgICBjcmVhdGVUcDogdHJ1ZSxcbiAgICAgICAgICBpbml0aWF0b3JQbGFpbkRhdGFTaWcsXG4gICAgICAgICAgdXBncmFkZSxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgfSk7XG5cbiAgICByZXR1cm4geyBsck11dGF0aW9uLCBvdEtleUsgfTtcbiAgfVxuXG4gIGFzeW5jIHJlc3BvbmRPdGsoe1xuICAgIGtleUV4Y2hhbmdlSWQsXG4gICAgdG9rZW4sXG4gICAgZGVjcnlwdGVkT3RrLFxuICAgIG1lc3NhZ2UsXG4gICAgaW5pdGlhdG9yQ29udGFjdENhcmQsXG4gICAgcmVzcG9uZGVyQ29udGFjdENhcmQsXG4gIH06IFJlc3BvbmRPdGtJbnB1dDIpIHtcbiAgICBjb25zdCByb290S2V5ID0gYXdhaXQgdGhpcy5rZXlTZXJ2aWNlLmdldEN1cnJlbnRSb290S2V5KCk7XG5cbiAgICBjb25zdCBtYXN0ZXJLZXlJZCA9IHRoaXMua2V5U2VydmljZS5nZXRDdXJyZW50TWFzdGVyS2V5KCkuaWQ7XG4gICAgY29uc3QgbWFzdGVyS2V5ID0gYXdhaXQgdGhpcy5rZXlTZXJ2aWNlLmdldEN1cnJlbnRNYXN0ZXJLZXkoKTtcblxuICAgIGNvbnN0IHNoYXJlZEtleSA9IGF3YWl0IHRoaXMua2V5RmFjdG9yeS5jcmVhdGVLZXkoKTtcbiAgICBjb25zdCBta1NoYXJlZEtleSA9IGF3YWl0IHRoaXMua2V5RmFjdG9yeS5jcmVhdGVLZXkoKTtcblxuICAgIGNvbnN0IHJrV3JhcHBlZFNoYXJlZEtleSA9IGF3YWl0IHRoaXMuZW5jcnlwdGlvblNlcnZpY2UuZW5jcnlwdChcbiAgICAgIHJvb3RLZXkuandrLFxuICAgICAgc2hhcmVkS2V5LnRvSlNPTih0cnVlKVxuICAgICk7XG4gICAgY29uc3QgbWtXcmFwcGVkTWtTaGFyZWRLZXkgPSBhd2FpdCB0aGlzLmVuY3J5cHRpb25TZXJ2aWNlLmVuY3J5cHQoXG4gICAgICBtYXN0ZXJLZXkuandrLFxuICAgICAgbWtTaGFyZWRLZXkudG9KU09OKHRydWUpXG4gICAgKTtcblxuICAgIGNvbnN0IGluaXRpYXRvck9uZVRpbWVQYmsgPSBhd2FpdCBLZXlGYWN0b3J5U2VydmljZS5hc0tleShcbiAgICAgIGRlY3J5cHRlZE90ay5vdEtleUNpcGhlckNsZWFySnNvbi5pbml0aWF0b3Iub25lVGltZVBia1xuICAgICk7XG5cbiAgICBjb25zdCBpbml0aWF0b3JQYmsgPSBhd2FpdCBLZXlGYWN0b3J5U2VydmljZS5hc0tleShcbiAgICAgIGRlY3J5cHRlZE90ay5vdEtleUNpcGhlckNsZWFySnNvbi5pbml0aWF0b3IucGJrXG4gICAgKTtcbiAgICBjb25zdCBpbml0aWF0b3JTaWdQYmsgPSBhd2FpdCBLZXlGYWN0b3J5U2VydmljZS5hc0tleShcbiAgICAgIGRlY3J5cHRlZE90ay5vdEtleUNpcGhlckNsZWFySnNvbi5pbml0aWF0b3Iuc2lnUGJrXG4gICAgKTtcblxuICAgIC8vIE9wdGlvbiAxOiBVc2luZyBuZXcgUHJrIGZvciBlYWNoIFRQIHBhaXJcbiAgICAvLyBDcmVhdGUgYSBuZXcgcHVibGljIHNpZ25pbmcga2V5IGZvciB0aGUgcmVzcG9uZGVyLlxuICAgIC8vIGNvbnN0IHJlc3BvbmRlclNpZ1ByayA9IGF3YWl0IHRoaXMua2V5U2VydmljZS5jcmVhdGVQa2NTaWduS2V5KClcbiAgICAvLyBjb25zdCBya1dyYXBwZWRSZXNwb25kZXJTaWdQcmsgPSBhd2FpdCB0aGlzLmVuY3J5cHQocm9vdEtleSwgcmVzcG9uZGVyU2lnUHJrLnRvSlNPTih0cnVlKSk7XG5cbiAgICAvLyBPcHRpb24gMjogUmVzcG9uZGVyIGFscmVhZHkgaGFzIGEgc2lnbmluZyBQcmtcbiAgICBjb25zdCByZXNwb25kZXJQcmsgPSBhd2FpdCB0aGlzLmtleVNlcnZpY2UuZ2V0Q3VycmVudFB4aygpO1xuICAgIGNvbnN0IHJlc3BvbmRlclNpZ1ByayA9IGF3YWl0IHRoaXMua2V5U2VydmljZS5nZXRDdXJyZW50U2lnUHhrKCk7XG5cbiAgICBjb25zdCBzaWduZWRJbml0aWF0b3JQYmsgPSBhd2FpdCB0aGlzLmVuY3J5cHRpb25TZXJ2aWNlLnNpZ24oXG4gICAgICByZXNwb25kZXJTaWdQcmsuandrLFxuICAgICAgaW5pdGlhdG9yUGJrLnRvSlNPTigpXG4gICAgKTtcbiAgICBjb25zdCBzaWduZWRJbml0aWF0b3JTaWdQYmsgPSBhd2FpdCB0aGlzLmVuY3J5cHRpb25TZXJ2aWNlLnNpZ24oXG4gICAgICByZXNwb25kZXJTaWdQcmsuandrLFxuICAgICAgaW5pdGlhdG9yU2lnUGJrLnRvSlNPTigpXG4gICAgKTtcblxuICAgIGNvbnN0IGluaXRpYXRvck9uZVRpbWVQYmtDaXBoZXJDbGVhckpzb246IEluaXRpYXRvck9uZVRpbWVQYmtDaXBoZXJDbGVhckpzb24gPSB7XG4gICAgICBub25jZTogZGVjcnlwdGVkT3RrLm90S2V5Q2lwaGVyQ2xlYXJKc29uLm5vbmNlLFxuICAgICAgc2hhcmVkS2V5OiBzaGFyZWRLZXkudG9KU09OKHRydWUpLFxuICAgICAgbWtTaGFyZWRLZXk6IG1rU2hhcmVkS2V5LnRvSlNPTih0cnVlKSxcbiAgICAgIHJlc3BvbmRlcjoge1xuICAgICAgICBwYms6IHJlc3BvbmRlclByay5qd2sudG9KU09OKCksIC8vIHB1YmxpYyBrZXlcbiAgICAgICAgc2lnUGJrOiByZXNwb25kZXJTaWdQcmsuandrLnRvSlNPTigpLCAvLyBwdWJsaWMga2V5XG4gICAgICAgIG1lc3NhZ2UsXG4gICAgICB9LFxuICAgIH07XG5cbiAgICBsZXQgcmVjZWl2ZWRDYXJkSW5wdXQ7XG4gICAgaWYgKGRlY3J5cHRlZE90ay5vdEtleUNpcGhlckNsZWFySnNvbi5pbml0aWF0b3IuY29udGFjdENhcmQpIHtcbiAgICAgIC8vIFNldCB0aGUgaW5mbyBhYm91dCB0aGUgaW5pdGlhdG9yIHRvIGJlIHRoZSBvbmVzIHNlbnQgYnkgdGhlIGluaXRpYXRvci4gV2UgbmVlZCB0aCByZXNwb25kZXIgdG8gZG8gdGhlIGVuY3J5cHRpb24gaGVyZVxuICAgICAgLy8gYmVjYXVzZSB0aGUgaW5pdGlhdG9yIGRvZXMgbm90IGhhdmUgdGhlIHNoYXJlZCBrZXkgeWV0LCBhbmQgd2Ugd2FudCB0aGUgcmVzcG9uZGVyIHRvIGhhdmUgYSBmdW5jdGlvbmFsIGNvbnRhY3QgY2FyZCBhZnRlclxuICAgICAgLy8gdGhpcyBleGNoYW5nZS4gVGhlIGluaXRpYXRvciBjYW4gZG91YmxlIGNoZWNrIHRoZSBjb250YWN0IGRldGFpbHMgYXJlIGNvcnJlY3QgYW5kIHNpZ24gaXQgd2hlbiBpdCBjb21wbGV0ZXMgdGhlIGV4Y2hhbmdlLlxuICAgICAgY29uc3Qgc2hhcmVkQ2lwaGVyRGF0YUNsZWFySnNvbiA9XG4gICAgICAgIGRlY3J5cHRlZE90ay5vdEtleUNpcGhlckNsZWFySnNvbi5pbml0aWF0b3IuY29udGFjdENhcmRcbiAgICAgICAgICAuc2hhcmVkQ2lwaGVyRGF0YUNsZWFySnNvbjtcblxuICAgICAgLy8gQ3JlYXRlIGtleXNcbiAgICAgIGNvbnN0IHJlY2VpdmVyS2V5ID0gYXdhaXQgdGhpcy5rZXlGYWN0b3J5LmNyZWF0ZUtleSgpO1xuICAgICAgY29uc3QgY2NTaGFyZWRLZXkgPSBhd2FpdCB0aGlzLmtleUZhY3RvcnkuY3JlYXRlS2V5KCk7XG4gICAgICBjb25zdCBzaWdQeGsgPSBhd2FpdCB0aGlzLmtleVNlcnZpY2UuZ2V0Q3VycmVudFNpZ1B4aygpO1xuXG4gICAgICByZWNlaXZlZENhcmRJbnB1dCA9IHtcbiAgICAgICAgcmVjZWl2ZXJXcmFwcGVkS2V5OiBKU09OLnN0cmluZ2lmeShcbiAgICAgICAgICBhd2FpdCB0aGlzLmVuY3J5cHRpb25TZXJ2aWNlLmVuY3J5cHQoXG4gICAgICAgICAgICByb290S2V5Lmp3ayxcbiAgICAgICAgICAgIHJlY2VpdmVyS2V5LnRvSlNPTih0cnVlKVxuICAgICAgICAgIClcbiAgICAgICAgKSxcbiAgICAgICAgcmVjZWl2ZXJXcmFwcGluZ0tleUlkOiByb290S2V5LmlkLFxuICAgICAgICByZWNlaXZlckNpcGhlckRhdGE6IGluaXRpYXRvckNvbnRhY3RDYXJkXG4gICAgICAgICAgPyBKU09OLnN0cmluZ2lmeShcbiAgICAgICAgICAgICAgYXdhaXQgdGhpcy5lbmNyeXB0aW9uU2VydmljZS5lbmNyeXB0KFxuICAgICAgICAgICAgICAgIHJlY2VpdmVyS2V5LFxuICAgICAgICAgICAgICAgIGluaXRpYXRvckNvbnRhY3RDYXJkLnJlY2VpdmVyQ2lwaGVyRGF0YUNsZWFySnNvblxuICAgICAgICAgICAgICApXG4gICAgICAgICAgICApXG4gICAgICAgICAgOiAnJyxcbiAgICAgICAgc2hhcmVkV3JhcHBlZEtleTogSlNPTi5zdHJpbmdpZnkoXG4gICAgICAgICAgYXdhaXQgdGhpcy5lbmNyeXB0aW9uU2VydmljZS5lbmNyeXB0KFxuICAgICAgICAgICAgc2hhcmVkS2V5LFxuICAgICAgICAgICAgY2NTaGFyZWRLZXkudG9KU09OKHRydWUpXG4gICAgICAgICAgKVxuICAgICAgICApLFxuICAgICAgfTtcblxuICAgICAgY29uc3Qgc2hhcmVkQ2lwaGVyRGF0YSA9IGF3YWl0IHRoaXMuZW5jcnlwdGlvblNlcnZpY2UuZW5jcnlwdChcbiAgICAgICAgY2NTaGFyZWRLZXksXG4gICAgICAgIHNoYXJlZENpcGhlckRhdGFDbGVhckpzb25cbiAgICAgICk7XG4gICAgICByZWNlaXZlZENhcmRJbnB1dC5zaGFyZWRDaXBoZXJEYXRhU2lnID0gSlNPTi5zdHJpbmdpZnkoXG4gICAgICAgIGF3YWl0IHRoaXMuZW5jcnlwdGlvblNlcnZpY2Uuc2lnbihzaWdQeGsuandrLCBzaGFyZWRDaXBoZXJEYXRhKVxuICAgICAgKTtcbiAgICAgIHJlY2VpdmVkQ2FyZElucHV0LnNpZ1B4a0lkID0gc2lnUHhrLmlkO1xuXG4gICAgICBpbml0aWF0b3JPbmVUaW1lUGJrQ2lwaGVyQ2xlYXJKc29uLnJlc3BvbmRlci5jb250YWN0Q2FyZCA9IHtcbiAgICAgICAgLi4uaW5pdGlhdG9yT25lVGltZVBia0NpcGhlckNsZWFySnNvbi5yZXNwb25kZXIuY29udGFjdENhcmQsXG4gICAgICAgIHNoYXJlZENpcGhlcktleTogY2NTaGFyZWRLZXkudG9KU09OKHRydWUpLFxuICAgICAgfTtcbiAgICB9XG5cbiAgICBsZXQgcmVzcG9uZGVyQ2FyZElucHV0O1xuICAgIGlmIChyZXNwb25kZXJDb250YWN0Q2FyZCkge1xuICAgICAgLy8gQ3JlYXRlIGtleXNcbiAgICAgIGNvbnN0IG93bmVyS2V5ID0gYXdhaXQgdGhpcy5rZXlGYWN0b3J5LmNyZWF0ZUtleSgpO1xuICAgICAgY29uc3QgY2NTaGFyZWRLZXkgPSBhd2FpdCB0aGlzLmtleUZhY3RvcnkuY3JlYXRlS2V5KCk7XG4gICAgICBjb25zdCBzaWdQeGsgPSBhd2FpdCB0aGlzLmtleVNlcnZpY2UuZ2V0Q3VycmVudFNpZ1B4aygpO1xuXG4gICAgICByZXNwb25kZXJDYXJkSW5wdXQgPSB7XG4gICAgICAgIG93bmVyV3JhcHBlZEtleTogSlNPTi5zdHJpbmdpZnkoXG4gICAgICAgICAgYXdhaXQgdGhpcy5lbmNyeXB0aW9uU2VydmljZS5lbmNyeXB0KFxuICAgICAgICAgICAgcm9vdEtleS5qd2ssXG4gICAgICAgICAgICBvd25lcktleS50b0pTT04odHJ1ZSlcbiAgICAgICAgICApXG4gICAgICAgICksXG4gICAgICAgIG93bmVyV3JhcHBpbmdLZXlJZDogcm9vdEtleS5pZCxcbiAgICAgICAgb3duZXJDaXBoZXJEYXRhOiByZXNwb25kZXJDb250YWN0Q2FyZC5vd25lckNpcGhlckRhdGFDbGVhckpzb25cbiAgICAgICAgICA/IEpTT04uc3RyaW5naWZ5KFxuICAgICAgICAgICAgICBhd2FpdCB0aGlzLmVuY3J5cHRpb25TZXJ2aWNlLmVuY3J5cHQoXG4gICAgICAgICAgICAgICAgb3duZXJLZXksXG4gICAgICAgICAgICAgICAgcmVzcG9uZGVyQ29udGFjdENhcmQub3duZXJDaXBoZXJEYXRhQ2xlYXJKc29uXG4gICAgICAgICAgICAgIClcbiAgICAgICAgICAgIClcbiAgICAgICAgICA6ICcnLFxuXG4gICAgICAgIHNoYXJlZFdyYXBwZWRLZXk6IEpTT04uc3RyaW5naWZ5KFxuICAgICAgICAgIGF3YWl0IHRoaXMuZW5jcnlwdGlvblNlcnZpY2UuZW5jcnlwdChcbiAgICAgICAgICAgIHNoYXJlZEtleSxcbiAgICAgICAgICAgIGNjU2hhcmVkS2V5LnRvSlNPTih0cnVlKVxuICAgICAgICAgIClcbiAgICAgICAgKSxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHNoYXJlZENpcGhlckRhdGEgPSBhd2FpdCB0aGlzLmVuY3J5cHRpb25TZXJ2aWNlLmVuY3J5cHQoXG4gICAgICAgIGNjU2hhcmVkS2V5LFxuICAgICAgICByZXNwb25kZXJDb250YWN0Q2FyZC5zaGFyZWRDaXBoZXJEYXRhQ2xlYXJKc29uXG4gICAgICApO1xuICAgICAgcmVzcG9uZGVyQ2FyZElucHV0LnNoYXJlZENpcGhlckRhdGFTaWcgPSBKU09OLnN0cmluZ2lmeShcbiAgICAgICAgYXdhaXQgdGhpcy5lbmNyeXB0aW9uU2VydmljZS5zaWduKHNpZ1B4ay5qd2ssIHNoYXJlZENpcGhlckRhdGEpXG4gICAgICApO1xuICAgICAgcmVzcG9uZGVyQ2FyZElucHV0LnNpZ1B4a0lkID0gc2lnUHhrLmlkO1xuXG4gICAgICBpZiAocmVzcG9uZGVyQ29udGFjdENhcmQub3duZXJQbGFpbkRhdGFKc29uKSB7XG4gICAgICAgIHJlc3BvbmRlckNhcmRJbnB1dC5vd25lclBsYWluRGF0YVNpZyA9IEpTT04uc3RyaW5naWZ5KFxuICAgICAgICAgIGF3YWl0IHRoaXMuZW5jcnlwdGlvblNlcnZpY2Uuc2lnbihcbiAgICAgICAgICAgIHJlc3BvbmRlclNpZ1Byay5qd2ssXG4gICAgICAgICAgICByZXNwb25kZXJDb250YWN0Q2FyZC5vd25lclBsYWluRGF0YUpzb25cbiAgICAgICAgICApXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIC8vIENvbnRhY3QgY2FyZCBpbmZvIHJlYWRhYmxlIGJ5IHRoZSBpbml0aWF0b3JcbiAgICAgIGluaXRpYXRvck9uZVRpbWVQYmtDaXBoZXJDbGVhckpzb24ucmVzcG9uZGVyLmNvbnRhY3RDYXJkID0ge1xuICAgICAgICAuLi5pbml0aWF0b3JPbmVUaW1lUGJrQ2lwaGVyQ2xlYXJKc29uLnJlc3BvbmRlci5jb250YWN0Q2FyZCxcbiAgICAgICAgc2hhcmVkQ2lwaGVyRGF0YUNsZWFySnNvbjpcbiAgICAgICAgICByZXNwb25kZXJDb250YWN0Q2FyZC5zaGFyZWRDaXBoZXJEYXRhQ2xlYXJKc29uLFxuICAgICAgfTtcbiAgICB9XG5cbiAgICAvLyBFbmNyeXB0IHdpdGggb25lLXRpbWUgcHVibGljIGtleVxuICAgIGxldCBpbml0aWF0b3JPbmVUaW1lUGJrQ2lwaGVyID0gYXdhaXQgdGhpcy5lbmNyeXB0aW9uU2VydmljZS5lbmNyeXB0KFxuICAgICAgaW5pdGlhdG9yT25lVGltZVBiayxcbiAgICAgIGluaXRpYXRvck9uZVRpbWVQYmtDaXBoZXJDbGVhckpzb25cbiAgICApO1xuXG4gICAgLy8gRW5jcnlwdCB3aXRoIHRoZSBvdGsgYWdhaW4gdG8ga2VlcCB1c2Ugb2YgYXN5bW1ldHJpYyBrZXlzIHRvIGEgbWluaW11bS5cbiAgICBpbml0aWF0b3JPbmVUaW1lUGJrQ2lwaGVyID0gYXdhaXQgdGhpcy5lbmNyeXB0aW9uU2VydmljZS5lbmNyeXB0KFxuICAgICAgZGVjcnlwdGVkT3RrLm90S2V5LFxuICAgICAgaW5pdGlhdG9yT25lVGltZVBia0NpcGhlclxuICAgICk7XG5cbiAgICByZXR1cm4gbmV3IExyTXV0YXRpb24oe1xuICAgICAgbXV0YXRpb246IFJlc3BvbmRLZXlFeGNoYW5nZU90a011dGF0aW9uLFxuICAgICAgdmFyaWFibGVzOiB7XG4gICAgICAgIGlucHV0OiB7XG4gICAgICAgICAga2V5RXhjaGFuZ2VJZCxcbiAgICAgICAgICBrZXlFeGNoYW5nZVRva2VuOiB0b2tlbixcbiAgICAgICAgICByb290S2V5SWQ6IHJvb3RLZXkuaWQsXG4gICAgICAgICAgbWFzdGVyS2V5SWQsXG4gICAgICAgICAgLy8gVGhlc2Ugd2lsbCBiZSBzdG9yZWQgb24gdGhlIHNlcnZlclxuICAgICAgICAgIHJlc3BvbmRlclB4a0lkOiByZXNwb25kZXJQcmsuaWQsXG4gICAgICAgICAgcmVzcG9uZGVyU2lnUHhrSWQ6IHJlc3BvbmRlclNpZ1Byay5pZCxcbiAgICAgICAgICBzaWduZWRJbml0aWF0b3JQYms6IEpTT04uc3RyaW5naWZ5KHNpZ25lZEluaXRpYXRvclBiayksXG4gICAgICAgICAgc2lnbmVkSW5pdGlhdG9yU2lnUGJrOiBKU09OLnN0cmluZ2lmeShzaWduZWRJbml0aWF0b3JTaWdQYmspLFxuICAgICAgICAgIC8vIHJrV3JhcHBlZEluaXRpYXRvclNpZ1BiazogSlNPTi5zdHJpbmdpZnkocmtXcmFwcGVkSW5pdGlhdG9yU2lnUGJrKSxcblxuICAgICAgICAgIC8vIE9wdGlvbiAxOiBVc2luZyBuZXcgUHJrIGZvciBlYWNoIFRQIHBhaXJcbiAgICAgICAgICAvLyBya1dyYXBwZWRSZXNwb25kZXJTaWdQcms6IEpTT04uc3RyaW5naWZ5KHJrV3JhcHBlZFJlc3BvbmRlclNpZ1ByayksXG4gICAgICAgICAgcmtXcmFwcGVkU2hhcmVkS2V5OiBKU09OLnN0cmluZ2lmeShya1dyYXBwZWRTaGFyZWRLZXkpLFxuICAgICAgICAgIG1rV3JhcHBlZE1rU2hhcmVkS2V5OiBKU09OLnN0cmluZ2lmeShta1dyYXBwZWRNa1NoYXJlZEtleSksXG4gICAgICAgICAgLy8gVGhlc2Ugd2lsbCBiZSBzZW50IHRvIHRoZSBpbml0aWF0b3JcbiAgICAgICAgICBpbml0aWF0b3JPbmVUaW1lUGJrQ2lwaGVyOiBKU09OLnN0cmluZ2lmeShpbml0aWF0b3JPbmVUaW1lUGJrQ2lwaGVyKSxcbiAgICAgICAgICBpbml0aWF0b3JDb250YWN0Q2FyZDogcmVjZWl2ZWRDYXJkSW5wdXQsXG4gICAgICAgICAgcmVzcG9uZGVyQ29udGFjdENhcmQ6IHJlc3BvbmRlckNhcmRJbnB1dCxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgfSk7XG4gIH1cblxuICBhc3luYyBjb21wbGV0ZU90ayh7XG4gICAga2V5RXhjaGFuZ2VJZCxcbiAgICBpbml0aWF0b3JSb290S2V5Q2lwaGVyLFxuICAgIGluaXRpYXRvck9uZVRpbWVQYmtDaXBoZXIsXG4gICAgcmVzcG9uZGVyQ29udGFjdENhcmQsXG4gICAgaW5pdGlhdG9yQ29udGFjdENhcmQsXG4gIH06IENvbXBsZXRlT3RrSW5wdXQyKSB7XG4gICAgY29uc3Qgcm9vdEtleSA9IGF3YWl0IHRoaXMua2V5U2VydmljZS5nZXRDdXJyZW50Um9vdEtleSgpO1xuICAgIGNvbnN0IG1hc3RlcktleSA9IGF3YWl0IHRoaXMua2V5U2VydmljZS5nZXRDdXJyZW50TWFzdGVyS2V5KCk7XG5cbiAgICAvLyBEZWNyeXB0IHVzaW5nIHRoZSByb290IGtleSB0byBnZXQgdGhlIFBya1xuICAgIGNvbnN0IGluaXRpYXRvclJvb3RLZXlDaXBoZXJDbGVhckpzb24gPSAoYXdhaXQgdGhpcy5lbmNyeXB0aW9uU2VydmljZS5kZWNyeXB0KFxuICAgICAgcm9vdEtleS5qd2ssXG4gICAgICBpbml0aWF0b3JSb290S2V5Q2lwaGVyXG4gICAgKSkgYXMgSW5pdGlhdG9yUm9vdEtleUNpcGhlckNsZWFySnNvbjI7XG5cbiAgICAvLyBUaGUgUHJrIGlzIHNpbmdsZS11c2UgYW5kIG9ubHkgdXNlZCB0byBzZW5kIGluZm9ybWF0aW9uIGZyb20gdGhlIHJlc3BvbmRlciBiYWNrIHRvIHRoZSBpbml0aWF0b3IuXG4gICAgY29uc3QgcGxhaW5Jbml0aWF0b3JPbmVUaW1lUGJrQ2lwaGVyID0gYXdhaXQgdGhpcy5kZWNyeXB0UmVzcG9uc2VDaXBoZXIoXG4gICAgICBhd2FpdCBLZXlGYWN0b3J5U2VydmljZS5hc0tleShpbml0aWF0b3JSb290S2V5Q2lwaGVyQ2xlYXJKc29uLm90S2V5KSxcbiAgICAgIGF3YWl0IEtleUZhY3RvcnlTZXJ2aWNlLmFzS2V5KGluaXRpYXRvclJvb3RLZXlDaXBoZXJDbGVhckpzb24ub25lVGltZVByayksXG4gICAgICBpbml0aWF0b3JPbmVUaW1lUGJrQ2lwaGVyXG4gICAgKTtcblxuICAgIC8vIENoZWNrIHRoZSBub25jZSBtYXRjaCB0byBlbnN1cmUgdGhlIHJlc3BvbmRlciB3YXMgdGhlIG9uZSBob2xkaW5nIHRoZSBPVEtcbiAgICBpZiAoXG4gICAgICBpbml0aWF0b3JSb290S2V5Q2lwaGVyQ2xlYXJKc29uLm5vbmNlICE9PVxuICAgICAgcGxhaW5Jbml0aWF0b3JPbmVUaW1lUGJrQ2lwaGVyLm5vbmNlXG4gICAgKSB7XG4gICAgICB0aHJvdyBuZXcgTHJDb2RlTWlzbWF0Y2hFeGNlcHRpb24oXG4gICAgICAgICdUaGUgbm9uY2UgcmV0dXJuZWQgYnkgcmVzcG9uZGVyIGRvZXMgbm90IG1hdGNoIHdpdGggdGhlIG9uZSBjcmVhdGVkIGJ5IHRoZSBpbml0aWF0b3IuJ1xuICAgICAgKTtcbiAgICB9XG5cbiAgICAvLyBPcHRpb24gMTogQXNzdW1pbmcgdGhlIHNpZ25pbmcga2V5IGlzIHVuaXF1ZSBiZXR3ZWVuIHVzZXJzLlxuICAgIC8vIGNvbnN0IGluaXRpYXRvclNpZ1ByayA9IGF3YWl0IEtGUy5hc0tleShrZS5wbGFpbkluaXRpYXRvclJvb3RLZXlDaXBoZXIuc2lnUHJrKTtcbiAgICAvLyBjb25zdCBya1dyYXBwZWRJbml0aWF0b3JTaWdQcmsgPSBhd2FpdCB0aGlzLmVuY3J5cHQocm9vdEtleSwgaW5pdGlhdG9yU2lnUHJrLnRvSlNPTih0cnVlKSk7XG5cbiAgICAvLyBPcHRpb24gMjogVXNlIHRoZSB1c2VyJ3MgZ2xvYmFsIHNpZ25pbmcga2V5LlxuICAgIC8vIEluIHRoaXMgY2FzZSB0aGUgaW5pdGlhdG9yU2lnUHJrIGlzIGFscmVhZHkgYSBwYXJ0IG9mIHRoZSBrZXkgZ3JhcGguXG4gICAgLy8gU28gdGhlcmUncyBub3RoaW5nIHRvIGRvIGhlcmUuXG5cbiAgICAvLyBQcm90ZWN0ZWQgdGhlIHNpZ25pbmcgcHVibGljIGtleSBvZiB0aGUgcmVzcG9uZGVyLlxuICAgIGNvbnN0IGluaXRpYXRvclNpZ1ByayA9IGF3YWl0IHRoaXMua2V5U2VydmljZS5nZXRDdXJyZW50U2lnUHhrKCk7XG4gICAgY29uc3QgcmVzcG9uZGVyU2lnUGJrID0gYXdhaXQgS2V5RmFjdG9yeVNlcnZpY2UuYXNLZXkoXG4gICAgICBwbGFpbkluaXRpYXRvck9uZVRpbWVQYmtDaXBoZXIucmVzcG9uZGVyLnNpZ1Bia1xuICAgICk7XG4gICAgY29uc3QgcmVzcG9uZGVyUGJrID0gYXdhaXQgS2V5RmFjdG9yeVNlcnZpY2UuYXNLZXkoXG4gICAgICBwbGFpbkluaXRpYXRvck9uZVRpbWVQYmtDaXBoZXIucmVzcG9uZGVyLnBia1xuICAgICk7XG5cbiAgICBjb25zdCBzaWduZWRSZXNwb25kZXJQYmsgPSBhd2FpdCB0aGlzLmVuY3J5cHRpb25TZXJ2aWNlLnNpZ24oXG4gICAgICBpbml0aWF0b3JTaWdQcmsuandrLFxuICAgICAgcmVzcG9uZGVyUGJrLnRvSlNPTigpXG4gICAgKTtcbiAgICBjb25zdCBzaWduZWRSZXNwb25kZXJTaWdQYmsgPSBhd2FpdCB0aGlzLmVuY3J5cHRpb25TZXJ2aWNlLnNpZ24oXG4gICAgICBpbml0aWF0b3JTaWdQcmsuandrLFxuICAgICAgcmVzcG9uZGVyU2lnUGJrLnRvSlNPTigpXG4gICAgKTtcblxuICAgIGNvbnN0IHNoYXJlZEtleSA9IGF3YWl0IEtleUZhY3RvcnlTZXJ2aWNlLmFzS2V5KFxuICAgICAgcGxhaW5Jbml0aWF0b3JPbmVUaW1lUGJrQ2lwaGVyLnNoYXJlZEtleVxuICAgICk7XG4gICAgY29uc3QgcmtXcmFwcGVkU2hhcmVkS2V5ID0gYXdhaXQgdGhpcy5lbmNyeXB0aW9uU2VydmljZS5lbmNyeXB0KFxuICAgICAgcm9vdEtleS5qd2ssXG4gICAgICBzaGFyZWRLZXkudG9KU09OKHRydWUpXG4gICAgKTtcblxuICAgIGNvbnN0IG1rU2hhcmVkS2V5ID0gYXdhaXQgS2V5RmFjdG9yeVNlcnZpY2UuYXNLZXkoXG4gICAgICBwbGFpbkluaXRpYXRvck9uZVRpbWVQYmtDaXBoZXIubWtTaGFyZWRLZXlcbiAgICApO1xuICAgIGNvbnN0IG1rV3JhcHBlZE1rU2hhcmVkS2V5ID0gYXdhaXQgdGhpcy5lbmNyeXB0aW9uU2VydmljZS5lbmNyeXB0KFxuICAgICAgbWFzdGVyS2V5Lmp3ayxcbiAgICAgIG1rU2hhcmVkS2V5LnRvSlNPTih0cnVlKVxuICAgICk7XG5cbiAgICBsZXQgcmVzcG9uZGVyQ29udGFjdENhcmRDaXBoZXJJbnB1dDtcbiAgICBpZiAocmVzcG9uZGVyQ29udGFjdENhcmQpIHtcbiAgICAgIC8vIENyZWF0ZSBrZXlcbiAgICAgIGNvbnN0IHJlY2VpdmVyS2V5ID0gYXdhaXQgdGhpcy5rZXlGYWN0b3J5LmNyZWF0ZUtleSgpO1xuXG4gICAgICByZXNwb25kZXJDb250YWN0Q2FyZENpcGhlcklucHV0ID0ge1xuICAgICAgICByZWNlaXZlcldyYXBwZWRLZXk6IEpTT04uc3RyaW5naWZ5KFxuICAgICAgICAgIGF3YWl0IHRoaXMuZW5jcnlwdGlvblNlcnZpY2UuZW5jcnlwdChcbiAgICAgICAgICAgIHJvb3RLZXkuandrLFxuICAgICAgICAgICAgcmVjZWl2ZXJLZXkudG9KU09OKHRydWUpXG4gICAgICAgICAgKVxuICAgICAgICApLFxuICAgICAgICByZWNlaXZlcldyYXBwaW5nS2V5SWQ6IHJvb3RLZXkuaWQsXG4gICAgICAgIHJlY2VpdmVyQ2lwaGVyRGF0YTogSlNPTi5zdHJpbmdpZnkoXG4gICAgICAgICAgYXdhaXQgdGhpcy5lbmNyeXB0aW9uU2VydmljZS5lbmNyeXB0KFxuICAgICAgICAgICAgcmVjZWl2ZXJLZXksXG4gICAgICAgICAgICByZXNwb25kZXJDb250YWN0Q2FyZC5yZWNlaXZlckNpcGhlckRhdGFDbGVhckpzb25cbiAgICAgICAgICApXG4gICAgICAgICksXG4gICAgICB9O1xuICAgIH1cblxuICAgIC8vIEdldCB0aGUgZGF0YSBuZWVkZWQgZnJvbSB0aGUgaW5pdGlhdG9yJ3MgY2lwaGVyIGRhdGEuXG4gICAgbGV0IGluaXRpYXRvckNvbnRhY3RDYXJkQ2lwaGVySW5wdXQ7XG4gICAgbGV0IGluaXRpYXRvckNvbnRhY3RDYXJkU2hhcmVkQ2lwaGVySW5wdXQ7XG4gICAgaWYgKGluaXRpYXRvclJvb3RLZXlDaXBoZXJDbGVhckpzb24uaW5pdGlhdG9yQ29udGFjdENhcmQpIHtcbiAgICAgIC8vIFRoZSBpbml0aWF0b3JDb250YWN0Q2FyZCBjcmVhdGVkIGR1cmluZyB0aGUgY3JlYXRpb24gb2YgdGhlIGludml0ZSBhbmQgZW5jcnlwdGVkIHVzaW5nIHRoZSBpbml0aWF0b3Inc1xuICAgICAgLy8gcm9vdCBrZXlcbiAgICAgIGNvbnN0IGluaXRpYXRvckNvbnRhY3RDYXJkRnJvbUluaXQgPVxuICAgICAgICBpbml0aWF0b3JSb290S2V5Q2lwaGVyQ2xlYXJKc29uLmluaXRpYXRvckNvbnRhY3RDYXJkO1xuICAgICAgY29uc3Qgb3duZXJLZXkgPSBhd2FpdCB0aGlzLmtleUZhY3RvcnkuY3JlYXRlS2V5KCk7XG4gICAgICBjb25zdCBzaGFyZWRDaXBoZXJLZXkgPSBhd2FpdCBLZXlGYWN0b3J5U2VydmljZS5hc0tleShcbiAgICAgICAgcGxhaW5Jbml0aWF0b3JPbmVUaW1lUGJrQ2lwaGVyLnJlc3BvbmRlci5jb250YWN0Q2FyZC5zaGFyZWRDaXBoZXJLZXlcbiAgICAgICk7XG5cbiAgICAgIGNvbnN0IG93bmVyV3JhcHBlZEtleSA9IEpTT04uc3RyaW5naWZ5KFxuICAgICAgICBhd2FpdCB0aGlzLmVuY3J5cHRpb25TZXJ2aWNlLmVuY3J5cHQocm9vdEtleS5qd2ssIG93bmVyS2V5LnRvSlNPTih0cnVlKSlcbiAgICAgICk7XG5cbiAgICAgIC8vIEFsbG93IHRoZSBpbml0aWF0b3JDb250YWN0Q2FyZCBwYXJhbWV0ZXIgdG8gb3ZlcnJpZGVcbiAgICAgIGNvbnN0IG93bmVyQ2lwaGVyRGF0YUNsZWFySnNvbiA9XG4gICAgICAgIGluaXRpYXRvckNvbnRhY3RDYXJkPy5vd25lckNpcGhlckRhdGFDbGVhckpzb24gfHxcbiAgICAgICAgaW5pdGlhdG9yQ29udGFjdENhcmRGcm9tSW5pdC5vd25lckNpcGhlckRhdGFDbGVhckpzb247XG5cbiAgICAgIGNvbnN0IG93bmVyQ2lwaGVyRGF0YSA9IG93bmVyQ2lwaGVyRGF0YUNsZWFySnNvblxuICAgICAgICA/IGF3YWl0IHRoaXMua2V5R3JhcGguZW5jcnlwdFRvU3RyaW5nKFxuICAgICAgICAgICAgb3duZXJLZXksXG4gICAgICAgICAgICBvd25lckNpcGhlckRhdGFDbGVhckpzb25cbiAgICAgICAgICApXG4gICAgICAgIDogJyc7XG5cbiAgICAgIGluaXRpYXRvckNvbnRhY3RDYXJkQ2lwaGVySW5wdXQgPSB7XG4gICAgICAgIG93bmVyV3JhcHBlZEtleSxcbiAgICAgICAgb3duZXJXcmFwcGluZ0tleUlkOiByb290S2V5LmlkLFxuICAgICAgICBvd25lckNpcGhlckRhdGEsXG4gICAgICB9O1xuXG4gICAgICBpbml0aWF0b3JDb250YWN0Q2FyZFNoYXJlZENpcGhlcklucHV0ID0ge1xuICAgICAgICBzaWdQeGtJZDogaW5pdGlhdG9yU2lnUHJrLmlkLFxuICAgICAgfTtcblxuICAgICAgY29uc3Qgc2hhcmVkQ2lwaGVyRGF0YSA9IGF3YWl0IHRoaXMuZW5jcnlwdGlvblNlcnZpY2UuZW5jcnlwdChcbiAgICAgICAgc2hhcmVkQ2lwaGVyS2V5LFxuICAgICAgICBpbml0aWF0b3JDb250YWN0Q2FyZEZyb21Jbml0LnNoYXJlZENpcGhlckRhdGFDbGVhckpzb25cbiAgICAgICk7XG4gICAgICBpbml0aWF0b3JDb250YWN0Q2FyZFNoYXJlZENpcGhlcklucHV0LnNoYXJlZENpcGhlckRhdGFTaWcgPSBKU09OLnN0cmluZ2lmeShcbiAgICAgICAgYXdhaXQgdGhpcy5lbmNyeXB0aW9uU2VydmljZS5zaWduKGluaXRpYXRvclNpZ1Byay5qd2ssIHNoYXJlZENpcGhlckRhdGEpXG4gICAgICApO1xuICAgIH1cblxuICAgIC8vIFRPRE8gaWRlYWxseSB3ZSB1cGRhdGUgdGhlIHNoYXJlZCBkYXRhIGluIHRoZSBjb250YWN0IGNhcmQgc2VudCB0byB0aGUgcmVzcG9uZGVyIGFzIHdlbGwgc2luY2UgdGhhdFxuICAgIC8vIENDIHdhcyBjcmVhdGVkIGJ5IHRoZSByZXNwb25kZXIuXG5cbiAgICByZXR1cm4gbmV3IExyTXV0YXRpb24oe1xuICAgICAgbXV0YXRpb246IENvbXBsZXRlS2V5RXhjaGFuZ2VPdGtNdXRhdGlvbixcbiAgICAgIHZhcmlhYmxlczoge1xuICAgICAgICBpbnB1dDoge1xuICAgICAgICAgIGtleUV4Y2hhbmdlSWQsXG4gICAgICAgICAgcm9vdEtleUlkOiByb290S2V5LmlkLFxuICAgICAgICAgIG1hc3RlcktleUlkOiBtYXN0ZXJLZXkuaWQsXG4gICAgICAgICAgaW5pdGlhdG9yU2lnUHhrSWQ6IGluaXRpYXRvclNpZ1Byay5pZCxcbiAgICAgICAgICBzaWduZWRSZXNwb25kZXJQYms6IEpTT04uc3RyaW5naWZ5KHNpZ25lZFJlc3BvbmRlclBiayksXG4gICAgICAgICAgc2lnbmVkUmVzcG9uZGVyU2lnUGJrOiBKU09OLnN0cmluZ2lmeShzaWduZWRSZXNwb25kZXJTaWdQYmspLFxuICAgICAgICAgIHJrV3JhcHBlZFNoYXJlZEtleTogSlNPTi5zdHJpbmdpZnkocmtXcmFwcGVkU2hhcmVkS2V5KSxcbiAgICAgICAgICBta1dyYXBwZWRNa1NoYXJlZEtleTogSlNPTi5zdHJpbmdpZnkobWtXcmFwcGVkTWtTaGFyZWRLZXkpLFxuICAgICAgICAgIHJlc3BvbmRlckNvbnRhY3RDYXJkQ2lwaGVyOiByZXNwb25kZXJDb250YWN0Q2FyZENpcGhlcklucHV0LFxuICAgICAgICAgIGluaXRpYXRvckNvbnRhY3RDYXJkQ2lwaGVyOiBpbml0aWF0b3JDb250YWN0Q2FyZENpcGhlcklucHV0LFxuICAgICAgICAgIGluaXRpYXRvckNvbnRhY3RDYXJkU2hhcmVkQ2lwaGVyOiBpbml0aWF0b3JDb250YWN0Q2FyZFNoYXJlZENpcGhlcklucHV0LFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9KTtcbiAgfVxufVxuIl19
1
+ import { __awaiter, __decorate } from "tslib";
2
+ import { Injectable, NgZone } from '@angular/core';
3
+ import { EncryptionService, JoseSerialization, } from '../cryptography/encryption.service';
4
+ import { KeyFactoryService } from '../cryptography/key-factory.service';
5
+ import { KeyGraphService } from '../cryptography/key-graph.service';
6
+ import { KeyService } from '../cryptography/key.service';
7
+ import { LrCodeMismatchException } from '../_common/exceptions';
8
+ import { RunOutsideAngular } from '../_common/run-outside-angular';
9
+ import { UserService } from './../users/user.service';
10
+ import { CancelKeyExchangeMutation, CompleteKeyExchangeOtkMutation, CurrentUserSharedKeyQuery2, DeclineKeyExchangeMutation, InitiateKeyExchangeOtkMutation, KeyExchangeQuery2, KeyExchangesQuery2, KeyExchangeTokenQuery2, RespondKeyExchangeOtkMutation, } from './key-exchange2.gql';
11
+ import { LrGraphQLService, LrMutation } from './lr-graphql';
12
+ import * as i0 from "@angular/core";
13
+ import * as i1 from "../cryptography/key-factory.service";
14
+ import * as i2 from "../cryptography/key.service";
15
+ import * as i3 from "../cryptography/encryption.service";
16
+ import * as i4 from "../users/user.service";
17
+ import * as i5 from "../cryptography/key-graph.service";
18
+ import * as i6 from "./lr-graphql/lr-graphql.service";
19
+ let KeyExchange2Service = class KeyExchange2Service {
20
+ constructor(ngZone, keyFactory, keyService, encryptionService, userService, keyGraph, lrGraphQL) {
21
+ this.ngZone = ngZone;
22
+ this.keyFactory = keyFactory;
23
+ this.keyService = keyService;
24
+ this.encryptionService = encryptionService;
25
+ this.userService = userService;
26
+ this.keyGraph = keyGraph;
27
+ this.lrGraphQL = lrGraphQL;
28
+ this.CLIENT_NONCE_LENGTH = 32;
29
+ }
30
+ getOtKey(keyExchange, otKeyK) {
31
+ return __awaiter(this, void 0, void 0, function* () {
32
+ if (otKeyK) {
33
+ return yield KeyFactoryService.asKey(Object.assign(Object.assign({}, JSON.parse(keyExchange.otk.otKeyParams)), { k: otKeyK }));
34
+ }
35
+ else if (keyExchange.otk.state === 'OTK_INITIATED' &&
36
+ !keyExchange.isInitiator &&
37
+ keyExchange.otk.responderPbkCipher) {
38
+ // Assuming existing user getting invited where OTK is wrapped in responder's public key.
39
+ const prk = yield this.keyService.getCurrentPxk();
40
+ const decryptedCipher = yield this.encryptionService.decrypt(prk.jwk, JSON.parse(keyExchange.otk.responderPbkCipher), {
41
+ serializations: [JoseSerialization.COMPACT],
42
+ });
43
+ if (decryptedCipher.otKey) {
44
+ return yield KeyFactoryService.asKey(decryptedCipher.otKey);
45
+ }
46
+ }
47
+ return null;
48
+ });
49
+ }
50
+ decryptOtk(keyExchange, otKeyK) {
51
+ return __awaiter(this, void 0, void 0, function* () {
52
+ const otKey = yield this.getOtKey(keyExchange, otKeyK);
53
+ let otk = keyExchange.otk;
54
+ if (otKey && otk.otKeyCipher) {
55
+ otk = Object.assign(Object.assign({}, otk), { otKey, otKeyCipherClearJson: yield this.encryptionService.decrypt(otKey, keyExchange.otk.otKeyCipher) });
56
+ }
57
+ return Object.assign(Object.assign({}, keyExchange), { otk });
58
+ });
59
+ }
60
+ decryptResponseCipher(otKey, otPrk, content) {
61
+ return __awaiter(this, void 0, void 0, function* () {
62
+ // The response could be wrapped by the OtK in addition to the OtPbk
63
+ try {
64
+ content = yield this.encryptionService.decrypt(otKey, content);
65
+ }
66
+ catch (error) {
67
+ if (error.message !== 'no key found') {
68
+ throw error;
69
+ }
70
+ // Do nothing to support older versions where message is not wrapped with otk.
71
+ }
72
+ // The Prk is single-use and only used to send information from the responder back to the initiator.
73
+ return yield this.encryptionService.decrypt(otPrk, content);
74
+ });
75
+ }
76
+ decryptKeyExchangeAsInitiator(keyExchange) {
77
+ return __awaiter(this, void 0, void 0, function* () {
78
+ const rootKey = yield this.keyService.getCurrentRootKey();
79
+ // Decrypt using the root key to get the Prk
80
+ const initiatorRootKeyCipherClearJson = (yield this.encryptionService.decrypt(rootKey.jwk, keyExchange.initiatorRootKeyCipher));
81
+ const otKey = yield KeyFactoryService.asKey(initiatorRootKeyCipherClearJson.otKey);
82
+ keyExchange = Object.assign(Object.assign({}, keyExchange), { initiatorRootKeyCipherClearJson });
83
+ let otk = keyExchange.otk;
84
+ if (otk.initiatorOneTimePbkCipher) {
85
+ otk = Object.assign(Object.assign({}, otk), { initiatorOneTimePbkCipherClearJson: yield this.decryptResponseCipher(otKey, yield KeyFactoryService.asKey(initiatorRootKeyCipherClearJson.oneTimePrk), otk.initiatorOneTimePbkCipher) });
86
+ }
87
+ if (otk.otKeyCipher) {
88
+ otk.otKeyCipherClearJson = yield this.encryptionService.decrypt(otKey, otk.otKeyCipher);
89
+ }
90
+ return Object.assign(Object.assign({}, keyExchange), { otk });
91
+ });
92
+ }
93
+ decryptKeyExchangeAsResponder(keyExchange, otKeyK) {
94
+ return __awaiter(this, void 0, void 0, function* () {
95
+ return this.decryptOtk(keyExchange, otKeyK);
96
+ });
97
+ }
98
+ decryptKeyExchange(keyExchange, otKeyK) {
99
+ return __awaiter(this, void 0, void 0, function* () {
100
+ if (keyExchange.isInitiator) {
101
+ return this.decryptKeyExchangeAsInitiator(keyExchange);
102
+ }
103
+ else {
104
+ return this.decryptKeyExchangeAsResponder(keyExchange, otKeyK);
105
+ }
106
+ });
107
+ }
108
+ getKeyExchanges({ state } = {}) {
109
+ return __awaiter(this, void 0, void 0, function* () {
110
+ const { keyExchanges } = yield this.lrGraphQL.query({
111
+ query: KeyExchangesQuery2,
112
+ variables: {
113
+ state,
114
+ },
115
+ });
116
+ return Promise.all(keyExchanges.edges.map((edge) => this.decryptKeyExchange(edge.node)));
117
+ });
118
+ }
119
+ /**
120
+ * @param id If the current user can responder the key exchange if they are either the initiator or the receiver.
121
+ * @param token If not signed in, or not the initiator or responder, 'token' must be given.
122
+ * @param otKeyK Is the raw one-time key (string). If the responder is explicitly specified at time of initiation, then
123
+ * it's possible to have the otKey wrapped by the public key of the responder. In which case, the otKeyK is not needed.
124
+ */
125
+ getKeyExchange(id, { otKeyK, token } = {}) {
126
+ return __awaiter(this, void 0, void 0, function* () {
127
+ const res = yield this.lrGraphQL.query({
128
+ query: token ? KeyExchangeTokenQuery2 : KeyExchangeQuery2,
129
+ variables: {
130
+ id,
131
+ token,
132
+ },
133
+ includeKeyGraph: !token,
134
+ });
135
+ return this.decryptKeyExchange(res.keyExchange, otKeyK);
136
+ });
137
+ }
138
+ getCurrentUserSharedKey(input) {
139
+ return __awaiter(this, void 0, void 0, function* () {
140
+ return this.lrGraphQL.query({
141
+ query: CurrentUserSharedKeyQuery2,
142
+ variables: {
143
+ username: input.username,
144
+ userId: input.userId,
145
+ },
146
+ });
147
+ });
148
+ }
149
+ // TODO: deprecate this
150
+ cancelKeyExchange(id) {
151
+ return __awaiter(this, void 0, void 0, function* () {
152
+ return this.cancelKeyExchangeMutation(id);
153
+ });
154
+ }
155
+ cancelKeyExchangeMutation(id) {
156
+ return new LrMutation({
157
+ mutation: CancelKeyExchangeMutation,
158
+ variables: {
159
+ input: {
160
+ id,
161
+ },
162
+ },
163
+ });
164
+ }
165
+ // TODO: deprecate this
166
+ declineKeyExchange(id, token) {
167
+ return __awaiter(this, void 0, void 0, function* () {
168
+ return this.declineKeyExchangeMutation(id, token);
169
+ });
170
+ }
171
+ declineKeyExchangeMutation(id, token) {
172
+ return new LrMutation({
173
+ mutation: DeclineKeyExchangeMutation,
174
+ variables: {
175
+ input: {
176
+ id,
177
+ token,
178
+ },
179
+ },
180
+ });
181
+ }
182
+ initiateOtk({ message, email, contactCard, upgrade, } = {}) {
183
+ return __awaiter(this, void 0, void 0, function* () {
184
+ const otKey = yield this.keyFactory.createKey();
185
+ const nonce = this.keyFactory.randomString(this.CLIENT_NONCE_LENGTH);
186
+ // New PKC key for encryption. This key is used only once when the responder sends
187
+ // back their signing public key.
188
+ const initiatorOneTimePrk = yield this.keyFactory.createPkcKey();
189
+ // Option 1: New PKC key for signing
190
+ // const initiatorSigPrk = await this.keyService.createPkcSignKey();
191
+ // Option 2: Use the user's global signing key.
192
+ // This key is used to prove the initiator's identity.
193
+ const initiatorPrk = yield this.keyService.getCurrentPxk();
194
+ const initiatorSigPrk = yield this.keyService.getCurrentSigPxk();
195
+ let initiatorPlainDataSig = null;
196
+ if (contactCard && contactCard.ownerPlainDataJson) {
197
+ initiatorPlainDataSig = yield this.encryptionService.signToString(initiatorSigPrk.jwk, contactCard.ownerPlainDataJson);
198
+ }
199
+ const initiator = {
200
+ message,
201
+ contactCard: contactCard && {
202
+ sharedCipherDataClearJson: contactCard.sharedCipherDataClearJson,
203
+ },
204
+ };
205
+ // Content to be encrypted using the OTK.
206
+ const plainOtKeyCipher = {
207
+ // TODO Make sure we also put the OOB code in here as well since the OOB code is the
208
+ // _only_ information the KC server does not have access to. The server may have
209
+ // access to OTK and hence the nonce here. It's good to have both the nonce and OOB code
210
+ // since the user may not be using the OOB code. And it's simple to always include
211
+ // the nonce, so why not.
212
+ nonce,
213
+ initiator: Object.assign(Object.assign({}, initiator), { oneTimePbk: initiatorOneTimePrk.toJSON(), pbk: initiatorPrk.jwk.toJSON(), sigPbk: initiatorSigPrk.jwk.toJSON() }),
214
+ };
215
+ const otKeyCipher = yield this.keyGraph.encryptToString(otKey, plainOtKeyCipher);
216
+ // Content to be encrypted using the initiator's root key.
217
+ const initiatorRootKeyCipherClearJson = {
218
+ nonce,
219
+ oneTimePrk: initiatorOneTimePrk.toJSON(true),
220
+ // Should not need to keep this encrypted since we are using the global signing key.
221
+ // sigPrk: initiatorSigPrk.toJSON(true),
222
+ // Save it in case the initiator want to decode the otKeyCipher.
223
+ // Since the otKey is only used once, and that otKeyCipher contains only
224
+ // the public key of the initiator, it's safe just leave the otKey stored here.
225
+ otKey: otKey.toJSON(true),
226
+ // These should be storing information such as how the fields of the shared contact card is
227
+ // derived from the master contact card.
228
+ initiatorContactCard: contactCard,
229
+ initiator,
230
+ };
231
+ const rootKey = yield this.keyService.getCurrentRootKey();
232
+ const initiatorRootKeyCipher = yield this.keyGraph.encryptToString(rootKey.jwk, initiatorRootKeyCipherClearJson);
233
+ // The raw OTK
234
+ const otKeyK = otKey.toJSON(true).k;
235
+ // API call
236
+ const lrMutation = new LrMutation({
237
+ mutation: InitiateKeyExchangeOtkMutation,
238
+ variables: {
239
+ input: {
240
+ // These will be stored on the server
241
+ initiatorRootKeyCipher,
242
+ initiatorPxkId: initiatorPrk.id,
243
+ initiatorSigPxkId: initiatorSigPrk.id,
244
+ // These will be sent to the responder
245
+ otKeyParams: JSON.stringify(otKey.toJSON()),
246
+ otKeyCipher,
247
+ sendEmail: email && {
248
+ email,
249
+ rawOtKey: otKeyK,
250
+ },
251
+ createTp: true,
252
+ initiatorPlainDataSig,
253
+ upgrade,
254
+ },
255
+ },
256
+ });
257
+ return { lrMutation, otKeyK };
258
+ });
259
+ }
260
+ respondOtk({ keyExchangeId, token, decryptedOtk, message, initiatorContactCard, responderContactCard, }) {
261
+ return __awaiter(this, void 0, void 0, function* () {
262
+ const rootKey = yield this.keyService.getCurrentRootKey();
263
+ const masterKeyId = this.keyService.getCurrentMasterKey().id;
264
+ const masterKey = yield this.keyService.getCurrentMasterKey();
265
+ const sharedKey = yield this.keyFactory.createKey();
266
+ const mkSharedKey = yield this.keyFactory.createKey();
267
+ const rkWrappedSharedKey = yield this.encryptionService.encrypt(rootKey.jwk, sharedKey.toJSON(true));
268
+ const mkWrappedMkSharedKey = yield this.encryptionService.encrypt(masterKey.jwk, mkSharedKey.toJSON(true));
269
+ const initiatorOneTimePbk = yield KeyFactoryService.asKey(decryptedOtk.otKeyCipherClearJson.initiator.oneTimePbk);
270
+ const initiatorPbk = yield KeyFactoryService.asKey(decryptedOtk.otKeyCipherClearJson.initiator.pbk);
271
+ const initiatorSigPbk = yield KeyFactoryService.asKey(decryptedOtk.otKeyCipherClearJson.initiator.sigPbk);
272
+ // Option 1: Using new Prk for each TP pair
273
+ // Create a new public signing key for the responder.
274
+ // const responderSigPrk = await this.keyService.createPkcSignKey()
275
+ // const rkWrappedResponderSigPrk = await this.encrypt(rootKey, responderSigPrk.toJSON(true));
276
+ // Option 2: Responder already has a signing Prk
277
+ const responderPrk = yield this.keyService.getCurrentPxk();
278
+ const responderSigPrk = yield this.keyService.getCurrentSigPxk();
279
+ const signedInitiatorPbk = yield this.encryptionService.sign(responderSigPrk.jwk, initiatorPbk.toJSON());
280
+ const signedInitiatorSigPbk = yield this.encryptionService.sign(responderSigPrk.jwk, initiatorSigPbk.toJSON());
281
+ const initiatorOneTimePbkCipherClearJson = {
282
+ nonce: decryptedOtk.otKeyCipherClearJson.nonce,
283
+ sharedKey: sharedKey.toJSON(true),
284
+ mkSharedKey: mkSharedKey.toJSON(true),
285
+ responder: {
286
+ pbk: responderPrk.jwk.toJSON(),
287
+ sigPbk: responderSigPrk.jwk.toJSON(),
288
+ message,
289
+ },
290
+ };
291
+ let receivedCardInput;
292
+ if (decryptedOtk.otKeyCipherClearJson.initiator.contactCard) {
293
+ // Set the info about the initiator to be the ones sent by the initiator. We need th responder to do the encryption here
294
+ // because the initiator does not have the shared key yet, and we want the responder to have a functional contact card after
295
+ // this exchange. The initiator can double check the contact details are correct and sign it when it completes the exchange.
296
+ const sharedCipherDataClearJson = decryptedOtk.otKeyCipherClearJson.initiator.contactCard
297
+ .sharedCipherDataClearJson;
298
+ // Create keys
299
+ const receiverKey = yield this.keyFactory.createKey();
300
+ const ccSharedKey = yield this.keyFactory.createKey();
301
+ const sigPxk = yield this.keyService.getCurrentSigPxk();
302
+ receivedCardInput = {
303
+ receiverWrappedKey: JSON.stringify(yield this.encryptionService.encrypt(rootKey.jwk, receiverKey.toJSON(true))),
304
+ receiverWrappingKeyId: rootKey.id,
305
+ receiverCipherData: initiatorContactCard
306
+ ? JSON.stringify(yield this.encryptionService.encrypt(receiverKey, initiatorContactCard.receiverCipherDataClearJson))
307
+ : '',
308
+ sharedWrappedKey: JSON.stringify(yield this.encryptionService.encrypt(sharedKey, ccSharedKey.toJSON(true))),
309
+ };
310
+ const sharedCipherData = yield this.encryptionService.encrypt(ccSharedKey, sharedCipherDataClearJson);
311
+ receivedCardInput.sharedCipherDataSig = JSON.stringify(yield this.encryptionService.sign(sigPxk.jwk, sharedCipherData));
312
+ receivedCardInput.sigPxkId = sigPxk.id;
313
+ initiatorOneTimePbkCipherClearJson.responder.contactCard = Object.assign(Object.assign({}, initiatorOneTimePbkCipherClearJson.responder.contactCard), { sharedCipherKey: ccSharedKey.toJSON(true) });
314
+ }
315
+ let responderCardInput;
316
+ if (responderContactCard) {
317
+ // Create keys
318
+ const ownerKey = yield this.keyFactory.createKey();
319
+ const ccSharedKey = yield this.keyFactory.createKey();
320
+ const sigPxk = yield this.keyService.getCurrentSigPxk();
321
+ responderCardInput = {
322
+ ownerWrappedKey: JSON.stringify(yield this.encryptionService.encrypt(rootKey.jwk, ownerKey.toJSON(true))),
323
+ ownerWrappingKeyId: rootKey.id,
324
+ ownerCipherData: responderContactCard.ownerCipherDataClearJson
325
+ ? JSON.stringify(yield this.encryptionService.encrypt(ownerKey, responderContactCard.ownerCipherDataClearJson))
326
+ : '',
327
+ sharedWrappedKey: JSON.stringify(yield this.encryptionService.encrypt(sharedKey, ccSharedKey.toJSON(true))),
328
+ };
329
+ const sharedCipherData = yield this.encryptionService.encrypt(ccSharedKey, responderContactCard.sharedCipherDataClearJson);
330
+ responderCardInput.sharedCipherDataSig = JSON.stringify(yield this.encryptionService.sign(sigPxk.jwk, sharedCipherData));
331
+ responderCardInput.sigPxkId = sigPxk.id;
332
+ if (responderContactCard.ownerPlainDataJson) {
333
+ responderCardInput.ownerPlainDataSig = JSON.stringify(yield this.encryptionService.sign(responderSigPrk.jwk, responderContactCard.ownerPlainDataJson));
334
+ }
335
+ // Contact card info readable by the initiator
336
+ initiatorOneTimePbkCipherClearJson.responder.contactCard = Object.assign(Object.assign({}, initiatorOneTimePbkCipherClearJson.responder.contactCard), { sharedCipherDataClearJson: responderContactCard.sharedCipherDataClearJson });
337
+ }
338
+ // Encrypt with one-time public key
339
+ let initiatorOneTimePbkCipher = yield this.encryptionService.encrypt(initiatorOneTimePbk, initiatorOneTimePbkCipherClearJson);
340
+ // Encrypt with the otk again to keep use of asymmetric keys to a minimum.
341
+ initiatorOneTimePbkCipher = yield this.encryptionService.encrypt(decryptedOtk.otKey, initiatorOneTimePbkCipher);
342
+ return new LrMutation({
343
+ mutation: RespondKeyExchangeOtkMutation,
344
+ variables: {
345
+ input: {
346
+ keyExchangeId,
347
+ keyExchangeToken: token,
348
+ rootKeyId: rootKey.id,
349
+ masterKeyId,
350
+ // These will be stored on the server
351
+ responderPxkId: responderPrk.id,
352
+ responderSigPxkId: responderSigPrk.id,
353
+ signedInitiatorPbk: JSON.stringify(signedInitiatorPbk),
354
+ signedInitiatorSigPbk: JSON.stringify(signedInitiatorSigPbk),
355
+ // rkWrappedInitiatorSigPbk: JSON.stringify(rkWrappedInitiatorSigPbk),
356
+ // Option 1: Using new Prk for each TP pair
357
+ // rkWrappedResponderSigPrk: JSON.stringify(rkWrappedResponderSigPrk),
358
+ rkWrappedSharedKey: JSON.stringify(rkWrappedSharedKey),
359
+ mkWrappedMkSharedKey: JSON.stringify(mkWrappedMkSharedKey),
360
+ // These will be sent to the initiator
361
+ initiatorOneTimePbkCipher: JSON.stringify(initiatorOneTimePbkCipher),
362
+ initiatorContactCard: receivedCardInput,
363
+ responderContactCard: responderCardInput,
364
+ },
365
+ },
366
+ });
367
+ });
368
+ }
369
+ completeOtk({ keyExchangeId, initiatorRootKeyCipher, initiatorOneTimePbkCipher, responderContactCard, initiatorContactCard, }) {
370
+ return __awaiter(this, void 0, void 0, function* () {
371
+ const rootKey = yield this.keyService.getCurrentRootKey();
372
+ const masterKey = yield this.keyService.getCurrentMasterKey();
373
+ // Decrypt using the root key to get the Prk
374
+ const initiatorRootKeyCipherClearJson = (yield this.encryptionService.decrypt(rootKey.jwk, initiatorRootKeyCipher));
375
+ // The Prk is single-use and only used to send information from the responder back to the initiator.
376
+ const plainInitiatorOneTimePbkCipher = yield this.decryptResponseCipher(yield KeyFactoryService.asKey(initiatorRootKeyCipherClearJson.otKey), yield KeyFactoryService.asKey(initiatorRootKeyCipherClearJson.oneTimePrk), initiatorOneTimePbkCipher);
377
+ // Check the nonce match to ensure the responder was the one holding the OTK
378
+ if (initiatorRootKeyCipherClearJson.nonce !==
379
+ plainInitiatorOneTimePbkCipher.nonce) {
380
+ throw new LrCodeMismatchException('The nonce returned by responder does not match with the one created by the initiator.');
381
+ }
382
+ // Option 1: Assuming the signing key is unique between users.
383
+ // const initiatorSigPrk = await KFS.asKey(ke.plainInitiatorRootKeyCipher.sigPrk);
384
+ // const rkWrappedInitiatorSigPrk = await this.encrypt(rootKey, initiatorSigPrk.toJSON(true));
385
+ // Option 2: Use the user's global signing key.
386
+ // In this case the initiatorSigPrk is already a part of the key graph.
387
+ // So there's nothing to do here.
388
+ // Protected the signing public key of the responder.
389
+ const initiatorSigPrk = yield this.keyService.getCurrentSigPxk();
390
+ const responderSigPbk = yield KeyFactoryService.asKey(plainInitiatorOneTimePbkCipher.responder.sigPbk);
391
+ const responderPbk = yield KeyFactoryService.asKey(plainInitiatorOneTimePbkCipher.responder.pbk);
392
+ const signedResponderPbk = yield this.encryptionService.sign(initiatorSigPrk.jwk, responderPbk.toJSON());
393
+ const signedResponderSigPbk = yield this.encryptionService.sign(initiatorSigPrk.jwk, responderSigPbk.toJSON());
394
+ const sharedKey = yield KeyFactoryService.asKey(plainInitiatorOneTimePbkCipher.sharedKey);
395
+ const rkWrappedSharedKey = yield this.encryptionService.encrypt(rootKey.jwk, sharedKey.toJSON(true));
396
+ const mkSharedKey = yield KeyFactoryService.asKey(plainInitiatorOneTimePbkCipher.mkSharedKey);
397
+ const mkWrappedMkSharedKey = yield this.encryptionService.encrypt(masterKey.jwk, mkSharedKey.toJSON(true));
398
+ let responderContactCardCipherInput;
399
+ if (responderContactCard) {
400
+ // Create key
401
+ const receiverKey = yield this.keyFactory.createKey();
402
+ responderContactCardCipherInput = {
403
+ receiverWrappedKey: JSON.stringify(yield this.encryptionService.encrypt(rootKey.jwk, receiverKey.toJSON(true))),
404
+ receiverWrappingKeyId: rootKey.id,
405
+ receiverCipherData: JSON.stringify(yield this.encryptionService.encrypt(receiverKey, responderContactCard.receiverCipherDataClearJson)),
406
+ };
407
+ }
408
+ // Get the data needed from the initiator's cipher data.
409
+ let initiatorContactCardCipherInput;
410
+ let initiatorContactCardSharedCipherInput;
411
+ if (initiatorRootKeyCipherClearJson.initiatorContactCard) {
412
+ // The initiatorContactCard created during the creation of the invite and encrypted using the initiator's
413
+ // root key
414
+ const initiatorContactCardFromInit = initiatorRootKeyCipherClearJson.initiatorContactCard;
415
+ const ownerKey = yield this.keyFactory.createKey();
416
+ const sharedCipherKey = yield KeyFactoryService.asKey(plainInitiatorOneTimePbkCipher.responder.contactCard.sharedCipherKey);
417
+ const ownerWrappedKey = JSON.stringify(yield this.encryptionService.encrypt(rootKey.jwk, ownerKey.toJSON(true)));
418
+ // Allow the initiatorContactCard parameter to override
419
+ const ownerCipherDataClearJson = (initiatorContactCard === null || initiatorContactCard === void 0 ? void 0 : initiatorContactCard.ownerCipherDataClearJson) ||
420
+ initiatorContactCardFromInit.ownerCipherDataClearJson;
421
+ const ownerCipherData = ownerCipherDataClearJson
422
+ ? yield this.keyGraph.encryptToString(ownerKey, ownerCipherDataClearJson)
423
+ : '';
424
+ initiatorContactCardCipherInput = {
425
+ ownerWrappedKey,
426
+ ownerWrappingKeyId: rootKey.id,
427
+ ownerCipherData,
428
+ };
429
+ initiatorContactCardSharedCipherInput = {
430
+ sigPxkId: initiatorSigPrk.id,
431
+ };
432
+ const sharedCipherData = yield this.encryptionService.encrypt(sharedCipherKey, initiatorContactCardFromInit.sharedCipherDataClearJson);
433
+ initiatorContactCardSharedCipherInput.sharedCipherDataSig = JSON.stringify(yield this.encryptionService.sign(initiatorSigPrk.jwk, sharedCipherData));
434
+ }
435
+ // TODO ideally we update the shared data in the contact card sent to the responder as well since that
436
+ // CC was created by the responder.
437
+ return new LrMutation({
438
+ mutation: CompleteKeyExchangeOtkMutation,
439
+ variables: {
440
+ input: {
441
+ keyExchangeId,
442
+ rootKeyId: rootKey.id,
443
+ masterKeyId: masterKey.id,
444
+ initiatorSigPxkId: initiatorSigPrk.id,
445
+ signedResponderPbk: JSON.stringify(signedResponderPbk),
446
+ signedResponderSigPbk: JSON.stringify(signedResponderSigPbk),
447
+ rkWrappedSharedKey: JSON.stringify(rkWrappedSharedKey),
448
+ mkWrappedMkSharedKey: JSON.stringify(mkWrappedMkSharedKey),
449
+ responderContactCardCipher: responderContactCardCipherInput,
450
+ initiatorContactCardCipher: initiatorContactCardCipherInput,
451
+ initiatorContactCardSharedCipher: initiatorContactCardSharedCipherInput,
452
+ },
453
+ },
454
+ });
455
+ });
456
+ }
457
+ };
458
+ KeyExchange2Service.ɵprov = i0.ɵɵdefineInjectable({ factory: function KeyExchange2Service_Factory() { return new KeyExchange2Service(i0.ɵɵinject(i0.NgZone), i0.ɵɵinject(i1.KeyFactoryService), i0.ɵɵinject(i2.KeyService), i0.ɵɵinject(i3.EncryptionService), i0.ɵɵinject(i4.UserService), i0.ɵɵinject(i5.KeyGraphService), i0.ɵɵinject(i6.LrGraphQLService)); }, token: KeyExchange2Service, providedIn: "root" });
459
+ KeyExchange2Service.decorators = [
460
+ { type: Injectable, args: [{
461
+ providedIn: 'root',
462
+ },] }
463
+ ];
464
+ KeyExchange2Service.ctorParameters = () => [
465
+ { type: NgZone },
466
+ { type: KeyFactoryService },
467
+ { type: KeyService },
468
+ { type: EncryptionService },
469
+ { type: UserService },
470
+ { type: KeyGraphService },
471
+ { type: LrGraphQLService }
472
+ ];
473
+ KeyExchange2Service = __decorate([
474
+ RunOutsideAngular({
475
+ ngZoneName: 'ngZone',
476
+ })
477
+ ], KeyExchange2Service);
478
+ export { KeyExchange2Service };
479
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoia2V5LWV4Y2hhbmdlMi5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IkM6L1Byb2plY3RzL25ld3JlcG8va2MtY2xpZW50L3Byb2plY3RzL2NvcmUvc3JjLyIsInNvdXJjZXMiOlsibGliL2FwaS9rZXktZXhjaGFuZ2UyLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBRW5ELE9BQU8sRUFDTCxpQkFBaUIsRUFDakIsaUJBQWlCLEdBQ2xCLE1BQU0sb0NBQW9DLENBQUM7QUFDNUMsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0scUNBQXFDLENBQUM7QUFDeEUsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLG1DQUFtQyxDQUFDO0FBQ3BFLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUN6RCxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUNoRSxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUNuRSxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFFdEQsT0FBTyxFQUNMLHlCQUF5QixFQUN6Qiw4QkFBOEIsRUFDOUIsMEJBQTBCLEVBQzFCLDBCQUEwQixFQUMxQiw4QkFBOEIsRUFFOUIsaUJBQWlCLEVBQ2pCLGtCQUFrQixFQUVsQixzQkFBc0IsRUFDdEIsNkJBQTZCLEdBQzlCLE1BQU0scUJBQXFCLENBQUM7QUFDN0IsT0FBTyxFQUFFLGdCQUFnQixFQUFFLFVBQVUsRUFBRSxNQUFNLGNBQWMsQ0FBQzs7Ozs7Ozs7SUE2SC9DLG1CQUFtQixTQUFuQixtQkFBbUI7SUFHOUIsWUFDVSxNQUFjLEVBQ2QsVUFBNkIsRUFDN0IsVUFBc0IsRUFDdEIsaUJBQW9DLEVBQ3BDLFdBQXdCLEVBQ3hCLFFBQXlCLEVBQ3pCLFNBQTJCO1FBTjNCLFdBQU0sR0FBTixNQUFN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aUJBQWlCLENBQUM7UUFDakIsVUFBVSxFQUFFLFFBQVE7S0FDckIsQ0FBQztHQUlXLG1CQUFtQixDQW10Qi9CO1NBbnRCWSxtQkFBbUIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlLCBOZ1pvbmUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgSldLIH0gZnJvbSAnbm9kZS1qb3NlJztcclxuaW1wb3J0IHtcclxuICBFbmNyeXB0aW9uU2VydmljZSxcclxuICBKb3NlU2VyaWFsaXphdGlvbixcclxufSBmcm9tICcuLi9jcnlwdG9ncmFwaHkvZW5jcnlwdGlvbi5zZXJ2aWNlJztcclxuaW1wb3J0IHsgS2V5RmFjdG9yeVNlcnZpY2UgfSBmcm9tICcuLi9jcnlwdG9ncmFwaHkva2V5LWZhY3Rvcnkuc2VydmljZSc7XHJcbmltcG9ydCB7IEtleUdyYXBoU2VydmljZSB9IGZyb20gJy4uL2NyeXB0b2dyYXBoeS9rZXktZ3JhcGguc2VydmljZSc7XHJcbmltcG9ydCB7IEtleVNlcnZpY2UgfSBmcm9tICcuLi9jcnlwdG9ncmFwaHkva2V5LnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBMckNvZGVNaXNtYXRjaEV4Y2VwdGlvbiB9IGZyb20gJy4uL19jb21tb24vZXhjZXB0aW9ucyc7XHJcbmltcG9ydCB7IFJ1bk91dHNpZGVBbmd1bGFyIH0gZnJvbSAnLi4vX2NvbW1vbi9ydW4tb3V0c2lkZS1hbmd1bGFyJztcclxuaW1wb3J0IHsgVXNlclNlcnZpY2UgfSBmcm9tICcuLy4uL3VzZXJzL3VzZXIuc2VydmljZSc7XHJcbmltcG9ydCB7IE93bmVyUGxhaW5EYXRhSnNvbiB9IGZyb20gJy4vY29udGFjdC1jYXJkMi5zZXJ2aWNlJztcclxuaW1wb3J0IHtcclxuICBDYW5jZWxLZXlFeGNoYW5nZU11dGF0aW9uLFxyXG4gIENvbXBsZXRlS2V5RXhjaGFuZ2VPdGtNdXRhdGlvbixcclxuICBDdXJyZW50VXNlclNoYXJlZEtleVF1ZXJ5MixcclxuICBEZWNsaW5lS2V5RXhjaGFuZ2VNdXRhdGlvbixcclxuICBJbml0aWF0ZUtleUV4Y2hhbmdlT3RrTXV0YXRpb24sXHJcbiAgS2V5RXhjaGFuZ2VGcmFnbWVudCxcclxuICBLZXlFeGNoYW5nZVF1ZXJ5MixcclxuICBLZXlFeGNoYW5nZXNRdWVyeTIsXHJcbiAgS2V5RXhjaGFuZ2VTdGF0ZTIsXHJcbiAgS2V5RXhjaGFuZ2VUb2tlblF1ZXJ5MixcclxuICBSZXNwb25kS2V5RXhjaGFuZ2VPdGtNdXRhdGlvbixcclxufSBmcm9tICcuL2tleS1leGNoYW5nZTIuZ3FsJztcclxuaW1wb3J0IHsgTHJHcmFwaFFMU2VydmljZSwgTHJNdXRhdGlvbiB9IGZyb20gJy4vbHItZ3JhcGhxbCc7XHJcbmltcG9ydCB7IENvbnRhY3RDYXJkU2hhcmVkQ2lwaGVyRGF0YSwgT3RLZXlDaXBoZXJDbGVhckpzb24yIH0gZnJvbSAnLi90eXBlcyc7XHJcblxyXG4vKipcclxuICogVGhlIGRlY3J5cHRlZCBjb250ZW50IG9mIHRoZSBvbmUtdGltZSBrZXkgY2lwaGVyO1xyXG4gKiBXaGVuIHVzZXIgc3VwcGxpZXMgdGhpcyBpbmZvcm1hdGlvbiB0aGUgbGliIGRvZXNuJ3QgbmVlZCB0byBkbyBhbm90aGVyIEFQSSBjYWxsXHJcbiAqIHRvIGZldGNoIHRoZSBrZXkgZXhjaGFuZ2Ugbm9kZS4gQW5kIHNpbmNlIHRoZSB0eXBpY2FsIHVzZSBjYXNlIGlzIHRvIGRpc3BsYXlcclxuICogc29tZSBpbmZvcm1hdGlvbiB0byB0aGUgdXNlciwgdGhlIGtleSBleGNoYW5nZSBub2RlIHdvdWxkIGFscmVhZHkgaGF2ZSBiZWVuXHJcbiAqIGZldGNoZWQgYW5kIGRlY3J5cHRlZC5cclxuICovXHJcbmV4cG9ydCBpbnRlcmZhY2UgRGVjcnlwdGVkT3RrMiB7XHJcbiAgb3RLZXlDaXBoZXJDbGVhckpzb246IE90S2V5Q2lwaGVyQ2xlYXJKc29uMjtcclxuICBvdEtleTogSldLLktleTsgLy8gVGhlIG9uZS10aW1lIGtleVxyXG59XHJcblxyXG5leHBvcnQgaW50ZXJmYWNlIENvbnRhY3RDYXJkUmVjZWl2ZXJDaXBoZXJEYXRhIHtcclxuICAvLyBUaGUgcmVjZWl2ZXIgb2YgdGhlIGNvbnRhY3QgY2FyZCBrZWVwcyBhIGNvcHlcclxuICAvLyBvZiB0aGUgb3duZXIncyBjb250YWN0IGNhcmQgaW5mb3JtYXRpb24sIGVuY3J5cHRlZCB1c2luZyB0aGUgcmVjZWl2ZXIncyBrZXlzLiBTbyB0aGF0IHdoZW5cclxuICAvLyB0aGUgb3duZXIgZGVjaWRlcyB0byB1cGRhdGUgdGhlaXIgc2hhcmVkIGNvbnRhY3QgY2FyZCBhdCBhIGxhdGVyIGRhdGUsIHRoZSByZWNlaXZlciBjYW5cclxuICAvLyBjb21wYXJlIGFnYWluc3QgdGhlIG9yaWdpbmFsIGNvbnRhY3QgY2FyZCBzZW50IGR1cmluZyBrZXkgZXhjaGFuZ2UuIFRoaXMgd2F5LCB0aGUgb3duZXJcclxuICAvLyBjYW4ndCB1bmlsYXRlcmFsbHkgdXBkYXRlIHRoZWlyIHNoYXJlZCBjb250YWN0IGNhcmQgd2l0aG91dCB0aGUgcmVjZWl2ZXIga25vd2luZyBhYm91dCBpdC5cclxuICByZWNlaXZlckNpcGhlckRhdGFDbGVhckpzb246IGFueTtcclxufVxyXG5cclxuZXhwb3J0IGludGVyZmFjZSBDb250YWN0Q2FyZE93bmVyUGxhaW5EYXRhIHtcclxuICAvLyBBY2Nlc3NpYmxlIGJ5IHRoZSBzZXJ2ZXIgYW5kIHRoZSBvd25lci4gU2VydmVyIHNpZGUgbm90aWZpY2F0aW9uIGVtYWlscyBuZWVkIHRvIGtub3cgc29tZVxyXG4gIC8vIGluZm9ybWF0aW9uIGFib3V0IHRoZSBvd25lci5cclxuICAvLyBUaGUgb3duZXIgY291bGQgZWl0aGVyIGJlIHRoZSBpbml0aWF0b3Igb3IgdGhlIHJlc3BvbmRlci5cclxuICBvd25lclBsYWluRGF0YUpzb246IE93bmVyUGxhaW5EYXRhSnNvbjtcclxufVxyXG5cclxuZXhwb3J0IGludGVyZmFjZSBDb250YWN0Q2FyZE93bmVyQ2lwaGVyRGF0YSB7XHJcbiAgLy8gT3duZXIgb25seSBhY2Nlc3MgdG8gdGhpcyBkYXRhXHJcbiAgb3duZXJDaXBoZXJEYXRhQ2xlYXJKc29uOiBhbnk7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBTZW5kaW5nIGNvbnRhY3QgY2FyZCBpbmZvcm1hdGlvbiBmcm9tIHRoZSBvd25lciB0byB0aGUgcmVjZWl2ZXIuXHJcbiAqL1xyXG5leHBvcnQgdHlwZSBTZW5kQ29udGFjdENhcmRJbnB1dCA9IENvbnRhY3RDYXJkT3duZXJQbGFpbkRhdGEgJlxyXG4gIENvbnRhY3RDYXJkT3duZXJDaXBoZXJEYXRhICZcclxuICBDb250YWN0Q2FyZFNoYXJlZENpcGhlckRhdGE7XHJcblxyXG5leHBvcnQgaW50ZXJmYWNlIEluaXRpYXRlT3RrSW5wdXQyIHtcclxuICAvLyBOb3RlIHRoYXQgaWYgbmVpdGhlciBlbWFpbCBub3IgcmVzcG9uZGVyVXNlcm5hbWUgYXJlIGdpdmVuLCB0aGUgb25lLXRpbWUga2V5XHJcbiAgLy8gY2FuIHN0aWxsIGJlIHNlbnQgdG8gdGhlIHJlc3BvbmRlciB2aWEgT09CXHJcbiAgZW1haWw/OiBzdHJpbmc7XHJcbiAgbWVzc2FnZT86IGFueTtcclxuICBjb250YWN0Q2FyZD86IFNlbmRDb250YWN0Q2FyZElucHV0O1xyXG4gIC8vIElmIFRydWUsIHRvIHVwZ3JhZGUgYW4gZW1haWwgaW52aXRlIHRvIGFuIGV4aXN0aW5nIHVzZXIgaW52aXRlIGlmIHRoZSBlbWFpbFxyXG4gIC8vIGlzIGFscmVhZHkgYXNzb2NpYXRlZCB3aXRoIGFuIGV4aXN0aW5nIHVzZXIuXHJcbiAgdXBncmFkZT86IGJvb2xlYW47XHJcbn1cclxuXHJcbmV4cG9ydCBpbnRlcmZhY2UgUmVzcG9uZE90a0lucHV0MiB7XHJcbiAga2V5RXhjaGFuZ2VJZDogc3RyaW5nO1xyXG4gIHRva2VuOiBzdHJpbmc7XHJcbiAgZGVjcnlwdGVkT3RrOiBEZWNyeXB0ZWRPdGsyO1xyXG4gIG1lc3NhZ2U/OiBhbnk7XHJcbiAgLy8gVGhlIGluaXRpYXRvciBpcyB0aGUgb3duZXIgZm8gdGhlIGluaXRpYXRvckNvbnRhY3RDYXJkLCB0aGUgcmVzcG9uZGVyXHJcbiAgLy8gaXMgdGhlIHJlY2VpdmVyLlxyXG4gIGluaXRpYXRvckNvbnRhY3RDYXJkPzogQ29udGFjdENhcmRSZWNlaXZlckNpcGhlckRhdGE7XHJcbiAgcmVzcG9uZGVyQ29udGFjdENhcmQ/OiBTZW5kQ29udGFjdENhcmRJbnB1dDtcclxufVxyXG5cclxuZXhwb3J0IGludGVyZmFjZSBDb21wbGV0ZU90a0lucHV0MiB7XHJcbiAga2V5RXhjaGFuZ2VJZDogc3RyaW5nO1xyXG4gIC8vIFRoaXMgaXMgYSBwYXJ0IG9mIHRoZSBrZXkgZXhjaGFuZ2UgZGF0YS4gSXQncyBlbmNyeXB0ZWQgdXNpbmcgdGhlIHJvb3Qga2V5XHJcbiAgaW5pdGlhdG9yUm9vdEtleUNpcGhlcjogc3RyaW5nO1xyXG4gIC8vIFRoaXMgaXMgYSBwYXJ0IG9mIHRoZSBrZXkgZXhjaGFuZ2UgZGF0YS4gSXQncyBlbmNyeXB0ZWQgdXNpbmcgdGhlIG9uZS10aW1lIGtleS5cclxuICBpbml0aWF0b3JPbmVUaW1lUGJrQ2lwaGVyOiBzdHJpbmc7XHJcbiAgLy8gVGhlIHJlc3BvbmRlciBpcyB0aGUgb3duZXIgZm8gdGhlIHJlc3BvbmRlckNvbnRhY3RDYXJkLCB0aGUgaW5pdGlhdG9yXHJcbiAgLy8gaXMgdGhlIHJlY2VpdmVyLlxyXG4gIHJlc3BvbmRlckNvbnRhY3RDYXJkPzogQ29udGFjdENhcmRSZWNlaXZlckNpcGhlckRhdGE7XHJcbiAgLy8gVGhlIGluaXRpYXRvciBjYW4gdXBkYXRlIHRoZSBjaXBoZXIgZGF0YSB0aGF0IGFyZSBvbmx5IHZpc2libGUgdG8gdGhlbS4gSXQgbWFrZXNcclxuICAvLyBsZXNzIHNlbnNlIHRvIHVwZGF0ZSB0aGUgc2hhcmVkIGRhdGEgYmVjYXVzZSB0aGUgcmVzcG9uZGVyIHdvdWxkIGhhdmUgYWxyZWFkeSBzZWVuXHJcbiAgLy8gdGhlIHNoYXJlZCBkYXRhIGFuZCBhY2NlcHRlZCB0aGF0IGl0J3MgbGVnaXQuXHJcbiAgLy8gQnV0IGluIGFueSBjYXNlLCB0aGUgaW5pdGlhdG9yIGNhbiB1cGRhdGUgdGhlIHNoYXJlZCBjb250YWN0IGNhcmQgaW5mbyBhdCBhbnkgdGltZS5cclxuICBpbml0aWF0b3JDb250YWN0Q2FyZD86IENvbnRhY3RDYXJkT3duZXJDaXBoZXJEYXRhO1xyXG59XHJcblxyXG5leHBvcnQgaW50ZXJmYWNlIEluaXRpYXRvclJvb3RLZXlDaXBoZXJDbGVhckpzb24yIHtcclxuICBub25jZTogc3RyaW5nO1xyXG4gIG9uZVRpbWVQcms6IG9iamVjdDsgLy8gb25lLXRpbWUgcHVibGljIGVuY3J5cHRpb24ga2V5IHJlc3BvbmRlciB1c2UgdG8gc2VuZCBkYXRhIGJhY2sgdG8gaW5pdGlhdG9yXHJcbiAgb3RLZXk6IG9iamVjdDsgLy8gb25lLXRpbWUgc3ltbWV0cmljIGtleSB0aGF0IG5lZWRzIHRvIGJlIHNoYXJlZCBPT0JcclxuICBpbml0aWF0b3JDb250YWN0Q2FyZD86IENvbnRhY3RDYXJkT3duZXJDaXBoZXJEYXRhICZcclxuICAgIENvbnRhY3RDYXJkU2hhcmVkQ2lwaGVyRGF0YTtcclxuICBpbml0aWF0b3I6IHtcclxuICAgIG1lc3NhZ2U/OiBhbnk7XHJcbiAgICBjb250YWN0Q2FyZD86IENvbnRhY3RDYXJkU2hhcmVkQ2lwaGVyRGF0YTtcclxuICB9O1xyXG59XHJcblxyXG5leHBvcnQgaW50ZXJmYWNlIEluaXRpYXRvck9uZVRpbWVQYmtDaXBoZXJDbGVhckpzb24ge1xyXG4gIG5vbmNlOiBzdHJpbmc7XHJcbiAgc2hhcmVkS2V5OiBvYmplY3Q7XHJcbiAgbWtTaGFyZWRLZXk6IG9iamVjdDtcclxuICByZXNwb25kZXI6IHtcclxuICAgIHBiazogb2JqZWN0O1xyXG4gICAgc2lnUGJrOiBvYmplY3Q7XHJcbiAgICBtZXNzYWdlPzogYW55O1xyXG4gICAgY29udGFjdENhcmQ/OiBDb250YWN0Q2FyZFNoYXJlZENpcGhlckRhdGEgJiB7XHJcbiAgICAgIC8vIE5vdGUgdGhhdCB0aGlzIGlzIF9ub3RfIHRoZSBzYW1lIGtleSBhcyB0aGUgc2hhcmVkS2V5LiBUaGUgc2hhcmVkS2V5IHdyYXBzXHJcbiAgICAgIC8vIHRoaXMga2V5IGluIHRoZSBrZXkgZ3JhcGguIEJ1dCBiZWNhdXNlIHRoaXMga2V5IGhhcyBub3QgYmVlbiBlbnRlcmVkIGludG9cclxuICAgICAgLy8gdGhlIGtleSBncmFwaCB3aGVuIHRoZSByZXNwb25kZXIgY2FsbHMgdGhlIEFQSSwgd2UgcGFzcyB0aGUgSldLIGRpcmVjdGx5IGhlcmUuXHJcbiAgICAgIHNoYXJlZENpcGhlcktleTogb2JqZWN0O1xyXG4gICAgfTtcclxuICB9O1xyXG59XHJcblxyXG5leHBvcnQgaW50ZXJmYWNlIEdldEtleUV4Y2hhbmdlT3B0aW9uczIge1xyXG4gIC8vIFRoZSBvdEtleSBhcyBhIHJhdyBzdHJpbmcuIGkuZS4ga2V5LnRvSlNPTih0cnVlKS5rXHJcbiAgb3RLZXlLPzogc3RyaW5nO1xyXG4gIC8vIFVzZXIgbmVlZCB0aGUgdG9rZW4gaWYgdGhleSBoYXZlIG5vdCByZXNwb25kZWQgdG8gdGhlIGtleSBleGNoYW5nZSB5ZXQuXHJcbiAgLy8gT25jZSB0aGV5J3ZlIHJlc3BvbmRlZCAoaGVuY2UgcHJvdmVuIHRoZXkgaGF2ZSB0aGUgT09CIEtleSkgdGhleSBiZWNvbWVcclxuICAvLyB0aGUgXCJyZXNwb25kZXJcIiBvZiB0aGlzIGV4Y2hhbmdlLCBhbmQgY2FuIGFjY2VzcyBpdCB3aGVuIHNpZ25lZCBpbi5cclxuICB0b2tlbj86IHN0cmluZztcclxufVxyXG5cclxuQFJ1bk91dHNpZGVBbmd1bGFyKHtcclxuICBuZ1pvbmVOYW1lOiAnbmdab25lJyxcclxufSlcclxuQEluamVjdGFibGUoe1xyXG4gIHByb3ZpZGVkSW46ICdyb290JyxcclxufSlcclxuZXhwb3J0IGNsYXNzIEtleUV4Y2hhbmdlMlNlcnZpY2Uge1xyXG4gIHByaXZhdGUgcmVhZG9ubHkgQ0xJRU5UX05PTkNFX0xFTkdUSCA9IDMyO1xyXG5cclxuICBjb25zdHJ1Y3RvcihcclxuICAgIHByaXZhdGUgbmdab25lOiBOZ1pvbmUsXHJcbiAgICBwcml2YXRlIGtleUZhY3Rvcnk6IEtleUZhY3RvcnlTZXJ2aWNlLFxyXG4gICAgcHJpdmF0ZSBrZXlTZXJ2aWNlOiBLZXlTZXJ2aWNlLFxyXG4gICAgcHJpdmF0ZSBlbmNyeXB0aW9uU2VydmljZTogRW5jcnlwdGlvblNlcnZpY2UsXHJcbiAgICBwcml2YXRlIHVzZXJTZXJ2aWNlOiBVc2VyU2VydmljZSxcclxuICAgIHByaXZhdGUga2V5R3JhcGg6IEtleUdyYXBoU2VydmljZSxcclxuICAgIHByaXZhdGUgbHJHcmFwaFFMOiBMckdyYXBoUUxTZXJ2aWNlXHJcbiAgKSB7fVxyXG5cclxuICBwcml2YXRlIGFzeW5jIGdldE90S2V5KFxyXG4gICAga2V5RXhjaGFuZ2U6IEtleUV4Y2hhbmdlRnJhZ21lbnQsXHJcbiAgICBvdEtleUs/OiBzdHJpbmdcclxuICApOiBQcm9taXNlPEpXSy5LZXk+IHtcclxuICAgIGlmIChvdEtleUspIHtcclxuICAgICAgcmV0dXJuIGF3YWl0IEtleUZhY3RvcnlTZXJ2aWNlLmFzS2V5KHtcclxuICAgICAgICAuLi5KU09OLnBhcnNlKGtleUV4Y2hhbmdlLm90ay5vdEtleVBhcmFtcyksXHJcbiAgICAgICAgazogb3RLZXlLLFxyXG4gICAgICB9KTtcclxuICAgIH0gZWxzZSBpZiAoXHJcbiAgICAgIGtleUV4Y2hhbmdlLm90ay5zdGF0ZSA9PT0gJ09US19JTklUSUFURUQnICYmXHJcbiAgICAgICFrZXlFeGNoYW5nZS5pc0luaXRpYXRvciAmJlxyXG4gICAgICBrZXlFeGNoYW5nZS5vdGsucmVzcG9uZGVyUGJrQ2lwaGVyXHJcbiAgICApIHtcclxuICAgICAgLy8gQXNzdW1pbmcgZXhpc3RpbmcgdXNlciBnZXR0aW5nIGludml0ZWQgd2hlcmUgT1RLIGlzIHdyYXBwZWQgaW4gcmVzcG9uZGVyJ3MgcHVibGljIGtleS5cclxuICAgICAgY29uc3QgcHJrID0gYXdhaXQgdGhpcy5rZXlTZXJ2aWNlLmdldEN1cnJlbnRQeGsoKTtcclxuICAgICAgY29uc3QgZGVjcnlwdGVkQ2lwaGVyOiBhbnkgPSBhd2FpdCB0aGlzLmVuY3J5cHRpb25TZXJ2aWNlLmRlY3J5cHQoXHJcbiAgICAgICAgcHJrLmp3ayxcclxuICAgICAgICBKU09OLnBhcnNlKGtleUV4Y2hhbmdlLm90ay5yZXNwb25kZXJQYmtDaXBoZXIpLFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIHNlcmlhbGl6YXRpb25zOiBbSm9zZVNlcmlhbGl6YXRpb24uQ09NUEFDVF0sXHJcbiAgICAgICAgfVxyXG4gICAgICApO1xyXG4gICAgICBpZiAoZGVjcnlwdGVkQ2lwaGVyLm90S2V5KSB7XHJcbiAgICAgICAgcmV0dXJuIGF3YWl0IEtleUZhY3RvcnlTZXJ2aWNlLmFzS2V5KGRlY3J5cHRlZENpcGhlci5vdEtleSk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybiBudWxsO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBhc3luYyBkZWNyeXB0T3RrKFxyXG4gICAga2V5RXhjaGFuZ2U6IEtleUV4Y2hhbmdlRnJhZ21lbnQsXHJcbiAgICBvdEtleUs/OiBzdHJpbmdcclxuICApOiBQcm9taXNlPEtleUV4Y2hhbmdlRnJhZ21lbnQ+IHtcclxuICAgIGNvbnN0IG90S2V5ID0gYXdhaXQgdGhpcy5nZXRPdEtleShrZXlFeGNoYW5nZSwgb3RLZXlLKTtcclxuXHJcbiAgICBsZXQgb3RrID0ga2V5RXhjaGFuZ2Uub3RrO1xyXG5cclxuICAgIGlmIChvdEtleSAmJiBvdGsub3RLZXlDaXBoZXIpIHtcclxuICAgICAgb3RrID0ge1xyXG4gICAgICAgIC4uLm90ayxcclxuICAgICAgICBvdEtleSxcclxuICAgICAgICBvdEtleUNpcGhlckNsZWFySnNvbjogYXdhaXQgdGhpcy5lbmNyeXB0aW9uU2VydmljZS5kZWNyeXB0KFxyXG4gICAgICAgICAgb3RLZXksXHJcbiAgICAgICAgICBrZXlFeGNoYW5nZS5vdGsub3RLZXlDaXBoZXJcclxuICAgICAgICApLFxyXG4gICAgICB9O1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiB7XHJcbiAgICAgIC4uLmtleUV4Y2hhbmdlLFxyXG4gICAgICBvdGssXHJcbiAgICB9O1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBhc3luYyBkZWNyeXB0UmVzcG9uc2VDaXBoZXIoXHJcbiAgICBvdEtleTogSldLLktleSxcclxuICAgIG90UHJrOiBKV0suS2V5LFxyXG4gICAgY29udGVudDogYW55XHJcbiAgKTogUHJvbWlzZTxJbml0aWF0b3JPbmVUaW1lUGJrQ2lwaGVyQ2xlYXJKc29uPiB7XHJcbiAgICAvLyBUaGUgcmVzcG9uc2UgY291bGQgYmUgd3JhcHBlZCBieSB0aGUgT3RLIGluIGFkZGl0aW9uIHRvIHRoZSBPdFBia1xyXG4gICAgdHJ5IHtcclxuICAgICAgY29udGVudCA9IGF3YWl0IHRoaXMuZW5jcnlwdGlvblNlcnZpY2UuZGVjcnlwdChvdEtleSwgY29udGVudCk7XHJcbiAgICB9IGNhdGNoIChlcnJvcikge1xyXG4gICAgICBpZiAoZXJyb3IubWVzc2FnZSAhPT0gJ25vIGtleSBmb3VuZCcpIHtcclxuICAgICAgICB0aHJvdyBlcnJvcjtcclxuICAgICAgfVxyXG4gICAgICAvLyBEbyBub3RoaW5nIHRvIHN1cHBvcnQgb2xkZXIgdmVyc2lvbnMgd2hlcmUgbWVzc2FnZSBpcyBub3Qgd3JhcHBlZCB3aXRoIG90ay5cclxuICAgIH1cclxuXHJcbiAgICAvLyBUaGUgUHJrIGlzIHNpbmdsZS11c2UgYW5kIG9ubHkgdXNlZCB0byBzZW5kIGluZm9ybWF0aW9uIGZyb20gdGhlIHJlc3BvbmRlciBiYWNrIHRvIHRoZSBpbml0aWF0b3IuXHJcbiAgICByZXR1cm4gYXdhaXQgdGhpcy5lbmNyeXB0aW9uU2VydmljZS5kZWNyeXB0KG90UHJrLCBjb250ZW50KTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgYXN5bmMgZGVjcnlwdEtleUV4Y2hhbmdlQXNJbml0aWF0b3IoXHJcbiAgICBrZXlFeGNoYW5nZTogS2V5RXhjaGFuZ2VGcmFnbWVudFxyXG4gICk6IFByb21pc2U8S2V5RXhjaGFuZ2VGcmFnbWVudD4ge1xyXG4gICAgY29uc3Qgcm9vdEtleSA9IGF3YWl0IHRoaXMua2V5U2VydmljZS5nZXRDdXJyZW50Um9vdEtleSgpO1xyXG5cclxuICAgIC8vIERlY3J5cHQgdXNpbmcgdGhlIHJvb3Qga2V5IHRvIGdldCB0aGUgUHJrXHJcbiAgICBjb25zdCBpbml0aWF0b3JSb290S2V5Q2lwaGVyQ2xlYXJKc29uID0gKGF3YWl0IHRoaXMuZW5jcnlwdGlvblNlcnZpY2UuZGVjcnlwdChcclxuICAgICAgcm9vdEtleS5qd2ssXHJcbiAgICAgIGtleUV4Y2hhbmdlLmluaXRpYXRvclJvb3RLZXlDaXBoZXJcclxuICAgICkpIGFzIEluaXRpYXRvclJvb3RLZXlDaXBoZXJDbGVhckpzb24yO1xyXG5cclxuICAgIGNvbnN0IG90S2V5ID0gYXdhaXQgS2V5RmFjdG9yeVNlcnZpY2UuYXNLZXkoXHJcbiAgICAgIGluaXRpYXRvclJvb3RLZXlDaXBoZXJDbGVhckpzb24ub3RLZXlcclxuICAgICk7XHJcblxyXG4gICAga2V5RXhjaGFuZ2UgPSB7XHJcbiAgICAgIC4uLmtleUV4Y2hhbmdlLFxyXG4gICAgICBpbml0aWF0b3JSb290S2V5Q2lwaGVyQ2xlYXJKc29uLFxyXG4gICAgfTtcclxuXHJcbiAgICBsZXQgb3RrID0ga2V5RXhjaGFuZ2Uub3RrO1xyXG5cclxuICAgIGlmIChvdGsuaW5pdGlhdG9yT25lVGltZVBia0NpcGhlcikge1xyXG4gICAgICBvdGsgPSB7XHJcbiAgICAgICAgLi4ub3RrLFxyXG4gICAgICAgIGluaXRpYXRvck9uZVRpbWVQYmtDaXBoZXJDbGVhckpzb246IGF3YWl0IHRoaXMuZGVjcnlwdFJlc3BvbnNlQ2lwaGVyKFxyXG4gICAgICAgICAgb3RLZXksXHJcbiAgICAgICAgICBhd2FpdCBLZXlGYWN0b3J5U2VydmljZS5hc0tleShcclxuICAgICAgICAgICAgaW5pdGlhdG9yUm9vdEtleUNpcGhlckNsZWFySnNvbi5vbmVUaW1lUHJrXHJcbiAgICAgICAgICApLFxyXG4gICAgICAgICAgb3RrLmluaXRpYXRvck9uZVRpbWVQYmtDaXBoZXJcclxuICAgICAgICApLFxyXG4gICAgICB9O1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChvdGsub3RLZXlDaXBoZXIpIHtcclxuICAgICAgb3RrLm90S2V5Q2lwaGVyQ2xlYXJKc29uID0gYXdhaXQgdGhpcy5lbmNyeXB0aW9uU2VydmljZS5kZWNyeXB0KFxyXG4gICAgICAgIG90S2V5LFxyXG4gICAgICAgIG90ay5vdEtleUNpcGhlclxyXG4gICAgICApO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiB7XHJcbiAgICAgIC4uLmtleUV4Y2hhbmdlLFxyXG4gICAgICBvdGssXHJcbiAgICB9O1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBhc3luYyBkZWNyeXB0S2V5RXhjaGFuZ2VBc1Jlc3BvbmRlcihcclxuICAgIGtleUV4Y2hhbmdlOiBLZXlFeGNoYW5nZUZyYWdtZW50LFxyXG4gICAgb3RLZXlLPzogc3RyaW5nXHJcbiAgKSB7XHJcbiAgICByZXR1cm4gdGhpcy5kZWNyeXB0T3RrKGtleUV4Y2hhbmdlLCBvdEtleUspO1xyXG4gIH1cclxuXHJcbiAgYXN5bmMgZGVjcnlwdEtleUV4Y2hhbmdlKGtleUV4Y2hhbmdlOiBLZXlFeGNoYW5nZUZyYWdtZW50LCBvdEtleUs/OiBzdHJpbmcpIHtcclxuICAgIGlmIChrZXlFeGNoYW5nZS5pc0luaXRpYXRvcikge1xyXG4gICAgICByZXR1cm4gdGhpcy5kZWNyeXB0S2V5RXhjaGFuZ2VBc0luaXRpYXRvcihrZXlFeGNoYW5nZSk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICByZXR1cm4gdGhpcy5kZWNyeXB0S2V5RXhjaGFuZ2VBc1Jlc3BvbmRlcihrZXlFeGNoYW5nZSwgb3RLZXlLKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIGFzeW5jIGdldEtleUV4Y2hhbmdlcyh7IHN0YXRlIH06IHsgc3RhdGU/OiBLZXlFeGNoYW5nZVN0YXRlMiB9ID0ge30pIHtcclxuICAgIGNvbnN0IHsga2V5RXhjaGFuZ2VzIH0gPSBhd2FpdCB0aGlzLmxyR3JhcGhRTC5xdWVyeSh7XHJcbiAgICAgIHF1ZXJ5OiBLZXlFeGNoYW5nZXNRdWVyeTIsXHJcbiAgICAgIHZhcmlhYmxlczoge1xyXG4gICAgICAgIHN0YXRlLFxyXG4gICAgICB9LFxyXG4gICAgfSk7XHJcblxyXG4gICAgcmV0dXJuIFByb21pc2UuYWxsKFxyXG4gICAgICBrZXlFeGNoYW5nZXMuZWRnZXMubWFwKChlZGdlKSA9PiB0aGlzLmRlY3J5cHRLZXlFeGNoYW5nZShlZGdlLm5vZGUpKVxyXG4gICAgKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEBwYXJhbSBpZCBJZiB0aGUgY3VycmVudCB1c2VyIGNhbiByZXNwb25kZXIgdGhlIGtleSBleGNoYW5nZSBpZiB0aGV5IGFyZSBlaXRoZXIgdGhlIGluaXRpYXRvciBvciB0aGUgcmVjZWl2ZXIuXHJcbiAgICogQHBhcmFtIHRva2VuIElmIG5vdCBzaWduZWQgaW4sIG9yIG5vdCB0aGUgaW5pdGlhdG9yIG9yIHJlc3BvbmRlciwgJ3Rva2VuJyBtdXN0IGJlIGdpdmVuLlxyXG4gICAqIEBwYXJhbSBvdEtleUsgSXMgdGhlIHJhdyBvbmUtdGltZSBrZXkgKHN0cmluZykuIElmIHRoZSByZXNwb25kZXIgaXMgZXhwbGljaXRseSBzcGVjaWZpZWQgYXQgdGltZSBvZiBpbml0aWF0aW9uLCB0aGVuXHJcbiAgICogICBpdCdzIHBvc3NpYmxlIHRvIGhhdmUgdGhlIG90S2V5IHdyYXBwZWQgYnkgdGhlIHB1YmxpYyBrZXkgb2YgdGhlIHJlc3BvbmRlci4gSW4gd2hpY2ggY2FzZSwgdGhlIG90S2V5SyBpcyBub3QgbmVlZGVkLlxyXG4gICAqL1xyXG4gIGFzeW5jIGdldEtleUV4Y2hhbmdlKFxyXG4gICAgaWQ6IHN0cmluZyxcclxuICAgIHsgb3RLZXlLLCB0b2tlbiB9OiBHZXRLZXlFeGNoYW5nZU9wdGlvbnMyID0ge31cclxuICApIHtcclxuICAgIGNvbnN0IHJlcyA9IGF3YWl0IHRoaXMubHJHcmFwaFFMLnF1ZXJ5KHtcclxuICAgICAgcXVlcnk6IHRva2VuID8gS2V5RXhjaGFuZ2VUb2tlblF1ZXJ5MiA6IEtleUV4Y2hhbmdlUXVlcnkyLFxyXG4gICAgICB2YXJpYWJsZXM6IHtcclxuICAgICAgICBpZCxcclxuICAgICAgICB0b2tlbixcclxuICAgICAgfSxcclxuICAgICAgaW5jbHVkZUtleUdyYXBoOiAhdG9rZW4sIC8vIGlmICF0b2tlbiB0aGVuIHdlIGFyZSBwb3N0IGF1dGgsIHNvIGNhbiBmZXRjaCBrZXlHcmFwaFxyXG4gICAgfSk7XHJcbiAgICByZXR1cm4gdGhpcy5kZWNyeXB0S2V5RXhjaGFuZ2UocmVzLmtleUV4Y2hhbmdlLCBvdEtleUspO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIGFzeW5jIGdldEN1cnJlbnRVc2VyU2hhcmVkS2V5KGlucHV0OiB7XHJcbiAgICB1c2VybmFtZT86IHN0cmluZztcclxuICAgIHVzZXJJZD86IHN0cmluZztcclxuICB9KSB7XHJcbiAgICByZXR1cm4gdGhpcy5sckdyYXBoUUwucXVlcnkoe1xyXG4gICAgICBxdWVyeTogQ3VycmVudFVzZXJTaGFyZWRLZXlRdWVyeTIsXHJcbiAgICAgIHZhcmlhYmxlczoge1xyXG4gICAgICAgIHVzZXJuYW1lOiBpbnB1dC51c2VybmFtZSxcclxuICAgICAgICB1c2VySWQ6IGlucHV0LnVzZXJJZCxcclxuICAgICAgfSxcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgLy8gVE9ETzogZGVwcmVjYXRlIHRoaXNcclxuICBhc3luYyBjYW5jZWxLZXlFeGNoYW5nZShpZDogc3RyaW5nKSB7XHJcbiAgICByZXR1cm4gdGhpcy5jYW5jZWxLZXlFeGNoYW5nZU11dGF0aW9uKGlkKTtcclxuICB9XHJcblxyXG4gIGNhbmNlbEtleUV4Y2hhbmdlTXV0YXRpb24oaWQ6IHN0cmluZykge1xyXG4gICAgcmV0dXJuIG5ldyBMck11dGF0aW9uKHtcclxuICAgICAgbXV0YXRpb246IENhbmNlbEtleUV4Y2hhbmdlTXV0YXRpb24sXHJcbiAgICAgIHZhcmlhYmxlczoge1xyXG4gICAgICAgIGlucHV0OiB7XHJcbiAgICAgICAgICBpZCxcclxuICAgICAgICB9LFxyXG4gICAgICB9LFxyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICAvLyBUT0RPOiBkZXByZWNhdGUgdGhpc1xyXG4gIGFzeW5jIGRlY2xpbmVLZXlFeGNoYW5nZShpZDogc3RyaW5nLCB0b2tlbjogc3RyaW5nKSB7XHJcbiAgICByZXR1cm4gdGhpcy5kZWNsaW5lS2V5RXhjaGFuZ2VNdXRhdGlvbihpZCwgdG9rZW4pO1xyXG4gIH1cclxuXHJcbiAgZGVjbGluZUtleUV4Y2hhbmdlTXV0YXRpb24oaWQ6IHN0cmluZywgdG9rZW46IHN0cmluZykge1xyXG4gICAgcmV0dXJuIG5ldyBMck11dGF0aW9uKHtcclxuICAgICAgbXV0YXRpb246IERlY2xpbmVLZXlFeGNoYW5nZU11dGF0aW9uLFxyXG4gICAgICB2YXJpYWJsZXM6IHtcclxuICAgICAgICBpbnB1dDoge1xyXG4gICAgICAgICAgaWQsXHJcbiAgICAgICAgICB0b2tlbixcclxuICAgICAgICB9LFxyXG4gICAgICB9LFxyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICBhc3luYyBpbml0aWF0ZU90ayh7XHJcbiAgICBtZXNzYWdlLFxyXG4gICAgZW1haWwsXHJcbiAgICBjb250YWN0Q2FyZCxcclxuICAgIHVwZ3JhZGUsXHJcbiAgfTogSW5pdGlhdGVPdGtJbnB1dDIgPSB7fSkge1xyXG4gICAgY29uc3Qgb3RLZXkgPSBhd2FpdCB0aGlzLmtleUZhY3RvcnkuY3JlYXRlS2V5KCk7XHJcbiAgICBjb25zdCBub25jZSA9IHRoaXMua2V5RmFjdG9yeS5yYW5kb21TdHJpbmcodGhpcy5DTElFTlRfTk9OQ0VfTEVOR1RIKTtcclxuXHJcbiAgICAvLyBOZXcgUEtDIGtleSBmb3IgZW5jcnlwdGlvbi4gVGhpcyBrZXkgaXMgdXNlZCBvbmx5IG9uY2Ugd2hlbiB0aGUgcmVzcG9uZGVyIHNlbmRzXHJcbiAgICAvLyBiYWNrIHRoZWlyIHNpZ25pbmcgcHVibGljIGtleS5cclxuICAgIGNvbnN0IGluaXRpYXRvck9uZVRpbWVQcmsgPSBhd2FpdCB0aGlzLmtleUZhY3RvcnkuY3JlYXRlUGtjS2V5KCk7XHJcblxyXG4gICAgLy8gT3B0aW9uIDE6IE5ldyBQS0Mga2V5IGZvciBzaWduaW5nXHJcbiAgICAvLyBjb25zdCBpbml0aWF0b3JTaWdQcmsgPSBhd2FpdCB0aGlzLmtleVNlcnZpY2UuY3JlYXRlUGtjU2lnbktleSgpO1xyXG5cclxuICAgIC8vIE9wdGlvbiAyOiBVc2UgdGhlIHVzZXIncyBnbG9iYWwgc2lnbmluZyBrZXkuXHJcbiAgICAvLyBUaGlzIGtleSBpcyB1c2VkIHRvIHByb3ZlIHRoZSBpbml0aWF0b3IncyBpZGVudGl0eS5cclxuICAgIGNvbnN0IGluaXRpYXRvclByayA9IGF3YWl0IHRoaXMua2V5U2VydmljZS5nZXRDdXJyZW50UHhrKCk7XHJcbiAgICBjb25zdCBpbml0aWF0b3JTaWdQcmsgPSBhd2FpdCB0aGlzLmtleVNlcnZpY2UuZ2V0Q3VycmVudFNpZ1B4aygpO1xyXG5cclxuICAgIGxldCBpbml0aWF0b3JQbGFpbkRhdGFTaWc6IHN0cmluZyA9IG51bGw7XHJcblxyXG4gICAgaWYgKGNvbnRhY3RDYXJkICYmIGNvbnRhY3RDYXJkLm93bmVyUGxhaW5EYXRhSnNvbikge1xyXG4gICAgICBpbml0aWF0b3JQbGFpbkRhdGFTaWcgPSBhd2FpdCB0aGlzLmVuY3J5cHRpb25TZXJ2aWNlLnNpZ25Ub1N0cmluZyhcclxuICAgICAgICBpbml0aWF0b3JTaWdQcmsuandrLFxyXG4gICAgICAgIGNvbnRhY3RDYXJkLm93bmVyUGxhaW5EYXRhSnNvblxyXG4gICAgICApO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IGluaXRpYXRvciA9IHtcclxuICAgICAgbWVzc2FnZSxcclxuICAgICAgY29udGFjdENhcmQ6IGNvbnRhY3RDYXJkICYmIHtcclxuICAgICAgICBzaGFyZWRDaXBoZXJEYXRhQ2xlYXJKc29uOiBjb250YWN0Q2FyZC5zaGFyZWRDaXBoZXJEYXRhQ2xlYXJKc29uLFxyXG4gICAgICB9LFxyXG4gICAgfTtcclxuXHJcbiAgICAvLyBDb250ZW50IHRvIGJlIGVuY3J5cHRlZCB1c2luZyB0aGUgT1RLLlxyXG4gICAgY29uc3QgcGxhaW5PdEtleUNpcGhlcjogT3RLZXlDaXBoZXJDbGVhckpzb24yID0ge1xyXG4gICAgICAvLyBUT0RPIE1ha2Ugc3VyZSB3ZSBhbHNvIHB1dCB0aGUgT09CIGNvZGUgaW4gaGVyZSBhcyB3ZWxsIHNpbmNlIHRoZSBPT0IgY29kZSBpcyB0aGVcclxuICAgICAgLy8gX29ubHlfIGluZm9ybWF0aW9uIHRoZSBLQyBzZXJ2ZXIgZG9lcyBub3QgaGF2ZSBhY2Nlc3MgdG8uIFRoZSBzZXJ2ZXIgbWF5IGhhdmVcclxuICAgICAgLy8gYWNjZXNzIHRvIE9USyBhbmQgaGVuY2UgdGhlIG5vbmNlIGhlcmUuIEl0J3MgZ29vZCB0byBoYXZlIGJvdGggdGhlIG5vbmNlIGFuZCBPT0IgY29kZVxyXG4gICAgICAvLyBzaW5jZSB0aGUgdXNlciBtYXkgbm90IGJlIHVzaW5nIHRoZSBPT0IgY29kZS4gQW5kIGl0J3Mgc2ltcGxlIHRvIGFsd2F5cyBpbmNsdWRlXHJcbiAgICAgIC8vIHRoZSBub25jZSwgc28gd2h5IG5vdC5cclxuICAgICAgbm9uY2UsXHJcbiAgICAgIGluaXRpYXRvcjoge1xyXG4gICAgICAgIC4uLmluaXRpYXRvcixcclxuICAgICAgICBvbmVUaW1lUGJrOiBpbml0aWF0b3JPbmVUaW1lUHJrLnRvSlNPTigpLCAvLyBvbmUtdGltZSBwdWJsaWMgZW5jcnlwdGlvbiBrZXkgcmVzcG9uZGVyIHVzZSB0byBzZW5kIGRhdGEgYmFjayB0byBpbml0aWF0b3JcclxuICAgICAgICBwYms6IGluaXRpYXRvclByay5qd2sudG9KU09OKCksIC8vIHB1YmxpYyBlbmNyeXB0aW9uIGtleVxyXG4gICAgICAgIHNpZ1BiazogaW5pdGlhdG9yU2lnUHJrLmp3ay50b0pTT04oKSwgLy8gcHVibGljIHNpZ25pbmcga2V5XHJcbiAgICAgIH0sXHJcbiAgICB9O1xyXG5cclxuICAgIGNvbnN0IG90S2V5Q2lwaGVyID0gYXdhaXQgdGhpcy5rZXlHcmFwaC5lbmNyeXB0VG9TdHJpbmcoXHJcbiAgICAgIG90S2V5LFxyXG4gICAgICBwbGFpbk90S2V5Q2lwaGVyXHJcbiAgICApO1xyXG5cclxuICAgIC8vIENvbnRlbnQgdG8gYmUgZW5jcnlwdGVkIHVzaW5nIHRoZSBpbml0aWF0b3IncyByb290IGtleS5cclxuICAgIGNvbnN0IGluaXRpYXRvclJvb3RLZXlDaXBoZXJDbGVhckpzb246IEluaXRpYXRvclJvb3RLZXlDaXBoZXJDbGVhckpzb24yID0ge1xyXG4gICAgICBub25jZSxcclxuICAgICAgb25lVGltZVByazogaW5pdGlhdG9yT25lVGltZVByay50b0pTT04odHJ1ZSksXHJcbiAgICAgIC8vIFNob3VsZCBub3QgbmVlZCB0byBrZWVwIHRoaXMgZW5jcnlwdGVkIHNpbmNlIHdlIGFyZSB1c2luZyB0aGUgZ2xvYmFsIHNpZ25pbmcga2V5LlxyXG4gICAgICAvLyBzaWdQcms6IGluaXRpYXRvclNpZ1Byay50b0pTT04odHJ1ZSksXHJcblxyXG4gICAgICAvLyBTYXZlIGl0IGluIGNhc2UgdGhlIGluaXRpYXRvciB3YW50IHRvIGRlY29kZSB0aGUgb3RLZXlDaXBoZXIuXHJcbiAgICAgIC8vIFNpbmNlIHRoZSBvdEtleSBpcyBvbmx5IHVzZWQgb25jZSwgYW5kIHRoYXQgb3RLZXlDaXBoZXIgY29udGFpbnMgb25seVxyXG4gICAgICAvLyB0aGUgcHVibGljIGtleSBvZiB0aGUgaW5pdGlhdG9yLCBpdCdzIHNhZmUganVzdCBsZWF2ZSB0aGUgb3RLZXkgc3RvcmVkIGhlcmUuXHJcbiAgICAgIG90S2V5OiBvdEtleS50b0pTT04odHJ1ZSksXHJcbiAgICAgIC8vIFRoZXNlIHNob3VsZCBiZSBzdG9yaW5nIGluZm9ybWF0aW9uIHN1Y2ggYXMgaG93IHRoZSBmaWVsZHMgb2YgdGhlIHNoYXJlZCBjb250YWN0IGNhcmQgaXNcclxuICAgICAgLy8gZGVyaXZlZCBmcm9tIHRoZSBtYXN0ZXIgY29udGFjdCBjYXJkLlxyXG4gICAgICBpbml0aWF0b3JDb250YWN0Q2FyZDogY29udGFjdENhcmQsXHJcbiAgICAgIGluaXRpYXRvcixcclxuICAgIH07XHJcblxyXG4gICAgY29uc3Qgcm9vdEtleSA9IGF3YWl0IHRoaXMua2V5U2VydmljZS5nZXRDdXJyZW50Um9vdEtleSgpO1xyXG4gICAgY29uc3QgaW5pdGlhdG9yUm9vdEtleUNpcGhlciA9IGF3YWl0IHRoaXMua2V5R3JhcGguZW5jcnlwdFRvU3RyaW5nKFxyXG4gICAgICByb290S2V5Lmp3ayxcclxuICAgICAgaW5pdGlhdG9yUm9vdEtleUNpcGhlckNsZWFySnNvblxyXG4gICAgKTtcclxuXHJcbiAgICAvLyBUaGUgcmF3IE9US1xyXG4gICAgY29uc3Qgb3RLZXlLOiBzdHJpbmcgPSAob3RLZXkudG9KU09OKHRydWUpIGFzIGFueSkuaztcclxuXHJcbiAgICAvLyBBUEkgY2FsbFxyXG4gICAgY29uc3QgbHJNdXRhdGlvbiA9IG5ldyBMck11dGF0aW9uKHtcclxuICAgICAgbXV0YXRpb246IEluaXRpYXRlS2V5RXhjaGFuZ2VPdGtNdXRhdGlvbixcclxuICAgICAgdmFyaWFibGVzOiB7XHJcbiAgICAgICAgaW5wdXQ6IHtcclxuICAgICAgICAgIC8vIFRoZXNlIHdpbGwgYmUgc3RvcmVkIG9uIHRoZSBzZXJ2ZXJcclxuICAgICAgICAgIGluaXRpYXRvclJvb3RLZXlDaXBoZXIsXHJcbiAgICAgICAgICBpbml0aWF0b3JQeGtJZDogaW5pdGlhdG9yUHJrLmlkLFxyXG4gICAgICAgICAgaW5pdGlhdG9yU2lnUHhrSWQ6IGluaXRpYXRvclNpZ1Byay5pZCxcclxuICAgICAgICAgIC8vIFRoZXNlIHdpbGwgYmUgc2VudCB0byB0aGUgcmVzcG9uZGVyXHJcbiAgICAgICAgICBvdEtleVBhcmFtczogSlNPTi5zdHJpbmdpZnkob3RLZXkudG9KU09OKCkpLFxyXG4gICAgICAgICAgb3RLZXlDaXBoZXIsXHJcbiAgICAgICAgICBzZW5kRW1haWw6IGVtYWlsICYmIHtcclxuICAgICAgICAgICAgZW1haWwsXHJcbiAgICAgICAgICAgIHJhd090S2V5OiBvdEtleUssXHJcbiAgICAgICAgICB9LFxyXG4gICAgICAgICAgY3JlYXRlVHA6IHRydWUsXHJcbiAgICAgICAgICBpbml0aWF0b3JQbGFpbkRhdGFTaWcsXHJcbiAgICAgICAgICB1cGdyYWRlLFxyXG4gICAgICAgIH0sXHJcbiAgICAgIH0sXHJcbiAgICB9KTtcclxuXHJcbiAgICByZXR1cm4geyBsck11dGF0aW9uLCBvdEtleUsgfTtcclxuICB9XHJcblxyXG4gIGFzeW5jIHJlc3BvbmRPdGsoe1xyXG4gICAga2V5RXhjaGFuZ2VJZCxcclxuICAgIHRva2VuLFxyXG4gICAgZGVjcnlwdGVkT3RrLFxyXG4gICAgbWVzc2FnZSxcclxuICAgIGluaXRpYXRvckNvbnRhY3RDYXJkLFxyXG4gICAgcmVzcG9uZGVyQ29udGFjdENhcmQsXHJcbiAgfTogUmVzcG9uZE90a0lucHV0Mikge1xyXG4gICAgY29uc3Qgcm9vdEtleSA9IGF3YWl0IHRoaXMua2V5U2VydmljZS5nZXRDdXJyZW50Um9vdEtleSgpO1xyXG5cclxuICAgIGNvbnN0IG1hc3RlcktleUlkID0gdGhpcy5rZXlTZXJ2aWNlLmdldEN1cnJlbnRNYXN0ZXJLZXkoKS5pZDtcclxuICAgIGNvbnN0IG1hc3RlcktleSA9IGF3YWl0IHRoaXMua2V5U2VydmljZS5nZXRDdXJyZW50TWFzdGVyS2V5KCk7XHJcblxyXG4gICAgY29uc3Qgc2hhcmVkS2V5ID0gYXdhaXQgdGhpcy5rZXlGYWN0b3J5LmNyZWF0ZUtleSgpO1xyXG4gICAgY29uc3QgbWtTaGFyZWRLZXkgPSBhd2FpdCB0aGlzLmtleUZhY3RvcnkuY3JlYXRlS2V5KCk7XHJcblxyXG4gICAgY29uc3QgcmtXcmFwcGVkU2hhcmVkS2V5ID0gYXdhaXQgdGhpcy5lbmNyeXB0aW9uU2VydmljZS5lbmNyeXB0KFxyXG4gICAgICByb290S2V5Lmp3ayxcclxuICAgICAgc2hhcmVkS2V5LnRvSlNPTih0cnVlKVxyXG4gICAgKTtcclxuICAgIGNvbnN0IG1rV3JhcHBlZE1rU2hhcmVkS2V5ID0gYXdhaXQgdGhpcy5lbmNyeXB0aW9uU2VydmljZS5lbmNyeXB0KFxyXG4gICAgICBtYXN0ZXJLZXkuandrLFxyXG4gICAgICBta1NoYXJlZEtleS50b0pTT04odHJ1ZSlcclxuICAgICk7XHJcblxyXG4gICAgY29uc3QgaW5pdGlhdG9yT25lVGltZVBiayA9IGF3YWl0IEtleUZhY3RvcnlTZXJ2aWNlLmFzS2V5KFxyXG4gICAgICBkZWNyeXB0ZWRPdGsub3RLZXlDaXBoZXJDbGVhckpzb24uaW5pdGlhdG9yLm9uZVRpbWVQYmtcclxuICAgICk7XHJcblxyXG4gICAgY29uc3QgaW5pdGlhdG9yUGJrID0gYXdhaXQgS2V5RmFjdG9yeVNlcnZpY2UuYXNLZXkoXHJcbiAgICAgIGRlY3J5cHRlZE90ay5vdEtleUNpcGhlckNsZWFySnNvbi5pbml0aWF0b3IucGJrXHJcbiAgICApO1xyXG4gICAgY29uc3QgaW5pdGlhdG9yU2lnUGJrID0gYXdhaXQgS2V5RmFjdG9yeVNlcnZpY2UuYXNLZXkoXHJcbiAgICAgIGRlY3J5cHRlZE90ay5vdEtleUNpcGhlckNsZWFySnNvbi5pbml0aWF0b3Iuc2lnUGJrXHJcbiAgICApO1xyXG5cclxuICAgIC8vIE9wdGlvbiAxOiBVc2luZyBuZXcgUHJrIGZvciBlYWNoIFRQIHBhaXJcclxuICAgIC8vIENyZWF0ZSBhIG5ldyBwdWJsaWMgc2lnbmluZyBrZXkgZm9yIHRoZSByZXNwb25kZXIuXHJcbiAgICAvLyBjb25zdCByZXNwb25kZXJTaWdQcmsgPSBhd2FpdCB0aGlzLmtleVNlcnZpY2UuY3JlYXRlUGtjU2lnbktleSgpXHJcbiAgICAvLyBjb25zdCBya1dyYXBwZWRSZXNwb25kZXJTaWdQcmsgPSBhd2FpdCB0aGlzLmVuY3J5cHQocm9vdEtleSwgcmVzcG9uZGVyU2lnUHJrLnRvSlNPTih0cnVlKSk7XHJcblxyXG4gICAgLy8gT3B0aW9uIDI6IFJlc3BvbmRlciBhbHJlYWR5IGhhcyBhIHNpZ25pbmcgUHJrXHJcbiAgICBjb25zdCByZXNwb25kZXJQcmsgPSBhd2FpdCB0aGlzLmtleVNlcnZpY2UuZ2V0Q3VycmVudFB4aygpO1xyXG4gICAgY29uc3QgcmVzcG9uZGVyU2lnUHJrID0gYXdhaXQgdGhpcy5rZXlTZXJ2aWNlLmdldEN1cnJlbnRTaWdQeGsoKTtcclxuXHJcbiAgICBjb25zdCBzaWduZWRJbml0aWF0b3JQYmsgPSBhd2FpdCB0aGlzLmVuY3J5cHRpb25TZXJ2aWNlLnNpZ24oXHJcbiAgICAgIHJlc3BvbmRlclNpZ1Byay5qd2ssXHJcbiAgICAgIGluaXRpYXRvclBiay50b0pTT04oKVxyXG4gICAgKTtcclxuICAgIGNvbnN0IHNpZ25lZEluaXRpYXRvclNpZ1BiayA9IGF3YWl0IHRoaXMuZW5jcnlwdGlvblNlcnZpY2Uuc2lnbihcclxuICAgICAgcmVzcG9uZGVyU2lnUHJrLmp3ayxcclxuICAgICAgaW5pdGlhdG9yU2lnUGJrLnRvSlNPTigpXHJcbiAgICApO1xyXG5cclxuICAgIGNvbnN0IGluaXRpYXRvck9uZVRpbWVQYmtDaXBoZXJDbGVhckpzb246IEluaXRpYXRvck9uZVRpbWVQYmtDaXBoZXJDbGVhckpzb24gPSB7XHJcbiAgICAgIG5vbmNlOiBkZWNyeXB0ZWRPdGsub3RLZXlDaXBoZXJDbGVhckpzb24ubm9uY2UsXHJcbiAgICAgIHNoYXJlZEtleTogc2hhcmVkS2V5LnRvSlNPTih0cnVlKSxcclxuICAgICAgbWtTaGFyZWRLZXk6IG1rU2hhcmVkS2V5LnRvSlNPTih0cnVlKSxcclxuICAgICAgcmVzcG9uZGVyOiB7XHJcbiAgICAgICAgcGJrOiByZXNwb25kZXJQcmsuandrLnRvSlNPTigpLCAvLyBwdWJsaWMga2V5XHJcbiAgICAgICAgc2lnUGJrOiByZXNwb25kZXJTaWdQcmsuandrLnRvSlNPTigpLCAvLyBwdWJsaWMga2V5XHJcbiAgICAgICAgbWVzc2FnZSxcclxuICAgICAgfSxcclxuICAgIH07XHJcblxyXG4gICAgbGV0IHJlY2VpdmVkQ2FyZElucHV0O1xyXG4gICAgaWYgKGRlY3J5cHRlZE90ay5vdEtleUNpcGhlckNsZWFySnNvbi5pbml0aWF0b3IuY29udGFjdENhcmQpIHtcclxuICAgICAgLy8gU2V0IHRoZSBpbmZvIGFib3V0IHRoZSBpbml0aWF0b3IgdG8gYmUgdGhlIG9uZXMgc2VudCBieSB0aGUgaW5pdGlhdG9yLiBXZSBuZWVkIHRoIHJlc3BvbmRlciB0byBkbyB0aGUgZW5jcnlwdGlvbiBoZXJlXHJcbiAgICAgIC8vIGJlY2F1c2UgdGhlIGluaXRpYXRvciBkb2VzIG5vdCBoYXZlIHRoZSBzaGFyZWQga2V5IHlldCwgYW5kIHdlIHdhbnQgdGhlIHJlc3BvbmRlciB0byBoYXZlIGEgZnVuY3Rpb25hbCBjb250YWN0IGNhcmQgYWZ0ZXJcclxuICAgICAgLy8gdGhpcyBleGNoYW5nZS4gVGhlIGluaXRpYXRvciBjYW4gZG91YmxlIGNoZWNrIHRoZSBjb250YWN0IGRldGFpbHMgYXJlIGNvcnJlY3QgYW5kIHNpZ24gaXQgd2hlbiBpdCBjb21wbGV0ZXMgdGhlIGV4Y2hhbmdlLlxyXG4gICAgICBjb25zdCBzaGFyZWRDaXBoZXJEYXRhQ2xlYXJKc29uID1cclxuICAgICAgICBkZWNyeXB0ZWRPdGsub3RLZXlDaXBoZXJDbGVhckpzb24uaW5pdGlhdG9yLmNvbnRhY3RDYXJkXHJcbiAgICAgICAgICAuc2hhcmVkQ2lwaGVyRGF0YUNsZWFySnNvbjtcclxuXHJcbiAgICAgIC8vIENyZWF0ZSBrZXlzXHJcbiAgICAgIGNvbnN0IHJlY2VpdmVyS2V5ID0gYXdhaXQgdGhpcy5rZXlGYWN0b3J5LmNyZWF0ZUtleSgpO1xyXG4gICAgICBjb25zdCBjY1NoYXJlZEtleSA9IGF3YWl0IHRoaXMua2V5RmFjdG9yeS5jcmVhdGVLZXkoKTtcclxuICAgICAgY29uc3Qgc2lnUHhrID0gYXdhaXQgdGhpcy5rZXlTZXJ2aWNlLmdldEN1cnJlbnRTaWdQeGsoKTtcclxuXHJcbiAgICAgIHJlY2VpdmVkQ2FyZElucHV0ID0ge1xyXG4gICAgICAgIHJlY2VpdmVyV3JhcHBlZEtleTogSlNPTi5zdHJpbmdpZnkoXHJcbiAgICAgICAgICBhd2FpdCB0aGlzLmVuY3J5cHRpb25TZXJ2aWNlLmVuY3J5cHQoXHJcbiAgICAgICAgICAgIHJvb3RLZXkuandrLFxyXG4gICAgICAgICAgICByZWNlaXZlcktleS50b0pTT04odHJ1ZSlcclxuICAgICAgICAgIClcclxuICAgICAgICApLFxyXG4gICAgICAgIHJlY2VpdmVyV3JhcHBpbmdLZXlJZDogcm9vdEtleS5pZCxcclxuICAgICAgICByZWNlaXZlckNpcGhlckRhdGE6IGluaXRpYXRvckNvbnRhY3RDYXJkXHJcbiAgICAgICAgICA/IEpTT04uc3RyaW5naWZ5KFxyXG4gICAgICAgICAgICAgIGF3YWl0IHRoaXMuZW5jcnlwdGlvblNlcnZpY2UuZW5jcnlwdChcclxuICAgICAgICAgICAgICAgIHJlY2VpdmVyS2V5LFxyXG4gICAgICAgICAgICAgICAgaW5pdGlhdG9yQ29udGFjdENhcmQucmVjZWl2ZXJDaXBoZXJEYXRhQ2xlYXJKc29uXHJcbiAgICAgICAgICAgICAgKVxyXG4gICAgICAgICAgICApXHJcbiAgICAgICAgICA6ICcnLFxyXG4gICAgICAgIHNoYXJlZFdyYXBwZWRLZXk6IEpTT04uc3RyaW5naWZ5KFxyXG4gICAgICAgICAgYXdhaXQgdGhpcy5lbmNyeXB0aW9uU2VydmljZS5lbmNyeXB0KFxyXG4gICAgICAgICAgICBzaGFyZWRLZXksXHJcbiAgICAgICAgICAgIGNjU2hhcmVkS2V5LnRvSlNPTih0cnVlKVxyXG4gICAgICAgICAgKVxyXG4gICAgICAgICksXHJcbiAgICAgIH07XHJcblxyXG4gICAgICBjb25zdCBzaGFyZWRDaXBoZXJEYXRhID0gYXdhaXQgdGhpcy5lbmNyeXB0aW9uU2VydmljZS5lbmNyeXB0KFxyXG4gICAgICAgIGNjU2hhcmVkS2V5LFxyXG4gICAgICAgIHNoYXJlZENpcGhlckRhdGFDbGVhckpzb25cclxuICAgICAgKTtcclxuICAgICAgcmVjZWl2ZWRDYXJkSW5wdXQuc2hhcmVkQ2lwaGVyRGF0YVNpZyA9IEpTT04uc3RyaW5naWZ5KFxyXG4gICAgICAgIGF3YWl0IHRoaXMuZW5jcnlwdGlvblNlcnZpY2Uuc2lnbihzaWdQeGsuandrLCBzaGFyZWRDaXBoZXJEYXRhKVxyXG4gICAgICApO1xyXG4gICAgICByZWNlaXZlZENhcmRJbnB1dC5zaWdQeGtJZCA9IHNpZ1B4ay5pZDtcclxuXHJcbiAgICAgIGluaXRpYXRvck9uZVRpbWVQYmtDaXBoZXJDbGVhckpzb24ucmVzcG9uZGVyLmNvbnRhY3RDYXJkID0ge1xyXG4gICAgICAgIC4uLmluaXRpYXRvck9uZVRpbWVQYmtDaXBoZXJDbGVhckpzb24ucmVzcG9uZGVyLmNvbnRhY3RDYXJkLFxyXG4gICAgICAgIHNoYXJlZENpcGhlcktleTogY2NTaGFyZWRLZXkudG9KU09OKHRydWUpLFxyXG4gICAgICB9O1xyXG4gICAgfVxyXG5cclxuICAgIGxldCByZXNwb25kZXJDYXJkSW5wdXQ7XHJcbiAgICBpZiAocmVzcG9uZGVyQ29udGFjdENhcmQpIHtcclxuICAgICAgLy8gQ3JlYXRlIGtleXNcclxuICAgICAgY29uc3Qgb3duZXJLZXkgPSBhd2FpdCB0aGlzLmtleUZhY3RvcnkuY3JlYXRlS2V5KCk7XHJcbiAgICAgIGNvbnN0IGNjU2hhcmVkS2V5ID0gYXdhaXQgdGhpcy5rZXlGYWN0b3J5LmNyZWF0ZUtleSgpO1xyXG4gICAgICBjb25zdCBzaWdQeGsgPSBhd2FpdCB0aGlzLmtleVNlcnZpY2UuZ2V0Q3VycmVudFNpZ1B4aygpO1xyXG5cclxuICAgICAgcmVzcG9uZGVyQ2FyZElucHV0ID0ge1xyXG4gICAgICAgIG93bmVyV3JhcHBlZEtleTogSlNPTi5zdHJpbmdpZnkoXHJcbiAgICAgICAgICBhd2FpdCB0aGlzLmVuY3J5cHRpb25TZXJ2aWNlLmVuY3J5cHQoXHJcbiAgICAgICAgICAgIHJvb3RLZXkuandrLFxyXG4gICAgICAgICAgICBvd25lcktleS50b0pTT04odHJ1ZSlcclxuICAgICAgICAgIClcclxuICAgICAgICApLFxyXG4gICAgICAgIG93bmVyV3JhcHBpbmdLZXlJZDogcm9vdEtleS5pZCxcclxuICAgICAgICBvd25lckNpcGhlckRhdGE6IHJlc3BvbmRlckNvbnRhY3RDYXJkLm93bmVyQ2lwaGVyRGF0YUNsZWFySnNvblxyXG4gICAgICAgICAgPyBKU09OLnN0cmluZ2lmeShcclxuICAgICAgICAgICAgICBhd2FpdCB0aGlzLmVuY3J5cHRpb25TZXJ2aWNlLmVuY3J5cHQoXHJcbiAgICAgICAgICAgICAgICBvd25lcktleSxcclxuICAgICAgICAgICAgICAgIHJlc3BvbmRlckNvbnRhY3RDYXJkLm93bmVyQ2lwaGVyRGF0YUNsZWFySnNvblxyXG4gICAgICAgICAgICAgIClcclxuICAgICAgICAgICAgKVxyXG4gICAgICAgICAgOiAnJyxcclxuXHJcbiAgICAgICAgc2hhcmVkV3JhcHBlZEtleTogSlNPTi5zdHJpbmdpZnkoXHJcbiAgICAgICAgICBhd2FpdCB0aGlzLmVuY3J5cHRpb25TZXJ2aWNlLmVuY3J5cHQoXHJcbiAgICAgICAgICAgIHNoYXJlZEtleSxcclxuICAgICAgICAgICAgY2NTaGFyZWRLZXkudG9KU09OKHRydWUpXHJcbiAgICAgICAgICApXHJcbiAgICAgICAgKSxcclxuICAgICAgfTtcclxuXHJcbiAgICAgIGNvbnN0IHNoYXJlZENpcGhlckRhdGEgPSBhd2FpdCB0aGlzLmVuY3J5cHRpb25TZXJ2aWNlLmVuY3J5cHQoXHJcbiAgICAgICAgY2NTaGFyZWRLZXksXHJcbiAgICAgICAgcmVzcG9uZGVyQ29udGFjdENhcmQuc2hhcmVkQ2lwaGVyRGF0YUNsZWFySnNvblxyXG4gICAgICApO1xyXG4gICAgICByZXNwb25kZXJDYXJkSW5wdXQuc2hhcmVkQ2lwaGVyRGF0YVNpZyA9IEpTT04uc3RyaW5naWZ5KFxyXG4gICAgICAgIGF3YWl0IHRoaXMuZW5jcnlwdGlvblNlcnZpY2Uuc2lnbihzaWdQeGsuandrLCBzaGFyZWRDaXBoZXJEYXRhKVxyXG4gICAgICApO1xyXG4gICAgICByZXNwb25kZXJDYXJkSW5wdXQuc2lnUHhrSWQgPSBzaWdQeGsuaWQ7XHJcblxyXG4gICAgICBpZiAocmVzcG9uZGVyQ29udGFjdENhcmQub3duZXJQbGFpbkRhdGFKc29uKSB7XHJcbiAgICAgICAgcmVzcG9uZGVyQ2FyZElucHV0Lm93bmVyUGxhaW5EYXRhU2lnID0gSlNPTi5zdHJpbmdpZnkoXHJcbiAgICAgICAgICBhd2FpdCB0aGlzLmVuY3J5cHRpb25TZXJ2aWNlLnNpZ24oXHJcbiAgICAgICAgICAgIHJlc3BvbmRlclNpZ1Byay5qd2ssXHJcbiAgICAgICAgICAgIHJlc3BvbmRlckNvbnRhY3RDYXJkLm93bmVyUGxhaW5EYXRhSnNvblxyXG4gICAgICAgICAgKVxyXG4gICAgICAgICk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIC8vIENvbnRhY3QgY2FyZCBpbmZvIHJlYWRhYmxlIGJ5IHRoZSBpbml0aWF0b3JcclxuICAgICAgaW5pdGlhdG9yT25lVGltZVBia0NpcGhlckNsZWFySnNvbi5yZXNwb25kZXIuY29udGFjdENhcmQgPSB7XHJcbiAgICAgICAgLi4uaW5pdGlhdG9yT25lVGltZVBia0NpcGhlckNsZWFySnNvbi5yZXNwb25kZXIuY29udGFjdENhcmQsXHJcbiAgICAgICAgc2hhcmVkQ2lwaGVyRGF0YUNsZWFySnNvbjpcclxuICAgICAgICAgIHJlc3BvbmRlckNvbnRhY3RDYXJkLnNoYXJlZENpcGhlckRhdGFDbGVhckpzb24sXHJcbiAgICAgIH07XHJcbiAgICB9XHJcblxyXG4gICAgLy8gRW5jcnlwdCB3aXRoIG9uZS10aW1lIHB1YmxpYyBrZXlcclxuICAgIGxldCBpbml0aWF0b3JPbmVUaW1lUGJrQ2lwaGVyID0gYXdhaXQgdGhpcy5lbmNyeXB0aW9uU2VydmljZS5lbmNyeXB0KFxyXG4gICAgICBpbml0aWF0b3JPbmVUaW1lUGJrLFxyXG4gICAgICBpbml0aWF0b3JPbmVUaW1lUGJrQ2lwaGVyQ2xlYXJKc29uXHJcbiAgICApO1xyXG5cclxuICAgIC8vIEVuY3J5cHQgd2l0aCB0aGUgb3RrIGFnYWluIHRvIGtlZXAgdXNlIG9mIGFzeW1tZXRyaWMga2V5cyB0byBhIG1pbmltdW0uXHJcbiAgICBpbml0aWF0b3JPbmVUaW1lUGJrQ2lwaGVyID0gYXdhaXQgdGhpcy5lbmNyeXB0aW9uU2VydmljZS5lbmNyeXB0KFxyXG4gICAgICBkZWNyeXB0ZWRPdGsub3RLZXksXHJcbiAgICAgIGluaXRpYXRvck9uZVRpbWVQYmtDaXBoZXJcclxuICAgICk7XHJcblxyXG4gICAgcmV0dXJuIG5ldyBMck11dGF0aW9uKHtcclxuICAgICAgbXV0YXRpb246IFJlc3BvbmRLZXlFeGNoYW5nZU90a011dGF0aW9uLFxyXG4gICAgICB2YXJpYWJsZXM6IHtcclxuICAgICAgICBpbnB1dDoge1xyXG4gICAgICAgICAga2V5RXhjaGFuZ2VJZCxcclxuICAgICAgICAgIGtleUV4Y2hhbmdlVG9rZW46IHRva2VuLFxyXG4gICAgICAgICAgcm9vdEtleUlkOiByb290S2V5LmlkLFxyXG4gICAgICAgICAgbWFzdGVyS2V5SWQsXHJcbiAgICAgICAgICAvLyBUaGVzZSB3aWxsIGJlIHN0b3JlZCBvbiB0aGUgc2VydmVyXHJcbiAgICAgICAgICByZXNwb25kZXJQeGtJZDogcmVzcG9uZGVyUHJrLmlkLFxyXG4gICAgICAgICAgcmVzcG9uZGVyU2lnUHhrSWQ6IHJlc3BvbmRlclNpZ1Byay5pZCxcclxuICAgICAgICAgIHNpZ25lZEluaXRpYXRvclBiazogSlNPTi5zdHJpbmdpZnkoc2lnbmVkSW5pdGlhdG9yUGJrKSxcclxuICAgICAgICAgIHNpZ25lZEluaXRpYXRvclNpZ1BiazogSlNPTi5zdHJpbmdpZnkoc2lnbmVkSW5pdGlhdG9yU2lnUGJrKSxcclxuICAgICAgICAgIC8vIHJrV3JhcHBlZEluaXRpYXRvclNpZ1BiazogSlNPTi5zdHJpbmdpZnkocmtXcmFwcGVkSW5pdGlhdG9yU2lnUGJrKSxcclxuXHJcbiAgICAgICAgICAvLyBPcHRpb24gMTogVXNpbmcgbmV3IFByayBmb3IgZWFjaCBUUCBwYWlyXHJcbiAgICAgICAgICAvLyBya1dyYXBwZWRSZXNwb25kZXJTaWdQcms6IEpTT04uc3RyaW5naWZ5KHJrV3JhcHBlZFJlc3BvbmRlclNpZ1ByayksXHJcbiAgICAgICAgICBya1dyYXBwZWRTaGFyZWRLZXk6IEpTT04uc3RyaW5naWZ5KHJrV3JhcHBlZFNoYXJlZEtleSksXHJcbiAgICAgICAgICBta1dyYXBwZWRNa1NoYXJlZEtleTogSlNPTi5zdHJpbmdpZnkobWtXcmFwcGVkTWtTaGFyZWRLZXkpLFxyXG4gICAgICAgICAgLy8gVGhlc2Ugd2lsbCBiZSBzZW50IHRvIHRoZSBpbml0aWF0b3JcclxuICAgICAgICAgIGluaXRpYXRvck9uZVRpbWVQYmtDaXBoZXI6IEpTT04uc3RyaW5naWZ5KGluaXRpYXRvck9uZVRpbWVQYmtDaXBoZXIpLFxyXG4gICAgICAgICAgaW5pdGlhdG9yQ29udGFjdENhcmQ6IHJlY2VpdmVkQ2FyZElucHV0LFxyXG4gICAgICAgICAgcmVzcG9uZGVyQ29udGFjdENhcmQ6IHJlc3BvbmRlckNhcmRJbnB1dCxcclxuICAgICAgICB9LFxyXG4gICAgICB9LFxyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICBhc3luYyBjb21wbGV0ZU90ayh7XHJcbiAgICBrZXlFeGNoYW5nZUlkLFxyXG4gICAgaW5pdGlhdG9yUm9vdEtleUNpcGhlcixcclxuICAgIGluaXRpYXRvck9uZVRpbWVQYmtDaXBoZXIsXHJcbiAgICByZXNwb25kZXJDb250YWN0Q2FyZCxcclxuICAgIGluaXRpYXRvckNvbnRhY3RDYXJkLFxyXG4gIH06IENvbXBsZXRlT3RrSW5wdXQyKSB7XHJcbiAgICBjb25zdCByb290S2V5ID0gYXdhaXQgdGhpcy5rZXlTZXJ2aWNlLmdldEN1cnJlbnRSb290S2V5KCk7XHJcbiAgICBjb25zdCBtYXN0ZXJLZXkgPSBhd2FpdCB0aGlzLmtleVNlcnZpY2UuZ2V0Q3VycmVudE1hc3RlcktleSgpO1xyXG5cclxuICAgIC8vIERlY3J5cHQgdXNpbmcgdGhlIHJvb3Qga2V5IHRvIGdldCB0aGUgUHJrXHJcbiAgICBjb25zdCBpbml0aWF0b3JSb290S2V5Q2lwaGVyQ2xlYXJKc29uID0gKGF3YWl0IHRoaXMuZW5jcnlwdGlvblNlcnZpY2UuZGVjcnlwdChcclxuICAgICAgcm9vdEtleS5qd2ssXHJcbiAgICAgIGluaXRpYXRvclJvb3RLZXlDaXBoZXJcclxuICAgICkpIGFzIEluaXRpYXRvclJvb3RLZXlDaXBoZXJDbGVhckpzb24yO1xyXG5cclxuICAgIC8vIFRoZSBQcmsgaXMgc2luZ2xlLXVzZSBhbmQgb25seSB1c2VkIHRvIHNlbmQgaW5mb3JtYXRpb24gZnJvbSB0aGUgcmVzcG9uZGVyIGJhY2sgdG8gdGhlIGluaXRpYXRvci5cclxuICAgIGNvbnN0IHBsYWluSW5pdGlhdG9yT25lVGltZVBia0NpcGhlciA9IGF3YWl0IHRoaXMuZGVjcnlwdFJlc3BvbnNlQ2lwaGVyKFxyXG4gICAgICBhd2FpdCBLZXlGYWN0b3J5U2VydmljZS5hc0tleShpbml0aWF0b3JSb290S2V5Q2lwaGVyQ2xlYXJKc29uLm90S2V5KSxcclxuICAgICAgYXdhaXQgS2V5RmFjdG9yeVNlcnZpY2UuYXNLZXkoaW5pdGlhdG9yUm9vdEtleUNpcGhlckNsZWFySnNvbi5vbmVUaW1lUHJrKSxcclxuICAgICAgaW5pdGlhdG9yT25lVGltZVBia0NpcGhlclxyXG4gICAgKTtcclxuXHJcbiAgICAvLyBDaGVjayB0aGUgbm9uY2UgbWF0Y2ggdG8gZW5zdXJlIHRoZSByZXNwb25kZXIgd2FzIHRoZSBvbmUgaG9sZGluZyB0aGUgT1RLXHJcbiAgICBpZiAoXHJcbiAgICAgIGluaXRpYXRvclJvb3RLZXlDaXBoZXJDbGVhckpzb24ubm9uY2UgIT09XHJcbiAgICAgIHBsYWluSW5pdGlhdG9yT25lVGltZVBia0NpcGhlci5ub25jZVxyXG4gICAgKSB7XHJcbiAgICAgIHRocm93IG5ldyBMckNvZGVNaXNtYXRjaEV4Y2VwdGlvbihcclxuICAgICAgICAnVGhlIG5vbmNlIHJldHVybmVkIGJ5IHJlc3BvbmRlciBkb2VzIG5vdCBtYXRjaCB3aXRoIHRoZSBvbmUgY3JlYXRlZCBieSB0aGUgaW5pdGlhdG9yLidcclxuICAgICAgKTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBPcHRpb24gMTogQXNzdW1pbmcgdGhlIHNpZ25pbmcga2V5IGlzIHVuaXF1ZSBiZXR3ZWVuIHVzZXJzLlxyXG4gICAgLy8gY29uc3QgaW5pdGlhdG9yU2lnUHJrID0gYXdhaXQgS0ZTLmFzS2V5KGtlLnBsYWluSW5pdGlhdG9yUm9vdEtleUNpcGhlci5zaWdQcmspO1xyXG4gICAgLy8gY29uc3QgcmtXcmFwcGVkSW5pdGlhdG9yU2lnUHJrID0gYXdhaXQgdGhpcy5lbmNyeXB0KHJvb3RLZXksIGluaXRpYXRvclNpZ1Byay50b0pTT04odHJ1ZSkpO1xyXG5cclxuICAgIC8vIE9wdGlvbiAyOiBVc2UgdGhlIHVzZXIncyBnbG9iYWwgc2lnbmluZyBrZXkuXHJcbiAgICAvLyBJbiB0aGlzIGNhc2UgdGhlIGluaXRpYXRvclNpZ1ByayBpcyBhbHJlYWR5IGEgcGFydCBvZiB0aGUga2V5IGdyYXBoLlxyXG4gICAgLy8gU28gdGhlcmUncyBub3RoaW5nIHRvIGRvIGhlcmUuXHJcblxyXG4gICAgLy8gUHJvdGVjdGVkIHRoZSBzaWduaW5nIHB1YmxpYyBrZXkgb2YgdGhlIHJlc3BvbmRlci5cclxuICAgIGNvbnN0IGluaXRpYXRvclNpZ1ByayA9IGF3YWl0IHRoaXMua2V5U2VydmljZS5nZXRDdXJyZW50U2lnUHhrKCk7XHJcbiAgICBjb25zdCByZXNwb25kZXJTaWdQYmsgPSBhd2FpdCBLZXlGYWN0b3J5U2VydmljZS5hc0tleShcclxuICAgICAgcGxhaW5Jbml0aWF0b3JPbmVUaW1lUGJrQ2lwaGVyLnJlc3BvbmRlci5zaWdQYmtcclxuICAgICk7XHJcbiAgICBjb25zdCByZXNwb25kZXJQYmsgPSBhd2FpdCBLZXlGYWN0b3J5U2VydmljZS5hc0tleShcclxuICAgICAgcGxhaW5Jbml0aWF0b3JPbmVUaW1lUGJrQ2lwaGVyLnJlc3BvbmRlci5wYmtcclxuICAgICk7XHJcblxyXG4gICAgY29uc3Qgc2lnbmVkUmVzcG9uZGVyUGJrID0gYXdhaXQgdGhpcy5lbmNyeXB0aW9uU2VydmljZS5zaWduKFxyXG4gICAgICBpbml0aWF0b3JTaWdQcmsuandrLFxyXG4gICAgICByZXNwb25kZXJQYmsudG9KU09OKClcclxuICAgICk7XHJcbiAgICBjb25zdCBzaWduZWRSZXNwb25kZXJTaWdQYmsgPSBhd2FpdCB0aGlzLmVuY3J5cHRpb25TZXJ2aWNlLnNpZ24oXHJcbiAgICAgIGluaXRpYXRvclNpZ1Byay5qd2ssXHJcbiAgICAgIHJlc3BvbmRlclNpZ1Biay50b0pTT04oKVxyXG4gICAgKTtcclxuXHJcbiAgICBjb25zdCBzaGFyZWRLZXkgPSBhd2FpdCBLZXlGYWN0b3J5U2VydmljZS5hc0tleShcclxuICAgICAgcGxhaW5Jbml0aWF0b3JPbmVUaW1lUGJrQ2lwaGVyLnNoYXJlZEtleVxyXG4gICAgKTtcclxuICAgIGNvbnN0IHJrV3JhcHBlZFNoYXJlZEtleSA9IGF3YWl0IHRoaXMuZW5jcnlwdGlvblNlcnZpY2UuZW5jcnlwdChcclxuICAgICAgcm9vdEtleS5qd2ssXHJcbiAgICAgIHNoYXJlZEtleS50b0pTT04odHJ1ZSlcclxuICAgICk7XHJcblxyXG4gICAgY29uc3QgbWtTaGFyZWRLZXkgPSBhd2FpdCBLZXlGYWN0b3J5U2VydmljZS5hc0tleShcclxuICAgICAgcGxhaW5Jbml0aWF0b3JPbmVUaW1lUGJrQ2lwaGVyLm1rU2hhcmVkS2V5XHJcbiAgICApO1xyXG4gICAgY29uc3QgbWtXcmFwcGVkTWtTaGFyZWRLZXkgPSBhd2FpdCB0aGlzLmVuY3J5cHRpb25TZXJ2aWNlLmVuY3J5cHQoXHJcbiAgICAgIG1hc3RlcktleS5qd2ssXHJcbiAgICAgIG1rU2hhcmVkS2V5LnRvSlNPTih0cnVlKVxyXG4gICAgKTtcclxuXHJcbiAgICBsZXQgcmVzcG9uZGVyQ29udGFjdENhcmRDaXBoZXJJbnB1dDtcclxuICAgIGlmIChyZXNwb25kZXJDb250YWN0Q2FyZCkge1xyXG4gICAgICAvLyBDcmVhdGUga2V5XHJcbiAgICAgIGNvbnN0IHJlY2VpdmVyS2V5ID0gYXdhaXQgdGhpcy5rZXlGYWN0b3J5LmNyZWF0ZUtleSgpO1xyXG5cclxuICAgICAgcmVzcG9uZGVyQ29udGFjdENhcmRDaXBoZXJJbnB1dCA9IHtcclxuICAgICAgICByZWNlaXZlcldyYXBwZWRLZXk6IEpTT04uc3RyaW5naWZ5KFxyXG4gICAgICAgICAgYXdhaXQgdGhpcy5lbmNyeXB0aW9uU2VydmljZS5lbmNyeXB0KFxyXG4gICAgICAgICAgICByb290S2V5Lmp3ayxcclxuICAgICAgICAgICAgcmVjZWl2ZXJLZXkudG9KU09OKHRydWUpXHJcbiAgICAgICAgICApXHJcbiAgICAgICAgKSxcclxuICAgICAgICByZWNlaXZlcldyYXBwaW5nS2V5SWQ6IHJvb3RLZXkuaWQsXHJcbiAgICAgICAgcmVjZWl2ZXJDaXBoZXJEYXRhOiBKU09OLnN0cmluZ2lmeShcclxuICAgICAgICAgIGF3YWl0IHRoaXMuZW5jcnlwdGlvblNlcnZpY2UuZW5jcnlwdChcclxuICAgICAgICAgICAgcmVjZWl2ZXJLZXksXHJcbiAgICAgICAgICAgIHJlc3BvbmRlckNvbnRhY3RDYXJkLnJlY2VpdmVyQ2lwaGVyRGF0YUNsZWFySnNvblxyXG4gICAgICAgICAgKVxyXG4gICAgICAgICksXHJcbiAgICAgIH07XHJcbiAgICB9XHJcblxyXG4gICAgLy8gR2V0IHRoZSBkYXRhIG5lZWRlZCBmcm9tIHRoZSBpbml0aWF0b3IncyBjaXBoZXIgZGF0YS5cclxuICAgIGxldCBpbml0aWF0b3JDb250YWN0Q2FyZENpcGhlcklucHV0O1xyXG4gICAgbGV0IGluaXRpYXRvckNvbnRhY3RDYXJkU2hhcmVkQ2lwaGVySW5wdXQ7XHJcbiAgICBpZiAoaW5pdGlhdG9yUm9vdEtleUNpcGhlckNsZWFySnNvbi5pbml0aWF0b3JDb250YWN0Q2FyZCkge1xyXG4gICAgICAvLyBUaGUgaW5pdGlhdG9yQ29udGFjdENhcmQgY3JlYXRlZCBkdXJpbmcgdGhlIGNyZWF0aW9uIG9mIHRoZSBpbnZpdGUgYW5kIGVuY3J5cHRlZCB1c2luZyB0aGUgaW5pdGlhdG9yJ3NcclxuICAgICAgLy8gcm9vdCBrZXlcclxuICAgICAgY29uc3QgaW5pdGlhdG9yQ29udGFjdENhcmRGcm9tSW5pdCA9XHJcbiAgICAgICAgaW5pdGlhdG9yUm9vdEtleUNpcGhlckNsZWFySnNvbi5pbml0aWF0b3JDb250YWN0Q2FyZDtcclxuICAgICAgY29uc3Qgb3duZXJLZXkgPSBhd2FpdCB0aGlzLmtleUZhY3RvcnkuY3JlYXRlS2V5KCk7XHJcbiAgICAgIGNvbnN0IHNoYXJlZENpcGhlcktleSA9IGF3YWl0IEtleUZhY3RvcnlTZXJ2aWNlLmFzS2V5KFxyXG4gICAgICAgIHBsYWluSW5pdGlhdG9yT25lVGltZVBia0NpcGhlci5yZXNwb25kZXIuY29udGFjdENhcmQuc2hhcmVkQ2lwaGVyS2V5XHJcbiAgICAgICk7XHJcblxyXG4gICAgICBjb25zdCBvd25lcldyYXBwZWRLZXkgPSBKU09OLnN0cmluZ2lmeShcclxuICAgICAgICBhd2FpdCB0aGlzLmVuY3J5cHRpb25TZXJ2aWNlLmVuY3J5cHQocm9vdEtleS5qd2ssIG93bmVyS2V5LnRvSlNPTih0cnVlKSlcclxuICAgICAgKTtcclxuXHJcbiAgICAgIC8vIEFsbG93IHRoZSBpbml0aWF0b3JDb250YWN0Q2FyZCBwYXJhbWV0ZXIgdG8gb3ZlcnJpZGVcclxuICAgICAgY29uc3Qgb3duZXJDaXBoZXJEYXRhQ2xlYXJKc29uID1cclxuICAgICAgICBpbml0aWF0b3JDb250YWN0Q2FyZD8ub3duZXJDaXBoZXJEYXRhQ2xlYXJKc29uIHx8XHJcbiAgICAgICAgaW5pdGlhdG9yQ29udGFjdENhcmRGcm9tSW5pdC5vd25lckNpcGhlckRhdGFDbGVhckpzb247XHJcblxyXG4gICAgICBjb25zdCBvd25lckNpcGhlckRhdGEgPSBvd25lckNpcGhlckRhdGFDbGVhckpzb25cclxuICAgICAgICA/IGF3YWl0IHRoaXMua2V5R3JhcGguZW5jcnlwdFRvU3RyaW5nKFxyXG4gICAgICAgICAgICBvd25lcktleSxcclxuICAgICAgICAgICAgb3duZXJDaXBoZXJEYXRhQ2xlYXJKc29uXHJcbiAgICAgICAgICApXHJcbiAgICAgICAgOiAnJztcclxuXHJcbiAgICAgIGluaXRpYXRvckNvbnRhY3RDYXJkQ2lwaGVySW5wdXQgPSB7XHJcbiAgICAgICAgb3duZXJXcmFwcGVkS2V5LFxyXG4gICAgICAgIG93bmVyV3JhcHBpbmdLZXlJZDogcm9vdEtleS5pZCxcclxuICAgICAgICBvd25lckNpcGhlckRhdGEsXHJcbiAgICAgIH07XHJcblxyXG4gICAgICBpbml0aWF0b3JDb250YWN0Q2FyZFNoYXJlZENpcGhlcklucHV0ID0ge1xyXG4gICAgICAgIHNpZ1B4a0lkOiBpbml0aWF0b3JTaWdQcmsuaWQsXHJcbiAgICAgIH07XHJcblxyXG4gICAgICBjb25zdCBzaGFyZWRDaXBoZXJEYXRhID0gYXdhaXQgdGhpcy5lbmNyeXB0aW9uU2VydmljZS5lbmNyeXB0KFxyXG4gICAgICAgIHNoYXJlZENpcGhlcktleSxcclxuICAgICAgICBpbml0aWF0b3JDb250YWN0Q2FyZEZyb21Jbml0LnNoYXJlZENpcGhlckRhdGFDbGVhckpzb25cclxuICAgICAgKTtcclxuICAgICAgaW5pdGlhdG9yQ29udGFjdENhcmRTaGFyZWRDaXBoZXJJbnB1dC5zaGFyZWRDaXBoZXJEYXRhU2lnID0gSlNPTi5zdHJpbmdpZnkoXHJcbiAgICAgICAgYXdhaXQgdGhpcy5lbmNyeXB0aW9uU2VydmljZS5zaWduKGluaXRpYXRvclNpZ1Byay5qd2ssIHNoYXJlZENpcGhlckRhdGEpXHJcbiAgICAgICk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gVE9ETyBpZGVhbGx5IHdlIHVwZGF0ZSB0aGUgc2hhcmVkIGRhdGEgaW4gdGhlIGNvbnRhY3QgY2FyZCBzZW50IHRvIHRoZSByZXNwb25kZXIgYXMgd2VsbCBzaW5jZSB0aGF0XHJcbiAgICAvLyBDQyB3YXMgY3JlYXRlZCBieSB0aGUgcmVzcG9uZGVyLlxyXG5cclxuICAgIHJldHVybiBuZXcgTHJNdXRhdGlvbih7XHJcbiAgICAgIG11dGF0aW9uOiBDb21wbGV0ZUtleUV4Y2hhbmdlT3RrTXV0YXRpb24sXHJcbiAgICAgIHZhcmlhYmxlczoge1xyXG4gICAgICAgIGlucHV0OiB7XHJcbiAgICAgICAgICBrZXlFeGNoYW5nZUlkLFxyXG4gICAgICAgICAgcm9vdEtleUlkOiByb290S2V5LmlkLFxyXG4gICAgICAgICAgbWFzdGVyS2V5SWQ6IG1hc3RlcktleS5pZCxcclxuICAgICAgICAgIGluaXRpYXRvclNpZ1B4a0lkOiBpbml0aWF0b3JTaWdQcmsuaWQsXHJcbiAgICAgICAgICBzaWduZWRSZXNwb25kZXJQYms6IEpTT04uc3RyaW5naWZ5KHNpZ25lZFJlc3BvbmRlclBiayksXHJcbiAgICAgICAgICBzaWduZWRSZXNwb25kZXJTaWdQYms6IEpTT04uc3RyaW5naWZ5KHNpZ25lZFJlc3BvbmRlclNpZ1BiayksXHJcbiAgICAgICAgICBya1dyYXBwZWRTaGFyZWRLZXk6IEpTT04uc3RyaW5naWZ5KHJrV3JhcHBlZFNoYXJlZEtleSksXHJcbiAgICAgICAgICBta1dyYXBwZWRNa1NoYXJlZEtleTogSlNPTi5zdHJpbmdpZnkobWtXcmFwcGVkTWtTaGFyZWRLZXkpLFxyXG4gICAgICAgICAgcmVzcG9uZGVyQ29udGFjdENhcmRDaXBoZXI6IHJlc3BvbmRlckNvbnRhY3RDYXJkQ2lwaGVySW5wdXQsXHJcbiAgICAgICAgICBpbml0aWF0b3JDb250YWN0Q2FyZENpcGhlcjogaW5pdGlhdG9yQ29udGFjdENhcmRDaXBoZXJJbnB1dCxcclxuICAgICAgICAgIGluaXRpYXRvckNvbnRhY3RDYXJkU2hhcmVkQ2lwaGVyOiBpbml0aWF0b3JDb250YWN0Q2FyZFNoYXJlZENpcGhlcklucHV0LFxyXG4gICAgICAgIH0sXHJcbiAgICAgIH0sXHJcbiAgICB9KTtcclxuICB9XHJcbn1cclxuIl19