@matter/protocol 0.14.1-alpha.0-20250605-9fc134af0 → 0.14.1-alpha.0-20250607-a93593303

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 (312) hide show
  1. package/dist/cjs/action/server/AccessControl.d.ts +5 -7
  2. package/dist/cjs/action/server/AccessControl.d.ts.map +1 -1
  3. package/dist/cjs/action/server/AccessControl.js.map +1 -1
  4. package/dist/cjs/action/server/AttributeWriteResponse.d.ts.map +1 -1
  5. package/dist/cjs/action/server/AttributeWriteResponse.js +23 -0
  6. package/dist/cjs/action/server/AttributeWriteResponse.js.map +1 -1
  7. package/dist/cjs/action/server/CommandInvokeResponse.d.ts.map +1 -1
  8. package/dist/cjs/action/server/CommandInvokeResponse.js +24 -1
  9. package/dist/cjs/action/server/CommandInvokeResponse.js.map +1 -1
  10. package/dist/cjs/action/server/DataResponse.d.ts +1 -1
  11. package/dist/cjs/action/server/DataResponse.d.ts.map +1 -1
  12. package/dist/cjs/action/server/Subject.d.ts +25 -0
  13. package/dist/cjs/action/server/Subject.d.ts.map +1 -0
  14. package/dist/cjs/action/server/Subject.js +54 -0
  15. package/dist/cjs/action/server/Subject.js.map +6 -0
  16. package/dist/cjs/action/server/index.d.ts +1 -0
  17. package/dist/cjs/action/server/index.d.ts.map +1 -1
  18. package/dist/cjs/action/server/index.js +1 -0
  19. package/dist/cjs/action/server/index.js.map +1 -1
  20. package/dist/cjs/certificate/DeviceCertification.d.ts +2 -2
  21. package/dist/cjs/certificate/DeviceCertification.d.ts.map +1 -1
  22. package/dist/cjs/certificate/DeviceCertification.js.map +1 -1
  23. package/dist/cjs/cluster/client/AttributeClient.d.ts +3 -3
  24. package/dist/cjs/cluster/client/AttributeClient.d.ts.map +1 -1
  25. package/dist/cjs/cluster/client/AttributeClient.js +14 -2
  26. package/dist/cjs/cluster/client/AttributeClient.js.map +1 -1
  27. package/dist/cjs/cluster/client/ClusterClient.d.ts +3 -2
  28. package/dist/cjs/cluster/client/ClusterClient.d.ts.map +1 -1
  29. package/dist/cjs/cluster/client/ClusterClient.js +66 -1
  30. package/dist/cjs/cluster/client/ClusterClient.js.map +1 -1
  31. package/dist/cjs/cluster/client/ClusterClientTypes.d.ts +36 -8
  32. package/dist/cjs/cluster/client/ClusterClientTypes.d.ts.map +1 -1
  33. package/dist/cjs/cluster/client/EventClient.d.ts +3 -3
  34. package/dist/cjs/cluster/client/EventClient.d.ts.map +1 -1
  35. package/dist/cjs/cluster/client/EventClient.js +7 -0
  36. package/dist/cjs/cluster/client/EventClient.js.map +1 -1
  37. package/dist/cjs/codec/MessageCodec.d.ts.map +1 -1
  38. package/dist/cjs/codec/MessageCodec.js +31 -6
  39. package/dist/cjs/codec/MessageCodec.js.map +1 -1
  40. package/dist/cjs/fabric/Fabric.d.ts +20 -30
  41. package/dist/cjs/fabric/Fabric.d.ts.map +1 -1
  42. package/dist/cjs/fabric/Fabric.js +38 -62
  43. package/dist/cjs/fabric/Fabric.js.map +2 -2
  44. package/dist/cjs/fabric/FabricManager.d.ts.map +1 -1
  45. package/dist/cjs/fabric/FabricManager.js +10 -4
  46. package/dist/cjs/fabric/FabricManager.js.map +1 -1
  47. package/dist/cjs/groups/FabricGroupsManager.d.ts +46 -0
  48. package/dist/cjs/groups/FabricGroupsManager.d.ts.map +1 -0
  49. package/dist/cjs/groups/FabricGroupsManager.js +155 -0
  50. package/dist/cjs/groups/FabricGroupsManager.js.map +6 -0
  51. package/dist/cjs/groups/Groups.d.ts +34 -0
  52. package/dist/cjs/groups/Groups.d.ts.map +1 -0
  53. package/dist/cjs/groups/Groups.js +89 -0
  54. package/dist/cjs/groups/Groups.js.map +6 -0
  55. package/dist/cjs/groups/KeySets.d.ts +64 -0
  56. package/dist/cjs/groups/KeySets.d.ts.map +1 -0
  57. package/dist/cjs/groups/KeySets.js +179 -0
  58. package/dist/cjs/groups/KeySets.js.map +6 -0
  59. package/dist/cjs/groups/MessagingState.d.ts +24 -0
  60. package/dist/cjs/groups/MessagingState.d.ts.map +1 -0
  61. package/dist/cjs/groups/MessagingState.js +91 -0
  62. package/dist/cjs/groups/MessagingState.js.map +6 -0
  63. package/dist/cjs/groups/index.d.ts +8 -0
  64. package/dist/cjs/groups/index.d.ts.map +1 -0
  65. package/dist/cjs/groups/index.js +25 -0
  66. package/dist/cjs/groups/index.js.map +6 -0
  67. package/dist/cjs/index.d.ts +1 -0
  68. package/dist/cjs/index.d.ts.map +1 -1
  69. package/dist/cjs/index.js +1 -0
  70. package/dist/cjs/index.js.map +1 -1
  71. package/dist/cjs/interaction/AccessControlManager.d.ts +4 -13
  72. package/dist/cjs/interaction/AccessControlManager.d.ts.map +1 -1
  73. package/dist/cjs/interaction/AccessControlManager.js +38 -47
  74. package/dist/cjs/interaction/AccessControlManager.js.map +1 -1
  75. package/dist/cjs/interaction/InteractionClient.d.ts +5 -4
  76. package/dist/cjs/interaction/InteractionClient.d.ts.map +1 -1
  77. package/dist/cjs/interaction/InteractionClient.js +53 -3
  78. package/dist/cjs/interaction/InteractionClient.js.map +1 -1
  79. package/dist/cjs/interaction/InteractionMessenger.d.ts.map +1 -1
  80. package/dist/cjs/interaction/InteractionMessenger.js +15 -0
  81. package/dist/cjs/interaction/InteractionMessenger.js.map +1 -1
  82. package/dist/cjs/interaction/Subscription.d.ts +3 -3
  83. package/dist/cjs/interaction/Subscription.d.ts.map +1 -1
  84. package/dist/cjs/interaction/Subscription.js.map +1 -1
  85. package/dist/cjs/peer/PeerAddress.d.ts +1 -0
  86. package/dist/cjs/peer/PeerAddress.d.ts.map +1 -1
  87. package/dist/cjs/peer/PeerAddress.js +5 -0
  88. package/dist/cjs/peer/PeerAddress.js.map +1 -1
  89. package/dist/cjs/peer/PeerSet.d.ts.map +1 -1
  90. package/dist/cjs/peer/PeerSet.js +31 -2
  91. package/dist/cjs/peer/PeerSet.js.map +1 -1
  92. package/dist/cjs/protocol/ChannelManager.d.ts.map +1 -1
  93. package/dist/cjs/protocol/ChannelManager.js +7 -8
  94. package/dist/cjs/protocol/ChannelManager.js.map +1 -1
  95. package/dist/cjs/protocol/ExchangeManager.d.ts.map +1 -1
  96. package/dist/cjs/protocol/ExchangeManager.js +39 -25
  97. package/dist/cjs/protocol/ExchangeManager.js.map +1 -1
  98. package/dist/cjs/protocol/MessageExchange.d.ts +1 -1
  99. package/dist/cjs/protocol/MessageExchange.d.ts.map +1 -1
  100. package/dist/cjs/protocol/MessageExchange.js +32 -4
  101. package/dist/cjs/protocol/MessageExchange.js.map +1 -1
  102. package/dist/cjs/protocol/MessageReceptionState.d.ts +1 -1
  103. package/dist/cjs/securechannel/SecureChannelProtocol.js +1 -1
  104. package/dist/cjs/securechannel/SecureChannelProtocol.js.map +1 -1
  105. package/dist/cjs/session/GroupSession.d.ts +56 -0
  106. package/dist/cjs/session/GroupSession.d.ts.map +1 -0
  107. package/dist/cjs/session/GroupSession.js +188 -0
  108. package/dist/cjs/session/GroupSession.js.map +6 -0
  109. package/dist/cjs/session/InsecureSession.d.ts +2 -1
  110. package/dist/cjs/session/InsecureSession.d.ts.map +1 -1
  111. package/dist/cjs/session/InsecureSession.js +3 -2
  112. package/dist/cjs/session/InsecureSession.js.map +1 -1
  113. package/dist/cjs/session/NodeSession.d.ts +88 -0
  114. package/dist/cjs/session/NodeSession.d.ts.map +1 -0
  115. package/dist/cjs/session/NodeSession.js +318 -0
  116. package/dist/cjs/session/NodeSession.js.map +6 -0
  117. package/dist/cjs/session/SecureSession.d.ts +10 -75
  118. package/dist/cjs/session/SecureSession.d.ts.map +1 -1
  119. package/dist/cjs/session/SecureSession.js +9 -280
  120. package/dist/cjs/session/SecureSession.js.map +2 -2
  121. package/dist/cjs/session/Session.d.ts +6 -5
  122. package/dist/cjs/session/Session.d.ts.map +1 -1
  123. package/dist/cjs/session/Session.js +11 -1
  124. package/dist/cjs/session/Session.js.map +1 -1
  125. package/dist/cjs/session/SessionManager.d.ts +27 -9
  126. package/dist/cjs/session/SessionManager.d.ts.map +1 -1
  127. package/dist/cjs/session/SessionManager.js +83 -5
  128. package/dist/cjs/session/SessionManager.js.map +2 -2
  129. package/dist/cjs/session/case/CaseClient.d.ts +1 -1
  130. package/dist/cjs/session/case/CaseClient.js +2 -2
  131. package/dist/cjs/session/case/CaseClient.js.map +1 -1
  132. package/dist/cjs/session/index.d.ts +2 -0
  133. package/dist/cjs/session/index.d.ts.map +1 -1
  134. package/dist/cjs/session/index.js +2 -0
  135. package/dist/cjs/session/index.js.map +1 -1
  136. package/dist/cjs/session/pase/PaseClient.d.ts +1 -1
  137. package/dist/esm/action/server/AccessControl.d.ts +5 -7
  138. package/dist/esm/action/server/AccessControl.d.ts.map +1 -1
  139. package/dist/esm/action/server/AccessControl.js.map +1 -1
  140. package/dist/esm/action/server/AttributeWriteResponse.d.ts.map +1 -1
  141. package/dist/esm/action/server/AttributeWriteResponse.js +23 -0
  142. package/dist/esm/action/server/AttributeWriteResponse.js.map +1 -1
  143. package/dist/esm/action/server/CommandInvokeResponse.d.ts.map +1 -1
  144. package/dist/esm/action/server/CommandInvokeResponse.js +24 -1
  145. package/dist/esm/action/server/CommandInvokeResponse.js.map +1 -1
  146. package/dist/esm/action/server/DataResponse.d.ts +1 -1
  147. package/dist/esm/action/server/DataResponse.d.ts.map +1 -1
  148. package/dist/esm/action/server/Subject.d.ts +25 -0
  149. package/dist/esm/action/server/Subject.d.ts.map +1 -0
  150. package/dist/esm/action/server/Subject.js +34 -0
  151. package/dist/esm/action/server/Subject.js.map +6 -0
  152. package/dist/esm/action/server/index.d.ts +1 -0
  153. package/dist/esm/action/server/index.d.ts.map +1 -1
  154. package/dist/esm/action/server/index.js +1 -0
  155. package/dist/esm/action/server/index.js.map +1 -1
  156. package/dist/esm/certificate/DeviceCertification.d.ts +2 -2
  157. package/dist/esm/certificate/DeviceCertification.d.ts.map +1 -1
  158. package/dist/esm/certificate/DeviceCertification.js.map +1 -1
  159. package/dist/esm/cluster/client/AttributeClient.d.ts +3 -3
  160. package/dist/esm/cluster/client/AttributeClient.d.ts.map +1 -1
  161. package/dist/esm/cluster/client/AttributeClient.js +13 -1
  162. package/dist/esm/cluster/client/AttributeClient.js.map +1 -1
  163. package/dist/esm/cluster/client/ClusterClient.d.ts +3 -2
  164. package/dist/esm/cluster/client/ClusterClient.d.ts.map +1 -1
  165. package/dist/esm/cluster/client/ClusterClient.js +67 -2
  166. package/dist/esm/cluster/client/ClusterClient.js.map +1 -1
  167. package/dist/esm/cluster/client/ClusterClientTypes.d.ts +36 -8
  168. package/dist/esm/cluster/client/ClusterClientTypes.d.ts.map +1 -1
  169. package/dist/esm/cluster/client/EventClient.d.ts +3 -3
  170. package/dist/esm/cluster/client/EventClient.d.ts.map +1 -1
  171. package/dist/esm/cluster/client/EventClient.js +7 -0
  172. package/dist/esm/cluster/client/EventClient.js.map +1 -1
  173. package/dist/esm/codec/MessageCodec.d.ts.map +1 -1
  174. package/dist/esm/codec/MessageCodec.js +41 -7
  175. package/dist/esm/codec/MessageCodec.js.map +1 -1
  176. package/dist/esm/fabric/Fabric.d.ts +20 -30
  177. package/dist/esm/fabric/Fabric.d.ts.map +1 -1
  178. package/dist/esm/fabric/Fabric.js +38 -62
  179. package/dist/esm/fabric/Fabric.js.map +2 -2
  180. package/dist/esm/fabric/FabricManager.d.ts.map +1 -1
  181. package/dist/esm/fabric/FabricManager.js +10 -4
  182. package/dist/esm/fabric/FabricManager.js.map +1 -1
  183. package/dist/esm/groups/FabricGroupsManager.d.ts +46 -0
  184. package/dist/esm/groups/FabricGroupsManager.d.ts.map +1 -0
  185. package/dist/esm/groups/FabricGroupsManager.js +135 -0
  186. package/dist/esm/groups/FabricGroupsManager.js.map +6 -0
  187. package/dist/esm/groups/Groups.d.ts +34 -0
  188. package/dist/esm/groups/Groups.d.ts.map +1 -0
  189. package/dist/esm/groups/Groups.js +69 -0
  190. package/dist/esm/groups/Groups.js.map +6 -0
  191. package/dist/esm/groups/KeySets.d.ts +64 -0
  192. package/dist/esm/groups/KeySets.d.ts.map +1 -0
  193. package/dist/esm/groups/KeySets.js +159 -0
  194. package/dist/esm/groups/KeySets.js.map +6 -0
  195. package/dist/esm/groups/MessagingState.d.ts +24 -0
  196. package/dist/esm/groups/MessagingState.d.ts.map +1 -0
  197. package/dist/esm/groups/MessagingState.js +71 -0
  198. package/dist/esm/groups/MessagingState.js.map +6 -0
  199. package/dist/esm/groups/index.d.ts +8 -0
  200. package/dist/esm/groups/index.d.ts.map +1 -0
  201. package/dist/esm/groups/index.js +8 -0
  202. package/dist/esm/groups/index.js.map +6 -0
  203. package/dist/esm/index.d.ts +1 -0
  204. package/dist/esm/index.d.ts.map +1 -1
  205. package/dist/esm/index.js +1 -0
  206. package/dist/esm/index.js.map +1 -1
  207. package/dist/esm/interaction/AccessControlManager.d.ts +4 -13
  208. package/dist/esm/interaction/AccessControlManager.d.ts.map +1 -1
  209. package/dist/esm/interaction/AccessControlManager.js +39 -48
  210. package/dist/esm/interaction/AccessControlManager.js.map +1 -1
  211. package/dist/esm/interaction/InteractionClient.d.ts +5 -4
  212. package/dist/esm/interaction/InteractionClient.d.ts.map +1 -1
  213. package/dist/esm/interaction/InteractionClient.js +54 -4
  214. package/dist/esm/interaction/InteractionClient.js.map +1 -1
  215. package/dist/esm/interaction/InteractionMessenger.d.ts.map +1 -1
  216. package/dist/esm/interaction/InteractionMessenger.js +15 -0
  217. package/dist/esm/interaction/InteractionMessenger.js.map +1 -1
  218. package/dist/esm/interaction/Subscription.d.ts +3 -3
  219. package/dist/esm/interaction/Subscription.d.ts.map +1 -1
  220. package/dist/esm/interaction/Subscription.js.map +1 -1
  221. package/dist/esm/peer/PeerAddress.d.ts +1 -0
  222. package/dist/esm/peer/PeerAddress.d.ts.map +1 -1
  223. package/dist/esm/peer/PeerAddress.js +5 -0
  224. package/dist/esm/peer/PeerAddress.js.map +1 -1
  225. package/dist/esm/peer/PeerSet.d.ts.map +1 -1
  226. package/dist/esm/peer/PeerSet.js +33 -3
  227. package/dist/esm/peer/PeerSet.js.map +1 -1
  228. package/dist/esm/protocol/ChannelManager.d.ts.map +1 -1
  229. package/dist/esm/protocol/ChannelManager.js +7 -8
  230. package/dist/esm/protocol/ChannelManager.js.map +1 -1
  231. package/dist/esm/protocol/ExchangeManager.d.ts.map +1 -1
  232. package/dist/esm/protocol/ExchangeManager.js +41 -27
  233. package/dist/esm/protocol/ExchangeManager.js.map +1 -1
  234. package/dist/esm/protocol/MessageExchange.d.ts +1 -1
  235. package/dist/esm/protocol/MessageExchange.d.ts.map +1 -1
  236. package/dist/esm/protocol/MessageExchange.js +39 -5
  237. package/dist/esm/protocol/MessageExchange.js.map +1 -1
  238. package/dist/esm/protocol/MessageReceptionState.d.ts +1 -1
  239. package/dist/esm/securechannel/SecureChannelProtocol.js +2 -2
  240. package/dist/esm/securechannel/SecureChannelProtocol.js.map +1 -1
  241. package/dist/esm/session/GroupSession.d.ts +56 -0
  242. package/dist/esm/session/GroupSession.d.ts.map +1 -0
  243. package/dist/esm/session/GroupSession.js +177 -0
  244. package/dist/esm/session/GroupSession.js.map +6 -0
  245. package/dist/esm/session/InsecureSession.d.ts +2 -1
  246. package/dist/esm/session/InsecureSession.d.ts.map +1 -1
  247. package/dist/esm/session/InsecureSession.js +3 -2
  248. package/dist/esm/session/InsecureSession.js.map +1 -1
  249. package/dist/esm/session/NodeSession.d.ts +88 -0
  250. package/dist/esm/session/NodeSession.d.ts.map +1 -0
  251. package/dist/esm/session/NodeSession.js +298 -0
  252. package/dist/esm/session/NodeSession.js.map +6 -0
  253. package/dist/esm/session/SecureSession.d.ts +10 -75
  254. package/dist/esm/session/SecureSession.d.ts.map +1 -1
  255. package/dist/esm/session/SecureSession.js +10 -291
  256. package/dist/esm/session/SecureSession.js.map +2 -2
  257. package/dist/esm/session/Session.d.ts +6 -5
  258. package/dist/esm/session/Session.d.ts.map +1 -1
  259. package/dist/esm/session/Session.js +12 -2
  260. package/dist/esm/session/Session.js.map +1 -1
  261. package/dist/esm/session/SessionManager.d.ts +27 -9
  262. package/dist/esm/session/SessionManager.d.ts.map +1 -1
  263. package/dist/esm/session/SessionManager.js +84 -6
  264. package/dist/esm/session/SessionManager.js.map +1 -1
  265. package/dist/esm/session/case/CaseClient.d.ts +1 -1
  266. package/dist/esm/session/case/CaseClient.js +2 -2
  267. package/dist/esm/session/case/CaseClient.js.map +1 -1
  268. package/dist/esm/session/index.d.ts +2 -0
  269. package/dist/esm/session/index.d.ts.map +1 -1
  270. package/dist/esm/session/index.js +2 -0
  271. package/dist/esm/session/index.js.map +1 -1
  272. package/dist/esm/session/pase/PaseClient.d.ts +1 -1
  273. package/package.json +6 -6
  274. package/src/action/server/AccessControl.ts +4 -7
  275. package/src/action/server/AttributeWriteResponse.ts +29 -7
  276. package/src/action/server/CommandInvokeResponse.ts +28 -7
  277. package/src/action/server/DataResponse.ts +1 -1
  278. package/src/action/server/Subject.ts +45 -0
  279. package/src/action/server/index.ts +1 -0
  280. package/src/certificate/DeviceCertification.ts +2 -2
  281. package/src/cluster/client/AttributeClient.ts +15 -3
  282. package/src/cluster/client/ClusterClient.ts +97 -4
  283. package/src/cluster/client/ClusterClientTypes.ts +45 -9
  284. package/src/cluster/client/EventClient.ts +9 -2
  285. package/src/codec/MessageCodec.ts +49 -8
  286. package/src/fabric/Fabric.ts +51 -85
  287. package/src/fabric/FabricManager.ts +11 -4
  288. package/src/groups/FabricGroupsManager.ts +164 -0
  289. package/src/groups/Groups.ts +81 -0
  290. package/src/groups/KeySets.ts +194 -0
  291. package/src/groups/MessagingState.ts +76 -0
  292. package/src/groups/index.ts +8 -0
  293. package/src/index.ts +1 -0
  294. package/src/interaction/AccessControlManager.ts +49 -81
  295. package/src/interaction/InteractionClient.ts +66 -6
  296. package/src/interaction/InteractionMessenger.ts +15 -0
  297. package/src/interaction/Subscription.ts +3 -3
  298. package/src/peer/PeerAddress.ts +4 -0
  299. package/src/peer/PeerSet.ts +39 -4
  300. package/src/protocol/ChannelManager.ts +7 -9
  301. package/src/protocol/ExchangeManager.ts +51 -35
  302. package/src/protocol/MessageExchange.ts +42 -7
  303. package/src/protocol/MessageReceptionState.ts +2 -2
  304. package/src/securechannel/SecureChannelProtocol.ts +2 -2
  305. package/src/session/GroupSession.ts +223 -0
  306. package/src/session/InsecureSession.ts +3 -2
  307. package/src/session/NodeSession.ts +367 -0
  308. package/src/session/SecureSession.ts +14 -363
  309. package/src/session/Session.ts +17 -6
  310. package/src/session/SessionManager.ts +94 -14
  311. package/src/session/case/CaseClient.ts +2 -2
  312. package/src/session/index.ts +2 -3
