@lifeready/core 1.0.4 → 1.0.6

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 (226) 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 +1 -1
  5. package/bundles/lifeready-core.umd.min.js.map +1 -1
  6. package/esm2015/lib/_common/ast.js +40 -40
  7. package/esm2015/lib/_common/deferred-promise.js +24 -24
  8. package/esm2015/lib/_common/exceptions.js +157 -157
  9. package/esm2015/lib/_common/queries.gql.js +190 -190
  10. package/esm2015/lib/_common/run-outside-angular.js +79 -79
  11. package/esm2015/lib/_common/types.js +1 -1
  12. package/esm2015/lib/_common/utils.js +44 -44
  13. package/esm2015/lib/api/contact-card.gql.js +79 -79
  14. package/esm2015/lib/api/contact-card.service.js +154 -154
  15. package/esm2015/lib/api/contact-card2.gql.js +60 -60
  16. package/esm2015/lib/api/contact-card2.service.js +103 -103
  17. package/esm2015/lib/api/file.service.js +74 -74
  18. package/esm2015/lib/api/item2.gql.js +110 -110
  19. package/esm2015/lib/api/item2.service.js +311 -311
  20. package/esm2015/lib/api/key-exchange.gql.js +188 -188
  21. package/esm2015/lib/api/key-exchange.service.js +442 -442
  22. package/esm2015/lib/api/key-exchange.types.js +18 -18
  23. package/esm2015/lib/api/key-exchange2.gql.js +171 -171
  24. package/esm2015/lib/api/key-exchange2.service.js +479 -479
  25. package/esm2015/lib/api/lock.gql.js +40 -40
  26. package/esm2015/lib/api/lock.service.js +64 -64
  27. package/esm2015/lib/api/lr-apollo.service.js +46 -46
  28. package/esm2015/lib/api/lr-graphql/index.js +6 -6
  29. package/esm2015/lib/api/lr-graphql/lr-graphql.service.js +155 -155
  30. package/esm2015/lib/api/lr-graphql/lr-merged-mutation.js +213 -213
  31. package/esm2015/lib/api/lr-graphql/lr-mutation-base.js +51 -51
  32. package/esm2015/lib/api/lr-graphql/lr-mutation.js +48 -48
  33. package/esm2015/lib/api/lr-graphql/lr.service.js +18 -18
  34. package/esm2015/lib/api/message.service.js +138 -138
  35. package/esm2015/lib/api/persist.service.js +181 -181
  36. package/esm2015/lib/api/query-processor/common-processors.service.js +93 -93
  37. package/esm2015/lib/api/query-processor/index.js +3 -3
  38. package/esm2015/lib/api/query-processor/query-processor.service.js +192 -192
  39. package/esm2015/lib/api/query-processor/tp-password-reset-processor.service.js +109 -109
  40. package/esm2015/lib/api/shared-contact-card.service.js +119 -119
  41. package/esm2015/lib/api/shared-contact-card2.gql.js +41 -41
  42. package/esm2015/lib/api/shared-contact-card2.service.js +117 -117
  43. package/esm2015/lib/api/time.service.js +146 -146
  44. package/esm2015/lib/api/types/graphql.types.js +7 -7
  45. package/esm2015/lib/api/types/index.js +3 -3
  46. package/esm2015/lib/api/types/lr-graphql.types.js +71 -71
  47. package/esm2015/lib/auth/auth.config.js +57 -57
  48. package/esm2015/lib/auth/auth.gql.js +48 -48
  49. package/esm2015/lib/auth/auth.types.js +27 -27
  50. package/esm2015/lib/auth/idle.service.js +168 -168
  51. package/esm2015/lib/auth/idle.types.js +7 -7
  52. package/esm2015/lib/auth/lbop.service.js +355 -355
  53. package/esm2015/lib/auth/life-ready-auth.service.js +500 -500
  54. package/esm2015/lib/auth/password.service.js +320 -320
  55. package/esm2015/lib/auth/register.service.js +172 -172
  56. package/esm2015/lib/auth/two-factor.service.js +74 -74
  57. package/esm2015/lib/category/category-meta.service.js +99 -99
  58. package/esm2015/lib/category/category.gql.js +406 -406
  59. package/esm2015/lib/category/category.service.js +390 -390
  60. package/esm2015/lib/category/category.types.js +29 -29
  61. package/esm2015/lib/cryptography/cryptography.types.js +11 -11
  62. package/esm2015/lib/cryptography/encryption.service.js +189 -189
  63. package/esm2015/lib/cryptography/key-factory.service.js +237 -237
  64. package/esm2015/lib/cryptography/key-graph.service.js +280 -280
  65. package/esm2015/lib/cryptography/key-meta.service.js +200 -200
  66. package/esm2015/lib/cryptography/key.service.js +124 -124
  67. package/esm2015/lib/cryptography/slip39.service.js +169 -169
  68. package/esm2015/lib/cryptography/web-crypto.service.js +29 -29
  69. package/esm2015/lib/life-ready.config.js +84 -84
  70. package/esm2015/lib/life-ready.module.js +74 -74
  71. package/esm2015/lib/plan/plan.gql.js +123 -123
  72. package/esm2015/lib/plan/plan.service.js +149 -149
  73. package/esm2015/lib/plan/plan.types.js +11 -11
  74. package/esm2015/lib/record/record-attachment.service.js +101 -101
  75. package/esm2015/lib/record/record.gql.js +179 -179
  76. package/esm2015/lib/record/record.service.js +206 -206
  77. package/esm2015/lib/record/record.types.js +15 -15
  78. package/esm2015/lib/record-type/record-type.service.js +75 -75
  79. package/esm2015/lib/record-type/record-type.types.js +28 -28
  80. package/esm2015/lib/scenario/approvals/scenario-approval.gql.js +105 -105
  81. package/esm2015/lib/scenario/approvals/scenario-approval.types.js +1 -1
  82. package/esm2015/lib/scenario/approvals/scenario-approver.service.js +300 -300
  83. package/esm2015/lib/scenario/claimants/scenario-claimant.gql.js +52 -52
  84. package/esm2015/lib/scenario/claimants/scenario-claimant.service.js +97 -97
  85. package/esm2015/lib/scenario/claimants/scenario-claimant.types.js +1 -1
  86. package/esm2015/lib/scenario/receivers/scenario-receiver.gql.js +150 -150
  87. package/esm2015/lib/scenario/receivers/scenario-receiver.service.js +229 -229
  88. package/esm2015/lib/scenario/receivers/scenario-receiver.types.js +1 -1
  89. package/esm2015/lib/scenario/scenario-setup.service.js +269 -269
  90. package/esm2015/lib/scenario/scenario.gql.js +368 -368
  91. package/esm2015/lib/scenario/scenario.service.js +611 -611
  92. package/esm2015/lib/scenario/scenario.types.js +64 -64
  93. package/esm2015/lib/search/search.gql.js +62 -62
  94. package/esm2015/lib/search/search.service.js +156 -156
  95. package/esm2015/lib/search/search.types.js +6 -6
  96. package/esm2015/lib/trusted-parties/tp-password-reset-request.service.js +112 -112
  97. package/esm2015/lib/trusted-parties/tp-password-reset-user.service.js +129 -129
  98. package/esm2015/lib/trusted-parties/tp-password-reset.constants.js +4 -4
  99. package/esm2015/lib/trusted-parties/tp-password-reset.gql.js +232 -232
  100. package/esm2015/lib/trusted-parties/tp-password-reset.service.js +299 -299
  101. package/esm2015/lib/trusted-parties/trusted-party.gql.js +148 -148
  102. package/esm2015/lib/trusted-parties/trusted-party.service.js +326 -326
  103. package/esm2015/lib/trusted-parties/trusted-party.types.js +41 -41
  104. package/esm2015/lib/trusted-parties/trusted-party2.gql.js +87 -87
  105. package/esm2015/lib/trusted-parties/trusted-party2.service.js +215 -215
  106. package/esm2015/lib/users/profile-details.service.js +214 -214
  107. package/esm2015/lib/users/profile.gql.js +97 -97
  108. package/esm2015/lib/users/profile.service.js +169 -169
  109. package/esm2015/lib/users/profile.types.js +34 -34
  110. package/esm2015/lib/users/user.gql.js +60 -60
  111. package/esm2015/lib/users/user.service.js +79 -79
  112. package/esm2015/lib/users/user.types.js +5 -5
  113. package/esm2015/lifeready-core.js +10 -10
  114. package/esm2015/public-api.js +81 -81
  115. package/fesm2015/lifeready-core.js +13088 -13088
  116. package/fesm2015/lifeready-core.js.map +1 -1
  117. package/lib/_common/ast.d.ts +11 -11
  118. package/lib/_common/deferred-promise.d.ts +12 -12
  119. package/lib/_common/exceptions.d.ts +109 -109
  120. package/lib/_common/queries.gql.d.ts +10 -10
  121. package/lib/_common/run-outside-angular.d.ts +14 -14
  122. package/lib/_common/types.d.ts +10 -10
  123. package/lib/_common/utils.d.ts +3 -3
  124. package/lib/api/contact-card.gql.d.ts +7 -7
  125. package/lib/api/contact-card.service.d.ts +52 -52
  126. package/lib/api/contact-card2.gql.d.ts +34 -34
  127. package/lib/api/contact-card2.service.d.ts +49 -49
  128. package/lib/api/file.service.d.ts +18 -18
  129. package/lib/api/item2.gql.d.ts +96 -96
  130. package/lib/api/item2.service.d.ts +177 -177
  131. package/lib/api/key-exchange.gql.d.ts +9 -9
  132. package/lib/api/key-exchange.service.d.ts +39 -39
  133. package/lib/api/key-exchange.types.d.ts +196 -196
  134. package/lib/api/key-exchange2.gql.d.ts +125 -125
  135. package/lib/api/key-exchange2.service.d.ts +187 -187
  136. package/lib/api/lock.gql.d.ts +27 -27
  137. package/lib/api/lock.service.d.ts +25 -25
  138. package/lib/api/lr-apollo.service.d.ts +15 -15
  139. package/lib/api/lr-graphql/index.d.ts +5 -5
  140. package/lib/api/lr-graphql/lr-graphql.service.d.ts +60 -60
  141. package/lib/api/lr-graphql/lr-merged-mutation.d.ts +27 -27
  142. package/lib/api/lr-graphql/lr-mutation-base.d.ts +28 -28
  143. package/lib/api/lr-graphql/lr-mutation.d.ts +8 -8
  144. package/lib/api/lr-graphql/lr.service.d.ts +9 -9
  145. package/lib/api/message.service.d.ts +58 -58
  146. package/lib/api/persist.service.d.ts +31 -31
  147. package/lib/api/query-processor/common-processors.service.d.ts +36 -36
  148. package/lib/api/query-processor/index.d.ts +2 -2
  149. package/lib/api/query-processor/query-processor.service.d.ts +18 -18
  150. package/lib/api/query-processor/tp-password-reset-processor.service.d.ts +15 -15
  151. package/lib/api/shared-contact-card.service.d.ts +33 -33
  152. package/lib/api/shared-contact-card2.gql.d.ts +36 -36
  153. package/lib/api/shared-contact-card2.service.d.ts +45 -45
  154. package/lib/api/time.service.d.ts +16 -16
  155. package/lib/api/types/graphql.types.d.ts +29 -29
  156. package/lib/api/types/index.d.ts +2 -2
  157. package/lib/api/types/lr-graphql.types.d.ts +393 -385
  158. package/lib/auth/auth.config.d.ts +5 -5
  159. package/lib/auth/auth.gql.d.ts +15 -15
  160. package/lib/auth/auth.types.d.ts +66 -66
  161. package/lib/auth/idle.service.d.ts +40 -40
  162. package/lib/auth/idle.types.d.ts +10 -10
  163. package/lib/auth/lbop.service.d.ts +91 -91
  164. package/lib/auth/life-ready-auth.service.d.ts +59 -59
  165. package/lib/auth/password.service.d.ts +78 -78
  166. package/lib/auth/register.service.d.ts +25 -25
  167. package/lib/auth/two-factor.service.d.ts +15 -15
  168. package/lib/category/category-meta.service.d.ts +23 -23
  169. package/lib/category/category.gql.d.ts +45 -45
  170. package/lib/category/category.service.d.ts +67 -67
  171. package/lib/category/category.types.d.ts +79 -79
  172. package/lib/cryptography/cryptography.types.d.ts +83 -83
  173. package/lib/cryptography/encryption.service.d.ts +41 -41
  174. package/lib/cryptography/key-factory.service.d.ts +38 -38
  175. package/lib/cryptography/key-graph.service.d.ts +33 -33
  176. package/lib/cryptography/key-meta.service.d.ts +44 -44
  177. package/lib/cryptography/key.service.d.ts +36 -36
  178. package/lib/cryptography/slip39.service.d.ts +43 -43
  179. package/lib/cryptography/web-crypto.service.d.ts +5 -5
  180. package/lib/life-ready.config.d.ts +14 -14
  181. package/lib/life-ready.module.d.ts +5 -5
  182. package/lib/plan/plan.gql.d.ts +11 -11
  183. package/lib/plan/plan.service.d.ts +33 -33
  184. package/lib/plan/plan.types.d.ts +31 -31
  185. package/lib/record/record-attachment.service.d.ts +16 -16
  186. package/lib/record/record.gql.d.ts +14 -14
  187. package/lib/record/record.service.d.ts +25 -25
  188. package/lib/record/record.types.d.ts +57 -57
  189. package/lib/record-type/record-type.service.d.ts +11 -11
  190. package/lib/record-type/record-type.types.d.ts +50 -50
  191. package/lib/scenario/approvals/scenario-approval.gql.d.ts +7 -7
  192. package/lib/scenario/approvals/scenario-approval.types.d.ts +63 -63
  193. package/lib/scenario/approvals/scenario-approver.service.d.ts +32 -32
  194. package/lib/scenario/claimants/scenario-claimant.gql.d.ts +5 -5
  195. package/lib/scenario/claimants/scenario-claimant.service.d.ts +17 -17
  196. package/lib/scenario/claimants/scenario-claimant.types.d.ts +18 -18
  197. package/lib/scenario/receivers/scenario-receiver.gql.d.ts +8 -8
  198. package/lib/scenario/receivers/scenario-receiver.service.d.ts +30 -30
  199. package/lib/scenario/receivers/scenario-receiver.types.d.ts +54 -54
  200. package/lib/scenario/scenario-setup.service.d.ts +22 -22
  201. package/lib/scenario/scenario.gql.d.ts +34 -34
  202. package/lib/scenario/scenario.service.d.ts +58 -58
  203. package/lib/scenario/scenario.types.d.ts +217 -217
  204. package/lib/search/search.gql.d.ts +1 -1
  205. package/lib/search/search.service.d.ts +25 -25
  206. package/lib/search/search.types.d.ts +20 -20
  207. package/lib/trusted-parties/tp-password-reset-request.service.d.ts +20 -20
  208. package/lib/trusted-parties/tp-password-reset-user.service.d.ts +35 -35
  209. package/lib/trusted-parties/tp-password-reset.constants.d.ts +3 -3
  210. package/lib/trusted-parties/tp-password-reset.gql.d.ts +218 -218
  211. package/lib/trusted-parties/tp-password-reset.service.d.ts +130 -130
  212. package/lib/trusted-parties/trusted-party.gql.d.ts +9 -9
  213. package/lib/trusted-parties/trusted-party.service.d.ts +44 -44
  214. package/lib/trusted-parties/trusted-party.types.d.ts +102 -102
  215. package/lib/trusted-parties/trusted-party2.gql.d.ts +79 -79
  216. package/lib/trusted-parties/trusted-party2.service.d.ts +114 -114
  217. package/lib/users/profile-details.service.d.ts +21 -21
  218. package/lib/users/profile.gql.d.ts +11 -11
  219. package/lib/users/profile.service.d.ts +35 -35
  220. package/lib/users/profile.types.d.ts +96 -96
  221. package/lib/users/user.gql.d.ts +9 -9
  222. package/lib/users/user.service.d.ts +12 -12
  223. package/lib/users/user.types.d.ts +23 -23
  224. package/lifeready-core.d.ts +9 -9
  225. package/package.json +1 -1
  226. 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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoia2V5LWZhY3Rvcnkuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiJDOi9Qcm9qZWN0cy9uZXdyZXBvL2tjLWNsaWVudC9wcm9qZWN0cy9jb3JlL3NyYy8iLCJzb3VyY2VzIjpbImxpYi9jcnlwdG9ncmFwaHkva2V5LWZhY3Rvcnkuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzQyxPQUFPLEVBQUUsR0FBRyxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBVWhDLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQ3hELE9BQU8sRUFDTCxzQkFBc0IsRUFDdEIscUJBQXFCLEdBQ3RCLE1BQU0sdUJBQXVCLENBQUM7OztBQUUvQixNQUFNLFVBQWdCLE1BQU0sQ0FBQyxPQUFPOztRQUNsQyxrQkFBa0I7UUFDbEIsTUFBTSxTQUFTLEdBQUcsSUFBSSxXQUFXLEVBQUUsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUM7UUFFcEQsbUJBQW1CO1FBQ25CLE1BQU0sVUFBVSxHQUFHLE1BQU0sTUFBTSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsU0FBUyxFQUFFLFNBQVMsQ0FBQyxDQUFDO1FBRXBFLCtCQUErQjtRQUMvQixNQUFNLFNBQVMsR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksVUFBVSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUM7UUFFekQsOEJBQThCO1FBQzlCLE1BQU0sT0FBTyxHQUFHLFNBQVM7YUFDdEIsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLElBQUksR0FBRyxDQUFDLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7YUFDN0MsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQ1osT0FBTyxPQUFPLENBQUM7SUFDakIsQ0FBQztDQUFB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O1lBQ3RHLDJEQUEyRDtZQUMzRCx1R0FBdUc7WUFDdkcscURBQXFEO1lBQ3JELE9BQU8sQ0FBQyxNQUFNLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQyxDQUFDLEdBQUcsQ0FBQztRQUN0QyxDQUFDO0tBQUE7SUFFSyxtQkFBbUI7O1lBQ3ZCLE9BQU87Z0JBQ0wsSUFBSSxFQUFFLElBQUksQ0FBQyxVQUFVLEVBQUU7Z0JBQ3ZCLFVBQVUsRUFBRSxJQUFJLENBQUMsMkJBQTJCO2FBQzdDLENBQUM7UUFDSixDQUFDO0tBQUE7SUFFSyxtQkFBbUI7O1lBQ3ZCLE9BQU87Z0JBQ0wsSUFBSSxFQUFFLElBQUksQ0FBQyxVQUFVLEVBQUU7Z0JBQ3ZCLEdBQUcsRUFBRSxNQUFNLElBQUksQ0FBQyxTQUFTLEVBQUU7Z0JBQzNCLFVBQVUsRUFBRSxJQUFJLENBQUMsMkJBQTJCO2FBQzdDLENBQUM7UUFDSixDQUFDO0tBQUE7SUFFSyxtQkFBbUI7O1lBQ3ZCLE9BQU87Z0JBQ0wsSUFBSSxFQUFFLElBQUksQ0FBQyxVQUFVLEVBQUU7Z0JBQ3ZCLHNHQUFzRztnQkFDdEcsMkRBQTJEO2dCQUMzRCx1R0FBdUc7Z0JBQ3ZHLHFEQUFxRDtnQkFDckQsR0FBRyxFQUFFLE1BQU0sSUFBSSxDQUFDLFNBQVMsRUFBRTtnQkFDM0IsVUFBVSxFQUFFLElBQUksQ0FBQywyQkFBMkI7YUFDN0MsQ0FBQztRQUNKLENBQUM7S0FBQTs7OztZQTNRRixVQUFVLFNBQUM7Z0JBQ1YsVUFBVSxFQUFFLE1BQU07YUFDbkI7OztZQXpCUSxnQkFBZ0IiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IEpXSyB9IGZyb20gJ25vZGUtam9zZSc7XHJcbmltcG9ydCB7XHJcbiAgTGJvcEtleVBhcmFtcyxcclxuICBQYXNzSWRwUGFyYW1zLFxyXG4gIFBhc3NLZXlQYXJhbXMsXHJcbiAgRGVyaXZlS2V5UmVzdWx0LFxyXG4gIERlcml2ZVBhc3NJZHBQYXJhbXMsXHJcbiAgRGVyaXZlUGFzc0tleVBhcmFtcyxcclxuICBEZXJpdmVMYm9wS2V5UGFyYW1zLFxyXG59IGZyb20gJy4vY3J5cHRvZ3JhcGh5LnR5cGVzJztcclxuaW1wb3J0IHsgV2ViQ3J5cHRvU2VydmljZSB9IGZyb20gJy4vd2ViLWNyeXB0by5zZXJ2aWNlJztcclxuaW1wb3J0IHtcclxuICBMckJhZEFyZ3VtZW50RXhjZXB0aW9uLFxyXG4gIExyU3VzcGljaW91c0V4Y2VwdGlvbixcclxufSBmcm9tICcuLi9fY29tbW9uL2V4Y2VwdGlvbnMnO1xyXG5cclxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHNoYTI1NihtZXNzYWdlKSB7XHJcbiAgLy8gZW5jb2RlIGFzIFVURi04XHJcbiAgY29uc3QgbXNnQnVmZmVyID0gbmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKG1lc3NhZ2UpO1xyXG5cclxuICAvLyBoYXNoIHRoZSBtZXNzYWdlXHJcbiAgY29uc3QgaGFzaEJ1ZmZlciA9IGF3YWl0IGNyeXB0by5zdWJ0bGUuZGlnZXN0KCdTSEEtMjU2JywgbXNnQnVmZmVyKTtcclxuXHJcbiAgLy8gY29udmVydCBBcnJheUJ1ZmZlciB0byBBcnJheVxyXG4gIGNvbnN0IGhhc2hBcnJheSA9IEFycmF5LmZyb20obmV3IFVpbnQ4QXJyYXkoaGFzaEJ1ZmZlcikpO1xyXG5cclxuICAvLyBjb252ZXJ0IGJ5dGVzIHRvIGhleCBzdHJpbmdcclxuICBjb25zdCBoYXNoSGV4ID0gaGFzaEFycmF5XHJcbiAgICAubWFwKChiKSA9PiAoJzAwJyArIGIudG9TdHJpbmcoMTYpKS5zbGljZSgtMikpXHJcbiAgICAuam9pbignJyk7XHJcbiAgcmV0dXJuIGhhc2hIZXg7XHJcbn1cclxuXHJcbkBJbmplY3RhYmxlKHtcclxuICBwcm92aWRlZEluOiAncm9vdCcsXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBLZXlGYWN0b3J5U2VydmljZSB7XHJcbiAgY29uc3RydWN0b3IocHJpdmF0ZSB3ZWJDcnlwdG9TZXJ2aWNlOiBXZWJDcnlwdG9TZXJ2aWNlKSB7XHJcbiAgICB0aGlzLmNyeXB0byA9IHRoaXMud2ViQ3J5cHRvU2VydmljZS5jcnlwdG87XHJcbiAgfVxyXG4gIHByaXZhdGUgcmVhZG9ubHkgY3J5cHRvO1xyXG4gIC8vIEdsb2JhbCBrZXlzIHN0b3JlLiBPdGhlcndpc2UsIGVhY2ggY2FsbCB0byBhc0tleSBjcmVhdGVzIGEgbmV3IGtleVN0b3JlLlxyXG4gIC8vIDxBWj4gRGlkIG5vdCBzZWVtIHRvIGltcHJvdmUgc3BlZWQuXHJcbiAgLy8gcHVibGljIHN0YXRpYyBrZXlTdG9yZSA9IEpXSy5jcmVhdGVLZXlTdG9yZSgpO1xyXG5cclxuICAvLyBBWjogVGhpcyBjYW4ndCBiZSBjaGFuZ2UgZWFzaWx5LiBJdCdzIGJhc2ljYWxseSBhIFBhc3NLIG9yIFBhc3NJZHAgcm90YXRpb24uXHJcbiAgLy8gdG9kbzogd2Ugc2hvdWxkIGV2ZW50dWFsbHkgaW5jcmVhc2UgdGhpcyBwZXJpb2RpY2FsbHkgdG8gbWF0Y2ggd2l0aCBNb29yZSdzIGxhdy5cclxuICAvLyBUaGUgaXRlcmF0aW9ucyBmb3IgZWFjaCBrZXkgYXJlIGtlcHQgYnkgdGhlIHNlcnZlciBhcyB3ZWxsIGJ1dCB3ZSBhc3N1bWUgdGhlIHZhbHVlXHJcbiAgLy8gZnJvbSB0aGUgc2VydmVyIGlzIG5vdCB0cnVzdHdvcnRoeSwgc28gbmVlZCB0byBoYXZlIG1pbmltdW0gdGhyZXNob2xkcyBoZXJlLlxyXG4gIC8vIElmIGNyZWF0aW5nIG5ldyBrZXlzLCB0aGVzZSBtaW5pbXVtIGFyZSB1c2VkLlxyXG4gIHB1YmxpYyByZWFkb25seSBNSU5fUEFTU19JRFBfUEJLREZfSVRFUiA9IDEwMDAwMDtcclxuICBwdWJsaWMgcmVhZG9ubHkgTUlOX1BBU1NfS0VZX1BCS0RGX0lURVIgPSAxMDAwMDA7XHJcbiAgcHVibGljIHJlYWRvbmx5IE1JTl9MQk9QX0tFWV9QQktERl9JVEVSID0gMTAwMDAwO1xyXG5cclxuICAvLyBUaGVzZSBhcmUgdXNlZCBhcyB0aGUgZGVmYXVsdCB2YWx1ZXMuIFRoZXkgbXVzdCBiZSBsYXJnZXIgdGhhbiB0aGUgbWluaW11bSB2YWx1ZXMuXHJcbiAgcHVibGljIHJlYWRvbmx5IERFRkFVTFRfUEFTU19JRFBfUEJLREZfSVRFUiA9IHRoaXMuTUlOX1BBU1NfSURQX1BCS0RGX0lURVI7XHJcbiAgcHVibGljIHJlYWRvbmx5IERFRkFVTFRfUEFTU19LRVlfUEJLREZfSVRFUiA9IHRoaXMuTUlOX1BBU1NfS0VZX1BCS0RGX0lURVI7XHJcbiAgcHVibGljIHJlYWRvbmx5IERFRkFVTFRfTEJPUF9LRVlfUEJLREZfSVRFUiA9IHRoaXMuTUlOX0xCT1BfS0VZX1BCS0RGX0lURVI7XHJcblxyXG4gIHN0YXRpYyBhc0tleShcclxuICAgIGtleTogc3RyaW5nIHwgQnVmZmVyIHwgb2JqZWN0IHwgSldLLlJhd0tleSxcclxuICAgIGZvcm0/OlxyXG4gICAgICB8ICdqc29uJ1xyXG4gICAgICB8ICdwcml2YXRlJ1xyXG4gICAgICB8ICdwa2NzOCdcclxuICAgICAgfCAncHVibGljJ1xyXG4gICAgICB8ICdzcGtpJ1xyXG4gICAgICB8ICdwa2l4J1xyXG4gICAgICB8ICd4NTA5J1xyXG4gICAgICB8ICdwZW0nLFxyXG4gICAgZXh0cmFzPzogUmVjb3JkPHN0cmluZywgdW5rbm93bj5cclxuICApOiBQcm9taXNlPEpXSy5LZXk+IHtcclxuICAgIC8vIDxBWj4gVXNpbmcgYSBzaW5nbGUgZ2xvYmFsIGtleSBzdG9yZSBkaWQgbm90IHNlZW0gdG8gaW1wcm92ZSBzcGVlZC5cclxuICAgIC8vIHJldHVybiBLZXlGYWN0b3J5U2VydmljZS5rZXlTdG9yZS5hZGQoa2V5LCBmb3JtLCBleHRyYXMpO1xyXG4gICAgcmV0dXJuIEpXSy5hc0tleShrZXksIGZvcm0sIGV4dHJhcyk7XHJcbiAgfVxyXG5cclxuICByYW5kb21TdHJpbmcoZGlnaXRzOiBudW1iZXIpOiBzdHJpbmcge1xyXG4gICAgaWYgKGRpZ2l0cyA8PSAwKSB7XHJcbiAgICAgIHRocm93IG5ldyBMckJhZEFyZ3VtZW50RXhjZXB0aW9uKCdkaWdpdHMgPD0gMCcpO1xyXG4gICAgfVxyXG4gICAgY29uc3QgdmFsaWRDaGFycyA9XHJcbiAgICAgICdBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OSc7XHJcbiAgICBsZXQgYXJyYXkgPSBuZXcgVWludDMyQXJyYXkoZGlnaXRzKTtcclxuICAgIHRoaXMuY3J5cHRvLmdldFJhbmRvbVZhbHVlcyhhcnJheSk7XHJcbiAgICBhcnJheSA9IGFycmF5Lm1hcCgoeCkgPT4gdmFsaWRDaGFycy5jaGFyQ29kZUF0KHggJSB2YWxpZENoYXJzLmxlbmd0aCkpO1xyXG4gICAgcmV0dXJuIFN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkobnVsbCwgYXJyYXkpO1xyXG4gIH1cclxuXHJcbiAgcmFuZG9tRGlnaXRzTm9aZXJvcyhkaWdpdHM6IG51bWJlcik6IHN0cmluZyB7XHJcbiAgICByZXR1cm4gdGhpcy5yYW5kb21DaG9pY2VzKFsxLCAyLCAzLCA0LCA1LCA2LCA3LCA4LCA5XSwgZGlnaXRzKS5qb2luKCcnKTtcclxuICB9XHJcblxyXG4gIHJhbmRvbUNob2ljZXM8VD4oYXJyYXk6IFRbXSwgY2hvb3NlTjogbnVtYmVyKTogVFtdIHtcclxuICAgIGlmIChhcnJheS5sZW5ndGggPD0gMSkge1xyXG4gICAgICB0aHJvdyBuZXcgTHJCYWRBcmd1bWVudEV4Y2VwdGlvbignYXJyYXkubGVuZ3RoIDw9IDAnKTtcclxuICAgIH1cclxuICAgIGlmIChjaG9vc2VOIDw9IDApIHtcclxuICAgICAgdGhyb3cgbmV3IExyQmFkQXJndW1lbnRFeGNlcHRpb24oJ2Nob29zZU4gPD0gMCcpO1xyXG4gICAgfVxyXG4gICAgY29uc3QgdmFsdWVzID0gbmV3IFVpbnQzMkFycmF5KGNob29zZU4pO1xyXG4gICAgdGhpcy5jcnlwdG8uZ2V0UmFuZG9tVmFsdWVzKHZhbHVlcyk7XHJcbiAgICBjb25zdCByZXQ6IFRbXSA9IFtdO1xyXG4gICAgdmFsdWVzLmZvckVhY2goKHYpID0+IHJldC5wdXNoKGFycmF5W3YgJSBhcnJheS5sZW5ndGhdKSk7XHJcbiAgICByZXR1cm4gcmV0O1xyXG4gIH1cclxuXHJcbiAgY3JlYXRlU2FsdCgpOiBzdHJpbmcge1xyXG4gICAgcmV0dXJuIHRoaXMucmFuZG9tU3RyaW5nKDE2KTtcclxuICB9XHJcblxyXG4gIGFzeW5jIGNyZWF0ZUtleSgpOiBQcm9taXNlPEpXSy5LZXk+IHtcclxuICAgIGNvbnN0IGtleSA9IGF3YWl0IHRoaXMuY3J5cHRvLnN1YnRsZS5nZW5lcmF0ZUtleShcclxuICAgICAge1xyXG4gICAgICAgIG5hbWU6ICdBRVMtR0NNJyxcclxuICAgICAgICBsZW5ndGg6IDI1NiwgLy8gY2FuIGJlICAxMjgsIDE5Miwgb3IgMjU2XHJcbiAgICAgIH0sXHJcbiAgICAgIHRydWUsIC8vIHdoZXRoZXIgdGhlIGtleSBpcyBleHRyYWN0YWJsZSAoaS5lLiBjYW4gYmUgdXNlZCBpbiBleHBvcnRLZXkpXHJcbiAgICAgIFsnZW5jcnlwdCcsICdkZWNyeXB0J10gLy8gbXVzdCBiZSBbXCJlbmNyeXB0XCIsIFwiZGVjcnlwdFwiXSBvciBbXCJ3cmFwS2V5XCIsIFwidW53cmFwS2V5XCJdXHJcbiAgICApO1xyXG5cclxuICAgIGNvbnN0IGp3ayA9IGF3YWl0IHRoaXMuY3J5cHRvLnN1YnRsZS5leHBvcnRLZXkoJ2p3aycsIGtleSk7XHJcblxyXG4gICAgLy8gUmVtb3ZpbmcgdGhlIGZpZWxkcyBub3QgbmVlZGVkIGJ5IG5vZGUtam9zZVxyXG4gICAgZGVsZXRlIGp3ay5leHQ7XHJcbiAgICBkZWxldGUgandrLmtleV9vcHM7XHJcblxyXG4gICAgcmV0dXJuIEtleUZhY3RvcnlTZXJ2aWNlLmFzS2V5KGp3ayk7XHJcbiAgfVxyXG5cclxuICBhc3luYyBjcmVhdGVTaWduS2V5KCk6IFByb21pc2U8SldLLktleT4ge1xyXG4gICAgY29uc3Qga2V5ID0gYXdhaXQgdGhpcy5jcnlwdG8uc3VidGxlLmdlbmVyYXRlS2V5KFxyXG4gICAgICB7XHJcbiAgICAgICAgbmFtZTogJ0hNQUMnLFxyXG4gICAgICAgIGhhc2g6IHsgbmFtZTogJ1NIQS01MTInIH0sXHJcbiAgICAgIH0sXHJcbiAgICAgIHRydWUsXHJcbiAgICAgIFsnc2lnbicsICd2ZXJpZnknXVxyXG4gICAgKTtcclxuXHJcbiAgICBjb25zdCBqd2sgPSBhd2FpdCB0aGlzLmNyeXB0by5zdWJ0bGUuZXhwb3J0S2V5KCdqd2snLCBrZXkpO1xyXG5cclxuICAgIC8vIFJlbW92aW5nIHRoZSBmaWVsZHMgbm90IG5lZWRlZCBieSBub2RlLWpvc2VcclxuICAgIGRlbGV0ZSBqd2sua2V5X29wcztcclxuICAgIGRlbGV0ZSBqd2suZXh0O1xyXG5cclxuICAgIHJldHVybiBLZXlGYWN0b3J5U2VydmljZS5hc0tleShqd2spO1xyXG4gIH1cclxuXHJcbiAgYXN5bmMgY3JlYXRlUGtjS2V5KCk6IFByb21pc2U8SldLLktleT4ge1xyXG4gICAgLy8gbm9kZS1qb3NlIGlzIG5vdCB1c2luZyBGb3JnZSBwcm9wZXJseS4gSXQgc2hvdWxkIGJlIGNhbGxpbmcgdGhlIGFzeW5jIHZlcnNpb24gb2ZcclxuICAgIC8vIHBraS5yc2EuZ2VuZXJhdGVLZXlQYWlyKCkgd2l0aCBhIGNhbGxiYWNrLiBJbnN0ZWFkIGl0IGNhbGxzIHRoZSBzeW5jIHZlcnNpb24uIFdlYmNyeXB0b1xyXG4gICAgLy8gZG9lcyBub3Qgc3VwcG9ydCBzeW5jIHZlcnNpb24sIHNvIGl0IHVzZXMgdGhlIGphdmFzY3JpcHQgaW1wbGVtZW50YXRpb24sIHdoaWNoIGlzIHdheSB0b28gc2xvdy5cclxuICAgIC8vIFNvIHdlIGdlbmVyYXRlIHVzaW5nIHdlYmNyeXB0byBhbmQgaW1wb3J0IHRoZSBrZXkuXHJcbiAgICAvLyBVbmZvcnR1bmF0ZWx5IEVsbGlwdGljYWwgQ3VydmUgaXMgbm90IHN1cHBvcnRlZCBieSBXZWJjcnlwdG8uIFNvIHdlIGhhdmUgdG8gc2V0dGxlIGZvciBSU0EuXHJcbiAgICBjb25zdCBrZXkgPSBhd2FpdCB0aGlzLmNyeXB0by5zdWJ0bGUuZ2VuZXJhdGVLZXkoXHJcbiAgICAgIHtcclxuICAgICAgICBuYW1lOiAnUlNBLU9BRVAnLFxyXG4gICAgICAgIG1vZHVsdXNMZW5ndGg6IDIwNDgsIC8vIGNhbiBiZSAxMDI0LCAyMDQ4LCAzMDcyLCA0MDk2IC4uLiAxNjM4NFxyXG4gICAgICAgIC8vIEFzIHBlciBzdWdnZXN0aW9uOiBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvUnNhSGFzaGVkS2V5R2VuUGFyYW1zXHJcbiAgICAgICAgcHVibGljRXhwb25lbnQ6IG5ldyBVaW50OEFycmF5KFsweDAxLCAweDAwLCAweDAxXSksXHJcbiAgICAgICAgaGFzaDogeyBuYW1lOiAnU0hBLTI1NicgfSwgLy8gY2FuIGJlIFwiU0hBLTFcIiwgXCJTSEEtMjU2XCIsIFwiU0hBLTM4NFwiLCBvciBcIlNIQS01MTJcIlxyXG4gICAgICB9LFxyXG4gICAgICB0cnVlLCAvLyB3aGV0aGVyIHRoZSBrZXkgaXMgZXh0cmFjdGFibGUgKGkuZS4gY2FuIGJlIHVzZWQgaW4gZXhwb3J0S2V5KVxyXG4gICAgICBbJ2VuY3J5cHQnLCAnZGVjcnlwdCddIC8vIG11c3QgYmUgW1wiZW5jcnlwdFwiLCBcImRlY3J5cHRcIl0gb3IgW1wid3JhcEtleVwiLCBcInVud3JhcEtleVwiXVxyXG4gICAgKTtcclxuXHJcbiAgICBjb25zdCBqd2sgPSBhd2FpdCB0aGlzLmNyeXB0by5zdWJ0bGUuZXhwb3J0S2V5KCdqd2snLCBrZXkucHJpdmF0ZUtleSk7XHJcbiAgICAvLyBSZW1vdmluZyB0aGUgZmllbGRzIG5vdCBuZWVkZWQgYnkgbm9kZS1qb3NlXHJcbiAgICBkZWxldGUgandrLmtleV9vcHM7XHJcbiAgICBkZWxldGUgandrLmV4dDtcclxuXHJcbiAgICByZXR1cm4gS2V5RmFjdG9yeVNlcnZpY2UuYXNLZXkoandrKTtcclxuICB9XHJcblxyXG4gIGFzeW5jIGNyZWF0ZVBrY1NpZ25LZXkoKTogUHJvbWlzZTxKV0suS2V5PiB7XHJcbiAgICBjb25zdCBrZXkgPSBhd2FpdCB0aGlzLmNyeXB0by5zdWJ0bGUuZ2VuZXJhdGVLZXkoXHJcbiAgICAgIHtcclxuICAgICAgICBuYW1lOiAnUlNBU1NBLVBLQ1MxLXYxXzUnLFxyXG4gICAgICAgIG1vZHVsdXNMZW5ndGg6IDIwNDgsIC8vIGNhbiBiZSAxMDI0LCAyMDQ4LCBvciA0MDk2XHJcbiAgICAgICAgLy8gQXMgcGVyIHN1Z2dlc3Rpb246IGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9Sc2FIYXNoZWRLZXlHZW5QYXJhbXNcclxuICAgICAgICBwdWJsaWNFeHBvbmVudDogbmV3IFVpbnQ4QXJyYXkoWzB4MDEsIDB4MDAsIDB4MDFdKSxcclxuICAgICAgICBoYXNoOiB7IG5hbWU6ICdTSEEtMjU2JyB9LCAvLyBjYW4gYmUgXCJTSEEtMVwiLCBcIlNIQS0yNTZcIiwgXCJTSEEtMzg0XCIsIG9yIFwiU0hBLTUxMlwiXHJcbiAgICAgIH0sXHJcbiAgICAgIHRydWUsIC8vIHdoZXRoZXIgdGhlIGtleSBpcyBleHRyYWN0YWJsZSAoaS5lLiBjYW4gYmUgdXNlZCBpbiBleHBvcnRLZXkpXHJcbiAgICAgIFsnc2lnbicsICd2ZXJpZnknXSAvLyBjYW4gYmUgYW55IGNvbWJpbmF0aW9uIG9mIFwic2lnblwiIGFuZCBcInZlcmlmeVwiXHJcbiAgICApO1xyXG5cclxuICAgIGNvbnN0IGp3ayA9IGF3YWl0IHRoaXMuY3J5cHRvLnN1YnRsZS5leHBvcnRLZXkoJ2p3aycsIGtleS5wcml2YXRlS2V5KTtcclxuXHJcbiAgICAvLyBSZW1vdmluZyB0aGUgZmllbGRzIG5vdCBuZWVkZWQgYnkgbm9kZS1qb3NlXHJcbiAgICBkZWxldGUgandrLmtleV9vcHM7XHJcbiAgICBkZWxldGUgandrLmV4dDtcclxuXHJcbiAgICByZXR1cm4gS2V5RmFjdG9yeVNlcnZpY2UuYXNLZXkoandrKTtcclxuICB9XHJcblxyXG4gIGFzeW5jIGRlcml2ZUtleSh7XHJcbiAgICBwYXNzd29yZCxcclxuICAgIHNhbHQsXHJcbiAgICBpdGVyYXRpb25zLFxyXG4gICAga2lkLFxyXG4gIH06IHtcclxuICAgIHBhc3N3b3JkOiBzdHJpbmc7XHJcbiAgICBzYWx0OiBzdHJpbmc7XHJcbiAgICBpdGVyYXRpb25zOiBudW1iZXI7XHJcbiAgICBraWQ/OiBzdHJpbmc7XHJcbiAgfSk6IFByb21pc2U8RGVyaXZlS2V5UmVzdWx0PiB7XHJcbiAgICBjb25zdCBlbmMgPSBuZXcgVGV4dEVuY29kZXIoKTtcclxuICAgIGNvbnN0IHJhd0tleSA9IGF3YWl0IHRoaXMuY3J5cHRvLnN1YnRsZS5pbXBvcnRLZXkoXHJcbiAgICAgICdyYXcnLFxyXG4gICAgICBlbmMuZW5jb2RlKHBhc3N3b3JkKSxcclxuICAgICAgJ1BCS0RGMicsXHJcbiAgICAgIGZhbHNlLFxyXG4gICAgICBbJ2Rlcml2ZUJpdHMnLCAnZGVyaXZlS2V5J11cclxuICAgICk7XHJcblxyXG4gICAgY29uc3QgcGFzc0tleSA9IGF3YWl0IGNyeXB0by5zdWJ0bGUuZGVyaXZlS2V5KFxyXG4gICAgICB7XHJcbiAgICAgICAgbmFtZTogJ1BCS0RGMicsXHJcbiAgICAgICAgc2FsdDogbmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKHNhbHQpLFxyXG4gICAgICAgIGl0ZXJhdGlvbnMsXHJcbiAgICAgICAgaGFzaDogJ1NIQS0yNTYnLFxyXG4gICAgICB9LFxyXG4gICAgICByYXdLZXksXHJcbiAgICAgIHsgbmFtZTogJ0FFUy1HQ00nLCBsZW5ndGg6IDI1NiB9LFxyXG4gICAgICB0cnVlLFxyXG4gICAgICBbJ2VuY3J5cHQnLCAnZGVjcnlwdCddXHJcbiAgICApO1xyXG5cclxuICAgIGNvbnN0IHBhc3NLZXlKc29uOiBhbnkgPSBhd2FpdCBjcnlwdG8uc3VidGxlLmV4cG9ydEtleSgnandrJywgcGFzc0tleSk7XHJcbiAgICBpZiAoa2lkKSB7XHJcbiAgICAgIHBhc3NLZXlKc29uLmtpZCA9IGtpZDtcclxuICAgIH1cclxuXHJcbiAgICBjb25zdCBqd2sgPSBhd2FpdCBLZXlGYWN0b3J5U2VydmljZS5hc0tleShwYXNzS2V5SnNvbik7XHJcblxyXG4gICAgcmV0dXJuIHsgandrIH07XHJcbiAgfVxyXG5cclxuICBhc3luYyBkZXJpdmVQYXNzSWRwKHBhcmFtczogRGVyaXZlUGFzc0lkcFBhcmFtcyk6IFByb21pc2U8RGVyaXZlS2V5UmVzdWx0PiB7XHJcbiAgICBpZiAocGFyYW1zLml0ZXJhdGlvbnMgPCB0aGlzLk1JTl9QQVNTX0lEUF9QQktERl9JVEVSKSB7XHJcbiAgICAgIHRocm93IG5ldyBMclN1c3BpY2lvdXNFeGNlcHRpb24oXHJcbiAgICAgICAgYFRoZSBudW1iZXIgb2YgUGFzc0lkcCBrZXkgZGVyaXZhdGlvbiBpdGVyYXRpb25zIHNlbnQgZnJvbSB0aGUgc2VydmVyICgke3BhcmFtcy5pdGVyYXRpb25zfSkgaXMgbG93ZXIgdGhhbiB0aGUgbWluaW11bSAoJHt0aGlzLk1JTl9QQVNTX0lEUF9QQktERl9JVEVSfSlgXHJcbiAgICAgICk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdGhpcy5kZXJpdmVLZXkocGFyYW1zKTtcclxuICB9XHJcblxyXG4gIGFzeW5jIGRlcml2ZVBhc3NLZXkocGFyYW1zOiBEZXJpdmVQYXNzS2V5UGFyYW1zKTogUHJvbWlzZTxEZXJpdmVLZXlSZXN1bHQ+IHtcclxuICAgIGlmIChwYXJhbXMuaXRlcmF0aW9ucyA8IHRoaXMuTUlOX1BBU1NfS0VZX1BCS0RGX0lURVIpIHtcclxuICAgICAgdGhyb3cgbmV3IExyU3VzcGljaW91c0V4Y2VwdGlvbihcclxuICAgICAgICBgVGhlIG51bWJlciBvZiBQYXNzS2V5IGtleSBkZXJpdmF0aW9uIGl0ZXJhdGlvbnMgc2VudCBmcm9tIHRoZSBzZXJ2ZXIoJHtwYXJhbXMuaXRlcmF0aW9uc30pIGlzIGxvd2VyIHRoYW4gdGhlIG1pbmltdW0oJHt0aGlzLk1JTl9QQVNTX0tFWV9QQktERl9JVEVSfSlgXHJcbiAgICAgICk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdGhpcy5kZXJpdmVLZXkocGFyYW1zKTtcclxuICB9XHJcblxyXG4gIGFzeW5jIGRlcml2ZUxib3BLZXkocGFyYW1zOiBEZXJpdmVMYm9wS2V5UGFyYW1zKTogUHJvbWlzZTxEZXJpdmVLZXlSZXN1bHQ+IHtcclxuICAgIGlmIChwYXJhbXMuaXRlcmF0aW9ucyA8IHRoaXMuTUlOX0xCT1BfS0VZX1BCS0RGX0lURVIpIHtcclxuICAgICAgdGhyb3cgbmV3IExyU3VzcGljaW91c0V4Y2VwdGlvbihcclxuICAgICAgICBgVGhlIG51bWJlciBvZiBMYm9wS2V5IGtleSBkZXJpdmF0aW9uIGl0ZXJhdGlvbnMgc2VudCBmcm9tIHRoZSBzZXJ2ZXIoJHtwYXJhbXMuaXRlcmF0aW9uc30pIGlzIGxvd2VyIHRoYW4gdGhlIG1pbmltdW0oJHt0aGlzLk1JTl9MQk9QX0tFWV9QQktERl9JVEVSfSlgXHJcbiAgICAgICk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdGhpcy5kZXJpdmVLZXkocGFyYW1zKTtcclxuICB9XHJcblxyXG4gIGFzeW5jIGNyZWF0ZUtpZCgpOiBQcm9taXNlPHN0cmluZz4ge1xyXG4gICAgLy8gdG9kbzogQVo6IG5vZGUtam9zZSBzb3VyY2UgdXNlcyBub2RlJ3MgZGVmYXVsdCBVVUlEKCkgZnVuY3Rpb24gZm9yIGtpZCwgc28ganVzdCBjaGFuZ2UgdG8gdXNlIHRoYXQuXHJcbiAgICAvLyBmb3Igbm93LCB3ZSBhcmUganVzdCBjcmVhdGluZyBhIG5ldyBrZXkgdG8gdXNlIGl0J3Mga2lkLlxyXG4gICAgLy8gVGhlIGtpZCBpcyBhIHBhcnQgb2YgdGhlIEpXSyBzeXN0ZW0uIExSIGJhY2tlbmQgbWFpbnRhaW5zIHRoZSBrZXkgaGllcmFyY2h5IHNlcGFyYXRlbHkgd2l0aCBpdCdzIG93blxyXG4gICAgLy8ga2V5IGlkLiBCdXQgd2UganVzdCB1c2UgaXQgaGVyZSBhcyBhIGRvdWJsZSBjaGVjay5cclxuICAgIHJldHVybiAoYXdhaXQgdGhpcy5jcmVhdGVLZXkoKSkua2lkO1xyXG4gIH1cclxuXHJcbiAgYXN5bmMgY3JlYXRlUGFzc0lkcFBhcmFtcygpOiBQcm9taXNlPFBhc3NJZHBQYXJhbXM+IHtcclxuICAgIHJldHVybiB7XHJcbiAgICAgIHNhbHQ6IHRoaXMuY3JlYXRlU2FsdCgpLFxyXG4gICAgICBpdGVyYXRpb25zOiB0aGlzLkRFRkFVTFRfUEFTU19JRFBfUEJLREZfSVRFUixcclxuICAgIH07XHJcbiAgfVxyXG5cclxuICBhc3luYyBjcmVhdGVQYXNzS2V5UGFyYW1zKCk6IFByb21pc2U8UGFzc0tleVBhcmFtcz4ge1xyXG4gICAgcmV0dXJuIHtcclxuICAgICAgc2FsdDogdGhpcy5jcmVhdGVTYWx0KCksXHJcbiAgICAgIGtpZDogYXdhaXQgdGhpcy5jcmVhdGVLaWQoKSxcclxuICAgICAgaXRlcmF0aW9uczogdGhpcy5ERUZBVUxUX1BBU1NfS0VZX1BCS0RGX0lURVIsXHJcbiAgICB9O1xyXG4gIH1cclxuXHJcbiAgYXN5bmMgY3JlYXRlTGJvcEtleVBhcmFtcygpOiBQcm9taXNlPExib3BLZXlQYXJhbXM+IHtcclxuICAgIHJldHVybiB7XHJcbiAgICAgIHNhbHQ6IHRoaXMuY3JlYXRlU2FsdCgpLFxyXG4gICAgICAvLyB0b2RvOiBBWjogbm9kZS1qb3NlIHNvdXJjZSB1c2VzIG5vZGUncyBkZWZhdWx0IFVVSUQoKSBmdW5jdGlvbiBmb3Iga2lkLCBzbyBqdXN0IGNoYW5nZSB0byB1c2UgdGhhdC5cclxuICAgICAgLy8gZm9yIG5vdywgd2UgYXJlIGp1c3QgY3JlYXRpbmcgYSBuZXcga2V5IHRvIHVzZSBpdCdzIGtpZC5cclxuICAgICAgLy8gVGhlIGtpZCBpcyBhIHBhcnQgb2YgdGhlIEpXSyBzeXN0ZW0uIExSIGJhY2tlbmQgbWFpbnRhaW5zIHRoZSBrZXkgaGllcmFyY2h5IHNlcGFyYXRlbHkgd2l0aCBpdCdzIG93blxyXG4gICAgICAvLyBrZXkgaWQuIEJ1dCB3ZSBqdXN0IHVzZSBpdCBoZXJlIGFzIGEgZG91YmxlIGNoZWNrLlxyXG4gICAgICBraWQ6IGF3YWl0IHRoaXMuY3JlYXRlS2lkKCksXHJcbiAgICAgIGl0ZXJhdGlvbnM6IHRoaXMuREVGQVVMVF9QQVNTX0tFWV9QQktERl9JVEVSLFxyXG4gICAgfTtcclxuICB9XHJcbn1cclxuIl19
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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoia2V5LWZhY3Rvcnkuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIvb3B0L2F0bGFzc2lhbi9waXBlbGluZXMvYWdlbnQvYnVpbGQvcHJvamVjdHMvY29yZS9zcmMvIiwic291cmNlcyI6WyJsaWIvY3J5cHRvZ3JhcGh5L2tleS1mYWN0b3J5LnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDM0MsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLFdBQVcsQ0FBQztBQVVoQyxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUN4RCxPQUFPLEVBQ0wsc0JBQXNCLEVBQ3RCLHFCQUFxQixHQUN0QixNQUFNLHVCQUF1QixDQUFDOzs7QUFFL0IsTUFBTSxVQUFnQixNQUFNLENBQUMsT0FBTzs7UUFDbEMsa0JBQWtCO1FBQ2xCLE1BQU0sU0FBUyxHQUFHLElBQUksV0FBVyxFQUFFLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBRXBELG1CQUFtQjtRQUNuQixNQUFNLFVBQVUsR0FBRyxNQUFNLE1BQU0sQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLFNBQVMsRUFBRSxTQUFTLENBQUMsQ0FBQztRQUVwRSwrQkFBK0I7UUFDL0IsTUFBTSxTQUFTLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLFVBQVUsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDO1FBRXpELDhCQUE4QjtRQUM5QixNQUFNLE9BQU8sR0FBRyxTQUFTO2FBQ3RCLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxJQUFJLEdBQUcsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO2FBQzdDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUNaLE9BQU8sT0FBTyxDQUFDO0lBQ2pCLENB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LHNHQUFzRztZQUN0RywyREFBMkQ7WUFDM0QsdUdBQXVHO1lBQ3ZHLHFEQUFxRDtZQUNyRCxPQUFPLENBQUMsTUFBTSxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUM7UUFDdEMsQ0FBQztLQUFBO0lBRUssbUJBQW1COztZQUN2QixPQUFPO2dCQUNMLElBQUksRUFBRSxJQUFJLENBQUMsVUFBVSxFQUFFO2dCQUN2QixVQUFVLEVBQUUsSUFBSSxDQUFDLDJCQUEyQjthQUM3QyxDQUFDO1FBQ0osQ0FBQztLQUFBO0lBRUssbUJBQW1COztZQUN2QixPQUFPO2dCQUNMLElBQUksRUFBRSxJQUFJLENBQUMsVUFBVSxFQUFFO2dCQUN2QixHQUFHLEVBQUUsTUFBTSxJQUFJLENBQUMsU0FBUyxFQUFFO2dCQUMzQixVQUFVLEVBQUUsSUFBSSxDQUFDLDJCQUEyQjthQUM3QyxDQUFDO1FBQ0osQ0FBQztLQUFBO0lBRUssbUJBQW1COztZQUN2QixPQUFPO2dCQUNMLElBQUksRUFBRSxJQUFJLENBQUMsVUFBVSxFQUFFO2dCQUN2QixzR0FBc0c7Z0JBQ3RHLDJEQUEyRDtnQkFDM0QsdUdBQXVHO2dCQUN2RyxxREFBcUQ7Z0JBQ3JELEdBQUcsRUFBRSxNQUFNLElBQUksQ0FBQyxTQUFTLEVBQUU7Z0JBQzNCLFVBQVUsRUFBRSxJQUFJLENBQUMsMkJBQTJCO2FBQzdDLENBQUM7UUFDSixDQUFDO0tBQUE7Ozs7WUEzUUYsVUFBVSxTQUFDO2dCQUNWLFVBQVUsRUFBRSxNQUFNO2FBQ25COzs7WUF6QlEsZ0JBQWdCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgSldLIH0gZnJvbSAnbm9kZS1qb3NlJztcbmltcG9ydCB7XG4gIExib3BLZXlQYXJhbXMsXG4gIFBhc3NJZHBQYXJhbXMsXG4gIFBhc3NLZXlQYXJhbXMsXG4gIERlcml2ZUtleVJlc3VsdCxcbiAgRGVyaXZlUGFzc0lkcFBhcmFtcyxcbiAgRGVyaXZlUGFzc0tleVBhcmFtcyxcbiAgRGVyaXZlTGJvcEtleVBhcmFtcyxcbn0gZnJvbSAnLi9jcnlwdG9ncmFwaHkudHlwZXMnO1xuaW1wb3J0IHsgV2ViQ3J5cHRvU2VydmljZSB9IGZyb20gJy4vd2ViLWNyeXB0by5zZXJ2aWNlJztcbmltcG9ydCB7XG4gIExyQmFkQXJndW1lbnRFeGNlcHRpb24sXG4gIExyU3VzcGljaW91c0V4Y2VwdGlvbixcbn0gZnJvbSAnLi4vX2NvbW1vbi9leGNlcHRpb25zJztcblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHNoYTI1NihtZXNzYWdlKSB7XG4gIC8vIGVuY29kZSBhcyBVVEYtOFxuICBjb25zdCBtc2dCdWZmZXIgPSBuZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUobWVzc2FnZSk7XG5cbiAgLy8gaGFzaCB0aGUgbWVzc2FnZVxuICBjb25zdCBoYXNoQnVmZmVyID0gYXdhaXQgY3J5cHRvLnN1YnRsZS5kaWdlc3QoJ1NIQS0yNTYnLCBtc2dCdWZmZXIpO1xuXG4gIC8vIGNvbnZlcnQgQXJyYXlCdWZmZXIgdG8gQXJyYXlcbiAgY29uc3QgaGFzaEFycmF5ID0gQXJyYXkuZnJvbShuZXcgVWludDhBcnJheShoYXNoQnVmZmVyKSk7XG5cbiAgLy8gY29udmVydCBieXRlcyB0byBoZXggc3RyaW5nXG4gIGNvbnN0IGhhc2hIZXggPSBoYXNoQXJyYXlcbiAgICAubWFwKChiKSA9PiAoJzAwJyArIGIudG9TdHJpbmcoMTYpKS5zbGljZSgtMikpXG4gICAgLmpvaW4oJycpO1xuICByZXR1cm4gaGFzaEhleDtcbn1cblxuQEluamVjdGFibGUoe1xuICBwcm92aWRlZEluOiAncm9vdCcsXG59KVxuZXhwb3J0IGNsYXNzIEtleUZhY3RvcnlTZXJ2aWNlIHtcbiAgY29uc3RydWN0b3IocHJpdmF0ZSB3ZWJDcnlwdG9TZXJ2aWNlOiBXZWJDcnlwdG9TZXJ2aWNlKSB7XG4gICAgdGhpcy5jcnlwdG8gPSB0aGlzLndlYkNyeXB0b1NlcnZpY2UuY3J5cHRvO1xuICB9XG4gIHByaXZhdGUgcmVhZG9ubHkgY3J5cHRvO1xuICAvLyBHbG9iYWwga2V5cyBzdG9yZS4gT3RoZXJ3aXNlLCBlYWNoIGNhbGwgdG8gYXNLZXkgY3JlYXRlcyBhIG5ldyBrZXlTdG9yZS5cbiAgLy8gPEFaPiBEaWQgbm90IHNlZW0gdG8gaW1wcm92ZSBzcGVlZC5cbiAgLy8gcHVibGljIHN0YXRpYyBrZXlTdG9yZSA9IEpXSy5jcmVhdGVLZXlTdG9yZSgpO1xuXG4gIC8vIEFaOiBUaGlzIGNhbid0IGJlIGNoYW5nZSBlYXNpbHkuIEl0J3MgYmFzaWNhbGx5IGEgUGFzc0sgb3IgUGFzc0lkcCByb3RhdGlvbi5cbiAgLy8gdG9kbzogd2Ugc2hvdWxkIGV2ZW50dWFsbHkgaW5jcmVhc2UgdGhpcyBwZXJpb2RpY2FsbHkgdG8gbWF0Y2ggd2l0aCBNb29yZSdzIGxhdy5cbiAgLy8gVGhlIGl0ZXJhdGlvbnMgZm9yIGVhY2gga2V5IGFyZSBrZXB0IGJ5IHRoZSBzZXJ2ZXIgYXMgd2VsbCBidXQgd2UgYXNzdW1lIHRoZSB2YWx1ZVxuICAvLyBmcm9tIHRoZSBzZXJ2ZXIgaXMgbm90IHRydXN0d29ydGh5LCBzbyBuZWVkIHRvIGhhdmUgbWluaW11bSB0aHJlc2hvbGRzIGhlcmUuXG4gIC8vIElmIGNyZWF0aW5nIG5ldyBrZXlzLCB0aGVzZSBtaW5pbXVtIGFyZSB1c2VkLlxuICBwdWJsaWMgcmVhZG9ubHkgTUlOX1BBU1NfSURQX1BCS0RGX0lURVIgPSAxMDAwMDA7XG4gIHB1YmxpYyByZWFkb25seSBNSU5fUEFTU19LRVlfUEJLREZfSVRFUiA9IDEwMDAwMDtcbiAgcHVibGljIHJlYWRvbmx5IE1JTl9MQk9QX0tFWV9QQktERl9JVEVSID0gMTAwMDAwO1xuXG4gIC8vIFRoZXNlIGFyZSB1c2VkIGFzIHRoZSBkZWZhdWx0IHZhbHVlcy4gVGhleSBtdXN0IGJlIGxhcmdlciB0aGFuIHRoZSBtaW5pbXVtIHZhbHVlcy5cbiAgcHVibGljIHJlYWRvbmx5IERFRkFVTFRfUEFTU19JRFBfUEJLREZfSVRFUiA9IHRoaXMuTUlOX1BBU1NfSURQX1BCS0RGX0lURVI7XG4gIHB1YmxpYyByZWFkb25seSBERUZBVUxUX1BBU1NfS0VZX1BCS0RGX0lURVIgPSB0aGlzLk1JTl9QQVNTX0tFWV9QQktERl9JVEVSO1xuICBwdWJsaWMgcmVhZG9ubHkgREVGQVVMVF9MQk9QX0tFWV9QQktERl9JVEVSID0gdGhpcy5NSU5fTEJPUF9LRVlfUEJLREZfSVRFUjtcblxuICBzdGF0aWMgYXNLZXkoXG4gICAga2V5OiBzdHJpbmcgfCBCdWZmZXIgfCBvYmplY3QgfCBKV0suUmF3S2V5LFxuICAgIGZvcm0/OlxuICAgICAgfCAnanNvbidcbiAgICAgIHwgJ3ByaXZhdGUnXG4gICAgICB8ICdwa2NzOCdcbiAgICAgIHwgJ3B1YmxpYydcbiAgICAgIHwgJ3Nwa2knXG4gICAgICB8ICdwa2l4J1xuICAgICAgfCAneDUwOSdcbiAgICAgIHwgJ3BlbScsXG4gICAgZXh0cmFzPzogUmVjb3JkPHN0cmluZywgdW5rbm93bj5cbiAgKTogUHJvbWlzZTxKV0suS2V5PiB7XG4gICAgLy8gPEFaPiBVc2luZyBhIHNpbmdsZSBnbG9iYWwga2V5IHN0b3JlIGRpZCBub3Qgc2VlbSB0byBpbXByb3ZlIHNwZWVkLlxuICAgIC8vIHJldHVybiBLZXlGYWN0b3J5U2VydmljZS5rZXlTdG9yZS5hZGQoa2V5LCBmb3JtLCBleHRyYXMpO1xuICAgIHJldHVybiBKV0suYXNLZXkoa2V5LCBmb3JtLCBleHRyYXMpO1xuICB9XG5cbiAgcmFuZG9tU3RyaW5nKGRpZ2l0czogbnVtYmVyKTogc3RyaW5nIHtcbiAgICBpZiAoZGlnaXRzIDw9IDApIHtcbiAgICAgIHRocm93IG5ldyBMckJhZEFyZ3VtZW50RXhjZXB0aW9uKCdkaWdpdHMgPD0gMCcpO1xuICAgIH1cbiAgICBjb25zdCB2YWxpZENoYXJzID1cbiAgICAgICdBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OSc7XG4gICAgbGV0IGFycmF5ID0gbmV3IFVpbnQzMkFycmF5KGRpZ2l0cyk7XG4gICAgdGhpcy5jcnlwdG8uZ2V0UmFuZG9tVmFsdWVzKGFycmF5KTtcbiAgICBhcnJheSA9IGFycmF5Lm1hcCgoeCkgPT4gdmFsaWRDaGFycy5jaGFyQ29kZUF0KHggJSB2YWxpZENoYXJzLmxlbmd0aCkpO1xuICAgIHJldHVybiBTdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KG51bGwsIGFycmF5KTtcbiAgfVxuXG4gIHJhbmRvbURpZ2l0c05vWmVyb3MoZGlnaXRzOiBudW1iZXIpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLnJhbmRvbUNob2ljZXMoWzEsIDIsIDMsIDQsIDUsIDYsIDcsIDgsIDldLCBkaWdpdHMpLmpvaW4oJycpO1xuICB9XG5cbiAgcmFuZG9tQ2hvaWNlczxUPihhcnJheTogVFtdLCBjaG9vc2VOOiBudW1iZXIpOiBUW10ge1xuICAgIGlmIChhcnJheS5sZW5ndGggPD0gMSkge1xuICAgICAgdGhyb3cgbmV3IExyQmFkQXJndW1lbnRFeGNlcHRpb24oJ2FycmF5Lmxlbmd0aCA8PSAwJyk7XG4gICAgfVxuICAgIGlmIChjaG9vc2VOIDw9IDApIHtcbiAgICAgIHRocm93IG5ldyBMckJhZEFyZ3VtZW50RXhjZXB0aW9uKCdjaG9vc2VOIDw9IDAnKTtcbiAgICB9XG4gICAgY29uc3QgdmFsdWVzID0gbmV3IFVpbnQzMkFycmF5KGNob29zZU4pO1xuICAgIHRoaXMuY3J5cHRvLmdldFJhbmRvbVZhbHVlcyh2YWx1ZXMpO1xuICAgIGNvbnN0IHJldDogVFtdID0gW107XG4gICAgdmFsdWVzLmZvckVhY2goKHYpID0+IHJldC5wdXNoKGFycmF5W3YgJSBhcnJheS5sZW5ndGhdKSk7XG4gICAgcmV0dXJuIHJldDtcbiAgfVxuXG4gIGNyZWF0ZVNhbHQoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5yYW5kb21TdHJpbmcoMTYpO1xuICB9XG5cbiAgYXN5bmMgY3JlYXRlS2V5KCk6IFByb21pc2U8SldLLktleT4ge1xuICAgIGNvbnN0IGtleSA9IGF3YWl0IHRoaXMuY3J5cHRvLnN1YnRsZS5nZW5lcmF0ZUtleShcbiAgICAgIHtcbiAgICAgICAgbmFtZTogJ0FFUy1HQ00nLFxuICAgICAgICBsZW5ndGg6IDI1NiwgLy8gY2FuIGJlICAxMjgsIDE5Miwgb3IgMjU2XG4gICAgICB9LFxuICAgICAgdHJ1ZSwgLy8gd2hldGhlciB0aGUga2V5IGlzIGV4dHJhY3RhYmxlIChpLmUuIGNhbiBiZSB1c2VkIGluIGV4cG9ydEtleSlcbiAgICAgIFsnZW5jcnlwdCcsICdkZWNyeXB0J10gLy8gbXVzdCBiZSBbXCJlbmNyeXB0XCIsIFwiZGVjcnlwdFwiXSBvciBbXCJ3cmFwS2V5XCIsIFwidW53cmFwS2V5XCJdXG4gICAgKTtcblxuICAgIGNvbnN0IGp3ayA9IGF3YWl0IHRoaXMuY3J5cHRvLnN1YnRsZS5leHBvcnRLZXkoJ2p3aycsIGtleSk7XG5cbiAgICAvLyBSZW1vdmluZyB0aGUgZmllbGRzIG5vdCBuZWVkZWQgYnkgbm9kZS1qb3NlXG4gICAgZGVsZXRlIGp3ay5leHQ7XG4gICAgZGVsZXRlIGp3ay5rZXlfb3BzO1xuXG4gICAgcmV0dXJuIEtleUZhY3RvcnlTZXJ2aWNlLmFzS2V5KGp3ayk7XG4gIH1cblxuICBhc3luYyBjcmVhdGVTaWduS2V5KCk6IFByb21pc2U8SldLLktleT4ge1xuICAgIGNvbnN0IGtleSA9IGF3YWl0IHRoaXMuY3J5cHRvLnN1YnRsZS5nZW5lcmF0ZUtleShcbiAgICAgIHtcbiAgICAgICAgbmFtZTogJ0hNQUMnLFxuICAgICAgICBoYXNoOiB7IG5hbWU6ICdTSEEtNTEyJyB9LFxuICAgICAgfSxcbiAgICAgIHRydWUsXG4gICAgICBbJ3NpZ24nLCAndmVyaWZ5J11cbiAgICApO1xuXG4gICAgY29uc3QgandrID0gYXdhaXQgdGhpcy5jcnlwdG8uc3VidGxlLmV4cG9ydEtleSgnandrJywga2V5KTtcblxuICAgIC8vIFJlbW92aW5nIHRoZSBmaWVsZHMgbm90IG5lZWRlZCBieSBub2RlLWpvc2VcbiAgICBkZWxldGUgandrLmtleV9vcHM7XG4gICAgZGVsZXRlIGp3ay5leHQ7XG5cbiAgICByZXR1cm4gS2V5RmFjdG9yeVNlcnZpY2UuYXNLZXkoandrKTtcbiAgfVxuXG4gIGFzeW5jIGNyZWF0ZVBrY0tleSgpOiBQcm9taXNlPEpXSy5LZXk+IHtcbiAgICAvLyBub2RlLWpvc2UgaXMgbm90IHVzaW5nIEZvcmdlIHByb3Blcmx5LiBJdCBzaG91bGQgYmUgY2FsbGluZyB0aGUgYXN5bmMgdmVyc2lvbiBvZlxuICAgIC8vIHBraS5yc2EuZ2VuZXJhdGVLZXlQYWlyKCkgd2l0aCBhIGNhbGxiYWNrLiBJbnN0ZWFkIGl0IGNhbGxzIHRoZSBzeW5jIHZlcnNpb24uIFdlYmNyeXB0b1xuICAgIC8vIGRvZXMgbm90IHN1cHBvcnQgc3luYyB2ZXJzaW9uLCBzbyBpdCB1c2VzIHRoZSBqYXZhc2NyaXB0IGltcGxlbWVudGF0aW9uLCB3aGljaCBpcyB3YXkgdG9vIHNsb3cuXG4gICAgLy8gU28gd2UgZ2VuZXJhdGUgdXNpbmcgd2ViY3J5cHRvIGFuZCBpbXBvcnQgdGhlIGtleS5cbiAgICAvLyBVbmZvcnR1bmF0ZWx5IEVsbGlwdGljYWwgQ3VydmUgaXMgbm90IHN1cHBvcnRlZCBieSBXZWJjcnlwdG8uIFNvIHdlIGhhdmUgdG8gc2V0dGxlIGZvciBSU0EuXG4gICAgY29uc3Qga2V5ID0gYXdhaXQgdGhpcy5jcnlwdG8uc3VidGxlLmdlbmVyYXRlS2V5KFxuICAgICAge1xuICAgICAgICBuYW1lOiAnUlNBLU9BRVAnLFxuICAgICAgICBtb2R1bHVzTGVuZ3RoOiAyMDQ4LCAvLyBjYW4gYmUgMTAyNCwgMjA0OCwgMzA3MiwgNDA5NiAuLi4gMTYzODRcbiAgICAgICAgLy8gQXMgcGVyIHN1Z2dlc3Rpb246IGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9Sc2FIYXNoZWRLZXlHZW5QYXJhbXNcbiAgICAgICAgcHVibGljRXhwb25lbnQ6IG5ldyBVaW50OEFycmF5KFsweDAxLCAweDAwLCAweDAxXSksXG4gICAgICAgIGhhc2g6IHsgbmFtZTogJ1NIQS0yNTYnIH0sIC8vIGNhbiBiZSBcIlNIQS0xXCIsIFwiU0hBLTI1NlwiLCBcIlNIQS0zODRcIiwgb3IgXCJTSEEtNTEyXCJcbiAgICAgIH0sXG4gICAgICB0cnVlLCAvLyB3aGV0aGVyIHRoZSBrZXkgaXMgZXh0cmFjdGFibGUgKGkuZS4gY2FuIGJlIHVzZWQgaW4gZXhwb3J0S2V5KVxuICAgICAgWydlbmNyeXB0JywgJ2RlY3J5cHQnXSAvLyBtdXN0IGJlIFtcImVuY3J5cHRcIiwgXCJkZWNyeXB0XCJdIG9yIFtcIndyYXBLZXlcIiwgXCJ1bndyYXBLZXlcIl1cbiAgICApO1xuXG4gICAgY29uc3QgandrID0gYXdhaXQgdGhpcy5jcnlwdG8uc3VidGxlLmV4cG9ydEtleSgnandrJywga2V5LnByaXZhdGVLZXkpO1xuICAgIC8vIFJlbW92aW5nIHRoZSBmaWVsZHMgbm90IG5lZWRlZCBieSBub2RlLWpvc2VcbiAgICBkZWxldGUgandrLmtleV9vcHM7XG4gICAgZGVsZXRlIGp3ay5leHQ7XG5cbiAgICByZXR1cm4gS2V5RmFjdG9yeVNlcnZpY2UuYXNLZXkoandrKTtcbiAgfVxuXG4gIGFzeW5jIGNyZWF0ZVBrY1NpZ25LZXkoKTogUHJvbWlzZTxKV0suS2V5PiB7XG4gICAgY29uc3Qga2V5ID0gYXdhaXQgdGhpcy5jcnlwdG8uc3VidGxlLmdlbmVyYXRlS2V5KFxuICAgICAge1xuICAgICAgICBuYW1lOiAnUlNBU1NBLVBLQ1MxLXYxXzUnLFxuICAgICAgICBtb2R1bHVzTGVuZ3RoOiAyMDQ4LCAvLyBjYW4gYmUgMTAyNCwgMjA0OCwgb3IgNDA5NlxuICAgICAgICAvLyBBcyBwZXIgc3VnZ2VzdGlvbjogaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL1JzYUhhc2hlZEtleUdlblBhcmFtc1xuICAgICAgICBwdWJsaWNFeHBvbmVudDogbmV3IFVpbnQ4QXJyYXkoWzB4MDEsIDB4MDAsIDB4MDFdKSxcbiAgICAgICAgaGFzaDogeyBuYW1lOiAnU0hBLTI1NicgfSwgLy8gY2FuIGJlIFwiU0hBLTFcIiwgXCJTSEEtMjU2XCIsIFwiU0hBLTM4NFwiLCBvciBcIlNIQS01MTJcIlxuICAgICAgfSxcbiAgICAgIHRydWUsIC8vIHdoZXRoZXIgdGhlIGtleSBpcyBleHRyYWN0YWJsZSAoaS5lLiBjYW4gYmUgdXNlZCBpbiBleHBvcnRLZXkpXG4gICAgICBbJ3NpZ24nLCAndmVyaWZ5J10gLy8gY2FuIGJlIGFueSBjb21iaW5hdGlvbiBvZiBcInNpZ25cIiBhbmQgXCJ2ZXJpZnlcIlxuICAgICk7XG5cbiAgICBjb25zdCBqd2sgPSBhd2FpdCB0aGlzLmNyeXB0by5zdWJ0bGUuZXhwb3J0S2V5KCdqd2snLCBrZXkucHJpdmF0ZUtleSk7XG5cbiAgICAvLyBSZW1vdmluZyB0aGUgZmllbGRzIG5vdCBuZWVkZWQgYnkgbm9kZS1qb3NlXG4gICAgZGVsZXRlIGp3ay5rZXlfb3BzO1xuICAgIGRlbGV0ZSBqd2suZXh0O1xuXG4gICAgcmV0dXJuIEtleUZhY3RvcnlTZXJ2aWNlLmFzS2V5KGp3ayk7XG4gIH1cblxuICBhc3luYyBkZXJpdmVLZXkoe1xuICAgIHBhc3N3b3JkLFxuICAgIHNhbHQsXG4gICAgaXRlcmF0aW9ucyxcbiAgICBraWQsXG4gIH06IHtcbiAgICBwYXNzd29yZDogc3RyaW5nO1xuICAgIHNhbHQ6IHN0cmluZztcbiAgICBpdGVyYXRpb25zOiBudW1iZXI7XG4gICAga2lkPzogc3RyaW5nO1xuICB9KTogUHJvbWlzZTxEZXJpdmVLZXlSZXN1bHQ+IHtcbiAgICBjb25zdCBlbmMgPSBuZXcgVGV4dEVuY29kZXIoKTtcbiAgICBjb25zdCByYXdLZXkgPSBhd2FpdCB0aGlzLmNyeXB0by5zdWJ0bGUuaW1wb3J0S2V5KFxuICAgICAgJ3JhdycsXG4gICAgICBlbmMuZW5jb2RlKHBhc3N3b3JkKSxcbiAgICAgICdQQktERjInLFxuICAgICAgZmFsc2UsXG4gICAgICBbJ2Rlcml2ZUJpdHMnLCAnZGVyaXZlS2V5J11cbiAgICApO1xuXG4gICAgY29uc3QgcGFzc0tleSA9IGF3YWl0IGNyeXB0by5zdWJ0bGUuZGVyaXZlS2V5KFxuICAgICAge1xuICAgICAgICBuYW1lOiAnUEJLREYyJyxcbiAgICAgICAgc2FsdDogbmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKHNhbHQpLFxuICAgICAgICBpdGVyYXRpb25zLFxuICAgICAgICBoYXNoOiAnU0hBLTI1NicsXG4gICAgICB9LFxuICAgICAgcmF3S2V5LFxuICAgICAgeyBuYW1lOiAnQUVTLUdDTScsIGxlbmd0aDogMjU2IH0sXG4gICAgICB0cnVlLFxuICAgICAgWydlbmNyeXB0JywgJ2RlY3J5cHQnXVxuICAgICk7XG5cbiAgICBjb25zdCBwYXNzS2V5SnNvbjogYW55ID0gYXdhaXQgY3J5cHRvLnN1YnRsZS5leHBvcnRLZXkoJ2p3aycsIHBhc3NLZXkpO1xuICAgIGlmIChraWQpIHtcbiAgICAgIHBhc3NLZXlKc29uLmtpZCA9IGtpZDtcbiAgICB9XG5cbiAgICBjb25zdCBqd2sgPSBhd2FpdCBLZXlGYWN0b3J5U2VydmljZS5hc0tleShwYXNzS2V5SnNvbik7XG5cbiAgICByZXR1cm4geyBqd2sgfTtcbiAgfVxuXG4gIGFzeW5jIGRlcml2ZVBhc3NJZHAocGFyYW1zOiBEZXJpdmVQYXNzSWRwUGFyYW1zKTogUHJvbWlzZTxEZXJpdmVLZXlSZXN1bHQ+IHtcbiAgICBpZiAocGFyYW1zLml0ZXJhdGlvbnMgPCB0aGlzLk1JTl9QQVNTX0lEUF9QQktERl9JVEVSKSB7XG4gICAgICB0aHJvdyBuZXcgTHJTdXNwaWNpb3VzRXhjZXB0aW9uKFxuICAgICAgICBgVGhlIG51bWJlciBvZiBQYXNzSWRwIGtleSBkZXJpdmF0aW9uIGl0ZXJhdGlvbnMgc2VudCBmcm9tIHRoZSBzZXJ2ZXIgKCR7cGFyYW1zLml0ZXJhdGlvbnN9KSBpcyBsb3dlciB0aGFuIHRoZSBtaW5pbXVtICgke3RoaXMuTUlOX1BBU1NfSURQX1BCS0RGX0lURVJ9KWBcbiAgICAgICk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmRlcml2ZUtleShwYXJhbXMpO1xuICB9XG5cbiAgYXN5bmMgZGVyaXZlUGFzc0tleShwYXJhbXM6IERlcml2ZVBhc3NLZXlQYXJhbXMpOiBQcm9taXNlPERlcml2ZUtleVJlc3VsdD4ge1xuICAgIGlmIChwYXJhbXMuaXRlcmF0aW9ucyA8IHRoaXMuTUlOX1BBU1NfS0VZX1BCS0RGX0lURVIpIHtcbiAgICAgIHRocm93IG5ldyBMclN1c3BpY2lvdXNFeGNlcHRpb24oXG4gICAgICAgIGBUaGUgbnVtYmVyIG9mIFBhc3NLZXkga2V5IGRlcml2YXRpb24gaXRlcmF0aW9ucyBzZW50IGZyb20gdGhlIHNlcnZlcigke3BhcmFtcy5pdGVyYXRpb25zfSkgaXMgbG93ZXIgdGhhbiB0aGUgbWluaW11bSgke3RoaXMuTUlOX1BBU1NfS0VZX1BCS0RGX0lURVJ9KWBcbiAgICAgICk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmRlcml2ZUtleShwYXJhbXMpO1xuICB9XG5cbiAgYXN5bmMgZGVyaXZlTGJvcEtleShwYXJhbXM6IERlcml2ZUxib3BLZXlQYXJhbXMpOiBQcm9taXNlPERlcml2ZUtleVJlc3VsdD4ge1xuICAgIGlmIChwYXJhbXMuaXRlcmF0aW9ucyA8IHRoaXMuTUlOX0xCT1BfS0VZX1BCS0RGX0lURVIpIHtcbiAgICAgIHRocm93IG5ldyBMclN1c3BpY2lvdXNFeGNlcHRpb24oXG4gICAgICAgIGBUaGUgbnVtYmVyIG9mIExib3BLZXkga2V5IGRlcml2YXRpb24gaXRlcmF0aW9ucyBzZW50IGZyb20gdGhlIHNlcnZlcigke3BhcmFtcy5pdGVyYXRpb25zfSkgaXMgbG93ZXIgdGhhbiB0aGUgbWluaW11bSgke3RoaXMuTUlOX0xCT1BfS0VZX1BCS0RGX0lURVJ9KWBcbiAgICAgICk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmRlcml2ZUtleShwYXJhbXMpO1xuICB9XG5cbiAgYXN5bmMgY3JlYXRlS2lkKCk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgLy8gdG9kbzogQVo6IG5vZGUtam9zZSBzb3VyY2UgdXNlcyBub2RlJ3MgZGVmYXVsdCBVVUlEKCkgZnVuY3Rpb24gZm9yIGtpZCwgc28ganVzdCBjaGFuZ2UgdG8gdXNlIHRoYXQuXG4gICAgLy8gZm9yIG5vdywgd2UgYXJlIGp1c3QgY3JlYXRpbmcgYSBuZXcga2V5IHRvIHVzZSBpdCdzIGtpZC5cbiAgICAvLyBUaGUga2lkIGlzIGEgcGFydCBvZiB0aGUgSldLIHN5c3RlbS4gTFIgYmFja2VuZCBtYWludGFpbnMgdGhlIGtleSBoaWVyYXJjaHkgc2VwYXJhdGVseSB3aXRoIGl0J3Mgb3duXG4gICAgLy8ga2V5IGlkLiBCdXQgd2UganVzdCB1c2UgaXQgaGVyZSBhcyBhIGRvdWJsZSBjaGVjay5cbiAgICByZXR1cm4gKGF3YWl0IHRoaXMuY3JlYXRlS2V5KCkpLmtpZDtcbiAgfVxuXG4gIGFzeW5jIGNyZWF0ZVBhc3NJZHBQYXJhbXMoKTogUHJvbWlzZTxQYXNzSWRwUGFyYW1zPiB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHNhbHQ6IHRoaXMuY3JlYXRlU2FsdCgpLFxuICAgICAgaXRlcmF0aW9uczogdGhpcy5ERUZBVUxUX1BBU1NfSURQX1BCS0RGX0lURVIsXG4gICAgfTtcbiAgfVxuXG4gIGFzeW5jIGNyZWF0ZVBhc3NLZXlQYXJhbXMoKTogUHJvbWlzZTxQYXNzS2V5UGFyYW1zPiB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHNhbHQ6IHRoaXMuY3JlYXRlU2FsdCgpLFxuICAgICAga2lkOiBhd2FpdCB0aGlzLmNyZWF0ZUtpZCgpLFxuICAgICAgaXRlcmF0aW9uczogdGhpcy5ERUZBVUxUX1BBU1NfS0VZX1BCS0RGX0lURVIsXG4gICAgfTtcbiAgfVxuXG4gIGFzeW5jIGNyZWF0ZUxib3BLZXlQYXJhbXMoKTogUHJvbWlzZTxMYm9wS2V5UGFyYW1zPiB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHNhbHQ6IHRoaXMuY3JlYXRlU2FsdCgpLFxuICAgICAgLy8gdG9kbzogQVo6IG5vZGUtam9zZSBzb3VyY2UgdXNlcyBub2RlJ3MgZGVmYXVsdCBVVUlEKCkgZnVuY3Rpb24gZm9yIGtpZCwgc28ganVzdCBjaGFuZ2UgdG8gdXNlIHRoYXQuXG4gICAgICAvLyBmb3Igbm93LCB3ZSBhcmUganVzdCBjcmVhdGluZyBhIG5ldyBrZXkgdG8gdXNlIGl0J3Mga2lkLlxuICAgICAgLy8gVGhlIGtpZCBpcyBhIHBhcnQgb2YgdGhlIEpXSyBzeXN0ZW0uIExSIGJhY2tlbmQgbWFpbnRhaW5zIHRoZSBrZXkgaGllcmFyY2h5IHNlcGFyYXRlbHkgd2l0aCBpdCdzIG93blxuICAgICAgLy8ga2V5IGlkLiBCdXQgd2UganVzdCB1c2UgaXQgaGVyZSBhcyBhIGRvdWJsZSBjaGVjay5cbiAgICAgIGtpZDogYXdhaXQgdGhpcy5jcmVhdGVLaWQoKSxcbiAgICAgIGl0ZXJhdGlvbnM6IHRoaXMuREVGQVVMVF9QQVNTX0tFWV9QQktERl9JVEVSLFxuICAgIH07XG4gIH1cbn1cbiJdfQ==