@matter/protocol 0.14.0 → 0.14.1-alpha.0-20250606-a9bcd03f9
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 +60 -1
- package/dist/cjs/cluster/client/ClusterClient.js.map +1 -1
- package/dist/cjs/cluster/client/ClusterClientTypes.d.ts +33 -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 +61 -2
- package/dist/esm/cluster/client/ClusterClient.js.map +1 -1
- package/dist/esm/cluster/client/ClusterClientTypes.d.ts +33 -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 +90 -4
- package/src/cluster/client/ClusterClientTypes.ts +38 -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
|
@@ -3,371 +3,22 @@
|
|
|
3
3
|
* Copyright 2022-2025 Matter.js Authors
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
|
-
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
MatterFlowError,
|
|
17
|
-
} from "#general";
|
|
18
|
-
import { Subscription } from "#interaction/Subscription.js";
|
|
19
|
-
import { PeerAddress } from "#peer/PeerAddress.js";
|
|
20
|
-
import { CaseAuthenticatedTag, FabricIndex, NodeId, StatusCode, StatusResponseError } from "#types";
|
|
21
|
-
import { DecodedMessage, DecodedPacket, Message, MessageCodec, Packet } from "../codec/MessageCodec.js";
|
|
22
|
-
import { Fabric } from "../fabric/Fabric.js";
|
|
23
|
-
import { NoChannelError } from "../protocol/ChannelManager.js";
|
|
24
|
-
import { MessageCounter } from "../protocol/MessageCounter.js";
|
|
25
|
-
import { MessageReceptionStateEncryptedWithoutRollover } from "../protocol/MessageReceptionState.js";
|
|
26
|
-
import { Session, SessionParameterOptions } from "./Session.js";
|
|
27
|
-
import { type SessionManager } from "./SessionManager.js";
|
|
28
|
-
|
|
29
|
-
const logger = Logger.get("SecureSession");
|
|
30
|
-
|
|
31
|
-
const SESSION_KEYS_INFO = Bytes.fromString("SessionKeys");
|
|
32
|
-
const SESSION_RESUMPTION_KEYS_INFO = Bytes.fromString("SessionResumptionKeys");
|
|
33
|
-
|
|
34
|
-
export class NoAssociatedFabricError extends StatusResponseError {
|
|
35
|
-
constructor(message: string) {
|
|
36
|
-
super(message, StatusCode.UnsupportedAccess);
|
|
37
|
-
}
|
|
6
|
+
import { Subject } from "#action/server/Subject.js";
|
|
7
|
+
import { Message } from "#codec/MessageCodec.js";
|
|
8
|
+
import { Fabric } from "#fabric/Fabric.js";
|
|
9
|
+
import { MatterFlowError } from "#general";
|
|
10
|
+
import { Session } from "./Session.js";
|
|
11
|
+
|
|
12
|
+
export abstract class SecureSession extends Session {
|
|
13
|
+
readonly isSecure = true;
|
|
14
|
+
abstract fabric: Fabric | undefined;
|
|
15
|
+
abstract subjectFor(message?: Message): Subject;
|
|
38
16
|
}
|
|
39
17
|
|
|
40
|
-
export
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
readonly #id: number;
|
|
45
|
-
readonly #isInitiator: boolean;
|
|
46
|
-
#fabric: Fabric | undefined;
|
|
47
|
-
readonly #peerNodeId: NodeId;
|
|
48
|
-
readonly #peerSessionId: number;
|
|
49
|
-
readonly #decryptKey: Uint8Array;
|
|
50
|
-
readonly #encryptKey: Uint8Array;
|
|
51
|
-
readonly #attestationKey: Uint8Array;
|
|
52
|
-
#caseAuthenticatedTags: CaseAuthenticatedTag[];
|
|
53
|
-
#isClosing = false;
|
|
54
|
-
readonly supportsMRP = true;
|
|
55
|
-
|
|
56
|
-
static async create(args: {
|
|
57
|
-
manager?: SessionManager;
|
|
58
|
-
id: number;
|
|
59
|
-
fabric: Fabric | undefined;
|
|
60
|
-
peerNodeId: NodeId;
|
|
61
|
-
peerSessionId: number;
|
|
62
|
-
sharedSecret: Uint8Array;
|
|
63
|
-
salt: Uint8Array;
|
|
64
|
-
isInitiator: boolean;
|
|
65
|
-
isResumption: boolean;
|
|
66
|
-
peerSessionParameters?: SessionParameterOptions;
|
|
67
|
-
caseAuthenticatedTags?: CaseAuthenticatedTag[];
|
|
68
|
-
}) {
|
|
69
|
-
const {
|
|
70
|
-
manager,
|
|
71
|
-
id,
|
|
72
|
-
fabric,
|
|
73
|
-
peerNodeId,
|
|
74
|
-
peerSessionId,
|
|
75
|
-
sharedSecret,
|
|
76
|
-
salt,
|
|
77
|
-
isInitiator,
|
|
78
|
-
isResumption,
|
|
79
|
-
peerSessionParameters,
|
|
80
|
-
caseAuthenticatedTags,
|
|
81
|
-
} = args;
|
|
82
|
-
const keys = await Crypto.hkdf(
|
|
83
|
-
sharedSecret,
|
|
84
|
-
salt,
|
|
85
|
-
isResumption ? SESSION_RESUMPTION_KEYS_INFO : SESSION_KEYS_INFO,
|
|
86
|
-
CRYPTO_SYMMETRIC_KEY_LENGTH * 3,
|
|
87
|
-
);
|
|
88
|
-
const decryptKey = isInitiator ? keys.slice(16, 32) : keys.slice(0, 16);
|
|
89
|
-
const encryptKey = isInitiator ? keys.slice(0, 16) : keys.slice(16, 32);
|
|
90
|
-
const attestationKey = keys.slice(32, 48);
|
|
91
|
-
return new SecureSession({
|
|
92
|
-
manager,
|
|
93
|
-
id,
|
|
94
|
-
fabric,
|
|
95
|
-
peerNodeId,
|
|
96
|
-
peerSessionId,
|
|
97
|
-
decryptKey,
|
|
98
|
-
encryptKey,
|
|
99
|
-
attestationKey,
|
|
100
|
-
sessionParameters: peerSessionParameters,
|
|
101
|
-
isInitiator,
|
|
102
|
-
caseAuthenticatedTags,
|
|
103
|
-
});
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
constructor(args: {
|
|
107
|
-
manager?: SessionManager;
|
|
108
|
-
id: number;
|
|
109
|
-
fabric: Fabric | undefined;
|
|
110
|
-
peerNodeId: NodeId;
|
|
111
|
-
peerSessionId: number;
|
|
112
|
-
decryptKey: Uint8Array;
|
|
113
|
-
encryptKey: Uint8Array;
|
|
114
|
-
attestationKey: Uint8Array;
|
|
115
|
-
sessionParameters?: SessionParameterOptions;
|
|
116
|
-
caseAuthenticatedTags?: CaseAuthenticatedTag[];
|
|
117
|
-
isInitiator: boolean;
|
|
118
|
-
}) {
|
|
119
|
-
super({
|
|
120
|
-
...args,
|
|
121
|
-
setActiveTimestamp: true, // We always set the active timestamp for Secure sessions
|
|
122
|
-
// Can be changed to a PersistedMessageCounter if we implement session storage
|
|
123
|
-
messageCounter: new MessageCounter(() => {
|
|
124
|
-
// Secure Session Message Counter
|
|
125
|
-
// Expire/End the session before the counter rolls over
|
|
126
|
-
this.end(true, true).catch(error => logger.error(`Error while closing session: ${error}`));
|
|
127
|
-
}),
|
|
128
|
-
messageReceptionState: new MessageReceptionStateEncryptedWithoutRollover(),
|
|
129
|
-
});
|
|
130
|
-
const {
|
|
131
|
-
manager,
|
|
132
|
-
id,
|
|
133
|
-
fabric,
|
|
134
|
-
peerNodeId,
|
|
135
|
-
peerSessionId,
|
|
136
|
-
decryptKey,
|
|
137
|
-
encryptKey,
|
|
138
|
-
attestationKey,
|
|
139
|
-
caseAuthenticatedTags,
|
|
140
|
-
isInitiator,
|
|
141
|
-
} = args;
|
|
142
|
-
|
|
143
|
-
this.#id = id;
|
|
144
|
-
this.#fabric = fabric;
|
|
145
|
-
this.#peerNodeId = peerNodeId;
|
|
146
|
-
this.#peerSessionId = peerSessionId;
|
|
147
|
-
this.#decryptKey = decryptKey;
|
|
148
|
-
this.#encryptKey = encryptKey;
|
|
149
|
-
this.#attestationKey = attestationKey;
|
|
150
|
-
this.#caseAuthenticatedTags = caseAuthenticatedTags ?? [];
|
|
151
|
-
this.#isInitiator = isInitiator;
|
|
152
|
-
|
|
153
|
-
manager?.sessions.add(this);
|
|
154
|
-
fabric?.addSession(this);
|
|
155
|
-
|
|
156
|
-
logger.debug(
|
|
157
|
-
`Created secure ${this.isPase ? "PASE" : "CASE"} session for fabric index ${fabric?.fabricIndex}`,
|
|
158
|
-
this.name,
|
|
159
|
-
this.parameterDiagnostics(),
|
|
160
|
-
);
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
parameterDiagnostics() {
|
|
164
|
-
return Diagnostic.dict(
|
|
165
|
-
{
|
|
166
|
-
SII: this.idleIntervalMs,
|
|
167
|
-
SAI: this.activeIntervalMs,
|
|
168
|
-
SAT: this.activeThresholdMs,
|
|
169
|
-
DMRev: this.dataModelRevision,
|
|
170
|
-
IMRev: this.interactionModelRevision,
|
|
171
|
-
spec: Diagnostic.hex(this.specificationVersion),
|
|
172
|
-
maxPaths: this.maxPathsPerInvoke,
|
|
173
|
-
CATs: this.#caseAuthenticatedTags,
|
|
174
|
-
},
|
|
175
|
-
true,
|
|
176
|
-
);
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
get caseAuthenticatedTags() {
|
|
180
|
-
return this.#caseAuthenticatedTags;
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
get closingAfterExchangeFinished() {
|
|
184
|
-
return this.#closingAfterExchangeFinished;
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
get sendCloseMessageWhenClosing() {
|
|
188
|
-
return this.#sendCloseMessageWhenClosing;
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
get isSecure(): boolean {
|
|
192
|
-
return true;
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
get isPase(): boolean {
|
|
196
|
-
return this.#peerNodeId === NodeId.UNSPECIFIED_NODE_ID;
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
get subscriptions() {
|
|
200
|
-
return this.#subscriptions;
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
get isInitiator() {
|
|
204
|
-
return this.#isInitiator;
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
get isClosing() {
|
|
208
|
-
return this.#isClosing;
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
async close(closeAfterExchangeFinished?: boolean) {
|
|
212
|
-
if (closeAfterExchangeFinished === undefined) {
|
|
213
|
-
closeAfterExchangeFinished = this.isPeerActive(); // We delay session close if the peer is actively communicating with us
|
|
214
|
-
}
|
|
215
|
-
await this.end(true, closeAfterExchangeFinished);
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
decode({ header, applicationPayload, messageExtension }: DecodedPacket, aad: Uint8Array): DecodedMessage {
|
|
219
|
-
if (header.hasMessageExtensions) {
|
|
220
|
-
logger.info(
|
|
221
|
-
`Message extensions are not supported. Ignoring ${messageExtension ? Bytes.toHex(messageExtension) : undefined}`,
|
|
222
|
-
);
|
|
223
|
-
}
|
|
224
|
-
const nonce = this.generateNonce(header.securityFlags, header.messageId, this.#peerNodeId);
|
|
225
|
-
const message = MessageCodec.decodePayload({
|
|
226
|
-
header,
|
|
227
|
-
applicationPayload: Crypto.decrypt(this.#decryptKey, applicationPayload, nonce, aad),
|
|
228
|
-
});
|
|
229
|
-
|
|
230
|
-
if (message.payloadHeader.hasSecuredExtension) {
|
|
231
|
-
logger.info(
|
|
232
|
-
`Secured extensions are not supported. Ignoring ${message.securityExtension ? Bytes.toHex(message.securityExtension) : undefined}`,
|
|
233
|
-
);
|
|
18
|
+
export namespace SecureSession {
|
|
19
|
+
export function assert(session?: Session, errorText?: string): asserts session is SecureSession {
|
|
20
|
+
if (!session?.isSecure) {
|
|
21
|
+
throw new MatterFlowError(errorText ?? "Insecure session in secure context");
|
|
234
22
|
}
|
|
235
|
-
|
|
236
|
-
return message;
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
encode(message: Message): Packet {
|
|
240
|
-
message.packetHeader.sessionId = this.#peerSessionId;
|
|
241
|
-
const { header, applicationPayload } = MessageCodec.encodePayload(message);
|
|
242
|
-
const headerBytes = MessageCodec.encodePacketHeader(message.packetHeader);
|
|
243
|
-
const securityFlags = headerBytes[3];
|
|
244
|
-
const sessionNodeId = this.isPase
|
|
245
|
-
? NodeId.UNSPECIFIED_NODE_ID
|
|
246
|
-
: (this.#fabric?.nodeId ?? NodeId.UNSPECIFIED_NODE_ID);
|
|
247
|
-
const nonce = this.generateNonce(securityFlags, header.messageId, sessionNodeId);
|
|
248
|
-
return { header, applicationPayload: Crypto.encrypt(this.#encryptKey, applicationPayload, nonce, headerBytes) };
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
get attestationChallengeKey(): Uint8Array {
|
|
252
|
-
return this.#attestationKey;
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
get fabric() {
|
|
256
|
-
return this.#fabric;
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
addAssociatedFabric(fabric: Fabric) {
|
|
260
|
-
if (this.#fabric !== undefined) {
|
|
261
|
-
throw new MatterFlowError("Session already has an associated Fabric. Cannot change this.");
|
|
262
|
-
}
|
|
263
|
-
this.#fabric = fabric;
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
get id() {
|
|
267
|
-
return this.#id;
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
get name() {
|
|
271
|
-
return `secure/${this.#id}`;
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
get peerSessionId(): number {
|
|
275
|
-
return this.#peerSessionId;
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
get nodeId() {
|
|
279
|
-
return this.#fabric?.nodeId ?? NodeId.UNSPECIFIED_NODE_ID;
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
get peerNodeId() {
|
|
283
|
-
return this.#peerNodeId;
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
get associatedFabric(): Fabric {
|
|
287
|
-
if (this.#fabric === undefined) {
|
|
288
|
-
throw new NoAssociatedFabricError(
|
|
289
|
-
`${this.isPase ? "PASE " : ""}Session needs to have an associated Fabric for fabric sensitive data handling.`,
|
|
290
|
-
);
|
|
291
|
-
}
|
|
292
|
-
return this.#fabric;
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
async clearSubscriptions(flushSubscriptions = false, cancelledByPeer = false) {
|
|
296
|
-
const subscriptions = [...this.#subscriptions]; // get all values because subscriptions will remove themselves when cancelled
|
|
297
|
-
for (const subscription of subscriptions) {
|
|
298
|
-
await subscription.close(flushSubscriptions, cancelledByPeer);
|
|
299
|
-
}
|
|
300
|
-
return subscriptions.length;
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
/** Ends a session. Outstanding subscription data will be flushed before the session is destroyed. */
|
|
304
|
-
async end(sendClose: boolean, closeAfterExchangeFinished = false) {
|
|
305
|
-
await this.clearSubscriptions(true);
|
|
306
|
-
await this.destroy(sendClose, closeAfterExchangeFinished);
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
/** Destroys a session. Outstanding subscription data will be discarded. */
|
|
310
|
-
async destroy(sendClose = false, closeAfterExchangeFinished = true) {
|
|
311
|
-
await this.clearSubscriptions(false);
|
|
312
|
-
this.#fabric?.removeSession(this);
|
|
313
|
-
if (!sendClose) {
|
|
314
|
-
this.#sendCloseMessageWhenClosing = false;
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
if (closeAfterExchangeFinished) {
|
|
318
|
-
logger.info(`Register Session ${this.name} to close when exchange is ended.`);
|
|
319
|
-
this.#closingAfterExchangeFinished = true;
|
|
320
|
-
} else {
|
|
321
|
-
this.#isClosing = true;
|
|
322
|
-
logger.info(`End ${this.isPase ? "PASE" : "CASE"} session ${this.name}`);
|
|
323
|
-
this.manager?.sessions.delete(this);
|
|
324
|
-
|
|
325
|
-
// Wait for the exchange to finish closing, but ignore errors if channel is already closed
|
|
326
|
-
if (this.closer) {
|
|
327
|
-
try {
|
|
328
|
-
await this.closer;
|
|
329
|
-
} catch (error) {
|
|
330
|
-
NoChannelError.accept(error);
|
|
331
|
-
} finally {
|
|
332
|
-
await this.destroyed.emit();
|
|
333
|
-
}
|
|
334
|
-
return;
|
|
335
|
-
}
|
|
336
|
-
await this.destroyed.emit();
|
|
337
|
-
}
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
/**
|
|
341
|
-
* The peer node's address.
|
|
342
|
-
*/
|
|
343
|
-
get peerAddress() {
|
|
344
|
-
return PeerAddress({
|
|
345
|
-
fabricIndex: this.#fabric?.fabricIndex ?? FabricIndex.NO_FABRIC,
|
|
346
|
-
nodeId: this.#peerNodeId,
|
|
347
|
-
});
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
/**
|
|
351
|
-
* Indicates whether a peer matches a specific address.
|
|
352
|
-
*/
|
|
353
|
-
peerIs(address: PeerAddress) {
|
|
354
|
-
return (
|
|
355
|
-
(this.#fabric?.fabricIndex ?? FabricIndex.NO_FABRIC) === address.fabricIndex &&
|
|
356
|
-
this.#peerNodeId === address.nodeId
|
|
357
|
-
);
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
private generateNonce(securityFlags: number, messageId: number, nodeId: NodeId) {
|
|
361
|
-
const writer = new DataWriter(Endian.Little);
|
|
362
|
-
writer.writeUInt8(securityFlags);
|
|
363
|
-
writer.writeUInt32(messageId);
|
|
364
|
-
writer.writeUInt64(nodeId);
|
|
365
|
-
return writer.toByteArray();
|
|
366
|
-
}
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
export function assertSecureSession(session?: Session, errorText?: string): asserts session is SecureSession {
|
|
370
|
-
if (!session?.isSecure) {
|
|
371
|
-
throw new MatterFlowError(errorText ?? "Insecure session in secure context");
|
|
372
23
|
}
|
|
373
24
|
}
|
package/src/session/Session.ts
CHANGED
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import { AsyncObservable, Time } from "#general";
|
|
7
|
+
import { AsyncObservable, DataWriter, Endian, InternalError, Time } from "#general";
|
|
8
8
|
import { NodeId, TypeFromPartialBitSchema } from "#types";
|
|
9
|
-
import { DecodedMessage, DecodedPacket, Message, Packet } from "../codec/MessageCodec.js";
|
|
9
|
+
import { DecodedMessage, DecodedPacket, Message, Packet, SessionType } from "../codec/MessageCodec.js";
|
|
10
10
|
import { SupportedTransportsBitmap } from "../common/Scanner.js";
|
|
11
11
|
import { Fabric } from "../fabric/Fabric.js";
|
|
12
12
|
import { MessageCounter } from "../protocol/MessageCounter.js";
|
|
@@ -103,6 +103,7 @@ export abstract class Session {
|
|
|
103
103
|
timestamp = Time.nowMs();
|
|
104
104
|
readonly createdAt = Time.nowMs();
|
|
105
105
|
activeTimestamp = 0;
|
|
106
|
+
abstract type: SessionType;
|
|
106
107
|
protected readonly idleIntervalMs: number;
|
|
107
108
|
protected readonly activeIntervalMs: number;
|
|
108
109
|
protected readonly activeThresholdMs: number;
|
|
@@ -111,7 +112,7 @@ export abstract class Session {
|
|
|
111
112
|
protected readonly specificationVersion: number;
|
|
112
113
|
protected readonly maxPathsPerInvoke: number;
|
|
113
114
|
protected readonly messageCounter: MessageCounter;
|
|
114
|
-
protected readonly messageReceptionState
|
|
115
|
+
protected readonly messageReceptionState?: MessageReceptionState;
|
|
115
116
|
protected readonly supportedTransports: TypeFromPartialBitSchema<typeof SupportedTransportsBitmap>;
|
|
116
117
|
protected readonly maxTcpMessageSize: number;
|
|
117
118
|
|
|
@@ -126,7 +127,7 @@ export abstract class Session {
|
|
|
126
127
|
constructor(args: {
|
|
127
128
|
manager?: SessionManager;
|
|
128
129
|
messageCounter: MessageCounter;
|
|
129
|
-
messageReceptionState
|
|
130
|
+
messageReceptionState?: MessageReceptionState;
|
|
130
131
|
sessionParameters?: SessionParameterOptions;
|
|
131
132
|
setActiveTimestamp: boolean;
|
|
132
133
|
}) {
|
|
@@ -184,10 +185,21 @@ export abstract class Session {
|
|
|
184
185
|
return this.messageCounter.getIncrementedCounter();
|
|
185
186
|
}
|
|
186
187
|
|
|
187
|
-
updateMessageCounter(messageCounter: number, _sourceNodeId?: NodeId) {
|
|
188
|
+
updateMessageCounter(messageCounter: number, _sourceNodeId?: NodeId, _operationalKey?: Uint8Array) {
|
|
189
|
+
if (this.messageReceptionState === undefined) {
|
|
190
|
+
throw new InternalError("MessageReceptionState is not defined for this session");
|
|
191
|
+
}
|
|
188
192
|
this.messageReceptionState.updateMessageCounter(messageCounter);
|
|
189
193
|
}
|
|
190
194
|
|
|
195
|
+
protected static generateNonce(securityFlags: number, messageId: number, nodeId: NodeId) {
|
|
196
|
+
const writer = new DataWriter(Endian.Little);
|
|
197
|
+
writer.writeUInt8(securityFlags);
|
|
198
|
+
writer.writeUInt32(messageId);
|
|
199
|
+
writer.writeUInt64(nodeId);
|
|
200
|
+
return writer.toByteArray();
|
|
201
|
+
}
|
|
202
|
+
|
|
191
203
|
/**
|
|
192
204
|
* The peer's session parameters.
|
|
193
205
|
*/
|
|
@@ -217,7 +229,6 @@ export abstract class Session {
|
|
|
217
229
|
}
|
|
218
230
|
|
|
219
231
|
abstract isSecure: boolean;
|
|
220
|
-
abstract isPase: boolean;
|
|
221
232
|
abstract id: number;
|
|
222
233
|
abstract peerSessionId: number;
|
|
223
234
|
abstract nodeId: NodeId | undefined;
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
+
import { DecodedPacket } from "#codec/index.js";
|
|
7
8
|
import { FabricManager } from "#fabric/FabricManager.js";
|
|
8
9
|
import {
|
|
9
10
|
BasicSet,
|
|
@@ -25,11 +26,14 @@ import {
|
|
|
25
26
|
import { Subscription } from "#interaction/Subscription.js";
|
|
26
27
|
import { Specification } from "#model";
|
|
27
28
|
import { PeerAddress, PeerAddressMap } from "#peer/PeerAddress.js";
|
|
28
|
-
import {
|
|
29
|
+
import { GroupSession } from "#session/GroupSession.js";
|
|
30
|
+
import { CaseAuthenticatedTag, DEFAULT_MAX_PATHS_PER_INVOKE, FabricId, FabricIndex, GroupId, NodeId } from "#types";
|
|
31
|
+
import { UnexpectedDataError } from "@matter/general";
|
|
29
32
|
import { SupportedTransportsSchema } from "../common/Scanner.js";
|
|
30
33
|
import { Fabric } from "../fabric/Fabric.js";
|
|
31
34
|
import { MessageCounter } from "../protocol/MessageCounter.js";
|
|
32
35
|
import { InsecureSession } from "./InsecureSession.js";
|
|
36
|
+
import { NodeSession } from "./NodeSession.js";
|
|
33
37
|
import { SecureSession } from "./SecureSession.js";
|
|
34
38
|
import {
|
|
35
39
|
FALLBACK_DATAMODEL_REVISION,
|
|
@@ -118,11 +122,12 @@ const ID_SPACE_UPPER_BOUND = 0xffff;
|
|
|
118
122
|
export class SessionManager {
|
|
119
123
|
readonly #context: SessionManagerContext;
|
|
120
124
|
readonly #insecureSessions = new Map<NodeId, InsecureSession>();
|
|
121
|
-
readonly #sessions = new BasicSet<
|
|
125
|
+
readonly #sessions = new BasicSet<NodeSession>();
|
|
126
|
+
readonly #groupSessions = new Map<NodeId, BasicSet<GroupSession>>();
|
|
122
127
|
#nextSessionId = Crypto.getRandomUInt16();
|
|
123
128
|
#resumptionRecords = new PeerAddressMap<ResumptionRecord>();
|
|
124
129
|
readonly #globalUnencryptedMessageCounter = new MessageCounter();
|
|
125
|
-
readonly #subscriptionsChanged = Observable<[session:
|
|
130
|
+
readonly #subscriptionsChanged = Observable<[session: NodeSession, subscription: Subscription]>();
|
|
126
131
|
#sessionParameters: SessionParameters;
|
|
127
132
|
readonly #resubmissionStarted = Observable<[session: Session]>();
|
|
128
133
|
readonly #construction: Construction<SessionManager>;
|
|
@@ -278,7 +283,7 @@ export class SessionManager {
|
|
|
278
283
|
peerSessionParameters,
|
|
279
284
|
caseAuthenticatedTags,
|
|
280
285
|
} = args;
|
|
281
|
-
const session = await
|
|
286
|
+
const session = await NodeSession.create({
|
|
282
287
|
manager: this,
|
|
283
288
|
id: sessionId,
|
|
284
289
|
fabric,
|
|
@@ -347,7 +352,7 @@ export class SessionManager {
|
|
|
347
352
|
findOldestInactiveSession() {
|
|
348
353
|
this.#construction.assert();
|
|
349
354
|
|
|
350
|
-
let oldestSession:
|
|
355
|
+
let oldestSession: NodeSession | undefined = undefined;
|
|
351
356
|
for (const session of this.#sessions) {
|
|
352
357
|
if (!oldestSession || session.activeTimestamp < oldestSession.activeTimestamp) {
|
|
353
358
|
oldestSession = session;
|
|
@@ -389,8 +394,8 @@ export class SessionManager {
|
|
|
389
394
|
this.#construction.assert();
|
|
390
395
|
|
|
391
396
|
return [...this.#sessions].find(
|
|
392
|
-
session => session
|
|
393
|
-
) as
|
|
397
|
+
session => NodeSession.is(session) && session.isPase && !session.closingAfterExchangeFinished,
|
|
398
|
+
) as NodeSession;
|
|
394
399
|
}
|
|
395
400
|
|
|
396
401
|
getSessionForNode(address: PeerAddress) {
|
|
@@ -427,15 +432,85 @@ export class SessionManager {
|
|
|
427
432
|
return this.#insecureSessions.get(sourceNodeId);
|
|
428
433
|
}
|
|
429
434
|
|
|
430
|
-
|
|
431
|
-
|
|
435
|
+
/**
|
|
436
|
+
* Creates or Returns a Group Session for a Group Peer Address.
|
|
437
|
+
* This is used for sending group messages because it returns the session for the current
|
|
438
|
+
* Group Epoch key. The Source Node Id is the own Node.
|
|
439
|
+
*/
|
|
440
|
+
groupSessionForAddress(address: PeerAddress) {
|
|
441
|
+
const groupId = GroupId.fromNodeId(address.nodeId);
|
|
442
|
+
GroupId.assertGroupId(groupId);
|
|
443
|
+
|
|
444
|
+
const fabric = this.fabricFor(address);
|
|
445
|
+
const { key, keySetId, sessionId } = fabric.groups.currentKeyForGroup(groupId);
|
|
446
|
+
if (sessionId === undefined || key === undefined) {
|
|
447
|
+
throw new UnexpectedDataError(
|
|
448
|
+
`No group session data found for group ${groupId} in fabric ${fabric.fabricId}.`,
|
|
449
|
+
);
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
let session = this.#groupSessions.get(fabric.nodeId)?.get("id", sessionId);
|
|
453
|
+
if (session === undefined) {
|
|
454
|
+
session = new GroupSession({
|
|
455
|
+
manager: this,
|
|
456
|
+
id: sessionId,
|
|
457
|
+
fabric,
|
|
458
|
+
keySetId,
|
|
459
|
+
operationalGroupKey: key,
|
|
460
|
+
peerNodeId: address.nodeId, // The peer node ID is the group node ID
|
|
461
|
+
});
|
|
462
|
+
}
|
|
463
|
+
return session;
|
|
464
|
+
}
|
|
432
465
|
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
466
|
+
/**
|
|
467
|
+
* Creates or Returns the Group session based on an incoming packet.
|
|
468
|
+
* The Session ID is determined by trying to decrypt te packet with possible keys.
|
|
469
|
+
*/
|
|
470
|
+
groupSessionFromPacket(packet: DecodedPacket, aad: Uint8Array) {
|
|
471
|
+
const groupId = packet.header.destGroupId;
|
|
472
|
+
if (groupId === undefined) {
|
|
473
|
+
throw new UnexpectedDataError("Group ID is required for GroupSession fromPacket.");
|
|
474
|
+
}
|
|
475
|
+
GroupId.assertGroupId(GroupId(groupId));
|
|
436
476
|
|
|
437
|
-
|
|
438
|
-
|
|
477
|
+
const { message, key, sessionId, sourceNodeId, keySetId, fabric } = GroupSession.decode(
|
|
478
|
+
this.#context.fabrics,
|
|
479
|
+
packet,
|
|
480
|
+
aad,
|
|
481
|
+
);
|
|
482
|
+
|
|
483
|
+
let session = this.#groupSessions.get(sourceNodeId)?.get("id", sessionId);
|
|
484
|
+
if (session === undefined) {
|
|
485
|
+
session = new GroupSession({
|
|
486
|
+
manager: this,
|
|
487
|
+
id: sessionId,
|
|
488
|
+
fabric,
|
|
489
|
+
keySetId,
|
|
490
|
+
operationalGroupKey: key,
|
|
491
|
+
peerNodeId: sourceNodeId,
|
|
492
|
+
});
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
return { session, message, key };
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
registerGroupSession(session: GroupSession) {
|
|
499
|
+
const sourceNodeId = session.peerNodeId;
|
|
500
|
+
const peerSessions = this.#groupSessions.get(sourceNodeId) ?? new BasicSet();
|
|
501
|
+
peerSessions.add(session);
|
|
502
|
+
this.#groupSessions.set(sourceNodeId, peerSessions);
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
removeGroupSession(session: GroupSession) {
|
|
506
|
+
const sourceNodeId = session.peerNodeId;
|
|
507
|
+
const peerSessions = this.#groupSessions.get(sourceNodeId);
|
|
508
|
+
if (peerSessions) {
|
|
509
|
+
peerSessions.delete(session);
|
|
510
|
+
if (peerSessions.size === 0) {
|
|
511
|
+
this.#groupSessions.delete(sourceNodeId);
|
|
512
|
+
}
|
|
513
|
+
}
|
|
439
514
|
}
|
|
440
515
|
|
|
441
516
|
findResumptionRecordById(resumptionId: Uint8Array) {
|
|
@@ -581,6 +656,11 @@ export class SessionManager {
|
|
|
581
656
|
for (const session of this.#insecureSessions.values()) {
|
|
582
657
|
closePromises.push(session?.end());
|
|
583
658
|
}
|
|
659
|
+
for (const sessions of this.#groupSessions.values()) {
|
|
660
|
+
for (const session of sessions) {
|
|
661
|
+
closePromises.push(session?.end());
|
|
662
|
+
}
|
|
663
|
+
}
|
|
584
664
|
await MatterAggregateError.allSettled(closePromises, "Error closing sessions").catch(error =>
|
|
585
665
|
logger.error(error),
|
|
586
666
|
);
|
|
@@ -69,7 +69,7 @@ export class CaseClient {
|
|
|
69
69
|
const initiatorResumeMic = Crypto.encrypt(resumeKey, new Uint8Array(0), RESUME1_MIC_NONCE);
|
|
70
70
|
sigma1Bytes = await messenger.sendSigma1({
|
|
71
71
|
initiatorSessionId,
|
|
72
|
-
destinationId: await fabric.
|
|
72
|
+
destinationId: await fabric.currentDestinationIdFor(peerNodeId, initiatorRandom),
|
|
73
73
|
initiatorEcdhPublicKey,
|
|
74
74
|
initiatorRandom,
|
|
75
75
|
resumptionId,
|
|
@@ -79,7 +79,7 @@ export class CaseClient {
|
|
|
79
79
|
} else {
|
|
80
80
|
sigma1Bytes = await messenger.sendSigma1({
|
|
81
81
|
initiatorSessionId,
|
|
82
|
-
destinationId: await fabric.
|
|
82
|
+
destinationId: await fabric.currentDestinationIdFor(peerNodeId, initiatorRandom),
|
|
83
83
|
initiatorEcdhPublicKey,
|
|
84
84
|
initiatorRandom,
|
|
85
85
|
initiatorSessionParams: this.#sessions.sessionParameters,
|
package/src/session/index.ts
CHANGED
|
@@ -4,14 +4,13 @@
|
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
// Export generic Session classes
|
|
8
|
-
// Export CaseSession classes
|
|
9
7
|
export * from "./case/CaseClient.js";
|
|
10
8
|
export * from "./case/CaseMessages.js";
|
|
11
9
|
export * from "./case/CaseMessenger.js";
|
|
12
10
|
export * from "./case/CaseServer.js";
|
|
13
|
-
|
|
11
|
+
export * from "./GroupSession.js";
|
|
14
12
|
export * from "./InsecureSession.js";
|
|
13
|
+
export * from "./NodeSession.js";
|
|
15
14
|
export * from "./pase/PaseClient.js";
|
|
16
15
|
export * from "./pase/PaseMessages.js";
|
|
17
16
|
export * from "./pase/PaseMessenger.js";
|