@matter/protocol 0.15.0-alpha.0-20250613-a55f991d4 → 0.15.0-alpha.0-20250616-4b3754906

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (229) hide show
  1. package/dist/cjs/certificate/AttestationCertificateManager.d.ts +3 -3
  2. package/dist/cjs/certificate/AttestationCertificateManager.d.ts.map +1 -1
  3. package/dist/cjs/certificate/AttestationCertificateManager.js +12 -10
  4. package/dist/cjs/certificate/AttestationCertificateManager.js.map +1 -1
  5. package/dist/cjs/certificate/CertificateAuthority.d.ts +5 -3
  6. package/dist/cjs/certificate/CertificateAuthority.d.ts.map +1 -1
  7. package/dist/cjs/certificate/CertificateAuthority.js +19 -11
  8. package/dist/cjs/certificate/CertificateAuthority.js.map +1 -1
  9. package/dist/cjs/certificate/CertificateManager.d.ts +18 -15
  10. package/dist/cjs/certificate/CertificateManager.d.ts.map +1 -1
  11. package/dist/cjs/certificate/CertificateManager.js +92 -83
  12. package/dist/cjs/certificate/CertificateManager.js.map +2 -2
  13. package/dist/cjs/certificate/CertificationDeclarationManager.d.ts +7 -1
  14. package/dist/cjs/certificate/CertificationDeclarationManager.d.ts.map +1 -1
  15. package/dist/cjs/certificate/CertificationDeclarationManager.js +2 -2
  16. package/dist/cjs/certificate/CertificationDeclarationManager.js.map +1 -1
  17. package/dist/cjs/certificate/DeviceCertification.d.ts +2 -2
  18. package/dist/cjs/certificate/DeviceCertification.d.ts.map +1 -1
  19. package/dist/cjs/certificate/DeviceCertification.js +10 -4
  20. package/dist/cjs/certificate/DeviceCertification.js.map +1 -1
  21. package/dist/cjs/common/FailsafeContext.js +1 -1
  22. package/dist/cjs/common/FailsafeContext.js.map +1 -1
  23. package/dist/cjs/fabric/Fabric.d.ts +6 -4
  24. package/dist/cjs/fabric/Fabric.d.ts.map +1 -1
  25. package/dist/cjs/fabric/Fabric.js +33 -20
  26. package/dist/cjs/fabric/Fabric.js.map +1 -1
  27. package/dist/cjs/fabric/FabricAuthority.d.ts +1 -1
  28. package/dist/cjs/fabric/FabricAuthority.d.ts.map +1 -1
  29. package/dist/cjs/fabric/FabricAuthority.js +7 -7
  30. package/dist/cjs/fabric/FabricAuthority.js.map +1 -1
  31. package/dist/cjs/fabric/FabricManager.d.ts +3 -2
  32. package/dist/cjs/fabric/FabricManager.d.ts.map +1 -1
  33. package/dist/cjs/fabric/FabricManager.js +8 -3
  34. package/dist/cjs/fabric/FabricManager.js.map +1 -1
  35. package/dist/cjs/fabric/TestFabric.d.ts.map +1 -1
  36. package/dist/cjs/fabric/TestFabric.js +15 -19
  37. package/dist/cjs/fabric/TestFabric.js.map +1 -1
  38. package/dist/cjs/groups/FabricGroups.d.ts.map +1 -1
  39. package/dist/cjs/groups/FabricGroups.js +11 -7
  40. package/dist/cjs/groups/FabricGroups.js.map +1 -1
  41. package/dist/cjs/groups/KeySets.d.ts +2 -2
  42. package/dist/cjs/groups/KeySets.d.ts.map +1 -1
  43. package/dist/cjs/groups/KeySets.js +2 -2
  44. package/dist/cjs/groups/KeySets.js.map +1 -1
  45. package/dist/cjs/groups/MessagingState.d.ts +2 -2
  46. package/dist/cjs/groups/MessagingState.d.ts.map +1 -1
  47. package/dist/cjs/groups/MessagingState.js +4 -2
  48. package/dist/cjs/groups/MessagingState.js.map +1 -1
  49. package/dist/cjs/mdns/MdnsBroadcaster.d.ts +3 -3
  50. package/dist/cjs/mdns/MdnsBroadcaster.d.ts.map +1 -1
  51. package/dist/cjs/mdns/MdnsBroadcaster.js +7 -4
  52. package/dist/cjs/mdns/MdnsBroadcaster.js.map +1 -1
  53. package/dist/cjs/mdns/MdnsService.d.ts.map +1 -1
  54. package/dist/cjs/mdns/MdnsService.js +2 -1
  55. package/dist/cjs/mdns/MdnsService.js.map +1 -1
  56. package/dist/cjs/peer/ControllerCommissioner.js +1 -1
  57. package/dist/cjs/peer/ControllerCommissioner.js.map +1 -1
  58. package/dist/cjs/peer/ControllerCommissioningFlow.d.ts +1 -1
  59. package/dist/cjs/peer/ControllerCommissioningFlow.d.ts.map +1 -1
  60. package/dist/cjs/peer/ControllerCommissioningFlow.js +3 -4
  61. package/dist/cjs/peer/ControllerCommissioningFlow.js.map +1 -1
  62. package/dist/cjs/protocol/DeviceCommissioner.d.ts.map +1 -1
  63. package/dist/cjs/protocol/DeviceCommissioner.js +1 -1
  64. package/dist/cjs/protocol/DeviceCommissioner.js.map +1 -1
  65. package/dist/cjs/protocol/ExchangeManager.d.ts +4 -2
  66. package/dist/cjs/protocol/ExchangeManager.d.ts.map +1 -1
  67. package/dist/cjs/protocol/ExchangeManager.js +11 -6
  68. package/dist/cjs/protocol/ExchangeManager.js.map +1 -1
  69. package/dist/cjs/protocol/MessageCounter.d.ts +4 -4
  70. package/dist/cjs/protocol/MessageCounter.d.ts.map +1 -1
  71. package/dist/cjs/protocol/MessageCounter.js +7 -6
  72. package/dist/cjs/protocol/MessageCounter.js.map +1 -1
  73. package/dist/cjs/session/GroupSession.d.ts.map +1 -1
  74. package/dist/cjs/session/GroupSession.js +7 -2
  75. package/dist/cjs/session/GroupSession.js.map +1 -1
  76. package/dist/cjs/session/InsecureSession.d.ts +2 -0
  77. package/dist/cjs/session/InsecureSession.d.ts.map +1 -1
  78. package/dist/cjs/session/InsecureSession.js +2 -2
  79. package/dist/cjs/session/InsecureSession.js.map +1 -1
  80. package/dist/cjs/session/NodeSession.d.ts +3 -1
  81. package/dist/cjs/session/NodeSession.d.ts.map +1 -1
  82. package/dist/cjs/session/NodeSession.js +21 -13
  83. package/dist/cjs/session/NodeSession.js.map +1 -1
  84. package/dist/cjs/session/SessionManager.d.ts +1 -0
  85. package/dist/cjs/session/SessionManager.d.ts.map +1 -1
  86. package/dist/cjs/session/SessionManager.js +13 -3
  87. package/dist/cjs/session/SessionManager.js.map +1 -1
  88. package/dist/cjs/session/case/CaseClient.d.ts.map +1 -1
  89. package/dist/cjs/session/case/CaseClient.js +16 -15
  90. package/dist/cjs/session/case/CaseClient.js.map +1 -1
  91. package/dist/cjs/session/case/CaseServer.d.ts.map +1 -1
  92. package/dist/cjs/session/case/CaseServer.js +22 -18
  93. package/dist/cjs/session/case/CaseServer.js.map +1 -1
  94. package/dist/cjs/session/pase/PaseClient.d.ts +4 -4
  95. package/dist/cjs/session/pase/PaseClient.d.ts.map +1 -1
  96. package/dist/cjs/session/pase/PaseClient.js +11 -9
  97. package/dist/cjs/session/pase/PaseClient.js.map +1 -1
  98. package/dist/cjs/session/pase/PaseServer.d.ts.map +1 -1
  99. package/dist/cjs/session/pase/PaseServer.js +6 -5
  100. package/dist/cjs/session/pase/PaseServer.js.map +1 -1
  101. package/dist/esm/certificate/AttestationCertificateManager.d.ts +3 -3
  102. package/dist/esm/certificate/AttestationCertificateManager.d.ts.map +1 -1
  103. package/dist/esm/certificate/AttestationCertificateManager.js +13 -11
  104. package/dist/esm/certificate/AttestationCertificateManager.js.map +1 -1
  105. package/dist/esm/certificate/CertificateAuthority.d.ts +5 -3
  106. package/dist/esm/certificate/CertificateAuthority.d.ts.map +1 -1
  107. package/dist/esm/certificate/CertificateAuthority.js +19 -11
  108. package/dist/esm/certificate/CertificateAuthority.js.map +1 -1
  109. package/dist/esm/certificate/CertificateManager.d.ts +18 -15
  110. package/dist/esm/certificate/CertificateManager.d.ts.map +1 -1
  111. package/dist/esm/certificate/CertificateManager.js +92 -84
  112. package/dist/esm/certificate/CertificateManager.js.map +2 -2
  113. package/dist/esm/certificate/CertificationDeclarationManager.d.ts +7 -1
  114. package/dist/esm/certificate/CertificationDeclarationManager.d.ts.map +1 -1
  115. package/dist/esm/certificate/CertificationDeclarationManager.js +2 -2
  116. package/dist/esm/certificate/CertificationDeclarationManager.js.map +1 -1
  117. package/dist/esm/certificate/DeviceCertification.d.ts +2 -2
  118. package/dist/esm/certificate/DeviceCertification.d.ts.map +1 -1
  119. package/dist/esm/certificate/DeviceCertification.js +11 -5
  120. package/dist/esm/certificate/DeviceCertification.js.map +1 -1
  121. package/dist/esm/common/FailsafeContext.js +1 -1
  122. package/dist/esm/common/FailsafeContext.js.map +1 -1
  123. package/dist/esm/fabric/Fabric.d.ts +6 -4
  124. package/dist/esm/fabric/Fabric.d.ts.map +1 -1
  125. package/dist/esm/fabric/Fabric.js +33 -21
  126. package/dist/esm/fabric/Fabric.js.map +1 -1
  127. package/dist/esm/fabric/FabricAuthority.d.ts +1 -1
  128. package/dist/esm/fabric/FabricAuthority.d.ts.map +1 -1
  129. package/dist/esm/fabric/FabricAuthority.js +8 -15
  130. package/dist/esm/fabric/FabricAuthority.js.map +1 -1
  131. package/dist/esm/fabric/FabricManager.d.ts +3 -2
  132. package/dist/esm/fabric/FabricManager.d.ts.map +1 -1
  133. package/dist/esm/fabric/FabricManager.js +9 -3
  134. package/dist/esm/fabric/FabricManager.js.map +1 -1
  135. package/dist/esm/fabric/TestFabric.d.ts.map +1 -1
  136. package/dist/esm/fabric/TestFabric.js +16 -20
  137. package/dist/esm/fabric/TestFabric.js.map +1 -1
  138. package/dist/esm/groups/FabricGroups.d.ts.map +1 -1
  139. package/dist/esm/groups/FabricGroups.js +12 -8
  140. package/dist/esm/groups/FabricGroups.js.map +1 -1
  141. package/dist/esm/groups/KeySets.d.ts +2 -2
  142. package/dist/esm/groups/KeySets.d.ts.map +1 -1
  143. package/dist/esm/groups/KeySets.js +3 -3
  144. package/dist/esm/groups/KeySets.js.map +1 -1
  145. package/dist/esm/groups/MessagingState.d.ts +2 -2
  146. package/dist/esm/groups/MessagingState.d.ts.map +1 -1
  147. package/dist/esm/groups/MessagingState.js +4 -2
  148. package/dist/esm/groups/MessagingState.js.map +1 -1
  149. package/dist/esm/mdns/MdnsBroadcaster.d.ts +3 -3
  150. package/dist/esm/mdns/MdnsBroadcaster.d.ts.map +1 -1
  151. package/dist/esm/mdns/MdnsBroadcaster.js +7 -5
  152. package/dist/esm/mdns/MdnsBroadcaster.js.map +1 -1
  153. package/dist/esm/mdns/MdnsService.d.ts.map +1 -1
  154. package/dist/esm/mdns/MdnsService.js +3 -1
  155. package/dist/esm/mdns/MdnsService.js.map +1 -1
  156. package/dist/esm/peer/ControllerCommissioner.js +1 -1
  157. package/dist/esm/peer/ControllerCommissioner.js.map +1 -1
  158. package/dist/esm/peer/ControllerCommissioningFlow.d.ts +1 -1
  159. package/dist/esm/peer/ControllerCommissioningFlow.d.ts.map +1 -1
  160. package/dist/esm/peer/ControllerCommissioningFlow.js +3 -5
  161. package/dist/esm/peer/ControllerCommissioningFlow.js.map +1 -1
  162. package/dist/esm/protocol/DeviceCommissioner.d.ts.map +1 -1
  163. package/dist/esm/protocol/DeviceCommissioner.js +1 -2
  164. package/dist/esm/protocol/DeviceCommissioner.js.map +1 -1
  165. package/dist/esm/protocol/ExchangeManager.d.ts +4 -2
  166. package/dist/esm/protocol/ExchangeManager.d.ts.map +1 -1
  167. package/dist/esm/protocol/ExchangeManager.js +11 -6
  168. package/dist/esm/protocol/ExchangeManager.js.map +1 -1
  169. package/dist/esm/protocol/MessageCounter.d.ts +4 -4
  170. package/dist/esm/protocol/MessageCounter.d.ts.map +1 -1
  171. package/dist/esm/protocol/MessageCounter.js +8 -7
  172. package/dist/esm/protocol/MessageCounter.js.map +1 -1
  173. package/dist/esm/session/GroupSession.d.ts.map +1 -1
  174. package/dist/esm/session/GroupSession.js +7 -3
  175. package/dist/esm/session/GroupSession.js.map +1 -1
  176. package/dist/esm/session/InsecureSession.d.ts +2 -0
  177. package/dist/esm/session/InsecureSession.d.ts.map +1 -1
  178. package/dist/esm/session/InsecureSession.js +2 -2
  179. package/dist/esm/session/InsecureSession.js.map +1 -1
  180. package/dist/esm/session/NodeSession.d.ts +3 -1
  181. package/dist/esm/session/NodeSession.d.ts.map +1 -1
  182. package/dist/esm/session/NodeSession.js +22 -14
  183. package/dist/esm/session/NodeSession.js.map +1 -1
  184. package/dist/esm/session/SessionManager.d.ts +1 -0
  185. package/dist/esm/session/SessionManager.d.ts.map +1 -1
  186. package/dist/esm/session/SessionManager.js +13 -4
  187. package/dist/esm/session/SessionManager.js.map +1 -1
  188. package/dist/esm/session/case/CaseClient.d.ts.map +1 -1
  189. package/dist/esm/session/case/CaseClient.js +17 -16
  190. package/dist/esm/session/case/CaseClient.js.map +1 -1
  191. package/dist/esm/session/case/CaseServer.d.ts.map +1 -1
  192. package/dist/esm/session/case/CaseServer.js +23 -19
  193. package/dist/esm/session/case/CaseServer.js.map +1 -1
  194. package/dist/esm/session/pase/PaseClient.d.ts +4 -4
  195. package/dist/esm/session/pase/PaseClient.d.ts.map +1 -1
  196. package/dist/esm/session/pase/PaseClient.js +12 -10
  197. package/dist/esm/session/pase/PaseClient.js.map +1 -1
  198. package/dist/esm/session/pase/PaseServer.d.ts.map +1 -1
  199. package/dist/esm/session/pase/PaseServer.js +6 -6
  200. package/dist/esm/session/pase/PaseServer.js.map +1 -1
  201. package/package.json +6 -6
  202. package/src/certificate/AttestationCertificateManager.ts +12 -10
  203. package/src/certificate/CertificateAuthority.ts +20 -11
  204. package/src/certificate/CertificateManager.ts +77 -72
  205. package/src/certificate/CertificationDeclarationManager.ts +3 -3
  206. package/src/certificate/DeviceCertification.ts +10 -4
  207. package/src/common/FailsafeContext.ts +1 -1
  208. package/src/fabric/Fabric.ts +36 -20
  209. package/src/fabric/FabricAuthority.ts +8 -16
  210. package/src/fabric/FabricManager.ts +10 -3
  211. package/src/fabric/TestFabric.ts +17 -22
  212. package/src/groups/FabricGroups.ts +20 -8
  213. package/src/groups/KeySets.ts +2 -2
  214. package/src/groups/MessagingState.ts +6 -3
  215. package/src/mdns/MdnsBroadcaster.ts +11 -4
  216. package/src/mdns/MdnsService.ts +3 -1
  217. package/src/peer/ControllerCommissioner.ts +1 -1
  218. package/src/peer/ControllerCommissioningFlow.ts +4 -6
  219. package/src/protocol/DeviceCommissioner.ts +1 -2
  220. package/src/protocol/ExchangeManager.ts +13 -6
  221. package/src/protocol/MessageCounter.ts +11 -3
  222. package/src/session/GroupSession.ts +7 -3
  223. package/src/session/InsecureSession.ts +4 -3
  224. package/src/session/NodeSession.ts +25 -14
  225. package/src/session/SessionManager.ts +14 -4
  226. package/src/session/case/CaseClient.ts +18 -16
  227. package/src/session/case/CaseServer.ts +22 -17
  228. package/src/session/pase/PaseClient.ts +11 -9
  229. package/src/session/pase/PaseServer.ts +6 -5
