@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.
- package/dist/cjs/action/server/AccessControl.d.ts +5 -7
- package/dist/cjs/action/server/AccessControl.d.ts.map +1 -1
- package/dist/cjs/action/server/AccessControl.js.map +1 -1
- package/dist/cjs/action/server/AttributeWriteResponse.d.ts.map +1 -1
- package/dist/cjs/action/server/AttributeWriteResponse.js +23 -0
- package/dist/cjs/action/server/AttributeWriteResponse.js.map +1 -1
- package/dist/cjs/action/server/CommandInvokeResponse.d.ts.map +1 -1
- package/dist/cjs/action/server/CommandInvokeResponse.js +24 -1
- package/dist/cjs/action/server/CommandInvokeResponse.js.map +1 -1
- package/dist/cjs/action/server/DataResponse.d.ts +1 -1
- package/dist/cjs/action/server/DataResponse.d.ts.map +1 -1
- package/dist/cjs/action/server/Subject.d.ts +25 -0
- package/dist/cjs/action/server/Subject.d.ts.map +1 -0
- package/dist/cjs/action/server/Subject.js +54 -0
- package/dist/cjs/action/server/Subject.js.map +6 -0
- package/dist/cjs/action/server/index.d.ts +1 -0
- package/dist/cjs/action/server/index.d.ts.map +1 -1
- package/dist/cjs/action/server/index.js +1 -0
- package/dist/cjs/action/server/index.js.map +1 -1
- package/dist/cjs/certificate/DeviceCertification.d.ts +2 -2
- package/dist/cjs/certificate/DeviceCertification.d.ts.map +1 -1
- package/dist/cjs/certificate/DeviceCertification.js.map +1 -1
- package/dist/cjs/cluster/client/AttributeClient.d.ts +3 -3
- package/dist/cjs/cluster/client/AttributeClient.d.ts.map +1 -1
- package/dist/cjs/cluster/client/AttributeClient.js +14 -2
- package/dist/cjs/cluster/client/AttributeClient.js.map +1 -1
- package/dist/cjs/cluster/client/ClusterClient.d.ts +3 -2
- package/dist/cjs/cluster/client/ClusterClient.d.ts.map +1 -1
- package/dist/cjs/cluster/client/ClusterClient.js +66 -1
- package/dist/cjs/cluster/client/ClusterClient.js.map +1 -1
- package/dist/cjs/cluster/client/ClusterClientTypes.d.ts +36 -8
- package/dist/cjs/cluster/client/ClusterClientTypes.d.ts.map +1 -1
- package/dist/cjs/cluster/client/EventClient.d.ts +3 -3
- package/dist/cjs/cluster/client/EventClient.d.ts.map +1 -1
- package/dist/cjs/cluster/client/EventClient.js +7 -0
- package/dist/cjs/cluster/client/EventClient.js.map +1 -1
- package/dist/cjs/codec/MessageCodec.d.ts.map +1 -1
- package/dist/cjs/codec/MessageCodec.js +31 -6
- package/dist/cjs/codec/MessageCodec.js.map +1 -1
- package/dist/cjs/fabric/Fabric.d.ts +20 -30
- package/dist/cjs/fabric/Fabric.d.ts.map +1 -1
- package/dist/cjs/fabric/Fabric.js +38 -62
- package/dist/cjs/fabric/Fabric.js.map +2 -2
- package/dist/cjs/fabric/FabricManager.d.ts.map +1 -1
- package/dist/cjs/fabric/FabricManager.js +10 -4
- package/dist/cjs/fabric/FabricManager.js.map +1 -1
- package/dist/cjs/groups/FabricGroupsManager.d.ts +46 -0
- package/dist/cjs/groups/FabricGroupsManager.d.ts.map +1 -0
- package/dist/cjs/groups/FabricGroupsManager.js +155 -0
- package/dist/cjs/groups/FabricGroupsManager.js.map +6 -0
- package/dist/cjs/groups/Groups.d.ts +34 -0
- package/dist/cjs/groups/Groups.d.ts.map +1 -0
- package/dist/cjs/groups/Groups.js +89 -0
- package/dist/cjs/groups/Groups.js.map +6 -0
- package/dist/cjs/groups/KeySets.d.ts +64 -0
- package/dist/cjs/groups/KeySets.d.ts.map +1 -0
- package/dist/cjs/groups/KeySets.js +179 -0
- package/dist/cjs/groups/KeySets.js.map +6 -0
- package/dist/cjs/groups/MessagingState.d.ts +24 -0
- package/dist/cjs/groups/MessagingState.d.ts.map +1 -0
- package/dist/cjs/groups/MessagingState.js +91 -0
- package/dist/cjs/groups/MessagingState.js.map +6 -0
- package/dist/cjs/groups/index.d.ts +8 -0
- package/dist/cjs/groups/index.d.ts.map +1 -0
- package/dist/cjs/groups/index.js +25 -0
- package/dist/cjs/groups/index.js.map +6 -0
- package/dist/cjs/index.d.ts +1 -0
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +1 -0
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/interaction/AccessControlManager.d.ts +4 -13
- package/dist/cjs/interaction/AccessControlManager.d.ts.map +1 -1
- package/dist/cjs/interaction/AccessControlManager.js +38 -47
- package/dist/cjs/interaction/AccessControlManager.js.map +1 -1
- package/dist/cjs/interaction/InteractionClient.d.ts +5 -4
- package/dist/cjs/interaction/InteractionClient.d.ts.map +1 -1
- package/dist/cjs/interaction/InteractionClient.js +53 -3
- package/dist/cjs/interaction/InteractionClient.js.map +1 -1
- package/dist/cjs/interaction/InteractionMessenger.d.ts.map +1 -1
- package/dist/cjs/interaction/InteractionMessenger.js +15 -0
- package/dist/cjs/interaction/InteractionMessenger.js.map +1 -1
- package/dist/cjs/interaction/Subscription.d.ts +3 -3
- package/dist/cjs/interaction/Subscription.d.ts.map +1 -1
- package/dist/cjs/interaction/Subscription.js.map +1 -1
- package/dist/cjs/peer/PeerAddress.d.ts +1 -0
- package/dist/cjs/peer/PeerAddress.d.ts.map +1 -1
- package/dist/cjs/peer/PeerAddress.js +5 -0
- package/dist/cjs/peer/PeerAddress.js.map +1 -1
- package/dist/cjs/peer/PeerSet.d.ts.map +1 -1
- package/dist/cjs/peer/PeerSet.js +31 -2
- package/dist/cjs/peer/PeerSet.js.map +1 -1
- package/dist/cjs/protocol/ChannelManager.d.ts.map +1 -1
- package/dist/cjs/protocol/ChannelManager.js +7 -8
- package/dist/cjs/protocol/ChannelManager.js.map +1 -1
- package/dist/cjs/protocol/ExchangeManager.d.ts.map +1 -1
- package/dist/cjs/protocol/ExchangeManager.js +39 -25
- package/dist/cjs/protocol/ExchangeManager.js.map +1 -1
- package/dist/cjs/protocol/MessageExchange.d.ts +1 -1
- package/dist/cjs/protocol/MessageExchange.d.ts.map +1 -1
- package/dist/cjs/protocol/MessageExchange.js +32 -4
- package/dist/cjs/protocol/MessageExchange.js.map +1 -1
- package/dist/cjs/protocol/MessageReceptionState.d.ts +1 -1
- package/dist/cjs/securechannel/SecureChannelProtocol.js +1 -1
- package/dist/cjs/securechannel/SecureChannelProtocol.js.map +1 -1
- package/dist/cjs/session/GroupSession.d.ts +56 -0
- package/dist/cjs/session/GroupSession.d.ts.map +1 -0
- package/dist/cjs/session/GroupSession.js +188 -0
- package/dist/cjs/session/GroupSession.js.map +6 -0
- package/dist/cjs/session/InsecureSession.d.ts +2 -1
- package/dist/cjs/session/InsecureSession.d.ts.map +1 -1
- package/dist/cjs/session/InsecureSession.js +3 -2
- package/dist/cjs/session/InsecureSession.js.map +1 -1
- package/dist/cjs/session/NodeSession.d.ts +88 -0
- package/dist/cjs/session/NodeSession.d.ts.map +1 -0
- package/dist/cjs/session/NodeSession.js +318 -0
- package/dist/cjs/session/NodeSession.js.map +6 -0
- package/dist/cjs/session/SecureSession.d.ts +10 -75
- package/dist/cjs/session/SecureSession.d.ts.map +1 -1
- package/dist/cjs/session/SecureSession.js +9 -280
- package/dist/cjs/session/SecureSession.js.map +2 -2
- package/dist/cjs/session/Session.d.ts +6 -5
- package/dist/cjs/session/Session.d.ts.map +1 -1
- package/dist/cjs/session/Session.js +11 -1
- package/dist/cjs/session/Session.js.map +1 -1
- package/dist/cjs/session/SessionManager.d.ts +27 -9
- package/dist/cjs/session/SessionManager.d.ts.map +1 -1
- package/dist/cjs/session/SessionManager.js +83 -5
- package/dist/cjs/session/SessionManager.js.map +2 -2
- package/dist/cjs/session/case/CaseClient.d.ts +1 -1
- package/dist/cjs/session/case/CaseClient.js +2 -2
- package/dist/cjs/session/case/CaseClient.js.map +1 -1
- package/dist/cjs/session/index.d.ts +2 -0
- package/dist/cjs/session/index.d.ts.map +1 -1
- package/dist/cjs/session/index.js +2 -0
- package/dist/cjs/session/index.js.map +1 -1
- package/dist/cjs/session/pase/PaseClient.d.ts +1 -1
- package/dist/esm/action/server/AccessControl.d.ts +5 -7
- package/dist/esm/action/server/AccessControl.d.ts.map +1 -1
- package/dist/esm/action/server/AccessControl.js.map +1 -1
- package/dist/esm/action/server/AttributeWriteResponse.d.ts.map +1 -1
- package/dist/esm/action/server/AttributeWriteResponse.js +23 -0
- package/dist/esm/action/server/AttributeWriteResponse.js.map +1 -1
- package/dist/esm/action/server/CommandInvokeResponse.d.ts.map +1 -1
- package/dist/esm/action/server/CommandInvokeResponse.js +24 -1
- package/dist/esm/action/server/CommandInvokeResponse.js.map +1 -1
- package/dist/esm/action/server/DataResponse.d.ts +1 -1
- package/dist/esm/action/server/DataResponse.d.ts.map +1 -1
- package/dist/esm/action/server/Subject.d.ts +25 -0
- package/dist/esm/action/server/Subject.d.ts.map +1 -0
- package/dist/esm/action/server/Subject.js +34 -0
- package/dist/esm/action/server/Subject.js.map +6 -0
- package/dist/esm/action/server/index.d.ts +1 -0
- package/dist/esm/action/server/index.d.ts.map +1 -1
- package/dist/esm/action/server/index.js +1 -0
- package/dist/esm/action/server/index.js.map +1 -1
- package/dist/esm/certificate/DeviceCertification.d.ts +2 -2
- package/dist/esm/certificate/DeviceCertification.d.ts.map +1 -1
- package/dist/esm/certificate/DeviceCertification.js.map +1 -1
- package/dist/esm/cluster/client/AttributeClient.d.ts +3 -3
- package/dist/esm/cluster/client/AttributeClient.d.ts.map +1 -1
- package/dist/esm/cluster/client/AttributeClient.js +13 -1
- package/dist/esm/cluster/client/AttributeClient.js.map +1 -1
- package/dist/esm/cluster/client/ClusterClient.d.ts +3 -2
- package/dist/esm/cluster/client/ClusterClient.d.ts.map +1 -1
- package/dist/esm/cluster/client/ClusterClient.js +67 -2
- package/dist/esm/cluster/client/ClusterClient.js.map +1 -1
- package/dist/esm/cluster/client/ClusterClientTypes.d.ts +36 -8
- package/dist/esm/cluster/client/ClusterClientTypes.d.ts.map +1 -1
- package/dist/esm/cluster/client/EventClient.d.ts +3 -3
- package/dist/esm/cluster/client/EventClient.d.ts.map +1 -1
- package/dist/esm/cluster/client/EventClient.js +7 -0
- package/dist/esm/cluster/client/EventClient.js.map +1 -1
- package/dist/esm/codec/MessageCodec.d.ts.map +1 -1
- package/dist/esm/codec/MessageCodec.js +41 -7
- package/dist/esm/codec/MessageCodec.js.map +1 -1
- package/dist/esm/fabric/Fabric.d.ts +20 -30
- package/dist/esm/fabric/Fabric.d.ts.map +1 -1
- package/dist/esm/fabric/Fabric.js +38 -62
- package/dist/esm/fabric/Fabric.js.map +2 -2
- package/dist/esm/fabric/FabricManager.d.ts.map +1 -1
- package/dist/esm/fabric/FabricManager.js +10 -4
- package/dist/esm/fabric/FabricManager.js.map +1 -1
- package/dist/esm/groups/FabricGroupsManager.d.ts +46 -0
- package/dist/esm/groups/FabricGroupsManager.d.ts.map +1 -0
- package/dist/esm/groups/FabricGroupsManager.js +135 -0
- package/dist/esm/groups/FabricGroupsManager.js.map +6 -0
- package/dist/esm/groups/Groups.d.ts +34 -0
- package/dist/esm/groups/Groups.d.ts.map +1 -0
- package/dist/esm/groups/Groups.js +69 -0
- package/dist/esm/groups/Groups.js.map +6 -0
- package/dist/esm/groups/KeySets.d.ts +64 -0
- package/dist/esm/groups/KeySets.d.ts.map +1 -0
- package/dist/esm/groups/KeySets.js +159 -0
- package/dist/esm/groups/KeySets.js.map +6 -0
- package/dist/esm/groups/MessagingState.d.ts +24 -0
- package/dist/esm/groups/MessagingState.d.ts.map +1 -0
- package/dist/esm/groups/MessagingState.js +71 -0
- package/dist/esm/groups/MessagingState.js.map +6 -0
- package/dist/esm/groups/index.d.ts +8 -0
- package/dist/esm/groups/index.d.ts.map +1 -0
- package/dist/esm/groups/index.js +8 -0
- package/dist/esm/groups/index.js.map +6 -0
- package/dist/esm/index.d.ts +1 -0
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +1 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/interaction/AccessControlManager.d.ts +4 -13
- package/dist/esm/interaction/AccessControlManager.d.ts.map +1 -1
- package/dist/esm/interaction/AccessControlManager.js +39 -48
- package/dist/esm/interaction/AccessControlManager.js.map +1 -1
- package/dist/esm/interaction/InteractionClient.d.ts +5 -4
- package/dist/esm/interaction/InteractionClient.d.ts.map +1 -1
- package/dist/esm/interaction/InteractionClient.js +54 -4
- package/dist/esm/interaction/InteractionClient.js.map +1 -1
- package/dist/esm/interaction/InteractionMessenger.d.ts.map +1 -1
- package/dist/esm/interaction/InteractionMessenger.js +15 -0
- package/dist/esm/interaction/InteractionMessenger.js.map +1 -1
- package/dist/esm/interaction/Subscription.d.ts +3 -3
- package/dist/esm/interaction/Subscription.d.ts.map +1 -1
- package/dist/esm/interaction/Subscription.js.map +1 -1
- package/dist/esm/peer/PeerAddress.d.ts +1 -0
- package/dist/esm/peer/PeerAddress.d.ts.map +1 -1
- package/dist/esm/peer/PeerAddress.js +5 -0
- package/dist/esm/peer/PeerAddress.js.map +1 -1
- package/dist/esm/peer/PeerSet.d.ts.map +1 -1
- package/dist/esm/peer/PeerSet.js +33 -3
- package/dist/esm/peer/PeerSet.js.map +1 -1
- package/dist/esm/protocol/ChannelManager.d.ts.map +1 -1
- package/dist/esm/protocol/ChannelManager.js +7 -8
- package/dist/esm/protocol/ChannelManager.js.map +1 -1
- package/dist/esm/protocol/ExchangeManager.d.ts.map +1 -1
- package/dist/esm/protocol/ExchangeManager.js +41 -27
- package/dist/esm/protocol/ExchangeManager.js.map +1 -1
- package/dist/esm/protocol/MessageExchange.d.ts +1 -1
- package/dist/esm/protocol/MessageExchange.d.ts.map +1 -1
- package/dist/esm/protocol/MessageExchange.js +39 -5
- package/dist/esm/protocol/MessageExchange.js.map +1 -1
- package/dist/esm/protocol/MessageReceptionState.d.ts +1 -1
- package/dist/esm/securechannel/SecureChannelProtocol.js +2 -2
- package/dist/esm/securechannel/SecureChannelProtocol.js.map +1 -1
- package/dist/esm/session/GroupSession.d.ts +56 -0
- package/dist/esm/session/GroupSession.d.ts.map +1 -0
- package/dist/esm/session/GroupSession.js +177 -0
- package/dist/esm/session/GroupSession.js.map +6 -0
- package/dist/esm/session/InsecureSession.d.ts +2 -1
- package/dist/esm/session/InsecureSession.d.ts.map +1 -1
- package/dist/esm/session/InsecureSession.js +3 -2
- package/dist/esm/session/InsecureSession.js.map +1 -1
- package/dist/esm/session/NodeSession.d.ts +88 -0
- package/dist/esm/session/NodeSession.d.ts.map +1 -0
- package/dist/esm/session/NodeSession.js +298 -0
- package/dist/esm/session/NodeSession.js.map +6 -0
- package/dist/esm/session/SecureSession.d.ts +10 -75
- package/dist/esm/session/SecureSession.d.ts.map +1 -1
- package/dist/esm/session/SecureSession.js +10 -291
- package/dist/esm/session/SecureSession.js.map +2 -2
- package/dist/esm/session/Session.d.ts +6 -5
- package/dist/esm/session/Session.d.ts.map +1 -1
- package/dist/esm/session/Session.js +12 -2
- package/dist/esm/session/Session.js.map +1 -1
- package/dist/esm/session/SessionManager.d.ts +27 -9
- package/dist/esm/session/SessionManager.d.ts.map +1 -1
- package/dist/esm/session/SessionManager.js +84 -6
- package/dist/esm/session/SessionManager.js.map +1 -1
- package/dist/esm/session/case/CaseClient.d.ts +1 -1
- package/dist/esm/session/case/CaseClient.js +2 -2
- package/dist/esm/session/case/CaseClient.js.map +1 -1
- package/dist/esm/session/index.d.ts +2 -0
- package/dist/esm/session/index.d.ts.map +1 -1
- package/dist/esm/session/index.js +2 -0
- package/dist/esm/session/index.js.map +1 -1
- package/dist/esm/session/pase/PaseClient.d.ts +1 -1
- package/package.json +6 -6
- package/src/action/server/AccessControl.ts +4 -7
- package/src/action/server/AttributeWriteResponse.ts +29 -7
- package/src/action/server/CommandInvokeResponse.ts +28 -7
- package/src/action/server/DataResponse.ts +1 -1
- package/src/action/server/Subject.ts +45 -0
- package/src/action/server/index.ts +1 -0
- package/src/certificate/DeviceCertification.ts +2 -2
- package/src/cluster/client/AttributeClient.ts +15 -3
- package/src/cluster/client/ClusterClient.ts +97 -4
- package/src/cluster/client/ClusterClientTypes.ts +45 -9
- package/src/cluster/client/EventClient.ts +9 -2
- package/src/codec/MessageCodec.ts +49 -8
- package/src/fabric/Fabric.ts +51 -85
- package/src/fabric/FabricManager.ts +11 -4
- package/src/groups/FabricGroupsManager.ts +164 -0
- package/src/groups/Groups.ts +81 -0
- package/src/groups/KeySets.ts +194 -0
- package/src/groups/MessagingState.ts +76 -0
- package/src/groups/index.ts +8 -0
- package/src/index.ts +1 -0
- package/src/interaction/AccessControlManager.ts +49 -81
- package/src/interaction/InteractionClient.ts +66 -6
- package/src/interaction/InteractionMessenger.ts +15 -0
- package/src/interaction/Subscription.ts +3 -3
- package/src/peer/PeerAddress.ts +4 -0
- package/src/peer/PeerSet.ts +39 -4
- package/src/protocol/ChannelManager.ts +7 -9
- package/src/protocol/ExchangeManager.ts +51 -35
- package/src/protocol/MessageExchange.ts +42 -7
- package/src/protocol/MessageReceptionState.ts +2 -2
- package/src/securechannel/SecureChannelProtocol.ts +2 -2
- package/src/session/GroupSession.ts +223 -0
- package/src/session/InsecureSession.ts +3 -2
- package/src/session/NodeSession.ts +367 -0
- package/src/session/SecureSession.ts +14 -363
- package/src/session/Session.ts +17 -6
- package/src/session/SessionManager.ts +94 -14
- package/src/session/case/CaseClient.ts +2 -2
- package/src/session/index.ts +2 -3
package/src/fabric/Fabric.ts
CHANGED
|
@@ -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 {
|
|
31
|
-
import {
|
|
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 #
|
|
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
|
-
|
|
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
|
|
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:
|
|
195
|
+
addSession(session: Session) {
|
|
203
196
|
this.#sessions.add(session);
|
|
204
197
|
}
|
|
205
198
|
|
|
206
|
-
removeSession(session:
|
|
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(
|
|
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
|
|
217
|
-
if (
|
|
218
|
-
|
|
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
|
-
|
|
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
|
+
}
|