@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.
Files changed (252) 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/events/OccurrenceManager.d.ts +1 -0
  24. package/dist/cjs/events/OccurrenceManager.d.ts.map +1 -1
  25. package/dist/cjs/events/OccurrenceManager.js +14 -8
  26. package/dist/cjs/events/OccurrenceManager.js.map +1 -1
  27. package/dist/cjs/fabric/Fabric.d.ts +6 -4
  28. package/dist/cjs/fabric/Fabric.d.ts.map +1 -1
  29. package/dist/cjs/fabric/Fabric.js +33 -20
  30. package/dist/cjs/fabric/Fabric.js.map +1 -1
  31. package/dist/cjs/fabric/FabricAuthority.d.ts +1 -1
  32. package/dist/cjs/fabric/FabricAuthority.d.ts.map +1 -1
  33. package/dist/cjs/fabric/FabricAuthority.js +7 -7
  34. package/dist/cjs/fabric/FabricAuthority.js.map +1 -1
  35. package/dist/cjs/fabric/FabricManager.d.ts +3 -2
  36. package/dist/cjs/fabric/FabricManager.d.ts.map +1 -1
  37. package/dist/cjs/fabric/FabricManager.js +8 -3
  38. package/dist/cjs/fabric/FabricManager.js.map +1 -1
  39. package/dist/cjs/fabric/TestFabric.d.ts.map +1 -1
  40. package/dist/cjs/fabric/TestFabric.js +15 -19
  41. package/dist/cjs/fabric/TestFabric.js.map +1 -1
  42. package/dist/cjs/groups/FabricGroups.d.ts.map +1 -1
  43. package/dist/cjs/groups/FabricGroups.js +11 -7
  44. package/dist/cjs/groups/FabricGroups.js.map +1 -1
  45. package/dist/cjs/groups/KeySets.d.ts +2 -2
  46. package/dist/cjs/groups/KeySets.d.ts.map +1 -1
  47. package/dist/cjs/groups/KeySets.js +2 -2
  48. package/dist/cjs/groups/KeySets.js.map +1 -1
  49. package/dist/cjs/groups/MessagingState.d.ts +2 -2
  50. package/dist/cjs/groups/MessagingState.d.ts.map +1 -1
  51. package/dist/cjs/groups/MessagingState.js +4 -2
  52. package/dist/cjs/groups/MessagingState.js.map +1 -1
  53. package/dist/cjs/interaction/FabricAccessControl.js +1 -1
  54. package/dist/cjs/interaction/FabricAccessControl.js.map +1 -1
  55. package/dist/cjs/mdns/MdnsBroadcaster.d.ts +3 -3
  56. package/dist/cjs/mdns/MdnsBroadcaster.d.ts.map +1 -1
  57. package/dist/cjs/mdns/MdnsBroadcaster.js +7 -4
  58. package/dist/cjs/mdns/MdnsBroadcaster.js.map +1 -1
  59. package/dist/cjs/mdns/MdnsScanner.d.ts +1 -1
  60. package/dist/cjs/mdns/MdnsScanner.d.ts.map +1 -1
  61. package/dist/cjs/mdns/MdnsScanner.js +2 -6
  62. package/dist/cjs/mdns/MdnsScanner.js.map +1 -1
  63. package/dist/cjs/mdns/MdnsService.d.ts.map +1 -1
  64. package/dist/cjs/mdns/MdnsService.js +2 -1
  65. package/dist/cjs/mdns/MdnsService.js.map +1 -1
  66. package/dist/cjs/peer/ControllerCommissioner.js +1 -1
  67. package/dist/cjs/peer/ControllerCommissioner.js.map +1 -1
  68. package/dist/cjs/peer/ControllerCommissioningFlow.d.ts +1 -1
  69. package/dist/cjs/peer/ControllerCommissioningFlow.d.ts.map +1 -1
  70. package/dist/cjs/peer/ControllerCommissioningFlow.js +3 -4
  71. package/dist/cjs/peer/ControllerCommissioningFlow.js.map +1 -1
  72. package/dist/cjs/protocol/DeviceCommissioner.d.ts.map +1 -1
  73. package/dist/cjs/protocol/DeviceCommissioner.js +1 -1
  74. package/dist/cjs/protocol/DeviceCommissioner.js.map +1 -1
  75. package/dist/cjs/protocol/ExchangeManager.d.ts +4 -2
  76. package/dist/cjs/protocol/ExchangeManager.d.ts.map +1 -1
  77. package/dist/cjs/protocol/ExchangeManager.js +11 -6
  78. package/dist/cjs/protocol/ExchangeManager.js.map +1 -1
  79. package/dist/cjs/protocol/MessageCounter.d.ts +4 -4
  80. package/dist/cjs/protocol/MessageCounter.d.ts.map +1 -1
  81. package/dist/cjs/protocol/MessageCounter.js +7 -6
  82. package/dist/cjs/protocol/MessageCounter.js.map +1 -1
  83. package/dist/cjs/session/GroupSession.d.ts.map +1 -1
  84. package/dist/cjs/session/GroupSession.js +7 -2
  85. package/dist/cjs/session/GroupSession.js.map +1 -1
  86. package/dist/cjs/session/InsecureSession.d.ts +2 -0
  87. package/dist/cjs/session/InsecureSession.d.ts.map +1 -1
  88. package/dist/cjs/session/InsecureSession.js +2 -2
  89. package/dist/cjs/session/InsecureSession.js.map +1 -1
  90. package/dist/cjs/session/NodeSession.d.ts +3 -1
  91. package/dist/cjs/session/NodeSession.d.ts.map +1 -1
  92. package/dist/cjs/session/NodeSession.js +21 -13
  93. package/dist/cjs/session/NodeSession.js.map +1 -1
  94. package/dist/cjs/session/SessionManager.d.ts +1 -0
  95. package/dist/cjs/session/SessionManager.d.ts.map +1 -1
  96. package/dist/cjs/session/SessionManager.js +13 -3
  97. package/dist/cjs/session/SessionManager.js.map +1 -1
  98. package/dist/cjs/session/case/CaseClient.d.ts.map +1 -1
  99. package/dist/cjs/session/case/CaseClient.js +16 -15
  100. package/dist/cjs/session/case/CaseClient.js.map +1 -1
  101. package/dist/cjs/session/case/CaseServer.d.ts.map +1 -1
  102. package/dist/cjs/session/case/CaseServer.js +22 -18
  103. package/dist/cjs/session/case/CaseServer.js.map +1 -1
  104. package/dist/cjs/session/pase/PaseClient.d.ts +4 -4
  105. package/dist/cjs/session/pase/PaseClient.d.ts.map +1 -1
  106. package/dist/cjs/session/pase/PaseClient.js +11 -9
  107. package/dist/cjs/session/pase/PaseClient.js.map +1 -1
  108. package/dist/cjs/session/pase/PaseServer.d.ts.map +1 -1
  109. package/dist/cjs/session/pase/PaseServer.js +6 -5
  110. package/dist/cjs/session/pase/PaseServer.js.map +1 -1
  111. package/dist/esm/certificate/AttestationCertificateManager.d.ts +3 -3
  112. package/dist/esm/certificate/AttestationCertificateManager.d.ts.map +1 -1
  113. package/dist/esm/certificate/AttestationCertificateManager.js +13 -11
  114. package/dist/esm/certificate/AttestationCertificateManager.js.map +1 -1
  115. package/dist/esm/certificate/CertificateAuthority.d.ts +5 -3
  116. package/dist/esm/certificate/CertificateAuthority.d.ts.map +1 -1
  117. package/dist/esm/certificate/CertificateAuthority.js +19 -11
  118. package/dist/esm/certificate/CertificateAuthority.js.map +1 -1
  119. package/dist/esm/certificate/CertificateManager.d.ts +18 -15
  120. package/dist/esm/certificate/CertificateManager.d.ts.map +1 -1
  121. package/dist/esm/certificate/CertificateManager.js +92 -84
  122. package/dist/esm/certificate/CertificateManager.js.map +2 -2
  123. package/dist/esm/certificate/CertificationDeclarationManager.d.ts +7 -1
  124. package/dist/esm/certificate/CertificationDeclarationManager.d.ts.map +1 -1
  125. package/dist/esm/certificate/CertificationDeclarationManager.js +2 -2
  126. package/dist/esm/certificate/CertificationDeclarationManager.js.map +1 -1
  127. package/dist/esm/certificate/DeviceCertification.d.ts +2 -2
  128. package/dist/esm/certificate/DeviceCertification.d.ts.map +1 -1
  129. package/dist/esm/certificate/DeviceCertification.js +11 -5
  130. package/dist/esm/certificate/DeviceCertification.js.map +1 -1
  131. package/dist/esm/common/FailsafeContext.js +1 -1
  132. package/dist/esm/common/FailsafeContext.js.map +1 -1
  133. package/dist/esm/events/OccurrenceManager.d.ts +1 -0
  134. package/dist/esm/events/OccurrenceManager.d.ts.map +1 -1
  135. package/dist/esm/events/OccurrenceManager.js +14 -8
  136. package/dist/esm/events/OccurrenceManager.js.map +1 -1
  137. package/dist/esm/fabric/Fabric.d.ts +6 -4
  138. package/dist/esm/fabric/Fabric.d.ts.map +1 -1
  139. package/dist/esm/fabric/Fabric.js +33 -21
  140. package/dist/esm/fabric/Fabric.js.map +1 -1
  141. package/dist/esm/fabric/FabricAuthority.d.ts +1 -1
  142. package/dist/esm/fabric/FabricAuthority.d.ts.map +1 -1
  143. package/dist/esm/fabric/FabricAuthority.js +8 -15
  144. package/dist/esm/fabric/FabricAuthority.js.map +1 -1
  145. package/dist/esm/fabric/FabricManager.d.ts +3 -2
  146. package/dist/esm/fabric/FabricManager.d.ts.map +1 -1
  147. package/dist/esm/fabric/FabricManager.js +9 -3
  148. package/dist/esm/fabric/FabricManager.js.map +1 -1
  149. package/dist/esm/fabric/TestFabric.d.ts.map +1 -1
  150. package/dist/esm/fabric/TestFabric.js +16 -20
  151. package/dist/esm/fabric/TestFabric.js.map +1 -1
  152. package/dist/esm/groups/FabricGroups.d.ts.map +1 -1
  153. package/dist/esm/groups/FabricGroups.js +12 -8
  154. package/dist/esm/groups/FabricGroups.js.map +1 -1
  155. package/dist/esm/groups/KeySets.d.ts +2 -2
  156. package/dist/esm/groups/KeySets.d.ts.map +1 -1
  157. package/dist/esm/groups/KeySets.js +3 -3
  158. package/dist/esm/groups/KeySets.js.map +1 -1
  159. package/dist/esm/groups/MessagingState.d.ts +2 -2
  160. package/dist/esm/groups/MessagingState.d.ts.map +1 -1
  161. package/dist/esm/groups/MessagingState.js +4 -2
  162. package/dist/esm/groups/MessagingState.js.map +1 -1
  163. package/dist/esm/interaction/FabricAccessControl.js +1 -1
  164. package/dist/esm/interaction/FabricAccessControl.js.map +1 -1
  165. package/dist/esm/mdns/MdnsBroadcaster.d.ts +3 -3
  166. package/dist/esm/mdns/MdnsBroadcaster.d.ts.map +1 -1
  167. package/dist/esm/mdns/MdnsBroadcaster.js +7 -5
  168. package/dist/esm/mdns/MdnsBroadcaster.js.map +1 -1
  169. package/dist/esm/mdns/MdnsScanner.d.ts +1 -1
  170. package/dist/esm/mdns/MdnsScanner.d.ts.map +1 -1
  171. package/dist/esm/mdns/MdnsScanner.js +2 -6
  172. package/dist/esm/mdns/MdnsScanner.js.map +1 -1
  173. package/dist/esm/mdns/MdnsService.d.ts.map +1 -1
  174. package/dist/esm/mdns/MdnsService.js +3 -1
  175. package/dist/esm/mdns/MdnsService.js.map +1 -1
  176. package/dist/esm/peer/ControllerCommissioner.js +1 -1
  177. package/dist/esm/peer/ControllerCommissioner.js.map +1 -1
  178. package/dist/esm/peer/ControllerCommissioningFlow.d.ts +1 -1
  179. package/dist/esm/peer/ControllerCommissioningFlow.d.ts.map +1 -1
  180. package/dist/esm/peer/ControllerCommissioningFlow.js +3 -5
  181. package/dist/esm/peer/ControllerCommissioningFlow.js.map +1 -1
  182. package/dist/esm/protocol/DeviceCommissioner.d.ts.map +1 -1
  183. package/dist/esm/protocol/DeviceCommissioner.js +1 -2
  184. package/dist/esm/protocol/DeviceCommissioner.js.map +1 -1
  185. package/dist/esm/protocol/ExchangeManager.d.ts +4 -2
  186. package/dist/esm/protocol/ExchangeManager.d.ts.map +1 -1
  187. package/dist/esm/protocol/ExchangeManager.js +11 -6
  188. package/dist/esm/protocol/ExchangeManager.js.map +1 -1
  189. package/dist/esm/protocol/MessageCounter.d.ts +4 -4
  190. package/dist/esm/protocol/MessageCounter.d.ts.map +1 -1
  191. package/dist/esm/protocol/MessageCounter.js +8 -7
  192. package/dist/esm/protocol/MessageCounter.js.map +1 -1
  193. package/dist/esm/session/GroupSession.d.ts.map +1 -1
  194. package/dist/esm/session/GroupSession.js +7 -3
  195. package/dist/esm/session/GroupSession.js.map +1 -1
  196. package/dist/esm/session/InsecureSession.d.ts +2 -0
  197. package/dist/esm/session/InsecureSession.d.ts.map +1 -1
  198. package/dist/esm/session/InsecureSession.js +2 -2
  199. package/dist/esm/session/InsecureSession.js.map +1 -1
  200. package/dist/esm/session/NodeSession.d.ts +3 -1
  201. package/dist/esm/session/NodeSession.d.ts.map +1 -1
  202. package/dist/esm/session/NodeSession.js +22 -14
  203. package/dist/esm/session/NodeSession.js.map +1 -1
  204. package/dist/esm/session/SessionManager.d.ts +1 -0
  205. package/dist/esm/session/SessionManager.d.ts.map +1 -1
  206. package/dist/esm/session/SessionManager.js +13 -4
  207. package/dist/esm/session/SessionManager.js.map +1 -1
  208. package/dist/esm/session/case/CaseClient.d.ts.map +1 -1
  209. package/dist/esm/session/case/CaseClient.js +17 -16
  210. package/dist/esm/session/case/CaseClient.js.map +1 -1
  211. package/dist/esm/session/case/CaseServer.d.ts.map +1 -1
  212. package/dist/esm/session/case/CaseServer.js +23 -19
  213. package/dist/esm/session/case/CaseServer.js.map +1 -1
  214. package/dist/esm/session/pase/PaseClient.d.ts +4 -4
  215. package/dist/esm/session/pase/PaseClient.d.ts.map +1 -1
  216. package/dist/esm/session/pase/PaseClient.js +12 -10
  217. package/dist/esm/session/pase/PaseClient.js.map +1 -1
  218. package/dist/esm/session/pase/PaseServer.d.ts.map +1 -1
  219. package/dist/esm/session/pase/PaseServer.js +6 -6
  220. package/dist/esm/session/pase/PaseServer.js.map +1 -1
  221. package/package.json +6 -6
  222. package/src/certificate/AttestationCertificateManager.ts +12 -10
  223. package/src/certificate/CertificateAuthority.ts +20 -11
  224. package/src/certificate/CertificateManager.ts +77 -72
  225. package/src/certificate/CertificationDeclarationManager.ts +3 -3
  226. package/src/certificate/DeviceCertification.ts +10 -4
  227. package/src/common/FailsafeContext.ts +1 -1
  228. package/src/events/OccurrenceManager.ts +16 -9
  229. package/src/fabric/Fabric.ts +36 -20
  230. package/src/fabric/FabricAuthority.ts +8 -16
  231. package/src/fabric/FabricManager.ts +10 -3
  232. package/src/fabric/TestFabric.ts +17 -22
  233. package/src/groups/FabricGroups.ts +20 -8
  234. package/src/groups/KeySets.ts +2 -2
  235. package/src/groups/MessagingState.ts +6 -3
  236. package/src/interaction/FabricAccessControl.ts +1 -1
  237. package/src/mdns/MdnsBroadcaster.ts +11 -4
  238. package/src/mdns/MdnsScanner.ts +2 -6
  239. package/src/mdns/MdnsService.ts +3 -1
  240. package/src/peer/ControllerCommissioner.ts +1 -1
  241. package/src/peer/ControllerCommissioningFlow.ts +4 -6
  242. package/src/protocol/DeviceCommissioner.ts +1 -2
  243. package/src/protocol/ExchangeManager.ts +13 -6
  244. package/src/protocol/MessageCounter.ts +11 -3
  245. package/src/session/GroupSession.ts +7 -3
  246. package/src/session/InsecureSession.ts +4 -3
  247. package/src/session/NodeSession.ts +25 -14
  248. package/src/session/SessionManager.ts +14 -4
  249. package/src/session/case/CaseClient.ts +18 -16
  250. package/src/session/case/CaseServer.ts +22 -17
  251. package/src/session/pase/PaseClient.ts +11 -9
  252. package/src/session/pase/PaseServer.ts +6 -5
