@icure/api 7.1.16 → 8.0.0-RC.2
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.d.ts +12 -1
- package/icc-api/api/IccAccesslogApi.js +142 -98
- package/icc-api/api/IccAccesslogApi.js.map +1 -1
- package/icc-api/api/IccBemikronoApi.d.ts +81 -0
- package/icc-api/api/IccBemikronoApi.js +163 -0
- package/icc-api/api/IccBemikronoApi.js.map +1 -0
- package/icc-api/api/IccCalendarItemApi.d.ts +21 -1
- package/icc-api/api/IccCalendarItemApi.js +183 -117
- package/icc-api/api/IccCalendarItemApi.js.map +1 -1
- package/icc-api/api/IccClassificationApi.d.ts +21 -1
- package/icc-api/api/IccClassificationApi.js +119 -63
- package/icc-api/api/IccClassificationApi.js.map +1 -1
- package/icc-api/api/IccContactApi.d.ts +21 -1
- package/icc-api/api/IccContactApi.js +385 -294
- package/icc-api/api/IccContactApi.js.map +1 -1
- package/icc-api/api/IccDocumentApi.d.ts +38 -25
- package/icc-api/api/IccDocumentApi.js +279 -212
- package/icc-api/api/IccDocumentApi.js.map +1 -1
- package/icc-api/api/IccExchangeDataApi.d.ts +19 -0
- package/icc-api/api/IccExchangeDataApi.js +85 -0
- package/icc-api/api/IccExchangeDataApi.js.map +1 -0
- package/icc-api/api/IccExchangeDataMapApi.d.ts +18 -0
- package/icc-api/api/IccExchangeDataMapApi.js +65 -0
- package/icc-api/api/IccExchangeDataMapApi.js.map +1 -0
- package/icc-api/api/IccFormApi.d.ts +21 -1
- package/icc-api/api/IccFormApi.js +321 -229
- package/icc-api/api/IccFormApi.js.map +1 -1
- package/icc-api/api/IccHelementApi.d.ts +21 -1
- package/icc-api/api/IccHelementApi.js +207 -137
- package/icc-api/api/IccHelementApi.js.map +1 -1
- package/icc-api/api/IccInvoiceApi.d.ts +21 -1
- package/icc-api/api/IccInvoiceApi.js +404 -298
- package/icc-api/api/IccInvoiceApi.js.map +1 -1
- package/icc-api/api/IccMaintenanceTaskApi.d.ts +12 -1
- package/icc-api/api/IccMaintenanceTaskApi.js +79 -43
- package/icc-api/api/IccMaintenanceTaskApi.js.map +1 -1
- package/icc-api/api/IccMessageApi.d.ts +28 -1
- package/icc-api/api/IccMessageApi.js +294 -191
- package/icc-api/api/IccMessageApi.js.map +1 -1
- package/icc-api/api/IccPatientApi.d.ts +12 -1
- package/icc-api/api/IccPatientApi.js +447 -351
- package/icc-api/api/IccPatientApi.js.map +1 -1
- package/icc-api/api/IccReceiptApi.d.ts +22 -8
- package/icc-api/api/IccReceiptApi.js +121 -64
- package/icc-api/api/IccReceiptApi.js.map +1 -1
- package/icc-api/api/IccRestApiPath.js +1 -1
- package/icc-api/api/IccRestApiPath.js.map +1 -1
- package/icc-api/api/IccSecureDelegationKeyMapApi.d.ts +26 -0
- package/icc-api/api/IccSecureDelegationKeyMapApi.js +71 -0
- package/icc-api/api/IccSecureDelegationKeyMapApi.js.map +1 -0
- package/icc-api/api/IccTimeTableApi.d.ts +12 -1
- package/icc-api/api/IccTimeTableApi.js +86 -48
- package/icc-api/api/IccTimeTableApi.js.map +1 -1
- package/icc-api/api/IccTopicApi.d.ts +90 -0
- package/icc-api/api/IccTopicApi.js +193 -0
- package/icc-api/api/IccTopicApi.js.map +1 -0
- package/icc-api/index.d.ts +2 -0
- package/icc-api/index.js +2 -0
- package/icc-api/index.js.map +1 -1
- package/icc-api/model/AbstractFilterMessage.d.ts +15 -0
- package/icc-api/model/AbstractFilterMessage.js +21 -0
- package/icc-api/model/AbstractFilterMessage.js.map +1 -0
- package/icc-api/model/AbstractFilterTopic.d.ts +15 -0
- package/icc-api/model/AbstractFilterTopic.js +21 -0
- package/icc-api/model/AbstractFilterTopic.js.map +1 -0
- package/icc-api/model/AccessLog.d.ts +2 -0
- package/icc-api/model/AccessLog.js.map +1 -1
- package/icc-api/model/Article.d.ts +2 -0
- package/icc-api/model/Article.js.map +1 -1
- package/icc-api/model/CalendarItem.d.ts +2 -0
- package/icc-api/model/CalendarItem.js.map +1 -1
- package/icc-api/model/Classification.d.ts +2 -0
- package/icc-api/model/Classification.js.map +1 -1
- package/icc-api/model/ClassificationTemplate.d.ts +2 -0
- package/icc-api/model/ClassificationTemplate.js.map +1 -1
- package/icc-api/model/Connection.d.ts +1 -1
- package/icc-api/model/Connection.js.map +1 -1
- package/icc-api/model/Contact.d.ts +2 -0
- package/icc-api/model/Contact.js.map +1 -1
- package/icc-api/model/Device.d.ts +4 -4
- package/icc-api/model/Device.js.map +1 -1
- package/icc-api/model/Document.d.ts +2 -0
- package/icc-api/model/Document.js.map +1 -1
- package/icc-api/model/ExchangeDataMapCreationBatch.d.ts +13 -0
- package/icc-api/model/ExchangeDataMapCreationBatch.js +10 -0
- package/icc-api/model/ExchangeDataMapCreationBatch.js.map +1 -0
- package/icc-api/model/FilterChainMessage.d.ts +19 -0
- package/icc-api/model/FilterChainMessage.js +11 -0
- package/icc-api/model/FilterChainMessage.js.map +1 -0
- package/icc-api/model/FilterChainTopic.d.ts +19 -0
- package/icc-api/model/FilterChainTopic.js +11 -0
- package/icc-api/model/FilterChainTopic.js.map +1 -0
- package/icc-api/model/Form.d.ts +2 -0
- package/icc-api/model/Form.js.map +1 -1
- package/icc-api/model/HealthElement.d.ts +2 -0
- package/icc-api/model/HealthElement.js.map +1 -1
- package/icc-api/model/HealthcareParty.d.ts +2 -2
- package/icc-api/model/HealthcareParty.js +13 -1
- package/icc-api/model/HealthcareParty.js.map +1 -1
- package/icc-api/model/IcureStub.d.ts +2 -0
- package/icc-api/model/IcureStub.js.map +1 -1
- package/icc-api/model/Invoice.d.ts +2 -0
- package/icc-api/model/Invoice.js.map +1 -1
- package/icc-api/model/MaintenanceTask.d.ts +13 -10
- package/icc-api/model/MaintenanceTask.js +13 -11
- package/icc-api/model/MaintenanceTask.js.map +1 -1
- package/icc-api/model/Message.d.ts +2 -0
- package/icc-api/model/Message.js.map +1 -1
- package/icc-api/model/PaginatedListExchangeData.d.ts +9 -0
- package/icc-api/model/PaginatedListExchangeData.js +10 -0
- package/icc-api/model/PaginatedListExchangeData.js.map +1 -0
- package/icc-api/model/PaginatedListTopic.d.ts +20 -0
- package/icc-api/model/PaginatedListTopic.js +10 -0
- package/icc-api/model/PaginatedListTopic.js.map +1 -0
- package/icc-api/model/Patient.d.ts +4 -2
- package/icc-api/model/Patient.js.map +1 -1
- package/icc-api/model/PatientByHcPartyGenderEducationProfession.d.ts +31 -0
- package/icc-api/model/PatientByHcPartyGenderEducationProfession.js +32 -0
- package/icc-api/model/PatientByHcPartyGenderEducationProfession.js.map +1 -0
- package/icc-api/model/Receipt.d.ts +2 -0
- package/icc-api/model/Receipt.js.map +1 -1
- package/icc-api/model/SecureDelegation.d.ts +52 -0
- package/icc-api/model/SecureDelegation.js +16 -0
- package/icc-api/model/SecureDelegation.js.map +1 -0
- package/icc-api/model/SecurityMetadata.d.ts +33 -0
- package/icc-api/model/SecurityMetadata.js +13 -0
- package/icc-api/model/SecurityMetadata.js.map +1 -0
- package/icc-api/model/Service.d.ts +2 -0
- package/icc-api/model/Service.js.map +1 -1
- package/icc-api/model/TimeTable.d.ts +2 -0
- package/icc-api/model/TimeTable.js.map +1 -1
- package/icc-api/model/Topic.d.ts +95 -0
- package/icc-api/model/Topic.js +16 -0
- package/icc-api/model/Topic.js.map +1 -0
- package/icc-api/model/internal/ExchangeData.d.ts +64 -0
- package/icc-api/model/internal/ExchangeData.js +15 -0
- package/icc-api/model/internal/ExchangeData.js.map +1 -0
- package/icc-api/model/internal/ExchangeDataMap.d.ts +24 -0
- package/icc-api/model/internal/ExchangeDataMap.js +13 -0
- package/icc-api/model/internal/ExchangeDataMap.js.map +1 -0
- package/icc-api/model/internal/SecureDelegationKeyMap.d.ts +14 -0
- package/icc-api/model/internal/SecureDelegationKeyMap.js +13 -0
- package/icc-api/model/internal/SecureDelegationKeyMap.js.map +1 -0
- package/icc-api/model/models.d.ts +26 -40
- package/icc-api/model/models.js +19 -37
- package/icc-api/model/models.js.map +1 -1
- package/icc-api/model/requests/EntityBulkShareResult.d.ts +28 -0
- package/icc-api/model/requests/EntityBulkShareResult.js +16 -0
- package/icc-api/model/requests/EntityBulkShareResult.js.map +1 -0
- package/icc-api/model/requests/EntityShareOrMetadataUpdateRequest.d.ts +10 -0
- package/icc-api/model/requests/EntityShareOrMetadataUpdateRequest.js +17 -0
- package/icc-api/model/requests/EntityShareOrMetadataUpdateRequest.js.map +1 -0
- package/icc-api/model/requests/EntityShareRequest.d.ts +110 -0
- package/icc-api/model/requests/EntityShareRequest.js +63 -0
- package/icc-api/model/requests/EntityShareRequest.js.map +1 -0
- package/icc-api/model/requests/EntitySharedMetadataUpdateRequest.d.ts +54 -0
- package/icc-api/model/requests/EntitySharedMetadataUpdateRequest.js +24 -0
- package/icc-api/model/requests/EntitySharedMetadataUpdateRequest.js.map +1 -0
- package/icc-api/model/requests/MinimalEntityBulkShareResult.d.ts +23 -0
- package/icc-api/model/requests/MinimalEntityBulkShareResult.js +13 -0
- package/icc-api/model/requests/MinimalEntityBulkShareResult.js.map +1 -0
- package/icc-api/model/requests/RejectedShareOrMetadataUpdateRequest.d.ts +21 -0
- package/icc-api/model/requests/RejectedShareOrMetadataUpdateRequest.js +14 -0
- package/icc-api/model/requests/RejectedShareOrMetadataUpdateRequest.js.map +1 -0
- package/icc-x-api/basexapi/EncryptedEntityXApi.d.ts +55 -6
- package/icc-x-api/basexapi/EncryptedEntityXApi.js.map +1 -1
- package/icc-x-api/crypto/AES.js +1 -1
- package/icc-x-api/crypto/AES.js.map +1 -1
- package/icc-x-api/crypto/AccessControlKeysHeadersProvider.d.ts +18 -0
- package/icc-x-api/crypto/AccessControlKeysHeadersProvider.js +50 -0
- package/icc-x-api/crypto/AccessControlKeysHeadersProvider.js.map +1 -0
- package/icc-x-api/crypto/AccessControlSecretUtils.d.ts +43 -0
- package/icc-x-api/crypto/AccessControlSecretUtils.js +97 -0
- package/icc-x-api/crypto/AccessControlSecretUtils.js.map +1 -0
- package/icc-x-api/crypto/BaseExchangeDataManager.d.ts +146 -0
- package/icc-x-api/crypto/BaseExchangeDataManager.js +342 -0
- package/icc-x-api/crypto/BaseExchangeDataManager.js.map +1 -0
- package/icc-x-api/crypto/BaseExchangeKeysManager.d.ts +0 -18
- package/icc-x-api/crypto/BaseExchangeKeysManager.js +11 -85
- package/icc-x-api/crypto/BaseExchangeKeysManager.js.map +1 -1
- package/icc-x-api/crypto/ConfidentialEntities.d.ts +26 -16
- package/icc-x-api/crypto/ConfidentialEntities.js +30 -17
- package/icc-x-api/crypto/ConfidentialEntities.js.map +1 -1
- package/icc-x-api/crypto/CryptoStrategies.d.ts +8 -1
- package/icc-x-api/crypto/CryptoStrategies.js.map +1 -1
- package/icc-x-api/crypto/DelegationsDeAnonymization.d.ts +44 -0
- package/icc-x-api/crypto/DelegationsDeAnonymization.js +235 -0
- package/icc-x-api/crypto/DelegationsDeAnonymization.js.map +1 -0
- package/icc-x-api/crypto/ExchangeDataManager.d.ts +97 -0
- package/icc-x-api/crypto/ExchangeDataManager.js +501 -0
- package/icc-x-api/crypto/ExchangeDataManager.js.map +1 -0
- package/icc-x-api/crypto/ExchangeDataMapManager.d.ts +32 -0
- package/icc-x-api/crypto/ExchangeDataMapManager.js +70 -0
- package/icc-x-api/crypto/ExchangeDataMapManager.js.map +1 -0
- package/icc-x-api/crypto/ExchangeKeysManager.d.ts +4 -16
- package/icc-x-api/crypto/ExchangeKeysManager.js +4 -62
- package/icc-x-api/crypto/ExchangeKeysManager.js.map +1 -1
- package/icc-x-api/crypto/ExtendedApisUtils.d.ts +326 -0
- package/icc-x-api/crypto/ExtendedApisUtils.js +3 -0
- package/icc-x-api/crypto/ExtendedApisUtils.js.map +1 -0
- package/icc-x-api/crypto/ExtendedApisUtilsImpl.d.ts +174 -0
- package/icc-x-api/crypto/ExtendedApisUtilsImpl.js +559 -0
- package/icc-x-api/crypto/ExtendedApisUtilsImpl.js.map +1 -0
- package/icc-x-api/crypto/KeyRecovery.d.ts +5 -2
- package/icc-x-api/crypto/KeyRecovery.js +59 -29
- package/icc-x-api/crypto/KeyRecovery.js.map +1 -1
- package/icc-x-api/crypto/LegacyCryptoStrategies.d.ts +7 -2
- package/icc-x-api/crypto/LegacyCryptoStrategies.js +8 -1
- package/icc-x-api/crypto/LegacyCryptoStrategies.js.map +1 -1
- package/icc-x-api/crypto/LegacyDelegationSecurityMetadataDecryptor.d.ts +33 -0
- package/icc-x-api/crypto/LegacyDelegationSecurityMetadataDecryptor.js +141 -0
- package/icc-x-api/crypto/LegacyDelegationSecurityMetadataDecryptor.js.map +1 -0
- package/icc-x-api/crypto/RSA.d.ts +34 -8
- package/icc-x-api/crypto/RSA.js +80 -13
- package/icc-x-api/crypto/RSA.js.map +1 -1
- package/icc-x-api/crypto/SecureDelegationsEncryption.d.ts +54 -0
- package/icc-x-api/crypto/SecureDelegationsEncryption.js +178 -0
- package/icc-x-api/crypto/SecureDelegationsEncryption.js.map +1 -0
- package/icc-x-api/crypto/SecureDelegationsManager.d.ts +66 -0
- package/icc-x-api/crypto/SecureDelegationsManager.js +261 -0
- package/icc-x-api/crypto/SecureDelegationsManager.js.map +1 -0
- package/icc-x-api/crypto/SecureDelegationsSecurityMetadataDecryptor.d.ts +46 -0
- package/icc-x-api/crypto/SecureDelegationsSecurityMetadataDecryptor.js +312 -0
- package/icc-x-api/crypto/SecureDelegationsSecurityMetadataDecryptor.js.map +1 -0
- package/icc-x-api/crypto/SecurityMetadataDecryptor.d.ts +97 -0
- package/icc-x-api/crypto/SecurityMetadataDecryptor.js +79 -0
- package/icc-x-api/crypto/SecurityMetadataDecryptor.js.map +1 -0
- package/icc-x-api/crypto/ShamirKeysManager.d.ts +5 -5
- package/icc-x-api/crypto/ShamirKeysManager.js +6 -9
- package/icc-x-api/crypto/ShamirKeysManager.js.map +1 -1
- package/icc-x-api/crypto/TransferKeysManager.d.ts +8 -6
- package/icc-x-api/crypto/TransferKeysManager.js +75 -52
- package/icc-x-api/crypto/TransferKeysManager.js.map +1 -1
- package/icc-x-api/crypto/{KeyManager.d.ts → UserEncryptionKeysManager.d.ts} +4 -6
- package/icc-x-api/crypto/{KeyManager.js → UserEncryptionKeysManager.js} +43 -23
- package/icc-x-api/crypto/UserEncryptionKeysManager.js.map +1 -0
- package/icc-x-api/crypto/UserSignatureKeysManager.d.ts +26 -0
- package/icc-x-api/crypto/UserSignatureKeysManager.js +74 -0
- package/icc-x-api/crypto/UserSignatureKeysManager.js.map +1 -0
- package/icc-x-api/crypto/utils.d.ts +61 -11
- package/icc-x-api/crypto/utils.js +113 -44
- package/icc-x-api/crypto/utils.js.map +1 -1
- package/icc-x-api/filters/LatestMessageByHcPartyTransportGuidFilter.d.ts +8 -0
- package/icc-x-api/filters/LatestMessageByHcPartyTransportGuidFilter.js +13 -0
- package/icc-x-api/filters/LatestMessageByHcPartyTransportGuidFilter.js.map +1 -0
- package/icc-x-api/filters/MessageByHcPartyFilter.d.ts +7 -0
- package/icc-x-api/filters/MessageByHcPartyFilter.js +13 -0
- package/icc-x-api/filters/MessageByHcPartyFilter.js.map +1 -0
- package/icc-x-api/filters/MessageByHcPartyTransportGuidFilter.d.ts +8 -0
- package/icc-x-api/filters/MessageByHcPartyTransportGuidFilter.js +13 -0
- package/icc-x-api/filters/MessageByHcPartyTransportGuidFilter.js.map +1 -0
- package/icc-x-api/filters/TopicByHcPartyFilter.d.ts +7 -0
- package/icc-x-api/filters/TopicByHcPartyFilter.js +13 -0
- package/icc-x-api/filters/TopicByHcPartyFilter.js.map +1 -0
- package/icc-x-api/filters/TopicByParticipantFilter.d.ts +7 -0
- package/icc-x-api/filters/TopicByParticipantFilter.js +13 -0
- package/icc-x-api/filters/TopicByParticipantFilter.js.map +1 -0
- package/icc-x-api/filters/filters.d.ts +5 -0
- package/icc-x-api/filters/filters.js +5 -0
- package/icc-x-api/filters/filters.js.map +1 -1
- package/icc-x-api/icc-accesslog-x-api.d.ts +49 -12
- package/icc-x-api/icc-accesslog-x-api.js +81 -44
- package/icc-x-api/icc-accesslog-x-api.js.map +1 -1
- package/icc-x-api/icc-calendar-item-x-api.d.ts +53 -15
- package/icc-x-api/icc-calendar-item-x-api.js +105 -51
- package/icc-x-api/icc-calendar-item-x-api.js.map +1 -1
- package/icc-x-api/icc-classification-x-api.d.ts +47 -10
- package/icc-x-api/icc-classification-x-api.js +62 -33
- package/icc-x-api/icc-classification-x-api.js.map +1 -1
- package/icc-x-api/icc-contact-x-api.d.ts +59 -33
- package/icc-x-api/icc-contact-x-api.js +101 -66
- package/icc-x-api/icc-contact-x-api.js.map +1 -1
- package/icc-x-api/icc-crypto-x-api.d.ts +33 -333
- package/icc-x-api/icc-crypto-x-api.js +47 -764
- package/icc-x-api/icc-crypto-x-api.js.map +1 -1
- package/icc-x-api/icc-data-owner-x-api.d.ts +20 -8
- package/icc-x-api/icc-data-owner-x-api.js +31 -10
- package/icc-x-api/icc-data-owner-x-api.js.map +1 -1
- package/icc-x-api/icc-document-x-api.d.ts +51 -12
- package/icc-x-api/icc-document-x-api.js +117 -66
- package/icc-x-api/icc-document-x-api.js.map +1 -1
- package/icc-x-api/icc-form-x-api.d.ts +48 -11
- package/icc-x-api/icc-form-x-api.js +71 -37
- package/icc-x-api/icc-form-x-api.js.map +1 -1
- package/icc-x-api/icc-hcparty-x-api.d.ts +2 -2
- package/icc-x-api/icc-hcparty-x-api.js +3 -3
- package/icc-x-api/icc-hcparty-x-api.js.map +1 -1
- package/icc-x-api/icc-helement-x-api.d.ts +59 -20
- package/icc-x-api/icc-helement-x-api.js +78 -43
- package/icc-x-api/icc-helement-x-api.js.map +1 -1
- package/icc-x-api/icc-icure-maintenance-x-api.d.ts +7 -2
- package/icc-x-api/icc-icure-maintenance-x-api.js +38 -27
- package/icc-x-api/icc-icure-maintenance-x-api.js.map +1 -1
- package/icc-x-api/icc-invoice-x-api.d.ts +53 -16
- package/icc-x-api/icc-invoice-x-api.js +69 -35
- package/icc-x-api/icc-invoice-x-api.js.map +1 -1
- package/icc-x-api/icc-maintenance-task-x-api.d.ts +56 -22
- package/icc-x-api/icc-maintenance-task-x-api.js +77 -36
- package/icc-x-api/icc-maintenance-task-x-api.js.map +1 -1
- package/icc-x-api/icc-message-x-api.d.ts +75 -19
- package/icc-x-api/icc-message-x-api.js +126 -37
- package/icc-x-api/icc-message-x-api.js.map +1 -1
- package/icc-x-api/icc-patient-x-api.d.ts +86 -29
- package/icc-x-api/icc-patient-x-api.js +318 -379
- package/icc-x-api/icc-patient-x-api.js.map +1 -1
- package/icc-x-api/icc-receipt-x-api.d.ts +47 -13
- package/icc-x-api/icc-receipt-x-api.js +72 -36
- package/icc-x-api/icc-receipt-x-api.js.map +1 -1
- package/icc-x-api/icc-time-table-x-api.d.ts +46 -13
- package/icc-x-api/icc-time-table-x-api.js +61 -27
- package/icc-x-api/icc-time-table-x-api.js.map +1 -1
- package/icc-x-api/icc-topic-x-api.d.ts +191 -0
- package/icc-x-api/icc-topic-x-api.js +307 -0
- package/icc-x-api/icc-topic-x-api.js.map +1 -0
- package/icc-x-api/icc-user-x-api.d.ts +2 -2
- package/icc-x-api/icc-user-x-api.js +3 -3
- package/icc-x-api/icc-user-x-api.js.map +1 -1
- package/icc-x-api/index.d.ts +18 -2
- package/icc-x-api/index.js +203 -156
- package/icc-x-api/index.js.map +1 -1
- package/icc-x-api/maintenance/KeyPairUpdateRequest.d.ts +1 -1
- package/icc-x-api/storage/DefaultStorageEntryKeysFactory.d.ts +2 -0
- package/icc-x-api/storage/DefaultStorageEntryKeysFactory.js +9 -2
- package/icc-x-api/storage/DefaultStorageEntryKeysFactory.js.map +1 -1
- package/icc-x-api/storage/IcureStorageFacade.d.ts +23 -2
- package/icc-x-api/storage/IcureStorageFacade.js +36 -2
- package/icc-x-api/storage/IcureStorageFacade.js.map +1 -1
- package/icc-x-api/storage/KeyStorageFacade.d.ts +12 -0
- package/icc-x-api/storage/KeyStorageFacade.js.map +1 -1
- package/icc-x-api/storage/KeyStorageImpl.d.ts +2 -0
- package/icc-x-api/storage/KeyStorageImpl.js +10 -0
- package/icc-x-api/storage/KeyStorageImpl.js.map +1 -1
- package/icc-x-api/storage/StorageEntryKeysFactory.d.ts +14 -1
- package/icc-x-api/storage/StorageEntryKeysFactory.js.map +1 -1
- package/icc-x-api/utils/EntityWithDelegationTypeName.d.ts +32 -0
- package/icc-x-api/utils/EntityWithDelegationTypeName.js +75 -0
- package/icc-x-api/utils/EntityWithDelegationTypeName.js.map +1 -0
- package/icc-x-api/utils/ShareResult.d.ts +74 -0
- package/icc-x-api/utils/ShareResult.js +61 -0
- package/icc-x-api/utils/ShareResult.js.map +1 -0
- package/icc-x-api/utils/binary-utils.d.ts +1 -0
- package/icc-x-api/utils/binary-utils.js +8 -1
- package/icc-x-api/utils/binary-utils.js.map +1 -1
- package/icc-x-api/utils/collection-utils.d.ts +5 -0
- package/icc-x-api/utils/collection-utils.js +26 -1
- package/icc-x-api/utils/collection-utils.js.map +1 -1
- package/icc-x-api/utils/crypto-utils.d.ts +4 -3
- package/icc-x-api/utils/crypto-utils.js +5 -4
- package/icc-x-api/utils/crypto-utils.js.map +1 -1
- package/icc-x-api/utils/lru-temporised-async-cache.d.ts +26 -3
- package/icc-x-api/utils/lru-temporised-async-cache.js +75 -15
- package/icc-x-api/utils/lru-temporised-async-cache.js.map +1 -1
- package/icc-x-api/utils/websocket.d.ts +14 -10
- package/icc-x-api/utils/websocket.js +26 -9
- package/icc-x-api/utils/websocket.js.map +1 -1
- package/index.d.ts +1 -1
- package/index.js +3 -1
- package/index.js.map +1 -1
- package/package.json +2 -3
- package/icc-x-api/crypto/EntitiesEncryption.d.ts +0 -275
- package/icc-x-api/crypto/EntitiesEncryption.js +0 -734
- package/icc-x-api/crypto/EntitiesEncryption.js.map +0 -1
- package/icc-x-api/crypto/KeyManager.js.map +0 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { DataOwnerOrStub, IccDataOwnerXApi } from '../icc-data-owner-x-api';
|
|
2
|
-
import {
|
|
3
|
-
import { ExchangeKeysManager } from './ExchangeKeysManager';
|
|
2
|
+
import { UserEncryptionKeysManager } from './UserEncryptionKeysManager';
|
|
4
3
|
import { CryptoPrimitives } from './CryptoPrimitives';
|
|
4
|
+
import { ExchangeDataManager } from './ExchangeDataManager';
|
|
5
5
|
import { CryptoActorStubWithType } from '../../icc-api/model/CryptoActorStub';
|
|
6
6
|
/**
|
|
7
7
|
* Allows to create or update shamir split keys.
|
|
@@ -9,9 +9,9 @@ import { CryptoActorStubWithType } from '../../icc-api/model/CryptoActorStub';
|
|
|
9
9
|
export declare class ShamirKeysManager {
|
|
10
10
|
private readonly primitives;
|
|
11
11
|
private readonly dataOwnerApi;
|
|
12
|
-
private readonly
|
|
13
|
-
private readonly
|
|
14
|
-
constructor(primitives: CryptoPrimitives, dataOwnerApi: IccDataOwnerXApi,
|
|
12
|
+
private readonly encryptionKeysManager;
|
|
13
|
+
private readonly exchangeDataManager;
|
|
14
|
+
constructor(primitives: CryptoPrimitives, dataOwnerApi: IccDataOwnerXApi, encryptionKeysManager: UserEncryptionKeysManager, exchangeDataManager: ExchangeDataManager);
|
|
15
15
|
/**
|
|
16
16
|
* Get information on existing private keys splits for the provided data owner. For each private key of the provided data owner which has been
|
|
17
17
|
* split using the Shamir sharing algorithm gives the list of the notaries (other data owners) which hold a copy of the key part.
|
|
@@ -16,11 +16,11 @@ const CryptoActorStub_1 = require("../../icc-api/model/CryptoActorStub");
|
|
|
16
16
|
* Allows to create or update shamir split keys.
|
|
17
17
|
*/
|
|
18
18
|
class ShamirKeysManager {
|
|
19
|
-
constructor(primitives, dataOwnerApi,
|
|
19
|
+
constructor(primitives, dataOwnerApi, encryptionKeysManager, exchangeDataManager) {
|
|
20
20
|
this.primitives = primitives;
|
|
21
21
|
this.dataOwnerApi = dataOwnerApi;
|
|
22
|
-
this.
|
|
23
|
-
this.
|
|
22
|
+
this.encryptionKeysManager = encryptionKeysManager;
|
|
23
|
+
this.exchangeDataManager = exchangeDataManager;
|
|
24
24
|
}
|
|
25
25
|
/**
|
|
26
26
|
* Get information on existing private keys splits for the provided data owner. For each private key of the provided data owner which has been
|
|
@@ -57,7 +57,7 @@ class ShamirKeysManager {
|
|
|
57
57
|
const toDeleteSet = new Set(keySplitsToDelete.slice(-32));
|
|
58
58
|
const intersection = Array.from(toDeleteSet).filter((x) => toUpdateSet.has(x));
|
|
59
59
|
const existingSplits = new Set(Object.keys(this.getExistingSplitsInfo(self.stub)));
|
|
60
|
-
const allKeys = this.
|
|
60
|
+
const allKeys = this.encryptionKeysManager.getDecryptionKeys();
|
|
61
61
|
if (toDeleteSet.size !== keySplitsToDelete.length || toUpdateSet.size !== Object.keys(keySplitsToUpdate).length || intersection.length > 0)
|
|
62
62
|
throw new Error(`Duplicate keys in input:\nkeySplitsToUpdate: ${keySplitsToUpdate}\nkeySplitsToDelete: ${keySplitsToDelete}`);
|
|
63
63
|
Object.entries(keySplitsToUpdate).forEach(([key, params]) => this.validateShamirParams(key, params));
|
|
@@ -70,11 +70,8 @@ class ShamirKeysManager {
|
|
|
70
70
|
const delegatesKeys = {};
|
|
71
71
|
let updatedSelf = self;
|
|
72
72
|
for (const delegateId of new Set(Object.values(keySplitsToUpdate).flatMap((x) => x.notariesIds))) {
|
|
73
|
-
const res = yield this.
|
|
74
|
-
delegatesKeys[delegateId] = res.
|
|
75
|
-
if (res.updatedDelegator) {
|
|
76
|
-
updatedSelf = res.updatedDelegator;
|
|
77
|
-
}
|
|
73
|
+
const res = yield this.exchangeDataManager.getOrCreateEncryptionDataTo(delegateId, undefined, undefined);
|
|
74
|
+
delegatesKeys[delegateId] = res.exchangeKey;
|
|
78
75
|
}
|
|
79
76
|
for (const [key, params] of Object.entries(keySplitsToUpdate)) {
|
|
80
77
|
updatedSelf = yield this.updateKeySplit(updatedSelf, key.slice(-32), params.notariesIds, params.minShares, delegatesKeys, allKeys);
|
|
@@ -1 +1 @@
|
|
|
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
|
+
{"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 { UserEncryptionKeysManager } from './UserEncryptionKeysManager'\nimport { CryptoPrimitives } from './CryptoPrimitives'\nimport { KeyPair } from './RSA'\nimport { hex2ua, ua2hex } from '../utils'\nimport { ExchangeDataManager } from './ExchangeDataManager'\nimport { CryptoActorStubWithType } from '../../icc-api/model/CryptoActorStub'\n\n/**\n * Allows to create or update shamir split keys.\n */\nexport class ShamirKeysManager {\n constructor(\n private readonly primitives: CryptoPrimitives,\n private readonly dataOwnerApi: IccDataOwnerXApi,\n private readonly encryptionKeysManager: UserEncryptionKeysManager,\n private readonly exchangeDataManager: ExchangeDataManager\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.encryptionKeysManager.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.exchangeDataManager.getOrCreateEncryptionDataTo(delegateId, undefined, undefined)\n delegatesKeys[delegateId] = res.exchangeKey\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
|
-
import { BaseExchangeKeysManager } from './BaseExchangeKeysManager';
|
|
2
1
|
import { IccDataOwnerXApi } from '../icc-data-owner-x-api';
|
|
3
|
-
import {
|
|
2
|
+
import { UserEncryptionKeysManager } from './UserEncryptionKeysManager';
|
|
4
3
|
import { CryptoPrimitives } from './CryptoPrimitives';
|
|
5
4
|
import { IcureStorageFacade } from '../storage/IcureStorageFacade';
|
|
5
|
+
import { BaseExchangeDataManager } from './BaseExchangeDataManager';
|
|
6
|
+
import { UserSignatureKeysManager } from './UserSignatureKeysManager';
|
|
6
7
|
import { CryptoActorStubWithType } from '../../icc-api/model/CryptoActorStub';
|
|
7
8
|
/**
|
|
8
9
|
* @internal this class is intended only for internal use and may be changed without notice.
|
|
@@ -10,11 +11,12 @@ import { CryptoActorStubWithType } from '../../icc-api/model/CryptoActorStub';
|
|
|
10
11
|
*/
|
|
11
12
|
export declare class TransferKeysManager {
|
|
12
13
|
private readonly primitives;
|
|
13
|
-
private readonly
|
|
14
|
+
private readonly baseExchangeDataManager;
|
|
14
15
|
private readonly dataOwnerApi;
|
|
15
|
-
private readonly
|
|
16
|
+
private readonly encryptionKeysManager;
|
|
17
|
+
private readonly userSignatureKeysManager;
|
|
16
18
|
private readonly icureStorage;
|
|
17
|
-
constructor(primitives: CryptoPrimitives,
|
|
19
|
+
constructor(primitives: CryptoPrimitives, baseExchangeDataManager: BaseExchangeDataManager, dataOwnerApi: IccDataOwnerXApi, encryptionKeysManager: UserEncryptionKeysManager, userSignatureKeysManager: UserSignatureKeysManager, icureStorage: IcureStorageFacade);
|
|
18
20
|
/**
|
|
19
21
|
* Analyses the transfer keys graph and creates new transfer keys which allow to improve data accessibility from other devices.
|
|
20
22
|
* 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
|
|
@@ -25,6 +27,6 @@ export declare class TransferKeysManager {
|
|
|
25
27
|
updateTransferKeys(self: CryptoActorStubWithType): Promise<void>;
|
|
26
28
|
private encryptTransferKey;
|
|
27
29
|
private transferKeysCandidatesFp;
|
|
28
|
-
private
|
|
30
|
+
private transferTargetKeys;
|
|
29
31
|
private getNewVerifiedTransferKeysEdges;
|
|
30
32
|
}
|
|
@@ -18,11 +18,12 @@ const utils_2 = require("./utils");
|
|
|
18
18
|
* Allows to create new transfer keys.
|
|
19
19
|
*/
|
|
20
20
|
class TransferKeysManager {
|
|
21
|
-
constructor(primitives,
|
|
21
|
+
constructor(primitives, baseExchangeDataManager, dataOwnerApi, encryptionKeysManager, userSignatureKeysManager, icureStorage) {
|
|
22
22
|
this.primitives = primitives;
|
|
23
|
-
this.
|
|
23
|
+
this.baseExchangeDataManager = baseExchangeDataManager;
|
|
24
24
|
this.dataOwnerApi = dataOwnerApi;
|
|
25
|
-
this.
|
|
25
|
+
this.encryptionKeysManager = encryptionKeysManager;
|
|
26
|
+
this.userSignatureKeysManager = userSignatureKeysManager;
|
|
26
27
|
this.icureStorage = icureStorage;
|
|
27
28
|
}
|
|
28
29
|
/**
|
|
@@ -35,25 +36,34 @@ class TransferKeysManager {
|
|
|
35
36
|
updateTransferKeys(self) {
|
|
36
37
|
var _a;
|
|
37
38
|
return __awaiter(this, void 0, void 0, function* () {
|
|
38
|
-
const
|
|
39
|
-
if (!
|
|
39
|
+
const newEdgesByTarget = yield this.getNewVerifiedTransferKeysEdges(self);
|
|
40
|
+
if (!newEdgesByTarget.length)
|
|
40
41
|
return;
|
|
41
|
-
const selfId =
|
|
42
|
-
const fpToPublicKey = (0, utils_2.fingerprintToPublicKeysMapOf)(self.stub);
|
|
43
|
-
const
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
const
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
42
|
+
const selfId = self.stub.id;
|
|
43
|
+
const fpToPublicKey = (0, utils_2.fingerprintToPublicKeysMapOf)(self.stub, 'sha-1');
|
|
44
|
+
const fpToPublicKeyWithSha256 = (0, utils_2.fingerprintToPublicKeysMapOf)(self.stub, 'sha-256');
|
|
45
|
+
const signatureKeyPair = yield this.userSignatureKeysManager.getOrCreateSignatureKeyPair();
|
|
46
|
+
const verifiedFps = new Set(this.encryptionKeysManager.getSelfVerifiedKeys().map((x) => x.fingerprint));
|
|
47
|
+
const allVerifiedSourcesAndTarget = Array.from(new Set(newEdgesByTarget.flatMap((x) =>
|
|
48
|
+
// Sources are guaranteed to be verified, but target may not be
|
|
49
|
+
verifiedFps.has(x.targetFp) ? [x.targetFp, ...x.sources] : x.sources)));
|
|
50
|
+
const newExchangeKeyPublicKeys = allVerifiedSourcesAndTarget.map((fp) => fpToPublicKey[fp]).filter((key) => !!key);
|
|
51
|
+
const newExchangeKeyPublicKeysWithSha256 = allVerifiedSourcesAndTarget.map((fp) => fpToPublicKeyWithSha256[fp]).filter((key) => !!key);
|
|
52
|
+
const createdExchangeData = yield this.baseExchangeDataManager.createExchangeData(selfId, { [signatureKeyPair.fingerprint]: signatureKeyPair.keyPair.privateKey }, Object.assign(Object.assign({}, (yield (0, utils_2.loadPublicKeys)(this.primitives.RSA, newExchangeKeyPublicKeys, 'sha-1'))), (yield (0, utils_2.loadPublicKeys)(this.primitives.RSA, newExchangeKeyPublicKeysWithSha256, 'sha-256'))));
|
|
53
|
+
let updatedTransferKeys = (_a = self.stub.transferKeys) !== null && _a !== void 0 ? _a : {};
|
|
54
|
+
for (const newEdges of newEdgesByTarget) {
|
|
55
|
+
const encryptedTransferKey = yield this.encryptTransferKey(newEdges.target, createdExchangeData.exchangeKey);
|
|
56
|
+
updatedTransferKeys = newEdges.sources.reduce((acc, candidateFp) => {
|
|
57
|
+
var _a;
|
|
58
|
+
const existingKeys = Object.assign({}, ((_a = acc[candidateFp]) !== null && _a !== void 0 ? _a : {}));
|
|
59
|
+
existingKeys[newEdges.targetFp] = encryptedTransferKey;
|
|
60
|
+
acc[candidateFp] = existingKeys;
|
|
61
|
+
return acc;
|
|
62
|
+
}, updatedTransferKeys);
|
|
63
|
+
}
|
|
54
64
|
yield this.dataOwnerApi.modifyCryptoActorStub({
|
|
55
|
-
|
|
56
|
-
|
|
65
|
+
stub: Object.assign(Object.assign({}, self.stub), { transferKeys: updatedTransferKeys }),
|
|
66
|
+
type: self.type,
|
|
57
67
|
});
|
|
58
68
|
});
|
|
59
69
|
}
|
|
@@ -71,49 +81,62 @@ class TransferKeysManager {
|
|
|
71
81
|
.filter(([from, reachable]) => from != keyToFp && !reachable.has(keyToFp))
|
|
72
82
|
.map((x) => x[0]);
|
|
73
83
|
}
|
|
74
|
-
|
|
84
|
+
transferTargetKeys(keyManager, graph) {
|
|
75
85
|
return __awaiter(this, void 0, void 0, function* () {
|
|
76
|
-
|
|
86
|
+
const availableGroups = new Set(Object.keys(keyManager.getDecryptionKeys()).map((x) => { var _a; return (_a = graph.originalLabelToAcyclicLabel[x]) !== null && _a !== void 0 ? _a : x; }));
|
|
87
|
+
const groupsReachableFromAvailable = new Set(Object.entries(graph.acyclicGraph).flatMap(([source, reachables]) => (availableGroups.has(source) ? Array.from(reachables) : [])));
|
|
88
|
+
const targetCandidates = Array.from(availableGroups).filter((x) => !groupsReachableFromAvailable.has(x));
|
|
89
|
+
const verifiedFps = new Set(keyManager.getSelfVerifiedKeys().map((x) => x.fingerprint));
|
|
90
|
+
return targetCandidates.map((candidateFp) => {
|
|
91
|
+
var _a, _b;
|
|
92
|
+
const candidateGroup = (_a = graph.acyclicLabelToGroup[candidateFp]) !== null && _a !== void 0 ? _a : [candidateFp]; // May not be part of transfer keys graph yet
|
|
93
|
+
const bestCandidateOfGroup = (_b = candidateGroup.find((x) => verifiedFps.has(x))) !== null && _b !== void 0 ? _b : candidateFp;
|
|
94
|
+
return { fingerprint: bestCandidateOfGroup, pair: keyManager.getKeyPairForFingerprint(bestCandidateOfGroup).pair };
|
|
95
|
+
});
|
|
77
96
|
});
|
|
78
97
|
}
|
|
79
98
|
// Decides the best edges considering the verified public keys.
|
|
80
99
|
getNewVerifiedTransferKeysEdges(self) {
|
|
81
100
|
return __awaiter(this, void 0, void 0, function* () {
|
|
82
|
-
const verifiedKeysFpSet = new Set(this.
|
|
101
|
+
const verifiedKeysFpSet = new Set(this.encryptionKeysManager.getSelfVerifiedKeys().map((x) => x.fingerprint));
|
|
83
102
|
Object.entries(yield this.icureStorage.loadSelfVerifiedKeys(self.stub.id)).forEach(([key, verified]) => {
|
|
84
103
|
if (verified)
|
|
85
|
-
verifiedKeysFpSet.add(
|
|
104
|
+
verifiedKeysFpSet.add((0, utils_2.fingerprintV1)(key));
|
|
86
105
|
});
|
|
87
106
|
if (verifiedKeysFpSet.size == 0)
|
|
88
|
-
return
|
|
107
|
+
return [];
|
|
89
108
|
const graph = (0, utils_2.transferKeysFpGraphOf)(self.stub);
|
|
90
|
-
// 1. Choose
|
|
91
|
-
const
|
|
92
|
-
|
|
93
|
-
const
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
109
|
+
// 1. Choose keys available in this device which should be reachable from all other verified keys
|
|
110
|
+
const targetKeys = yield this.transferTargetKeys(this.encryptionKeysManager, graph);
|
|
111
|
+
const res = [];
|
|
112
|
+
for (const { fingerprint: targetKeyFp, pair: targetKey } of targetKeys) {
|
|
113
|
+
// 2. Find groups which can't reach the existing target keys
|
|
114
|
+
const candidatesFp = this.transferKeysCandidatesFp(targetKeyFp, graph);
|
|
115
|
+
// 3. Keep only groups which contain at least a verified candidate
|
|
116
|
+
const verifiedGroupCandidates = candidatesFp.filter((candidate) => graph.acyclicLabelToGroup[candidate].some((candidateGroupMember) => verifiedKeysFpSet.has(candidateGroupMember)));
|
|
117
|
+
const verifiedCandidatesSet = new Set(verifiedGroupCandidates);
|
|
118
|
+
if (verifiedCandidatesSet.size == 0)
|
|
119
|
+
continue;
|
|
120
|
+
// 4. Drop all candidates which can already reach another candidate group: it is sufficient to create a transfer key from that group.
|
|
121
|
+
const reachSets = (0, graph_utils_1.reachSetsAcyclic)(graph.acyclicGraph);
|
|
122
|
+
const optimizedCandidates = verifiedGroupCandidates.filter((candidate) => Array.from(reachSets[candidate]).every((reachableNode) => !verifiedCandidatesSet.has(reachableNode)));
|
|
123
|
+
if (optimizedCandidates.length == 0)
|
|
124
|
+
throw new Error('Check failed: at least one candidate should survive optimization');
|
|
125
|
+
// 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
|
|
126
|
+
// keys
|
|
127
|
+
const verifiedOptimizedCandidates = optimizedCandidates.map((candidate) => {
|
|
128
|
+
const res = graph.acyclicLabelToGroup[candidate].find((groupMemberFp) => verifiedKeysFpSet.has(groupMemberFp));
|
|
129
|
+
if (!res)
|
|
130
|
+
throw new Error('Check failed: optimized candidates groups should have at least a verified member');
|
|
131
|
+
return res;
|
|
132
|
+
});
|
|
133
|
+
res.push({
|
|
134
|
+
sources: verifiedOptimizedCandidates,
|
|
135
|
+
target: targetKey,
|
|
136
|
+
targetFp: targetKeyFp,
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
return res;
|
|
117
140
|
});
|
|
118
141
|
}
|
|
119
142
|
}
|
|
@@ -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 { 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"]}
|
|
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 { IccDataOwnerXApi } from '../icc-data-owner-x-api'\nimport { ua2hex } from '../utils'\nimport { UserEncryptionKeysManager } from './UserEncryptionKeysManager'\nimport { reachSetsAcyclic, StronglyConnectedGraph } from '../utils/graph-utils'\nimport { fingerprintToPublicKeysMapOf, fingerprintV1, loadPublicKeys, transferKeysFpGraphOf, fingerprintIsV1, fingerprintV1toV2 } from './utils'\nimport { CryptoPrimitives } from './CryptoPrimitives'\nimport { IcureStorageFacade } from '../storage/IcureStorageFacade'\nimport { BaseExchangeDataManager } from './BaseExchangeDataManager'\nimport { UserSignatureKeysManager } from './UserSignatureKeysManager'\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 constructor(\n private readonly primitives: CryptoPrimitives,\n private readonly baseExchangeDataManager: BaseExchangeDataManager,\n private readonly dataOwnerApi: IccDataOwnerXApi,\n private readonly encryptionKeysManager: UserEncryptionKeysManager,\n private readonly userSignatureKeysManager: UserSignatureKeysManager,\n private readonly icureStorage: IcureStorageFacade\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 newEdgesByTarget = await this.getNewVerifiedTransferKeysEdges(self)\n if (!newEdgesByTarget.length) return\n const selfId = self.stub.id!\n const fpToPublicKey = fingerprintToPublicKeysMapOf(self.stub, 'sha-1')\n const fpToPublicKeyWithSha256 = fingerprintToPublicKeysMapOf(self.stub, 'sha-256')\n const signatureKeyPair = await this.userSignatureKeysManager.getOrCreateSignatureKeyPair()\n const verifiedFps = new Set(this.encryptionKeysManager.getSelfVerifiedKeys().map((x) => x.fingerprint))\n const allVerifiedSourcesAndTarget = Array.from(\n new Set(\n newEdgesByTarget.flatMap((x) =>\n // Sources are guaranteed to be verified, but target may not be\n verifiedFps.has(x.targetFp) ? [x.targetFp, ...x.sources] : x.sources\n )\n )\n )\n const newExchangeKeyPublicKeys = allVerifiedSourcesAndTarget.map((fp) => fpToPublicKey[fp]).filter((key) => !!key)\n const newExchangeKeyPublicKeysWithSha256 = allVerifiedSourcesAndTarget.map((fp) => fpToPublicKeyWithSha256[fp]).filter((key) => !!key)\n const createdExchangeData = await this.baseExchangeDataManager.createExchangeData(\n selfId,\n { [signatureKeyPair.fingerprint]: signatureKeyPair.keyPair.privateKey },\n {\n ...(await loadPublicKeys(this.primitives.RSA, newExchangeKeyPublicKeys, 'sha-1')),\n ...(await loadPublicKeys(this.primitives.RSA, newExchangeKeyPublicKeysWithSha256, 'sha-256')),\n }\n )\n let updatedTransferKeys = self.stub.transferKeys ?? {}\n for (const newEdges of newEdgesByTarget) {\n const encryptedTransferKey = await this.encryptTransferKey(newEdges.target, createdExchangeData.exchangeKey)\n updatedTransferKeys = newEdges.sources.reduce((acc, candidateFp) => {\n const existingKeys = { ...(acc[candidateFp] ?? {}) }\n existingKeys[newEdges.targetFp] = encryptedTransferKey\n acc[candidateFp] = existingKeys\n return acc\n }, updatedTransferKeys)\n }\n await this.dataOwnerApi.modifyCryptoActorStub({\n stub: {\n ...self.stub,\n transferKeys: updatedTransferKeys,\n },\n type: self.type,\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 transferTargetKeys(\n keyManager: UserEncryptionKeysManager,\n graph: StronglyConnectedGraph\n ): Promise<{ fingerprint: string; pair: KeyPair<CryptoKey> }[]> {\n const availableGroups = new Set(Object.keys(keyManager.getDecryptionKeys()).map((x) => graph.originalLabelToAcyclicLabel[x] ?? x))\n const groupsReachableFromAvailable = new Set(\n Object.entries(graph.acyclicGraph).flatMap(([source, reachables]) => (availableGroups.has(source) ? Array.from(reachables) : []))\n )\n const targetCandidates = Array.from(availableGroups).filter((x) => !groupsReachableFromAvailable.has(x))\n const verifiedFps = new Set(keyManager.getSelfVerifiedKeys().map((x) => x.fingerprint))\n return targetCandidates.map((candidateFp) => {\n const candidateGroup = graph.acyclicLabelToGroup[candidateFp] ?? [candidateFp] // May not be part of transfer keys graph yet\n const bestCandidateOfGroup = candidateGroup.find((x) => verifiedFps.has(x)) ?? candidateFp\n return { fingerprint: bestCandidateOfGroup, pair: keyManager.getKeyPairForFingerprint(bestCandidateOfGroup)!.pair }\n })\n }\n\n // Decides the best edges considering the verified public keys.\n private async getNewVerifiedTransferKeysEdges(self: CryptoActorStubWithType): Promise<\n {\n sources: string[]\n target: KeyPair<CryptoKey>\n targetFp: string\n }[]\n > {\n const verifiedKeysFpSet = new Set(this.encryptionKeysManager.getSelfVerifiedKeys().map((x) => x.fingerprint))\n Object.entries(await this.icureStorage.loadSelfVerifiedKeys(self.stub.id!)).forEach(([key, verified]) => {\n if (verified) verifiedKeysFpSet.add(fingerprintV1(key))\n })\n if (verifiedKeysFpSet.size == 0) return []\n const graph = transferKeysFpGraphOf(self.stub)\n // 1. Choose keys available in this device which should be reachable from all other verified keys\n const targetKeys = await this.transferTargetKeys(this.encryptionKeysManager, graph)\n const res = []\n for (const { fingerprint: targetKeyFp, pair: targetKey } of targetKeys) {\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) continue\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 res.push({\n sources: verifiedOptimizedCandidates,\n target: targetKey,\n targetFp: targetKeyFp,\n })\n }\n return res\n }\n}\n"]}
|
|
@@ -1,25 +1,23 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { DataOwnerOrStub, IccDataOwnerXApi } from '../icc-data-owner-x-api';
|
|
2
2
|
import { KeyPair } from './RSA';
|
|
3
3
|
import { IcureStorageFacade } from '../storage/IcureStorageFacade';
|
|
4
|
-
import { BaseExchangeKeysManager } from './BaseExchangeKeysManager';
|
|
5
4
|
import { CryptoPrimitives } from './CryptoPrimitives';
|
|
6
5
|
import { KeyRecovery } from './KeyRecovery';
|
|
7
6
|
import { CryptoStrategies } from './CryptoStrategies';
|
|
8
7
|
/**
|
|
9
8
|
* Allows to manage public and private keys for the current user and his parent hierarchy.
|
|
10
9
|
*/
|
|
11
|
-
export declare class
|
|
10
|
+
export declare class UserEncryptionKeysManager {
|
|
12
11
|
private readonly primitives;
|
|
13
12
|
private readonly dataOwnerApi;
|
|
14
13
|
private readonly icureStorage;
|
|
15
14
|
private readonly keyRecovery;
|
|
16
|
-
private readonly baseExchangeKeyManager;
|
|
17
15
|
private readonly strategies;
|
|
18
16
|
private readonly initialiseParentKeys;
|
|
19
17
|
private selfId;
|
|
20
18
|
private selfLegacyPublicKey;
|
|
21
19
|
private keysCache;
|
|
22
|
-
constructor(primitives: CryptoPrimitives, dataOwnerApi: IccDataOwnerXApi, icureStorage: IcureStorageFacade, keyRecovery: KeyRecovery,
|
|
20
|
+
constructor(primitives: CryptoPrimitives, dataOwnerApi: IccDataOwnerXApi, icureStorage: IcureStorageFacade, keyRecovery: KeyRecovery, strategies: CryptoStrategies, initialiseParentKeys: boolean);
|
|
23
21
|
/**
|
|
24
22
|
* @internal
|
|
25
23
|
* Get all key pairs available for the current data owner and his parents.
|
|
@@ -105,7 +103,7 @@ export declare class KeyManager {
|
|
|
105
103
|
* @param dataOwner the current data owner or a member of his hierarchy.
|
|
106
104
|
* @throws if the provided data owner is not part of the current data owner hierarchy
|
|
107
105
|
*/
|
|
108
|
-
getVerifiedPublicKeysFor(dataOwner:
|
|
106
|
+
getVerifiedPublicKeysFor(dataOwner: DataOwnerOrStub): Promise<string[]>;
|
|
109
107
|
/**
|
|
110
108
|
* @internal This method is intended for internal use only and may be changed without notice.
|
|
111
109
|
* 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.
|
|
@@ -9,20 +9,20 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.
|
|
12
|
+
exports.UserEncryptionKeysManager = void 0;
|
|
13
13
|
const utils_1 = require("../utils");
|
|
14
14
|
const utils_2 = require("./utils");
|
|
15
|
+
const CryptoActorStub_1 = require("../../icc-api/model/CryptoActorStub");
|
|
15
16
|
const nothingKeyRecovererAndVerifier = (x) => Promise.resolve(x.reduce((acc, { dataOwner }) => (Object.assign(Object.assign({}, acc), { [dataOwner.dataOwner.id]: { recoveredKeys: {}, keyAuthenticity: {} } })), {}));
|
|
16
17
|
/**
|
|
17
18
|
* Allows to manage public and private keys for the current user and his parent hierarchy.
|
|
18
19
|
*/
|
|
19
|
-
class
|
|
20
|
-
constructor(primitives, dataOwnerApi, icureStorage, keyRecovery,
|
|
20
|
+
class UserEncryptionKeysManager {
|
|
21
|
+
constructor(primitives, dataOwnerApi, icureStorage, keyRecovery, strategies, initialiseParentKeys) {
|
|
21
22
|
this.primitives = primitives;
|
|
22
23
|
this.dataOwnerApi = dataOwnerApi;
|
|
23
24
|
this.icureStorage = icureStorage;
|
|
24
25
|
this.keyRecovery = keyRecovery;
|
|
25
|
-
this.baseExchangeKeyManager = baseExchangeKeyManager;
|
|
26
26
|
this.strategies = strategies;
|
|
27
27
|
this.initialiseParentKeys = initialiseParentKeys;
|
|
28
28
|
this.keysCache = undefined;
|
|
@@ -167,8 +167,11 @@ class KeyManager {
|
|
|
167
167
|
throw new Error(`Data owner ${dataOwner.id} is not part of the hierarchy of the current data owner ${this.selfId}`);
|
|
168
168
|
const availableVerifiedKeysFp = new Set(Object.entries(availableKeys).flatMap(([fp, info]) => (info.isVerified || info.isDevice ? [fp] : [])));
|
|
169
169
|
const otherVerifiedFp = new Set(Object.entries(yield this.icureStorage.loadSelfVerifiedKeys(dataOwner.id)).flatMap(([fp, verified]) => (verified ? [fp] : [])));
|
|
170
|
-
return Array.from(
|
|
171
|
-
|
|
170
|
+
return Array.from([
|
|
171
|
+
...this.dataOwnerApi.getHexPublicKeysWithSha1Of(dataOwner),
|
|
172
|
+
...this.dataOwnerApi.getHexPublicKeysWithSha256Of(dataOwner),
|
|
173
|
+
]).filter((key) => {
|
|
174
|
+
const fp = (0, utils_2.fingerprintV1)(key);
|
|
172
175
|
return availableVerifiedKeysFp.has(fp) || otherVerifiedFp.has(fp);
|
|
173
176
|
});
|
|
174
177
|
});
|
|
@@ -206,11 +209,14 @@ class KeyManager {
|
|
|
206
209
|
const availableKeys = yield this.loadAndRecoverKeysFor(dowt);
|
|
207
210
|
const availableKeysFpSet = new Set(Object.keys(availableKeys));
|
|
208
211
|
const verifiedKeysMap = yield this.icureStorage.loadSelfVerifiedKeys(dowt.dataOwner.id);
|
|
209
|
-
const allPublicKeys =
|
|
212
|
+
const allPublicKeys = new Set([
|
|
213
|
+
...this.dataOwnerApi.getHexPublicKeysWithSha1Of(dowt.dataOwner),
|
|
214
|
+
...this.dataOwnerApi.getHexPublicKeysWithSha256Of(dowt.dataOwner),
|
|
215
|
+
]);
|
|
210
216
|
const unavailableKeys = Array.from(allPublicKeys).flatMap((key) => {
|
|
211
217
|
return availableKeysFpSet.has(key.slice(-32)) ? [] : [key];
|
|
212
218
|
});
|
|
213
|
-
const unknownKeys = Array.from(allPublicKeys).filter((x) => { var _a; return !(
|
|
219
|
+
const unknownKeys = Array.from(allPublicKeys).filter((x) => { var _a; return !((0, utils_2.fingerprintV1)(x) in verifiedKeysMap) && !(((_a = availableKeys === null || availableKeys === void 0 ? void 0 : availableKeys[(0, utils_2.fingerprintV1)(x)]) === null || _a === void 0 ? void 0 : _a.isDevice) === true); });
|
|
214
220
|
keysData.push({ dowt, availableKeys, unavailableKeys, unknownKeys });
|
|
215
221
|
}
|
|
216
222
|
const recoveryInfo = keysData.map(({ dowt, unavailableKeys, unknownKeys }) => ({ dataOwner: dowt, unavailableKeys, unknownKeys }));
|
|
@@ -255,25 +261,36 @@ class KeyManager {
|
|
|
255
261
|
});
|
|
256
262
|
}
|
|
257
263
|
createAndSaveNewKeyPair(importedKeyPair, selfDataOwner) {
|
|
264
|
+
var _a;
|
|
258
265
|
return __awaiter(this, void 0, void 0, function* () {
|
|
259
|
-
const keyPair = importedKeyPair !== null && importedKeyPair !== void 0 ? importedKeyPair : (yield this.primitives.RSA.generateKeyPair());
|
|
266
|
+
const keyPair = importedKeyPair !== null && importedKeyPair !== void 0 ? importedKeyPair : (yield this.primitives.RSA.generateKeyPair('sha-256'));
|
|
260
267
|
const publicKeyHex = (0, utils_1.ua2hex)(yield this.primitives.RSA.exportKey(keyPair.publicKey, 'spki'));
|
|
261
|
-
const
|
|
268
|
+
const jwKey = yield this.primitives.RSA.exportKey(keyPair.publicKey, 'jwk');
|
|
269
|
+
if (jwKey.alg !== 'RSA-OAEP-256') {
|
|
270
|
+
throw new Error('Only keys generated with SHA-256 are currently supported');
|
|
271
|
+
}
|
|
272
|
+
const publicKeyFingerprint = (0, utils_2.fingerprintV1)(publicKeyHex);
|
|
262
273
|
yield this.icureStorage.saveKey(selfDataOwner.dataOwner.id, publicKeyFingerprint, yield this.primitives.RSA.exportKeys(keyPair, 'jwk', 'jwk'), true);
|
|
263
|
-
|
|
264
|
-
const
|
|
265
|
-
|
|
274
|
+
yield this.icureStorage.saveSelfVerifiedKeys(selfDataOwner.dataOwner.id, { [publicKeyFingerprint]: true });
|
|
275
|
+
const updatedSelf = yield this.dataOwnerApi.modifyCryptoActorStub({
|
|
276
|
+
stub: Object.assign(Object.assign({}, CryptoActorStub_1.CryptoActorStub.fromDataOwner(selfDataOwner.dataOwner)), { publicKeysForOaepWithSha256: [...((_a = selfDataOwner.dataOwner.publicKeysForOaepWithSha256) !== null && _a !== void 0 ? _a : []), publicKeyHex] }),
|
|
277
|
+
type: selfDataOwner.type,
|
|
278
|
+
});
|
|
279
|
+
return { publicKeyFingerprint, keyPair: keyPair, updatedSelf };
|
|
266
280
|
});
|
|
267
281
|
}
|
|
268
282
|
loadStoredKeys(dataOwner, pubKeysFingerprints) {
|
|
269
283
|
return __awaiter(this, void 0, void 0, function* () {
|
|
270
|
-
|
|
284
|
+
const pubKeysFingerprintsWithVersion = Object.entries(pubKeysFingerprints).flatMap(([shaVersion, fps]) => {
|
|
285
|
+
return fps.map((fp) => [shaVersion, fp]);
|
|
286
|
+
});
|
|
287
|
+
return yield pubKeysFingerprintsWithVersion.reduce((acc, [shaVersion, currentFingerprint]) => __awaiter(this, void 0, void 0, function* () {
|
|
271
288
|
const awaitedAcc = yield acc;
|
|
272
289
|
let loadedPair = undefined;
|
|
273
290
|
try {
|
|
274
291
|
const storedKeypair = yield this.icureStorage.loadKey(dataOwner.dataOwner.id, currentFingerprint, dataOwner.dataOwner.publicKey);
|
|
275
|
-
if (storedKeypair) {
|
|
276
|
-
const importedKey = yield this.primitives.RSA.importKeyPair('jwk', storedKeypair.pair.privateKey, 'jwk', storedKeypair.pair.publicKey);
|
|
292
|
+
if (!!storedKeypair) {
|
|
293
|
+
const importedKey = yield this.primitives.RSA.importKeyPair('jwk', storedKeypair.pair.privateKey, 'jwk', storedKeypair.pair.publicKey, shaVersion);
|
|
277
294
|
loadedPair = { pair: importedKey, isDevice: storedKeypair.isDevice };
|
|
278
295
|
}
|
|
279
296
|
}
|
|
@@ -306,11 +323,14 @@ class KeyManager {
|
|
|
306
323
|
}
|
|
307
324
|
loadAndRecoverKeysFor(dataOwner) {
|
|
308
325
|
return __awaiter(this, void 0, void 0, function* () {
|
|
309
|
-
const
|
|
310
|
-
|
|
311
|
-
|
|
326
|
+
const pubKeysFingerprints = {
|
|
327
|
+
'sha-1': [...new Set(this.dataOwnerApi.getHexPublicKeysWithSha1Of(dataOwner.dataOwner))].map((x) => (0, utils_2.fingerprintV1)(x)),
|
|
328
|
+
'sha-256': [...new Set(this.dataOwnerApi.getHexPublicKeysWithSha256Of(dataOwner.dataOwner))].map((x) => (0, utils_2.fingerprintV1)(x)),
|
|
329
|
+
};
|
|
330
|
+
const loadedKeys = pubKeysFingerprints['sha-1'].length + pubKeysFingerprints['sha-256'].length > 0 ? yield this.loadStoredKeys(dataOwner, pubKeysFingerprints) : {};
|
|
312
331
|
const loadedKeysFingerprints = Object.keys(loadedKeys);
|
|
313
|
-
if (loadedKeysFingerprints.length !== pubKeysFingerprints.length
|
|
332
|
+
if (loadedKeysFingerprints.length !== pubKeysFingerprints['sha-1'].length + pubKeysFingerprints['sha-256'].length &&
|
|
333
|
+
loadedKeysFingerprints.length > 0) {
|
|
314
334
|
const recoveredKeys = yield this.recoverAndCacheKeys(dataOwner, this.plainKeysByFingerprint(loadedKeys));
|
|
315
335
|
for (const [fp, pair] of Object.entries(recoveredKeys)) {
|
|
316
336
|
loadedKeys[fp] = { pair, isDevice: false };
|
|
@@ -320,11 +340,11 @@ class KeyManager {
|
|
|
320
340
|
});
|
|
321
341
|
}
|
|
322
342
|
ensureFingerprintKeys(obj) {
|
|
323
|
-
return Object.fromEntries(Object.entries(obj).map(([k, v]) => [
|
|
343
|
+
return Object.fromEntries(Object.entries(obj).map(([k, v]) => [(0, utils_2.fingerprintV1)(k), v]));
|
|
324
344
|
}
|
|
325
345
|
hasVerifiedKey(keysData) {
|
|
326
346
|
return Object.values(keysData).some((x) => x.isVerified || x.isDevice);
|
|
327
347
|
}
|
|
328
348
|
}
|
|
329
|
-
exports.
|
|
330
|
-
//# sourceMappingURL=
|
|
349
|
+
exports.UserEncryptionKeysManager = UserEncryptionKeysManager;
|
|
350
|
+
//# sourceMappingURL=UserEncryptionKeysManager.js.map
|