@lifeready/core 1.0.12 → 1.0.15

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 (219) hide show
  1. package/README.md +62 -62
  2. package/bundles/lifeready-core.umd.js +14315 -14315
  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 +52 -52
  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/key-exchange.gql.js +188 -188
  18. package/esm2015/lib/api/key-exchange.service.js +442 -442
  19. package/esm2015/lib/api/key-exchange.types.js +18 -18
  20. package/esm2015/lib/api/key-exchange2.gql.js +171 -171
  21. package/esm2015/lib/api/key-exchange2.service.js +479 -479
  22. package/esm2015/lib/api/lock.gql.js +40 -40
  23. package/esm2015/lib/api/lock.service.js +64 -64
  24. package/esm2015/lib/api/lr-apollo.service.js +46 -46
  25. package/esm2015/lib/api/lr-graphql/index.js +6 -6
  26. package/esm2015/lib/api/lr-graphql/lr-graphql.service.js +155 -155
  27. package/esm2015/lib/api/lr-graphql/lr-merged-mutation.js +213 -213
  28. package/esm2015/lib/api/lr-graphql/lr-mutation-base.js +51 -51
  29. package/esm2015/lib/api/lr-graphql/lr-mutation.js +48 -48
  30. package/esm2015/lib/api/lr-graphql/lr.service.js +18 -18
  31. package/esm2015/lib/api/message.service.js +138 -138
  32. package/esm2015/lib/api/persist.service.js +181 -181
  33. package/esm2015/lib/api/query-processor/common-processors.service.js +93 -93
  34. package/esm2015/lib/api/query-processor/index.js +3 -3
  35. package/esm2015/lib/api/query-processor/query-processor.service.js +262 -262
  36. package/esm2015/lib/api/query-processor/tp-password-reset-processor.service.js +109 -109
  37. package/esm2015/lib/api/shared-contact-card.service.js +119 -119
  38. package/esm2015/lib/api/shared-contact-card2.gql.js +41 -41
  39. package/esm2015/lib/api/shared-contact-card2.service.js +117 -117
  40. package/esm2015/lib/api/time.service.js +146 -146
  41. package/esm2015/lib/api/types/graphql.types.js +7 -7
  42. package/esm2015/lib/api/types/index.js +3 -3
  43. package/esm2015/lib/api/types/lr-graphql.types.js +101 -101
  44. package/esm2015/lib/auth/auth.config.js +57 -57
  45. package/esm2015/lib/auth/auth.gql.js +48 -48
  46. package/esm2015/lib/auth/auth.types.js +27 -27
  47. package/esm2015/lib/auth/idle.service.js +168 -168
  48. package/esm2015/lib/auth/idle.types.js +7 -7
  49. package/esm2015/lib/auth/lbop.service.js +355 -355
  50. package/esm2015/lib/auth/life-ready-auth.service.js +488 -488
  51. package/esm2015/lib/auth/password.service.js +320 -320
  52. package/esm2015/lib/auth/register.service.js +172 -172
  53. package/esm2015/lib/auth/two-factor.service.js +74 -74
  54. package/esm2015/lib/category/category-meta.service.js +99 -99
  55. package/esm2015/lib/category/category.gql.js +406 -406
  56. package/esm2015/lib/category/category.service.js +390 -390
  57. package/esm2015/lib/category/category.types.js +29 -29
  58. package/esm2015/lib/cryptography/cryptography.types.js +11 -11
  59. package/esm2015/lib/cryptography/encryption.service.js +189 -189
  60. package/esm2015/lib/cryptography/key-factory.service.js +237 -237
  61. package/esm2015/lib/cryptography/key-graph.service.js +299 -299
  62. package/esm2015/lib/cryptography/key-meta.service.js +200 -200
  63. package/esm2015/lib/cryptography/key.service.js +124 -124
  64. package/esm2015/lib/cryptography/slip39.service.js +169 -169
  65. package/esm2015/lib/cryptography/web-crypto.service.js +29 -29
  66. package/esm2015/lib/items2/item2.gql.js +139 -139
  67. package/esm2015/lib/items2/item2.service.js +498 -498
  68. package/esm2015/lib/items2/item2.types.js +1 -1
  69. package/esm2015/lib/life-ready.config.js +84 -84
  70. package/esm2015/lib/life-ready.module.js +74 -74
  71. package/esm2015/lib/notification/notification.gql.js +43 -43
  72. package/esm2015/lib/notification/notification.service.js +118 -118
  73. package/esm2015/lib/plan/plan.gql.js +123 -123
  74. package/esm2015/lib/plan/plan.service.js +149 -149
  75. package/esm2015/lib/plan/plan.types.js +11 -11
  76. package/esm2015/lib/record/record-attachment.service.js +101 -101
  77. package/esm2015/lib/record/record.gql.js +179 -179
  78. package/esm2015/lib/record/record.service.js +206 -206
  79. package/esm2015/lib/record/record.types.js +15 -15
  80. package/esm2015/lib/record-type/record-type.service.js +75 -75
  81. package/esm2015/lib/record-type/record-type.types.js +28 -28
  82. package/esm2015/lib/scenario/scenario.constants.js +2 -2
  83. package/esm2015/lib/scenario/scenario.controller.js +34 -34
  84. package/esm2015/lib/scenario/scenario.gql.js +72 -72
  85. package/esm2015/lib/scenario/scenario.gql.private.js +198 -198
  86. package/esm2015/lib/scenario/scenario.service.js +538 -538
  87. package/esm2015/lib/scenario/scenario.types.js +1 -1
  88. package/esm2015/lib/trusted-parties/tp-assembly.gql.private.js +22 -22
  89. package/esm2015/lib/trusted-parties/tp-assembly.js +362 -362
  90. package/esm2015/lib/trusted-parties/tp-assembly.types.js +1 -1
  91. package/esm2015/lib/trusted-parties/tp-password-reset-request.service.js +113 -113
  92. package/esm2015/lib/trusted-parties/tp-password-reset-user.service.js +129 -129
  93. package/esm2015/lib/trusted-parties/tp-password-reset.constants.js +4 -4
  94. package/esm2015/lib/trusted-parties/tp-password-reset.controller.js +34 -34
  95. package/esm2015/lib/trusted-parties/tp-password-reset.gql.js +236 -236
  96. package/esm2015/lib/trusted-parties/tp-password-reset.service.js +95 -95
  97. package/esm2015/lib/trusted-parties/trusted-party.gql.js +148 -148
  98. package/esm2015/lib/trusted-parties/trusted-party.service.js +326 -326
  99. package/esm2015/lib/trusted-parties/trusted-party.types.js +41 -41
  100. package/esm2015/lib/trusted-parties/trusted-party2.gql.js +87 -87
  101. package/esm2015/lib/trusted-parties/trusted-party2.service.js +215 -215
  102. package/esm2015/lib/users/profile-details.service.js +214 -214
  103. package/esm2015/lib/users/profile.gql.js +97 -97
  104. package/esm2015/lib/users/profile.service.js +169 -169
  105. package/esm2015/lib/users/profile.types.js +34 -34
  106. package/esm2015/lib/users/user.gql.js +60 -60
  107. package/esm2015/lib/users/user.service.js +79 -79
  108. package/esm2015/lib/users/user.types.js +5 -5
  109. package/esm2015/lifeready-core.js +13 -13
  110. package/esm2015/public-api.js +71 -71
  111. package/fesm2015/lifeready-core.js +12258 -12258
  112. package/fesm2015/lifeready-core.js.map +1 -1
  113. package/lib/_common/ast.d.ts +11 -11
  114. package/lib/_common/deferred-promise.d.ts +12 -12
  115. package/lib/_common/exceptions.d.ts +109 -109
  116. package/lib/_common/queries.gql.d.ts +10 -10
  117. package/lib/_common/run-outside-angular.d.ts +14 -14
  118. package/lib/_common/types.d.ts +10 -10
  119. package/lib/_common/utils.d.ts +9 -9
  120. package/lib/api/contact-card.gql.d.ts +7 -7
  121. package/lib/api/contact-card.service.d.ts +52 -52
  122. package/lib/api/contact-card2.gql.d.ts +34 -34
  123. package/lib/api/contact-card2.service.d.ts +49 -49
  124. package/lib/api/file.service.d.ts +18 -18
  125. package/lib/api/key-exchange.gql.d.ts +9 -9
  126. package/lib/api/key-exchange.service.d.ts +39 -39
  127. package/lib/api/key-exchange.types.d.ts +196 -196
  128. package/lib/api/key-exchange2.gql.d.ts +125 -125
  129. package/lib/api/key-exchange2.service.d.ts +187 -187
  130. package/lib/api/lock.gql.d.ts +27 -27
  131. package/lib/api/lock.service.d.ts +34 -34
  132. package/lib/api/lr-apollo.service.d.ts +15 -15
  133. package/lib/api/lr-graphql/index.d.ts +5 -5
  134. package/lib/api/lr-graphql/lr-graphql.service.d.ts +60 -60
  135. package/lib/api/lr-graphql/lr-merged-mutation.d.ts +28 -28
  136. package/lib/api/lr-graphql/lr-mutation-base.d.ts +28 -28
  137. package/lib/api/lr-graphql/lr-mutation.d.ts +8 -8
  138. package/lib/api/lr-graphql/lr.service.d.ts +9 -9
  139. package/lib/api/message.service.d.ts +58 -58
  140. package/lib/api/persist.service.d.ts +31 -31
  141. package/lib/api/query-processor/common-processors.service.d.ts +36 -36
  142. package/lib/api/query-processor/index.d.ts +2 -2
  143. package/lib/api/query-processor/query-processor.service.d.ts +18 -18
  144. package/lib/api/query-processor/tp-password-reset-processor.service.d.ts +15 -15
  145. package/lib/api/shared-contact-card.service.d.ts +33 -33
  146. package/lib/api/shared-contact-card2.gql.d.ts +36 -36
  147. package/lib/api/shared-contact-card2.service.d.ts +45 -45
  148. package/lib/api/time.service.d.ts +16 -16
  149. package/lib/api/types/graphql.types.d.ts +29 -29
  150. package/lib/api/types/index.d.ts +2 -2
  151. package/lib/api/types/lr-graphql.types.d.ts +502 -502
  152. package/lib/auth/auth.config.d.ts +5 -5
  153. package/lib/auth/auth.gql.d.ts +15 -15
  154. package/lib/auth/auth.types.d.ts +66 -66
  155. package/lib/auth/idle.service.d.ts +40 -40
  156. package/lib/auth/idle.types.d.ts +10 -10
  157. package/lib/auth/lbop.service.d.ts +91 -91
  158. package/lib/auth/life-ready-auth.service.d.ts +61 -61
  159. package/lib/auth/password.service.d.ts +78 -78
  160. package/lib/auth/register.service.d.ts +25 -25
  161. package/lib/auth/two-factor.service.d.ts +15 -15
  162. package/lib/category/category-meta.service.d.ts +23 -23
  163. package/lib/category/category.gql.d.ts +45 -45
  164. package/lib/category/category.service.d.ts +67 -67
  165. package/lib/category/category.types.d.ts +79 -79
  166. package/lib/cryptography/cryptography.types.d.ts +83 -83
  167. package/lib/cryptography/encryption.service.d.ts +41 -41
  168. package/lib/cryptography/key-factory.service.d.ts +38 -38
  169. package/lib/cryptography/key-graph.service.d.ts +41 -41
  170. package/lib/cryptography/key-meta.service.d.ts +44 -44
  171. package/lib/cryptography/key.service.d.ts +36 -36
  172. package/lib/cryptography/slip39.service.d.ts +43 -43
  173. package/lib/cryptography/web-crypto.service.d.ts +5 -5
  174. package/lib/items2/item2.gql.d.ts +123 -123
  175. package/lib/items2/item2.service.d.ts +203 -203
  176. package/lib/items2/item2.types.d.ts +70 -70
  177. package/lib/life-ready.config.d.ts +14 -14
  178. package/lib/life-ready.module.d.ts +5 -5
  179. package/lib/notification/notification.gql.d.ts +37 -37
  180. package/lib/notification/notification.service.d.ts +63 -63
  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/scenario.constants.d.ts +1 -1
  191. package/lib/scenario/scenario.controller.d.ts +10 -10
  192. package/lib/scenario/scenario.gql.d.ts +62 -62
  193. package/lib/scenario/scenario.gql.private.d.ts +16 -16
  194. package/lib/scenario/scenario.service.d.ts +233 -233
  195. package/lib/scenario/scenario.types.d.ts +50 -50
  196. package/lib/trusted-parties/tp-assembly.d.ts +177 -177
  197. package/lib/trusted-parties/tp-assembly.gql.private.d.ts +5 -5
  198. package/lib/trusted-parties/tp-assembly.types.d.ts +38 -38
  199. package/lib/trusted-parties/tp-password-reset-request.service.d.ts +20 -20
  200. package/lib/trusted-parties/tp-password-reset-user.service.d.ts +35 -35
  201. package/lib/trusted-parties/tp-password-reset.constants.d.ts +3 -3
  202. package/lib/trusted-parties/tp-password-reset.controller.d.ts +10 -10
  203. package/lib/trusted-parties/tp-password-reset.gql.d.ts +223 -223
  204. package/lib/trusted-parties/tp-password-reset.service.d.ts +188 -188
  205. package/lib/trusted-parties/trusted-party.gql.d.ts +9 -9
  206. package/lib/trusted-parties/trusted-party.service.d.ts +44 -44
  207. package/lib/trusted-parties/trusted-party.types.d.ts +102 -102
  208. package/lib/trusted-parties/trusted-party2.gql.d.ts +79 -79
  209. package/lib/trusted-parties/trusted-party2.service.d.ts +114 -114
  210. package/lib/users/profile-details.service.d.ts +21 -21
  211. package/lib/users/profile.gql.d.ts +11 -11
  212. package/lib/users/profile.service.d.ts +35 -35
  213. package/lib/users/profile.types.d.ts +96 -96
  214. package/lib/users/user.gql.d.ts +9 -9
  215. package/lib/users/user.service.d.ts +12 -12
  216. package/lib/users/user.types.d.ts +23 -23
  217. package/lifeready-core.d.ts +12 -12
  218. package/package.json +1 -1
  219. package/public-api.d.ts +67 -67
