@icure/api 7.1.14 → 8.0.0-RC.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (322) hide show
  1. package/icc-api/api/IccAccesslogApi.d.ts +12 -1
  2. package/icc-api/api/IccAccesslogApi.js +142 -98
  3. package/icc-api/api/IccAccesslogApi.js.map +1 -1
  4. package/icc-api/api/IccBemikronoApi.d.ts +81 -0
  5. package/icc-api/api/IccBemikronoApi.js +163 -0
  6. package/icc-api/api/IccBemikronoApi.js.map +1 -0
  7. package/icc-api/api/IccCalendarItemApi.d.ts +21 -1
  8. package/icc-api/api/IccCalendarItemApi.js +183 -117
  9. package/icc-api/api/IccCalendarItemApi.js.map +1 -1
  10. package/icc-api/api/IccClassificationApi.d.ts +21 -1
  11. package/icc-api/api/IccClassificationApi.js +119 -63
  12. package/icc-api/api/IccClassificationApi.js.map +1 -1
  13. package/icc-api/api/IccContactApi.d.ts +21 -1
  14. package/icc-api/api/IccContactApi.js +385 -294
  15. package/icc-api/api/IccContactApi.js.map +1 -1
  16. package/icc-api/api/IccDocumentApi.d.ts +32 -25
  17. package/icc-api/api/IccDocumentApi.js +264 -212
  18. package/icc-api/api/IccDocumentApi.js.map +1 -1
  19. package/icc-api/api/IccExchangeDataApi.d.ts +19 -0
  20. package/icc-api/api/IccExchangeDataApi.js +85 -0
  21. package/icc-api/api/IccExchangeDataApi.js.map +1 -0
  22. package/icc-api/api/IccExchangeDataMapApi.d.ts +18 -0
  23. package/icc-api/api/IccExchangeDataMapApi.js +65 -0
  24. package/icc-api/api/IccExchangeDataMapApi.js.map +1 -0
  25. package/icc-api/api/IccFormApi.d.ts +21 -1
  26. package/icc-api/api/IccFormApi.js +321 -229
  27. package/icc-api/api/IccFormApi.js.map +1 -1
  28. package/icc-api/api/IccHelementApi.d.ts +21 -1
  29. package/icc-api/api/IccHelementApi.js +207 -137
  30. package/icc-api/api/IccHelementApi.js.map +1 -1
  31. package/icc-api/api/IccInvoiceApi.d.ts +21 -1
  32. package/icc-api/api/IccInvoiceApi.js +404 -298
  33. package/icc-api/api/IccInvoiceApi.js.map +1 -1
  34. package/icc-api/api/IccMaintenanceTaskApi.d.ts +12 -1
  35. package/icc-api/api/IccMaintenanceTaskApi.js +79 -43
  36. package/icc-api/api/IccMaintenanceTaskApi.js.map +1 -1
  37. package/icc-api/api/IccMessageApi.d.ts +12 -1
  38. package/icc-api/api/IccMessageApi.js +257 -191
  39. package/icc-api/api/IccMessageApi.js.map +1 -1
  40. package/icc-api/api/IccPatientApi.d.ts +12 -1
  41. package/icc-api/api/IccPatientApi.js +447 -351
  42. package/icc-api/api/IccPatientApi.js.map +1 -1
  43. package/icc-api/api/IccReceiptApi.d.ts +22 -8
  44. package/icc-api/api/IccReceiptApi.js +121 -64
  45. package/icc-api/api/IccReceiptApi.js.map +1 -1
  46. package/icc-api/api/IccRestApiPath.js +1 -1
  47. package/icc-api/api/IccRestApiPath.js.map +1 -1
  48. package/icc-api/api/IccTimeTableApi.d.ts +12 -1
  49. package/icc-api/api/IccTimeTableApi.js +86 -48
  50. package/icc-api/api/IccTimeTableApi.js.map +1 -1
  51. package/icc-api/index.d.ts +1 -0
  52. package/icc-api/index.js +1 -0
  53. package/icc-api/index.js.map +1 -1
  54. package/icc-api/model/AccessLog.d.ts +4 -0
  55. package/icc-api/model/AccessLog.js +1 -0
  56. package/icc-api/model/AccessLog.js.map +1 -1
  57. package/icc-api/model/Article.d.ts +4 -0
  58. package/icc-api/model/Article.js +1 -0
  59. package/icc-api/model/Article.js.map +1 -1
  60. package/icc-api/model/CalendarItem.d.ts +4 -0
  61. package/icc-api/model/CalendarItem.js +1 -0
  62. package/icc-api/model/CalendarItem.js.map +1 -1
  63. package/icc-api/model/Classification.d.ts +4 -0
  64. package/icc-api/model/Classification.js +1 -0
  65. package/icc-api/model/Classification.js.map +1 -1
  66. package/icc-api/model/ClassificationTemplate.d.ts +2 -0
  67. package/icc-api/model/ClassificationTemplate.js.map +1 -1
  68. package/icc-api/model/Contact.d.ts +4 -0
  69. package/icc-api/model/Contact.js +1 -0
  70. package/icc-api/model/Contact.js.map +1 -1
  71. package/icc-api/model/Device.d.ts +4 -4
  72. package/icc-api/model/Device.js.map +1 -1
  73. package/icc-api/model/Document.d.ts +4 -0
  74. package/icc-api/model/Document.js +1 -0
  75. package/icc-api/model/Document.js.map +1 -1
  76. package/icc-api/model/ExchangeData.d.ts +61 -0
  77. package/icc-api/model/ExchangeData.js +12 -0
  78. package/icc-api/model/ExchangeData.js.map +1 -0
  79. package/icc-api/model/ExchangeDataMap.d.ts +21 -0
  80. package/icc-api/model/ExchangeDataMap.js +10 -0
  81. package/icc-api/model/ExchangeDataMap.js.map +1 -0
  82. package/icc-api/model/ExchangeDataMapCreationBatch.d.ts +13 -0
  83. package/icc-api/model/ExchangeDataMapCreationBatch.js +10 -0
  84. package/icc-api/model/ExchangeDataMapCreationBatch.js.map +1 -0
  85. package/icc-api/model/Form.d.ts +4 -0
  86. package/icc-api/model/Form.js +1 -0
  87. package/icc-api/model/Form.js.map +1 -1
  88. package/icc-api/model/HealthElement.d.ts +4 -0
  89. package/icc-api/model/HealthElement.js +1 -0
  90. package/icc-api/model/HealthElement.js.map +1 -1
  91. package/icc-api/model/HealthcareParty.d.ts +2 -2
  92. package/icc-api/model/HealthcareParty.js.map +1 -1
  93. package/icc-api/model/IcureStub.d.ts +2 -0
  94. package/icc-api/model/IcureStub.js.map +1 -1
  95. package/icc-api/model/Invoice.d.ts +4 -0
  96. package/icc-api/model/Invoice.js +1 -0
  97. package/icc-api/model/Invoice.js.map +1 -1
  98. package/icc-api/model/MaintenanceTask.d.ts +4 -0
  99. package/icc-api/model/MaintenanceTask.js +1 -0
  100. package/icc-api/model/MaintenanceTask.js.map +1 -1
  101. package/icc-api/model/Message.d.ts +4 -0
  102. package/icc-api/model/Message.js +1 -0
  103. package/icc-api/model/Message.js.map +1 -1
  104. package/icc-api/model/PaginatedListExchangeData.d.ts +9 -0
  105. package/icc-api/model/PaginatedListExchangeData.js +10 -0
  106. package/icc-api/model/PaginatedListExchangeData.js.map +1 -0
  107. package/icc-api/model/Patient.d.ts +6 -2
  108. package/icc-api/model/Patient.js +1 -0
  109. package/icc-api/model/Patient.js.map +1 -1
  110. package/icc-api/model/PatientByHcPartyGenderEducationProfession.d.ts +31 -0
  111. package/icc-api/model/PatientByHcPartyGenderEducationProfession.js +32 -0
  112. package/icc-api/model/PatientByHcPartyGenderEducationProfession.js.map +1 -0
  113. package/icc-api/model/Receipt.d.ts +4 -0
  114. package/icc-api/model/Receipt.js +1 -0
  115. package/icc-api/model/Receipt.js.map +1 -1
  116. package/icc-api/model/SecureDelegation.d.ts +52 -0
  117. package/icc-api/model/SecureDelegation.js +16 -0
  118. package/icc-api/model/SecureDelegation.js.map +1 -0
  119. package/icc-api/model/SecurityMetadata.d.ts +33 -0
  120. package/icc-api/model/SecurityMetadata.js +13 -0
  121. package/icc-api/model/SecurityMetadata.js.map +1 -0
  122. package/icc-api/model/Service.d.ts +2 -0
  123. package/icc-api/model/Service.js.map +1 -1
  124. package/icc-api/model/TimeTable.d.ts +4 -0
  125. package/icc-api/model/TimeTable.js +1 -0
  126. package/icc-api/model/TimeTable.js.map +1 -1
  127. package/icc-api/model/models.d.ts +20 -39
  128. package/icc-api/model/models.js +15 -37
  129. package/icc-api/model/models.js.map +1 -1
  130. package/icc-api/model/requests/EntityBulkShareResult.d.ts +28 -0
  131. package/icc-api/model/requests/EntityBulkShareResult.js +16 -0
  132. package/icc-api/model/requests/EntityBulkShareResult.js.map +1 -0
  133. package/icc-api/model/requests/EntityShareOrMetadataUpdateRequest.d.ts +10 -0
  134. package/icc-api/model/requests/EntityShareOrMetadataUpdateRequest.js +17 -0
  135. package/icc-api/model/requests/EntityShareOrMetadataUpdateRequest.js.map +1 -0
  136. package/icc-api/model/requests/EntityShareRequest.d.ts +110 -0
  137. package/icc-api/model/requests/EntityShareRequest.js +63 -0
  138. package/icc-api/model/requests/EntityShareRequest.js.map +1 -0
  139. package/icc-api/model/requests/EntitySharedMetadataUpdateRequest.d.ts +54 -0
  140. package/icc-api/model/requests/EntitySharedMetadataUpdateRequest.js +24 -0
  141. package/icc-api/model/requests/EntitySharedMetadataUpdateRequest.js.map +1 -0
  142. package/icc-api/model/requests/MinimalEntityBulkShareResult.d.ts +23 -0
  143. package/icc-api/model/requests/MinimalEntityBulkShareResult.js +13 -0
  144. package/icc-api/model/requests/MinimalEntityBulkShareResult.js.map +1 -0
  145. package/icc-api/model/requests/RejectedShareOrMetadataUpdateRequest.d.ts +21 -0
  146. package/icc-api/model/requests/RejectedShareOrMetadataUpdateRequest.js +14 -0
  147. package/icc-api/model/requests/RejectedShareOrMetadataUpdateRequest.js.map +1 -0
  148. package/icc-x-api/basexapi/EncryptedEntityXApi.d.ts +3 -2
  149. package/icc-x-api/basexapi/EncryptedEntityXApi.js.map +1 -1
  150. package/icc-x-api/crypto/AES.js +1 -1
  151. package/icc-x-api/crypto/AES.js.map +1 -1
  152. package/icc-x-api/crypto/AccessControlKeysHeadersProvider.d.ts +16 -0
  153. package/icc-x-api/crypto/AccessControlKeysHeadersProvider.js +41 -0
  154. package/icc-x-api/crypto/AccessControlKeysHeadersProvider.js.map +1 -0
  155. package/icc-x-api/crypto/AccessControlSecretUtils.d.ts +42 -0
  156. package/icc-x-api/crypto/AccessControlSecretUtils.js +86 -0
  157. package/icc-x-api/crypto/AccessControlSecretUtils.js.map +1 -0
  158. package/icc-x-api/crypto/BaseExchangeDataManager.d.ts +146 -0
  159. package/icc-x-api/crypto/BaseExchangeDataManager.js +342 -0
  160. package/icc-x-api/crypto/BaseExchangeDataManager.js.map +1 -0
  161. package/icc-x-api/crypto/BaseExchangeKeysManager.d.ts +0 -18
  162. package/icc-x-api/crypto/BaseExchangeKeysManager.js +11 -85
  163. package/icc-x-api/crypto/BaseExchangeKeysManager.js.map +1 -1
  164. package/icc-x-api/crypto/ConfidentialEntities.d.ts +26 -16
  165. package/icc-x-api/crypto/ConfidentialEntities.js +30 -17
  166. package/icc-x-api/crypto/ConfidentialEntities.js.map +1 -1
  167. package/icc-x-api/crypto/CryptoStrategies.d.ts +8 -1
  168. package/icc-x-api/crypto/CryptoStrategies.js.map +1 -1
  169. package/icc-x-api/crypto/ExchangeDataManager.d.ts +95 -0
  170. package/icc-x-api/crypto/ExchangeDataManager.js +493 -0
  171. package/icc-x-api/crypto/ExchangeDataManager.js.map +1 -0
  172. package/icc-x-api/crypto/ExchangeDataMapManager.d.ts +32 -0
  173. package/icc-x-api/crypto/ExchangeDataMapManager.js +70 -0
  174. package/icc-x-api/crypto/ExchangeDataMapManager.js.map +1 -0
  175. package/icc-x-api/crypto/ExchangeKeysManager.d.ts +4 -16
  176. package/icc-x-api/crypto/ExchangeKeysManager.js +4 -62
  177. package/icc-x-api/crypto/ExchangeKeysManager.js.map +1 -1
  178. package/icc-x-api/crypto/ExtendedApisUtils.d.ts +336 -0
  179. package/icc-x-api/crypto/ExtendedApisUtils.js +3 -0
  180. package/icc-x-api/crypto/ExtendedApisUtils.js.map +1 -0
  181. package/icc-x-api/crypto/ExtendedApisUtilsImpl.d.ts +181 -0
  182. package/icc-x-api/crypto/ExtendedApisUtilsImpl.js +562 -0
  183. package/icc-x-api/crypto/ExtendedApisUtilsImpl.js.map +1 -0
  184. package/icc-x-api/crypto/KeyRecovery.d.ts +5 -2
  185. package/icc-x-api/crypto/KeyRecovery.js +59 -29
  186. package/icc-x-api/crypto/KeyRecovery.js.map +1 -1
  187. package/icc-x-api/crypto/LegacyCryptoStrategies.d.ts +7 -2
  188. package/icc-x-api/crypto/LegacyCryptoStrategies.js +8 -1
  189. package/icc-x-api/crypto/LegacyCryptoStrategies.js.map +1 -1
  190. package/icc-x-api/crypto/LegacyDelegationSecurityMetadataDecryptor.d.ts +39 -0
  191. package/icc-x-api/crypto/LegacyDelegationSecurityMetadataDecryptor.js +150 -0
  192. package/icc-x-api/crypto/LegacyDelegationSecurityMetadataDecryptor.js.map +1 -0
  193. package/icc-x-api/crypto/RSA.d.ts +34 -8
  194. package/icc-x-api/crypto/RSA.js +80 -13
  195. package/icc-x-api/crypto/RSA.js.map +1 -1
  196. package/icc-x-api/crypto/SecureDelegationsEncryption.d.ts +54 -0
  197. package/icc-x-api/crypto/SecureDelegationsEncryption.js +178 -0
  198. package/icc-x-api/crypto/SecureDelegationsEncryption.js.map +1 -0
  199. package/icc-x-api/crypto/SecureDelegationsManager.d.ts +66 -0
  200. package/icc-x-api/crypto/SecureDelegationsManager.js +261 -0
  201. package/icc-x-api/crypto/SecureDelegationsManager.js.map +1 -0
  202. package/icc-x-api/crypto/SecureDelegationsSecurityMetadataDecryptor.d.ts +37 -0
  203. package/icc-x-api/crypto/SecureDelegationsSecurityMetadataDecryptor.js +294 -0
  204. package/icc-x-api/crypto/SecureDelegationsSecurityMetadataDecryptor.js.map +1 -0
  205. package/icc-x-api/crypto/SecurityMetadataDecryptor.d.ts +114 -0
  206. package/icc-x-api/crypto/SecurityMetadataDecryptor.js +98 -0
  207. package/icc-x-api/crypto/SecurityMetadataDecryptor.js.map +1 -0
  208. package/icc-x-api/crypto/ShamirKeysManager.d.ts +5 -5
  209. package/icc-x-api/crypto/ShamirKeysManager.js +6 -9
  210. package/icc-x-api/crypto/ShamirKeysManager.js.map +1 -1
  211. package/icc-x-api/crypto/TransferKeysManager.d.ts +8 -6
  212. package/icc-x-api/crypto/TransferKeysManager.js +75 -52
  213. package/icc-x-api/crypto/TransferKeysManager.js.map +1 -1
  214. package/icc-x-api/crypto/{KeyManager.d.ts → UserEncryptionKeysManager.d.ts} +4 -6
  215. package/icc-x-api/crypto/{KeyManager.js → UserEncryptionKeysManager.js} +43 -23
  216. package/icc-x-api/crypto/UserEncryptionKeysManager.js.map +1 -0
  217. package/icc-x-api/crypto/UserSignatureKeysManager.d.ts +26 -0
  218. package/icc-x-api/crypto/UserSignatureKeysManager.js +74 -0
  219. package/icc-x-api/crypto/UserSignatureKeysManager.js.map +1 -0
  220. package/icc-x-api/crypto/utils.d.ts +61 -11
  221. package/icc-x-api/crypto/utils.js +113 -44
  222. package/icc-x-api/crypto/utils.js.map +1 -1
  223. package/icc-x-api/filters/filters.js.map +1 -1
  224. package/icc-x-api/icc-accesslog-x-api.d.ts +46 -11
  225. package/icc-x-api/icc-accesslog-x-api.js +75 -42
  226. package/icc-x-api/icc-accesslog-x-api.js.map +1 -1
  227. package/icc-x-api/icc-calendar-item-x-api.d.ts +50 -14
  228. package/icc-x-api/icc-calendar-item-x-api.js +99 -49
  229. package/icc-x-api/icc-calendar-item-x-api.js.map +1 -1
  230. package/icc-x-api/icc-classification-x-api.d.ts +44 -9
  231. package/icc-x-api/icc-classification-x-api.js +56 -31
  232. package/icc-x-api/icc-classification-x-api.js.map +1 -1
  233. package/icc-x-api/icc-contact-x-api.d.ts +56 -32
  234. package/icc-x-api/icc-contact-x-api.js +95 -64
  235. package/icc-x-api/icc-contact-x-api.js.map +1 -1
  236. package/icc-x-api/icc-crypto-x-api.d.ts +28 -334
  237. package/icc-x-api/icc-crypto-x-api.js +41 -765
  238. package/icc-x-api/icc-crypto-x-api.js.map +1 -1
  239. package/icc-x-api/icc-data-owner-x-api.d.ts +20 -8
  240. package/icc-x-api/icc-data-owner-x-api.js +31 -10
  241. package/icc-x-api/icc-data-owner-x-api.js.map +1 -1
  242. package/icc-x-api/icc-document-x-api.d.ts +48 -11
  243. package/icc-x-api/icc-document-x-api.js +111 -64
  244. package/icc-x-api/icc-document-x-api.js.map +1 -1
  245. package/icc-x-api/icc-form-x-api.d.ts +45 -10
  246. package/icc-x-api/icc-form-x-api.js +65 -35
  247. package/icc-x-api/icc-form-x-api.js.map +1 -1
  248. package/icc-x-api/icc-hcparty-x-api.d.ts +2 -2
  249. package/icc-x-api/icc-hcparty-x-api.js +3 -3
  250. package/icc-x-api/icc-hcparty-x-api.js.map +1 -1
  251. package/icc-x-api/icc-helement-x-api.d.ts +55 -18
  252. package/icc-x-api/icc-helement-x-api.js +76 -41
  253. package/icc-x-api/icc-helement-x-api.js.map +1 -1
  254. package/icc-x-api/icc-icure-maintenance-x-api.d.ts +7 -2
  255. package/icc-x-api/icc-icure-maintenance-x-api.js +38 -27
  256. package/icc-x-api/icc-icure-maintenance-x-api.js.map +1 -1
  257. package/icc-x-api/icc-invoice-x-api.d.ts +50 -15
  258. package/icc-x-api/icc-invoice-x-api.js +63 -33
  259. package/icc-x-api/icc-invoice-x-api.js.map +1 -1
  260. package/icc-x-api/icc-maintenance-task-x-api.d.ts +53 -21
  261. package/icc-x-api/icc-maintenance-task-x-api.js +72 -35
  262. package/icc-x-api/icc-maintenance-task-x-api.js.map +1 -1
  263. package/icc-x-api/icc-message-x-api.d.ts +53 -15
  264. package/icc-x-api/icc-message-x-api.js +65 -36
  265. package/icc-x-api/icc-message-x-api.js.map +1 -1
  266. package/icc-x-api/icc-patient-x-api.d.ts +84 -29
  267. package/icc-x-api/icc-patient-x-api.js +313 -378
  268. package/icc-x-api/icc-patient-x-api.js.map +1 -1
  269. package/icc-x-api/icc-receipt-x-api.d.ts +44 -12
  270. package/icc-x-api/icc-receipt-x-api.js +67 -35
  271. package/icc-x-api/icc-receipt-x-api.js.map +1 -1
  272. package/icc-x-api/icc-time-table-x-api.d.ts +43 -12
  273. package/icc-x-api/icc-time-table-x-api.js +56 -26
  274. package/icc-x-api/icc-time-table-x-api.js.map +1 -1
  275. package/icc-x-api/icc-user-x-api.d.ts +2 -2
  276. package/icc-x-api/icc-user-x-api.js +3 -3
  277. package/icc-x-api/icc-user-x-api.js.map +1 -1
  278. package/icc-x-api/index.d.ts +4 -2
  279. package/icc-x-api/index.js +154 -135
  280. package/icc-x-api/index.js.map +1 -1
  281. package/icc-x-api/storage/DefaultStorageEntryKeysFactory.d.ts +2 -0
  282. package/icc-x-api/storage/DefaultStorageEntryKeysFactory.js +9 -2
  283. package/icc-x-api/storage/DefaultStorageEntryKeysFactory.js.map +1 -1
  284. package/icc-x-api/storage/IcureStorageFacade.d.ts +23 -2
  285. package/icc-x-api/storage/IcureStorageFacade.js +36 -2
  286. package/icc-x-api/storage/IcureStorageFacade.js.map +1 -1
  287. package/icc-x-api/storage/KeyStorageFacade.d.ts +12 -0
  288. package/icc-x-api/storage/KeyStorageFacade.js.map +1 -1
  289. package/icc-x-api/storage/KeyStorageImpl.d.ts +2 -0
  290. package/icc-x-api/storage/KeyStorageImpl.js +10 -0
  291. package/icc-x-api/storage/KeyStorageImpl.js.map +1 -1
  292. package/icc-x-api/storage/StorageEntryKeysFactory.d.ts +14 -1
  293. package/icc-x-api/storage/StorageEntryKeysFactory.js.map +1 -1
  294. package/icc-x-api/utils/EntityWithDelegationTypeName.d.ts +32 -0
  295. package/icc-x-api/utils/EntityWithDelegationTypeName.js +75 -0
  296. package/icc-x-api/utils/EntityWithDelegationTypeName.js.map +1 -0
  297. package/icc-x-api/utils/ShareResult.d.ts +74 -0
  298. package/icc-x-api/utils/ShareResult.js +61 -0
  299. package/icc-x-api/utils/ShareResult.js.map +1 -0
  300. package/icc-x-api/utils/binary-utils.d.ts +1 -0
  301. package/icc-x-api/utils/binary-utils.js +8 -1
  302. package/icc-x-api/utils/binary-utils.js.map +1 -1
  303. package/icc-x-api/utils/collection-utils.d.ts +5 -0
  304. package/icc-x-api/utils/collection-utils.js +26 -1
  305. package/icc-x-api/utils/collection-utils.js.map +1 -1
  306. package/icc-x-api/utils/crypto-utils.d.ts +4 -3
  307. package/icc-x-api/utils/crypto-utils.js +5 -4
  308. package/icc-x-api/utils/crypto-utils.js.map +1 -1
  309. package/icc-x-api/utils/lru-temporised-async-cache.d.ts +26 -3
  310. package/icc-x-api/utils/lru-temporised-async-cache.js +75 -15
  311. package/icc-x-api/utils/lru-temporised-async-cache.js.map +1 -1
  312. package/icc-x-api/utils/websocket.d.ts +10 -10
  313. package/icc-x-api/utils/websocket.js +18 -9
  314. package/icc-x-api/utils/websocket.js.map +1 -1
  315. package/index.d.ts +1 -1
  316. package/index.js +3 -1
  317. package/index.js.map +1 -1
  318. package/package.json +2 -3
  319. package/icc-x-api/crypto/EntitiesEncryption.d.ts +0 -275
  320. package/icc-x-api/crypto/EntitiesEncryption.js +0 -734
  321. package/icc-x-api/crypto/EntitiesEncryption.js.map +0 -1
  322. package/icc-x-api/crypto/KeyManager.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SecurityMetadataDecryptor.js","sourceRoot":"","sources":["../../../icc-x-api/crypto/SecurityMetadataDecryptor.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAEA,2EAAuE;AACvE,IAAO,WAAW,GAAG,mCAAgB,CAAC,eAAe,CAAA;AAuFrD;;;GAGG;AACH,MAAa,8BAA8B;IACzC,YAA6B,UAAuC;QAAvC,eAAU,GAAV,UAAU,CAA6B;IAAG,CAAC;IAExE,uBAAuB,CACrB,WAAoC,EACpC,yBAAmC;QAEnC,OAAO,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,uBAAuB,CAAC,WAAW,EAAE,yBAAyB,CAAC,CAAC,CAAA;IACnG,CAAC;IAED,wBAAwB,CACtB,WAAoC,EACpC,yBAAmC;QAEnC,OAAO,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,wBAAwB,CAAC,WAAW,EAAE,yBAAyB,CAAC,CAAC,CAAA;IACpG,CAAC;IAED,kBAAkB,CAChB,WAAoC,EACpC,yBAAmC;QAEnC,OAAO,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,kBAAkB,CAAC,WAAW,EAAE,yBAAyB,CAAC,CAAC,CAAA;IAC9F,CAAC;IAEK,oBAAoB,CACxB,WAAoC,EACpC,yBAAmC;;YAEnC,IAAI,YAAY,GAAiD,SAAS,CAAA;YAC1E,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,UAAU,EAAE;gBAC/B,MAAM,SAAS,GAAG,MAAM,CAAC,CAAC,oBAAoB,CAAC,WAAW,EAAE,yBAAyB,CAAC,CAAA;gBACtF,IAAI,SAAS,KAAK,WAAW,CAAC,KAAK,EAAE;oBACnC,OAAO,SAAS,CAAA;iBACjB;gBACD,IAAI,SAAS,KAAK,WAAW,CAAC,IAAI,EAAE;oBAClC,YAAY,GAAG,WAAW,CAAC,IAAI,CAAA;iBAChC;aACF;YACD,OAAO,YAAY,CAAA;QACrB,CAAC;KAAA;IAED,oBAAoB,CAAC,MAA6C;QAChE,OAAO,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC,CAAA;IACpE,CAAC;IAEK,yBAAyB,CAAC,WAAoC;;YAIlE,MAAM,sBAAsB,GAA+C,EAAE,CAAA;YAC7E,IAAI,6BAA6B,GAAG,KAAK,CAAA;YACzC,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,UAAU,EAAE;gBAC/B,MAAM,UAAU,GAAG,MAAM,CAAC,CAAC,yBAAyB,CAAC,WAAW,CAAC,CAAA;gBACjE,6BAA6B,GAAG,6BAA6B,IAAI,UAAU,CAAC,6BAA6B,CAAA;gBACzG,KAAK,MAAM,CAAC,WAAW,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,wBAAwB,CAAC,EAAE;oBACtF,IAAI,sBAAsB,CAAC,WAAW,CAAC,KAAK,WAAW,CAAC,KAAK,EAAE;wBAC7D,sBAAsB,CAAC,WAAW,CAAC,GAAG,KAAK,CAAA;qBAC5C;iBACF;aACF;YACD,OAAO;gBACL,wBAAwB,EAAE,sBAAsB;gBAChD,6BAA6B;aAC9B,CAAA;QACH,CAAC;KAAA;IAEO,WAAW,CAAI,YAA8E;QACnG,SAAgB,SAAS,CAAC,UAAuC;;gBAC/D,KAAK,MAAM,CAAC,IAAI,UAAU,EAAE;oBAC1B,MAAM,aAAa,GAAG,YAAY,CAAC,CAAC,CAAC,CAAA;oBACrC,IAAI,IAAI,GAAG,cAAM,aAAa,CAAC,IAAI,EAAE,CAAA,CAAA;oBACrC,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE;wBACjB,oBAAM,IAAI,CAAC,KAAK,CAAA,CAAA;wBAChB,IAAI,GAAG,cAAM,aAAa,CAAC,IAAI,EAAE,CAAA,CAAA;qBAClC;iBACF;YACH,CAAC;SAAA;QACD,OAAO,SAAS,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;IACnC,CAAC;CACF;AA/ED,wEA+EC","sourcesContent":["import { EncryptedEntity, EncryptedEntityStub } from '../../icc-api/model/models'\nimport { EncryptedEntityWithType } from '../utils/EntityWithDelegationTypeName'\nimport { SecureDelegation } from '../../icc-api/model/SecureDelegation'\nimport AccessLevel = SecureDelegation.AccessLevelEnum\nimport AccessLevelEnum = SecureDelegation.AccessLevelEnum\n\n/**\n * @internal this class is for internal use only and may be changed without notice.\n * Logic for the decryption of the metadata used for access control, encryption, and other security features in an entity.\n */\nexport interface SecurityMetadataDecryptor {\n /**\n * Decrypt the encryption keys for an entity. Keys must be returned in raw hex format, removing dashes if they were generated from a UUID.\n * @param typedEntity an encrypted entity or its stub.\n * @param dataOwnersHierarchySubset only exchange data that is accessible to data owners in this array will be considered when decrypting. It should\n * contain only data owners from the current data owner hierarchy.\n * @throws if dataOwnersHierarchySubset is empty\n * @return a generator for the decrypted exchange key which yields objects containing:\n * - `decrypted`: a decrypted encryption key for {@link typedEntity}. Note that the same key may be yielded multiple times by the generator.\n * - `dataOwnersWithAccess`: data owners which have access to the exchange data necessary for the decryption of the encrypted data from which this\n * key was extracted. The generator may yield more elements with the same `decrypted` but different `dataOwnersWithAccess`\n */\n decryptEncryptionKeysOf(\n typedEntity: EncryptedEntityWithType,\n dataOwnersHierarchySubset: string[]\n ): AsyncGenerator<{ decrypted: string; dataOwnersWithAccess: string[] }, void, never>\n\n /**\n * Decrypt the secret ids for an entity.\n * @param typedEntity an encrypted entity or its stub.\n * @param dataOwnersHierarchySubset only exchange data that is accessible to data owners in this array will be considered when decrypting. It should\n * contain only data owners from the current data owner hierarchy.\n * @throws if dataOwnersHierarchySubset is empty\n * @return a generator for the decrypted secret ids which yields objects containing:\n * - `decrypted`: a decrypted secret id of {@link entity}. Note that the same id may be yielded multiple times by the generator.\n * - `dataOwnersWithAccess`: data owners which have access to the exchange data necessary for the decryption of the encrypted data from which this\n * id was extracted. The generator may yield more elements with the same `decrypted` but different `dataOwnersWithAccess`\n */\n decryptSecretIdsOf(\n typedEntity: EncryptedEntityWithType,\n dataOwnersHierarchySubset: string[]\n ): AsyncGenerator<{ decrypted: string; dataOwnersWithAccess: string[] }, void, never>\n\n /**\n * Decrypt the owning entity ids of an entity.\n * @param typedEntity an encrypted entity or its stub.\n * @param dataOwnersHierarchySubset only exchange data that is accessible to data owners in this array will be considered when decrypting. It should\n * contain only data owners from the current data owner hierarchy.\n * @throws if dataOwnersHierarchySubset is empty\n * @return a generator for the decrypted owning entity ids which yields objects containing:\n * - `decrypted`: a decrypted owning entity id of {@link entity}. Note that the same id may be yielded multiple times by the generator.\n * - `dataOwnersWithAccess`: data owners which have access to the exchange data necessary for the decryption of the encrypted data from which this\n * id was extracted. The generator may yield more elements with the same `decrypted` but different `dataOwnersWithAccess`\n */\n decryptOwningEntityIdsOf(\n typedEntity: EncryptedEntityWithType,\n dataOwnersHierarchySubset: string[]\n ): AsyncGenerator<{ decrypted: string; dataOwnersWithAccess: string[] }, void, never>\n\n /**\n * Get the maximum access level that any data owner in {@link dataOwnersHierarchySubset} has to {@link typedEntity}, according to the metadata\n * supported by this decryptor.\n * - If at least a data owner in {@link dataOwnersHierarchySubset} has write access the method returns {@link AccessLevel.WRITE}.\n * - If at least a data owner in {@link dataOwnersHierarchySubset} has read access and no data owner has write access the method returns\n * {@link AccessLevel.READ}.\n * - If a data owner has no access to the entity the method returns undefined (this can happen if the data owner has access to an entity through\n * some metadata which is not supported by this decryptor).\n * @param typedEntity an entity\n * @param dataOwnersHierarchySubset only exchange data that is accessible to data owners in this array will be considered when calculating the\n * access level. This array should contain only data owners from the current data owner hierarchy.\n * @return the access level to the entity or undefined if none of the data owners has full access to the entity.\n */\n getEntityAccessLevel(typedEntity: EncryptedEntityWithType, dataOwnersHierarchySubset: string[]): Promise<AccessLevel | undefined>\n\n /**\n * Get the access level of each data owner with access to the entity according to the metadata supported by this decryptor.\n * See {@link EncryptedEntityXApi.getDataOwnersWithAccessTo} for details on the expected behaviour.\n */\n getDataOwnersWithAccessTo(typedEntity: EncryptedEntityWithType): Promise<{\n permissionsByDataOwnerId: { [dataOwnerId: string]: AccessLevelEnum }\n hasUnknownAnonymousDataOwners: boolean\n }>\n\n /**\n * Verifies if there is at least one (encrypted) encryption key in the metadata supported by this decryptor, even if it can't be decrypted by the\n * current data owner.\n */\n hasAnyEncryptionKeys(entity: EncryptedEntity | EncryptedEntityStub): boolean\n}\n\n/**\n * @internal this class is meant for internal use only and may be changed without notice.\n * Security metadata decryptor which combines other existing decryptors.\n */\nexport class SecurityMetadataDecryptorChain implements SecurityMetadataDecryptor {\n constructor(private readonly decryptors: SecurityMetadataDecryptor[]) {}\n\n decryptEncryptionKeysOf(\n typedEntity: EncryptedEntityWithType,\n dataOwnersHierarchySubset: string[]\n ): AsyncGenerator<{ decrypted: string; dataOwnersWithAccess: string[] }, void, never> {\n return this.concatenate((d) => d.decryptEncryptionKeysOf(typedEntity, dataOwnersHierarchySubset))\n }\n\n decryptOwningEntityIdsOf(\n typedEntity: EncryptedEntityWithType,\n dataOwnersHierarchySubset: string[]\n ): AsyncGenerator<{ decrypted: string; dataOwnersWithAccess: string[] }, void, never> {\n return this.concatenate((d) => d.decryptOwningEntityIdsOf(typedEntity, dataOwnersHierarchySubset))\n }\n\n decryptSecretIdsOf(\n typedEntity: EncryptedEntityWithType,\n dataOwnersHierarchySubset: string[]\n ): AsyncGenerator<{ decrypted: string; dataOwnersWithAccess: string[] }, void, never> {\n return this.concatenate((d) => d.decryptSecretIdsOf(typedEntity, dataOwnersHierarchySubset))\n }\n\n async getEntityAccessLevel(\n typedEntity: EncryptedEntityWithType,\n dataOwnersHierarchySubset: string[]\n ): Promise<SecureDelegation.AccessLevelEnum | undefined> {\n let currMaxLevel: SecureDelegation.AccessLevelEnum | undefined = undefined\n for (const d of this.decryptors) {\n const currLevel = await d.getEntityAccessLevel(typedEntity, dataOwnersHierarchySubset)\n if (currLevel === AccessLevel.WRITE) {\n return currLevel\n }\n if (currLevel === AccessLevel.READ) {\n currMaxLevel = AccessLevel.READ\n }\n }\n return currMaxLevel\n }\n\n hasAnyEncryptionKeys(entity: EncryptedEntity | EncryptedEntityStub): boolean {\n return this.decryptors.some((d) => d.hasAnyEncryptionKeys(entity))\n }\n\n async getDataOwnersWithAccessTo(typedEntity: EncryptedEntityWithType): Promise<{\n permissionsByDataOwnerId: { [dataOwnerId: string]: AccessLevelEnum }\n hasUnknownAnonymousDataOwners: boolean\n }> {\n const accumulatedPermissions: { [dataOwnerId: string]: AccessLevelEnum } = {}\n let hasUnknownAnonymousDataOwners = false\n for (const d of this.decryptors) {\n const currAccess = await d.getDataOwnersWithAccessTo(typedEntity)\n hasUnknownAnonymousDataOwners = hasUnknownAnonymousDataOwners || currAccess.hasUnknownAnonymousDataOwners\n for (const [dataOwnerId, level] of Object.entries(currAccess.permissionsByDataOwnerId)) {\n if (accumulatedPermissions[dataOwnerId] !== AccessLevel.WRITE) {\n accumulatedPermissions[dataOwnerId] = level\n }\n }\n }\n return {\n permissionsByDataOwnerId: accumulatedPermissions,\n hasUnknownAnonymousDataOwners,\n }\n }\n\n private concatenate<T>(getGenerator: (d: SecurityMetadataDecryptor) => AsyncGenerator<T, void, never>): AsyncGenerator<T, void, never> {\n async function* generator(decryptors: SecurityMetadataDecryptor[]): AsyncGenerator<T, void, never> {\n for (const d of decryptors) {\n const currGenerator = getGenerator(d)\n let next = await currGenerator.next()\n while (!next.done) {\n yield next.value\n next = await currGenerator.next()\n }\n }\n }\n return generator(this.decryptors)\n }\n}\n"]}
