@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.
- package/dist/cjs/certificate/AttestationCertificateManager.d.ts +3 -3
- package/dist/cjs/certificate/AttestationCertificateManager.d.ts.map +1 -1
- package/dist/cjs/certificate/AttestationCertificateManager.js +12 -10
- package/dist/cjs/certificate/AttestationCertificateManager.js.map +1 -1
- package/dist/cjs/certificate/CertificateAuthority.d.ts +5 -3
- package/dist/cjs/certificate/CertificateAuthority.d.ts.map +1 -1
- package/dist/cjs/certificate/CertificateAuthority.js +19 -11
- package/dist/cjs/certificate/CertificateAuthority.js.map +1 -1
- package/dist/cjs/certificate/CertificateManager.d.ts +18 -15
- package/dist/cjs/certificate/CertificateManager.d.ts.map +1 -1
- package/dist/cjs/certificate/CertificateManager.js +92 -83
- package/dist/cjs/certificate/CertificateManager.js.map +2 -2
- package/dist/cjs/certificate/CertificationDeclarationManager.d.ts +7 -1
- package/dist/cjs/certificate/CertificationDeclarationManager.d.ts.map +1 -1
- package/dist/cjs/certificate/CertificationDeclarationManager.js +2 -2
- package/dist/cjs/certificate/CertificationDeclarationManager.js.map +1 -1
- package/dist/cjs/certificate/DeviceCertification.d.ts +2 -2
- package/dist/cjs/certificate/DeviceCertification.d.ts.map +1 -1
- package/dist/cjs/certificate/DeviceCertification.js +10 -4
- package/dist/cjs/certificate/DeviceCertification.js.map +1 -1
- package/dist/cjs/common/FailsafeContext.js +1 -1
- package/dist/cjs/common/FailsafeContext.js.map +1 -1
- package/dist/cjs/fabric/Fabric.d.ts +6 -4
- package/dist/cjs/fabric/Fabric.d.ts.map +1 -1
- package/dist/cjs/fabric/Fabric.js +33 -20
- package/dist/cjs/fabric/Fabric.js.map +1 -1
- package/dist/cjs/fabric/FabricAuthority.d.ts +1 -1
- package/dist/cjs/fabric/FabricAuthority.d.ts.map +1 -1
- package/dist/cjs/fabric/FabricAuthority.js +7 -7
- package/dist/cjs/fabric/FabricAuthority.js.map +1 -1
- package/dist/cjs/fabric/FabricManager.d.ts +3 -2
- package/dist/cjs/fabric/FabricManager.d.ts.map +1 -1
- package/dist/cjs/fabric/FabricManager.js +8 -3
- package/dist/cjs/fabric/FabricManager.js.map +1 -1
- package/dist/cjs/fabric/TestFabric.d.ts.map +1 -1
- package/dist/cjs/fabric/TestFabric.js +15 -19
- package/dist/cjs/fabric/TestFabric.js.map +1 -1
- package/dist/cjs/groups/FabricGroups.d.ts.map +1 -1
- package/dist/cjs/groups/FabricGroups.js +11 -7
- package/dist/cjs/groups/FabricGroups.js.map +1 -1
- package/dist/cjs/groups/KeySets.d.ts +2 -2
- package/dist/cjs/groups/KeySets.d.ts.map +1 -1
- package/dist/cjs/groups/KeySets.js +2 -2
- package/dist/cjs/groups/KeySets.js.map +1 -1
- package/dist/cjs/groups/MessagingState.d.ts +2 -2
- package/dist/cjs/groups/MessagingState.d.ts.map +1 -1
- package/dist/cjs/groups/MessagingState.js +4 -2
- package/dist/cjs/groups/MessagingState.js.map +1 -1
- package/dist/cjs/mdns/MdnsBroadcaster.d.ts +3 -3
- package/dist/cjs/mdns/MdnsBroadcaster.d.ts.map +1 -1
- package/dist/cjs/mdns/MdnsBroadcaster.js +7 -4
- package/dist/cjs/mdns/MdnsBroadcaster.js.map +1 -1
- package/dist/cjs/mdns/MdnsService.d.ts.map +1 -1
- package/dist/cjs/mdns/MdnsService.js +2 -1
- package/dist/cjs/mdns/MdnsService.js.map +1 -1
- package/dist/cjs/peer/ControllerCommissioner.js +1 -1
- package/dist/cjs/peer/ControllerCommissioner.js.map +1 -1
- package/dist/cjs/peer/ControllerCommissioningFlow.d.ts +1 -1
- package/dist/cjs/peer/ControllerCommissioningFlow.d.ts.map +1 -1
- package/dist/cjs/peer/ControllerCommissioningFlow.js +3 -4
- package/dist/cjs/peer/ControllerCommissioningFlow.js.map +1 -1
- package/dist/cjs/protocol/DeviceCommissioner.d.ts.map +1 -1
- package/dist/cjs/protocol/DeviceCommissioner.js +1 -1
- package/dist/cjs/protocol/DeviceCommissioner.js.map +1 -1
- package/dist/cjs/protocol/ExchangeManager.d.ts +4 -2
- package/dist/cjs/protocol/ExchangeManager.d.ts.map +1 -1
- package/dist/cjs/protocol/ExchangeManager.js +11 -6
- package/dist/cjs/protocol/ExchangeManager.js.map +1 -1
- package/dist/cjs/protocol/MessageCounter.d.ts +4 -4
- package/dist/cjs/protocol/MessageCounter.d.ts.map +1 -1
- package/dist/cjs/protocol/MessageCounter.js +7 -6
- package/dist/cjs/protocol/MessageCounter.js.map +1 -1
- package/dist/cjs/session/GroupSession.d.ts.map +1 -1
- package/dist/cjs/session/GroupSession.js +7 -2
- package/dist/cjs/session/GroupSession.js.map +1 -1
- package/dist/cjs/session/InsecureSession.d.ts +2 -0
- package/dist/cjs/session/InsecureSession.d.ts.map +1 -1
- package/dist/cjs/session/InsecureSession.js +2 -2
- package/dist/cjs/session/InsecureSession.js.map +1 -1
- package/dist/cjs/session/NodeSession.d.ts +3 -1
- package/dist/cjs/session/NodeSession.d.ts.map +1 -1
- package/dist/cjs/session/NodeSession.js +21 -13
- package/dist/cjs/session/NodeSession.js.map +1 -1
- package/dist/cjs/session/SessionManager.d.ts +1 -0
- package/dist/cjs/session/SessionManager.d.ts.map +1 -1
- package/dist/cjs/session/SessionManager.js +13 -3
- package/dist/cjs/session/SessionManager.js.map +1 -1
- package/dist/cjs/session/case/CaseClient.d.ts.map +1 -1
- package/dist/cjs/session/case/CaseClient.js +16 -15
- package/dist/cjs/session/case/CaseClient.js.map +1 -1
- package/dist/cjs/session/case/CaseServer.d.ts.map +1 -1
- package/dist/cjs/session/case/CaseServer.js +22 -18
- package/dist/cjs/session/case/CaseServer.js.map +1 -1
- package/dist/cjs/session/pase/PaseClient.d.ts +4 -4
- package/dist/cjs/session/pase/PaseClient.d.ts.map +1 -1
- package/dist/cjs/session/pase/PaseClient.js +11 -9
- package/dist/cjs/session/pase/PaseClient.js.map +1 -1
- package/dist/cjs/session/pase/PaseServer.d.ts.map +1 -1
- package/dist/cjs/session/pase/PaseServer.js +6 -5
- package/dist/cjs/session/pase/PaseServer.js.map +1 -1
- package/dist/esm/certificate/AttestationCertificateManager.d.ts +3 -3
- package/dist/esm/certificate/AttestationCertificateManager.d.ts.map +1 -1
- package/dist/esm/certificate/AttestationCertificateManager.js +13 -11
- package/dist/esm/certificate/AttestationCertificateManager.js.map +1 -1
- package/dist/esm/certificate/CertificateAuthority.d.ts +5 -3
- package/dist/esm/certificate/CertificateAuthority.d.ts.map +1 -1
- package/dist/esm/certificate/CertificateAuthority.js +19 -11
- package/dist/esm/certificate/CertificateAuthority.js.map +1 -1
- package/dist/esm/certificate/CertificateManager.d.ts +18 -15
- package/dist/esm/certificate/CertificateManager.d.ts.map +1 -1
- package/dist/esm/certificate/CertificateManager.js +92 -84
- package/dist/esm/certificate/CertificateManager.js.map +2 -2
- package/dist/esm/certificate/CertificationDeclarationManager.d.ts +7 -1
- package/dist/esm/certificate/CertificationDeclarationManager.d.ts.map +1 -1
- package/dist/esm/certificate/CertificationDeclarationManager.js +2 -2
- package/dist/esm/certificate/CertificationDeclarationManager.js.map +1 -1
- package/dist/esm/certificate/DeviceCertification.d.ts +2 -2
- package/dist/esm/certificate/DeviceCertification.d.ts.map +1 -1
- package/dist/esm/certificate/DeviceCertification.js +11 -5
- package/dist/esm/certificate/DeviceCertification.js.map +1 -1
- package/dist/esm/common/FailsafeContext.js +1 -1
- package/dist/esm/common/FailsafeContext.js.map +1 -1
- package/dist/esm/fabric/Fabric.d.ts +6 -4
- package/dist/esm/fabric/Fabric.d.ts.map +1 -1
- package/dist/esm/fabric/Fabric.js +33 -21
- package/dist/esm/fabric/Fabric.js.map +1 -1
- package/dist/esm/fabric/FabricAuthority.d.ts +1 -1
- package/dist/esm/fabric/FabricAuthority.d.ts.map +1 -1
- package/dist/esm/fabric/FabricAuthority.js +8 -15
- package/dist/esm/fabric/FabricAuthority.js.map +1 -1
- package/dist/esm/fabric/FabricManager.d.ts +3 -2
- package/dist/esm/fabric/FabricManager.d.ts.map +1 -1
- package/dist/esm/fabric/FabricManager.js +9 -3
- package/dist/esm/fabric/FabricManager.js.map +1 -1
- package/dist/esm/fabric/TestFabric.d.ts.map +1 -1
- package/dist/esm/fabric/TestFabric.js +16 -20
- package/dist/esm/fabric/TestFabric.js.map +1 -1
- package/dist/esm/groups/FabricGroups.d.ts.map +1 -1
- package/dist/esm/groups/FabricGroups.js +12 -8
- package/dist/esm/groups/FabricGroups.js.map +1 -1
- package/dist/esm/groups/KeySets.d.ts +2 -2
- package/dist/esm/groups/KeySets.d.ts.map +1 -1
- package/dist/esm/groups/KeySets.js +3 -3
- package/dist/esm/groups/KeySets.js.map +1 -1
- package/dist/esm/groups/MessagingState.d.ts +2 -2
- package/dist/esm/groups/MessagingState.d.ts.map +1 -1
- package/dist/esm/groups/MessagingState.js +4 -2
- package/dist/esm/groups/MessagingState.js.map +1 -1
- package/dist/esm/mdns/MdnsBroadcaster.d.ts +3 -3
- package/dist/esm/mdns/MdnsBroadcaster.d.ts.map +1 -1
- package/dist/esm/mdns/MdnsBroadcaster.js +7 -5
- package/dist/esm/mdns/MdnsBroadcaster.js.map +1 -1
- package/dist/esm/mdns/MdnsService.d.ts.map +1 -1
- package/dist/esm/mdns/MdnsService.js +3 -1
- package/dist/esm/mdns/MdnsService.js.map +1 -1
- package/dist/esm/peer/ControllerCommissioner.js +1 -1
- package/dist/esm/peer/ControllerCommissioner.js.map +1 -1
- package/dist/esm/peer/ControllerCommissioningFlow.d.ts +1 -1
- package/dist/esm/peer/ControllerCommissioningFlow.d.ts.map +1 -1
- package/dist/esm/peer/ControllerCommissioningFlow.js +3 -5
- package/dist/esm/peer/ControllerCommissioningFlow.js.map +1 -1
- package/dist/esm/protocol/DeviceCommissioner.d.ts.map +1 -1
- package/dist/esm/protocol/DeviceCommissioner.js +1 -2
- package/dist/esm/protocol/DeviceCommissioner.js.map +1 -1
- package/dist/esm/protocol/ExchangeManager.d.ts +4 -2
- package/dist/esm/protocol/ExchangeManager.d.ts.map +1 -1
- package/dist/esm/protocol/ExchangeManager.js +11 -6
- package/dist/esm/protocol/ExchangeManager.js.map +1 -1
- package/dist/esm/protocol/MessageCounter.d.ts +4 -4
- package/dist/esm/protocol/MessageCounter.d.ts.map +1 -1
- package/dist/esm/protocol/MessageCounter.js +8 -7
- package/dist/esm/protocol/MessageCounter.js.map +1 -1
- package/dist/esm/session/GroupSession.d.ts.map +1 -1
- package/dist/esm/session/GroupSession.js +7 -3
- package/dist/esm/session/GroupSession.js.map +1 -1
- package/dist/esm/session/InsecureSession.d.ts +2 -0
- package/dist/esm/session/InsecureSession.d.ts.map +1 -1
- package/dist/esm/session/InsecureSession.js +2 -2
- package/dist/esm/session/InsecureSession.js.map +1 -1
- package/dist/esm/session/NodeSession.d.ts +3 -1
- package/dist/esm/session/NodeSession.d.ts.map +1 -1
- package/dist/esm/session/NodeSession.js +22 -14
- package/dist/esm/session/NodeSession.js.map +1 -1
- package/dist/esm/session/SessionManager.d.ts +1 -0
- package/dist/esm/session/SessionManager.d.ts.map +1 -1
- package/dist/esm/session/SessionManager.js +13 -4
- package/dist/esm/session/SessionManager.js.map +1 -1
- package/dist/esm/session/case/CaseClient.d.ts.map +1 -1
- package/dist/esm/session/case/CaseClient.js +17 -16
- package/dist/esm/session/case/CaseClient.js.map +1 -1
- package/dist/esm/session/case/CaseServer.d.ts.map +1 -1
- package/dist/esm/session/case/CaseServer.js +23 -19
- package/dist/esm/session/case/CaseServer.js.map +1 -1
- package/dist/esm/session/pase/PaseClient.d.ts +4 -4
- package/dist/esm/session/pase/PaseClient.d.ts.map +1 -1
- package/dist/esm/session/pase/PaseClient.js +12 -10
- package/dist/esm/session/pase/PaseClient.js.map +1 -1
- package/dist/esm/session/pase/PaseServer.d.ts.map +1 -1
- package/dist/esm/session/pase/PaseServer.js +6 -6
- package/dist/esm/session/pase/PaseServer.js.map +1 -1
- package/package.json +6 -6
- package/src/certificate/AttestationCertificateManager.ts +12 -10
- package/src/certificate/CertificateAuthority.ts +20 -11
- package/src/certificate/CertificateManager.ts +77 -72
- package/src/certificate/CertificationDeclarationManager.ts +3 -3
- package/src/certificate/DeviceCertification.ts +10 -4
- package/src/common/FailsafeContext.ts +1 -1
- package/src/fabric/Fabric.ts +36 -20
- package/src/fabric/FabricAuthority.ts +8 -16
- package/src/fabric/FabricManager.ts +10 -3
- package/src/fabric/TestFabric.ts +17 -22
- package/src/groups/FabricGroups.ts +20 -8
- package/src/groups/KeySets.ts +2 -2
- package/src/groups/MessagingState.ts +6 -3
- package/src/mdns/MdnsBroadcaster.ts +11 -4
- package/src/mdns/MdnsService.ts +3 -1
- package/src/peer/ControllerCommissioner.ts +1 -1
- package/src/peer/ControllerCommissioningFlow.ts +4 -6
- package/src/protocol/DeviceCommissioner.ts +1 -2
- package/src/protocol/ExchangeManager.ts +13 -6
- package/src/protocol/MessageCounter.ts +11 -3
- package/src/session/GroupSession.ts +7 -3
- package/src/session/InsecureSession.ts +4 -3
- package/src/session/NodeSession.ts +25 -14
- package/src/session/SessionManager.ts +14 -4
- package/src/session/case/CaseClient.ts +18 -16
- package/src/session/case/CaseServer.ts +22 -17
- package/src/session/pase/PaseClient.ts +11 -9
- package/src/session/pase/PaseServer.ts +6 -5
|
@@ -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
|
|
62
|
-
this.#rootKeyIdentifier = (await
|
|
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
|
|
147
|
+
const signature = await this.#certs.crypto.signEcdsa(
|
|
139
148
|
this.#initializedRootKeyPair,
|
|
140
|
-
|
|
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
|
|
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
|
|
183
|
+
const signature = await this.#certs.crypto.signEcdsa(
|
|
175
184
|
this.#initializedRootKeyPair,
|
|
176
|
-
|
|
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
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
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
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
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
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
625
|
+
export class CertificateManager {
|
|
626
|
+
#crypto: Crypto;
|
|
627
|
+
|
|
628
|
+
constructor(crypto: Crypto) {
|
|
629
|
+
this.#crypto = crypto;
|
|
624
630
|
}
|
|
625
631
|
|
|
626
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
677
|
+
async deviceAttestationCertToAsn1(cert: Unsigned<DeviceAttestationCertificate>, key: Key) {
|
|
668
678
|
const certificate = genericBuildAsn1Structure(cert);
|
|
669
|
-
const signature = await
|
|
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
|
-
|
|
689
|
+
async productAttestationIntermediateCertToAsn1(
|
|
680
690
|
cert: Unsigned<ProductAttestationIntermediateCertificate>,
|
|
681
691
|
key: Key,
|
|
682
692
|
) {
|
|
683
693
|
const certificate = genericBuildAsn1Structure(cert);
|
|
684
|
-
const signature = await
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
783
|
-
|
|
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
|
|
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
|
-
|
|
882
|
+
async verifyNodeOperationalCertificate(
|
|
878
883
|
nocCert: OperationalCertificate,
|
|
879
884
|
rootCert: RootCertificate,
|
|
880
885
|
icaCert?: IntermediateCertificate,
|
|
881
886
|
) {
|
|
882
|
-
|
|
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
|
|
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
|
-
|
|
1006
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
1135
|
+
signature: DerBitString(await this.#crypto.signEcdsa(key, DerCodec.encode(request), "der")),
|
|
1131
1136
|
});
|
|
1132
1137
|
}
|
|
1133
1138
|
|
|
1134
|
-
|
|
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
|
|
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(
|
|
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
|
|
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
|
|
package/src/fabric/Fabric.ts
CHANGED
|
@@ -49,6 +49,7 @@ export type ExposedFabricInformation = {
|
|
|
49
49
|
};
|
|
50
50
|
|
|
51
51
|
export class Fabric {
|
|
52
|
+
readonly #certs: CertificateManager;
|
|
52
53
|
readonly fabricIndex: FabricIndex;
|
|
53
54
|
readonly fabricId: FabricId;
|
|
54
55
|
readonly nodeId: NodeId;
|
|
@@ -63,14 +64,18 @@ export class Fabric {
|
|
|
63
64
|
readonly operationalCert: Uint8Array;
|
|
64
65
|
readonly #keyPair: Key;
|
|
65
66
|
readonly #sessions = new Set<Session>();
|
|
66
|
-
readonly #
|
|
67
|
+
readonly #groups: FabricGroups;
|
|
67
68
|
readonly #aclManager: FabricAccessControl;
|
|
68
69
|
#label: string;
|
|
69
70
|
#removeCallbacks = new Array<() => MaybePromise<void>>();
|
|
70
71
|
#persistCallback: ((isUpdate?: boolean) => MaybePromise<void>) | undefined;
|
|
71
72
|
#storage?: StorageContext;
|
|
72
73
|
|
|
73
|
-
constructor(config: Fabric.Config) {
|
|
74
|
+
constructor(certs: CertificateManager | Crypto, config: Fabric.Config) {
|
|
75
|
+
if (!(certs instanceof CertificateManager)) {
|
|
76
|
+
certs = new CertificateManager(certs);
|
|
77
|
+
}
|
|
78
|
+
this.#certs = certs;
|
|
74
79
|
this.fabricIndex = config.fabricIndex;
|
|
75
80
|
this.fabricId = config.fabricId;
|
|
76
81
|
this.nodeId = config.nodeId;
|
|
@@ -86,7 +91,11 @@ export class Fabric {
|
|
|
86
91
|
this.#label = config.label;
|
|
87
92
|
this.#keyPair = PrivateKey(config.keyPair);
|
|
88
93
|
this.#aclManager = new FabricAccessControl(this);
|
|
89
|
-
this.#
|
|
94
|
+
this.#groups = new FabricGroups(this);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
get crypto() {
|
|
98
|
+
return this.#certs.crypto;
|
|
90
99
|
}
|
|
91
100
|
|
|
92
101
|
get config(): Fabric.Config {
|
|
@@ -125,7 +134,7 @@ export class Fabric {
|
|
|
125
134
|
|
|
126
135
|
set storage(storage: StorageContext) {
|
|
127
136
|
this.#storage = storage;
|
|
128
|
-
this.#
|
|
137
|
+
this.#groups.storage = storage;
|
|
129
138
|
}
|
|
130
139
|
|
|
131
140
|
get storage(): StorageContext | undefined {
|
|
@@ -133,7 +142,7 @@ export class Fabric {
|
|
|
133
142
|
}
|
|
134
143
|
|
|
135
144
|
get groups() {
|
|
136
|
-
return this.#
|
|
145
|
+
return this.#groups;
|
|
137
146
|
}
|
|
138
147
|
|
|
139
148
|
get acl() {
|
|
@@ -145,7 +154,7 @@ export class Fabric {
|
|
|
145
154
|
}
|
|
146
155
|
|
|
147
156
|
sign(data: Uint8Array) {
|
|
148
|
-
return
|
|
157
|
+
return this.#certs.crypto.signEcdsa(this.#keyPair, data);
|
|
149
158
|
}
|
|
150
159
|
|
|
151
160
|
async verifyCredentials(operationalCert: Uint8Array, intermediateCACert?: Uint8Array) {
|
|
@@ -155,10 +164,10 @@ export class Fabric {
|
|
|
155
164
|
intermediateCACert !== undefined ? TlvIntermediateCertificate.decode(intermediateCACert) : undefined;
|
|
156
165
|
if (icaCert !== undefined) {
|
|
157
166
|
// Validate ICACertificate against Root Certificate
|
|
158
|
-
await
|
|
167
|
+
await this.#certs.verifyIntermediateCaCertificate(rootCert, icaCert);
|
|
159
168
|
}
|
|
160
169
|
// Validate NOC Certificate against ICA Certificate
|
|
161
|
-
await
|
|
170
|
+
await this.#certs.verifyNodeOperationalCertificate(nocCert, rootCert, icaCert);
|
|
162
171
|
}
|
|
163
172
|
|
|
164
173
|
matchesFabricIdAndRootPublicKey(fabricId: FabricId, rootPublicKey: Uint8Array) {
|
|
@@ -186,7 +195,10 @@ export class Fabric {
|
|
|
186
195
|
* returns the time-wise valid operational keys for that groupId.
|
|
187
196
|
*/
|
|
188
197
|
async currentDestinationIdFor(nodeId: NodeId, random: Uint8Array) {
|
|
189
|
-
return await
|
|
198
|
+
return await this.#certs.crypto.signHmac(
|
|
199
|
+
this.groups.keySets.currentKeyForId(0).key,
|
|
200
|
+
this.#generateSalt(nodeId, random),
|
|
201
|
+
);
|
|
190
202
|
}
|
|
191
203
|
|
|
192
204
|
/**
|
|
@@ -196,7 +208,9 @@ export class Fabric {
|
|
|
196
208
|
async destinationIdsFor(nodeId: NodeId, random: Uint8Array) {
|
|
197
209
|
const salt = this.#generateSalt(nodeId, random);
|
|
198
210
|
// Check all keys of keyset 0 - typically it is only the IPK
|
|
199
|
-
const destinationIds = this.groups.keySets
|
|
211
|
+
const destinationIds = this.groups.keySets
|
|
212
|
+
.allKeysForId(0)
|
|
213
|
+
.map(({ key }) => this.#certs.crypto.signHmac(key, salt));
|
|
200
214
|
return await Promise.all(destinationIds);
|
|
201
215
|
}
|
|
202
216
|
|
|
@@ -260,6 +274,7 @@ export class Fabric {
|
|
|
260
274
|
}
|
|
261
275
|
|
|
262
276
|
export class FabricBuilder {
|
|
277
|
+
#certs: CertificateManager;
|
|
263
278
|
#keyPair: PrivateKey;
|
|
264
279
|
#rootVendorId?: VendorId;
|
|
265
280
|
#rootCert?: Uint8Array;
|
|
@@ -273,12 +288,13 @@ export class FabricBuilder {
|
|
|
273
288
|
#fabricIndex?: FabricIndex;
|
|
274
289
|
#label = "";
|
|
275
290
|
|
|
276
|
-
constructor(key: PrivateKey) {
|
|
291
|
+
constructor(crypto: Crypto, key: PrivateKey) {
|
|
292
|
+
this.#certs = new CertificateManager(crypto);
|
|
277
293
|
this.#keyPair = key;
|
|
278
294
|
}
|
|
279
295
|
|
|
280
|
-
static async create() {
|
|
281
|
-
return new FabricBuilder(await
|
|
296
|
+
static async create(crypto: Crypto) {
|
|
297
|
+
return new FabricBuilder(crypto, await crypto.createKeyPair());
|
|
282
298
|
}
|
|
283
299
|
|
|
284
300
|
get publicKey() {
|
|
@@ -290,12 +306,12 @@ export class FabricBuilder {
|
|
|
290
306
|
}
|
|
291
307
|
|
|
292
308
|
createCertificateSigningRequest() {
|
|
293
|
-
return
|
|
309
|
+
return this.#certs.createCertificateSigningRequest(this.#keyPair);
|
|
294
310
|
}
|
|
295
311
|
|
|
296
312
|
async setRootCert(rootCert: Uint8Array) {
|
|
297
313
|
const decodedRootCertificate = TlvRootCertificate.decode(rootCert);
|
|
298
|
-
await
|
|
314
|
+
await this.#certs.verifyRootCertificate(decodedRootCertificate);
|
|
299
315
|
this.#rootCert = rootCert;
|
|
300
316
|
this.#rootPublicKey = decodedRootCertificate.ellipticCurvePublicKey;
|
|
301
317
|
return this;
|
|
@@ -334,9 +350,9 @@ export class FabricBuilder {
|
|
|
334
350
|
const icaCert =
|
|
335
351
|
intermediateCACert !== undefined ? TlvIntermediateCertificate.decode(intermediateCACert) : undefined;
|
|
336
352
|
if (icaCert !== undefined) {
|
|
337
|
-
await
|
|
353
|
+
await this.#certs.verifyIntermediateCaCertificate(rootCert, icaCert);
|
|
338
354
|
}
|
|
339
|
-
await
|
|
355
|
+
await this.#certs.verifyNodeOperationalCertificate(nocCert, rootCert, icaCert);
|
|
340
356
|
|
|
341
357
|
this.#operationalCert = operationalCert;
|
|
342
358
|
this.#intermediateCACert = intermediateCACert;
|
|
@@ -410,14 +426,14 @@ export class FabricBuilder {
|
|
|
410
426
|
this.#fabricIndex = fabricIndex;
|
|
411
427
|
const saltWriter = new DataWriter();
|
|
412
428
|
saltWriter.writeUInt64(this.#fabricId);
|
|
413
|
-
const operationalId = await
|
|
429
|
+
const operationalId = await this.#certs.crypto.createHkdfKey(
|
|
414
430
|
this.#rootPublicKey.slice(1),
|
|
415
431
|
saltWriter.toByteArray(),
|
|
416
432
|
COMPRESSED_FABRIC_ID_INFO,
|
|
417
433
|
8,
|
|
418
434
|
);
|
|
419
435
|
|
|
420
|
-
return new Fabric({
|
|
436
|
+
return new Fabric(this.#certs, {
|
|
421
437
|
fabricIndex: this.#fabricIndex,
|
|
422
438
|
fabricId: this.#fabricId,
|
|
423
439
|
nodeId: this.#nodeId,
|
|
@@ -428,7 +444,7 @@ export class FabricBuilder {
|
|
|
428
444
|
rootVendorId: this.#rootVendorId,
|
|
429
445
|
rootCert: this.#rootCert,
|
|
430
446
|
identityProtectionKey: this.#identityProtectionKey, // Epoch Key
|
|
431
|
-
operationalIdentityProtectionKey: await
|
|
447
|
+
operationalIdentityProtectionKey: await this.#certs.crypto.createHkdfKey(
|
|
432
448
|
this.#identityProtectionKey,
|
|
433
449
|
operationalId,
|
|
434
450
|
GROUP_SECURITY_INFO,
|