@icure/api 5.0.30 → 5.0.32

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.
@@ -4,6 +4,8 @@ import { RSAUtils } from './crypto/RSA';
4
4
  import { ShamirClass } from './crypto/shamir';
5
5
  import { Delegation, Device, Document, EncryptedEntity, EncryptedParentEntity, HealthcareParty, Patient, User } from '../icc-api/model/models';
6
6
  import { IccMaintenanceTaskXApi } from './icc-maintenance-task-x-api';
7
+ import { StorageFacade } from './storage/StorageFacade';
8
+ import { KeyStorageFacade } from './storage/KeyStorageFacade';
7
9
  interface DelegatorAndKeys {
8
10
  delegatorId: string;
9
11
  key: CryptoKey;
@@ -64,10 +66,12 @@ export declare class IccCryptoXApi {
64
66
  private readonly _AES;
65
67
  private readonly _RSA;
66
68
  private readonly _shamir;
69
+ private readonly _storage;
70
+ private readonly _keyStorage;
67
71
  constructor(host: string, headers: {
68
72
  [key: string]: string;
69
73
  }, hcpartyBaseApi: IccHcpartyApi, //Init with a hcparty x api for better performances
70
- patientBaseApi: IccPatientApi, deviceBaseApi: IccDeviceApi, crypto?: Crypto);
74
+ patientBaseApi: IccPatientApi, deviceBaseApi: IccDeviceApi, crypto?: Crypto, storage?: StorageFacade<string>, keyStorage?: KeyStorageFacade);
71
75
  loadAllKeysFromLocalStorage(dataOwnerId: string): Promise<void>;
72
76
  getCachedRsaKeyPairForFingerprint(dataOwnerId: string, pubKeyOrFingerprint: string): Promise<{
73
77
  publicKey: CryptoKey;
@@ -373,18 +377,9 @@ export declare class IccCryptoXApi {
373
377
  remote: boolean;
374
378
  local: boolean;
375
379
  }>;
376
- getKeychainInBrowserLocalStorageAsBase64(id: string): string | null;
377
- getKeychainValidityDateInBrowserLocalStorage(id: string): string | null;
380
+ getKeychainInBrowserLocalStorageAsBase64(id: string): string | undefined;
381
+ getKeychainValidityDateInBrowserLocalStorage(id: string): string | undefined;
378
382
  loadKeychainFromBrowserLocalStorage(id: string): Uint8Array[] | null;
379
- /**
380
- *
381
- * @param id
382
- * @param keyPair should be JWK
383
- */
384
- storeKeyPair(id: string, keyPair: {
385
- publicKey: any;
386
- privateKey: any;
387
- }): void;
388
383
  /**
389
384
  * loads the RSA key pair (hcparty) in JWK from local storage, not imported
390
385
  *
@@ -17,9 +17,11 @@ const _ = require("lodash");
17
17
  const models_1 = require("../icc-api/model/models");
18
18
  const binary_utils_1 = require("./utils/binary-utils");
19
19
  const utils_1 = require("./utils");
20
+ const LocalStorageImpl_1 = require("./storage/LocalStorageImpl");
21
+ const KeyStorageImpl_1 = require("./storage/KeyStorageImpl");
20
22
  class IccCryptoXApi {
21
23
  constructor(host, headers, hcpartyBaseApi, //Init with a hcparty x api for better performances
22
- patientBaseApi, deviceBaseApi, crypto = typeof window !== 'undefined' ? window.crypto : typeof self !== 'undefined' ? self.crypto : {}) {
24
+ patientBaseApi, deviceBaseApi, crypto = typeof window !== 'undefined' ? window.crypto : typeof self !== 'undefined' ? self.crypto : {}, storage, keyStorage) {
23
25
  this.hcPartyKeysCache = {};
24
26
  //[delegateId][delegatorId] = delegateEncryptedHcPartyKey
25
27
  //for each delegate, it stores the list of delegators and the corresponding delegateEncryptedHcPartyKey (shared HcPartyKey, from delegator to delegate, encrypted with the RSA key of the delegate)
@@ -40,6 +42,8 @@ class IccCryptoXApi {
40
42
  this._AES = new AES_1.AESUtils(crypto);
41
43
  this._RSA = new RSA_1.RSAUtils(crypto);
42
44
  this._shamir = new shamir_1.ShamirClass(crypto);
45
+ this._storage = storage || new LocalStorageImpl_1.LocalStorageImpl();
46
+ this._keyStorage = keyStorage || new KeyStorageImpl_1.KeyStorageImpl(this._storage);
43
47
  }
44
48
  get crypto() {
45
49
  return this._crypto;
@@ -181,7 +185,7 @@ class IccCryptoXApi {
181
185
  const importedPrivateKey = yield this._RSA.importKey('pkcs8', (0, binary_utils_1.hex2ua)(decryptedPrivatedKey), ['decrypt']);
182
186
  const importedPublicKey = yield this._RSA.importKey('spki', (0, binary_utils_1.hex2ua)(hcp.publicKey), ['encrypt']);
183
187
  const exportedKeyPair = yield this._RSA.exportKeys({ publicKey: importedPublicKey, privateKey: importedPrivateKey }, 'jwk', 'jwk');
184
- this.storeKeyPair(hcp.id, exportedKeyPair);
188
+ this._keyStorage.storeKeyPair(`${this.rsaLocalStoreIdPrefix}${hcp.id}`, exportedKeyPair);
185
189
  }
186
190
  catch (e) {
187
191
  console.log('Cannot decrypt shamir RSA key');
@@ -251,7 +255,7 @@ class IccCryptoXApi {
251
255
  const reason = `Cannot decrypt RSA encrypted AES HcPartyKey from ${delegatorId} to ${delegateHcPartyId} for pubKey ${fingerprint}: impossible to decrypt`;
252
256
  console.log(reason);
253
257
  }
254
- }), Promise.resolve());
258
+ }), Promise.resolve(undefined));
255
259
  const availablePublicKeys = publicKeys.filter((pk) => this.rsaKeyPairs[pk.slice(-32)]);
256
260
  if (!result) {
257
261
  //Try to find another key from the transfer keys
@@ -341,8 +345,7 @@ class IccCryptoXApi {
341
345
  */
342
346
  decryptAndImportAesHcPartyKeysForDelegators(delegatorsHcPartyIdsSet, delegateHcPartyId, minCacheDurationInSeconds = 60) {
343
347
  return __awaiter(this, void 0, void 0, function* () {
344
- const aesExchangeKeys = yield (this.hcPartyKeysRequestsCache[delegateHcPartyId] ||
345
- (this.hcPartyKeysRequestsCache[delegateHcPartyId] = this.getEncryptedAesExchangeKeysForDelegate(delegateHcPartyId))).then((delegatorIdsWithDelegateEncryptedHcPartyKeys) => __awaiter(this, void 0, void 0, function* () {
348
+ const aesExchangeKeys = yield this.getEncryptedAesExchangeKeysForDelegate(delegateHcPartyId).then((delegatorIdsWithDelegateEncryptedHcPartyKeys) => __awaiter(this, void 0, void 0, function* () {
346
349
  // [key: delegatorId] = delegateEncryptedHcPartyKey
347
350
  // For each delegatorId, obtain the AES key (decrypted HcParty Key) shared with the delegate, decrypted by the delegate
348
351
  return (yield Promise.all(delegatorsHcPartyIdsSet.map((delegatorId) => __awaiter(this, void 0, void 0, function* () {
@@ -472,7 +475,7 @@ class IccCryptoXApi {
472
475
  catch (e) {
473
476
  return undefined;
474
477
  }
475
- }), Promise.resolve());
478
+ }), Promise.resolve(undefined));
476
479
  if (!importedAESHcPartyKey) {
477
480
  throw new Error(`No hcParty key can be decrypted from ${delegatorId} to ${delegateHcPartyId} using currently available private keys`);
478
481
  }
@@ -827,7 +830,6 @@ class IccCryptoXApi {
827
830
  }
828
831
  const eckeysForAllDelegates = document.encryptionKeys;
829
832
  if (!eckeysForAllDelegates || !Object.keys(eckeysForAllDelegates).length) {
830
- //console.log(`There is no encryption key in document (${document.id})`)
831
833
  return Promise.resolve({ extractedKeys: [], hcpartyId: hcpartyId });
832
834
  }
833
835
  return this.extractKeysFromDelegationsForHcpHierarchy(hcpartyId, document.id, eckeysForAllDelegates);
@@ -912,7 +914,7 @@ class IccCryptoXApi {
912
914
  return { extractedKeys: extractedKeys.concat(parentExtractedKeys.extractedKeys), hcpartyId: (_a = parentExtractedKeys.hcpartyId) !== null && _a !== void 0 ? _a : dataOwnerId };
913
915
  })))
914
916
  .catch((e) => {
915
- console.error(`Dataowner with id ${dataOwnerId} cannot be resolved`);
917
+ console.error(`DataOwner with id ${dataOwnerId} cannot be resolved`);
916
918
  throw e;
917
919
  });
918
920
  }
@@ -930,20 +932,24 @@ class IccCryptoXApi {
930
932
  // Find other keys through aesExchangeKeys
931
933
  const dataOwnerPubKeys = yield this.getPublicKeys();
932
934
  const keysToDecrypt = (0, utils_1.fold)(Object.entries(dataOwner.aesExchangeKeys), {}, (acc, [pub, aesForPub]) => {
933
- Object.entries(aesForPub).forEach(([delegateId, aesKeys]) => {
934
- if (delegateId != dataOwner.id) {
935
- const aesAcc = {};
936
- Object.entries(aesKeys)
937
- .filter(([encrPubKey]) => dataOwnerPubKeys.some((pubKey) => pubKey.slice(-32) == encrPubKey))
938
- .forEach(([pubKeyFingerprint, aesEncr]) => {
939
- aesAcc[pubKeyFingerprint] = aesEncr;
940
- });
941
- if (acc[delegateId] == undefined) {
942
- acc[delegateId] = {};
935
+ if (dataOwnerPubKeys.find((pubKey) => pubKey.slice(-32) == pub.slice(-32)) == undefined) {
936
+ // We get AES Keys only from delegates of keys we don't currently have
937
+ // Otherwise, decrypted AES Keys would have previously worked
938
+ Object.entries(aesForPub).forEach(([delegateId, aesKeys]) => {
939
+ if (delegateId != dataOwner.id) {
940
+ const aesAcc = {};
941
+ Object.entries(aesKeys)
942
+ .filter(([encrPubKey]) => dataOwnerPubKeys.some((pubKey) => pubKey.slice(-32) == encrPubKey))
943
+ .forEach(([pubKeyFingerprint, aesEncr]) => {
944
+ aesAcc[pubKeyFingerprint] = aesEncr;
945
+ });
946
+ if (acc[delegateId] == undefined) {
947
+ acc[delegateId] = {};
948
+ }
949
+ acc[delegateId][pub] = aesAcc;
943
950
  }
944
- acc[delegateId][pub] = aesAcc;
945
- }
946
- });
951
+ });
952
+ }
947
953
  return acc;
948
954
  });
949
955
  const decryptedAndImportedAesHcPartyKeys = yield (0, utils_1.foldAsync)(Object.entries(keysToDecrypt), [], (delKeysAcc, [delegateId, keysForDelegate]) => __awaiter(this, void 0, void 0, function* () {
@@ -1010,10 +1016,9 @@ class IccCryptoXApi {
1010
1016
  }
1011
1017
  catch (err) {
1012
1018
  console.log(`Could not decrypt generic delegation in object with ID: ${masterId} from ${genericDelegationItem.owner} to ${genericDelegationItem.delegatedTo}: ${err}`);
1013
- console.log(`AES key is: ${aesKey.rawKey}. Encrypted data is ${genericDelegationItem.key}.`);
1014
1019
  return undefined;
1015
1020
  }
1016
- }), Promise.resolve());
1021
+ }), Promise.resolve(undefined));
1017
1022
  }
1018
1023
  else {
1019
1024
  console.log(`Could not find aes key for object with ID: ${masterId}`);
@@ -1046,7 +1051,7 @@ class IccCryptoXApi {
1046
1051
  const keyPair = yield this._RSA.importKeyPair('jwk', privateKeyInJwk, 'jwk', (0, utils_1.spkiToJwk)((0, binary_utils_1.hex2ua)(publicKey)));
1047
1052
  this.rsaKeyPairs[publicKey.slice(-32)] = keyPair;
1048
1053
  const exportedKeyPair = yield this._RSA.exportKeys(keyPair, 'jwk', 'jwk');
1049
- return this.storeKeyPair(`${healthcarePartyId}.${publicKey.slice(-32)}`, exportedKeyPair);
1054
+ return this._keyStorage.storeKeyPair(`${this.rsaLocalStoreIdPrefix}${healthcarePartyId}.${publicKey.slice(-32)}`, exportedKeyPair);
1050
1055
  });
1051
1056
  }
1052
1057
  loadKeyPairsAsJwkInBrowserLocalStorage(healthcarePartyId, privateKey) {
@@ -1063,7 +1068,7 @@ class IccCryptoXApi {
1063
1068
  const keyPair = yield this._RSA.importKeyPair('jwk', privateKey, 'jwk', (0, utils_1.spkiToJwk)((0, binary_utils_1.hex2ua)(publicKey)));
1064
1069
  this.rsaKeyPairs[publicKey.slice(-32)] = keyPair;
1065
1070
  const exportedKeyPair = yield this._RSA.exportKeys(keyPair, 'jwk', 'jwk');
1066
- return this.storeKeyPair(`${healthcarePartyId}.${publicKey.slice(-32)}`, exportedKeyPair);
1071
+ return this._keyStorage.storeKeyPair(`${this.rsaLocalStoreIdPrefix}${healthcarePartyId}.${publicKey.slice(-32)}`, exportedKeyPair);
1067
1072
  });
1068
1073
  }
1069
1074
  // noinspection JSUnusedGlobalSymbols
@@ -1084,20 +1089,20 @@ class IccCryptoXApi {
1084
1089
  }
1085
1090
  // noinspection JSUnusedGlobalSymbols
1086
1091
  saveKeychainInBrowserLocalStorage(id, keychain) {
1087
- localStorage.setItem(this.keychainLocalStoreIdPrefix + id, (0, binary_utils_1.b2a)(new Uint8Array(keychain).reduce((data, byte) => data + String.fromCharCode(byte), '')));
1092
+ this._storage.setItem(this.keychainLocalStoreIdPrefix + id, (0, binary_utils_1.b2a)(new Uint8Array(keychain).reduce((data, byte) => data + String.fromCharCode(byte), '')));
1088
1093
  }
1089
1094
  saveKeychainInBrowserLocalStorageAsBase64(id, keyChainB64) {
1090
- localStorage.setItem(this.keychainLocalStoreIdPrefix + id, keyChainB64);
1095
+ this._storage.setItem(this.keychainLocalStoreIdPrefix + id, keyChainB64);
1091
1096
  }
1092
1097
  // noinspection JSUnusedGlobalSymbols
1093
1098
  saveKeychainValidityDateInBrowserLocalStorage(id, date) {
1094
1099
  if (!id)
1095
1100
  return;
1096
1101
  if (!date) {
1097
- localStorage.removeItem(this.keychainValidityDateLocalStoreIdPrefix + id);
1102
+ this._storage.deleteItem(this.keychainValidityDateLocalStoreIdPrefix + id);
1098
1103
  }
1099
1104
  else {
1100
- localStorage.setItem(this.keychainValidityDateLocalStoreIdPrefix + id, date);
1105
+ this._storage.setItem(this.keychainValidityDateLocalStoreIdPrefix + id, date);
1101
1106
  }
1102
1107
  }
1103
1108
  /**
@@ -1203,28 +1208,15 @@ class IccCryptoXApi {
1203
1208
  });
1204
1209
  }
1205
1210
  getKeychainInBrowserLocalStorageAsBase64(id) {
1206
- return localStorage.getItem(this.keychainLocalStoreIdPrefix + id);
1211
+ return this._storage.getItem(this.keychainLocalStoreIdPrefix + id);
1207
1212
  }
1208
1213
  getKeychainValidityDateInBrowserLocalStorage(id) {
1209
- return localStorage.getItem(this.keychainValidityDateLocalStoreIdPrefix + id);
1214
+ return this._storage.getItem(this.keychainValidityDateLocalStoreIdPrefix + id);
1210
1215
  }
1211
1216
  // noinspection JSUnusedGlobalSymbols
1212
1217
  loadKeychainFromBrowserLocalStorage(id) {
1213
- const lsItem = localStorage.getItem('org.taktik.icure.ehealth.keychain.' + id);
1214
- return lsItem !== null ? (0, binary_utils_1.b64_2uas)(lsItem) : null;
1215
- }
1216
- /**
1217
- *
1218
- * @param id
1219
- * @param keyPair should be JWK
1220
- */
1221
- storeKeyPair(id, keyPair) {
1222
- if (typeof Storage === 'undefined') {
1223
- console.log('Your browser does not support HTML5 Browser Local Storage !');
1224
- throw 'Your browser does not support HTML5 Browser Local Storage !';
1225
- }
1226
- //TODO encryption
1227
- localStorage.setItem(this.rsaLocalStoreIdPrefix + id, JSON.stringify(keyPair));
1218
+ const lsItem = this._storage.getItem(this.keychainLocalStoreIdPrefix + id);
1219
+ return lsItem !== undefined ? (0, binary_utils_1.b64_2uas)(lsItem) : null;
1228
1220
  }
1229
1221
  /**
1230
1222
  * loads the RSA key pair (hcparty) in JWK from local storage, not imported
@@ -1240,11 +1232,13 @@ class IccCryptoXApi {
1240
1232
  throw 'Your browser does not support HTML5 Browser Local Storage !';
1241
1233
  }
1242
1234
  //TODO decryption
1243
- const item = (_a = (publicKeyFingerPrint && localStorage.getItem(this.rsaLocalStoreIdPrefix + id + '.' + publicKeyFingerPrint.slice(-32)))) !== null && _a !== void 0 ? _a : localStorage.getItem(this.rsaLocalStoreIdPrefix + id);
1235
+ const item = publicKeyFingerPrint
1236
+ ? (_a = this._keyStorage.getKeypair(this.rsaLocalStoreIdPrefix + id + '.' + publicKeyFingerPrint.slice(-32))) !== null && _a !== void 0 ? _a : this._keyStorage.getKeypair(this.rsaLocalStoreIdPrefix + id)
1237
+ : this._keyStorage.getKeypair(this.rsaLocalStoreIdPrefix + id);
1244
1238
  if (!item) {
1245
1239
  console.warn(`No key can be found in local storage for id ${id} and publicKeyFingerPrint ${publicKeyFingerPrint}`);
1246
1240
  }
1247
- return JSON.parse(item);
1241
+ return item;
1248
1242
  }
1249
1243
  /**
1250
1244
  * Loads and imports the RSA key pair (hcparty) from local storage
@@ -1255,24 +1249,23 @@ class IccCryptoXApi {
1255
1249
  loadKeyPairImported(id) {
1256
1250
  return new Promise((resolve, reject) => {
1257
1251
  try {
1258
- const jwkKey = localStorage.getItem(this.rsaLocalStoreIdPrefix + id);
1259
- if (jwkKey) {
1260
- const jwkKeyPair = JSON.parse(jwkKey);
1252
+ const jwkKeyPair = this._keyStorage.getKeypair(this.rsaLocalStoreIdPrefix + id);
1253
+ if (jwkKeyPair !== undefined) {
1261
1254
  if (jwkKeyPair.publicKey && jwkKeyPair.privateKey) {
1262
1255
  this._RSA.importKeyPair('jwk', jwkKeyPair.privateKey, 'jwk', jwkKeyPair.publicKey).then(resolve, (err) => {
1263
- console.log('Error in RSA.importKeyPair: ' + err);
1256
+ console.error('Error in RSA.importKeyPair: ' + err);
1264
1257
  reject(err);
1265
1258
  });
1266
1259
  }
1267
1260
  else {
1268
1261
  const message = 'Error in RSA.importKeyPair: Invalid key';
1269
- console.log(message);
1262
+ console.error(message);
1270
1263
  reject(Error(message));
1271
1264
  }
1272
1265
  }
1273
1266
  else {
1274
1267
  const message = 'Error in RSA.importKeyPair: Missing key';
1275
- console.log(message);
1268
+ console.error(message);
1276
1269
  reject(Error(message));
1277
1270
  }
1278
1271
  }
@@ -1375,9 +1368,11 @@ class IccCryptoXApi {
1375
1368
  const { type: ownerType, dataOwner: ownerToUpdate } = yield this.createOrUpdateAesExchangeKeysFor(cdo, gen, {
1376
1369
  pubKey: keypair.publicKey,
1377
1370
  privKey: keypair.privateKey,
1378
- }).then((dataOwnerWithUpdatedAesKeys) => generateTransferKey
1379
- ? this.createOrUpdateTransferKeysFor(dataOwnerWithUpdatedAesKeys, gen, { pubKey: keypair.publicKey, privKey: keypair.privateKey })
1380
- : dataOwnerWithUpdatedAesKeys);
1371
+ }).then((dataOwnerWithUpdatedAesKeys) => __awaiter(this, void 0, void 0, function* () {
1372
+ return generateTransferKey
1373
+ ? yield this.createOrUpdateTransferKeysFor(dataOwnerWithUpdatedAesKeys, gen, { pubKey: keypair.publicKey, privKey: keypair.privateKey })
1374
+ : dataOwnerWithUpdatedAesKeys;
1375
+ }));
1381
1376
  const modifiedDataOwnerAndType = yield this._saveDataOwner({ type: ownerType, dataOwner: ownerToUpdate });
1382
1377
  const sentMaintenanceTasks = sendMaintenanceTasks
1383
1378
  ? yield this.sendMaintenanceTasks(maintenanceTasksApi, user, modifiedDataOwnerAndType.dataOwner, keypair.publicKey)
@@ -1451,6 +1446,7 @@ class IccCryptoXApi {
1451
1446
  });
1452
1447
  }
1453
1448
  retrieveDataOwnerInfoAfterPotentialUpdate(dataOwnerToUpdate) {
1449
+ this.emptyHcpCache(dataOwnerToUpdate.id);
1454
1450
  return this.getDataOwner(dataOwnerToUpdate.id).then(({ type, dataOwner }) => {
1455
1451
  var _a, _b, _c, _d;
1456
1452
  return {
@@ -1486,16 +1482,16 @@ class IccCryptoXApi {
1486
1482
  });
1487
1483
  });
1488
1484
  });
1489
- const tasksForDelegator = (yield this._getDelegateIdsOf(dataOwner)).map((delegateId) => {
1485
+ const tasksForDelegator = (yield this._getDelegateIdsOf(dataOwner))
1486
+ .filter((delegateId) => delegateId != dataOwner.id)
1487
+ .map((delegateId) => {
1490
1488
  return { delegateId: delegateId, maintenanceTask: this.createMaintenanceTask(dataOwner, hexNewPubKey) };
1491
1489
  });
1492
- return Promise.all(tasksForDelegates
1493
- .concat(tasksForDelegator)
1494
- .map(({ delegateId, maintenanceTask }) => __awaiter(this, void 0, void 0, function* () {
1495
- const taskToCreate = yield (maintenanceTaskApi === null || maintenanceTaskApi === void 0 ? void 0 : maintenanceTaskApi.newInstance(user, maintenanceTask, [delegateId]));
1496
- return taskToCreate ? maintenanceTaskApi === null || maintenanceTaskApi === void 0 ? void 0 : maintenanceTaskApi.createMaintenanceTaskWithUser(user, taskToCreate) : undefined;
1497
- }))
1498
- .filter((createdTask) => createdTask != undefined));
1490
+ return yield tasksForDelegates.concat(tasksForDelegator).reduce((existingTasks, task) => __awaiter(this, void 0, void 0, function* () {
1491
+ const taskToCreate = yield (maintenanceTaskApi === null || maintenanceTaskApi === void 0 ? void 0 : maintenanceTaskApi.newInstance(user, task.maintenanceTask, [task.delegateId]));
1492
+ const createdTask = taskToCreate ? yield (maintenanceTaskApi === null || maintenanceTaskApi === void 0 ? void 0 : maintenanceTaskApi.createMaintenanceTaskWithUser(user, taskToCreate)) : undefined;
1493
+ return createdTask ? (yield existingTasks).concat(createdTask) : yield existingTasks;
1494
+ }), Promise.resolve([]));
1499
1495
  }
1500
1496
  else {
1501
1497
  return [];
@@ -1545,8 +1541,11 @@ class IccCryptoXApi {
1545
1541
  this.getDataOwner(ownerId),
1546
1542
  this.getDataOwner(delegateId),
1547
1543
  ]);
1548
- const ownerLegacyPublicKey = owner.publicKey;
1549
1544
  const availablePublicKeysFingerprints = Object.keys(this.rsaKeyPairs);
1545
+ const ownerLegacyPublicKey = owner.publicKey;
1546
+ const isOwnerLegacyPublicKeyAvailable = ownerLegacyPublicKey
1547
+ ? availablePublicKeysFingerprints.some((fp) => ownerLegacyPublicKey.endsWith(fp))
1548
+ : false;
1550
1549
  const availableOwnerPublicKeys = [
1551
1550
  ownerLegacyPublicKey,
1552
1551
  ...Object.keys(owner.aesExchangeKeys || {}).filter((x) => x !== ownerLegacyPublicKey),
@@ -1583,7 +1582,7 @@ class IccCryptoXApi {
1583
1582
  const encryptedAesKeys = yield allPubKeys.reduce((map, pubK) => __awaiter(this, void 0, void 0, function* () {
1584
1583
  return (Object.assign(Object.assign({}, (yield map)), { [pubK.slice(-32)]: (0, binary_utils_1.ua2hex)(yield this._RSA.encrypt(yield this._RSA.importKey('jwk', (0, utils_1.spkiToJwk)((0, binary_utils_1.hex2ua)(pubK)), ['encrypt']), (0, binary_utils_1.hex2ua)(AESKey))) }));
1585
1584
  }), Promise.resolve({}));
1586
- if (delegate.publicKey && ownerLegacyPublicKey) {
1585
+ if (delegate.publicKey && ownerLegacyPublicKey && isOwnerLegacyPublicKeyAvailable) {
1587
1586
  owner.hcPartyKeys[delegateId] = [encryptedAesKeys[ownerLegacyPublicKey.slice(-32)], encryptedAesKeys[delegate.publicKey.slice(-32)]];
1588
1587
  }
1589
1588
  owner.aesExchangeKeys = Object.assign(Object.assign({}, (ownerCombinedAesExchangeKeys !== null && ownerCombinedAesExchangeKeys !== void 0 ? ownerCombinedAesExchangeKeys : {})), { [selectedPublicKey]: Object.assign(Object.assign({}, ((_g = (_f = owner.aesExchangeKeys) === null || _f === void 0 ? void 0 : _f[selectedPublicKey]) !== null && _g !== void 0 ? _g : {})), { [delegateId]: encryptedAesKeys }) });