@@ -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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoia2V5LWV4Y2hhbmdlLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiQzovUHJvamVjdHMva2MtY2xpZW50L3Byb2plY3RzL2NvcmUvc3JjLyIsInNvdXJjZXMiOlsibGliL2FwaS9rZXktZXhjaGFuZ2Uuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUUzQyxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUV2RSxPQUFPLEVBQ0wsaUJBQWlCLEVBQ2pCLGlCQUFpQixHQUNsQixNQUFNLG9DQUFvQyxDQUFDO0FBQzVDLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUN6RCxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUNoRSxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDdEQsT0FBTyxFQUNMLG1CQUFtQixFQUNuQix5QkFBeUIsRUFDekIsbUJBQW1CLEVBQ25CLGdCQUFnQixFQUNoQixpQkFBaUIsRUFDakIscUJBQXFCLEVBQ3JCLGtCQUFrQixHQUNuQixNQUFNLG9CQUFvQixDQUFDO0FBQzVCLE9BQU8sRUFRTCxRQUFRLEdBUVQsTUFBTSxzQkFBc0IsQ0FBQztBQUM5QixPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDdEQsT0FBTyxFQUFFLGlCQUFpQixJQUFJLEdBQUcsRUFBRSxNQUFNLHFDQUFxQyxDQUFDO0FBQy9FLDBHQUEwRztBQUMxRyxPQUFPLEtBQUssT0FBTyxNQUFNLFFBQVEsQ0FBQzs7Ozs7Ozs7QUFDbEMsTUFBTSxNQUFNLEdBQUcsT0FBTyxDQUFDO0FBS3ZCLE1BQU0sT0FBTyxrQkFBa0I7SUFHN0IsWUFDVSxVQUFlLEVBQ2YsVUFBc0IsRUFDdEIsUUFBeUIsRUFDekIsaUJBQW9DLEVBQ3BDLFdBQWlDLEVBQ2pDLFdBQXdCO1FB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TyxDQUFDLEVBQUU7d0JBQ3JCLFdBQVcsRUFBRSxTQUFTLENBQUMsRUFBRTt3QkFDekIsaUJBQWlCLEVBQUUsZUFBZSxDQUFDLEVBQUU7d0JBQ3JDLGtCQUFrQixFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsa0JBQWtCLENBQUM7d0JBQ3RELHFCQUFxQixFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMscUJBQXFCLENBQUM7d0JBQzVELGtCQUFrQixFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsa0JBQWtCLENBQUM7d0JBQ3RELG9CQUFvQixFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsb0JBQW9CLENBQUM7d0JBQzFELDBCQUEwQixFQUFFLCtCQUErQjt3QkFDM0QsMEJBQTBCLEVBQUUsK0JBQStCO3dCQUMzRCxnQ0FBZ0MsRUFBRSxxQ0FBcUM7cUJBQ3hFO2lCQUNGO2FBQ0YsQ0FBQyxDQUFDO1lBQ0gsT0FBTyxHQUFHLENBQUMsc0JBQXNCLENBQUM7UUFDcEMsQ0FBQztLQUFBO0lBRVksb0JBQW9CLENBQUMsS0FHakM7O1lBQ0MsTUFBTSxFQUFFLG9CQUFvQixFQUFFLEdBQUcsTUFBTSxJQUFJLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBTTtnQkFDOUQsS0FBSyxFQUFFLHlCQUF5QjtnQkFDaEMsU0FBUyxFQUFFO29CQUNULFFBQVEsRUFBRSxLQUFLLENBQUMsUUFBUTtvQkFDeEIsTUFBTSxFQUFFLEtBQUssQ0FBQyxNQUFNO2lCQUNyQjthQUNGLENBQUMsQ0FBQztZQUNILE9BQU8sb0JBQW9CLENBQUMsYUFBYSxDQUFDO1FBQzVDLENBQUM7S0FBQTs7OztZQTlxQkYsVUFBVSxTQUFDO2dCQUNWLFVBQVUsRUFBRSxNQUFNO2FBQ25COzs7WUFQNkIsR0FBRztZQTlCeEIsVUFBVTtZQTZCVixlQUFlO1lBaEN0QixpQkFBaUI7WUFIVixvQkFBb0I7WUFRcEIsV0FBVyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgSldLIH0gZnJvbSAnbm9kZS1qb3NlJztcclxuaW1wb3J0IHsgTGlmZVJlYWR5QXV0aFNlcnZpY2UgfSBmcm9tICcuLi9hdXRoL2xpZmUtcmVhZHktYXV0aC5zZXJ2aWNlJztcclxuaW1wb3J0IHsgS2V5R3JhcGhSZXNwb25zZSB9IGZyb20gJy4uL2NyeXB0b2dyYXBoeS9jcnlwdG9ncmFwaHkudHlwZXMnO1xyXG5pbXBvcnQge1xyXG4gIEVuY3J5cHRpb25TZXJ2aWNlLFxyXG4gIEpvc2VTZXJpYWxpemF0aW9uLFxyXG59IGZyb20gJy4uL2NyeXB0b2dyYXBoeS9lbmNyeXB0aW9uLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBLZXlTZXJ2aWNlIH0gZnJvbSAnLi4vY3J5cHRvZ3JhcGh5L2tleS5zZXJ2aWNlJztcclxuaW1wb3J0IHsgTHJDb2RlTWlzbWF0Y2hFeGNlcHRpb24gfSBmcm9tICcuLi9fY29tbW9uL2V4Y2VwdGlvbnMnO1xyXG5pbXBvcnQgeyBVc2VyU2VydmljZSB9IGZyb20gJy4vLi4vdXNlcnMvdXNlci5zZXJ2aWNlJztcclxuaW1wb3J0IHtcclxuICBDb21wbGV0ZU90a011dGF0aW9uLFxyXG4gIEN1cnJlbnRVc2VyU2hhcmVkS2V5UXVlcnksXHJcbiAgSW5pdGlhdGVPdGtNdXRhdGlvbixcclxuICBLZXlFeGNoYW5nZVF1ZXJ5LFxyXG4gIEtleUV4Y2hhbmdlc1F1ZXJ5LFxyXG4gIEtleUV4Y2hhbmdlVG9rZW5RdWVyeSxcclxuICBSZXNwb25kT3RrTXV0YXRpb24sXHJcbn0gZnJvbSAnLi9rZXktZXhjaGFuZ2UuZ3FsJztcclxuaW1wb3J0IHtcclxuICBDb21wbGV0ZU90ayxcclxuICBEZWNyeXB0ZWRLZXlFeGNoYW5nZSxcclxuICBEZWNyeXB0ZWRPdGssXHJcbiAgR2V0S2V5RXhjaGFuZ2VMaXN0T3B0aW9ucyxcclxuICBHZXRLZXlFeGNoYW5nZU9wdGlvbnMsXHJcbiAgSW5pdGlhdGVPdGtJbnB1dCxcclxuICBLZXlFeGNoYW5nZSxcclxuICBPdGtTdGF0ZSxcclxuICBQbGFpbkluaXRpYXRvck9uZVRpbWVQYmtDaXBoZXIsXHJcbiAgUGxhaW5Jbml0aWF0b3JSb290S2V5Q2lwaGVyLFxyXG4gIFBsYWluT3RLZXlDaXBoZXIsXHJcbiAgUGxhaW5SZXNwb25kZXJQYmtDaXBoZXIsXHJcbiAgUmVzcG9uZE90ayxcclxuICBSZXNwb25kT3RrSW5wdXQsXHJcbiAgVXNlclNoYXJlZEtleSxcclxufSBmcm9tICcuL2tleS1leGNoYW5nZS50eXBlcyc7XHJcbmltcG9ydCB7IExyQXBvbGxvU2VydmljZSB9IGZyb20gJy4vbHItYXBvbGxvLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBLZXlGYWN0b3J5U2VydmljZSBhcyBLRlMgfSBmcm9tICcuLi9jcnlwdG9ncmFwaHkva2V5LWZhY3Rvcnkuc2VydmljZSc7XHJcbi8vIFJlZjogaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvNTk3MzUyODAvYW5ndWxhci04LW1vbWVudC1lcnJvci1jYW5ub3QtY2FsbC1hLW5hbWVzcGFjZS1tb21lbnRcclxuaW1wb3J0ICogYXMgbW9tZW50XyBmcm9tICdtb21lbnQnO1xyXG5jb25zdCBtb21lbnQgPSBtb21lbnRfO1xyXG5cclxuQEluamVjdGFibGUoe1xyXG4gIHByb3ZpZGVkSW46ICdyb290JyxcclxufSlcclxuZXhwb3J0IGNsYXNzIEtleUV4Y2hhbmdlU2VydmljZSB7XHJcbiAgcHJpdmF0ZSByZWFkb25seSBDTElFTlRfTk9OQ0VfTEVOR1RIID0gMzI7XHJcblxyXG4gIGNvbnN0cnVjdG9yKFxyXG4gICAgcHJpdmF0ZSBrZXlGYWN0b3J5OiBLRlMsXHJcbiAgICBwcml2YXRlIGtleVNlcnZpY2U6IEtleVNlcnZpY2UsXHJcbiAgICBwcml2YXRlIGxyQXBvbGxvOiBMckFwb2xsb1NlcnZpY2UsXHJcbiAgICBwcml2YXRlIGVuY3J5cHRpb25TZXJ2aWNlOiBFbmNyeXB0aW9uU2VydmljZSxcclxuICAgIHByaXZhdGUgYXV0aFNlcnZpY2U6IExpZmVSZWFkeUF1dGhTZXJ2aWNlLFxyXG4gICAgcHJpdmF0ZSB1c2VyU2VydmljZTogVXNlclNlcnZpY2VcclxuICApIHt9XHJcblxyXG4gIHB1YmxpYyBhc3luYyBnZXRLZXlFeGNoYW5nZUxpc3QoXHJcbiAgICBpbnB1dDogR2V0S2V5RXhjaGFuZ2VMaXN0T3B0aW9ucyA9IHt9XHJcbiAgKTogUHJvbWlzZTxhbnk+IHtcclxuICAgIGNvbnN0IHsga2V5RXhjaGFuZ2VzIH0gPSBhd2FpdCB0aGlzLmxyQXBvbGxvLnF1ZXJ5PHtcclxuICAgICAga2V5RXhjaGFuZ2VzOiBhbnk7XHJcbiAgICAgIGtleUdyYXBoOiBLZXlHcmFwaFJlc3BvbnNlO1xyXG4gICAgfT4oe1xyXG4gICAgICBxdWVyeTogS2V5RXhjaGFuZ2VzUXVlcnksXHJcbiAgICAgIHZhcmlhYmxlczoge1xyXG4gICAgICAgIC4uLmlucHV0LFxyXG4gICAgICB9LFxyXG4gICAgfSk7XHJcbiAgICByZXR1cm4ga2V5RXhjaGFuZ2VzO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQHBhcmFtIGlkIElmIHRoZSBjdXJyZW50IHVzZXIgY2FuIHJlc3BvbmRlciB0aGUga2V5IGV4Y2hhbmdlIGlmIHRoZXkgYXJlIGVpdGhlciB0aGUgaW5pdGlhdG9yIG9yIHRoZSByZWNlaXZlci5cclxuICAgKiBAcGFyYW0gdG9rZW4gSWYgbm90IHNpZ25lZCBpbiwgb3Igbm90IHRoZSBpbml0aWF0b3Igb3IgcmVzcG9uZGVyLCAndG9rZW4nIG11c3QgYmUgZ2l2ZW4uXHJcbiAgICogQHBhcmFtIG90S2V5SyBJcyB0aGUgcmF3IG9uZS10aW1lIGtleSAoc3RyaW5nKS4gSWYgdGhlIHJlc3BvbmRlciBpcyBleHBsaWNpdGx5IHNwZWNpZmllZCBhdCB0aW1lIG9mIGluaXRpYXRpb24sIHRoZW5cclxuICAgKiAgIGl0J3MgcG9zc2libGUgdG8gaGF2ZSB0aGUgb3RLZXkgd3JhcHBlZCBieSB0aGUgcHVibGljIGtleSBvZiB0aGUgcmVzcG9uZGVyLiBJbiB3aGljaCBjYXNlLCB0aGUgb3RLZXlLIGlzIG5vdCBuZWVkZWQuXHJcbiAgICovXHJcbiAgcHVibGljIGFzeW5jIGdldEtleUV4Y2hhbmdlKFxyXG4gICAgaWQ6IHN0cmluZyxcclxuICAgIHsgb3RLZXlLLCB0b2tlbiB9OiBHZXRLZXlFeGNoYW5nZU9wdGlvbnMgPSB7fVxyXG4gICk6IFByb21pc2U8RGVjcnlwdGVkS2V5RXhjaGFuZ2U+IHtcclxuICAgIGNvbnN0IHsga2V5RXhjaGFuZ2UgfSA9IGF3YWl0IHRoaXMubHJBcG9sbG8ucXVlcnk8e1xyXG4gICAgICBrZXlFeGNoYW5nZTogS2V5RXhjaGFuZ2U7XHJcbiAgICAgIGtleUdyYXBoOiBLZXlHcmFwaFJlc3BvbnNlO1xyXG4gICAgfT4oe1xyXG4gICAgICBxdWVyeTogdG9rZW4gPyBLZXlFeGNoYW5nZVRva2VuUXVlcnkgOiBLZXlFeGNoYW5nZVF1ZXJ5LFxyXG4gICAgICB2YXJpYWJsZXM6IHtcclxuICAgICAgICBpZCxcclxuICAgICAgICB0b2tlbixcclxuICAgICAgfSxcclxuICAgIH0pO1xyXG4gICAgcmV0dXJuIGF3YWl0IHRoaXMuZGVjcnlwdEtleUV4Y2hhbmdlKGtleUV4Y2hhbmdlLCBvdEtleUspO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBhc3luYyBkZWNyeXB0UmVzcG9uc2VDaXBoZXIoXHJcbiAgICBvdEtleTogSldLLktleSxcclxuICAgIG90UHJrOiBKV0suS2V5LFxyXG4gICAgY29udGVudDogYW55XHJcbiAgKTogUHJvbWlzZTxQbGFpbkluaXRpYXRvck9uZVRpbWVQYmtDaXBoZXI+IHtcclxuICAgIC8vIFRoZSByZXNwb25zZSBjb3VsZCBiZSB3cmFwcGVkIGJ5IHRoZSBPdEsgYXMgd2VsbCBhcyB3ZSB0aGUgT3RQcmtcclxuICAgIHRyeSB7XHJcbiAgICAgIGNvbnRlbnQgPSBhd2FpdCB0aGlzLmVuY3J5cHRpb25TZXJ2aWNlLmRlY3J5cHQob3RLZXksIGNvbnRlbnQpO1xyXG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcclxuICAgICAgaWYgKGVycm9yLm1lc3NhZ2UgIT09ICdubyBrZXkgZm91bmQnKSB7XHJcbiAgICAgICAgdGhyb3cgZXJyb3I7XHJcbiAgICAgIH1cclxuICAgICAgLy8gRG8gbm90aGluZyB0byBzdXBwb3J0IG9sZGVyIHZlcnNpb25zIHdoZXJlIG1lc3NhZ2UgaXMgbm90IHdyYXBwZWQgd2l0aCBvdGsuXHJcbiAgICB9XHJcblxyXG4gICAgLy8gVGhlIFByayBpcyBzaW5nbGUtdXNlIGFuZCBvbmx5IHVzZWQgdG8gc2VuZCBpbmZvcm1hdGlvbiBmcm9tIHRoZSByZXNwb25kZXIgYmFjayB0byB0aGUgaW5pdGlhdG9yLlxyXG4gICAgcmV0dXJuIGF3YWl0IHRoaXMuZW5jcnlwdGlvblNlcnZpY2UuZGVjcnlwdChvdFByaywgY29udGVudCk7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgYXN5bmMgZGVjcnlwdEtleUV4Y2hhbmdlKFxyXG4gICAga2V5RXhjaGFuZ2U6IEtleUV4Y2hhbmdlLFxyXG4gICAgb3RLZXlLPzogc3RyaW5nXHJcbiAgKTogUHJvbWlzZTxEZWNyeXB0ZWRLZXlFeGNoYW5nZT4ge1xyXG4gICAgaWYgKGtleUV4Y2hhbmdlLmlzSW5pdGlhdG9yKSB7XHJcbiAgICAgIGNvbnN0IHJvb3RLZXkgPSBhd2FpdCB0aGlzLmtleVNlcnZpY2UuZ2V0Q3VycmVudFJvb3RLZXkoKTtcclxuICAgICAgLy8gRGVjcnlwdCB1c2luZyB0aGUgcm9vdCBrZXkgdG8gZ2V0IHRoZSBQcmtcclxuICAgICAgY29uc3QgcGxhaW5Jbml0aWF0b3JSb290S2V5Q2lwaGVyID0gKChhd2FpdCB0aGlzLmVuY3J5cHRpb25TZXJ2aWNlLmRlY3J5cHQoXHJcbiAgICAgICAgcm9vdEtleS5qd2ssXHJcbiAgICAgICAga2V5RXhjaGFuZ2UuaW5pdGlhdG9yUm9vdEtleUNpcGhlclxyXG4gICAgICApKSBhcyB1bmtub3duKSBhcyBQbGFpbkluaXRpYXRvclJvb3RLZXlDaXBoZXI7XHJcblxyXG4gICAgICBjb25zdCBwbGFpbkluaXRpYXRvck9uZVRpbWVQYmtDaXBoZXIgPSBrZXlFeGNoYW5nZS5vdGtcclxuICAgICAgICAuaW5pdGlhdG9yT25lVGltZVBia0NpcGhlclxyXG4gICAgICAgID8gYXdhaXQgdGhpcy5kZWNyeXB0UmVzcG9uc2VDaXBoZXIoXHJcbiAgICAgICAgICAgIGF3YWl0IEtGUy5hc0tleShwbGFpbkluaXRpYXRvclJvb3RLZXlDaXBoZXIub3RLZXkpLFxyXG4gICAgICAgICAgICBhd2FpdCBLRlMuYXNLZXkocGxhaW5Jbml0aWF0b3JSb290S2V5Q2lwaGVyLm9uZVRpbWVQcmspLFxyXG4gICAgICAgICAgICBrZXlFeGNoYW5nZS5vdGsuaW5pdGlhdG9yT25lVGltZVBia0NpcGhlclxyXG4gICAgICAgICAgKVxyXG4gICAgICAgIDogbnVsbDtcclxuXHJcbiAgICAgIGNvbnN0IHJlc3BvbmRlciA9XHJcbiAgICAgICAgcGxhaW5Jbml0aWF0b3JPbmVUaW1lUGJrQ2lwaGVyICYmXHJcbiAgICAgICAgcGxhaW5Jbml0aWF0b3JPbmVUaW1lUGJrQ2lwaGVyLnJlc3BvbmRlcjtcclxuICAgICAgY29uc3QgaW5pdGlhdG9yID1cclxuICAgICAgICBwbGFpbkluaXRpYXRvclJvb3RLZXlDaXBoZXIgJiYgcGxhaW5Jbml0aWF0b3JSb290S2V5Q2lwaGVyLmluaXRpYXRvcjtcclxuXHJcbiAgICAgIHJldHVybiB7XHJcbiAgICAgICAgLi4ua2V5RXhjaGFuZ2UsXHJcbiAgICAgICAgbWVzc2FnZTogcmVzcG9uZGVyID8gcmVzcG9uZGVyLm1lc3NhZ2UgOiBudWxsLFxyXG4gICAgICAgIGNvbnRhY3RDYXJkOlxyXG4gICAgICAgICAgcmVzcG9uZGVyICYmIHJlc3BvbmRlci5jb250YWN0Q2FyZFxyXG4gICAgICAgICAgICA/IHJlc3BvbmRlci5jb250YWN0Q2FyZC5wbGFpblNoYXJlZENpcGhlckRhdGFKc29uXHJcbiAgICAgICAgICAgIDogbnVsbCxcclxuICAgICAgICBteUNvbnRhY3RDYXJkOlxyXG4gICAgICAgICAgaW5pdGlhdG9yICYmIGluaXRpYXRvci5jb250YWN0Q2FyZFxyXG4gICAgICAgICAgICA/IGluaXRpYXRvci5jb250YWN0Q2FyZC5wbGFpblNoYXJlZENpcGhlckRhdGFKc29uXHJcbiAgICAgICAgICAgIDogbnVsbCxcclxuICAgICAgICBteU1lc3NhZ2U6IGluaXRpYXRvciAmJiBpbml0aWF0b3IubWVzc2FnZSxcclxuICAgICAgfTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGNvbnN0IGRlY3J5cHRlZE90ayA9IGF3YWl0IHRoaXMuZGVjcnlwdE90ayhrZXlFeGNoYW5nZSwgb3RLZXlLKTtcclxuXHJcbiAgICAgIGNvbnN0IGluaXRpYXRvciA9IGRlY3J5cHRlZE90ayAmJiBkZWNyeXB0ZWRPdGsucGxhaW5PdEtleUNpcGhlci5pbml0aWF0b3I7XHJcblxyXG4gICAgICByZXR1cm4ge1xyXG4gICAgICAgIC4uLmtleUV4Y2hhbmdlLFxyXG4gICAgICAgIGRlY3J5cHRlZE90ayxcclxuICAgICAgICBtZXNzYWdlOiBpbml0aWF0b3IgJiYgaW5pdGlhdG9yLm1lc3NhZ2UsXHJcbiAgICAgICAgY29udGFjdENhcmQ6XHJcbiAgICAgICAgICBpbml0aWF0b3IgJiZcclxuICAgICAgICAgIGluaXRpYXRvci5jb250YWN0Q2FyZCAmJlxyXG4gICAgICAgICAgaW5pdGlhdG9yLmNvbnRhY3RDYXJkLnBsYWluU2hhcmVkQ2lwaGVyRGF0YUpzb24sXHJcbiAgICAgIH07XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGFzeW5jIGRlY3J5cHRPdGsoXHJcbiAgICBrZXlFeGNoYW5nZTogS2V5RXhjaGFuZ2UsXHJcbiAgICBvdEtleUs/OiBzdHJpbmdcclxuICApOiBQcm9taXNlPERlY3J5cHRlZE90az4ge1xyXG4gICAgY29uc3Qgb3RLZXkgPSBhd2FpdCB0aGlzLmdldE90S2V5KGtleUV4Y2hhbmdlLCBvdEtleUspO1xyXG5cclxuICAgIHJldHVybiBvdEtleSAmJiBrZXlFeGNoYW5nZS5vdGsub3RLZXlDaXBoZXJcclxuICAgICAgPyB7XHJcbiAgICAgICAgICBwbGFpbk90S2V5Q2lwaGVyOiBhd2FpdCB0aGlzLmVuY3J5cHRpb25TZXJ2aWNlLmRlY3J5cHQoXHJcbiAgICAgICAgICAgIG90S2V5LFxyXG4gICAgICAgICAgICBrZXlFeGNoYW5nZS5vdGsub3RLZXlDaXBoZXJcclxuICAgICAgICAgICksXHJcbiAgICAgICAgICBvdEtleSxcclxuICAgICAgICB9XHJcbiAgICAgIDogbnVsbDtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgYXN5bmMgZ2V0T3RLZXkoXHJcbiAgICBrZXlFeGNoYW5nZTogS2V5RXhjaGFuZ2UsXHJcbiAgICBvdEtleUs/OiBzdHJpbmdcclxuICApOiBQcm9taXNlPEpXSy5LZXk+IHtcclxuICAgIGlmIChvdEtleUspIHtcclxuICAgICAgcmV0dXJuIGF3YWl0IEtGUy5hc0tleSh7XHJcbiAgICAgICAgLi4uSlNPTi5wYXJzZShrZXlFeGNoYW5nZS5vdGsub3RLZXlQYXJhbXMpLFxyXG4gICAgICAgIGs6IG90S2V5SyxcclxuICAgICAgfSk7XHJcbiAgICB9IGVsc2UgaWYgKFxyXG4gICAgICBrZXlFeGNoYW5nZS5vdGsuc3RhdGUgPT09IE90a1N0YXRlLk9US19JTklUSUFURUQgJiZcclxuICAgICAgIWtleUV4Y2hhbmdlLmlzSW5pdGlhdG9yICYmXHJcbiAgICAgIGtleUV4Y2hhbmdlLm90ay5yZXNwb25kZXJQYmtDaXBoZXJcclxuICAgICkge1xyXG4gICAgICAvLyBBc3N1bWluZyBleGlzdGluZyB1c2VyIGdldHRpbmcgaW52aXRlZCB3aGVyZSBPVEsgaXMgd3JhcHBlZCBpbiByZXNwb25kZXIncyBwdWJsaWMga2V5LlxyXG4gICAgICBjb25zdCBwcmsgPSBhd2FpdCB0aGlzLmtleVNlcnZpY2UuZ2V0Q3VycmVudFB4aygpO1xyXG4gICAgICBjb25zdCBkZWNyeXB0ZWRDaXBoZXI6IGFueSA9IGF3YWl0IHRoaXMuZW5jcnlwdGlvblNlcnZpY2UuZGVjcnlwdChcclxuICAgICAgICBwcmsuandrLFxyXG4gICAgICAgIEpTT04ucGFyc2Uoa2V5RXhjaGFuZ2Uub3RrLnJlc3BvbmRlclBia0NpcGhlciksXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgc2VyaWFsaXphdGlvbnM6IFtKb3NlU2VyaWFsaXphdGlvbi5DT01QQUNUXSxcclxuICAgICAgICB9XHJcbiAgICAgICk7XHJcbiAgICAgIGlmIChkZWNyeXB0ZWRDaXBoZXIub3RLZXkpIHtcclxuICAgICAgICByZXR1cm4gYXdhaXQgS0ZTLmFzS2V5KGRlY3J5cHRlZENpcGhlci5vdEtleSk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybiBudWxsO1xyXG4gIH1cclxuXHJcbiAgYXN5bmMgaW5pdGlhdGVPdGsoe1xyXG4gICAgbWVzc2FnZSxcclxuICAgIGVtYWlsLFxyXG4gICAgY29udGFjdENhcmQsXHJcbiAgICB1cGdyYWRlLFxyXG4gIH06IEluaXRpYXRlT3RrSW5wdXQpOiBQcm9taXNlPHsga2V5RXhjaGFuZ2U6IEtleUV4Y2hhbmdlOyBvdEtleUs6IHN0cmluZyB9PiB7XHJcbiAgICBjb25zdCBvdEtleSA9IGF3YWl0IHRoaXMua2V5RmFjdG9yeS5jcmVhdGVLZXkoKTtcclxuICAgIGNvbnN0IG5vbmNlID0gdGhpcy5rZXlGYWN0b3J5LnJhbmRvbVN0cmluZyh0aGlzLkNMSUVOVF9OT05DRV9MRU5HVEgpO1xyXG4gICAgY29uc3QgdXNlciA9IGF3YWl0IHRoaXMuYXV0aFNlcnZpY2UuZ2V0VXNlcigpO1xyXG5cclxuICAgIC8vIE5ldyBQS0Mga2V5IGZvciBlbmNyeXB0aW9uLiBUaGlzIGtleSBpcyB1c2VkIG9ubHkgb25jZSB3aGVuIHRoZSByZXNwb25kZXIgc2VuZHNcclxuICAgIC8vIGJhY2sgdGhlaXIgc2lnbmluZyBwdWJsaWMga2V5LlxyXG4gICAgY29uc3QgaW5pdGlhdG9yT25lVGltZVByayA9IGF3YWl0IHRoaXMua2V5RmFjdG9yeS5jcmVhdGVQa2NLZXkoKTtcclxuXHJcbiAgICAvLyBPcHRpb24gMTogTmV3IFBLQyBrZXkgZm9yIHNpZ25pbmdcclxuICAgIC8vIGNvbnN0IGluaXRpYXRvclNpZ1ByayA9IGF3YWl0IHRoaXMua2V5U2VydmljZS5jcmVhdGVQa2NTaWduS2V5KCk7XHJcblxyXG4gICAgLy8gT3B0aW9uIDI6IFVzZSB0aGUgdXNlcidzIGdsb2JhbCBzaWduaW5nIGtleS5cclxuICAgIC8vIFRoaXMga2V5IGlzIHVzZWQgdG8gcHJvdmUgdGhlIGluaXRpYXRvcidzIGlkZW50aXR5LlxyXG4gICAgY29uc3QgaW5pdGlhdG9yUHJrID0gYXdhaXQgdGhpcy5rZXlTZXJ2aWNlLmdldEN1cnJlbnRQeGsoKTtcclxuICAgIGNvbnN0IGluaXRpYXRvclNpZ1ByayA9IGF3YWl0IHRoaXMua2V5U2VydmljZS5nZXRDdXJyZW50U2lnUHhrKCk7XHJcblxyXG4gICAgbGV0IGluaXRpYXRvclBsYWluRGF0YVNpZzogc3RyaW5nID0gbnVsbDtcclxuXHJcbiAgICBpZiAoY29udGFjdENhcmQgJiYgY29udGFjdENhcmQub3duZXJQbGFpbkRhdGEpIHtcclxuICAgICAgaW5pdGlhdG9yUGxhaW5EYXRhU2lnID0gSlNPTi5zdHJpbmdpZnkoXHJcbiAgICAgICAgYXdhaXQgdGhpcy5lbmNyeXB0aW9uU2VydmljZS5zaWduKFxyXG4gICAgICAgICAgaW5pdGlhdG9yU2lnUHJrLmp3ayxcclxuICAgICAgICAgIGNvbnRhY3RDYXJkLm93bmVyUGxhaW5EYXRhXHJcbiAgICAgICAgKVxyXG4gICAgICApO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IGluaXRpYXRvciA9IHtcclxuICAgICAgbWVzc2FnZSxcclxuICAgICAgY29udGFjdENhcmQ6IGNvbnRhY3RDYXJkXHJcbiAgICAgICAgPyB7XHJcbiAgICAgICAgICAgIHBsYWluU2hhcmVkQ2lwaGVyRGF0YUpzb246IGNvbnRhY3RDYXJkLnBsYWluU2hhcmVkQ2lwaGVyRGF0YUpzb24sXHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgOiBudWxsLFxyXG4gICAgfTtcclxuXHJcbiAgICAvLyBDb250ZW50IHRvIGJlIGVuY3J5cHRlZCB1c2luZyB0aGUgT1RLLlxyXG4gICAgY29uc3QgcGxhaW5PdEtleUNpcGhlcjogUGxhaW5PdEtleUNpcGhlciA9IHtcclxuICAgICAgbm9uY2UsXHJcbiAgICAgIGluaXRpYXRvcjoge1xyXG4gICAgICAgIC4uLmluaXRpYXRvcixcclxuICAgICAgICBvbmVUaW1lUGJrOiBpbml0aWF0b3JPbmVUaW1lUHJrLnRvSlNPTigpLCAvLyBvbmV0aW1lIHB1YmxpYyBlbmNyeXB0aW9uIGtleSByZXNwb25kZXIgdXNlIHRvIHNlbmQgZGF0YSBiYWNrIHRvIGluaXRpYXRvclxyXG4gICAgICAgIHBiazogaW5pdGlhdG9yUHJrLmp3ay50b0pTT04oKSwgLy8gcHVibGljIGVuY3J5cHRpb24ga2V5XHJcbiAgICAgICAgc2lnUGJrOiBpbml0aWF0b3JTaWdQcmsuandrLnRvSlNPTigpLCAvLyBwdWJsaWMgc2lnbmluZyBrZXlcclxuICAgICAgICBwcm9maWxlOiB7XHJcbiAgICAgICAgICB1c2VybmFtZTogdXNlci51c2VybmFtZSxcclxuICAgICAgICB9LFxyXG4gICAgICB9LFxyXG4gICAgfTtcclxuXHJcbiAgICBjb25zdCBvdEtleUNpcGhlciA9IGF3YWl0IHRoaXMuZW5jcnlwdGlvblNlcnZpY2UuZW5jcnlwdChcclxuICAgICAgb3RLZXksXHJcbiAgICAgIHBsYWluT3RLZXlDaXBoZXJcclxuICAgICk7XHJcblxyXG4gICAgLy8gQ29udGVudCB0byBiZSBlbmNyeXB0ZWQgdXNpbmcgdGhlIGluaXRpYXRvcidzIHJvb3Qga2V5LlxyXG4gICAgY29uc3QgcGxhaW5Jbml0aWF0b3JSb290S2V5Q2lwaGVyOiBQbGFpbkluaXRpYXRvclJvb3RLZXlDaXBoZXIgPSB7XHJcbiAgICAgIG5vbmNlLFxyXG4gICAgICBvbmVUaW1lUHJrOiBpbml0aWF0b3JPbmVUaW1lUHJrLnRvSlNPTih0cnVlKSxcclxuICAgICAgLy8gU2hvdWxkIG5vdCBuZWVkIHRvIGtlZXAgdGhpcyBlbmNyeXB0ZWQgc2luY2Ugd2UgYXJlIHVzaW5nIHRoZSBnbG9iYWwgc2lnbmluZyBrZXkuXHJcbiAgICAgIC8vIHNpZ1ByazogaW5pdGlhdG9yU2lnUHJrLnRvSlNPTih0cnVlKSxcclxuXHJcbiAgICAgIC8vIFNhdmUgaXQgaW4gY2FzZSB0aGUgaW5pdGlhdG9yIHdhbnQgdG8gZGVjb2RlIHRoZSBvdEtleUNpcGhlci5cclxuICAgICAgLy8gU2luY2UgdGhlIG90S2V5IGlzIG9ubHkgdXNlZCBvbmNlLCBhbmQgdGhhdCBvdEtleUNpcGhlciBjb250YWlucyBvbmx5XHJcbiAgICAgIC8vIHRoZSBwdWJsaWMga2V5IG9mIHRoZSBpbml0aWF0b3IsIGl0J3Mgc2FmZSBqdXN0IGxlYXZlIHRoZSBvdEtleSBzdG9yZWQgaGVyZS5cclxuICAgICAgb3RLZXk6IG90S2V5LnRvSlNPTih0cnVlKSxcclxuICAgICAgLy8gVGhlc2Ugc2hvdWxkIGJlIHN0b3JpbmcgaW5mb3JtYXRpb24gc3VjaCBhcyBob3cgdGhlIGZpZWxkcyBvZiB0aGUgc2hhcmVkIGNvbnRhY3QgY2FyZCBpc1xyXG4gICAgICAvLyBkZXJpdmVkIGZyb20gdGhlIG1hc3RlciBjb250YWN0IGNhcmQuXHJcbiAgICAgIGluaXRpYXRvckNvbnRhY3RDYXJkOiBjb250YWN0Q2FyZCxcclxuICAgICAgaW5pdGlhdG9yLFxyXG4gICAgfTtcclxuXHJcbiAgICBjb25zdCByb290S2V5ID0gYXdhaXQgdGhpcy5rZXlTZXJ2aWNlLmdldEN1cnJlbnRSb290S2V5KCk7XHJcbiAgICBjb25zdCBpbml0aWF0b3JSb290S2V5Q2lwaGVyID0gYXdhaXQgdGhpcy5lbmNyeXB0aW9uU2VydmljZS5lbmNyeXB0KFxyXG4gICAgICByb290S2V5Lmp3ayxcclxuICAgICAgcGxhaW5Jbml0aWF0b3JSb290S2V5Q2lwaGVyXHJcbiAgICApO1xyXG5cclxuICAgIC8vIFRoZSByYXcgT1RLXHJcbiAgICBjb25zdCBvdEtleUs6IHN0cmluZyA9IChvdEtleS50b0pTT04odHJ1ZSkgYXMgYW55KS5rO1xyXG5cclxuICAgIC8vIEFQSSBjYWxsXHJcbiAgICBjb25zdCB7IGluaXRpYXRlS2V5RXhjaGFuZ2VPdGsgfSA9IGF3YWl0IHRoaXMubHJBcG9sbG8ubXV0YXRlPGFueT4oe1xyXG4gICAgICBtdXRhdGlvbjogSW5pdGlhdGVPdGtNdXRhdGlvbixcclxuICAgICAgdmFyaWFibGVzOiB7XHJcbiAgICAgICAgaW5wdXQ6IHtcclxuICAgICAgICAgIC8vIFRoZXNlIHdpbGwgYmUgc3RvcmVkIG9uIHRoZSBzZXJ2ZXJcclxuICAgICAgICAgIGluaXRpYXRvclJvb3RLZXlDaXBoZXI6IEpTT04uc3RyaW5naWZ5KGluaXRpYXRvclJvb3RLZXlDaXBoZXIpLFxyXG4gICAgICAgICAgaW5pdGlhdG9yUHhrSWQ6IGluaXRpYXRvclByay5pZCxcclxuICAgICAgICAgIGluaXRpYXRvclNpZ1B4a0lkOiBpbml0aWF0b3JTaWdQcmsuaWQsXHJcbiAgICAgICAgICAvLyBUaGVzZSB3aWxsIGJlIHNlbnQgdG8gdGhlIHJlc3BvbmRlclxyXG4gICAgICAgICAgb3RLZXlQYXJhbXM6IEpTT04uc3RyaW5naWZ5KG90S2V5LnRvSlNPTigpKSxcclxuICAgICAgICAgIG90S2V5Q2lwaGVyOiBKU09OLnN0cmluZ2lmeShvdEtleUNpcGhlciksXHJcbiAgICAgICAgICBzZW5kRW1haWw6IGVtYWlsXHJcbiAgICAgICAgICAgID8ge1xyXG4gICAgICAgICAgICAgICAgZW1haWwsXHJcbiAgICAgICAgICAgICAgICByYXdPdEtleTogb3RLZXlLLFxyXG4gICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgOiBudWxsLFxyXG4gICAgICAgICAgY3JlYXRlVHA6IHRydWUsXHJcbiAgICAgICAgICBpbml0aWF0b3JQbGFpbkRhdGFTaWcsXHJcbiAgICAgICAgICB1cGdyYWRlLFxyXG4gICAgICAgIH0sXHJcbiAgICAgIH0sXHJcbiAgICB9KTtcclxuICAgIHJldHVybiB7IGtleUV4Y2hhbmdlOiBpbml0aWF0ZUtleUV4Y2hhbmdlT3RrLmtleUV4Y2hhbmdlLCBvdEtleUsgfTtcclxuICB9XHJcblxyXG4gIGFzeW5jIHJlc3BvbmRPdGsoe1xyXG4gICAgaWQsXHJcbiAgICB0b2tlbixcclxuICAgIGRlY3J5cHRlZE90ayxcclxuICAgIG1lc3NhZ2UsXHJcbiAgICBpbml0aWF0b3JDb250YWN0Q2FyZCxcclxuICAgIHJlc3BvbmRlckNvbnRhY3RDYXJkOiBzZW50Q29udGFjdENhcmQsXHJcbiAgfTogUmVzcG9uZE90a0lucHV0KTogUHJvbWlzZTxSZXNwb25kT3RrPiB7XHJcbiAgICBjb25zdCB1c2VyID0gYXdhaXQgdGhpcy5hdXRoU2VydmljZS5nZXRVc2VyKCk7XHJcbiAgICBjb25zdCByb290S2V5ID0gYXdhaXQgdGhpcy5rZXlTZXJ2aWNlLmdldEN1cnJlbnRSb290S2V5KCk7XHJcblxyXG4gICAgY29uc3QgbWFzdGVyS2V5SWQgPSB0aGlzLmtleVNlcnZpY2UuZ2V0Q3VycmVudE1hc3RlcktleSgpLmlkO1xyXG4gICAgY29uc3QgbWFzdGVyS2V5ID0gYXdhaXQgdGhpcy5rZXlTZXJ2aWNlLmdldEN1cnJlbnRNYXN0ZXJLZXkoKTtcclxuXHJcbiAgICBjb25zdCBzaGFyZWRLZXkgPSBhd2FpdCB0aGlzLmtleUZhY3RvcnkuY3JlYXRlS2V5KCk7XHJcbiAgICBjb25zdCBta1NoYXJlZEtleSA9IGF3YWl0IHRoaXMua2V5RmFjdG9yeS5jcmVhdGVLZXkoKTtcclxuXHJcbiAgICBjb25zdCBya1dyYXBwZWRTaGFyZWRLZXkgPSBhd2FpdCB0aGlzLmVuY3J5cHRpb25TZXJ2aWNlLmVuY3J5cHQoXHJcbiAgICAgIHJvb3RLZXkuandrLFxyXG4gICAgICBzaGFyZWRLZXkudG9KU09OKHRydWUpXHJcbiAgICApO1xyXG4gICAgY29uc3QgbWtXcmFwcGVkTWtTaGFyZWRLZXkgPSBhd2FpdCB0aGlzLmVuY3J5cHRpb25TZXJ2aWNlLmVuY3J5cHQoXHJcbiAgICAgIG1hc3RlcktleS5qd2ssXHJcbiAgICAgIG1rU2hhcmVkS2V5LnRvSlNPTih0cnVlKVxyXG4gICAgKTtcclxuXHJcbiAgICBjb25zdCBpbml0aWF0b3JPbmVUaW1lUGJrID0gYXdhaXQgS0ZTLmFzS2V5KFxyXG4gICAgICBkZWNyeXB0ZWRPdGsucGxhaW5PdEtleUNpcGhlci5pbml0aWF0b3Iub25lVGltZVBia1xyXG4gICAgKTtcclxuXHJcbiAgICBjb25zdCBpbml0aWF0b3JQYmsgPSBhd2FpdCBLRlMuYXNLZXkoXHJcbiAgICAgIGRlY3J5cHRlZE90ay5wbGFpbk90S2V5Q2lwaGVyLmluaXRpYXRvci5wYmtcclxuICAgICk7XHJcbiAgICBjb25zdCBpbml0aWF0b3JTaWdQYmsgPSBhd2FpdCBLRlMuYXNLZXkoXHJcbiAgICAgIGRlY3J5cHRlZE90ay5wbGFpbk90S2V5Q2lwaGVyLmluaXRpYXRvci5zaWdQYmtcclxuICAgICk7XHJcblxyXG4gICAgLy8gT3B0aW9uIDE6IFVzaW5nIG5ldyBQcmsgZm9yIGVhY2ggVFAgcGFpclxyXG4gICAgLy8gQ3JlYXRlIGEgbmV3IHB1YmxpYyBzaWduaW5nIGtleSBmb3IgdGhlIHJlc3BvbmRlci5cclxuICAgIC8vIGNvbnN0IHJlc3BvbmRlclNpZ1ByayA9IGF3YWl0IHRoaXMua2V5U2VydmljZS5jcmVhdGVQa2NTaWduS2V5KClcclxuICAgIC8vIGNvbnN0IHJrV3JhcHBlZFJlc3BvbmRlclNpZ1ByayA9IGF3YWl0IHRoaXMuZW5jcnlwdChyb290S2V5LCByZXNwb25kZXJTaWdQcmsudG9KU09OKHRydWUpKTtcclxuXHJcbiAgICAvLyBPcHRpb24gMjogUmVzcG9uZGVyIGFscmVhZHkgaGFzIGEgc2lnbmluZyBQcmtcclxuICAgIGNvbnN0IHJlc3BvbmRlclByayA9IGF3YWl0IHRoaXMua2V5U2VydmljZS5nZXRDdXJyZW50UHhrKCk7XHJcbiAgICBjb25zdCByZXNwb25kZXJTaWdQcmsgPSBhd2FpdCB0aGlzLmtleVNlcnZpY2UuZ2V0Q3VycmVudFNpZ1B4aygpO1xyXG5cclxuICAgIGNvbnN0IHNpZ25lZEluaXRpYXRvclBiayA9IGF3YWl0IHRoaXMuZW5jcnlwdGlvblNlcnZpY2Uuc2lnbihcclxuICAgICAgcmVzcG9uZGVyU2lnUHJrLmp3ayxcclxuICAgICAgaW5pdGlhdG9yUGJrLnRvSlNPTigpXHJcbiAgICApO1xyXG4gICAgY29uc3Qgc2lnbmVkSW5pdGlhdG9yU2lnUGJrID0gYXdhaXQgdGhpcy5lbmNyeXB0aW9uU2VydmljZS5zaWduKFxyXG4gICAgICByZXNwb25kZXJTaWdQcmsuandrLFxyXG4gICAgICBpbml0aWF0b3JTaWdQYmsudG9KU09OKClcclxuICAgICk7XHJcblxyXG4gICAgY29uc3QgcGxhaW5Jbml0aWF0b3JPbmVUaW1lUGJrQ2lwaGVyOiBQbGFpbkluaXRpYXRvck9uZVRpbWVQYmtDaXBoZXIgPSB7XHJcbiAgICAgIG5vbmNlOiBkZWNyeXB0ZWRPdGsucGxhaW5PdEtleUNpcGhlci5ub25jZSxcclxuICAgICAgc2hhcmVkS2V5OiBzaGFyZWRLZXkudG9KU09OKHRydWUpLFxyXG4gICAgICBta1NoYXJlZEtleTogbWtTaGFyZWRLZXkudG9KU09OKHRydWUpLFxyXG4gICAgICByZXNwb25kZXI6IHtcclxuICAgICAgICBwYms6IHJlc3BvbmRlclByay5qd2sudG9KU09OKCksIC8vIHB1YmxpYyBrZXlcclxuICAgICAgICBzaWdQYms6IHJlc3BvbmRlclNpZ1Byay5qd2sudG9KU09OKCksIC8vIHB1YmxpYyBrZXlcclxuICAgICAgICBwcm9maWxlOiB7XHJcbiAgICAgICAgICB1c2VybmFtZTogdXNlci51c2VybmFtZSxcclxuICAgICAgICB9LFxyXG4gICAgICAgIG1lc3NhZ2UsXHJcbiAgICAgIH0sXHJcbiAgICB9O1xyXG5cclxuICAgIGxldCByZWNlaXZlZENhcmRJbnB1dDtcclxuICAgIGlmIChkZWNyeXB0ZWRPdGsucGxhaW5PdEtleUNpcGhlci5pbml0aWF0b3IuY29udGFjdENhcmQpIHtcclxuICAgICAgLy8gU2V0IHRoZSBpbmZvIGFib3V0IHRoZSBpbml0aWF0b3IgdG8gYmUgdGhlIG9uZXMgc2VudCBieSB0aGUgaW5pdGlhdG9yLiBXZSBuZWVkIHRoIHJlc3BvbmRlciB0byBkbyB0aGUgZW5jcnlwdGlvbiBoZXJlXHJcbiAgICAgIC8vIGJlY2F1c2UgdGhlIGluaXRpYXRvciBkb2VzIG5vdCBoYXZlIHRoZSBzaGFyZWQga2V5IHlldCwgYW5kIHdlIHdhbnQgdGhlIHJlc3BvbmRlciB0byBoYXZlIGEgZnVuY3Rpb25hbCBjb250YWN0IGNhcmQgYWZ0ZXJcclxuICAgICAgLy8gdGhpcyBleGNoYW5nZS4gVGhlIGluaXRpYXRvciBjYW4gZG91YmxlIGNoZWNrIHRoZSBjb250YWN0IGRldGFpbHMgYXJlIGNvcnJlY3QgYW5kIHNpZ24gaXQgd2hlbiBpdCBjb21wbGV0ZXMgdGhlIGV4Y2hhbmdlLlxyXG4gICAgICBjb25zdCBwbGFpblNoYXJlZENpcGhlckRhdGFKc29uID1cclxuICAgICAgICBkZWNyeXB0ZWRPdGsucGxhaW5PdEtleUNpcGhlci5pbml0aWF0b3IuY29udGFjdENhcmRcclxuICAgICAgICAgIC5wbGFpblNoYXJlZENpcGhlckRhdGFKc29uO1xyXG5cclxuICAgICAgLy8gQ3JlYXRlIGtleXNcclxuICAgICAgY29uc3QgcmVjZWl2ZXJLZXkgPSBhd2FpdCB0aGlzLmtleUZhY3RvcnkuY3JlYXRlS2V5KCk7XHJcbiAgICAgIGNvbnN0IGNjU2hhcmVkS2V5ID0gYXdhaXQgdGhpcy5rZXlGYWN0b3J5LmNyZWF0ZUtleSgpO1xyXG4gICAgICBjb25zdCBzaWdQeGsgPSBhd2FpdCB0aGlzLmtleVNlcnZpY2UuZ2V0Q3VycmVudFNpZ1B4aygpO1xyXG5cclxuICAgICAgcmVjZWl2ZWRDYXJkSW5wdXQgPSB7XHJcbiAgICAgICAgcmVjZWl2ZXJXcmFwcGVkS2V5OiBKU09OLnN0cmluZ2lmeShcclxuICAgICAgICAgIGF3YWl0IHRoaXMuZW5jcnlwdGlvblNlcnZpY2UuZW5jcnlwdChcclxuICAgICAgICAgICAgcm9vdEtleS5qd2ssXHJcbiAgICAgICAgICAgIHJlY2VpdmVyS2V5LnRvSlNPTih0cnVlKVxyXG4gICAgICAgICAgKVxyXG4gICAgICAgICksXHJcbiAgICAgICAgcmVjZWl2ZXJXcmFwcGluZ0tleUlkOiByb290S2V5LmlkLFxyXG4gICAgICAgIHJlY2VpdmVyQ2lwaGVyRGF0YTogaW5pdGlhdG9yQ29udGFjdENhcmRcclxuICAgICAgICAgID8gSlNPTi5zdHJpbmdpZnkoXHJcbiAgICAgICAgICAgICAgYXdhaXQgdGhpcy5lbmNyeXB0aW9uU2VydmljZS5lbmNyeXB0KFxyXG4gICAgICAgICAgICAgICAgcmVjZWl2ZXJLZXksXHJcbiAgICAgICAgICAgICAgICBpbml0aWF0b3JDb250YWN0Q2FyZC5wbGFpblJlY2VpdmVyQ2lwaGVyRGF0YUpzb25cclxuICAgICAgICAgICAgICApXHJcbiAgICAgICAgICAgIClcclxuICAgICAgICAgIDogJycsXHJcbiAgICAgICAgc2hhcmVkV3JhcHBlZEtleTogSlNPTi5zdHJpbmdpZnkoXHJcbiAgICAgICAgICBhd2FpdCB0aGlzLmVuY3J5cHRpb25TZXJ2aWNlLmVuY3J5cHQoXHJcbiAgICAgICAgICAgIHNoYXJlZEtleSxcclxuICAgICAgICAgICAgY2NTaGFyZWRLZXkudG9KU09OKHRydWUpXHJcbiAgICAgICAgICApXHJcbiAgICAgICAgKSxcclxuICAgICAgfTtcclxuXHJcbiAgICAgIGNvbnN0IHNoYXJlZENpcGhlckRhdGEgPSBhd2FpdCB0aGlzLmVuY3J5cHRpb25TZXJ2aWNlLmVuY3J5cHQoXHJcbiAgICAgICAgY2NTaGFyZWRLZXksXHJcbiAgICAgICAgcGxhaW5TaGFyZWRDaXBoZXJEYXRhSnNvblxyXG4gICAgICApO1xyXG4gICAgICByZWNlaXZlZENhcmRJbnB1dC5zaGFyZWRDaXBoZXJEYXRhU2lnID0gSlNPTi5zdHJpbmdpZnkoXHJcbiAgICAgICAgYXdhaXQgdGhpcy5lbmNyeXB0aW9uU2VydmljZS5zaWduKHNpZ1B4ay5qd2ssIHNoYXJlZENpcGhlckRhdGEpXHJcbiAgICAgICk7XHJcbiAgICAgIHJlY2VpdmVkQ2FyZElucHV0LnNpZ1B4a0lkID0gc2lnUHhrLmlkO1xyXG5cclxuICAgICAgcGxhaW5Jbml0aWF0b3JPbmVUaW1lUGJrQ2lwaGVyLnJlc3BvbmRlci5jb250YWN0Q2FyZCA9IHtcclxuICAgICAgICAuLi5wbGFpbkluaXRpYXRvck9uZVRpbWVQYmtDaXBoZXIucmVzcG9uZGVyLmNvbnRhY3RDYXJkLFxyXG4gICAgICAgIHNoYXJlZENpcGhlcktleTogY2NTaGFyZWRLZXkudG9KU09OKHRydWUpLFxyXG4gICAgICB9O1xyXG4gICAgfVxyXG5cclxuICAgIGxldCBzZW50Q2FyZElucHV0O1xyXG4gICAgaWYgKHNlbnRDb250YWN0Q2FyZCkge1xyXG4gICAgICAvLyBDcmVhdGUga2V5c1xyXG4gICAgICBjb25zdCBvd25lcktleSA9IGF3YWl0IHRoaXMua2V5RmFjdG9yeS5jcmVhdGVLZXkoKTtcclxuICAgICAgY29uc3QgY2NTaGFyZWRLZXkgPSBhd2FpdCB0aGlzLmtleUZhY3RvcnkuY3JlYXRlS2V5KCk7XHJcbiAgICAgIGNvbnN0IHNpZ1B4ayA9IGF3YWl0IHRoaXMua2V5U2VydmljZS5nZXRDdXJyZW50U2lnUHhrKCk7XHJcblxyXG4gICAgICBzZW50Q2FyZElucHV0ID0ge1xyXG4gICAgICAgIG93bmVyV3JhcHBlZEtleTogSlNPTi5zdHJpbmdpZnkoXHJcbiAgICAgICAgICBhd2FpdCB0aGlzLmVuY3J5cHRpb25TZXJ2aWNlLmVuY3J5cHQoXHJcbiAgICAgICAgICAgIHJvb3RLZXkuandrLFxyXG4gICAgICAgICAgICBvd25lcktleS50b0pTT04odHJ1ZSlcclxuICAgICAgICAgIClcclxuICAgICAgICApLFxyXG4gICAgICAgIG93bmVyV3JhcHBpbmdLZXlJZDogcm9vdEtleS5pZCxcclxuICAgICAgICBvd25lckNpcGhlckRhdGE6IHNlbnRDb250YWN0Q2FyZC5wbGFpbk93bmVyQ2lwaGVyRGF0YUpzb25cclxuICAgICAgICAgID8gSlNPTi5zdHJpbmdpZnkoXHJcbiAgICAgICAgICAgICAgYXdhaXQgdGhpcy5lbmNyeXB0aW9uU2VydmljZS5lbmNyeXB0KFxyXG4gICAgICAgICAgICAgICAgb3duZXJLZXksXHJcbiAgICAgICAgICAgICAgICBzZW50Q29udGFjdENhcmQucGxhaW5Pd25lckNpcGhlckRhdGFKc29uXHJcbiAgICAgICAgICAgICAgKVxyXG4gICAgICAgICAgICApXHJcbiAgICAgICAgICA6ICcnLFxyXG5cclxuICAgICAgICBzaGFyZWRXcmFwcGVkS2V5OiBKU09OLnN0cmluZ2lmeShcclxuICAgICAgICAgIGF3YWl0IHRoaXMuZW5jcnlwdGlvblNlcnZpY2UuZW5jcnlwdChcclxuICAgICAgICAgICAgc2hhcmVkS2V5LFxyXG4gICAgICAgICAgICBjY1NoYXJlZEtleS50b0pTT04odHJ1ZSlcclxuICAgICAgICAgIClcclxuICAgICAgICApLFxyXG4gICAgICB9O1xyXG5cclxuICAgICAgY29uc3Qgc2hhcmVkQ2lwaGVyRGF0YSA9IGF3YWl0IHRoaXMuZW5jcnlwdGlvblNlcnZpY2UuZW5jcnlwdChcclxuICAgICAgICBjY1NoYXJlZEtleSxcclxuICAgICAgICBzZW50Q29udGFjdENhcmQucGxhaW5TaGFyZWRDaXBoZXJEYXRhSnNvblxyXG4gICAgICApO1xyXG4gICAgICBzZW50Q2FyZElucHV0LnNoYXJlZENpcGhlckRhdGFTaWcgPSBKU09OLnN0cmluZ2lmeShcclxuICAgICAgICBhd2FpdCB0aGlzLmVuY3J5cHRpb25TZXJ2aWNlLnNpZ24oc2lnUHhrLmp3aywgc2hhcmVkQ2lwaGVyRGF0YSlcclxuICAgICAgKTtcclxuICAgICAgc2VudENhcmRJbnB1dC5zaWdQeGtJZCA9IHNpZ1B4ay5pZDtcclxuXHJcbiAgICAgIGlmIChzZW50Q29udGFjdENhcmQub3duZXJQbGFpbkRhdGEpIHtcclxuICAgICAgICBzZW50Q2FyZElucHV0Lm93bmVyUGxhaW5EYXRhU2lnID0gSlNPTi5zdHJpbmdpZnkoXHJcbiAgICAgICAgICBhd2FpdCB0aGlzLmVuY3J5cHRpb25TZXJ2aWNlLnNpZ24oXHJcbiAgICAgICAgICAgIHJlc3BvbmRlclNpZ1Byay5qd2ssXHJcbiAgICAgICAgICAgIHNlbnRDb250YWN0Q2FyZC5vd25lclBsYWluRGF0YVxyXG4gICAgICAgICAgKVxyXG4gICAgICAgICk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIC8vIENvbnRhY3QgY2FyZCBpbmZvIHJlYWRhYmxlIGJ5IHRoZSBpbml0aWF0b3JcclxuICAgICAgcGxhaW5Jbml0aWF0b3JPbmVUaW1lUGJrQ2lwaGVyLnJlc3BvbmRlci5jb250YWN0Q2FyZCA9IHtcclxuICAgICAgICAuLi5wbGFpbkluaXRpYXRvck9uZVRpbWVQYmtDaXBoZXIucmVzcG9uZGVyLmNvbnRhY3RDYXJkLFxyXG4gICAgICAgIHBsYWluU2hhcmVkQ2lwaGVyRGF0YUpzb246IHNlbnRDb250YWN0Q2FyZC5wbGFpblNoYXJlZENpcGhlckRhdGFKc29uLFxyXG4gICAgICB9O1xyXG4gICAgfVxyXG5cclxuICAgIC8vIEVuY3J5cHQgd2l0aCBvbmUtdGltZSBwdWJsaWMga2V5XHJcbiAgICBsZXQgaW5pdGlhdG9yT25lVGltZVBia0NpcGhlciA9IGF3YWl0IHRoaXMuZW5jcnlwdGlvblNlcnZpY2UuZW5jcnlwdChcclxuICAgICAgaW5pdGlhdG9yT25lVGltZVBiayxcclxuICAgICAgcGxhaW5Jbml0aWF0b3JPbmVUaW1lUGJrQ2lwaGVyXHJcbiAgICApO1xyXG5cclxuICAgIC8vIEVuY3J5cHQgd2l0aCB0aGUgb3RrIGFnYWluIHRvIGtlZXAgdXNlIG9mIGFzeW1tZXRyaWMga2V5cyB0byBhIG1pbmltdW0uXHJcbiAgICBpbml0aWF0b3JPbmVUaW1lUGJrQ2lwaGVyID0gYXdhaXQgdGhpcy5lbmNyeXB0aW9uU2VydmljZS5lbmNyeXB0KFxyXG4gICAgICBkZWNyeXB0ZWRPdGsub3RLZXksXHJcbiAgICAgIGluaXRpYXRvck9uZVRpbWVQYmtDaXBoZXJcclxuICAgICk7XHJcblxyXG4gICAgY29uc3QgeyByZXNwb25kS2V5RXhjaGFuZ2VPdGsgfSA9IGF3YWl0IHRoaXMubHJBcG9sbG8ubXV0YXRlPGFueT4oe1xyXG4gICAgICBtdXRhdGlvbjogUmVzcG9uZE90a011dGF0aW9uLFxyXG4gICAgICB2YXJpYWJsZXM6IHtcclxuICAgICAgICBpbnB1dDoge1xyXG4gICAgICAgICAga2V5RXhjaGFuZ2VJZDogaWQsXHJcbiAgICAgICAgICBrZXlFeGNoYW5nZVRva2VuOiB0b2tlbixcclxuICAgICAgICAgIHJvb3RLZXlJZDogcm9vdEtleS5pZCxcclxuICAgICAgICAgIG1hc3RlcktleUlkLFxyXG4gICAgICAgICAgLy8gVGhlc2Ugd2lsbCBiZSBzdG9yZWQgb24gdGhlIHNlcnZlclxyXG4gICAgICAgICAgcmVzcG9uZGVyUHhrSWQ6IHJlc3BvbmRlclByay5pZCxcclxuICAgICAgICAgIHJlc3BvbmRlclNpZ1B4a0lkOiByZXNwb25kZXJTaWdQcmsuaWQsXHJcbiAgICAgICAgICBzaWduZWRJbml0aWF0b3JQYms6IEpTT04uc3RyaW5naWZ5KHNpZ25lZEluaXRpYXRvclBiayksXHJcbiAgICAgICAgICBzaWduZWRJbml0aWF0b3JTaWdQYms6IEpTT04uc3RyaW5naWZ5KHNpZ25lZEluaXRpYXRvclNpZ1BiayksXHJcbiAgICAgICAgICAvLyBya1dyYXBwZWRJbml0aWF0b3JTaWdQYms6IEpTT04uc3RyaW5naWZ5KHJrV3JhcHBlZEluaXRpYXRvclNpZ1BiayksXHJcblxyXG4gICAgICAgICAgLy8gT3B0aW9uIDE6IFVzaW5nIG5ldyBQcmsgZm9yIGVhY2ggVFAgcGFpclxyXG4gICAgICAgICAgLy8gcmtXcmFwcGVkUmVzcG9uZGVyU2lnUHJrOiBKU09OLnN0cmluZ2lmeShya1dyYXBwZWRSZXNwb25kZXJTaWdQcmspLFxyXG4gICAgICAgICAgcmtXcmFwcGVkU2hhcmVkS2V5OiBKU09OLnN0cmluZ2lmeShya1dyYXBwZWRTaGFyZWRLZXkpLFxyXG4gICAgICAgICAgbWtXcmFwcGVkTWtTaGFyZWRLZXk6IEpTT04uc3RyaW5naWZ5KG1rV3JhcHBlZE1rU2hhcmVkS2V5KSxcclxuICAgICAgICAgIC8vIFRoZXNlIHdpbGwgYmUgc2VudCB0byB0aGUgaW5pdGlhdG9yXHJcbiAgICAgICAgICBpbml0aWF0b3JPbmVUaW1lUGJrQ2lwaGVyOiBKU09OLnN0cmluZ2lmeShpbml0aWF0b3JPbmVUaW1lUGJrQ2lwaGVyKSxcclxuICAgICAgICAgIGluaXRpYXRvckNvbnRhY3RDYXJkOiByZWNlaXZlZENhcmRJbnB1dCxcclxuICAgICAgICAgIHJlc3BvbmRlckNvbnRhY3RDYXJkOiBzZW50Q2FyZElucHV0LFxyXG4gICAgICAgIH0sXHJcbiAgICAgIH0sXHJcbiAgICB9KTtcclxuXHJcbiAgICByZXR1cm4ge1xyXG4gICAgICBrZXlFeGNoYW5nZTogcmVzcG9uZEtleUV4Y2hhbmdlT3RrLmtleUV4Y2hhbmdlLFxyXG4gICAgICB1c2VyU2hhcmVkS2V5OiByZXNwb25kS2V5RXhjaGFuZ2VPdGsudXNlclNoYXJlZEtleSxcclxuICAgICAgdHA6IHJlc3BvbmRLZXlFeGNoYW5nZU90ay50cCxcclxuICAgIH07XHJcbiAgfVxyXG5cclxuICBhc3luYyBjb21wbGV0ZU90ayhcclxuICAgIGtleUV4Y2hhbmdlSWQ6IHN0cmluZyxcclxuICAgIGluaXRpYXRvclJvb3RLZXlDaXBoZXI6IHN0cmluZyxcclxuICAgIGluaXRpYXRvck9uZVRpbWVQYmtDaXBoZXI6IHN0cmluZyxcclxuICAgIHJlc3BvbmRlckNvbnRhY3RDYXJkPzogc3RyaW5nXHJcbiAgKTogUHJvbWlzZTxDb21wbGV0ZU90az4ge1xyXG4gICAgY29uc3Qgcm9vdEtleSA9IGF3YWl0IHRoaXMua2V5U2VydmljZS5nZXRDdXJyZW50Um9vdEtleSgpO1xyXG4gICAgY29uc3QgbWFzdGVyS2V5ID0gYXdhaXQgdGhpcy5rZXlTZXJ2aWNlLmdldEN1cnJlbnRNYXN0ZXJLZXkoKTtcclxuXHJcbiAgICAvLyBEZWNyeXB0IHVzaW5nIHRoZSByb290IGtleSB0byBnZXQgdGhlIFBya1xyXG4gICAgY29uc3QgcGxhaW5Jbml0aWF0b3JSb290S2V5Q2lwaGVyID0gKChhd2FpdCB0aGlzLmVuY3J5cHRpb25TZXJ2aWNlLmRlY3J5cHQoXHJcbiAgICAgIHJvb3RLZXkuandrLFxyXG4gICAgICBpbml0aWF0b3JSb290S2V5Q2lwaGVyXHJcbiAgICApKSBhcyB1bmtub3duKSBhcyBQbGFpbkluaXRpYXRvclJvb3RLZXlDaXBoZXI7XHJcblxyXG4gICAgLy8gVGhlIFByayBpcyBzaW5nbGUtdXNlIGFuZCBvbmx5IHVzZWQgdG8gc2VuZCBpbmZvcm1hdGlvbiBmcm9tIHRoZSByZXNwb25kZXIgYmFjayB0byB0aGUgaW5pdGlhdG9yLlxyXG4gICAgY29uc3QgcGxhaW5Jbml0aWF0b3JPbmVUaW1lUGJrQ2lwaGVyID0gYXdhaXQgdGhpcy5kZWNyeXB0UmVzcG9uc2VDaXBoZXIoXHJcbiAgICAgIGF3YWl0IEtGUy5hc0tleShwbGFpbkluaXRpYXRvclJvb3RLZXlDaXBoZXIub3RLZXkpLFxyXG4gICAgICBhd2FpdCBLRlMuYXNLZXkocGxhaW5Jbml0aWF0b3JSb290S2V5Q2lwaGVyLm9uZVRpbWVQcmspLFxyXG4gICAgICBpbml0aWF0b3JPbmVUaW1lUGJrQ2lwaGVyXHJcbiAgICApO1xyXG5cclxuICAgIC8vIENoZWNrIHRoZSBub25jZSBtYXRjaCB0byBlbnN1cmUgdGhlIHJlc3BvbmRlciB3YXMgdGhlIG9uZSBob2xkaW5nIHRoZSBPVEtcclxuICAgIGlmIChcclxuICAgICAgcGxhaW5Jbml0aWF0b3JSb290S2V5Q2lwaGVyLm5vbmNlICE9PSBwbGFpbkluaXRpYXRvck9uZVRpbWVQYmtDaXBoZXIubm9uY2VcclxuICAgICkge1xyXG4gICAgICB0aHJvdyBuZXcgTHJDb2RlTWlzbWF0Y2hFeGNlcHRpb24oXHJcbiAgICAgICAgJ1RoZSBub25jZSByZXR1cm5lZCBieSByZXNwb25kZXIgZG9lcyBub3QgbWF0Y2ggd2l0aCB0aGUgb25lIGNyZWF0ZWQgYnkgdGhlIGluaXRpYXRvci4nXHJcbiAgICAgICk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gT3B0aW9uIDE6IEFzc3VtaW5nIHRoZSBzaWduaW5nIGtleSBpcyB1bmlxdWUgYmV0d2VlbiB1c2Vycy5cclxuICAgIC8vIGNvbnN0IGluaXRpYXRvclNpZ1ByayA9IGF3YWl0IEtGUy5hc0tleShrZS5wbGFpbkluaXRpYXRvclJvb3RLZXlDaXBoZXIuc2lnUHJrKTtcclxuICAgIC8vIGNvbnN0IHJrV3JhcHBlZEluaXRpYXRvclNpZ1ByayA9IGF3YWl0IHRoaXMuZW5jcnlwdChyb290S2V5LCBpbml0aWF0b3JTaWdQcmsudG9KU09OKHRydWUpKTtcclxuXHJcbiAgICAvLyBPcHRpb24gMjogVXNlIHRoZSB1c2VyJ3MgZ2xvYmFsIHNpZ25pbmcga2V5LlxyXG4gICAgLy8gSW4gdGhpcyBjYXNlIHRoZSBpbml0aWF0b3JTaWdQcmsgaXMgYWxyZWFkeSBhIHBhcnQgb2YgdGhlIGtleSBncmFwaC5cclxuICAgIC8vIFNvIHRoZXJlJ3Mgbm90aGluZyB0byBkbyBoZXJlLlxyXG5cclxuICAgIC8vIFByb3RlY3RlZCB0aGUgc2lnbmluZyBwdWJsaWMga2V5IG9mIHRoZSByZXNwb25kZXIuXHJcbiAgICBjb25zdCBpbml0aWF0b3JTaWdQcmsgPSBhd2FpdCB0aGlzLmtleVNlcnZpY2UuZ2V0Q3VycmVudFNpZ1B4aygpO1xyXG4gICAgY29uc3QgcmVzcG9uZGVyU2lnUGJrID0gYXdhaXQgS0ZTLmFzS2V5KFxyXG4gICAgICBwbGFpbkluaXRpYXRvck9uZVRpbWVQYmtDaXBoZXIucmVzcG9uZGVyLnNpZ1Bia1xyXG4gICAgKTtcclxuICAgIGNvbnN0IHJlc3BvbmRlclBiayA9IGF3YWl0IEtGUy5hc0tleShcclxuICAgICAgcGxhaW5Jbml0aWF0b3JPbmVUaW1lUGJrQ2lwaGVyLnJlc3BvbmRlci5wYmtcclxuICAgICk7XHJcblxyXG4gICAgY29uc3Qgc2lnbmVkUmVzcG9uZGVyUGJrID0gYXdhaXQgdGhpcy5lbmNyeXB0aW9uU2VydmljZS5zaWduKFxyXG4gICAgICBpbml0aWF0b3JTaWdQcmsuandrLFxyXG4gICAgICByZXNwb25kZXJQYmsudG9KU09OKClcclxuICAgICk7XHJcbiAgICBjb25zdCBzaWduZWRSZXNwb25kZXJTaWdQYmsgPSBhd2FpdCB0aGlzLmVuY3J5cHRpb25TZXJ2aWNlLnNpZ24oXHJcbiAgICAgIGluaXRpYXRvclNpZ1Byay5qd2ssXHJcbiAgICAgIHJlc3BvbmRlclNpZ1Biay50b0pTT04oKVxyXG4gICAgKTtcclxuXHJcbiAgICBjb25zdCBzaGFyZWRLZXkgPSBhd2FpdCBLRlMuYXNLZXkocGxhaW5Jbml0aWF0b3JPbmVUaW1lUGJrQ2lwaGVyLnNoYXJlZEtleSk7XHJcbiAgICBjb25zdCBya1dyYXBwZWRTaGFyZWRLZXkgPSBhd2FpdCB0aGlzLmVuY3J5cHRpb25TZXJ2aWNlLmVuY3J5cHQoXHJcbiAgICAgIHJvb3RLZXkuandrLFxyXG4gICAgICBzaGFyZWRLZXkudG9KU09OKHRydWUpXHJcbiAgICApO1xyXG5cclxuICAgIGNvbnN0IG1rU2hhcmVkS2V5ID0gYXdhaXQgS0ZTLmFzS2V5KFxyXG4gICAgICBwbGFpbkluaXRpYXRvck9uZVRpbWVQYmtDaXBoZXIubWtTaGFyZWRLZXlcclxuICAgICk7XHJcbiAgICBjb25zdCBta1dyYXBwZWRNa1NoYXJlZEtleSA9IGF3YWl0IHRoaXMuZW5jcnlwdGlvblNlcnZpY2UuZW5jcnlwdChcclxuICAgICAgbWFzdGVyS2V5Lmp3ayxcclxuICAgICAgbWtTaGFyZWRLZXkudG9KU09OKHRydWUpXHJcbiAgICApO1xyXG5cclxuICAgIGxldCByZXNwb25kZXJDb250YWN0Q2FyZENpcGhlcklucHV0O1xyXG4gICAgaWYgKHJlc3BvbmRlckNvbnRhY3RDYXJkKSB7XHJcbiAgICAgIC8vIENyZWF0ZSBrZXlcclxuICAgICAgY29uc3QgcmVjZWl2ZXJLZXkgPSBhd2FpdCB0aGlzLmtleUZhY3RvcnkuY3JlYXRlS2V5KCk7XHJcblxyXG4gICAgICByZXNwb25kZXJDb250YWN0Q2FyZENpcGhlcklucHV0ID0ge1xyXG4gICAgICAgIHJlY2VpdmVyV3JhcHBlZEtleTogSlNPTi5zdHJpbmdpZnkoXHJcbiAgICAgICAgICBhd2FpdCB0aGlzLmVuY3J5cHRpb25TZXJ2aWNlLmVuY3J5cHQoXHJcbiAgICAgICAgICAgIHJvb3RLZXkuandrLFxyXG4gICAgICAgICAgICByZWNlaXZlcktleS50b0pTT04odHJ1ZSlcclxuICAgICAgICAgIClcclxuICAgICAgICApLFxyXG4gICAgICAgIHJlY2VpdmVyV3JhcHBpbmdLZXlJZDogcm9vdEtleS5pZCxcclxuICAgICAgICByZWNlaXZlckNpcGhlckRhdGE6IEpTT04uc3RyaW5naWZ5KFxyXG4gICAgICAgICAgYXdhaXQgdGhpcy5lbmNyeXB0aW9uU2VydmljZS5lbmNyeXB0KFxyXG4gICAgICAgICAgICByZWNlaXZlcktleSxcclxuICAgICAgICAgICAgcmVzcG9uZGVyQ29udGFjdENhcmRcclxuICAgICAgICAgIClcclxuICAgICAgICApLFxyXG4gICAgICB9O1xyXG4gICAgfVxyXG5cclxuICAgIC8vIEdldCB0aGUgZGF0YSBuZWVkZWQgZnJvbSB0aGUgaW5pdGlhdG9yJ3MgY2lwaGVyIGRhdGEuXHJcbiAgICBsZXQgaW5pdGlhdG9yQ29udGFjdENhcmRDaXBoZXJJbnB1dDtcclxuICAgIGxldCBpbml0aWF0b3JDb250YWN0Q2FyZFNoYXJlZENpcGhlcklucHV0O1xyXG4gICAgaWYgKHBsYWluSW5pdGlhdG9yUm9vdEtleUNpcGhlci5pbml0aWF0b3JDb250YWN0Q2FyZCkge1xyXG4gICAgICBjb25zdCBpbml0aWF0b3JDb250YWN0Q2FyZCA9XHJcbiAgICAgICAgcGxhaW5Jbml0aWF0b3JSb290S2V5Q2lwaGVyLmluaXRpYXRvckNvbnRhY3RDYXJkO1xyXG4gICAgICBjb25zdCBvd25lcktleSA9IGF3YWl0IHRoaXMua2V5RmFjdG9yeS5jcmVhdGVLZXkoKTtcclxuICAgICAgY29uc3Qgc2hhcmVkQ2lwaGVyS2V5ID0gYXdhaXQgS0ZTLmFzS2V5KFxyXG4gICAgICAgIHBsYWluSW5pdGlhdG9yT25lVGltZVBia0NpcGhlci5yZXNwb25kZXIuY29udGFjdENhcmQuc2hhcmVkQ2lwaGVyS2V5XHJcbiAgICAgICk7XHJcblxyXG4gICAgICBjb25zdCBvd25lcldyYXBwZWRLZXkgPSBKU09OLnN0cmluZ2lmeShcclxuICAgICAgICBhd2FpdCB0aGlzLmVuY3J5cHRpb25TZXJ2aWNlLmVuY3J5cHQocm9vdEtleS5qd2ssIG93bmVyS2V5LnRvSlNPTih0cnVlKSlcclxuICAgICAgKTtcclxuICAgICAgY29uc3Qgb3duZXJDaXBoZXJEYXRhID0gaW5pdGlhdG9yQ29udGFjdENhcmQucGxhaW5Pd25lckNpcGhlckRhdGFKc29uXHJcbiAgICAgICAgPyBKU09OLnN0cmluZ2lmeShcclxuICAgICAgICAgICAgYXdhaXQgdGhpcy5lbmNyeXB0aW9uU2VydmljZS5lbmNyeXB0KFxyXG4gICAgICAgICAgICAgIG93bmVyS2V5LFxyXG4gICAgICAgICAgICAgIGluaXRpYXRvckNvbnRhY3RDYXJkLnBsYWluT3duZXJDaXBoZXJEYXRhSnNvblxyXG4gICAgICAgICAgICApXHJcbiAgICAgICAgICApXHJcbiAgICAgICAgOiAnJztcclxuXHJcbiAgICAgIGluaXRpYXRvckNvbnRhY3RDYXJkQ2lwaGVySW5wdXQgPSB7XHJcbiAgICAgICAgb3duZXJXcmFwcGVkS2V5LFxyXG4gICAgICAgIG93bmVyV3JhcHBpbmdLZXlJZDogcm9vdEtleS5pZCxcclxuICAgICAgICBvd25lckNpcGhlckRhdGEsXHJcbiAgICAgIH07XHJcblxyXG4gICAgICBpbml0aWF0b3JDb250YWN0Q2FyZFNoYXJlZENpcGhlcklucHV0ID0ge1xyXG4gICAgICAgIHNpZ1B4a0lkOiBpbml0aWF0b3JTaWdQcmsuaWQsXHJcbiAgICAgIH07XHJcblxyXG4gICAgICBjb25zdCBzaGFyZWRDaXBoZXJEYXRhID0gYXdhaXQgdGhpcy5lbmNyeXB0aW9uU2VydmljZS5lbmNyeXB0KFxyXG4gICAgICAgIHNoYXJlZENpcGhlcktleSxcclxuICAgICAgICBpbml0aWF0b3JDb250YWN0Q2FyZC5wbGFpblNoYXJlZENpcGhlckRhdGFKc29uXHJcbiAgICAgICk7XHJcbiAgICAgIGluaXRpYXRvckNvbnRhY3RDYXJkU2hhcmVkQ2lwaGVySW5wdXQuc2hhcmVkQ2lwaGVyRGF0YVNpZyA9IEpTT04uc3RyaW5naWZ5KFxyXG4gICAgICAgIGF3YWl0IHRoaXMuZW5jcnlwdGlvblNlcnZpY2Uuc2lnbihpbml0aWF0b3JTaWdQcmsuandrLCBzaGFyZWRDaXBoZXJEYXRhKVxyXG4gICAgICApO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIFRPRE8gaWRlYWxseSB3ZSB1cGRhdGUgdGhlIHNoYXJlZCBkYXRhIGluIHRoZSBjb250YWN0IGNhcmQgc2VudCB0byB0aGUgcmVzcG9uZGVyIGFzIHdlbGwgc2luY2UgdGhhdFxyXG4gICAgLy8gQ0Mgd2FzIGNyZWF0ZWQgYnkgdGhlIHJlc3BvbmRlci5cclxuXHJcbiAgICBjb25zdCByZXMgPSBhd2FpdCB0aGlzLmxyQXBvbGxvLm11dGF0ZTxhbnk+KHtcclxuICAgICAgbXV0YXRpb246IENvbXBsZXRlT3RrTXV0YXRpb24sXHJcbiAgICAgIHZhcmlhYmxlczoge1xyXG4gICAgICAgIGlucHV0OiB7XHJcbiAgICAgICAgICBrZXlFeGNoYW5nZUlkLFxyXG4gICAgICAgICAgcm9vdEtleUlkOiByb290S2V5LmlkLFxyXG4gICAgICAgICAgbWFzdGVyS2V5SWQ6IG1hc3RlcktleS5pZCxcclxuICAgICAgICAgIGluaXRpYXRvclNpZ1B4a0lkOiBpbml0aWF0b3JTaWdQcmsuaWQsXHJcbiAgICAgICAgICBzaWduZWRSZXNwb25kZXJQYms6IEpTT04uc3RyaW5naWZ5KHNpZ25lZFJlc3BvbmRlclBiayksXHJcbiAgICAgICAgICBzaWduZWRSZXNwb25kZXJTaWdQYms6IEpTT04uc3RyaW5naWZ5KHNpZ25lZFJlc3BvbmRlclNpZ1BiayksXHJcbiAgICAgICAgICBya1dyYXBwZWRTaGFyZWRLZXk6IEpTT04uc3RyaW5naWZ5KHJrV3JhcHBlZFNoYXJlZEtleSksXHJcbiAgICAgICAgICBta1dyYXBwZWRNa1NoYXJlZEtleTogSlNPTi5zdHJpbmdpZnkobWtXcmFwcGVkTWtTaGFyZWRLZXkpLFxyXG4gICAgICAgICAgcmVzcG9uZGVyQ29udGFjdENhcmRDaXBoZXI6IHJlc3BvbmRlckNvbnRhY3RDYXJkQ2lwaGVySW5wdXQsXHJcbiAgICAgICAgICBpbml0aWF0b3JDb250YWN0Q2FyZENpcGhlcjogaW5pdGlhdG9yQ29udGFjdENhcmRDaXBoZXJJbnB1dCxcclxuICAgICAgICAgIGluaXRpYXRvckNvbnRhY3RDYXJkU2hhcmVkQ2lwaGVyOiBpbml0aWF0b3JDb250YWN0Q2FyZFNoYXJlZENpcGhlcklucHV0LFxyXG4gICAgICAgIH0sXHJcbiAgICAgIH0sXHJcbiAgICB9KTtcclxuICAgIHJldHVybiByZXMuY29tcGxldGVLZXlFeGNoYW5nZU90aztcclxuICB9XHJcblxyXG4gIHB1YmxpYyBhc3luYyBjdXJyZW50VXNlclNoYXJlZEtleShpbnB1dDoge1xyXG4gICAgdXNlcm5hbWU/OiBzdHJpbmc7XHJcbiAgICB1c2VySWQ/OiBzdHJpbmc7XHJcbiAgfSk6IFByb21pc2U8VXNlclNoYXJlZEtleT4ge1xyXG4gICAgY29uc3QgeyBjdXJyZW50VXNlclNoYXJlZEtleSB9ID0gYXdhaXQgdGhpcy5sckFwb2xsby5xdWVyeTxhbnk+KHtcclxuICAgICAgcXVlcnk6IEN1cnJlbnRVc2VyU2hhcmVkS2V5UXVlcnksXHJcbiAgICAgIHZhcmlhYmxlczoge1xyXG4gICAgICAgIHVzZXJuYW1lOiBpbnB1dC51c2VybmFtZSxcclxuICAgICAgICB1c2VySWQ6IGlucHV0LnVzZXJJZCxcclxuICAgICAgfSxcclxuICAgIH0pO1xyXG4gICAgcmV0dXJuIGN1cnJlbnRVc2VyU2hhcmVkS2V5LnVzZXJTaGFyZWRLZXk7XHJcbiAgfVxyXG59XHJcbiJdfQ==