@matter/protocol 0.15.0-alpha.0-20250616-4b3754906 → 0.15.0-alpha.0-20250619-df2264f15

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 (207) hide show
  1. package/dist/cjs/certificate/AttestationCertificateManager.d.ts.map +1 -1
  2. package/dist/cjs/certificate/AttestationCertificateManager.js +26 -22
  3. package/dist/cjs/certificate/AttestationCertificateManager.js.map +1 -1
  4. package/dist/cjs/certificate/CertificateAuthority.d.ts +1 -2
  5. package/dist/cjs/certificate/CertificateAuthority.d.ts.map +1 -1
  6. package/dist/cjs/certificate/CertificateAuthority.js +22 -29
  7. package/dist/cjs/certificate/CertificateAuthority.js.map +1 -1
  8. package/dist/cjs/certificate/DeviceCertification.d.ts.map +1 -1
  9. package/dist/cjs/certificate/DeviceCertification.js +2 -6
  10. package/dist/cjs/certificate/DeviceCertification.js.map +1 -1
  11. package/dist/cjs/certificate/index.d.ts +7 -2
  12. package/dist/cjs/certificate/index.d.ts.map +1 -1
  13. package/dist/cjs/certificate/index.js +14 -2
  14. package/dist/cjs/certificate/index.js.map +1 -1
  15. package/dist/cjs/certificate/kinds/AttestationCertificates.d.ts +34 -0
  16. package/dist/cjs/certificate/kinds/AttestationCertificates.d.ts.map +1 -0
  17. package/dist/cjs/certificate/kinds/AttestationCertificates.js +64 -0
  18. package/dist/cjs/certificate/kinds/AttestationCertificates.js.map +6 -0
  19. package/dist/cjs/certificate/kinds/CertificationDeclaration.d.ts +23 -0
  20. package/dist/cjs/certificate/kinds/CertificationDeclaration.d.ts.map +1 -0
  21. package/dist/cjs/certificate/kinds/CertificationDeclaration.js +86 -0
  22. package/dist/cjs/certificate/kinds/CertificationDeclaration.js.map +6 -0
  23. package/dist/cjs/certificate/kinds/Icac.d.ts +29 -0
  24. package/dist/cjs/certificate/kinds/Icac.d.ts.map +1 -0
  25. package/dist/cjs/certificate/kinds/Icac.js +138 -0
  26. package/dist/cjs/certificate/kinds/Icac.js.map +6 -0
  27. package/dist/cjs/certificate/kinds/Noc.d.ts +27 -0
  28. package/dist/cjs/certificate/kinds/Noc.d.ts.map +1 -0
  29. package/dist/cjs/certificate/kinds/Noc.js +148 -0
  30. package/dist/cjs/certificate/kinds/Noc.js.map +6 -0
  31. package/dist/cjs/certificate/kinds/OperationalBase.d.ts +24 -0
  32. package/dist/cjs/certificate/kinds/OperationalBase.d.ts.map +1 -0
  33. package/dist/cjs/certificate/kinds/OperationalBase.js +68 -0
  34. package/dist/cjs/certificate/kinds/OperationalBase.js.map +6 -0
  35. package/dist/cjs/certificate/kinds/Rcac.d.ts +25 -0
  36. package/dist/cjs/certificate/kinds/Rcac.d.ts.map +1 -0
  37. package/dist/cjs/certificate/kinds/Rcac.js +119 -0
  38. package/dist/cjs/certificate/kinds/Rcac.js.map +6 -0
  39. package/dist/cjs/certificate/kinds/X509Base.d.ts +92 -0
  40. package/dist/cjs/certificate/kinds/X509Base.d.ts.map +1 -0
  41. package/dist/cjs/certificate/kinds/X509Base.js +344 -0
  42. package/dist/cjs/certificate/kinds/X509Base.js.map +6 -0
  43. package/dist/cjs/certificate/kinds/common.d.ts +18 -0
  44. package/dist/cjs/certificate/kinds/common.d.ts.map +1 -0
  45. package/dist/cjs/certificate/kinds/common.js +42 -0
  46. package/dist/cjs/certificate/kinds/common.js.map +6 -0
  47. package/dist/cjs/certificate/kinds/definitions/asn.d.ts +25 -0
  48. package/dist/cjs/certificate/kinds/definitions/asn.d.ts.map +1 -0
  49. package/dist/cjs/certificate/kinds/definitions/asn.js +83 -0
  50. package/dist/cjs/certificate/kinds/definitions/asn.js.map +6 -0
  51. package/dist/cjs/certificate/kinds/definitions/attestation.d.ts +44 -0
  52. package/dist/cjs/certificate/kinds/definitions/attestation.d.ts.map +1 -0
  53. package/dist/cjs/certificate/kinds/definitions/attestation.js +22 -0
  54. package/dist/cjs/certificate/kinds/definitions/attestation.js.map +6 -0
  55. package/dist/cjs/certificate/kinds/definitions/base.d.ts +52 -0
  56. package/dist/cjs/certificate/kinds/definitions/base.d.ts.map +1 -0
  57. package/dist/cjs/certificate/kinds/definitions/base.js +43 -0
  58. package/dist/cjs/certificate/kinds/definitions/base.js.map +6 -0
  59. package/dist/cjs/certificate/kinds/definitions/certification-declaration.d.ts +18 -0
  60. package/dist/cjs/certificate/kinds/definitions/certification-declaration.d.ts.map +1 -0
  61. package/dist/cjs/certificate/kinds/definitions/certification-declaration.js +50 -0
  62. package/dist/cjs/certificate/kinds/definitions/certification-declaration.js.map +6 -0
  63. package/dist/cjs/certificate/kinds/definitions/operational.d.ts +368 -0
  64. package/dist/cjs/certificate/kinds/definitions/operational.d.ts.map +1 -0
  65. package/dist/cjs/certificate/kinds/definitions/operational.js +149 -0
  66. package/dist/cjs/certificate/kinds/definitions/operational.js.map +6 -0
  67. package/dist/cjs/certificate/kinds/index.d.ts +12 -0
  68. package/dist/cjs/certificate/kinds/index.d.ts.map +1 -0
  69. package/dist/cjs/certificate/kinds/index.js +29 -0
  70. package/dist/cjs/certificate/kinds/index.js.map +6 -0
  71. package/dist/cjs/fabric/Fabric.d.ts +1 -2
  72. package/dist/cjs/fabric/Fabric.d.ts.map +1 -1
  73. package/dist/cjs/fabric/Fabric.js +28 -31
  74. package/dist/cjs/fabric/Fabric.js.map +1 -1
  75. package/dist/cjs/peer/ControllerCommissioningFlow.d.ts.map +1 -1
  76. package/dist/cjs/peer/ControllerCommissioningFlow.js +2 -1
  77. package/dist/cjs/peer/ControllerCommissioningFlow.js.map +1 -1
  78. package/dist/cjs/session/case/CaseClient.d.ts.map +1 -1
  79. package/dist/cjs/session/case/CaseClient.js +3 -3
  80. package/dist/cjs/session/case/CaseClient.js.map +1 -1
  81. package/dist/cjs/session/case/CaseServer.d.ts.map +1 -1
  82. package/dist/cjs/session/case/CaseServer.js +2 -2
  83. package/dist/cjs/session/case/CaseServer.js.map +1 -1
  84. package/dist/esm/certificate/AttestationCertificateManager.d.ts.map +1 -1
  85. package/dist/esm/certificate/AttestationCertificateManager.js +20 -16
  86. package/dist/esm/certificate/AttestationCertificateManager.js.map +1 -1
  87. package/dist/esm/certificate/CertificateAuthority.d.ts +1 -2
  88. package/dist/esm/certificate/CertificateAuthority.d.ts.map +1 -1
  89. package/dist/esm/certificate/CertificateAuthority.js +18 -30
  90. package/dist/esm/certificate/CertificateAuthority.js.map +1 -1
  91. package/dist/esm/certificate/DeviceCertification.d.ts.map +1 -1
  92. package/dist/esm/certificate/DeviceCertification.js +2 -6
  93. package/dist/esm/certificate/DeviceCertification.js.map +1 -1
  94. package/dist/esm/certificate/index.d.ts +7 -2
  95. package/dist/esm/certificate/index.d.ts.map +1 -1
  96. package/dist/esm/certificate/index.js +10 -2
  97. package/dist/esm/certificate/index.js.map +1 -1
  98. package/dist/esm/certificate/kinds/AttestationCertificates.d.ts +34 -0
  99. package/dist/esm/certificate/kinds/AttestationCertificates.d.ts.map +1 -0
  100. package/dist/esm/certificate/kinds/AttestationCertificates.js +44 -0
  101. package/dist/esm/certificate/kinds/AttestationCertificates.js.map +6 -0
  102. package/dist/esm/certificate/kinds/CertificationDeclaration.d.ts +23 -0
  103. package/dist/esm/certificate/kinds/CertificationDeclaration.d.ts.map +1 -0
  104. package/dist/esm/certificate/kinds/CertificationDeclaration.js +66 -0
  105. package/dist/esm/certificate/kinds/CertificationDeclaration.js.map +6 -0
  106. package/dist/esm/certificate/kinds/Icac.d.ts +29 -0
  107. package/dist/esm/certificate/kinds/Icac.d.ts.map +1 -0
  108. package/dist/esm/certificate/kinds/Icac.js +118 -0
  109. package/dist/esm/certificate/kinds/Icac.js.map +6 -0
  110. package/dist/esm/certificate/kinds/Noc.d.ts +27 -0
  111. package/dist/esm/certificate/kinds/Noc.d.ts.map +1 -0
  112. package/dist/esm/certificate/kinds/Noc.js +128 -0
  113. package/dist/esm/certificate/kinds/Noc.js.map +6 -0
  114. package/dist/esm/certificate/kinds/OperationalBase.d.ts +24 -0
  115. package/dist/esm/certificate/kinds/OperationalBase.d.ts.map +1 -0
  116. package/dist/esm/certificate/kinds/OperationalBase.js +48 -0
  117. package/dist/esm/certificate/kinds/OperationalBase.js.map +6 -0
  118. package/dist/esm/certificate/kinds/Rcac.d.ts +25 -0
  119. package/dist/esm/certificate/kinds/Rcac.d.ts.map +1 -0
  120. package/dist/esm/certificate/kinds/Rcac.js +99 -0
  121. package/dist/esm/certificate/kinds/Rcac.js.map +6 -0
  122. package/dist/esm/certificate/kinds/X509Base.d.ts +92 -0
  123. package/dist/esm/certificate/kinds/X509Base.d.ts.map +1 -0
  124. package/dist/esm/certificate/kinds/X509Base.js +347 -0
  125. package/dist/esm/certificate/kinds/X509Base.js.map +6 -0
  126. package/dist/esm/certificate/kinds/common.d.ts +18 -0
  127. package/dist/esm/certificate/kinds/common.d.ts.map +1 -0
  128. package/dist/esm/certificate/kinds/common.js +22 -0
  129. package/dist/esm/certificate/kinds/common.js.map +6 -0
  130. package/dist/esm/certificate/kinds/definitions/asn.d.ts +25 -0
  131. package/dist/esm/certificate/kinds/definitions/asn.d.ts.map +1 -0
  132. package/dist/esm/certificate/kinds/definitions/asn.js +63 -0
  133. package/dist/esm/certificate/kinds/definitions/asn.js.map +6 -0
  134. package/dist/esm/certificate/kinds/definitions/attestation.d.ts +44 -0
  135. package/dist/esm/certificate/kinds/definitions/attestation.d.ts.map +1 -0
  136. package/dist/esm/certificate/kinds/definitions/attestation.js +6 -0
  137. package/dist/esm/certificate/kinds/definitions/attestation.js.map +6 -0
  138. package/dist/esm/certificate/kinds/definitions/base.d.ts +52 -0
  139. package/dist/esm/certificate/kinds/definitions/base.d.ts.map +1 -0
  140. package/dist/esm/certificate/kinds/definitions/base.js +23 -0
  141. package/dist/esm/certificate/kinds/definitions/base.js.map +6 -0
  142. package/dist/esm/certificate/kinds/definitions/certification-declaration.d.ts +18 -0
  143. package/dist/esm/certificate/kinds/definitions/certification-declaration.d.ts.map +1 -0
  144. package/dist/esm/certificate/kinds/definitions/certification-declaration.js +41 -0
  145. package/dist/esm/certificate/kinds/definitions/certification-declaration.js.map +6 -0
  146. package/dist/esm/certificate/kinds/definitions/operational.d.ts +368 -0
  147. package/dist/esm/certificate/kinds/definitions/operational.d.ts.map +1 -0
  148. package/dist/esm/certificate/kinds/definitions/operational.js +148 -0
  149. package/dist/esm/certificate/kinds/definitions/operational.js.map +6 -0
  150. package/dist/esm/certificate/kinds/index.d.ts +12 -0
  151. package/dist/esm/certificate/kinds/index.d.ts.map +1 -0
  152. package/dist/esm/certificate/kinds/index.js +12 -0
  153. package/dist/esm/certificate/kinds/index.js.map +6 -0
  154. package/dist/esm/fabric/Fabric.d.ts +1 -2
  155. package/dist/esm/fabric/Fabric.d.ts.map +1 -1
  156. package/dist/esm/fabric/Fabric.js +28 -36
  157. package/dist/esm/fabric/Fabric.js.map +1 -1
  158. package/dist/esm/peer/ControllerCommissioningFlow.d.ts.map +1 -1
  159. package/dist/esm/peer/ControllerCommissioningFlow.js +2 -1
  160. package/dist/esm/peer/ControllerCommissioningFlow.js.map +1 -1
  161. package/dist/esm/session/case/CaseClient.d.ts.map +1 -1
  162. package/dist/esm/session/case/CaseClient.js +3 -3
  163. package/dist/esm/session/case/CaseClient.js.map +1 -1
  164. package/dist/esm/session/case/CaseServer.d.ts.map +1 -1
  165. package/dist/esm/session/case/CaseServer.js +2 -2
  166. package/dist/esm/session/case/CaseServer.js.map +1 -1
  167. package/package.json +6 -6
  168. package/src/certificate/AttestationCertificateManager.ts +20 -16
  169. package/src/certificate/CertificateAuthority.ts +18 -35
  170. package/src/certificate/DeviceCertification.ts +2 -6
  171. package/src/certificate/index.ts +7 -2
  172. package/src/certificate/kinds/AttestationCertificates.ts +48 -0
  173. package/src/certificate/kinds/CertificationDeclaration.ts +91 -0
  174. package/src/certificate/kinds/Icac.ts +156 -0
  175. package/src/certificate/kinds/Noc.ts +164 -0
  176. package/src/certificate/kinds/OperationalBase.ts +72 -0
  177. package/src/certificate/kinds/Rcac.ts +126 -0
  178. package/src/certificate/kinds/X509Base.ts +380 -0
  179. package/src/certificate/kinds/common.ts +24 -0
  180. package/src/certificate/kinds/definitions/asn.ts +97 -0
  181. package/src/certificate/kinds/definitions/attestation.ts +46 -0
  182. package/src/certificate/kinds/definitions/base.ts +43 -0
  183. package/src/certificate/kinds/definitions/certification-declaration.ts +38 -0
  184. package/src/certificate/kinds/definitions/operational.ts +179 -0
  185. package/src/certificate/kinds/index.ts +12 -0
  186. package/src/fabric/Fabric.ts +28 -40
  187. package/src/peer/ControllerCommissioningFlow.ts +2 -1
  188. package/src/session/case/CaseClient.ts +3 -3
  189. package/src/session/case/CaseServer.ts +2 -2
  190. package/dist/cjs/certificate/CertificateManager.d.ts +0 -578
  191. package/dist/cjs/certificate/CertificateManager.d.ts.map +0 -1
  192. package/dist/cjs/certificate/CertificateManager.js +0 -843
  193. package/dist/cjs/certificate/CertificateManager.js.map +0 -6
  194. package/dist/cjs/certificate/CertificationDeclarationManager.d.ts +0 -11
  195. package/dist/cjs/certificate/CertificationDeclarationManager.d.ts.map +0 -1
  196. package/dist/cjs/certificate/CertificationDeclarationManager.js +0 -54
  197. package/dist/cjs/certificate/CertificationDeclarationManager.js.map +0 -6
  198. package/dist/esm/certificate/CertificateManager.d.ts +0 -578
  199. package/dist/esm/certificate/CertificateManager.d.ts.map +0 -1
  200. package/dist/esm/certificate/CertificateManager.js +0 -870
  201. package/dist/esm/certificate/CertificateManager.js.map +0 -6
  202. package/dist/esm/certificate/CertificationDeclarationManager.d.ts +0 -11
  203. package/dist/esm/certificate/CertificationDeclarationManager.d.ts.map +0 -1
  204. package/dist/esm/certificate/CertificationDeclarationManager.js +0 -34
  205. package/dist/esm/certificate/CertificationDeclarationManager.js.map +0 -6
  206. package/src/certificate/CertificateManager.ts +0 -1176
  207. package/src/certificate/CertificationDeclarationManager.ts +0 -52
