@icure/api 8.0.9 → 8.0.11

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.
@@ -409,7 +409,7 @@ class BaseExchangeDataManager {
409
409
  sharedSignatureKey: decryptedSharedSignatureKey,
410
410
  });
411
411
  for (const [fp, signature] of Object.entries(exchangeData.delegatorSignature)) {
412
- const verificationKey = yield getVerificationKey(fp.slice(-32));
412
+ const verificationKey = yield getVerificationKey(fp);
413
413
  if (verificationKey && (yield this.primitives.RSA.verifySignature(verificationKey, (0, utils_1.b64_2ua)(signature), delegatorSignatureData)))
414
414
  return true;
415
415
  }
@@ -1 +1 @@
1
- {"version":3,"file":"BaseExchangeDataManager.js","sourceRoot":"","sources":["../../../icc-x-api/crypto/BaseExchangeDataManager.ts"],"names":[],"mappings":"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","sourcesContent":["import { IccDataOwnerXApi } from '../icc-data-owner-x-api'\nimport { KeyPair } from './RSA'\nimport { ExchangeData } from '../../icc-api/model/internal/ExchangeData'\nimport { IccExchangeDataApi } from '../../icc-api/api/internal/IccExchangeDataApi'\nimport { XHR } from '../../icc-api/api/XHR'\nimport XHRError = XHR.XHRError\nimport { CryptoPrimitives } from './CryptoPrimitives'\nimport { b64_2ua, hex2ua, ua2b64, ua2hex, ua2utf8, utf8_2ua } from '../utils'\nimport * as _ from 'lodash'\nimport { fingerprintV1toV2, fingerprintIsV1 } from './utils'\n\n/**\n * @internal this class is intended for internal use only and may be modified without notice\n * Functions to create and get exchange data.\n * The methods of this api require to pass the appropriate keys for encryption/decryption manually.\n */\nexport class BaseExchangeDataManager {\n constructor(\n readonly api: IccExchangeDataApi,\n private readonly dataOwnerApi: IccDataOwnerXApi,\n private readonly primitives: CryptoPrimitives,\n private readonly selfRequiresAnonymousDelegations: boolean\n ) {}\n\n /**\n * Get all the exchange data where the current data owner is the delegator or the delegate. However, some data owners, generally HCPs, may have a\n * prohibitively high amount of exchange data. If the crypto strategies specify that the current data owner requires anonymous delegation this\n * method returns all the exchange data found for the data owner, else the method returns undefined.\n * @return all the exchange data for the current data owner or undefined if the crypto strategies don't allow to retrieve all data for the current\n * data owner.\n */\n async getAllExchangeDataForCurrentDataOwnerIfAllowed(): Promise<ExchangeData[] | undefined> {\n if (!this.selfRequiresAnonymousDelegations) return undefined\n const dataOwnerId = await this.dataOwnerApi.getCurrentDataOwnerId()\n let latestResult = await this.api.getExchangeDataByParticipant(dataOwnerId, undefined, 1000)\n const allRetrieved = latestResult.rows ?? []\n while (latestResult.nextKeyPair?.startKeyDocId) {\n latestResult = await this.api.getExchangeDataByParticipant(dataOwnerId, latestResult.nextKeyPair.startKeyDocId, 1000)\n if (latestResult.rows) allRetrieved.push(...latestResult.rows)\n }\n return allRetrieved\n }\n\n /**\n * Get all exchange data for the provided delegator-delegate pair.\n * @param delegatorId id of a delegator data owner.\n * @param delegateId id of a delegate data owner.\n * @return all exchange data for the provided delegator-delegate pair.\n */\n async getExchangeDataByDelegatorDelegatePair(delegatorId: string, delegateId: string): Promise<ExchangeData[]> {\n return await this.api.getExchangeDataByDelegatorDelegate(delegatorId, delegateId)\n }\n\n /**\n * Get the exchange data with the provided id.\n * @param exchangeDataId id of the exchange data.\n * @return the exchange data with the provided id or undefined if no exchange data with such id could be found.\n */\n async getExchangeDataById(exchangeDataId: string): Promise<ExchangeData | undefined> {\n return await this.api.getExchangeDataById(exchangeDataId).catch((e) => {\n if (e instanceof XHRError && e.statusCode === 404) {\n return undefined\n } else throw e\n })\n }\n\n /**\n * Verifies the authenticity of the exchange data by checking the signature.\n * Note that all exchange data created by data owners other than the current data owner (including members of his hierarchy)\n * will always be unverified.\n * @param data collects the following information about the exchange data being verified:\n * - exchangeData the exchange data to verify.\n * - decryptedAccessControlSecret the access control secret decrypted from the exchange data.\n * - decryptedExchangeKey the exchange key decrypted from the exchange data.\n * - decryptedSharedSignatureKey the shared signature key decrypted from the exchange data.\n * @param getVerificationKey function to retrieve keys to use for verification by fingerprint.\n * @param verifyAsDelegator if true the method will also verify that the hmac key used for the signature was created by the delegator of the\n * exchange data. If true and the data was not created by the current data owner this method will return false.\n * @return the exchange data which could be verified given his signature and the available verification keys.\n * @throws if any of the provided exchange data has been created by a data owner other than the current data owner.\n */\n async verifyExchangeData(\n data: {\n exchangeData: ExchangeData\n decryptedAccessControlSecret: string\n decryptedExchangeKey: CryptoKey\n decryptedSharedSignatureKey: CryptoKey\n },\n getVerificationKey: (publicKeyFingerprint: string) => Promise<CryptoKey | undefined>,\n verifyAsDelegator: boolean\n ): Promise<boolean> {\n if (verifyAsDelegator && data.exchangeData.delegator !== (await this.dataOwnerApi.getCurrentDataOwnerId())) return false\n if (verifyAsDelegator && !(await this.verifyDelegatorSignature(data.exchangeData, data.decryptedSharedSignatureKey, getVerificationKey)))\n return false\n const sharedSignatureData = await this.bytesToSignForSharedSignature({\n decryptedAccessControlSecret: data.decryptedAccessControlSecret,\n decryptedExchangeKey: data.decryptedExchangeKey,\n delegator: data.exchangeData.delegator,\n delegate: data.exchangeData.delegate,\n publicKeysFingerprintsV2: [\n ...new Set([\n ...Object.keys(data.exchangeData.exchangeKey),\n ...Object.keys(data.exchangeData.accessControlSecret),\n ...Object.keys(data.exchangeData.sharedSignatureKey),\n ]),\n ],\n })\n return await this.verifyDataWithSharedKey(sharedSignatureData, data.decryptedSharedSignatureKey, data.exchangeData.sharedSignature)\n }\n\n /**\n * Extracts and decrypts the access control secret from the provided exchange data.\n * These need to be hashed together with the entity class and confidentiality level in order to get the actual access control key\n * which will be sent to the server.\n * @param exchangeData the exchange data from which to extract access control secrets.\n * @param decryptionKeys rsa key pairs to use for decryption of the access control secret.\n * @return an object composed of:\n * - successfulDecryptions: array of all successfully decrypted access control keys\n * - failedDecryptions: array containing all exchange data for which the access control key could not be decrypted (using the provided keys).\n */\n async tryDecryptAccessControlSecret(\n exchangeData: ExchangeData[],\n decryptionKeys: { [publicKeyFingerprint: string]: KeyPair<CryptoKey> }\n ): Promise<{\n successfulDecryptions: string[]\n failedDecryptions: ExchangeData[]\n }> {\n return await this.tryDecryptExchangeData(\n exchangeData,\n decryptionKeys,\n (ed) => ed.accessControlSecret,\n (d) => this.importAccessControlSecret(new Uint8Array(d))\n )\n }\n\n /**\n * Extract and decrypts the exchange keys from the provided exchange data.\n * @param exchangeData the exchange data from which to extract exchange keys.\n * @param decryptionKeys rsa key pairs to use for the decryption of the exchange keys.\n * @return an object composed of:\n * - successfulDecryptions: array containing the successfully decrypted exchange keys.\n * - failedDecryptions: array containing all exchange data for which the access control key could not be decrypted (using the provided keys).\n */\n async tryDecryptExchangeKeys(\n exchangeData: ExchangeData[],\n decryptionKeys: { [publicKeyFingerprint: string]: KeyPair<CryptoKey> }\n ): Promise<{\n successfulDecryptions: CryptoKey[]\n failedDecryptions: ExchangeData[]\n }> {\n return await this.tryDecryptExchangeData(\n exchangeData,\n decryptionKeys,\n (ed) => ed.exchangeKey,\n (d) => this.importExchangeKey(new Uint8Array(d))\n )\n }\n\n /**\n * Extract and decrypts the shared signature key from the provided exchange data.\n * @param exchangeData the exchange data from which to extract exchange keys.\n * @param decryptionKeys rsa key pairs to use for the decryption of the exchange keys.\n * @return an object composed of:\n * - successfulDecryptions: array containing the successfully decrypted exchange keys.\n * - failedDecryptions: array containing all exchange data for which the access control key could not be decrypted (using the provided keys).\n */\n async tryDecryptSharedSignatureKeys(\n exchangeData: ExchangeData[],\n decryptionKeys: { [publicKeyFingerprint: string]: KeyPair<CryptoKey> }\n ): Promise<{\n successfulDecryptions: CryptoKey[]\n failedDecryptions: ExchangeData[]\n }> {\n return await this.tryDecryptExchangeData(\n exchangeData,\n decryptionKeys,\n (ed) => ed.sharedSignatureKey,\n (d) => this.importSharedSignatureKey(new Uint8Array(d))\n )\n }\n\n private async tryDecryptExchangeData<T>(\n exchangeData: ExchangeData[],\n decryptionKeys: { [publicKeyFingerprint: string]: KeyPair<CryptoKey> },\n encryptedDataSelector: (data: ExchangeData) => { [keyPairFingerprint: string]: string },\n unmarshalDecrypted: (decrypted: ArrayBuffer) => Promise<T>\n ): Promise<{\n successfulDecryptions: T[]\n failedDecryptions: ExchangeData[]\n }> {\n const successfulDecryptions: T[] = []\n const failedDecryptions: ExchangeData[] = []\n for (const ed of exchangeData) {\n try {\n const decrypted = await this.tryDecrypt(encryptedDataSelector(ed), decryptionKeys)\n if (decrypted) {\n successfulDecryptions.push(await unmarshalDecrypted(decrypted))\n } else {\n failedDecryptions.push(ed)\n }\n } catch (e) {\n failedDecryptions.push(ed)\n }\n }\n return { successfulDecryptions, failedDecryptions }\n }\n\n private async tryDecrypt(\n encryptedData: { [keyPairFingerprintV2: string]: string },\n decryptionKeys: { [publicKeyFingerprintV1: string]: KeyPair<CryptoKey> }\n ): Promise<ArrayBuffer | undefined> {\n const decryptionKeysWithV2Fp = Object.keys(decryptionKeys).reduce((prev, fp) => {\n return {\n ...prev,\n [fingerprintIsV1(fp) ? fingerprintV1toV2(fp) : fp]: decryptionKeys[fp],\n }\n }, {} as { [publicKeyFingerprint: string]: KeyPair<CryptoKey> })\n for (const [fp, encrypted] of Object.entries(encryptedData)) {\n try {\n const key = decryptionKeysWithV2Fp[fp]?.privateKey\n if (key) return await this.primitives.RSA.decrypt(key, b64_2ua(encrypted))\n } catch (e) {\n // Try with another key\n }\n }\n }\n\n /**\n * Creates exchange data from the current data owner to the provided delegate, uploading the newly created exchange data to the cloud.\n * This assumes that the keys have been verified.\n * @param delegateId id of the delegate for the new exchange data.\n * @param signatureKeys private keys to use for signing the created data.\n * @param encryptionKeys public keys to use for the encryption of the exchange data (from delegator and delegate).\n * @param optionalAttributes optional precalculated attributes for the creation of data\n * @return the newly created exchange data, and its decrypted exchange key and access control secret.\n */\n async createExchangeData(\n delegateId: string,\n signatureKeys: { [keyPairFingerprint: string]: CryptoKey },\n encryptionKeys: { [keyPairFingerprint: string]: CryptoKey },\n optionalAttributes: {\n id?: string\n } = {}\n ): Promise<{\n exchangeData: ExchangeData\n exchangeKey: CryptoKey\n accessControlSecret: string\n }> {\n if (!Object.keys(signatureKeys).length || !Object.keys(encryptionKeys).length) {\n throw new Error('Must specify at least one signature key and ')\n }\n const exchangeKey = await this.generateExchangeKey()\n const accessControlSecret = await this.generateAccessControlSecret()\n const sharedSignatureKey = await this.generateSharedSignatureKey()\n const encryptedExchangeKey = await this.encryptDataWithKeys(exchangeKey.rawBytes, encryptionKeys)\n const encryptedAccessControlSecret = await this.encryptDataWithKeys(accessControlSecret.rawBytes, encryptionKeys)\n const encryptedSharedSignatureKey = await this.encryptDataWithKeys(sharedSignatureKey.rawBytes, encryptionKeys)\n const baseExchangeData = {\n id: optionalAttributes.id ?? this.primitives.randomUuid(),\n delegator: await this.dataOwnerApi.getCurrentDataOwnerId(),\n delegate: delegateId,\n exchangeKey: encryptedExchangeKey,\n accessControlSecret: encryptedAccessControlSecret,\n sharedSignatureKey: encryptedSharedSignatureKey,\n }\n const sharedSignature = await this.signDataWithSharedKey(\n await this.bytesToSignForSharedSignature({\n delegate: baseExchangeData.delegate,\n delegator: baseExchangeData.delegator,\n decryptedAccessControlSecret: accessControlSecret.secret,\n decryptedExchangeKey: exchangeKey.key,\n publicKeysFingerprintsV2: Object.keys(encryptionKeys).map(fingerprintV1toV2),\n }),\n sharedSignatureKey.key\n )\n const delegatorSignature = await this.signDataWithDelegatorKeys(\n await this.bytesToSignForDelegatorSignature({\n sharedSignatureKey: sharedSignatureKey.key,\n }),\n signatureKeys\n )\n const exchangeData = new ExchangeData({ ...baseExchangeData, delegatorSignature, sharedSignature })\n return {\n exchangeData: await this.api.createExchangeData(exchangeData),\n exchangeKey: exchangeKey.key,\n accessControlSecret: accessControlSecret.secret,\n }\n }\n\n async tryRawDecryptExchangeData(\n exchangeData: ExchangeData,\n decryptionKeys: { [publicKeyFingerprint: string]: KeyPair<CryptoKey> }\n ): Promise<\n | {\n rawExchangeKey: ArrayBuffer\n rawAccessControlSecret: ArrayBuffer\n rawSharedSignatureKey: ArrayBuffer\n }\n | undefined\n > {\n const rawExchangeKey = await this.tryDecrypt(exchangeData.exchangeKey, decryptionKeys)\n const rawAccessControlSecret = await this.tryDecrypt(exchangeData.accessControlSecret, decryptionKeys)\n const rawSharedSignatureKey = await this.tryDecrypt(exchangeData.sharedSignatureKey, decryptionKeys)\n if (!rawExchangeKey || !rawAccessControlSecret || !rawSharedSignatureKey) return undefined\n return { rawExchangeKey, rawAccessControlSecret, rawSharedSignatureKey }\n }\n\n /**\n * Updates existing exchange data and uploads it to the cloud in order to share it also with additional public keys, useful for example in cases\n * where one of the data owners involved in the exchange data has lost one of his keys.\n * If the content of the exchange data could not be decrypted using the provided keys the method will not update anything and will return undefined.\n * This method assumes that the new encryption keys have been verified.\n * @param exchangeData exchange data to update.\n * @param decryptionKeys keys to use to extract the content of the exchange data which will be shared with the new keys.\n * @param newEncryptionKeys new keys to add to the exchange data.\n * @return the updated exchange data, and its decrypted exchange key and access control secret, or undefined if the exchange data content could not\n * be decrypted and the exchange data could not be updated.\n */\n async tryUpdateExchangeData(\n exchangeData: ExchangeData,\n decryptionKeys: { [publicKeyFingerprint: string]: KeyPair<CryptoKey> },\n newEncryptionKeys: { [keyPairFingerprint: string]: CryptoKey }\n ): Promise<\n | {\n exchangeData: ExchangeData\n exchangeKey: CryptoKey\n accessControlSecret: string\n }\n | undefined\n > {\n const rawExchangeKey = await this.tryDecrypt(exchangeData.exchangeKey, decryptionKeys)\n const rawAccessControlSecret = await this.tryDecrypt(exchangeData.accessControlSecret, decryptionKeys)\n const rawSharedSignatureKey = await this.tryDecrypt(exchangeData.sharedSignatureKey, decryptionKeys)\n if (!rawExchangeKey || !rawAccessControlSecret || !rawSharedSignatureKey) return undefined\n return await this.updateExchangeDataWithRawDecryptedContent(\n exchangeData,\n newEncryptionKeys,\n rawExchangeKey,\n rawAccessControlSecret,\n rawSharedSignatureKey\n )\n }\n\n /**\n * Same as [tryUpdateExchangeData] but the decrypted content is already provided.\n */\n async updateExchangeDataWithRawDecryptedContent(\n exchangeData: ExchangeData,\n newEncryptionKeys: { [keyPairFingerprint: string]: CryptoKey },\n rawExchangeKey: ArrayBuffer,\n rawAccessControlSecret: ArrayBuffer,\n rawSharedSignatureKey: ArrayBuffer\n ): Promise<{\n exchangeData: ExchangeData\n exchangeKey: CryptoKey\n accessControlSecret: string\n }> {\n const exchangeKey = await this.importExchangeKey(new Uint8Array(rawExchangeKey))\n const accessControlSecret = await this.importAccessControlSecret(new Uint8Array(rawAccessControlSecret))\n const sharedSignatureKey = await this.importSharedSignatureKey(new Uint8Array(rawSharedSignatureKey))\n const existingExchangeKeyEntries = new Set(Object.keys(exchangeData.exchangeKey))\n const existingAcsEntries = new Set(Object.keys(exchangeData.accessControlSecret))\n const existingSharedSignatureKeyEntries = new Set(Object.keys(exchangeData.sharedSignatureKey))\n const missingEntries = Object.keys(newEncryptionKeys).filter(\n (fp) => !existingAcsEntries.has(fp) || !existingExchangeKeyEntries.has(fp) || !existingSharedSignatureKeyEntries.has(fp)\n )\n if (!missingEntries.length) return { exchangeData, exchangeKey, accessControlSecret }\n const encryptionKeysForMissingEntries = missingEntries.reduce((obj, fp) => {\n obj[fp] = newEncryptionKeys[fp]\n return obj\n }, {} as { [keyPairFingerprint: string]: CryptoKey })\n const updatedExchangeData = _.cloneDeep(exchangeData)\n updatedExchangeData.exchangeKey = {\n ...exchangeData.exchangeKey,\n ...(await this.encryptDataWithKeys(rawExchangeKey, encryptionKeysForMissingEntries)),\n }\n updatedExchangeData.accessControlSecret = {\n ...exchangeData.accessControlSecret,\n ...(await this.encryptDataWithKeys(rawAccessControlSecret, encryptionKeysForMissingEntries)),\n }\n updatedExchangeData.sharedSignatureKey = {\n ...exchangeData.sharedSignatureKey,\n ...(await this.encryptDataWithKeys(rawSharedSignatureKey, encryptionKeysForMissingEntries)),\n }\n const isVerified = await this.verifyExchangeData(\n {\n exchangeData,\n decryptedAccessControlSecret: accessControlSecret,\n decryptedExchangeKey: exchangeKey,\n decryptedSharedSignatureKey: sharedSignatureKey,\n },\n () => Promise.resolve(undefined),\n false\n )\n if (isVerified) {\n updatedExchangeData.sharedSignature = await this.signDataWithSharedKey(\n await this.bytesToSignForSharedSignature({\n delegate: updatedExchangeData.delegate,\n delegator: updatedExchangeData.delegator,\n decryptedAccessControlSecret: accessControlSecret,\n decryptedExchangeKey: exchangeKey,\n publicKeysFingerprintsV2: Object.keys(updatedExchangeData.exchangeKey),\n }),\n sharedSignatureKey\n )\n }\n return { exchangeData: await this.api.modifyExchangeData(new ExchangeData(updatedExchangeData)), exchangeKey, accessControlSecret }\n }\n\n private async bytesToSignForSharedSignature(data: {\n delegator: string\n delegate: string\n decryptedAccessControlSecret: string\n decryptedExchangeKey: CryptoKey\n publicKeysFingerprintsV2: string[]\n }): Promise<ArrayBuffer> {\n // Use array of array to ensure that order is preserved regardless of how the specific js implementation orders\n // the keys of an object\n const signObject = [\n ['delegator', data.delegator],\n ['delegate', data.delegate],\n ['exchangeKey', ua2hex(await this.primitives.AES.exportKey(data.decryptedExchangeKey, 'raw'))],\n ['accessControlSecret', data.decryptedAccessControlSecret],\n ['publicKeysFingerprints', data.publicKeysFingerprintsV2.sort()],\n ]\n const signJson = JSON.stringify(signObject)\n return utf8_2ua(signJson)\n }\n\n private async bytesToSignForDelegatorSignature(data: { sharedSignatureKey: CryptoKey }): Promise<ArrayBuffer> {\n return this.primitives.sha256(await this.primitives.HMAC.exportKey(data.sharedSignatureKey))\n }\n\n // Generates a new exchange key\n private async generateExchangeKey(): Promise<{\n key: CryptoKey // the imported key\n rawBytes: ArrayBuffer // the bytes to encrypt for in the exchange data\n }> {\n const rawBytes = await this.primitives.randomBytes(32)\n return {\n key: await this.importExchangeKey(rawBytes),\n rawBytes,\n }\n }\n\n private async importExchangeKey(decryptedBytes: ArrayBuffer): Promise<CryptoKey> {\n return await this.primitives.AES.importKey('raw', decryptedBytes)\n }\n\n private async exportExchangeKey(key: CryptoKey): Promise<ArrayBuffer> {\n return await this.primitives.AES.exportKey(key, 'raw')\n }\n\n private async generateSharedSignatureKey(): Promise<{\n key: CryptoKey // the imported key\n rawBytes: ArrayBuffer // the bytes to encrypt for in the exchange data\n }> {\n const key = await this.primitives.HMAC.generateKey()\n return { key, rawBytes: await this.primitives.HMAC.exportKey(key) }\n }\n\n private async importSharedSignatureKey(decryptedBytes: ArrayBuffer): Promise<CryptoKey> {\n return await this.primitives.HMAC.importKey(decryptedBytes)\n }\n\n private async exportSharedSignatureKey(key: CryptoKey): Promise<ArrayBuffer> {\n return await this.primitives.HMAC.exportKey(key)\n }\n\n // Generates a new access control secret\n private async generateAccessControlSecret(): Promise<{\n secret: string // the imported secret\n rawBytes: ArrayBuffer // the bytes to encrypt for in the exchange data\n }> {\n const rawBytes = this.primitives.randomBytes(16)\n return {\n secret: await this.importAccessControlSecret(rawBytes),\n rawBytes,\n }\n }\n\n private importAccessControlSecret(decryptedBytes: ArrayBuffer): Promise<string> {\n return Promise.resolve(ua2hex(decryptedBytes))\n }\n\n private exportAccessControlSecret(secret: string): Promise<ArrayBuffer> {\n return Promise.resolve(hex2ua(secret))\n }\n\n private async encryptDataWithKeys(\n rawData: ArrayBuffer,\n keys: { [keyPairFingerprintV1: string]: CryptoKey }\n ): Promise<{ [keyPairFingerprintV2: string]: string }> {\n const res: { [keyPairFingerprintV2: string]: string } = {}\n for (const [fp, key] of Object.entries(keys)) {\n res[fingerprintIsV1(fp) ? fingerprintV1toV2(fp) : fp] = ua2b64(await this.primitives.RSA.encrypt(key, new Uint8Array(rawData)))\n }\n return res\n }\n\n private async signDataWithDelegatorKeys(\n rawData: ArrayBuffer,\n keys: { [keyPairFingerprint: string]: CryptoKey }\n ): Promise<{ [keyPairFingerprint: string]: string }> {\n const res: { [keyPairFingerprint: string]: string } = {}\n for (const [fp, key] of Object.entries(keys)) {\n res[fp] = ua2b64(await this.primitives.RSA.sign(key, new Uint8Array(rawData)))\n }\n return res\n }\n\n private async verifyDelegatorSignature(\n exchangeData: ExchangeData,\n decryptedSharedSignatureKey: CryptoKey,\n getVerificationKey: (publicKeyFingerprint: string) => Promise<CryptoKey | undefined>\n ): Promise<Boolean> {\n const delegatorSignatureData = await this.bytesToSignForDelegatorSignature({\n sharedSignatureKey: decryptedSharedSignatureKey,\n })\n for (const [fp, signature] of Object.entries(exchangeData.delegatorSignature)) {\n const verificationKey = await getVerificationKey(fp.slice(-32))\n if (verificationKey && (await this.primitives.RSA.verifySignature(verificationKey, b64_2ua(signature), delegatorSignatureData))) return true\n }\n return false\n }\n\n private async signDataWithSharedKey(rawData: ArrayBuffer, key: CryptoKey): Promise<string> {\n return ua2b64(await this.primitives.HMAC.sign(key, new Uint8Array(rawData)))\n }\n\n private async verifyDataWithSharedKey(rawData: ArrayBuffer, key: CryptoKey, signature: string): Promise<boolean> {\n return await this.primitives.HMAC.verify(key, new Uint8Array(rawData), b64_2ua(signature))\n }\n}\n"]}
1
+ {"version":3,"file":"BaseExchangeDataManager.js","sourceRoot":"","sources":["../../../icc-x-api/crypto/BaseExchangeDataManager.ts"],"names":[],"mappings":"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","sourcesContent":["import { IccDataOwnerXApi } from '../icc-data-owner-x-api'\nimport { KeyPair } from './RSA'\nimport { ExchangeData } from '../../icc-api/model/internal/ExchangeData'\nimport { IccExchangeDataApi } from '../../icc-api/api/internal/IccExchangeDataApi'\nimport { XHR } from '../../icc-api/api/XHR'\nimport XHRError = XHR.XHRError\nimport { CryptoPrimitives } from './CryptoPrimitives'\nimport { b64_2ua, hex2ua, ua2b64, ua2hex, ua2utf8, utf8_2ua } from '../utils'\nimport * as _ from 'lodash'\nimport { fingerprintV1toV2, fingerprintIsV1 } from './utils'\n\n/**\n * @internal this class is intended for internal use only and may be modified without notice\n * Functions to create and get exchange data.\n * The methods of this api require to pass the appropriate keys for encryption/decryption manually.\n */\nexport class BaseExchangeDataManager {\n constructor(\n readonly api: IccExchangeDataApi,\n private readonly dataOwnerApi: IccDataOwnerXApi,\n private readonly primitives: CryptoPrimitives,\n private readonly selfRequiresAnonymousDelegations: boolean\n ) {}\n\n /**\n * Get all the exchange data where the current data owner is the delegator or the delegate. However, some data owners, generally HCPs, may have a\n * prohibitively high amount of exchange data. If the crypto strategies specify that the current data owner requires anonymous delegation this\n * method returns all the exchange data found for the data owner, else the method returns undefined.\n * @return all the exchange data for the current data owner or undefined if the crypto strategies don't allow to retrieve all data for the current\n * data owner.\n */\n async getAllExchangeDataForCurrentDataOwnerIfAllowed(): Promise<ExchangeData[] | undefined> {\n if (!this.selfRequiresAnonymousDelegations) return undefined\n const dataOwnerId = await this.dataOwnerApi.getCurrentDataOwnerId()\n let latestResult = await this.api.getExchangeDataByParticipant(dataOwnerId, undefined, 1000)\n const allRetrieved = latestResult.rows ?? []\n while (latestResult.nextKeyPair?.startKeyDocId) {\n latestResult = await this.api.getExchangeDataByParticipant(dataOwnerId, latestResult.nextKeyPair.startKeyDocId, 1000)\n if (latestResult.rows) allRetrieved.push(...latestResult.rows)\n }\n return allRetrieved\n }\n\n /**\n * Get all exchange data for the provided delegator-delegate pair.\n * @param delegatorId id of a delegator data owner.\n * @param delegateId id of a delegate data owner.\n * @return all exchange data for the provided delegator-delegate pair.\n */\n async getExchangeDataByDelegatorDelegatePair(delegatorId: string, delegateId: string): Promise<ExchangeData[]> {\n return await this.api.getExchangeDataByDelegatorDelegate(delegatorId, delegateId)\n }\n\n /**\n * Get the exchange data with the provided id.\n * @param exchangeDataId id of the exchange data.\n * @return the exchange data with the provided id or undefined if no exchange data with such id could be found.\n */\n async getExchangeDataById(exchangeDataId: string): Promise<ExchangeData | undefined> {\n return await this.api.getExchangeDataById(exchangeDataId).catch((e) => {\n if (e instanceof XHRError && e.statusCode === 404) {\n return undefined\n } else throw e\n })\n }\n\n /**\n * Verifies the authenticity of the exchange data by checking the signature.\n * Note that all exchange data created by data owners other than the current data owner (including members of his hierarchy)\n * will always be unverified.\n * @param data collects the following information about the exchange data being verified:\n * - exchangeData the exchange data to verify.\n * - decryptedAccessControlSecret the access control secret decrypted from the exchange data.\n * - decryptedExchangeKey the exchange key decrypted from the exchange data.\n * - decryptedSharedSignatureKey the shared signature key decrypted from the exchange data.\n * @param getVerificationKey function to retrieve keys to use for verification by fingerprint.\n * @param verifyAsDelegator if true the method will also verify that the hmac key used for the signature was created by the delegator of the\n * exchange data. If true and the data was not created by the current data owner this method will return false.\n * @return the exchange data which could be verified given his signature and the available verification keys.\n * @throws if any of the provided exchange data has been created by a data owner other than the current data owner.\n */\n async verifyExchangeData(\n data: {\n exchangeData: ExchangeData\n decryptedAccessControlSecret: string\n decryptedExchangeKey: CryptoKey\n decryptedSharedSignatureKey: CryptoKey\n },\n getVerificationKey: (publicKeyFingerprint: string) => Promise<CryptoKey | undefined>,\n verifyAsDelegator: boolean\n ): Promise<boolean> {\n if (verifyAsDelegator && data.exchangeData.delegator !== (await this.dataOwnerApi.getCurrentDataOwnerId())) return false\n if (verifyAsDelegator && !(await this.verifyDelegatorSignature(data.exchangeData, data.decryptedSharedSignatureKey, getVerificationKey)))\n return false\n const sharedSignatureData = await this.bytesToSignForSharedSignature({\n decryptedAccessControlSecret: data.decryptedAccessControlSecret,\n decryptedExchangeKey: data.decryptedExchangeKey,\n delegator: data.exchangeData.delegator,\n delegate: data.exchangeData.delegate,\n publicKeysFingerprintsV2: [\n ...new Set([\n ...Object.keys(data.exchangeData.exchangeKey),\n ...Object.keys(data.exchangeData.accessControlSecret),\n ...Object.keys(data.exchangeData.sharedSignatureKey),\n ]),\n ],\n })\n return await this.verifyDataWithSharedKey(sharedSignatureData, data.decryptedSharedSignatureKey, data.exchangeData.sharedSignature)\n }\n\n /**\n * Extracts and decrypts the access control secret from the provided exchange data.\n * These need to be hashed together with the entity class and confidentiality level in order to get the actual access control key\n * which will be sent to the server.\n * @param exchangeData the exchange data from which to extract access control secrets.\n * @param decryptionKeys rsa key pairs to use for decryption of the access control secret.\n * @return an object composed of:\n * - successfulDecryptions: array of all successfully decrypted access control keys\n * - failedDecryptions: array containing all exchange data for which the access control key could not be decrypted (using the provided keys).\n */\n async tryDecryptAccessControlSecret(\n exchangeData: ExchangeData[],\n decryptionKeys: { [publicKeyFingerprint: string]: KeyPair<CryptoKey> }\n ): Promise<{\n successfulDecryptions: string[]\n failedDecryptions: ExchangeData[]\n }> {\n return await this.tryDecryptExchangeData(\n exchangeData,\n decryptionKeys,\n (ed) => ed.accessControlSecret,\n (d) => this.importAccessControlSecret(new Uint8Array(d))\n )\n }\n\n /**\n * Extract and decrypts the exchange keys from the provided exchange data.\n * @param exchangeData the exchange data from which to extract exchange keys.\n * @param decryptionKeys rsa key pairs to use for the decryption of the exchange keys.\n * @return an object composed of:\n * - successfulDecryptions: array containing the successfully decrypted exchange keys.\n * - failedDecryptions: array containing all exchange data for which the access control key could not be decrypted (using the provided keys).\n */\n async tryDecryptExchangeKeys(\n exchangeData: ExchangeData[],\n decryptionKeys: { [publicKeyFingerprint: string]: KeyPair<CryptoKey> }\n ): Promise<{\n successfulDecryptions: CryptoKey[]\n failedDecryptions: ExchangeData[]\n }> {\n return await this.tryDecryptExchangeData(\n exchangeData,\n decryptionKeys,\n (ed) => ed.exchangeKey,\n (d) => this.importExchangeKey(new Uint8Array(d))\n )\n }\n\n /**\n * Extract and decrypts the shared signature key from the provided exchange data.\n * @param exchangeData the exchange data from which to extract exchange keys.\n * @param decryptionKeys rsa key pairs to use for the decryption of the exchange keys.\n * @return an object composed of:\n * - successfulDecryptions: array containing the successfully decrypted exchange keys.\n * - failedDecryptions: array containing all exchange data for which the access control key could not be decrypted (using the provided keys).\n */\n async tryDecryptSharedSignatureKeys(\n exchangeData: ExchangeData[],\n decryptionKeys: { [publicKeyFingerprint: string]: KeyPair<CryptoKey> }\n ): Promise<{\n successfulDecryptions: CryptoKey[]\n failedDecryptions: ExchangeData[]\n }> {\n return await this.tryDecryptExchangeData(\n exchangeData,\n decryptionKeys,\n (ed) => ed.sharedSignatureKey,\n (d) => this.importSharedSignatureKey(new Uint8Array(d))\n )\n }\n\n private async tryDecryptExchangeData<T>(\n exchangeData: ExchangeData[],\n decryptionKeys: { [publicKeyFingerprint: string]: KeyPair<CryptoKey> },\n encryptedDataSelector: (data: ExchangeData) => { [keyPairFingerprint: string]: string },\n unmarshalDecrypted: (decrypted: ArrayBuffer) => Promise<T>\n ): Promise<{\n successfulDecryptions: T[]\n failedDecryptions: ExchangeData[]\n }> {\n const successfulDecryptions: T[] = []\n const failedDecryptions: ExchangeData[] = []\n for (const ed of exchangeData) {\n try {\n const decrypted = await this.tryDecrypt(encryptedDataSelector(ed), decryptionKeys)\n if (decrypted) {\n successfulDecryptions.push(await unmarshalDecrypted(decrypted))\n } else {\n failedDecryptions.push(ed)\n }\n } catch (e) {\n failedDecryptions.push(ed)\n }\n }\n return { successfulDecryptions, failedDecryptions }\n }\n\n private async tryDecrypt(\n encryptedData: { [keyPairFingerprintV2: string]: string },\n decryptionKeys: { [publicKeyFingerprintV1: string]: KeyPair<CryptoKey> }\n ): Promise<ArrayBuffer | undefined> {\n const decryptionKeysWithV2Fp = Object.keys(decryptionKeys).reduce((prev, fp) => {\n return {\n ...prev,\n [fingerprintIsV1(fp) ? fingerprintV1toV2(fp) : fp]: decryptionKeys[fp],\n }\n }, {} as { [publicKeyFingerprint: string]: KeyPair<CryptoKey> })\n for (const [fp, encrypted] of Object.entries(encryptedData)) {\n try {\n const key = decryptionKeysWithV2Fp[fp]?.privateKey\n if (key) return await this.primitives.RSA.decrypt(key, b64_2ua(encrypted))\n } catch (e) {\n // Try with another key\n }\n }\n }\n\n /**\n * Creates exchange data from the current data owner to the provided delegate, uploading the newly created exchange data to the cloud.\n * This assumes that the keys have been verified.\n * @param delegateId id of the delegate for the new exchange data.\n * @param signatureKeys private keys to use for signing the created data.\n * @param encryptionKeys public keys to use for the encryption of the exchange data (from delegator and delegate).\n * @param optionalAttributes optional precalculated attributes for the creation of data\n * @return the newly created exchange data, and its decrypted exchange key and access control secret.\n */\n async createExchangeData(\n delegateId: string,\n signatureKeys: { [keyPairFingerprint: string]: CryptoKey },\n encryptionKeys: { [keyPairFingerprint: string]: CryptoKey },\n optionalAttributes: {\n id?: string\n } = {}\n ): Promise<{\n exchangeData: ExchangeData\n exchangeKey: CryptoKey\n accessControlSecret: string\n }> {\n if (!Object.keys(signatureKeys).length || !Object.keys(encryptionKeys).length) {\n throw new Error('Must specify at least one signature key and ')\n }\n const exchangeKey = await this.generateExchangeKey()\n const accessControlSecret = await this.generateAccessControlSecret()\n const sharedSignatureKey = await this.generateSharedSignatureKey()\n const encryptedExchangeKey = await this.encryptDataWithKeys(exchangeKey.rawBytes, encryptionKeys)\n const encryptedAccessControlSecret = await this.encryptDataWithKeys(accessControlSecret.rawBytes, encryptionKeys)\n const encryptedSharedSignatureKey = await this.encryptDataWithKeys(sharedSignatureKey.rawBytes, encryptionKeys)\n const baseExchangeData = {\n id: optionalAttributes.id ?? this.primitives.randomUuid(),\n delegator: await this.dataOwnerApi.getCurrentDataOwnerId(),\n delegate: delegateId,\n exchangeKey: encryptedExchangeKey,\n accessControlSecret: encryptedAccessControlSecret,\n sharedSignatureKey: encryptedSharedSignatureKey,\n }\n const sharedSignature = await this.signDataWithSharedKey(\n await this.bytesToSignForSharedSignature({\n delegate: baseExchangeData.delegate,\n delegator: baseExchangeData.delegator,\n decryptedAccessControlSecret: accessControlSecret.secret,\n decryptedExchangeKey: exchangeKey.key,\n publicKeysFingerprintsV2: Object.keys(encryptionKeys).map(fingerprintV1toV2),\n }),\n sharedSignatureKey.key\n )\n const delegatorSignature = await this.signDataWithDelegatorKeys(\n await this.bytesToSignForDelegatorSignature({\n sharedSignatureKey: sharedSignatureKey.key,\n }),\n signatureKeys\n )\n const exchangeData = new ExchangeData({ ...baseExchangeData, delegatorSignature, sharedSignature })\n return {\n exchangeData: await this.api.createExchangeData(exchangeData),\n exchangeKey: exchangeKey.key,\n accessControlSecret: accessControlSecret.secret,\n }\n }\n\n async tryRawDecryptExchangeData(\n exchangeData: ExchangeData,\n decryptionKeys: { [publicKeyFingerprint: string]: KeyPair<CryptoKey> }\n ): Promise<\n | {\n rawExchangeKey: ArrayBuffer\n rawAccessControlSecret: ArrayBuffer\n rawSharedSignatureKey: ArrayBuffer\n }\n | undefined\n > {\n const rawExchangeKey = await this.tryDecrypt(exchangeData.exchangeKey, decryptionKeys)\n const rawAccessControlSecret = await this.tryDecrypt(exchangeData.accessControlSecret, decryptionKeys)\n const rawSharedSignatureKey = await this.tryDecrypt(exchangeData.sharedSignatureKey, decryptionKeys)\n if (!rawExchangeKey || !rawAccessControlSecret || !rawSharedSignatureKey) return undefined\n return { rawExchangeKey, rawAccessControlSecret, rawSharedSignatureKey }\n }\n\n /**\n * Updates existing exchange data and uploads it to the cloud in order to share it also with additional public keys, useful for example in cases\n * where one of the data owners involved in the exchange data has lost one of his keys.\n * If the content of the exchange data could not be decrypted using the provided keys the method will not update anything and will return undefined.\n * This method assumes that the new encryption keys have been verified.\n * @param exchangeData exchange data to update.\n * @param decryptionKeys keys to use to extract the content of the exchange data which will be shared with the new keys.\n * @param newEncryptionKeys new keys to add to the exchange data.\n * @return the updated exchange data, and its decrypted exchange key and access control secret, or undefined if the exchange data content could not\n * be decrypted and the exchange data could not be updated.\n */\n async tryUpdateExchangeData(\n exchangeData: ExchangeData,\n decryptionKeys: { [publicKeyFingerprint: string]: KeyPair<CryptoKey> },\n newEncryptionKeys: { [keyPairFingerprint: string]: CryptoKey }\n ): Promise<\n | {\n exchangeData: ExchangeData\n exchangeKey: CryptoKey\n accessControlSecret: string\n }\n | undefined\n > {\n const rawExchangeKey = await this.tryDecrypt(exchangeData.exchangeKey, decryptionKeys)\n const rawAccessControlSecret = await this.tryDecrypt(exchangeData.accessControlSecret, decryptionKeys)\n const rawSharedSignatureKey = await this.tryDecrypt(exchangeData.sharedSignatureKey, decryptionKeys)\n if (!rawExchangeKey || !rawAccessControlSecret || !rawSharedSignatureKey) return undefined\n return await this.updateExchangeDataWithRawDecryptedContent(\n exchangeData,\n newEncryptionKeys,\n rawExchangeKey,\n rawAccessControlSecret,\n rawSharedSignatureKey\n )\n }\n\n /**\n * Same as [tryUpdateExchangeData] but the decrypted content is already provided.\n */\n async updateExchangeDataWithRawDecryptedContent(\n exchangeData: ExchangeData,\n newEncryptionKeys: { [keyPairFingerprint: string]: CryptoKey },\n rawExchangeKey: ArrayBuffer,\n rawAccessControlSecret: ArrayBuffer,\n rawSharedSignatureKey: ArrayBuffer\n ): Promise<{\n exchangeData: ExchangeData\n exchangeKey: CryptoKey\n accessControlSecret: string\n }> {\n const exchangeKey = await this.importExchangeKey(new Uint8Array(rawExchangeKey))\n const accessControlSecret = await this.importAccessControlSecret(new Uint8Array(rawAccessControlSecret))\n const sharedSignatureKey = await this.importSharedSignatureKey(new Uint8Array(rawSharedSignatureKey))\n const existingExchangeKeyEntries = new Set(Object.keys(exchangeData.exchangeKey))\n const existingAcsEntries = new Set(Object.keys(exchangeData.accessControlSecret))\n const existingSharedSignatureKeyEntries = new Set(Object.keys(exchangeData.sharedSignatureKey))\n const missingEntries = Object.keys(newEncryptionKeys).filter(\n (fp) => !existingAcsEntries.has(fp) || !existingExchangeKeyEntries.has(fp) || !existingSharedSignatureKeyEntries.has(fp)\n )\n if (!missingEntries.length) return { exchangeData, exchangeKey, accessControlSecret }\n const encryptionKeysForMissingEntries = missingEntries.reduce((obj, fp) => {\n obj[fp] = newEncryptionKeys[fp]\n return obj\n }, {} as { [keyPairFingerprint: string]: CryptoKey })\n const updatedExchangeData = _.cloneDeep(exchangeData)\n updatedExchangeData.exchangeKey = {\n ...exchangeData.exchangeKey,\n ...(await this.encryptDataWithKeys(rawExchangeKey, encryptionKeysForMissingEntries)),\n }\n updatedExchangeData.accessControlSecret = {\n ...exchangeData.accessControlSecret,\n ...(await this.encryptDataWithKeys(rawAccessControlSecret, encryptionKeysForMissingEntries)),\n }\n updatedExchangeData.sharedSignatureKey = {\n ...exchangeData.sharedSignatureKey,\n ...(await this.encryptDataWithKeys(rawSharedSignatureKey, encryptionKeysForMissingEntries)),\n }\n const isVerified = await this.verifyExchangeData(\n {\n exchangeData,\n decryptedAccessControlSecret: accessControlSecret,\n decryptedExchangeKey: exchangeKey,\n decryptedSharedSignatureKey: sharedSignatureKey,\n },\n () => Promise.resolve(undefined),\n false\n )\n if (isVerified) {\n updatedExchangeData.sharedSignature = await this.signDataWithSharedKey(\n await this.bytesToSignForSharedSignature({\n delegate: updatedExchangeData.delegate,\n delegator: updatedExchangeData.delegator,\n decryptedAccessControlSecret: accessControlSecret,\n decryptedExchangeKey: exchangeKey,\n publicKeysFingerprintsV2: Object.keys(updatedExchangeData.exchangeKey),\n }),\n sharedSignatureKey\n )\n }\n return { exchangeData: await this.api.modifyExchangeData(new ExchangeData(updatedExchangeData)), exchangeKey, accessControlSecret }\n }\n\n private async bytesToSignForSharedSignature(data: {\n delegator: string\n delegate: string\n decryptedAccessControlSecret: string\n decryptedExchangeKey: CryptoKey\n publicKeysFingerprintsV2: string[]\n }): Promise<ArrayBuffer> {\n // Use array of array to ensure that order is preserved regardless of how the specific js implementation orders\n // the keys of an object\n const signObject = [\n ['delegator', data.delegator],\n ['delegate', data.delegate],\n ['exchangeKey', ua2hex(await this.primitives.AES.exportKey(data.decryptedExchangeKey, 'raw'))],\n ['accessControlSecret', data.decryptedAccessControlSecret],\n ['publicKeysFingerprints', data.publicKeysFingerprintsV2.sort()],\n ]\n const signJson = JSON.stringify(signObject)\n return utf8_2ua(signJson)\n }\n\n private async bytesToSignForDelegatorSignature(data: { sharedSignatureKey: CryptoKey }): Promise<ArrayBuffer> {\n return this.primitives.sha256(await this.primitives.HMAC.exportKey(data.sharedSignatureKey))\n }\n\n // Generates a new exchange key\n private async generateExchangeKey(): Promise<{\n key: CryptoKey // the imported key\n rawBytes: ArrayBuffer // the bytes to encrypt for in the exchange data\n }> {\n const rawBytes = await this.primitives.randomBytes(32)\n return {\n key: await this.importExchangeKey(rawBytes),\n rawBytes,\n }\n }\n\n private async importExchangeKey(decryptedBytes: ArrayBuffer): Promise<CryptoKey> {\n return await this.primitives.AES.importKey('raw', decryptedBytes)\n }\n\n private async exportExchangeKey(key: CryptoKey): Promise<ArrayBuffer> {\n return await this.primitives.AES.exportKey(key, 'raw')\n }\n\n private async generateSharedSignatureKey(): Promise<{\n key: CryptoKey // the imported key\n rawBytes: ArrayBuffer // the bytes to encrypt for in the exchange data\n }> {\n const key = await this.primitives.HMAC.generateKey()\n return { key, rawBytes: await this.primitives.HMAC.exportKey(key) }\n }\n\n private async importSharedSignatureKey(decryptedBytes: ArrayBuffer): Promise<CryptoKey> {\n return await this.primitives.HMAC.importKey(decryptedBytes)\n }\n\n private async exportSharedSignatureKey(key: CryptoKey): Promise<ArrayBuffer> {\n return await this.primitives.HMAC.exportKey(key)\n }\n\n // Generates a new access control secret\n private async generateAccessControlSecret(): Promise<{\n secret: string // the imported secret\n rawBytes: ArrayBuffer // the bytes to encrypt for in the exchange data\n }> {\n const rawBytes = this.primitives.randomBytes(16)\n return {\n secret: await this.importAccessControlSecret(rawBytes),\n rawBytes,\n }\n }\n\n private importAccessControlSecret(decryptedBytes: ArrayBuffer): Promise<string> {\n return Promise.resolve(ua2hex(decryptedBytes))\n }\n\n private exportAccessControlSecret(secret: string): Promise<ArrayBuffer> {\n return Promise.resolve(hex2ua(secret))\n }\n\n private async encryptDataWithKeys(\n rawData: ArrayBuffer,\n keys: { [keyPairFingerprintV1: string]: CryptoKey }\n ): Promise<{ [keyPairFingerprintV2: string]: string }> {\n const res: { [keyPairFingerprintV2: string]: string } = {}\n for (const [fp, key] of Object.entries(keys)) {\n res[fingerprintIsV1(fp) ? fingerprintV1toV2(fp) : fp] = ua2b64(await this.primitives.RSA.encrypt(key, new Uint8Array(rawData)))\n }\n return res\n }\n\n private async signDataWithDelegatorKeys(\n rawData: ArrayBuffer,\n keys: { [keyPairFingerprint: string]: CryptoKey }\n ): Promise<{ [keyPairFingerprint: string]: string }> {\n const res: { [keyPairFingerprint: string]: string } = {}\n for (const [fp, key] of Object.entries(keys)) {\n res[fp] = ua2b64(await this.primitives.RSA.sign(key, new Uint8Array(rawData)))\n }\n return res\n }\n\n private async verifyDelegatorSignature(\n exchangeData: ExchangeData,\n decryptedSharedSignatureKey: CryptoKey,\n getVerificationKey: (publicKeyFingerprint: string) => Promise<CryptoKey | undefined>\n ): Promise<Boolean> {\n const delegatorSignatureData = await this.bytesToSignForDelegatorSignature({\n sharedSignatureKey: decryptedSharedSignatureKey,\n })\n for (const [fp, signature] of Object.entries(exchangeData.delegatorSignature)) {\n const verificationKey = await getVerificationKey(fp)\n if (verificationKey && (await this.primitives.RSA.verifySignature(verificationKey, b64_2ua(signature), delegatorSignatureData))) return true\n }\n return false\n }\n\n private async signDataWithSharedKey(rawData: ArrayBuffer, key: CryptoKey): Promise<string> {\n return ua2b64(await this.primitives.HMAC.sign(key, new Uint8Array(rawData)))\n }\n\n private async verifyDataWithSharedKey(rawData: ArrayBuffer, key: CryptoKey, signature: string): Promise<boolean> {\n return await this.primitives.HMAC.verify(key, new Uint8Array(rawData), b64_2ua(signature))\n }\n}\n"]}
@@ -186,7 +186,7 @@ class BaseExchangeKeysManager {
186
186
  return __awaiter(this, void 0, void 0, function* () {
187
187
  for (const [entryKey, encrypted] of Object.entries(encryptedExchangeKey)) {
188
188
  // Due to bugs in past version the entry may actually contain the full public key instead of just the fingerprint.
189
- const fp = entryKey.slice(-32);
189
+ const fp = (0, utils_2.fingerprintV1)(entryKey);
190
190
  const keyPair = keyPairsByFingerprint[fp];
191
191
  if (keyPair !== undefined) {
192
192
  const res = yield this.tryDecryptExchangeKeyWith(encrypted, keyPair, fp);
@@ -278,8 +278,12 @@ class BaseExchangeKeysManager {
278
278
  return acc;
279
279
  }, {});
280
280
  return Object.assign({ [ownerLegacyPublicKey]: Object.entries((_c = owner.hcPartyKeys) !== null && _c !== void 0 ? _c : {}).reduce((acc, [hcpId, keys]) => {
281
- var _a, _b, _c;
282
- acc[hcpId] = { [ownerLegacyPublicKey.slice(-32)]: keys[0], [(_c = (_b = (_a = counterPartsById[hcpId]) === null || _a === void 0 ? void 0 : _a.publicKey) === null || _b === void 0 ? void 0 : _b.slice(-32)) !== null && _c !== void 0 ? _c : '']: keys[1] };
281
+ var _a, _b;
282
+ const counterpartKey = (_a = counterPartsById[hcpId]) === null || _a === void 0 ? void 0 : _a.publicKey;
283
+ acc[hcpId] = {
284
+ [(0, utils_2.fingerprintV1)(ownerLegacyPublicKey)]: keys[0],
285
+ [(_b = (counterpartKey && (0, utils_2.fingerprintV1)(counterpartKey))) !== null && _b !== void 0 ? _b : '']: keys[1],
286
+ };
283
287
  return acc;
284
288
  }, {}) }, ((_d = owner.aesExchangeKeys) !== null && _d !== void 0 ? _d : {}));
285
289
  }
@@ -1 +1 @@
1
- {"version":3,"file":"BaseExchangeKeysManager.js","sourceRoot":"","sources":["../../../icc-x-api/crypto/BaseExchangeKeysManager.ts"],"names":[],"mappings":"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","sourcesContent":["import { KeyPair } from './RSA'\nimport { hex2ua, notConcurrent, ua2hex } from '../utils'\nimport { DataOwner, IccDataOwnerXApi } from '../icc-data-owner-x-api'\nimport { CryptoPrimitives } from './CryptoPrimitives'\nimport { IccDeviceApi, IccHcpartyApi, IccPatientApi } from '../../icc-api'\nimport { fingerprintV1, getShaVersionForKey } from './utils'\nimport { CryptoActorStub, CryptoActorStubWithType } from '../../icc-api/model/CryptoActorStub'\nimport { DataOwnerTypeEnum } from '../../icc-api/model/DataOwnerTypeEnum'\n\n/**\n * @internal This class is meant only for internal use and may be changed without notice.\n * Functions to create and get exchange keys.\n * The methods of this api require to pass the appropriate keys for encryption/decryption manually.\n */\nexport class BaseExchangeKeysManager {\n private readonly generateKeyConcurrencyMap: { [key: string]: PromiseLike<any> } = {}\n private readonly primitives: CryptoPrimitives\n private readonly dataOwnerApi: IccDataOwnerXApi\n private readonly hcpartyBaseApi: IccHcpartyApi\n private readonly patientBaseApi: IccPatientApi\n private readonly deviceBaseApi: IccDeviceApi\n\n constructor(\n primitives: CryptoPrimitives,\n dataOwnerApi: IccDataOwnerXApi,\n hcpartyBaseApi: IccHcpartyApi,\n patientBaseApi: IccPatientApi,\n deviceBaseApi: IccDeviceApi\n ) {\n this.primitives = primitives\n this.dataOwnerApi = dataOwnerApi\n this.hcpartyBaseApi = hcpartyBaseApi\n this.patientBaseApi = patientBaseApi\n this.deviceBaseApi = deviceBaseApi\n }\n\n /**\n * Updates the aes exchange keys between the current data owner and another data owner to allow the other data owner to access the exchange key\n * using his new public key. Note that this will make existing exchange keys from the other data owner to the current data owner invalid for\n * encryption.\n * @param otherDataOwner the other data owner.\n * @param newDataOwnerPublicKey a new public key of the other data owner.\n * @param keyPairsByFingerprint all available key pairs to use for the decryption of existing aes exchange keys.\n */\n async giveAccessBackTo(\n otherDataOwner: string,\n newDataOwnerPublicKey: string,\n keyPairsByFingerprint: { [publicKeyFingerprint: string]: KeyPair<CryptoKey> }\n ) {\n const selfId = await this.dataOwnerApi.getCurrentDataOwnerId()\n const other = await this.dataOwnerApi.getCryptoActorStub(otherDataOwner)\n const newKeyHashVersion = getShaVersionForKey(other.stub, newDataOwnerPublicKey)\n if (!newKeyHashVersion) throw new Error(`Public key not found for data owner ${otherDataOwner}`)\n const newPublicKey = await this.primitives.RSA.importKey('spki', hex2ua(newDataOwnerPublicKey), ['encrypt'], newKeyHashVersion)\n await this.extendForGiveAccessBackTo(selfId, otherDataOwner, fingerprintV1(newDataOwnerPublicKey), newPublicKey, keyPairsByFingerprint)\n await this.extendForGiveAccessBackTo(otherDataOwner, selfId, fingerprintV1(newDataOwnerPublicKey), newPublicKey, keyPairsByFingerprint)\n }\n\n /**\n * Get the encrypted exchange keys for a delegator-delegate pair.\n * @param delegatorId id of the delegator data owner.\n * @param delegateId id of the delegate data owner.\n * @return an array of exchange keys from the delegator to delegate where each key is encrypted with one or more public keys.\n */\n async getEncryptedExchangeKeysFor(delegatorId: string, delegateId: string): Promise<{ [publicKeyFingerprint: string]: string }[]> {\n const delegator = await this.dataOwnerApi.getCryptoActorStub(delegatorId)\n const res: { [publicKeyFingerprint: string]: string }[] = Object.values(delegator.stub.aesExchangeKeys ?? {}).flatMap((delegateToKey) => {\n const encryptedKeyForDelegate = delegateToKey[delegateId]\n if (encryptedKeyForDelegate) {\n return [encryptedKeyForDelegate]\n } else {\n return []\n }\n })\n const legacyDelegation = delegator.stub.hcPartyKeys?.[delegateId]?.[1]\n if (legacyDelegation) res.push({ '': legacyDelegation })\n return res\n }\n\n /**\n * Get all exchange keys where the provided data owner is involved either as the delegator or as the delegate.\n * @param dataOwnerId id of a data owner.\n * @param otherOwnerTypes only exchange keys between the current data owner and data owners of this type will be included in the result.\n * @return all exchange keys involving the provided data owner. Note that there may be an overlap between some keys to and from the data owner.\n */\n async getAllExchangeKeysWith(\n dataOwnerId: string,\n otherOwnerTypes: DataOwnerTypeEnum[]\n ): Promise<{\n keysToOwner: { [delegatorId: string]: { [delegatorFp: string]: { [entryFp: string]: string } } }\n keysFromOwner: { [delegatorFp: string]: { [delegateId: string]: { [entryFp: string]: string } } }\n }> {\n if (otherOwnerTypes.length === 0) throw new Error('otherOwnerTypes must not be empty!')\n const keysToOwner = await Promise.all([\n otherOwnerTypes.find((x) => x === 'hcp') ? this.hcpartyBaseApi.getAesExchangeKeysForDelegate(dataOwnerId).catch(() => {}) : Promise.resolve({}),\n otherOwnerTypes.find((x) => x === 'patient')\n ? this.patientBaseApi.getPatientAesExchangeKeysForDelegate(dataOwnerId).catch(() => {})\n : Promise.resolve({}),\n otherOwnerTypes.find((x) => x === 'device')\n ? this.deviceBaseApi.getDeviceAesExchangeKeysForDelegate(dataOwnerId).catch(() => {})\n : Promise.resolve({}),\n ]).then(([a, b, c]) => ({ ...a, ...b, ...c } as { [delegatorId: string]: { [delegatorFp: string]: { [entryFp: string]: string } } }))\n const dataOwner = await this.dataOwnerApi.getCryptoActorStub(dataOwnerId)\n const allOwnerKeys = await this.combineLegacyHcpKeysWithAesExchangeKeys(dataOwner.stub, undefined)\n const filteredDelegates = new Set(\n await Array.from(new Set(Object.values(allOwnerKeys).flatMap((x) => Object.keys(x)))).reduce(async (acc, ownerId) => {\n const awaitedAcc = await acc\n if (ownerId === dataOwnerId) {\n return [...awaitedAcc, ownerId]\n } else {\n const dataOwnerType: DataOwnerTypeEnum = (await this.dataOwnerApi.getCryptoActorStub(ownerId)).type\n if (otherOwnerTypes.some((x) => x === dataOwnerType)) {\n return [...awaitedAcc, ownerId]\n } else return awaitedAcc\n }\n }, Promise.resolve([] as string[]))\n )\n const keysFromOwner = Object.fromEntries(\n Object.entries(allOwnerKeys)\n .map(([delegatorPubKey, delegateToKeys]) => [\n delegatorPubKey,\n Object.fromEntries(\n Object.entries(delegateToKeys).filter(([delegateId]) => filteredDelegates.has(delegateId)) as [string, { [k: string]: string }][]\n ),\n ])\n .filter(([, x]) => Object.keys(x).length > 0) as [string, { [k: string]: { [k: string]: string } }][]\n )\n return { keysToOwner, keysFromOwner }\n }\n\n /**\n * Attempts to decrypt many exchange keys using any of the provided key pairs.\n * @param encryptedExchangeKeys an array of exchange keys where each key is encrypted with one or more public keys.\n * @param keyPairsByFingerprint rsa key pairs to use for decryption.\n * @return an array all successfully decrypted exchange keys and an array containing all exchange keys which could not be decrypted.\n */\n async tryDecryptExchangeKeys(\n encryptedExchangeKeys: { [publicKeyFingerprint: string]: string }[],\n keyPairsByFingerprint: { [publicKeyFingerprint: string]: KeyPair<CryptoKey> }\n ): Promise<{\n successfulDecryptions: CryptoKey[]\n failedDecryptions: { [publicKeyFingerprint: string]: string }[]\n }> {\n const raws = new Set<string>()\n const res: {\n successfulDecryptions: CryptoKey[]\n failedDecryptions: { [publicKeyFingerprint: string]: string }[]\n } = { successfulDecryptions: [], failedDecryptions: [] }\n for (const encryptedExchangeKey of encryptedExchangeKeys) {\n const decrypted = await this.tryDecryptExchangeKey(encryptedExchangeKey, keyPairsByFingerprint)\n if (decrypted !== undefined && !raws.has(decrypted.raw)) {\n raws.add(decrypted.raw)\n res.successfulDecryptions.push(decrypted.key)\n } else {\n res.failedDecryptions.push(encryptedExchangeKey)\n }\n }\n return res\n }\n\n private async extendForGiveAccessBackTo(\n delegatorId: string,\n delegateId: string,\n newPublicKeyFp: string,\n newPublicKey: CryptoKey,\n decryptionKeyPairsByFingerprint: { [publicKeyFingerprint: string]: KeyPair<CryptoKey> }\n ) {\n await notConcurrent(this.generateKeyConcurrencyMap, delegatorId, async () => {\n const delegator = await this.dataOwnerApi.getCryptoActorStub(delegatorId)\n const delegate = await this.dataOwnerApi.getCryptoActorStub(delegateId)\n let didUpdateSomeKey = false\n const combinedKeys = await this.combineLegacyHcpKeysWithAesExchangeKeys(delegator.stub, delegate.stub)\n const updatedExchangeKeys: { [delegatorKey: string]: { [delegateId: string]: { [keyFp: string]: string } } } = {}\n const newEncryptionKeys = { [newPublicKeyFp]: newPublicKey }\n for (const [currDelegatorKey, currDelegatesToKeys] of Object.entries(combinedKeys)) {\n const updatedDelegatesToKeys: { [delegateId: string]: { [keyFp: string]: string } } = {}\n for (const [currDelegateId, currEncryptedKey] of Object.entries(currDelegatesToKeys)) {\n if (delegateId !== currDelegateId || newPublicKeyFp in currEncryptedKey) {\n updatedDelegatesToKeys[currDelegateId] = currEncryptedKey\n } else {\n const decrypted = await this.tryDecryptExchangeKey(currEncryptedKey, decryptionKeyPairsByFingerprint)\n if (decrypted) {\n didUpdateSomeKey = true\n updatedDelegatesToKeys[currDelegateId] = {\n ...currEncryptedKey,\n ...(await this.encryptExchangeKey(decrypted, newEncryptionKeys)).encryptedExchangeKey,\n }\n } else {\n updatedDelegatesToKeys[currDelegateId] = currEncryptedKey\n }\n }\n }\n updatedExchangeKeys[currDelegatorKey] = updatedDelegatesToKeys\n }\n if (didUpdateSomeKey) {\n await this.dataOwnerApi.modifyCryptoActorStub({\n type: delegator.type,\n stub: {\n ...delegator.stub,\n aesExchangeKeys: updatedExchangeKeys,\n },\n })\n }\n })\n }\n\n /**\n * Attempts to decrypt an exchange key using any of the provided key pairs.\n * @param encryptedExchangeKey an encrypted exchange key, in the form publicKeyXyzFingerprint -> hex(exchangeKeyEncryptedByPrivateKeyXyz).\n * @param keyPairsByFingerprint rsa key pairs to use for decryption.\n * @return the decrypted exchange key, in raw and key format (to allow deduplication), or undefined if the key could not be decrypted using the\n * provided keys.\n */\n private async tryDecryptExchangeKey(\n encryptedExchangeKey: { [publicKeyFingerprint: string]: string },\n keyPairsByFingerprint: { [publicKeyFingerprint: string]: KeyPair<CryptoKey> }\n ): Promise<{ raw: string; key: CryptoKey } | undefined> {\n for (const [entryKey, encrypted] of Object.entries(encryptedExchangeKey)) {\n // Due to bugs in past version the entry may actually contain the full public key instead of just the fingerprint.\n const fp = entryKey.slice(-32)\n const keyPair = keyPairsByFingerprint[fp]\n if (keyPair !== undefined) {\n const res = await this.tryDecryptExchangeKeyWith(encrypted, keyPair, fp)\n if (res !== undefined) return res\n }\n }\n const defaultEncryptedKey = encryptedExchangeKey['']\n if (defaultEncryptedKey !== undefined) {\n for (const keyPair of Object.values(keyPairsByFingerprint)) {\n // disable error logging, we are not sure keyPair is the correct key\n const res = await this.tryDecryptExchangeKeyWith(defaultEncryptedKey, keyPair, undefined)\n if (res !== undefined) return res\n }\n }\n return undefined\n }\n\n /**\n * Creates an encrypted exchange key for the provided public keys.\n * @param exchangeKey the exchange key in raw and imported format. If undefined a new key will be automatically created.\n * @param publicKeys additional public keys that will have access to the exchange key in spki format, hex-encoded.\n * @return the exchangeKey and an object with the exchange key encrypted with each of the provided public keys, hex-encoded, by fingerprint.\n */\n private async encryptExchangeKey(\n exchangeKey: { raw: string; key: CryptoKey } | undefined,\n publicKeys: { [keyFingerprint: string]: CryptoKey }\n ): Promise<{\n exchangeKey: CryptoKey\n encryptedExchangeKey: { [pubKeyFp: string]: string }\n }> {\n const exchangeKeyCrypto = exchangeKey?.key ?? (await this.primitives.AES.generateCryptoKey(false))\n const exchangeKeyBytes = exchangeKey !== undefined ? hex2ua(exchangeKey.raw) : await this.primitives.AES.exportKey(exchangeKeyCrypto, 'raw')\n const encryptedExchangeKey = await Object.entries(publicKeys).reduce(\n async (acc, [currKeyFp, currKey]) => ({\n ...(await acc),\n [currKeyFp]: ua2hex(await this.primitives.RSA.encrypt(currKey, new Uint8Array(exchangeKeyBytes))),\n }),\n Promise.resolve({} as { [pubKeyFp: string]: string })\n )\n return { exchangeKey: exchangeKeyCrypto, encryptedExchangeKey }\n }\n\n /**\n * Attempts to decrypt an exchange key using the provided key pairs.\n * If you are confident that the provided {@link keyPair} was used to encrypt {@link encryptedByOneKey} you should also provide {@link keyPairFp},\n * so that if the decryption fail an error will be logged to console before returning undefined.\n * @param encryptedByOneKey an exchange key which may be encrypted with {@link keyPair}.\n * @param keyPair an rsa key pair.\n * @param keyPairFp the fingerprint of the provided key pair or undefined to disable logging of error if the decryption failed.\n * @return the decrypted exchange key, in raw and key format (to allow deduplication), or undefined if the key could not be decrypted using the\n * provided key.\n */\n private async tryDecryptExchangeKeyWith(\n encryptedByOneKey: string,\n keyPair: KeyPair<CryptoKey>,\n keyPairFp: string | undefined // if undefined will not log errors, when we are not sure the key to be used is the provided key.\n ): Promise<{ raw: string; key: CryptoKey } | undefined> {\n try {\n const decrypted = await this.primitives.RSA.decrypt(keyPair.privateKey, hex2ua(encryptedByOneKey))\n return { raw: ua2hex(decrypted), key: await this.primitives.AES.importKey('raw', decrypted) }\n } catch (e) {\n if (keyPairFp) {\n console.error(`Failed to decrypt or import exchange key ${encryptedByOneKey} using key with fingerprint ${keyPairFp}.`, e)\n }\n }\n }\n\n private updateLegacyExchangeKeys(\n delegator: CryptoActorStubWithType,\n delegate: CryptoActorStubWithType,\n encryptedKeyMap: { [fp: string]: string }\n ): { [delegateId: string]: string[] } | undefined {\n const legacyEncryptedKeyDelegator = delegator.stub.publicKey ? encryptedKeyMap[delegator.stub.publicKey] : undefined\n const legacyEncryptedKeyDelegate = delegate.stub.publicKey ? encryptedKeyMap[delegate.stub.publicKey] : undefined\n if (legacyEncryptedKeyDelegator && legacyEncryptedKeyDelegate) {\n return {\n ...(delegator.stub.hcPartyKeys ?? {}),\n [delegate.stub.id!]: [legacyEncryptedKeyDelegator, legacyEncryptedKeyDelegate],\n }\n } else return delegator.stub.hcPartyKeys\n }\n\n // Copy all legacy hcp exchange keys into the new aes exchange keys\n private async combineLegacyHcpKeysWithAesExchangeKeys(\n owner: CryptoActorStub,\n delegate: CryptoActorStub | undefined\n ): Promise<{ [ownerPublicKey: string]: { [delegateId: string]: { [fingerprint: string]: string } } }> {\n const ownerLegacyPublicKey = owner.publicKey\n if (ownerLegacyPublicKey && !(owner.aesExchangeKeys ?? {})[ownerLegacyPublicKey]) {\n /*\n * This condition would technically prevent new updates to the hcPartyKeys to be migrated to the aes exchange keys, but since I can only update\n * data for self data owner and parent entities this is not an issue, because I will always be using the new api from now on and I won't have\n * a situation where the legacy keys are updated but the aes exchange keys are not.\n */\n const unknownDataOwnerCounterPartIds = Object.keys(owner.hcPartyKeys ?? {}).filter((x) => x !== owner.id && x !== delegate?.id)\n const counterPartsById = [\n owner,\n ...(delegate ? [delegate] : []),\n ...(await Promise.all(unknownDataOwnerCounterPartIds.map(async (cpid) => (await this.dataOwnerApi.getCryptoActorStub(cpid)).stub))),\n ].reduce((acc, dataOwner) => {\n acc[dataOwner.id!] = dataOwner\n return acc\n }, {} as { [id: string]: CryptoActorStub })\n return {\n [ownerLegacyPublicKey]: Object.entries(owner.hcPartyKeys ?? {}).reduce((acc, [hcpId, keys]) => {\n acc[hcpId] = { [ownerLegacyPublicKey.slice(-32)]: keys[0], [counterPartsById[hcpId]?.publicKey?.slice(-32) ?? '']: keys[1] }\n return acc\n }, {} as { [delegateId: string]: { [fingerprint: string]: string } }),\n ...(owner.aesExchangeKeys ?? {}),\n }\n } else return owner.aesExchangeKeys ?? {}\n }\n}\n"]}
1
+ {"version":3,"file":"BaseExchangeKeysManager.js","sourceRoot":"","sources":["../../../icc-x-api/crypto/BaseExchangeKeysManager.ts"],"names":[],"mappings":"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","sourcesContent":["import { KeyPair } from './RSA'\nimport { hex2ua, notConcurrent, ua2hex } from '../utils'\nimport { DataOwner, IccDataOwnerXApi } from '../icc-data-owner-x-api'\nimport { CryptoPrimitives } from './CryptoPrimitives'\nimport { IccDeviceApi, IccHcpartyApi, IccPatientApi } from '../../icc-api'\nimport { fingerprintV1, getShaVersionForKey } from './utils'\nimport { CryptoActorStub, CryptoActorStubWithType } from '../../icc-api/model/CryptoActorStub'\nimport { DataOwnerTypeEnum } from '../../icc-api/model/DataOwnerTypeEnum'\n\n/**\n * @internal This class is meant only for internal use and may be changed without notice.\n * Functions to create and get exchange keys.\n * The methods of this api require to pass the appropriate keys for encryption/decryption manually.\n */\nexport class BaseExchangeKeysManager {\n private readonly generateKeyConcurrencyMap: { [key: string]: PromiseLike<any> } = {}\n private readonly primitives: CryptoPrimitives\n private readonly dataOwnerApi: IccDataOwnerXApi\n private readonly hcpartyBaseApi: IccHcpartyApi\n private readonly patientBaseApi: IccPatientApi\n private readonly deviceBaseApi: IccDeviceApi\n\n constructor(\n primitives: CryptoPrimitives,\n dataOwnerApi: IccDataOwnerXApi,\n hcpartyBaseApi: IccHcpartyApi,\n patientBaseApi: IccPatientApi,\n deviceBaseApi: IccDeviceApi\n ) {\n this.primitives = primitives\n this.dataOwnerApi = dataOwnerApi\n this.hcpartyBaseApi = hcpartyBaseApi\n this.patientBaseApi = patientBaseApi\n this.deviceBaseApi = deviceBaseApi\n }\n\n /**\n * Updates the aes exchange keys between the current data owner and another data owner to allow the other data owner to access the exchange key\n * using his new public key. Note that this will make existing exchange keys from the other data owner to the current data owner invalid for\n * encryption.\n * @param otherDataOwner the other data owner.\n * @param newDataOwnerPublicKey a new public key of the other data owner.\n * @param keyPairsByFingerprint all available key pairs to use for the decryption of existing aes exchange keys.\n */\n async giveAccessBackTo(\n otherDataOwner: string,\n newDataOwnerPublicKey: string,\n keyPairsByFingerprint: { [publicKeyFingerprint: string]: KeyPair<CryptoKey> }\n ) {\n const selfId = await this.dataOwnerApi.getCurrentDataOwnerId()\n const other = await this.dataOwnerApi.getCryptoActorStub(otherDataOwner)\n const newKeyHashVersion = getShaVersionForKey(other.stub, newDataOwnerPublicKey)\n if (!newKeyHashVersion) throw new Error(`Public key not found for data owner ${otherDataOwner}`)\n const newPublicKey = await this.primitives.RSA.importKey('spki', hex2ua(newDataOwnerPublicKey), ['encrypt'], newKeyHashVersion)\n await this.extendForGiveAccessBackTo(selfId, otherDataOwner, fingerprintV1(newDataOwnerPublicKey), newPublicKey, keyPairsByFingerprint)\n await this.extendForGiveAccessBackTo(otherDataOwner, selfId, fingerprintV1(newDataOwnerPublicKey), newPublicKey, keyPairsByFingerprint)\n }\n\n /**\n * Get the encrypted exchange keys for a delegator-delegate pair.\n * @param delegatorId id of the delegator data owner.\n * @param delegateId id of the delegate data owner.\n * @return an array of exchange keys from the delegator to delegate where each key is encrypted with one or more public keys.\n */\n async getEncryptedExchangeKeysFor(delegatorId: string, delegateId: string): Promise<{ [publicKeyFingerprint: string]: string }[]> {\n const delegator = await this.dataOwnerApi.getCryptoActorStub(delegatorId)\n const res: { [publicKeyFingerprint: string]: string }[] = Object.values(delegator.stub.aesExchangeKeys ?? {}).flatMap((delegateToKey) => {\n const encryptedKeyForDelegate = delegateToKey[delegateId]\n if (encryptedKeyForDelegate) {\n return [encryptedKeyForDelegate]\n } else {\n return []\n }\n })\n const legacyDelegation = delegator.stub.hcPartyKeys?.[delegateId]?.[1]\n if (legacyDelegation) res.push({ '': legacyDelegation })\n return res\n }\n\n /**\n * Get all exchange keys where the provided data owner is involved either as the delegator or as the delegate.\n * @param dataOwnerId id of a data owner.\n * @param otherOwnerTypes only exchange keys between the current data owner and data owners of this type will be included in the result.\n * @return all exchange keys involving the provided data owner. Note that there may be an overlap between some keys to and from the data owner.\n */\n async getAllExchangeKeysWith(\n dataOwnerId: string,\n otherOwnerTypes: DataOwnerTypeEnum[]\n ): Promise<{\n keysToOwner: { [delegatorId: string]: { [delegatorFp: string]: { [entryFp: string]: string } } }\n keysFromOwner: { [delegatorFp: string]: { [delegateId: string]: { [entryFp: string]: string } } }\n }> {\n if (otherOwnerTypes.length === 0) throw new Error('otherOwnerTypes must not be empty!')\n const keysToOwner = await Promise.all([\n otherOwnerTypes.find((x) => x === 'hcp') ? this.hcpartyBaseApi.getAesExchangeKeysForDelegate(dataOwnerId).catch(() => {}) : Promise.resolve({}),\n otherOwnerTypes.find((x) => x === 'patient')\n ? this.patientBaseApi.getPatientAesExchangeKeysForDelegate(dataOwnerId).catch(() => {})\n : Promise.resolve({}),\n otherOwnerTypes.find((x) => x === 'device')\n ? this.deviceBaseApi.getDeviceAesExchangeKeysForDelegate(dataOwnerId).catch(() => {})\n : Promise.resolve({}),\n ]).then(([a, b, c]) => ({ ...a, ...b, ...c } as { [delegatorId: string]: { [delegatorFp: string]: { [entryFp: string]: string } } }))\n const dataOwner = await this.dataOwnerApi.getCryptoActorStub(dataOwnerId)\n const allOwnerKeys = await this.combineLegacyHcpKeysWithAesExchangeKeys(dataOwner.stub, undefined)\n const filteredDelegates = new Set(\n await Array.from(new Set(Object.values(allOwnerKeys).flatMap((x) => Object.keys(x)))).reduce(async (acc, ownerId) => {\n const awaitedAcc = await acc\n if (ownerId === dataOwnerId) {\n return [...awaitedAcc, ownerId]\n } else {\n const dataOwnerType: DataOwnerTypeEnum = (await this.dataOwnerApi.getCryptoActorStub(ownerId)).type\n if (otherOwnerTypes.some((x) => x === dataOwnerType)) {\n return [...awaitedAcc, ownerId]\n } else return awaitedAcc\n }\n }, Promise.resolve([] as string[]))\n )\n const keysFromOwner = Object.fromEntries(\n Object.entries(allOwnerKeys)\n .map(([delegatorPubKey, delegateToKeys]) => [\n delegatorPubKey,\n Object.fromEntries(\n Object.entries(delegateToKeys).filter(([delegateId]) => filteredDelegates.has(delegateId)) as [string, { [k: string]: string }][]\n ),\n ])\n .filter(([, x]) => Object.keys(x).length > 0) as [string, { [k: string]: { [k: string]: string } }][]\n )\n return { keysToOwner, keysFromOwner }\n }\n\n /**\n * Attempts to decrypt many exchange keys using any of the provided key pairs.\n * @param encryptedExchangeKeys an array of exchange keys where each key is encrypted with one or more public keys.\n * @param keyPairsByFingerprint rsa key pairs to use for decryption.\n * @return an array all successfully decrypted exchange keys and an array containing all exchange keys which could not be decrypted.\n */\n async tryDecryptExchangeKeys(\n encryptedExchangeKeys: { [publicKeyFingerprint: string]: string }[],\n keyPairsByFingerprint: { [publicKeyFingerprint: string]: KeyPair<CryptoKey> }\n ): Promise<{\n successfulDecryptions: CryptoKey[]\n failedDecryptions: { [publicKeyFingerprint: string]: string }[]\n }> {\n const raws = new Set<string>()\n const res: {\n successfulDecryptions: CryptoKey[]\n failedDecryptions: { [publicKeyFingerprint: string]: string }[]\n } = { successfulDecryptions: [], failedDecryptions: [] }\n for (const encryptedExchangeKey of encryptedExchangeKeys) {\n const decrypted = await this.tryDecryptExchangeKey(encryptedExchangeKey, keyPairsByFingerprint)\n if (decrypted !== undefined && !raws.has(decrypted.raw)) {\n raws.add(decrypted.raw)\n res.successfulDecryptions.push(decrypted.key)\n } else {\n res.failedDecryptions.push(encryptedExchangeKey)\n }\n }\n return res\n }\n\n private async extendForGiveAccessBackTo(\n delegatorId: string,\n delegateId: string,\n newPublicKeyFp: string,\n newPublicKey: CryptoKey,\n decryptionKeyPairsByFingerprint: { [publicKeyFingerprint: string]: KeyPair<CryptoKey> }\n ) {\n await notConcurrent(this.generateKeyConcurrencyMap, delegatorId, async () => {\n const delegator = await this.dataOwnerApi.getCryptoActorStub(delegatorId)\n const delegate = await this.dataOwnerApi.getCryptoActorStub(delegateId)\n let didUpdateSomeKey = false\n const combinedKeys = await this.combineLegacyHcpKeysWithAesExchangeKeys(delegator.stub, delegate.stub)\n const updatedExchangeKeys: { [delegatorKey: string]: { [delegateId: string]: { [keyFp: string]: string } } } = {}\n const newEncryptionKeys = { [newPublicKeyFp]: newPublicKey }\n for (const [currDelegatorKey, currDelegatesToKeys] of Object.entries(combinedKeys)) {\n const updatedDelegatesToKeys: { [delegateId: string]: { [keyFp: string]: string } } = {}\n for (const [currDelegateId, currEncryptedKey] of Object.entries(currDelegatesToKeys)) {\n if (delegateId !== currDelegateId || newPublicKeyFp in currEncryptedKey) {\n updatedDelegatesToKeys[currDelegateId] = currEncryptedKey\n } else {\n const decrypted = await this.tryDecryptExchangeKey(currEncryptedKey, decryptionKeyPairsByFingerprint)\n if (decrypted) {\n didUpdateSomeKey = true\n updatedDelegatesToKeys[currDelegateId] = {\n ...currEncryptedKey,\n ...(await this.encryptExchangeKey(decrypted, newEncryptionKeys)).encryptedExchangeKey,\n }\n } else {\n updatedDelegatesToKeys[currDelegateId] = currEncryptedKey\n }\n }\n }\n updatedExchangeKeys[currDelegatorKey] = updatedDelegatesToKeys\n }\n if (didUpdateSomeKey) {\n await this.dataOwnerApi.modifyCryptoActorStub({\n type: delegator.type,\n stub: {\n ...delegator.stub,\n aesExchangeKeys: updatedExchangeKeys,\n },\n })\n }\n })\n }\n\n /**\n * Attempts to decrypt an exchange key using any of the provided key pairs.\n * @param encryptedExchangeKey an encrypted exchange key, in the form publicKeyXyzFingerprint -> hex(exchangeKeyEncryptedByPrivateKeyXyz).\n * @param keyPairsByFingerprint rsa key pairs to use for decryption.\n * @return the decrypted exchange key, in raw and key format (to allow deduplication), or undefined if the key could not be decrypted using the\n * provided keys.\n */\n private async tryDecryptExchangeKey(\n encryptedExchangeKey: { [publicKeyFingerprint: string]: string },\n keyPairsByFingerprint: { [publicKeyFingerprint: string]: KeyPair<CryptoKey> }\n ): Promise<{ raw: string; key: CryptoKey } | undefined> {\n for (const [entryKey, encrypted] of Object.entries(encryptedExchangeKey)) {\n // Due to bugs in past version the entry may actually contain the full public key instead of just the fingerprint.\n const fp = fingerprintV1(entryKey)\n const keyPair = keyPairsByFingerprint[fp]\n if (keyPair !== undefined) {\n const res = await this.tryDecryptExchangeKeyWith(encrypted, keyPair, fp)\n if (res !== undefined) return res\n }\n }\n const defaultEncryptedKey = encryptedExchangeKey['']\n if (defaultEncryptedKey !== undefined) {\n for (const keyPair of Object.values(keyPairsByFingerprint)) {\n // disable error logging, we are not sure keyPair is the correct key\n const res = await this.tryDecryptExchangeKeyWith(defaultEncryptedKey, keyPair, undefined)\n if (res !== undefined) return res\n }\n }\n return undefined\n }\n\n /**\n * Creates an encrypted exchange key for the provided public keys.\n * @param exchangeKey the exchange key in raw and imported format. If undefined a new key will be automatically created.\n * @param publicKeys additional public keys that will have access to the exchange key in spki format, hex-encoded.\n * @return the exchangeKey and an object with the exchange key encrypted with each of the provided public keys, hex-encoded, by fingerprint.\n */\n private async encryptExchangeKey(\n exchangeKey: { raw: string; key: CryptoKey } | undefined,\n publicKeys: { [keyFingerprint: string]: CryptoKey }\n ): Promise<{\n exchangeKey: CryptoKey\n encryptedExchangeKey: { [pubKeyFp: string]: string }\n }> {\n const exchangeKeyCrypto = exchangeKey?.key ?? (await this.primitives.AES.generateCryptoKey(false))\n const exchangeKeyBytes = exchangeKey !== undefined ? hex2ua(exchangeKey.raw) : await this.primitives.AES.exportKey(exchangeKeyCrypto, 'raw')\n const encryptedExchangeKey = await Object.entries(publicKeys).reduce(\n async (acc, [currKeyFp, currKey]) => ({\n ...(await acc),\n [currKeyFp]: ua2hex(await this.primitives.RSA.encrypt(currKey, new Uint8Array(exchangeKeyBytes))),\n }),\n Promise.resolve({} as { [pubKeyFp: string]: string })\n )\n return { exchangeKey: exchangeKeyCrypto, encryptedExchangeKey }\n }\n\n /**\n * Attempts to decrypt an exchange key using the provided key pairs.\n * If you are confident that the provided {@link keyPair} was used to encrypt {@link encryptedByOneKey} you should also provide {@link keyPairFp},\n * so that if the decryption fail an error will be logged to console before returning undefined.\n * @param encryptedByOneKey an exchange key which may be encrypted with {@link keyPair}.\n * @param keyPair an rsa key pair.\n * @param keyPairFp the fingerprint of the provided key pair or undefined to disable logging of error if the decryption failed.\n * @return the decrypted exchange key, in raw and key format (to allow deduplication), or undefined if the key could not be decrypted using the\n * provided key.\n */\n private async tryDecryptExchangeKeyWith(\n encryptedByOneKey: string,\n keyPair: KeyPair<CryptoKey>,\n keyPairFp: string | undefined // if undefined will not log errors, when we are not sure the key to be used is the provided key.\n ): Promise<{ raw: string; key: CryptoKey } | undefined> {\n try {\n const decrypted = await this.primitives.RSA.decrypt(keyPair.privateKey, hex2ua(encryptedByOneKey))\n return { raw: ua2hex(decrypted), key: await this.primitives.AES.importKey('raw', decrypted) }\n } catch (e) {\n if (keyPairFp) {\n console.error(`Failed to decrypt or import exchange key ${encryptedByOneKey} using key with fingerprint ${keyPairFp}.`, e)\n }\n }\n }\n\n private updateLegacyExchangeKeys(\n delegator: CryptoActorStubWithType,\n delegate: CryptoActorStubWithType,\n encryptedKeyMap: { [fp: string]: string }\n ): { [delegateId: string]: string[] } | undefined {\n const legacyEncryptedKeyDelegator = delegator.stub.publicKey ? encryptedKeyMap[delegator.stub.publicKey] : undefined\n const legacyEncryptedKeyDelegate = delegate.stub.publicKey ? encryptedKeyMap[delegate.stub.publicKey] : undefined\n if (legacyEncryptedKeyDelegator && legacyEncryptedKeyDelegate) {\n return {\n ...(delegator.stub.hcPartyKeys ?? {}),\n [delegate.stub.id!]: [legacyEncryptedKeyDelegator, legacyEncryptedKeyDelegate],\n }\n } else return delegator.stub.hcPartyKeys\n }\n\n // Copy all legacy hcp exchange keys into the new aes exchange keys\n private async combineLegacyHcpKeysWithAesExchangeKeys(\n owner: CryptoActorStub,\n delegate: CryptoActorStub | undefined\n ): Promise<{ [ownerPublicKey: string]: { [delegateId: string]: { [fingerprint: string]: string } } }> {\n const ownerLegacyPublicKey = owner.publicKey\n if (ownerLegacyPublicKey && !(owner.aesExchangeKeys ?? {})[ownerLegacyPublicKey]) {\n /*\n * This condition would technically prevent new updates to the hcPartyKeys to be migrated to the aes exchange keys, but since I can only update\n * data for self data owner and parent entities this is not an issue, because I will always be using the new api from now on and I won't have\n * a situation where the legacy keys are updated but the aes exchange keys are not.\n */\n const unknownDataOwnerCounterPartIds = Object.keys(owner.hcPartyKeys ?? {}).filter((x) => x !== owner.id && x !== delegate?.id)\n const counterPartsById = [\n owner,\n ...(delegate ? [delegate] : []),\n ...(await Promise.all(unknownDataOwnerCounterPartIds.map(async (cpid) => (await this.dataOwnerApi.getCryptoActorStub(cpid)).stub))),\n ].reduce((acc, dataOwner) => {\n acc[dataOwner.id!] = dataOwner\n return acc\n }, {} as { [id: string]: CryptoActorStub })\n return {\n [ownerLegacyPublicKey]: Object.entries(owner.hcPartyKeys ?? {}).reduce((acc, [hcpId, keys]) => {\n const counterpartKey = counterPartsById[hcpId]?.publicKey\n acc[hcpId] = {\n [fingerprintV1(ownerLegacyPublicKey)]: keys[0],\n [(counterpartKey && fingerprintV1(counterpartKey)) ?? '']: keys[1],\n }\n return acc\n }, {} as { [delegateId: string]: { [fingerprint: string]: string } }),\n ...(owner.aesExchangeKeys ?? {}),\n }\n } else return owner.aesExchangeKeys ?? {}\n }\n}\n"]}
@@ -85,7 +85,7 @@ class KeyRecovery {
85
85
  Object.keys(dataOwner.dataOwner.privateKeyShamirPartitions).length > 0) {
86
86
  const selfId = dataOwner.dataOwner.id;
87
87
  const shamirSplits = {
88
- [dataOwner.dataOwner.publicKey.slice(-32)]: dataOwner.dataOwner.privateKeyShamirPartitions,
88
+ [(0, utils_2.fingerprintV1)(dataOwner.dataOwner.publicKey)]: dataOwner.dataOwner.privateKeyShamirPartitions,
89
89
  };
90
90
  const delegatesOfSplits = Array.from(new Set(Object.entries(shamirSplits).flatMap(([splitKeyFp, splitKeyData]) => (missingKeysFp.has(splitKeyFp) ? Object.keys(splitKeyData) : []))));
91
91
  const exchangeKeys = {};
@@ -1 +1 @@
1
- {"version":3,"file":"KeyRecovery.js","sourceRoot":"","sources":["../../../icc-x-api/crypto/KeyRecovery.ts"],"names":[],"mappings":"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","sourcesContent":["import { IccDataOwnerXApi } from '../icc-data-owner-x-api'\nimport { KeyPair, ShaVersion } from './RSA'\nimport { CryptoPrimitives } from './CryptoPrimitives'\nimport { BaseExchangeKeysManager } from './BaseExchangeKeysManager'\nimport { hex2ua, ua2hex } from '../utils'\nimport { fingerprintToPublicKeysMapOf, fingerprintV1, getShaVersionForKey } from './utils'\nimport { BaseExchangeDataManager } from './BaseExchangeDataManager'\nimport { DataOwnerWithType } from '../../icc-api/model/DataOwnerWithType'\n\n/**\n * @internal this class is intended only for internal use and may be changed without notice.\n *\n */\nexport class KeyRecovery {\n constructor(\n private readonly primitives: CryptoPrimitives,\n private readonly dataOwnerApi: IccDataOwnerXApi,\n private readonly baseExchangeKeysManager: BaseExchangeKeysManager,\n private readonly baseExchangeDataManager: BaseExchangeDataManager\n ) {}\n\n /*TODO\n * Currently there is no support for the recovery of signature keys. When implementing a recovery solution we should consider:\n * - unlike decryption keys signature keys are completely useless if not verified.\n * - we are fine losing the signature private key, but if we could recover and verify the public key it would reduce the inconveniences on user and\n * limit the creation of new exchange data\n * - We can't guarantee that encrypted data in iCure was put there by us... unless we put a piece of the private key as well: we can save an\n * hash of (any verification public key + any encryption private key) in the data owner: only the owner of the private key can create this hash,\n * so if the data owner can recreate the hash with one of his recovered and verified encryption private keys then the signature public key will\n * for sure be safe as well.\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([\n ...this.dataOwnerApi.getHexPublicKeysWithSha1Of(dataOwner.dataOwner),\n ...this.dataOwnerApi.getHexPublicKeysWithSha256Of(dataOwner.dataOwner),\n ])\n const knownKeysFpSet = new Set(Object.keys(knownKeys))\n const missingKeysFpSet = new Set(selfPublicKeys.map((x) => fingerprintV1(x)).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 exchangeKeys[delegate] = await this.getExchangeKeys(selfId, delegate, allKeys)\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, ShaVersion.Sha1)\n const keysByFpWithSha256 = fingerprintToPublicKeysMapOf(dataOwner.dataOwner, ShaVersion.Sha256)\n for (const [fp, split] of Object.entries(splits)) {\n const pub = keysByFp[fp] ?? keysByFpWithSha256[fp]\n const shaVersion = !!pub && !!keysByFp[fp] ? ShaVersion.Sha1 : !!pub && !!keysByFpWithSha256[fp] ? ShaVersion.Sha256 : undefined\n if (!!pub && !!shaVersion) {\n const recovered = await this.tryRecoverSplitPrivate(split, exchangeKeys, shaVersion)\n if (recovered) {\n const pub = keysByFp[fp]\n try {\n res[fp] = {\n privateKey: recovered,\n publicKey: await this.primitives.RSA.importKey('spki', hex2ua(pub), ['encrypt'], shaVersion),\n }\n } catch (e) {\n console.warn(`Failed to import public key ${pub}`, e)\n }\n }\n } else {\n console.warn(`Missing public key for fingerprint ${fp} of recovered shamir key.`)\n }\n }\n return res\n }\n\n private async tryRecoverSplitPrivate(\n split: { [delegateId: string]: string },\n exchangeKeys: { [delegateId: string]: CryptoKey[] },\n shaVersion: ShaVersion\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'], shaVersion)\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'], shaVersion)\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 = {\n ...fingerprintToPublicKeysMapOf(dataOwner.dataOwner, ShaVersion.Sha1),\n ...fingerprintToPublicKeysMapOf(dataOwner.dataOwner, ShaVersion.Sha256),\n }\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 = fingerprintV1(transferToPublicKey) // 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 const availableExchangeKeys = await this.getExchangeKeys(dataOwner.dataOwner.id!, dataOwner.dataOwner.id!, allKeys)\n\n return Object.entries(missingKeysTransferData).reduce(async (acc, [recoverableKeyPubFp, transferData]) => {\n const awaitedAcc = await acc\n const shaVersion = getShaVersionForKey(dataOwner.dataOwner, transferData.publicKey)\n if (!!shaVersion) {\n const decryptedTransferData = await this.tryDecryptTransferData(transferData, availableExchangeKeys, shaVersion)\n if (decryptedTransferData != undefined) {\n return { ...awaitedAcc, [recoverableKeyPubFp]: decryptedTransferData }\n } else return awaitedAcc\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 shaVersion: ShaVersion\n ): Promise<KeyPair<CryptoKey> | undefined> {\n for (const encryptedTransferKey of transferData.encryptedPrivateKey) {\n const decryptedTransferKey = await this.tryDecryptTransferKey(encryptedTransferKey, availableExchangeKeys, shaVersion)\n if (decryptedTransferKey != undefined)\n return {\n privateKey: decryptedTransferKey,\n publicKey: await this.primitives.RSA.importKey('spki', hex2ua(transferData.publicKey), ['encrypt'], shaVersion),\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 shaVersion: ShaVersion\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, shaVersion)\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 // Get exchange keys from aes exchange keys / hc party keys and exchange data\n private async getExchangeKeys(\n from: string,\n to: string,\n availableDecryptionKeys: { [pubKeyFingerprint: string]: KeyPair<CryptoKey> }\n ): Promise<CryptoKey[]> {\n const aesExchangeKeys = await this.baseExchangeKeysManager.tryDecryptExchangeKeys(\n await this.baseExchangeKeysManager.getEncryptedExchangeKeysFor(from, to),\n availableDecryptionKeys\n )\n const decryptedExchangeDataKeys = await this.baseExchangeDataManager.tryDecryptExchangeKeys(\n await this.baseExchangeDataManager.getExchangeDataByDelegatorDelegatePair(from, to),\n availableDecryptionKeys\n )\n return [...aesExchangeKeys.successfulDecryptions, ...decryptedExchangeDataKeys.successfulDecryptions]\n }\n}\n"]}
1
+ {"version":3,"file":"KeyRecovery.js","sourceRoot":"","sources":["../../../icc-x-api/crypto/KeyRecovery.ts"],"names":[],"mappings":"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","sourcesContent":["import { IccDataOwnerXApi } from '../icc-data-owner-x-api'\nimport { KeyPair, ShaVersion } from './RSA'\nimport { CryptoPrimitives } from './CryptoPrimitives'\nimport { BaseExchangeKeysManager } from './BaseExchangeKeysManager'\nimport { hex2ua, ua2hex } from '../utils'\nimport { fingerprintToPublicKeysMapOf, fingerprintV1, getShaVersionForKey } from './utils'\nimport { BaseExchangeDataManager } from './BaseExchangeDataManager'\nimport { DataOwnerWithType } from '../../icc-api/model/DataOwnerWithType'\n\n/**\n * @internal this class is intended only for internal use and may be changed without notice.\n *\n */\nexport class KeyRecovery {\n constructor(\n private readonly primitives: CryptoPrimitives,\n private readonly dataOwnerApi: IccDataOwnerXApi,\n private readonly baseExchangeKeysManager: BaseExchangeKeysManager,\n private readonly baseExchangeDataManager: BaseExchangeDataManager\n ) {}\n\n /*TODO\n * Currently there is no support for the recovery of signature keys. When implementing a recovery solution we should consider:\n * - unlike decryption keys signature keys are completely useless if not verified.\n * - we are fine losing the signature private key, but if we could recover and verify the public key it would reduce the inconveniences on user and\n * limit the creation of new exchange data\n * - We can't guarantee that encrypted data in iCure was put there by us... unless we put a piece of the private key as well: we can save an\n * hash of (any verification public key + any encryption private key) in the data owner: only the owner of the private key can create this hash,\n * so if the data owner can recreate the hash with one of his recovered and verified encryption private keys then the signature public key will\n * for sure be safe as well.\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([\n ...this.dataOwnerApi.getHexPublicKeysWithSha1Of(dataOwner.dataOwner),\n ...this.dataOwnerApi.getHexPublicKeysWithSha256Of(dataOwner.dataOwner),\n ])\n const knownKeysFpSet = new Set(Object.keys(knownKeys))\n const missingKeysFpSet = new Set(selfPublicKeys.map((x) => fingerprintV1(x)).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 [fingerprintV1(dataOwner.dataOwner.publicKey!)]: 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 exchangeKeys[delegate] = await this.getExchangeKeys(selfId, delegate, allKeys)\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, ShaVersion.Sha1)\n const keysByFpWithSha256 = fingerprintToPublicKeysMapOf(dataOwner.dataOwner, ShaVersion.Sha256)\n for (const [fp, split] of Object.entries(splits)) {\n const pub = keysByFp[fp] ?? keysByFpWithSha256[fp]\n const shaVersion = !!pub && !!keysByFp[fp] ? ShaVersion.Sha1 : !!pub && !!keysByFpWithSha256[fp] ? ShaVersion.Sha256 : undefined\n if (!!pub && !!shaVersion) {\n const recovered = await this.tryRecoverSplitPrivate(split, exchangeKeys, shaVersion)\n if (recovered) {\n const pub = keysByFp[fp]\n try {\n res[fp] = {\n privateKey: recovered,\n publicKey: await this.primitives.RSA.importKey('spki', hex2ua(pub), ['encrypt'], shaVersion),\n }\n } catch (e) {\n console.warn(`Failed to import public key ${pub}`, e)\n }\n }\n } else {\n console.warn(`Missing public key for fingerprint ${fp} of recovered shamir key.`)\n }\n }\n return res\n }\n\n private async tryRecoverSplitPrivate(\n split: { [delegateId: string]: string },\n exchangeKeys: { [delegateId: string]: CryptoKey[] },\n shaVersion: ShaVersion\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'], shaVersion)\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'], shaVersion)\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 = {\n ...fingerprintToPublicKeysMapOf(dataOwner.dataOwner, ShaVersion.Sha1),\n ...fingerprintToPublicKeysMapOf(dataOwner.dataOwner, ShaVersion.Sha256),\n }\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 = fingerprintV1(transferToPublicKey) // 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 const availableExchangeKeys = await this.getExchangeKeys(dataOwner.dataOwner.id!, dataOwner.dataOwner.id!, allKeys)\n\n return Object.entries(missingKeysTransferData).reduce(async (acc, [recoverableKeyPubFp, transferData]) => {\n const awaitedAcc = await acc\n const shaVersion = getShaVersionForKey(dataOwner.dataOwner, transferData.publicKey)\n if (!!shaVersion) {\n const decryptedTransferData = await this.tryDecryptTransferData(transferData, availableExchangeKeys, shaVersion)\n if (decryptedTransferData != undefined) {\n return { ...awaitedAcc, [recoverableKeyPubFp]: decryptedTransferData }\n } else return awaitedAcc\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 shaVersion: ShaVersion\n ): Promise<KeyPair<CryptoKey> | undefined> {\n for (const encryptedTransferKey of transferData.encryptedPrivateKey) {\n const decryptedTransferKey = await this.tryDecryptTransferKey(encryptedTransferKey, availableExchangeKeys, shaVersion)\n if (decryptedTransferKey != undefined)\n return {\n privateKey: decryptedTransferKey,\n publicKey: await this.primitives.RSA.importKey('spki', hex2ua(transferData.publicKey), ['encrypt'], shaVersion),\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 shaVersion: ShaVersion\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, shaVersion)\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 // Get exchange keys from aes exchange keys / hc party keys and exchange data\n private async getExchangeKeys(\n from: string,\n to: string,\n availableDecryptionKeys: { [pubKeyFingerprint: string]: KeyPair<CryptoKey> }\n ): Promise<CryptoKey[]> {\n const aesExchangeKeys = await this.baseExchangeKeysManager.tryDecryptExchangeKeys(\n await this.baseExchangeKeysManager.getEncryptedExchangeKeysFor(from, to),\n availableDecryptionKeys\n )\n const decryptedExchangeDataKeys = await this.baseExchangeDataManager.tryDecryptExchangeKeys(\n await this.baseExchangeDataManager.getExchangeDataByDelegatorDelegatePair(from, to),\n availableDecryptionKeys\n )\n return [...aesExchangeKeys.successfulDecryptions, ...decryptedExchangeDataKeys.successfulDecryptions]\n }\n}\n"]}
@@ -12,6 +12,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.ShamirKeysManager = void 0;
13
13
  const utils_1 = require("../utils");
14
14
  const CryptoActorStub_1 = require("../../icc-api/model/CryptoActorStub");
15
+ const utils_2 = require("./utils");
15
16
  /**
16
17
  * Allows to create or update shamir split keys.
17
18
  */
@@ -29,10 +30,10 @@ class ShamirKeysManager {
29
30
  * @return the existing splits for the current data owner as a publicKeyFingerprint -> notariesIds object
30
31
  */
31
32
  getExistingSplitsInfo(dataOwner) {
32
- var _a, _b;
33
+ var _a;
33
34
  const legacyPartitionDelegates = Object.keys((_a = dataOwner.privateKeyShamirPartitions) !== null && _a !== void 0 ? _a : {});
34
35
  if (legacyPartitionDelegates.length > 0) {
35
- const fp = (_b = dataOwner.publicKey) === null || _b === void 0 ? void 0 : _b.slice(-32);
36
+ const fp = dataOwner.publicKey && (0, utils_2.fingerprintV1)(dataOwner.publicKey);
36
37
  if (!fp) {
37
38
  console.error('Invalid data owner: the owner has legacy key partitions but no legacy key.');
38
39
  }
@@ -53,8 +54,8 @@ class ShamirKeysManager {
53
54
  updateSelfSplits(keySplitsToUpdate, keySplitsToDelete) {
54
55
  return __awaiter(this, void 0, void 0, function* () {
55
56
  const self = CryptoActorStub_1.CryptoActorStubWithType.fromDataOwner(yield this.dataOwnerApi.getCurrentDataOwner());
56
- const toUpdateSet = new Set(Object.keys(keySplitsToUpdate).map((x) => x.slice(-32)));
57
- const toDeleteSet = new Set(keySplitsToDelete.slice(-32));
57
+ const toUpdateSet = new Set(Object.keys(keySplitsToUpdate).map((x) => (0, utils_2.fingerprintV1)(x)));
58
+ const toDeleteSet = new Set(Object.keys(keySplitsToDelete).map((x) => (0, utils_2.fingerprintV1)(x)));
58
59
  const intersection = Array.from(toDeleteSet).filter((x) => toUpdateSet.has(x));
59
60
  const existingSplits = new Set(Object.keys(this.getExistingSplitsInfo(self.stub)));
60
61
  const allKeys = this.encryptionKeysManager.getDecryptionKeys();
@@ -74,7 +75,7 @@ class ShamirKeysManager {
74
75
  delegatesKeys[delegateId] = res.exchangeKey;
75
76
  }
76
77
  for (const [key, params] of Object.entries(keySplitsToUpdate)) {
77
- updatedSelf = yield this.updateKeySplit(updatedSelf, key.slice(-32), params.notariesIds, params.minShares, delegatesKeys, allKeys);
78
+ updatedSelf = yield this.updateKeySplit(updatedSelf, (0, utils_2.fingerprintV1)(key), params.notariesIds, params.minShares, delegatesKeys, allKeys);
78
79
  }
79
80
  for (const keyFp of toDeleteSet) {
80
81
  updatedSelf = this.deleteKeySplit(updatedSelf, keyFp);
@@ -95,8 +96,7 @@ class ShamirKeysManager {
95
96
  throw new Error(`Invalid parameters for key ${key}: must have at least one delegate. ${params}`);
96
97
  }
97
98
  deleteKeySplit(dataOwner, keyFp) {
98
- var _a;
99
- if (keyFp !== ((_a = dataOwner.stub.publicKey) === null || _a === void 0 ? void 0 : _a.slice(-32))) {
99
+ if (!dataOwner.stub.publicKey || keyFp !== (0, utils_2.fingerprintV1)(dataOwner.stub.publicKey)) {
100
100
  throw new Error('Currently it is possible to use shamir splits only for the legacy public key');
101
101
  }
102
102
  return {
@@ -105,9 +105,8 @@ class ShamirKeysManager {
105
105
  };
106
106
  }
107
107
  updateKeySplit(dataOwner, keyFp, delegateIds, minShares, delegatesKeys, allKeys) {
108
- var _a;
109
108
  return __awaiter(this, void 0, void 0, function* () {
110
- if (keyFp !== ((_a = dataOwner.stub.publicKey) === null || _a === void 0 ? void 0 : _a.slice(-32))) {
109
+ if (!dataOwner.stub.publicKey || keyFp !== (0, utils_2.fingerprintV1)(dataOwner.stub.publicKey)) {
111
110
  throw new Error('Currently it is possible to use shamir splits only for the legacy public key');
112
111
  }
113
112
  return {