@matter/protocol 0.15.0-alpha.0-20250612-ddd428561 → 0.15.0-alpha.0-20250614-b9829e223
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/certificate/AttestationCertificateManager.d.ts +3 -3
- package/dist/cjs/certificate/AttestationCertificateManager.d.ts.map +1 -1
- package/dist/cjs/certificate/AttestationCertificateManager.js +12 -10
- package/dist/cjs/certificate/AttestationCertificateManager.js.map +1 -1
- package/dist/cjs/certificate/CertificateAuthority.d.ts +5 -3
- package/dist/cjs/certificate/CertificateAuthority.d.ts.map +1 -1
- package/dist/cjs/certificate/CertificateAuthority.js +19 -11
- package/dist/cjs/certificate/CertificateAuthority.js.map +1 -1
- package/dist/cjs/certificate/CertificateManager.d.ts +18 -15
- package/dist/cjs/certificate/CertificateManager.d.ts.map +1 -1
- package/dist/cjs/certificate/CertificateManager.js +92 -83
- package/dist/cjs/certificate/CertificateManager.js.map +2 -2
- package/dist/cjs/certificate/CertificationDeclarationManager.d.ts +7 -1
- package/dist/cjs/certificate/CertificationDeclarationManager.d.ts.map +1 -1
- package/dist/cjs/certificate/CertificationDeclarationManager.js +2 -2
- package/dist/cjs/certificate/CertificationDeclarationManager.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 +10 -4
- package/dist/cjs/certificate/DeviceCertification.js.map +1 -1
- package/dist/cjs/common/FailsafeContext.js +1 -1
- package/dist/cjs/common/FailsafeContext.js.map +1 -1
- package/dist/cjs/events/OccurrenceManager.d.ts +1 -0
- package/dist/cjs/events/OccurrenceManager.d.ts.map +1 -1
- package/dist/cjs/events/OccurrenceManager.js +14 -8
- package/dist/cjs/events/OccurrenceManager.js.map +1 -1
- package/dist/cjs/fabric/Fabric.d.ts +6 -4
- package/dist/cjs/fabric/Fabric.d.ts.map +1 -1
- package/dist/cjs/fabric/Fabric.js +33 -20
- package/dist/cjs/fabric/Fabric.js.map +1 -1
- package/dist/cjs/fabric/FabricAuthority.d.ts +1 -1
- package/dist/cjs/fabric/FabricAuthority.d.ts.map +1 -1
- package/dist/cjs/fabric/FabricAuthority.js +7 -7
- package/dist/cjs/fabric/FabricAuthority.js.map +1 -1
- package/dist/cjs/fabric/FabricManager.d.ts +3 -2
- package/dist/cjs/fabric/FabricManager.d.ts.map +1 -1
- package/dist/cjs/fabric/FabricManager.js +8 -3
- package/dist/cjs/fabric/FabricManager.js.map +1 -1
- package/dist/cjs/fabric/TestFabric.d.ts.map +1 -1
- package/dist/cjs/fabric/TestFabric.js +15 -19
- package/dist/cjs/fabric/TestFabric.js.map +1 -1
- package/dist/cjs/groups/FabricGroups.d.ts.map +1 -1
- package/dist/cjs/groups/FabricGroups.js +11 -7
- package/dist/cjs/groups/FabricGroups.js.map +1 -1
- package/dist/cjs/groups/KeySets.d.ts +2 -2
- package/dist/cjs/groups/KeySets.d.ts.map +1 -1
- package/dist/cjs/groups/KeySets.js +2 -2
- package/dist/cjs/groups/KeySets.js.map +1 -1
- package/dist/cjs/groups/MessagingState.d.ts +2 -2
- package/dist/cjs/groups/MessagingState.d.ts.map +1 -1
- package/dist/cjs/groups/MessagingState.js +4 -2
- package/dist/cjs/groups/MessagingState.js.map +1 -1
- package/dist/cjs/interaction/FabricAccessControl.js +1 -1
- package/dist/cjs/interaction/FabricAccessControl.js.map +1 -1
- package/dist/cjs/mdns/MdnsBroadcaster.d.ts +3 -3
- package/dist/cjs/mdns/MdnsBroadcaster.d.ts.map +1 -1
- package/dist/cjs/mdns/MdnsBroadcaster.js +7 -4
- package/dist/cjs/mdns/MdnsBroadcaster.js.map +1 -1
- package/dist/cjs/mdns/MdnsScanner.d.ts +1 -1
- package/dist/cjs/mdns/MdnsScanner.d.ts.map +1 -1
- package/dist/cjs/mdns/MdnsScanner.js +2 -6
- package/dist/cjs/mdns/MdnsScanner.js.map +1 -1
- package/dist/cjs/mdns/MdnsService.d.ts.map +1 -1
- package/dist/cjs/mdns/MdnsService.js +2 -1
- package/dist/cjs/mdns/MdnsService.js.map +1 -1
- package/dist/cjs/peer/ControllerCommissioner.js +1 -1
- package/dist/cjs/peer/ControllerCommissioner.js.map +1 -1
- package/dist/cjs/peer/ControllerCommissioningFlow.d.ts +1 -1
- package/dist/cjs/peer/ControllerCommissioningFlow.d.ts.map +1 -1
- package/dist/cjs/peer/ControllerCommissioningFlow.js +3 -4
- package/dist/cjs/peer/ControllerCommissioningFlow.js.map +1 -1
- package/dist/cjs/protocol/DeviceCommissioner.d.ts.map +1 -1
- package/dist/cjs/protocol/DeviceCommissioner.js +1 -1
- package/dist/cjs/protocol/DeviceCommissioner.js.map +1 -1
- package/dist/cjs/protocol/ExchangeManager.d.ts +4 -2
- package/dist/cjs/protocol/ExchangeManager.d.ts.map +1 -1
- package/dist/cjs/protocol/ExchangeManager.js +11 -6
- package/dist/cjs/protocol/ExchangeManager.js.map +1 -1
- package/dist/cjs/protocol/MessageCounter.d.ts +4 -4
- package/dist/cjs/protocol/MessageCounter.d.ts.map +1 -1
- package/dist/cjs/protocol/MessageCounter.js +7 -6
- package/dist/cjs/protocol/MessageCounter.js.map +1 -1
- package/dist/cjs/session/GroupSession.d.ts.map +1 -1
- package/dist/cjs/session/GroupSession.js +7 -2
- package/dist/cjs/session/GroupSession.js.map +1 -1
- package/dist/cjs/session/InsecureSession.d.ts +2 -0
- package/dist/cjs/session/InsecureSession.d.ts.map +1 -1
- package/dist/cjs/session/InsecureSession.js +2 -2
- package/dist/cjs/session/InsecureSession.js.map +1 -1
- package/dist/cjs/session/NodeSession.d.ts +3 -1
- package/dist/cjs/session/NodeSession.d.ts.map +1 -1
- package/dist/cjs/session/NodeSession.js +21 -13
- package/dist/cjs/session/NodeSession.js.map +1 -1
- package/dist/cjs/session/SessionManager.d.ts +1 -0
- package/dist/cjs/session/SessionManager.d.ts.map +1 -1
- package/dist/cjs/session/SessionManager.js +13 -3
- package/dist/cjs/session/SessionManager.js.map +1 -1
- package/dist/cjs/session/case/CaseClient.d.ts.map +1 -1
- package/dist/cjs/session/case/CaseClient.js +16 -15
- package/dist/cjs/session/case/CaseClient.js.map +1 -1
- package/dist/cjs/session/case/CaseServer.d.ts.map +1 -1
- package/dist/cjs/session/case/CaseServer.js +22 -18
- package/dist/cjs/session/case/CaseServer.js.map +1 -1
- package/dist/cjs/session/pase/PaseClient.d.ts +4 -4
- package/dist/cjs/session/pase/PaseClient.d.ts.map +1 -1
- package/dist/cjs/session/pase/PaseClient.js +11 -9
- package/dist/cjs/session/pase/PaseClient.js.map +1 -1
- package/dist/cjs/session/pase/PaseServer.d.ts.map +1 -1
- package/dist/cjs/session/pase/PaseServer.js +6 -5
- package/dist/cjs/session/pase/PaseServer.js.map +1 -1
- package/dist/esm/certificate/AttestationCertificateManager.d.ts +3 -3
- package/dist/esm/certificate/AttestationCertificateManager.d.ts.map +1 -1
- package/dist/esm/certificate/AttestationCertificateManager.js +13 -11
- package/dist/esm/certificate/AttestationCertificateManager.js.map +1 -1
- package/dist/esm/certificate/CertificateAuthority.d.ts +5 -3
- package/dist/esm/certificate/CertificateAuthority.d.ts.map +1 -1
- package/dist/esm/certificate/CertificateAuthority.js +19 -11
- package/dist/esm/certificate/CertificateAuthority.js.map +1 -1
- package/dist/esm/certificate/CertificateManager.d.ts +18 -15
- package/dist/esm/certificate/CertificateManager.d.ts.map +1 -1
- package/dist/esm/certificate/CertificateManager.js +92 -84
- package/dist/esm/certificate/CertificateManager.js.map +2 -2
- package/dist/esm/certificate/CertificationDeclarationManager.d.ts +7 -1
- package/dist/esm/certificate/CertificationDeclarationManager.d.ts.map +1 -1
- package/dist/esm/certificate/CertificationDeclarationManager.js +2 -2
- package/dist/esm/certificate/CertificationDeclarationManager.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 +11 -5
- package/dist/esm/certificate/DeviceCertification.js.map +1 -1
- package/dist/esm/common/FailsafeContext.js +1 -1
- package/dist/esm/common/FailsafeContext.js.map +1 -1
- package/dist/esm/events/OccurrenceManager.d.ts +1 -0
- package/dist/esm/events/OccurrenceManager.d.ts.map +1 -1
- package/dist/esm/events/OccurrenceManager.js +14 -8
- package/dist/esm/events/OccurrenceManager.js.map +1 -1
- package/dist/esm/fabric/Fabric.d.ts +6 -4
- package/dist/esm/fabric/Fabric.d.ts.map +1 -1
- package/dist/esm/fabric/Fabric.js +33 -21
- package/dist/esm/fabric/Fabric.js.map +1 -1
- package/dist/esm/fabric/FabricAuthority.d.ts +1 -1
- package/dist/esm/fabric/FabricAuthority.d.ts.map +1 -1
- package/dist/esm/fabric/FabricAuthority.js +8 -15
- package/dist/esm/fabric/FabricAuthority.js.map +1 -1
- package/dist/esm/fabric/FabricManager.d.ts +3 -2
- package/dist/esm/fabric/FabricManager.d.ts.map +1 -1
- package/dist/esm/fabric/FabricManager.js +9 -3
- package/dist/esm/fabric/FabricManager.js.map +1 -1
- package/dist/esm/fabric/TestFabric.d.ts.map +1 -1
- package/dist/esm/fabric/TestFabric.js +16 -20
- package/dist/esm/fabric/TestFabric.js.map +1 -1
- package/dist/esm/groups/FabricGroups.d.ts.map +1 -1
- package/dist/esm/groups/FabricGroups.js +12 -8
- package/dist/esm/groups/FabricGroups.js.map +1 -1
- package/dist/esm/groups/KeySets.d.ts +2 -2
- package/dist/esm/groups/KeySets.d.ts.map +1 -1
- package/dist/esm/groups/KeySets.js +3 -3
- package/dist/esm/groups/KeySets.js.map +1 -1
- package/dist/esm/groups/MessagingState.d.ts +2 -2
- package/dist/esm/groups/MessagingState.d.ts.map +1 -1
- package/dist/esm/groups/MessagingState.js +4 -2
- package/dist/esm/groups/MessagingState.js.map +1 -1
- package/dist/esm/interaction/FabricAccessControl.js +1 -1
- package/dist/esm/interaction/FabricAccessControl.js.map +1 -1
- package/dist/esm/mdns/MdnsBroadcaster.d.ts +3 -3
- package/dist/esm/mdns/MdnsBroadcaster.d.ts.map +1 -1
- package/dist/esm/mdns/MdnsBroadcaster.js +7 -5
- package/dist/esm/mdns/MdnsBroadcaster.js.map +1 -1
- package/dist/esm/mdns/MdnsScanner.d.ts +1 -1
- package/dist/esm/mdns/MdnsScanner.d.ts.map +1 -1
- package/dist/esm/mdns/MdnsScanner.js +2 -6
- package/dist/esm/mdns/MdnsScanner.js.map +1 -1
- package/dist/esm/mdns/MdnsService.d.ts.map +1 -1
- package/dist/esm/mdns/MdnsService.js +3 -1
- package/dist/esm/mdns/MdnsService.js.map +1 -1
- package/dist/esm/peer/ControllerCommissioner.js +1 -1
- package/dist/esm/peer/ControllerCommissioner.js.map +1 -1
- package/dist/esm/peer/ControllerCommissioningFlow.d.ts +1 -1
- package/dist/esm/peer/ControllerCommissioningFlow.d.ts.map +1 -1
- package/dist/esm/peer/ControllerCommissioningFlow.js +3 -5
- package/dist/esm/peer/ControllerCommissioningFlow.js.map +1 -1
- package/dist/esm/protocol/DeviceCommissioner.d.ts.map +1 -1
- package/dist/esm/protocol/DeviceCommissioner.js +1 -2
- package/dist/esm/protocol/DeviceCommissioner.js.map +1 -1
- package/dist/esm/protocol/ExchangeManager.d.ts +4 -2
- package/dist/esm/protocol/ExchangeManager.d.ts.map +1 -1
- package/dist/esm/protocol/ExchangeManager.js +11 -6
- package/dist/esm/protocol/ExchangeManager.js.map +1 -1
- package/dist/esm/protocol/MessageCounter.d.ts +4 -4
- package/dist/esm/protocol/MessageCounter.d.ts.map +1 -1
- package/dist/esm/protocol/MessageCounter.js +8 -7
- package/dist/esm/protocol/MessageCounter.js.map +1 -1
- package/dist/esm/session/GroupSession.d.ts.map +1 -1
- package/dist/esm/session/GroupSession.js +7 -3
- package/dist/esm/session/GroupSession.js.map +1 -1
- package/dist/esm/session/InsecureSession.d.ts +2 -0
- package/dist/esm/session/InsecureSession.d.ts.map +1 -1
- package/dist/esm/session/InsecureSession.js +2 -2
- package/dist/esm/session/InsecureSession.js.map +1 -1
- package/dist/esm/session/NodeSession.d.ts +3 -1
- package/dist/esm/session/NodeSession.d.ts.map +1 -1
- package/dist/esm/session/NodeSession.js +22 -14
- package/dist/esm/session/NodeSession.js.map +1 -1
- package/dist/esm/session/SessionManager.d.ts +1 -0
- package/dist/esm/session/SessionManager.d.ts.map +1 -1
- package/dist/esm/session/SessionManager.js +13 -4
- package/dist/esm/session/SessionManager.js.map +1 -1
- package/dist/esm/session/case/CaseClient.d.ts.map +1 -1
- package/dist/esm/session/case/CaseClient.js +17 -16
- package/dist/esm/session/case/CaseClient.js.map +1 -1
- package/dist/esm/session/case/CaseServer.d.ts.map +1 -1
- package/dist/esm/session/case/CaseServer.js +23 -19
- package/dist/esm/session/case/CaseServer.js.map +1 -1
- package/dist/esm/session/pase/PaseClient.d.ts +4 -4
- package/dist/esm/session/pase/PaseClient.d.ts.map +1 -1
- package/dist/esm/session/pase/PaseClient.js +12 -10
- package/dist/esm/session/pase/PaseClient.js.map +1 -1
- package/dist/esm/session/pase/PaseServer.d.ts.map +1 -1
- package/dist/esm/session/pase/PaseServer.js +6 -6
- package/dist/esm/session/pase/PaseServer.js.map +1 -1
- package/package.json +6 -6
- package/src/certificate/AttestationCertificateManager.ts +12 -10
- package/src/certificate/CertificateAuthority.ts +20 -11
- package/src/certificate/CertificateManager.ts +77 -72
- package/src/certificate/CertificationDeclarationManager.ts +3 -3
- package/src/certificate/DeviceCertification.ts +10 -4
- package/src/common/FailsafeContext.ts +1 -1
- package/src/events/OccurrenceManager.ts +16 -9
- package/src/fabric/Fabric.ts +36 -20
- package/src/fabric/FabricAuthority.ts +8 -16
- package/src/fabric/FabricManager.ts +10 -3
- package/src/fabric/TestFabric.ts +17 -22
- package/src/groups/FabricGroups.ts +20 -8
- package/src/groups/KeySets.ts +2 -2
- package/src/groups/MessagingState.ts +6 -3
- package/src/interaction/FabricAccessControl.ts +1 -1
- package/src/mdns/MdnsBroadcaster.ts +11 -4
- package/src/mdns/MdnsScanner.ts +2 -6
- package/src/mdns/MdnsService.ts +3 -1
- package/src/peer/ControllerCommissioner.ts +1 -1
- package/src/peer/ControllerCommissioningFlow.ts +4 -6
- package/src/protocol/DeviceCommissioner.ts +1 -2
- package/src/protocol/ExchangeManager.ts +13 -6
- package/src/protocol/MessageCounter.ts +11 -3
- package/src/session/GroupSession.ts +7 -3
- package/src/session/InsecureSession.ts +4 -3
- package/src/session/NodeSession.ts +25 -14
- package/src/session/SessionManager.ts +14 -4
- package/src/session/case/CaseClient.ts +18 -16
- package/src/session/case/CaseServer.ts +22 -17
- package/src/session/pase/PaseClient.ts +11 -9
- package/src/session/pase/PaseServer.ts +6 -5
|
@@ -104,6 +104,7 @@ export class MessageChannel implements Channel<Message> {
|
|
|
104
104
|
* Interfaces {@link ExchangeManager} with other components.
|
|
105
105
|
*/
|
|
106
106
|
export interface ExchangeManagerContext {
|
|
107
|
+
crypto: Crypto;
|
|
107
108
|
transportInterfaces: TransportInterfaceSet;
|
|
108
109
|
sessionManager: SessionManager;
|
|
109
110
|
channelManager: ChannelManager;
|
|
@@ -113,7 +114,7 @@ export class ExchangeManager {
|
|
|
113
114
|
readonly #transportInterfaces: TransportInterfaceSet;
|
|
114
115
|
readonly #sessionManager: SessionManager;
|
|
115
116
|
readonly #channelManager: ChannelManager;
|
|
116
|
-
readonly #exchangeCounter
|
|
117
|
+
readonly #exchangeCounter: ExchangeCounter;
|
|
117
118
|
readonly #exchanges = new Map<number, MessageExchange>();
|
|
118
119
|
readonly #protocols = new Map<number, ProtocolHandler>();
|
|
119
120
|
readonly #listeners = new Map<TransportInterface, TransportInterface.Listener>();
|
|
@@ -125,6 +126,7 @@ export class ExchangeManager {
|
|
|
125
126
|
this.#transportInterfaces = context.transportInterfaces;
|
|
126
127
|
this.#sessionManager = context.sessionManager;
|
|
127
128
|
this.#channelManager = context.channelManager;
|
|
129
|
+
this.#exchangeCounter = new ExchangeCounter(context.crypto);
|
|
128
130
|
|
|
129
131
|
for (const transportInterface of this.#transportInterfaces) {
|
|
130
132
|
this.#addListener(transportInterface);
|
|
@@ -143,6 +145,7 @@ export class ExchangeManager {
|
|
|
143
145
|
|
|
144
146
|
static [Environmental.create](env: Environment) {
|
|
145
147
|
const instance = new ExchangeManager({
|
|
148
|
+
crypto: env.get(Crypto),
|
|
146
149
|
transportInterfaces: env.get(TransportInterfaceSet),
|
|
147
150
|
sessionManager: env.get(SessionManager),
|
|
148
151
|
channelManager: env.get(ChannelManager),
|
|
@@ -515,13 +518,17 @@ export class ExchangeManager {
|
|
|
515
518
|
}
|
|
516
519
|
|
|
517
520
|
export class ExchangeCounter {
|
|
518
|
-
|
|
521
|
+
#exchangeCounter: number;
|
|
522
|
+
|
|
523
|
+
constructor(crypto: Crypto) {
|
|
524
|
+
this.#exchangeCounter = crypto.randomUint16;
|
|
525
|
+
}
|
|
519
526
|
|
|
520
527
|
getIncrementedCounter() {
|
|
521
|
-
this
|
|
522
|
-
if (this
|
|
523
|
-
this
|
|
528
|
+
this.#exchangeCounter++;
|
|
529
|
+
if (this.#exchangeCounter > 0xffff) {
|
|
530
|
+
this.#exchangeCounter = 0;
|
|
524
531
|
}
|
|
525
|
-
return this
|
|
532
|
+
return this.#exchangeCounter;
|
|
526
533
|
}
|
|
527
534
|
}
|
|
@@ -43,7 +43,7 @@ export enum MessageCounterTypes {
|
|
|
43
43
|
* Rollover can be allowed or forbidden and a callback can be provided to be notified before a rollover would happen.
|
|
44
44
|
*/
|
|
45
45
|
export class MessageCounter {
|
|
46
|
-
protected messageCounter
|
|
46
|
+
protected messageCounter: number;
|
|
47
47
|
|
|
48
48
|
/**
|
|
49
49
|
* Creates a new message counter with a random start value. If a aboutToRolloverCallback is provided this
|
|
@@ -51,9 +51,14 @@ export class MessageCounter {
|
|
|
51
51
|
* a number of messages before the rollover callback is called (Default 1000).
|
|
52
52
|
*/
|
|
53
53
|
constructor(
|
|
54
|
+
crypto: Crypto,
|
|
54
55
|
protected readonly aboutToRolloverCallback?: () => void,
|
|
56
|
+
|
|
57
|
+
// Counter is a 28 bit random number plus 1
|
|
55
58
|
protected readonly rolloverInfoDifference = ROLLOVER_INFO_DIFFERENCE,
|
|
56
|
-
) {
|
|
59
|
+
) {
|
|
60
|
+
this.messageCounter = (crypto.randomUint32 >>> 4) + 1;
|
|
61
|
+
}
|
|
57
62
|
|
|
58
63
|
async getIncrementedCounter() {
|
|
59
64
|
this.messageCounter++;
|
|
@@ -82,6 +87,7 @@ export class PersistedMessageCounter extends MessageCounter {
|
|
|
82
87
|
}
|
|
83
88
|
|
|
84
89
|
static async create(
|
|
90
|
+
crypto: Crypto,
|
|
85
91
|
storageContext: StorageContext,
|
|
86
92
|
storageKey: string,
|
|
87
93
|
aboutToRolloverCallback?: () => void,
|
|
@@ -89,6 +95,7 @@ export class PersistedMessageCounter extends MessageCounter {
|
|
|
89
95
|
) {
|
|
90
96
|
return asyncNew(
|
|
91
97
|
PersistedMessageCounter,
|
|
98
|
+
crypto,
|
|
92
99
|
storageContext,
|
|
93
100
|
storageKey,
|
|
94
101
|
aboutToRolloverCallback,
|
|
@@ -97,12 +104,13 @@ export class PersistedMessageCounter extends MessageCounter {
|
|
|
97
104
|
}
|
|
98
105
|
|
|
99
106
|
constructor(
|
|
107
|
+
crypto: Crypto,
|
|
100
108
|
private readonly storageContext: StorageContext,
|
|
101
109
|
private readonly storageKey: string,
|
|
102
110
|
aboutToRolloverCallback?: () => void,
|
|
103
111
|
rolloverInfoDifference = ROLLOVER_INFO_DIFFERENCE,
|
|
104
112
|
) {
|
|
105
|
-
super(aboutToRolloverCallback, rolloverInfoDifference);
|
|
113
|
+
super(crypto, aboutToRolloverCallback, rolloverInfoDifference);
|
|
106
114
|
this.#construction = Construction(this, async () => {
|
|
107
115
|
if (await storageContext.has(storageKey)) {
|
|
108
116
|
this.messageCounter = await storageContext.get<number>(storageKey);
|
|
@@ -9,7 +9,6 @@ import { Fabric } from "#fabric/Fabric.js";
|
|
|
9
9
|
import { FabricManager } from "#fabric/FabricManager.js";
|
|
10
10
|
import {
|
|
11
11
|
Bytes,
|
|
12
|
-
Crypto,
|
|
13
12
|
CryptoDecryptError,
|
|
14
13
|
ImplementationError,
|
|
15
14
|
InternalError,
|
|
@@ -126,7 +125,12 @@ export class GroupSession extends SecureSession {
|
|
|
126
125
|
|
|
127
126
|
return {
|
|
128
127
|
header,
|
|
129
|
-
applicationPayload:
|
|
128
|
+
applicationPayload: this.#fabric.crypto.encrypt(
|
|
129
|
+
this.#operationalGroupKey,
|
|
130
|
+
applicationPayload,
|
|
131
|
+
nonce,
|
|
132
|
+
headerBytes,
|
|
133
|
+
),
|
|
130
134
|
};
|
|
131
135
|
}
|
|
132
136
|
|
|
@@ -179,7 +183,7 @@ export class GroupSession extends SecureSession {
|
|
|
179
183
|
try {
|
|
180
184
|
message = MessageCodec.decodePayload({
|
|
181
185
|
header,
|
|
182
|
-
applicationPayload:
|
|
186
|
+
applicationPayload: fabric.crypto.decrypt(key, applicationPayload, nonce, aad),
|
|
183
187
|
});
|
|
184
188
|
found = true;
|
|
185
189
|
break; // Exit loop on first successful decryption
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import { Logger, MatterFlowError } from "#general";
|
|
7
|
+
import { Crypto, Logger, MatterFlowError } from "#general";
|
|
8
8
|
import { NodeId } from "#types";
|
|
9
9
|
import { DecodedMessage, DecodedPacket, Message, MessageCodec, Packet, SessionType } from "../codec/MessageCodec.js";
|
|
10
10
|
import { Fabric } from "../fabric/Fabric.js";
|
|
@@ -23,19 +23,20 @@ export class InsecureSession extends Session {
|
|
|
23
23
|
readonly type = SessionType.Unicast;
|
|
24
24
|
|
|
25
25
|
constructor(args: {
|
|
26
|
+
crypto: Crypto;
|
|
26
27
|
manager?: SessionManager;
|
|
27
28
|
messageCounter: MessageCounter;
|
|
28
29
|
initiatorNodeId?: NodeId;
|
|
29
30
|
sessionParameters?: SessionParameterOptions;
|
|
30
31
|
isInitiator?: boolean;
|
|
31
32
|
}) {
|
|
32
|
-
const { initiatorNodeId, isInitiator } = args;
|
|
33
|
+
const { crypto, initiatorNodeId, isInitiator } = args;
|
|
33
34
|
super({
|
|
34
35
|
...args,
|
|
35
36
|
setActiveTimestamp: !isInitiator, // When we are the initiator we assume the node is in idle mode
|
|
36
37
|
messageReceptionState: new MessageReceptionStateUnencryptedWithRollover(),
|
|
37
38
|
});
|
|
38
|
-
this.#initiatorNodeId = initiatorNodeId ?? NodeId.randomOperationalNodeId();
|
|
39
|
+
this.#initiatorNodeId = initiatorNodeId ?? NodeId.randomOperationalNodeId(crypto);
|
|
39
40
|
}
|
|
40
41
|
|
|
41
42
|
get isSecure() {
|
|
@@ -30,6 +30,7 @@ export class NoAssociatedFabricError extends StatusResponseError {
|
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
export class NodeSession extends SecureSession {
|
|
33
|
+
readonly #crypto: Crypto;
|
|
33
34
|
readonly #subscriptions = new BasicSet<Subscription>();
|
|
34
35
|
#closingAfterExchangeFinished = false;
|
|
35
36
|
#sendCloseMessageWhenClosing = true;
|
|
@@ -47,6 +48,7 @@ export class NodeSession extends SecureSession {
|
|
|
47
48
|
readonly type = SessionType.Unicast;
|
|
48
49
|
|
|
49
50
|
static async create(args: {
|
|
51
|
+
crypto: Crypto;
|
|
50
52
|
manager?: SessionManager;
|
|
51
53
|
id: number;
|
|
52
54
|
fabric: Fabric | undefined;
|
|
@@ -60,6 +62,7 @@ export class NodeSession extends SecureSession {
|
|
|
60
62
|
caseAuthenticatedTags?: CaseAuthenticatedTag[];
|
|
61
63
|
}) {
|
|
62
64
|
const {
|
|
65
|
+
crypto,
|
|
63
66
|
manager,
|
|
64
67
|
id,
|
|
65
68
|
fabric,
|
|
@@ -72,7 +75,7 @@ export class NodeSession extends SecureSession {
|
|
|
72
75
|
peerSessionParameters,
|
|
73
76
|
caseAuthenticatedTags,
|
|
74
77
|
} = args;
|
|
75
|
-
const keys = await
|
|
78
|
+
const keys = await args.crypto.createHkdfKey(
|
|
76
79
|
sharedSecret,
|
|
77
80
|
salt,
|
|
78
81
|
isResumption ? SESSION_RESUMPTION_KEYS_INFO : SESSION_KEYS_INFO,
|
|
@@ -82,6 +85,7 @@ export class NodeSession extends SecureSession {
|
|
|
82
85
|
const encryptKey = isInitiator ? keys.slice(0, 16) : keys.slice(16, 32);
|
|
83
86
|
const attestationKey = keys.slice(32, 48);
|
|
84
87
|
return new NodeSession({
|
|
88
|
+
crypto,
|
|
85
89
|
manager,
|
|
86
90
|
id,
|
|
87
91
|
fabric,
|
|
@@ -97,6 +101,7 @@ export class NodeSession extends SecureSession {
|
|
|
97
101
|
}
|
|
98
102
|
|
|
99
103
|
constructor(args: {
|
|
104
|
+
crypto: Crypto;
|
|
100
105
|
manager?: SessionManager;
|
|
101
106
|
id: number;
|
|
102
107
|
fabric: Fabric | undefined;
|
|
@@ -109,18 +114,8 @@ export class NodeSession extends SecureSession {
|
|
|
109
114
|
caseAuthenticatedTags?: CaseAuthenticatedTag[];
|
|
110
115
|
isInitiator: boolean;
|
|
111
116
|
}) {
|
|
112
|
-
super({
|
|
113
|
-
...args,
|
|
114
|
-
setActiveTimestamp: true, // We always set the active timestamp for Secure sessions
|
|
115
|
-
// Can be changed to a PersistedMessageCounter if we implement session storage
|
|
116
|
-
messageCounter: new MessageCounter(() => {
|
|
117
|
-
// Secure Session Message Counter
|
|
118
|
-
// Expire/End the session before the counter rolls over
|
|
119
|
-
this.end(true, true).catch(error => logger.error(`Error while closing session: ${error}`));
|
|
120
|
-
}),
|
|
121
|
-
messageReceptionState: new MessageReceptionStateEncryptedWithoutRollover(),
|
|
122
|
-
});
|
|
123
117
|
const {
|
|
118
|
+
crypto,
|
|
124
119
|
manager,
|
|
125
120
|
id,
|
|
126
121
|
fabric,
|
|
@@ -133,6 +128,19 @@ export class NodeSession extends SecureSession {
|
|
|
133
128
|
isInitiator,
|
|
134
129
|
} = args;
|
|
135
130
|
|
|
131
|
+
super({
|
|
132
|
+
...args,
|
|
133
|
+
setActiveTimestamp: true, // We always set the active timestamp for Secure sessions
|
|
134
|
+
// Can be changed to a PersistedMessageCounter if we implement session storage
|
|
135
|
+
messageCounter: new MessageCounter(crypto, () => {
|
|
136
|
+
// Secure Session Message Counter
|
|
137
|
+
// Expire/End the session before the counter rolls over
|
|
138
|
+
this.end(true, true).catch(error => logger.error(`Error while closing session: ${error}`));
|
|
139
|
+
}),
|
|
140
|
+
messageReceptionState: new MessageReceptionStateEncryptedWithoutRollover(),
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
this.#crypto = crypto;
|
|
136
144
|
this.#id = id;
|
|
137
145
|
this.#fabric = fabric;
|
|
138
146
|
this.#peerNodeId = peerNodeId;
|
|
@@ -220,7 +228,7 @@ export class NodeSession extends SecureSession {
|
|
|
220
228
|
const nonce = Session.generateNonce(header.securityFlags, header.messageId, this.#peerNodeId);
|
|
221
229
|
const message = MessageCodec.decodePayload({
|
|
222
230
|
header,
|
|
223
|
-
applicationPayload:
|
|
231
|
+
applicationPayload: this.#crypto.decrypt(this.#decryptKey, applicationPayload, nonce, aad),
|
|
224
232
|
});
|
|
225
233
|
|
|
226
234
|
if (message.payloadHeader.hasSecuredExtension) {
|
|
@@ -241,7 +249,10 @@ export class NodeSession extends SecureSession {
|
|
|
241
249
|
? NodeId.UNSPECIFIED_NODE_ID
|
|
242
250
|
: (this.#fabric?.nodeId ?? NodeId.UNSPECIFIED_NODE_ID);
|
|
243
251
|
const nonce = Session.generateNonce(securityFlags, header.messageId, sessionNodeId);
|
|
244
|
-
return {
|
|
252
|
+
return {
|
|
253
|
+
header,
|
|
254
|
+
applicationPayload: this.#crypto.encrypt(this.#encryptKey, applicationPayload, nonce, headerBytes),
|
|
255
|
+
};
|
|
245
256
|
}
|
|
246
257
|
|
|
247
258
|
get attestationChallengeKey(): Uint8Array {
|
|
@@ -10,7 +10,6 @@ import {
|
|
|
10
10
|
BasicSet,
|
|
11
11
|
Bytes,
|
|
12
12
|
Construction,
|
|
13
|
-
Crypto,
|
|
14
13
|
Environment,
|
|
15
14
|
Environmental,
|
|
16
15
|
Lifecycle,
|
|
@@ -124,9 +123,9 @@ export class SessionManager {
|
|
|
124
123
|
readonly #insecureSessions = new Map<NodeId, InsecureSession>();
|
|
125
124
|
readonly #sessions = new BasicSet<NodeSession>();
|
|
126
125
|
readonly #groupSessions = new Map<NodeId, BasicSet<GroupSession>>();
|
|
127
|
-
#nextSessionId
|
|
126
|
+
#nextSessionId: number;
|
|
128
127
|
#resumptionRecords = new PeerAddressMap<ResumptionRecord>();
|
|
129
|
-
readonly #globalUnencryptedMessageCounter
|
|
128
|
+
readonly #globalUnencryptedMessageCounter;
|
|
130
129
|
readonly #subscriptionsChanged = Observable<[session: NodeSession, subscription: Subscription]>();
|
|
131
130
|
#sessionParameters: SessionParameters;
|
|
132
131
|
readonly #resubmissionStarted = Observable<[session: Session]>();
|
|
@@ -137,7 +136,12 @@ export class SessionManager {
|
|
|
137
136
|
|
|
138
137
|
constructor(context: SessionManagerContext) {
|
|
139
138
|
this.#context = context;
|
|
139
|
+
const {
|
|
140
|
+
fabrics: { crypto },
|
|
141
|
+
} = context;
|
|
140
142
|
this.#sessionParameters = { ...DEFAULT_SESSION_PARAMETERS, ...context.parameters };
|
|
143
|
+
this.#nextSessionId = crypto.randomUint16;
|
|
144
|
+
this.#globalUnencryptedMessageCounter = new MessageCounter(crypto);
|
|
141
145
|
|
|
142
146
|
// When fabric is removed, also remove the resumption record
|
|
143
147
|
this.#observers.on(context.fabrics.events.deleted, async fabric => {
|
|
@@ -164,6 +168,10 @@ export class SessionManager {
|
|
|
164
168
|
return this.#context;
|
|
165
169
|
}
|
|
166
170
|
|
|
171
|
+
get crypto() {
|
|
172
|
+
return this.#context.fabrics.crypto;
|
|
173
|
+
}
|
|
174
|
+
|
|
167
175
|
/**
|
|
168
176
|
* Active secure sessions.
|
|
169
177
|
*/
|
|
@@ -242,6 +250,7 @@ export class SessionManager {
|
|
|
242
250
|
}
|
|
243
251
|
while (true) {
|
|
244
252
|
const session = new InsecureSession({
|
|
253
|
+
crypto: this.#context.fabrics.crypto,
|
|
245
254
|
manager: this,
|
|
246
255
|
messageCounter: this.#globalUnencryptedMessageCounter,
|
|
247
256
|
initiatorNodeId,
|
|
@@ -284,6 +293,7 @@ export class SessionManager {
|
|
|
284
293
|
caseAuthenticatedTags,
|
|
285
294
|
} = args;
|
|
286
295
|
const session = await NodeSession.create({
|
|
296
|
+
crypto: this.crypto,
|
|
287
297
|
manager: this,
|
|
288
298
|
id: sessionId,
|
|
289
299
|
fabric,
|
|
@@ -698,7 +708,7 @@ export class SessionManager {
|
|
|
698
708
|
*/
|
|
699
709
|
compressIdRange(upperBound: number) {
|
|
700
710
|
this.#idUpperBound = upperBound;
|
|
701
|
-
this.#nextSessionId =
|
|
711
|
+
this.#nextSessionId = this.#context.fabrics.crypto.randomUint32 % upperBound;
|
|
702
712
|
if (this.#nextSessionId === 0) this.#nextSessionId++;
|
|
703
713
|
}
|
|
704
714
|
}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import { Bytes,
|
|
7
|
+
import { Bytes, Logger, PublicKey, UnexpectedDataError } from "#general";
|
|
8
8
|
import { ChannelStatusResponseError } from "#securechannel/index.js";
|
|
9
9
|
import { SessionManager } from "#session/SessionManager.js";
|
|
10
10
|
import { NodeId, ProtocolStatusCode } from "#types";
|
|
@@ -49,11 +49,13 @@ export class CaseClient {
|
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
async #doPair(messenger: CaseClientMessenger, exchange: MessageExchange, fabric: Fabric, peerNodeId: NodeId) {
|
|
52
|
+
const { crypto } = fabric;
|
|
53
|
+
|
|
52
54
|
// Generate pairing info
|
|
53
|
-
const initiatorRandom =
|
|
55
|
+
const initiatorRandom = crypto.randomBytes(32);
|
|
54
56
|
const initiatorSessionId = await this.#sessions.getNextAvailableSessionId(); // Initiator Session Id
|
|
55
57
|
const { operationalIdentityProtectionKey, operationalCert: localNoc, intermediateCACert: localIcac } = fabric;
|
|
56
|
-
const localKey = await
|
|
58
|
+
const localKey = await crypto.createKeyPair();
|
|
57
59
|
|
|
58
60
|
// Send sigma1
|
|
59
61
|
let sigma1Bytes;
|
|
@@ -61,12 +63,12 @@ export class CaseClient {
|
|
|
61
63
|
let resumptionRecord = this.#sessions.findResumptionRecordByAddress(fabric.addressOf(peerNodeId));
|
|
62
64
|
if (resumptionRecord !== undefined) {
|
|
63
65
|
const { sharedSecret, resumptionId } = resumptionRecord;
|
|
64
|
-
const resumeKey = await
|
|
66
|
+
const resumeKey = await crypto.createHkdfKey(
|
|
65
67
|
sharedSecret,
|
|
66
68
|
Bytes.concat(initiatorRandom, resumptionId),
|
|
67
69
|
KDFSR1_KEY_INFO,
|
|
68
70
|
);
|
|
69
|
-
const initiatorResumeMic =
|
|
71
|
+
const initiatorResumeMic = crypto.encrypt(resumeKey, new Uint8Array(0), RESUME1_MIC_NONCE);
|
|
70
72
|
sigma1Bytes = await messenger.sendSigma1({
|
|
71
73
|
initiatorSessionId,
|
|
72
74
|
destinationId: await fabric.currentDestinationIdFor(peerNodeId, initiatorRandom),
|
|
@@ -106,8 +108,8 @@ export class CaseClient {
|
|
|
106
108
|
};
|
|
107
109
|
|
|
108
110
|
const resumeSalt = Bytes.concat(initiatorRandom, resumptionId);
|
|
109
|
-
const resumeKey = await
|
|
110
|
-
|
|
111
|
+
const resumeKey = await crypto.createHkdfKey(sharedSecret, resumeSalt, KDFSR2_KEY_INFO);
|
|
112
|
+
crypto.decrypt(resumeKey, resumeMic, RESUME2_MIC_NONCE);
|
|
111
113
|
|
|
112
114
|
const secureSessionSalt = Bytes.concat(initiatorRandom, resumptionRecord.resumptionId);
|
|
113
115
|
secureSession = await this.#sessions.createSecureSession({
|
|
@@ -145,15 +147,15 @@ export class CaseClient {
|
|
|
145
147
|
...exchange.session.parameters,
|
|
146
148
|
...(responderSessionParams ?? {}),
|
|
147
149
|
};
|
|
148
|
-
const sharedSecret = await
|
|
150
|
+
const sharedSecret = await crypto.generateDhSecret(localKey, PublicKey(peerKey));
|
|
149
151
|
const sigma2Salt = Bytes.concat(
|
|
150
152
|
operationalIdentityProtectionKey,
|
|
151
153
|
responderRandom,
|
|
152
154
|
peerKey,
|
|
153
|
-
await
|
|
155
|
+
await crypto.computeSha256(sigma1Bytes),
|
|
154
156
|
);
|
|
155
|
-
const sigma2Key = await
|
|
156
|
-
const peerEncryptedData =
|
|
157
|
+
const sigma2Key = await crypto.createHkdfKey(sharedSecret, sigma2Salt, KDFSR2_INFO);
|
|
158
|
+
const peerEncryptedData = crypto.decrypt(sigma2Key, peerEncrypted, TBE_DATA2_NONCE);
|
|
157
159
|
const {
|
|
158
160
|
responderNoc: peerNoc,
|
|
159
161
|
responderIcac: peerIcac,
|
|
@@ -171,7 +173,7 @@ export class CaseClient {
|
|
|
171
173
|
subject: { fabricId: peerFabricIdNOCert, nodeId: peerNodeIdNOCert },
|
|
172
174
|
} = TlvOperationalCertificate.decode(peerNoc);
|
|
173
175
|
|
|
174
|
-
await
|
|
176
|
+
await crypto.verifyEcdsa(PublicKey(peerPublicKey), peerSignatureData, peerSignature);
|
|
175
177
|
|
|
176
178
|
if (peerNodeIdNOCert !== peerNodeId) {
|
|
177
179
|
throw new UnexpectedDataError(
|
|
@@ -199,9 +201,9 @@ export class CaseClient {
|
|
|
199
201
|
// Generate and send sigma3
|
|
200
202
|
const sigma3Salt = Bytes.concat(
|
|
201
203
|
operationalIdentityProtectionKey,
|
|
202
|
-
await
|
|
204
|
+
await crypto.computeSha256([sigma1Bytes, sigma2Bytes]),
|
|
203
205
|
);
|
|
204
|
-
const sigma3Key = await
|
|
206
|
+
const sigma3Key = await crypto.createHkdfKey(sharedSecret, sigma3Salt, KDFSR3_INFO);
|
|
205
207
|
const signatureData = TlvSignedData.encode({
|
|
206
208
|
responderNoc: localNoc,
|
|
207
209
|
responderIcac: localIcac,
|
|
@@ -214,7 +216,7 @@ export class CaseClient {
|
|
|
214
216
|
responderIcac: localIcac,
|
|
215
217
|
signature,
|
|
216
218
|
});
|
|
217
|
-
const encrypted =
|
|
219
|
+
const encrypted = crypto.encrypt(sigma3Key, encryptedData, TBE_DATA3_NONCE);
|
|
218
220
|
const sigma3Bytes = await messenger.sendSigma3({ encrypted });
|
|
219
221
|
await messenger.waitForSuccess("Sigma3-Success");
|
|
220
222
|
|
|
@@ -222,7 +224,7 @@ export class CaseClient {
|
|
|
222
224
|
const { caseAuthenticatedTags } = resumptionRecord ?? {}; // Even if resumption does not work try to reuse the caseAuthenticatedTags
|
|
223
225
|
const secureSessionSalt = Bytes.concat(
|
|
224
226
|
operationalIdentityProtectionKey,
|
|
225
|
-
await
|
|
227
|
+
await crypto.computeSha256([sigma1Bytes, sigma2Bytes, sigma3Bytes]),
|
|
226
228
|
);
|
|
227
229
|
secureSession = await this.#sessions.createSecureSession({
|
|
228
230
|
sessionId: initiatorSessionId,
|
|
@@ -73,7 +73,7 @@ export class CaseServer implements ProtocolHandler {
|
|
|
73
73
|
? this.#sessions.findResumptionRecordById(sigma1.resumptionId)
|
|
74
74
|
: undefined;
|
|
75
75
|
|
|
76
|
-
const context = new Sigma1Context(messenger, sigma1Bytes, sigma1, resumptionRecord);
|
|
76
|
+
const context = new Sigma1Context(this.#fabrics.crypto, messenger, sigma1Bytes, sigma1, resumptionRecord);
|
|
77
77
|
|
|
78
78
|
// Attempt resumption
|
|
79
79
|
if (await this.#resume(context)) {
|
|
@@ -100,14 +100,15 @@ export class CaseServer implements ProtocolHandler {
|
|
|
100
100
|
}
|
|
101
101
|
|
|
102
102
|
const { sharedSecret, fabric, peerNodeId, caseAuthenticatedTags } = cx.resumptionRecord;
|
|
103
|
-
const
|
|
103
|
+
const { crypto } = this.#fabrics;
|
|
104
|
+
const peerResumeKey = await crypto.createHkdfKey(
|
|
104
105
|
sharedSecret,
|
|
105
106
|
Bytes.concat(cx.peerRandom, cx.peerResumptionId),
|
|
106
107
|
KDFSR1_KEY_INFO,
|
|
107
108
|
);
|
|
108
109
|
|
|
109
110
|
try {
|
|
110
|
-
|
|
111
|
+
crypto.decrypt(peerResumeKey, cx.peerResumeMic, RESUME1_MIC_NONCE);
|
|
111
112
|
} catch (e) {
|
|
112
113
|
CryptoDecryptError.accept(e);
|
|
113
114
|
|
|
@@ -135,8 +136,8 @@ export class CaseServer implements ProtocolHandler {
|
|
|
135
136
|
|
|
136
137
|
// Generate sigma 2 resume
|
|
137
138
|
const resumeSalt = Bytes.concat(cx.peerRandom, cx.localResumptionId);
|
|
138
|
-
const resumeKey = await
|
|
139
|
-
const resumeMic =
|
|
139
|
+
const resumeKey = await crypto.createHkdfKey(sharedSecret, resumeSalt, KDFSR2_KEY_INFO);
|
|
140
|
+
const resumeMic = crypto.encrypt(resumeKey, new Uint8Array(0), RESUME2_MIC_NONCE);
|
|
140
141
|
try {
|
|
141
142
|
await cx.messenger.sendSigma2Resume({
|
|
142
143
|
resumptionId: cx.localResumptionId,
|
|
@@ -179,22 +180,23 @@ export class CaseServer implements ProtocolHandler {
|
|
|
179
180
|
}
|
|
180
181
|
|
|
181
182
|
// Generate pairing info
|
|
182
|
-
const
|
|
183
|
+
const { crypto } = this.#fabrics;
|
|
184
|
+
const responderRandom = crypto.randomBytes(32);
|
|
183
185
|
|
|
184
186
|
// TODO: Pass through a group id?
|
|
185
187
|
const fabric = await this.#fabrics.findFabricFromDestinationId(cx.destinationId, cx.peerRandom);
|
|
186
188
|
const { operationalCert: nodeOpCert, intermediateCACert, operationalIdentityProtectionKey } = fabric;
|
|
187
|
-
const key = await
|
|
189
|
+
const key = await crypto.createKeyPair();
|
|
188
190
|
const responderEcdhPublicKey = key.publicBits;
|
|
189
|
-
const sharedSecret = await
|
|
191
|
+
const sharedSecret = await crypto.generateDhSecret(key, PublicKey(cx.peerEcdhPublicKey));
|
|
190
192
|
|
|
191
193
|
const sigma2Salt = Bytes.concat(
|
|
192
194
|
operationalIdentityProtectionKey,
|
|
193
195
|
responderRandom,
|
|
194
196
|
responderEcdhPublicKey,
|
|
195
|
-
await
|
|
197
|
+
await crypto.computeSha256(cx.bytes),
|
|
196
198
|
);
|
|
197
|
-
const sigma2Key = await
|
|
199
|
+
const sigma2Key = await crypto.createHkdfKey(sharedSecret, sigma2Salt, KDFSR2_INFO);
|
|
198
200
|
const signatureData = TlvSignedData.encode({
|
|
199
201
|
responderNoc: nodeOpCert,
|
|
200
202
|
responderIcac: intermediateCACert,
|
|
@@ -208,7 +210,7 @@ export class CaseServer implements ProtocolHandler {
|
|
|
208
210
|
signature,
|
|
209
211
|
resumptionId: cx.localResumptionId,
|
|
210
212
|
});
|
|
211
|
-
const encrypted =
|
|
213
|
+
const encrypted = crypto.encrypt(sigma2Key, encryptedData, TBE_DATA2_NONCE);
|
|
212
214
|
const responderSessionId = await this.#sessions.getNextAvailableSessionId();
|
|
213
215
|
const sigma2Bytes = await cx.messenger.sendSigma2({
|
|
214
216
|
responderRandom,
|
|
@@ -225,10 +227,10 @@ export class CaseServer implements ProtocolHandler {
|
|
|
225
227
|
} = await cx.messenger.readSigma3();
|
|
226
228
|
const sigma3Salt = Bytes.concat(
|
|
227
229
|
operationalIdentityProtectionKey,
|
|
228
|
-
await
|
|
230
|
+
await crypto.computeSha256([cx.bytes, sigma2Bytes]),
|
|
229
231
|
);
|
|
230
|
-
const sigma3Key = await
|
|
231
|
-
const peerDecryptedData =
|
|
232
|
+
const sigma3Key = await crypto.createHkdfKey(sharedSecret, sigma3Salt, KDFSR3_INFO);
|
|
233
|
+
const peerDecryptedData = crypto.decrypt(sigma3Key, peerEncrypted, TBE_DATA3_NONCE);
|
|
232
234
|
const {
|
|
233
235
|
responderNoc: peerNewOpCert,
|
|
234
236
|
responderIcac: peerIntermediateCACert,
|
|
@@ -252,12 +254,12 @@ export class CaseServer implements ProtocolHandler {
|
|
|
252
254
|
throw new UnexpectedDataError(`Fabric ID mismatch: ${fabric.fabricId} !== ${peerFabricId}`);
|
|
253
255
|
}
|
|
254
256
|
|
|
255
|
-
await
|
|
257
|
+
await crypto.verifyEcdsa(PublicKey(peerPublicKey), peerSignatureData, peerSignature);
|
|
256
258
|
|
|
257
259
|
// All good! Create secure session
|
|
258
260
|
const secureSessionSalt = Bytes.concat(
|
|
259
261
|
operationalIdentityProtectionKey,
|
|
260
|
-
await
|
|
262
|
+
await crypto.computeSha256([cx.bytes, sigma2Bytes, sigma3Bytes]),
|
|
261
263
|
);
|
|
262
264
|
const secureSession = await this.#sessions.createSecureSession({
|
|
263
265
|
sessionId: responderSessionId,
|
|
@@ -301,6 +303,7 @@ export class CaseServer implements ProtocolHandler {
|
|
|
301
303
|
}
|
|
302
304
|
|
|
303
305
|
class Sigma1Context {
|
|
306
|
+
crypto: Crypto;
|
|
304
307
|
messenger: CaseServerMessenger;
|
|
305
308
|
bytes: Uint8Array;
|
|
306
309
|
peerSessionId: number;
|
|
@@ -315,11 +318,13 @@ class Sigma1Context {
|
|
|
315
318
|
#localResumptionId?: Uint8Array;
|
|
316
319
|
|
|
317
320
|
constructor(
|
|
321
|
+
crypto: Crypto,
|
|
318
322
|
messenger: CaseServerMessenger,
|
|
319
323
|
bytes: Uint8Array,
|
|
320
324
|
sigma1: TypeFromSchema<typeof TlvCaseSigma1>,
|
|
321
325
|
resumptionRecord?: ResumptionRecord,
|
|
322
326
|
) {
|
|
327
|
+
this.crypto = crypto;
|
|
323
328
|
this.messenger = messenger;
|
|
324
329
|
this.bytes = bytes;
|
|
325
330
|
this.peerSessionId = sigma1.initiatorSessionId;
|
|
@@ -333,6 +338,6 @@ class Sigma1Context {
|
|
|
333
338
|
}
|
|
334
339
|
|
|
335
340
|
get localResumptionId() {
|
|
336
|
-
return (this.#localResumptionId ??=
|
|
341
|
+
return (this.#localResumptionId ??= this.crypto.randomBytes(16));
|
|
337
342
|
}
|
|
338
343
|
}
|
|
@@ -22,27 +22,28 @@ export class PaseClient {
|
|
|
22
22
|
this.#sessions = sessions;
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
static async generatePakePasscodeVerifier(setupPinCode: number, pbkdfParameters: PbkdfParameters) {
|
|
26
|
-
const { w0, L } = await Spake2p.computeW0L(pbkdfParameters, setupPinCode);
|
|
25
|
+
static async generatePakePasscodeVerifier(crypto: Crypto, setupPinCode: number, pbkdfParameters: PbkdfParameters) {
|
|
26
|
+
const { w0, L } = await Spake2p.computeW0L(crypto, pbkdfParameters, setupPinCode);
|
|
27
27
|
return Bytes.concat(numberToBytesBE(w0, 32), L);
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
static generateRandomPasscode() {
|
|
30
|
+
static generateRandomPasscode(crypto: Crypto) {
|
|
31
31
|
let passcode: number;
|
|
32
|
-
passcode = (
|
|
32
|
+
passcode = (crypto.randomUint32 % 99999998) + 1; // prevents 00000000 and 99999999
|
|
33
33
|
if (CommissioningOptions.FORBIDDEN_PASSCODES.includes(passcode)) {
|
|
34
34
|
passcode += 1; // With current forbidden passcode list can never collide
|
|
35
35
|
}
|
|
36
36
|
return passcode;
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
static generateRandomDiscriminator() {
|
|
40
|
-
return
|
|
39
|
+
static generateRandomDiscriminator(crypto: Crypto) {
|
|
40
|
+
return crypto.randomUint16 % 4096;
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
async pair(sessionParameters: SessionParameters, exchange: MessageExchange, setupPin: number) {
|
|
44
44
|
const messenger = new PaseClientMessenger(exchange);
|
|
45
|
-
const
|
|
45
|
+
const { crypto } = this.#sessions;
|
|
46
|
+
const initiatorRandom = crypto.randomBytes(32);
|
|
46
47
|
const initiatorSessionId = await this.#sessions.getNextAvailableSessionId(); // Initiator Session Id
|
|
47
48
|
|
|
48
49
|
// Send pbkdfRequest and Read pbkdfResponse
|
|
@@ -80,9 +81,10 @@ export class PaseClient {
|
|
|
80
81
|
};
|
|
81
82
|
|
|
82
83
|
// Compute pake1 and read pake2
|
|
83
|
-
const { w0, w1 } = await Spake2p.computeW0W1(pbkdfParameters, setupPin);
|
|
84
|
+
const { w0, w1 } = await Spake2p.computeW0W1(crypto, pbkdfParameters, setupPin);
|
|
84
85
|
const spake2p = Spake2p.create(
|
|
85
|
-
|
|
86
|
+
crypto,
|
|
87
|
+
await crypto.computeSha256([SPAKE_CONTEXT, requestPayload, responsePayload]),
|
|
86
88
|
w0,
|
|
87
89
|
);
|
|
88
90
|
const X = spake2p.computeX();
|