@@ -1,7 +1,7 @@
1
1
  import { DataOwnerOrStub, IccDataOwnerXApi } from '../icc-data-owner-x-api';
2
- import { KeyManager } from './KeyManager';
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 keyManager;
13
- private readonly exchangeKeysManager;
14
- constructor(primitives: CryptoPrimitives, dataOwnerApi: IccDataOwnerXApi, keyManager: KeyManager, exchangeKeysManager: ExchangeKeysManager);
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, keyManager, exchangeKeysManager) {
19
+ constructor(primitives, dataOwnerApi, encryptionKeysManager, exchangeDataManager) {
20
20
  this.primitives = primitives;
21
21
  this.dataOwnerApi = dataOwnerApi;
22
- this.keyManager = keyManager;
23
- this.exchangeKeysManager = exchangeKeysManager;
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.keyManager.getDecryptionKeys();
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.exchangeKeysManager.getOrCreateEncryptionExchangeKeysTo(delegateId);
74
- delegatesKeys[delegateId] = res.keys[0];
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 { KeyManager } from './KeyManager';
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 baseExchangeKeysManager;
14
+ private readonly baseExchangeDataManager;
14
15
  private readonly dataOwnerApi;
15
- private readonly keyManager;
16
+ private readonly encryptionKeysManager;
17
+ private readonly userSignatureKeysManager;
16
18
  private readonly icureStorage;
17
- constructor(primitives: CryptoPrimitives, baseExchangeKeysManager: BaseExchangeKeysManager, dataOwnerApi: IccDataOwnerXApi, keyManager: KeyManager, icureStorage: IcureStorageFacade);
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 transferTargetVerifiedKey;
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, baseExchangeKeysManager, dataOwnerApi, keyManager, icureStorage) {
21
+ constructor(primitives, baseExchangeDataManager, dataOwnerApi, encryptionKeysManager, userSignatureKeysManager, icureStorage) {
22
22
  this.primitives = primitives;
23
- this.baseExchangeKeysManager = baseExchangeKeysManager;
23
+ this.baseExchangeDataManager = baseExchangeDataManager;
24
24
  this.dataOwnerApi = dataOwnerApi;
25
- this.keyManager = keyManager;
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 newEdges = yield this.getNewVerifiedTransferKeysEdges(self);
39
- if (!newEdges)
39
+ const newEdgesByTarget = yield this.getNewVerifiedTransferKeysEdges(self);
40
+ if (!newEdgesByTarget.length)
40
41
  return;
41
- const selfId = yield this.dataOwnerApi.getCurrentDataOwnerId();
42
- const fpToPublicKey = (0, utils_2.fingerprintToPublicKeysMapOf)(self.stub);
43
- const newExchangeKeyPublicKeys = newEdges.sources.map((fp) => fpToPublicKey[fp]);
44
- const { key: exchangeKey, updatedDelegator: updatedSelf } = yield this.baseExchangeKeysManager.createOrUpdateEncryptedExchangeKeyTo(selfId, newEdges.target, yield (0, utils_2.loadPublicKeys)(this.primitives.RSA, newExchangeKeyPublicKeys));
45
- // note: createEncryptedExchangeKeyFor may update self
46
- const encryptedTransferKey = yield this.encryptTransferKey(newEdges.target, exchangeKey);
47
- const newTransferKeys = newEdges.sources.reduce((acc, candidateFp) => {
48
- var _a;
49
- const existingKeys = Object.assign({}, ((_a = acc[candidateFp]) !== null && _a !== void 0 ? _a : {}));
50
- existingKeys[newEdges.targetFp] = encryptedTransferKey;
51
- acc[candidateFp] = existingKeys;
52
- return acc;
53
- }, Object.assign({}, ((_a = updatedSelf.stub.transferKeys) !== null && _a !== void 0 ? _a : {})));
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
- type: updatedSelf.type,
56
- stub: Object.assign(Object.assign({}, updatedSelf.stub), { transferKeys: newTransferKeys }),
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
- transferTargetVerifiedKey(keyManager) {
84
+ transferTargetKeys(keyManager, graph) {
75
85
  return __awaiter(this, void 0, void 0, function* () {
76
- return keyManager.getSelfVerifiedKeys()[0];
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.keyManager.getSelfVerifiedKeys().map((x) => x.fingerprint));
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(key.slice(-32));
104
+ verifiedKeysFpSet.add((0, utils_2.fingerprintV1)(key));
86
105
  });
87
106
  if (verifiedKeysFpSet.size == 0)
88
- return undefined;
107
+ return [];
89
108
  const graph = (0, utils_2.transferKeysFpGraphOf)(self.stub);
90
- // 1. Choose a key available in this device which should be reachable from all other verified keys
91
- const { fingerprint: targetKeyFp, pair: targetKey } = yield this.transferTargetVerifiedKey(this.keyManager);
92
- // 2. Find groups which can't reach the existing target keys
93
- const candidatesFp = this.transferKeysCandidatesFp(targetKeyFp, graph);
94
- // 3. Keep only groups which contain at least a verified candidate
95
- const verifiedGroupCandidates = candidatesFp.filter((candidate) => graph.acyclicLabelToGroup[candidate].some((candidateGroupMember) => verifiedKeysFpSet.has(candidateGroupMember)));
96
- const verifiedCandidatesSet = new Set(verifiedGroupCandidates);
97
- if (verifiedCandidatesSet.size == 0)
98
- return undefined;
99
- // 4. Drop all candidates which can already reach another candidate group: it is sufficient to create a transfer key from that group.
100
- const reachSets = (0, graph_utils_1.reachSetsAcyclic)(graph.acyclicGraph);
101
- const optimizedCandidates = verifiedGroupCandidates.filter((candidate) => Array.from(reachSets[candidate]).every((reachableNode) => !verifiedCandidatesSet.has(reachableNode)));
102
- if (optimizedCandidates.length == 0)
103
- throw new Error('Check failed: at least one candidate should survive optimization');
104
- // 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
105
- // keys
106
- const verifiedOptimizedCandidates = optimizedCandidates.map((candidate) => {
107
- const res = graph.acyclicLabelToGroup[candidate].find((groupMemberFp) => verifiedKeysFpSet.has(groupMemberFp));
108
- if (!res)
109
- throw new Error('Check failed: optimized candidates groups should have at least a verified member');
110
- return res;
111
- });
112
- return {
113
- sources: verifiedOptimizedCandidates,
114
- target: targetKey,
115
- targetFp: targetKeyFp,
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 { DataOwner, IccDataOwnerXApi } from '../icc-data-owner-x-api';
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 KeyManager {
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, baseExchangeKeyManager: BaseExchangeKeysManager, strategies: CryptoStrategies, initialiseParentKeys: boolean);
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: DataOwner): Promise<string[]>;
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.KeyManager = void 0;
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 KeyManager {
20
- constructor(primitives, dataOwnerApi, icureStorage, keyRecovery, baseExchangeKeyManager, strategies, initialiseParentKeys) {
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(this.dataOwnerApi.getHexPublicKeysOf(dataOwner)).filter((key) => {
171
- const fp = key.slice(-32);
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 = this.dataOwnerApi.getHexPublicKeysOf(dowt.dataOwner);
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 !(x.slice(-32) in verifiedKeysMap) && !(((_a = availableKeys === null || availableKeys === void 0 ? void 0 : availableKeys[x.slice(-32)]) === null || _a === void 0 ? void 0 : _a.isDevice) === true); });
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 publicKeyFingerprint = publicKeyHex.slice(-32);
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
- const verifiedPublicKeysMap = yield this.icureStorage.saveSelfVerifiedKeys(selfDataOwner.dataOwner.id, { [publicKeyFingerprint]: true });
264
- const { updatedDelegator } = yield this.baseExchangeKeyManager.createOrUpdateEncryptedExchangeKeyTo(selfDataOwner.dataOwner.id, keyPair, yield (0, utils_2.loadPublicKeys)(this.primitives.RSA, Array.from(this.dataOwnerApi.getHexPublicKeysOf(selfDataOwner.dataOwner)).filter((x) => verifiedPublicKeysMap[x.slice(-32)])));
265
- return { publicKeyFingerprint, keyPair: keyPair, updatedSelf: updatedDelegator };
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
- return yield pubKeysFingerprints.reduce((acc, currentFingerprint) => __awaiter(this, void 0, void 0, function* () {
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 selfPublicKeys = this.dataOwnerApi.getHexPublicKeysOf(dataOwner.dataOwner);
310
- const pubKeysFingerprints = Array.from(selfPublicKeys).map((x) => x.slice(-32));
311
- const loadedKeys = pubKeysFingerprints.length > 0 ? yield this.loadStoredKeys(dataOwner, pubKeysFingerprints) : {};
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 && loadedKeysFingerprints.length > 0) {
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]) => [k.slice(-32), 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.KeyManager = KeyManager;
330
- //# sourceMappingURL=KeyManager.js.map
349
+ exports.UserEncryptionKeysManager = UserEncryptionKeysManager;
350
+ //# sourceMappingURL=UserEncryptionKeysManager.js.map