@@ -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 Crypto.createHkdfKey(
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: Crypto.decrypt(this.#decryptKey, applicationPayload, nonce, aad),
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 { header, applicationPayload: Crypto.encrypt(this.#encryptKey, applicationPayload, nonce, headerBytes) };
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 = Crypto.getRandomUInt16();
126
+ #nextSessionId: number;
128
127
  #resumptionRecords = new PeerAddressMap<ResumptionRecord>();
129
- readonly #globalUnencryptedMessageCounter = new MessageCounter();
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 = Crypto.getRandomUInt32() % upperBound;
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, Crypto, Logger, PublicKey, UnexpectedDataError } from "#general";
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 = Crypto.getRandom();
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 Crypto.createKeyPair();
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 Crypto.createHkdfKey(
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 = Crypto.encrypt(resumeKey, new Uint8Array(0), RESUME1_MIC_NONCE);
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 Crypto.createHkdfKey(sharedSecret, resumeSalt, KDFSR2_KEY_INFO);
110
- Crypto.decrypt(resumeKey, resumeMic, RESUME2_MIC_NONCE);
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 Crypto.generateDhSecret(localKey, PublicKey(peerKey));
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 Crypto.computeSha256(sigma1Bytes),
155
+ await crypto.computeSha256(sigma1Bytes),
154
156
  );
155
- const sigma2Key = await Crypto.createHkdfKey(sharedSecret, sigma2Salt, KDFSR2_INFO);
156
- const peerEncryptedData = Crypto.decrypt(sigma2Key, peerEncrypted, TBE_DATA2_NONCE);
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 Crypto.verifyEcdsa(PublicKey(peerPublicKey), peerSignatureData, peerSignature);
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 Crypto.computeSha256([sigma1Bytes, sigma2Bytes]),
204
+ await crypto.computeSha256([sigma1Bytes, sigma2Bytes]),
203
205
  );
204
- const sigma3Key = await Crypto.createHkdfKey(sharedSecret, sigma3Salt, KDFSR3_INFO);
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 = Crypto.encrypt(sigma3Key, encryptedData, TBE_DATA3_NONCE);
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 Crypto.computeSha256([sigma1Bytes, sigma2Bytes, sigma3Bytes]),
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 peerResumeKey = await Crypto.createHkdfKey(
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
- Crypto.decrypt(peerResumeKey, cx.peerResumeMic, RESUME1_MIC_NONCE);
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 Crypto.createHkdfKey(sharedSecret, resumeSalt, KDFSR2_KEY_INFO);
139
- const resumeMic = Crypto.encrypt(resumeKey, new Uint8Array(0), RESUME2_MIC_NONCE);
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 responderRandom = Crypto.getRandom();
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 Crypto.createKeyPair();
189
+ const key = await crypto.createKeyPair();
188
190
  const responderEcdhPublicKey = key.publicBits;
189
- const sharedSecret = await Crypto.generateDhSecret(key, PublicKey(cx.peerEcdhPublicKey));
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 Crypto.computeSha256(cx.bytes),
197
+ await crypto.computeSha256(cx.bytes),
196
198
  );
197
- const sigma2Key = await Crypto.createHkdfKey(sharedSecret, sigma2Salt, KDFSR2_INFO);
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 = Crypto.encrypt(sigma2Key, encryptedData, TBE_DATA2_NONCE);
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 Crypto.computeSha256([cx.bytes, sigma2Bytes]),
230
+ await crypto.computeSha256([cx.bytes, sigma2Bytes]),
229
231
  );
230
- const sigma3Key = await Crypto.createHkdfKey(sharedSecret, sigma3Salt, KDFSR3_INFO);
231
- const peerDecryptedData = Crypto.decrypt(sigma3Key, peerEncrypted, TBE_DATA3_NONCE);
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 Crypto.verifyEcdsa(PublicKey(peerPublicKey), peerSignatureData, peerSignature);
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 Crypto.computeSha256([cx.bytes, sigma2Bytes, sigma3Bytes]),
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 ??= Crypto.getRandomData(16));
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 = (Crypto.getRandomUInt32() % 99999998) + 1; // prevents 00000000 and 99999999
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 Crypto.getRandomUInt16() % 4096;
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 initiatorRandom = Crypto.getRandom();
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
- await Crypto.computeSha256([SPAKE_CONTEXT, requestPayload, responsePayload]),
86
+ crypto,
87
+ await crypto.computeSha256([SPAKE_CONTEXT, requestPayload, responsePayload]),
86
88
  w0,