@@ -38,6 +38,7 @@ const logger = Logger.get("CertificateAuthority");
38
38
  * TODO: Add support for (optional) ICACs
39
39
  */
40
40
  export class CertificateAuthority {
41
+ #certs: CertificateManager;
41
42
  #rootCertId = BigInt(0);
42
43
  #rootKeyPair?: PrivateKey;
43
44
  #rootKeyIdentifier?: Uint8Array<ArrayBufferLike>;
@@ -45,21 +46,29 @@ export class CertificateAuthority {
45
46
  #nextCertificateId = BigInt(1);
46
47
  #construction: Construction<CertificateAuthority>;
47
48
 
49
+ get certs() {
50
+ return this.#certs;
51
+ }
52
+
48
53
  get construction() {
49
54
  return this.#construction;
50
55
  }
51
56
 
52
- static async create(options?: StorageContext | CertificateAuthority.Configuration) {
53
- return asyncNew(CertificateAuthority, options);
57
+ static async create(crypto: Crypto, options?: StorageContext | CertificateAuthority.Configuration) {
58
+ return asyncNew(CertificateAuthority, crypto, options);
54
59
  }
55
60
 
56
- constructor(options?: StorageContext | CertificateAuthority.Configuration) {
61
+ constructor(crypto: Crypto, options?: StorageContext | CertificateAuthority.Configuration) {
62
+ this.#certs = new CertificateManager(crypto);
57
63
  this.#construction = Construction(this, async () => {
58
64
  // Use provided CA config or read from storage, otherwise initialize and store
59
65
  const certValues = options instanceof StorageContext ? await options.values() : (options ?? {});
60
66
 
61
- this.#rootKeyPair = await Crypto.createKeyPair();
62
- this.#rootKeyIdentifier = (await Crypto.computeSha256(this.#rootKeyPair.publicKey)).slice(0, 20);
67
+ this.#rootKeyPair = await this.#certs.crypto.createKeyPair();
68
+ this.#rootKeyIdentifier = (await this.#certs.crypto.computeSha256(this.#rootKeyPair.publicKey)).slice(
69
+ 0,
70
+ 20,
71
+ );
63
72
  this.#rootCertBytes = await this.#generateRootCert();
64
73
 
65
74
  if (
@@ -94,7 +103,7 @@ export class CertificateAuthority {
94
103
 
95
104
  static [Environmental.create](env: Environment) {
96
105
  const storage = env.get(StorageManager).createContext("certificates");
97
- const instance = new CertificateAuthority(storage);
106
+ const instance = new CertificateAuthority(env.get(Crypto), storage);
98
107
  env.set(CertificateAuthority, instance);
99
108
  return instance;
100
109
  }
@@ -135,9 +144,9 @@ export class CertificateAuthority {
135
144
  authorityKeyIdentifier: this.#initializedRootKeyIdentifier,
136
145
  },
137
146
  };
138
- const signature = await Crypto.signEcdsa(
147
+ const signature = await this.#certs.crypto.signEcdsa(
139
148
  this.#initializedRootKeyPair,
140
- CertificateManager.rootCertToAsn1(unsignedCertificate),
149
+ this.#certs.rootCertToAsn1(unsignedCertificate),
141
150
  );
142
151
  return TlvRootCertificate.encode({ ...unsignedCertificate, signature });
143
152
  }
@@ -166,14 +175,14 @@ export class CertificateAuthority {
166
175
  digitalSignature: true,
167
176
  },
168
177
  extendedKeyUsage: [2, 1],
169
- subjectKeyIdentifier: (await Crypto.computeSha256(publicKey)).slice(0, 20),
178
+ subjectKeyIdentifier: (await this.#certs.crypto.computeSha256(publicKey)).slice(0, 20),
170
179
  authorityKeyIdentifier: this.#initializedRootKeyIdentifier,
171
180
  },
172
181
  };
173
182
 
174
- const signature = await Crypto.signEcdsa(
183
+ const signature = await this.#certs.crypto.signEcdsa(
175
184
  this.#initializedRootKeyPair,
176
- CertificateManager.nodeOperationalCertToAsn1(unsignedCertificate),
185
+ this.#certs.nodeOperationalCertToAsn1(unsignedCertificate),
177
186
  );
178
187
 
179
188
  return TlvOperationalCertificate.encode({ ...unsignedCertificate, signature });
@@ -578,52 +578,62 @@ function extensionsToAsn1(extensions: BaseCertificate["extensions"]) {
578
578
  return asn;
579
579
  }
580
580
 
581
- export namespace CertificateManager {
582
- function assertCertificateDerSize(certBytes: Uint8Array) {
583
- if (certBytes.length > MAX_DER_CERTIFICATE_SIZE) {
584
- throw new ImplementationError(
585
- `Certificate to generate is too big: ${certBytes.length} bytes instead of max ${MAX_DER_CERTIFICATE_SIZE} bytes`,
586
- );
587
- }
581
+ function genericBuildAsn1Structure({
582
+ serialNumber,
583
+ notBefore,
584
+ notAfter,
585
+ issuer,
586
+ subject,
587
+ ellipticCurvePublicKey,
588
+ extensions,
589
+ }: Unsigned<BaseCertificate>) {
590
+ const {
591
+ basicConstraints: { isCa, pathLen },
592
+ } = extensions;
593
+ if (!isCa && pathLen !== undefined) {
594
+ throw new CertificateError("Path length must be undefined for non-CA certificates.");
588
595
  }
596
+ return {
597
+ version: ContextTagged(0, 2), // v3
598
+ serialNumber: DatatypeOverride(DerType.Integer, serialNumber),
599
+ signatureAlgorithm: X962.EcdsaWithSHA256,
600
+ issuer: subjectOrIssuerToAsn1(issuer),
601
+ validity: {
602
+ notBefore: matterToJsDate(notBefore),
603
+ notAfter: matterToJsDate(notAfter),
604
+ },
605
+ subject: subjectOrIssuerToAsn1(subject),
606
+ publicKey: X962.PublicKeyEcPrime256v1(ellipticCurvePublicKey),
607
+ extensions: ContextTagged(3, extensionsToAsn1(extensions)),
608
+ };
609
+ }
589
610
 
590
- function genericBuildAsn1Structure({
591
- serialNumber,
592
- notBefore,
593
- notAfter,
594
- issuer,
595
- subject,
596
- ellipticCurvePublicKey,
597
- extensions,
598
- }: Unsigned<BaseCertificate>) {
599
- const {
600
- basicConstraints: { isCa, pathLen },
601
- } = extensions;
602
- if (!isCa && pathLen !== undefined) {
603
- throw new CertificateError("Path length must be undefined for non-CA certificates.");
604
- }
605
- return {
606
- version: ContextTagged(0, 2), // v3
607
- serialNumber: DatatypeOverride(DerType.Integer, serialNumber),
608
- signatureAlgorithm: X962.EcdsaWithSHA256,
609
- issuer: subjectOrIssuerToAsn1(issuer),
610
- validity: {
611
- notBefore: matterToJsDate(notBefore),
612
- notAfter: matterToJsDate(notAfter),
613
- },
614
- subject: subjectOrIssuerToAsn1(subject),
615
- publicKey: X962.PublicKeyEcPrime256v1(ellipticCurvePublicKey),
616
- extensions: ContextTagged(3, extensionsToAsn1(extensions)),
617
- };
611
+ function genericCertToAsn1(cert: Unsigned<BaseCertificate>) {
612
+ const certBytes = DerCodec.encode(genericBuildAsn1Structure(cert));
613
+ assertCertificateDerSize(certBytes);
614
+ return certBytes;
615
+ }
616
+
617
+ function assertCertificateDerSize(certBytes: Uint8Array) {
618
+ if (certBytes.length > MAX_DER_CERTIFICATE_SIZE) {
619
+ throw new ImplementationError(
620
+ `Certificate to generate is too big: ${certBytes.length} bytes instead of max ${MAX_DER_CERTIFICATE_SIZE} bytes`,
621
+ );
618
622
  }
623
+ }
619
624
 
620
- function genericCertToAsn1(cert: Unsigned<BaseCertificate>) {
621
- const certBytes = DerCodec.encode(genericBuildAsn1Structure(cert));
622
- assertCertificateDerSize(certBytes);
623
- return certBytes;
625
+ export class CertificateManager {
626
+ #crypto: Crypto;
627
+
628
+ constructor(crypto: Crypto) {
629
+ this.#crypto = crypto;
624
630
  }
625
631
 
626
- export function rootCertToAsn1(cert: Unsigned<RootCertificate>) {
632
+ get crypto() {
633
+ return this.#crypto;
634
+ }
635
+
636
+ rootCertToAsn1(cert: Unsigned<RootCertificate>) {
627
637
  const {
628
638
  extensions: {
629
639
  basicConstraints: { isCa },
@@ -635,7 +645,7 @@ export namespace CertificateManager {
635
645
  return genericCertToAsn1(cert);
636
646
  }
637
647
 
638
- export function intermediateCaCertToAsn1(cert: Unsigned<IntermediateCertificate>) {
648
+ intermediateCaCertToAsn1(cert: Unsigned<IntermediateCertificate>) {
639
649
  const {
640
650
  extensions: {
641
651
  basicConstraints: { isCa },
@@ -647,7 +657,7 @@ export namespace CertificateManager {
647
657
  return genericCertToAsn1(cert);
648
658
  }
649
659
 
650
- export function nodeOperationalCertToAsn1(cert: Unsigned<OperationalCertificate>) {
660
+ nodeOperationalCertToAsn1(cert: Unsigned<OperationalCertificate>) {
651
661
  const {
652
662
  issuer: { icacId, rcacId },
653
663
  extensions: {
@@ -664,9 +674,9 @@ export namespace CertificateManager {
664
674
  return genericCertToAsn1(cert);
665
675
  }
666
676
 
667
- export async function deviceAttestationCertToAsn1(cert: Unsigned<DeviceAttestationCertificate>, key: Key) {
677
+ async deviceAttestationCertToAsn1(cert: Unsigned<DeviceAttestationCertificate>, key: Key) {
668
678
  const certificate = genericBuildAsn1Structure(cert);
669
- const signature = await Crypto.signEcdsa(key, DerCodec.encode(certificate), "der");
679
+ const signature = await this.#crypto.signEcdsa(key, DerCodec.encode(certificate), "der");
670
680
  const certBytes = DerCodec.encode({
671
681
  certificate,
672
682
  signAlgorithm: X962.EcdsaWithSHA256,
@@ -676,12 +686,12 @@ export namespace CertificateManager {
676
686
  return certBytes;
677
687
  }
678
688
 
679
- export async function productAttestationIntermediateCertToAsn1(
689
+ async productAttestationIntermediateCertToAsn1(
680
690
  cert: Unsigned<ProductAttestationIntermediateCertificate>,
681
691
  key: Key,
682
692
  ) {
683
693
  const certificate = genericBuildAsn1Structure(cert);
684
- const signature = await Crypto.signEcdsa(key, DerCodec.encode(certificate), "der");
694
+ const signature = await this.#crypto.signEcdsa(key, DerCodec.encode(certificate), "der");
685
695
  const certBytes = DerCodec.encode({
686
696
  certificate,
687
697
  signAlgorithm: X962.EcdsaWithSHA256,
@@ -691,21 +701,18 @@ export namespace CertificateManager {
691
701
  return certBytes;
692
702
  }
693
703
 
694
- export async function productAttestationAuthorityCertToAsn1(
695
- cert: Unsigned<ProductAttestationAuthorityCertificate>,
696
- key: Key,
697
- ) {
704
+ async productAttestationAuthorityCertToAsn1(cert: Unsigned<ProductAttestationAuthorityCertificate>, key: Key) {
698
705
  const certificate = genericBuildAsn1Structure(cert);
699
706
  const certBytes = DerCodec.encode({
700
707
  certificate,
701
708
  signAlgorithm: X962.EcdsaWithSHA256,
702
- signature: DerBitString(await Crypto.signEcdsa(key, DerCodec.encode(certificate), "der")),
709
+ signature: DerBitString(await this.#crypto.signEcdsa(key, DerCodec.encode(certificate), "der")),
703
710
  });
704
711
  assertCertificateDerSize(certBytes);
705
712
  return certBytes;
706
713
  }
707
714
 
708
- export async function certificationDeclarationToAsn1(
715
+ async certificationDeclarationToAsn1(
709
716
  eContent: Uint8Array,
710
717
  subjectKeyIdentifier: Uint8Array,
711
718
  privateKey: JsonWebKey,
@@ -720,7 +727,7 @@ export namespace CertificateManager {
720
727
  subjectKeyIdentifier: ContextTaggedBytes(0, subjectKeyIdentifier),
721
728
  digestAlgorithm: SHA256_CMS,
722
729
  signatureAlgorithm: X962.EcdsaWithSHA256,
723
- signature: await Crypto.signEcdsa(privateKey, eContent, "der"),
730
+ signature: await this.#crypto.signEcdsa(privateKey, eContent, "der"),
724
731
  },
725
732
  ],
726
733
  };
@@ -734,9 +741,7 @@ export namespace CertificateManager {
734
741
  * Validate general requirements a Matter certificate fields must fulfill.
735
742
  * Rules for this are listed in @see {@link MatterSpecification.v12.Core} §6.5.x
736
743
  */
737
- export function validateGeneralCertificateFields(
738
- cert: RootCertificate | OperationalCertificate | IntermediateCertificate,
739
- ) {
744
+ validateGeneralCertificateFields(cert: RootCertificate | OperationalCertificate | IntermediateCertificate) {
740
745
  if (cert.serialNumber.length > 20)
741
746
  throw new CertificateError(
742
747
  `Serial number must not be longer then 20 octets. Current serial number has ${cert.serialNumber.length} octets.`,
@@ -779,8 +784,8 @@ export namespace CertificateManager {
779
784
  * Verify requirements a Matter Root certificate must fulfill.
780
785
  * Rules for this are listed in @see {@link MatterSpecification.v12.Core} §6.5.x
781
786
  */
782
- export async function verifyRootCertificate(rootCert: RootCertificate) {
783
- CertificateManager.validateGeneralCertificateFields(rootCert);
787
+ async verifyRootCertificate(rootCert: RootCertificate) {
788
+ this.validateGeneralCertificateFields(rootCert);
784
789
 
785
790
  // The subject DN SHALL NOT encode any matter-node-id attribute.
786
791
  if ("nodeId" in rootCert.subject) {
@@ -863,9 +868,9 @@ export namespace CertificateManager {
863
868
  );
864
869
  }
865
870
 
866
- await Crypto.verifyEcdsa(
871
+ await this.#crypto.verifyEcdsa(
867
872
  PublicKey(rootCert.ellipticCurvePublicKey),
868
- rootCertToAsn1(rootCert),
873
+ this.rootCertToAsn1(rootCert),
869
874
  rootCert.signature,
870
875
  );
871
876
  }
@@ -874,12 +879,12 @@ export namespace CertificateManager {
874
879
  * Verify requirements a Matter Node Operational certificate must fulfill.
875
880
  * Rules for this are listed in @see {@link MatterSpecification.v12.Core} §6.5.x
876
881
  */
877
- export async function verifyNodeOperationalCertificate(
882
+ async verifyNodeOperationalCertificate(
878
883
  nocCert: OperationalCertificate,
879
884
  rootCert: RootCertificate,
880
885
  icaCert?: IntermediateCertificate,
881
886
  ) {
882
- CertificateManager.validateGeneralCertificateFields(nocCert);
887
+ this.validateGeneralCertificateFields(nocCert);
883
888
 
884
889
  // The subject DN SHALL encode exactly one matter-node-id attribute.
885
890
  if (nocCert.subject.nodeId === undefined || Array.isArray(nocCert.subject.nodeId)) {
@@ -991,9 +996,9 @@ export namespace CertificateManager {
991
996
  );
992
997
  }
993
998
 
994
- await Crypto.verifyEcdsa(
999
+ await this.#crypto.verifyEcdsa(
995
1000
  PublicKey((icaCert ?? rootCert).ellipticCurvePublicKey),
996
- nodeOperationalCertToAsn1(nocCert),
1001
+ this.nodeOperationalCertToAsn1(nocCert),
997
1002
  nocCert.signature,
998
1003
  );
999
1004
  }
@@ -1002,8 +1007,8 @@ export namespace CertificateManager {
1002
1007
  * Verify requirements a Matter Intermediate CA certificate must fulfill.
1003
1008
  * Rules for this are listed in @see {@link MatterSpecification.v12.Core} §6.5.x
1004
1009
  */
1005
- export async function verifyIntermediateCaCertificate(rootCert: RootCertificate, icaCert: IntermediateCertificate) {
1006
- CertificateManager.validateGeneralCertificateFields(icaCert);
1010
+ async verifyIntermediateCaCertificate(rootCert: RootCertificate, icaCert: IntermediateCertificate) {
1011
+ this.validateGeneralCertificateFields(icaCert);
1007
1012
 
1008
1013
  // The subject DN SHALL NOT encode any matter-node-id attribute.
1009
1014
  if ("nodeId" in icaCert.subject) {
@@ -1109,14 +1114,14 @@ export namespace CertificateManager {
1109
1114
  );
1110
1115
  }
1111
1116
 
1112
- await Crypto.verifyEcdsa(
1117
+ await this.#crypto.verifyEcdsa(
1113
1118
  PublicKey(rootCert.ellipticCurvePublicKey),
1114
- intermediateCaCertToAsn1(icaCert),
1119
+ this.intermediateCaCertToAsn1(icaCert),
1115
1120
  icaCert.signature,
1116
1121
  );
1117
1122
  }
1118
1123
 
1119
- export async function createCertificateSigningRequest(key: Key) {
1124
+ async createCertificateSigningRequest(key: Key) {
1120
1125
  const request = {
1121
1126
  version: 0,
1122
1127
  subject: { organization: X520.OrganisationName("CSR") },
@@ -1127,11 +1132,11 @@ export namespace CertificateManager {
1127
1132
  return DerCodec.encode({
1128
1133
  request,
1129
1134
  signAlgorithm: X962.EcdsaWithSHA256,
1130
- signature: DerBitString(await Crypto.signEcdsa(key, DerCodec.encode(request), "der")),
1135
+ signature: DerBitString(await this.#crypto.signEcdsa(key, DerCodec.encode(request), "der")),
1131
1136
  });
1132
1137
  }
1133
1138
 
1134
- export async function getPublicKeyFromCsr(csr: Uint8Array) {
1139
+ async getPublicKeyFromCsr(csr: Uint8Array) {
1135
1140
  const { [DerKey.Elements]: rootElements } = DerCodec.decode(csr);
1136
1141
  if (rootElements?.length !== 3) throw new CertificateError("Invalid CSR data");
1137
1142
  const [requestNode, signAlgorithmNode, signatureNode] = rootElements;
@@ -1159,7 +1164,7 @@ export namespace CertificateManager {
1159
1164
  )
1160
1165
  )
1161
1166
  throw new CertificateError("Unsupported signature type");
1162
- await Crypto.verifyEcdsa(
1167
+ await this.#crypto.verifyEcdsa(
1163
1168
  PublicKey(publicKey),
1164
1169
  DerCodec.encode(requestNode),
1165
1170
  signatureNode[DerKey.Bytes],
@@ -3,7 +3,7 @@
3
3
  * Copyright 2022-2025 Matter.js Authors
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
- import { Bytes, PrivateKey } from "#general";
6
+ import { Bytes, Crypto, PrivateKey } from "#general";
7
7
  import { VendorId } from "#types";
8
8
  import { CertificateManager, TlvCertificationDeclaration } from "./CertificateManager.js";
9
9
 
@@ -30,7 +30,7 @@ const TestCMS_SignerPrivateKey = Bytes.fromHex("AEF3484116E9481EC57BE0472DF41BF4
30
30
  const TestCMS_SignerSubjectKeyIdentifier = Bytes.fromHex("62FA823359ACFAA9963E1CFA140ADDF504F37160");
31
31
 
32
32
  export class CertificationDeclarationManager {
33
- static generate(vendorId: VendorId, productId: number, provisional = false) {
33
+ static generate(crypto: Crypto, vendorId: VendorId, productId: number, provisional = false) {
34
34
  const certificationElements = TlvCertificationDeclaration.encode({
35
35
  formatVersion: 1,
36
36
  vendorId,
@@ -43,7 +43,7 @@ export class CertificationDeclarationManager {
43
43
  certificationType: provisional ? 1 : 0, // 0 = Test, 1 = Provisional/In certification, 2 = official
44
44
  });
45
45
 
46
- return CertificateManager.certificationDeclarationToAsn1(
46
+ return new CertificateManager(crypto).certificationDeclarationToAsn1(
47
47
  certificationElements,
48
48
  TestCMS_SignerSubjectKeyIdentifier,
49
49
  PrivateKey(TestCMS_SignerPrivateKey),
@@ -14,6 +14,7 @@ import { CertificationDeclarationManager } from "./CertificationDeclarationManag
14
14
  * Device certification used by the OperationalCredentials cluster.
15
15
  */
16
16
  export class DeviceCertification {
17
+ #crypto: Crypto;
17
18
  #privateKey?: PrivateKey;
18
19
  #certificate?: Uint8Array;
19
20
  #intermediateCertificate?: Uint8Array;
@@ -36,7 +37,8 @@ export class DeviceCertification {
36
37
  return this.#assertInitialized().declaration;
37
38
  }
38
39
 
39
- constructor(config?: DeviceCertification.Definition, product?: ProductDescription) {
40
+ constructor(crypto: Crypto, config?: DeviceCertification.Definition, product?: ProductDescription) {
41
+ this.#crypto = crypto;
40
42
  let configProvider;
41
43
  if (typeof config === "function") {
42
44
  configProvider = config;
@@ -48,14 +50,18 @@ export class DeviceCertification {
48
50
  throw new ImplementationError(`Cannot generate device certification without product information`);
49
51
  }
50
52
 
51
- const paa = await AttestationCertificateManager.create(product.vendorId);
53
+ const paa = await AttestationCertificateManager.create(crypto, product.vendorId);
52
54
  const { keyPair: dacKeyPair, dac } = await paa.getDACert(product.productId);
53
55
 
54
56
  return {
55
57
  privateKey: PrivateKey(dacKeyPair.privateKey),
56
58
  certificate: dac,
57
59
  intermediateCertificate: await paa.getPAICert(),
58
- declaration: await CertificationDeclarationManager.generate(product.vendorId, product.productId),
60
+ declaration: await CertificationDeclarationManager.generate(
61
+ crypto,
62
+ product.vendorId,
63
+ product.productId,
64
+ ),
59
65
  };
60
66
  };
61
67
  }
@@ -73,7 +79,7 @@ export class DeviceCertification {
73
79
 
74
80
  async sign(session: NodeSession, data: Uint8Array) {
75
81
  const { privateKey } = this.#assertInitialized();
76
- const signature = await Crypto.signEcdsa(privateKey, [data, session.attestationChallengeKey]);
82
+ const signature = await this.#crypto.signEcdsa(privateKey, [data, session.attestationChallengeKey]);
77
83
  return signature;
78
84
  }
79
85
 
@@ -52,7 +52,7 @@ export abstract class FailsafeContext {
52
52
  this.#associatedFabric = options.associatedFabric;
53
53
 
54
54
  this.#construction = Construction(this, async () => {
55
- this.#fabricBuilder = await FabricBuilder.create();
55
+ this.#fabricBuilder = await FabricBuilder.create(this.#fabrics.crypto);
56
56
  // Ensure derived class construction is complete
57
57
  await Promise.resolve();
58
58
 
@@ -49,7 +49,6 @@ export interface OccurrenceManagerContext {
49
49
  */
50
50
  export class OccurrenceManager {
51
51
  #store: EventStore;
52
- #storedEventCount = 0;
53
52
  #bufferConfig: OccurrenceManager.BufferConfig;
54
53
  #cull?: Promise<void>;
55
54
  #iteratingValuesInProgress = false;
@@ -87,7 +86,6 @@ export class OccurrenceManager {
87
86
 
88
87
  this.#construction = Construction(this, () => {
89
88
  return MaybePromise.then(this.#store.load(), index => {
90
- this.#storedEventCount = index.length;
91
89
  // To be sure, sort the entries by number
92
90
  index.sort(
93
91
  // sort that way because Bigint & Number mix
@@ -108,7 +106,6 @@ export class OccurrenceManager {
108
106
  async clear() {
109
107
  await this.construction;
110
108
  await this.#store.clear();
111
- this.#storedEventCount = 0;
112
109
  this.#occurrences.length = 0;
113
110
  }
114
111
 
@@ -282,8 +279,7 @@ export class OccurrenceManager {
282
279
  return MaybePromise.then(this.#store.add(occurrence), entry => {
283
280
  logger.debug(`Recorded event #${entry.number}: ${Diagnostic.json(occurrence)}`);
284
281
  this.#occurrences.push(entry);
285
- this.#storedEventCount++;
286
- if (this.#storedEventCount > this.#bufferConfig.maxEventAllowance) {
282
+ if (this.#occurrences.length > this.#bufferConfig.maxEventAllowance) {
287
283
  this.#startCull();
288
284
  }
289
285
  const numberedOccurrence = {
@@ -295,6 +291,19 @@ export class OccurrenceManager {
295
291
  });
296
292
  }
297
293
 
294
+ remove(number: EventNumber) {
295
+ const index = this.#occurrences.findIndex(entry => entry.number === number);
296
+ if (index === -1) {
297
+ // Should not happen but just in case
298
+ return;
299
+ }
300
+ this.#occurrences.splice(index, 1);
301
+ if (this.#cull) {
302
+ return this.#cull.then(() => this.#store.delete(number));
303
+ }
304
+ return this.#store.delete(number);
305
+ }
306
+
298
307
  #startCull() {
299
308
  if (this.#cull || this.#iteratingValuesInProgress) {
300
309
  return;
@@ -306,7 +315,7 @@ export class OccurrenceManager {
306
315
  }
307
316
 
308
317
  #dropOldOccurrences() {
309
- let toDelete = this.#storedEventCount - this.#bufferConfig.minEventAllowance;
318
+ let toDelete = this.#occurrences.length - this.#bufferConfig.minEventAllowance;
310
319
  if (toDelete <= 0) {
311
320
  return;
312
321
  }
@@ -357,7 +366,7 @@ export class OccurrenceManager {
357
366
  const occurrences = this.#occurrences as Array<OccurrenceSummary | undefined>;
358
367
  for (const priority of [EventPriority.Debug, EventPriority.Info, EventPriority.Critical]) {
359
368
  const checkUpTo =
360
- priority === EventPriority.Critical ? this.#storedEventCount : prioData[priority].minPosition;
369
+ priority === EventPriority.Critical ? this.#occurrences.length : prioData[priority].minPosition;
361
370
  if (checkUpTo === -1) {
362
371
  // We have less than the minimum of this event type, so we can not remove any
363
372
  continue;
@@ -382,8 +391,6 @@ export class OccurrenceManager {
382
391
  }
383
392
  this.#occurrences = occurrences.filter(entry => entry) as OccurrenceSummary[];
384
393
 
385
- this.#storedEventCount = this.#occurrences.length;
386
-
387
394
  if (asyncDrops.length) {
388
395
  return MatterAggregateError.allSettled(asyncDrops, "Error dropping occurrences")
389
396
  .then(() => {})