@icure/api 7.0.0-beta.2 → 7.0.0-beta.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/icc-api/api/IccAccesslogApi.js +2 -1
- package/icc-api/api/IccAccesslogApi.js.map +1 -1
- package/icc-api/api/IccAgendaApi.js +2 -1
- package/icc-api/api/IccAgendaApi.js.map +1 -1
- package/icc-api/api/IccAnonymousAccessApi.js +2 -1
- package/icc-api/api/IccAnonymousAccessApi.js.map +1 -1
- package/icc-api/api/IccApplicationsettingsApi.js +2 -1
- package/icc-api/api/IccApplicationsettingsApi.js.map +1 -1
- package/icc-api/api/IccArticleApi.js +2 -1
- package/icc-api/api/IccArticleApi.js.map +1 -1
- package/icc-api/api/IccAuthApi.d.ts +23 -0
- package/icc-api/api/IccAuthApi.js +59 -2
- package/icc-api/api/IccAuthApi.js.map +1 -1
- package/icc-api/api/IccBeefactApi.js +2 -1
- package/icc-api/api/IccBeefactApi.js.map +1 -1
- package/icc-api/api/IccBekmehrApi.js +2 -1
- package/icc-api/api/IccBekmehrApi.js.map +1 -1
- package/icc-api/api/IccBeresultexportApi.js +2 -1
- package/icc-api/api/IccBeresultexportApi.js.map +1 -1
- package/icc-api/api/IccBeresultimportApi.js +2 -1
- package/icc-api/api/IccBeresultimportApi.js.map +1 -1
- package/icc-api/api/IccBesamv2Api.d.ts +6 -0
- package/icc-api/api/IccBesamv2Api.js +15 -1
- package/icc-api/api/IccBesamv2Api.js.map +1 -1
- package/icc-api/api/IccCalendarItemApi.js +2 -1
- package/icc-api/api/IccCalendarItemApi.js.map +1 -1
- package/icc-api/api/IccCalendarItemTypeApi.js +2 -1
- package/icc-api/api/IccCalendarItemTypeApi.js.map +1 -1
- package/icc-api/api/IccClassificationApi.js +2 -1
- package/icc-api/api/IccClassificationApi.js.map +1 -1
- package/icc-api/api/IccClassificationTemplateApi.js +2 -1
- package/icc-api/api/IccClassificationTemplateApi.js.map +1 -1
- package/icc-api/api/IccCodeApi.js +2 -1
- package/icc-api/api/IccCodeApi.js.map +1 -1
- package/icc-api/api/IccContactApi.d.ts +6 -0
- package/icc-api/api/IccContactApi.js +26 -1
- package/icc-api/api/IccContactApi.js.map +1 -1
- package/icc-api/api/IccDataownerApi.d.ts +13 -2
- package/icc-api/api/IccDataownerApi.js +32 -5
- package/icc-api/api/IccDataownerApi.js.map +1 -1
- package/icc-api/api/IccDeviceApi.js +2 -1
- package/icc-api/api/IccDeviceApi.js.map +1 -1
- package/icc-api/api/IccDoctemplateApi.js +2 -1
- package/icc-api/api/IccDoctemplateApi.js.map +1 -1
- package/icc-api/api/IccDocumentApi.js +2 -1
- package/icc-api/api/IccDocumentApi.js.map +1 -1
- package/icc-api/api/IccDocumentTemplateApi.js +2 -1
- package/icc-api/api/IccDocumentTemplateApi.js.map +1 -1
- package/icc-api/api/IccEntityrefApi.js +2 -1
- package/icc-api/api/IccEntityrefApi.js.map +1 -1
- package/icc-api/api/IccEntitytemplateApi.js +2 -1
- package/icc-api/api/IccEntitytemplateApi.js.map +1 -1
- package/icc-api/api/IccFormApi.js +2 -1
- package/icc-api/api/IccFormApi.js.map +1 -1
- package/icc-api/api/IccFrontendmigrationApi.js +2 -1
- package/icc-api/api/IccFrontendmigrationApi.js.map +1 -1
- package/icc-api/api/IccGroupApi.d.ts +6 -0
- package/icc-api/api/IccGroupApi.js +15 -1
- package/icc-api/api/IccGroupApi.js.map +1 -1
- package/icc-api/api/IccHcpartyApi.js +2 -1
- package/icc-api/api/IccHcpartyApi.js.map +1 -1
- package/icc-api/api/IccHelementApi.js +2 -1
- package/icc-api/api/IccHelementApi.js.map +1 -1
- package/icc-api/api/IccIcureApi.js +2 -1
- package/icc-api/api/IccIcureApi.js.map +1 -1
- package/icc-api/api/IccInsuranceApi.js +2 -1
- package/icc-api/api/IccInsuranceApi.js.map +1 -1
- package/icc-api/api/IccInvoiceApi.js +2 -1
- package/icc-api/api/IccInvoiceApi.js.map +1 -1
- package/icc-api/api/IccKeywordApi.js +2 -1
- package/icc-api/api/IccKeywordApi.js.map +1 -1
- package/icc-api/api/IccMaintenanceTaskApi.js +2 -1
- package/icc-api/api/IccMaintenanceTaskApi.js.map +1 -1
- package/icc-api/api/IccMedexApi.js +2 -1
- package/icc-api/api/IccMedexApi.js.map +1 -1
- package/icc-api/api/IccMedicallocationApi.js +2 -1
- package/icc-api/api/IccMedicallocationApi.js.map +1 -1
- package/icc-api/api/IccMessageApi.js +2 -1
- package/icc-api/api/IccMessageApi.js.map +1 -1
- package/icc-api/api/IccPatientApi.js +2 -1
- package/icc-api/api/IccPatientApi.js.map +1 -1
- package/icc-api/api/IccPermissionApi.js +2 -1
- package/icc-api/api/IccPermissionApi.js.map +1 -1
- package/icc-api/api/IccPlaceApi.js +2 -1
- package/icc-api/api/IccPlaceApi.js.map +1 -1
- package/icc-api/api/IccPubsubApi.js +2 -1
- package/icc-api/api/IccPubsubApi.js.map +1 -1
- package/icc-api/api/IccReceiptApi.js +2 -1
- package/icc-api/api/IccReceiptApi.js.map +1 -1
- package/icc-api/api/IccReplicationApi.js +2 -1
- package/icc-api/api/IccReplicationApi.js.map +1 -1
- package/icc-api/api/IccRestApiPath.d.ts +1 -0
- package/icc-api/api/IccRestApiPath.js +10 -0
- package/icc-api/api/IccRestApiPath.js.map +1 -0
- package/icc-api/api/IccTarificationApi.js +2 -1
- package/icc-api/api/IccTarificationApi.js.map +1 -1
- package/icc-api/api/IccTimeTableApi.js +2 -1
- package/icc-api/api/IccTimeTableApi.js.map +1 -1
- package/icc-api/api/IccTmpApi.js +2 -1
- package/icc-api/api/IccTmpApi.js.map +1 -1
- package/icc-api/api/IccUserApi.js +2 -1
- package/icc-api/api/IccUserApi.js.map +1 -1
- package/icc-api/index.d.ts +0 -1
- package/icc-api/index.js +0 -1
- package/icc-api/index.js.map +1 -1
- package/icc-api/model/AuthenticationToken.d.ts +1 -0
- package/icc-api/model/AuthenticationToken.js.map +1 -1
- package/icc-api/model/CryptoActorStub.d.ts +55 -0
- package/icc-api/model/CryptoActorStub.js +35 -0
- package/icc-api/model/CryptoActorStub.js.map +1 -0
- package/icc-api/model/DataOwnerTypeEnum.d.ts +8 -0
- package/icc-api/model/DataOwnerTypeEnum.js +13 -0
- package/icc-api/model/DataOwnerTypeEnum.js.map +1 -0
- package/icc-api/model/DataOwnerWithType.d.ts +16 -3
- package/icc-api/model/DataOwnerWithType.js +22 -7
- package/icc-api/model/DataOwnerWithType.js.map +1 -1
- package/icc-api/model/Device.d.ts +4 -0
- package/icc-api/model/Device.js.map +1 -1
- package/icc-api/model/FlatRateTarification.d.ts +4 -1
- package/icc-api/model/FlatRateTarification.js +3 -0
- package/icc-api/model/FlatRateTarification.js.map +1 -1
- package/icc-api/model/HealthcareParty.d.ts +4 -0
- package/icc-api/model/HealthcareParty.js.map +1 -1
- package/icc-api/model/Patient.d.ts +4 -0
- package/icc-api/model/Patient.js.map +1 -1
- package/icc-api/model/UserGroup.d.ts +1 -0
- package/icc-api/model/UserGroup.js.map +1 -1
- package/icc-x-api/auth/AuthenticationProvider.d.ts +67 -6
- package/icc-x-api/auth/AuthenticationProvider.js +100 -7
- package/icc-x-api/auth/AuthenticationProvider.js.map +1 -1
- package/icc-x-api/auth/EnsembleAuthService.d.ts +7 -2
- package/icc-x-api/auth/EnsembleAuthService.js +9 -0
- package/icc-x-api/auth/EnsembleAuthService.js.map +1 -1
- package/icc-x-api/auth/JwtAuthService.d.ts +10 -5
- package/icc-x-api/auth/JwtAuthService.js +22 -26
- package/icc-x-api/auth/JwtAuthService.js.map +1 -1
- package/icc-x-api/auth/JwtBridgedAuthService.d.ts +27 -0
- package/icc-x-api/auth/JwtBridgedAuthService.js +131 -0
- package/icc-x-api/auth/JwtBridgedAuthService.js.map +1 -0
- package/icc-x-api/crypto/AES.js +9 -1
- package/icc-x-api/crypto/AES.js.map +1 -1
- package/icc-x-api/crypto/BaseExchangeKeysManager.d.ts +4 -2
- package/icc-x-api/crypto/BaseExchangeKeysManager.js +32 -31
- package/icc-x-api/crypto/BaseExchangeKeysManager.js.map +1 -1
- package/icc-x-api/crypto/CryptoStrategies.d.ts +5 -4
- package/icc-x-api/crypto/CryptoStrategies.js.map +1 -1
- package/icc-x-api/crypto/EntitiesEncryption.d.ts +3 -3
- package/icc-x-api/crypto/EntitiesEncryption.js +9 -7
- package/icc-x-api/crypto/EntitiesEncryption.js.map +1 -1
- package/icc-x-api/crypto/ExchangeKeysManager.d.ts +3 -2
- package/icc-x-api/crypto/ExchangeKeysManager.js +3 -3
- package/icc-x-api/crypto/ExchangeKeysManager.js.map +1 -1
- package/icc-x-api/crypto/KeyManager.js +4 -4
- package/icc-x-api/crypto/KeyManager.js.map +1 -1
- package/icc-x-api/crypto/KeyRecovery.d.ts +2 -1
- package/icc-x-api/crypto/KeyRecovery.js.map +1 -1
- package/icc-x-api/crypto/LegacyCryptoStrategies.d.ts +5 -4
- package/icc-x-api/crypto/LegacyCryptoStrategies.js +1 -1
- package/icc-x-api/crypto/LegacyCryptoStrategies.js.map +1 -1
- package/icc-x-api/crypto/ShamirKeysManager.d.ts +4 -3
- package/icc-x-api/crypto/ShamirKeysManager.js +8 -7
- package/icc-x-api/crypto/ShamirKeysManager.js.map +1 -1
- package/icc-x-api/crypto/TransferKeysManager.d.ts +3 -2
- package/icc-x-api/crypto/TransferKeysManager.js +6 -6
- package/icc-x-api/crypto/TransferKeysManager.js.map +1 -1
- package/icc-x-api/crypto/utils.d.ts +7 -6
- package/icc-x-api/crypto/utils.js +4 -7
- package/icc-x-api/crypto/utils.js.map +1 -1
- package/icc-x-api/filters/ServiceByHcPartyTagCodeDateFilter.d.ts +1 -0
- package/icc-x-api/filters/ServiceByHcPartyTagCodeDateFilter.js.map +1 -1
- package/icc-x-api/icc-accesslog-x-api.d.ts +2 -2
- package/icc-x-api/icc-accesslog-x-api.js +9 -4
- package/icc-x-api/icc-accesslog-x-api.js.map +1 -1
- package/icc-x-api/icc-calendar-item-x-api.js +11 -3
- package/icc-x-api/icc-calendar-item-x-api.js.map +1 -1
- package/icc-x-api/icc-classification-x-api.js +7 -2
- package/icc-x-api/icc-classification-x-api.js.map +1 -1
- package/icc-x-api/icc-contact-x-api.d.ts +1 -0
- package/icc-x-api/icc-contact-x-api.js +16 -4
- package/icc-x-api/icc-contact-x-api.js.map +1 -1
- package/icc-x-api/icc-crypto-x-api.d.ts +6 -6
- package/icc-x-api/icc-crypto-x-api.js +4 -4
- package/icc-x-api/icc-crypto-x-api.js.map +1 -1
- package/icc-x-api/icc-data-owner-x-api.d.ts +21 -52
- package/icc-x-api/icc-data-owner-x-api.js +36 -68
- package/icc-x-api/icc-data-owner-x-api.js.map +1 -1
- package/icc-x-api/icc-document-x-api.js +7 -2
- package/icc-x-api/icc-document-x-api.js.map +1 -1
- package/icc-x-api/icc-form-x-api.js +7 -2
- package/icc-x-api/icc-form-x-api.js.map +1 -1
- package/icc-x-api/icc-helement-x-api.js +7 -2
- package/icc-x-api/icc-helement-x-api.js.map +1 -1
- package/icc-x-api/icc-icure-maintenance-x-api.js +8 -8
- package/icc-x-api/icc-icure-maintenance-x-api.js.map +1 -1
- package/icc-x-api/icc-invoice-x-api.js +7 -2
- package/icc-x-api/icc-invoice-x-api.js.map +1 -1
- package/icc-x-api/icc-maintenance-task-x-api.js +6 -1
- package/icc-x-api/icc-maintenance-task-x-api.js.map +1 -1
- package/icc-x-api/icc-message-x-api.js +7 -2
- package/icc-x-api/icc-message-x-api.js.map +1 -1
- package/icc-x-api/icc-patient-x-api.d.ts +4 -1
- package/icc-x-api/icc-patient-x-api.js +8 -7
- package/icc-x-api/icc-patient-x-api.js.map +1 -1
- package/icc-x-api/icc-receipt-x-api.js +6 -1
- package/icc-x-api/icc-receipt-x-api.js.map +1 -1
- package/icc-x-api/icc-time-table-x-api.js +6 -1
- package/icc-x-api/icc-time-table-x-api.js.map +1 -1
- package/icc-x-api/index.d.ts +178 -35
- package/icc-x-api/index.js +305 -81
- package/icc-x-api/index.js.map +1 -1
- package/icc-x-api/maintenance/KeyPairUpdateRequest.d.ts +12 -9
- package/icc-x-api/maintenance/KeyPairUpdateRequest.js +11 -17
- package/icc-x-api/maintenance/KeyPairUpdateRequest.js.map +1 -1
- package/package.json +1 -1
- package/icc-api/api/IccBemikronoApi.d.ts +0 -81
- package/icc-api/api/IccBemikronoApi.js +0 -162
- package/icc-api/api/IccBemikronoApi.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"KeyManager.js","sourceRoot":"","sources":["../../../icc-x-api/crypto/KeyManager.ts"],"names":[],"mappings":"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","sourcesContent":["import { DataOwner, DataOwnerWithType, IccDataOwnerXApi } from '../icc-data-owner-x-api'\nimport { KeyPair } from './RSA'\nimport { ua2hex } from '../utils'\nimport { IcureStorageFacade } from '../storage/IcureStorageFacade'\nimport { BaseExchangeKeysManager } from './BaseExchangeKeysManager'\nimport { fingerprintToPublicKeysMapOf, loadPublicKeys } from './utils'\nimport { CryptoPrimitives } from './CryptoPrimitives'\nimport { KeyRecovery } from './KeyRecovery'\nimport { CryptoStrategies } from './CryptoStrategies'\n\ntype KeyPairData = { pair: KeyPair<CryptoKey>; isVerified: boolean; isDevice: boolean }\ntype KeyRecovererAndVerifier = (\n keysData: {\n dataOwner: DataOwner\n unknownKeys: string[]\n unavailableKeys: string[]\n }[]\n) => Promise<{\n [dataOwnerId: string]: {\n recoveredKeys: { [keyPairFingerprint: string]: KeyPair<CryptoKey> }\n keyAuthenticity: { [keyPairFingerprint: string]: boolean }\n }\n}>\ntype CurrentOwnerKeyGenerator = (self: DataOwner) => Promise<KeyPair<CryptoKey> | boolean>\n\n/**\n * Allows to manage public and private keys for the current user and his parent hierarchy.\n */\nexport class KeyManager {\n private readonly primitives: CryptoPrimitives\n private readonly dataOwnerApi: IccDataOwnerXApi\n private readonly keyRecovery: KeyRecovery\n private readonly icureStorage: IcureStorageFacade\n private readonly baseExchangeKeyManager: BaseExchangeKeysManager\n private readonly strategies: CryptoStrategies\n\n private selfId: string | undefined\n private selfLegacyPublicKey: string | undefined\n private keysCache: { [selfOrParentId: string]: { [pubKeyFingerprint: string]: KeyPairData } } | undefined = undefined\n\n constructor(\n primitives: CryptoPrimitives,\n dataOwnerApi: IccDataOwnerXApi,\n icureStorage: IcureStorageFacade,\n keyRecovery: KeyRecovery,\n baseExchangeKeyManager: BaseExchangeKeysManager,\n strategies: CryptoStrategies\n ) {\n this.primitives = primitives\n this.icureStorage = icureStorage\n this.dataOwnerApi = dataOwnerApi\n this.keyRecovery = keyRecovery\n this.baseExchangeKeyManager = baseExchangeKeyManager\n this.strategies = strategies\n }\n\n /**\n * Get the public keys of available key pairs for the current user in hex-encoded spki representation (uses cached keys: no request is done to the\n * server).\n * By setting {@link verifiedOnly} to true only the public keys for verified key pairs will be returned: these will include only key pairs created\n * on this device or which have been verified using {@link CryptoStrategies} on this device.\n * @param verifiedOnly if true only the verified public keys will be returned.\n * @return the spki representation of public keys of available keypairs for the current user.\n */\n async getCurrentUserAvailablePublicKeysHex(verifiedOnly: boolean): Promise<string[]> {\n this.ensureInitialised()\n let selectedData = Object.values(this.keysCache![this.selfId!])\n if (verifiedOnly) {\n selectedData = selectedData.filter((data) => data.isVerified || data.isDevice)\n }\n return await Promise.all(selectedData.map(async (keyData) => ua2hex(await this.primitives.RSA.exportKey(keyData.pair.publicKey, 'spki'))))\n }\n\n /**\n * Get the public keys of available key pairs for the current user and his parents in hex-encoded spki representation (uses cached keys: no request\n * is done to the server).\n * Note that this will also include unverified keys.\n * @return the spki representation of public keys of available keypairs for the current user.\n */\n async getCurrentUserHierarchyAvailablePublicKeysHex(): Promise<string[]> {\n return await Promise.all(\n Object.values(this.keysCache!)\n .flatMap((pairsForParent) => Object.values(pairsForParent))\n .map(async (keyPairData) => ua2hex(await this.primitives.RSA.exportKey(keyPairData.pair.publicKey, 'spki')))\n )\n }\n\n /**\n * Get a key pair with the provided fingerprint if present.\n * @param fingerprint a key-pair/public-key fingerprint\n * @return the pair associated to the fingerprint and a boolean indicating if the pair is verified, if present, else undefined\n */\n getKeyPairForFingerprint(fingerprint: string): { pair: KeyPair<CryptoKey>; verified: boolean } | undefined {\n const foundVerified = this.getSelfVerifiedKeys().find((x) => x.fingerprint === fingerprint)\n if (foundVerified) return { pair: foundVerified.pair, verified: true }\n const foundOther = this.getDecryptionKeys()[fingerprint]\n if (foundOther) return { pair: foundOther, verified: false }\n return undefined\n }\n\n /**\n * @internal This method is intended for internal use only and may be changed without notice.\n * Initializes all keys for the current data owner. This method needs to be called before any other method of this class can be used.\n * @throws if the current user is not a data owner, or if there is no key and no new key could be created according to this manager crypt\n * strategies.\n * @return if a new key was created during initialisation the newly created key, else undefined.\n */\n async initialiseKeys(): Promise<{ newKeyPair: KeyPair<CryptoKey>; newKeyFingerprint: string } | undefined> {\n const newKey = await this.doLoadKeys(\n (x) => this.strategies.recoverAndVerifySelfHierarchyKeys(x, this.primitives),\n (x) => this.strategies.generateNewKeyForDataOwner(x, this.primitives)\n )\n return newKey ? { newKeyPair: newKey.pair, newKeyFingerprint: newKey.fingerprint } : undefined\n }\n\n /**\n * @internal This method is intended for internal use only and may be changed without notice.\n * Forces to reload keys for the current data owner. This could be useful if the data owner has logged in from another device in order to update the\n * transfer keys.\n * This method will complete only after keys have been reloaded successfully.\n */\n async reloadKeys(): Promise<void> {\n await this.doLoadKeys(\n (x) =>\n Promise.resolve(\n x.reduce(\n (acc, { dataOwner }) => ({ ...acc, [dataOwner.id]: { recoveredKeys: {}, keyAuthenticity: {} } }),\n {} as {\n [dataOwnerId: string]: {\n recoveredKeys: { [keyPairFingerprint: string]: KeyPair<CryptoKey> }\n keyAuthenticity: { [keyPairFingerprint: string]: boolean }\n }\n }\n )\n ),\n (x) => {\n throw new Error(\"Can't create new keys at reload time: it should have already been created on initialisation\")\n }\n )\n }\n\n /**\n * @internal This method is intended for internal use only and may be changed without notice.\n * Get all verified key pairs for the current data owner which can safely be used for encryption. This includes all key pairs created on the current\n * device and all recovered key pairs which have been verified.\n * The keys returned by this method will be in the following order:\n * 1. Legacy key pair if it is verified\n * 2. All device key pais, in alphabetical order according to the fingerprint\n * 3. Other verified key pairs, in alphabetical order according to the fingerprint\n * @return all verified keys, in order.\n */\n getSelfVerifiedKeys(): { fingerprint: string; pair: KeyPair<CryptoKey> }[] {\n this.ensureInitialised()\n const selfKeys = this.keysCache![this.selfId!]\n const allKeysEntries = Object.entries(selfKeys)\n\n const legacyKeyFp = this.selfLegacyPublicKey?.slice(-32)\n const legacyKeyData = legacyKeyFp ? selfKeys[legacyKeyFp] : undefined\n const legacyEntry = legacyKeyData?.isVerified && legacyKeyFp ? [{ fingerprint: legacyKeyFp, pair: legacyKeyData.pair }] : []\n\n function filteredEntries(filterFunction: (fp: string, data: KeyPairData) => boolean) {\n return allKeysEntries\n .filter(([fp, data]) => filterFunction(fp, data) && fp !== legacyKeyFp)\n .sort(([a], [b]) => {\n // need to make sure that the comparison is independent of the locale, but the actual ordering is not that important\n return a == b ? 0 : a > b ? 1 : -1\n })\n .map(([fingerprint, { pair }]) => ({ fingerprint, pair }))\n }\n return [...legacyEntry, ...filteredEntries((_, data) => data.isDevice), ...filteredEntries((_, data) => !data.isDevice && data.isVerified)]\n }\n\n /**\n * Get all verified keys for a member of the current data owner hierarchy in no particular order.\n * @param dataOwner the current data owner or a member of his hierarchy.\n * @throws if the provided data owner is not part of the current data owner hierarchy\n */\n async getVerifiedPublicKeysFor(dataOwner: DataOwner): Promise<string[]> {\n this.ensureInitialised()\n const availableKeys = this.keysCache![dataOwner.id!]\n if (!availableKeys) throw new Error(`Data owner ${dataOwner.id} is not part of the hierarchy of the current data owner ${this.selfId}`)\n const availableVerifiedKeysFp = new Set(Object.entries(availableKeys).flatMap(([fp, info]) => (info.isVerified || info.isDevice ? [fp] : [])))\n const otherVerifiedFp = new Set(\n Object.entries(await this.icureStorage.loadSelfVerifiedKeys(dataOwner.id)).flatMap(([fp, verified]) => (verified ? [fp] : []))\n )\n return Array.from(this.dataOwnerApi.getHexPublicKeysOf(dataOwner)).filter((key) => {\n const fp = key.slice(-32)\n return availableVerifiedKeysFp.has(fp) || otherVerifiedFp.has(fp)\n })\n }\n\n /**\n * @internal This method is intended for internal use only and may be changed without notice.\n * Get all key pairs for the current data owner and his parents. These keys should be used only for decryption as they may have not been verified.\n * @return all key pairs available for decryption.\n */\n getDecryptionKeys(): { [fingerprint: string]: KeyPair<CryptoKey> } {\n this.ensureInitialised()\n return Object.values(this.keysCache!).reduce((acc, curr) => {\n return {\n ...acc,\n ...this.plainKeysByFingerprint(curr),\n }\n }, {} as { [fp: string]: KeyPair<CryptoKey> })\n }\n\n private async doLoadKeys(\n keyRecovererAndVerifier: KeyRecovererAndVerifier,\n currentOwnerKeyGenerator: CurrentOwnerKeyGenerator\n ): Promise<{ pair: KeyPair<CryptoKey>; fingerprint: string } | undefined> {\n // Load all keys for self from key store\n const hierarchy = await this.dataOwnerApi.getCurrentDataOwnerHierarchy()\n const self = hierarchy[hierarchy.length - 1]\n this.selfId = self.dataOwner.id!\n const keysData = []\n for (const dowt of hierarchy) {\n const availableKeys = await this.loadAndRecoverKeysFor(dowt)\n const verifiedKeysMap = await this.icureStorage.loadSelfVerifiedKeys(dowt.dataOwner.id!)\n const allPublicKeys = this.dataOwnerApi.getHexPublicKeysOf(dowt.dataOwner)\n const fpToFullMap = fingerprintToPublicKeysMapOf(dowt.dataOwner)\n const unavailableKeys = Object.keys(availableKeys).flatMap((fp) => {\n const fullPublicKey = fpToFullMap[fp]\n return allPublicKeys.has(fullPublicKey) ? [] : [fullPublicKey]\n })\n const unknownKeys = Array.from(allPublicKeys).filter(\n (x) => !(x.slice(-32) in verifiedKeysMap) && !(availableKeys?.[x.slice(-32)]?.isDevice === true)\n )\n keysData.push({ dowt, availableKeys, unavailableKeys, unknownKeys })\n }\n const recoveryAndVerificationResult = await keyRecovererAndVerifier(\n keysData.map(({ dowt, unavailableKeys, unknownKeys }) => ({ dataOwner: dowt.dataOwner, unavailableKeys, unknownKeys }))\n )\n const keysCache: { [dataOwnerId: string]: { [fp: string]: KeyPairData } } = {}\n for (const keyData of keysData) {\n const currAuthenticity = this.ensureFingerprintKeys(recoveryAndVerificationResult[keyData.dowt.dataOwner.id].keyAuthenticity)\n const currExternallyRecovered = this.ensureFingerprintKeys(recoveryAndVerificationResult[keyData.dowt.dataOwner.id].recoveredKeys)\n for (const [fp, keyPair] of Object.entries(currExternallyRecovered)) {\n const jwkPair = await this.primitives.RSA.exportKeys(keyPair, 'jwk', 'jwk')\n await this.icureStorage.saveKey(keyData.dowt.dataOwner.id!, fp, jwkPair, true)\n }\n const updatedVerifiedMap = await this.icureStorage.saveSelfVerifiedKeys(\n keyData.dowt.dataOwner.id!,\n [...Object.keys(currAuthenticity), ...Object.keys(currExternallyRecovered)].reduce(\n (acc, currFp) => ({\n ...acc,\n [currFp]: currFp in currExternallyRecovered || currAuthenticity[currFp],\n }),\n {}\n )\n )\n const keysWithExternallyRecovered = {\n ...keyData.availableKeys,\n ...Object.fromEntries(Object.entries(currExternallyRecovered).map(([k, v]) => [k, { pair: v, isDevice: false }])),\n }\n const additionallyRecovered = await this.recoverAndCacheKeys(keyData.dowt, this.plainKeysByFingerprint(keysWithExternallyRecovered))\n const keys = {\n ...keysWithExternallyRecovered,\n ...Object.fromEntries(Object.entries(additionallyRecovered).map(([k, v]) => [k, { pair: v, isDevice: false }])),\n }\n keysCache[keyData.dowt.dataOwner.id!] = this.verifyKeys(keys, updatedVerifiedMap)\n }\n if (Object.entries(keysCache).some(([ownerId, data]) => ownerId !== self.dataOwner.id && !this.hasVerifiedKey(data))) {\n throw new Error('Some parent hcps have no verified keys: impossible to generate locally a new key for a parent.')\n } else if (this.hasVerifiedKey(keysCache[self.dataOwner.id])) {\n this.keysCache = keysCache\n this.selfLegacyPublicKey = self.dataOwner.publicKey\n return undefined\n } else {\n const whatToDo = await currentOwnerKeyGenerator(self.dataOwner)\n if (whatToDo === false) {\n throw new Error(`No verified key found for ${self.dataOwner.id} and settings do not allow creation of a new key.`)\n } else {\n const updateInfo = await this.createAndSaveNewKeyPair(whatToDo === true ? undefined : whatToDo, self)\n // self may be outdated now\n this.selfLegacyPublicKey = updateInfo.updatedSelf.dataOwner.publicKey\n this.keysCache = {\n ...keysCache,\n [self.dataOwner.id!]: {\n ...keysCache[self.dataOwner.id],\n [updateInfo.publicKeyFingerprint]: { pair: updateInfo.keyPair, isDevice: true, isVerified: true },\n },\n }\n return { pair: updateInfo.keyPair, fingerprint: updateInfo.publicKeyFingerprint }\n }\n }\n }\n\n private async createAndSaveNewKeyPair(\n importedKeyPair: undefined | KeyPair<CryptoKey>,\n selfDataOwner: DataOwnerWithType\n ): Promise<{ publicKeyFingerprint: string; keyPair: KeyPair<CryptoKey>; updatedSelf: DataOwnerWithType }> {\n const keyPair = importedKeyPair ?? (await this.primitives.RSA.generateKeyPair())\n const publicKeyHex = ua2hex(await this.primitives.RSA.exportKey(keyPair.publicKey, 'spki'))\n const publicKeyFingerprint = publicKeyHex.slice(-32)\n await this.icureStorage.saveKey(\n selfDataOwner.dataOwner.id!,\n publicKeyFingerprint,\n await this.primitives.RSA.exportKeys(keyPair, 'jwk', 'jwk'),\n true\n )\n const verifiedPublicKeysMap = await this.icureStorage.saveSelfVerifiedKeys(selfDataOwner.dataOwner.id!, { [publicKeyFingerprint]: true })\n const { updatedDelegator } = await this.baseExchangeKeyManager.createOrUpdateEncryptedExchangeKeyTo(\n selfDataOwner.dataOwner.id!,\n keyPair,\n await loadPublicKeys(\n this.primitives.RSA,\n Array.from(this.dataOwnerApi.getHexPublicKeysOf(selfDataOwner.dataOwner)).filter((x) => verifiedPublicKeysMap[x.slice(-32)])\n )\n )\n return { publicKeyFingerprint, keyPair: keyPair, updatedSelf: updatedDelegator }\n }\n\n private async loadStoredKeys(\n dataOwner: DataOwnerWithType,\n pubKeysFingerprints: string[]\n ): Promise<{ [pubKeyFingerprint: string]: { pair: KeyPair<CryptoKey>; isDevice: boolean } }> {\n return await pubKeysFingerprints.reduce(async (acc, currentFingerprint) => {\n const awaitedAcc = await acc\n let loadedPair: { pair: KeyPair<CryptoKey>; isDevice: boolean } | undefined = undefined\n try {\n const storedKeypair = await this.icureStorage.loadKey(dataOwner.dataOwner.id!, currentFingerprint, dataOwner.dataOwner.publicKey)\n if (storedKeypair) {\n const importedKey = await this.primitives.RSA.importKeyPair('jwk', storedKeypair.pair.privateKey, 'jwk', storedKeypair.pair.publicKey)\n loadedPair = { pair: importedKey, isDevice: storedKeypair.isDevice }\n }\n } catch (e) {\n console.warn('Error while loading keypair', currentFingerprint, e)\n }\n return loadedPair\n ? {\n ...awaitedAcc,\n [currentFingerprint]: loadedPair,\n }\n : awaitedAcc\n }, Promise.resolve({} as { [pubKeyFingerprint: string]: { pair: KeyPair<CryptoKey>; isDevice: boolean } }))\n }\n\n private verifyKeys(\n keys: { [pubKeyFingerprint: string]: { pair: KeyPair<CryptoKey>; isDevice: boolean } },\n verifiedKeysMap: { [pubKeyFingerprint: string]: boolean }\n ): { [pubKeyFingerprint: string]: KeyPairData } {\n return Object.fromEntries(\n Object.entries(keys).map(\n ([fp, keyData]) => [fp, { ...keyData, isVerified: keyData.isDevice || verifiedKeysMap?.[fp] === true }] as [string, KeyPairData]\n )\n )\n }\n\n private plainKeysByFingerprint(richKeys: { [pubKeyFingerprint: string]: { pair: KeyPair<CryptoKey> } }): {\n [pubKeyFingerprint: string]: KeyPair<CryptoKey>\n } {\n return Object.fromEntries(Object.entries(richKeys).map(([fp, keyData]) => [fp, keyData.pair]))\n }\n\n private ensureInitialised() {\n if (!this.keysCache) throw new Error('Key manager was not properly initialised')\n }\n\n private async recoverAndCacheKeys(\n dataOwner: DataOwnerWithType,\n availableKeys: { [pubKeyFingerprint: string]: KeyPair<CryptoKey> }\n ): Promise<{ [p: string]: KeyPair<CryptoKey> }> {\n const recoveredKeys = await this.keyRecovery.recoverKeys(dataOwner, availableKeys)\n for (const [fp, pair] of Object.entries(recoveredKeys)) {\n await this.icureStorage.saveKey(dataOwner.dataOwner.id!, fp, await this.primitives.RSA.exportKeys(pair, 'jwk', 'jwk'), false)\n }\n return recoveredKeys\n }\n\n private async loadAndRecoverKeysFor(dataOwner: DataOwnerWithType): Promise<{ [keyFp: string]: { pair: KeyPair<CryptoKey>; isDevice: boolean } }> {\n const selfPublicKeys = this.dataOwnerApi.getHexPublicKeysOf(dataOwner.dataOwner)\n const pubKeysFingerprints = Array.from(selfPublicKeys).map((x) => x.slice(-32))\n const loadedKeys = pubKeysFingerprints.length > 0 ? await this.loadStoredKeys(dataOwner, pubKeysFingerprints) : {}\n const loadedKeysFingerprints = Object.keys(loadedKeys)\n if (loadedKeysFingerprints.length !== pubKeysFingerprints.length && loadedKeysFingerprints.length > 0) {\n const recoveredKeys = await this.recoverAndCacheKeys(dataOwner, this.plainKeysByFingerprint(loadedKeys))\n for (const [fp, pair] of Object.entries(recoveredKeys)) {\n loadedKeys[fp] = { pair, isDevice: false }\n }\n }\n return loadedKeys\n }\n\n private ensureFingerprintKeys<T>(obj: { [shouldBeFingerprint: string]: T }): { [definitelyFingerprint: string]: T } {\n return Object.fromEntries(Object.entries(obj).map(([k, v]) => [k.slice(-32), v]))\n }\n\n private hasVerifiedKey(keysData: { [fp: string]: KeyPairData }) {\n return Object.values(keysData).some((x) => x.isVerified || x.isDevice)\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"KeyManager.js","sourceRoot":"","sources":["../../../icc-x-api/crypto/KeyManager.ts"],"names":[],"mappings":"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","sourcesContent":["import { DataOwner, IccDataOwnerXApi } from '../icc-data-owner-x-api'\nimport { KeyPair } from './RSA'\nimport { ua2hex } from '../utils'\nimport { IcureStorageFacade } from '../storage/IcureStorageFacade'\nimport { BaseExchangeKeysManager } from './BaseExchangeKeysManager'\nimport { fingerprintToPublicKeysMapOf, loadPublicKeys } from './utils'\nimport { CryptoPrimitives } from './CryptoPrimitives'\nimport { KeyRecovery } from './KeyRecovery'\nimport { CryptoStrategies } from './CryptoStrategies'\nimport { DataOwnerWithType } from '../../icc-api/model/DataOwnerWithType'\nimport { CryptoActorStubWithType } from '../../icc-api/model/CryptoActorStub'\n\ntype KeyPairData = { pair: KeyPair<CryptoKey>; isVerified: boolean; isDevice: boolean }\ntype KeyRecovererAndVerifier = (\n keysData: {\n dataOwner: DataOwnerWithType\n unknownKeys: string[]\n unavailableKeys: string[]\n }[]\n) => Promise<{\n [dataOwnerId: string]: {\n recoveredKeys: { [keyPairFingerprint: string]: KeyPair<CryptoKey> }\n keyAuthenticity: { [keyPairFingerprint: string]: boolean }\n }\n}>\ntype CurrentOwnerKeyGenerator = (self: DataOwnerWithType) => Promise<KeyPair<CryptoKey> | boolean>\n\n/**\n * Allows to manage public and private keys for the current user and his parent hierarchy.\n */\nexport class KeyManager {\n private readonly primitives: CryptoPrimitives\n private readonly dataOwnerApi: IccDataOwnerXApi\n private readonly keyRecovery: KeyRecovery\n private readonly icureStorage: IcureStorageFacade\n private readonly baseExchangeKeyManager: BaseExchangeKeysManager\n private readonly strategies: CryptoStrategies\n\n private selfId: string | undefined\n private selfLegacyPublicKey: string | undefined\n private keysCache: { [selfOrParentId: string]: { [pubKeyFingerprint: string]: KeyPairData } } | undefined = undefined\n\n constructor(\n primitives: CryptoPrimitives,\n dataOwnerApi: IccDataOwnerXApi,\n icureStorage: IcureStorageFacade,\n keyRecovery: KeyRecovery,\n baseExchangeKeyManager: BaseExchangeKeysManager,\n strategies: CryptoStrategies\n ) {\n this.primitives = primitives\n this.icureStorage = icureStorage\n this.dataOwnerApi = dataOwnerApi\n this.keyRecovery = keyRecovery\n this.baseExchangeKeyManager = baseExchangeKeyManager\n this.strategies = strategies\n }\n\n /**\n * Get the public keys of available key pairs for the current user in hex-encoded spki representation (uses cached keys: no request is done to the\n * server).\n * By setting {@link verifiedOnly} to true only the public keys for verified key pairs will be returned: these will include only key pairs created\n * on this device or which have been verified using {@link CryptoStrategies} on this device.\n * @param verifiedOnly if true only the verified public keys will be returned.\n * @return the spki representation of public keys of available keypairs for the current user.\n */\n async getCurrentUserAvailablePublicKeysHex(verifiedOnly: boolean): Promise<string[]> {\n this.ensureInitialised()\n let selectedData = Object.values(this.keysCache![this.selfId!])\n if (verifiedOnly) {\n selectedData = selectedData.filter((data) => data.isVerified || data.isDevice)\n }\n return await Promise.all(selectedData.map(async (keyData) => ua2hex(await this.primitives.RSA.exportKey(keyData.pair.publicKey, 'spki'))))\n }\n\n /**\n * Get the public keys of available key pairs for the current user and his parents in hex-encoded spki representation (uses cached keys: no request\n * is done to the server).\n * Note that this will also include unverified keys.\n * @return the spki representation of public keys of available keypairs for the current user.\n */\n async getCurrentUserHierarchyAvailablePublicKeysHex(): Promise<string[]> {\n return await Promise.all(\n Object.values(this.keysCache!)\n .flatMap((pairsForParent) => Object.values(pairsForParent))\n .map(async (keyPairData) => ua2hex(await this.primitives.RSA.exportKey(keyPairData.pair.publicKey, 'spki')))\n )\n }\n\n /**\n * Get a key pair with the provided fingerprint if present.\n * @param fingerprint a key-pair/public-key fingerprint\n * @return the pair associated to the fingerprint and a boolean indicating if the pair is verified, if present, else undefined\n */\n getKeyPairForFingerprint(fingerprint: string): { pair: KeyPair<CryptoKey>; verified: boolean } | undefined {\n const foundVerified = this.getSelfVerifiedKeys().find((x) => x.fingerprint === fingerprint)\n if (foundVerified) return { pair: foundVerified.pair, verified: true }\n const foundOther = this.getDecryptionKeys()[fingerprint]\n if (foundOther) return { pair: foundOther, verified: false }\n return undefined\n }\n\n /**\n * @internal This method is intended for internal use only and may be changed without notice.\n * Initializes all keys for the current data owner. This method needs to be called before any other method of this class can be used.\n * @throws if the current user is not a data owner, or if there is no key and no new key could be created according to this manager crypt\n * strategies.\n * @return if a new key was created during initialisation the newly created key, else undefined.\n */\n async initialiseKeys(): Promise<{ newKeyPair: KeyPair<CryptoKey>; newKeyFingerprint: string } | undefined> {\n const newKey = await this.doLoadKeys(\n (x) => this.strategies.recoverAndVerifySelfHierarchyKeys(x, this.primitives),\n (x) => this.strategies.generateNewKeyForDataOwner(x, this.primitives)\n )\n return newKey ? { newKeyPair: newKey.pair, newKeyFingerprint: newKey.fingerprint } : undefined\n }\n\n /**\n * @internal This method is intended for internal use only and may be changed without notice.\n * Forces to reload keys for the current data owner. This could be useful if the data owner has logged in from another device in order to update the\n * transfer keys.\n * This method will complete only after keys have been reloaded successfully.\n */\n async reloadKeys(): Promise<void> {\n await this.doLoadKeys(\n (x) =>\n Promise.resolve(\n x.reduce(\n (acc, { dataOwner }) => ({ ...acc, [dataOwner.dataOwner.id!]: { recoveredKeys: {}, keyAuthenticity: {} } }),\n {} as {\n [dataOwnerId: string]: {\n recoveredKeys: { [keyPairFingerprint: string]: KeyPair<CryptoKey> }\n keyAuthenticity: { [keyPairFingerprint: string]: boolean }\n }\n }\n )\n ),\n (x) => {\n throw new Error(\"Can't create new keys at reload time: it should have already been created on initialisation\")\n }\n )\n }\n\n /**\n * @internal This method is intended for internal use only and may be changed without notice.\n * Get all verified key pairs for the current data owner which can safely be used for encryption. This includes all key pairs created on the current\n * device and all recovered key pairs which have been verified.\n * The keys returned by this method will be in the following order:\n * 1. Legacy key pair if it is verified\n * 2. All device key pais, in alphabetical order according to the fingerprint\n * 3. Other verified key pairs, in alphabetical order according to the fingerprint\n * @return all verified keys, in order.\n */\n getSelfVerifiedKeys(): { fingerprint: string; pair: KeyPair<CryptoKey> }[] {\n this.ensureInitialised()\n const selfKeys = this.keysCache![this.selfId!]\n const allKeysEntries = Object.entries(selfKeys)\n\n const legacyKeyFp = this.selfLegacyPublicKey?.slice(-32)\n const legacyKeyData = legacyKeyFp ? selfKeys[legacyKeyFp] : undefined\n const legacyEntry = legacyKeyData?.isVerified && legacyKeyFp ? [{ fingerprint: legacyKeyFp, pair: legacyKeyData.pair }] : []\n\n function filteredEntries(filterFunction: (fp: string, data: KeyPairData) => boolean) {\n return allKeysEntries\n .filter(([fp, data]) => filterFunction(fp, data) && fp !== legacyKeyFp)\n .sort(([a], [b]) => {\n // need to make sure that the comparison is independent of the locale, but the actual ordering is not that important\n return a == b ? 0 : a > b ? 1 : -1\n })\n .map(([fingerprint, { pair }]) => ({ fingerprint, pair }))\n }\n return [...legacyEntry, ...filteredEntries((_, data) => data.isDevice), ...filteredEntries((_, data) => !data.isDevice && data.isVerified)]\n }\n\n /**\n * Get all verified keys for a member of the current data owner hierarchy in no particular order.\n * @param dataOwner the current data owner or a member of his hierarchy.\n * @throws if the provided data owner is not part of the current data owner hierarchy\n */\n async getVerifiedPublicKeysFor(dataOwner: DataOwner): Promise<string[]> {\n this.ensureInitialised()\n const availableKeys = this.keysCache![dataOwner.id!]\n if (!availableKeys) throw new Error(`Data owner ${dataOwner.id} is not part of the hierarchy of the current data owner ${this.selfId}`)\n const availableVerifiedKeysFp = new Set(Object.entries(availableKeys).flatMap(([fp, info]) => (info.isVerified || info.isDevice ? [fp] : [])))\n const otherVerifiedFp = new Set(\n Object.entries(await this.icureStorage.loadSelfVerifiedKeys(dataOwner.id!)).flatMap(([fp, verified]) => (verified ? [fp] : []))\n )\n return Array.from(this.dataOwnerApi.getHexPublicKeysOf(dataOwner)).filter((key) => {\n const fp = key.slice(-32)\n return availableVerifiedKeysFp.has(fp) || otherVerifiedFp.has(fp)\n })\n }\n\n /**\n * @internal This method is intended for internal use only and may be changed without notice.\n * Get all key pairs for the current data owner and his parents. These keys should be used only for decryption as they may have not been verified.\n * @return all key pairs available for decryption.\n */\n getDecryptionKeys(): { [fingerprint: string]: KeyPair<CryptoKey> } {\n this.ensureInitialised()\n return Object.values(this.keysCache!).reduce((acc, curr) => {\n return {\n ...acc,\n ...this.plainKeysByFingerprint(curr),\n }\n }, {} as { [fp: string]: KeyPair<CryptoKey> })\n }\n\n private async doLoadKeys(\n keyRecovererAndVerifier: KeyRecovererAndVerifier,\n currentOwnerKeyGenerator: CurrentOwnerKeyGenerator\n ): Promise<{ pair: KeyPair<CryptoKey>; fingerprint: string } | undefined> {\n // Load all keys for self from key store\n const hierarchy = await this.dataOwnerApi.getCurrentDataOwnerHierarchy()\n const self = hierarchy[hierarchy.length - 1]\n this.selfId = self.dataOwner.id!\n const keysData = []\n for (const dowt of hierarchy) {\n const availableKeys = await this.loadAndRecoverKeysFor(dowt)\n const verifiedKeysMap = await this.icureStorage.loadSelfVerifiedKeys(dowt.dataOwner.id!)\n const allPublicKeys = this.dataOwnerApi.getHexPublicKeysOf(dowt.dataOwner)\n const fpToFullMap = fingerprintToPublicKeysMapOf(dowt.dataOwner)\n const unavailableKeys = Object.keys(availableKeys).flatMap((fp) => {\n const fullPublicKey = fpToFullMap[fp]\n return allPublicKeys.has(fullPublicKey) ? [] : [fullPublicKey]\n })\n const unknownKeys = Array.from(allPublicKeys).filter(\n (x) => !(x.slice(-32) in verifiedKeysMap) && !(availableKeys?.[x.slice(-32)]?.isDevice === true)\n )\n keysData.push({ dowt, availableKeys, unavailableKeys, unknownKeys })\n }\n const recoveryAndVerificationResult = await keyRecovererAndVerifier(\n keysData.map(({ dowt, unavailableKeys, unknownKeys }) => ({ dataOwner: dowt, unavailableKeys, unknownKeys }))\n )\n const keysCache: { [dataOwnerId: string]: { [fp: string]: KeyPairData } } = {}\n for (const keyData of keysData) {\n const currAuthenticity = this.ensureFingerprintKeys(recoveryAndVerificationResult[keyData.dowt.dataOwner.id!].keyAuthenticity)\n const currExternallyRecovered = this.ensureFingerprintKeys(recoveryAndVerificationResult[keyData.dowt.dataOwner.id!].recoveredKeys)\n for (const [fp, keyPair] of Object.entries(currExternallyRecovered)) {\n const jwkPair = await this.primitives.RSA.exportKeys(keyPair, 'jwk', 'jwk')\n await this.icureStorage.saveKey(keyData.dowt.dataOwner.id!, fp, jwkPair, true)\n }\n const updatedVerifiedMap = await this.icureStorage.saveSelfVerifiedKeys(\n keyData.dowt.dataOwner.id!,\n [...Object.keys(currAuthenticity), ...Object.keys(currExternallyRecovered)].reduce(\n (acc, currFp) => ({\n ...acc,\n [currFp]: currFp in currExternallyRecovered || currAuthenticity[currFp],\n }),\n {}\n )\n )\n const keysWithExternallyRecovered = {\n ...keyData.availableKeys,\n ...Object.fromEntries(Object.entries(currExternallyRecovered).map(([k, v]) => [k, { pair: v, isDevice: false }])),\n }\n const additionallyRecovered = await this.recoverAndCacheKeys(keyData.dowt, this.plainKeysByFingerprint(keysWithExternallyRecovered))\n const keys = {\n ...keysWithExternallyRecovered,\n ...Object.fromEntries(Object.entries(additionallyRecovered).map(([k, v]) => [k, { pair: v, isDevice: false }])),\n }\n keysCache[keyData.dowt.dataOwner.id!] = this.verifyKeys(keys, updatedVerifiedMap)\n }\n if (Object.entries(keysCache).some(([ownerId, data]) => ownerId !== self.dataOwner.id && !this.hasVerifiedKey(data))) {\n throw new Error('Some parent hcps have no verified keys: impossible to generate locally a new key for a parent.')\n } else if (this.hasVerifiedKey(keysCache[self.dataOwner.id!])) {\n this.keysCache = keysCache\n this.selfLegacyPublicKey = self.dataOwner.publicKey\n return undefined\n } else {\n const whatToDo = await currentOwnerKeyGenerator(self)\n if (whatToDo === false) {\n throw new Error(`No verified key found for ${self.dataOwner.id} and settings do not allow creation of a new key.`)\n } else {\n const updateInfo = await this.createAndSaveNewKeyPair(whatToDo === true ? undefined : whatToDo, self)\n // self may be outdated now\n this.selfLegacyPublicKey = updateInfo.updatedSelf.stub.publicKey\n this.keysCache = {\n ...keysCache,\n [self.dataOwner.id!]: {\n ...keysCache[self.dataOwner.id!],\n [updateInfo.publicKeyFingerprint]: { pair: updateInfo.keyPair, isDevice: true, isVerified: true },\n },\n }\n return { pair: updateInfo.keyPair, fingerprint: updateInfo.publicKeyFingerprint }\n }\n }\n }\n\n private async createAndSaveNewKeyPair(\n importedKeyPair: undefined | KeyPair<CryptoKey>,\n selfDataOwner: DataOwnerWithType\n ): Promise<{ publicKeyFingerprint: string; keyPair: KeyPair<CryptoKey>; updatedSelf: CryptoActorStubWithType }> {\n const keyPair = importedKeyPair ?? (await this.primitives.RSA.generateKeyPair())\n const publicKeyHex = ua2hex(await this.primitives.RSA.exportKey(keyPair.publicKey, 'spki'))\n const publicKeyFingerprint = publicKeyHex.slice(-32)\n await this.icureStorage.saveKey(\n selfDataOwner.dataOwner.id!,\n publicKeyFingerprint,\n await this.primitives.RSA.exportKeys(keyPair, 'jwk', 'jwk'),\n true\n )\n const verifiedPublicKeysMap = await this.icureStorage.saveSelfVerifiedKeys(selfDataOwner.dataOwner.id!, { [publicKeyFingerprint]: true })\n const { updatedDelegator } = await this.baseExchangeKeyManager.createOrUpdateEncryptedExchangeKeyTo(\n selfDataOwner.dataOwner.id!,\n keyPair,\n await loadPublicKeys(\n this.primitives.RSA,\n Array.from(this.dataOwnerApi.getHexPublicKeysOf(selfDataOwner.dataOwner)).filter((x) => verifiedPublicKeysMap[x.slice(-32)])\n )\n )\n return { publicKeyFingerprint, keyPair: keyPair, updatedSelf: updatedDelegator }\n }\n\n private async loadStoredKeys(\n dataOwner: DataOwnerWithType,\n pubKeysFingerprints: string[]\n ): Promise<{ [pubKeyFingerprint: string]: { pair: KeyPair<CryptoKey>; isDevice: boolean } }> {\n return await pubKeysFingerprints.reduce(async (acc, currentFingerprint) => {\n const awaitedAcc = await acc\n let loadedPair: { pair: KeyPair<CryptoKey>; isDevice: boolean } | undefined = undefined\n try {\n const storedKeypair = await this.icureStorage.loadKey(dataOwner.dataOwner.id!, currentFingerprint, dataOwner.dataOwner.publicKey)\n if (storedKeypair) {\n const importedKey = await this.primitives.RSA.importKeyPair('jwk', storedKeypair.pair.privateKey, 'jwk', storedKeypair.pair.publicKey)\n loadedPair = { pair: importedKey, isDevice: storedKeypair.isDevice }\n }\n } catch (e) {\n console.warn('Error while loading keypair', currentFingerprint, e)\n }\n return loadedPair\n ? {\n ...awaitedAcc,\n [currentFingerprint]: loadedPair,\n }\n : awaitedAcc\n }, Promise.resolve({} as { [pubKeyFingerprint: string]: { pair: KeyPair<CryptoKey>; isDevice: boolean } }))\n }\n\n private verifyKeys(\n keys: { [pubKeyFingerprint: string]: { pair: KeyPair<CryptoKey>; isDevice: boolean } },\n verifiedKeysMap: { [pubKeyFingerprint: string]: boolean }\n ): { [pubKeyFingerprint: string]: KeyPairData } {\n return Object.fromEntries(\n Object.entries(keys).map(\n ([fp, keyData]) => [fp, { ...keyData, isVerified: keyData.isDevice || verifiedKeysMap?.[fp] === true }] as [string, KeyPairData]\n )\n )\n }\n\n private plainKeysByFingerprint(richKeys: { [pubKeyFingerprint: string]: { pair: KeyPair<CryptoKey> } }): {\n [pubKeyFingerprint: string]: KeyPair<CryptoKey>\n } {\n return Object.fromEntries(Object.entries(richKeys).map(([fp, keyData]) => [fp, keyData.pair]))\n }\n\n private ensureInitialised() {\n if (!this.keysCache) throw new Error('Key manager was not properly initialised')\n }\n\n private async recoverAndCacheKeys(\n dataOwner: DataOwnerWithType,\n availableKeys: { [pubKeyFingerprint: string]: KeyPair<CryptoKey> }\n ): Promise<{ [p: string]: KeyPair<CryptoKey> }> {\n const recoveredKeys = await this.keyRecovery.recoverKeys(dataOwner, availableKeys)\n for (const [fp, pair] of Object.entries(recoveredKeys)) {\n await this.icureStorage.saveKey(dataOwner.dataOwner.id!, fp, await this.primitives.RSA.exportKeys(pair, 'jwk', 'jwk'), false)\n }\n return recoveredKeys\n }\n\n private async loadAndRecoverKeysFor(dataOwner: DataOwnerWithType): Promise<{ [keyFp: string]: { pair: KeyPair<CryptoKey>; isDevice: boolean } }> {\n const selfPublicKeys = this.dataOwnerApi.getHexPublicKeysOf(dataOwner.dataOwner)\n const pubKeysFingerprints = Array.from(selfPublicKeys).map((x) => x.slice(-32))\n const loadedKeys = pubKeysFingerprints.length > 0 ? await this.loadStoredKeys(dataOwner, pubKeysFingerprints) : {}\n const loadedKeysFingerprints = Object.keys(loadedKeys)\n if (loadedKeysFingerprints.length !== pubKeysFingerprints.length && loadedKeysFingerprints.length > 0) {\n const recoveredKeys = await this.recoverAndCacheKeys(dataOwner, this.plainKeysByFingerprint(loadedKeys))\n for (const [fp, pair] of Object.entries(recoveredKeys)) {\n loadedKeys[fp] = { pair, isDevice: false }\n }\n }\n return loadedKeys\n }\n\n private ensureFingerprintKeys<T>(obj: { [shouldBeFingerprint: string]: T }): { [definitelyFingerprint: string]: T } {\n return Object.fromEntries(Object.entries(obj).map(([k, v]) => [k.slice(-32), v]))\n }\n\n private hasVerifiedKey(keysData: { [fp: string]: KeyPairData }) {\n return Object.values(keysData).some((x) => x.isVerified || x.isDevice)\n }\n}\n"]}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { IccDataOwnerXApi } from '../icc-data-owner-x-api';
|
|
2
2
|
import { KeyPair } from './RSA';
|
|
3
3
|
import { CryptoPrimitives } from './CryptoPrimitives';
|
|
4
4
|
import { BaseExchangeKeysManager } from './BaseExchangeKeysManager';
|
|
5
|
+
import { DataOwnerWithType } from '../../icc-api/model/DataOwnerWithType';
|
|
5
6
|
/**
|
|
6
7
|
* @internal this class is intended only for internal use and may be changed without notice.
|
|
7
8
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"KeyRecovery.js","sourceRoot":"","sources":["../../../icc-x-api/crypto/KeyRecovery.ts"],"names":[],"mappings":"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","sourcesContent":["import { DataOwnerWithType, IccDataOwnerXApi } from '../icc-data-owner-x-api'\nimport { KeyPair } from './RSA'\nimport { CryptoPrimitives } from './CryptoPrimitives'\nimport { BaseExchangeKeysManager } from './BaseExchangeKeysManager'\nimport { hex2ua, ua2hex } from '../utils'\nimport { fingerprintToPublicKeysMapOf } from './utils'\n\n/**\n * @internal this class is intended only for internal use and may be changed without notice.\n *\n */\nexport class KeyRecovery {\n private readonly primitives: CryptoPrimitives\n private readonly baseExchangeKeysManager: BaseExchangeKeysManager\n private readonly dataOwnerApi: IccDataOwnerXApi\n\n constructor(primitives: CryptoPrimitives, baseExchangeKeysManager: BaseExchangeKeysManager, dataOwnerApi: IccDataOwnerXApi) {\n this.primitives = primitives\n this.baseExchangeKeysManager = baseExchangeKeysManager\n this.dataOwnerApi = dataOwnerApi\n }\n\n /**\n * Attempt to recover private keys of a data owner using all available key recovery methods and all available private keys. The method will\n * automatically try to use newly recovered key pairs to recover additional key pairs.\n * @param dataOwner a data owner.\n * @param knownKeys keys available for the data owner.\n * @return new key pairs (exclude already known pairs) which could be recovered using the known keys.\n */\n async recoverKeys(\n dataOwner: DataOwnerWithType,\n knownKeys: { [pubKeyFp: string]: KeyPair<CryptoKey> }\n ): Promise<{ [pubKeyFp: string]: KeyPair<CryptoKey> }> {\n const selfPublicKeys = Array.from(this.dataOwnerApi.getHexPublicKeysOf(dataOwner.dataOwner))\n const knownKeysFpSet = new Set(Object.keys(knownKeys))\n const missingKeysFpSet = new Set(selfPublicKeys.map((x) => x.slice(-32)).filter((x) => !knownKeysFpSet.has(x)))\n\n const recoveryFunctions = [this.recoverFromTransferKeys.bind(this), this.recoverFromShamirSplitKeys.bind(this)]\n let allPrivateKeys: { [pubKeyFingerprint: string]: KeyPair<CryptoKey> } = { ...knownKeys }\n let foundNewPrivateKeys = true\n\n while (missingKeysFpSet.size > 0 && foundNewPrivateKeys) {\n // TODO for each recovered verify correct association with public key\n foundNewPrivateKeys = false\n for (const recover of recoveryFunctions) {\n const recovered = await recover(dataOwner, allPrivateKeys, missingKeysFpSet)\n const validatedRecovered: { [fp: string]: KeyPair<CryptoKey> } = {}\n for (const [fp, keyPair] of Object.entries(recovered)) {\n const valid = await this.primitives.RSA.checkKeyPairValidity(keyPair)\n if (valid) {\n validatedRecovered[fp] = keyPair\n }\n }\n if (Object.keys(validatedRecovered).length > 0) {\n foundNewPrivateKeys = true\n Object.keys(validatedRecovered).forEach((fp) => missingKeysFpSet.delete(fp))\n allPrivateKeys = { ...allPrivateKeys, ...validatedRecovered }\n }\n }\n }\n\n return Object.fromEntries(Object.entries(allPrivateKeys).filter(([keyFp]) => !knownKeysFpSet.has(keyFp)))\n }\n\n /*TODO?\n * Ask access back suggestion: if by getting access back to an exchange key with another data owner I may recover additional keys we could suggest\n * to ask for access back to that data owner.\n */\n\n private async recoverFromShamirSplitKeys(\n dataOwner: DataOwnerWithType,\n allKeys: { [pubKeyFingerprint: string]: KeyPair<CryptoKey> },\n missingKeysFp: Set<string>\n ): Promise<{ [pubKeyFingerprint: string]: KeyPair<CryptoKey> }> {\n if (\n dataOwner.dataOwner.publicKey &&\n dataOwner.dataOwner.privateKeyShamirPartitions &&\n Object.keys(dataOwner.dataOwner.privateKeyShamirPartitions).length > 0\n ) {\n const selfId = dataOwner.dataOwner.id!\n const shamirSplits: { [keyPairFp: string]: { [delegateId: string]: string } } = {\n [dataOwner.dataOwner.publicKey!.slice(-32)]: dataOwner.dataOwner.privateKeyShamirPartitions!,\n }\n const delegatesOfSplits = Array.from(\n new Set(\n Object.entries(shamirSplits).flatMap(([splitKeyFp, splitKeyData]) => (missingKeysFp.has(splitKeyFp) ? Object.keys(splitKeyData) : []))\n )\n )\n const exchangeKeys: { [delegateId: string]: CryptoKey[] } = {}\n for (const delegate of delegatesOfSplits) {\n const currExchangeKeys = await this.baseExchangeKeysManager.getEncryptedExchangeKeysFor(selfId, delegate)\n exchangeKeys[delegate] = (await this.baseExchangeKeysManager.tryDecryptExchangeKeys(currExchangeKeys, allKeys)).successfulDecryptions\n }\n return await this.recoverWithSplits(dataOwner, shamirSplits, exchangeKeys)\n } else return {}\n }\n\n private async recoverWithSplits(\n dataOwner: DataOwnerWithType,\n splits: { [keyPairFp: string]: { [delegateId: string]: string } },\n exchangeKeys: { [delegateId: string]: CryptoKey[] }\n ): Promise<{ [pubKeyFingerprint: string]: KeyPair<CryptoKey> }> {\n const res: { [pubKeyFingerprint: string]: KeyPair<CryptoKey> } = {}\n const keysByFp = fingerprintToPublicKeysMapOf(dataOwner.dataOwner)\n for (const [fp, split] of Object.entries(splits)) {\n const recovered = await this.tryRecoverSplitPrivate(split, exchangeKeys)\n if (recovered) {\n const pub = keysByFp[fp]\n if (!pub) {\n console.warn(`Missing public key for fingerprint ${fp} of recovered shamir key.`)\n } else {\n try {\n res[fp] = {\n privateKey: recovered,\n publicKey: await this.primitives.RSA.importKey('spki', hex2ua(pub), ['encrypt']),\n }\n } catch (e) {\n console.warn(`Failed to import public key ${pub}`, e)\n }\n }\n }\n }\n return res\n }\n\n private async tryRecoverSplitPrivate(\n split: { [delegateId: string]: string },\n exchangeKeys: { [delegateId: string]: CryptoKey[] }\n ): Promise<CryptoKey | undefined> {\n const splitsCount = Object.keys(split).length\n if (splitsCount === 1) {\n // Not sure about the key nor if the key is accessible\n const [delegate, encryptedKey] = Object.entries(split)[0]\n for (const exchangeKey of exchangeKeys[delegate] ?? []) {\n try {\n const decrypted = await this.primitives.AES.decrypt(exchangeKey, hex2ua(encryptedKey))\n const importedKey = await this.primitives.RSA.importKey('pkcs8', decrypted, ['decrypt'])\n if (importedKey) return importedKey\n } catch (e) {}\n }\n return undefined\n } else {\n const decryptedSplits: string[] = []\n for (const delegateAndEncryptedSplit of Object.entries(split)) {\n const decrypted = await this.tryDecryptSplitPiece(delegateAndEncryptedSplit, exchangeKeys, splitsCount)\n if (decrypted) decryptedSplits.push(ua2hex(decrypted).slice(1)) // Drop padding\n }\n try {\n const combinedKey = hex2ua(this.primitives.shamir.combine(decryptedSplits))\n return await this.primitives.RSA.importKey('pkcs8', combinedKey, ['decrypt'])\n } catch (e) {\n // Could be not enough splits decrypted\n return undefined\n }\n }\n }\n\n private async tryDecryptSplitPiece(\n delegateAndEncryptedSplit: [string, string],\n exchangeKeys: { [delegateId: string]: CryptoKey[] },\n splitsCount: number\n ): Promise<ArrayBuffer | undefined> {\n const [delegate, encryptedPiece] = delegateAndEncryptedSplit\n for (const exchangeKey of exchangeKeys[delegate] ?? []) {\n try {\n const decrypted = await this.primitives.AES.decrypt(exchangeKey, hex2ua(encryptedPiece))\n if (this.validateDecryptedSplit(decrypted, splitsCount)) return decrypted\n } catch (e) {}\n }\n return undefined\n }\n\n private validateDecryptedSplit(decryptedSplit: ArrayBuffer, splitsCount: number): boolean {\n // Normally shamir split starts with 8 followed by the index of the split in hexadecimal.\n // However, we pad with an extra 'f' at the beginning\n const decryptedHex = ua2hex(decryptedSplit)\n if (decryptedHex[0] !== 'f' || decryptedHex[1] !== '8') return false\n try {\n const splitIndex = parseInt(decryptedHex.slice(2, 4), 16)\n return splitIndex > 0 && splitIndex <= splitsCount\n } catch (e) {\n return false\n }\n }\n\n private async recoverFromTransferKeys(\n dataOwner: DataOwnerWithType,\n allKeys: { [pubKeyFingerprint: string]: KeyPair<CryptoKey> },\n missingKeysFp: Set<string>\n ): Promise<{ [pubKeyFingerprint: string]: KeyPair<CryptoKey> }> {\n const publicKeyFingerprintToPublicKey = fingerprintToPublicKeysMapOf(dataOwner.dataOwner)\n const missingKeysTransferData: { [recoverableKeyPubFp: string]: { publicKey: string; encryptedPrivateKey: Set<string> } } = {}\n Object.values(dataOwner.dataOwner.transferKeys ?? {}).forEach((transferKeysByEncryptor) => {\n Object.entries(transferKeysByEncryptor).forEach(([transferToPublicKey, transferPrivateKeyEncrypted]) => {\n const transferToPublicKeyFp = transferToPublicKey.slice(-32) // We are not sure if transfer public key will be a fp or not\n if (missingKeysFp.has(transferToPublicKeyFp)) {\n const existingEntryValue = missingKeysTransferData[transferToPublicKeyFp]\n if (existingEntryValue) {\n existingEntryValue.encryptedPrivateKey.add(transferPrivateKeyEncrypted)\n } else {\n const fullPublicKey = publicKeyFingerprintToPublicKey[transferToPublicKeyFp]\n if (fullPublicKey) {\n missingKeysTransferData[transferToPublicKeyFp] = {\n publicKey: fullPublicKey,\n encryptedPrivateKey: new Set([transferPrivateKeyEncrypted]),\n }\n } else {\n console.warn('Invalid data owner: there is a transfer key for an unknown public key')\n }\n }\n }\n })\n })\n\n const { successfulDecryptions: availableExchangeKeys } = await this.baseExchangeKeysManager.tryDecryptExchangeKeys(\n await this.baseExchangeKeysManager.getEncryptedExchangeKeysFor(dataOwner.dataOwner.id!, dataOwner.dataOwner.id!),\n allKeys\n )\n\n return Object.entries(missingKeysTransferData).reduce(async (acc, [recoverableKeyPubFp, transferData]) => {\n const awaitedAcc = await acc\n const decryptedTransferData = await this.tryDecryptTransferData(transferData, availableExchangeKeys)\n if (decryptedTransferData != undefined) {\n return { ...awaitedAcc, [recoverableKeyPubFp]: decryptedTransferData }\n } else return awaitedAcc\n }, Promise.resolve({} as { [pubKeyFingerprint: string]: KeyPair<CryptoKey> }))\n }\n\n private async tryDecryptTransferData(\n transferData: { publicKey: string; encryptedPrivateKey: Set<string> },\n availableExchangeKeys: CryptoKey[]\n ): Promise<KeyPair<CryptoKey> | undefined> {\n for (const encryptedTransferKey of transferData.encryptedPrivateKey) {\n const decryptedTransferKey = await this.tryDecryptTransferKey(encryptedTransferKey, availableExchangeKeys)\n if (decryptedTransferKey != undefined)\n return {\n privateKey: decryptedTransferKey,\n publicKey: await this.primitives.RSA.importKey('spki', hex2ua(transferData.publicKey), ['encrypt']),\n }\n }\n return undefined\n }\n\n // attempt to decrypt a transfer key in pkcs8 using any of the provided exchange keys\n private async tryDecryptTransferKey(\n encryptedTransferKey: string, // in hex format\n exchangeKeys: CryptoKey[]\n ): Promise<CryptoKey | undefined> {\n const encryptedKeyBytes = hex2ua(encryptedTransferKey)\n for (const exchangeKey of exchangeKeys) {\n try {\n const decryptedKeyData = await this.primitives.AES.decrypt(exchangeKey, encryptedKeyBytes)\n const importedPrivateKey = await this.primitives.RSA.importPrivateKey('pkcs8', decryptedKeyData)\n if (importedPrivateKey != undefined) return importedPrivateKey\n } catch (e) {\n /* failure is a valid possibility: we don't know the correct key to use */\n }\n }\n return undefined\n }\n}\n"]}
|
|
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 } from './RSA'\nimport { CryptoPrimitives } from './CryptoPrimitives'\nimport { BaseExchangeKeysManager } from './BaseExchangeKeysManager'\nimport { hex2ua, ua2hex } from '../utils'\nimport { fingerprintToPublicKeysMapOf } from './utils'\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 private readonly primitives: CryptoPrimitives\n private readonly baseExchangeKeysManager: BaseExchangeKeysManager\n private readonly dataOwnerApi: IccDataOwnerXApi\n\n constructor(primitives: CryptoPrimitives, baseExchangeKeysManager: BaseExchangeKeysManager, dataOwnerApi: IccDataOwnerXApi) {\n this.primitives = primitives\n this.baseExchangeKeysManager = baseExchangeKeysManager\n this.dataOwnerApi = dataOwnerApi\n }\n\n /**\n * Attempt to recover private keys of a data owner using all available key recovery methods and all available private keys. The method will\n * automatically try to use newly recovered key pairs to recover additional key pairs.\n * @param dataOwner a data owner.\n * @param knownKeys keys available for the data owner.\n * @return new key pairs (exclude already known pairs) which could be recovered using the known keys.\n */\n async recoverKeys(\n dataOwner: DataOwnerWithType,\n knownKeys: { [pubKeyFp: string]: KeyPair<CryptoKey> }\n ): Promise<{ [pubKeyFp: string]: KeyPair<CryptoKey> }> {\n const selfPublicKeys = Array.from(this.dataOwnerApi.getHexPublicKeysOf(dataOwner.dataOwner))\n const knownKeysFpSet = new Set(Object.keys(knownKeys))\n const missingKeysFpSet = new Set(selfPublicKeys.map((x) => x.slice(-32)).filter((x) => !knownKeysFpSet.has(x)))\n\n const recoveryFunctions = [this.recoverFromTransferKeys.bind(this), this.recoverFromShamirSplitKeys.bind(this)]\n let allPrivateKeys: { [pubKeyFingerprint: string]: KeyPair<CryptoKey> } = { ...knownKeys }\n let foundNewPrivateKeys = true\n\n while (missingKeysFpSet.size > 0 && foundNewPrivateKeys) {\n // TODO for each recovered verify correct association with public key\n foundNewPrivateKeys = false\n for (const recover of recoveryFunctions) {\n const recovered = await recover(dataOwner, allPrivateKeys, missingKeysFpSet)\n const validatedRecovered: { [fp: string]: KeyPair<CryptoKey> } = {}\n for (const [fp, keyPair] of Object.entries(recovered)) {\n const valid = await this.primitives.RSA.checkKeyPairValidity(keyPair)\n if (valid) {\n validatedRecovered[fp] = keyPair\n }\n }\n if (Object.keys(validatedRecovered).length > 0) {\n foundNewPrivateKeys = true\n Object.keys(validatedRecovered).forEach((fp) => missingKeysFpSet.delete(fp))\n allPrivateKeys = { ...allPrivateKeys, ...validatedRecovered }\n }\n }\n }\n\n return Object.fromEntries(Object.entries(allPrivateKeys).filter(([keyFp]) => !knownKeysFpSet.has(keyFp)))\n }\n\n /*TODO?\n * Ask access back suggestion: if by getting access back to an exchange key with another data owner I may recover additional keys we could suggest\n * to ask for access back to that data owner.\n */\n\n private async recoverFromShamirSplitKeys(\n dataOwner: DataOwnerWithType,\n allKeys: { [pubKeyFingerprint: string]: KeyPair<CryptoKey> },\n missingKeysFp: Set<string>\n ): Promise<{ [pubKeyFingerprint: string]: KeyPair<CryptoKey> }> {\n if (\n dataOwner.dataOwner.publicKey &&\n dataOwner.dataOwner.privateKeyShamirPartitions &&\n Object.keys(dataOwner.dataOwner.privateKeyShamirPartitions).length > 0\n ) {\n const selfId = dataOwner.dataOwner.id!\n const shamirSplits: { [keyPairFp: string]: { [delegateId: string]: string } } = {\n [dataOwner.dataOwner.publicKey!.slice(-32)]: dataOwner.dataOwner.privateKeyShamirPartitions!,\n }\n const delegatesOfSplits = Array.from(\n new Set(\n Object.entries(shamirSplits).flatMap(([splitKeyFp, splitKeyData]) => (missingKeysFp.has(splitKeyFp) ? Object.keys(splitKeyData) : []))\n )\n )\n const exchangeKeys: { [delegateId: string]: CryptoKey[] } = {}\n for (const delegate of delegatesOfSplits) {\n const currExchangeKeys = await this.baseExchangeKeysManager.getEncryptedExchangeKeysFor(selfId, delegate)\n exchangeKeys[delegate] = (await this.baseExchangeKeysManager.tryDecryptExchangeKeys(currExchangeKeys, allKeys)).successfulDecryptions\n }\n return await this.recoverWithSplits(dataOwner, shamirSplits, exchangeKeys)\n } else return {}\n }\n\n private async recoverWithSplits(\n dataOwner: DataOwnerWithType,\n splits: { [keyPairFp: string]: { [delegateId: string]: string } },\n exchangeKeys: { [delegateId: string]: CryptoKey[] }\n ): Promise<{ [pubKeyFingerprint: string]: KeyPair<CryptoKey> }> {\n const res: { [pubKeyFingerprint: string]: KeyPair<CryptoKey> } = {}\n const keysByFp = fingerprintToPublicKeysMapOf(dataOwner.dataOwner)\n for (const [fp, split] of Object.entries(splits)) {\n const recovered = await this.tryRecoverSplitPrivate(split, exchangeKeys)\n if (recovered) {\n const pub = keysByFp[fp]\n if (!pub) {\n console.warn(`Missing public key for fingerprint ${fp} of recovered shamir key.`)\n } else {\n try {\n res[fp] = {\n privateKey: recovered,\n publicKey: await this.primitives.RSA.importKey('spki', hex2ua(pub), ['encrypt']),\n }\n } catch (e) {\n console.warn(`Failed to import public key ${pub}`, e)\n }\n }\n }\n }\n return res\n }\n\n private async tryRecoverSplitPrivate(\n split: { [delegateId: string]: string },\n exchangeKeys: { [delegateId: string]: CryptoKey[] }\n ): Promise<CryptoKey | undefined> {\n const splitsCount = Object.keys(split).length\n if (splitsCount === 1) {\n // Not sure about the key nor if the key is accessible\n const [delegate, encryptedKey] = Object.entries(split)[0]\n for (const exchangeKey of exchangeKeys[delegate] ?? []) {\n try {\n const decrypted = await this.primitives.AES.decrypt(exchangeKey, hex2ua(encryptedKey))\n const importedKey = await this.primitives.RSA.importKey('pkcs8', decrypted, ['decrypt'])\n if (importedKey) return importedKey\n } catch (e) {}\n }\n return undefined\n } else {\n const decryptedSplits: string[] = []\n for (const delegateAndEncryptedSplit of Object.entries(split)) {\n const decrypted = await this.tryDecryptSplitPiece(delegateAndEncryptedSplit, exchangeKeys, splitsCount)\n if (decrypted) decryptedSplits.push(ua2hex(decrypted).slice(1)) // Drop padding\n }\n try {\n const combinedKey = hex2ua(this.primitives.shamir.combine(decryptedSplits))\n return await this.primitives.RSA.importKey('pkcs8', combinedKey, ['decrypt'])\n } catch (e) {\n // Could be not enough splits decrypted\n return undefined\n }\n }\n }\n\n private async tryDecryptSplitPiece(\n delegateAndEncryptedSplit: [string, string],\n exchangeKeys: { [delegateId: string]: CryptoKey[] },\n splitsCount: number\n ): Promise<ArrayBuffer | undefined> {\n const [delegate, encryptedPiece] = delegateAndEncryptedSplit\n for (const exchangeKey of exchangeKeys[delegate] ?? []) {\n try {\n const decrypted = await this.primitives.AES.decrypt(exchangeKey, hex2ua(encryptedPiece))\n if (this.validateDecryptedSplit(decrypted, splitsCount)) return decrypted\n } catch (e) {}\n }\n return undefined\n }\n\n private validateDecryptedSplit(decryptedSplit: ArrayBuffer, splitsCount: number): boolean {\n // Normally shamir split starts with 8 followed by the index of the split in hexadecimal.\n // However, we pad with an extra 'f' at the beginning\n const decryptedHex = ua2hex(decryptedSplit)\n if (decryptedHex[0] !== 'f' || decryptedHex[1] !== '8') return false\n try {\n const splitIndex = parseInt(decryptedHex.slice(2, 4), 16)\n return splitIndex > 0 && splitIndex <= splitsCount\n } catch (e) {\n return false\n }\n }\n\n private async recoverFromTransferKeys(\n dataOwner: DataOwnerWithType,\n allKeys: { [pubKeyFingerprint: string]: KeyPair<CryptoKey> },\n missingKeysFp: Set<string>\n ): Promise<{ [pubKeyFingerprint: string]: KeyPair<CryptoKey> }> {\n const publicKeyFingerprintToPublicKey = fingerprintToPublicKeysMapOf(dataOwner.dataOwner)\n const missingKeysTransferData: { [recoverableKeyPubFp: string]: { publicKey: string; encryptedPrivateKey: Set<string> } } = {}\n Object.values(dataOwner.dataOwner.transferKeys ?? {}).forEach((transferKeysByEncryptor) => {\n Object.entries(transferKeysByEncryptor).forEach(([transferToPublicKey, transferPrivateKeyEncrypted]) => {\n const transferToPublicKeyFp = transferToPublicKey.slice(-32) // We are not sure if transfer public key will be a fp or not\n if (missingKeysFp.has(transferToPublicKeyFp)) {\n const existingEntryValue = missingKeysTransferData[transferToPublicKeyFp]\n if (existingEntryValue) {\n existingEntryValue.encryptedPrivateKey.add(transferPrivateKeyEncrypted)\n } else {\n const fullPublicKey = publicKeyFingerprintToPublicKey[transferToPublicKeyFp]\n if (fullPublicKey) {\n missingKeysTransferData[transferToPublicKeyFp] = {\n publicKey: fullPublicKey,\n encryptedPrivateKey: new Set([transferPrivateKeyEncrypted]),\n }\n } else {\n console.warn('Invalid data owner: there is a transfer key for an unknown public key')\n }\n }\n }\n })\n })\n\n const { successfulDecryptions: availableExchangeKeys } = await this.baseExchangeKeysManager.tryDecryptExchangeKeys(\n await this.baseExchangeKeysManager.getEncryptedExchangeKeysFor(dataOwner.dataOwner.id!, dataOwner.dataOwner.id!),\n allKeys\n )\n\n return Object.entries(missingKeysTransferData).reduce(async (acc, [recoverableKeyPubFp, transferData]) => {\n const awaitedAcc = await acc\n const decryptedTransferData = await this.tryDecryptTransferData(transferData, availableExchangeKeys)\n if (decryptedTransferData != undefined) {\n return { ...awaitedAcc, [recoverableKeyPubFp]: decryptedTransferData }\n } else return awaitedAcc\n }, Promise.resolve({} as { [pubKeyFingerprint: string]: KeyPair<CryptoKey> }))\n }\n\n private async tryDecryptTransferData(\n transferData: { publicKey: string; encryptedPrivateKey: Set<string> },\n availableExchangeKeys: CryptoKey[]\n ): Promise<KeyPair<CryptoKey> | undefined> {\n for (const encryptedTransferKey of transferData.encryptedPrivateKey) {\n const decryptedTransferKey = await this.tryDecryptTransferKey(encryptedTransferKey, availableExchangeKeys)\n if (decryptedTransferKey != undefined)\n return {\n privateKey: decryptedTransferKey,\n publicKey: await this.primitives.RSA.importKey('spki', hex2ua(transferData.publicKey), ['encrypt']),\n }\n }\n return undefined\n }\n\n // attempt to decrypt a transfer key in pkcs8 using any of the provided exchange keys\n private async tryDecryptTransferKey(\n encryptedTransferKey: string, // in hex format\n exchangeKeys: CryptoKey[]\n ): Promise<CryptoKey | undefined> {\n const encryptedKeyBytes = hex2ua(encryptedTransferKey)\n for (const exchangeKey of exchangeKeys) {\n try {\n const decryptedKeyData = await this.primitives.AES.decrypt(exchangeKey, encryptedKeyBytes)\n const importedPrivateKey = await this.primitives.RSA.importPrivateKey('pkcs8', decryptedKeyData)\n if (importedPrivateKey != undefined) return importedPrivateKey\n } catch (e) {\n /* failure is a valid possibility: we don't know the correct key to use */\n }\n }\n return undefined\n }\n}\n"]}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { CryptoStrategies } from './CryptoStrategies';
|
|
2
|
-
import { DataOwner } from '../icc-data-owner-x-api';
|
|
3
2
|
import { CryptoPrimitives } from './CryptoPrimitives';
|
|
4
3
|
import { KeyPair } from './RSA';
|
|
4
|
+
import { DataOwnerWithType } from '../../icc-api/model/DataOwnerWithType';
|
|
5
|
+
import { CryptoActorStubWithType } from '../../icc-api/model/CryptoActorStub';
|
|
5
6
|
/**
|
|
6
7
|
* Implementation of crypto strategies which should closely resemble a basic legacy behaviour of the crypto api:
|
|
7
8
|
* - Automatically creates a new key if there is no verified key available
|
|
@@ -9,9 +10,9 @@ import { KeyPair } from './RSA';
|
|
|
9
10
|
* - Never trust the own public keys coming from the server: this way the sdk will not automatically create data for key recovery.
|
|
10
11
|
*/
|
|
11
12
|
export declare class LegacyCryptoStrategies implements CryptoStrategies {
|
|
12
|
-
generateNewKeyForDataOwner(self:
|
|
13
|
+
generateNewKeyForDataOwner(self: DataOwnerWithType, cryptoPrimitives: CryptoPrimitives): Promise<KeyPair<CryptoKey> | boolean>;
|
|
13
14
|
recoverAndVerifySelfHierarchyKeys(keysData: {
|
|
14
|
-
dataOwner:
|
|
15
|
+
dataOwner: DataOwnerWithType;
|
|
15
16
|
unknownKeys: string[];
|
|
16
17
|
unavailableKeys: string[];
|
|
17
18
|
}[], cryptoPrimitives: CryptoPrimitives): Promise<{
|
|
@@ -24,5 +25,5 @@ export declare class LegacyCryptoStrategies implements CryptoStrategies {
|
|
|
24
25
|
};
|
|
25
26
|
};
|
|
26
27
|
}>;
|
|
27
|
-
verifyDelegatePublicKeys(delegate:
|
|
28
|
+
verifyDelegatePublicKeys(delegate: CryptoActorStubWithType, publicKeys: string[], cryptoPrimitives: CryptoPrimitives): Promise<string[]>;
|
|
28
29
|
}
|
|
@@ -12,7 +12,7 @@ class LegacyCryptoStrategies {
|
|
|
12
12
|
return Promise.resolve(true);
|
|
13
13
|
}
|
|
14
14
|
recoverAndVerifySelfHierarchyKeys(keysData, cryptoPrimitives) {
|
|
15
|
-
return Promise.resolve(Object.fromEntries(keysData.map(({ dataOwner }) => [dataOwner.id, { recoveredKeys: {}, keyAuthenticity: {} }])));
|
|
15
|
+
return Promise.resolve(Object.fromEntries(keysData.map(({ dataOwner }) => [dataOwner.dataOwner.id, { recoveredKeys: {}, keyAuthenticity: {} }])));
|
|
16
16
|
}
|
|
17
17
|
verifyDelegatePublicKeys(delegate, publicKeys, cryptoPrimitives) {
|
|
18
18
|
return Promise.resolve(publicKeys);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LegacyCryptoStrategies.js","sourceRoot":"","sources":["../../../icc-x-api/crypto/LegacyCryptoStrategies.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"LegacyCryptoStrategies.js","sourceRoot":"","sources":["../../../icc-x-api/crypto/LegacyCryptoStrategies.ts"],"names":[],"mappings":";;;AAMA;;;;;GAKG;AACH,MAAa,sBAAsB;IACjC,0BAA0B,CAAC,IAAuB,EAAE,gBAAkC;QACpF,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;IAC9B,CAAC;IAED,iCAAiC,CAC/B,QAA8F,EAC9F,gBAAkC;QAElC,OAAO,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,aAAa,EAAE,EAAE,EAAE,eAAe,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAA;IACnJ,CAAC;IAED,wBAAwB,CAAC,QAAiC,EAAE,UAAoB,EAAE,gBAAkC;QAClH,OAAO,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,CAAA;IACpC,CAAC;CACF;AAfD,wDAeC","sourcesContent":["import { CryptoStrategies } from './CryptoStrategies'\nimport { CryptoPrimitives } from './CryptoPrimitives'\nimport { KeyPair } from './RSA'\nimport { DataOwnerWithType } from '../../icc-api/model/DataOwnerWithType'\nimport { CryptoActorStubWithType } from '../../icc-api/model/CryptoActorStub'\n\n/**\n * Implementation of crypto strategies which should closely resemble a basic legacy behaviour of the crypto api:\n * - Automatically creates a new key if there is no verified key available\n * - Fully trusts the public keys coming from the server for the creation of aes exchange keys to delegates\n * - Never trust the own public keys coming from the server: this way the sdk will not automatically create data for key recovery.\n */\nexport class LegacyCryptoStrategies implements CryptoStrategies {\n generateNewKeyForDataOwner(self: DataOwnerWithType, cryptoPrimitives: CryptoPrimitives): Promise<KeyPair<CryptoKey> | boolean> {\n return Promise.resolve(true)\n }\n\n recoverAndVerifySelfHierarchyKeys(\n keysData: { dataOwner: DataOwnerWithType; unknownKeys: string[]; unavailableKeys: string[] }[],\n cryptoPrimitives: CryptoPrimitives\n ): Promise<{ [p: string]: { recoveredKeys: { [p: string]: KeyPair<CryptoKey> }; keyAuthenticity: { [p: string]: boolean } } }> {\n return Promise.resolve(Object.fromEntries(keysData.map(({ dataOwner }) => [dataOwner.dataOwner.id, { recoveredKeys: {}, keyAuthenticity: {} }])))\n }\n\n verifyDelegatePublicKeys(delegate: CryptoActorStubWithType, publicKeys: string[], cryptoPrimitives: CryptoPrimitives): Promise<string[]> {\n return Promise.resolve(publicKeys)\n }\n}\n"]}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { DataOwnerOrStub, IccDataOwnerXApi } from '../icc-data-owner-x-api';
|
|
2
2
|
import { KeyManager } from './KeyManager';
|
|
3
3
|
import { ExchangeKeysManager } from './ExchangeKeysManager';
|
|
4
4
|
import { CryptoPrimitives } from './CryptoPrimitives';
|
|
5
|
+
import { CryptoActorStubWithType } from '../../icc-api/model/CryptoActorStub';
|
|
5
6
|
/**
|
|
6
7
|
* Allows to create or update shamir split keys.
|
|
7
8
|
*/
|
|
@@ -17,7 +18,7 @@ export declare class ShamirKeysManager {
|
|
|
17
18
|
* @param dataOwner a data owner
|
|
18
19
|
* @return the existing splits for the current data owner as a publicKeyFingerprint -> notariesIds object
|
|
19
20
|
*/
|
|
20
|
-
getExistingSplitsInfo(dataOwner:
|
|
21
|
+
getExistingSplitsInfo(dataOwner: DataOwnerOrStub): {
|
|
21
22
|
[keyPairFingerprint: string]: string[];
|
|
22
23
|
};
|
|
23
24
|
/**
|
|
@@ -34,7 +35,7 @@ export declare class ShamirKeysManager {
|
|
|
34
35
|
notariesIds: string[];
|
|
35
36
|
minShares: number;
|
|
36
37
|
};
|
|
37
|
-
}, keySplitsToDelete: string[]): Promise<
|
|
38
|
+
}, keySplitsToDelete: string[]): Promise<CryptoActorStubWithType>;
|
|
38
39
|
private validateShamirParams;
|
|
39
40
|
private deleteKeySplit;
|
|
40
41
|
private updateKeySplit;
|
|
@@ -11,6 +11,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.ShamirKeysManager = void 0;
|
|
13
13
|
const utils_1 = require("../utils");
|
|
14
|
+
const CryptoActorStub_1 = require("../../icc-api/model/CryptoActorStub");
|
|
14
15
|
/**
|
|
15
16
|
* Allows to create or update shamir split keys.
|
|
16
17
|
*/
|
|
@@ -51,11 +52,11 @@ class ShamirKeysManager {
|
|
|
51
52
|
*/
|
|
52
53
|
updateSelfSplits(keySplitsToUpdate, keySplitsToDelete) {
|
|
53
54
|
return __awaiter(this, void 0, void 0, function* () {
|
|
54
|
-
const self = yield this.dataOwnerApi.getCurrentDataOwner();
|
|
55
|
+
const self = CryptoActorStub_1.CryptoActorStubWithType.fromDataOwner(yield this.dataOwnerApi.getCurrentDataOwner());
|
|
55
56
|
const toUpdateSet = new Set(Object.keys(keySplitsToUpdate).map((x) => x.slice(-32)));
|
|
56
57
|
const toDeleteSet = new Set(keySplitsToDelete.slice(-32));
|
|
57
58
|
const intersection = Array.from(toDeleteSet).filter((x) => toUpdateSet.has(x));
|
|
58
|
-
const existingSplits = new Set(Object.keys(this.getExistingSplitsInfo(self.
|
|
59
|
+
const existingSplits = new Set(Object.keys(this.getExistingSplitsInfo(self.stub)));
|
|
59
60
|
const allKeys = this.keyManager.getDecryptionKeys();
|
|
60
61
|
if (toDeleteSet.size !== keySplitsToDelete.length || toUpdateSet.size !== Object.keys(keySplitsToUpdate).length || intersection.length > 0)
|
|
61
62
|
throw new Error(`Duplicate keys in input:\nkeySplitsToUpdate: ${keySplitsToUpdate}\nkeySplitsToDelete: ${keySplitsToDelete}`);
|
|
@@ -81,7 +82,7 @@ class ShamirKeysManager {
|
|
|
81
82
|
for (const keyFp of toDeleteSet) {
|
|
82
83
|
updatedSelf = this.deleteKeySplit(updatedSelf, keyFp);
|
|
83
84
|
}
|
|
84
|
-
return yield this.dataOwnerApi.
|
|
85
|
+
return yield this.dataOwnerApi.modifyCryptoActorStub(updatedSelf);
|
|
85
86
|
});
|
|
86
87
|
}
|
|
87
88
|
/*TODO
|
|
@@ -98,23 +99,23 @@ class ShamirKeysManager {
|
|
|
98
99
|
}
|
|
99
100
|
deleteKeySplit(dataOwner, keyFp) {
|
|
100
101
|
var _a;
|
|
101
|
-
if (keyFp !== ((_a = dataOwner.
|
|
102
|
+
if (keyFp !== ((_a = dataOwner.stub.publicKey) === null || _a === void 0 ? void 0 : _a.slice(-32))) {
|
|
102
103
|
throw new Error('Currently it is possible to use shamir splits only for the legacy public key');
|
|
103
104
|
}
|
|
104
105
|
return {
|
|
105
106
|
type: dataOwner.type,
|
|
106
|
-
|
|
107
|
+
stub: Object.assign(Object.assign({}, dataOwner.stub), { privateKeyShamirPartitions: {} }),
|
|
107
108
|
};
|
|
108
109
|
}
|
|
109
110
|
updateKeySplit(dataOwner, keyFp, delegateIds, minShares, delegatesKeys, allKeys) {
|
|
110
111
|
var _a;
|
|
111
112
|
return __awaiter(this, void 0, void 0, function* () {
|
|
112
|
-
if (keyFp !== ((_a = dataOwner.
|
|
113
|
+
if (keyFp !== ((_a = dataOwner.stub.publicKey) === null || _a === void 0 ? void 0 : _a.slice(-32))) {
|
|
113
114
|
throw new Error('Currently it is possible to use shamir splits only for the legacy public key');
|
|
114
115
|
}
|
|
115
116
|
return {
|
|
116
117
|
type: dataOwner.type,
|
|
117
|
-
|
|
118
|
+
stub: Object.assign(Object.assign({}, dataOwner.stub), { privateKeyShamirPartitions: yield this.createPartitionsFor(allKeys[keyFp], delegateIds, minShares, delegatesKeys) }),
|
|
118
119
|
};
|
|
119
120
|
});
|
|
120
121
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ShamirKeysManager.js","sourceRoot":"","sources":["../../../icc-x-api/crypto/ShamirKeysManager.ts"],"names":[],"mappings":"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","sourcesContent":["import { DataOwner, DataOwnerWithType, IccDataOwnerXApi } from '../icc-data-owner-x-api'\nimport { KeyManager } from './KeyManager'\nimport { ExchangeKeysManager } from './ExchangeKeysManager'\nimport { CryptoPrimitives } from './CryptoPrimitives'\nimport { KeyPair } from './RSA'\nimport { hex2ua, ua2hex } from '../utils'\n\n/**\n * Allows to create or update shamir split keys.\n */\nexport class ShamirKeysManager {\n private readonly primitives: CryptoPrimitives\n private readonly dataOwnerApi: IccDataOwnerXApi\n private readonly keyManager: KeyManager\n private readonly exchangeKeysManager: ExchangeKeysManager\n\n constructor(primitives: CryptoPrimitives, dataOwnerApi: IccDataOwnerXApi, keyManager: KeyManager, exchangeKeysManager: ExchangeKeysManager) {\n this.primitives = primitives\n this.dataOwnerApi = dataOwnerApi\n this.keyManager = keyManager\n this.exchangeKeysManager = exchangeKeysManager\n }\n\n /**\n * Get information on existing private keys splits for the provided data owner. For each private key of the provided data owner which has been\n * split using the Shamir sharing algorithm gives the list of the notaries (other data owners) which hold a copy of the key part.\n * @param dataOwner a data owner\n * @return the existing splits for the current data owner as a publicKeyFingerprint -> notariesIds object\n */\n getExistingSplitsInfo(dataOwner: DataOwner): { [keyPairFingerprint: string]: string[] } {\n const legacyPartitionDelegates = Object.keys(dataOwner.privateKeyShamirPartitions ?? {})\n if (legacyPartitionDelegates.length > 0) {\n const fp = dataOwner.publicKey?.slice(-32)\n if (!fp) {\n console.error('Invalid data owner: the owner has legacy key partitions but no legacy key.')\n } else return { [fp]: legacyPartitionDelegates }\n }\n return {}\n }\n\n /**\n * Creates, updates or deletes shamir splits for keys of the current data owner. Any request to update the splits for a specific key will completely\n * replace any existing data on that split (all previous notaries will be ignored).\n * Note: currently you can only split the legacy key pair.\n * @param keySplitsToUpdate the fingerprints of key pairs which will have updated/new splits and the details on how to create the updated splits.\n * @param keySplitsToDelete the fingerprints or hex-encoded spki public keys which will not be shared anymore.\n * @throws if the parameters refer to non-existing or unavailable keys, have split creation details, or if they request to delete a non-existing\n * split.\n */\n async updateSelfSplits(\n keySplitsToUpdate: { [publicKeyHexOrFp: string]: { notariesIds: string[]; minShares: number } },\n keySplitsToDelete: string[]\n ): Promise<DataOwnerWithType> {\n const self = await this.dataOwnerApi.getCurrentDataOwner()\n const toUpdateSet = new Set(Object.keys(keySplitsToUpdate).map((x) => x.slice(-32)))\n const toDeleteSet = new Set(keySplitsToDelete.slice(-32))\n const intersection = Array.from(toDeleteSet).filter((x) => toUpdateSet.has(x))\n const existingSplits = new Set(Object.keys(this.getExistingSplitsInfo(self.dataOwner)))\n const allKeys = this.keyManager.getDecryptionKeys()\n if (toDeleteSet.size !== keySplitsToDelete.length || toUpdateSet.size !== Object.keys(keySplitsToUpdate).length || intersection.length > 0)\n throw new Error(`Duplicate keys in input:\\nkeySplitsToUpdate: ${keySplitsToUpdate}\\nkeySplitsToDelete: ${keySplitsToDelete}`)\n Object.entries(keySplitsToUpdate).forEach(([key, params]) => this.validateShamirParams(key, params))\n if (!Array.from(existingSplits).every((x) => existingSplits.has(x))) {\n throw new Error(`Requested to delete non-existing split.\\nexistingSplits: ${Array.from(existingSplits)}\\ntoDelete:${Array.from(toDeleteSet)}`)\n }\n if (Array.from(toUpdateSet).some((x) => !allKeys[x])) {\n throw new Error(`Private key is not available for some of the requested key split updates. ${keySplitsToUpdate}`)\n }\n const delegatesKeys: { [delegateId: string]: CryptoKey } = {}\n let updatedSelf = self\n for (const delegateId of new Set(Object.values(keySplitsToUpdate).flatMap((x) => x.notariesIds))) {\n const res = await this.exchangeKeysManager.getOrCreateEncryptionExchangeKeysTo(delegateId)\n delegatesKeys[delegateId] = res.keys[0]\n if (res.updatedDelegator) {\n updatedSelf = res.updatedDelegator\n }\n }\n for (const [key, params] of Object.entries(keySplitsToUpdate)) {\n updatedSelf = await this.updateKeySplit(updatedSelf, key.slice(-32), params.notariesIds, params.minShares, delegatesKeys, allKeys)\n }\n for (const keyFp of toDeleteSet) {\n updatedSelf = this.deleteKeySplit(updatedSelf, keyFp)\n }\n return await this.dataOwnerApi.updateDataOwner(updatedSelf)\n }\n\n /*TODO\n * Get suggested recovery keys: analyse transfer keys and shamir to get keys which should be shared with shamir for optimal recovery.\n */\n\n private validateShamirParams(key: string, params: { notariesIds: string[]; minShares: number }) {\n if (params.notariesIds.length > 0) {\n if (params.minShares > params.notariesIds.length) {\n throw new Error(`Invalid parameters for key ${key}: min shares can't be greater than the number of delegates. ${params}`)\n }\n } else throw new Error(`Invalid parameters for key ${key}: must have at least one delegate. ${params}`)\n }\n\n private deleteKeySplit(dataOwner: DataOwnerWithType, keyFp: string): DataOwnerWithType {\n if (keyFp !== dataOwner.dataOwner.publicKey?.slice(-32)) {\n throw new Error('Currently it is possible to use shamir splits only for the legacy public key')\n }\n return {\n type: dataOwner.type,\n dataOwner: {\n ...dataOwner.dataOwner,\n privateKeyShamirPartitions: {},\n },\n }\n }\n\n private async updateKeySplit(\n dataOwner: DataOwnerWithType,\n keyFp: string,\n delegateIds: string[],\n minShares: number,\n delegatesKeys: { [p: string]: CryptoKey },\n allKeys: { [p: string]: KeyPair<CryptoKey> }\n ): Promise<DataOwnerWithType> {\n if (keyFp !== dataOwner.dataOwner.publicKey?.slice(-32)) {\n throw new Error('Currently it is possible to use shamir splits only for the legacy public key')\n }\n return {\n type: dataOwner.type,\n dataOwner: {\n ...dataOwner.dataOwner,\n privateKeyShamirPartitions: await this.createPartitionsFor(allKeys[keyFp], delegateIds, minShares, delegatesKeys),\n },\n }\n }\n\n private async createPartitionsFor(\n keyPair: KeyPair<CryptoKey>,\n delegateIds: string[],\n minShares: number,\n delegatesKeys: { [p: string]: CryptoKey }\n ): Promise<{ [delegateId: string]: string }> {\n const exportedKey = await this.primitives.RSA.exportKey(keyPair.privateKey, 'pkcs8')\n if (delegateIds.length == 1) {\n return await this.encryptShares([exportedKey], delegateIds, delegatesKeys)\n } else {\n const exportedKeysHex = ua2hex(exportedKey)\n const stringShares = this.primitives.shamir.share(exportedKeysHex, delegateIds.length, minShares)\n const paddedStringShares = stringShares.map((x) => `f${x}`) // Shares are uneven length, apart from that they are perfect hexes\n for (const share of paddedStringShares) {\n if (!/^(?:[0-9a-f][0-9a-f])+$/g.test(share)) throw new Error('Unexpected result of shamir split: padded shares should be a valid hex value')\n if (share !== ua2hex(hex2ua(share))) throw new Error('Unexpected result with encoding-decoding share')\n }\n return await this.encryptShares(\n paddedStringShares.map((x) => hex2ua(x)),\n delegateIds,\n delegatesKeys\n )\n }\n }\n\n private async encryptShares(\n shares: ArrayBuffer[],\n delegateIds: string[],\n delegatesKeys: { [p: string]: CryptoKey }\n ): Promise<{ [delegateId: string]: string }> {\n return delegateIds.reduce(\n async (acc, delegateId, index) => ({\n ...(await acc),\n [delegateId]: ua2hex(await this.primitives.AES.encrypt(delegatesKeys[delegateId], shares[index])),\n }),\n Promise.resolve({} as { [delegateId: string]: string })\n )\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"ShamirKeysManager.js","sourceRoot":"","sources":["../../../icc-x-api/crypto/ShamirKeysManager.ts"],"names":[],"mappings":"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","sourcesContent":["import { DataOwnerOrStub, IccDataOwnerXApi } from '../icc-data-owner-x-api'\nimport { KeyManager } from './KeyManager'\nimport { ExchangeKeysManager } from './ExchangeKeysManager'\nimport { CryptoPrimitives } from './CryptoPrimitives'\nimport { KeyPair } from './RSA'\nimport { hex2ua, ua2hex } from '../utils'\nimport { CryptoActorStubWithType } from '../../icc-api/model/CryptoActorStub'\n\n/**\n * Allows to create or update shamir split keys.\n */\nexport class ShamirKeysManager {\n private readonly primitives: CryptoPrimitives\n private readonly dataOwnerApi: IccDataOwnerXApi\n private readonly keyManager: KeyManager\n private readonly exchangeKeysManager: ExchangeKeysManager\n\n constructor(primitives: CryptoPrimitives, dataOwnerApi: IccDataOwnerXApi, keyManager: KeyManager, exchangeKeysManager: ExchangeKeysManager) {\n this.primitives = primitives\n this.dataOwnerApi = dataOwnerApi\n this.keyManager = keyManager\n this.exchangeKeysManager = exchangeKeysManager\n }\n\n /**\n * Get information on existing private keys splits for the provided data owner. For each private key of the provided data owner which has been\n * split using the Shamir sharing algorithm gives the list of the notaries (other data owners) which hold a copy of the key part.\n * @param dataOwner a data owner\n * @return the existing splits for the current data owner as a publicKeyFingerprint -> notariesIds object\n */\n getExistingSplitsInfo(dataOwner: DataOwnerOrStub): { [keyPairFingerprint: string]: string[] } {\n const legacyPartitionDelegates = Object.keys(dataOwner.privateKeyShamirPartitions ?? {})\n if (legacyPartitionDelegates.length > 0) {\n const fp = dataOwner.publicKey?.slice(-32)\n if (!fp) {\n console.error('Invalid data owner: the owner has legacy key partitions but no legacy key.')\n } else return { [fp]: legacyPartitionDelegates }\n }\n return {}\n }\n\n /**\n * Creates, updates or deletes shamir splits for keys of the current data owner. Any request to update the splits for a specific key will completely\n * replace any existing data on that split (all previous notaries will be ignored).\n * Note: currently you can only split the legacy key pair.\n * @param keySplitsToUpdate the fingerprints of key pairs which will have updated/new splits and the details on how to create the updated splits.\n * @param keySplitsToDelete the fingerprints or hex-encoded spki public keys which will not be shared anymore.\n * @throws if the parameters refer to non-existing or unavailable keys, have split creation details, or if they request to delete a non-existing\n * split.\n */\n async updateSelfSplits(\n keySplitsToUpdate: { [publicKeyHexOrFp: string]: { notariesIds: string[]; minShares: number } },\n keySplitsToDelete: string[]\n ): Promise<CryptoActorStubWithType> {\n const self = CryptoActorStubWithType.fromDataOwner(await this.dataOwnerApi.getCurrentDataOwner())\n const toUpdateSet = new Set(Object.keys(keySplitsToUpdate).map((x) => x.slice(-32)))\n const toDeleteSet = new Set(keySplitsToDelete.slice(-32))\n const intersection = Array.from(toDeleteSet).filter((x) => toUpdateSet.has(x))\n const existingSplits = new Set(Object.keys(this.getExistingSplitsInfo(self.stub)))\n const allKeys = this.keyManager.getDecryptionKeys()\n if (toDeleteSet.size !== keySplitsToDelete.length || toUpdateSet.size !== Object.keys(keySplitsToUpdate).length || intersection.length > 0)\n throw new Error(`Duplicate keys in input:\\nkeySplitsToUpdate: ${keySplitsToUpdate}\\nkeySplitsToDelete: ${keySplitsToDelete}`)\n Object.entries(keySplitsToUpdate).forEach(([key, params]) => this.validateShamirParams(key, params))\n if (!Array.from(existingSplits).every((x) => existingSplits.has(x))) {\n throw new Error(`Requested to delete non-existing split.\\nexistingSplits: ${Array.from(existingSplits)}\\ntoDelete:${Array.from(toDeleteSet)}`)\n }\n if (Array.from(toUpdateSet).some((x) => !allKeys[x])) {\n throw new Error(`Private key is not available for some of the requested key split updates. ${keySplitsToUpdate}`)\n }\n const delegatesKeys: { [delegateId: string]: CryptoKey } = {}\n let updatedSelf = self\n for (const delegateId of new Set(Object.values(keySplitsToUpdate).flatMap((x) => x.notariesIds))) {\n const res = await this.exchangeKeysManager.getOrCreateEncryptionExchangeKeysTo(delegateId)\n delegatesKeys[delegateId] = res.keys[0]\n if (res.updatedDelegator) {\n updatedSelf = res.updatedDelegator\n }\n }\n for (const [key, params] of Object.entries(keySplitsToUpdate)) {\n updatedSelf = await this.updateKeySplit(updatedSelf, key.slice(-32), params.notariesIds, params.minShares, delegatesKeys, allKeys)\n }\n for (const keyFp of toDeleteSet) {\n updatedSelf = this.deleteKeySplit(updatedSelf, keyFp)\n }\n return await this.dataOwnerApi.modifyCryptoActorStub(updatedSelf)\n }\n\n /*TODO\n * Get suggested recovery keys: analyse transfer keys and shamir to get keys which should be shared with shamir for optimal recovery.\n */\n\n private validateShamirParams(key: string, params: { notariesIds: string[]; minShares: number }) {\n if (params.notariesIds.length > 0) {\n if (params.minShares > params.notariesIds.length) {\n throw new Error(`Invalid parameters for key ${key}: min shares can't be greater than the number of delegates. ${params}`)\n }\n } else throw new Error(`Invalid parameters for key ${key}: must have at least one delegate. ${params}`)\n }\n\n private deleteKeySplit(dataOwner: CryptoActorStubWithType, keyFp: string): CryptoActorStubWithType {\n if (keyFp !== dataOwner.stub.publicKey?.slice(-32)) {\n throw new Error('Currently it is possible to use shamir splits only for the legacy public key')\n }\n return {\n type: dataOwner.type,\n stub: {\n ...dataOwner.stub,\n privateKeyShamirPartitions: {},\n },\n }\n }\n\n private async updateKeySplit(\n dataOwner: CryptoActorStubWithType,\n keyFp: string,\n delegateIds: string[],\n minShares: number,\n delegatesKeys: { [p: string]: CryptoKey },\n allKeys: { [p: string]: KeyPair<CryptoKey> }\n ): Promise<CryptoActorStubWithType> {\n if (keyFp !== dataOwner.stub.publicKey?.slice(-32)) {\n throw new Error('Currently it is possible to use shamir splits only for the legacy public key')\n }\n return {\n type: dataOwner.type,\n stub: {\n ...dataOwner.stub,\n privateKeyShamirPartitions: await this.createPartitionsFor(allKeys[keyFp], delegateIds, minShares, delegatesKeys),\n },\n }\n }\n\n private async createPartitionsFor(\n keyPair: KeyPair<CryptoKey>,\n delegateIds: string[],\n minShares: number,\n delegatesKeys: { [p: string]: CryptoKey }\n ): Promise<{ [delegateId: string]: string }> {\n const exportedKey = await this.primitives.RSA.exportKey(keyPair.privateKey, 'pkcs8')\n if (delegateIds.length == 1) {\n return await this.encryptShares([exportedKey], delegateIds, delegatesKeys)\n } else {\n const exportedKeysHex = ua2hex(exportedKey)\n const stringShares = this.primitives.shamir.share(exportedKeysHex, delegateIds.length, minShares)\n const paddedStringShares = stringShares.map((x) => `f${x}`) // Shares are uneven length, apart from that they are perfect hexes\n for (const share of paddedStringShares) {\n if (!/^(?:[0-9a-f][0-9a-f])+$/g.test(share)) throw new Error('Unexpected result of shamir split: padded shares should be a valid hex value')\n if (share !== ua2hex(hex2ua(share))) throw new Error('Unexpected result with encoding-decoding share')\n }\n return await this.encryptShares(\n paddedStringShares.map((x) => hex2ua(x)),\n delegateIds,\n delegatesKeys\n )\n }\n }\n\n private async encryptShares(\n shares: ArrayBuffer[],\n delegateIds: string[],\n delegatesKeys: { [p: string]: CryptoKey }\n ): Promise<{ [delegateId: string]: string }> {\n return delegateIds.reduce(\n async (acc, delegateId, index) => ({\n ...(await acc),\n [delegateId]: ua2hex(await this.primitives.AES.encrypt(delegatesKeys[delegateId], shares[index])),\n }),\n Promise.resolve({} as { [delegateId: string]: string })\n )\n }\n}\n"]}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { BaseExchangeKeysManager } from './BaseExchangeKeysManager';
|
|
2
|
-
import {
|
|
2
|
+
import { IccDataOwnerXApi } from '../icc-data-owner-x-api';
|
|
3
3
|
import { KeyManager } from './KeyManager';
|
|
4
4
|
import { CryptoPrimitives } from './CryptoPrimitives';
|
|
5
5
|
import { IcureStorageFacade } from '../storage/IcureStorageFacade';
|
|
6
|
+
import { CryptoActorStubWithType } from '../../icc-api/model/CryptoActorStub';
|
|
6
7
|
/**
|
|
7
8
|
* @internal this class is intended only for internal use and may be changed without notice.
|
|
8
9
|
* Allows to create new transfer keys.
|
|
@@ -21,7 +22,7 @@ export declare class TransferKeysManager {
|
|
|
21
22
|
* @param self the current data owner.
|
|
22
23
|
* @return the updated data owner.
|
|
23
24
|
*/
|
|
24
|
-
updateTransferKeys(self:
|
|
25
|
+
updateTransferKeys(self: CryptoActorStubWithType): Promise<void>;
|
|
25
26
|
private encryptTransferKey;
|
|
26
27
|
private transferKeysCandidatesFp;
|
|
27
28
|
private transferTargetVerifiedKey;
|
|
@@ -39,7 +39,7 @@ class TransferKeysManager {
|
|
|
39
39
|
if (!newEdges)
|
|
40
40
|
return;
|
|
41
41
|
const selfId = yield this.dataOwnerApi.getCurrentDataOwnerId();
|
|
42
|
-
const fpToPublicKey = (0, utils_2.fingerprintToPublicKeysMapOf)(self.
|
|
42
|
+
const fpToPublicKey = (0, utils_2.fingerprintToPublicKeysMapOf)(self.stub);
|
|
43
43
|
const newExchangeKeyPublicKeys = newEdges.sources.map((fp) => fpToPublicKey[fp]);
|
|
44
44
|
const { key: exchangeKey, updatedDelegator: updatedSelf } = yield this.baseExchangeKeysManager.createOrUpdateEncryptedExchangeKeyTo(selfId, newEdges.target, yield (0, utils_2.loadPublicKeys)(this.primitives.RSA, newExchangeKeyPublicKeys));
|
|
45
45
|
// note: createEncryptedExchangeKeyFor may update self
|
|
@@ -50,10 +50,10 @@ class TransferKeysManager {
|
|
|
50
50
|
existingKeys[newEdges.targetFp] = encryptedTransferKey;
|
|
51
51
|
acc[candidateFp] = existingKeys;
|
|
52
52
|
return acc;
|
|
53
|
-
}, Object.assign({}, ((_a = updatedSelf.
|
|
54
|
-
yield this.dataOwnerApi.
|
|
53
|
+
}, Object.assign({}, ((_a = updatedSelf.stub.transferKeys) !== null && _a !== void 0 ? _a : {})));
|
|
54
|
+
yield this.dataOwnerApi.modifyCryptoActorStub({
|
|
55
55
|
type: updatedSelf.type,
|
|
56
|
-
|
|
56
|
+
stub: Object.assign(Object.assign({}, updatedSelf.stub), { transferKeys: newTransferKeys }),
|
|
57
57
|
});
|
|
58
58
|
});
|
|
59
59
|
}
|
|
@@ -80,13 +80,13 @@ class TransferKeysManager {
|
|
|
80
80
|
getNewVerifiedTransferKeysEdges(self) {
|
|
81
81
|
return __awaiter(this, void 0, void 0, function* () {
|
|
82
82
|
const verifiedKeysFpSet = new Set(this.keyManager.getSelfVerifiedKeys().map((x) => x.fingerprint));
|
|
83
|
-
Object.entries(yield this.icureStorage.loadSelfVerifiedKeys(self.
|
|
83
|
+
Object.entries(yield this.icureStorage.loadSelfVerifiedKeys(self.stub.id)).forEach(([key, verified]) => {
|
|
84
84
|
if (verified)
|
|
85
85
|
verifiedKeysFpSet.add(key.slice(-32));
|
|
86
86
|
});
|
|
87
87
|
if (verifiedKeysFpSet.size == 0)
|
|
88
88
|
return undefined;
|
|
89
|
-
const graph = (0, utils_2.transferKeysFpGraphOf)(self.
|
|
89
|
+
const graph = (0, utils_2.transferKeysFpGraphOf)(self.stub);
|
|
90
90
|
// 1. Choose a key available in this device which should be reachable from all other verified keys
|
|
91
91
|
const { fingerprint: targetKeyFp, pair: targetKey } = yield this.transferTargetVerifiedKey(this.keyManager);
|
|
92
92
|
// 2. Find groups which can't reach the existing target keys
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TransferKeysManager.js","sourceRoot":"","sources":["../../../icc-x-api/crypto/TransferKeysManager.ts"],"names":[],"mappings":"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","sourcesContent":["import { KeyPair } from './RSA'\nimport { BaseExchangeKeysManager } from './BaseExchangeKeysManager'\nimport { DataOwnerWithType, IccDataOwnerXApi } from '../icc-data-owner-x-api'\nimport { ua2hex } from '../utils'\nimport { KeyManager } from './KeyManager'\nimport { reachSetsAcyclic, StronglyConnectedGraph } from '../utils/graph-utils'\nimport { fingerprintToPublicKeysMapOf, loadPublicKeys, transferKeysFpGraphOf } from './utils'\nimport { CryptoPrimitives } from './CryptoPrimitives'\nimport { IcureStorageFacade } from '../storage/IcureStorageFacade'\n\n/**\n * @internal this class is intended only for internal use and may be changed without notice.\n * Allows to create new transfer keys.\n */\nexport class TransferKeysManager {\n private readonly primitives: CryptoPrimitives\n private readonly baseExchangeKeysManager: BaseExchangeKeysManager\n private readonly dataOwnerApi: IccDataOwnerXApi\n private readonly keyManager: KeyManager\n private readonly icureStorage: IcureStorageFacade\n\n constructor(\n primitives: CryptoPrimitives,\n baseExchangeKeysManager: BaseExchangeKeysManager,\n dataOwnerApi: IccDataOwnerXApi,\n keyManager: KeyManager,\n icureStorage: IcureStorageFacade\n ) {\n this.primitives = primitives\n this.baseExchangeKeysManager = baseExchangeKeysManager\n this.dataOwnerApi = dataOwnerApi\n this.keyManager = keyManager\n this.icureStorage = icureStorage\n }\n\n /**\n * Analyses the transfer keys graph and creates new transfer keys which allow to improve data accessibility from other devices.\n * For security reasons transfer keys will only be created between keys verified by the user, but this will be done ignoring any existing edges from\n * unverified keys to verified keys.\n * @param self the current data owner.\n * @return the updated data owner.\n */\n async updateTransferKeys(self: DataOwnerWithType): Promise<void> {\n const newEdges = await this.getNewVerifiedTransferKeysEdges(self)\n if (!newEdges) return\n const selfId = await this.dataOwnerApi.getCurrentDataOwnerId()\n const fpToPublicKey = fingerprintToPublicKeysMapOf(self.dataOwner)\n const newExchangeKeyPublicKeys = newEdges.sources.map((fp) => fpToPublicKey[fp])\n const { key: exchangeKey, updatedDelegator: updatedSelf } = await this.baseExchangeKeysManager.createOrUpdateEncryptedExchangeKeyTo(\n selfId,\n newEdges.target,\n await loadPublicKeys(this.primitives.RSA, newExchangeKeyPublicKeys)\n )\n // note: createEncryptedExchangeKeyFor may update self\n const encryptedTransferKey = await this.encryptTransferKey(newEdges.target, exchangeKey)\n const newTransferKeys = newEdges.sources.reduce(\n (acc, candidateFp) => {\n const existingKeys = { ...(acc[candidateFp] ?? {}) }\n existingKeys[newEdges.targetFp] = encryptedTransferKey\n acc[candidateFp] = existingKeys\n return acc\n },\n { ...(updatedSelf.dataOwner.transferKeys ?? {}) }\n )\n await this.dataOwnerApi.updateDataOwner({\n type: updatedSelf.type,\n dataOwner: {\n ...updatedSelf.dataOwner,\n transferKeys: newTransferKeys,\n },\n })\n }\n\n // encrypts a transfer key in pkcs8 format using an exchange key, returns the hex representation\n private async encryptTransferKey(transferKey: KeyPair<CryptoKey>, exchangeKey: CryptoKey): Promise<string> {\n const exportedKey = await this.primitives.RSA.exportKey(transferKey.privateKey, 'pkcs8')\n return ua2hex(await this.primitives.AES.encrypt(exchangeKey, exportedKey))\n }\n\n // all public keys would go to the stored keys -> no need for specifying the key.\n // Result only includes the acyclic label, not the full group\n private transferKeysCandidatesFp(keyToFp: string, graph: StronglyConnectedGraph): string[] {\n return Object.entries(reachSetsAcyclic(graph.acyclicGraph))\n .filter(([from, reachable]) => from != keyToFp && !reachable.has(keyToFp))\n .map((x) => x[0])\n }\n\n private async transferTargetVerifiedKey(keyManager: KeyManager): Promise<{ fingerprint: string; pair: KeyPair<CryptoKey> }> {\n return keyManager.getSelfVerifiedKeys()[0]\n }\n\n // Decides the best edges considering the verified public keys.\n private async getNewVerifiedTransferKeysEdges(self: DataOwnerWithType): Promise<\n | undefined\n | {\n sources: string[]\n target: KeyPair<CryptoKey>\n targetFp: string\n }\n > {\n const verifiedKeysFpSet = new Set(this.keyManager.getSelfVerifiedKeys().map((x) => x.fingerprint))\n Object.entries(await this.icureStorage.loadSelfVerifiedKeys(self.dataOwner.id!)).forEach(([key, verified]) => {\n if (verified) verifiedKeysFpSet.add(key.slice(-32))\n })\n if (verifiedKeysFpSet.size == 0) return undefined\n const graph = transferKeysFpGraphOf(self.dataOwner)\n // 1. Choose a key available in this device which should be reachable from all other verified keys\n const { fingerprint: targetKeyFp, pair: targetKey } = await this.transferTargetVerifiedKey(this.keyManager)\n // 2. Find groups which can't reach the existing target keys\n const candidatesFp = this.transferKeysCandidatesFp(targetKeyFp, graph)\n // 3. Keep only groups which contain at least a verified candidate\n const verifiedGroupCandidates = candidatesFp.filter((candidate) =>\n graph.acyclicLabelToGroup[candidate].some((candidateGroupMember) => verifiedKeysFpSet.has(candidateGroupMember))\n )\n const verifiedCandidatesSet = new Set(verifiedGroupCandidates)\n if (verifiedCandidatesSet.size == 0) return undefined\n // 4. Drop all candidates which can already reach another candidate group: it is sufficient to create a transfer key from that group.\n const reachSets = reachSetsAcyclic(graph.acyclicGraph)\n const optimizedCandidates = verifiedGroupCandidates.filter((candidate) =>\n Array.from(reachSets[candidate]).every((reachableNode) => !verifiedCandidatesSet.has(reachableNode))\n )\n if (optimizedCandidates.length == 0) throw new Error('Check failed: at least one candidate should survive optimization')\n // 5. Transfer keys could also be faked: to make sure we are not giving access to unauthorised people we remap the candidates to a verified public\n // keys\n const verifiedOptimizedCandidates = optimizedCandidates.map((candidate) => {\n const res = graph.acyclicLabelToGroup[candidate].find((groupMemberFp) => verifiedKeysFpSet.has(groupMemberFp))\n if (!res) throw new Error('Check failed: optimized candidates groups should have at least a verified member')\n return res\n })\n return {\n sources: verifiedOptimizedCandidates,\n target: targetKey,\n targetFp: targetKeyFp,\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"TransferKeysManager.js","sourceRoot":"","sources":["../../../icc-x-api/crypto/TransferKeysManager.ts"],"names":[],"mappings":"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","sourcesContent":["import { KeyPair } from './RSA'\nimport { BaseExchangeKeysManager } from './BaseExchangeKeysManager'\nimport { IccDataOwnerXApi } from '../icc-data-owner-x-api'\nimport { ua2hex } from '../utils'\nimport { KeyManager } from './KeyManager'\nimport { reachSetsAcyclic, StronglyConnectedGraph } from '../utils/graph-utils'\nimport { fingerprintToPublicKeysMapOf, loadPublicKeys, transferKeysFpGraphOf } from './utils'\nimport { CryptoPrimitives } from './CryptoPrimitives'\nimport { IcureStorageFacade } from '../storage/IcureStorageFacade'\nimport { CryptoActorStubWithType } from '../../icc-api/model/CryptoActorStub'\n\n/**\n * @internal this class is intended only for internal use and may be changed without notice.\n * Allows to create new transfer keys.\n */\nexport class TransferKeysManager {\n private readonly primitives: CryptoPrimitives\n private readonly baseExchangeKeysManager: BaseExchangeKeysManager\n private readonly dataOwnerApi: IccDataOwnerXApi\n private readonly keyManager: KeyManager\n private readonly icureStorage: IcureStorageFacade\n\n constructor(\n primitives: CryptoPrimitives,\n baseExchangeKeysManager: BaseExchangeKeysManager,\n dataOwnerApi: IccDataOwnerXApi,\n keyManager: KeyManager,\n icureStorage: IcureStorageFacade\n ) {\n this.primitives = primitives\n this.baseExchangeKeysManager = baseExchangeKeysManager\n this.dataOwnerApi = dataOwnerApi\n this.keyManager = keyManager\n this.icureStorage = icureStorage\n }\n\n /**\n * Analyses the transfer keys graph and creates new transfer keys which allow to improve data accessibility from other devices.\n * For security reasons transfer keys will only be created between keys verified by the user, but this will be done ignoring any existing edges from\n * unverified keys to verified keys.\n * @param self the current data owner.\n * @return the updated data owner.\n */\n async updateTransferKeys(self: CryptoActorStubWithType): Promise<void> {\n const newEdges = await this.getNewVerifiedTransferKeysEdges(self)\n if (!newEdges) return\n const selfId = await this.dataOwnerApi.getCurrentDataOwnerId()\n const fpToPublicKey = fingerprintToPublicKeysMapOf(self.stub)\n const newExchangeKeyPublicKeys = newEdges.sources.map((fp) => fpToPublicKey[fp])\n const { key: exchangeKey, updatedDelegator: updatedSelf } = await this.baseExchangeKeysManager.createOrUpdateEncryptedExchangeKeyTo(\n selfId,\n newEdges.target,\n await loadPublicKeys(this.primitives.RSA, newExchangeKeyPublicKeys)\n )\n // note: createEncryptedExchangeKeyFor may update self\n const encryptedTransferKey = await this.encryptTransferKey(newEdges.target, exchangeKey)\n const newTransferKeys = newEdges.sources.reduce(\n (acc, candidateFp) => {\n const existingKeys = { ...(acc[candidateFp] ?? {}) }\n existingKeys[newEdges.targetFp] = encryptedTransferKey\n acc[candidateFp] = existingKeys\n return acc\n },\n { ...(updatedSelf.stub.transferKeys ?? {}) }\n )\n await this.dataOwnerApi.modifyCryptoActorStub({\n type: updatedSelf.type,\n stub: {\n ...updatedSelf.stub,\n transferKeys: newTransferKeys,\n },\n })\n }\n\n // encrypts a transfer key in pkcs8 format using an exchange key, returns the hex representation\n private async encryptTransferKey(transferKey: KeyPair<CryptoKey>, exchangeKey: CryptoKey): Promise<string> {\n const exportedKey = await this.primitives.RSA.exportKey(transferKey.privateKey, 'pkcs8')\n return ua2hex(await this.primitives.AES.encrypt(exchangeKey, exportedKey))\n }\n\n // all public keys would go to the stored keys -> no need for specifying the key.\n // Result only includes the acyclic label, not the full group\n private transferKeysCandidatesFp(keyToFp: string, graph: StronglyConnectedGraph): string[] {\n return Object.entries(reachSetsAcyclic(graph.acyclicGraph))\n .filter(([from, reachable]) => from != keyToFp && !reachable.has(keyToFp))\n .map((x) => x[0])\n }\n\n private async transferTargetVerifiedKey(keyManager: KeyManager): Promise<{ fingerprint: string; pair: KeyPair<CryptoKey> }> {\n return keyManager.getSelfVerifiedKeys()[0]\n }\n\n // Decides the best edges considering the verified public keys.\n private async getNewVerifiedTransferKeysEdges(self: CryptoActorStubWithType): Promise<\n | undefined\n | {\n sources: string[]\n target: KeyPair<CryptoKey>\n targetFp: string\n }\n > {\n const verifiedKeysFpSet = new Set(this.keyManager.getSelfVerifiedKeys().map((x) => x.fingerprint))\n Object.entries(await this.icureStorage.loadSelfVerifiedKeys(self.stub.id!)).forEach(([key, verified]) => {\n if (verified) verifiedKeysFpSet.add(key.slice(-32))\n })\n if (verifiedKeysFpSet.size == 0) return undefined\n const graph = transferKeysFpGraphOf(self.stub)\n // 1. Choose a key available in this device which should be reachable from all other verified keys\n const { fingerprint: targetKeyFp, pair: targetKey } = await this.transferTargetVerifiedKey(this.keyManager)\n // 2. Find groups which can't reach the existing target keys\n const candidatesFp = this.transferKeysCandidatesFp(targetKeyFp, graph)\n // 3. Keep only groups which contain at least a verified candidate\n const verifiedGroupCandidates = candidatesFp.filter((candidate) =>\n graph.acyclicLabelToGroup[candidate].some((candidateGroupMember) => verifiedKeysFpSet.has(candidateGroupMember))\n )\n const verifiedCandidatesSet = new Set(verifiedGroupCandidates)\n if (verifiedCandidatesSet.size == 0) return undefined\n // 4. Drop all candidates which can already reach another candidate group: it is sufficient to create a transfer key from that group.\n const reachSets = reachSetsAcyclic(graph.acyclicGraph)\n const optimizedCandidates = verifiedGroupCandidates.filter((candidate) =>\n Array.from(reachSets[candidate]).every((reachableNode) => !verifiedCandidatesSet.has(reachableNode))\n )\n if (optimizedCandidates.length == 0) throw new Error('Check failed: at least one candidate should survive optimization')\n // 5. Transfer keys could also be faked: to make sure we are not giving access to unauthorised people we remap the candidates to a verified public\n // keys\n const verifiedOptimizedCandidates = optimizedCandidates.map((candidate) => {\n const res = graph.acyclicLabelToGroup[candidate].find((groupMemberFp) => verifiedKeysFpSet.has(groupMemberFp))\n if (!res) throw new Error('Check failed: optimized candidates groups should have at least a verified member')\n return res\n })\n return {\n sources: verifiedOptimizedCandidates,\n target: targetKey,\n targetFp: targetKeyFp,\n }\n }\n}\n"]}
|