@lifeready/core 1.0.2 → 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (225) hide show
  1. package/README.md +62 -62
  2. package/bundles/lifeready-core.umd.js +15445 -15445
  3. package/bundles/lifeready-core.umd.js.map +1 -1
  4. package/bundles/lifeready-core.umd.min.js.map +1 -1
  5. package/esm2015/lib/_common/ast.js +40 -40
  6. package/esm2015/lib/_common/deferred-promise.js +24 -24
  7. package/esm2015/lib/_common/exceptions.js +157 -157
  8. package/esm2015/lib/_common/queries.gql.js +190 -190
  9. package/esm2015/lib/_common/run-outside-angular.js +79 -79
  10. package/esm2015/lib/_common/types.js +1 -1
  11. package/esm2015/lib/_common/utils.js +44 -44
  12. package/esm2015/lib/api/contact-card.gql.js +79 -79
  13. package/esm2015/lib/api/contact-card.service.js +154 -154
  14. package/esm2015/lib/api/contact-card2.gql.js +60 -60
  15. package/esm2015/lib/api/contact-card2.service.js +103 -103
  16. package/esm2015/lib/api/file.service.js +74 -74
  17. package/esm2015/lib/api/item2.gql.js +110 -110
  18. package/esm2015/lib/api/item2.service.js +311 -311
  19. package/esm2015/lib/api/key-exchange.gql.js +188 -188
  20. package/esm2015/lib/api/key-exchange.service.js +442 -442
  21. package/esm2015/lib/api/key-exchange.types.js +18 -18
  22. package/esm2015/lib/api/key-exchange2.gql.js +171 -171
  23. package/esm2015/lib/api/key-exchange2.service.js +479 -479
  24. package/esm2015/lib/api/lock.gql.js +40 -40
  25. package/esm2015/lib/api/lock.service.js +64 -64
  26. package/esm2015/lib/api/lr-apollo.service.js +46 -46
  27. package/esm2015/lib/api/lr-graphql/index.js +6 -6
  28. package/esm2015/lib/api/lr-graphql/lr-graphql.service.js +155 -155
  29. package/esm2015/lib/api/lr-graphql/lr-merged-mutation.js +213 -213
  30. package/esm2015/lib/api/lr-graphql/lr-mutation-base.js +51 -51
  31. package/esm2015/lib/api/lr-graphql/lr-mutation.js +48 -48
  32. package/esm2015/lib/api/lr-graphql/lr.service.js +18 -18
  33. package/esm2015/lib/api/message.service.js +138 -138
  34. package/esm2015/lib/api/persist.service.js +181 -181
  35. package/esm2015/lib/api/query-processor/common-processors.service.js +93 -93
  36. package/esm2015/lib/api/query-processor/index.js +3 -3
  37. package/esm2015/lib/api/query-processor/query-processor.service.js +192 -192
  38. package/esm2015/lib/api/query-processor/tp-password-reset-processor.service.js +109 -109
  39. package/esm2015/lib/api/shared-contact-card.service.js +119 -119
  40. package/esm2015/lib/api/shared-contact-card2.gql.js +41 -41
  41. package/esm2015/lib/api/shared-contact-card2.service.js +117 -117
  42. package/esm2015/lib/api/time.service.js +146 -146
  43. package/esm2015/lib/api/types/graphql.types.js +7 -7
  44. package/esm2015/lib/api/types/index.js +3 -3
  45. package/esm2015/lib/api/types/lr-graphql.types.js +71 -71
  46. package/esm2015/lib/auth/auth.config.js +57 -57
  47. package/esm2015/lib/auth/auth.gql.js +48 -48
  48. package/esm2015/lib/auth/auth.types.js +27 -27
  49. package/esm2015/lib/auth/idle.service.js +168 -168
  50. package/esm2015/lib/auth/idle.types.js +7 -7
  51. package/esm2015/lib/auth/lbop.service.js +355 -355
  52. package/esm2015/lib/auth/life-ready-auth.service.js +500 -500
  53. package/esm2015/lib/auth/password.service.js +320 -320
  54. package/esm2015/lib/auth/register.service.js +172 -172
  55. package/esm2015/lib/auth/two-factor.service.js +74 -74
  56. package/esm2015/lib/category/category-meta.service.js +99 -99
  57. package/esm2015/lib/category/category.gql.js +406 -406
  58. package/esm2015/lib/category/category.service.js +390 -390
  59. package/esm2015/lib/category/category.types.js +29 -29
  60. package/esm2015/lib/cryptography/cryptography.types.js +11 -11
  61. package/esm2015/lib/cryptography/encryption.service.js +189 -189
  62. package/esm2015/lib/cryptography/key-factory.service.js +237 -237
  63. package/esm2015/lib/cryptography/key-graph.service.js +280 -280
  64. package/esm2015/lib/cryptography/key-meta.service.js +200 -200
  65. package/esm2015/lib/cryptography/key.service.js +124 -124
  66. package/esm2015/lib/cryptography/slip39.service.js +169 -169
  67. package/esm2015/lib/cryptography/web-crypto.service.js +29 -29
  68. package/esm2015/lib/life-ready.config.js +84 -84
  69. package/esm2015/lib/life-ready.module.js +74 -74
  70. package/esm2015/lib/plan/plan.gql.js +123 -123
  71. package/esm2015/lib/plan/plan.service.js +149 -149
  72. package/esm2015/lib/plan/plan.types.js +11 -11
  73. package/esm2015/lib/record/record-attachment.service.js +101 -101
  74. package/esm2015/lib/record/record.gql.js +179 -179
  75. package/esm2015/lib/record/record.service.js +206 -206
  76. package/esm2015/lib/record/record.types.js +15 -15
  77. package/esm2015/lib/record-type/record-type.service.js +75 -75
  78. package/esm2015/lib/record-type/record-type.types.js +28 -28
  79. package/esm2015/lib/scenario/approvals/scenario-approval.gql.js +105 -105
  80. package/esm2015/lib/scenario/approvals/scenario-approval.types.js +1 -1
  81. package/esm2015/lib/scenario/approvals/scenario-approver.service.js +300 -300
  82. package/esm2015/lib/scenario/claimants/scenario-claimant.gql.js +52 -52
  83. package/esm2015/lib/scenario/claimants/scenario-claimant.service.js +97 -97
  84. package/esm2015/lib/scenario/claimants/scenario-claimant.types.js +1 -1
  85. package/esm2015/lib/scenario/receivers/scenario-receiver.gql.js +150 -150
  86. package/esm2015/lib/scenario/receivers/scenario-receiver.service.js +229 -229
  87. package/esm2015/lib/scenario/receivers/scenario-receiver.types.js +1 -1
  88. package/esm2015/lib/scenario/scenario-setup.service.js +269 -269
  89. package/esm2015/lib/scenario/scenario.gql.js +368 -368
  90. package/esm2015/lib/scenario/scenario.service.js +611 -611
  91. package/esm2015/lib/scenario/scenario.types.js +64 -64
  92. package/esm2015/lib/search/search.gql.js +62 -62
  93. package/esm2015/lib/search/search.service.js +156 -156
  94. package/esm2015/lib/search/search.types.js +6 -6
  95. package/esm2015/lib/trusted-parties/tp-password-reset-request.service.js +112 -112
  96. package/esm2015/lib/trusted-parties/tp-password-reset-user.service.js +129 -129
  97. package/esm2015/lib/trusted-parties/tp-password-reset.constants.js +4 -4
  98. package/esm2015/lib/trusted-parties/tp-password-reset.gql.js +232 -232
  99. package/esm2015/lib/trusted-parties/tp-password-reset.service.js +299 -299
  100. package/esm2015/lib/trusted-parties/trusted-party.gql.js +148 -148
  101. package/esm2015/lib/trusted-parties/trusted-party.service.js +326 -326
  102. package/esm2015/lib/trusted-parties/trusted-party.types.js +41 -41
  103. package/esm2015/lib/trusted-parties/trusted-party2.gql.js +87 -87
  104. package/esm2015/lib/trusted-parties/trusted-party2.service.js +215 -215
  105. package/esm2015/lib/users/profile-details.service.js +214 -214
  106. package/esm2015/lib/users/profile.gql.js +97 -97
  107. package/esm2015/lib/users/profile.service.js +169 -169
  108. package/esm2015/lib/users/profile.types.js +34 -34
  109. package/esm2015/lib/users/user.gql.js +60 -60
  110. package/esm2015/lib/users/user.service.js +79 -79
  111. package/esm2015/lib/users/user.types.js +5 -5
  112. package/esm2015/lifeready-core.js +10 -10
  113. package/esm2015/public-api.js +81 -81
  114. package/fesm2015/lifeready-core.js +13088 -13088
  115. package/fesm2015/lifeready-core.js.map +1 -1
  116. package/lib/_common/ast.d.ts +11 -11
  117. package/lib/_common/deferred-promise.d.ts +12 -12
  118. package/lib/_common/exceptions.d.ts +109 -109
  119. package/lib/_common/queries.gql.d.ts +10 -10
  120. package/lib/_common/run-outside-angular.d.ts +14 -14
  121. package/lib/_common/types.d.ts +10 -10
  122. package/lib/_common/utils.d.ts +3 -3
  123. package/lib/api/contact-card.gql.d.ts +7 -7
  124. package/lib/api/contact-card.service.d.ts +52 -52
  125. package/lib/api/contact-card2.gql.d.ts +34 -34
  126. package/lib/api/contact-card2.service.d.ts +49 -49
  127. package/lib/api/file.service.d.ts +18 -18
  128. package/lib/api/item2.gql.d.ts +96 -96
  129. package/lib/api/item2.service.d.ts +177 -177
  130. package/lib/api/key-exchange.gql.d.ts +9 -9
  131. package/lib/api/key-exchange.service.d.ts +39 -39
  132. package/lib/api/key-exchange.types.d.ts +196 -196
  133. package/lib/api/key-exchange2.gql.d.ts +125 -125
  134. package/lib/api/key-exchange2.service.d.ts +187 -187
  135. package/lib/api/lock.gql.d.ts +27 -27
  136. package/lib/api/lock.service.d.ts +25 -25
  137. package/lib/api/lr-apollo.service.d.ts +15 -15
  138. package/lib/api/lr-graphql/index.d.ts +5 -5
  139. package/lib/api/lr-graphql/lr-graphql.service.d.ts +60 -60
  140. package/lib/api/lr-graphql/lr-merged-mutation.d.ts +27 -27
  141. package/lib/api/lr-graphql/lr-mutation-base.d.ts +28 -28
  142. package/lib/api/lr-graphql/lr-mutation.d.ts +8 -8
  143. package/lib/api/lr-graphql/lr.service.d.ts +9 -9
  144. package/lib/api/message.service.d.ts +58 -58
  145. package/lib/api/persist.service.d.ts +31 -31
  146. package/lib/api/query-processor/common-processors.service.d.ts +36 -36
  147. package/lib/api/query-processor/index.d.ts +2 -2
  148. package/lib/api/query-processor/query-processor.service.d.ts +18 -18
  149. package/lib/api/query-processor/tp-password-reset-processor.service.d.ts +15 -15
  150. package/lib/api/shared-contact-card.service.d.ts +33 -33
  151. package/lib/api/shared-contact-card2.gql.d.ts +36 -36
  152. package/lib/api/shared-contact-card2.service.d.ts +45 -45
  153. package/lib/api/time.service.d.ts +16 -16
  154. package/lib/api/types/graphql.types.d.ts +29 -29
  155. package/lib/api/types/index.d.ts +2 -2
  156. package/lib/api/types/lr-graphql.types.d.ts +385 -385
  157. package/lib/auth/auth.config.d.ts +5 -5
  158. package/lib/auth/auth.gql.d.ts +15 -15
  159. package/lib/auth/auth.types.d.ts +66 -66
  160. package/lib/auth/idle.service.d.ts +40 -40
  161. package/lib/auth/idle.types.d.ts +10 -10
  162. package/lib/auth/lbop.service.d.ts +91 -91
  163. package/lib/auth/life-ready-auth.service.d.ts +59 -59
  164. package/lib/auth/password.service.d.ts +78 -78
  165. package/lib/auth/register.service.d.ts +25 -25
  166. package/lib/auth/two-factor.service.d.ts +15 -15
  167. package/lib/category/category-meta.service.d.ts +23 -23
  168. package/lib/category/category.gql.d.ts +45 -45
  169. package/lib/category/category.service.d.ts +67 -67
  170. package/lib/category/category.types.d.ts +79 -79
  171. package/lib/cryptography/cryptography.types.d.ts +83 -83
  172. package/lib/cryptography/encryption.service.d.ts +41 -41
  173. package/lib/cryptography/key-factory.service.d.ts +38 -38
  174. package/lib/cryptography/key-graph.service.d.ts +33 -33
  175. package/lib/cryptography/key-meta.service.d.ts +44 -44
  176. package/lib/cryptography/key.service.d.ts +36 -36
  177. package/lib/cryptography/slip39.service.d.ts +43 -43
  178. package/lib/cryptography/web-crypto.service.d.ts +5 -5
  179. package/lib/life-ready.config.d.ts +14 -14
  180. package/lib/life-ready.module.d.ts +5 -5
  181. package/lib/plan/plan.gql.d.ts +11 -11
  182. package/lib/plan/plan.service.d.ts +33 -33
  183. package/lib/plan/plan.types.d.ts +31 -31
  184. package/lib/record/record-attachment.service.d.ts +16 -16
  185. package/lib/record/record.gql.d.ts +14 -14
  186. package/lib/record/record.service.d.ts +25 -25
  187. package/lib/record/record.types.d.ts +57 -57
  188. package/lib/record-type/record-type.service.d.ts +11 -11
  189. package/lib/record-type/record-type.types.d.ts +50 -50
  190. package/lib/scenario/approvals/scenario-approval.gql.d.ts +7 -7
  191. package/lib/scenario/approvals/scenario-approval.types.d.ts +63 -63
  192. package/lib/scenario/approvals/scenario-approver.service.d.ts +32 -32
  193. package/lib/scenario/claimants/scenario-claimant.gql.d.ts +5 -5
  194. package/lib/scenario/claimants/scenario-claimant.service.d.ts +17 -17
  195. package/lib/scenario/claimants/scenario-claimant.types.d.ts +18 -18
  196. package/lib/scenario/receivers/scenario-receiver.gql.d.ts +8 -8
  197. package/lib/scenario/receivers/scenario-receiver.service.d.ts +30 -30
  198. package/lib/scenario/receivers/scenario-receiver.types.d.ts +54 -54
  199. package/lib/scenario/scenario-setup.service.d.ts +22 -22
  200. package/lib/scenario/scenario.gql.d.ts +34 -34
  201. package/lib/scenario/scenario.service.d.ts +58 -58
  202. package/lib/scenario/scenario.types.d.ts +217 -217
  203. package/lib/search/search.gql.d.ts +1 -1
  204. package/lib/search/search.service.d.ts +25 -25
  205. package/lib/search/search.types.d.ts +20 -20
  206. package/lib/trusted-parties/tp-password-reset-request.service.d.ts +20 -20
  207. package/lib/trusted-parties/tp-password-reset-user.service.d.ts +35 -35
  208. package/lib/trusted-parties/tp-password-reset.constants.d.ts +3 -3
  209. package/lib/trusted-parties/tp-password-reset.gql.d.ts +218 -218
  210. package/lib/trusted-parties/tp-password-reset.service.d.ts +130 -130
  211. package/lib/trusted-parties/trusted-party.gql.d.ts +9 -9
  212. package/lib/trusted-parties/trusted-party.service.d.ts +44 -44
  213. package/lib/trusted-parties/trusted-party.types.d.ts +102 -102
  214. package/lib/trusted-parties/trusted-party2.gql.d.ts +79 -79
  215. package/lib/trusted-parties/trusted-party2.service.d.ts +114 -114
  216. package/lib/users/profile-details.service.d.ts +21 -21
  217. package/lib/users/profile.gql.d.ts +11 -11
  218. package/lib/users/profile.service.d.ts +35 -35
  219. package/lib/users/profile.types.d.ts +96 -96
  220. package/lib/users/user.gql.d.ts +9 -9
  221. package/lib/users/user.service.d.ts +12 -12
  222. package/lib/users/user.types.d.ts +23 -23
  223. package/lifeready-core.d.ts +9 -9
  224. package/package.json +1 -1
  225. package/public-api.d.ts +77 -77
