@icure/api 6.4.0 → 7.0.0-beta.1

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 (154) hide show
  1. package/icc-api/api/IccDeviceApi.d.ts +1 -1
  2. package/icc-api/api/IccDeviceApi.js.map +1 -1
  3. package/icc-api/api/IccDoctemplateApi.js.map +1 -1
  4. package/icc-api/api/IccDocumentTemplateApi.js.map +1 -1
  5. package/icc-api/api/IccHcpartyApi.d.ts +1 -1
  6. package/icc-api/api/IccHcpartyApi.js.map +1 -1
  7. package/icc-api/api/IccPatientApi.d.ts +1 -1
  8. package/icc-api/api/IccPatientApi.js.map +1 -1
  9. package/icc-api/model/MaintenanceTask.d.ts +6 -5
  10. package/icc-api/model/MaintenanceTask.js +5 -0
  11. package/icc-api/model/MaintenanceTask.js.map +1 -1
  12. package/icc-api/model/User.d.ts +23 -1
  13. package/icc-api/model/User.js +21 -0
  14. package/icc-api/model/User.js.map +1 -1
  15. package/icc-api/model/models.d.ts +14 -0
  16. package/icc-api/model/models.js.map +1 -1
  17. package/icc-x-api/crypto/AES.d.ts +2 -0
  18. package/icc-x-api/crypto/AES.js +12 -0
  19. package/icc-x-api/crypto/AES.js.map +1 -1
  20. package/icc-x-api/crypto/BaseExchangeKeysManager.d.ts +122 -0
  21. package/icc-x-api/crypto/BaseExchangeKeysManager.js +356 -0
  22. package/icc-x-api/crypto/BaseExchangeKeysManager.js.map +1 -0
  23. package/icc-x-api/crypto/ConfidentialEntities.d.ts +58 -0
  24. package/icc-x-api/crypto/ConfidentialEntities.js +99 -0
  25. package/icc-x-api/crypto/ConfidentialEntities.js.map +1 -0
  26. package/icc-x-api/crypto/CryptoPrimitives.d.ts +31 -0
  27. package/icc-x-api/crypto/CryptoPrimitives.js +55 -0
  28. package/icc-x-api/crypto/CryptoPrimitives.js.map +1 -0
  29. package/icc-x-api/crypto/CryptoStrategies.d.ts +82 -0
  30. package/icc-x-api/crypto/CryptoStrategies.js +3 -0
  31. package/icc-x-api/crypto/CryptoStrategies.js.map +1 -0
  32. package/icc-x-api/crypto/EntitiesEncryption.d.ts +254 -0
  33. package/icc-x-api/crypto/EntitiesEncryption.js +700 -0
  34. package/icc-x-api/crypto/EntitiesEncryption.js.map +1 -0
  35. package/icc-x-api/crypto/ExchangeKeysManager.d.ts +56 -0
  36. package/icc-x-api/crypto/ExchangeKeysManager.js +147 -0
  37. package/icc-x-api/crypto/ExchangeKeysManager.js.map +1 -0
  38. package/icc-x-api/crypto/KeyManager.d.ts +103 -0
  39. package/icc-x-api/crypto/KeyManager.js +288 -0
  40. package/icc-x-api/crypto/KeyManager.js.map +1 -0
  41. package/icc-x-api/crypto/KeyRecovery.d.ts +34 -0
  42. package/icc-x-api/crypto/KeyRecovery.js +253 -0
  43. package/icc-x-api/crypto/KeyRecovery.js.map +1 -0
  44. package/icc-x-api/crypto/LegacyCryptoStrategies.d.ts +28 -0
  45. package/icc-x-api/crypto/LegacyCryptoStrategies.js +22 -0
  46. package/icc-x-api/crypto/LegacyCryptoStrategies.js.map +1 -0
  47. package/icc-x-api/crypto/RSA.d.ts +19 -20
  48. package/icc-x-api/crypto/RSA.js +30 -1
  49. package/icc-x-api/crypto/RSA.js.map +1 -1
  50. package/icc-x-api/crypto/ShamirKeysManager.d.ts +43 -0
  51. package/icc-x-api/crypto/ShamirKeysManager.js +150 -0
  52. package/icc-x-api/crypto/ShamirKeysManager.js.map +1 -0
  53. package/icc-x-api/crypto/ShareMetadataBehaviour.d.ts +19 -0
  54. package/icc-x-api/crypto/ShareMetadataBehaviour.js +24 -0
  55. package/icc-x-api/crypto/ShareMetadataBehaviour.js.map +1 -0
  56. package/icc-x-api/crypto/TransferKeysManager.d.ts +29 -0
  57. package/icc-x-api/crypto/TransferKeysManager.js +121 -0
  58. package/icc-x-api/crypto/TransferKeysManager.js.map +1 -0
  59. package/icc-x-api/crypto/utils.d.ts +46 -0
  60. package/icc-x-api/crypto/utils.js +128 -0
  61. package/icc-x-api/crypto/utils.js.map +1 -1
  62. package/icc-x-api/filters/ContactByHcPartyTagCodeDateFilter.d.ts +11 -0
  63. package/icc-x-api/filters/ContactByHcPartyTagCodeDateFilter.js +11 -0
  64. package/icc-x-api/filters/ContactByHcPartyTagCodeDateFilter.js.map +1 -1
  65. package/icc-x-api/filters/DeviceByHcPartyFilter.d.ts +11 -0
  66. package/icc-x-api/filters/DeviceByHcPartyFilter.js +11 -0
  67. package/icc-x-api/filters/DeviceByHcPartyFilter.js.map +1 -1
  68. package/icc-x-api/filters/DeviceByIdsFilter.d.ts +11 -0
  69. package/icc-x-api/filters/DeviceByIdsFilter.js +11 -0
  70. package/icc-x-api/filters/DeviceByIdsFilter.js.map +1 -1
  71. package/icc-x-api/filters/HealthElementByHcPartySecretForeignKeysFilter.d.ts +11 -0
  72. package/icc-x-api/filters/HealthElementByHcPartySecretForeignKeysFilter.js +11 -0
  73. package/icc-x-api/filters/HealthElementByHcPartySecretForeignKeysFilter.js.map +1 -1
  74. package/icc-x-api/icc-accesslog-x-api.d.ts +49 -4
  75. package/icc-x-api/icc-accesslog-x-api.js +112 -102
  76. package/icc-x-api/icc-accesslog-x-api.js.map +1 -1
  77. package/icc-x-api/icc-calendar-item-x-api.d.ts +53 -5
  78. package/icc-x-api/icc-calendar-item-x-api.js +112 -100
  79. package/icc-x-api/icc-calendar-item-x-api.js.map +1 -1
  80. package/icc-x-api/icc-classification-x-api.d.ts +45 -2
  81. package/icc-x-api/icc-classification-x-api.js +89 -41
  82. package/icc-x-api/icc-classification-x-api.js.map +1 -1
  83. package/icc-x-api/icc-contact-x-api.d.ts +57 -19
  84. package/icc-x-api/icc-contact-x-api.js +149 -154
  85. package/icc-x-api/icc-contact-x-api.js.map +1 -1
  86. package/icc-x-api/icc-crypto-x-api.d.ts +266 -366
  87. package/icc-x-api/icc-crypto-x-api.js +416 -1327
  88. package/icc-x-api/icc-crypto-x-api.js.map +1 -1
  89. package/icc-x-api/icc-data-owner-x-api.d.ts +110 -11
  90. package/icc-x-api/icc-data-owner-x-api.js +188 -14
  91. package/icc-x-api/icc-data-owner-x-api.js.map +1 -1
  92. package/icc-x-api/icc-doctemplate-x-api.js +3 -3
  93. package/icc-x-api/icc-doctemplate-x-api.js.map +1 -1
  94. package/icc-x-api/icc-document-x-api.d.ts +76 -5
  95. package/icc-x-api/icc-document-x-api.js +137 -59
  96. package/icc-x-api/icc-document-x-api.js.map +1 -1
  97. package/icc-x-api/icc-form-x-api.d.ts +47 -7
  98. package/icc-x-api/icc-form-x-api.js +85 -86
  99. package/icc-x-api/icc-form-x-api.js.map +1 -1
  100. package/icc-x-api/icc-hcparty-x-api.d.ts +1 -1
  101. package/icc-x-api/icc-hcparty-x-api.js +1 -1
  102. package/icc-x-api/icc-hcparty-x-api.js.map +1 -1
  103. package/icc-x-api/icc-helement-x-api.d.ts +50 -3
  104. package/icc-x-api/icc-helement-x-api.js +101 -118
  105. package/icc-x-api/icc-helement-x-api.js.map +1 -1
  106. package/icc-x-api/icc-icure-maintenance-x-api.d.ts +31 -0
  107. package/icc-x-api/icc-icure-maintenance-x-api.js +124 -0
  108. package/icc-x-api/icc-icure-maintenance-x-api.js.map +1 -0
  109. package/icc-x-api/icc-invoice-x-api.d.ts +45 -5
  110. package/icc-x-api/icc-invoice-x-api.js +89 -64
  111. package/icc-x-api/icc-invoice-x-api.js.map +1 -1
  112. package/icc-x-api/icc-maintenance-task-x-api.d.ts +38 -6
  113. package/icc-x-api/icc-maintenance-task-x-api.js +73 -102
  114. package/icc-x-api/icc-maintenance-task-x-api.js.map +1 -1
  115. package/icc-x-api/icc-message-x-api.d.ts +55 -2
  116. package/icc-x-api/icc-message-x-api.js +92 -33
  117. package/icc-x-api/icc-message-x-api.js.map +1 -1
  118. package/icc-x-api/icc-patient-x-api.d.ts +67 -7
  119. package/icc-x-api/icc-patient-x-api.js +409 -473
  120. package/icc-x-api/icc-patient-x-api.js.map +1 -1
  121. package/icc-x-api/icc-receipt-x-api.d.ts +49 -5
  122. package/icc-x-api/icc-receipt-x-api.js +85 -47
  123. package/icc-x-api/icc-receipt-x-api.js.map +1 -1
  124. package/icc-x-api/icc-time-table-x-api.d.ts +34 -10
  125. package/icc-x-api/icc-time-table-x-api.js +61 -18
  126. package/icc-x-api/icc-time-table-x-api.js.map +1 -1
  127. package/icc-x-api/index.d.ts +30 -1
  128. package/icc-x-api/index.js +112 -49
  129. package/icc-x-api/index.js.map +1 -1
  130. package/icc-x-api/maintenance/KeyPairUpdateRequest.d.ts +35 -0
  131. package/icc-x-api/maintenance/KeyPairUpdateRequest.js +54 -0
  132. package/icc-x-api/maintenance/KeyPairUpdateRequest.js.map +1 -0
  133. package/icc-x-api/storage/DefaultStorageEntryKeysFactory.d.ts +9 -0
  134. package/icc-x-api/storage/DefaultStorageEntryKeysFactory.js +23 -0
  135. package/icc-x-api/storage/DefaultStorageEntryKeysFactory.js.map +1 -0
  136. package/icc-x-api/storage/IcureStorageFacade.d.ts +55 -0
  137. package/icc-x-api/storage/IcureStorageFacade.js +95 -0
  138. package/icc-x-api/storage/IcureStorageFacade.js.map +1 -0
  139. package/icc-x-api/storage/StorageEntryKeysFactory.d.ts +31 -0
  140. package/icc-x-api/storage/StorageEntryKeysFactory.js +3 -0
  141. package/icc-x-api/storage/StorageEntryKeysFactory.js.map +1 -0
  142. package/icc-x-api/utils/collection-utils.d.ts +8 -0
  143. package/icc-x-api/utils/collection-utils.js +26 -0
  144. package/icc-x-api/utils/collection-utils.js.map +1 -0
  145. package/icc-x-api/utils/crypto-utils.d.ts +8 -1
  146. package/icc-x-api/utils/crypto-utils.js +19 -3
  147. package/icc-x-api/utils/crypto-utils.js.map +1 -1
  148. package/icc-x-api/utils/graph-utils.d.ts +45 -0
  149. package/icc-x-api/utils/graph-utils.js +203 -0
  150. package/icc-x-api/utils/graph-utils.js.map +1 -0
  151. package/icc-x-api/utils/lru-temporised-async-cache.d.ts +27 -0
  152. package/icc-x-api/utils/lru-temporised-async-cache.js +120 -0
  153. package/icc-x-api/utils/lru-temporised-async-cache.js.map +1 -0
  154. package/package.json +1 -1