@@ -6,12 +6,13 @@
6
6
 
7
7
  import { Bytes, Crypto, PrivateKey, Time, toHex } from "#general";
8
8
  import { VendorId } from "#types";
9
- import { CertificateManager, jsToMatterDate } from "./CertificateManager.js";
10
9
  import {
11
10
  TestCert_PAA_NoVID_PrivateKey,
12
11
  TestCert_PAA_NoVID_PublicKey,
13
12
  TestCert_PAA_NoVID_SKID,
14
13
  } from "./ChipPAAuthorities.js";
14
+ import { Dac, Paa, Pai } from "./kinds/AttestationCertificates.js";
15
+ import { jsToMatterDate } from "./kinds/definitions/asn.js";
15
16
 
16
17
  function getPaiCommonName(vendorId: VendorId, productId?: number) {
17
18
  return `node-matter Dev PAI 0x${vendorId.toString(16).toUpperCase()} ${
@@ -36,7 +37,7 @@ export class AttestationCertificateManager {
36
37
  readonly #paaKeyPair = PrivateKey(TestCert_PAA_NoVID_PrivateKey, {
37
38
  publicKey: TestCert_PAA_NoVID_PublicKey,
38
39
  });
39
- readonly #certs: CertificateManager;
40
+ readonly #crypto: Crypto;
40
41
  readonly #vendorId: VendorId;
41
42
  readonly #paiKeyPair: PrivateKey;
42
43
  readonly #paiKeyIdentifier: Uint8Array;
@@ -46,7 +47,7 @@ export class AttestationCertificateManager {
46
47
  #nextCertificateId = 2;
47
48
 
48
49
  constructor(crypto: Crypto, vendorId: VendorId, paiKeyPair: PrivateKey, paiKeyIdentifier: Uint8Array) {
49
- this.#certs = new CertificateManager(crypto);
50
+ this.#crypto = crypto;
50
51
  this.#vendorId = vendorId;
51
52
  this.#paiKeyPair = paiKeyPair;
52
53
  this.#paiKeyIdentifier = paiKeyIdentifier;
@@ -64,7 +65,7 @@ export class AttestationCertificateManager {
64
65
  }
65
66
 
66
67
  async getDACert(productId: number) {
67
- const dacKeyPair = await this.#certs.crypto.createKeyPair();
68
+ const dacKeyPair = await this.#crypto.createKeyPair();
68
69
  return {
69
70
  keyPair: dacKeyPair,
70
71
  dac: await this.generateDaCert(dacKeyPair.publicKey, this.#vendorId, productId),
@@ -74,9 +75,9 @@ export class AttestationCertificateManager {
74
75
  // Method unused for now because we use the official Matter Test PAA, but is functional
75
76
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
76
77
  // @ts-ignore
77
- private generatePAACert(vendorId?: VendorId) {
78
+ private async generatePAACert(vendorId?: VendorId) {
78
79
  const now = Time.get().now();
79
- const unsignedCertificate = {
80
+ const cert = new Paa({
80
81
  serialNumber: Bytes.fromHex(toHex(this.paaCertId)),
81
82
  signatureAlgorithm: 1 /* EcdsaWithSHA256 */,
82
83
  publicKeyAlgorithm: 1 /* EC */,
@@ -104,13 +105,14 @@ export class AttestationCertificateManager {
104
105
  subjectKeyIdentifier: this.#paaKeyIdentifier,
105
106
  authorityKeyIdentifier: this.#paaKeyIdentifier,
106
107
  },
107
- };
108
- return this.#certs.productAttestationAuthorityCertToAsn1(unsignedCertificate, this.#paaKeyPair);
108
+ });
109
+ await cert.sign(this.#crypto, this.#paaKeyPair);
110
+ return cert.asSignedAsn1();
109
111
  }
110
112
 
111
- private generatePAICert(vendorId: VendorId, productId?: number) {
113
+ private async generatePAICert(vendorId: VendorId, productId?: number) {
112
114
  const now = Time.get().now();
113
- const unsignedCertificate = {
115
+ const cert = new Pai({
114
116
  serialNumber: Bytes.fromHex(toHex(this.#paiCertId)),
115
117
  signatureAlgorithm: 1 /* EcdsaWithSHA256 */,
116
118
  publicKeyAlgorithm: 1 /* EC */,
@@ -138,14 +140,15 @@ export class AttestationCertificateManager {
138
140
  subjectKeyIdentifier: this.#paiKeyIdentifier,
139
141
  authorityKeyIdentifier: this.#paaKeyIdentifier,
140
142
  },
141
- };
142
- return this.#certs.productAttestationIntermediateCertToAsn1(unsignedCertificate, this.#paaKeyPair);
143
+ });
144
+ await cert.sign(this.#crypto, this.#paaKeyPair);
145
+ return cert.asSignedAsn1();
143
146
  }
144
147
 
145
148
  async generateDaCert(publicKey: Uint8Array, vendorId: VendorId, productId: number) {
146
149
  const now = Time.get().now();
147
150
  const certId = this.#nextCertificateId++;
148
- const unsignedCertificate = {
151
+ const cert = new Dac({
149
152
  serialNumber: Bytes.fromHex(toHex(certId)),
150
153
  signatureAlgorithm: 1 /* EcdsaWithSHA256 */,
151
154
  publicKeyAlgorithm: 1 /* EC */,
@@ -169,10 +172,11 @@ export class AttestationCertificateManager {
169
172
  keyUsage: {
170
173
  digitalSignature: true,
171
174
  },
172
- subjectKeyIdentifier: (await this.#certs.crypto.computeSha256(publicKey)).slice(0, 20),
175
+ subjectKeyIdentifier: (await this.#crypto.computeSha256(publicKey)).slice(0, 20),
173
176
  authorityKeyIdentifier: this.#paiKeyIdentifier,
174
177
  },
175
- };
176
- return this.#certs.deviceAttestationCertToAsn1(unsignedCertificate, this.#paiKeyPair);
178
+ });
179
+ await cert.sign(this.#crypto, this.#paiKeyPair);
180
+ return cert.asSignedAsn1();
177
181
  }
178
182
  }
@@ -21,15 +21,9 @@ import {
21
21
  toHex,
22
22
  } from "#general";
23
23
  import { CaseAuthenticatedTag, FabricId, NodeId } from "#types";
24
- import {
25
- CertificateManager,
26
- OperationalCertificate,
27
- RootCertificate,
28
- TlvOperationalCertificate,
29
- TlvRootCertificate,
30
- Unsigned,
31
- jsToMatterDate,
32
- } from "./CertificateManager.js";
24
+ import { jsToMatterDate } from "./kinds/definitions/asn.js";
25
+ import { Noc } from "./kinds/Noc.js";
26
+ import { Rcac } from "./kinds/Rcac.js";
33
27
 
34
28
  const logger = Logger.get("CertificateAuthority");
35
29
 
@@ -38,7 +32,7 @@ const logger = Logger.get("CertificateAuthority");
38
32
  * TODO: Add support for (optional) ICACs
39
33
  */
40
34
  export class CertificateAuthority {
41
- #certs: CertificateManager;
35
+ #crypto: Crypto;
42
36
  #rootCertId = BigInt(0);
43
37
  #rootKeyPair?: PrivateKey;
44
38
  #rootKeyIdentifier?: Uint8Array<ArrayBufferLike>;
@@ -46,8 +40,8 @@ export class CertificateAuthority {
46
40
  #nextCertificateId = BigInt(1);
47
41
  #construction: Construction<CertificateAuthority>;
48
42
 
49
- get certs() {
50
- return this.#certs;
43
+ get crypto() {
44
+ return this.#crypto;
51
45
  }
52
46
 
53
47
  get construction() {
@@ -59,16 +53,13 @@ export class CertificateAuthority {
59
53
  }
60
54
 
61
55
  constructor(crypto: Crypto, options?: StorageContext | CertificateAuthority.Configuration) {
62
- this.#certs = new CertificateManager(crypto);
56
+ this.#crypto = crypto;
63
57
  this.#construction = Construction(this, async () => {
64
58
  // Use provided CA config or read from storage, otherwise initialize and store
65
59
  const certValues = options instanceof StorageContext ? await options.values() : (options ?? {});
66
60
 
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
- );
61
+ this.#rootKeyPair = await this.#crypto.createKeyPair();
62
+ this.#rootKeyIdentifier = (await this.#crypto.computeSha256(this.#rootKeyPair.publicKey)).slice(0, 20);
72
63
  this.#rootCertBytes = await this.#generateRootCert();
73
64
 
74
65
  if (
@@ -124,7 +115,7 @@ export class CertificateAuthority {
124
115
 
125
116
  async #generateRootCert() {
126
117
  const now = Time.get().now();
127
- const unsignedCertificate: Unsigned<RootCertificate> = {
118
+ const cert = new Rcac({
128
119
  serialNumber: Bytes.fromHex(toHex(this.#rootCertId)),
129
120
  signatureAlgorithm: 1 /* EcdsaWithSHA256 */,
130
121
  publicKeyAlgorithm: 1 /* EC */,
@@ -143,12 +134,9 @@ export class CertificateAuthority {
143
134
  subjectKeyIdentifier: this.#initializedRootKeyIdentifier,
144
135
  authorityKeyIdentifier: this.#initializedRootKeyIdentifier,
145
136
  },
146
- };
147
- const signature = await this.#certs.crypto.signEcdsa(
148
- this.#initializedRootKeyPair,
149
- this.#certs.rootCertToAsn1(unsignedCertificate),
150
- );
151
- return TlvRootCertificate.encode({ ...unsignedCertificate, signature });
137
+ });
138
+ await cert.sign(this.#crypto, this.#initializedRootKeyPair);
139
+ return cert.asSignedTlv();
152
140
  }
153
141
 
154
142
  async generateNoc(
@@ -159,7 +147,7 @@ export class CertificateAuthority {
159
147
  ) {
160
148
  const now = Time.get().now();
161
149
  const certId = this.#nextCertificateId++;
162
- const unsignedCertificate: Unsigned<OperationalCertificate> = {
150
+ const cert = new Noc({
163
151
  serialNumber: Bytes.fromHex(toHex(certId)),
164
152
  signatureAlgorithm: 1 /* EcdsaWithSHA256 */,
165
153
  publicKeyAlgorithm: 1 /* EC */,
@@ -175,17 +163,12 @@ export class CertificateAuthority {
175
163
  digitalSignature: true,
176
164
  },
177
165
  extendedKeyUsage: [2, 1],
178
- subjectKeyIdentifier: (await this.#certs.crypto.computeSha256(publicKey)).slice(0, 20),
166
+ subjectKeyIdentifier: (await this.#crypto.computeSha256(publicKey)).slice(0, 20),
179
167
  authorityKeyIdentifier: this.#initializedRootKeyIdentifier,
180
168
  },
181
- };
182
-
183
- const signature = await this.#certs.crypto.signEcdsa(
184
- this.#initializedRootKeyPair,
185
- this.#certs.nodeOperationalCertToAsn1(unsignedCertificate),
186
- );
187
-
188
- return TlvOperationalCertificate.encode({ ...unsignedCertificate, signature });
169
+ });
170
+ await cert.sign(this.#crypto, this.#initializedRootKeyPair);
171
+ return cert.asSignedTlv();
189
172
  }
190
173
 
191
174
  get #initializedRootKeyPair() {
@@ -4,11 +4,11 @@
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
6
 
7
+ import { CertificationDeclaration } from "#certificate/kinds/CertificationDeclaration.js";
7
8
  import { Construction, Crypto, ImplementationError, InternalError, PrivateKey } from "#general";
8
9
  import { NodeSession } from "#session/NodeSession.js";
9
10
  import { ProductDescription } from "#types";
10
11
  import { AttestationCertificateManager } from "./AttestationCertificateManager.js";
11
- import { CertificationDeclarationManager } from "./CertificationDeclarationManager.js";
12
12
 
13
13
  /**
14
14
  * Device certification used by the OperationalCredentials cluster.
@@ -57,11 +57,7 @@ export class DeviceCertification {
57
57
  privateKey: PrivateKey(dacKeyPair.privateKey),
58
58
  certificate: dac,
59
59
  intermediateCertificate: await paa.getPAICert(),
60
- declaration: await CertificationDeclarationManager.generate(
61
- crypto,
62
- product.vendorId,
63
- product.productId,
64
- ),
60
+ declaration: await CertificationDeclaration.generate(crypto, product.vendorId, product.productId),
65
61
  };
66
62
  };
67
63
  }
@@ -6,7 +6,12 @@
6
6
 
7
7
  export * from "./AttestationCertificateManager.js";
8
8
  export * from "./CertificateAuthority.js";
9
- export * from "./CertificateManager.js";
10
- export * from "./CertificationDeclarationManager.js";
11
9
  export * from "./ChipPAAuthorities.js";
12
10
  export * from "./DeviceCertification.js";
11
+ export * from "./kinds/AttestationCertificates.js";
12
+ export * from "./kinds/CertificationDeclaration.js";
13
+ export { CertificateError } from "./kinds/common.js";
14
+ export * from "./kinds/Icac.js";
15
+ export * from "./kinds/Noc.js";
16
+ export * from "./kinds/Rcac.js";
17
+ export * from "./kinds/X509Base.js";
@@ -0,0 +1,48 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2022-2025 Matter.js Authors
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+
7
+ import { Crypto, DerBitString, DerCodec, X962 } from "#general";
8
+ import { assertCertificateDerSize } from "./common.js";
9
+ import { AttestationCertificate } from "./definitions/attestation.js";
10
+ import { X509Certificate } from "./definitions/base.js";
11
+ import { X509Base } from "./X509Base.js";
12
+
13
+ /**
14
+ * Base class for Attestation Certificates (PAA, PAI, DAC).
15
+ */
16
+ export abstract class AttestationBaseCertificate<CT extends X509Certificate> extends X509Base<CT> {
17
+ /**
18
+ * Sign the certificate using the provided crypto and key.
19
+ * If the certificate is already signed, it throws a CertificateError.
20
+ */
21
+ override async sign(crypto: Crypto, key: JsonWebKey) {
22
+ this.signature = await crypto.signEcdsa(key, this.asUnsignedAsn1(), "der");
23
+ }
24
+
25
+ /**
26
+ * Returns the signed certificate in ASN.1 DER format.
27
+ * If the certificate is not signed, it throws a CertificateError.
28
+ */
29
+ asSignedAsn1(): Uint8Array<ArrayBufferLike> {
30
+ const certificate = this.genericBuildAsn1Structure(this.cert);
31
+ const certBytes = DerCodec.encode({
32
+ certificate,
33
+ signAlgorithm: X962.EcdsaWithSHA256,
34
+ signature: DerBitString(this.signature),
35
+ });
36
+ assertCertificateDerSize(certBytes);
37
+ return certBytes;
38
+ }
39
+ }
40
+
41
+ /** PAA (Product Attestation Authority) Certificate. */
42
+ export class Paa extends AttestationBaseCertificate<AttestationCertificate.Paa> {}
43
+
44
+ /** PAI (Product Attestation Intermediate) Certificate. */
45
+ export class Pai extends AttestationBaseCertificate<AttestationCertificate.Pai> {}
46
+
47
+ /** DAC (Device Attestation Certificate) Certificate. */
48
+ export class Dac extends AttestationBaseCertificate<AttestationCertificate.Dac> {}
@@ -0,0 +1,91 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2022-2025 Matter.js Authors
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { Bytes, ContextTaggedBytes, Crypto, DerCodec, Pkcs7, PrivateKey, SHA256_CMS, X962 } from "#general";
7
+ import { TypeFromBitmapSchema, VendorId } from "#types";
8
+ import { assertCertificateDerSize } from "./common.js";
9
+ import { CertificationDeclaration as CertificationDeclarationDef } from "./definitions/certification-declaration.js";
10
+
11
+ // This is the private key from Appendix F of the Matter 1.1 Core Specification.
12
+ // The specification specifies it in PEM format:
13
+ //
14
+ // -----BEGIN EC PRIVATE KEY-----
15
+ // MHcCAQEEIK7zSEEW6UgexXvgRy30G/SZBk5QJK2GnspeiJgC1IB1oAoGCCqGSM49
16
+ // AwEHoUQDQgAEPDmJIkUrVcrzicJb0bykZWlSzLkOiGkkmthHRlMBTL+V1oeWXgNr
17
+ // UhxRA35rjO3vyh60QEZpT6CIgu7WUZ3sug==
18
+ // -----END EC PRIVATE KEY-----
19
+ //
20
+ // You can extract the key using openssl:
21
+ //
22
+ // openssl asn1parse -in key.txt
23
+ const TestCMS_SignerPrivateKey = Bytes.fromHex("AEF3484116E9481EC57BE0472DF41BF499064E5024AD869ECA5E889802D48075");
24
+
25
+ // You can extract the subject key identifier from the certificate in the same
26
+ // section. The x509 command is best for that:
27
+ //
28
+ // openssl x509 -in cert.txt -text
29
+ //
30
+ // Look for the line under "X509v3 Subject Key Identifier:"
31
+ const TestCMS_SignerSubjectKeyIdentifier = Bytes.fromHex("62FA823359ACFAA9963E1CFA140ADDF504F37160");
32
+
33
+ /** A Matter Certification Declaration */
34
+ export class CertificationDeclaration {
35
+ #eContent: Uint8Array;
36
+ #subjectKeyIdentifier: Uint8Array;
37
+
38
+ /**
39
+ * Generator which is the main usage for the class from outside.
40
+ * It constructs the class with the relevant details and returns a signed ASN.1 DER version of the CD.
41
+ */
42
+ static generate(crypto: Crypto, vendorId: VendorId, productId: number, provisional = false) {
43
+ const cd = new CertificationDeclaration(
44
+ {
45
+ formatVersion: 1,
46
+ vendorId,
47
+ produceIdArray: [productId],
48
+ deviceTypeId: 22,
49
+ certificateId: "CSA00000SWC00000-00",
50
+ securityLevel: 0,
51
+ securityInformation: 0,
52
+ versionNumber: 1,
53
+ certificationType: provisional ? 1 : 0, // 0 = Test, 1 = Provisional/In certification, 2 = official
54
+ },
55
+ TestCMS_SignerSubjectKeyIdentifier,
56
+ );
57
+
58
+ return cd.asSignedAsn1(crypto, PrivateKey(TestCMS_SignerPrivateKey));
59
+ }
60
+
61
+ constructor(
62
+ content: TypeFromBitmapSchema<typeof CertificationDeclarationDef.TlvDc>,
63
+ subjectKeyIdentifier: Uint8Array,
64
+ ) {
65
+ this.#eContent = CertificationDeclarationDef.TlvDc.encode(content);
66
+ this.#subjectKeyIdentifier = subjectKeyIdentifier;
67
+ }
68
+
69
+ /**
70
+ * Returns the signed certificate in ASN.1 DER format.
71
+ */
72
+ async asSignedAsn1(crypto: Crypto, privateKey: JsonWebKey) {
73
+ const cert = {
74
+ version: 3,
75
+ digestAlgorithm: [SHA256_CMS],
76
+ encapContentInfo: Pkcs7.Data(this.#eContent),
77
+ signerInfo: [
78
+ {
79
+ version: 3,
80
+ subjectKeyIdentifier: ContextTaggedBytes(0, this.#subjectKeyIdentifier),
81
+ digestAlgorithm: SHA256_CMS,
82
+ signatureAlgorithm: X962.EcdsaWithSHA256,
83
+ signature: await crypto.signEcdsa(privateKey, this.#eContent, "der"),
84
+ },
85
+ ],
86
+ };
87
+ const certBytes = DerCodec.encode(Pkcs7.SignedData(cert));
88
+ assertCertificateDerSize(certBytes);
89
+ return certBytes;
90
+ }
91
+ }
@@ -0,0 +1,156 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2022-2025 Matter.js Authors
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+
7
+ import { Bytes, Crypto, Diagnostic, PublicKey } from "#general";
8
+ import { FabricId } from "#types";
9
+ import { CertificateError } from "./common.js";
10
+ import { ExtensionKeyUsageSchema } from "./definitions/base.js";
11
+ import { OperationalCertificate } from "./definitions/operational.js";
12
+ import { OperationalBase } from "./OperationalBase.js";
13
+ import { Rcac } from "./Rcac.js";
14
+
15
+ /**
16
+ * Represents an Intermediate Certificate
17
+ */
18
+ export class Icac extends OperationalBase<OperationalCertificate.Icac> {
19
+ /** Construct the class from a Tlv version of the certificate */
20
+ static fromTlv(tlv: Uint8Array): Icac {
21
+ return new Icac(OperationalCertificate.TlvIcac.decode(tlv));
22
+ }
23
+
24
+ /** Validates all basic certificate fields on construction. */
25
+ protected validateFields() {
26
+ const {
27
+ extensions: {
28
+ basicConstraints: { isCa },
29
+ },
30
+ } = this.cert;
31
+ if (!isCa) {
32
+ throw new CertificateError("Intermediate certificate must be a CA.");
33
+ }
34
+ }
35
+
36
+ /**
37
+ * Encodes the certificate with the signature as Matter Tlv.
38
+ * If the certificate is not signed, it throws a CertificateError.
39
+ */
40
+ asSignedTlv() {
41
+ return OperationalCertificate.TlvIcac.encode({ ...this.cert, signature: this.signature });
42
+ }
43
+
44
+ /**
45
+ * Verify requirements a Matter Intermediate CA certificate must fulfill.
46
+ * Rules for this are listed in @see {@link MatterSpecification.v12.Core} §6.5.x
47
+ */
48
+ async verify(crypto: Crypto, root: Rcac) {
49
+ this.generalVerify();
50
+
51
+ const {
52
+ subject,
53
+ issuer: { rcacId },
54
+ extensions,
55
+ } = this.cert;
56
+ const { fabricId, icacId } = subject;
57
+ const { basicConstraints, extendedKeyUsage, subjectKeyIdentifier, authorityKeyIdentifier } = extensions;
58
+
59
+ const { fabricId: rootFabricId } = root.cert.subject;
60
+ // The subject DN SHALL NOT encode any matter-node-id attribute.
61
+ if ("nodeId" in subject) {
62
+ throw new CertificateError(`Ica certificate must not contain a nodeId.`);
63
+ }
64
+
65
+ // The subject DN MAY encode at most one matter-fabric-id attribute.
66
+ if (fabricId !== undefined) {
67
+ if (Array.isArray(fabricId)) {
68
+ throw new CertificateError(`Invalid fabricId in NoC certificate: ${Diagnostic.json(fabricId)}`);
69
+ }
70
+ // If present, the matter-fabric-id attribute’s value SHALL NOT be 0
71
+ if (fabricId === FabricId(0)) {
72
+ throw new CertificateError(`Invalid fabricId in NoC certificate: ${Diagnostic.json(fabricId)}`);
73
+ }
74
+ }
75
+
76
+ // The subject DN SHALL encode exactly one matter-icac-id attribute.
77
+ if (icacId === undefined || Array.isArray(icacId)) {
78
+ throw new CertificateError(`Invalid icacId in Ica certificate: ${Diagnostic.json(icacId)}`);
79
+ }
80
+
81
+ // The subject DN SHALL NOT encode any matter-rcac-id attribute.
82
+ if ("rcacId" in subject) {
83
+ throw new CertificateError(`Ica certificate must not contain an rcacId.`);
84
+ }
85
+
86
+ // The subject DN SHALL NOT encode any matter-noc-cat attribute.
87
+ if ("caseAuthenticatedTags" in subject) {
88
+ throw new CertificateError(`Ica certificate must not contain a caseAuthenticatedTags.`);
89
+ }
90
+
91
+ // When any matter-fabric-id attributes are present in either the Matter Root CA Certificate or the Matter ICA
92
+ // Certificate, the value SHALL match the one present in the Matter Node Operational Certificate (NOC) within
93
+ // the same certificate chain.
94
+ // Here means: When both are set, they must match
95
+ if (rootFabricId !== undefined && fabricId !== undefined && rootFabricId !== fabricId) {
96
+ throw new CertificateError(
97
+ `FabricId in Ica certificate does not match the fabricId in the parent certificate. ${Diagnostic.json(
98
+ rootFabricId,
99
+ )} !== ${Diagnostic.json(fabricId)}`,
100
+ );
101
+ }
102
+
103
+ // Verify the certificate chain by checking rcac ids in subject and issuer
104
+ if (root.cert.subject.rcacId !== rcacId) {
105
+ throw new CertificateError(
106
+ `RcacId in Ica certificate does not match the rcacId in the parent certificate. ${Diagnostic.json(
107
+ root.cert.subject.rcacId,
108
+ )} !== ${Diagnostic.json(rcacId)}`,
109
+ );
110
+ }
111
+
112
+ // The basic constraints extension SHALL be encoded with is-ca set to true.
113
+ if (!basicConstraints.isCa) {
114
+ throw new CertificateError(`Ica certificate must have isCa set to true.`);
115
+ }
116
+
117
+ // The key usage extension SHALL be encoded with at least two flags: keyCertSign (0x0020) and CRLSign (0x0040)
118
+ // and optionally with digitalSignature (0x0001).
119
+ const keyUsage = ExtensionKeyUsageSchema.encode(extensions.keyUsage);
120
+ if (keyUsage !== 0x0060 && keyUsage !== 0x0061) {
121
+ throw new CertificateError(
122
+ `Ica certificate keyUsage must have keyCertSign and CRLSign and optionally digitalSignature set.`,
123
+ );
124
+ }
125
+
126
+ // The extended key usage extension SHALL NOT be present.
127
+ if (extendedKeyUsage !== undefined) {
128
+ throw new CertificateError(`Ica certificate must not have extendedKeyUsage set.`);
129
+ }
130
+
131
+ // The subject key identifier extension SHALL be present and 160 bit long.
132
+ if (subjectKeyIdentifier === undefined) {
133
+ throw new CertificateError(`Ica certificate must have subjectKeyIdentifier set.`);
134
+ }
135
+ if (subjectKeyIdentifier.length !== 20) {
136
+ throw new CertificateError(`Ica certificate subjectKeyIdentifier must be 160 bit.`);
137
+ }
138
+
139
+ // The authority key identifier extension SHALL be present and 160 bit long.
140
+ if (authorityKeyIdentifier === undefined) {
141
+ throw new CertificateError(`Ica certificate must have authorityKeyIdentifier set.`);
142
+ }
143
+ if (authorityKeyIdentifier.length !== 20) {
144
+ throw new CertificateError(`Ica certificate authorityKeyIdentifier must be 160 bit.`);
145
+ }
146
+
147
+ // Validate authority key identifier against subject key identifier
148
+ if (!Bytes.areEqual(authorityKeyIdentifier, root.cert.extensions.subjectKeyIdentifier)) {
149
+ throw new CertificateError(
150
+ `Ica certificate authorityKeyIdentifier must be equal to root cert subjectKeyIdentifier.`,
151
+ );
152
+ }
153
+
154
+ await crypto.verifyEcdsa(PublicKey(root.cert.ellipticCurvePublicKey), this.asUnsignedAsn1(), this.signature);
155
+ }
156
+ }