@@ -1,237 +1,237 @@
1
- import { __awaiter } from "tslib";
2
- import { Injectable } from '@angular/core';
3
- import { JWK } from 'node-jose';
4
- import { WebCryptoService } from './web-crypto.service';
5
- import { LrBadArgumentException, LrSuspiciousException, } from '../_common/exceptions';
6
- import * as i0 from "@angular/core";
7
- import * as i1 from "./web-crypto.service";
8
- export function sha256(message) {
9
- return __awaiter(this, void 0, void 0, function* () {
10
- // encode as UTF-8
11
- const msgBuffer = new TextEncoder().encode(message);
12
- // hash the message
13
- const hashBuffer = yield crypto.subtle.digest('SHA-256', msgBuffer);
14
- // convert ArrayBuffer to Array
15
- const hashArray = Array.from(new Uint8Array(hashBuffer));
16
- // convert bytes to hex string
17
- const hashHex = hashArray
18
- .map((b) => ('00' + b.toString(16)).slice(-2))
19
- .join('');
20
- return hashHex;
21
- });
22
- }
23
- export class KeyFactoryService {
24
- constructor(webCryptoService) {
25
- this.webCryptoService = webCryptoService;
26
- // Global keys store. Otherwise, each call to asKey creates a new keyStore.
27
- // <AZ> Did not seem to improve speed.
28
- // public static keyStore = JWK.createKeyStore();
29
- // AZ: This can't be change easily. It's basically a PassK or PassIdp rotation.
30
- // todo: we should eventually increase this periodically to match with Moore's law.
31
- // The iterations for each key are kept by the server as well but we assume the value
32
- // from the server is not trustworthy, so need to have minimum thresholds here.
33
- // If creating new keys, these minimum are used.
34
- this.MIN_PASS_IDP_PBKDF_ITER = 100000;
35
- this.MIN_PASS_KEY_PBKDF_ITER = 100000;
36
- this.MIN_LBOP_KEY_PBKDF_ITER = 100000;
37
- // These are used as the default values. They must be larger than the minimum values.
38
- this.DEFAULT_PASS_IDP_PBKDF_ITER = this.MIN_PASS_IDP_PBKDF_ITER;
39
- this.DEFAULT_PASS_KEY_PBKDF_ITER = this.MIN_PASS_KEY_PBKDF_ITER;
40
- this.DEFAULT_LBOP_KEY_PBKDF_ITER = this.MIN_LBOP_KEY_PBKDF_ITER;
41
- this.crypto = this.webCryptoService.crypto;
42
- }
43
- static asKey(key, form, extras) {
44
- // <AZ> Using a single global key store did not seem to improve speed.
45
- // return KeyFactoryService.keyStore.add(key, form, extras);
46
- return JWK.asKey(key, form, extras);
47
- }
48
- randomString(digits) {
49
- if (digits <= 0) {
50
- throw new LrBadArgumentException('digits <= 0');
51
- }
52
- const validChars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
53
- let array = new Uint32Array(digits);
54
- this.crypto.getRandomValues(array);
55
- array = array.map((x) => validChars.charCodeAt(x % validChars.length));
56
- return String.fromCharCode.apply(null, array);
57
- }
58
- randomDigitsNoZeros(digits) {
59
- return this.randomChoices([1, 2, 3, 4, 5, 6, 7, 8, 9], digits).join('');
60
- }
61
- randomChoices(array, chooseN) {
62
- if (array.length <= 1) {
63
- throw new LrBadArgumentException('array.length <= 0');
64
- }
65
- if (chooseN <= 0) {
66
- throw new LrBadArgumentException('chooseN <= 0');
67
- }
68
- const values = new Uint32Array(chooseN);
69
- this.crypto.getRandomValues(values);
70
- const ret = [];
71
- values.forEach((v) => ret.push(array[v % array.length]));
72
- return ret;
73
- }
74
- createSalt() {
75
- return this.randomString(16);
76
- }
77
- createKey() {
78
- return __awaiter(this, void 0, void 0, function* () {
79
- const key = yield this.crypto.subtle.generateKey({
80
- name: 'AES-GCM',
81
- length: 256,
82
- }, true, // whether the key is extractable (i.e. can be used in exportKey)
83
- ['encrypt', 'decrypt'] // must be ["encrypt", "decrypt"] or ["wrapKey", "unwrapKey"]
84
- );
85
- const jwk = yield this.crypto.subtle.exportKey('jwk', key);
86
- // Removing the fields not needed by node-jose
87
- delete jwk.ext;
88
- delete jwk.key_ops;
89
- return KeyFactoryService.asKey(jwk);
90
- });
91
- }
92
- createSignKey() {
93
- return __awaiter(this, void 0, void 0, function* () {
94
- const key = yield this.crypto.subtle.generateKey({
95
- name: 'HMAC',
96
- hash: { name: 'SHA-512' },
97
- }, true, ['sign', 'verify']);
98
- const jwk = yield this.crypto.subtle.exportKey('jwk', key);
99
- // Removing the fields not needed by node-jose
100
- delete jwk.key_ops;
101
- delete jwk.ext;
102
- return KeyFactoryService.asKey(jwk);
103
- });
104
- }
105
- createPkcKey() {
106
- return __awaiter(this, void 0, void 0, function* () {
107
- // node-jose is not using Forge properly. It should be calling the async version of
108
- // pki.rsa.generateKeyPair() with a callback. Instead it calls the sync version. Webcrypto
109
- // does not support sync version, so it uses the javascript implementation, which is way too slow.
110
- // So we generate using webcrypto and import the key.
111
- // Unfortunately Elliptical Curve is not supported by Webcrypto. So we have to settle for RSA.
112
- const key = yield this.crypto.subtle.generateKey({
113
- name: 'RSA-OAEP',
114
- modulusLength: 2048,
115
- // As per suggestion: https://developer.mozilla.org/en-US/docs/Web/API/RsaHashedKeyGenParams
116
- publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
117
- hash: { name: 'SHA-256' },
118
- }, true, // whether the key is extractable (i.e. can be used in exportKey)
119
- ['encrypt', 'decrypt'] // must be ["encrypt", "decrypt"] or ["wrapKey", "unwrapKey"]
120
- );
121
- const jwk = yield this.crypto.subtle.exportKey('jwk', key.privateKey);
122
- // Removing the fields not needed by node-jose
123
- delete jwk.key_ops;
124
- delete jwk.ext;
125
- return KeyFactoryService.asKey(jwk);
126
- });
127
- }
128
- createPkcSignKey() {
129
- return __awaiter(this, void 0, void 0, function* () {
130
- const key = yield this.crypto.subtle.generateKey({
131
- name: 'RSASSA-PKCS1-v1_5',
132
- modulusLength: 2048,
133
- // As per suggestion: https://developer.mozilla.org/en-US/docs/Web/API/RsaHashedKeyGenParams
134
- publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
135
- hash: { name: 'SHA-256' },
136
- }, true, // whether the key is extractable (i.e. can be used in exportKey)
137
- ['sign', 'verify'] // can be any combination of "sign" and "verify"
138
- );
139
- const jwk = yield this.crypto.subtle.exportKey('jwk', key.privateKey);
140
- // Removing the fields not needed by node-jose
141
- delete jwk.key_ops;
142
- delete jwk.ext;
143
- return KeyFactoryService.asKey(jwk);
144
- });
145
- }
146
- deriveKey({ password, salt, iterations, kid, }) {
147
- return __awaiter(this, void 0, void 0, function* () {
148
- const enc = new TextEncoder();
149
- const rawKey = yield this.crypto.subtle.importKey('raw', enc.encode(password), 'PBKDF2', false, ['deriveBits', 'deriveKey']);
150
- const passKey = yield crypto.subtle.deriveKey({
151
- name: 'PBKDF2',
152
- salt: new TextEncoder().encode(salt),
153
- iterations,
154
- hash: 'SHA-256',
155
- }, rawKey, { name: 'AES-GCM', length: 256 }, true, ['encrypt', 'decrypt']);
156
- const passKeyJson = yield crypto.subtle.exportKey('jwk', passKey);
157
- if (kid) {
158
- passKeyJson.kid = kid;
159
- }
160
- const jwk = yield KeyFactoryService.asKey(passKeyJson);
161
- return { jwk };
162
- });
163
- }
164
- derivePassIdp(params) {
165
- return __awaiter(this, void 0, void 0, function* () {
166
- if (params.iterations < this.MIN_PASS_IDP_PBKDF_ITER) {
167
- throw new LrSuspiciousException(`The number of PassIdp key derivation iterations sent from the server (${params.iterations}) is lower than the minimum (${this.MIN_PASS_IDP_PBKDF_ITER})`);
168
- }
169
- return this.deriveKey(params);
170
- });
171
- }
172
- derivePassKey(params) {
173
- return __awaiter(this, void 0, void 0, function* () {
174
- if (params.iterations < this.MIN_PASS_KEY_PBKDF_ITER) {
175
- throw new LrSuspiciousException(`The number of PassKey key derivation iterations sent from the server(${params.iterations}) is lower than the minimum(${this.MIN_PASS_KEY_PBKDF_ITER})`);
176
- }
177
- return this.deriveKey(params);
178
- });
179
- }
180
- deriveLbopKey(params) {
181
- return __awaiter(this, void 0, void 0, function* () {
182
- if (params.iterations < this.MIN_LBOP_KEY_PBKDF_ITER) {
183
- throw new LrSuspiciousException(`The number of LbopKey key derivation iterations sent from the server(${params.iterations}) is lower than the minimum(${this.MIN_LBOP_KEY_PBKDF_ITER})`);
184
- }
185
- return this.deriveKey(params);
186
- });
187
- }
188
- createKid() {
189
- return __awaiter(this, void 0, void 0, function* () {
190
- // todo: AZ: node-jose source uses node's default UUID() function for kid, so just change to use that.
191
- // for now, we are just creating a new key to use it's kid.
192
- // The kid is a part of the JWK system. LR backend maintains the key hierarchy separately with it's own
193
- // key id. But we just use it here as a double check.
194
- return (yield this.createKey()).kid;
195
- });
196
- }
197
- createPassIdpParams() {
198
- return __awaiter(this, void 0, void 0, function* () {
199
- return {
200
- salt: this.createSalt(),
201
- iterations: this.DEFAULT_PASS_IDP_PBKDF_ITER,
202
- };
203
- });
204
- }
205
- createPassKeyParams() {
206
- return __awaiter(this, void 0, void 0, function* () {
207
- return {
208
- salt: this.createSalt(),
209
- kid: yield this.createKid(),
210
- iterations: this.DEFAULT_PASS_KEY_PBKDF_ITER,
211
- };
212
- });
213
- }
214
- createLbopKeyParams() {
215
- return __awaiter(this, void 0, void 0, function* () {
216
- return {
217
- salt: this.createSalt(),
218
- // todo: AZ: node-jose source uses node's default UUID() function for kid, so just change to use that.
219
- // for now, we are just creating a new key to use it's kid.
220
- // The kid is a part of the JWK system. LR backend maintains the key hierarchy separately with it's own
221
- // key id. But we just use it here as a double check.
222
- kid: yield this.createKid(),
223
- iterations: this.DEFAULT_PASS_KEY_PBKDF_ITER,
224
- };
225
- });
226
- }
227
- }
228
- KeyFactoryService.ɵprov = i0.ɵɵdefineInjectable({ factory: function KeyFactoryService_Factory() { return new KeyFactoryService(i0.ɵɵinject(i1.WebCryptoService)); }, token: KeyFactoryService, providedIn: "root" });
229
- KeyFactoryService.decorators = [
230
- { type: Injectable, args: [{
231
- providedIn: 'root',
232
- },] }
233
- ];
234
- KeyFactoryService.ctorParameters = () => [
235
- { type: WebCryptoService }
236
- ];
237
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoia2V5LWZhY3Rvcnkuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIvb3B0L2F0bGFzc2lhbi9waXBlbGluZXMvYWdlbnQvYnVpbGQvcHJvamVjdHMvY29yZS9zcmMvIiwic291cmNlcyI6WyJsaWIvY3J5cHRvZ3JhcGh5L2tleS1mYWN0b3J5LnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDM0MsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLFdBQVcsQ0FBQztBQVVoQyxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUN4RCxPQUFPLEVBQ0wsc0JBQXNCLEVBQ3RCLHFCQUFxQixHQUN0QixNQUFNLHVCQUF1QixDQUFDOzs7QUFFL0IsTUFBTSxVQUFnQixNQUFNLENBQUMsT0FBTzs7UUFDbEMsa0JBQWtCO1FBQ2xCLE1BQU0sU0FBUyxHQUFHLElBQUksV0FBVyxFQUFFLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBRXBELG1CQUFtQjtRQUNuQixNQUFNLFVBQVUsR0FBRyxNQUFNLE1BQU0sQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLFNBQVMsRUFBRSxTQUFTLENBQUMsQ0FBQztRQUVwRSwrQkFBK0I7UUFDL0IsTUFBTSxTQUFTLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLFVBQVUsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDO1FBRXpELDhCQUE4QjtRQUM5QixNQUFNLE9BQU8sR0FBRyxTQUFTO2FBQ3RCLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxJQUFJLEdBQUcsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO2FBQzdDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUNaLE9BQU8sT0FBTyxDQUFDO0lBQ2pCLENBQUM7Q0FBQTtBQUtELE1BQU0sT0FBTyxpQkFBaUI7SUFDNUIsWUFBb0IsZ0JBQWtDO1FBQWxDLHFCQUFnQixHQUFoQixnQkFBZ0IsQ0FBa0I7UUFJdEQsMkVBQTJFO1FBQzNFLHNDQUFzQztRQUN0QyxpREFBaUQ7UUFFakQsK0VBQStFO1FBQy9FLG1GQUFtRjtRQUNuRixxRkFBcUY7UUFDckYsK0VBQStFO1FBQy9FLGdEQUFnRDtRQUNoQyw0QkFBdUIsR0FBRyxNQUFNLENBQUM7UUFDakMsNEJBQXVCLEdBQUcsTUFBTSxDQUFDO1FBQ2pDLDRCQUF1QixHQUFHLE1BQU0sQ0FBQztRQUVqRCxxRkFBcUY7UUFDckUsZ0NBQTJCLEdBQUcsSUFBSSxDQUFDLHVCQUF1QixDQUFDO1FBQzNELGdDQUEyQixHQUFHLElBQUksQ0FBQyx1QkFBdUIsQ0FBQztRQUMzRCxnQ0FBMkIsR0FBRyxJQUFJLENBQUMsdUJBQXVCLENBQUM7UUFuQnpFLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLE1BQU0sQ0FBQztJQUM3QyxDQUFDO0lBb0JELE1BQU0sQ0FBQyxLQUFLLENBQ1YsR0FBMEMsRUFDMUMsSUFRUyxFQUNULE1BQWdDO1FBRWhDLHNFQUFzRTtRQUN0RSw0REFBNEQ7UUFDNUQsT0FBTyxHQUFHLENBQUMsS0FBSyxDQUFDLEdBQUcsRUFBRSxJQUFJLEVBQUUsTUFBTSxDQUFDLENBQUM7SUFDdEMsQ0FBQztJQUVELFlBQVksQ0FBQyxNQUFjO1FBQ3pCLElBQUksTUFBTSxJQUFJLENBQUMsRUFBRTtZQUNmLE1BQU0sSUFBSSxzQkFBc0IsQ0FBQyxhQUFhLENBQUMsQ0FBQztTQUNqRDtRQUNELE1BQU0sVUFBVSxHQUNkLGdFQUFnRSxDQUFDO1FBQ25FLElBQUksS0FBSyxHQUFHLElBQUksV0FBVyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ3BDLElBQUksQ0FBQyxNQUFNLENBQUMsZUFBZSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ25DLEtBQUssR0FBRyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxVQUFVLENBQUMsVUFBVSxDQUFDLENBQUMsR0FBRyxVQUFVLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztRQUN2RSxPQUFPLE1BQU0sQ0FBQyxZQUFZLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxLQUFLLENBQUMsQ0FBQztJQUNoRCxDQUFDO0lBRUQsbUJBQW1CLENBQUMsTUFBYztRQUNoQyxPQUFPLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUMxRSxDQUFDO0lBRUQsYUFBYSxDQUFJLEtBQVUsRUFBRSxPQUFlO1FBQzFDLElBQUksS0FBSyxDQUFDLE1BQU0sSUFBSSxDQUFDLEVBQUU7WUFDckIsTUFBTSxJQUFJLHNCQUFzQixDQUFDLG1CQUFtQixDQUFDLENBQUM7U0FDdkQ7UUFDRCxJQUFJLE9BQU8sSUFBSSxDQUFDLEVBQUU7WUFDaEIsTUFBTSxJQUFJLHNCQUFzQixDQUFDLGNBQWMsQ0FBQyxDQUFDO1NBQ2xEO1FBQ0QsTUFBTSxNQUFNLEdBQUcsSUFBSSxXQUFXLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDeEMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxlQUFlLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDcEMsTUFBTSxHQUFHLEdBQVEsRUFBRSxDQUFDO1FBQ3BCLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3pELE9BQU8sR0FBRyxDQUFDO0lBQ2IsQ0FBQztJQUVELFVBQVU7UUFDUixPQUFPLElBQUksQ0FBQyxZQUFZLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDL0IsQ0FBQztJQUVLLFNBQVM7O1lBQ2IsTUFBTSxHQUFHLEdBQUcsTUFBTSxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxXQUFXLENBQzlDO2dCQUNFLElBQUksRUFBRSxTQUFTO2dCQUNmLE1BQU0sRUFBRSxHQUFHO2FBQ1osRUFDRCxJQUFJLEVBQUUsaUVBQWlFO1lBQ3ZFLENBQUMsU0FBUyxFQUFFLFNBQVMsQ0FBQyxDQUFDLDZEQUE2RDthQUNyRixDQUFDO1lBRUYsTUFBTSxHQUFHLEdBQUcsTUFBTSxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsS0FBSyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1lBRTNELDhDQUE4QztZQUM5QyxPQUFPLEdBQUcsQ0FBQyxHQUFHLENBQUM7WUFDZixPQUFPLEdBQUcsQ0FBQyxPQUFPLENBQUM7WUFFbkIsT0FBTyxpQkFBaUIsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDdEMsQ0FBQztLQUFBO0lBRUssYUFBYTs7WUFDakIsTUFBTSxHQUFHLEdBQUcsTUFBTSxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxXQUFXLENBQzlDO2dCQUNFLElBQUksRUFBRSxNQUFNO2dCQUNaLElBQUksRUFBRSxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUU7YUFDMUIsRUFDRCxJQUFJLEVBQ0osQ0FBQyxNQUFNLEVBQUUsUUFBUSxDQUFDLENBQ25CLENBQUM7WUFFRixNQUFNLEdBQUcsR0FBRyxNQUFNLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxLQUFLLEVBQUUsR0FBRyxDQUFDLENBQUM7WUFFM0QsOENBQThDO1lBQzlDLE9BQU8sR0FBRyxDQUFDLE9BQU8sQ0FBQztZQUNuQixPQUFPLEdBQUcsQ0FBQyxHQUFHLENBQUM7WUFFZixPQUFPLGlCQUFpQixDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUN0QyxDQUFDO0tBQUE7SUFFSyxZQUFZOztZQUNoQixtRkFBbUY7WUFDbkYsMEZBQTBGO1lBQzFGLGtHQUFrRztZQUNsRyxxREFBcUQ7WUFDckQsOEZBQThGO1lBQzlGLE1BQU0sR0FBRyxHQUFHLE1BQU0sSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUM5QztnQkFDRSxJQUFJLEVBQUUsVUFBVTtnQkFDaEIsYUFBYSxFQUFFLElBQUk7Z0JBQ25CLDRGQUE0RjtnQkFDNUYsY0FBYyxFQUFFLElBQUksVUFBVSxDQUFDLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQztnQkFDbEQsSUFBSSxFQUFFLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRTthQUMxQixFQUNELElBQUksRUFBRSxpRUFBaUU7WUFDdkUsQ0FBQyxTQUFTLEVBQUUsU0FBUyxDQUFDLENBQUMsNkRBQTZEO2FBQ3JGLENBQUM7WUFFRixNQUFNLEdBQUcsR0FBRyxNQUFNLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxLQUFLLEVBQUUsR0FBRyxDQUFDLFVBQVUsQ0FBQyxDQUFDO1lBQ3RFLDhDQUE4QztZQUM5QyxPQUFPLEdBQUcsQ0FBQyxPQUFPLENBQUM7WUFDbkIsT0FBTyxHQUFHLENBQUMsR0FBRyxDQUFDO1lBRWYsT0FBTyxpQkFBaUIsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDdEMsQ0FBQztLQUFBO0lBRUssZ0JBQWdCOztZQUNwQixNQUFNLEdBQUcsR0FBRyxNQUFNLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FDOUM7Z0JBQ0UsSUFBSSxFQUFFLG1CQUFtQjtnQkFDekIsYUFBYSxFQUFFLElBQUk7Z0JBQ25CLDRGQUE0RjtnQkFDNUYsY0FBYyxFQUFFLElBQUksVUFBVSxDQUFDLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQztnQkFDbEQsSUFBSSxFQUFFLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRTthQUMxQixFQUNELElBQUksRUFBRSxpRUFBaUU7WUFDdkUsQ0FBQyxNQUFNLEVBQUUsUUFBUSxDQUFDLENBQUMsZ0RBQWdEO2FBQ3BFLENBQUM7WUFFRixNQUFNLEdBQUcsR0FBRyxNQUFNLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxLQUFLLEVBQUUsR0FBRyxDQUFDLFVBQVUsQ0FBQyxDQUFDO1lBRXRFLDhDQUE4QztZQUM5QyxPQUFPLEdBQUcsQ0FBQyxPQUFPLENBQUM7WUFDbkIsT0FBTyxHQUFHLENBQUMsR0FBRyxDQUFDO1lBRWYsT0FBTyxpQkFBaUIsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDdEMsQ0FBQztLQUFBO0lBRUssU0FBUyxDQUFDLEVBQ2QsUUFBUSxFQUNSLElBQUksRUFDSixVQUFVLEVBQ1YsR0FBRyxHQU1KOztZQUNDLE1BQU0sR0FBRyxHQUFHLElBQUksV0FBVyxFQUFFLENBQUM7WUFDOUIsTUFBTSxNQUFNLEdBQUcsTUFBTSxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQy9DLEtBQUssRUFDTCxHQUFHLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxFQUNwQixRQUFRLEVBQ1IsS0FBSyxFQUNMLENBQUMsWUFBWSxFQUFFLFdBQVcsQ0FBQyxDQUM1QixDQUFDO1lBRUYsTUFBTSxPQUFPLEdBQUcsTUFBTSxNQUFNLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FDM0M7Z0JBQ0UsSUFBSSxFQUFFLFFBQVE7Z0JBQ2QsSUFBSSxFQUFFLElBQUksV0FBVyxFQUFFLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQztnQkFDcEMsVUFBVTtnQkFDVixJQUFJLEVBQUUsU0FBUzthQUNoQixFQUNELE1BQU0sRUFDTixFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsTUFBTSxFQUFFLEdBQUcsRUFBRSxFQUNoQyxJQUFJLEVBQ0osQ0FBQyxTQUFTLEVBQUUsU0FBUyxDQUFDLENBQ3ZCLENBQUM7WUFFRixNQUFNLFdBQVcsR0FBUSxNQUFNLE1BQU0sQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLEtBQUssRUFBRSxPQUFPLENBQUMsQ0FBQztZQUN2RSxJQUFJLEdBQUcsRUFBRTtnQkFDUCxXQUFXLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQzthQUN2QjtZQUVELE1BQU0sR0FBRyxHQUFHLE1BQU0saUJBQWlCLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxDQUFDO1lBRXZELE9BQU8sRUFBRSxHQUFHLEVBQUUsQ0FBQztRQUNqQixDQUFDO0tBQUE7SUFFSyxhQUFhLENBQUMsTUFBMkI7O1lBQzdDLElBQUksTUFBTSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUMsdUJBQXVCLEVBQUU7Z0JBQ3BELE1BQU0sSUFBSSxxQkFBcUIsQ0FDN0IseUVBQXlFLE1BQU0sQ0FBQyxVQUFVLGdDQUFnQyxJQUFJLENBQUMsdUJBQXVCLEdBQUcsQ0FDMUosQ0FBQzthQUNIO1lBQ0QsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ2hDLENBQUM7S0FBQTtJQUVLLGFBQWEsQ0FBQyxNQUEyQjs7WUFDN0MsSUFBSSxNQUFNLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQyx1QkFBdUIsRUFBRTtnQkFDcEQsTUFBTSxJQUFJLHFCQUFxQixDQUM3Qix3RUFBd0UsTUFBTSxDQUFDLFVBQVUsK0JBQStCLElBQUksQ0FBQyx1QkFBdUIsR0FBRyxDQUN4SixDQUFDO2FBQ0g7WUFDRCxPQUFPLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDaEMsQ0FBQztLQUFBO0lBRUssYUFBYSxDQUFDLE1BQTJCOztZQUM3QyxJQUFJLE1BQU0sQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLHVCQUF1QixFQUFFO2dCQUNwRCxNQUFNLElBQUkscUJBQXFCLENBQzdCLHdFQUF3RSxNQUFNLENBQUMsVUFBVSwrQkFBK0IsSUFBSSxDQUFDLHVCQUF1QixHQUFHLENBQ3hKLENBQUM7YUFDSDtZQUNELE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUNoQyxDQUFDO0tBQUE7SUFFSyxTQUFTOztZQUNiLHNHQUFzRztZQUN0RywyREFBMkQ7WUFDM0QsdUdBQXVHO1lBQ3ZHLHFEQUFxRDtZQUNyRCxPQUFPLENBQUMsTUFBTSxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUM7UUFDdEMsQ0FBQztLQUFBO0lBRUssbUJBQW1COztZQUN2QixPQUFPO2dCQUNMLElBQUksRUFBRSxJQUFJLENBQUMsVUFBVSxFQUFFO2dCQUN2QixVQUFVLEVBQUUsSUFBSSxDQUFDLDJCQUEyQjthQUM3QyxDQUFDO1FBQ0osQ0FBQztLQUFBO0lBRUssbUJBQW1COztZQUN2QixPQUFPO2dCQUNMLElBQUksRUFBRSxJQUFJLENBQUMsVUFBVSxFQUFFO2dCQUN2QixHQUFHLEVBQUUsTUFBTSxJQUFJLENBQUMsU0FBUyxFQUFFO2dCQUMzQixVQUFVLEVBQUUsSUFBSSxDQUFDLDJCQUEyQjthQUM3QyxDQUFDO1FBQ0osQ0FBQztLQUFBO0lBRUssbUJBQW1COztZQUN2QixPQUFPO2dCQUNMLElBQUksRUFBRSxJQUFJLENBQUMsVUFBVSxFQUFFO2dCQUN2QixzR0FBc0c7Z0JBQ3RHLDJEQUEyRDtnQkFDM0QsdUdBQXVHO2dCQUN2RyxxREFBcUQ7Z0JBQ3JELEdBQUcsRUFBRSxNQUFNLElBQUksQ0FBQyxTQUFTLEVBQUU7Z0JBQzNCLFVBQVUsRUFBRSxJQUFJLENBQUMsMkJBQTJCO2FBQzdDLENBQUM7UUFDSixDQUFDO0tBQUE7Ozs7WUEzUUYsVUFBVSxTQUFDO2dCQUNWLFVBQVUsRUFBRSxNQUFNO2FBQ25COzs7WUF6QlEsZ0JBQWdCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgSldLIH0gZnJvbSAnbm9kZS1qb3NlJztcbmltcG9ydCB7XG4gIExib3BLZXlQYXJhbXMsXG4gIFBhc3NJZHBQYXJhbXMsXG4gIFBhc3NLZXlQYXJhbXMsXG4gIERlcml2ZUtleVJlc3VsdCxcbiAgRGVyaXZlUGFzc0lkcFBhcmFtcyxcbiAgRGVyaXZlUGFzc0tleVBhcmFtcyxcbiAgRGVyaXZlTGJvcEtleVBhcmFtcyxcbn0gZnJvbSAnLi9jcnlwdG9ncmFwaHkudHlwZXMnO1xuaW1wb3J0IHsgV2ViQ3J5cHRvU2VydmljZSB9IGZyb20gJy4vd2ViLWNyeXB0by5zZXJ2aWNlJztcbmltcG9ydCB7XG4gIExyQmFkQXJndW1lbnRFeGNlcHRpb24sXG4gIExyU3VzcGljaW91c0V4Y2VwdGlvbixcbn0gZnJvbSAnLi4vX2NvbW1vbi9leGNlcHRpb25zJztcblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHNoYTI1NihtZXNzYWdlKSB7XG4gIC8vIGVuY29kZSBhcyBVVEYtOFxuICBjb25zdCBtc2dCdWZmZXIgPSBuZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUobWVzc2FnZSk7XG5cbiAgLy8gaGFzaCB0aGUgbWVzc2FnZVxuICBjb25zdCBoYXNoQnVmZmVyID0gYXdhaXQgY3J5cHRvLnN1YnRsZS5kaWdlc3QoJ1NIQS0yNTYnLCBtc2dCdWZmZXIpO1xuXG4gIC8vIGNvbnZlcnQgQXJyYXlCdWZmZXIgdG8gQXJyYXlcbiAgY29uc3QgaGFzaEFycmF5ID0gQXJyYXkuZnJvbShuZXcgVWludDhBcnJheShoYXNoQnVmZmVyKSk7XG5cbiAgLy8gY29udmVydCBieXRlcyB0byBoZXggc3RyaW5nXG4gIGNvbnN0IGhhc2hIZXggPSBoYXNoQXJyYXlcbiAgICAubWFwKChiKSA9PiAoJzAwJyArIGIudG9TdHJpbmcoMTYpKS5zbGljZSgtMikpXG4gICAgLmpvaW4oJycpO1xuICByZXR1cm4gaGFzaEhleDtcbn1cblxuQEluamVjdGFibGUoe1xuICBwcm92aWRlZEluOiAncm9vdCcsXG59KVxuZXhwb3J0IGNsYXNzIEtleUZhY3RvcnlTZXJ2aWNlIHtcbiAgY29uc3RydWN0b3IocHJpdmF0ZSB3ZWJDcnlwdG9TZXJ2aWNlOiBXZWJDcnlwdG9TZXJ2aWNlKSB7XG4gICAgdGhpcy5jcnlwdG8gPSB0aGlzLndlYkNyeXB0b1NlcnZpY2UuY3J5cHRvO1xuICB9XG4gIHByaXZhdGUgcmVhZG9ubHkgY3J5cHRvO1xuICAvLyBHbG9iYWwga2V5cyBzdG9yZS4gT3RoZXJ3aXNlLCBlYWNoIGNhbGwgdG8gYXNLZXkgY3JlYXRlcyBhIG5ldyBrZXlTdG9yZS5cbiAgLy8gPEFaPiBEaWQgbm90IHNlZW0gdG8gaW1wcm92ZSBzcGVlZC5cbiAgLy8gcHVibGljIHN0YXRpYyBrZXlTdG9yZSA9IEpXSy5jcmVhdGVLZXlTdG9yZSgpO1xuXG4gIC8vIEFaOiBUaGlzIGNhbid0IGJlIGNoYW5nZSBlYXNpbHkuIEl0J3MgYmFzaWNhbGx5IGEgUGFzc0sgb3IgUGFzc0lkcCByb3RhdGlvbi5cbiAgLy8gdG9kbzogd2Ugc2hvdWxkIGV2ZW50dWFsbHkgaW5jcmVhc2UgdGhpcyBwZXJpb2RpY2FsbHkgdG8gbWF0Y2ggd2l0aCBNb29yZSdzIGxhdy5cbiAgLy8gVGhlIGl0ZXJhdGlvbnMgZm9yIGVhY2gga2V5IGFyZSBrZXB0IGJ5IHRoZSBzZXJ2ZXIgYXMgd2VsbCBidXQgd2UgYXNzdW1lIHRoZSB2YWx1ZVxuICAvLyBmcm9tIHRoZSBzZXJ2ZXIgaXMgbm90IHRydXN0d29ydGh5LCBzbyBuZWVkIHRvIGhhdmUgbWluaW11bSB0aHJlc2hvbGRzIGhlcmUuXG4gIC8vIElmIGNyZWF0aW5nIG5ldyBrZXlzLCB0aGVzZSBtaW5pbXVtIGFyZSB1c2VkLlxuICBwdWJsaWMgcmVhZG9ubHkgTUlOX1BBU1NfSURQX1BCS0RGX0lURVIgPSAxMDAwMDA7XG4gIHB1YmxpYyByZWFkb25seSBNSU5fUEFTU19LRVlfUEJLREZfSVRFUiA9IDEwMDAwMDtcbiAgcHVibGljIHJlYWRvbmx5IE1JTl9MQk9QX0tFWV9QQktERl9JVEVSID0gMTAwMDAwO1xuXG4gIC8vIFRoZXNlIGFyZSB1c2VkIGFzIHRoZSBkZWZhdWx0IHZhbHVlcy4gVGhleSBtdXN0IGJlIGxhcmdlciB0aGFuIHRoZSBtaW5pbXVtIHZhbHVlcy5cbiAgcHVibGljIHJlYWRvbmx5IERFRkFVTFRfUEFTU19JRFBfUEJLREZfSVRFUiA9IHRoaXMuTUlOX1BBU1NfSURQX1BCS0RGX0lURVI7XG4gIHB1YmxpYyByZWFkb25seSBERUZBVUxUX1BBU1NfS0VZX1BCS0RGX0lURVIgPSB0aGlzLk1JTl9QQVNTX0tFWV9QQktERl9JVEVSO1xuICBwdWJsaWMgcmVhZG9ubHkgREVGQVVMVF9MQk9QX0tFWV9QQktERl9JVEVSID0gdGhpcy5NSU5fTEJPUF9LRVlfUEJLREZfSVRFUjtcblxuICBzdGF0aWMgYXNLZXkoXG4gICAga2V5OiBzdHJpbmcgfCBCdWZmZXIgfCBvYmplY3QgfCBKV0suUmF3S2V5LFxuICAgIGZvcm0/OlxuICAgICAgfCAnanNvbidcbiAgICAgIHwgJ3ByaXZhdGUnXG4gICAgICB8ICdwa2NzOCdcbiAgICAgIHwgJ3B1YmxpYydcbiAgICAgIHwgJ3Nwa2knXG4gICAgICB8ICdwa2l4J1xuICAgICAgfCAneDUwOSdcbiAgICAgIHwgJ3BlbScsXG4gICAgZXh0cmFzPzogUmVjb3JkPHN0cmluZywgdW5rbm93bj5cbiAgKTogUHJvbWlzZTxKV0suS2V5PiB7XG4gICAgLy8gPEFaPiBVc2luZyBhIHNpbmdsZSBnbG9iYWwga2V5IHN0b3JlIGRpZCBub3Qgc2VlbSB0byBpbXByb3ZlIHNwZWVkLlxuICAgIC8vIHJldHVybiBLZXlGYWN0b3J5U2VydmljZS5rZXlTdG9yZS5hZGQoa2V5LCBmb3JtLCBleHRyYXMpO1xuICAgIHJldHVybiBKV0suYXNLZXkoa2V5LCBmb3JtLCBleHRyYXMpO1xuICB9XG5cbiAgcmFuZG9tU3RyaW5nKGRpZ2l0czogbnVtYmVyKTogc3RyaW5nIHtcbiAgICBpZiAoZGlnaXRzIDw9IDApIHtcbiAgICAgIHRocm93IG5ldyBMckJhZEFyZ3VtZW50RXhjZXB0aW9uKCdkaWdpdHMgPD0gMCcpO1xuICAgIH1cbiAgICBjb25zdCB2YWxpZENoYXJzID1cbiAgICAgICdBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OSc7XG4gICAgbGV0IGFycmF5ID0gbmV3IFVpbnQzMkFycmF5KGRpZ2l0cyk7XG4gICAgdGhpcy5jcnlwdG8uZ2V0UmFuZG9tVmFsdWVzKGFycmF5KTtcbiAgICBhcnJheSA9IGFycmF5Lm1hcCgoeCkgPT4gdmFsaWRDaGFycy5jaGFyQ29kZUF0KHggJSB2YWxpZENoYXJzLmxlbmd0aCkpO1xuICAgIHJldHVybiBTdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KG51bGwsIGFycmF5KTtcbiAgfVxuXG4gIHJhbmRvbURpZ2l0c05vWmVyb3MoZGlnaXRzOiBudW1iZXIpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLnJhbmRvbUNob2ljZXMoWzEsIDIsIDMsIDQsIDUsIDYsIDcsIDgsIDldLCBkaWdpdHMpLmpvaW4oJycpO1xuICB9XG5cbiAgcmFuZG9tQ2hvaWNlczxUPihhcnJheTogVFtdLCBjaG9vc2VOOiBudW1iZXIpOiBUW10ge1xuICAgIGlmIChhcnJheS5sZW5ndGggPD0gMSkge1xuICAgICAgdGhyb3cgbmV3IExyQmFkQXJndW1lbnRFeGNlcHRpb24oJ2FycmF5Lmxlbmd0aCA8PSAwJyk7XG4gICAgfVxuICAgIGlmIChjaG9vc2VOIDw9IDApIHtcbiAgICAgIHRocm93IG5ldyBMckJhZEFyZ3VtZW50RXhjZXB0aW9uKCdjaG9vc2VOIDw9IDAnKTtcbiAgICB9XG4gICAgY29uc3QgdmFsdWVzID0gbmV3IFVpbnQzMkFycmF5KGNob29zZU4pO1xuICAgIHRoaXMuY3J5cHRvLmdldFJhbmRvbVZhbHVlcyh2YWx1ZXMpO1xuICAgIGNvbnN0IHJldDogVFtdID0gW107XG4gICAgdmFsdWVzLmZvckVhY2goKHYpID0+IHJldC5wdXNoKGFycmF5W3YgJSBhcnJheS5sZW5ndGhdKSk7XG4gICAgcmV0dXJuIHJldDtcbiAgfVxuXG4gIGNyZWF0ZVNhbHQoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5yYW5kb21TdHJpbmcoMTYpO1xuICB9XG5cbiAgYXN5bmMgY3JlYXRlS2V5KCk6IFByb21pc2U8SldLLktleT4ge1xuICAgIGNvbnN0IGtleSA9IGF3YWl0IHRoaXMuY3J5cHRvLnN1YnRsZS5nZW5lcmF0ZUtleShcbiAgICAgIHtcbiAgICAgICAgbmFtZTogJ0FFUy1HQ00nLFxuICAgICAgICBsZW5ndGg6IDI1NiwgLy8gY2FuIGJlICAxMjgsIDE5Miwgb3IgMjU2XG4gICAgICB9LFxuICAgICAgdHJ1ZSwgLy8gd2hldGhlciB0aGUga2V5IGlzIGV4dHJhY3RhYmxlIChpLmUuIGNhbiBiZSB1c2VkIGluIGV4cG9ydEtleSlcbiAgICAgIFsnZW5jcnlwdCcsICdkZWNyeXB0J10gLy8gbXVzdCBiZSBbXCJlbmNyeXB0XCIsIFwiZGVjcnlwdFwiXSBvciBbXCJ3cmFwS2V5XCIsIFwidW53cmFwS2V5XCJdXG4gICAgKTtcblxuICAgIGNvbnN0IGp3ayA9IGF3YWl0IHRoaXMuY3J5cHRvLnN1YnRsZS5leHBvcnRLZXkoJ2p3aycsIGtleSk7XG5cbiAgICAvLyBSZW1vdmluZyB0aGUgZmllbGRzIG5vdCBuZWVkZWQgYnkgbm9kZS1qb3NlXG4gICAgZGVsZXRlIGp3ay5leHQ7XG4gICAgZGVsZXRlIGp3ay5rZXlfb3BzO1xuXG4gICAgcmV0dXJuIEtleUZhY3RvcnlTZXJ2aWNlLmFzS2V5KGp3ayk7XG4gIH1cblxuICBhc3luYyBjcmVhdGVTaWduS2V5KCk6IFByb21pc2U8SldLLktleT4ge1xuICAgIGNvbnN0IGtleSA9IGF3YWl0IHRoaXMuY3J5cHRvLnN1YnRsZS5nZW5lcmF0ZUtleShcbiAgICAgIHtcbiAgICAgICAgbmFtZTogJ0hNQUMnLFxuICAgICAgICBoYXNoOiB7IG5hbWU6ICdTSEEtNTEyJyB9LFxuICAgICAgfSxcbiAgICAgIHRydWUsXG4gICAgICBbJ3NpZ24nLCAndmVyaWZ5J11cbiAgICApO1xuXG4gICAgY29uc3QgandrID0gYXdhaXQgdGhpcy5jcnlwdG8uc3VidGxlLmV4cG9ydEtleSgnandrJywga2V5KTtcblxuICAgIC8vIFJlbW92aW5nIHRoZSBmaWVsZHMgbm90IG5lZWRlZCBieSBub2RlLWpvc2VcbiAgICBkZWxldGUgandrLmtleV9vcHM7XG4gICAgZGVsZXRlIGp3ay5leHQ7XG5cbiAgICByZXR1cm4gS2V5RmFjdG9yeVNlcnZpY2UuYXNLZXkoandrKTtcbiAgfVxuXG4gIGFzeW5jIGNyZWF0ZVBrY0tleSgpOiBQcm9taXNlPEpXSy5LZXk+IHtcbiAgICAvLyBub2RlLWpvc2UgaXMgbm90IHVzaW5nIEZvcmdlIHByb3Blcmx5LiBJdCBzaG91bGQgYmUgY2FsbGluZyB0aGUgYXN5bmMgdmVyc2lvbiBvZlxuICAgIC8vIHBraS5yc2EuZ2VuZXJhdGVLZXlQYWlyKCkgd2l0aCBhIGNhbGxiYWNrLiBJbnN0ZWFkIGl0IGNhbGxzIHRoZSBzeW5jIHZlcnNpb24uIFdlYmNyeXB0b1xuICAgIC8vIGRvZXMgbm90IHN1cHBvcnQgc3luYyB2ZXJzaW9uLCBzbyBpdCB1c2VzIHRoZSBqYXZhc2NyaXB0IGltcGxlbWVudGF0aW9uLCB3aGljaCBpcyB3YXkgdG9vIHNsb3cuXG4gICAgLy8gU28gd2UgZ2VuZXJhdGUgdXNpbmcgd2ViY3J5cHRvIGFuZCBpbXBvcnQgdGhlIGtleS5cbiAgICAvLyBVbmZvcnR1bmF0ZWx5IEVsbGlwdGljYWwgQ3VydmUgaXMgbm90IHN1cHBvcnRlZCBieSBXZWJjcnlwdG8uIFNvIHdlIGhhdmUgdG8gc2V0dGxlIGZvciBSU0EuXG4gICAgY29uc3Qga2V5ID0gYXdhaXQgdGhpcy5jcnlwdG8uc3VidGxlLmdlbmVyYXRlS2V5KFxuICAgICAge1xuICAgICAgICBuYW1lOiAnUlNBLU9BRVAnLFxuICAgICAgICBtb2R1bHVzTGVuZ3RoOiAyMDQ4LCAvLyBjYW4gYmUgMTAyNCwgMjA0OCwgMzA3MiwgNDA5NiAuLi4gMTYzODRcbiAgICAgICAgLy8gQXMgcGVyIHN1Z2dlc3Rpb246IGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9Sc2FIYXNoZWRLZXlHZW5QYXJhbXNcbiAgICAgICAgcHVibGljRXhwb25lbnQ6IG5ldyBVaW50OEFycmF5KFsweDAxLCAweDAwLCAweDAxXSksXG4gICAgICAgIGhhc2g6IHsgbmFtZTogJ1NIQS0yNTYnIH0sIC8vIGNhbiBiZSBcIlNIQS0xXCIsIFwiU0hBLTI1NlwiLCBcIlNIQS0zODRcIiwgb3IgXCJTSEEtNTEyXCJcbiAgICAgIH0sXG4gICAgICB0cnVlLCAvLyB3aGV0aGVyIHRoZSBrZXkgaXMgZXh0cmFjdGFibGUgKGkuZS4gY2FuIGJlIHVzZWQgaW4gZXhwb3J0S2V5KVxuICAgICAgWydlbmNyeXB0JywgJ2RlY3J5cHQnXSAvLyBtdXN0IGJlIFtcImVuY3J5cHRcIiwgXCJkZWNyeXB0XCJdIG9yIFtcIndyYXBLZXlcIiwgXCJ1bndyYXBLZXlcIl1cbiAgICApO1xuXG4gICAgY29uc3QgandrID0gYXdhaXQgdGhpcy5jcnlwdG8uc3VidGxlLmV4cG9ydEtleSgnandrJywga2V5LnByaXZhdGVLZXkpO1xuICAgIC8vIFJlbW92aW5nIHRoZSBmaWVsZHMgbm90IG5lZWRlZCBieSBub2RlLWpvc2VcbiAgICBkZWxldGUgandrLmtleV9vcHM7XG4gICAgZGVsZXRlIGp3ay5leHQ7XG5cbiAgICByZXR1cm4gS2V5RmFjdG9yeVNlcnZpY2UuYXNLZXkoandrKTtcbiAgfVxuXG4gIGFzeW5jIGNyZWF0ZVBrY1NpZ25LZXkoKTogUHJvbWlzZTxKV0suS2V5PiB7XG4gICAgY29uc3Qga2V5ID0gYXdhaXQgdGhpcy5jcnlwdG8uc3VidGxlLmdlbmVyYXRlS2V5KFxuICAgICAge1xuICAgICAgICBuYW1lOiAnUlNBU1NBLVBLQ1MxLXYxXzUnLFxuICAgICAgICBtb2R1bHVzTGVuZ3RoOiAyMDQ4LCAvLyBjYW4gYmUgMTAyNCwgMjA0OCwgb3IgNDA5NlxuICAgICAgICAvLyBBcyBwZXIgc3VnZ2VzdGlvbjogaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL1JzYUhhc2hlZEtleUdlblBhcmFtc1xuICAgICAgICBwdWJsaWNFeHBvbmVudDogbmV3IFVpbnQ4QXJyYXkoWzB4MDEsIDB4MDAsIDB4MDFdKSxcbiAgICAgICAgaGFzaDogeyBuYW1lOiAnU0hBLTI1NicgfSwgLy8gY2FuIGJlIFwiU0hBLTFcIiwgXCJTSEEtMjU2XCIsIFwiU0hBLTM4NFwiLCBvciBcIlNIQS01MTJcIlxuICAgICAgfSxcbiAgICAgIHRydWUsIC8vIHdoZXRoZXIgdGhlIGtleSBpcyBleHRyYWN0YWJsZSAoaS5lLiBjYW4gYmUgdXNlZCBpbiBleHBvcnRLZXkpXG4gICAgICBbJ3NpZ24nLCAndmVyaWZ5J10gLy8gY2FuIGJlIGFueSBjb21iaW5hdGlvbiBvZiBcInNpZ25cIiBhbmQgXCJ2ZXJpZnlcIlxuICAgICk7XG5cbiAgICBjb25zdCBqd2sgPSBhd2FpdCB0aGlzLmNyeXB0by5zdWJ0bGUuZXhwb3J0S2V5KCdqd2snLCBrZXkucHJpdmF0ZUtleSk7XG5cbiAgICAvLyBSZW1vdmluZyB0aGUgZmllbGRzIG5vdCBuZWVkZWQgYnkgbm9kZS1qb3NlXG4gICAgZGVsZXRlIGp3ay5rZXlfb3BzO1xuICAgIGRlbGV0ZSBqd2suZXh0O1xuXG4gICAgcmV0dXJuIEtleUZhY3RvcnlTZXJ2aWNlLmFzS2V5KGp3ayk7XG4gIH1cblxuICBhc3luYyBkZXJpdmVLZXkoe1xuICAgIHBhc3N3b3JkLFxuICAgIHNhbHQsXG4gICAgaXRlcmF0aW9ucyxcbiAgICBraWQsXG4gIH06IHtcbiAgICBwYXNzd29yZDogc3RyaW5nO1xuICAgIHNhbHQ6IHN0cmluZztcbiAgICBpdGVyYXRpb25zOiBudW1iZXI7XG4gICAga2lkPzogc3RyaW5nO1xuICB9KTogUHJvbWlzZTxEZXJpdmVLZXlSZXN1bHQ+IHtcbiAgICBjb25zdCBlbmMgPSBuZXcgVGV4dEVuY29kZXIoKTtcbiAgICBjb25zdCByYXdLZXkgPSBhd2FpdCB0aGlzLmNyeXB0by5zdWJ0bGUuaW1wb3J0S2V5KFxuICAgICAgJ3JhdycsXG4gICAgICBlbmMuZW5jb2RlKHBhc3N3b3JkKSxcbiAgICAgICdQQktERjInLFxuICAgICAgZmFsc2UsXG4gICAgICBbJ2Rlcml2ZUJpdHMnLCAnZGVyaXZlS2V5J11cbiAgICApO1xuXG4gICAgY29uc3QgcGFzc0tleSA9IGF3YWl0IGNyeXB0by5zdWJ0bGUuZGVyaXZlS2V5KFxuICAgICAge1xuICAgICAgICBuYW1lOiAnUEJLREYyJyxcbiAgICAgICAgc2FsdDogbmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKHNhbHQpLFxuICAgICAgICBpdGVyYXRpb25zLFxuICAgICAgICBoYXNoOiAnU0hBLTI1NicsXG4gICAgICB9LFxuICAgICAgcmF3S2V5LFxuICAgICAgeyBuYW1lOiAnQUVTLUdDTScsIGxlbmd0aDogMjU2IH0sXG4gICAgICB0cnVlLFxuICAgICAgWydlbmNyeXB0JywgJ2RlY3J5cHQnXVxuICAgICk7XG5cbiAgICBjb25zdCBwYXNzS2V5SnNvbjogYW55ID0gYXdhaXQgY3J5cHRvLnN1YnRsZS5leHBvcnRLZXkoJ2p3aycsIHBhc3NLZXkpO1xuICAgIGlmIChraWQpIHtcbiAgICAgIHBhc3NLZXlKc29uLmtpZCA9IGtpZDtcbiAgICB9XG5cbiAgICBjb25zdCBqd2sgPSBhd2FpdCBLZXlGYWN0b3J5U2VydmljZS5hc0tleShwYXNzS2V5SnNvbik7XG5cbiAgICByZXR1cm4geyBqd2sgfTtcbiAgfVxuXG4gIGFzeW5jIGRlcml2ZVBhc3NJZHAocGFyYW1zOiBEZXJpdmVQYXNzSWRwUGFyYW1zKTogUHJvbWlzZTxEZXJpdmVLZXlSZXN1bHQ+IHtcbiAgICBpZiAocGFyYW1zLml0ZXJhdGlvbnMgPCB0aGlzLk1JTl9QQVNTX0lEUF9QQktERl9JVEVSKSB7XG4gICAgICB0aHJvdyBuZXcgTHJTdXNwaWNpb3VzRXhjZXB0aW9uKFxuICAgICAgICBgVGhlIG51bWJlciBvZiBQYXNzSWRwIGtleSBkZXJpdmF0aW9uIGl0ZXJhdGlvbnMgc2VudCBmcm9tIHRoZSBzZXJ2ZXIgKCR7cGFyYW1zLml0ZXJhdGlvbnN9KSBpcyBsb3dlciB0aGFuIHRoZSBtaW5pbXVtICgke3RoaXMuTUlOX1BBU1NfSURQX1BCS0RGX0lURVJ9KWBcbiAgICAgICk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmRlcml2ZUtleShwYXJhbXMpO1xuICB9XG5cbiAgYXN5bmMgZGVyaXZlUGFzc0tleShwYXJhbXM6IERlcml2ZVBhc3NLZXlQYXJhbXMpOiBQcm9taXNlPERlcml2ZUtleVJlc3VsdD4ge1xuICAgIGlmIChwYXJhbXMuaXRlcmF0aW9ucyA8IHRoaXMuTUlOX1BBU1NfS0VZX1BCS0RGX0lURVIpIHtcbiAgICAgIHRocm93IG5ldyBMclN1c3BpY2lvdXNFeGNlcHRpb24oXG4gICAgICAgIGBUaGUgbnVtYmVyIG9mIFBhc3NLZXkga2V5IGRlcml2YXRpb24gaXRlcmF0aW9ucyBzZW50IGZyb20gdGhlIHNlcnZlcigke3BhcmFtcy5pdGVyYXRpb25zfSkgaXMgbG93ZXIgdGhhbiB0aGUgbWluaW11bSgke3RoaXMuTUlOX1BBU1NfS0VZX1BCS0RGX0lURVJ9KWBcbiAgICAgICk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmRlcml2ZUtleShwYXJhbXMpO1xuICB9XG5cbiAgYXN5bmMgZGVyaXZlTGJvcEtleShwYXJhbXM6IERlcml2ZUxib3BLZXlQYXJhbXMpOiBQcm9taXNlPERlcml2ZUtleVJlc3VsdD4ge1xuICAgIGlmIChwYXJhbXMuaXRlcmF0aW9ucyA8IHRoaXMuTUlOX0xCT1BfS0VZX1BCS0RGX0lURVIpIHtcbiAgICAgIHRocm93IG5ldyBMclN1c3BpY2lvdXNFeGNlcHRpb24oXG4gICAgICAgIGBUaGUgbnVtYmVyIG9mIExib3BLZXkga2V5IGRlcml2YXRpb24gaXRlcmF0aW9ucyBzZW50IGZyb20gdGhlIHNlcnZlcigke3BhcmFtcy5pdGVyYXRpb25zfSkgaXMgbG93ZXIgdGhhbiB0aGUgbWluaW11bSgke3RoaXMuTUlOX0xCT1BfS0VZX1BCS0RGX0lURVJ9KWBcbiAgICAgICk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmRlcml2ZUtleShwYXJhbXMpO1xuICB9XG5cbiAgYXN5bmMgY3JlYXRlS2lkKCk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgLy8gdG9kbzogQVo6IG5vZGUtam9zZSBzb3VyY2UgdXNlcyBub2RlJ3MgZGVmYXVsdCBVVUlEKCkgZnVuY3Rpb24gZm9yIGtpZCwgc28ganVzdCBjaGFuZ2UgdG8gdXNlIHRoYXQuXG4gICAgLy8gZm9yIG5vdywgd2UgYXJlIGp1c3QgY3JlYXRpbmcgYSBuZXcga2V5IHRvIHVzZSBpdCdzIGtpZC5cbiAgICAvLyBUaGUga2lkIGlzIGEgcGFydCBvZiB0aGUgSldLIHN5c3RlbS4gTFIgYmFja2VuZCBtYWludGFpbnMgdGhlIGtleSBoaWVyYXJjaHkgc2VwYXJhdGVseSB3aXRoIGl0J3Mgb3duXG4gICAgLy8ga2V5IGlkLiBCdXQgd2UganVzdCB1c2UgaXQgaGVyZSBhcyBhIGRvdWJsZSBjaGVjay5cbiAgICByZXR1cm4gKGF3YWl0IHRoaXMuY3JlYXRlS2V5KCkpLmtpZDtcbiAgfVxuXG4gIGFzeW5jIGNyZWF0ZVBhc3NJZHBQYXJhbXMoKTogUHJvbWlzZTxQYXNzSWRwUGFyYW1zPiB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHNhbHQ6IHRoaXMuY3JlYXRlU2FsdCgpLFxuICAgICAgaXRlcmF0aW9uczogdGhpcy5ERUZBVUxUX1BBU1NfSURQX1BCS0RGX0lURVIsXG4gICAgfTtcbiAgfVxuXG4gIGFzeW5jIGNyZWF0ZVBhc3NLZXlQYXJhbXMoKTogUHJvbWlzZTxQYXNzS2V5UGFyYW1zPiB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHNhbHQ6IHRoaXMuY3JlYXRlU2FsdCgpLFxuICAgICAga2lkOiBhd2FpdCB0aGlzLmNyZWF0ZUtpZCgpLFxuICAgICAgaXRlcmF0aW9uczogdGhpcy5ERUZBVUxUX1BBU1NfS0VZX1BCS0RGX0lURVIsXG4gICAgfTtcbiAgfVxuXG4gIGFzeW5jIGNyZWF0ZUxib3BLZXlQYXJhbXMoKTogUHJvbWlzZTxMYm9wS2V5UGFyYW1zPiB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHNhbHQ6IHRoaXMuY3JlYXRlU2FsdCgpLFxuICAgICAgLy8gdG9kbzogQVo6IG5vZGUtam9zZSBzb3VyY2UgdXNlcyBub2RlJ3MgZGVmYXVsdCBVVUlEKCkgZnVuY3Rpb24gZm9yIGtpZCwgc28ganVzdCBjaGFuZ2UgdG8gdXNlIHRoYXQuXG4gICAgICAvLyBmb3Igbm93LCB3ZSBhcmUganVzdCBjcmVhdGluZyBhIG5ldyBrZXkgdG8gdXNlIGl0J3Mga2lkLlxuICAgICAgLy8gVGhlIGtpZCBpcyBhIHBhcnQgb2YgdGhlIEpXSyBzeXN0ZW0uIExSIGJhY2tlbmQgbWFpbnRhaW5zIHRoZSBrZXkgaGllcmFyY2h5IHNlcGFyYXRlbHkgd2l0aCBpdCdzIG93blxuICAgICAgLy8ga2V5IGlkLiBCdXQgd2UganVzdCB1c2UgaXQgaGVyZSBhcyBhIGRvdWJsZSBjaGVjay5cbiAgICAgIGtpZDogYXdhaXQgdGhpcy5jcmVhdGVLaWQoKSxcbiAgICAgIGl0ZXJhdGlvbnM6IHRoaXMuREVGQVVMVF9QQVNTX0tFWV9QQktERl9JVEVSLFxuICAgIH07XG4gIH1cbn1cbiJdfQ==
1
+ import { __awaiter } from "tslib";
2
+ import { Injectable } from '@angular/core';
3
+ import { JWK } from 'node-jose';
4
+ import { WebCryptoService } from './web-crypto.service';
5
+ import { LrBadArgumentException, LrSuspiciousException, } from '../_common/exceptions';
6
+ import * as i0 from "@angular/core";
7
+ import * as i1 from "./web-crypto.service";
8
+ export function sha256(message) {
9
+ return __awaiter(this, void 0, void 0, function* () {
10
+ // encode as UTF-8
11
+ const msgBuffer = new TextEncoder().encode(message);
12
+ // hash the message
13
+ const hashBuffer = yield crypto.subtle.digest('SHA-256', msgBuffer);
14
+ // convert ArrayBuffer to Array
15
+ const hashArray = Array.from(new Uint8Array(hashBuffer));
16
+ // convert bytes to hex string
17
+ const hashHex = hashArray
18
+ .map((b) => ('00' + b.toString(16)).slice(-2))
19
+ .join('');
20
+ return hashHex;
21
+ });
22
+ }
23
+ export class KeyFactoryService {
24
+ constructor(webCryptoService) {
25
+ this.webCryptoService = webCryptoService;
26
+ // Global keys store. Otherwise, each call to asKey creates a new keyStore.
27
+ // <AZ> Did not seem to improve speed.
28
+ // public static keyStore = JWK.createKeyStore();
29
+ // AZ: This can't be change easily. It's basically a PassK or PassIdp rotation.
30
+ // todo: we should eventually increase this periodically to match with Moore's law.
31
+ // The iterations for each key are kept by the server as well but we assume the value
32
+ // from the server is not trustworthy, so need to have minimum thresholds here.
33
+ // If creating new keys, these minimum are used.
34
+ this.MIN_PASS_IDP_PBKDF_ITER = 100000;
35
+ this.MIN_PASS_KEY_PBKDF_ITER = 100000;
36
+ this.MIN_LBOP_KEY_PBKDF_ITER = 100000;
37
+ // These are used as the default values. They must be larger than the minimum values.
38
+ this.DEFAULT_PASS_IDP_PBKDF_ITER = this.MIN_PASS_IDP_PBKDF_ITER;
39
+ this.DEFAULT_PASS_KEY_PBKDF_ITER = this.MIN_PASS_KEY_PBKDF_ITER;
40
+ this.DEFAULT_LBOP_KEY_PBKDF_ITER = this.MIN_LBOP_KEY_PBKDF_ITER;
41
+ this.crypto = this.webCryptoService.crypto;
42
+ }
43
+ static asKey(key, form, extras) {
44
+ // <AZ> Using a single global key store did not seem to improve speed.
45
+ // return KeyFactoryService.keyStore.add(key, form, extras);
46
+ return JWK.asKey(key, form, extras);
47
+ }
48
+ randomString(digits) {
49
+ if (digits <= 0) {
50
+ throw new LrBadArgumentException('digits <= 0');
51
+ }
52
+ const validChars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
53
+ let array = new Uint32Array(digits);
54
+ this.crypto.getRandomValues(array);
55
+ array = array.map((x) => validChars.charCodeAt(x % validChars.length));
56
+ return String.fromCharCode.apply(null, array);
57
+ }
58
+ randomDigitsNoZeros(digits) {
59
+ return this.randomChoices([1, 2, 3, 4, 5, 6, 7, 8, 9], digits).join('');
60
+ }
61
+ randomChoices(array, chooseN) {
62
+ if (array.length <= 1) {
63
+ throw new LrBadArgumentException('array.length <= 0');
64
+ }
65
+ if (chooseN <= 0) {
66
+ throw new LrBadArgumentException('chooseN <= 0');
67
+ }
68
+ const values = new Uint32Array(chooseN);
69
+ this.crypto.getRandomValues(values);
70
+ const ret = [];
71
+ values.forEach((v) => ret.push(array[v % array.length]));
72
+ return ret;
73
+ }
74
+ createSalt() {
75
+ return this.randomString(16);
76
+ }
77
+ createKey() {
78
+ return __awaiter(this, void 0, void 0, function* () {
79
+ const key = yield this.crypto.subtle.generateKey({
80
+ name: 'AES-GCM',
81
+ length: 256,
82
+ }, true, // whether the key is extractable (i.e. can be used in exportKey)
83
+ ['encrypt', 'decrypt'] // must be ["encrypt", "decrypt"] or ["wrapKey", "unwrapKey"]
84
+ );
85
+ const jwk = yield this.crypto.subtle.exportKey('jwk', key);
86
+ // Removing the fields not needed by node-jose
87
+ delete jwk.ext;
88
+ delete jwk.key_ops;
89
+ return KeyFactoryService.asKey(jwk);
90
+ });
91
+ }
92
+ createSignKey() {
93
+ return __awaiter(this, void 0, void 0, function* () {
94
+ const key = yield this.crypto.subtle.generateKey({
95
+ name: 'HMAC',
96
+ hash: { name: 'SHA-512' },
97
+ }, true, ['sign', 'verify']);
98
+ const jwk = yield this.crypto.subtle.exportKey('jwk', key);
99
+ // Removing the fields not needed by node-jose
100
+ delete jwk.key_ops;
101
+ delete jwk.ext;
102
+ return KeyFactoryService.asKey(jwk);
103
+ });
104
+ }
105
+ createPkcKey() {
106
+ return __awaiter(this, void 0, void 0, function* () {
107
+ // node-jose is not using Forge properly. It should be calling the async version of
108
+ // pki.rsa.generateKeyPair() with a callback. Instead it calls the sync version. Webcrypto
109
+ // does not support sync version, so it uses the javascript implementation, which is way too slow.
110
+ // So we generate using webcrypto and import the key.
111
+ // Unfortunately Elliptical Curve is not supported by Webcrypto. So we have to settle for RSA.
112
+ const key = yield this.crypto.subtle.generateKey({
113
+ name: 'RSA-OAEP',
114
+ modulusLength: 2048,
115
+ // As per suggestion: https://developer.mozilla.org/en-US/docs/Web/API/RsaHashedKeyGenParams
116
+ publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
117
+ hash: { name: 'SHA-256' },
118
+ }, true, // whether the key is extractable (i.e. can be used in exportKey)
119
+ ['encrypt', 'decrypt'] // must be ["encrypt", "decrypt"] or ["wrapKey", "unwrapKey"]
120
+ );
121
+ const jwk = yield this.crypto.subtle.exportKey('jwk', key.privateKey);
122
+ // Removing the fields not needed by node-jose
123
+ delete jwk.key_ops;
124
+ delete jwk.ext;
125
+ return KeyFactoryService.asKey(jwk);
126
+ });
127
+ }
128
+ createPkcSignKey() {
129
+ return __awaiter(this, void 0, void 0, function* () {
130
+ const key = yield this.crypto.subtle.generateKey({
131
+ name: 'RSASSA-PKCS1-v1_5',
132
+ modulusLength: 2048,
133
+ // As per suggestion: https://developer.mozilla.org/en-US/docs/Web/API/RsaHashedKeyGenParams
134
+ publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
135
+ hash: { name: 'SHA-256' },
136
+ }, true, // whether the key is extractable (i.e. can be used in exportKey)
137
+ ['sign', 'verify'] // can be any combination of "sign" and "verify"
138
+ );
139
+ const jwk = yield this.crypto.subtle.exportKey('jwk', key.privateKey);
140
+ // Removing the fields not needed by node-jose
141
+ delete jwk.key_ops;
142
+ delete jwk.ext;
143
+ return KeyFactoryService.asKey(jwk);
144
+ });
145
+ }
146
+ deriveKey({ password, salt, iterations, kid, }) {
147
+ return __awaiter(this, void 0, void 0, function* () {
148
+ const enc = new TextEncoder();
149
+ const rawKey = yield this.crypto.subtle.importKey('raw', enc.encode(password), 'PBKDF2', false, ['deriveBits', 'deriveKey']);
150
+ const passKey = yield crypto.subtle.deriveKey({
151
+ name: 'PBKDF2',
152
+ salt: new TextEncoder().encode(salt),
153
+ iterations,
154
+ hash: 'SHA-256',
155
+ }, rawKey, { name: 'AES-GCM', length: 256 }, true, ['encrypt', 'decrypt']);
156
+ const passKeyJson = yield crypto.subtle.exportKey('jwk', passKey);
157
+ if (kid) {
158
+ passKeyJson.kid = kid;
159
+ }
160
+ const jwk = yield KeyFactoryService.asKey(passKeyJson);
161
+ return { jwk };
162
+ });
163
+ }
164
+ derivePassIdp(params) {
165
+ return __awaiter(this, void 0, void 0, function* () {
166
+ if (params.iterations < this.MIN_PASS_IDP_PBKDF_ITER) {
167
+ throw new LrSuspiciousException(`The number of PassIdp key derivation iterations sent from the server (${params.iterations}) is lower than the minimum (${this.MIN_PASS_IDP_PBKDF_ITER})`);
168
+ }
169
+ return this.deriveKey(params);
170
+ });
171
+ }
172
+ derivePassKey(params) {
173
+ return __awaiter(this, void 0, void 0, function* () {
174
+ if (params.iterations < this.MIN_PASS_KEY_PBKDF_ITER) {
175
+ throw new LrSuspiciousException(`The number of PassKey key derivation iterations sent from the server(${params.iterations}) is lower than the minimum(${this.MIN_PASS_KEY_PBKDF_ITER})`);
176
+ }
177
+ return this.deriveKey(params);
178
+ });
179
+ }
180
+ deriveLbopKey(params) {
181
+ return __awaiter(this, void 0, void 0, function* () {
182
+ if (params.iterations < this.MIN_LBOP_KEY_PBKDF_ITER) {
183
+ throw new LrSuspiciousException(`The number of LbopKey key derivation iterations sent from the server(${params.iterations}) is lower than the minimum(${this.MIN_LBOP_KEY_PBKDF_ITER})`);
184
+ }
185
+ return this.deriveKey(params);
186
+ });
187
+ }
188
+ createKid() {
189
+ return __awaiter(this, void 0, void 0, function* () {
190
+ // todo: AZ: node-jose source uses node's default UUID() function for kid, so just change to use that.
191
+ // for now, we are just creating a new key to use it's kid.
192
+ // The kid is a part of the JWK system. LR backend maintains the key hierarchy separately with it's own
193
+ // key id. But we just use it here as a double check.
194
+ return (yield this.createKey()).kid;
195
+ });
196
+ }
197
+ createPassIdpParams() {
198
+ return __awaiter(this, void 0, void 0, function* () {
199
+ return {
200
+ salt: this.createSalt(),
201
+ iterations: this.DEFAULT_PASS_IDP_PBKDF_ITER,
202
+ };
203
+ });
204
+ }
205
+ createPassKeyParams() {
206
+ return __awaiter(this, void 0, void 0, function* () {
207
+ return {
208
+ salt: this.createSalt(),
209
+ kid: yield this.createKid(),
210
+ iterations: this.DEFAULT_PASS_KEY_PBKDF_ITER,
211
+ };
212
+ });
213
+ }
214
+ createLbopKeyParams() {
215
+ return __awaiter(this, void 0, void 0, function* () {
216
+ return {
217
+ salt: this.createSalt(),
218
+ // todo: AZ: node-jose source uses node's default UUID() function for kid, so just change to use that.
219
+ // for now, we are just creating a new key to use it's kid.
220
+ // The kid is a part of the JWK system. LR backend maintains the key hierarchy separately with it's own
221
+ // key id. But we just use it here as a double check.
222
+ kid: yield this.createKid(),
223
+ iterations: this.DEFAULT_PASS_KEY_PBKDF_ITER,
224
+ };
225
+ });
226
+ }
227
+ }
228
+ KeyFactoryService.ɵprov = i0.ɵɵdefineInjectable({ factory: function KeyFactoryService_Factory() { return new KeyFactoryService(i0.ɵɵinject(i1.WebCryptoService)); }, token: KeyFactoryService, providedIn: "root" });
229
+ KeyFactoryService.decorators = [
230
+ { type: Injectable, args: [{
231
+ providedIn: 'root',
232
+ },] }
233
+ ];
234
+ KeyFactoryService.ctorParameters = () => [
235
+ { type: WebCryptoService }
236
+ ];
237
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoia2V5LWZhY3Rvcnkuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiJDOi9Qcm9qZWN0cy9uZXdyZXBvL2tjLWNsaWVudC9wcm9qZWN0cy9jb3JlL3NyYy8iLCJzb3VyY2VzIjpbImxpYi9jcnlwdG9ncmFwaHkva2V5LWZhY3Rvcnkuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzQyxPQUFPLEVBQUUsR0FBRyxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBVWhDLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQ3hELE9BQU8sRUFDTCxzQkFBc0IsRUFDdEIscUJBQXFCLEdBQ3RCLE1BQU0sdUJBQXVCLENBQUM7OztBQUUvQixNQUFNLFVBQWdCLE1BQU0sQ0FBQyxPQUFPOztRQUNsQyxrQkFBa0I7UUFDbEIsTUFBTSxTQUFTLEdBQUcsSUFBSSxXQUFXLEVBQUUsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUM7UUFFcEQsbUJBQW1CO1FBQ25CLE1BQU0sVUFBVSxHQUFHLE1BQU0sTUFBTSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsU0FBUyxFQUFFLFNBQVMsQ0FBQyxDQUFDO1FBRXBFLCtCQUErQjtRQUMvQixNQUFNLFNBQVMsR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksVUFBVSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUM7UUFFekQsOEJBQThCO1FBQzlCLE1BQU0sT0FBTyxHQUFHLFNBQVM7YUFDdEIsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLElBQUksR0FBRyxDQUFDLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7YUFDN0MsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQ1osT0FBTyxPQUFPLENBQUM7SUFDakIsQ0FBQztDQUFB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O1lBQ3RHLDJEQUEyRDtZQUMzRCx1R0FBdUc7WUFDdkcscURBQXFEO1lBQ3JELE9BQU8sQ0FBQyxNQUFNLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQyxDQUFDLEdBQUcsQ0FBQztRQUN0QyxDQUFDO0tBQUE7SUFFSyxtQkFBbUI7O1lBQ3ZCLE9BQU87Z0JBQ0wsSUFBSSxFQUFFLElBQUksQ0FBQyxVQUFVLEVBQUU7Z0JBQ3ZCLFVBQVUsRUFBRSxJQUFJLENBQUMsMkJBQTJCO2FBQzdDLENBQUM7UUFDSixDQUFDO0tBQUE7SUFFSyxtQkFBbUI7O1lBQ3ZCLE9BQU87Z0JBQ0wsSUFBSSxFQUFFLElBQUksQ0FBQyxVQUFVLEVBQUU7Z0JBQ3ZCLEdBQUcsRUFBRSxNQUFNLElBQUksQ0FBQyxTQUFTLEVBQUU7Z0JBQzNCLFVBQVUsRUFBRSxJQUFJLENBQUMsMkJBQTJCO2FBQzdDLENBQUM7UUFDSixDQUFDO0tBQUE7SUFFSyxtQkFBbUI7O1lBQ3ZCLE9BQU87Z0JBQ0wsSUFBSSxFQUFFLElBQUksQ0FBQyxVQUFVLEVBQUU7Z0JBQ3ZCLHNHQUFzRztnQkFDdEcsMkRBQTJEO2dCQUMzRCx1R0FBdUc7Z0JBQ3ZHLHFEQUFxRDtnQkFDckQsR0FBRyxFQUFFLE1BQU0sSUFBSSxDQUFDLFNBQVMsRUFBRTtnQkFDM0IsVUFBVSxFQUFFLElBQUksQ0FBQywyQkFBMkI7YUFDN0MsQ0FBQztRQUNKLENBQUM7S0FBQTs7OztZQTNRRixVQUFVLFNBQUM7Z0JBQ1YsVUFBVSxFQUFFLE1BQU07YUFDbkI7OztZQXpCUSxnQkFBZ0IiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IEpXSyB9IGZyb20gJ25vZGUtam9zZSc7XHJcbmltcG9ydCB7XHJcbiAgTGJvcEtleVBhcmFtcyxcclxuICBQYXNzSWRwUGFyYW1zLFxyXG4gIFBhc3NLZXlQYXJhbXMsXHJcbiAgRGVyaXZlS2V5UmVzdWx0LFxyXG4gIERlcml2ZVBhc3NJZHBQYXJhbXMsXHJcbiAgRGVyaXZlUGFzc0tleVBhcmFtcyxcclxuICBEZXJpdmVMYm9wS2V5UGFyYW1zLFxyXG59IGZyb20gJy4vY3J5cHRvZ3JhcGh5LnR5cGVzJztcclxuaW1wb3J0IHsgV2ViQ3J5cHRvU2VydmljZSB9IGZyb20gJy4vd2ViLWNyeXB0by5zZXJ2aWNlJztcclxuaW1wb3J0IHtcclxuICBMckJhZEFyZ3VtZW50RXhjZXB0aW9uLFxyXG4gIExyU3VzcGljaW91c0V4Y2VwdGlvbixcclxufSBmcm9tICcuLi9fY29tbW9uL2V4Y2VwdGlvbnMnO1xyXG5cclxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHNoYTI1NihtZXNzYWdlKSB7XHJcbiAgLy8gZW5jb2RlIGFzIFVURi04XHJcbiAgY29uc3QgbXNnQnVmZmVyID0gbmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKG1lc3NhZ2UpO1xyXG5cclxuICAvLyBoYXNoIHRoZSBtZXNzYWdlXHJcbiAgY29uc3QgaGFzaEJ1ZmZlciA9IGF3YWl0IGNyeXB0by5zdWJ0bGUuZGlnZXN0KCdTSEEtMjU2JywgbXNnQnVmZmVyKTtcclxuXHJcbiAgLy8gY29udmVydCBBcnJheUJ1ZmZlciB0byBBcnJheVxyXG4gIGNvbnN0IGhhc2hBcnJheSA9IEFycmF5LmZyb20obmV3IFVpbnQ4QXJyYXkoaGFzaEJ1ZmZlcikpO1xyXG5cclxuICAvLyBjb252ZXJ0IGJ5dGVzIHRvIGhleCBzdHJpbmdcclxuICBjb25zdCBoYXNoSGV4ID0gaGFzaEFycmF5XHJcbiAgICAubWFwKChiKSA9PiAoJzAwJyArIGIudG9TdHJpbmcoMTYpKS5zbGljZSgtMikpXHJcbiAgICAuam9pbignJyk7XHJcbiAgcmV0dXJuIGhhc2hIZXg7XHJcbn1cclxuXHJcbkBJbmplY3RhYmxlKHtcclxuICBwcm92aWRlZEluOiAncm9vdCcsXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBLZXlGYWN0b3J5U2VydmljZSB7XHJcbiAgY29uc3RydWN0b3IocHJpdmF0ZSB3ZWJDcnlwdG9TZXJ2aWNlOiBXZWJDcnlwdG9TZXJ2aWNlKSB7XHJcbiAgICB0aGlzLmNyeXB0byA9IHRoaXMud2ViQ3J5cHRvU2VydmljZS5jcnlwdG87XHJcbiAgfVxyXG4gIHByaXZhdGUgcmVhZG9ubHkgY3J5cHRvO1xyXG4gIC8vIEdsb2JhbCBrZXlzIHN0b3JlLiBPdGhlcndpc2UsIGVhY2ggY2FsbCB0byBhc0tleSBjcmVhdGVzIGEgbmV3IGtleVN0b3JlLlxyXG4gIC8vIDxBWj4gRGlkIG5vdCBzZWVtIHRvIGltcHJvdmUgc3BlZWQuXHJcbiAgLy8gcHVibGljIHN0YXRpYyBrZXlTdG9yZSA9IEpXSy5jcmVhdGVLZXlTdG9yZSgpO1xyXG5cclxuICAvLyBBWjogVGhpcyBjYW4ndCBiZSBjaGFuZ2UgZWFzaWx5LiBJdCdzIGJhc2ljYWxseSBhIFBhc3NLIG9yIFBhc3NJZHAgcm90YXRpb24uXHJcbiAgLy8gdG9kbzogd2Ugc2hvdWxkIGV2ZW50dWFsbHkgaW5jcmVhc2UgdGhpcyBwZXJpb2RpY2FsbHkgdG8gbWF0Y2ggd2l0aCBNb29yZSdzIGxhdy5cclxuICAvLyBUaGUgaXRlcmF0aW9ucyBmb3IgZWFjaCBrZXkgYXJlIGtlcHQgYnkgdGhlIHNlcnZlciBhcyB3ZWxsIGJ1dCB3ZSBhc3N1bWUgdGhlIHZhbHVlXHJcbiAgLy8gZnJvbSB0aGUgc2VydmVyIGlzIG5vdCB0cnVzdHdvcnRoeSwgc28gbmVlZCB0byBoYXZlIG1pbmltdW0gdGhyZXNob2xkcyBoZXJlLlxyXG4gIC8vIElmIGNyZWF0aW5nIG5ldyBrZXlzLCB0aGVzZSBtaW5pbXVtIGFyZSB1c2VkLlxyXG4gIHB1YmxpYyByZWFkb25seSBNSU5fUEFTU19JRFBfUEJLREZfSVRFUiA9IDEwMDAwMDtcclxuICBwdWJsaWMgcmVhZG9ubHkgTUlOX1BBU1NfS0VZX1BCS0RGX0lURVIgPSAxMDAwMDA7XHJcbiAgcHVibGljIHJlYWRvbmx5IE1JTl9MQk9QX0tFWV9QQktERl9JVEVSID0gMTAwMDAwO1xyXG5cclxuICAvLyBUaGVzZSBhcmUgdXNlZCBhcyB0aGUgZGVmYXVsdCB2YWx1ZXMuIFRoZXkgbXVzdCBiZSBsYXJnZXIgdGhhbiB0aGUgbWluaW11bSB2YWx1ZXMuXHJcbiAgcHVibGljIHJlYWRvbmx5IERFRkFVTFRfUEFTU19JRFBfUEJLREZfSVRFUiA9IHRoaXMuTUlOX1BBU1NfSURQX1BCS0RGX0lURVI7XHJcbiAgcHVibGljIHJlYWRvbmx5IERFRkFVTFRfUEFTU19LRVlfUEJLREZfSVRFUiA9IHRoaXMuTUlOX1BBU1NfS0VZX1BCS0RGX0lURVI7XHJcbiAgcHVibGljIHJlYWRvbmx5IERFRkFVTFRfTEJPUF9LRVlfUEJLREZfSVRFUiA9IHRoaXMuTUlOX0xCT1BfS0VZX1BCS0RGX0lURVI7XHJcblxyXG4gIHN0YXRpYyBhc0tleShcclxuICAgIGtleTogc3RyaW5nIHwgQnVmZmVyIHwgb2JqZWN0IHwgSldLLlJhd0tleSxcclxuICAgIGZvcm0/OlxyXG4gICAgICB8ICdqc29uJ1xyXG4gICAgICB8ICdwcml2YXRlJ1xyXG4gICAgICB8ICdwa2NzOCdcclxuICAgICAgfCAncHVibGljJ1xyXG4gICAgICB8ICdzcGtpJ1xyXG4gICAgICB8ICdwa2l4J1xyXG4gICAgICB8ICd4NTA5J1xyXG4gICAgICB8ICdwZW0nLFxyXG4gICAgZXh0cmFzPzogUmVjb3JkPHN0cmluZywgdW5rbm93bj5cclxuICApOiBQcm9taXNlPEpXSy5LZXk+IHtcclxuICAgIC8vIDxBWj4gVXNpbmcgYSBzaW5nbGUgZ2xvYmFsIGtleSBzdG9yZSBkaWQgbm90IHNlZW0gdG8gaW1wcm92ZSBzcGVlZC5cclxuICAgIC8vIHJldHVybiBLZXlGYWN0b3J5U2VydmljZS5rZXlTdG9yZS5hZGQoa2V5LCBmb3JtLCBleHRyYXMpO1xyXG4gICAgcmV0dXJuIEpXSy5hc0tleShrZXksIGZvcm0sIGV4dHJhcyk7XHJcbiAgfVxyXG5cclxuICByYW5kb21TdHJpbmcoZGlnaXRzOiBudW1iZXIpOiBzdHJpbmcge1xyXG4gICAgaWYgKGRpZ2l0cyA8PSAwKSB7XHJcbiAgICAgIHRocm93IG5ldyBMckJhZEFyZ3VtZW50RXhjZXB0aW9uKCdkaWdpdHMgPD0gMCcpO1xyXG4gICAgfVxyXG4gICAgY29uc3QgdmFsaWRDaGFycyA9XHJcbiAgICAgICdBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OSc7XHJcbiAgICBsZXQgYXJyYXkgPSBuZXcgVWludDMyQXJyYXkoZGlnaXRzKTtcclxuICAgIHRoaXMuY3J5cHRvLmdldFJhbmRvbVZhbHVlcyhhcnJheSk7XHJcbiAgICBhcnJheSA9IGFycmF5Lm1hcCgoeCkgPT4gdmFsaWRDaGFycy5jaGFyQ29kZUF0KHggJSB2YWxpZENoYXJzLmxlbmd0aCkpO1xyXG4gICAgcmV0dXJuIFN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkobnVsbCwgYXJyYXkpO1xyXG4gIH1cclxuXHJcbiAgcmFuZG9tRGlnaXRzTm9aZXJvcyhkaWdpdHM6IG51bWJlcik6IHN0cmluZyB7XHJcbiAgICByZXR1cm4gdGhpcy5yYW5kb21DaG9pY2VzKFsxLCAyLCAzLCA0LCA1LCA2LCA3LCA4LCA5XSwgZGlnaXRzKS5qb2luKCcnKTtcclxuICB9XHJcblxyXG4gIHJhbmRvbUNob2ljZXM8VD4oYXJyYXk6IFRbXSwgY2hvb3NlTjogbnVtYmVyKTogVFtdIHtcclxuICAgIGlmIChhcnJheS5sZW5ndGggPD0gMSkge1xyXG4gICAgICB0aHJvdyBuZXcgTHJCYWRBcmd1bWVudEV4Y2VwdGlvbignYXJyYXkubGVuZ3RoIDw9IDAnKTtcclxuICAgIH1cclxuICAgIGlmIChjaG9vc2VOIDw9IDApIHtcclxuICAgICAgdGhyb3cgbmV3IExyQmFkQXJndW1lbnRFeGNlcHRpb24oJ2Nob29zZU4gPD0gMCcpO1xyXG4gICAgfVxyXG4gICAgY29uc3QgdmFsdWVzID0gbmV3IFVpbnQzMkFycmF5KGNob29zZU4pO1xyXG4gICAgdGhpcy5jcnlwdG8uZ2V0UmFuZG9tVmFsdWVzKHZhbHVlcyk7XHJcbiAgICBjb25zdCByZXQ6IFRbXSA9IFtdO1xyXG4gICAgdmFsdWVzLmZvckVhY2goKHYpID0+IHJldC5wdXNoKGFycmF5W3YgJSBhcnJheS5sZW5ndGhdKSk7XHJcbiAgICByZXR1cm4gcmV0O1xyXG4gIH1cclxuXHJcbiAgY3JlYXRlU2FsdCgpOiBzdHJpbmcge1xyXG4gICAgcmV0dXJuIHRoaXMucmFuZG9tU3RyaW5nKDE2KTtcclxuICB9XHJcblxyXG4gIGFzeW5jIGNyZWF0ZUtleSgpOiBQcm9taXNlPEpXSy5LZXk+IHtcclxuICAgIGNvbnN0IGtleSA9IGF3YWl0IHRoaXMuY3J5cHRvLnN1YnRsZS5nZW5lcmF0ZUtleShcclxuICAgICAge1xyXG4gICAgICAgIG5hbWU6ICdBRVMtR0NNJyxcclxuICAgICAgICBsZW5ndGg6IDI1NiwgLy8gY2FuIGJlICAxMjgsIDE5Miwgb3IgMjU2XHJcbiAgICAgIH0sXHJcbiAgICAgIHRydWUsIC8vIHdoZXRoZXIgdGhlIGtleSBpcyBleHRyYWN0YWJsZSAoaS5lLiBjYW4gYmUgdXNlZCBpbiBleHBvcnRLZXkpXHJcbiAgICAgIFsnZW5jcnlwdCcsICdkZWNyeXB0J10gLy8gbXVzdCBiZSBbXCJlbmNyeXB0XCIsIFwiZGVjcnlwdFwiXSBvciBbXCJ3cmFwS2V5XCIsIFwidW53cmFwS2V5XCJdXHJcbiAgICApO1xyXG5cclxuICAgIGNvbnN0IGp3ayA9IGF3YWl0IHRoaXMuY3J5cHRvLnN1YnRsZS5leHBvcnRLZXkoJ2p3aycsIGtleSk7XHJcblxyXG4gICAgLy8gUmVtb3ZpbmcgdGhlIGZpZWxkcyBub3QgbmVlZGVkIGJ5IG5vZGUtam9zZVxyXG4gICAgZGVsZXRlIGp3ay5leHQ7XHJcbiAgICBkZWxldGUgandrLmtleV9vcHM7XHJcblxyXG4gICAgcmV0dXJuIEtleUZhY3RvcnlTZXJ2aWNlLmFzS2V5KGp3ayk7XHJcbiAgfVxyXG5cclxuICBhc3luYyBjcmVhdGVTaWduS2V5KCk6IFByb21pc2U8SldLLktleT4ge1xyXG4gICAgY29uc3Qga2V5ID0gYXdhaXQgdGhpcy5jcnlwdG8uc3VidGxlLmdlbmVyYXRlS2V5KFxyXG4gICAgICB7XHJcbiAgICAgICAgbmFtZTogJ0hNQUMnLFxyXG4gICAgICAgIGhhc2g6IHsgbmFtZTogJ1NIQS01MTInIH0sXHJcbiAgICAgIH0sXHJcbiAgICAgIHRydWUsXHJcbiAgICAgIFsnc2lnbicsICd2ZXJpZnknXVxyXG4gICAgKTtcclxuXHJcbiAgICBjb25zdCBqd2sgPSBhd2FpdCB0aGlzLmNyeXB0by5zdWJ0bGUuZXhwb3J0S2V5KCdqd2snLCBrZXkpO1xyXG5cclxuICAgIC8vIFJlbW92aW5nIHRoZSBmaWVsZHMgbm90IG5lZWRlZCBieSBub2RlLWpvc2VcclxuICAgIGRlbGV0ZSBqd2sua2V5X29wcztcclxuICAgIGRlbGV0ZSBqd2suZXh0O1xyXG5cclxuICAgIHJldHVybiBLZXlGYWN0b3J5U2VydmljZS5hc0tleShqd2spO1xyXG4gIH1cclxuXHJcbiAgYXN5bmMgY3JlYXRlUGtjS2V5KCk6IFByb21pc2U8SldLLktleT4ge1xyXG4gICAgLy8gbm9kZS1qb3NlIGlzIG5vdCB1c2luZyBGb3JnZSBwcm9wZXJseS4gSXQgc2hvdWxkIGJlIGNhbGxpbmcgdGhlIGFzeW5jIHZlcnNpb24gb2ZcclxuICAgIC8vIHBraS5yc2EuZ2VuZXJhdGVLZXlQYWlyKCkgd2l0aCBhIGNhbGxiYWNrLiBJbnN0ZWFkIGl0IGNhbGxzIHRoZSBzeW5jIHZlcnNpb24uIFdlYmNyeXB0b1xyXG4gICAgLy8gZG9lcyBub3Qgc3VwcG9ydCBzeW5jIHZlcnNpb24sIHNvIGl0IHVzZXMgdGhlIGphdmFzY3JpcHQgaW1wbGVtZW50YXRpb24sIHdoaWNoIGlzIHdheSB0b28gc2xvdy5cclxuICAgIC8vIFNvIHdlIGdlbmVyYXRlIHVzaW5nIHdlYmNyeXB0byBhbmQgaW1wb3J0IHRoZSBrZXkuXHJcbiAgICAvLyBVbmZvcnR1bmF0ZWx5IEVsbGlwdGljYWwgQ3VydmUgaXMgbm90IHN1cHBvcnRlZCBieSBXZWJjcnlwdG8uIFNvIHdlIGhhdmUgdG8gc2V0dGxlIGZvciBSU0EuXHJcbiAgICBjb25zdCBrZXkgPSBhd2FpdCB0aGlzLmNyeXB0by5zdWJ0bGUuZ2VuZXJhdGVLZXkoXHJcbiAgICAgIHtcclxuICAgICAgICBuYW1lOiAnUlNBLU9BRVAnLFxyXG4gICAgICAgIG1vZHVsdXNMZW5ndGg6IDIwNDgsIC8vIGNhbiBiZSAxMDI0LCAyMDQ4LCAzMDcyLCA0MDk2IC4uLiAxNjM4NFxyXG4gICAgICAgIC8vIEFzIHBlciBzdWdnZXN0aW9uOiBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvUnNhSGFzaGVkS2V5R2VuUGFyYW1zXHJcbiAgICAgICAgcHVibGljRXhwb25lbnQ6IG5ldyBVaW50OEFycmF5KFsweDAxLCAweDAwLCAweDAxXSksXHJcbiAgICAgICAgaGFzaDogeyBuYW1lOiAnU0hBLTI1NicgfSwgLy8gY2FuIGJlIFwiU0hBLTFcIiwgXCJTSEEtMjU2XCIsIFwiU0hBLTM4NFwiLCBvciBcIlNIQS01MTJcIlxyXG4gICAgICB9LFxyXG4gICAgICB0cnVlLCAvLyB3aGV0aGVyIHRoZSBrZXkgaXMgZXh0cmFjdGFibGUgKGkuZS4gY2FuIGJlIHVzZWQgaW4gZXhwb3J0S2V5KVxyXG4gICAgICBbJ2VuY3J5cHQnLCAnZGVjcnlwdCddIC8vIG11c3QgYmUgW1wiZW5jcnlwdFwiLCBcImRlY3J5cHRcIl0gb3IgW1wid3JhcEtleVwiLCBcInVud3JhcEtleVwiXVxyXG4gICAgKTtcclxuXHJcbiAgICBjb25zdCBqd2sgPSBhd2FpdCB0aGlzLmNyeXB0by5zdWJ0bGUuZXhwb3J0S2V5KCdqd2snLCBrZXkucHJpdmF0ZUtleSk7XHJcbiAgICAvLyBSZW1vdmluZyB0aGUgZmllbGRzIG5vdCBuZWVkZWQgYnkgbm9kZS1qb3NlXHJcbiAgICBkZWxldGUgandrLmtleV9vcHM7XHJcbiAgICBkZWxldGUgandrLmV4dDtcclxuXHJcbiAgICByZXR1cm4gS2V5RmFjdG9yeVNlcnZpY2UuYXNLZXkoandrKTtcclxuICB9XHJcblxyXG4gIGFzeW5jIGNyZWF0ZVBrY1NpZ25LZXkoKTogUHJvbWlzZTxKV0suS2V5PiB7XHJcbiAgICBjb25zdCBrZXkgPSBhd2FpdCB0aGlzLmNyeXB0by5zdWJ0bGUuZ2VuZXJhdGVLZXkoXHJcbiAgICAgIHtcclxuICAgICAgICBuYW1lOiAnUlNBU1NBLVBLQ1MxLXYxXzUnLFxyXG4gICAgICAgIG1vZHVsdXNMZW5ndGg6IDIwNDgsIC8vIGNhbiBiZSAxMDI0LCAyMDQ4LCBvciA0MDk2XHJcbiAgICAgICAgLy8gQXMgcGVyIHN1Z2dlc3Rpb246IGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9Sc2FIYXNoZWRLZXlHZW5QYXJhbXNcclxuICAgICAgICBwdWJsaWNFeHBvbmVudDogbmV3IFVpbnQ4QXJyYXkoWzB4MDEsIDB4MDAsIDB4MDFdKSxcclxuICAgICAgICBoYXNoOiB7IG5hbWU6ICdTSEEtMjU2JyB9LCAvLyBjYW4gYmUgXCJTSEEtMVwiLCBcIlNIQS0yNTZcIiwgXCJTSEEtMzg0XCIsIG9yIFwiU0hBLTUxMlwiXHJcbiAgICAgIH0sXHJcbiAgICAgIHRydWUsIC8vIHdoZXRoZXIgdGhlIGtleSBpcyBleHRyYWN0YWJsZSAoaS5lLiBjYW4gYmUgdXNlZCBpbiBleHBvcnRLZXkpXHJcbiAgICAgIFsnc2lnbicsICd2ZXJpZnknXSAvLyBjYW4gYmUgYW55IGNvbWJpbmF0aW9uIG9mIFwic2lnblwiIGFuZCBcInZlcmlmeVwiXHJcbiAgICApO1xyXG5cclxuICAgIGNvbnN0IGp3ayA9IGF3YWl0IHRoaXMuY3J5cHRvLnN1YnRsZS5leHBvcnRLZXkoJ2p3aycsIGtleS5wcml2YXRlS2V5KTtcclxuXHJcbiAgICAvLyBSZW1vdmluZyB0aGUgZmllbGRzIG5vdCBuZWVkZWQgYnkgbm9kZS1qb3NlXHJcbiAgICBkZWxldGUgandrLmtleV9vcHM7XHJcbiAgICBkZWxldGUgandrLmV4dDtcclxuXHJcbiAgICByZXR1cm4gS2V5RmFjdG9yeVNlcnZpY2UuYXNLZXkoandrKTtcclxuICB9XHJcblxyXG4gIGFzeW5jIGRlcml2ZUtleSh7XHJcbiAgICBwYXNzd29yZCxcclxuICAgIHNhbHQsXHJcbiAgICBpdGVyYXRpb25zLFxyXG4gICAga2lkLFxyXG4gIH06IHtcclxuICAgIHBhc3N3b3JkOiBzdHJpbmc7XHJcbiAgICBzYWx0OiBzdHJpbmc7XHJcbiAgICBpdGVyYXRpb25zOiBudW1iZXI7XHJcbiAgICBraWQ/OiBzdHJpbmc7XHJcbiAgfSk6IFByb21pc2U8RGVyaXZlS2V5UmVzdWx0PiB7XHJcbiAgICBjb25zdCBlbmMgPSBuZXcgVGV4dEVuY29kZXIoKTtcclxuICAgIGNvbnN0IHJhd0tleSA9IGF3YWl0IHRoaXMuY3J5cHRvLnN1YnRsZS5pbXBvcnRLZXkoXHJcbiAgICAgICdyYXcnLFxyXG4gICAgICBlbmMuZW5jb2RlKHBhc3N3b3JkKSxcclxuICAgICAgJ1BCS0RGMicsXHJcbiAgICAgIGZhbHNlLFxyXG4gICAgICBbJ2Rlcml2ZUJpdHMnLCAnZGVyaXZlS2V5J11cclxuICAgICk7XHJcblxyXG4gICAgY29uc3QgcGFzc0tleSA9IGF3YWl0IGNyeXB0by5zdWJ0bGUuZGVyaXZlS2V5KFxyXG4gICAgICB7XHJcbiAgICAgICAgbmFtZTogJ1BCS0RGMicsXHJcbiAgICAgICAgc2FsdDogbmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKHNhbHQpLFxyXG4gICAgICAgIGl0ZXJhdGlvbnMsXHJcbiAgICAgICAgaGFzaDogJ1NIQS0yNTYnLFxyXG4gICAgICB9LFxyXG4gICAgICByYXdLZXksXHJcbiAgICAgIHsgbmFtZTogJ0FFUy1HQ00nLCBsZW5ndGg6IDI1NiB9LFxyXG4gICAgICB0cnVlLFxyXG4gICAgICBbJ2VuY3J5cHQnLCAnZGVjcnlwdCddXHJcbiAgICApO1xyXG5cclxuICAgIGNvbnN0IHBhc3NLZXlKc29uOiBhbnkgPSBhd2FpdCBjcnlwdG8uc3VidGxlLmV4cG9ydEtleSgnandrJywgcGFzc0tleSk7XHJcbiAgICBpZiAoa2lkKSB7XHJcbiAgICAgIHBhc3NLZXlKc29uLmtpZCA9IGtpZDtcclxuICAgIH1cclxuXHJcbiAgICBjb25zdCBqd2sgPSBhd2FpdCBLZXlGYWN0b3J5U2VydmljZS5hc0tleShwYXNzS2V5SnNvbik7XHJcblxyXG4gICAgcmV0dXJuIHsgandrIH07XHJcbiAgfVxyXG5cclxuICBhc3luYyBkZXJpdmVQYXNzSWRwKHBhcmFtczogRGVyaXZlUGFzc0lkcFBhcmFtcyk6IFByb21pc2U8RGVyaXZlS2V5UmVzdWx0PiB7XHJcbiAgICBpZiAocGFyYW1zLml0ZXJhdGlvbnMgPCB0aGlzLk1JTl9QQVNTX0lEUF9QQktERl9JVEVSKSB7XHJcbiAgICAgIHRocm93IG5ldyBMclN1c3BpY2lvdXNFeGNlcHRpb24oXHJcbiAgICAgICAgYFRoZSBudW1iZXIgb2YgUGFzc0lkcCBrZXkgZGVyaXZhdGlvbiBpdGVyYXRpb25zIHNlbnQgZnJvbSB0aGUgc2VydmVyICgke3BhcmFtcy5pdGVyYXRpb25zfSkgaXMgbG93ZXIgdGhhbiB0aGUgbWluaW11bSAoJHt0aGlzLk1JTl9QQVNTX0lEUF9QQktERl9JVEVSfSlgXHJcbiAgICAgICk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdGhpcy5kZXJpdmVLZXkocGFyYW1zKTtcclxuICB9XHJcblxyXG4gIGFzeW5jIGRlcml2ZVBhc3NLZXkocGFyYW1zOiBEZXJpdmVQYXNzS2V5UGFyYW1zKTogUHJvbWlzZTxEZXJpdmVLZXlSZXN1bHQ+IHtcclxuICAgIGlmIChwYXJhbXMuaXRlcmF0aW9ucyA8IHRoaXMuTUlOX1BBU1NfS0VZX1BCS0RGX0lURVIpIHtcclxuICAgICAgdGhyb3cgbmV3IExyU3VzcGljaW91c0V4Y2VwdGlvbihcclxuICAgICAgICBgVGhlIG51bWJlciBvZiBQYXNzS2V5IGtleSBkZXJpdmF0aW9uIGl0ZXJhdGlvbnMgc2VudCBmcm9tIHRoZSBzZXJ2ZXIoJHtwYXJhbXMuaXRlcmF0aW9uc30pIGlzIGxvd2VyIHRoYW4gdGhlIG1pbmltdW0oJHt0aGlzLk1JTl9QQVNTX0tFWV9QQktERl9JVEVSfSlgXHJcbiAgICAgICk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdGhpcy5kZXJpdmVLZXkocGFyYW1zKTtcclxuICB9XHJcblxyXG4gIGFzeW5jIGRlcml2ZUxib3BLZXkocGFyYW1zOiBEZXJpdmVMYm9wS2V5UGFyYW1zKTogUHJvbWlzZTxEZXJpdmVLZXlSZXN1bHQ+IHtcclxuICAgIGlmIChwYXJhbXMuaXRlcmF0aW9ucyA8IHRoaXMuTUlOX0xCT1BfS0VZX1BCS0RGX0lURVIpIHtcclxuICAgICAgdGhyb3cgbmV3IExyU3VzcGljaW91c0V4Y2VwdGlvbihcclxuICAgICAgICBgVGhlIG51bWJlciBvZiBMYm9wS2V5IGtleSBkZXJpdmF0aW9uIGl0ZXJhdGlvbnMgc2VudCBmcm9tIHRoZSBzZXJ2ZXIoJHtwYXJhbXMuaXRlcmF0aW9uc30pIGlzIGxvd2VyIHRoYW4gdGhlIG1pbmltdW0oJHt0aGlzLk1JTl9MQk9QX0tFWV9QQktERl9JVEVSfSlgXHJcbiAgICAgICk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdGhpcy5kZXJpdmVLZXkocGFyYW1zKTtcclxuICB9XHJcblxyXG4gIGFzeW5jIGNyZWF0ZUtpZCgpOiBQcm9taXNlPHN0cmluZz4ge1xyXG4gICAgLy8gdG9kbzogQVo6IG5vZGUtam9zZSBzb3VyY2UgdXNlcyBub2RlJ3MgZGVmYXVsdCBVVUlEKCkgZnVuY3Rpb24gZm9yIGtpZCwgc28ganVzdCBjaGFuZ2UgdG8gdXNlIHRoYXQuXHJcbiAgICAvLyBmb3Igbm93LCB3ZSBhcmUganVzdCBjcmVhdGluZyBhIG5ldyBrZXkgdG8gdXNlIGl0J3Mga2lkLlxyXG4gICAgLy8gVGhlIGtpZCBpcyBhIHBhcnQgb2YgdGhlIEpXSyBzeXN0ZW0uIExSIGJhY2tlbmQgbWFpbnRhaW5zIHRoZSBrZXkgaGllcmFyY2h5IHNlcGFyYXRlbHkgd2l0aCBpdCdzIG93blxyXG4gICAgLy8ga2V5IGlkLiBCdXQgd2UganVzdCB1c2UgaXQgaGVyZSBhcyBhIGRvdWJsZSBjaGVjay5cclxuICAgIHJldHVybiAoYXdhaXQgdGhpcy5jcmVhdGVLZXkoKSkua2lkO1xyXG4gIH1cclxuXHJcbiAgYXN5bmMgY3JlYXRlUGFzc0lkcFBhcmFtcygpOiBQcm9taXNlPFBhc3NJZHBQYXJhbXM+IHtcclxuICAgIHJldHVybiB7XHJcbiAgICAgIHNhbHQ6IHRoaXMuY3JlYXRlU2FsdCgpLFxyXG4gICAgICBpdGVyYXRpb25zOiB0aGlzLkRFRkFVTFRfUEFTU19JRFBfUEJLREZfSVRFUixcclxuICAgIH07XHJcbiAgfVxyXG5cclxuICBhc3luYyBjcmVhdGVQYXNzS2V5UGFyYW1zKCk6IFByb21pc2U8UGFzc0tleVBhcmFtcz4ge1xyXG4gICAgcmV0dXJuIHtcclxuICAgICAgc2FsdDogdGhpcy5jcmVhdGVTYWx0KCksXHJcbiAgICAgIGtpZDogYXdhaXQgdGhpcy5jcmVhdGVLaWQoKSxcclxuICAgICAgaXRlcmF0aW9uczogdGhpcy5ERUZBVUxUX1BBU1NfS0VZX1BCS0RGX0lURVIsXHJcbiAgICB9O1xyXG4gIH1cclxuXHJcbiAgYXN5bmMgY3JlYXRlTGJvcEtleVBhcmFtcygpOiBQcm9taXNlPExib3BLZXlQYXJhbXM+IHtcclxuICAgIHJldHVybiB7XHJcbiAgICAgIHNhbHQ6IHRoaXMuY3JlYXRlU2FsdCgpLFxyXG4gICAgICAvLyB0b2RvOiBBWjogbm9kZS1qb3NlIHNvdXJjZSB1c2VzIG5vZGUncyBkZWZhdWx0IFVVSUQoKSBmdW5jdGlvbiBmb3Iga2lkLCBzbyBqdXN0IGNoYW5nZSB0byB1c2UgdGhhdC5cclxuICAgICAgLy8gZm9yIG5vdywgd2UgYXJlIGp1c3QgY3JlYXRpbmcgYSBuZXcga2V5IHRvIHVzZSBpdCdzIGtpZC5cclxuICAgICAgLy8gVGhlIGtpZCBpcyBhIHBhcnQgb2YgdGhlIEpXSyBzeXN0ZW0uIExSIGJhY2tlbmQgbWFpbnRhaW5zIHRoZSBrZXkgaGllcmFyY2h5IHNlcGFyYXRlbHkgd2l0aCBpdCdzIG93blxyXG4gICAgICAvLyBrZXkgaWQuIEJ1dCB3ZSBqdXN0IHVzZSBpdCBoZXJlIGFzIGEgZG91YmxlIGNoZWNrLlxyXG4gICAgICBraWQ6IGF3YWl0IHRoaXMuY3JlYXRlS2lkKCksXHJcbiAgICAgIGl0ZXJhdGlvbnM6IHRoaXMuREVGQVVMVF9QQVNTX0tFWV9QQktERl9JVEVSLFxyXG4gICAgfTtcclxuICB9XHJcbn1cclxuIl19