@@ -10,7 +10,6 @@ import {
10
10
  TlvOperationalCertificate,
11
11
  TlvRootCertificate,
12
12
  } from "#certificate/CertificateManager.js";
13
- import { GroupKeyManagement } from "#clusters/group-key-management";
14
13
  import {
15
14
  BinaryKeyPair,
16
15
  Bytes,
@@ -25,56 +24,19 @@ import {
25
24
  MatterFlowError,
26
25
  MaybePromise,
27
26
  PrivateKey,
27
+ StorageContext,
28
28
  } from "#general";
29
+ import { FabricGroupsManager, GROUP_SECURITY_INFO } from "#groups/FabricGroupsManager.js";
29
30
  import { PeerAddress } from "#peer/PeerAddress.js";
30
- import { CaseAuthenticatedTag, FabricId, FabricIndex, NodeId, TypeFromSchema, VendorId } from "#types";
31
- import { SecureSession } from "../session/SecureSession.js";
31
+ import { Session } from "#session/Session.js";
32
+ import { CaseAuthenticatedTag, FabricId, FabricIndex, GroupId, NodeId, VendorId } from "#types";
32
33
 
33
34
  const logger = Logger.get("Fabric");
34
35
 
35
36
  const COMPRESSED_FABRIC_ID_INFO = Bytes.fromString("CompressedFabric");
36
- const GROUP_SECURITY_INFO = Bytes.fromString("GroupKey v1.0");
37
37
 
38
38
  export class PublicKeyError extends MatterError {}
39
39
 
40
- type OperationalGroupKeySet = TypeFromSchema<typeof GroupKeyManagement.TlvGroupKeySet> & {
41
- operationalEpochKey0: Uint8Array;
42
- groupSessionId0: number | null;
43
- operationalEpochKey1: Uint8Array | null;
44
- groupSessionId1: number | null;
45
- operationalEpochKey2: Uint8Array | null;
46
- groupSessionId2: number | null;
47
- };
48
-
49
- namespace OperationalGroupKeySet {
50
- export const asTlvGroupSet = (
51
- operationalGroupSet: OperationalGroupKeySet,
52
- ): TypeFromSchema<typeof GroupKeyManagement.TlvGroupKeySet> => {
53
- const {
54
- groupKeySetId,
55
- epochKey0,
56
- epochStartTime0,
57
- epochKey1,
58
- epochStartTime1,
59
- epochKey2,
60
- epochStartTime2,
61
- groupKeySecurityPolicy,
62
- groupKeyMulticastPolicy,
63
- } = operationalGroupSet;
64
- return {
65
- groupKeySetId,
66
- epochKey0,
67
- epochStartTime0,
68
- epochKey1,
69
- epochStartTime1,
70
- epochKey2,
71
- epochStartTime2,
72
- groupKeySecurityPolicy,
73
- groupKeyMulticastPolicy,
74
- };
75
- };
76
- }
77
-
78
40
  export type ExposedFabricInformation = {
79
41
  fabricIndex: FabricIndex;
80
42
  fabricId: FabricId;
@@ -97,14 +59,13 @@ export class Fabric {
97
59
  readonly operationalIdentityProtectionKey: Uint8Array;
98
60
  readonly intermediateCACert: Uint8Array | undefined;
99
61
  readonly operationalCert: Uint8Array;
100
-
101
62
  readonly #keyPair: Key;
102
-
103
- readonly #sessions = new Set<SecureSession>();
104
-
63
+ readonly #sessions = new Set<Session>();
64
+ readonly #groupManager: FabricGroupsManager;
105
65
  #label: string;
106
66
  #removeCallbacks = new Array<() => MaybePromise<void>>();
107
67
  #persistCallback: ((isUpdate?: boolean) => MaybePromise<void>) | undefined;
68
+ #storage?: StorageContext;
108
69
 
109
70
  constructor(config: Fabric.Config) {
110
71
  this.fabricIndex = config.fabricIndex;
@@ -120,8 +81,8 @@ export class Fabric {
120
81
  this.intermediateCACert = config.intermediateCACert;
121
82
  this.operationalCert = config.operationalCert;
122
83
  this.#label = config.label;
123
-
124
84
  this.#keyPair = PrivateKey(config.keyPair);
85
+ this.#groupManager = new FabricGroupsManager(this);
125
86
  }
126
87
 
127
88
  get config(): Fabric.Config {
@@ -158,6 +119,19 @@ export class Fabric {
158
119
  await this.persist();
159
120
  }
160
121
 
122
+ set storage(storage: StorageContext) {
123
+ this.#storage = storage;
124
+ this.#groupManager.storage = storage;
125
+ }
126
+
127
+ get storage(): StorageContext | undefined {
128
+ return this.#storage;
129
+ }
130
+
131
+ get groups() {
132
+ return this.#groupManager;
133
+ }
134
+
161
135
  get publicKey() {
162
136
  return this.#keyPair.publicKey;
163
137
  }
@@ -190,20 +164,39 @@ export class Fabric {
190
164
  );
191
165
  }
192
166
 
193
- getDestinationId(nodeId: NodeId, random: Uint8Array) {
167
+ #generateSalt(nodeId: NodeId, random: Uint8Array) {
194
168
  const writer = new DataWriter(Endian.Little);
195
169
  writer.writeByteArray(random);
196
170
  writer.writeByteArray(this.rootPublicKey);
197
171
  writer.writeUInt64(this.fabricId);
198
172
  writer.writeUInt64(nodeId);
199
- return Crypto.hmac(this.operationalIdentityProtectionKey, writer.toByteArray());
173
+ return writer.toByteArray();
174
+ }
175
+
176
+ /**
177
+ * Returns the destination IDs for a given nodeId, random value and optional groupId.
178
+ * When groupId is provided, it returns the time-wise valid operational keys for that groupId.
179
+ */
180
+ async currentDestinationIdFor(nodeId: NodeId, random: Uint8Array) {
181
+ return await Crypto.hmac(this.groups.keySets.currentKeyForId(0).key, this.#generateSalt(nodeId, random));
182
+ }
183
+
184
+ /**
185
+ * Returns the destination IDs for a given nodeId, random value and optional groupId.
186
+ * When groupId is provided, it returns all operational keys for that groupId.
187
+ */
188
+ async destinationIdsFor(nodeId: NodeId, random: Uint8Array) {
189
+ const salt = this.#generateSalt(nodeId, random);
190
+ // Check all keys of keyset 0 - typically it is only the IPK
191
+ const destinationIds = this.groups.keySets.allKeysForId(0).map(({ key }) => Crypto.hmac(key, salt));
192
+ return await Promise.all(destinationIds);
200
193
  }
201
194
 
202
- addSession(session: SecureSession) {
195
+ addSession(session: Session) {
203
196
  this.#sessions.add(session);
204
197
  }
205
198
 
206
- removeSession(session: SecureSession) {
199
+ removeSession(session: Session) {
207
200
  this.#sessions.delete(session);
208
201
  }
209
202
 
@@ -236,39 +229,6 @@ export class Fabric {
236
229
  return this.#persistCallback?.(isUpdate);
237
230
  }
238
231
 
239
- getGroupKeySet(groupKeySetId: number) {
240
- if (groupKeySetId === 0) {
241
- return OperationalGroupKeySet.asTlvGroupSet(this.getGroupSetForIpk());
242
- }
243
- // TODO add correct group handling later, right now only IPK exists
244
- return undefined;
245
- }
246
-
247
- private getGroupSetForIpk(): OperationalGroupKeySet {
248
- return {
249
- groupKeySetId: 0,
250
- epochKey0: this.identityProtectionKey,
251
- operationalEpochKey0: this.operationalIdentityProtectionKey,
252
- epochStartTime0: 0, // or do we need to track Fabric creation date?
253
- groupSessionId0: null,
254
- epochKey1: null,
255
- operationalEpochKey1: null,
256
- epochStartTime1: null,
257
- groupSessionId1: null,
258
- epochKey2: null,
259
- operationalEpochKey2: null,
260
- epochStartTime2: null,
261
- groupSessionId2: null,
262
- groupKeySecurityPolicy: GroupKeyManagement.GroupKeySecurityPolicy.TrustFirst,
263
- groupKeyMulticastPolicy: GroupKeyManagement.GroupKeyMulticastPolicy.PerGroupId,
264
- };
265
- }
266
-
267
- getAllGroupKeySets() {
268
- // TODO add correct group handling later, right now only IPK exists
269
- return [OperationalGroupKeySet.asTlvGroupSet(this.getGroupSetForIpk())];
270
- }
271
-
272
232
  get externalInformation(): ExposedFabricInformation {
273
233
  return {
274
234
  fabricIndex: this.fabricIndex,
@@ -283,6 +243,12 @@ export class Fabric {
283
243
  addressOf(nodeId: NodeId) {
284
244
  return PeerAddress({ fabricIndex: this.fabricIndex, nodeId });
285
245
  }
246
+
247
+ groupAddressOf(groupId: GroupId) {
248
+ GroupId.assertGroupId(groupId);
249
+
250
+ return PeerAddress({ fabricIndex: this.fabricIndex, nodeId: NodeId.fromGroupId(groupId) });
251
+ }
286
252
  }
287
253
 
288
254
  export class FabricBuilder {
@@ -433,7 +399,7 @@ export class FabricBuilder {
433
399
  throw new InternalError("operationalCert needs to be set");
434
400
 
435
401
  this.#fabricIndex = fabricIndex;
436
- const saltWriter = new DataWriter(Endian.Big);
402
+ const saltWriter = new DataWriter();
437
403
  saltWriter.writeUInt64(this.#fabricId);
438
404
  const operationalId = await Crypto.hkdf(
439
405
  this.#rootPublicKey.slice(1),
@@ -167,6 +167,9 @@ export class FabricManager {
167
167
  }
168
168
  });
169
169
  };
170
+ if (this.#storage !== undefined) {
171
+ fabric.storage = this.#storage.createContext(`fabric-${fabricIndex}`);
172
+ }
170
173
  if (this.#initializationDone) {
171
174
  this.#events.added.emit(fabric);
172
175
  }
@@ -182,6 +185,7 @@ export class FabricManager {
182
185
  );
183
186
  this.#fabrics.delete(fabricIndex);
184
187
  await this.persistFabrics();
188
+ await fabric.storage?.clearAll();
185
189
  this.#events.deleted.emit(fabric);
186
190
  }
187
191
 
@@ -213,9 +217,10 @@ export class FabricManager {
213
217
  this.#construction.assert();
214
218
 
215
219
  for (const fabric of this.#fabrics.values()) {
216
- const candidateDestinationId = await fabric.getDestinationId(fabric.nodeId, initiatorRandom);
217
- if (!Bytes.areEqual(candidateDestinationId, destinationId)) continue;
218
- return fabric;
220
+ const candidateDestinationIds = await fabric.destinationIdsFor(fabric.nodeId, initiatorRandom);
221
+ if (candidateDestinationIds.some(candidate => Bytes.areEqual(candidate, destinationId))) {
222
+ return fabric;
223
+ }
219
224
  }
220
225
 
221
226
  throw new FabricNotFoundError();
@@ -233,7 +238,9 @@ export class FabricManager {
233
238
  }
234
239
 
235
240
  findByIndex(index: FabricIndex) {
236
- return Array.from(this.#fabrics.values()).find(fabric => fabric.fabricIndex === index);
241
+ this.#construction.assert();
242
+
243
+ return this.#fabrics.get(index);
237
244
  }
238
245
 
239
246
  async updateFabric(fabric: Fabric) {
@@ -0,0 +1,164 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2022-2025 Matter.js Authors
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { Fabric } from "#fabric/Fabric.js";
7
+ import { BasicMap, Bytes, Crypto, InternalError, MatterFlowError, StorageContext } from "#general";
8
+ import { GroupKeySet, KeySets, OperationalKeySet } from "#groups/KeySets.js";
9
+ import { MessagingState } from "#groups/MessagingState.js";
10
+ import { GroupId } from "#types";
11
+ import { Groups } from "./Groups.js";
12
+
13
+ export const GROUP_SECURITY_INFO = Bytes.fromString("GroupKey v1.0");
14
+
15
+ /**
16
+ * Class that contains an operational view on the Group Keys for a fabric
17
+ */
18
+ export class FabricGroupsManager {
19
+ #fabric: Fabric;
20
+ #groups: Groups;
21
+ #messagingState: MessagingState;
22
+
23
+ /** Operationally enhanced variants of the group key sets based on their ID. */
24
+ #keySets = new KeySets();
25
+
26
+ constructor(fabric: Fabric, storage?: StorageContext) {
27
+ this.#fabric = fabric;
28
+ this.#groups = new Groups(fabric, this.#keySets);
29
+ this.#messagingState = new MessagingState(storage);
30
+
31
+ // KeySet with ID 0 is always the Fabric IPK, so we initialize from there because this is not stored
32
+ // in Key Management Cluster
33
+ this.#keySets.add({
34
+ groupKeySetId: 0,
35
+ epochKey0: fabric.identityProtectionKey,
36
+ operationalEpochKey0: fabric.operationalIdentityProtectionKey,
37
+ epochStartTime0: 0, // 0 is always ok, but only for the IPK key
38
+ groupSessionId0: null,
39
+ epochKey1: null,
40
+ operationalEpochKey1: null,
41
+ epochStartTime1: null,
42
+ groupSessionId1: null,
43
+ epochKey2: null,
44
+ operationalEpochKey2: null,
45
+ epochStartTime2: null,
46
+ groupSessionId2: null,
47
+ groupKeySecurityPolicy: 0, // GroupKeyManagement.GroupKeySecurityPolicy.TrustFirst, the other option is provisional
48
+ groupKeyMulticastPolicy: 0, // GroupKeyManagement.GroupKeyMulticastPolicy.PerGroupId, provisional!
49
+ });
50
+ if (storage !== undefined) {
51
+ this.storage = storage;
52
+ }
53
+ }
54
+
55
+ set storage(storage: StorageContext) {
56
+ this.#messagingState.storage = storage;
57
+ }
58
+
59
+ /** Operative lookup of the group key sets by their id. */
60
+ get keySets(): KeySets<OperationalKeySet> {
61
+ return this.#keySets;
62
+ }
63
+
64
+ get messaging(): MessagingState {
65
+ return this.#messagingState;
66
+ }
67
+
68
+ /** Operative lookup of the group key set id and the key by a group session Id. */
69
+ get sessions() {
70
+ return this.#keySets.sessions;
71
+ }
72
+
73
+ get groupKeyIdMap(): BasicMap<GroupId, number> {
74
+ return this.#groups.idMap;
75
+ }
76
+
77
+ set groupKeyIdMap(map: Map<GroupId, number>) {
78
+ this.#groups.idMap = map;
79
+ }
80
+
81
+ get endpoints() {
82
+ return this.#groups.endpointMap;
83
+ }
84
+
85
+ currentKeyForGroup(groupId: GroupId) {
86
+ return this.#groups.currentKeyForId(groupId);
87
+ }
88
+
89
+ subjectForGroup(id: GroupId, keySetId: number) {
90
+ return this.#groups.subjectForGroup(id, keySetId);
91
+ }
92
+
93
+ multicastAddressFor(groupId: GroupId): string {
94
+ return this.#groups.multicastAddress(groupId);
95
+ }
96
+
97
+ /*
98
+ TODO for Controller to generate new epochs
99
+ addGroupEpoch(groupKeySetId: number, startTimeMs = Time.nowMs()) {
100
+ // TODO for Controller to generate new epochs
101
+ const epochKey = Crypto.getRandomData(CRYPTO_SYMMETRIC_KEY_LENGTH);
102
+ const operationalEpochKey = Crypto.hkdf(epochKey, this.#fabric.operationalId, GROUP_SECURITY_INFO);
103
+ const epochStartTime = startTimeMs * 1000;
104
+ logger.debug(`addGroupEpoch: epochStartTime=${epochStartTime}`, operationalEpochKey);
105
+ // TODO extend in structure and such
106
+ }
107
+ */
108
+
109
+ /**
110
+ * Sets new group key set data and pre-calculates all operative data like session ids and operational keys.
111
+ * Overwriting the existing one if it exists.
112
+ */
113
+ async setFromGroupKeySet(groupKeySet: GroupKeySet) {
114
+ const { groupKeySetId, epochKey0, epochKey1, epochKey2 } = groupKeySet;
115
+
116
+ if (epochKey0 === null) {
117
+ throw new MatterFlowError("EpochKey0 must be set"); // checked before, but to make typing happy
118
+ }
119
+
120
+ // Clean up the counters and data from old keys, will be initialized again on next use
121
+ await this.#cleanUpCounters(groupKeySetId);
122
+
123
+ // Lets pre-calculate the operational keys
124
+ const operationalId = this.#fabric.operationalId;
125
+ const operationalEpochKey0 = await Crypto.hkdf(epochKey0, operationalId, GROUP_SECURITY_INFO);
126
+ const operationalEpochKey1 =
127
+ epochKey1 !== null ? await Crypto.hkdf(epochKey1, operationalId, GROUP_SECURITY_INFO) : null;
128
+ const operationalEpochKey2 =
129
+ epochKey2 !== null ? await Crypto.hkdf(epochKey2, operationalId, GROUP_SECURITY_INFO) : null;
130
+ this.#keySets.add({
131
+ ...groupKeySet,
132
+ operationalEpochKey0,
133
+ groupSessionId0: await this.#keySets.sessionIdFromKey(operationalEpochKey0),
134
+ operationalEpochKey1,
135
+ groupSessionId1:
136
+ operationalEpochKey1 !== null ? await this.#keySets.sessionIdFromKey(operationalEpochKey1) : null,
137
+ operationalEpochKey2,
138
+ groupSessionId2:
139
+ operationalEpochKey2 !== null ? await this.#keySets.sessionIdFromKey(operationalEpochKey2) : null,
140
+ });
141
+ }
142
+
143
+ /** Removes a group key set by its id and cleans up the counters and data. */
144
+ async removeGroupKeySet(groupKeySetId: number) {
145
+ if (groupKeySetId === 0) {
146
+ throw new InternalError("Cannot remove the group key set 0.");
147
+ }
148
+ await this.#cleanUpCounters(groupKeySetId, true);
149
+ return this.#keySets.delete("groupKeySetId", groupKeySetId);
150
+ }
151
+
152
+ /** Cleans up the counters and data for a group key set by its id. */
153
+ async #cleanUpCounters(groupKeySetId: number, forDelete = false) {
154
+ if (this.#keySets.forId(groupKeySetId) === undefined) {
155
+ return;
156
+ }
157
+
158
+ // Clean up counters for the group key set
159
+ const operationalKeys = this.#keySets.allKeysForId(groupKeySetId);
160
+ for (const { key } of operationalKeys) {
161
+ await this.#messagingState.removeCounter(key, forDelete);
162
+ }
163
+ }
164
+ }
@@ -0,0 +1,81 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2022-2025 Matter.js Authors
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { Subject } from "#action/index.js";
7
+ import { Fabric } from "#fabric/Fabric.js";
8
+ import { BasicMap, DataWriter, ImplementationError, ipv6BytesToString } from "#general";
9
+ import { EndpointNumber, GroupId } from "#types";
10
+ import { KeySets, OperationalKeySet } from "./KeySets.js";
11
+
12
+ export class Groups {
13
+ #fabric: Fabric;
14
+ #keySets: KeySets<OperationalKeySet>;
15
+
16
+ /** Operational variant of the group key map attribute from Group Key Management cluster, maps group Ids to key sets. */
17
+ readonly #groupKeyIdMap = new BasicMap<GroupId, number>();
18
+
19
+ /** Operational variant of the group table, maps group Ids to a list of enabled endpoints. */
20
+ readonly endpointMap = new Map<GroupId, EndpointNumber[]>();
21
+
22
+ constructor(fabric: Fabric, keySets: KeySets<OperationalKeySet>) {
23
+ this.#fabric = fabric;
24
+ this.#keySets = keySets;
25
+ }
26
+
27
+ /** Operative lookup of the group key sets by a group id and to react on added removed groups. */
28
+ get idMap(): BasicMap<GroupId, number> {
29
+ return this.#groupKeyIdMap;
30
+ }
31
+
32
+ /** Updates the group key id map when changed in Group Key Management Cluster. Only changes are taken over. */
33
+ set idMap(map: Map<GroupId, number>) {
34
+ for (const [groupId, keySetId] of map.entries()) {
35
+ this.#groupKeyIdMap.set(groupId, keySetId);
36
+ }
37
+ for (const groupId of this.#groupKeyIdMap.keys()) {
38
+ if (!map.has(groupId)) {
39
+ // If the groupId is not in the new map, we remove it from the groupKeyIdMap
40
+ this.#groupKeyIdMap.delete(groupId);
41
+ }
42
+ }
43
+ }
44
+
45
+ subjectForGroup(id: GroupId, keySetId: number) {
46
+ return Subject.Group({
47
+ id,
48
+ hasValidMapping: this.idMap.get(id) === keySetId,
49
+ endpoints: this.endpointMap.get(id) ?? [],
50
+ });
51
+ }
52
+
53
+ /** Returns the multicast address for a given group id for this fabric. */
54
+ multicastAddress(groupId: GroupId) {
55
+ GroupId.assertGroupId(groupId);
56
+
57
+ // If GroupKeyMulticastPolicy ever becomes non-provisional then we need to adjust logic here, but so far we
58
+ // just use the default which is PerGroupId, which means we use the GroupId to create the multicast address.
59
+
60
+ const writer = new DataWriter();
61
+ writer.writeUInt16(0xff35);
62
+ writer.writeUInt16(0x0040);
63
+ writer.writeUInt8(0xfd);
64
+ writer.writeUInt64(this.#fabric.fabricId);
65
+ writer.writeUInt8(0x00);
66
+ writer.writeUInt16(GroupId(groupId));
67
+ return ipv6BytesToString(writer.toByteArray());
68
+ }
69
+
70
+ /**
71
+ * Returns the current operational group key for a given group id and returns the keys, start time and
72
+ * their session IDs.
73
+ */
74
+ currentKeyForId(groupId: GroupId) {
75
+ const keySetId = this.#groupKeyIdMap.get(groupId);
76
+ if (keySetId === undefined) {
77
+ throw new ImplementationError(`No group key set found for groupId ${groupId}.`);
78
+ }
79
+ return { ...this.#keySets.currentKeyForId(keySetId), keySetId };
80
+ }
81
+ }