87
89
  );
88
90
  const X = spake2p.computeX();
@@ -40,7 +40,7 @@ export class PaseServer implements ProtocolHandler {
40
40
  #pairingErrors = 0;
41
41
 
42
42
  static async fromPin(sessions: SessionManager, setupPinCode: number, pbkdfParameters: PbkdfParameters) {
43
- const { w0, L } = await Spake2p.computeW0L(pbkdfParameters, setupPinCode);
43
+ const { w0, L } = await Spake2p.computeW0L(sessions.crypto, pbkdfParameters, setupPinCode);
44
44
  return new PaseServer(sessions, w0, L, pbkdfParameters);
45
45
  }
46
46
 
@@ -76,7 +76,7 @@ export class PaseServer implements ProtocolHandler {
76
76
  );
77
77
  } else {
78
78
  // Ok new pairing try, handle it
79
- await this.handlePairingRequest(messenger);
79
+ await this.handlePairingRequest(this.sessions.crypto, messenger);
80
80
  }
81
81
  } catch (error) {
82
82
  this.#pairingErrors++;
@@ -100,7 +100,7 @@ export class PaseServer implements ProtocolHandler {
100
100
  }
101
101
  }
102
102
 
103
- private async handlePairingRequest(messenger: PaseServerMessenger) {
103
+ private async handlePairingRequest(crypto: Crypto, messenger: PaseServerMessenger) {
104
104
  logger.info(`Received pairing request from ${messenger.getChannelName()}.`);
105
105
 
106
106
  this.#pairingTimer = Time.getTimer("PASE pairing timeout", PASE_PAIRING_TIMEOUT_MS, () =>
@@ -123,7 +123,7 @@ export class PaseServer implements ProtocolHandler {
123
123
  }
124
124
 
125
125
  const responderSessionId = await this.sessions.getNextAvailableSessionId(); // Responder Session Id
126
- const responderRandom = Crypto.getRandom();
126
+ const responderRandom = crypto.randomBytes(32);
127
127
 
128
128
  const responderSessionParams = this.sessions.sessionParameters;
129
129
  const tcpSupported =
@@ -145,7 +145,8 @@ export class PaseServer implements ProtocolHandler {
145
145
 
146
146
  // Process pake1 and send pake2
147
147
  const spake2p = Spake2p.create(
148
- await Crypto.computeSha256([SPAKE_CONTEXT, requestPayload, responsePayload]),
148
+ crypto,
149
+ await crypto.computeSha256([SPAKE_CONTEXT, requestPayload, responsePayload]),
149
150
  this.w0,
150
151
  );
151
152
  const { x: X } = await messenger.readPasePake1();