@@ -0,0 +1,253 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.KeyRecovery = void 0;
13
+ const utils_1 = require("../utils");
14
+ const utils_2 = require("./utils");
15
+ /**
16
+ * @internal this class is intended only for internal use and may be changed without notice.
17
+ *
18
+ */
19
+ class KeyRecovery {
20
+ constructor(primitives, baseExchangeKeysManager, dataOwnerApi) {
21
+ this.primitives = primitives;
22
+ this.baseExchangeKeysManager = baseExchangeKeysManager;
23
+ this.dataOwnerApi = dataOwnerApi;
24
+ }
25
+ /**
26
+ * Attempt to recover private keys of a data owner using all available key recovery methods and all available private keys. The method will
27
+ * automatically try to use newly recovered key pairs to recover additional key pairs.
28
+ * @param dataOwner a data owner.
29
+ * @param knownKeys keys available for the data owner.
30
+ * @return new key pairs (exclude already known pairs) which could be recovered using the known keys.
31
+ */
32
+ recoverKeys(dataOwner, knownKeys) {
33
+ return __awaiter(this, void 0, void 0, function* () {
34
+ const selfPublicKeys = Array.from(this.dataOwnerApi.getHexPublicKeysOf(dataOwner.dataOwner));
35
+ const knownKeysFpSet = new Set(Object.keys(knownKeys));
36
+ const missingKeysFpSet = new Set(selfPublicKeys.map((x) => x.slice(-32)).filter((x) => !knownKeysFpSet.has(x)));
37
+ const recoveryFunctions = [this.recoverFromTransferKeys.bind(this), this.recoverFromShamirSplitKeys.bind(this)];
38
+ let allPrivateKeys = Object.assign({}, knownKeys);
39
+ let foundNewPrivateKeys = true;
40
+ while (missingKeysFpSet.size > 0 && foundNewPrivateKeys) {
41
+ // TODO for each recovered verify correct association with public key
42
+ foundNewPrivateKeys = false;
43
+ for (const recover of recoveryFunctions) {
44
+ const recovered = yield recover(dataOwner, allPrivateKeys, missingKeysFpSet);
45
+ const validatedRecovered = {};
46
+ for (const [fp, keyPair] of Object.entries(recovered)) {
47
+ const valid = yield this.primitives.RSA.checkKeyPairValidity(keyPair);
48
+ if (valid) {
49
+ validatedRecovered[fp] = keyPair;
50
+ }
51
+ }
52
+ if (Object.keys(validatedRecovered).length > 0) {
53
+ foundNewPrivateKeys = true;
54
+ Object.keys(validatedRecovered).forEach((fp) => missingKeysFpSet.delete(fp));
55
+ allPrivateKeys = Object.assign(Object.assign({}, allPrivateKeys), validatedRecovered);
56
+ }
57
+ }
58
+ }
59
+ return Object.fromEntries(Object.entries(allPrivateKeys).filter(([keyFp]) => !knownKeysFpSet.has(keyFp)));
60
+ });
61
+ }
62
+ /*TODO?
63
+ * Ask access back suggestion: if by getting access back to an exchange key with another data owner I may recover additional keys we could suggest
64
+ * to ask for access back to that data owner.
65
+ */
66
+ recoverFromShamirSplitKeys(dataOwner, allKeys, missingKeysFp) {
67
+ return __awaiter(this, void 0, void 0, function* () {
68
+ if (dataOwner.dataOwner.publicKey &&
69
+ dataOwner.dataOwner.privateKeyShamirPartitions &&
70
+ Object.keys(dataOwner.dataOwner.privateKeyShamirPartitions).length > 0) {
71
+ const selfId = dataOwner.dataOwner.id;
72
+ const shamirSplits = {
73
+ [dataOwner.dataOwner.publicKey.slice(-32)]: dataOwner.dataOwner.privateKeyShamirPartitions,
74
+ };
75
+ const delegatesOfSplits = Array.from(new Set(Object.entries(shamirSplits).flatMap(([splitKeyFp, splitKeyData]) => (missingKeysFp.has(splitKeyFp) ? Object.keys(splitKeyData) : []))));
76
+ const exchangeKeys = {};
77
+ for (const delegate of delegatesOfSplits) {
78
+ const currExchangeKeys = yield this.baseExchangeKeysManager.getEncryptedExchangeKeysFor(selfId, delegate);
79
+ exchangeKeys[delegate] = (yield this.baseExchangeKeysManager.tryDecryptExchangeKeys(currExchangeKeys, allKeys)).successfulDecryptions;
80
+ }
81
+ return yield this.recoverWithSplits(dataOwner, shamirSplits, exchangeKeys);
82
+ }
83
+ else
84
+ return {};
85
+ });
86
+ }
87
+ recoverWithSplits(dataOwner, splits, exchangeKeys) {
88
+ return __awaiter(this, void 0, void 0, function* () {
89
+ const res = {};
90
+ const keysByFp = (0, utils_2.fingerprintToPublicKeysMapOf)(dataOwner.dataOwner);
91
+ for (const [fp, split] of Object.entries(splits)) {
92
+ const recovered = yield this.tryRecoverSplitPrivate(split, exchangeKeys);
93
+ if (recovered) {
94
+ const pub = keysByFp[fp];
95
+ if (!pub) {
96
+ console.warn(`Missing public key for fingerprint ${fp} of recovered shamir key.`);
97
+ }
98
+ else {
99
+ try {
100
+ res[fp] = {
101
+ privateKey: recovered,
102
+ publicKey: yield this.primitives.RSA.importKey('spki', (0, utils_1.hex2ua)(pub), ['encrypt']),
103
+ };
104
+ }
105
+ catch (e) {
106
+ console.warn(`Failed to import public key ${pub}`, e);
107
+ }
108
+ }
109
+ }
110
+ }
111
+ return res;
112
+ });
113
+ }
114
+ tryRecoverSplitPrivate(split, exchangeKeys) {
115
+ var _a;
116
+ return __awaiter(this, void 0, void 0, function* () {
117
+ const splitsCount = Object.keys(split).length;
118
+ if (splitsCount === 1) {
119
+ // Not sure about the key nor if the key is accessible
120
+ const [delegate, encryptedKey] = Object.entries(split)[0];
121
+ for (const exchangeKey of (_a = exchangeKeys[delegate]) !== null && _a !== void 0 ? _a : []) {
122
+ try {
123
+ const decrypted = yield this.primitives.AES.decrypt(exchangeKey, (0, utils_1.hex2ua)(encryptedKey));
124
+ const importedKey = yield this.primitives.RSA.importKey('pkcs8', decrypted, ['decrypt']);
125
+ if (importedKey)
126
+ return importedKey;
127
+ }
128
+ catch (e) { }
129
+ }
130
+ return undefined;
131
+ }
132
+ else {
133
+ const decryptedSplits = [];
134
+ for (const delegateAndEncryptedSplit of Object.entries(split)) {
135
+ const decrypted = yield this.tryDecryptSplitPiece(delegateAndEncryptedSplit, exchangeKeys, splitsCount);
136
+ if (decrypted)
137
+ decryptedSplits.push((0, utils_1.ua2hex)(decrypted).slice(1)); // Drop padding
138
+ }
139
+ try {
140
+ const combinedKey = (0, utils_1.hex2ua)(this.primitives.shamir.combine(decryptedSplits));
141
+ return yield this.primitives.RSA.importKey('pkcs8', combinedKey, ['decrypt']);
142
+ }
143
+ catch (e) {
144
+ // Could be not enough splits decrypted
145
+ return undefined;
146
+ }
147
+ }
148
+ });
149
+ }
150
+ tryDecryptSplitPiece(delegateAndEncryptedSplit, exchangeKeys, splitsCount) {
151
+ var _a;
152
+ return __awaiter(this, void 0, void 0, function* () {
153
+ const [delegate, encryptedPiece] = delegateAndEncryptedSplit;
154
+ for (const exchangeKey of (_a = exchangeKeys[delegate]) !== null && _a !== void 0 ? _a : []) {
155
+ try {
156
+ const decrypted = yield this.primitives.AES.decrypt(exchangeKey, (0, utils_1.hex2ua)(encryptedPiece));
157
+ if (this.validateDecryptedSplit(decrypted, splitsCount))
158
+ return decrypted;
159
+ }
160
+ catch (e) { }
161
+ }
162
+ return undefined;
163
+ });
164
+ }
165
+ validateDecryptedSplit(decryptedSplit, splitsCount) {
166
+ // Normally shamir split starts with 8 followed by the index of the split in hexadecimal.
167
+ // However, we pad with an extra 'f' at the beginning
168
+ const decryptedHex = (0, utils_1.ua2hex)(decryptedSplit);
169
+ if (decryptedHex[0] !== 'f' || decryptedHex[1] !== '8')
170
+ return false;
171
+ try {
172
+ const splitIndex = parseInt(decryptedHex.slice(2, 4), 16);
173
+ return splitIndex > 0 && splitIndex <= splitsCount;
174
+ }
175
+ catch (e) {
176
+ return false;
177
+ }
178
+ }
179
+ recoverFromTransferKeys(dataOwner, allKeys, missingKeysFp) {
180
+ var _a;
181
+ return __awaiter(this, void 0, void 0, function* () {
182
+ const publicKeyFingerprintToPublicKey = (0, utils_2.fingerprintToPublicKeysMapOf)(dataOwner.dataOwner);
183
+ const missingKeysTransferData = {};
184
+ Object.values((_a = dataOwner.dataOwner.transferKeys) !== null && _a !== void 0 ? _a : {}).forEach((transferKeysByEncryptor) => {
185
+ Object.entries(transferKeysByEncryptor).forEach(([transferToPublicKey, transferPrivateKeyEncrypted]) => {
186
+ const transferToPublicKeyFp = transferToPublicKey.slice(-32); // We are not sure if transfer public key will be a fp or not
187
+ if (missingKeysFp.has(transferToPublicKeyFp)) {
188
+ const existingEntryValue = missingKeysTransferData[transferToPublicKeyFp];
189
+ if (existingEntryValue) {
190
+ existingEntryValue.encryptedPrivateKey.add(transferPrivateKeyEncrypted);
191
+ }
192
+ else {
193
+ const fullPublicKey = publicKeyFingerprintToPublicKey[transferToPublicKeyFp];
194
+ if (fullPublicKey) {
195
+ missingKeysTransferData[transferToPublicKeyFp] = {
196
+ publicKey: fullPublicKey,
197
+ encryptedPrivateKey: new Set([transferPrivateKeyEncrypted]),
198
+ };
199
+ }
200
+ else {
201
+ console.warn('Invalid data owner: there is a transfer key for an unknown public key');
202
+ }
203
+ }
204
+ }
205
+ });
206
+ });
207
+ const { successfulDecryptions: availableExchangeKeys } = yield this.baseExchangeKeysManager.tryDecryptExchangeKeys(yield this.baseExchangeKeysManager.getEncryptedExchangeKeysFor(dataOwner.dataOwner.id, dataOwner.dataOwner.id), allKeys);
208
+ return Object.entries(missingKeysTransferData).reduce((acc, [recoverableKeyPubFp, transferData]) => __awaiter(this, void 0, void 0, function* () {
209
+ const awaitedAcc = yield acc;
210
+ const decryptedTransferData = yield this.tryDecryptTransferData(transferData, availableExchangeKeys);
211
+ if (decryptedTransferData != undefined) {
212
+ return Object.assign(Object.assign({}, awaitedAcc), { [recoverableKeyPubFp]: decryptedTransferData });
213
+ }
214
+ else
215
+ return awaitedAcc;
216
+ }), Promise.resolve({}));
217
+ });
218
+ }
219
+ tryDecryptTransferData(transferData, availableExchangeKeys) {
220
+ return __awaiter(this, void 0, void 0, function* () {
221
+ for (const encryptedTransferKey of transferData.encryptedPrivateKey) {
222
+ const decryptedTransferKey = yield this.tryDecryptTransferKey(encryptedTransferKey, availableExchangeKeys);
223
+ if (decryptedTransferKey != undefined)
224
+ return {
225
+ privateKey: decryptedTransferKey,
226
+ publicKey: yield this.primitives.RSA.importKey('spki', (0, utils_1.hex2ua)(transferData.publicKey), ['encrypt']),
227
+ };
228
+ }
229
+ return undefined;
230
+ });
231
+ }
232
+ // attempt to decrypt a transfer key in pkcs8 using any of the provided exchange keys
233
+ tryDecryptTransferKey(encryptedTransferKey, // in hex format
234
+ exchangeKeys) {
235
+ return __awaiter(this, void 0, void 0, function* () {
236
+ const encryptedKeyBytes = (0, utils_1.hex2ua)(encryptedTransferKey);
237
+ for (const exchangeKey of exchangeKeys) {
238
+ try {
239
+ const decryptedKeyData = yield this.primitives.AES.decrypt(exchangeKey, encryptedKeyBytes);
240
+ const importedPrivateKey = yield this.primitives.RSA.importPrivateKey('pkcs8', decryptedKeyData);
241
+ if (importedPrivateKey != undefined)
242
+ return importedPrivateKey;
243
+ }
244
+ catch (e) {
245
+ /* failure is a valid possibility: we don't know the correct key to use */
246
+ }
247
+ }
248
+ return undefined;
249
+ });
250
+ }
251
+ }
252
+ exports.KeyRecovery = KeyRecovery;
253
+ //# sourceMappingURL=KeyRecovery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"KeyRecovery.js","sourceRoot":"","sources":["../../../icc-x-api/crypto/KeyRecovery.ts"],"names":[],"mappings":"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","sourcesContent":["import { DataOwnerWithType, IccDataOwnerXApi } from '../icc-data-owner-x-api'\nimport { KeyPair } from './RSA'\nimport { CryptoPrimitives } from './CryptoPrimitives'\nimport { BaseExchangeKeysManager } from './BaseExchangeKeysManager'\nimport { hex2ua, ua2hex } from '../utils'\nimport { fingerprintToPublicKeysMapOf } from './utils'\n\n/**\n * @internal this class is intended only for internal use and may be changed without notice.\n *\n */\nexport class KeyRecovery {\n private readonly primitives: CryptoPrimitives\n private readonly baseExchangeKeysManager: BaseExchangeKeysManager\n private readonly dataOwnerApi: IccDataOwnerXApi\n\n constructor(primitives: CryptoPrimitives, baseExchangeKeysManager: BaseExchangeKeysManager, dataOwnerApi: IccDataOwnerXApi) {\n this.primitives = primitives\n this.baseExchangeKeysManager = baseExchangeKeysManager\n this.dataOwnerApi = dataOwnerApi\n }\n\n /**\n * Attempt to recover private keys of a data owner using all available key recovery methods and all available private keys. The method will\n * automatically try to use newly recovered key pairs to recover additional key pairs.\n * @param dataOwner a data owner.\n * @param knownKeys keys available for the data owner.\n * @return new key pairs (exclude already known pairs) which could be recovered using the known keys.\n */\n async recoverKeys(\n dataOwner: DataOwnerWithType,\n knownKeys: { [pubKeyFp: string]: KeyPair<CryptoKey> }\n ): Promise<{ [pubKeyFp: string]: KeyPair<CryptoKey> }> {\n const selfPublicKeys = Array.from(this.dataOwnerApi.getHexPublicKeysOf(dataOwner.dataOwner))\n const knownKeysFpSet = new Set(Object.keys(knownKeys))\n const missingKeysFpSet = new Set(selfPublicKeys.map((x) => x.slice(-32)).filter((x) => !knownKeysFpSet.has(x)))\n\n const recoveryFunctions = [this.recoverFromTransferKeys.bind(this), this.recoverFromShamirSplitKeys.bind(this)]\n let allPrivateKeys: { [pubKeyFingerprint: string]: KeyPair<CryptoKey> } = { ...knownKeys }\n let foundNewPrivateKeys = true\n\n while (missingKeysFpSet.size > 0 && foundNewPrivateKeys) {\n // TODO for each recovered verify correct association with public key\n foundNewPrivateKeys = false\n for (const recover of recoveryFunctions) {\n const recovered = await recover(dataOwner, allPrivateKeys, missingKeysFpSet)\n const validatedRecovered: { [fp: string]: KeyPair<CryptoKey> } = {}\n for (const [fp, keyPair] of Object.entries(recovered)) {\n const valid = await this.primitives.RSA.checkKeyPairValidity(keyPair)\n if (valid) {\n validatedRecovered[fp] = keyPair\n }\n }\n if (Object.keys(validatedRecovered).length > 0) {\n foundNewPrivateKeys = true\n Object.keys(validatedRecovered).forEach((fp) => missingKeysFpSet.delete(fp))\n allPrivateKeys = { ...allPrivateKeys, ...validatedRecovered }\n }\n }\n }\n\n return Object.fromEntries(Object.entries(allPrivateKeys).filter(([keyFp]) => !knownKeysFpSet.has(keyFp)))\n }\n\n /*TODO?\n * Ask access back suggestion: if by getting access back to an exchange key with another data owner I may recover additional keys we could suggest\n * to ask for access back to that data owner.\n */\n\n private async recoverFromShamirSplitKeys(\n dataOwner: DataOwnerWithType,\n allKeys: { [pubKeyFingerprint: string]: KeyPair<CryptoKey> },\n missingKeysFp: Set<string>\n ): Promise<{ [pubKeyFingerprint: string]: KeyPair<CryptoKey> }> {\n if (\n dataOwner.dataOwner.publicKey &&\n dataOwner.dataOwner.privateKeyShamirPartitions &&\n Object.keys(dataOwner.dataOwner.privateKeyShamirPartitions).length > 0\n ) {\n const selfId = dataOwner.dataOwner.id!\n const shamirSplits: { [keyPairFp: string]: { [delegateId: string]: string } } = {\n [dataOwner.dataOwner.publicKey!.slice(-32)]: dataOwner.dataOwner.privateKeyShamirPartitions!,\n }\n const delegatesOfSplits = Array.from(\n new Set(\n Object.entries(shamirSplits).flatMap(([splitKeyFp, splitKeyData]) => (missingKeysFp.has(splitKeyFp) ? Object.keys(splitKeyData) : []))\n )\n )\n const exchangeKeys: { [delegateId: string]: CryptoKey[] } = {}\n for (const delegate of delegatesOfSplits) {\n const currExchangeKeys = await this.baseExchangeKeysManager.getEncryptedExchangeKeysFor(selfId, delegate)\n exchangeKeys[delegate] = (await this.baseExchangeKeysManager.tryDecryptExchangeKeys(currExchangeKeys, allKeys)).successfulDecryptions\n }\n return await this.recoverWithSplits(dataOwner, shamirSplits, exchangeKeys)\n } else return {}\n }\n\n private async recoverWithSplits(\n dataOwner: DataOwnerWithType,\n splits: { [keyPairFp: string]: { [delegateId: string]: string } },\n exchangeKeys: { [delegateId: string]: CryptoKey[] }\n ): Promise<{ [pubKeyFingerprint: string]: KeyPair<CryptoKey> }> {\n const res: { [pubKeyFingerprint: string]: KeyPair<CryptoKey> } = {}\n const keysByFp = fingerprintToPublicKeysMapOf(dataOwner.dataOwner)\n for (const [fp, split] of Object.entries(splits)) {\n const recovered = await this.tryRecoverSplitPrivate(split, exchangeKeys)\n if (recovered) {\n const pub = keysByFp[fp]\n if (!pub) {\n console.warn(`Missing public key for fingerprint ${fp} of recovered shamir key.`)\n } else {\n try {\n res[fp] = {\n privateKey: recovered,\n publicKey: await this.primitives.RSA.importKey('spki', hex2ua(pub), ['encrypt']),\n }\n } catch (e) {\n console.warn(`Failed to import public key ${pub}`, e)\n }\n }\n }\n }\n return res\n }\n\n private async tryRecoverSplitPrivate(\n split: { [delegateId: string]: string },\n exchangeKeys: { [delegateId: string]: CryptoKey[] }\n ): Promise<CryptoKey | undefined> {\n const splitsCount = Object.keys(split).length\n if (splitsCount === 1) {\n // Not sure about the key nor if the key is accessible\n const [delegate, encryptedKey] = Object.entries(split)[0]\n for (const exchangeKey of exchangeKeys[delegate] ?? []) {\n try {\n const decrypted = await this.primitives.AES.decrypt(exchangeKey, hex2ua(encryptedKey))\n const importedKey = await this.primitives.RSA.importKey('pkcs8', decrypted, ['decrypt'])\n if (importedKey) return importedKey\n } catch (e) {}\n }\n return undefined\n } else {\n const decryptedSplits: string[] = []\n for (const delegateAndEncryptedSplit of Object.entries(split)) {\n const decrypted = await this.tryDecryptSplitPiece(delegateAndEncryptedSplit, exchangeKeys, splitsCount)\n if (decrypted) decryptedSplits.push(ua2hex(decrypted).slice(1)) // Drop padding\n }\n try {\n const combinedKey = hex2ua(this.primitives.shamir.combine(decryptedSplits))\n return await this.primitives.RSA.importKey('pkcs8', combinedKey, ['decrypt'])\n } catch (e) {\n // Could be not enough splits decrypted\n return undefined\n }\n }\n }\n\n private async tryDecryptSplitPiece(\n delegateAndEncryptedSplit: [string, string],\n exchangeKeys: { [delegateId: string]: CryptoKey[] },\n splitsCount: number\n ): Promise<ArrayBuffer | undefined> {\n const [delegate, encryptedPiece] = delegateAndEncryptedSplit\n for (const exchangeKey of exchangeKeys[delegate] ?? []) {\n try {\n const decrypted = await this.primitives.AES.decrypt(exchangeKey, hex2ua(encryptedPiece))\n if (this.validateDecryptedSplit(decrypted, splitsCount)) return decrypted\n } catch (e) {}\n }\n return undefined\n }\n\n private validateDecryptedSplit(decryptedSplit: ArrayBuffer, splitsCount: number): boolean {\n // Normally shamir split starts with 8 followed by the index of the split in hexadecimal.\n // However, we pad with an extra 'f' at the beginning\n const decryptedHex = ua2hex(decryptedSplit)\n if (decryptedHex[0] !== 'f' || decryptedHex[1] !== '8') return false\n try {\n const splitIndex = parseInt(decryptedHex.slice(2, 4), 16)\n return splitIndex > 0 && splitIndex <= splitsCount\n } catch (e) {\n return false\n }\n }\n\n private async recoverFromTransferKeys(\n dataOwner: DataOwnerWithType,\n allKeys: { [pubKeyFingerprint: string]: KeyPair<CryptoKey> },\n missingKeysFp: Set<string>\n ): Promise<{ [pubKeyFingerprint: string]: KeyPair<CryptoKey> }> {\n const publicKeyFingerprintToPublicKey = fingerprintToPublicKeysMapOf(dataOwner.dataOwner)\n const missingKeysTransferData: { [recoverableKeyPubFp: string]: { publicKey: string; encryptedPrivateKey: Set<string> } } = {}\n Object.values(dataOwner.dataOwner.transferKeys ?? {}).forEach((transferKeysByEncryptor) => {\n Object.entries(transferKeysByEncryptor).forEach(([transferToPublicKey, transferPrivateKeyEncrypted]) => {\n const transferToPublicKeyFp = transferToPublicKey.slice(-32) // We are not sure if transfer public key will be a fp or not\n if (missingKeysFp.has(transferToPublicKeyFp)) {\n const existingEntryValue = missingKeysTransferData[transferToPublicKeyFp]\n if (existingEntryValue) {\n existingEntryValue.encryptedPrivateKey.add(transferPrivateKeyEncrypted)\n } else {\n const fullPublicKey = publicKeyFingerprintToPublicKey[transferToPublicKeyFp]\n if (fullPublicKey) {\n missingKeysTransferData[transferToPublicKeyFp] = {\n publicKey: fullPublicKey,\n encryptedPrivateKey: new Set([transferPrivateKeyEncrypted]),\n }\n } else {\n console.warn('Invalid data owner: there is a transfer key for an unknown public key')\n }\n }\n }\n })\n })\n\n const { successfulDecryptions: availableExchangeKeys } = await this.baseExchangeKeysManager.tryDecryptExchangeKeys(\n await this.baseExchangeKeysManager.getEncryptedExchangeKeysFor(dataOwner.dataOwner.id!, dataOwner.dataOwner.id!),\n allKeys\n )\n\n return Object.entries(missingKeysTransferData).reduce(async (acc, [recoverableKeyPubFp, transferData]) => {\n const awaitedAcc = await acc\n const decryptedTransferData = await this.tryDecryptTransferData(transferData, availableExchangeKeys)\n if (decryptedTransferData != undefined) {\n return { ...awaitedAcc, [recoverableKeyPubFp]: decryptedTransferData }\n } else return awaitedAcc\n }, Promise.resolve({} as { [pubKeyFingerprint: string]: KeyPair<CryptoKey> }))\n }\n\n private async tryDecryptTransferData(\n transferData: { publicKey: string; encryptedPrivateKey: Set<string> },\n availableExchangeKeys: CryptoKey[]\n ): Promise<KeyPair<CryptoKey> | undefined> {\n for (const encryptedTransferKey of transferData.encryptedPrivateKey) {\n const decryptedTransferKey = await this.tryDecryptTransferKey(encryptedTransferKey, availableExchangeKeys)\n if (decryptedTransferKey != undefined)\n return {\n privateKey: decryptedTransferKey,\n publicKey: await this.primitives.RSA.importKey('spki', hex2ua(transferData.publicKey), ['encrypt']),\n }\n }\n return undefined\n }\n\n // attempt to decrypt a transfer key in pkcs8 using any of the provided exchange keys\n private async tryDecryptTransferKey(\n encryptedTransferKey: string, // in hex format\n exchangeKeys: CryptoKey[]\n ): Promise<CryptoKey | undefined> {\n const encryptedKeyBytes = hex2ua(encryptedTransferKey)\n for (const exchangeKey of exchangeKeys) {\n try {\n const decryptedKeyData = await this.primitives.AES.decrypt(exchangeKey, encryptedKeyBytes)\n const importedPrivateKey = await this.primitives.RSA.importPrivateKey('pkcs8', decryptedKeyData)\n if (importedPrivateKey != undefined) return importedPrivateKey\n } catch (e) {\n /* failure is a valid possibility: we don't know the correct key to use */\n }\n }\n return undefined\n }\n}\n"]}
@@ -0,0 +1,28 @@
1
+ import { CryptoStrategies } from './CryptoStrategies';
2
+ import { DataOwner } from '../icc-data-owner-x-api';
3
+ import { CryptoPrimitives } from './CryptoPrimitives';
4
+ import { KeyPair } from './RSA';
5
+ /**
6
+ * Implementation of crypto strategies which should closely resemble a basic legacy behaviour of the crypto api:
7
+ * - Automatically creates a new key if there is no verified key available
8
+ * - Fully trusts the public keys coming from the server for the creation of aes exchange keys to delegates
9
+ * - Never trust the own public keys coming from the server: this way the sdk will not automatically create data for key recovery.
10
+ */
11
+ export declare class LegacyCryptoStrategies implements CryptoStrategies {
12
+ generateNewKeyForDataOwner(self: DataOwner, cryptoPrimitives: CryptoPrimitives): Promise<KeyPair<CryptoKey> | boolean>;
13
+ recoverAndVerifySelfHierarchyKeys(keysData: {
14
+ dataOwner: DataOwner;
15
+ unknownKeys: string[];
16
+ unavailableKeys: string[];
17
+ }[], cryptoPrimitives: CryptoPrimitives): Promise<{
18
+ [p: string]: {
19
+ recoveredKeys: {
20
+ [p: string]: KeyPair<CryptoKey>;
21
+ };
22
+ keyAuthenticity: {
23
+ [p: string]: boolean;
24
+ };
25
+ };
26
+ }>;
27
+ verifyDelegatePublicKeys(delegate: DataOwner, publicKeys: string[], cryptoPrimitives: CryptoPrimitives): Promise<string[]>;
28
+ }
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.LegacyCryptoStrategies = void 0;
4
+ /**
5
+ * Implementation of crypto strategies which should closely resemble a basic legacy behaviour of the crypto api:
6
+ * - Automatically creates a new key if there is no verified key available
7
+ * - Fully trusts the public keys coming from the server for the creation of aes exchange keys to delegates
8
+ * - Never trust the own public keys coming from the server: this way the sdk will not automatically create data for key recovery.
9
+ */
10
+ class LegacyCryptoStrategies {
11
+ generateNewKeyForDataOwner(self, cryptoPrimitives) {
12
+ return Promise.resolve(true);
13
+ }
14
+ recoverAndVerifySelfHierarchyKeys(keysData, cryptoPrimitives) {
15
+ return Promise.resolve(Object.fromEntries(keysData.map(({ dataOwner }) => [dataOwner.id, { recoveredKeys: {}, keyAuthenticity: {} }])));
16
+ }
17
+ verifyDelegatePublicKeys(delegate, publicKeys, cryptoPrimitives) {
18
+ return Promise.resolve(publicKeys);
19
+ }
20
+ }
21
+ exports.LegacyCryptoStrategies = LegacyCryptoStrategies;
22
+ //# sourceMappingURL=LegacyCryptoStrategies.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LegacyCryptoStrategies.js","sourceRoot":"","sources":["../../../icc-x-api/crypto/LegacyCryptoStrategies.ts"],"names":[],"mappings":";;;AAKA;;;;;GAKG;AACH,MAAa,sBAAsB;IACjC,0BAA0B,CAAC,IAAe,EAAE,gBAAkC;QAC5E,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;IAC9B,CAAC;IAED,iCAAiC,CAC/B,QAAsF,EACtF,gBAAkC;QAElC,OAAO,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,aAAa,EAAE,EAAE,EAAE,eAAe,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAA;IACzI,CAAC;IAED,wBAAwB,CAAC,QAAmB,EAAE,UAAoB,EAAE,gBAAkC;QACpG,OAAO,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,CAAA;IACpC,CAAC;CACF;AAfD,wDAeC","sourcesContent":["import { CryptoStrategies } from './CryptoStrategies'\nimport { DataOwner } from '../icc-data-owner-x-api'\nimport { CryptoPrimitives } from './CryptoPrimitives'\nimport { KeyPair } from './RSA'\n\n/**\n * Implementation of crypto strategies which should closely resemble a basic legacy behaviour of the crypto api:\n * - Automatically creates a new key if there is no verified key available\n * - Fully trusts the public keys coming from the server for the creation of aes exchange keys to delegates\n * - Never trust the own public keys coming from the server: this way the sdk will not automatically create data for key recovery.\n */\nexport class LegacyCryptoStrategies implements CryptoStrategies {\n generateNewKeyForDataOwner(self: DataOwner, cryptoPrimitives: CryptoPrimitives): Promise<KeyPair<CryptoKey> | boolean> {\n return Promise.resolve(true)\n }\n\n recoverAndVerifySelfHierarchyKeys(\n keysData: { dataOwner: DataOwner; unknownKeys: string[]; unavailableKeys: string[] }[],\n cryptoPrimitives: CryptoPrimitives\n ): Promise<{ [p: string]: { recoveredKeys: { [p: string]: KeyPair<CryptoKey> }; keyAuthenticity: { [p: string]: boolean } } }> {\n return Promise.resolve(Object.fromEntries(keysData.map(({ dataOwner }) => [dataOwner.id, { recoveredKeys: {}, keyAuthenticity: {} }])))\n }\n\n verifyDelegatePublicKeys(delegate: DataOwner, publicKeys: string[], cryptoPrimitives: CryptoPrimitives): Promise<string[]> {\n return Promise.resolve(publicKeys)\n }\n}\n"]}
@@ -1,3 +1,10 @@
1
+ /**
2
+ * Represents an RSA KeyPair in a generic format.
3
+ */
4
+ export type KeyPair<T> = {
5
+ publicKey: T;
6
+ privateKey: T;
7
+ };
1
8
  export declare class RSAUtils {
2
9
  /********* RSA Config **********/
3
10
  rsaParams: any;
@@ -7,10 +14,10 @@ export declare class RSAUtils {
7
14
  /**
8
15
  * It returns CryptoKey promise, which doesn't hold the bytes of the key.
9
16
  * If bytes are needed, you must export the generated key.
10
- * R
17
+ *
11
18
  * @returns {Promise} will be {publicKey: CryptoKey, privateKey: CryptoKey}
12
19
  */
13
- generateKeyPair(): Promise<CryptoKeyPair>;
20
+ generateKeyPair(): Promise<KeyPair<CryptoKey>>;
14
21
  /**
15
22
  *
16
23
  * 'JWK': Json Web key (ref. http://tools.ietf.org/html/draft-ietf-jose-json-web-key-11)
@@ -22,20 +29,8 @@ export declare class RSAUtils {
22
29
  * @param pubKeyFormat will be 'spki' or 'jwk'
23
30
  * @returns {Promise} will the AES Key
24
31
  */
25
- exportKeys(keyPair: {
26
- publicKey: CryptoKey;
27
- privateKey: CryptoKey;
28
- }, privKeyFormat: 'jwk', pubKeyFormat: 'jwk'): Promise<{
29
- publicKey: JsonWebKey;
30
- privateKey: JsonWebKey;
31
- }>;
32
- exportKeys(keyPair: {
33
- publicKey: CryptoKey;
34
- privateKey: CryptoKey;
35
- }, privKeyFormat: 'pkcs8', pubKeyFormat: 'spki'): Promise<{
36
- publicKey: ArrayBuffer;
37
- privateKey: ArrayBuffer;
38
- }>;
32
+ exportKeys(keyPair: KeyPair<CryptoKey>, privKeyFormat: 'jwk', pubKeyFormat: 'jwk'): Promise<KeyPair<JsonWebKey>>;
33
+ exportKeys(keyPair: KeyPair<CryptoKey>, privKeyFormat: 'pkcs8', pubKeyFormat: 'spki'): Promise<KeyPair<ArrayBuffer>>;
39
34
  /**
40
35
  * Format:
41
36
  *
@@ -85,9 +80,13 @@ export declare class RSAUtils {
85
80
  * @param publicKeyData should be the key data based on the format.
86
81
  * @returns {Promise|*}
87
82
  */
88
- importKeyPair(privateKeyFormat: string, privateKeydata: JsonWebKey | ArrayBuffer, publicKeyFormat: string, publicKeyData: JsonWebKey | ArrayBuffer): Promise<{
89
- publicKey: CryptoKey;
90
- privateKey: CryptoKey;
91
- }>;
83
+ importKeyPair(privateKeyFormat: string, privateKeydata: JsonWebKey | ArrayBuffer, publicKeyFormat: string, publicKeyData: JsonWebKey | ArrayBuffer): Promise<KeyPair<CryptoKey>>;
84
+ /**
85
+ * Tries to encrypt then decrypt data using a keypair. If both operations succeed without throwing an error and the decrypted data matches the
86
+ * original data returns true, else false.
87
+ * @param keyPair a key pair.
88
+ * @return if the key pair could be successfully used to encrypt then decrypt data.
89
+ */
90
+ checkKeyPairValidity(keyPair: KeyPair<CryptoKey>): Promise<boolean>;
92
91
  }
93
92
  export declare const RSA: RSAUtils;
@@ -1,6 +1,16 @@
1
1
  "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
2
11
  Object.defineProperty(exports, "__esModule", { value: true });
3
12
  exports.RSA = exports.RSAUtils = void 0;
13
+ const utils_1 = require("../utils");
4
14
  class RSAUtils {
5
15
  constructor(crypto = typeof window !== 'undefined' ? window.crypto : typeof self !== 'undefined' ? self.crypto : {}) {
6
16
  /********* RSA Config **********/
@@ -19,7 +29,7 @@ class RSAUtils {
19
29
  /**
20
30
  * It returns CryptoKey promise, which doesn't hold the bytes of the key.
21
31
  * If bytes are needed, you must export the generated key.
22
- * R
32
+ *
23
33
  * @returns {Promise} will be {publicKey: CryptoKey, privateKey: CryptoKey}
24
34
  */
25
35
  generateKeyPair() {
@@ -108,6 +118,25 @@ class RSAUtils {
108
118
  };
109
119
  });
110
120
  }
121
+ /**
122
+ * Tries to encrypt then decrypt data using a keypair. If both operations succeed without throwing an error and the decrypted data matches the
123
+ * original data returns true, else false.
124
+ * @param keyPair a key pair.
125
+ * @return if the key pair could be successfully used to encrypt then decrypt data.
126
+ */
127
+ checkKeyPairValidity(keyPair) {
128
+ return __awaiter(this, void 0, void 0, function* () {
129
+ try {
130
+ const text = 'shibboleth';
131
+ const encryptedText = yield this.encrypt(keyPair.publicKey, (0, utils_1.utf8_2ua)(text));
132
+ const decryptedText = (0, utils_1.ua2utf8)(yield this.decrypt(keyPair.privateKey, new Uint8Array(encryptedText)));
133
+ return decryptedText === text;
134
+ }
135
+ catch (e) {
136
+ return false;
137
+ }
138
+ });
139
+ }
111
140
  }
112
141
  exports.RSAUtils = RSAUtils;
113
142
  exports.RSA = new RSAUtils();
@@ -1 +1 @@
1
- {"version":3,"file":"RSA.js","sourceRoot":"","sources":["../../../icc-x-api/crypto/RSA.ts"],"names":[],"mappings":"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","sourcesContent":["import { RsaPrivateKey } from 'crypto'\n\nexport class RSAUtils {\n /********* RSA Config **********/\n //TODO bigger modulus\n //TODO PSS for signing\n rsaParams: any = { name: 'RSA-OAEP' }\n // RSA params for 'import' and 'generate' function.\n rsaHashedParams: any = {\n name: 'RSA-OAEP',\n modulusLength: 2048,\n publicExponent: new Uint8Array([0x01, 0x00, 0x01]), // Equivalent to 65537 (Fermat F4), read http://en.wikipedia.org/wiki/65537_(number)\n hash: { name: 'sha-1' },\n }\n\n private crypto: Crypto\n\n constructor(crypto: Crypto = typeof window !== 'undefined' ? window.crypto : typeof self !== 'undefined' ? self.crypto : ({} as Crypto)) {\n this.crypto = crypto\n }\n\n /**\n * It returns CryptoKey promise, which doesn't hold the bytes of the key.\n * If bytes are needed, you must export the generated key.\n * R\n * @returns {Promise} will be {publicKey: CryptoKey, privateKey: CryptoKey}\n */\n generateKeyPair(): Promise<CryptoKeyPair> {\n const extractable = true\n const keyUsages: KeyUsage[] = ['decrypt', 'encrypt']\n\n return new Promise((resolve: (value: CryptoKeyPair) => any, reject) => {\n this.crypto.subtle.generateKey(this.rsaHashedParams, extractable, keyUsages).then(resolve, reject)\n })\n }\n\n /**\n *\n * 'JWK': Json Web key (ref. http://tools.ietf.org/html/draft-ietf-jose-json-web-key-11)\n * 'spki': for private key\n * 'pkcs8': for private Key\n *\n * @param keyPair is {publicKey: CryptoKey, privateKey: CryptoKey}\n * @param privKeyFormat will be 'pkcs8' or 'jwk'\n * @param pubKeyFormat will be 'spki' or 'jwk'\n * @returns {Promise} will the AES Key\n */\n exportKeys(\n keyPair: { publicKey: CryptoKey; privateKey: CryptoKey },\n privKeyFormat: 'jwk',\n pubKeyFormat: 'jwk'\n ): Promise<{ publicKey: JsonWebKey; privateKey: JsonWebKey }>\n exportKeys(\n keyPair: { publicKey: CryptoKey; privateKey: CryptoKey },\n privKeyFormat: 'pkcs8',\n pubKeyFormat: 'spki'\n ): Promise<{ publicKey: ArrayBuffer; privateKey: ArrayBuffer }>\n exportKeys(\n keyPair: { publicKey: CryptoKey; privateKey: CryptoKey },\n privKeyFormat: string,\n pubKeyFormat: string\n ): Promise<{ publicKey: JsonWebKey | ArrayBuffer; privateKey: JsonWebKey | ArrayBuffer }> {\n const pubPromise = this.crypto.subtle.exportKey(pubKeyFormat as any, keyPair.publicKey)\n const privPromise = this.crypto.subtle.exportKey(privKeyFormat as any, keyPair.privateKey)\n\n return Promise.all([pubPromise, privPromise]).then(function (results) {\n return {\n publicKey: results[0],\n privateKey: results[1],\n }\n })\n }\n\n /**\n * Format:\n *\n * 'JWK': Json Web key (ref. http://tools.ietf.org/html/draft-ietf-jose-json-web-key-11)\n * 'spki': for private key\n * 'pkcs8': for private Key\n *\n * @param cryptoKey public or private\n * @param format either 'jwk' or 'spki' or 'pkcs8'\n * @returns {Promise|*} will be RSA key (public or private)\n */\n exportKey(cryptoKey: CryptoKey, format: 'jwk'): Promise<JsonWebKey>\n exportKey(cryptoKey: CryptoKey, format: 'spki'): Promise<ArrayBuffer>\n exportKey(cryptoKey: CryptoKey, format: 'pkcs8'): Promise<ArrayBuffer>\n exportKey(cryptoKey: CryptoKey, format: string): Promise<JsonWebKey | ArrayBuffer> {\n return new Promise((resolve: (value: JsonWebKey | ArrayBuffer) => any, reject) => {\n this.crypto.subtle.exportKey(format as any, cryptoKey).then(resolve, reject)\n })\n }\n\n /**\n *\n * @param publicKey (CryptoKey)\n * @param plainData (Uint8Array)\n */\n encrypt(publicKey: CryptoKey, plainData: Uint8Array) {\n return new Promise((resolve: (value: ArrayBuffer) => any, reject) => {\n this.crypto.subtle.encrypt(this.rsaParams, publicKey, plainData.buffer ? plainData.buffer : plainData).then(resolve, reject) //Node prefers arrayBuffer\n })\n }\n\n /**\n *\n * @param privateKey (CryptoKey)\n * @param encryptedData (Uint8Array)\n */\n decrypt(privateKey: CryptoKey, encryptedData: Uint8Array): Promise<ArrayBuffer> {\n return new Promise((resolve: (value: ArrayBuffer) => any, reject) => {\n this.crypto.subtle.decrypt(this.rsaParams, privateKey, encryptedData).then(resolve, reject)\n })\n }\n\n /**\n *\n * @param format 'jwk', 'spki', or 'pkcs8'\n * @param keydata should be the key data based on the format.\n * @param keyUsages Array of usages. For example, ['encrypt'] for public key.\n * @returns {*}\n */\n importKey(format: string, keydata: JsonWebKey | ArrayBuffer, keyUsages: KeyUsage[]) {\n const extractable = true\n return new Promise((resolve: (value: CryptoKey) => any, reject) => {\n this.crypto.subtle.importKey(format as any, keydata as any, this.rsaHashedParams, extractable, keyUsages).then(resolve, reject)\n })\n }\n\n /**\n *\n * @param format 'jwk' or 'pkcs8'\n * @param keydata should be the key data based on the format.\n * @returns {*}\n */\n importPrivateKey(format: string, keydata: JsonWebKey | ArrayBuffer) {\n const extractable = true\n return new Promise((resolve: (value: CryptoKey) => any, reject) => {\n this.crypto.subtle.importKey(format as any, keydata as any, this.rsaHashedParams, extractable, ['decrypt']).then(resolve, reject)\n })\n }\n\n /**\n *\n * @param privateKeyFormat 'jwk' or 'pkcs8'\n * @param privateKeydata should be the key data based on the format.\n * @param publicKeyFormat 'jwk' or 'spki'\n * @param publicKeyData should be the key data based on the format.\n * @returns {Promise|*}\n */\n importKeyPair(\n privateKeyFormat: string,\n privateKeydata: JsonWebKey | ArrayBuffer,\n publicKeyFormat: string,\n publicKeyData: JsonWebKey | ArrayBuffer\n ) {\n const extractable = true\n const privPromise = this.crypto.subtle.importKey(privateKeyFormat as any, privateKeydata as any, this.rsaHashedParams, extractable, ['decrypt'])\n const pubPromise = this.crypto.subtle.importKey(publicKeyFormat as any, publicKeyData as any, this.rsaHashedParams, extractable, ['encrypt'])\n\n return Promise.all([pubPromise, privPromise]).then(function (results) {\n return {\n publicKey: results[0],\n privateKey: results[1],\n }\n })\n }\n}\n\nexport const RSA = new RSAUtils()\n"]}
1
+ {"version":3,"file":"RSA.js","sourceRoot":"","sources":["../../../icc-x-api/crypto/RSA.ts"],"names":[],"mappings":"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","sourcesContent":["import { ua2utf8, utf8_2ua } from '../utils'\n\n/**\n * Represents an RSA KeyPair in a generic format.\n */\nexport type KeyPair<T> = { publicKey: T; privateKey: T }\n\nexport class RSAUtils {\n /********* RSA Config **********/\n //TODO bigger modulus\n //TODO PSS for signing\n rsaParams: any = { name: 'RSA-OAEP' }\n // RSA params for 'import' and 'generate' function.\n rsaHashedParams: any = {\n name: 'RSA-OAEP',\n modulusLength: 2048,\n publicExponent: new Uint8Array([0x01, 0x00, 0x01]), // Equivalent to 65537 (Fermat F4), read http://en.wikipedia.org/wiki/65537_(number)\n hash: { name: 'sha-1' },\n }\n\n private crypto: Crypto\n\n constructor(crypto: Crypto = typeof window !== 'undefined' ? window.crypto : typeof self !== 'undefined' ? self.crypto : ({} as Crypto)) {\n this.crypto = crypto\n }\n\n /**\n * It returns CryptoKey promise, which doesn't hold the bytes of the key.\n * If bytes are needed, you must export the generated key.\n *\n * @returns {Promise} will be {publicKey: CryptoKey, privateKey: CryptoKey}\n */\n generateKeyPair(): Promise<KeyPair<CryptoKey>> {\n const extractable = true\n const keyUsages: KeyUsage[] = ['decrypt', 'encrypt']\n\n return new Promise<KeyPair<CryptoKey>>((resolve, reject) => {\n this.crypto.subtle.generateKey(this.rsaHashedParams, extractable, keyUsages).then(resolve, reject)\n })\n }\n\n /**\n *\n * 'JWK': Json Web key (ref. http://tools.ietf.org/html/draft-ietf-jose-json-web-key-11)\n * 'spki': for private key\n * 'pkcs8': for private Key\n *\n * @param keyPair is {publicKey: CryptoKey, privateKey: CryptoKey}\n * @param privKeyFormat will be 'pkcs8' or 'jwk'\n * @param pubKeyFormat will be 'spki' or 'jwk'\n * @returns {Promise} will the AES Key\n */\n exportKeys(keyPair: KeyPair<CryptoKey>, privKeyFormat: 'jwk', pubKeyFormat: 'jwk'): Promise<KeyPair<JsonWebKey>>\n exportKeys(keyPair: KeyPair<CryptoKey>, privKeyFormat: 'pkcs8', pubKeyFormat: 'spki'): Promise<KeyPair<ArrayBuffer>>\n exportKeys(keyPair: KeyPair<CryptoKey>, privKeyFormat: string, pubKeyFormat: string): Promise<KeyPair<JsonWebKey | ArrayBuffer>> {\n const pubPromise = this.crypto.subtle.exportKey(pubKeyFormat as any, keyPair.publicKey)\n const privPromise = this.crypto.subtle.exportKey(privKeyFormat as any, keyPair.privateKey)\n\n return Promise.all([pubPromise, privPromise]).then(function (results) {\n return {\n publicKey: results[0],\n privateKey: results[1],\n }\n })\n }\n\n /**\n * Format:\n *\n * 'JWK': Json Web key (ref. http://tools.ietf.org/html/draft-ietf-jose-json-web-key-11)\n * 'spki': for private key\n * 'pkcs8': for private Key\n *\n * @param cryptoKey public or private\n * @param format either 'jwk' or 'spki' or 'pkcs8'\n * @returns {Promise|*} will be RSA key (public or private)\n */\n exportKey(cryptoKey: CryptoKey, format: 'jwk'): Promise<JsonWebKey>\n exportKey(cryptoKey: CryptoKey, format: 'spki'): Promise<ArrayBuffer>\n exportKey(cryptoKey: CryptoKey, format: 'pkcs8'): Promise<ArrayBuffer>\n exportKey(cryptoKey: CryptoKey, format: string): Promise<JsonWebKey | ArrayBuffer> {\n return new Promise((resolve: (value: JsonWebKey | ArrayBuffer) => any, reject) => {\n this.crypto.subtle.exportKey(format as any, cryptoKey).then(resolve, reject)\n })\n }\n\n /**\n *\n * @param publicKey (CryptoKey)\n * @param plainData (Uint8Array)\n */\n encrypt(publicKey: CryptoKey, plainData: Uint8Array): Promise<ArrayBuffer> {\n return new Promise((resolve: (value: ArrayBuffer) => any, reject) => {\n this.crypto.subtle.encrypt(this.rsaParams, publicKey, plainData.buffer ? plainData.buffer : plainData).then(resolve, reject) //Node prefers arrayBuffer\n })\n }\n\n /**\n *\n * @param privateKey (CryptoKey)\n * @param encryptedData (Uint8Array)\n */\n decrypt(privateKey: CryptoKey, encryptedData: Uint8Array): Promise<ArrayBuffer> {\n return new Promise((resolve: (value: ArrayBuffer) => any, reject) => {\n this.crypto.subtle.decrypt(this.rsaParams, privateKey, encryptedData).then(resolve, reject)\n })\n }\n\n /**\n *\n * @param format 'jwk', 'spki', or 'pkcs8'\n * @param keydata should be the key data based on the format.\n * @param keyUsages Array of usages. For example, ['encrypt'] for public key.\n * @returns {*}\n */\n importKey(format: string, keydata: JsonWebKey | ArrayBuffer, keyUsages: KeyUsage[]): Promise<CryptoKey> {\n const extractable = true\n return new Promise((resolve: (value: CryptoKey) => any, reject) => {\n this.crypto.subtle.importKey(format as any, keydata as any, this.rsaHashedParams, extractable, keyUsages).then(resolve, reject)\n })\n }\n\n /**\n *\n * @param format 'jwk' or 'pkcs8'\n * @param keydata should be the key data based on the format.\n * @returns {*}\n */\n importPrivateKey(format: string, keydata: JsonWebKey | ArrayBuffer): Promise<CryptoKey> {\n const extractable = true\n return new Promise((resolve: (value: CryptoKey) => any, reject) => {\n this.crypto.subtle.importKey(format as any, keydata as any, this.rsaHashedParams, extractable, ['decrypt']).then(resolve, reject)\n })\n }\n\n /**\n *\n * @param privateKeyFormat 'jwk' or 'pkcs8'\n * @param privateKeydata should be the key data based on the format.\n * @param publicKeyFormat 'jwk' or 'spki'\n * @param publicKeyData should be the key data based on the format.\n * @returns {Promise|*}\n */\n importKeyPair(\n privateKeyFormat: string,\n privateKeydata: JsonWebKey | ArrayBuffer,\n publicKeyFormat: string,\n publicKeyData: JsonWebKey | ArrayBuffer\n ): Promise<KeyPair<CryptoKey>> {\n const extractable = true\n const privPromise = this.crypto.subtle.importKey(privateKeyFormat as any, privateKeydata as any, this.rsaHashedParams, extractable, ['decrypt'])\n const pubPromise = this.crypto.subtle.importKey(publicKeyFormat as any, publicKeyData as any, this.rsaHashedParams, extractable, ['encrypt'])\n\n return Promise.all([pubPromise, privPromise]).then(function (results) {\n return {\n publicKey: results[0],\n privateKey: results[1],\n }\n })\n }\n\n /**\n * Tries to encrypt then decrypt data using a keypair. If both operations succeed without throwing an error and the decrypted data matches the\n * original data returns true, else false.\n * @param keyPair a key pair.\n * @return if the key pair could be successfully used to encrypt then decrypt data.\n */\n async checkKeyPairValidity(keyPair: KeyPair<CryptoKey>): Promise<boolean> {\n try {\n const text = 'shibboleth'\n const encryptedText = await this.encrypt(keyPair.publicKey, utf8_2ua(text))\n const decryptedText = ua2utf8(await this.decrypt(keyPair.privateKey, new Uint8Array(encryptedText)))\n return decryptedText === text\n } catch (e) {\n return false\n }\n }\n}\n\nexport const RSA = new RSAUtils()\n"]}
@@ -0,0 +1,43 @@
1
+ import { DataOwner, DataOwnerWithType, IccDataOwnerXApi } from '../icc-data-owner-x-api';
2
+ import { KeyManager } from './KeyManager';
3
+ import { ExchangeKeysManager } from './ExchangeKeysManager';
4
+ import { CryptoPrimitives } from './CryptoPrimitives';
5
+ /**
6
+ * Allows to create or update shamir split keys.
7
+ */
8
+ export declare class ShamirKeysManager {
9
+ private readonly primitives;
10
+ private readonly dataOwnerApi;
11
+ private readonly keyManager;
12
+ private readonly exchangeKeysManager;
13
+ constructor(primitives: CryptoPrimitives, dataOwnerApi: IccDataOwnerXApi, keyManager: KeyManager, exchangeKeysManager: ExchangeKeysManager);
14
+ /**
15
+ * Get information on existing private keys splits for the provided data owner. For each private key of the provided data owner which has been
16
+ * split using the Shamir sharing algorithm gives the list of the notaries (other data owners) which hold a copy of the key part.
17
+ * @param dataOwner a data owner
18
+ * @return the existing splits for the current data owner as a publicKeyFingerprint -> notariesIds object
19
+ */
20
+ getExistingSplitsInfo(dataOwner: DataOwner): {
21
+ [keyPairFingerprint: string]: string[];
22
+ };
23
+ /**
24
+ * Creates, updates or deletes shamir splits for keys of the current data owner. Any request to update the splits for a specific key will completely
25
+ * replace any existing data on that split (all previous notaries will be ignored).
26
+ * Note: currently you can only split the legacy key pair.
27
+ * @param keySplitsToUpdate the fingerprints of key pairs which will have updated/new splits and the details on how to create the updated splits.
28
+ * @param keySplitsToDelete the fingerprints or hex-encoded spki public keys which will not be shared anymore.
29
+ * @throws if the parameters refer to non-existing or unavailable keys, have split creation details, or if they request to delete a non-existing
30
+ * split.
31
+ */
32
+ updateSelfSplits(keySplitsToUpdate: {
33
+ [publicKeyHexOrFp: string]: {
34
+ notariesIds: string[];
35
+ minShares: number;
36
+ };
37
+ }, keySplitsToDelete: string[]): Promise<DataOwnerWithType>;
38
+ private validateShamirParams;
39
+ private deleteKeySplit;
40
+ private updateKeySplit;
41
+ private createPartitionsFor;
42
+ private encryptShares;
43
+ }