@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,442 +1,442 @@
1
- import { __awaiter } from "tslib";
2
- import { Injectable } from '@angular/core';
3
- import { LifeReadyAuthService } from '../auth/life-ready-auth.service';
4
- import { EncryptionService, JoseSerialization, } from '../cryptography/encryption.service';
5
- import { KeyService } from '../cryptography/key.service';
6
- import { LrCodeMismatchException } from '../_common/exceptions';
7
- import { UserService } from './../users/user.service';
8
- import { CompleteOtkMutation, CurrentUserSharedKeyQuery, InitiateOtkMutation, KeyExchangeQuery, KeyExchangesQuery, KeyExchangeTokenQuery, RespondOtkMutation, } from './key-exchange.gql';
9
- import { OtkState, } from './key-exchange.types';
10
- import { LrApolloService } from './lr-apollo.service';
11
- import { KeyFactoryService as KFS } from '../cryptography/key-factory.service';
12
- // Ref: https://stackoverflow.com/questions/59735280/angular-8-moment-error-cannot-call-a-namespace-moment
13
- import * as moment_ from 'moment';
14
- import * as i0 from "@angular/core";
15
- import * as i1 from "../cryptography/key-factory.service";
16
- import * as i2 from "../cryptography/key.service";
17
- import * as i3 from "./lr-apollo.service";
18
- import * as i4 from "../cryptography/encryption.service";
19
- import * as i5 from "../auth/life-ready-auth.service";
20
- import * as i6 from "../users/user.service";
21
- const moment = moment_;
22
- export class KeyExchangeService {
23
- constructor(keyFactory, keyService, lrApollo, encryptionService, authService, userService) {
24
- this.keyFactory = keyFactory;
25
- this.keyService = keyService;
26
- this.lrApollo = lrApollo;
27
- this.encryptionService = encryptionService;
28
- this.authService = authService;
29
- this.userService = userService;
30
- this.CLIENT_NONCE_LENGTH = 32;
31
- }
32
- getKeyExchangeList(input = {}) {
33
- return __awaiter(this, void 0, void 0, function* () {
34
- const { keyExchanges } = yield this.lrApollo.query({
35
- query: KeyExchangesQuery,
36
- variables: Object.assign({}, input),
37
- });
38
- return keyExchanges;
39
- });
40
- }
41
- /**
42
- * @param id If the current user can responder the key exchange if they are either the initiator or the receiver.
43
- * @param token If not signed in, or not the initiator or responder, 'token' must be given.
44
- * @param otKeyK Is the raw one-time key (string). If the responder is explicitly specified at time of initiation, then
45
- * it's possible to have the otKey wrapped by the public key of the responder. In which case, the otKeyK is not needed.
46
- */
47
- getKeyExchange(id, { otKeyK, token } = {}) {
48
- return __awaiter(this, void 0, void 0, function* () {
49
- const { keyExchange } = yield this.lrApollo.query({
50
- query: token ? KeyExchangeTokenQuery : KeyExchangeQuery,
51
- variables: {
52
- id,
53
- token,
54
- },
55
- });
56
- return yield this.decryptKeyExchange(keyExchange, otKeyK);
57
- });
58
- }
59
- decryptResponseCipher(otKey, otPrk, content) {
60
- return __awaiter(this, void 0, void 0, function* () {
61
- // The response could be wrapped by the OtK as well as we the OtPrk
62
- try {
63
- content = yield this.encryptionService.decrypt(otKey, content);
64
- }
65
- catch (error) {
66
- if (error.message !== 'no key found') {
67
- throw error;
68
- }
69
- // Do nothing to support older versions where message is not wrapped with otk.
70
- }
71
- // The Prk is single-use and only used to send information from the responder back to the initiator.
72
- return yield this.encryptionService.decrypt(otPrk, content);
73
- });
74
- }
75
- decryptKeyExchange(keyExchange, otKeyK) {
76
- return __awaiter(this, void 0, void 0, function* () {
77
- if (keyExchange.isInitiator) {
78
- const rootKey = yield this.keyService.getCurrentRootKey();
79
- // Decrypt using the root key to get the Prk
80
- const plainInitiatorRootKeyCipher = (yield this.encryptionService.decrypt(rootKey.jwk, keyExchange.initiatorRootKeyCipher));
81
- const plainInitiatorOneTimePbkCipher = keyExchange.otk
82
- .initiatorOneTimePbkCipher
83
- ? yield this.decryptResponseCipher(yield KFS.asKey(plainInitiatorRootKeyCipher.otKey), yield KFS.asKey(plainInitiatorRootKeyCipher.oneTimePrk), keyExchange.otk.initiatorOneTimePbkCipher)
84
- : null;
85
- const responder = plainInitiatorOneTimePbkCipher &&
86
- plainInitiatorOneTimePbkCipher.responder;
87
- const initiator = plainInitiatorRootKeyCipher && plainInitiatorRootKeyCipher.initiator;
88
- return Object.assign(Object.assign({}, keyExchange), { message: responder ? responder.message : null, contactCard: responder && responder.contactCard
89
- ? responder.contactCard.plainSharedCipherDataJson
90
- : null, myContactCard: initiator && initiator.contactCard
91
- ? initiator.contactCard.plainSharedCipherDataJson
92
- : null, myMessage: initiator && initiator.message });
93
- }
94
- else {
95
- const decryptedOtk = yield this.decryptOtk(keyExchange, otKeyK);
96
- const initiator = decryptedOtk && decryptedOtk.plainOtKeyCipher.initiator;
97
- return Object.assign(Object.assign({}, keyExchange), { decryptedOtk, message: initiator && initiator.message, contactCard: initiator &&
98
- initiator.contactCard &&
99
- initiator.contactCard.plainSharedCipherDataJson });
100
- }
101
- });
102
- }
103
- decryptOtk(keyExchange, otKeyK) {
104
- return __awaiter(this, void 0, void 0, function* () {
105
- const otKey = yield this.getOtKey(keyExchange, otKeyK);
106
- return otKey && keyExchange.otk.otKeyCipher
107
- ? {
108
- plainOtKeyCipher: yield this.encryptionService.decrypt(otKey, keyExchange.otk.otKeyCipher),
109
- otKey,
110
- }
111
- : null;
112
- });
113
- }
114
- getOtKey(keyExchange, otKeyK) {
115
- return __awaiter(this, void 0, void 0, function* () {
116
- if (otKeyK) {
117
- return yield KFS.asKey(Object.assign(Object.assign({}, JSON.parse(keyExchange.otk.otKeyParams)), { k: otKeyK }));
118
- }
119
- else if (keyExchange.otk.state === OtkState.OTK_INITIATED &&
120
- !keyExchange.isInitiator &&
121
- keyExchange.otk.responderPbkCipher) {
122
- // Assuming existing user getting invited where OTK is wrapped in responder's public key.
123
- const prk = yield this.keyService.getCurrentPxk();
124
- const decryptedCipher = yield this.encryptionService.decrypt(prk.jwk, JSON.parse(keyExchange.otk.responderPbkCipher), {
125
- serializations: [JoseSerialization.COMPACT],
126
- });
127
- if (decryptedCipher.otKey) {
128
- return yield KFS.asKey(decryptedCipher.otKey);
129
- }
130
- }
131
- return null;
132
- });
133
- }
134
- initiateOtk({ message, email, contactCard, upgrade, }) {
135
- return __awaiter(this, void 0, void 0, function* () {
136
- const otKey = yield this.keyFactory.createKey();
137
- const nonce = this.keyFactory.randomString(this.CLIENT_NONCE_LENGTH);
138
- const user = yield this.authService.getUser();
139
- // New PKC key for encryption. This key is used only once when the responder sends
140
- // back their signing public key.
141
- const initiatorOneTimePrk = yield this.keyFactory.createPkcKey();
142
- // Option 1: New PKC key for signing
143
- // const initiatorSigPrk = await this.keyService.createPkcSignKey();
144
- // Option 2: Use the user's global signing key.
145
- // This key is used to prove the initiator's identity.
146
- const initiatorPrk = yield this.keyService.getCurrentPxk();
147
- const initiatorSigPrk = yield this.keyService.getCurrentSigPxk();
148
- let initiatorPlainDataSig = null;
149
- if (contactCard && contactCard.ownerPlainData) {
150
- initiatorPlainDataSig = JSON.stringify(yield this.encryptionService.sign(initiatorSigPrk.jwk, contactCard.ownerPlainData));
151
- }
152
- const initiator = {
153
- message,
154
- contactCard: contactCard
155
- ? {
156
- plainSharedCipherDataJson: contactCard.plainSharedCipherDataJson,
157
- }
158
- : null,
159
- };
160
- // Content to be encrypted using the OTK.
161
- const plainOtKeyCipher = {
162
- nonce,
163
- initiator: Object.assign(Object.assign({}, initiator), { oneTimePbk: initiatorOneTimePrk.toJSON(), pbk: initiatorPrk.jwk.toJSON(), sigPbk: initiatorSigPrk.jwk.toJSON(), profile: {
164
- username: user.username,
165
- } }),
166
- };
167
- const otKeyCipher = yield this.encryptionService.encrypt(otKey, plainOtKeyCipher);
168
- // Content to be encrypted using the initiator's root key.
169
- const plainInitiatorRootKeyCipher = {
170
- nonce,
171
- oneTimePrk: initiatorOneTimePrk.toJSON(true),
172
- // Should not need to keep this encrypted since we are using the global signing key.
173
- // sigPrk: initiatorSigPrk.toJSON(true),
174
- // Save it in case the initiator want to decode the otKeyCipher.
175
- // Since the otKey is only used once, and that otKeyCipher contains only
176
- // the public key of the initiator, it's safe just leave the otKey stored here.
177
- otKey: otKey.toJSON(true),
178
- // These should be storing information such as how the fields of the shared contact card is
179
- // derived from the master contact card.
180
- initiatorContactCard: contactCard,
181
- initiator,
182
- };
183
- const rootKey = yield this.keyService.getCurrentRootKey();
184
- const initiatorRootKeyCipher = yield this.encryptionService.encrypt(rootKey.jwk, plainInitiatorRootKeyCipher);
185
- // The raw OTK
186
- const otKeyK = otKey.toJSON(true).k;
187
- // API call
188
- const { initiateKeyExchangeOtk } = yield this.lrApollo.mutate({
189
- mutation: InitiateOtkMutation,
190
- variables: {
191
- input: {
192
- // These will be stored on the server
193
- initiatorRootKeyCipher: JSON.stringify(initiatorRootKeyCipher),
194
- initiatorPxkId: initiatorPrk.id,
195
- initiatorSigPxkId: initiatorSigPrk.id,
196
- // These will be sent to the responder
197
- otKeyParams: JSON.stringify(otKey.toJSON()),
198
- otKeyCipher: JSON.stringify(otKeyCipher),
199
- sendEmail: email
200
- ? {
201
- email,
202
- rawOtKey: otKeyK,
203
- }
204
- : null,
205
- createTp: true,
206
- initiatorPlainDataSig,
207
- upgrade,
208
- },
209
- },
210
- });
211
- return { keyExchange: initiateKeyExchangeOtk.keyExchange, otKeyK };
212
- });
213
- }
214
- respondOtk({ id, token, decryptedOtk, message, initiatorContactCard, responderContactCard: sentContactCard, }) {
215
- return __awaiter(this, void 0, void 0, function* () {
216
- const user = yield this.authService.getUser();
217
- const rootKey = yield this.keyService.getCurrentRootKey();
218
- const masterKeyId = this.keyService.getCurrentMasterKey().id;
219
- const masterKey = yield this.keyService.getCurrentMasterKey();
220
- const sharedKey = yield this.keyFactory.createKey();
221
- const mkSharedKey = yield this.keyFactory.createKey();
222
- const rkWrappedSharedKey = yield this.encryptionService.encrypt(rootKey.jwk, sharedKey.toJSON(true));
223
- const mkWrappedMkSharedKey = yield this.encryptionService.encrypt(masterKey.jwk, mkSharedKey.toJSON(true));
224
- const initiatorOneTimePbk = yield KFS.asKey(decryptedOtk.plainOtKeyCipher.initiator.oneTimePbk);
225
- const initiatorPbk = yield KFS.asKey(decryptedOtk.plainOtKeyCipher.initiator.pbk);
226
- const initiatorSigPbk = yield KFS.asKey(decryptedOtk.plainOtKeyCipher.initiator.sigPbk);
227
- // Option 1: Using new Prk for each TP pair
228
- // Create a new public signing key for the responder.
229
- // const responderSigPrk = await this.keyService.createPkcSignKey()
230
- // const rkWrappedResponderSigPrk = await this.encrypt(rootKey, responderSigPrk.toJSON(true));
231
- // Option 2: Responder already has a signing Prk
232
- const responderPrk = yield this.keyService.getCurrentPxk();
233
- const responderSigPrk = yield this.keyService.getCurrentSigPxk();
234
- const signedInitiatorPbk = yield this.encryptionService.sign(responderSigPrk.jwk, initiatorPbk.toJSON());
235
- const signedInitiatorSigPbk = yield this.encryptionService.sign(responderSigPrk.jwk, initiatorSigPbk.toJSON());
236
- const plainInitiatorOneTimePbkCipher = {
237
- nonce: decryptedOtk.plainOtKeyCipher.nonce,
238
- sharedKey: sharedKey.toJSON(true),
239
- mkSharedKey: mkSharedKey.toJSON(true),
240
- responder: {
241
- pbk: responderPrk.jwk.toJSON(),
242
- sigPbk: responderSigPrk.jwk.toJSON(),
243
- profile: {
244
- username: user.username,
245
- },
246
- message,
247
- },
248
- };
249
- let receivedCardInput;
250
- if (decryptedOtk.plainOtKeyCipher.initiator.contactCard) {
251
- // Set the info about the initiator to be the ones sent by the initiator. We need th responder to do the encryption here
252
- // because the initiator does not have the shared key yet, and we want the responder to have a functional contact card after
253
- // this exchange. The initiator can double check the contact details are correct and sign it when it completes the exchange.
254
- const plainSharedCipherDataJson = decryptedOtk.plainOtKeyCipher.initiator.contactCard
255
- .plainSharedCipherDataJson;
256
- // Create keys
257
- const receiverKey = yield this.keyFactory.createKey();
258
- const ccSharedKey = yield this.keyFactory.createKey();
259
- const sigPxk = yield this.keyService.getCurrentSigPxk();
260
- receivedCardInput = {
261
- receiverWrappedKey: JSON.stringify(yield this.encryptionService.encrypt(rootKey.jwk, receiverKey.toJSON(true))),
262
- receiverWrappingKeyId: rootKey.id,
263
- receiverCipherData: initiatorContactCard
264
- ? JSON.stringify(yield this.encryptionService.encrypt(receiverKey, initiatorContactCard.plainReceiverCipherDataJson))
265
- : '',
266
- sharedWrappedKey: JSON.stringify(yield this.encryptionService.encrypt(sharedKey, ccSharedKey.toJSON(true))),
267
- };
268
- const sharedCipherData = yield this.encryptionService.encrypt(ccSharedKey, plainSharedCipherDataJson);
269
- receivedCardInput.sharedCipherDataSig = JSON.stringify(yield this.encryptionService.sign(sigPxk.jwk, sharedCipherData));
270
- receivedCardInput.sigPxkId = sigPxk.id;
271
- plainInitiatorOneTimePbkCipher.responder.contactCard = Object.assign(Object.assign({}, plainInitiatorOneTimePbkCipher.responder.contactCard), { sharedCipherKey: ccSharedKey.toJSON(true) });
272
- }
273
- let sentCardInput;
274
- if (sentContactCard) {
275
- // Create keys
276
- const ownerKey = yield this.keyFactory.createKey();
277
- const ccSharedKey = yield this.keyFactory.createKey();
278
- const sigPxk = yield this.keyService.getCurrentSigPxk();
279
- sentCardInput = {
280
- ownerWrappedKey: JSON.stringify(yield this.encryptionService.encrypt(rootKey.jwk, ownerKey.toJSON(true))),
281
- ownerWrappingKeyId: rootKey.id,
282
- ownerCipherData: sentContactCard.plainOwnerCipherDataJson
283
- ? JSON.stringify(yield this.encryptionService.encrypt(ownerKey, sentContactCard.plainOwnerCipherDataJson))
284
- : '',
285
- sharedWrappedKey: JSON.stringify(yield this.encryptionService.encrypt(sharedKey, ccSharedKey.toJSON(true))),
286
- };
287
- const sharedCipherData = yield this.encryptionService.encrypt(ccSharedKey, sentContactCard.plainSharedCipherDataJson);
288
- sentCardInput.sharedCipherDataSig = JSON.stringify(yield this.encryptionService.sign(sigPxk.jwk, sharedCipherData));
289
- sentCardInput.sigPxkId = sigPxk.id;
290
- if (sentContactCard.ownerPlainData) {
291
- sentCardInput.ownerPlainDataSig = JSON.stringify(yield this.encryptionService.sign(responderSigPrk.jwk, sentContactCard.ownerPlainData));
292
- }
293
- // Contact card info readable by the initiator
294
- plainInitiatorOneTimePbkCipher.responder.contactCard = Object.assign(Object.assign({}, plainInitiatorOneTimePbkCipher.responder.contactCard), { plainSharedCipherDataJson: sentContactCard.plainSharedCipherDataJson });
295
- }
296
- // Encrypt with one-time public key
297
- let initiatorOneTimePbkCipher = yield this.encryptionService.encrypt(initiatorOneTimePbk, plainInitiatorOneTimePbkCipher);
298
- // Encrypt with the otk again to keep use of asymmetric keys to a minimum.
299
- initiatorOneTimePbkCipher = yield this.encryptionService.encrypt(decryptedOtk.otKey, initiatorOneTimePbkCipher);
300
- const { respondKeyExchangeOtk } = yield this.lrApollo.mutate({
301
- mutation: RespondOtkMutation,
302
- variables: {
303
- input: {
304
- keyExchangeId: id,
305
- keyExchangeToken: token,
306
- rootKeyId: rootKey.id,
307
- masterKeyId,
308
- // These will be stored on the server
309
- responderPxkId: responderPrk.id,
310
- responderSigPxkId: responderSigPrk.id,
311
- signedInitiatorPbk: JSON.stringify(signedInitiatorPbk),
312
- signedInitiatorSigPbk: JSON.stringify(signedInitiatorSigPbk),
313
- // rkWrappedInitiatorSigPbk: JSON.stringify(rkWrappedInitiatorSigPbk),
314
- // Option 1: Using new Prk for each TP pair
315
- // rkWrappedResponderSigPrk: JSON.stringify(rkWrappedResponderSigPrk),
316
- rkWrappedSharedKey: JSON.stringify(rkWrappedSharedKey),
317
- mkWrappedMkSharedKey: JSON.stringify(mkWrappedMkSharedKey),
318
- // These will be sent to the initiator
319
- initiatorOneTimePbkCipher: JSON.stringify(initiatorOneTimePbkCipher),
320
- initiatorContactCard: receivedCardInput,
321
- responderContactCard: sentCardInput,
322
- },
323
- },
324
- });
325
- return {
326
- keyExchange: respondKeyExchangeOtk.keyExchange,
327
- userSharedKey: respondKeyExchangeOtk.userSharedKey,
328
- tp: respondKeyExchangeOtk.tp,
329
- };
330
- });
331
- }
332
- completeOtk(keyExchangeId, initiatorRootKeyCipher, initiatorOneTimePbkCipher, responderContactCard) {
333
- return __awaiter(this, void 0, void 0, function* () {
334
- const rootKey = yield this.keyService.getCurrentRootKey();
335
- const masterKey = yield this.keyService.getCurrentMasterKey();
336
- // Decrypt using the root key to get the Prk
337
- const plainInitiatorRootKeyCipher = (yield this.encryptionService.decrypt(rootKey.jwk, initiatorRootKeyCipher));
338
- // The Prk is single-use and only used to send information from the responder back to the initiator.
339
- const plainInitiatorOneTimePbkCipher = yield this.decryptResponseCipher(yield KFS.asKey(plainInitiatorRootKeyCipher.otKey), yield KFS.asKey(plainInitiatorRootKeyCipher.oneTimePrk), initiatorOneTimePbkCipher);
340
- // Check the nonce match to ensure the responder was the one holding the OTK
341
- if (plainInitiatorRootKeyCipher.nonce !== plainInitiatorOneTimePbkCipher.nonce) {
342
- throw new LrCodeMismatchException('The nonce returned by responder does not match with the one created by the initiator.');
343
- }
344
- // Option 1: Assuming the signing key is unique between users.
345
- // const initiatorSigPrk = await KFS.asKey(ke.plainInitiatorRootKeyCipher.sigPrk);
346
- // const rkWrappedInitiatorSigPrk = await this.encrypt(rootKey, initiatorSigPrk.toJSON(true));
347
- // Option 2: Use the user's global signing key.
348
- // In this case the initiatorSigPrk is already a part of the key graph.
349
- // So there's nothing to do here.
350
- // Protected the signing public key of the responder.
351
- const initiatorSigPrk = yield this.keyService.getCurrentSigPxk();
352
- const responderSigPbk = yield KFS.asKey(plainInitiatorOneTimePbkCipher.responder.sigPbk);
353
- const responderPbk = yield KFS.asKey(plainInitiatorOneTimePbkCipher.responder.pbk);
354
- const signedResponderPbk = yield this.encryptionService.sign(initiatorSigPrk.jwk, responderPbk.toJSON());
355
- const signedResponderSigPbk = yield this.encryptionService.sign(initiatorSigPrk.jwk, responderSigPbk.toJSON());
356
- const sharedKey = yield KFS.asKey(plainInitiatorOneTimePbkCipher.sharedKey);
357
- const rkWrappedSharedKey = yield this.encryptionService.encrypt(rootKey.jwk, sharedKey.toJSON(true));
358
- const mkSharedKey = yield KFS.asKey(plainInitiatorOneTimePbkCipher.mkSharedKey);
359
- const mkWrappedMkSharedKey = yield this.encryptionService.encrypt(masterKey.jwk, mkSharedKey.toJSON(true));
360
- let responderContactCardCipherInput;
361
- if (responderContactCard) {
362
- // Create key
363
- const receiverKey = yield this.keyFactory.createKey();
364
- responderContactCardCipherInput = {
365
- receiverWrappedKey: JSON.stringify(yield this.encryptionService.encrypt(rootKey.jwk, receiverKey.toJSON(true))),
366
- receiverWrappingKeyId: rootKey.id,
367
- receiverCipherData: JSON.stringify(yield this.encryptionService.encrypt(receiverKey, responderContactCard)),
368
- };
369
- }
370
- // Get the data needed from the initiator's cipher data.
371
- let initiatorContactCardCipherInput;
372
- let initiatorContactCardSharedCipherInput;
373
- if (plainInitiatorRootKeyCipher.initiatorContactCard) {
374
- const initiatorContactCard = plainInitiatorRootKeyCipher.initiatorContactCard;
375
- const ownerKey = yield this.keyFactory.createKey();
376
- const sharedCipherKey = yield KFS.asKey(plainInitiatorOneTimePbkCipher.responder.contactCard.sharedCipherKey);
377
- const ownerWrappedKey = JSON.stringify(yield this.encryptionService.encrypt(rootKey.jwk, ownerKey.toJSON(true)));
378
- const ownerCipherData = initiatorContactCard.plainOwnerCipherDataJson
379
- ? JSON.stringify(yield this.encryptionService.encrypt(ownerKey, initiatorContactCard.plainOwnerCipherDataJson))
380
- : '';
381
- initiatorContactCardCipherInput = {
382
- ownerWrappedKey,
383
- ownerWrappingKeyId: rootKey.id,
384
- ownerCipherData,
385
- };
386
- initiatorContactCardSharedCipherInput = {
387
- sigPxkId: initiatorSigPrk.id,
388
- };
389
- const sharedCipherData = yield this.encryptionService.encrypt(sharedCipherKey, initiatorContactCard.plainSharedCipherDataJson);
390
- initiatorContactCardSharedCipherInput.sharedCipherDataSig = JSON.stringify(yield this.encryptionService.sign(initiatorSigPrk.jwk, sharedCipherData));
391
- }
392
- // TODO ideally we update the shared data in the contact card sent to the responder as well since that
393
- // CC was created by the responder.
394
- const res = yield this.lrApollo.mutate({
395
- mutation: CompleteOtkMutation,
396
- variables: {
397
- input: {
398
- keyExchangeId,
399
- rootKeyId: rootKey.id,
400
- masterKeyId: masterKey.id,
401
- initiatorSigPxkId: initiatorSigPrk.id,
402
- signedResponderPbk: JSON.stringify(signedResponderPbk),
403
- signedResponderSigPbk: JSON.stringify(signedResponderSigPbk),
404
- rkWrappedSharedKey: JSON.stringify(rkWrappedSharedKey),
405
- mkWrappedMkSharedKey: JSON.stringify(mkWrappedMkSharedKey),
406
- responderContactCardCipher: responderContactCardCipherInput,
407
- initiatorContactCardCipher: initiatorContactCardCipherInput,
408
- initiatorContactCardSharedCipher: initiatorContactCardSharedCipherInput,
409
- },
410
- },
411
- });
412
- return res.completeKeyExchangeOtk;
413
- });
414
- }
415
- currentUserSharedKey(input) {
416
- return __awaiter(this, void 0, void 0, function* () {
417
- const { currentUserSharedKey } = yield this.lrApollo.query({
418
- query: CurrentUserSharedKeyQuery,
419
- variables: {
420
- username: input.username,
421
- userId: input.userId,
422
- },
423
- });
424
- return currentUserSharedKey.userSharedKey;
425
- });
426
- }
427
- }
428
- KeyExchangeService.ɵprov = i0.ɵɵdefineInjectable({ factory: function KeyExchangeService_Factory() { return new KeyExchangeService(i0.ɵɵinject(i1.KeyFactoryService), i0.ɵɵinject(i2.KeyService), i0.ɵɵinject(i3.LrApolloService), i0.ɵɵinject(i4.EncryptionService), i0.ɵɵinject(i5.LifeReadyAuthService), i0.ɵɵinject(i6.UserService)); }, token: KeyExchangeService, providedIn: "root" });
429
- KeyExchangeService.decorators = [
430
- { type: Injectable, args: [{
431
- providedIn: 'root',
432
- },] }
433
- ];
434
- KeyExchangeService.ctorParameters = () => [
435
- { type: KFS },
436
- { type: KeyService },
437
- { type: LrApolloService },
438
- { type: EncryptionService },
439
- { type: LifeReadyAuthService },
440
- { type: UserService }
441
- ];
442
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoia2V5LWV4Y2hhbmdlLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiL29wdC9hdGxhc3NpYW4vcGlwZWxpbmVzL2FnZW50L2J1aWxkL3Byb2plY3RzL2NvcmUvc3JjLyIsInNvdXJjZXMiOlsibGliL2FwaS9rZXktZXhjaGFuZ2Uuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUUzQyxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUV2RSxPQUFPLEVBQ0wsaUJBQWlCLEVBQ2pCLGlCQUFpQixHQUNsQixNQUFNLG9DQUFvQyxDQUFDO0FBQzVDLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUN6RCxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUNoRSxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDdEQsT0FBTyxFQUNMLG1CQUFtQixFQUNuQix5QkFBeUIsRUFDekIsbUJBQW1CLEVBQ25CLGdCQUFnQixFQUNoQixpQkFBaUIsRUFDakIscUJBQXFCLEVBQ3JCLGtCQUFrQixHQUNuQixNQUFNLG9CQUFvQixDQUFDO0FBQzVCLE9BQU8sRUFRTCxRQUFRLEdBUVQsTUFBTSxzQkFBc0IsQ0FBQztBQUM5QixPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDdEQsT0FBTyxFQUFFLGlCQUFpQixJQUFJLEdBQUcsRUFBRSxNQUFNLHFDQUFxQyxDQUFDO0FBQy9FLDBHQUEwRztBQUMxRyxPQUFPLEtBQUssT0FBTyxNQUFNLFFBQVEsQ0FBQzs7Ozs7Ozs7QUFDbEMsTUFBTSxNQUFNLEdBQUcsT0FBTyxDQUFDO0FBS3ZCLE1BQU0sT0FBTyxrQkFBa0I7SUFHN0IsWUFDVSxVQUFlLEVBQ2YsVUFBc0IsRUFDdEIsUUFBeUIsRUFDekIsaUJBQW9DLEVBQ3BDLFdBQWlD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bmltcG9ydCB7IEpXSyB9IGZyb20gJ25vZGUtam9zZSc7XG5pbXBvcnQgeyBMaWZlUmVhZHlBdXRoU2VydmljZSB9IGZyb20gJy4uL2F1dGgvbGlmZS1yZWFkeS1hdXRoLnNlcnZpY2UnO1xuaW1wb3J0IHsgS2V5R3JhcGhSZXNwb25zZSB9IGZyb20gJy4uL2NyeXB0b2dyYXBoeS9jcnlwdG9ncmFwaHkudHlwZXMnO1xuaW1wb3J0IHtcbiAgRW5jcnlwdGlvblNlcnZpY2UsXG4gIEpvc2VTZXJpYWxpemF0aW9uLFxufSBmcm9tICcuLi9jcnlwdG9ncmFwaHkvZW5jcnlwdGlvbi5zZXJ2aWNlJztcbmltcG9ydCB7IEtleVNlcnZpY2UgfSBmcm9tICcuLi9jcnlwdG9ncmFwaHkva2V5LnNlcnZpY2UnO1xuaW1wb3J0IHsgTHJDb2RlTWlzbWF0Y2hFeGNlcHRpb24gfSBmcm9tICcuLi9fY29tbW9uL2V4Y2VwdGlvbnMnO1xuaW1wb3J0IHsgVXNlclNlcnZpY2UgfSBmcm9tICcuLy4uL3VzZXJzL3VzZXIuc2VydmljZSc7XG5pbXBvcnQge1xuICBDb21wbGV0ZU90a011dGF0aW9uLFxuICBDdXJyZW50VXNlclNoYXJlZEtleVF1ZXJ5LFxuICBJbml0aWF0ZU90a011dGF0aW9uLFxuICBLZXlFeGNoYW5nZVF1ZXJ5LFxuICBLZXlFeGNoYW5nZXNRdWVyeSxcbiAgS2V5RXhjaGFuZ2VUb2tlblF1ZXJ5LFxuICBSZXNwb25kT3RrTXV0YXRpb24sXG59IGZyb20gJy4va2V5LWV4Y2hhbmdlLmdxbCc7XG5pbXBvcnQge1xuICBDb21wbGV0ZU90ayxcbiAgRGVjcnlwdGVkS2V5RXhjaGFuZ2UsXG4gIERlY3J5cHRlZE90ayxcbiAgR2V0S2V5RXhjaGFuZ2VMaXN0T3B0aW9ucyxcbiAgR2V0S2V5RXhjaGFuZ2VPcHRpb25zLFxuICBJbml0aWF0ZU90a0lucHV0LFxuICBLZXlFeGNoYW5nZSxcbiAgT3RrU3RhdGUsXG4gIFBsYWluSW5pdGlhdG9yT25lVGltZVBia0NpcGhlcixcbiAgUGxhaW5Jbml0aWF0b3JSb290S2V5Q2lwaGVyLFxuICBQbGFpbk90S2V5Q2lwaGVyLFxuICBQbGFpblJlc3BvbmRlclBia0NpcGhlcixcbiAgUmVzcG9uZE90ayxcbiAgUmVzcG9uZE90a0lucHV0LFxuICBVc2VyU2hhcmVkS2V5LFxufSBmcm9tICcuL2tleS1leGNoYW5nZS50eXBlcyc7XG5pbXBvcnQgeyBMckFwb2xsb1NlcnZpY2UgfSBmcm9tICcuL2xyLWFwb2xsby5zZXJ2aWNlJztcbmltcG9ydCB7IEtleUZhY3RvcnlTZXJ2aWNlIGFzIEtGUyB9IGZyb20gJy4uL2NyeXB0b2dyYXBoeS9rZXktZmFjdG9yeS5zZXJ2aWNlJztcbi8vIFJlZjogaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvNTk3MzUyODAvYW5ndWxhci04LW1vbWVudC1lcnJvci1jYW5ub3QtY2FsbC1hLW5hbWVzcGFjZS1tb21lbnRcbmltcG9ydCAqIGFzIG1vbWVudF8gZnJvbSAnbW9tZW50JztcbmNvbnN0IG1vbWVudCA9IG1vbWVudF87XG5cbkBJbmplY3RhYmxlKHtcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnLFxufSlcbmV4cG9ydCBjbGFzcyBLZXlFeGNoYW5nZVNlcnZpY2Uge1xuICBwcml2YXRlIHJlYWRvbmx5IENMSUVOVF9OT05DRV9MRU5HVEggPSAzMjtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIGtleUZhY3Rvcnk6IEtGUyxcbiAgICBwcml2YXRlIGtleVNlcnZpY2U6IEtleVNlcnZpY2UsXG4gICAgcHJpdmF0ZSBsckFwb2xsbzogTHJBcG9sbG9TZXJ2aWNlLFxuICAgIHByaXZhdGUgZW5jcnlwdGlvblNlcnZpY2U6IEVuY3J5cHRpb25TZXJ2aWNlLFxuICAgIHByaXZhdGUgYXV0aFNlcnZpY2U6IExpZmVSZWFkeUF1dGhTZXJ2aWNlLFxuICAgIHByaXZhdGUgdXNlclNlcnZpY2U6IFVzZXJTZXJ2aWNlXG4gICkge31cblxuICBwdWJsaWMgYXN5bmMgZ2V0S2V5RXhjaGFuZ2VMaXN0KFxuICAgIGlucHV0OiBHZXRLZXlFeGNoYW5nZUxpc3RPcHRpb25zID0ge31cbiAgKTogUHJvbWlzZTxhbnk+IHtcbiAgICBjb25zdCB7IGtleUV4Y2hhbmdlcyB9ID0gYXdhaXQgdGhpcy5sckFwb2xsby5xdWVyeTx7XG4gICAgICBrZXlFeGNoYW5nZXM6IGFueTtcbiAgICAgIGtleUdyYXBoOiBLZXlHcmFwaFJlc3BvbnNlO1xuICAgIH0+KHtcbiAgICAgIHF1ZXJ5OiBLZXlFeGNoYW5nZXNRdWVyeSxcbiAgICAgIHZhcmlhYmxlczoge1xuICAgICAgICAuLi5pbnB1dCxcbiAgICAgIH0sXG4gICAgfSk7XG4gICAgcmV0dXJuIGtleUV4Y2hhbmdlcztcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0gaWQgSWYgdGhlIGN1cnJlbnQgdXNlciBjYW4gcmVzcG9uZGVyIHRoZSBrZXkgZXhjaGFuZ2UgaWYgdGhleSBhcmUgZWl0aGVyIHRoZSBpbml0aWF0b3Igb3IgdGhlIHJlY2VpdmVyLlxuICAgKiBAcGFyYW0gdG9rZW4gSWYgbm90IHNpZ25lZCBpbiwgb3Igbm90IHRoZSBpbml0aWF0b3Igb3IgcmVzcG9uZGVyLCAndG9rZW4nIG11c3QgYmUgZ2l2ZW4uXG4gICAqIEBwYXJhbSBvdEtleUsgSXMgdGhlIHJhdyBvbmUtdGltZSBrZXkgKHN0cmluZykuIElmIHRoZSByZXNwb25kZXIgaXMgZXhwbGljaXRseSBzcGVjaWZpZWQgYXQgdGltZSBvZiBpbml0aWF0aW9uLCB0aGVuXG4gICAqICAgaXQncyBwb3NzaWJsZSB0byBoYXZlIHRoZSBvdEtleSB3cmFwcGVkIGJ5IHRoZSBwdWJsaWMga2V5IG9mIHRoZSByZXNwb25kZXIuIEluIHdoaWNoIGNhc2UsIHRoZSBvdEtleUsgaXMgbm90IG5lZWRlZC5cbiAgICovXG4gIHB1YmxpYyBhc3luYyBnZXRLZXlFeGNoYW5nZShcbiAgICBpZDogc3RyaW5nLFxuICAgIHsgb3RLZXlLLCB0b2tlbiB9OiBHZXRLZXlFeGNoYW5nZU9wdGlvbnMgPSB7fVxuICApOiBQcm9taXNlPERlY3J5cHRlZEtleUV4Y2hhbmdlPiB7XG4gICAgY29uc3QgeyBrZXlFeGNoYW5nZSB9ID0gYXdhaXQgdGhpcy5sckFwb2xsby5xdWVyeTx7XG4gICAgICBrZXlFeGNoYW5nZTogS2V5RXhjaGFuZ2U7XG4gICAgICBrZXlHcmFwaDogS2V5R3JhcGhSZXNwb25zZTtcbiAgICB9Pih7XG4gICAgICBxdWVyeTogdG9rZW4gPyBLZXlFeGNoYW5nZVRva2VuUXVlcnkgOiBLZXlFeGNoYW5nZVF1ZXJ5LFxuICAgICAgdmFyaWFibGVzOiB7XG4gICAgICAgIGlkLFxuICAgICAgICB0b2tlbixcbiAgICAgIH0sXG4gICAgfSk7XG4gICAgcmV0dXJuIGF3YWl0IHRoaXMuZGVjcnlwdEtleUV4Y2hhbmdlKGtleUV4Y2hhbmdlLCBvdEtleUspO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBkZWNyeXB0UmVzcG9uc2VDaXBoZXIoXG4gICAgb3RLZXk6IEpXSy5LZXksXG4gICAgb3RQcms6IEpXSy5LZXksXG4gICAgY29udGVudDogYW55XG4gICk6IFByb21pc2U8UGxhaW5Jbml0aWF0b3JPbmVUaW1lUGJrQ2lwaGVyPiB7XG4gICAgLy8gVGhlIHJlc3BvbnNlIGNvdWxkIGJlIHdyYXBwZWQgYnkgdGhlIE90SyBhcyB3ZWxsIGFzIHdlIHRoZSBPdFBya1xuICAgIHRyeSB7XG4gICAgICBjb250ZW50ID0gYXdhaXQgdGhpcy5lbmNyeXB0aW9uU2VydmljZS5kZWNyeXB0KG90S2V5LCBjb250ZW50KTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgaWYgKGVycm9yLm1lc3NhZ2UgIT09ICdubyBrZXkgZm91bmQnKSB7XG4gICAgICAgIHRocm93IGVycm9yO1xuICAgICAgfVxuICAgICAgLy8gRG8gbm90aGluZyB0byBzdXBwb3J0IG9sZGVyIHZlcnNpb25zIHdoZXJlIG1lc3NhZ2UgaXMgbm90IHdyYXBwZWQgd2l0aCBvdGsuXG4gICAgfVxuXG4gICAgLy8gVGhlIFByayBpcyBzaW5nbGUtdXNlIGFuZCBvbmx5IHVzZWQgdG8gc2VuZCBpbmZvcm1hdGlvbiBmcm9tIHRoZSByZXNwb25kZXIgYmFjayB0byB0aGUgaW5pdGlhdG9yLlxuICAgIHJldHVybiBhd2FpdCB0aGlzLmVuY3J5cHRpb25TZXJ2aWNlLmRlY3J5cHQob3RQcmssIGNvbnRlbnQpO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIGRlY3J5cHRLZXlFeGNoYW5nZShcbiAgICBrZXlFeGNoYW5nZTogS2V5RXhjaGFuZ2UsXG4gICAgb3RLZXlLPzogc3RyaW5nXG4gICk6IFByb21pc2U8RGVjcnlwdGVkS2V5RXhjaGFuZ2U+IHtcbiAgICBpZiAoa2V5RXhjaGFuZ2UuaXNJbml0aWF0b3IpIHtcbiAgICAgIGNvbnN0IHJvb3RLZXkgPSBhd2FpdCB0aGlzLmtleVNlcnZpY2UuZ2V0Q3VycmVudFJvb3RLZXkoKTtcbiAgICAgIC8vIERlY3J5cHQgdXNpbmcgdGhlIHJvb3Qga2V5IHRvIGdldCB0aGUgUHJrXG4gICAgICBjb25zdCBwbGFpbkluaXRpYXRvclJvb3RLZXlDaXBoZXIgPSAoKGF3YWl0IHRoaXMuZW5jcnlwdGlvblNlcnZpY2UuZGVjcnlwdChcbiAgICAgICAgcm9vdEtleS5qd2ssXG4gICAgICAgIGtleUV4Y2hhbmdlLmluaXRpYXRvclJvb3RLZXlDaXBoZXJcbiAgICAgICkpIGFzIHVua25vd24pIGFzIFBsYWluSW5pdGlhdG9yUm9vdEtleUNpcGhlcjtcblxuICAgICAgY29uc3QgcGxhaW5Jbml0aWF0b3JPbmVUaW1lUGJrQ2lwaGVyID0ga2V5RXhjaGFuZ2Uub3RrXG4gICAgICAgIC5pbml0aWF0b3JPbmVUaW1lUGJrQ2lwaGVyXG4gICAgICAgID8gYXdhaXQgdGhpcy5kZWNyeXB0UmVzcG9uc2VDaXBoZXIoXG4gICAgICAgICAgICBhd2FpdCBLRlMuYXNLZXkocGxhaW5Jbml0aWF0b3JSb290S2V5Q2lwaGVyLm90S2V5KSxcbiAgICAgICAgICAgIGF3YWl0IEtGUy5hc0tleShwbGFpbkluaXRpYXRvclJvb3RLZXlDaXBoZXIub25lVGltZVByayksXG4gICAgICAgICAgICBrZXlFeGNoYW5nZS5vdGsuaW5pdGlhdG9yT25lVGltZVBia0NpcGhlclxuICAgICAgICAgIClcbiAgICAgICAgOiBudWxsO1xuXG4gICAgICBjb25zdCByZXNwb25kZXIgPVxuICAgICAgICBwbGFpbkluaXRpYXRvck9uZVRpbWVQYmtDaXBoZXIgJiZcbiAgICAgICAgcGxhaW5Jbml0aWF0b3JPbmVUaW1lUGJrQ2lwaGVyLnJlc3BvbmRlcjtcbiAgICAgIGNvbnN0IGluaXRpYXRvciA9XG4gICAgICAgIHBsYWluSW5pdGlhdG9yUm9vdEtleUNpcGhlciAmJiBwbGFpbkluaXRpYXRvclJvb3RLZXlDaXBoZXIuaW5pdGlhdG9yO1xuXG4gICAgICByZXR1cm4ge1xuICAgICAgICAuLi5rZXlFeGNoYW5nZSxcbiAgICAgICAgbWVzc2FnZTogcmVzcG9uZGVyID8gcmVzcG9uZGVyLm1lc3NhZ2UgOiBudWxsLFxuICAgICAgICBjb250YWN0Q2FyZDpcbiAgICAgICAgICByZXNwb25kZXIgJiYgcmVzcG9uZGVyLmNvbnRhY3RDYXJkXG4gICAgICAgICAgICA/IHJlc3BvbmRlci5jb250YWN0Q2FyZC5wbGFpblNoYXJlZENpcGhlckRhdGFKc29uXG4gICAgICAgICAgICA6IG51bGwsXG4gICAgICAgIG15Q29udGFjdENhcmQ6XG4gICAgICAgICAgaW5pdGlhdG9yICYmIGluaXRpYXRvci5jb250YWN0Q2FyZFxuICAgICAgICAgICAgPyBpbml0aWF0b3IuY29udGFjdENhcmQucGxhaW5TaGFyZWRDaXBoZXJEYXRhSnNvblxuICAgICAgICAgICAgOiBudWxsLFxuICAgICAgICBteU1lc3NhZ2U6IGluaXRpYXRvciAmJiBpbml0aWF0b3IubWVzc2FnZSxcbiAgICAgIH07XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IGRlY3J5cHRlZE90ayA9IGF3YWl0IHRoaXMuZGVjcnlwdE90ayhrZXlFeGNoYW5nZSwgb3RLZXlLKTtcblxuICAgICAgY29uc3QgaW5pdGlhdG9yID0gZGVjcnlwdGVkT3RrICYmIGRlY3J5cHRlZE90ay5wbGFpbk90S2V5Q2lwaGVyLmluaXRpYXRvcjtcblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgLi4ua2V5RXhjaGFuZ2UsXG4gICAgICAgIGRlY3J5cHRlZE90ayxcbiAgICAgICAgbWVzc2FnZTogaW5pdGlhdG9yICYmIGluaXRpYXRvci5tZXNzYWdlLFxuICAgICAgICBjb250YWN0Q2FyZDpcbiAgICAgICAgICBpbml0aWF0b3IgJiZcbiAgICAgICAgICBpbml0aWF0b3IuY29udGFjdENhcmQgJiZcbiAgICAgICAgICBpbml0aWF0b3IuY29udGFjdENhcmQucGxhaW5TaGFyZWRDaXBoZXJEYXRhSnNvbixcbiAgICAgIH07XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBkZWNyeXB0T3RrKFxuICAgIGtleUV4Y2hhbmdlOiBLZXlFeGNoYW5nZSxcbiAgICBvdEtleUs/OiBzdHJpbmdcbiAgKTogUHJvbWlzZTxEZWNyeXB0ZWRPdGs+IHtcbiAgICBjb25zdCBvdEtleSA9IGF3YWl0IHRoaXMuZ2V0T3RLZXkoa2V5RXhjaGFuZ2UsIG90S2V5Syk7XG5cbiAgICByZXR1cm4gb3RLZXkgJiYga2V5RXhjaGFuZ2Uub3RrLm90S2V5Q2lwaGVyXG4gICAgICA/IHtcbiAgICAgICAgICBwbGFpbk90S2V5Q2lwaGVyOiBhd2FpdCB0aGlzLmVuY3J5cHRpb25TZXJ2aWNlLmRlY3J5cHQoXG4gICAgICAgICAgICBvdEtleSxcbiAgICAgICAgICAgIGtleUV4Y2hhbmdlLm90ay5vdEtleUNpcGhlclxuICAgICAgICAgICksXG4gICAgICAgICAgb3RLZXksXG4gICAgICAgIH1cbiAgICAgIDogbnVsbDtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgZ2V0T3RLZXkoXG4gICAga2V5RXhjaGFuZ2U6IEtleUV4Y2hhbmdlLFxuICAgIG90S2V5Sz86IHN0cmluZ1xuICApOiBQcm9taXNlPEpXSy5LZXk+IHtcbiAgICBpZiAob3RLZXlLKSB7XG4gICAgICByZXR1cm4gYXdhaXQgS0ZTLmFzS2V5KHtcbiAgICAgICAgLi4uSlNPTi5wYXJzZShrZXlFeGNoYW5nZS5vdGsub3RLZXlQYXJhbXMpLFxuICAgICAgICBrOiBvdEtleUssXG4gICAgICB9KTtcbiAgICB9IGVsc2UgaWYgKFxuICAgICAga2V5RXhjaGFuZ2Uub3RrLnN0YXRlID09PSBPdGtTdGF0ZS5PVEtfSU5JVElBVEVEICYmXG4gICAgICAha2V5RXhjaGFuZ2UuaXNJbml0aWF0b3IgJiZcbiAgICAgIGtleUV4Y2hhbmdlLm90ay5yZXNwb25kZXJQYmtDaXBoZXJcbiAgICApIHtcbiAgICAgIC8vIEFzc3VtaW5nIGV4aXN0aW5nIHVzZXIgZ2V0dGluZyBpbnZpdGVkIHdoZXJlIE9USyBpcyB3cmFwcGVkIGluIHJlc3BvbmRlcidzIHB1YmxpYyBrZXkuXG4gICAgICBjb25zdCBwcmsgPSBhd2FpdCB0aGlzLmtleVNlcnZpY2UuZ2V0Q3VycmVudFB4aygpO1xuICAgICAgY29uc3QgZGVjcnlwdGVkQ2lwaGVyOiBhbnkgPSBhd2FpdCB0aGlzLmVuY3J5cHRpb25TZXJ2aWNlLmRlY3J5cHQoXG4gICAgICAgIHByay5qd2ssXG4gICAgICAgIEpTT04ucGFyc2Uoa2V5RXhjaGFuZ2Uub3RrLnJlc3BvbmRlclBia0NpcGhlciksXG4gICAgICAgIHtcbiAgICAgICAgICBzZXJpYWxpemF0aW9uczogW0pvc2VTZXJpYWxpemF0aW9uLkNPTVBBQ1RdLFxuICAgICAgICB9XG4gICAgICApO1xuICAgICAgaWYgKGRlY3J5cHRlZENpcGhlci5vdEtleSkge1xuICAgICAgICByZXR1cm4gYXdhaXQgS0ZTLmFzS2V5KGRlY3J5cHRlZENpcGhlci5vdEtleSk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgYXN5bmMgaW5pdGlhdGVPdGsoe1xuICAgIG1lc3NhZ2UsXG4gICAgZW1haWwsXG4gICAgY29udGFjdENhcmQsXG4gICAgdXBncmFkZSxcbiAgfTogSW5pdGlhdGVPdGtJbnB1dCk6IFByb21pc2U8eyBrZXlFeGNoYW5nZTogS2V5RXhjaGFuZ2U7IG90S2V5Szogc3RyaW5nIH0+IHtcbiAgICBjb25zdCBvdEtleSA9IGF3YWl0IHRoaXMua2V5RmFjdG9yeS5jcmVhdGVLZXkoKTtcbiAgICBjb25zdCBub25jZSA9IHRoaXMua2V5RmFjdG9yeS5yYW5kb21TdHJpbmcodGhpcy5DTElFTlRfTk9OQ0VfTEVOR1RIKTtcbiAgICBjb25zdCB1c2VyID0gYXdhaXQgdGhpcy5hdXRoU2VydmljZS5nZXRVc2VyKCk7XG5cbiAgICAvLyBOZXcgUEtDIGtleSBmb3IgZW5jcnlwdGlvbi4gVGhpcyBrZXkgaXMgdXNlZCBvbmx5IG9uY2Ugd2hlbiB0aGUgcmVzcG9uZGVyIHNlbmRzXG4gICAgLy8gYmFjayB0aGVpciBzaWduaW5nIHB1YmxpYyBrZXkuXG4gICAgY29uc3QgaW5pdGlhdG9yT25lVGltZVByayA9IGF3YWl0IHRoaXMua2V5RmFjdG9yeS5jcmVhdGVQa2NLZXkoKTtcblxuICAgIC8vIE9wdGlvbiAxOiBOZXcgUEtDIGtleSBmb3Igc2lnbmluZ1xuICAgIC8vIGNvbnN0IGluaXRpYXRvclNpZ1ByayA9IGF3YWl0IHRoaXMua2V5U2VydmljZS5jcmVhdGVQa2NTaWduS2V5KCk7XG5cbiAgICAvLyBPcHRpb24gMjogVXNlIHRoZSB1c2VyJ3MgZ2xvYmFsIHNpZ25pbmcga2V5LlxuICAgIC8vIFRoaXMga2V5IGlzIHVzZWQgdG8gcHJvdmUgdGhlIGluaXRpYXRvcidzIGlkZW50aXR5LlxuICAgIGNvbnN0IGluaXRpYXRvclByayA9IGF3YWl0IHRoaXMua2V5U2VydmljZS5nZXRDdXJyZW50UHhrKCk7XG4gICAgY29uc3QgaW5pdGlhdG9yU2lnUHJrID0gYXdhaXQgdGhpcy5rZXlTZXJ2aWNlLmdldEN1cnJlbnRTaWdQeGsoKTtcblxuICAgIGxldCBpbml0aWF0b3JQbGFpbkRhdGFTaWc6IHN0cmluZyA9IG51bGw7XG5cbiAgICBpZiAoY29udGFjdENhcmQgJiYgY29udGFjdENhcmQub3duZXJQbGFpbkRhdGEpIHtcbiAgICAgIGluaXRpYXRvclBsYWluRGF0YVNpZyA9IEpTT04uc3RyaW5naWZ5KFxuICAgICAgICBhd2FpdCB0aGlzLmVuY3J5cHRpb25TZXJ2aWNlLnNpZ24oXG4gICAgICAgICAgaW5pdGlhdG9yU2lnUHJrLmp3ayxcbiAgICAgICAgICBjb250YWN0Q2FyZC5vd25lclBsYWluRGF0YVxuICAgICAgICApXG4gICAgICApO1xuICAgIH1cblxuICAgIGNvbnN0IGluaXRpYXRvciA9IHtcbiAgICAgIG1lc3NhZ2UsXG4gICAgICBjb250YWN0Q2FyZDogY29udGFjdENhcmRcbiAgICAgICAgPyB7XG4gICAgICAgICAgICBwbGFpblNoYXJlZENpcGhlckRhdGFKc29uOiBjb250YWN0Q2FyZC5wbGFpblNoYXJlZENpcGhlckRhdGFKc29uLFxuICAgICAgICAgIH1cbiAgICAgICAgOiBudWxsLFxuICAgIH07XG5cbiAgICAvLyBDb250ZW50IHRvIGJlIGVuY3J5cHRlZCB1c2luZyB0aGUgT1RLLlxuICAgIGNvbnN0IHBsYWluT3RLZXlDaXBoZXI6IFBsYWluT3RLZXlDaXBoZXIgPSB7XG4gICAgICBub25jZSxcbiAgICAgIGluaXRpYXRvcjoge1xuICAgICAgICAuLi5pbml0aWF0b3IsXG4gICAgICAgIG9uZVRpbWVQYms6IGluaXRpYXRvck9uZVRpbWVQcmsudG9KU09OKCksIC8vIG9uZXRpbWUgcHVibGljIGVuY3J5cHRpb24ga2V5IHJlc3BvbmRlciB1c2UgdG8gc2VuZCBkYXRhIGJhY2sgdG8gaW5pdGlhdG9yXG4gICAgICAgIHBiazogaW5pdGlhdG9yUHJrLmp3ay50b0pTT04oKSwgLy8gcHVibGljIGVuY3J5cHRpb24ga2V5XG4gICAgICAgIHNpZ1BiazogaW5pdGlhdG9yU2lnUHJrLmp3ay50b0pTT04oKSwgLy8gcHVibGljIHNpZ25pbmcga2V5XG4gICAgICAgIHByb2ZpbGU6IHtcbiAgICAgICAgICB1c2VybmFtZTogdXNlci51c2VybmFtZSxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgfTtcblxuICAgIGNvbnN0IG90S2V5Q2lwaGVyID0gYXdhaXQgdGhpcy5lbmNyeXB0aW9uU2VydmljZS5lbmNyeXB0KFxuICAgICAgb3RLZXksXG4gICAgICBwbGFpbk90S2V5Q2lwaGVyXG4gICAgKTtcblxuICAgIC8vIENvbnRlbnQgdG8gYmUgZW5jcnlwdGVkIHVzaW5nIHRoZSBpbml0aWF0b3IncyByb290IGtleS5cbiAgICBjb25zdCBwbGFpbkluaXRpYXRvclJvb3RLZXlDaXBoZXI6IFBsYWluSW5pdGlhdG9yUm9vdEtleUNpcGhlciA9IHtcbiAgICAgIG5vbmNlLFxuICAgICAgb25lVGltZVByazogaW5pdGlhdG9yT25lVGltZVByay50b0pTT04odHJ1ZSksXG4gICAgICAvLyBTaG91bGQgbm90IG5lZWQgdG8ga2VlcCB0aGlzIGVuY3J5cHRlZCBzaW5jZSB3ZSBhcmUgdXNpbmcgdGhlIGdsb2JhbCBzaWduaW5nIGtleS5cbiAgICAgIC8vIHNpZ1ByazogaW5pdGlhdG9yU2lnUHJrLnRvSlNPTih0cnVlKSxcblxuICAgICAgLy8gU2F2ZSBpdCBpbiBjYXNlIHRoZSBpbml0aWF0b3Igd2FudCB0byBkZWNvZGUgdGhlIG90S2V5Q2lwaGVyLlxuICAgICAgLy8gU2luY2UgdGhlIG90S2V5IGlzIG9ubHkgdXNlZCBvbmNlLCBhbmQgdGhhdCBvdEtleUNpcGhlciBjb250YWlucyBvbmx5XG4gICAgICAvLyB0aGUgcHVibGljIGtleSBvZiB0aGUgaW5pdGlhdG9yLCBpdCdzIHNhZmUganVzdCBsZWF2ZSB0aGUgb3RLZXkgc3RvcmVkIGhlcmUuXG4gICAgICBvdEtleTogb3RLZXkudG9KU09OKHRydWUpLFxuICAgICAgLy8gVGhlc2Ugc2hvdWxkIGJlIHN0b3JpbmcgaW5mb3JtYXRpb24gc3VjaCBhcyBob3cgdGhlIGZpZWxkcyBvZiB0aGUgc2hhcmVkIGNvbnRhY3QgY2FyZCBpc1xuICAgICAgLy8gZGVyaXZlZCBmcm9tIHRoZSBtYXN0ZXIgY29udGFjdCBjYXJkLlxuICAgICAgaW5pdGlhdG9yQ29udGFjdENhcmQ6IGNvbnRhY3RDYXJkLFxuICAgICAgaW5pdGlhdG9yLFxuICAgIH07XG5cbiAgICBjb25zdCByb290S2V5ID0gYXdhaXQgdGhpcy5rZXlTZXJ2aWNlLmdldEN1cnJlbnRSb290S2V5KCk7XG4gICAgY29uc3QgaW5pdGlhdG9yUm9vdEtleUNpcGhlciA9IGF3YWl0IHRoaXMuZW5jcnlwdGlvblNlcnZpY2UuZW5jcnlwdChcbiAgICAgIHJvb3RLZXkuandrLFxuICAgICAgcGxhaW5Jbml0aWF0b3JSb290S2V5Q2lwaGVyXG4gICAgKTtcblxuICAgIC8vIFRoZSByYXcgT1RLXG4gICAgY29uc3Qgb3RLZXlLOiBzdHJpbmcgPSAob3RLZXkudG9KU09OKHRydWUpIGFzIGFueSkuaztcblxuICAgIC8vIEFQSSBjYWxsXG4gICAgY29uc3QgeyBpbml0aWF0ZUtleUV4Y2hhbmdlT3RrIH0gPSBhd2FpdCB0aGlzLmxyQXBvbGxvLm11dGF0ZTxhbnk+KHtcbiAgICAgIG11dGF0aW9uOiBJbml0aWF0ZU90a011dGF0aW9uLFxuICAgICAgdmFyaWFibGVzOiB7XG4gICAgICAgIGlucHV0OiB7XG4gICAgICAgICAgLy8gVGhlc2Ugd2lsbCBiZSBzdG9yZWQgb24gdGhlIHNlcnZlclxuICAgICAgICAgIGluaXRpYXRvclJvb3RLZXlDaXBoZXI6IEpTT04uc3RyaW5naWZ5KGluaXRpYXRvclJvb3RLZXlDaXBoZXIpLFxuICAgICAgICAgIGluaXRpYXRvclB4a0lkOiBpbml0aWF0b3JQcmsuaWQsXG4gICAgICAgICAgaW5pdGlhdG9yU2lnUHhrSWQ6IGluaXRpYXRvclNpZ1Byay5pZCxcbiAgICAgICAgICAvLyBUaGVzZSB3aWxsIGJlIHNlbnQgdG8gdGhlIHJlc3BvbmRlclxuICAgICAgICAgIG90S2V5UGFyYW1zOiBKU09OLnN0cmluZ2lmeShvdEtleS50b0pTT04oKSksXG4gICAgICAgICAgb3RLZXlDaXBoZXI6IEpTT04uc3RyaW5naWZ5KG90S2V5Q2lwaGVyKSxcbiAgICAgICAgICBzZW5kRW1haWw6IGVtYWlsXG4gICAgICAgICAgICA/IHtcbiAgICAgICAgICAgICAgICBlbWFpbCxcbiAgICAgICAgICAgICAgICByYXdPdEtleTogb3RLZXlLLFxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICA6IG51bGwsXG4gICAgICAgICAgY3JlYXRlVHA6IHRydWUsXG4gICAgICAgICAgaW5pdGlhdG9yUGxhaW5EYXRhU2lnLFxuICAgICAgICAgIHVwZ3JhZGUsXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIH0pO1xuICAgIHJldHVybiB7IGtleUV4Y2hhbmdlOiBpbml0aWF0ZUtleUV4Y2hhbmdlT3RrLmtleUV4Y2hhbmdlLCBvdEtleUsgfTtcbiAgfVxuXG4gIGFzeW5jIHJlc3BvbmRPdGsoe1xuICAgIGlkLFxuICAgIHRva2VuLFxuICAgIGRlY3J5cHRlZE90ayxcbiAgICBtZXNzYWdlLFxuICAgIGluaXRpYXRvckNvbnRhY3RDYXJkLFxuICAgIHJlc3BvbmRlckNvbnRhY3RDYXJkOiBzZW50Q29udGFjdENhcmQsXG4gIH06IFJlc3BvbmRPdGtJbnB1dCk6IFByb21pc2U8UmVzcG9uZE90az4ge1xuICAgIGNvbnN0IHVzZXIgPSBhd2FpdCB0aGlzLmF1dGhTZXJ2aWNlLmdldFVzZXIoKTtcbiAgICBjb25zdCByb290S2V5ID0gYXdhaXQgdGhpcy5rZXlTZXJ2aWNlLmdldEN1cnJlbnRSb290S2V5KCk7XG5cbiAgICBjb25zdCBtYXN0ZXJLZXlJZCA9IHRoaXMua2V5U2VydmljZS5nZXRDdXJyZW50TWFzdGVyS2V5KCkuaWQ7XG4gICAgY29uc3QgbWFzdGVyS2V5ID0gYXdhaXQgdGhpcy5rZXlTZXJ2aWNlLmdldEN1cnJlbnRNYXN0ZXJLZXkoKTtcblxuICAgIGNvbnN0IHNoYXJlZEtleSA9IGF3YWl0IHRoaXMua2V5RmFjdG9yeS5jcmVhdGVLZXkoKTtcbiAgICBjb25zdCBta1NoYXJlZEtleSA9IGF3YWl0IHRoaXMua2V5RmFjdG9yeS5jcmVhdGVLZXkoKTtcblxuICAgIGNvbnN0IHJrV3JhcHBlZFNoYXJlZEtleSA9IGF3YWl0IHRoaXMuZW5jcnlwdGlvblNlcnZpY2UuZW5jcnlwdChcbiAgICAgIHJvb3RLZXkuandrLFxuICAgICAgc2hhcmVkS2V5LnRvSlNPTih0cnVlKVxuICAgICk7XG4gICAgY29uc3QgbWtXcmFwcGVkTWtTaGFyZWRLZXkgPSBhd2FpdCB0aGlzLmVuY3J5cHRpb25TZXJ2aWNlLmVuY3J5cHQoXG4gICAgICBtYXN0ZXJLZXkuandrLFxuICAgICAgbWtTaGFyZWRLZXkudG9KU09OKHRydWUpXG4gICAgKTtcblxuICAgIGNvbnN0IGluaXRpYXRvck9uZVRpbWVQYmsgPSBhd2FpdCBLRlMuYXNLZXkoXG4gICAgICBkZWNyeXB0ZWRPdGsucGxhaW5PdEtleUNpcGhlci5pbml0aWF0b3Iub25lVGltZVBia1xuICAgICk7XG5cbiAgICBjb25zdCBpbml0aWF0b3JQYmsgPSBhd2FpdCBLRlMuYXNLZXkoXG4gICAgICBkZWNyeXB0ZWRPdGsucGxhaW5PdEtleUNpcGhlci5pbml0aWF0b3IucGJrXG4gICAgKTtcbiAgICBjb25zdCBpbml0aWF0b3JTaWdQYmsgPSBhd2FpdCBLRlMuYXNLZXkoXG4gICAgICBkZWNyeXB0ZWRPdGsucGxhaW5PdEtleUNpcGhlci5pbml0aWF0b3Iuc2lnUGJrXG4gICAgKTtcblxuICAgIC8vIE9wdGlvbiAxOiBVc2luZyBuZXcgUHJrIGZvciBlYWNoIFRQIHBhaXJcbiAgICAvLyBDcmVhdGUgYSBuZXcgcHVibGljIHNpZ25pbmcga2V5IGZvciB0aGUgcmVzcG9uZGVyLlxuICAgIC8vIGNvbnN0IHJlc3BvbmRlclNpZ1ByayA9IGF3YWl0IHRoaXMua2V5U2VydmljZS5jcmVhdGVQa2NTaWduS2V5KClcbiAgICAvLyBjb25zdCBya1dyYXBwZWRSZXNwb25kZXJTaWdQcmsgPSBhd2FpdCB0aGlzLmVuY3J5cHQocm9vdEtleSwgcmVzcG9uZGVyU2lnUHJrLnRvSlNPTih0cnVlKSk7XG5cbiAgICAvLyBPcHRpb24gMjogUmVzcG9uZGVyIGFscmVhZHkgaGFzIGEgc2lnbmluZyBQcmtcbiAgICBjb25zdCByZXNwb25kZXJQcmsgPSBhd2FpdCB0aGlzLmtleVNlcnZpY2UuZ2V0Q3VycmVudFB4aygpO1xuICAgIGNvbnN0IHJlc3BvbmRlclNpZ1ByayA9IGF3YWl0IHRoaXMua2V5U2VydmljZS5nZXRDdXJyZW50U2lnUHhrKCk7XG5cbiAgICBjb25zdCBzaWduZWRJbml0aWF0b3JQYmsgPSBhd2FpdCB0aGlzLmVuY3J5cHRpb25TZXJ2aWNlLnNpZ24oXG4gICAgICByZXNwb25kZXJTaWdQcmsuandrLFxuICAgICAgaW5pdGlhdG9yUGJrLnRvSlNPTigpXG4gICAgKTtcbiAgICBjb25zdCBzaWduZWRJbml0aWF0b3JTaWdQYmsgPSBhd2FpdCB0aGlzLmVuY3J5cHRpb25TZXJ2aWNlLnNpZ24oXG4gICAgICByZXNwb25kZXJTaWdQcmsuandrLFxuICAgICAgaW5pdGlhdG9yU2lnUGJrLnRvSlNPTigpXG4gICAgKTtcblxuICAgIGNvbnN0IHBsYWluSW5pdGlhdG9yT25lVGltZVBia0NpcGhlcjogUGxhaW5Jbml0aWF0b3JPbmVUaW1lUGJrQ2lwaGVyID0ge1xuICAgICAgbm9uY2U6IGRlY3J5cHRlZE90ay5wbGFpbk90S2V5Q2lwaGVyLm5vbmNlLFxuICAgICAgc2hhcmVkS2V5OiBzaGFyZWRLZXkudG9KU09OKHRydWUpLFxuICAgICAgbWtTaGFyZWRLZXk6IG1rU2hhcmVkS2V5LnRvSlNPTih0cnVlKSxcbiAgICAgIHJlc3BvbmRlcjoge1xuICAgICAgICBwYms6IHJlc3BvbmRlclByay5qd2sudG9KU09OKCksIC8vIHB1YmxpYyBrZXlcbiAgICAgICAgc2lnUGJrOiByZXNwb25kZXJTaWdQcmsuandrLnRvSlNPTigpLCAvLyBwdWJsaWMga2V5XG4gICAgICAgIHByb2ZpbGU6IHtcbiAgICAgICAgICB1c2VybmFtZTogdXNlci51c2VybmFtZSxcbiAgICAgICAgfSxcbiAgICAgICAgbWVzc2FnZSxcbiAgICAgIH0sXG4gICAgfTtcblxuICAgIGxldCByZWNlaXZlZENhcmRJbnB1dDtcbiAgICBpZiAoZGVjcnlwdGVkT3RrLnBsYWluT3RLZXlDaXBoZXIuaW5pdGlhdG9yLmNvbnRhY3RDYXJkKSB7XG4gICAgICAvLyBTZXQgdGhlIGluZm8gYWJvdXQgdGhlIGluaXRpYXRvciB0byBiZSB0aGUgb25lcyBzZW50IGJ5IHRoZSBpbml0aWF0b3IuIFdlIG5lZWQgdGggcmVzcG9uZGVyIHRvIGRvIHRoZSBlbmNyeXB0aW9uIGhlcmVcbiAgICAgIC8vIGJlY2F1c2UgdGhlIGluaXRpYXRvciBkb2VzIG5vdCBoYXZlIHRoZSBzaGFyZWQga2V5IHlldCwgYW5kIHdlIHdhbnQgdGhlIHJlc3BvbmRlciB0byBoYXZlIGEgZnVuY3Rpb25hbCBjb250YWN0IGNhcmQgYWZ0ZXJcbiAgICAgIC8vIHRoaXMgZXhjaGFuZ2UuIFRoZSBpbml0aWF0b3IgY2FuIGRvdWJsZSBjaGVjayB0aGUgY29udGFjdCBkZXRhaWxzIGFyZSBjb3JyZWN0IGFuZCBzaWduIGl0IHdoZW4gaXQgY29tcGxldGVzIHRoZSBleGNoYW5nZS5cbiAgICAgIGNvbnN0IHBsYWluU2hhcmVkQ2lwaGVyRGF0YUpzb24gPVxuICAgICAgICBkZWNyeXB0ZWRPdGsucGxhaW5PdEtleUNpcGhlci5pbml0aWF0b3IuY29udGFjdENhcmRcbiAgICAgICAgICAucGxhaW5TaGFyZWRDaXBoZXJEYXRhSnNvbjtcblxuICAgICAgLy8gQ3JlYXRlIGtleXNcbiAgICAgIGNvbnN0IHJlY2VpdmVyS2V5ID0gYXdhaXQgdGhpcy5rZXlGYWN0b3J5LmNyZWF0ZUtleSgpO1xuICAgICAgY29uc3QgY2NTaGFyZWRLZXkgPSBhd2FpdCB0aGlzLmtleUZhY3RvcnkuY3JlYXRlS2V5KCk7XG4gICAgICBjb25zdCBzaWdQeGsgPSBhd2FpdCB0aGlzLmtleVNlcnZpY2UuZ2V0Q3VycmVudFNpZ1B4aygpO1xuXG4gICAgICByZWNlaXZlZENhcmRJbnB1dCA9IHtcbiAgICAgICAgcmVjZWl2ZXJXcmFwcGVkS2V5OiBKU09OLnN0cmluZ2lmeShcbiAgICAgICAgICBhd2FpdCB0aGlzLmVuY3J5cHRpb25TZXJ2aWNlLmVuY3J5cHQoXG4gICAgICAgICAgICByb290S2V5Lmp3ayxcbiAgICAgICAgICAgIHJlY2VpdmVyS2V5LnRvSlNPTih0cnVlKVxuICAgICAgICAgIClcbiAgICAgICAgKSxcbiAgICAgICAgcmVjZWl2ZXJXcmFwcGluZ0tleUlkOiByb290S2V5LmlkLFxuICAgICAgICByZWNlaXZlckNpcGhlckRhdGE6IGluaXRpYXRvckNvbnRhY3RDYXJkXG4gICAgICAgICAgPyBKU09OLnN0cmluZ2lmeShcbiAgICAgICAgICAgICAgYXdhaXQgdGhpcy5lbmNyeXB0aW9uU2VydmljZS5lbmNyeXB0KFxuICAgICAgICAgICAgICAgIHJlY2VpdmVyS2V5LFxuICAgICAgICAgICAgICAgIGluaXRpYXRvckNvbnRhY3RDYXJkLnBsYWluUmVjZWl2ZXJDaXBoZXJEYXRhSnNvblxuICAgICAgICAgICAgICApXG4gICAgICAgICAgICApXG4gICAgICAgICAgOiAnJyxcbiAgICAgICAgc2hhcmVkV3JhcHBlZEtleTogSlNPTi5zdHJpbmdpZnkoXG4gICAgICAgICAgYXdhaXQgdGhpcy5lbmNyeXB0aW9uU2VydmljZS5lbmNyeXB0KFxuICAgICAgICAgICAgc2hhcmVkS2V5LFxuICAgICAgICAgICAgY2NTaGFyZWRLZXkudG9KU09OKHRydWUpXG4gICAgICAgICAgKVxuICAgICAgICApLFxuICAgICAgfTtcblxuICAgICAgY29uc3Qgc2hhcmVkQ2lwaGVyRGF0YSA9IGF3YWl0IHRoaXMuZW5jcnlwdGlvblNlcnZpY2UuZW5jcnlwdChcbiAgICAgICAgY2NTaGFyZWRLZXksXG4gICAgICAgIHBsYWluU2hhcmVkQ2lwaGVyRGF0YUpzb25cbiAgICAgICk7XG4gICAgICByZWNlaXZlZENhcmRJbnB1dC5zaGFyZWRDaXBoZXJEYXRhU2lnID0gSlNPTi5zdHJpbmdpZnkoXG4gICAgICAgIGF3YWl0IHRoaXMuZW5jcnlwdGlvblNlcnZpY2Uuc2lnbihzaWdQeGsuandrLCBzaGFyZWRDaXBoZXJEYXRhKVxuICAgICAgKTtcbiAgICAgIHJlY2VpdmVkQ2FyZElucHV0LnNpZ1B4a0lkID0gc2lnUHhrLmlkO1xuXG4gICAgICBwbGFpbkluaXRpYXRvck9uZVRpbWVQYmtDaXBoZXIucmVzcG9uZGVyLmNvbnRhY3RDYXJkID0ge1xuICAgICAgICAuLi5wbGFpbkluaXRpYXRvck9uZVRpbWVQYmtDaXBoZXIucmVzcG9uZGVyLmNvbnRhY3RDYXJkLFxuICAgICAgICBzaGFyZWRDaXBoZXJLZXk6IGNjU2hhcmVkS2V5LnRvSlNPTih0cnVlKSxcbiAgICAgIH07XG4gICAgfVxuXG4gICAgbGV0IHNlbnRDYXJkSW5wdXQ7XG4gICAgaWYgKHNlbnRDb250YWN0Q2FyZCkge1xuICAgICAgLy8gQ3JlYXRlIGtleXNcbiAgICAgIGNvbnN0IG93bmVyS2V5ID0gYXdhaXQgdGhpcy5rZXlGYWN0b3J5LmNyZWF0ZUtleSgpO1xuICAgICAgY29uc3QgY2NTaGFyZWRLZXkgPSBhd2FpdCB0aGlzLmtleUZhY3RvcnkuY3JlYXRlS2V5KCk7XG4gICAgICBjb25zdCBzaWdQeGsgPSBhd2FpdCB0aGlzLmtleVNlcnZpY2UuZ2V0Q3VycmVudFNpZ1B4aygpO1xuXG4gICAgICBzZW50Q2FyZElucHV0ID0ge1xuICAgICAgICBvd25lcldyYXBwZWRLZXk6IEpTT04uc3RyaW5naWZ5KFxuICAgICAgICAgIGF3YWl0IHRoaXMuZW5jcnlwdGlvblNlcnZpY2UuZW5jcnlwdChcbiAgICAgICAgICAgIHJvb3RLZXkuandrLFxuICAgICAgICAgICAgb3duZXJLZXkudG9KU09OKHRydWUpXG4gICAgICAgICAgKVxuICAgICAgICApLFxuICAgICAgICBvd25lcldyYXBwaW5nS2V5SWQ6IHJvb3RLZXkuaWQsXG4gICAgICAgIG93bmVyQ2lwaGVyRGF0YTogc2VudENvbnRhY3RDYXJkLnBsYWluT3duZXJDaXBoZXJEYXRhSnNvblxuICAgICAgICAgID8gSlNPTi5zdHJpbmdpZnkoXG4gICAgICAgICAgICAgIGF3YWl0IHRoaXMuZW5jcnlwdGlvblNlcnZpY2UuZW5jcnlwdChcbiAgICAgICAgICAgICAgICBvd25lcktleSxcbiAgICAgICAgICAgICAgICBzZW50Q29udGFjdENhcmQucGxhaW5Pd25lckNpcGhlckRhdGFKc29uXG4gICAgICAgICAgICAgIClcbiAgICAgICAgICAgIClcbiAgICAgICAgICA6ICcnLFxuXG4gICAgICAgIHNoYXJlZFdyYXBwZWRLZXk6IEpTT04uc3RyaW5naWZ5KFxuICAgICAgICAgIGF3YWl0IHRoaXMuZW5jcnlwdGlvblNlcnZpY2UuZW5jcnlwdChcbiAgICAgICAgICAgIHNoYXJlZEtleSxcbiAgICAgICAgICAgIGNjU2hhcmVkS2V5LnRvSlNPTih0cnVlKVxuICAgICAgICAgIClcbiAgICAgICAgKSxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHNoYXJlZENpcGhlckRhdGEgPSBhd2FpdCB0aGlzLmVuY3J5cHRpb25TZXJ2aWNlLmVuY3J5cHQoXG4gICAgICAgIGNjU2hhcmVkS2V5LFxuICAgICAgICBzZW50Q29udGFjdENhcmQucGxhaW5TaGFyZWRDaXBoZXJEYXRhSnNvblxuICAgICAgKTtcbiAgICAgIHNlbnRDYXJkSW5wdXQuc2hhcmVkQ2lwaGVyRGF0YVNpZyA9IEpTT04uc3RyaW5naWZ5KFxuICAgICAgICBhd2FpdCB0aGlzLmVuY3J5cHRpb25TZXJ2aWNlLnNpZ24oc2lnUHhrLmp3aywgc2hhcmVkQ2lwaGVyRGF0YSlcbiAgICAgICk7XG4gICAgICBzZW50Q2FyZElucHV0LnNpZ1B4a0lkID0gc2lnUHhrLmlkO1xuXG4gICAgICBpZiAoc2VudENvbnRhY3RDYXJkLm93bmVyUGxhaW5EYXRhKSB7XG4gICAgICAgIHNlbnRDYXJkSW5wdXQub3duZXJQbGFpbkRhdGFTaWcgPSBKU09OLnN0cmluZ2lmeShcbiAgICAgICAgICBhd2FpdCB0aGlzLmVuY3J5cHRpb25TZXJ2aWNlLnNpZ24oXG4gICAgICAgICAgICByZXNwb25kZXJTaWdQcmsuandrLFxuICAgICAgICAgICAgc2VudENvbnRhY3RDYXJkLm93bmVyUGxhaW5EYXRhXG4gICAgICAgICAgKVxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICAvLyBDb250YWN0IGNhcmQgaW5mbyByZWFkYWJsZSBieSB0aGUgaW5pdGlhdG9yXG4gICAgICBwbGFpbkluaXRpYXRvck9uZVRpbWVQYmtDaXBoZXIucmVzcG9uZGVyLmNvbnRhY3RDYXJkID0ge1xuICAgICAgICAuLi5wbGFpbkluaXRpYXRvck9uZVRpbWVQYmtDaXBoZXIucmVzcG9uZGVyLmNvbnRhY3RDYXJkLFxuICAgICAgICBwbGFpblNoYXJlZENpcGhlckRhdGFKc29uOiBzZW50Q29udGFjdENhcmQucGxhaW5TaGFyZWRDaXBoZXJEYXRhSnNvbixcbiAgICAgIH07XG4gICAgfVxuXG4gICAgLy8gRW5jcnlwdCB3aXRoIG9uZS10aW1lIHB1YmxpYyBrZXlcbiAgICBsZXQgaW5pdGlhdG9yT25lVGltZVBia0NpcGhlciA9IGF3YWl0IHRoaXMuZW5jcnlwdGlvblNlcnZpY2UuZW5jcnlwdChcbiAgICAgIGluaXRpYXRvck9uZVRpbWVQYmssXG4gICAgICBwbGFpbkluaXRpYXRvck9uZVRpbWVQYmtDaXBoZXJcbiAgICApO1xuXG4gICAgLy8gRW5jcnlwdCB3aXRoIHRoZSBvdGsgYWdhaW4gdG8ga2VlcCB1c2Ugb2YgYXN5bW1ldHJpYyBrZXlzIHRvIGEgbWluaW11bS5cbiAgICBpbml0aWF0b3JPbmVUaW1lUGJrQ2lwaGVyID0gYXdhaXQgdGhpcy5lbmNyeXB0aW9uU2VydmljZS5lbmNyeXB0KFxuICAgICAgZGVjcnlwdGVkT3RrLm90S2V5LFxuICAgICAgaW5pdGlhdG9yT25lVGltZVBia0NpcGhlclxuICAgICk7XG5cbiAgICBjb25zdCB7IHJlc3BvbmRLZXlFeGNoYW5nZU90ayB9ID0gYXdhaXQgdGhpcy5sckFwb2xsby5tdXRhdGU8YW55Pih7XG4gICAgICBtdXRhdGlvbjogUmVzcG9uZE90a011dGF0aW9uLFxuICAgICAgdmFyaWFibGVzOiB7XG4gICAgICAgIGlucHV0OiB7XG4gICAgICAgICAga2V5RXhjaGFuZ2VJZDogaWQsXG4gICAgICAgICAga2V5RXhjaGFuZ2VUb2tlbjogdG9rZW4sXG4gICAgICAgICAgcm9vdEtleUlkOiByb290S2V5LmlkLFxuICAgICAgICAgIG1hc3RlcktleUlkLFxuICAgICAgICAgIC8vIFRoZXNlIHdpbGwgYmUgc3RvcmVkIG9uIHRoZSBzZXJ2ZXJcbiAgICAgICAgICByZXNwb25kZXJQeGtJZDogcmVzcG9uZGVyUHJrLmlkLFxuICAgICAgICAgIHJlc3BvbmRlclNpZ1B4a0lkOiByZXNwb25kZXJTaWdQcmsuaWQsXG4gICAgICAgICAgc2lnbmVkSW5pdGlhdG9yUGJrOiBKU09OLnN0cmluZ2lmeShzaWduZWRJbml0aWF0b3JQYmspLFxuICAgICAgICAgIHNpZ25lZEluaXRpYXRvclNpZ1BiazogSlNPTi5zdHJpbmdpZnkoc2lnbmVkSW5pdGlhdG9yU2lnUGJrKSxcbiAgICAgICAgICAvLyBya1dyYXBwZWRJbml0aWF0b3JTaWdQYms6IEpTT04uc3RyaW5naWZ5KHJrV3JhcHBlZEluaXRpYXRvclNpZ1BiayksXG5cbiAgICAgICAgICAvLyBPcHRpb24gMTogVXNpbmcgbmV3IFByayBmb3IgZWFjaCBUUCBwYWlyXG4gICAgICAgICAgLy8gcmtXcmFwcGVkUmVzcG9uZGVyU2lnUHJrOiBKU09OLnN0cmluZ2lmeShya1dyYXBwZWRSZXNwb25kZXJTaWdQcmspLFxuICAgICAgICAgIHJrV3JhcHBlZFNoYXJlZEtleTogSlNPTi5zdHJpbmdpZnkocmtXcmFwcGVkU2hhcmVkS2V5KSxcbiAgICAgICAgICBta1dyYXBwZWRNa1NoYXJlZEtleTogSlNPTi5zdHJpbmdpZnkobWtXcmFwcGVkTWtTaGFyZWRLZXkpLFxuICAgICAgICAgIC8vIFRoZXNlIHdpbGwgYmUgc2VudCB0byB0aGUgaW5pdGlhdG9yXG4gICAgICAgICAgaW5pdGlhdG9yT25lVGltZVBia0NpcGhlcjogSlNPTi5zdHJpbmdpZnkoaW5pdGlhdG9yT25lVGltZVBia0NpcGhlciksXG4gICAgICAgICAgaW5pdGlhdG9yQ29udGFjdENhcmQ6IHJlY2VpdmVkQ2FyZElucHV0LFxuICAgICAgICAgIHJlc3BvbmRlckNvbnRhY3RDYXJkOiBzZW50Q2FyZElucHV0LFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9KTtcblxuICAgIHJldHVybiB7XG4gICAgICBrZXlFeGNoYW5nZTogcmVzcG9uZEtleUV4Y2hhbmdlT3RrLmtleUV4Y2hhbmdlLFxuICAgICAgdXNlclNoYXJlZEtleTogcmVzcG9uZEtleUV4Y2hhbmdlT3RrLnVzZXJTaGFyZWRLZXksXG4gICAgICB0cDogcmVzcG9uZEtleUV4Y2hhbmdlT3RrLnRwLFxuICAgIH07XG4gIH1cblxuICBhc3luYyBjb21wbGV0ZU90ayhcbiAgICBrZXlFeGNoYW5nZUlkOiBzdHJpbmcsXG4gICAgaW5pdGlhdG9yUm9vdEtleUNpcGhlcjogc3RyaW5nLFxuICAgIGluaXRpYXRvck9uZVRpbWVQYmtDaXBoZXI6IHN0cmluZyxcbiAgICByZXNwb25kZXJDb250YWN0Q2FyZD86IHN0cmluZ1xuICApOiBQcm9taXNlPENvbXBsZXRlT3RrPiB7XG4gICAgY29uc3Qgcm9vdEtleSA9IGF3YWl0IHRoaXMua2V5U2VydmljZS5nZXRDdXJyZW50Um9vdEtleSgpO1xuICAgIGNvbnN0IG1hc3RlcktleSA9IGF3YWl0IHRoaXMua2V5U2VydmljZS5nZXRDdXJyZW50TWFzdGVyS2V5KCk7XG5cbiAgICAvLyBEZWNyeXB0IHVzaW5nIHRoZSByb290IGtleSB0byBnZXQgdGhlIFBya1xuICAgIGNvbnN0IHBsYWluSW5pdGlhdG9yUm9vdEtleUNpcGhlciA9ICgoYXdhaXQgdGhpcy5lbmNyeXB0aW9uU2VydmljZS5kZWNyeXB0KFxuICAgICAgcm9vdEtleS5qd2ssXG4gICAgICBpbml0aWF0b3JSb290S2V5Q2lwaGVyXG4gICAgKSkgYXMgdW5rbm93bikgYXMgUGxhaW5Jbml0aWF0b3JSb290S2V5Q2lwaGVyO1xuXG4gICAgLy8gVGhlIFByayBpcyBzaW5nbGUtdXNlIGFuZCBvbmx5IHVzZWQgdG8gc2VuZCBpbmZvcm1hdGlvbiBmcm9tIHRoZSByZXNwb25kZXIgYmFjayB0byB0aGUgaW5pdGlhdG9yLlxuICAgIGNvbnN0IHBsYWluSW5pdGlhdG9yT25lVGltZVBia0NpcGhlciA9IGF3YWl0IHRoaXMuZGVjcnlwdFJlc3BvbnNlQ2lwaGVyKFxuICAgICAgYXdhaXQgS0ZTLmFzS2V5KHBsYWluSW5pdGlhdG9yUm9vdEtleUNpcGhlci5vdEtleSksXG4gICAgICBhd2FpdCBLRlMuYXNLZXkocGxhaW5Jbml0aWF0b3JSb290S2V5Q2lwaGVyLm9uZVRpbWVQcmspLFxuICAgICAgaW5pdGlhdG9yT25lVGltZVBia0NpcGhlclxuICAgICk7XG5cbiAgICAvLyBDaGVjayB0aGUgbm9uY2UgbWF0Y2ggdG8gZW5zdXJlIHRoZSByZXNwb25kZXIgd2FzIHRoZSBvbmUgaG9sZGluZyB0aGUgT1RLXG4gICAgaWYgKFxuICAgICAgcGxhaW5Jbml0aWF0b3JSb290S2V5Q2lwaGVyLm5vbmNlICE9PSBwbGFpbkluaXRpYXRvck9uZVRpbWVQYmtDaXBoZXIubm9uY2VcbiAgICApIHtcbiAgICAgIHRocm93IG5ldyBMckNvZGVNaXNtYXRjaEV4Y2VwdGlvbihcbiAgICAgICAgJ1RoZSBub25jZSByZXR1cm5lZCBieSByZXNwb25kZXIgZG9lcyBub3QgbWF0Y2ggd2l0aCB0aGUgb25lIGNyZWF0ZWQgYnkgdGhlIGluaXRpYXRvci4nXG4gICAgICApO1xuICAgIH1cblxuICAgIC8vIE9wdGlvbiAxOiBBc3N1bWluZyB0aGUgc2lnbmluZyBrZXkgaXMgdW5pcXVlIGJldHdlZW4gdXNlcnMuXG4gICAgLy8gY29uc3QgaW5pdGlhdG9yU2lnUHJrID0gYXdhaXQgS0ZTLmFzS2V5KGtlLnBsYWluSW5pdGlhdG9yUm9vdEtleUNpcGhlci5zaWdQcmspO1xuICAgIC8vIGNvbnN0IHJrV3JhcHBlZEluaXRpYXRvclNpZ1ByayA9IGF3YWl0IHRoaXMuZW5jcnlwdChyb290S2V5LCBpbml0aWF0b3JTaWdQcmsudG9KU09OKHRydWUpKTtcblxuICAgIC8vIE9wdGlvbiAyOiBVc2UgdGhlIHVzZXIncyBnbG9iYWwgc2lnbmluZyBrZXkuXG4gICAgLy8gSW4gdGhpcyBjYXNlIHRoZSBpbml0aWF0b3JTaWdQcmsgaXMgYWxyZWFkeSBhIHBhcnQgb2YgdGhlIGtleSBncmFwaC5cbiAgICAvLyBTbyB0aGVyZSdzIG5vdGhpbmcgdG8gZG8gaGVyZS5cblxuICAgIC8vIFByb3RlY3RlZCB0aGUgc2lnbmluZyBwdWJsaWMga2V5IG9mIHRoZSByZXNwb25kZXIuXG4gICAgY29uc3QgaW5pdGlhdG9yU2lnUHJrID0gYXdhaXQgdGhpcy5rZXlTZXJ2aWNlLmdldEN1cnJlbnRTaWdQeGsoKTtcbiAgICBjb25zdCByZXNwb25kZXJTaWdQYmsgPSBhd2FpdCBLRlMuYXNLZXkoXG4gICAgICBwbGFpbkluaXRpYXRvck9uZVRpbWVQYmtDaXBoZXIucmVzcG9uZGVyLnNpZ1Bia1xuICAgICk7XG4gICAgY29uc3QgcmVzcG9uZGVyUGJrID0gYXdhaXQgS0ZTLmFzS2V5KFxuICAgICAgcGxhaW5Jbml0aWF0b3JPbmVUaW1lUGJrQ2lwaGVyLnJlc3BvbmRlci5wYmtcbiAgICApO1xuXG4gICAgY29uc3Qgc2lnbmVkUmVzcG9uZGVyUGJrID0gYXdhaXQgdGhpcy5lbmNyeXB0aW9uU2VydmljZS5zaWduKFxuICAgICAgaW5pdGlhdG9yU2lnUHJrLmp3ayxcbiAgICAgIHJlc3BvbmRlclBiay50b0pTT04oKVxuICAgICk7XG4gICAgY29uc3Qgc2lnbmVkUmVzcG9uZGVyU2lnUGJrID0gYXdhaXQgdGhpcy5lbmNyeXB0aW9uU2VydmljZS5zaWduKFxuICAgICAgaW5pdGlhdG9yU2lnUHJrLmp3ayxcbiAgICAgIHJlc3BvbmRlclNpZ1Biay50b0pTT04oKVxuICAgICk7XG5cbiAgICBjb25zdCBzaGFyZWRLZXkgPSBhd2FpdCBLRlMuYXNLZXkocGxhaW5Jbml0aWF0b3JPbmVUaW1lUGJrQ2lwaGVyLnNoYXJlZEtleSk7XG4gICAgY29uc3QgcmtXcmFwcGVkU2hhcmVkS2V5ID0gYXdhaXQgdGhpcy5lbmNyeXB0aW9uU2VydmljZS5lbmNyeXB0KFxuICAgICAgcm9vdEtleS5qd2ssXG4gICAgICBzaGFyZWRLZXkudG9KU09OKHRydWUpXG4gICAgKTtcblxuICAgIGNvbnN0IG1rU2hhcmVkS2V5ID0gYXdhaXQgS0ZTLmFzS2V5KFxuICAgICAgcGxhaW5Jbml0aWF0b3JPbmVUaW1lUGJrQ2lwaGVyLm1rU2hhcmVkS2V5XG4gICAgKTtcbiAgICBjb25zdCBta1dyYXBwZWRNa1NoYXJlZEtleSA9IGF3YWl0IHRoaXMuZW5jcnlwdGlvblNlcnZpY2UuZW5jcnlwdChcbiAgICAgIG1hc3RlcktleS5qd2ssXG4gICAgICBta1NoYXJlZEtleS50b0pTT04odHJ1ZSlcbiAgICApO1xuXG4gICAgbGV0IHJlc3BvbmRlckNvbnRhY3RDYXJkQ2lwaGVySW5wdXQ7XG4gICAgaWYgKHJlc3BvbmRlckNvbnRhY3RDYXJkKSB7XG4gICAgICAvLyBDcmVhdGUga2V5XG4gICAgICBjb25zdCByZWNlaXZlcktleSA9IGF3YWl0IHRoaXMua2V5RmFjdG9yeS5jcmVhdGVLZXkoKTtcblxuICAgICAgcmVzcG9uZGVyQ29udGFjdENhcmRDaXBoZXJJbnB1dCA9IHtcbiAgICAgICAgcmVjZWl2ZXJXcmFwcGVkS2V5OiBKU09OLnN0cmluZ2lmeShcbiAgICAgICAgICBhd2FpdCB0aGlzLmVuY3J5cHRpb25TZXJ2aWNlLmVuY3J5cHQoXG4gICAgICAgICAgICByb290S2V5Lmp3ayxcbiAgICAgICAgICAgIHJlY2VpdmVyS2V5LnRvSlNPTih0cnVlKVxuICAgICAgICAgIClcbiAgICAgICAgKSxcbiAgICAgICAgcmVjZWl2ZXJXcmFwcGluZ0tleUlkOiByb290S2V5LmlkLFxuICAgICAgICByZWNlaXZlckNpcGhlckRhdGE6IEpTT04uc3RyaW5naWZ5KFxuICAgICAgICAgIGF3YWl0IHRoaXMuZW5jcnlwdGlvblNlcnZpY2UuZW5jcnlwdChcbiAgICAgICAgICAgIHJlY2VpdmVyS2V5LFxuICAgICAgICAgICAgcmVzcG9uZGVyQ29udGFjdENhcmRcbiAgICAgICAgICApXG4gICAgICAgICksXG4gICAgICB9O1xuICAgIH1cblxuICAgIC8vIEdldCB0aGUgZGF0YSBuZWVkZWQgZnJvbSB0aGUgaW5pdGlhdG9yJ3MgY2lwaGVyIGRhdGEuXG4gICAgbGV0IGluaXRpYXRvckNvbnRhY3RDYXJkQ2lwaGVySW5wdXQ7XG4gICAgbGV0IGluaXRpYXRvckNvbnRhY3RDYXJkU2hhcmVkQ2lwaGVySW5wdXQ7XG4gICAgaWYgKHBsYWluSW5pdGlhdG9yUm9vdEtleUNpcGhlci5pbml0aWF0b3JDb250YWN0Q2FyZCkge1xuICAgICAgY29uc3QgaW5pdGlhdG9yQ29udGFjdENhcmQgPVxuICAgICAgICBwbGFpbkluaXRpYXRvclJvb3RLZXlDaXBoZXIuaW5pdGlhdG9yQ29udGFjdENhcmQ7XG4gICAgICBjb25zdCBvd25lcktleSA9IGF3YWl0IHRoaXMua2V5RmFjdG9yeS5jcmVhdGVLZXkoKTtcbiAgICAgIGNvbnN0IHNoYXJlZENpcGhlcktleSA9IGF3YWl0IEtGUy5hc0tleShcbiAgICAgICAgcGxhaW5Jbml0aWF0b3JPbmVUaW1lUGJrQ2lwaGVyLnJlc3BvbmRlci5jb250YWN0Q2FyZC5zaGFyZWRDaXBoZXJLZXlcbiAgICAgICk7XG5cbiAgICAgIGNvbnN0IG93bmVyV3JhcHBlZEtleSA9IEpTT04uc3RyaW5naWZ5KFxuICAgICAgICBhd2FpdCB0aGlzLmVuY3J5cHRpb25TZXJ2aWNlLmVuY3J5cHQocm9vdEtleS5qd2ssIG93bmVyS2V5LnRvSlNPTih0cnVlKSlcbiAgICAgICk7XG4gICAgICBjb25zdCBvd25lckNpcGhlckRhdGEgPSBpbml0aWF0b3JDb250YWN0Q2FyZC5wbGFpbk93bmVyQ2lwaGVyRGF0YUpzb25cbiAgICAgICAgPyBKU09OLnN0cmluZ2lmeShcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuZW5jcnlwdGlvblNlcnZpY2UuZW5jcnlwdChcbiAgICAgICAgICAgICAgb3duZXJLZXksXG4gICAgICAgICAgICAgIGluaXRpYXRvckNvbnRhY3RDYXJkLnBsYWluT3duZXJDaXBoZXJEYXRhSnNvblxuICAgICAgICAgICAgKVxuICAgICAgICAgIClcbiAgICAgICAgOiAnJztcblxuICAgICAgaW5pdGlhdG9yQ29udGFjdENhcmRDaXBoZXJJbnB1dCA9IHtcbiAgICAgICAgb3duZXJXcmFwcGVkS2V5LFxuICAgICAgICBvd25lcldyYXBwaW5nS2V5SWQ6IHJvb3RLZXkuaWQsXG4gICAgICAgIG93bmVyQ2lwaGVyRGF0YSxcbiAgICAgIH07XG5cbiAgICAgIGluaXRpYXRvckNvbnRhY3RDYXJkU2hhcmVkQ2lwaGVySW5wdXQgPSB7XG4gICAgICAgIHNpZ1B4a0lkOiBpbml0aWF0b3JTaWdQcmsuaWQsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBzaGFyZWRDaXBoZXJEYXRhID0gYXdhaXQgdGhpcy5lbmNyeXB0aW9uU2VydmljZS5lbmNyeXB0KFxuICAgICAgICBzaGFyZWRDaXBoZXJLZXksXG4gICAgICAgIGluaXRpYXRvckNvbnRhY3RDYXJkLnBsYWluU2hhcmVkQ2lwaGVyRGF0YUpzb25cbiAgICAgICk7XG4gICAgICBpbml0aWF0b3JDb250YWN0Q2FyZFNoYXJlZENpcGhlcklucHV0LnNoYXJlZENpcGhlckRhdGFTaWcgPSBKU09OLnN0cmluZ2lmeShcbiAgICAgICAgYXdhaXQgdGhpcy5lbmNyeXB0aW9uU2VydmljZS5zaWduKGluaXRpYXRvclNpZ1Byay5qd2ssIHNoYXJlZENpcGhlckRhdGEpXG4gICAgICApO1xuICAgIH1cblxuICAgIC8vIFRPRE8gaWRlYWxseSB3ZSB1cGRhdGUgdGhlIHNoYXJlZCBkYXRhIGluIHRoZSBjb250YWN0IGNhcmQgc2VudCB0byB0aGUgcmVzcG9uZGVyIGFzIHdlbGwgc2luY2UgdGhhdFxuICAgIC8vIENDIHdhcyBjcmVhdGVkIGJ5IHRoZSByZXNwb25kZXIuXG5cbiAgICBjb25zdCByZXMgPSBhd2FpdCB0aGlzLmxyQXBvbGxvLm11dGF0ZTxhbnk+KHtcbiAgICAgIG11dGF0aW9uOiBDb21wbGV0ZU90a011dGF0aW9uLFxuICAgICAgdmFyaWFibGVzOiB7XG4gICAgICAgIGlucHV0OiB7XG4gICAgICAgICAga2V5RXhjaGFuZ2VJZCxcbiAgICAgICAgICByb290S2V5SWQ6IHJvb3RLZXkuaWQsXG4gICAgICAgICAgbWFzdGVyS2V5SWQ6IG1hc3RlcktleS5pZCxcbiAgICAgICAgICBpbml0aWF0b3JTaWdQeGtJZDogaW5pdGlhdG9yU2lnUHJrLmlkLFxuICAgICAgICAgIHNpZ25lZFJlc3BvbmRlclBiazogSlNPTi5zdHJpbmdpZnkoc2lnbmVkUmVzcG9uZGVyUGJrKSxcbiAgICAgICAgICBzaWduZWRSZXNwb25kZXJTaWdQYms6IEpTT04uc3RyaW5naWZ5KHNpZ25lZFJlc3BvbmRlclNpZ1BiayksXG4gICAgICAgICAgcmtXcmFwcGVkU2hhcmVkS2V5OiBKU09OLnN0cmluZ2lmeShya1dyYXBwZWRTaGFyZWRLZXkpLFxuICAgICAgICAgIG1rV3JhcHBlZE1rU2hhcmVkS2V5OiBKU09OLnN0cmluZ2lmeShta1dyYXBwZWRNa1NoYXJlZEtleSksXG4gICAgICAgICAgcmVzcG9uZGVyQ29udGFjdENhcmRDaXBoZXI6IHJlc3BvbmRlckNvbnRhY3RDYXJkQ2lwaGVySW5wdXQsXG4gICAgICAgICAgaW5pdGlhdG9yQ29udGFjdENhcmRDaXBoZXI6IGluaXRpYXRvckNvbnRhY3RDYXJkQ2lwaGVySW5wdXQsXG4gICAgICAgICAgaW5pdGlhdG9yQ29udGFjdENhcmRTaGFyZWRDaXBoZXI6IGluaXRpYXRvckNvbnRhY3RDYXJkU2hhcmVkQ2lwaGVySW5wdXQsXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIH0pO1xuICAgIHJldHVybiByZXMuY29tcGxldGVLZXlFeGNoYW5nZU90aztcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBjdXJyZW50VXNlclNoYXJlZEtleShpbnB1dDoge1xuICAgIHVzZXJuYW1lPzogc3RyaW5nO1xuICAgIHVzZXJJZD86IHN0cmluZztcbiAgfSk6IFByb21pc2U8VXNlclNoYXJlZEtleT4ge1xuICAgIGNvbnN0IHsgY3VycmVudFVzZXJTaGFyZWRLZXkgfSA9IGF3YWl0IHRoaXMubHJBcG9sbG8ucXVlcnk8YW55Pih7XG4gICAgICBxdWVyeTogQ3VycmVudFVzZXJTaGFyZWRLZXlRdWVyeSxcbiAgICAgIHZhcmlhYmxlczoge1xuICAgICAgICB1c2VybmFtZTogaW5wdXQudXNlcm5hbWUsXG4gICAgICAgIHVzZXJJZDogaW5wdXQudXNlcklkLFxuICAgICAgfSxcbiAgICB9KTtcbiAgICByZXR1cm4gY3VycmVudFVzZXJTaGFyZWRLZXkudXNlclNoYXJlZEtleTtcbiAgfVxufVxuIl19
1
+ import { __awaiter } from "tslib";
2
+ import { Injectable } from '@angular/core';
3
+ import { LifeReadyAuthService } from '../auth/life-ready-auth.service';
4
+ import { EncryptionService, JoseSerialization, } from '../cryptography/encryption.service';
5
+ import { KeyService } from '../cryptography/key.service';
6
+ import { LrCodeMismatchException } from '../_common/exceptions';
7
+ import { UserService } from './../users/user.service';
8
+ import { CompleteOtkMutation, CurrentUserSharedKeyQuery, InitiateOtkMutation, KeyExchangeQuery, KeyExchangesQuery, KeyExchangeTokenQuery, RespondOtkMutation, } from './key-exchange.gql';
9
+ import { OtkState, } from './key-exchange.types';
10
+ import { LrApolloService } from './lr-apollo.service';
11
+ import { KeyFactoryService as KFS } from '../cryptography/key-factory.service';
12
+ // Ref: https://stackoverflow.com/questions/59735280/angular-8-moment-error-cannot-call-a-namespace-moment
13
+ import * as moment_ from 'moment';
14
+ import * as i0 from "@angular/core";
15
+ import * as i1 from "../cryptography/key-factory.service";
16
+ import * as i2 from "../cryptography/key.service";
17
+ import * as i3 from "./lr-apollo.service";
18
+ import * as i4 from "../cryptography/encryption.service";
19
+ import * as i5 from "../auth/life-ready-auth.service";
20
+ import * as i6 from "../users/user.service";
21
+ const moment = moment_;
22
+ export class KeyExchangeService {
23
+ constructor(keyFactory, keyService, lrApollo, encryptionService, authService, userService) {
24
+ this.keyFactory = keyFactory;
25
+ this.keyService = keyService;
26
+ this.lrApollo = lrApollo;
27
+ this.encryptionService = encryptionService;
28
+ this.authService = authService;
29
+ this.userService = userService;
30
+ this.CLIENT_NONCE_LENGTH = 32;
31
+ }
32
+ getKeyExchangeList(input = {}) {
33
+ return __awaiter(this, void 0, void 0, function* () {
34
+ const { keyExchanges } = yield this.lrApollo.query({
35
+ query: KeyExchangesQuery,
36
+ variables: Object.assign({}, input),
37
+ });
38
+ return keyExchanges;
39
+ });
40
+ }
41
+ /**
42
+ * @param id If the current user can responder the key exchange if they are either the initiator or the receiver.
43
+ * @param token If not signed in, or not the initiator or responder, 'token' must be given.
44
+ * @param otKeyK Is the raw one-time key (string). If the responder is explicitly specified at time of initiation, then
45
+ * it's possible to have the otKey wrapped by the public key of the responder. In which case, the otKeyK is not needed.
46
+ */
47
+ getKeyExchange(id, { otKeyK, token } = {}) {
48
+ return __awaiter(this, void 0, void 0, function* () {
49
+ const { keyExchange } = yield this.lrApollo.query({
50
+ query: token ? KeyExchangeTokenQuery : KeyExchangeQuery,
51
+ variables: {
52
+ id,
53
+ token,
54
+ },
55
+ });
56
+ return yield this.decryptKeyExchange(keyExchange, otKeyK);
57
+ });
58
+ }
59
+ decryptResponseCipher(otKey, otPrk, content) {
60
+ return __awaiter(this, void 0, void 0, function* () {
61
+ // The response could be wrapped by the OtK as well as we the OtPrk
62
+ try {
63
+ content = yield this.encryptionService.decrypt(otKey, content);
64
+ }
65
+ catch (error) {
66
+ if (error.message !== 'no key found') {
67
+ throw error;
68
+ }
69
+ // Do nothing to support older versions where message is not wrapped with otk.
70
+ }
71
+ // The Prk is single-use and only used to send information from the responder back to the initiator.
72
+ return yield this.encryptionService.decrypt(otPrk, content);
73
+ });
74
+ }
75
+ decryptKeyExchange(keyExchange, otKeyK) {
76
+ return __awaiter(this, void 0, void 0, function* () {
77
+ if (keyExchange.isInitiator) {
78
+ const rootKey = yield this.keyService.getCurrentRootKey();
79
+ // Decrypt using the root key to get the Prk
80
+ const plainInitiatorRootKeyCipher = (yield this.encryptionService.decrypt(rootKey.jwk, keyExchange.initiatorRootKeyCipher));
81
+ const plainInitiatorOneTimePbkCipher = keyExchange.otk
82
+ .initiatorOneTimePbkCipher
83
+ ? yield this.decryptResponseCipher(yield KFS.asKey(plainInitiatorRootKeyCipher.otKey), yield KFS.asKey(plainInitiatorRootKeyCipher.oneTimePrk), keyExchange.otk.initiatorOneTimePbkCipher)
84
+ : null;
85
+ const responder = plainInitiatorOneTimePbkCipher &&
86
+ plainInitiatorOneTimePbkCipher.responder;
87
+ const initiator = plainInitiatorRootKeyCipher && plainInitiatorRootKeyCipher.initiator;
88
+ return Object.assign(Object.assign({}, keyExchange), { message: responder ? responder.message : null, contactCard: responder && responder.contactCard
89
+ ? responder.contactCard.plainSharedCipherDataJson
90
+ : null, myContactCard: initiator && initiator.contactCard
91
+ ? initiator.contactCard.plainSharedCipherDataJson
92
+ : null, myMessage: initiator && initiator.message });
93
+ }
94
+ else {
95
+ const decryptedOtk = yield this.decryptOtk(keyExchange, otKeyK);
96
+ const initiator = decryptedOtk && decryptedOtk.plainOtKeyCipher.initiator;
97
+ return Object.assign(Object.assign({}, keyExchange), { decryptedOtk, message: initiator && initiator.message, contactCard: initiator &&
98
+ initiator.contactCard &&
99
+ initiator.contactCard.plainSharedCipherDataJson });
100
+ }
101
+ });
102
+ }
103
+ decryptOtk(keyExchange, otKeyK) {
104
+ return __awaiter(this, void 0, void 0, function* () {
105
+ const otKey = yield this.getOtKey(keyExchange, otKeyK);
106
+ return otKey && keyExchange.otk.otKeyCipher
107
+ ? {
108
+ plainOtKeyCipher: yield this.encryptionService.decrypt(otKey, keyExchange.otk.otKeyCipher),
109
+ otKey,
110
+ }
111
+ : null;
112
+ });
113
+ }
114
+ getOtKey(keyExchange, otKeyK) {
115
+ return __awaiter(this, void 0, void 0, function* () {
116
+ if (otKeyK) {
117
+ return yield KFS.asKey(Object.assign(Object.assign({}, JSON.parse(keyExchange.otk.otKeyParams)), { k: otKeyK }));
118
+ }
119
+ else if (keyExchange.otk.state === OtkState.OTK_INITIATED &&
120
+ !keyExchange.isInitiator &&
121
+ keyExchange.otk.responderPbkCipher) {
122
+ // Assuming existing user getting invited where OTK is wrapped in responder's public key.
123
+ const prk = yield this.keyService.getCurrentPxk();
124
+ const decryptedCipher = yield this.encryptionService.decrypt(prk.jwk, JSON.parse(keyExchange.otk.responderPbkCipher), {
125
+ serializations: [JoseSerialization.COMPACT],
126
+ });
127
+ if (decryptedCipher.otKey) {
128
+ return yield KFS.asKey(decryptedCipher.otKey);
129
+ }
130
+ }
131
+ return null;
132
+ });
133
+ }
134
+ initiateOtk({ message, email, contactCard, upgrade, }) {
135
+ return __awaiter(this, void 0, void 0, function* () {
136
+ const otKey = yield this.keyFactory.createKey();
137
+ const nonce = this.keyFactory.randomString(this.CLIENT_NONCE_LENGTH);
138
+ const user = yield this.authService.getUser();
139
+ // New PKC key for encryption. This key is used only once when the responder sends
140
+ // back their signing public key.
141
+ const initiatorOneTimePrk = yield this.keyFactory.createPkcKey();
142
+ // Option 1: New PKC key for signing
143
+ // const initiatorSigPrk = await this.keyService.createPkcSignKey();
144
+ // Option 2: Use the user's global signing key.
145
+ // This key is used to prove the initiator's identity.
146
+ const initiatorPrk = yield this.keyService.getCurrentPxk();
147
+ const initiatorSigPrk = yield this.keyService.getCurrentSigPxk();
148
+ let initiatorPlainDataSig = null;
149
+ if (contactCard && contactCard.ownerPlainData) {
150
+ initiatorPlainDataSig = JSON.stringify(yield this.encryptionService.sign(initiatorSigPrk.jwk, contactCard.ownerPlainData));
151
+ }
152
+ const initiator = {
153
+ message,
154
+ contactCard: contactCard
155
+ ? {
156
+ plainSharedCipherDataJson: contactCard.plainSharedCipherDataJson,
157
+ }
158
+ : null,
159
+ };
160
+ // Content to be encrypted using the OTK.
161
+ const plainOtKeyCipher = {
162
+ nonce,
163
+ initiator: Object.assign(Object.assign({}, initiator), { oneTimePbk: initiatorOneTimePrk.toJSON(), pbk: initiatorPrk.jwk.toJSON(), sigPbk: initiatorSigPrk.jwk.toJSON(), profile: {
164
+ username: user.username,
165
+ } }),
166
+ };
167
+ const otKeyCipher = yield this.encryptionService.encrypt(otKey, plainOtKeyCipher);
168
+ // Content to be encrypted using the initiator's root key.
169
+ const plainInitiatorRootKeyCipher = {
170
+ nonce,
171
+ oneTimePrk: initiatorOneTimePrk.toJSON(true),
172
+ // Should not need to keep this encrypted since we are using the global signing key.
173
+ // sigPrk: initiatorSigPrk.toJSON(true),
174
+ // Save it in case the initiator want to decode the otKeyCipher.
175
+ // Since the otKey is only used once, and that otKeyCipher contains only
176
+ // the public key of the initiator, it's safe just leave the otKey stored here.
177
+ otKey: otKey.toJSON(true),
178
+ // These should be storing information such as how the fields of the shared contact card is
179
+ // derived from the master contact card.
180
+ initiatorContactCard: contactCard,
181
+ initiator,
182
+ };
183
+ const rootKey = yield this.keyService.getCurrentRootKey();
184
+ const initiatorRootKeyCipher = yield this.encryptionService.encrypt(rootKey.jwk, plainInitiatorRootKeyCipher);
185
+ // The raw OTK
186
+ const otKeyK = otKey.toJSON(true).k;
187
+ // API call
188
+ const { initiateKeyExchangeOtk } = yield this.lrApollo.mutate({
189
+ mutation: InitiateOtkMutation,
190
+ variables: {
191
+ input: {
192
+ // These will be stored on the server
193
+ initiatorRootKeyCipher: JSON.stringify(initiatorRootKeyCipher),
194
+ initiatorPxkId: initiatorPrk.id,
195
+ initiatorSigPxkId: initiatorSigPrk.id,
196
+ // These will be sent to the responder
197
+ otKeyParams: JSON.stringify(otKey.toJSON()),
198
+ otKeyCipher: JSON.stringify(otKeyCipher),
199
+ sendEmail: email
200
+ ? {
201
+ email,
202
+ rawOtKey: otKeyK,
203
+ }
204
+ : null,
205
+ createTp: true,
206
+ initiatorPlainDataSig,
207
+ upgrade,
208
+ },
209
+ },
210
+ });
211
+ return { keyExchange: initiateKeyExchangeOtk.keyExchange, otKeyK };
212
+ });
213
+ }
214
+ respondOtk({ id, token, decryptedOtk, message, initiatorContactCard, responderContactCard: sentContactCard, }) {
215
+ return __awaiter(this, void 0, void 0, function* () {
216
+ const user = yield this.authService.getUser();
217
+ const rootKey = yield this.keyService.getCurrentRootKey();
218
+ const masterKeyId = this.keyService.getCurrentMasterKey().id;
219
+ const masterKey = yield this.keyService.getCurrentMasterKey();
220
+ const sharedKey = yield this.keyFactory.createKey();
221
+ const mkSharedKey = yield this.keyFactory.createKey();
222
+ const rkWrappedSharedKey = yield this.encryptionService.encrypt(rootKey.jwk, sharedKey.toJSON(true));
223
+ const mkWrappedMkSharedKey = yield this.encryptionService.encrypt(masterKey.jwk, mkSharedKey.toJSON(true));
224
+ const initiatorOneTimePbk = yield KFS.asKey(decryptedOtk.plainOtKeyCipher.initiator.oneTimePbk);
225
+ const initiatorPbk = yield KFS.asKey(decryptedOtk.plainOtKeyCipher.initiator.pbk);
226
+ const initiatorSigPbk = yield KFS.asKey(decryptedOtk.plainOtKeyCipher.initiator.sigPbk);
227
+ // Option 1: Using new Prk for each TP pair
228
+ // Create a new public signing key for the responder.
229
+ // const responderSigPrk = await this.keyService.createPkcSignKey()
230
+ // const rkWrappedResponderSigPrk = await this.encrypt(rootKey, responderSigPrk.toJSON(true));
231
+ // Option 2: Responder already has a signing Prk
232
+ const responderPrk = yield this.keyService.getCurrentPxk();
233
+ const responderSigPrk = yield this.keyService.getCurrentSigPxk();
234
+ const signedInitiatorPbk = yield this.encryptionService.sign(responderSigPrk.jwk, initiatorPbk.toJSON());
235
+ const signedInitiatorSigPbk = yield this.encryptionService.sign(responderSigPrk.jwk, initiatorSigPbk.toJSON());
236
+ const plainInitiatorOneTimePbkCipher = {
237
+ nonce: decryptedOtk.plainOtKeyCipher.nonce,
238
+ sharedKey: sharedKey.toJSON(true),
239
+ mkSharedKey: mkSharedKey.toJSON(true),
240
+ responder: {
241
+ pbk: responderPrk.jwk.toJSON(),
242
+ sigPbk: responderSigPrk.jwk.toJSON(),
243
+ profile: {
244
+ username: user.username,
245
+ },
246
+ message,
247
+ },
248
+ };
249
+ let receivedCardInput;
250
+ if (decryptedOtk.plainOtKeyCipher.initiator.contactCard) {
251
+ // Set the info about the initiator to be the ones sent by the initiator. We need th responder to do the encryption here
252
+ // because the initiator does not have the shared key yet, and we want the responder to have a functional contact card after
253
+ // this exchange. The initiator can double check the contact details are correct and sign it when it completes the exchange.
254
+ const plainSharedCipherDataJson = decryptedOtk.plainOtKeyCipher.initiator.contactCard
255
+ .plainSharedCipherDataJson;
256
+ // Create keys
257
+ const receiverKey = yield this.keyFactory.createKey();
258
+ const ccSharedKey = yield this.keyFactory.createKey();
259
+ const sigPxk = yield this.keyService.getCurrentSigPxk();
260
+ receivedCardInput = {
261
+ receiverWrappedKey: JSON.stringify(yield this.encryptionService.encrypt(rootKey.jwk, receiverKey.toJSON(true))),
262
+ receiverWrappingKeyId: rootKey.id,
263
+ receiverCipherData: initiatorContactCard
264
+ ? JSON.stringify(yield this.encryptionService.encrypt(receiverKey, initiatorContactCard.plainReceiverCipherDataJson))
265
+ : '',
266
+ sharedWrappedKey: JSON.stringify(yield this.encryptionService.encrypt(sharedKey, ccSharedKey.toJSON(true))),
267
+ };
268
+ const sharedCipherData = yield this.encryptionService.encrypt(ccSharedKey, plainSharedCipherDataJson);
269
+ receivedCardInput.sharedCipherDataSig = JSON.stringify(yield this.encryptionService.sign(sigPxk.jwk, sharedCipherData));
270
+ receivedCardInput.sigPxkId = sigPxk.id;
271
+ plainInitiatorOneTimePbkCipher.responder.contactCard = Object.assign(Object.assign({}, plainInitiatorOneTimePbkCipher.responder.contactCard), { sharedCipherKey: ccSharedKey.toJSON(true) });
272
+ }
273
+ let sentCardInput;
274
+ if (sentContactCard) {
275
+ // Create keys
276
+ const ownerKey = yield this.keyFactory.createKey();
277
+ const ccSharedKey = yield this.keyFactory.createKey();
278
+ const sigPxk = yield this.keyService.getCurrentSigPxk();
279
+ sentCardInput = {
280
+ ownerWrappedKey: JSON.stringify(yield this.encryptionService.encrypt(rootKey.jwk, ownerKey.toJSON(true))),
281
+ ownerWrappingKeyId: rootKey.id,
282
+ ownerCipherData: sentContactCard.plainOwnerCipherDataJson
283
+ ? JSON.stringify(yield this.encryptionService.encrypt(ownerKey, sentContactCard.plainOwnerCipherDataJson))
284
+ : '',
285
+ sharedWrappedKey: JSON.stringify(yield this.encryptionService.encrypt(sharedKey, ccSharedKey.toJSON(true))),
286
+ };
287
+ const sharedCipherData = yield this.encryptionService.encrypt(ccSharedKey, sentContactCard.plainSharedCipherDataJson);
288
+ sentCardInput.sharedCipherDataSig = JSON.stringify(yield this.encryptionService.sign(sigPxk.jwk, sharedCipherData));
289
+ sentCardInput.sigPxkId = sigPxk.id;
290
+ if (sentContactCard.ownerPlainData) {
291
+ sentCardInput.ownerPlainDataSig = JSON.stringify(yield this.encryptionService.sign(responderSigPrk.jwk, sentContactCard.ownerPlainData));
292
+ }
293
+ // Contact card info readable by the initiator
294
+ plainInitiatorOneTimePbkCipher.responder.contactCard = Object.assign(Object.assign({}, plainInitiatorOneTimePbkCipher.responder.contactCard), { plainSharedCipherDataJson: sentContactCard.plainSharedCipherDataJson });
295
+ }
296
+ // Encrypt with one-time public key
297
+ let initiatorOneTimePbkCipher = yield this.encryptionService.encrypt(initiatorOneTimePbk, plainInitiatorOneTimePbkCipher);
298
+ // Encrypt with the otk again to keep use of asymmetric keys to a minimum.
299
+ initiatorOneTimePbkCipher = yield this.encryptionService.encrypt(decryptedOtk.otKey, initiatorOneTimePbkCipher);
300
+ const { respondKeyExchangeOtk } = yield this.lrApollo.mutate({
301
+ mutation: RespondOtkMutation,
302
+ variables: {
303
+ input: {
304
+ keyExchangeId: id,
305
+ keyExchangeToken: token,
306
+ rootKeyId: rootKey.id,
307
+ masterKeyId,
308
+ // These will be stored on the server
309
+ responderPxkId: responderPrk.id,
310
+ responderSigPxkId: responderSigPrk.id,
311
+ signedInitiatorPbk: JSON.stringify(signedInitiatorPbk),
312
+ signedInitiatorSigPbk: JSON.stringify(signedInitiatorSigPbk),
313
+ // rkWrappedInitiatorSigPbk: JSON.stringify(rkWrappedInitiatorSigPbk),
314
+ // Option 1: Using new Prk for each TP pair
315
+ // rkWrappedResponderSigPrk: JSON.stringify(rkWrappedResponderSigPrk),
316
+ rkWrappedSharedKey: JSON.stringify(rkWrappedSharedKey),
317
+ mkWrappedMkSharedKey: JSON.stringify(mkWrappedMkSharedKey),
318
+ // These will be sent to the initiator
319
+ initiatorOneTimePbkCipher: JSON.stringify(initiatorOneTimePbkCipher),
320
+ initiatorContactCard: receivedCardInput,
321
+ responderContactCard: sentCardInput,
322
+ },
323
+ },
324
+ });
325
+ return {
326
+ keyExchange: respondKeyExchangeOtk.keyExchange,
327
+ userSharedKey: respondKeyExchangeOtk.userSharedKey,
328
+ tp: respondKeyExchangeOtk.tp,
329
+ };
330
+ });
331
+ }
332
+ completeOtk(keyExchangeId, initiatorRootKeyCipher, initiatorOneTimePbkCipher, responderContactCard) {
333
+ return __awaiter(this, void 0, void 0, function* () {
334
+ const rootKey = yield this.keyService.getCurrentRootKey();
335
+ const masterKey = yield this.keyService.getCurrentMasterKey();
336
+ // Decrypt using the root key to get the Prk
337
+ const plainInitiatorRootKeyCipher = (yield this.encryptionService.decrypt(rootKey.jwk, initiatorRootKeyCipher));
338
+ // The Prk is single-use and only used to send information from the responder back to the initiator.
339
+ const plainInitiatorOneTimePbkCipher = yield this.decryptResponseCipher(yield KFS.asKey(plainInitiatorRootKeyCipher.otKey), yield KFS.asKey(plainInitiatorRootKeyCipher.oneTimePrk), initiatorOneTimePbkCipher);
340
+ // Check the nonce match to ensure the responder was the one holding the OTK
341
+ if (plainInitiatorRootKeyCipher.nonce !== plainInitiatorOneTimePbkCipher.nonce) {
342
+ throw new LrCodeMismatchException('The nonce returned by responder does not match with the one created by the initiator.');
343
+ }
344
+ // Option 1: Assuming the signing key is unique between users.
345
+ // const initiatorSigPrk = await KFS.asKey(ke.plainInitiatorRootKeyCipher.sigPrk);
346
+ // const rkWrappedInitiatorSigPrk = await this.encrypt(rootKey, initiatorSigPrk.toJSON(true));
347
+ // Option 2: Use the user's global signing key.
348
+ // In this case the initiatorSigPrk is already a part of the key graph.
349
+ // So there's nothing to do here.
350
+ // Protected the signing public key of the responder.
351
+ const initiatorSigPrk = yield this.keyService.getCurrentSigPxk();
352
+ const responderSigPbk = yield KFS.asKey(plainInitiatorOneTimePbkCipher.responder.sigPbk);
353
+ const responderPbk = yield KFS.asKey(plainInitiatorOneTimePbkCipher.responder.pbk);
354
+ const signedResponderPbk = yield this.encryptionService.sign(initiatorSigPrk.jwk, responderPbk.toJSON());
355
+ const signedResponderSigPbk = yield this.encryptionService.sign(initiatorSigPrk.jwk, responderSigPbk.toJSON());
356
+ const sharedKey = yield KFS.asKey(plainInitiatorOneTimePbkCipher.sharedKey);
357
+ const rkWrappedSharedKey = yield this.encryptionService.encrypt(rootKey.jwk, sharedKey.toJSON(true));
358
+ const mkSharedKey = yield KFS.asKey(plainInitiatorOneTimePbkCipher.mkSharedKey);
359
+ const mkWrappedMkSharedKey = yield this.encryptionService.encrypt(masterKey.jwk, mkSharedKey.toJSON(true));
360
+ let responderContactCardCipherInput;
361
+ if (responderContactCard) {
362
+ // Create key
363
+ const receiverKey = yield this.keyFactory.createKey();
364
+ responderContactCardCipherInput = {
365
+ receiverWrappedKey: JSON.stringify(yield this.encryptionService.encrypt(rootKey.jwk, receiverKey.toJSON(true))),
366
+ receiverWrappingKeyId: rootKey.id,
367
+ receiverCipherData: JSON.stringify(yield this.encryptionService.encrypt(receiverKey, responderContactCard)),
368
+ };
369
+ }
370
+ // Get the data needed from the initiator's cipher data.
371
+ let initiatorContactCardCipherInput;
372
+ let initiatorContactCardSharedCipherInput;
373
+ if (plainInitiatorRootKeyCipher.initiatorContactCard) {
374
+ const initiatorContactCard = plainInitiatorRootKeyCipher.initiatorContactCard;
375
+ const ownerKey = yield this.keyFactory.createKey();
376
+ const sharedCipherKey = yield KFS.asKey(plainInitiatorOneTimePbkCipher.responder.contactCard.sharedCipherKey);
377
+ const ownerWrappedKey = JSON.stringify(yield this.encryptionService.encrypt(rootKey.jwk, ownerKey.toJSON(true)));
378
+ const ownerCipherData = initiatorContactCard.plainOwnerCipherDataJson
379
+ ? JSON.stringify(yield this.encryptionService.encrypt(ownerKey, initiatorContactCard.plainOwnerCipherDataJson))
380
+ : '';
381
+ initiatorContactCardCipherInput = {
382
+ ownerWrappedKey,
383
+ ownerWrappingKeyId: rootKey.id,
384
+ ownerCipherData,
385
+ };
386
+ initiatorContactCardSharedCipherInput = {
387
+ sigPxkId: initiatorSigPrk.id,
388
+ };
389
+ const sharedCipherData = yield this.encryptionService.encrypt(sharedCipherKey, initiatorContactCard.plainSharedCipherDataJson);
390
+ initiatorContactCardSharedCipherInput.sharedCipherDataSig = JSON.stringify(yield this.encryptionService.sign(initiatorSigPrk.jwk, sharedCipherData));
391
+ }
392
+ // TODO ideally we update the shared data in the contact card sent to the responder as well since that
393
+ // CC was created by the responder.
394
+ const res = yield this.lrApollo.mutate({
395
+ mutation: CompleteOtkMutation,
396
+ variables: {
397
+ input: {
398
+ keyExchangeId,
399
+ rootKeyId: rootKey.id,
400
+ masterKeyId: masterKey.id,
401
+ initiatorSigPxkId: initiatorSigPrk.id,
402
+ signedResponderPbk: JSON.stringify(signedResponderPbk),
403
+ signedResponderSigPbk: JSON.stringify(signedResponderSigPbk),
404
+ rkWrappedSharedKey: JSON.stringify(rkWrappedSharedKey),
405
+ mkWrappedMkSharedKey: JSON.stringify(mkWrappedMkSharedKey),
406
+ responderContactCardCipher: responderContactCardCipherInput,
407
+ initiatorContactCardCipher: initiatorContactCardCipherInput,
408
+ initiatorContactCardSharedCipher: initiatorContactCardSharedCipherInput,
409
+ },
410
+ },
411
+ });
412
+ return res.completeKeyExchangeOtk;
413
+ });
414
+ }
415
+ currentUserSharedKey(input) {
416
+ return __awaiter(this, void 0, void 0, function* () {
417
+ const { currentUserSharedKey } = yield this.lrApollo.query({
418
+ query: CurrentUserSharedKeyQuery,
419
+ variables: {
420
+ username: input.username,
421
+ userId: input.userId,
422
+ },
423
+ });
424
+ return currentUserSharedKey.userSharedKey;
425
+ });
426
+ }
427
+ }
428
+ KeyExchangeService.ɵprov = i0.ɵɵdefineInjectable({ factory: function KeyExchangeService_Factory() { return new KeyExchangeService(i0.ɵɵinject(i1.KeyFactoryService), i0.ɵɵinject(i2.KeyService), i0.ɵɵinject(i3.LrApolloService), i0.ɵɵinject(i4.EncryptionService), i0.ɵɵinject(i5.LifeReadyAuthService), i0.ɵɵinject(i6.UserService)); }, token: KeyExchangeService, providedIn: "root" });
429
+ KeyExchangeService.decorators = [
430
+ { type: Injectable, args: [{
431
+ providedIn: 'root',
432
+ },] }
433
+ ];
434
+ KeyExchangeService.ctorParameters = () => [
435
+ { type: KFS },
436
+ { type: KeyService },
437
+ { type: LrApolloService },
438
+ { type: EncryptionService },
439
+ { type: LifeReadyAuthService },
440
+ { type: UserService }
441
+ ];
442
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoia2V5LWV4Y2hhbmdlLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiQzovUHJvamVjdHMvbmV3cmVwby9rYy1jbGllbnQvcHJvamVjdHMvY29yZS9zcmMvIiwic291cmNlcyI6WyJsaWIvYXBpL2tleS1leGNoYW5nZS5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBRTNDLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBRXZFLE9BQU8sRUFDTCxpQkFBaUIsRUFDakIsaUJBQWlCLEdBQ2xCLE1BQU0sb0NBQW9DLENBQUM7QUFDNUMsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBQ3pELE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQ2hFLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUN0RCxPQUFPLEVBQ0wsbUJBQW1CLEVBQ25CLHlCQUF5QixFQUN6QixtQkFBbUIsRUFDbkIsZ0JBQWdCLEVBQ2hCLGlCQUFpQixFQUNqQixxQkFBcUIsRUFDckIsa0JBQWtCLEdBQ25CLE1BQU0sb0JBQW9CLENBQUM7QUFDNUIsT0FBTyxFQVFMLFFBQVEsR0FRVCxNQUFNLHNCQUFzQixDQUFDO0FBQzlCLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUN0RCxPQUFPLEVBQUUsaUJBQWlCLElBQUksR0FBRyxFQUFFLE1BQU0scUNBQXFDLENBQUM7QUFDL0UsMEdBQTBHO0FBQzFHLE9BQU8sS0FBSyxPQUFPLE1BQU0sUUFBUSxDQUFDOzs7Ozs7OztBQUNsQyxNQUFNLE1BQU0sR0FBRyxPQUFPLENBQUM7QUFLdkIsTUFBTSxPQUFPLGtCQUFrQjtJQUc3QixZQUNVLFVBQWUsRUFDZixVQUFzQixFQUN0QixRQUF5QixFQUN6QixpQkFBb0MsRUFDcEMsV0FBaUMsRUFDakMs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cnQgeyBKV0sgfSBmcm9tICdub2RlLWpvc2UnO1xyXG5pbXBvcnQgeyBMaWZlUmVhZHlBdXRoU2VydmljZSB9IGZyb20gJy4uL2F1dGgvbGlmZS1yZWFkeS1hdXRoLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBLZXlHcmFwaFJlc3BvbnNlIH0gZnJvbSAnLi4vY3J5cHRvZ3JhcGh5L2NyeXB0b2dyYXBoeS50eXBlcyc7XHJcbmltcG9ydCB7XHJcbiAgRW5jcnlwdGlvblNlcnZpY2UsXHJcbiAgSm9zZVNlcmlhbGl6YXRpb24sXHJcbn0gZnJvbSAnLi4vY3J5cHRvZ3JhcGh5L2VuY3J5cHRpb24uc2VydmljZSc7XHJcbmltcG9ydCB7IEtleVNlcnZpY2UgfSBmcm9tICcuLi9jcnlwdG9ncmFwaHkva2V5LnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBMckNvZGVNaXNtYXRjaEV4Y2VwdGlvbiB9IGZyb20gJy4uL19jb21tb24vZXhjZXB0aW9ucyc7XHJcbmltcG9ydCB7IFVzZXJTZXJ2aWNlIH0gZnJvbSAnLi8uLi91c2Vycy91c2VyLnNlcnZpY2UnO1xyXG5pbXBvcnQge1xyXG4gIENvbXBsZXRlT3RrTXV0YXRpb24sXHJcbiAgQ3VycmVudFVzZXJTaGFyZWRLZXlRdWVyeSxcclxuICBJbml0aWF0ZU90a011dGF0aW9uLFxyXG4gIEtleUV4Y2hhbmdlUXVlcnksXHJcbiAgS2V5RXhjaGFuZ2VzUXVlcnksXHJcbiAgS2V5RXhjaGFuZ2VUb2tlblF1ZXJ5LFxyXG4gIFJlc3BvbmRPdGtNdXRhdGlvbixcclxufSBmcm9tICcuL2tleS1leGNoYW5nZS5ncWwnO1xyXG5pbXBvcnQge1xyXG4gIENvbXBsZXRlT3RrLFxyXG4gIERlY3J5cHRlZEtleUV4Y2hhbmdlLFxyXG4gIERlY3J5cHRlZE90ayxcclxuICBHZXRLZXlFeGNoYW5nZUxpc3RPcHRpb25zLFxyXG4gIEdldEtleUV4Y2hhbmdlT3B0aW9ucyxcclxuICBJbml0aWF0ZU90a0lucHV0LFxyXG4gIEtleUV4Y2hhbmdlLFxyXG4gIE90a1N0YXRlLFxyXG4gIFBsYWluSW5pdGlhdG9yT25lVGltZVBia0NpcGhlcixcclxuICBQbGFpbkluaXRpYXRvclJvb3RLZXlDaXBoZXIsXHJcbiAgUGxhaW5PdEtleUNpcGhlcixcclxuICBQbGFpblJlc3BvbmRlclBia0NpcGhlcixcclxuICBSZXNwb25kT3RrLFxyXG4gIFJlc3BvbmRPdGtJbnB1dCxcclxuICBVc2VyU2hhcmVkS2V5LFxyXG59IGZyb20gJy4va2V5LWV4Y2hhbmdlLnR5cGVzJztcclxuaW1wb3J0IHsgTHJBcG9sbG9TZXJ2aWNlIH0gZnJvbSAnLi9sci1hcG9sbG8uc2VydmljZSc7XHJcbmltcG9ydCB7IEtleUZhY3RvcnlTZXJ2aWNlIGFzIEtGUyB9IGZyb20gJy4uL2NyeXB0b2dyYXBoeS9rZXktZmFjdG9yeS5zZXJ2aWNlJztcclxuLy8gUmVmOiBodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy81OTczNTI4MC9hbmd1bGFyLTgtbW9tZW50LWVycm9yLWNhbm5vdC1jYWxsLWEtbmFtZXNwYWNlLW1vbWVudFxyXG5pbXBvcnQgKiBhcyBtb21lbnRfIGZyb20gJ21vbWVudCc7XHJcbmNvbnN0IG1vbWVudCA9IG1vbWVudF87XHJcblxyXG5ASW5qZWN0YWJsZSh7XHJcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnLFxyXG59KVxyXG5leHBvcnQgY2xhc3MgS2V5RXhjaGFuZ2VTZXJ2aWNlIHtcclxuICBwcml2YXRlIHJlYWRvbmx5IENMSUVOVF9OT05DRV9MRU5HVEggPSAzMjtcclxuXHJcbiAgY29uc3RydWN0b3IoXHJcbiAgICBwcml2YXRlIGtleUZhY3Rvcnk6IEtGUyxcclxuICAgIHByaXZhdGUga2V5U2VydmljZTogS2V5U2VydmljZSxcclxuICAgIHByaXZhdGUgbHJBcG9sbG86IExyQXBvbGxvU2VydmljZSxcclxuICAgIHByaXZhdGUgZW5jcnlwdGlvblNlcnZpY2U6IEVuY3J5cHRpb25TZXJ2aWNlLFxyXG4gICAgcHJpdmF0ZSBhdXRoU2VydmljZTogTGlmZVJlYWR5QXV0aFNlcnZpY2UsXHJcbiAgICBwcml2YXRlIHVzZXJTZXJ2aWNlOiBVc2VyU2VydmljZVxyXG4gICkge31cclxuXHJcbiAgcHVibGljIGFzeW5jIGdldEtleUV4Y2hhbmdlTGlzdChcclxuICAgIGlucHV0OiBHZXRLZXlFeGNoYW5nZUxpc3RPcHRpb25zID0ge31cclxuICApOiBQcm9taXNlPGFueT4ge1xyXG4gICAgY29uc3QgeyBrZXlFeGNoYW5nZXMgfSA9IGF3YWl0IHRoaXMubHJBcG9sbG8ucXVlcnk8e1xyXG4gICAgICBrZXlFeGNoYW5nZXM6IGFueTtcclxuICAgICAga2V5R3JhcGg6IEtleUdyYXBoUmVzcG9uc2U7XHJcbiAgICB9Pih7XHJcbiAgICAgIHF1ZXJ5OiBLZXlFeGNoYW5nZXNRdWVyeSxcclxuICAgICAgdmFyaWFibGVzOiB7XHJcbiAgICAgICAgLi4uaW5wdXQsXHJcbiAgICAgIH0sXHJcbiAgICB9KTtcclxuICAgIHJldHVybiBrZXlFeGNoYW5nZXM7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBAcGFyYW0gaWQgSWYgdGhlIGN1cnJlbnQgdXNlciBjYW4gcmVzcG9uZGVyIHRoZSBrZXkgZXhjaGFuZ2UgaWYgdGhleSBhcmUgZWl0aGVyIHRoZSBpbml0aWF0b3Igb3IgdGhlIHJlY2VpdmVyLlxyXG4gICAqIEBwYXJhbSB0b2tlbiBJZiBub3Qgc2lnbmVkIGluLCBvciBub3QgdGhlIGluaXRpYXRvciBvciByZXNwb25kZXIsICd0b2tlbicgbXVzdCBiZSBnaXZlbi5cclxuICAgKiBAcGFyYW0gb3RLZXlLIElzIHRoZSByYXcgb25lLXRpbWUga2V5IChzdHJpbmcpLiBJZiB0aGUgcmVzcG9uZGVyIGlzIGV4cGxpY2l0bHkgc3BlY2lmaWVkIGF0IHRpbWUgb2YgaW5pdGlhdGlvbiwgdGhlblxyXG4gICAqICAgaXQncyBwb3NzaWJsZSB0byBoYXZlIHRoZSBvdEtleSB3cmFwcGVkIGJ5IHRoZSBwdWJsaWMga2V5IG9mIHRoZSByZXNwb25kZXIuIEluIHdoaWNoIGNhc2UsIHRoZSBvdEtleUsgaXMgbm90IG5lZWRlZC5cclxuICAgKi9cclxuICBwdWJsaWMgYXN5bmMgZ2V0S2V5RXhjaGFuZ2UoXHJcbiAgICBpZDogc3RyaW5nLFxyXG4gICAgeyBvdEtleUssIHRva2VuIH06IEdldEtleUV4Y2hhbmdlT3B0aW9ucyA9IHt9XHJcbiAgKTogUHJvbWlzZTxEZWNyeXB0ZWRLZXlFeGNoYW5nZT4ge1xyXG4gICAgY29uc3QgeyBrZXlFeGNoYW5nZSB9ID0gYXdhaXQgdGhpcy5sckFwb2xsby5xdWVyeTx7XHJcbiAgICAgIGtleUV4Y2hhbmdlOiBLZXlFeGNoYW5nZTtcclxuICAgICAga2V5R3JhcGg6IEtleUdyYXBoUmVzcG9uc2U7XHJcbiAgICB9Pih7XHJcbiAgICAgIHF1ZXJ5OiB0b2tlbiA/IEtleUV4Y2hhbmdlVG9rZW5RdWVyeSA6IEtleUV4Y2hhbmdlUXVlcnksXHJcbiAgICAgIHZhcmlhYmxlczoge1xyXG4gICAgICAgIGlkLFxyXG4gICAgICAgIHRva2VuLFxyXG4gICAgICB9LFxyXG4gICAgfSk7XHJcbiAgICByZXR1cm4gYXdhaXQgdGhpcy5kZWNyeXB0S2V5RXhjaGFuZ2Uoa2V5RXhjaGFuZ2UsIG90S2V5Syk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGFzeW5jIGRlY3J5cHRSZXNwb25zZUNpcGhlcihcclxuICAgIG90S2V5OiBKV0suS2V5LFxyXG4gICAgb3RQcms6IEpXSy5LZXksXHJcbiAgICBjb250ZW50OiBhbnlcclxuICApOiBQcm9taXNlPFBsYWluSW5pdGlhdG9yT25lVGltZVBia0NpcGhlcj4ge1xyXG4gICAgLy8gVGhlIHJlc3BvbnNlIGNvdWxkIGJlIHdyYXBwZWQgYnkgdGhlIE90SyBhcyB3ZWxsIGFzIHdlIHRoZSBPdFBya1xyXG4gICAgdHJ5IHtcclxuICAgICAgY29udGVudCA9IGF3YWl0IHRoaXMuZW5jcnlwdGlvblNlcnZpY2UuZGVjcnlwdChvdEtleSwgY29udGVudCk7XHJcbiAgICB9IGNhdGNoIChlcnJvcikge1xyXG4gICAgICBpZiAoZXJyb3IubWVzc2FnZSAhPT0gJ25vIGtleSBmb3VuZCcpIHtcclxuICAgICAgICB0aHJvdyBlcnJvcjtcclxuICAgICAgfVxyXG4gICAgICAvLyBEbyBub3RoaW5nIHRvIHN1cHBvcnQgb2xkZXIgdmVyc2lvbnMgd2hlcmUgbWVzc2FnZSBpcyBub3Qgd3JhcHBlZCB3aXRoIG90ay5cclxuICAgIH1cclxuXHJcbiAgICAvLyBUaGUgUHJrIGlzIHNpbmdsZS11c2UgYW5kIG9ubHkgdXNlZCB0byBzZW5kIGluZm9ybWF0aW9uIGZyb20gdGhlIHJlc3BvbmRlciBiYWNrIHRvIHRoZSBpbml0aWF0b3IuXHJcbiAgICByZXR1cm4gYXdhaXQgdGhpcy5lbmNyeXB0aW9uU2VydmljZS5kZWNyeXB0KG90UHJrLCBjb250ZW50KTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBhc3luYyBkZWNyeXB0S2V5RXhjaGFuZ2UoXHJcbiAgICBrZXlFeGNoYW5nZTogS2V5RXhjaGFuZ2UsXHJcbiAgICBvdEtleUs/OiBzdHJpbmdcclxuICApOiBQcm9taXNlPERlY3J5cHRlZEtleUV4Y2hhbmdlPiB7XHJcbiAgICBpZiAoa2V5RXhjaGFuZ2UuaXNJbml0aWF0b3IpIHtcclxuICAgICAgY29uc3Qgcm9vdEtleSA9IGF3YWl0IHRoaXMua2V5U2VydmljZS5nZXRDdXJyZW50Um9vdEtleSgpO1xyXG4gICAgICAvLyBEZWNyeXB0IHVzaW5nIHRoZSByb290IGtleSB0byBnZXQgdGhlIFBya1xyXG4gICAgICBjb25zdCBwbGFpbkluaXRpYXRvclJvb3RLZXlDaXBoZXIgPSAoKGF3YWl0IHRoaXMuZW5jcnlwdGlvblNlcnZpY2UuZGVjcnlwdChcclxuICAgICAgICByb290S2V5Lmp3ayxcclxuICAgICAgICBrZXlFeGNoYW5nZS5pbml0aWF0b3JSb290S2V5Q2lwaGVyXHJcbiAgICAgICkpIGFzIHVua25vd24pIGFzIFBsYWluSW5pdGlhdG9yUm9vdEtleUNpcGhlcjtcclxuXHJcbiAgICAgIGNvbnN0IHBsYWluSW5pdGlhdG9yT25lVGltZVBia0NpcGhlciA9IGtleUV4Y2hhbmdlLm90a1xyXG4gICAgICAgIC5pbml0aWF0b3JPbmVUaW1lUGJrQ2lwaGVyXHJcbiAgICAgICAgPyBhd2FpdCB0aGlzLmRlY3J5cHRSZXNwb25zZUNpcGhlcihcclxuICAgICAgICAgICAgYXdhaXQgS0ZTLmFzS2V5KHBsYWluSW5pdGlhdG9yUm9vdEtleUNpcGhlci5vdEtleSksXHJcbiAgICAgICAgICAgIGF3YWl0IEtGUy5hc0tleShwbGFpbkluaXRpYXRvclJvb3RLZXlDaXBoZXIub25lVGltZVByayksXHJcbiAgICAgICAgICAgIGtleUV4Y2hhbmdlLm90ay5pbml0aWF0b3JPbmVUaW1lUGJrQ2lwaGVyXHJcbiAgICAgICAgICApXHJcbiAgICAgICAgOiBudWxsO1xyXG5cclxuICAgICAgY29uc3QgcmVzcG9uZGVyID1cclxuICAgICAgICBwbGFpbkluaXRpYXRvck9uZVRpbWVQYmtDaXBoZXIgJiZcclxuICAgICAgICBwbGFpbkluaXRpYXRvck9uZVRpbWVQYmtDaXBoZXIucmVzcG9uZGVyO1xyXG4gICAgICBjb25zdCBpbml0aWF0b3IgPVxyXG4gICAgICAgIHBsYWluSW5pdGlhdG9yUm9vdEtleUNpcGhlciAmJiBwbGFpbkluaXRpYXRvclJvb3RLZXlDaXBoZXIuaW5pdGlhdG9yO1xyXG5cclxuICAgICAgcmV0dXJuIHtcclxuICAgICAgICAuLi5rZXlFeGNoYW5nZSxcclxuICAgICAgICBtZXNzYWdlOiByZXNwb25kZXIgPyByZXNwb25kZXIubWVzc2FnZSA6IG51bGwsXHJcbiAgICAgICAgY29udGFjdENhcmQ6XHJcbiAgICAgICAgICByZXNwb25kZXIgJiYgcmVzcG9uZGVyLmNvbnRhY3RDYXJkXHJcbiAgICAgICAgICAgID8gcmVzcG9uZGVyLmNvbnRhY3RDYXJkLnBsYWluU2hhcmVkQ2lwaGVyRGF0YUpzb25cclxuICAgICAgICAgICAgOiBudWxsLFxyXG4gICAgICAgIG15Q29udGFjdENhcmQ6XHJcbiAgICAgICAgICBpbml0aWF0b3IgJiYgaW5pdGlhdG9yLmNvbnRhY3RDYXJkXHJcbiAgICAgICAgICAgID8gaW5pdGlhdG9yLmNvbnRhY3RDYXJkLnBsYWluU2hhcmVkQ2lwaGVyRGF0YUpzb25cclxuICAgICAgICAgICAgOiBudWxsLFxyXG4gICAgICAgIG15TWVzc2FnZTogaW5pdGlhdG9yICYmIGluaXRpYXRvci5tZXNzYWdlLFxyXG4gICAgICB9O1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgY29uc3QgZGVjcnlwdGVkT3RrID0gYXdhaXQgdGhpcy5kZWNyeXB0T3RrKGtleUV4Y2hhbmdlLCBvdEtleUspO1xyXG5cclxuICAgICAgY29uc3QgaW5pdGlhdG9yID0gZGVjcnlwdGVkT3RrICYmIGRlY3J5cHRlZE90ay5wbGFpbk90S2V5Q2lwaGVyLmluaXRpYXRvcjtcclxuXHJcbiAgICAgIHJldHVybiB7XHJcbiAgICAgICAgLi4ua2V5RXhjaGFuZ2UsXHJcbiAgICAgICAgZGVjcnlwdGVkT3RrLFxyXG4gICAgICAgIG1lc3NhZ2U6IGluaXRpYXRvciAmJiBpbml0aWF0b3IubWVzc2FnZSxcclxuICAgICAgICBjb250YWN0Q2FyZDpcclxuICAgICAgICAgIGluaXRpYXRvciAmJlxyXG4gICAgICAgICAgaW5pdGlhdG9yLmNvbnRhY3RDYXJkICYmXHJcbiAgICAgICAgICBpbml0aWF0b3IuY29udGFjdENhcmQucGxhaW5TaGFyZWRDaXBoZXJEYXRhSnNvbixcclxuICAgICAgfTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHByaXZhdGUgYXN5bmMgZGVjcnlwdE90ayhcclxuICAgIGtleUV4Y2hhbmdlOiBLZXlFeGNoYW5nZSxcclxuICAgIG90S2V5Sz86IHN0cmluZ1xyXG4gICk6IFByb21pc2U8RGVjcnlwdGVkT3RrPiB7XHJcbiAgICBjb25zdCBvdEtleSA9IGF3YWl0IHRoaXMuZ2V0T3RLZXkoa2V5RXhjaGFuZ2UsIG90S2V5Syk7XHJcblxyXG4gICAgcmV0dXJuIG90S2V5ICYmIGtleUV4Y2hhbmdlLm90ay5vdEtleUNpcGhlclxyXG4gICAgICA/IHtcclxuICAgICAgICAgIHBsYWluT3RLZXlDaXBoZXI6IGF3YWl0IHRoaXMuZW5jcnlwdGlvblNlcnZpY2UuZGVjcnlwdChcclxuICAgICAgICAgICAgb3RLZXksXHJcbiAgICAgICAgICAgIGtleUV4Y2hhbmdlLm90ay5vdEtleUNpcGhlclxyXG4gICAgICAgICAgKSxcclxuICAgICAgICAgIG90S2V5LFxyXG4gICAgICAgIH1cclxuICAgICAgOiBudWxsO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBhc3luYyBnZXRPdEtleShcclxuICAgIGtleUV4Y2hhbmdlOiBLZXlFeGNoYW5nZSxcclxuICAgIG90S2V5Sz86IHN0cmluZ1xyXG4gICk6IFByb21pc2U8SldLLktleT4ge1xyXG4gICAgaWYgKG90S2V5Sykge1xyXG4gICAgICByZXR1cm4gYXdhaXQgS0ZTLmFzS2V5KHtcclxuICAgICAgICAuLi5KU09OLnBhcnNlKGtleUV4Y2hhbmdlLm90ay5vdEtleVBhcmFtcyksXHJcbiAgICAgICAgazogb3RLZXlLLFxyXG4gICAgICB9KTtcclxuICAgIH0gZWxzZSBpZiAoXHJcbiAgICAgIGtleUV4Y2hhbmdlLm90ay5zdGF0ZSA9PT0gT3RrU3RhdGUuT1RLX0lOSVRJQVRFRCAmJlxyXG4gICAgICAha2V5RXhjaGFuZ2UuaXNJbml0aWF0b3IgJiZcclxuICAgICAga2V5RXhjaGFuZ2Uub3RrLnJlc3BvbmRlclBia0NpcGhlclxyXG4gICAgKSB7XHJcbiAgICAgIC8vIEFzc3VtaW5nIGV4aXN0aW5nIHVzZXIgZ2V0dGluZyBpbnZpdGVkIHdoZXJlIE9USyBpcyB3cmFwcGVkIGluIHJlc3BvbmRlcidzIHB1YmxpYyBrZXkuXHJcbiAgICAgIGNvbnN0IHByayA9IGF3YWl0IHRoaXMua2V5U2VydmljZS5nZXRDdXJyZW50UHhrKCk7XHJcbiAgICAgIGNvbnN0IGRlY3J5cHRlZENpcGhlcjogYW55ID0gYXdhaXQgdGhpcy5lbmNyeXB0aW9uU2VydmljZS5kZWNyeXB0KFxyXG4gICAgICAgIHByay5qd2ssXHJcbiAgICAgICAgSlNPTi5wYXJzZShrZXlFeGNoYW5nZS5vdGsucmVzcG9uZGVyUGJrQ2lwaGVyKSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICBzZXJpYWxpemF0aW9uczogW0pvc2VTZXJpYWxpemF0aW9uLkNPTVBBQ1RdLFxyXG4gICAgICAgIH1cclxuICAgICAgKTtcclxuICAgICAgaWYgKGRlY3J5cHRlZENpcGhlci5vdEtleSkge1xyXG4gICAgICAgIHJldHVybiBhd2FpdCBLRlMuYXNLZXkoZGVjcnlwdGVkQ2lwaGVyLm90S2V5KTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIG51bGw7XHJcbiAgfVxyXG5cclxuICBhc3luYyBpbml0aWF0ZU90ayh7XHJcbiAgICBtZXNzYWdlLFxyXG4gICAgZW1haWwsXHJcbiAgICBjb250YWN0Q2FyZCxcclxuICAgIHVwZ3JhZGUsXHJcbiAgfTogSW5pdGlhdGVPdGtJbnB1dCk6IFByb21pc2U8eyBrZXlFeGNoYW5nZTogS2V5RXhjaGFuZ2U7IG90S2V5Szogc3RyaW5nIH0+IHtcclxuICAgIGNvbnN0IG90S2V5ID0gYXdhaXQgdGhpcy5rZXlGYWN0b3J5LmNyZWF0ZUtleSgpO1xyXG4gICAgY29uc3Qgbm9uY2UgPSB0aGlzLmtleUZhY3RvcnkucmFuZG9tU3RyaW5nKHRoaXMuQ0xJRU5UX05PTkNFX0xFTkdUSCk7XHJcbiAgICBjb25zdCB1c2VyID0gYXdhaXQgdGhpcy5hdXRoU2VydmljZS5nZXRVc2VyKCk7XHJcblxyXG4gICAgLy8gTmV3IFBLQyBrZXkgZm9yIGVuY3J5cHRpb24uIFRoaXMga2V5IGlzIHVzZWQgb25seSBvbmNlIHdoZW4gdGhlIHJlc3BvbmRlciBzZW5kc1xyXG4gICAgLy8gYmFjayB0aGVpciBzaWduaW5nIHB1YmxpYyBrZXkuXHJcbiAgICBjb25zdCBpbml0aWF0b3JPbmVUaW1lUHJrID0gYXdhaXQgdGhpcy5rZXlGYWN0b3J5LmNyZWF0ZVBrY0tleSgpO1xyXG5cclxuICAgIC8vIE9wdGlvbiAxOiBOZXcgUEtDIGtleSBmb3Igc2lnbmluZ1xyXG4gICAgLy8gY29uc3QgaW5pdGlhdG9yU2lnUHJrID0gYXdhaXQgdGhpcy5rZXlTZXJ2aWNlLmNyZWF0ZVBrY1NpZ25LZXkoKTtcclxuXHJcbiAgICAvLyBPcHRpb24gMjogVXNlIHRoZSB1c2VyJ3MgZ2xvYmFsIHNpZ25pbmcga2V5LlxyXG4gICAgLy8gVGhpcyBrZXkgaXMgdXNlZCB0byBwcm92ZSB0aGUgaW5pdGlhdG9yJ3MgaWRlbnRpdHkuXHJcbiAgICBjb25zdCBpbml0aWF0b3JQcmsgPSBhd2FpdCB0aGlzLmtleVNlcnZpY2UuZ2V0Q3VycmVudFB4aygpO1xyXG4gICAgY29uc3QgaW5pdGlhdG9yU2lnUHJrID0gYXdhaXQgdGhpcy5rZXlTZXJ2aWNlLmdldEN1cnJlbnRTaWdQeGsoKTtcclxuXHJcbiAgICBsZXQgaW5pdGlhdG9yUGxhaW5EYXRhU2lnOiBzdHJpbmcgPSBudWxsO1xyXG5cclxuICAgIGlmIChjb250YWN0Q2FyZCAmJiBjb250YWN0Q2FyZC5vd25lclBsYWluRGF0YSkge1xyXG4gICAgICBpbml0aWF0b3JQbGFpbkRhdGFTaWcgPSBKU09OLnN0cmluZ2lmeShcclxuICAgICAgICBhd2FpdCB0aGlzLmVuY3J5cHRpb25TZXJ2aWNlLnNpZ24oXHJcbiAgICAgICAgICBpbml0aWF0b3JTaWdQcmsuandrLFxyXG4gICAgICAgICAgY29udGFjdENhcmQub3duZXJQbGFpbkRhdGFcclxuICAgICAgICApXHJcbiAgICAgICk7XHJcbiAgICB9XHJcblxyXG4gICAgY29uc3QgaW5pdGlhdG9yID0ge1xyXG4gICAgICBtZXNzYWdlLFxyXG4gICAgICBjb250YWN0Q2FyZDogY29udGFjdENhcmRcclxuICAgICAgICA/IHtcclxuICAgICAgICAgICAgcGxhaW5TaGFyZWRDaXBoZXJEYXRhSnNvbjogY29udGFjdENhcmQucGxhaW5TaGFyZWRDaXBoZXJEYXRhSnNvbixcclxuICAgICAgICAgIH1cclxuICAgICAgICA6IG51bGwsXHJcbiAgICB9O1xyXG5cclxuICAgIC8vIENvbnRlbnQgdG8gYmUgZW5jcnlwdGVkIHVzaW5nIHRoZSBPVEsuXHJcbiAgICBjb25zdCBwbGFpbk90S2V5Q2lwaGVyOiBQbGFpbk90S2V5Q2lwaGVyID0ge1xyXG4gICAgICBub25jZSxcclxuICAgICAgaW5pdGlhdG9yOiB7XHJcbiAgICAgICAgLi4uaW5pdGlhdG9yLFxyXG4gICAgICAgIG9uZVRpbWVQYms6IGluaXRpYXRvck9uZVRpbWVQcmsudG9KU09OKCksIC8vIG9uZXRpbWUgcHVibGljIGVuY3J5cHRpb24ga2V5IHJlc3BvbmRlciB1c2UgdG8gc2VuZCBkYXRhIGJhY2sgdG8gaW5pdGlhdG9yXHJcbiAgICAgICAgcGJrOiBpbml0aWF0b3JQcmsuandrLnRvSlNPTigpLCAvLyBwdWJsaWMgZW5jcnlwdGlvbiBrZXlcclxuICAgICAgICBzaWdQYms6IGluaXRpYXRvclNpZ1Byay5qd2sudG9KU09OKCksIC8vIHB1YmxpYyBzaWduaW5nIGtleVxyXG4gICAgICAgIHByb2ZpbGU6IHtcclxuICAgICAgICAgIHVzZXJuYW1lOiB1c2VyLnVzZXJuYW1lLFxyXG4gICAgICAgIH0sXHJcbiAgICAgIH0sXHJcbiAgICB9O1xyXG5cclxuICAgIGNvbnN0IG90S2V5Q2lwaGVyID0gYXdhaXQgdGhpcy5lbmNyeXB0aW9uU2VydmljZS5lbmNyeXB0KFxyXG4gICAgICBvdEtleSxcclxuICAgICAgcGxhaW5PdEtleUNpcGhlclxyXG4gICAgKTtcclxuXHJcbiAgICAvLyBDb250ZW50IHRvIGJlIGVuY3J5cHRlZCB1c2luZyB0aGUgaW5pdGlhdG9yJ3Mgcm9vdCBrZXkuXHJcbiAgICBjb25zdCBwbGFpbkluaXRpYXRvclJvb3RLZXlDaXBoZXI6IFBsYWluSW5pdGlhdG9yUm9vdEtleUNpcGhlciA9IHtcclxuICAgICAgbm9uY2UsXHJcbiAgICAgIG9uZVRpbWVQcms6IGluaXRpYXRvck9uZVRpbWVQcmsudG9KU09OKHRydWUpLFxyXG4gICAgICAvLyBTaG91bGQgbm90IG5lZWQgdG8ga2VlcCB0aGlzIGVuY3J5cHRlZCBzaW5jZSB3ZSBhcmUgdXNpbmcgdGhlIGdsb2JhbCBzaWduaW5nIGtleS5cclxuICAgICAgLy8gc2lnUHJrOiBpbml0aWF0b3JTaWdQcmsudG9KU09OKHRydWUpLFxyXG5cclxuICAgICAgLy8gU2F2ZSBpdCBpbiBjYXNlIHRoZSBpbml0aWF0b3Igd2FudCB0byBkZWNvZGUgdGhlIG90S2V5Q2lwaGVyLlxyXG4gICAgICAvLyBTaW5jZSB0aGUgb3RLZXkgaXMgb25seSB1c2VkIG9uY2UsIGFuZCB0aGF0IG90S2V5Q2lwaGVyIGNvbnRhaW5zIG9ubHlcclxuICAgICAgLy8gdGhlIHB1YmxpYyBrZXkgb2YgdGhlIGluaXRpYXRvciwgaXQncyBzYWZlIGp1c3QgbGVhdmUgdGhlIG90S2V5IHN0b3JlZCBoZXJlLlxyXG4gICAgICBvdEtleTogb3RLZXkudG9KU09OKHRydWUpLFxyXG4gICAgICAvLyBUaGVzZSBzaG91bGQgYmUgc3RvcmluZyBpbmZvcm1hdGlvbiBzdWNoIGFzIGhvdyB0aGUgZmllbGRzIG9mIHRoZSBzaGFyZWQgY29udGFjdCBjYXJkIGlzXHJcbiAgICAgIC8vIGRlcml2ZWQgZnJvbSB0aGUgbWFzdGVyIGNvbnRhY3QgY2FyZC5cclxuICAgICAgaW5pdGlhdG9yQ29udGFjdENhcmQ6IGNvbnRhY3RDYXJkLFxyXG4gICAgICBpbml0aWF0b3IsXHJcbiAgICB9O1xyXG5cclxuICAgIGNvbnN0IHJvb3RLZXkgPSBhd2FpdCB0aGlzLmtleVNlcnZpY2UuZ2V0Q3VycmVudFJvb3RLZXkoKTtcclxuICAgIGNvbnN0IGluaXRpYXRvclJvb3RLZXlDaXBoZXIgPSBhd2FpdCB0aGlzLmVuY3J5cHRpb25TZXJ2aWNlLmVuY3J5cHQoXHJcbiAgICAgIHJvb3RLZXkuandrLFxyXG4gICAgICBwbGFpbkluaXRpYXRvclJvb3RLZXlDaXBoZXJcclxuICAgICk7XHJcblxyXG4gICAgLy8gVGhlIHJhdyBPVEtcclxuICAgIGNvbnN0IG90S2V5Szogc3RyaW5nID0gKG90S2V5LnRvSlNPTih0cnVlKSBhcyBhbnkpLms7XHJcblxyXG4gICAgLy8gQVBJIGNhbGxcclxuICAgIGNvbnN0IHsgaW5pdGlhdGVLZXlFeGNoYW5nZU90ayB9ID0gYXdhaXQgdGhpcy5sckFwb2xsby5tdXRhdGU8YW55Pih7XHJcbiAgICAgIG11dGF0aW9uOiBJbml0aWF0ZU90a011dGF0aW9uLFxyXG4gICAgICB2YXJpYWJsZXM6IHtcclxuICAgICAgICBpbnB1dDoge1xyXG4gICAgICAgICAgLy8gVGhlc2Ugd2lsbCBiZSBzdG9yZWQgb24gdGhlIHNlcnZlclxyXG4gICAgICAgICAgaW5pdGlhdG9yUm9vdEtleUNpcGhlcjogSlNPTi5zdHJpbmdpZnkoaW5pdGlhdG9yUm9vdEtleUNpcGhlciksXHJcbiAgICAgICAgICBpbml0aWF0b3JQeGtJZDogaW5pdGlhdG9yUHJrLmlkLFxyXG4gICAgICAgICAgaW5pdGlhdG9yU2lnUHhrSWQ6IGluaXRpYXRvclNpZ1Byay5pZCxcclxuICAgICAgICAgIC8vIFRoZXNlIHdpbGwgYmUgc2VudCB0byB0aGUgcmVzcG9uZGVyXHJcbiAgICAgICAgICBvdEtleVBhcmFtczogSlNPTi5zdHJpbmdpZnkob3RLZXkudG9KU09OKCkpLFxyXG4gICAgICAgICAgb3RLZXlDaXBoZXI6IEpTT04uc3RyaW5naWZ5KG90S2V5Q2lwaGVyKSxcclxuICAgICAgICAgIHNlbmRFbWFpbDogZW1haWxcclxuICAgICAgICAgICAgPyB7XHJcbiAgICAgICAgICAgICAgICBlbWFpbCxcclxuICAgICAgICAgICAgICAgIHJhd090S2V5OiBvdEtleUssXHJcbiAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICA6IG51bGwsXHJcbiAgICAgICAgICBjcmVhdGVUcDogdHJ1ZSxcclxuICAgICAgICAgIGluaXRpYXRvclBsYWluRGF0YVNpZyxcclxuICAgICAgICAgIHVwZ3JhZGUsXHJcbiAgICAgICAgfSxcclxuICAgICAgfSxcclxuICAgIH0pO1xyXG4gICAgcmV0dXJuIHsga2V5RXhjaGFuZ2U6IGluaXRpYXRlS2V5RXhjaGFuZ2VPdGsua2V5RXhjaGFuZ2UsIG90S2V5SyB9O1xyXG4gIH1cclxuXHJcbiAgYXN5bmMgcmVzcG9uZE90ayh7XHJcbiAgICBpZCxcclxuICAgIHRva2VuLFxyXG4gICAgZGVjcnlwdGVkT3RrLFxyXG4gICAgbWVzc2FnZSxcclxuICAgIGluaXRpYXRvckNvbnRhY3RDYXJkLFxyXG4gICAgcmVzcG9uZGVyQ29udGFjdENhcmQ6IHNlbnRDb250YWN0Q2FyZCxcclxuICB9OiBSZXNwb25kT3RrSW5wdXQpOiBQcm9taXNlPFJlc3BvbmRPdGs+IHtcclxuICAgIGNvbnN0IHVzZXIgPSBhd2FpdCB0aGlzLmF1dGhTZXJ2aWNlLmdldFVzZXIoKTtcclxuICAgIGNvbnN0IHJvb3RLZXkgPSBhd2FpdCB0aGlzLmtleVNlcnZpY2UuZ2V0Q3VycmVudFJvb3RLZXkoKTtcclxuXHJcbiAgICBjb25zdCBtYXN0ZXJLZXlJZCA9IHRoaXMua2V5U2VydmljZS5nZXRDdXJyZW50TWFzdGVyS2V5KCkuaWQ7XHJcbiAgICBjb25zdCBtYXN0ZXJLZXkgPSBhd2FpdCB0aGlzLmtleVNlcnZpY2UuZ2V0Q3VycmVudE1hc3RlcktleSgpO1xyXG5cclxuICAgIGNvbnN0IHNoYXJlZEtleSA9IGF3YWl0IHRoaXMua2V5RmFjdG9yeS5jcmVhdGVLZXkoKTtcclxuICAgIGNvbnN0IG1rU2hhcmVkS2V5ID0gYXdhaXQgdGhpcy5rZXlGYWN0b3J5LmNyZWF0ZUtleSgpO1xyXG5cclxuICAgIGNvbnN0IHJrV3JhcHBlZFNoYXJlZEtleSA9IGF3YWl0IHRoaXMuZW5jcnlwdGlvblNlcnZpY2UuZW5jcnlwdChcclxuICAgICAgcm9vdEtleS5qd2ssXHJcbiAgICAgIHNoYXJlZEtleS50b0pTT04odHJ1ZSlcclxuICAgICk7XHJcbiAgICBjb25zdCBta1dyYXBwZWRNa1NoYXJlZEtleSA9IGF3YWl0IHRoaXMuZW5jcnlwdGlvblNlcnZpY2UuZW5jcnlwdChcclxuICAgICAgbWFzdGVyS2V5Lmp3ayxcclxuICAgICAgbWtTaGFyZWRLZXkudG9KU09OKHRydWUpXHJcbiAgICApO1xyXG5cclxuICAgIGNvbnN0IGluaXRpYXRvck9uZVRpbWVQYmsgPSBhd2FpdCBLRlMuYXNLZXkoXHJcbiAgICAgIGRlY3J5cHRlZE90ay5wbGFpbk90S2V5Q2lwaGVyLmluaXRpYXRvci5vbmVUaW1lUGJrXHJcbiAgICApO1xyXG5cclxuICAgIGNvbnN0IGluaXRpYXRvclBiayA9IGF3YWl0IEtGUy5hc0tleShcclxuICAgICAgZGVjcnlwdGVkT3RrLnBsYWluT3RLZXlDaXBoZXIuaW5pdGlhdG9yLnBia1xyXG4gICAgKTtcclxuICAgIGNvbnN0IGluaXRpYXRvclNpZ1BiayA9IGF3YWl0IEtGUy5hc0tleShcclxuICAgICAgZGVjcnlwdGVkT3RrLnBsYWluT3RLZXlDaXBoZXIuaW5pdGlhdG9yLnNpZ1Bia1xyXG4gICAgKTtcclxuXHJcbiAgICAvLyBPcHRpb24gMTogVXNpbmcgbmV3IFByayBmb3IgZWFjaCBUUCBwYWlyXHJcbiAgICAvLyBDcmVhdGUgYSBuZXcgcHVibGljIHNpZ25pbmcga2V5IGZvciB0aGUgcmVzcG9uZGVyLlxyXG4gICAgLy8gY29uc3QgcmVzcG9uZGVyU2lnUHJrID0gYXdhaXQgdGhpcy5rZXlTZXJ2aWNlLmNyZWF0ZVBrY1NpZ25LZXkoKVxyXG4gICAgLy8gY29uc3QgcmtXcmFwcGVkUmVzcG9uZGVyU2lnUHJrID0gYXdhaXQgdGhpcy5lbmNyeXB0KHJvb3RLZXksIHJlc3BvbmRlclNpZ1Byay50b0pTT04odHJ1ZSkpO1xyXG5cclxuICAgIC8vIE9wdGlvbiAyOiBSZXNwb25kZXIgYWxyZWFkeSBoYXMgYSBzaWduaW5nIFBya1xyXG4gICAgY29uc3QgcmVzcG9uZGVyUHJrID0gYXdhaXQgdGhpcy5rZXlTZXJ2aWNlLmdldEN1cnJlbnRQeGsoKTtcclxuICAgIGNvbnN0IHJlc3BvbmRlclNpZ1ByayA9IGF3YWl0IHRoaXMua2V5U2VydmljZS5nZXRDdXJyZW50U2lnUHhrKCk7XHJcblxyXG4gICAgY29uc3Qgc2lnbmVkSW5pdGlhdG9yUGJrID0gYXdhaXQgdGhpcy5lbmNyeXB0aW9uU2VydmljZS5zaWduKFxyXG4gICAgICByZXNwb25kZXJTaWdQcmsuandrLFxyXG4gICAgICBpbml0aWF0b3JQYmsudG9KU09OKClcclxuICAgICk7XHJcbiAgICBjb25zdCBzaWduZWRJbml0aWF0b3JTaWdQYmsgPSBhd2FpdCB0aGlzLmVuY3J5cHRpb25TZXJ2aWNlLnNpZ24oXHJcbiAgICAgIHJlc3BvbmRlclNpZ1Byay5qd2ssXHJcbiAgICAgIGluaXRpYXRvclNpZ1Biay50b0pTT04oKVxyXG4gICAgKTtcclxuXHJcbiAgICBjb25zdCBwbGFpbkluaXRpYXRvck9uZVRpbWVQYmtDaXBoZXI6IFBsYWluSW5pdGlhdG9yT25lVGltZVBia0NpcGhlciA9IHtcclxuICAgICAgbm9uY2U6IGRlY3J5cHRlZE90ay5wbGFpbk90S2V5Q2lwaGVyLm5vbmNlLFxyXG4gICAgICBzaGFyZWRLZXk6IHNoYXJlZEtleS50b0pTT04odHJ1ZSksXHJcbiAgICAgIG1rU2hhcmVkS2V5OiBta1NoYXJlZEtleS50b0pTT04odHJ1ZSksXHJcbiAgICAgIHJlc3BvbmRlcjoge1xyXG4gICAgICAgIHBiazogcmVzcG9uZGVyUHJrLmp3ay50b0pTT04oKSwgLy8gcHVibGljIGtleVxyXG4gICAgICAgIHNpZ1BiazogcmVzcG9uZGVyU2lnUHJrLmp3ay50b0pTT04oKSwgLy8gcHVibGljIGtleVxyXG4gICAgICAgIHByb2ZpbGU6IHtcclxuICAgICAgICAgIHVzZXJuYW1lOiB1c2VyLnVzZXJuYW1lLFxyXG4gICAgICAgIH0sXHJcbiAgICAgICAgbWVzc2FnZSxcclxuICAgICAgfSxcclxuICAgIH07XHJcblxyXG4gICAgbGV0IHJlY2VpdmVkQ2FyZElucHV0O1xyXG4gICAgaWYgKGRlY3J5cHRlZE90ay5wbGFpbk90S2V5Q2lwaGVyLmluaXRpYXRvci5jb250YWN0Q2FyZCkge1xyXG4gICAgICAvLyBTZXQgdGhlIGluZm8gYWJvdXQgdGhlIGluaXRpYXRvciB0byBiZSB0aGUgb25lcyBzZW50IGJ5IHRoZSBpbml0aWF0b3IuIFdlIG5lZWQgdGggcmVzcG9uZGVyIHRvIGRvIHRoZSBlbmNyeXB0aW9uIGhlcmVcclxuICAgICAgLy8gYmVjYXVzZSB0aGUgaW5pdGlhdG9yIGRvZXMgbm90IGhhdmUgdGhlIHNoYXJlZCBrZXkgeWV0LCBhbmQgd2Ugd2FudCB0aGUgcmVzcG9uZGVyIHRvIGhhdmUgYSBmdW5jdGlvbmFsIGNvbnRhY3QgY2FyZCBhZnRlclxyXG4gICAgICAvLyB0aGlzIGV4Y2hhbmdlLiBUaGUgaW5pdGlhdG9yIGNhbiBkb3VibGUgY2hlY2sgdGhlIGNvbnRhY3QgZGV0YWlscyBhcmUgY29ycmVjdCBhbmQgc2lnbiBpdCB3aGVuIGl0IGNvbXBsZXRlcyB0aGUgZXhjaGFuZ2UuXHJcbiAgICAgIGNvbnN0IHBsYWluU2hhcmVkQ2lwaGVyRGF0YUpzb24gPVxyXG4gICAgICAgIGRlY3J5cHRlZE90ay5wbGFpbk90S2V5Q2lwaGVyLmluaXRpYXRvci5jb250YWN0Q2FyZFxyXG4gICAgICAgICAgLnBsYWluU2hhcmVkQ2lwaGVyRGF0YUpzb247XHJcblxyXG4gICAgICAvLyBDcmVhdGUga2V5c1xyXG4gICAgICBjb25zdCByZWNlaXZlcktleSA9IGF3YWl0IHRoaXMua2V5RmFjdG9yeS5jcmVhdGVLZXkoKTtcclxuICAgICAgY29uc3QgY2NTaGFyZWRLZXkgPSBhd2FpdCB0aGlzLmtleUZhY3RvcnkuY3JlYXRlS2V5KCk7XHJcbiAgICAgIGNvbnN0IHNpZ1B4ayA9IGF3YWl0IHRoaXMua2V5U2VydmljZS5nZXRDdXJyZW50U2lnUHhrKCk7XHJcblxyXG4gICAgICByZWNlaXZlZENhcmRJbnB1dCA9IHtcclxuICAgICAgICByZWNlaXZlcldyYXBwZWRLZXk6IEpTT04uc3RyaW5naWZ5KFxyXG4gICAgICAgICAgYXdhaXQgdGhpcy5lbmNyeXB0aW9uU2VydmljZS5lbmNyeXB0KFxyXG4gICAgICAgICAgICByb290S2V5Lmp3ayxcclxuICAgICAgICAgICAgcmVjZWl2ZXJLZXkudG9KU09OKHRydWUpXHJcbiAgICAgICAgICApXHJcbiAgICAgICAgKSxcclxuICAgICAgICByZWNlaXZlcldyYXBwaW5nS2V5SWQ6IHJvb3RLZXkuaWQsXHJcbiAgICAgICAgcmVjZWl2ZXJDaXBoZXJEYXRhOiBpbml0aWF0b3JDb250YWN0Q2FyZFxyXG4gICAgICAgICAgPyBKU09OLnN0cmluZ2lmeShcclxuICAgICAgICAgICAgICBhd2FpdCB0aGlzLmVuY3J5cHRpb25TZXJ2aWNlLmVuY3J5cHQoXHJcbiAgICAgICAgICAgICAgICByZWNlaXZlcktleSxcclxuICAgICAgICAgICAgICAgIGluaXRpYXRvckNvbnRhY3RDYXJkLnBsYWluUmVjZWl2ZXJDaXBoZXJEYXRhSnNvblxyXG4gICAgICAgICAgICAgIClcclxuICAgICAgICAgICAgKVxyXG4gICAgICAgICAgOiAnJyxcclxuICAgICAgICBzaGFyZWRXcmFwcGVkS2V5OiBKU09OLnN0cmluZ2lmeShcclxuICAgICAgICAgIGF3YWl0IHRoaXMuZW5jcnlwdGlvblNlcnZpY2UuZW5jcnlwdChcclxuICAgICAgICAgICAgc2hhcmVkS2V5LFxyXG4gICAgICAgICAgICBjY1NoYXJlZEtleS50b0pTT04odHJ1ZSlcclxuICAgICAgICAgIClcclxuICAgICAgICApLFxyXG4gICAgICB9O1xyXG5cclxuICAgICAgY29uc3Qgc2hhcmVkQ2lwaGVyRGF0YSA9IGF3YWl0IHRoaXMuZW5jcnlwdGlvblNlcnZpY2UuZW5jcnlwdChcclxuICAgICAgICBjY1NoYXJlZEtleSxcclxuICAgICAgICBwbGFpblNoYXJlZENpcGhlckRhdGFKc29uXHJcbiAgICAgICk7XHJcbiAgICAgIHJlY2VpdmVkQ2FyZElucHV0LnNoYXJlZENpcGhlckRhdGFTaWcgPSBKU09OLnN0cmluZ2lmeShcclxuICAgICAgICBhd2FpdCB0aGlzLmVuY3J5cHRpb25TZXJ2aWNlLnNpZ24oc2lnUHhrLmp3aywgc2hhcmVkQ2lwaGVyRGF0YSlcclxuICAgICAgKTtcclxuICAgICAgcmVjZWl2ZWRDYXJkSW5wdXQuc2lnUHhrSWQgPSBzaWdQeGsuaWQ7XHJcblxyXG4gICAgICBwbGFpbkluaXRpYXRvck9uZVRpbWVQYmtDaXBoZXIucmVzcG9uZGVyLmNvbnRhY3RDYXJkID0ge1xyXG4gICAgICAgIC4uLnBsYWluSW5pdGlhdG9yT25lVGltZVBia0NpcGhlci5yZXNwb25kZXIuY29udGFjdENhcmQsXHJcbiAgICAgICAgc2hhcmVkQ2lwaGVyS2V5OiBjY1NoYXJlZEtleS50b0pTT04odHJ1ZSksXHJcbiAgICAgIH07XHJcbiAgICB9XHJcblxyXG4gICAgbGV0IHNlbnRDYXJkSW5wdXQ7XHJcbiAgICBpZiAoc2VudENvbnRhY3RDYXJkKSB7XHJcbiAgICAgIC8vIENyZWF0ZSBrZXlzXHJcbiAgICAgIGNvbnN0IG93bmVyS2V5ID0gYXdhaXQgdGhpcy5rZXlGYWN0b3J5LmNyZWF0ZUtleSgpO1xyXG4gICAgICBjb25zdCBjY1NoYXJlZEtleSA9IGF3YWl0IHRoaXMua2V5RmFjdG9yeS5jcmVhdGVLZXkoKTtcclxuICAgICAgY29uc3Qgc2lnUHhrID0gYXdhaXQgdGhpcy5rZXlTZXJ2aWNlLmdldEN1cnJlbnRTaWdQeGsoKTtcclxuXHJcbiAgICAgIHNlbnRDYXJkSW5wdXQgPSB7XHJcbiAgICAgICAgb3duZXJXcmFwcGVkS2V5OiBKU09OLnN0cmluZ2lmeShcclxuICAgICAgICAgIGF3YWl0IHRoaXMuZW5jcnlwdGlvblNlcnZpY2UuZW5jcnlwdChcclxuICAgICAgICAgICAgcm9vdEtleS5qd2ssXHJcbiAgICAgICAgICAgIG93bmVyS2V5LnRvSlNPTih0cnVlKVxyXG4gICAgICAgICAgKVxyXG4gICAgICAgICksXHJcbiAgICAgICAgb3duZXJXcmFwcGluZ0tleUlkOiByb290S2V5LmlkLFxyXG4gICAgICAgIG93bmVyQ2lwaGVyRGF0YTogc2VudENvbnRhY3RDYXJkLnBsYWluT3duZXJDaXBoZXJEYXRhSnNvblxyXG4gICAgICAgICAgPyBKU09OLnN0cmluZ2lmeShcclxuICAgICAgICAgICAgICBhd2FpdCB0aGlzLmVuY3J5cHRpb25TZXJ2aWNlLmVuY3J5cHQoXHJcbiAgICAgICAgICAgICAgICBvd25lcktleSxcclxuICAgICAgICAgICAgICAgIHNlbnRDb250YWN0Q2FyZC5wbGFpbk93bmVyQ2lwaGVyRGF0YUpzb25cclxuICAgICAgICAgICAgICApXHJcbiAgICAgICAgICAgIClcclxuICAgICAgICAgIDogJycsXHJcblxyXG4gICAgICAgIHNoYXJlZFdyYXBwZWRLZXk6IEpTT04uc3RyaW5naWZ5KFxyXG4gICAgICAgICAgYXdhaXQgdGhpcy5lbmNyeXB0aW9uU2VydmljZS5lbmNyeXB0KFxyXG4gICAgICAgICAgICBzaGFyZWRLZXksXHJcbiAgICAgICAgICAgIGNjU2hhcmVkS2V5LnRvSlNPTih0cnVlKVxyXG4gICAgICAgICAgKVxyXG4gICAgICAgICksXHJcbiAgICAgIH07XHJcblxyXG4gICAgICBjb25zdCBzaGFyZWRDaXBoZXJEYXRhID0gYXdhaXQgdGhpcy5lbmNyeXB0aW9uU2VydmljZS5lbmNyeXB0KFxyXG4gICAgICAgIGNjU2hhcmVkS2V5LFxyXG4gICAgICAgIHNlbnRDb250YWN0Q2FyZC5wbGFpblNoYXJlZENpcGhlckRhdGFKc29uXHJcbiAgICAgICk7XHJcbiAgICAgIHNlbnRDYXJkSW5wdXQuc2hhcmVkQ2lwaGVyRGF0YVNpZyA9IEpTT04uc3RyaW5naWZ5KFxyXG4gICAgICAgIGF3YWl0IHRoaXMuZW5jcnlwdGlvblNlcnZpY2Uuc2lnbihzaWdQeGsuandrLCBzaGFyZWRDaXBoZXJEYXRhKVxyXG4gICAgICApO1xyXG4gICAgICBzZW50Q2FyZElucHV0LnNpZ1B4a0lkID0gc2lnUHhrLmlkO1xyXG5cclxuICAgICAgaWYgKHNlbnRDb250YWN0Q2FyZC5vd25lclBsYWluRGF0YSkge1xyXG4gICAgICAgIHNlbnRDYXJkSW5wdXQub3duZXJQbGFpbkRhdGFTaWcgPSBKU09OLnN0cmluZ2lmeShcclxuICAgICAgICAgIGF3YWl0IHRoaXMuZW5jcnlwdGlvblNlcnZpY2Uuc2lnbihcclxuICAgICAgICAgICAgcmVzcG9uZGVyU2lnUHJrLmp3ayxcclxuICAgICAgICAgICAgc2VudENvbnRhY3RDYXJkLm93bmVyUGxhaW5EYXRhXHJcbiAgICAgICAgICApXHJcbiAgICAgICAgKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgLy8gQ29udGFjdCBjYXJkIGluZm8gcmVhZGFibGUgYnkgdGhlIGluaXRpYXRvclxyXG4gICAgICBwbGFpbkluaXRpYXRvck9uZVRpbWVQYmtDaXBoZXIucmVzcG9uZGVyLmNvbnRhY3RDYXJkID0ge1xyXG4gICAgICAgIC4uLnBsYWluSW5pdGlhdG9yT25lVGltZVBia0NpcGhlci5yZXNwb25kZXIuY29udGFjdENhcmQsXHJcbiAgICAgICAgcGxhaW5TaGFyZWRDaXBoZXJEYXRhSnNvbjogc2VudENvbnRhY3RDYXJkLnBsYWluU2hhcmVkQ2lwaGVyRGF0YUpzb24sXHJcbiAgICAgIH07XHJcbiAgICB9XHJcblxyXG4gICAgLy8gRW5jcnlwdCB3aXRoIG9uZS10aW1lIHB1YmxpYyBrZXlcclxuICAgIGxldCBpbml0aWF0b3JPbmVUaW1lUGJrQ2lwaGVyID0gYXdhaXQgdGhpcy5lbmNyeXB0aW9uU2VydmljZS5lbmNyeXB0KFxyXG4gICAgICBpbml0aWF0b3JPbmVUaW1lUGJrLFxyXG4gICAgICBwbGFpbkluaXRpYXRvck9uZVRpbWVQYmtDaXBoZXJcclxuICAgICk7XHJcblxyXG4gICAgLy8gRW5jcnlwdCB3aXRoIHRoZSBvdGsgYWdhaW4gdG8ga2VlcCB1c2Ugb2YgYXN5bW1ldHJpYyBrZXlzIHRvIGEgbWluaW11bS5cclxuICAgIGluaXRpYXRvck9uZVRpbWVQYmtDaXBoZXIgPSBhd2FpdCB0aGlzLmVuY3J5cHRpb25TZXJ2aWNlLmVuY3J5cHQoXHJcbiAgICAgIGRlY3J5cHRlZE90ay5vdEtleSxcclxuICAgICAgaW5pdGlhdG9yT25lVGltZVBia0NpcGhlclxyXG4gICAgKTtcclxuXHJcbiAgICBjb25zdCB7IHJlc3BvbmRLZXlFeGNoYW5nZU90ayB9ID0gYXdhaXQgdGhpcy5sckFwb2xsby5tdXRhdGU8YW55Pih7XHJcbiAgICAgIG11dGF0aW9uOiBSZXNwb25kT3RrTXV0YXRpb24sXHJcbiAgICAgIHZhcmlhYmxlczoge1xyXG4gICAgICAgIGlucHV0OiB7XHJcbiAgICAgICAgICBrZXlFeGNoYW5nZUlkOiBpZCxcclxuICAgICAgICAgIGtleUV4Y2hhbmdlVG9rZW46IHRva2VuLFxyXG4gICAgICAgICAgcm9vdEtleUlkOiByb290S2V5LmlkLFxyXG4gICAgICAgICAgbWFzdGVyS2V5SWQsXHJcbiAgICAgICAgICAvLyBUaGVzZSB3aWxsIGJlIHN0b3JlZCBvbiB0aGUgc2VydmVyXHJcbiAgICAgICAgICByZXNwb25kZXJQeGtJZDogcmVzcG9uZGVyUHJrLmlkLFxyXG4gICAgICAgICAgcmVzcG9uZGVyU2lnUHhrSWQ6IHJlc3BvbmRlclNpZ1Byay5pZCxcclxuICAgICAgICAgIHNpZ25lZEluaXRpYXRvclBiazogSlNPTi5zdHJpbmdpZnkoc2lnbmVkSW5pdGlhdG9yUGJrKSxcclxuICAgICAgICAgIHNpZ25lZEluaXRpYXRvclNpZ1BiazogSlNPTi5zdHJpbmdpZnkoc2lnbmVkSW5pdGlhdG9yU2lnUGJrKSxcclxuICAgICAgICAgIC8vIHJrV3JhcHBlZEluaXRpYXRvclNpZ1BiazogSlNPTi5zdHJpbmdpZnkocmtXcmFwcGVkSW5pdGlhdG9yU2lnUGJrKSxcclxuXHJcbiAgICAgICAgICAvLyBPcHRpb24gMTogVXNpbmcgbmV3IFByayBmb3IgZWFjaCBUUCBwYWlyXHJcbiAgICAgICAgICAvLyBya1dyYXBwZWRSZXNwb25kZXJTaWdQcms6IEpTT04uc3RyaW5naWZ5KHJrV3JhcHBlZFJlc3BvbmRlclNpZ1ByayksXHJcbiAgICAgICAgICBya1dyYXBwZWRTaGFyZWRLZXk6IEpTT04uc3RyaW5naWZ5KHJrV3JhcHBlZFNoYXJlZEtleSksXHJcbiAgICAgICAgICBta1dyYXBwZWRNa1NoYXJlZEtleTogSlNPTi5zdHJpbmdpZnkobWtXcmFwcGVkTWtTaGFyZWRLZXkpLFxyXG4gICAgICAgICAgLy8gVGhlc2Ugd2lsbCBiZSBzZW50IHRvIHRoZSBpbml0aWF0b3JcclxuICAgICAgICAgIGluaXRpYXRvck9uZVRpbWVQYmtDaXBoZXI6IEpTT04uc3RyaW5naWZ5KGluaXRpYXRvck9uZVRpbWVQYmtDaXBoZXIpLFxyXG4gICAgICAgICAgaW5pdGlhdG9yQ29udGFjdENhcmQ6IHJlY2VpdmVkQ2FyZElucHV0LFxyXG4gICAgICAgICAgcmVzcG9uZGVyQ29udGFjdENhcmQ6IHNlbnRDYXJkSW5wdXQsXHJcbiAgICAgICAgfSxcclxuICAgICAgfSxcclxuICAgIH0pO1xyXG5cclxuICAgIHJldHVybiB7XHJcbiAgICAgIGtleUV4Y2hhbmdlOiByZXNwb25kS2V5RXhjaGFuZ2VPdGsua2V5RXhjaGFuZ2UsXHJcbiAgICAgIHVzZXJTaGFyZWRLZXk6IHJlc3BvbmRLZXlFeGNoYW5nZU90ay51c2VyU2hhcmVkS2V5LFxyXG4gICAgICB0cDogcmVzcG9uZEtleUV4Y2hhbmdlT3RrLnRwLFxyXG4gICAgfTtcclxuICB9XHJcblxyXG4gIGFzeW5jIGNvbXBsZXRlT3RrKFxyXG4gICAga2V5RXhjaGFuZ2VJZDogc3RyaW5nLFxyXG4gICAgaW5pdGlhdG9yUm9vdEtleUNpcGhlcjogc3RyaW5nLFxyXG4gICAgaW5pdGlhdG9yT25lVGltZVBia0NpcGhlcjogc3RyaW5nLFxyXG4gICAgcmVzcG9uZGVyQ29udGFjdENhcmQ/OiBzdHJpbmdcclxuICApOiBQcm9taXNlPENvbXBsZXRlT3RrPiB7XHJcbiAgICBjb25zdCByb290S2V5ID0gYXdhaXQgdGhpcy5rZXlTZXJ2aWNlLmdldEN1cnJlbnRSb290S2V5KCk7XHJcbiAgICBjb25zdCBtYXN0ZXJLZXkgPSBhd2FpdCB0aGlzLmtleVNlcnZpY2UuZ2V0Q3VycmVudE1hc3RlcktleSgpO1xyXG5cclxuICAgIC8vIERlY3J5cHQgdXNpbmcgdGhlIHJvb3Qga2V5IHRvIGdldCB0aGUgUHJrXHJcbiAgICBjb25zdCBwbGFpbkluaXRpYXRvclJvb3RLZXlDaXBoZXIgPSAoKGF3YWl0IHRoaXMuZW5jcnlwdGlvblNlcnZpY2UuZGVjcnlwdChcclxuICAgICAgcm9vdEtleS5qd2ssXHJcbiAgICAgIGluaXRpYXRvclJvb3RLZXlDaXBoZXJcclxuICAgICkpIGFzIHVua25vd24pIGFzIFBsYWluSW5pdGlhdG9yUm9vdEtleUNpcGhlcjtcclxuXHJcbiAgICAvLyBUaGUgUHJrIGlzIHNpbmdsZS11c2UgYW5kIG9ubHkgdXNlZCB0byBzZW5kIGluZm9ybWF0aW9uIGZyb20gdGhlIHJlc3BvbmRlciBiYWNrIHRvIHRoZSBpbml0aWF0b3IuXHJcbiAgICBjb25zdCBwbGFpbkluaXRpYXRvck9uZVRpbWVQYmtDaXBoZXIgPSBhd2FpdCB0aGlzLmRlY3J5cHRSZXNwb25zZUNpcGhlcihcclxuICAgICAgYXdhaXQgS0ZTLmFzS2V5KHBsYWluSW5pdGlhdG9yUm9vdEtleUNpcGhlci5vdEtleSksXHJcbiAgICAgIGF3YWl0IEtGUy5hc0tleShwbGFpbkluaXRpYXRvclJvb3RLZXlDaXBoZXIub25lVGltZVByayksXHJcbiAgICAgIGluaXRpYXRvck9uZVRpbWVQYmtDaXBoZXJcclxuICAgICk7XHJcblxyXG4gICAgLy8gQ2hlY2sgdGhlIG5vbmNlIG1hdGNoIHRvIGVuc3VyZSB0aGUgcmVzcG9uZGVyIHdhcyB0aGUgb25lIGhvbGRpbmcgdGhlIE9US1xyXG4gICAgaWYgKFxyXG4gICAgICBwbGFpbkluaXRpYXRvclJvb3RLZXlDaXBoZXIubm9uY2UgIT09IHBsYWluSW5pdGlhdG9yT25lVGltZVBia0NpcGhlci5ub25jZVxyXG4gICAgKSB7XHJcbiAgICAgIHRocm93IG5ldyBMckNvZGVNaXNtYXRjaEV4Y2VwdGlvbihcclxuICAgICAgICAnVGhlIG5vbmNlIHJldHVybmVkIGJ5IHJlc3BvbmRlciBkb2VzIG5vdCBtYXRjaCB3aXRoIHRoZSBvbmUgY3JlYXRlZCBieSB0aGUgaW5pdGlhdG9yLidcclxuICAgICAgKTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBPcHRpb24gMTogQXNzdW1pbmcgdGhlIHNpZ25pbmcga2V5IGlzIHVuaXF1ZSBiZXR3ZWVuIHVzZXJzLlxyXG4gICAgLy8gY29uc3QgaW5pdGlhdG9yU2lnUHJrID0gYXdhaXQgS0ZTLmFzS2V5KGtlLnBsYWluSW5pdGlhdG9yUm9vdEtleUNpcGhlci5zaWdQcmspO1xyXG4gICAgLy8gY29uc3QgcmtXcmFwcGVkSW5pdGlhdG9yU2lnUHJrID0gYXdhaXQgdGhpcy5lbmNyeXB0KHJvb3RLZXksIGluaXRpYXRvclNpZ1Byay50b0pTT04odHJ1ZSkpO1xyXG5cclxuICAgIC8vIE9wdGlvbiAyOiBVc2UgdGhlIHVzZXIncyBnbG9iYWwgc2lnbmluZyBrZXkuXHJcbiAgICAvLyBJbiB0aGlzIGNhc2UgdGhlIGluaXRpYXRvclNpZ1ByayBpcyBhbHJlYWR5IGEgcGFydCBvZiB0aGUga2V5IGdyYXBoLlxyXG4gICAgLy8gU28gdGhlcmUncyBub3RoaW5nIHRvIGRvIGhlcmUuXHJcblxyXG4gICAgLy8gUHJvdGVjdGVkIHRoZSBzaWduaW5nIHB1YmxpYyBrZXkgb2YgdGhlIHJlc3BvbmRlci5cclxuICAgIGNvbnN0IGluaXRpYXRvclNpZ1ByayA9IGF3YWl0IHRoaXMua2V5U2VydmljZS5nZXRDdXJyZW50U2lnUHhrKCk7XHJcbiAgICBjb25zdCByZXNwb25kZXJTaWdQYmsgPSBhd2FpdCBLRlMuYXNLZXkoXHJcbiAgICAgIHBsYWluSW5pdGlhdG9yT25lVGltZVBia0NpcGhlci5yZXNwb25kZXIuc2lnUGJrXHJcbiAgICApO1xyXG4gICAgY29uc3QgcmVzcG9uZGVyUGJrID0gYXdhaXQgS0ZTLmFzS2V5KFxyXG4gICAgICBwbGFpbkluaXRpYXRvck9uZVRpbWVQYmtDaXBoZXIucmVzcG9uZGVyLnBia1xyXG4gICAgKTtcclxuXHJcbiAgICBjb25zdCBzaWduZWRSZXNwb25kZXJQYmsgPSBhd2FpdCB0aGlzLmVuY3J5cHRpb25TZXJ2aWNlLnNpZ24oXHJcbiAgICAgIGluaXRpYXRvclNpZ1Byay5qd2ssXHJcbiAgICAgIHJlc3BvbmRlclBiay50b0pTT04oKVxyXG4gICAgKTtcclxuICAgIGNvbnN0IHNpZ25lZFJlc3BvbmRlclNpZ1BiayA9IGF3YWl0IHRoaXMuZW5jcnlwdGlvblNlcnZpY2Uuc2lnbihcclxuICAgICAgaW5pdGlhdG9yU2lnUHJrLmp3ayxcclxuICAgICAgcmVzcG9uZGVyU2lnUGJrLnRvSlNPTigpXHJcbiAgICApO1xyXG5cclxuICAgIGNvbnN0IHNoYXJlZEtleSA9IGF3YWl0IEtGUy5hc0tleShwbGFpbkluaXRpYXRvck9uZVRpbWVQYmtDaXBoZXIuc2hhcmVkS2V5KTtcclxuICAgIGNvbnN0IHJrV3JhcHBlZFNoYXJlZEtleSA9IGF3YWl0IHRoaXMuZW5jcnlwdGlvblNlcnZpY2UuZW5jcnlwdChcclxuICAgICAgcm9vdEtleS5qd2ssXHJcbiAgICAgIHNoYXJlZEtleS50b0pTT04odHJ1ZSlcclxuICAgICk7XHJcblxyXG4gICAgY29uc3QgbWtTaGFyZWRLZXkgPSBhd2FpdCBLRlMuYXNLZXkoXHJcbiAgICAgIHBsYWluSW5pdGlhdG9yT25lVGltZVBia0NpcGhlci5ta1NoYXJlZEtleVxyXG4gICAgKTtcclxuICAgIGNvbnN0IG1rV3JhcHBlZE1rU2hhcmVkS2V5ID0gYXdhaXQgdGhpcy5lbmNyeXB0aW9uU2VydmljZS5lbmNyeXB0KFxyXG4gICAgICBtYXN0ZXJLZXkuandrLFxyXG4gICAgICBta1NoYXJlZEtleS50b0pTT04odHJ1ZSlcclxuICAgICk7XHJcblxyXG4gICAgbGV0IHJlc3BvbmRlckNvbnRhY3RDYXJkQ2lwaGVySW5wdXQ7XHJcbiAgICBpZiAocmVzcG9uZGVyQ29udGFjdENhcmQpIHtcclxuICAgICAgLy8gQ3JlYXRlIGtleVxyXG4gICAgICBjb25zdCByZWNlaXZlcktleSA9IGF3YWl0IHRoaXMua2V5RmFjdG9yeS5jcmVhdGVLZXkoKTtcclxuXHJcbiAgICAgIHJlc3BvbmRlckNvbnRhY3RDYXJkQ2lwaGVySW5wdXQgPSB7XHJcbiAgICAgICAgcmVjZWl2ZXJXcmFwcGVkS2V5OiBKU09OLnN0cmluZ2lmeShcclxuICAgICAgICAgIGF3YWl0IHRoaXMuZW5jcnlwdGlvblNlcnZpY2UuZW5jcnlwdChcclxuICAgICAgICAgICAgcm9vdEtleS5qd2ssXHJcbiAgICAgICAgICAgIHJlY2VpdmVyS2V5LnRvSlNPTih0cnVlKVxyXG4gICAgICAgICAgKVxyXG4gICAgICAgICksXHJcbiAgICAgICAgcmVjZWl2ZXJXcmFwcGluZ0tleUlkOiByb290S2V5LmlkLFxyXG4gICAgICAgIHJlY2VpdmVyQ2lwaGVyRGF0YTogSlNPTi5zdHJpbmdpZnkoXHJcbiAgICAgICAgICBhd2FpdCB0aGlzLmVuY3J5cHRpb25TZXJ2aWNlLmVuY3J5cHQoXHJcbiAgICAgICAgICAgIHJlY2VpdmVyS2V5LFxyXG4gICAgICAgICAgICByZXNwb25kZXJDb250YWN0Q2FyZFxyXG4gICAgICAgICAgKVxyXG4gICAgICAgICksXHJcbiAgICAgIH07XHJcbiAgICB9XHJcblxyXG4gICAgLy8gR2V0IHRoZSBkYXRhIG5lZWRlZCBmcm9tIHRoZSBpbml0aWF0b3IncyBjaXBoZXIgZGF0YS5cclxuICAgIGxldCBpbml0aWF0b3JDb250YWN0Q2FyZENpcGhlcklucHV0O1xyXG4gICAgbGV0IGluaXRpYXRvckNvbnRhY3RDYXJkU2hhcmVkQ2lwaGVySW5wdXQ7XHJcbiAgICBpZiAocGxhaW5Jbml0aWF0b3JSb290S2V5Q2lwaGVyLmluaXRpYXRvckNvbnRhY3RDYXJkKSB7XHJcbiAgICAgIGNvbnN0IGluaXRpYXRvckNvbnRhY3RDYXJkID1cclxuICAgICAgICBwbGFpbkluaXRpYXRvclJvb3RLZXlDaXBoZXIuaW5pdGlhdG9yQ29udGFjdENhcmQ7XHJcbiAgICAgIGNvbnN0IG93bmVyS2V5ID0gYXdhaXQgdGhpcy5rZXlGYWN0b3J5LmNyZWF0ZUtleSgpO1xyXG4gICAgICBjb25zdCBzaGFyZWRDaXBoZXJLZXkgPSBhd2FpdCBLRlMuYXNLZXkoXHJcbiAgICAgICAgcGxhaW5Jbml0aWF0b3JPbmVUaW1lUGJrQ2lwaGVyLnJlc3BvbmRlci5jb250YWN0Q2FyZC5zaGFyZWRDaXBoZXJLZXlcclxuICAgICAgKTtcclxuXHJcbiAgICAgIGNvbnN0IG93bmVyV3JhcHBlZEtleSA9IEpTT04uc3RyaW5naWZ5KFxyXG4gICAgICAgIGF3YWl0IHRoaXMuZW5jcnlwdGlvblNlcnZpY2UuZW5jcnlwdChyb290S2V5Lmp3aywgb3duZXJLZXkudG9KU09OKHRydWUpKVxyXG4gICAgICApO1xyXG4gICAgICBjb25zdCBvd25lckNpcGhlckRhdGEgPSBpbml0aWF0b3JDb250YWN0Q2FyZC5wbGFpbk93bmVyQ2lwaGVyRGF0YUpzb25cclxuICAgICAgICA/IEpTT04uc3RyaW5naWZ5KFxyXG4gICAgICAgICAgICBhd2FpdCB0aGlzLmVuY3J5cHRpb25TZXJ2aWNlLmVuY3J5cHQoXHJcbiAgICAgICAgICAgICAgb3duZXJLZXksXHJcbiAgICAgICAgICAgICAgaW5pdGlhdG9yQ29udGFjdENhcmQucGxhaW5Pd25lckNpcGhlckRhdGFKc29uXHJcbiAgICAgICAgICAgIClcclxuICAgICAgICAgIClcclxuICAgICAgICA6ICcnO1xyXG5cclxuICAgICAgaW5pdGlhdG9yQ29udGFjdENhcmRDaXBoZXJJbnB1dCA9IHtcclxuICAgICAgICBvd25lcldyYXBwZWRLZXksXHJcbiAgICAgICAgb3duZXJXcmFwcGluZ0tleUlkOiByb290S2V5LmlkLFxyXG4gICAgICAgIG93bmVyQ2lwaGVyRGF0YSxcclxuICAgICAgfTtcclxuXHJcbiAgICAgIGluaXRpYXRvckNvbnRhY3RDYXJkU2hhcmVkQ2lwaGVySW5wdXQgPSB7XHJcbiAgICAgICAgc2lnUHhrSWQ6IGluaXRpYXRvclNpZ1Byay5pZCxcclxuICAgICAgfTtcclxuXHJcbiAgICAgIGNvbnN0IHNoYXJlZENpcGhlckRhdGEgPSBhd2FpdCB0aGlzLmVuY3J5cHRpb25TZXJ2aWNlLmVuY3J5cHQoXHJcbiAgICAgICAgc2hhcmVkQ2lwaGVyS2V5LFxyXG4gICAgICAgIGluaXRpYXRvckNvbnRhY3RDYXJkLnBsYWluU2hhcmVkQ2lwaGVyRGF0YUpzb25cclxuICAgICAgKTtcclxuICAgICAgaW5pdGlhdG9yQ29udGFjdENhcmRTaGFyZWRDaXBoZXJJbnB1dC5zaGFyZWRDaXBoZXJEYXRhU2lnID0gSlNPTi5zdHJpbmdpZnkoXHJcbiAgICAgICAgYXdhaXQgdGhpcy5lbmNyeXB0aW9uU2VydmljZS5zaWduKGluaXRpYXRvclNpZ1Byay5qd2ssIHNoYXJlZENpcGhlckRhdGEpXHJcbiAgICAgICk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gVE9ETyBpZGVhbGx5IHdlIHVwZGF0ZSB0aGUgc2hhcmVkIGRhdGEgaW4gdGhlIGNvbnRhY3QgY2FyZCBzZW50IHRvIHRoZSByZXNwb25kZXIgYXMgd2VsbCBzaW5jZSB0aGF0XHJcbiAgICAvLyBDQyB3YXMgY3JlYXRlZCBieSB0aGUgcmVzcG9uZGVyLlxyXG5cclxuICAgIGNvbnN0IHJlcyA9IGF3YWl0IHRoaXMubHJBcG9sbG8ubXV0YXRlPGFueT4oe1xyXG4gICAgICBtdXRhdGlvbjogQ29tcGxldGVPdGtNdXRhdGlvbixcclxuICAgICAgdmFyaWFibGVzOiB7XHJcbiAgICAgICAgaW5wdXQ6IHtcclxuICAgICAgICAgIGtleUV4Y2hhbmdlSWQsXHJcbiAgICAgICAgICByb290S2V5SWQ6IHJvb3RLZXkuaWQsXHJcbiAgICAgICAgICBtYXN0ZXJLZXlJZDogbWFzdGVyS2V5LmlkLFxyXG4gICAgICAgICAgaW5pdGlhdG9yU2lnUHhrSWQ6IGluaXRpYXRvclNpZ1Byay5pZCxcclxuICAgICAgICAgIHNpZ25lZFJlc3BvbmRlclBiazogSlNPTi5zdHJpbmdpZnkoc2lnbmVkUmVzcG9uZGVyUGJrKSxcclxuICAgICAgICAgIHNpZ25lZFJlc3BvbmRlclNpZ1BiazogSlNPTi5zdHJpbmdpZnkoc2lnbmVkUmVzcG9uZGVyU2lnUGJrKSxcclxuICAgICAgICAgIHJrV3JhcHBlZFNoYXJlZEtleTogSlNPTi5zdHJpbmdpZnkocmtXcmFwcGVkU2hhcmVkS2V5KSxcclxuICAgICAgICAgIG1rV3JhcHBlZE1rU2hhcmVkS2V5OiBKU09OLnN0cmluZ2lmeShta1dyYXBwZWRNa1NoYXJlZEtleSksXHJcbiAgICAgICAgICByZXNwb25kZXJDb250YWN0Q2FyZENpcGhlcjogcmVzcG9uZGVyQ29udGFjdENhcmRDaXBoZXJJbnB1dCxcclxuICAgICAgICAgIGluaXRpYXRvckNvbnRhY3RDYXJkQ2lwaGVyOiBpbml0aWF0b3JDb250YWN0Q2FyZENpcGhlcklucHV0LFxyXG4gICAgICAgICAgaW5pdGlhdG9yQ29udGFjdENhcmRTaGFyZWRDaXBoZXI6IGluaXRpYXRvckNvbnRhY3RDYXJkU2hhcmVkQ2lwaGVySW5wdXQsXHJcbiAgICAgICAgfSxcclxuICAgICAgfSxcclxuICAgIH0pO1xyXG4gICAgcmV0dXJuIHJlcy5jb21wbGV0ZUtleUV4Y2hhbmdlT3RrO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIGFzeW5jIGN1cnJlbnRVc2VyU2hhcmVkS2V5KGlucHV0OiB7XHJcbiAgICB1c2VybmFtZT86IHN0cmluZztcclxuICAgIHVzZXJJZD86IHN0cmluZztcclxuICB9KTogUHJvbWlzZTxVc2VyU2hhcmVkS2V5PiB7XHJcbiAgICBjb25zdCB7IGN1cnJlbnRVc2VyU2hhcmVkS2V5IH0gPSBhd2FpdCB0aGlzLmxyQXBvbGxvLnF1ZXJ5PGFueT4oe1xyXG4gICAgICBxdWVyeTogQ3VycmVudFVzZXJTaGFyZWRLZXlRdWVyeSxcclxuICAgICAgdmFyaWFibGVzOiB7XHJcbiAgICAgICAgdXNlcm5hbWU6IGlucHV0LnVzZXJuYW1lLFxyXG4gICAgICAgIHVzZXJJZDogaW5wdXQudXNlcklkLFxyXG4gICAgICB9LFxyXG4gICAgfSk7XHJcbiAgICByZXR1cm4gY3VycmVudFVzZXJTaGFyZWRLZXkudXNlclNoYXJlZEtleTtcclxuICB9XHJcbn1cclxuIl19