@matter/protocol 0.14.1-alpha.0-20250606-a9bcd03f9 → 0.15.0-alpha.0-20250612-ddd428561
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.js +2 -2
- package/dist/cjs/certificate/AttestationCertificateManager.js.map +1 -1
- package/dist/cjs/certificate/CertificateAuthority.d.ts +2 -2
- package/dist/cjs/certificate/CertificateAuthority.d.ts.map +1 -1
- package/dist/cjs/certificate/CertificateAuthority.js +5 -5
- package/dist/cjs/certificate/CertificateAuthority.js.map +1 -1
- package/dist/cjs/certificate/CertificateManager.d.ts +1 -1
- package/dist/cjs/certificate/CertificateManager.d.ts.map +1 -1
- package/dist/cjs/certificate/CertificateManager.js +21 -10
- package/dist/cjs/certificate/CertificateManager.js.map +1 -1
- package/dist/cjs/certificate/CertificationDeclarationManager.d.ts +1 -1
- package/dist/cjs/certificate/DeviceCertification.d.ts +1 -1
- package/dist/cjs/certificate/DeviceCertification.d.ts.map +1 -1
- package/dist/cjs/certificate/DeviceCertification.js +5 -3
- package/dist/cjs/certificate/DeviceCertification.js.map +1 -1
- package/dist/cjs/cluster/client/ClusterClient.d.ts.map +1 -1
- package/dist/cjs/cluster/client/ClusterClient.js +6 -0
- package/dist/cjs/cluster/client/ClusterClient.js.map +1 -1
- package/dist/cjs/cluster/client/ClusterClientTypes.d.ts +4 -1
- package/dist/cjs/cluster/client/ClusterClientTypes.d.ts.map +1 -1
- package/dist/cjs/codec/BtpCodec.d.ts +1 -1
- package/dist/cjs/codec/MessageCodec.d.ts +1 -1
- package/dist/cjs/fabric/Fabric.d.ts +8 -6
- package/dist/cjs/fabric/Fabric.d.ts.map +1 -1
- package/dist/cjs/fabric/Fabric.js +22 -15
- package/dist/cjs/fabric/Fabric.js.map +1 -1
- package/dist/cjs/fabric/FabricAuthority.d.ts +4 -0
- package/dist/cjs/fabric/FabricAuthority.d.ts.map +1 -1
- package/dist/cjs/fabric/FabricAuthority.js +6 -0
- package/dist/cjs/fabric/FabricAuthority.js.map +1 -1
- package/dist/cjs/fabric/FabricManager.d.ts.map +1 -1
- package/dist/cjs/fabric/FabricManager.js +9 -2
- package/dist/cjs/fabric/FabricManager.js.map +1 -1
- package/dist/cjs/fabric/TestFabric.d.ts +30 -0
- package/dist/cjs/fabric/TestFabric.d.ts.map +1 -0
- package/dist/cjs/fabric/TestFabric.js +70 -0
- package/dist/cjs/fabric/TestFabric.js.map +6 -0
- package/dist/cjs/fabric/index.d.ts +1 -0
- package/dist/cjs/fabric/index.d.ts.map +1 -1
- package/dist/cjs/fabric/index.js +1 -0
- package/dist/cjs/fabric/index.js.map +1 -1
- package/dist/cjs/groups/{FabricGroupsManager.d.ts → FabricGroups.d.ts} +2 -2
- package/dist/cjs/groups/FabricGroups.d.ts.map +1 -0
- package/dist/cjs/groups/{FabricGroupsManager.js → FabricGroups.js} +9 -9
- package/dist/cjs/groups/FabricGroups.js.map +6 -0
- package/dist/cjs/groups/KeySets.js +1 -1
- package/dist/cjs/groups/KeySets.js.map +1 -1
- package/dist/cjs/groups/index.d.ts +1 -1
- package/dist/cjs/groups/index.d.ts.map +1 -1
- package/dist/cjs/groups/index.js +1 -1
- package/dist/cjs/groups/index.js.map +1 -1
- package/dist/cjs/interaction/{AccessControlManager.d.ts → FabricAccessControl.d.ts} +12 -7
- package/dist/cjs/interaction/FabricAccessControl.d.ts.map +1 -0
- package/dist/cjs/interaction/{AccessControlManager.js → FabricAccessControl.js} +46 -21
- package/dist/cjs/interaction/FabricAccessControl.js.map +6 -0
- package/dist/cjs/interaction/index.d.ts +1 -1
- package/dist/cjs/interaction/index.d.ts.map +1 -1
- package/dist/cjs/interaction/index.js +1 -1
- package/dist/cjs/interaction/index.js.map +1 -1
- package/dist/cjs/peer/ControllerCommissioningFlow.d.ts.map +1 -1
- package/dist/cjs/peer/ControllerCommissioningFlow.js +2 -4
- package/dist/cjs/peer/ControllerCommissioningFlow.js.map +1 -1
- package/dist/cjs/protocol/DeviceCommissioner.js +1 -1
- package/dist/cjs/protocol/DeviceCommissioner.js.map +1 -1
- package/dist/cjs/protocol/MessageExchange.d.ts +6 -0
- package/dist/cjs/protocol/MessageExchange.d.ts.map +1 -1
- package/dist/cjs/protocol/MessageExchange.js +13 -0
- package/dist/cjs/protocol/MessageExchange.js.map +1 -1
- package/dist/cjs/securechannel/SecureChannelStatusMessageSchema.d.ts +1 -1
- package/dist/cjs/session/NodeSession.js +1 -1
- package/dist/cjs/session/Session.d.ts +1 -1
- package/dist/cjs/session/SessionManager.d.ts.map +1 -1
- package/dist/cjs/session/SessionManager.js +1 -0
- 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 +34 -30
- package/dist/cjs/session/case/CaseClient.js.map +1 -1
- package/dist/cjs/session/case/CaseMessages.d.ts +8 -8
- package/dist/cjs/session/case/CaseMessages.js +8 -8
- package/dist/cjs/session/case/CaseMessages.js.map +1 -1
- package/dist/cjs/session/case/CaseServer.d.ts.map +1 -1
- package/dist/cjs/session/case/CaseServer.js +26 -23
- package/dist/cjs/session/case/CaseServer.js.map +1 -1
- package/dist/cjs/session/pase/PaseClient.d.ts.map +1 -1
- package/dist/cjs/session/pase/PaseClient.js +4 -1
- 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 +4 -1
- package/dist/cjs/session/pase/PaseServer.js.map +1 -1
- package/dist/esm/certificate/AttestationCertificateManager.js +2 -2
- package/dist/esm/certificate/AttestationCertificateManager.js.map +1 -1
- package/dist/esm/certificate/CertificateAuthority.d.ts +2 -2
- package/dist/esm/certificate/CertificateAuthority.d.ts.map +1 -1
- package/dist/esm/certificate/CertificateAuthority.js +5 -5
- package/dist/esm/certificate/CertificateAuthority.js.map +1 -1
- package/dist/esm/certificate/CertificateManager.d.ts +1 -1
- package/dist/esm/certificate/CertificateManager.d.ts.map +1 -1
- package/dist/esm/certificate/CertificateManager.js +22 -11
- package/dist/esm/certificate/CertificateManager.js.map +1 -1
- package/dist/esm/certificate/CertificationDeclarationManager.d.ts +1 -1
- package/dist/esm/certificate/DeviceCertification.d.ts +1 -1
- package/dist/esm/certificate/DeviceCertification.d.ts.map +1 -1
- package/dist/esm/certificate/DeviceCertification.js +5 -3
- package/dist/esm/certificate/DeviceCertification.js.map +1 -1
- package/dist/esm/cluster/client/ClusterClient.d.ts.map +1 -1
- package/dist/esm/cluster/client/ClusterClient.js +6 -0
- package/dist/esm/cluster/client/ClusterClient.js.map +1 -1
- package/dist/esm/cluster/client/ClusterClientTypes.d.ts +4 -1
- package/dist/esm/cluster/client/ClusterClientTypes.d.ts.map +1 -1
- package/dist/esm/codec/BtpCodec.d.ts +1 -1
- package/dist/esm/codec/MessageCodec.d.ts +1 -1
- package/dist/esm/fabric/Fabric.d.ts +8 -6
- package/dist/esm/fabric/Fabric.d.ts.map +1 -1
- package/dist/esm/fabric/Fabric.js +22 -14
- package/dist/esm/fabric/Fabric.js.map +1 -1
- package/dist/esm/fabric/FabricAuthority.d.ts +4 -0
- package/dist/esm/fabric/FabricAuthority.d.ts.map +1 -1
- package/dist/esm/fabric/FabricAuthority.js +6 -0
- package/dist/esm/fabric/FabricAuthority.js.map +1 -1
- package/dist/esm/fabric/FabricManager.d.ts.map +1 -1
- package/dist/esm/fabric/FabricManager.js +9 -2
- package/dist/esm/fabric/FabricManager.js.map +1 -1
- package/dist/esm/fabric/TestFabric.d.ts +30 -0
- package/dist/esm/fabric/TestFabric.d.ts.map +1 -0
- package/dist/esm/fabric/TestFabric.js +50 -0
- package/dist/esm/fabric/TestFabric.js.map +6 -0
- package/dist/esm/fabric/index.d.ts +1 -0
- package/dist/esm/fabric/index.d.ts.map +1 -1
- package/dist/esm/fabric/index.js +1 -0
- package/dist/esm/fabric/index.js.map +1 -1
- package/dist/esm/groups/{FabricGroupsManager.d.ts → FabricGroups.d.ts} +2 -2
- package/dist/esm/groups/FabricGroups.d.ts.map +1 -0
- package/dist/esm/groups/{FabricGroupsManager.js → FabricGroups.js} +6 -6
- package/dist/esm/groups/FabricGroups.js.map +6 -0
- package/dist/esm/groups/KeySets.js +1 -1
- package/dist/esm/groups/KeySets.js.map +1 -1
- package/dist/esm/groups/index.d.ts +1 -1
- package/dist/esm/groups/index.d.ts.map +1 -1
- package/dist/esm/groups/index.js +1 -1
- package/dist/esm/interaction/{AccessControlManager.d.ts → FabricAccessControl.d.ts} +12 -7
- package/dist/esm/interaction/FabricAccessControl.d.ts.map +1 -0
- package/dist/esm/interaction/{AccessControlManager.js → FabricAccessControl.js} +44 -19
- package/dist/esm/interaction/FabricAccessControl.js.map +6 -0
- package/dist/esm/interaction/index.d.ts +1 -1
- package/dist/esm/interaction/index.d.ts.map +1 -1
- package/dist/esm/interaction/index.js +1 -1
- package/dist/esm/peer/ControllerCommissioningFlow.d.ts.map +1 -1
- package/dist/esm/peer/ControllerCommissioningFlow.js +2 -4
- package/dist/esm/peer/ControllerCommissioningFlow.js.map +1 -1
- package/dist/esm/protocol/DeviceCommissioner.js +1 -1
- package/dist/esm/protocol/DeviceCommissioner.js.map +1 -1
- package/dist/esm/protocol/MessageExchange.d.ts +6 -0
- package/dist/esm/protocol/MessageExchange.d.ts.map +1 -1
- package/dist/esm/protocol/MessageExchange.js +13 -0
- package/dist/esm/protocol/MessageExchange.js.map +1 -1
- package/dist/esm/securechannel/SecureChannelStatusMessageSchema.d.ts +1 -1
- package/dist/esm/session/NodeSession.js +1 -1
- package/dist/esm/session/Session.d.ts +1 -1
- package/dist/esm/session/SessionManager.d.ts.map +1 -1
- package/dist/esm/session/SessionManager.js +1 -0
- 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 +34 -30
- package/dist/esm/session/case/CaseClient.js.map +1 -1
- package/dist/esm/session/case/CaseMessages.d.ts +8 -8
- package/dist/esm/session/case/CaseMessages.js +8 -8
- package/dist/esm/session/case/CaseMessages.js.map +1 -1
- package/dist/esm/session/case/CaseServer.d.ts.map +1 -1
- package/dist/esm/session/case/CaseServer.js +26 -23
- package/dist/esm/session/case/CaseServer.js.map +1 -1
- package/dist/esm/session/pase/PaseClient.d.ts.map +1 -1
- package/dist/esm/session/pase/PaseClient.js +4 -1
- 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 +4 -1
- package/dist/esm/session/pase/PaseServer.js.map +1 -1
- package/package.json +6 -6
- package/src/certificate/AttestationCertificateManager.ts +2 -2
- package/src/certificate/CertificateAuthority.ts +7 -7
- package/src/certificate/CertificateManager.ts +22 -11
- package/src/certificate/DeviceCertification.ts +5 -3
- package/src/cluster/client/ClusterClient.ts +7 -0
- package/src/cluster/client/ClusterClientTypes.ts +7 -0
- package/src/fabric/Fabric.ts +24 -15
- package/src/fabric/FabricAuthority.ts +7 -0
- package/src/fabric/FabricManager.ts +9 -2
- package/src/fabric/TestFabric.ts +73 -0
- package/src/fabric/index.ts +1 -0
- package/src/groups/{FabricGroupsManager.ts → FabricGroups.ts} +4 -4
- package/src/groups/KeySets.ts +1 -1
- package/src/groups/index.ts +1 -1
- package/src/interaction/{AccessControlManager.ts → FabricAccessControl.ts} +61 -25
- package/src/interaction/index.ts +1 -1
- package/src/peer/ControllerCommissioningFlow.ts +2 -4
- package/src/protocol/DeviceCommissioner.ts +1 -1
- package/src/protocol/MessageExchange.ts +14 -0
- package/src/session/NodeSession.ts +1 -1
- package/src/session/SessionManager.ts +1 -0
- package/src/session/case/CaseClient.ts +34 -30
- package/src/session/case/CaseMessages.ts +8 -8
- package/src/session/case/CaseServer.ts +27 -23
- package/src/session/pase/PaseClient.ts +4 -1
- package/src/session/pase/PaseServer.ts +4 -1
- package/dist/cjs/groups/FabricGroupsManager.d.ts.map +0 -1
- package/dist/cjs/groups/FabricGroupsManager.js.map +0 -6
- package/dist/cjs/interaction/AccessControlManager.d.ts.map +0 -1
- package/dist/cjs/interaction/AccessControlManager.js.map +0 -6
- package/dist/esm/groups/FabricGroupsManager.d.ts.map +0 -1
- package/dist/esm/groups/FabricGroupsManager.js.map +0 -6
- package/dist/esm/interaction/AccessControlManager.d.ts.map +0 -1
- package/dist/esm/interaction/AccessControlManager.js.map +0 -6
|
@@ -5,12 +5,12 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import {
|
|
8
|
-
BitByteArray,
|
|
9
8
|
Bytes,
|
|
10
9
|
ContextTagged,
|
|
11
10
|
ContextTaggedBytes,
|
|
12
11
|
Crypto,
|
|
13
12
|
DatatypeOverride,
|
|
13
|
+
DerBitString,
|
|
14
14
|
DerCodec,
|
|
15
15
|
DerKey,
|
|
16
16
|
DerObject,
|
|
@@ -666,10 +666,11 @@ export namespace CertificateManager {
|
|
|
666
666
|
|
|
667
667
|
export async function deviceAttestationCertToAsn1(cert: Unsigned<DeviceAttestationCertificate>, key: Key) {
|
|
668
668
|
const certificate = genericBuildAsn1Structure(cert);
|
|
669
|
+
const signature = await Crypto.signEcdsa(key, DerCodec.encode(certificate), "der");
|
|
669
670
|
const certBytes = DerCodec.encode({
|
|
670
671
|
certificate,
|
|
671
672
|
signAlgorithm: X962.EcdsaWithSHA256,
|
|
672
|
-
signature:
|
|
673
|
+
signature: DerBitString(signature),
|
|
673
674
|
});
|
|
674
675
|
assertCertificateDerSize(certBytes);
|
|
675
676
|
return certBytes;
|
|
@@ -680,10 +681,11 @@ export namespace CertificateManager {
|
|
|
680
681
|
key: Key,
|
|
681
682
|
) {
|
|
682
683
|
const certificate = genericBuildAsn1Structure(cert);
|
|
684
|
+
const signature = await Crypto.signEcdsa(key, DerCodec.encode(certificate), "der");
|
|
683
685
|
const certBytes = DerCodec.encode({
|
|
684
686
|
certificate,
|
|
685
687
|
signAlgorithm: X962.EcdsaWithSHA256,
|
|
686
|
-
signature:
|
|
688
|
+
signature: DerBitString(signature),
|
|
687
689
|
});
|
|
688
690
|
assertCertificateDerSize(certBytes);
|
|
689
691
|
return certBytes;
|
|
@@ -697,13 +699,13 @@ export namespace CertificateManager {
|
|
|
697
699
|
const certBytes = DerCodec.encode({
|
|
698
700
|
certificate,
|
|
699
701
|
signAlgorithm: X962.EcdsaWithSHA256,
|
|
700
|
-
signature:
|
|
702
|
+
signature: DerBitString(await Crypto.signEcdsa(key, DerCodec.encode(certificate), "der")),
|
|
701
703
|
});
|
|
702
704
|
assertCertificateDerSize(certBytes);
|
|
703
705
|
return certBytes;
|
|
704
706
|
}
|
|
705
707
|
|
|
706
|
-
export function certificationDeclarationToAsn1(
|
|
708
|
+
export async function certificationDeclarationToAsn1(
|
|
707
709
|
eContent: Uint8Array,
|
|
708
710
|
subjectKeyIdentifier: Uint8Array,
|
|
709
711
|
privateKey: JsonWebKey,
|
|
@@ -718,7 +720,7 @@ export namespace CertificateManager {
|
|
|
718
720
|
subjectKeyIdentifier: ContextTaggedBytes(0, subjectKeyIdentifier),
|
|
719
721
|
digestAlgorithm: SHA256_CMS,
|
|
720
722
|
signatureAlgorithm: X962.EcdsaWithSHA256,
|
|
721
|
-
signature: Crypto.
|
|
723
|
+
signature: await Crypto.signEcdsa(privateKey, eContent, "der"),
|
|
722
724
|
},
|
|
723
725
|
],
|
|
724
726
|
};
|
|
@@ -861,7 +863,11 @@ export namespace CertificateManager {
|
|
|
861
863
|
);
|
|
862
864
|
}
|
|
863
865
|
|
|
864
|
-
await Crypto.
|
|
866
|
+
await Crypto.verifyEcdsa(
|
|
867
|
+
PublicKey(rootCert.ellipticCurvePublicKey),
|
|
868
|
+
rootCertToAsn1(rootCert),
|
|
869
|
+
rootCert.signature,
|
|
870
|
+
);
|
|
865
871
|
}
|
|
866
872
|
|
|
867
873
|
/**
|
|
@@ -985,7 +991,7 @@ export namespace CertificateManager {
|
|
|
985
991
|
);
|
|
986
992
|
}
|
|
987
993
|
|
|
988
|
-
await Crypto.
|
|
994
|
+
await Crypto.verifyEcdsa(
|
|
989
995
|
PublicKey((icaCert ?? rootCert).ellipticCurvePublicKey),
|
|
990
996
|
nodeOperationalCertToAsn1(nocCert),
|
|
991
997
|
nocCert.signature,
|
|
@@ -1103,7 +1109,7 @@ export namespace CertificateManager {
|
|
|
1103
1109
|
);
|
|
1104
1110
|
}
|
|
1105
1111
|
|
|
1106
|
-
await Crypto.
|
|
1112
|
+
await Crypto.verifyEcdsa(
|
|
1107
1113
|
PublicKey(rootCert.ellipticCurvePublicKey),
|
|
1108
1114
|
intermediateCaCertToAsn1(icaCert),
|
|
1109
1115
|
icaCert.signature,
|
|
@@ -1121,7 +1127,7 @@ export namespace CertificateManager {
|
|
|
1121
1127
|
return DerCodec.encode({
|
|
1122
1128
|
request,
|
|
1123
1129
|
signAlgorithm: X962.EcdsaWithSHA256,
|
|
1124
|
-
signature:
|
|
1130
|
+
signature: DerBitString(await Crypto.signEcdsa(key, DerCodec.encode(request), "der")),
|
|
1125
1131
|
});
|
|
1126
1132
|
}
|
|
1127
1133
|
|
|
@@ -1153,7 +1159,12 @@ export namespace CertificateManager {
|
|
|
1153
1159
|
)
|
|
1154
1160
|
)
|
|
1155
1161
|
throw new CertificateError("Unsupported signature type");
|
|
1156
|
-
await Crypto.
|
|
1162
|
+
await Crypto.verifyEcdsa(
|
|
1163
|
+
PublicKey(publicKey),
|
|
1164
|
+
DerCodec.encode(requestNode),
|
|
1165
|
+
signatureNode[DerKey.Bytes],
|
|
1166
|
+
"der",
|
|
1167
|
+
);
|
|
1157
1168
|
|
|
1158
1169
|
return publicKey;
|
|
1159
1170
|
}
|
|
@@ -55,7 +55,7 @@ export class DeviceCertification {
|
|
|
55
55
|
privateKey: PrivateKey(dacKeyPair.privateKey),
|
|
56
56
|
certificate: dac,
|
|
57
57
|
intermediateCertificate: await paa.getPAICert(),
|
|
58
|
-
declaration: CertificationDeclarationManager.generate(product.vendorId, product.productId),
|
|
58
|
+
declaration: await CertificationDeclarationManager.generate(product.vendorId, product.productId),
|
|
59
59
|
};
|
|
60
60
|
};
|
|
61
61
|
}
|
|
@@ -71,8 +71,10 @@ export class DeviceCertification {
|
|
|
71
71
|
});
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
-
sign(session: NodeSession, data: Uint8Array) {
|
|
75
|
-
|
|
74
|
+
async sign(session: NodeSession, data: Uint8Array) {
|
|
75
|
+
const { privateKey } = this.#assertInitialized();
|
|
76
|
+
const signature = await Crypto.signEcdsa(privateKey, [data, session.attestationChallengeKey]);
|
|
77
|
+
return signature;
|
|
76
78
|
}
|
|
77
79
|
|
|
78
80
|
/**
|
|
@@ -91,6 +91,13 @@ export function ClusterClient<const T extends ClusterType>(
|
|
|
91
91
|
throw e;
|
|
92
92
|
}
|
|
93
93
|
};
|
|
94
|
+
result[`get${capitalizedAttributeName}AttributeFromCache`] = () => {
|
|
95
|
+
if (isGroupAddress) {
|
|
96
|
+
throw new ImplementationError("Group cluster clients do not support reading attributes");
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return (attributes as any)[attributeName].getLocal();
|
|
100
|
+
};
|
|
94
101
|
result[`set${capitalizedAttributeName}Attribute`] = async <T>(value: T, dataVersion?: number) =>
|
|
95
102
|
(attributes as any)[attributeName].set(value, dataVersion);
|
|
96
103
|
result[`subscribe${capitalizedAttributeName}Attribute`] = async <T>(
|
|
@@ -100,6 +100,12 @@ type ClientAttributeGetters<A extends Attributes> = Omit<
|
|
|
100
100
|
},
|
|
101
101
|
keyof GlobalAttributes<any>
|
|
102
102
|
>;
|
|
103
|
+
type ClientLocalAttributeGetters<A extends Attributes> = Omit<
|
|
104
|
+
{
|
|
105
|
+
[P in keyof A as `get${Capitalize<string & P>}AttributeFromCache`]: () => GetterTypeFromSpec<A[P]> | undefined;
|
|
106
|
+
},
|
|
107
|
+
keyof GlobalAttributes<any>
|
|
108
|
+
>;
|
|
103
109
|
type ClientGlobalAttributeGetters<F extends BitSchema> = {
|
|
104
110
|
[P in GlobalAttributeNames<F> as `get${Capitalize<string & P>}Attribute`]: () => Promise<
|
|
105
111
|
GetterTypeFromSpec<GlobalAttributes<F>[P]>
|
|
@@ -265,6 +271,7 @@ export type ClusterClientObj<T extends ClusterType = ClusterType> = BaseClusterC
|
|
|
265
271
|
/** Returns if a given Command with provided name is present and supported at the connected cluster server. */
|
|
266
272
|
isCommandSupportedByName: (commandName: string) => boolean;
|
|
267
273
|
} & ClientAttributeGetters<T["attributes"]> &
|
|
274
|
+
ClientLocalAttributeGetters<T["attributes"]> &
|
|
268
275
|
ClientGlobalAttributeGetters<T["features"]> &
|
|
269
276
|
ClientAttributeSubscribers<T["attributes"]> &
|
|
270
277
|
ClientAttributeListeners<T["attributes"]> &
|
package/src/fabric/Fabric.ts
CHANGED
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
Bytes,
|
|
16
16
|
Crypto,
|
|
17
17
|
DataWriter,
|
|
18
|
+
Diagnostic,
|
|
18
19
|
Endian,
|
|
19
20
|
ImplementationError,
|
|
20
21
|
InternalError,
|
|
@@ -26,7 +27,8 @@ import {
|
|
|
26
27
|
PrivateKey,
|
|
27
28
|
StorageContext,
|
|
28
29
|
} from "#general";
|
|
29
|
-
import {
|
|
30
|
+
import { FabricGroups, GROUP_SECURITY_INFO } from "#groups/FabricGroups.js";
|
|
31
|
+
import { FabricAccessControl } from "#interaction/FabricAccessControl.js";
|
|
30
32
|
import { PeerAddress } from "#peer/PeerAddress.js";
|
|
31
33
|
import { Session } from "#session/Session.js";
|
|
32
34
|
import { CaseAuthenticatedTag, FabricId, FabricIndex, GroupId, NodeId, VendorId } from "#types";
|
|
@@ -61,7 +63,8 @@ export class Fabric {
|
|
|
61
63
|
readonly operationalCert: Uint8Array;
|
|
62
64
|
readonly #keyPair: Key;
|
|
63
65
|
readonly #sessions = new Set<Session>();
|
|
64
|
-
readonly #groupManager:
|
|
66
|
+
readonly #groupManager: FabricGroups;
|
|
67
|
+
readonly #aclManager: FabricAccessControl;
|
|
65
68
|
#label: string;
|
|
66
69
|
#removeCallbacks = new Array<() => MaybePromise<void>>();
|
|
67
70
|
#persistCallback: ((isUpdate?: boolean) => MaybePromise<void>) | undefined;
|
|
@@ -82,7 +85,8 @@ export class Fabric {
|
|
|
82
85
|
this.operationalCert = config.operationalCert;
|
|
83
86
|
this.#label = config.label;
|
|
84
87
|
this.#keyPair = PrivateKey(config.keyPair);
|
|
85
|
-
this.#
|
|
88
|
+
this.#aclManager = new FabricAccessControl(this);
|
|
89
|
+
this.#groupManager = new FabricGroups(this);
|
|
86
90
|
}
|
|
87
91
|
|
|
88
92
|
get config(): Fabric.Config {
|
|
@@ -132,12 +136,16 @@ export class Fabric {
|
|
|
132
136
|
return this.#groupManager;
|
|
133
137
|
}
|
|
134
138
|
|
|
139
|
+
get acl() {
|
|
140
|
+
return this.#aclManager;
|
|
141
|
+
}
|
|
142
|
+
|
|
135
143
|
get publicKey() {
|
|
136
144
|
return this.#keyPair.publicKey;
|
|
137
145
|
}
|
|
138
146
|
|
|
139
147
|
sign(data: Uint8Array) {
|
|
140
|
-
return Crypto.
|
|
148
|
+
return Crypto.signEcdsa(this.#keyPair, data);
|
|
141
149
|
}
|
|
142
150
|
|
|
143
151
|
async verifyCredentials(operationalCert: Uint8Array, intermediateCACert?: Uint8Array) {
|
|
@@ -174,21 +182,21 @@ export class Fabric {
|
|
|
174
182
|
}
|
|
175
183
|
|
|
176
184
|
/**
|
|
177
|
-
* Returns the destination IDs for a given nodeId, random value and optional groupId.
|
|
178
|
-
*
|
|
185
|
+
* Returns the destination IDs for a given nodeId, random value and optional groupId. When groupId is provided, it
|
|
186
|
+
* returns the time-wise valid operational keys for that groupId.
|
|
179
187
|
*/
|
|
180
188
|
async currentDestinationIdFor(nodeId: NodeId, random: Uint8Array) {
|
|
181
|
-
return await Crypto.
|
|
189
|
+
return await Crypto.signHmac(this.groups.keySets.currentKeyForId(0).key, this.#generateSalt(nodeId, random));
|
|
182
190
|
}
|
|
183
191
|
|
|
184
192
|
/**
|
|
185
|
-
* Returns the destination IDs for a given nodeId, random value and optional groupId.
|
|
186
|
-
*
|
|
193
|
+
* Returns the destination IDs for a given nodeId, random value and optional groupId. When groupId is provided, it
|
|
194
|
+
* returns all operational keys for that groupId.
|
|
187
195
|
*/
|
|
188
196
|
async destinationIdsFor(nodeId: NodeId, random: Uint8Array) {
|
|
189
197
|
const salt = this.#generateSalt(nodeId, random);
|
|
190
198
|
// Check all keys of keyset 0 - typically it is only the IPK
|
|
191
|
-
const destinationIds = this.groups.keySets.allKeysForId(0).map(({ key }) => Crypto.
|
|
199
|
+
const destinationIds = this.groups.keySets.allKeysForId(0).map(({ key }) => Crypto.signHmac(key, salt));
|
|
192
200
|
return await Promise.all(destinationIds);
|
|
193
201
|
}
|
|
194
202
|
|
|
@@ -306,18 +314,19 @@ export class FabricBuilder {
|
|
|
306
314
|
ellipticCurvePublicKey,
|
|
307
315
|
} = TlvOperationalCertificate.decode(operationalCert);
|
|
308
316
|
logger.debug(
|
|
309
|
-
|
|
317
|
+
"Installing operational certificate",
|
|
318
|
+
Diagnostic.dict({ nodeId, fabricId, caseAuthenticatedTags }),
|
|
310
319
|
);
|
|
311
320
|
if (caseAuthenticatedTags !== undefined) {
|
|
312
321
|
CaseAuthenticatedTag.validateNocTagList(caseAuthenticatedTags);
|
|
313
322
|
}
|
|
314
323
|
|
|
315
324
|
if (!Bytes.areEqual(ellipticCurvePublicKey, this.#keyPair.publicKey)) {
|
|
316
|
-
throw new PublicKeyError("Operational
|
|
325
|
+
throw new PublicKeyError("Operational certificate does not match public key");
|
|
317
326
|
}
|
|
318
327
|
|
|
319
328
|
if (this.#rootCert === undefined) {
|
|
320
|
-
throw new MatterFlowError("Root
|
|
329
|
+
throw new MatterFlowError("Root certificate needs to be set first");
|
|
321
330
|
}
|
|
322
331
|
|
|
323
332
|
const rootCert = TlvRootCertificate.decode(this.#rootCert);
|
|
@@ -401,7 +410,7 @@ export class FabricBuilder {
|
|
|
401
410
|
this.#fabricIndex = fabricIndex;
|
|
402
411
|
const saltWriter = new DataWriter();
|
|
403
412
|
saltWriter.writeUInt64(this.#fabricId);
|
|
404
|
-
const operationalId = await Crypto.
|
|
413
|
+
const operationalId = await Crypto.createHkdfKey(
|
|
405
414
|
this.#rootPublicKey.slice(1),
|
|
406
415
|
saltWriter.toByteArray(),
|
|
407
416
|
COMPRESSED_FABRIC_ID_INFO,
|
|
@@ -419,7 +428,7 @@ export class FabricBuilder {
|
|
|
419
428
|
rootVendorId: this.#rootVendorId,
|
|
420
429
|
rootCert: this.#rootCert,
|
|
421
430
|
identityProtectionKey: this.#identityProtectionKey, // Epoch Key
|
|
422
|
-
operationalIdentityProtectionKey: await Crypto.
|
|
431
|
+
operationalIdentityProtectionKey: await Crypto.createHkdfKey(
|
|
423
432
|
this.#identityProtectionKey,
|
|
424
433
|
operationalId,
|
|
425
434
|
GROUP_SECURITY_INFO,
|
|
@@ -160,6 +160,9 @@ export class FabricManager {
|
|
|
160
160
|
this.#fabrics.set(fabricIndex, fabric);
|
|
161
161
|
fabric.addRemoveCallback(async () => this.removeFabric(fabricIndex));
|
|
162
162
|
fabric.persistCallback = (isUpdate = true) => {
|
|
163
|
+
if (!this.#storage) {
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
163
166
|
const persistResult = this.persistFabrics();
|
|
164
167
|
return MaybePromise.then(persistResult, () => {
|
|
165
168
|
if (isUpdate) {
|
|
@@ -184,7 +187,9 @@ export class FabricManager {
|
|
|
184
187
|
`Fabric with index ${fabricIndex} cannot be removed because it does not exist.`,
|
|
185
188
|
);
|
|
186
189
|
this.#fabrics.delete(fabricIndex);
|
|
187
|
-
|
|
190
|
+
if (this.#storage) {
|
|
191
|
+
await this.persistFabrics();
|
|
192
|
+
}
|
|
188
193
|
await fabric.storage?.clearAll();
|
|
189
194
|
this.#events.deleted.emit(fabric);
|
|
190
195
|
}
|
|
@@ -253,7 +258,9 @@ export class FabricManager {
|
|
|
253
258
|
);
|
|
254
259
|
}
|
|
255
260
|
this.#fabrics.set(fabricIndex, fabric);
|
|
256
|
-
|
|
261
|
+
if (this.#storage) {
|
|
262
|
+
await this.persistFabrics();
|
|
263
|
+
}
|
|
257
264
|
this.#events.updated.emit(fabric);
|
|
258
265
|
}
|
|
259
266
|
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2022-2025 Project CHIP Authors
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { CertificateAuthority } from "#certificate/CertificateAuthority.js";
|
|
8
|
+
import { ImplementationError, nonentropic } from "#general";
|
|
9
|
+
import { FabricIndex, VendorId } from "#types";
|
|
10
|
+
import { FabricAuthority } from "./FabricAuthority.js";
|
|
11
|
+
import { FabricManager } from "./FabricManager.js";
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* WARNING: ONLY FOR USE IN PROTECTED TESTING ENVIRONMENTS WHERE SECURITY IS NOT A CONCERN
|
|
15
|
+
*
|
|
16
|
+
* Generate a fabric useful for testing purposes.
|
|
17
|
+
*
|
|
18
|
+
* The properties of the fabric, including crypto matter, are stable with regards to {@link index}.
|
|
19
|
+
*/
|
|
20
|
+
export async function TestFabric(options: TestFabric.Options = {}) {
|
|
21
|
+
const authority = await TestFabric.Authority(options);
|
|
22
|
+
|
|
23
|
+
return authority.createFabric();
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export namespace TestFabric {
|
|
27
|
+
/**
|
|
28
|
+
* WARNING: ONLY FOR USE IN PROTECTED TESTING ENVIRONMENTS WHERE SECURITY IS NOT A CONCERN
|
|
29
|
+
*
|
|
30
|
+
* Obtain a test authority.
|
|
31
|
+
*
|
|
32
|
+
* Crypto matter is stable with respect to {@link index}.
|
|
33
|
+
*/
|
|
34
|
+
export async function Authority({ index, fabrics }: Options = {}) {
|
|
35
|
+
if (index === undefined) {
|
|
36
|
+
if (fabrics) {
|
|
37
|
+
index = fabrics.allocateFabricIndex();
|
|
38
|
+
} else {
|
|
39
|
+
index = 1;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return forFabric(index, async () => {
|
|
44
|
+
const authority = new FabricAuthority({
|
|
45
|
+
ca: await CertificateAuthority.create(),
|
|
46
|
+
config: {
|
|
47
|
+
adminFabricLabel: `mock-fabric-${index}`,
|
|
48
|
+
adminVendorId: VendorId(0xfff1),
|
|
49
|
+
fabricIndex: FabricIndex(index),
|
|
50
|
+
},
|
|
51
|
+
fabrics: fabrics ?? new FabricManager(),
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
const createFabric = authority.createFabric.bind(authority);
|
|
55
|
+
authority.createFabric = () => forFabric(index ?? 1, createFabric);
|
|
56
|
+
|
|
57
|
+
return authority;
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export interface Options {
|
|
62
|
+
index?: number;
|
|
63
|
+
fabrics?: FabricManager;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
async function forFabric<T>(index: number, actor: () => Promise<T>): Promise<T> {
|
|
68
|
+
if (index < 1 || index > 254) {
|
|
69
|
+
throw new ImplementationError("Test fabric indexes must be in the range 1-254");
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return nonentropic(index, actor);
|
|
73
|
+
}
|
package/src/fabric/index.ts
CHANGED
|
@@ -15,7 +15,7 @@ export const GROUP_SECURITY_INFO = Bytes.fromString("GroupKey v1.0");
|
|
|
15
15
|
/**
|
|
16
16
|
* Class that contains an operational view on the Group Keys for a fabric
|
|
17
17
|
*/
|
|
18
|
-
export class
|
|
18
|
+
export class FabricGroups {
|
|
19
19
|
#fabric: Fabric;
|
|
20
20
|
#groups: Groups;
|
|
21
21
|
#messagingState: MessagingState;
|
|
@@ -122,11 +122,11 @@ export class FabricGroupsManager {
|
|
|
122
122
|
|
|
123
123
|
// Lets pre-calculate the operational keys
|
|
124
124
|
const operationalId = this.#fabric.operationalId;
|
|
125
|
-
const operationalEpochKey0 = await Crypto.
|
|
125
|
+
const operationalEpochKey0 = await Crypto.createHkdfKey(epochKey0, operationalId, GROUP_SECURITY_INFO);
|
|
126
126
|
const operationalEpochKey1 =
|
|
127
|
-
epochKey1 !== null ? await Crypto.
|
|
127
|
+
epochKey1 !== null ? await Crypto.createHkdfKey(epochKey1, operationalId, GROUP_SECURITY_INFO) : null;
|
|
128
128
|
const operationalEpochKey2 =
|
|
129
|
-
epochKey2 !== null ? await Crypto.
|
|
129
|
+
epochKey2 !== null ? await Crypto.createHkdfKey(epochKey2, operationalId, GROUP_SECURITY_INFO) : null;
|
|
130
130
|
this.#keySets.add({
|
|
131
131
|
...groupKeySet,
|
|
132
132
|
operationalEpochKey0,
|
package/src/groups/KeySets.ts
CHANGED
|
@@ -143,7 +143,7 @@ export class KeySets<T extends OperationalKeySet> extends BasicSet<T> {
|
|
|
143
143
|
/** Calculates a group session id based on the operational group key. */
|
|
144
144
|
async sessionIdFromKey(operationalGroupKey: Uint8Array) {
|
|
145
145
|
// GroupKeyHash is an array of 2 bytes (16 bits) per Crypto_KDF
|
|
146
|
-
const groupKeyHash = await Crypto.
|
|
146
|
+
const groupKeyHash = await Crypto.createHkdfKey(operationalGroupKey, new Uint8Array(), GROUP_KEY_INFO, 2);
|
|
147
147
|
|
|
148
148
|
// GroupSessionId is computed by considering the GroupKeyHash as a Big-Endian value. GroupSessionId is a scalar.
|
|
149
149
|
// Its use in fields within messages may cause a re-serialization into a different byte order than the one used
|
package/src/groups/index.ts
CHANGED
|
@@ -5,7 +5,8 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { Subject } from "#action/server/Subject.js";
|
|
7
7
|
import { AccessControl } from "#clusters/access-control";
|
|
8
|
-
import {
|
|
8
|
+
import { Fabric } from "#fabric/Fabric.js";
|
|
9
|
+
import { InternalError, Logger, MatterFlowError } from "#general";
|
|
9
10
|
import { AccessLevel } from "#model";
|
|
10
11
|
import {
|
|
11
12
|
CaseAuthenticatedTag,
|
|
@@ -20,6 +21,8 @@ import {
|
|
|
20
21
|
} from "#types";
|
|
21
22
|
import { AccessControl as AccessControlContext } from "../action/server/AccessControl.js";
|
|
22
23
|
|
|
24
|
+
const logger = Logger.get("FabricAccessControlManager");
|
|
25
|
+
|
|
23
26
|
export type AclEntry = Omit<AccessControl.AccessControlEntry, "privilege"> & {
|
|
24
27
|
privilege: AccessLevel;
|
|
25
28
|
};
|
|
@@ -59,10 +62,11 @@ export class AccessDeniedError extends StatusResponseError {
|
|
|
59
62
|
}
|
|
60
63
|
|
|
61
64
|
/**
|
|
62
|
-
* Implements Access Control Logic as per Matter Specification @see {@link MatterSpecification.v12.Core} § 6.6.5.2.
|
|
65
|
+
* Implements Access Control Logic For one fabric as per Matter Specification @see {@link MatterSpecification.v12.Core} § 6.6.5.2.
|
|
63
66
|
*/
|
|
64
|
-
export class
|
|
65
|
-
#
|
|
67
|
+
export class FabricAccessControl {
|
|
68
|
+
#fabricIndex: FabricIndex;
|
|
69
|
+
#aclList: AclList = [];
|
|
66
70
|
#extensionEntryAccessCheck: (
|
|
67
71
|
aclList: AclList,
|
|
68
72
|
aclEntry: AclEntry,
|
|
@@ -71,9 +75,36 @@ export class AccessControlManager {
|
|
|
71
75
|
clusterId: ClusterId,
|
|
72
76
|
) => boolean = () => true;
|
|
73
77
|
|
|
74
|
-
constructor(
|
|
75
|
-
|
|
76
|
-
|
|
78
|
+
constructor(fabric?: Fabric) {
|
|
79
|
+
if (fabric === undefined) {
|
|
80
|
+
this.#fabricIndex = FabricIndex.NO_FABRIC;
|
|
81
|
+
// Add the implicit default PASE ACL entry for the fabric
|
|
82
|
+
this.#aclList.push(ImplicitDefaultPaseAclEntry);
|
|
83
|
+
} else {
|
|
84
|
+
this.#fabricIndex = fabric.fabricIndex;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
set fabricIndex(fabricIndex: FabricIndex) {
|
|
89
|
+
if (this.#fabricIndex === undefined || this.#fabricIndex === FabricIndex.NO_FABRIC) {
|
|
90
|
+
this.#fabricIndex = fabricIndex;
|
|
91
|
+
}
|
|
92
|
+
throw new InternalError("Can not overwrite FabricIndex");
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Public method used to update the Access Control List on changes.
|
|
97
|
+
*/
|
|
98
|
+
set aclList(aclList: AccessControl.AccessControlEntry[]) {
|
|
99
|
+
if (aclList.some(({ fabricIndex }) => fabricIndex !== this.#fabricIndex)) {
|
|
100
|
+
throw new InternalError("ACL entries must match the fabric index of the manager");
|
|
101
|
+
}
|
|
102
|
+
this.#aclList = [...aclList] as unknown as AclList; // It is the same structure we just use an internal type for privilege
|
|
103
|
+
logger.info("ACL List updated for FabricIndex ", this.#fabricIndex, this.#aclList);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
set extensionEntryAccessCheck(
|
|
107
|
+
func: (
|
|
77
108
|
aclList: AclList,
|
|
78
109
|
aclEntry: AclEntry,
|
|
79
110
|
subjectDesc: IncomingSubjectDescriptor,
|
|
@@ -81,24 +112,31 @@ export class AccessControlManager {
|
|
|
81
112
|
clusterId: ClusterId,
|
|
82
113
|
) => boolean,
|
|
83
114
|
) {
|
|
84
|
-
this.#
|
|
85
|
-
if (extensionEntryAccessCheck !== undefined) {
|
|
86
|
-
this.#extensionEntryAccessCheck = extensionEntryAccessCheck;
|
|
87
|
-
}
|
|
115
|
+
this.#extensionEntryAccessCheck = func;
|
|
88
116
|
}
|
|
89
117
|
|
|
90
118
|
/**
|
|
91
|
-
*
|
|
119
|
+
* Implements the access control check for the given context, location and endpoint and is called by the
|
|
120
|
+
* InteractionServer. The method returns the list of granted Access privileges for the given context, location and
|
|
121
|
+
* endpoint.
|
|
92
122
|
*/
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
123
|
+
accessLevelsFor(
|
|
124
|
+
context: AccessControlContext.Session,
|
|
125
|
+
location: AccessControlContext.Location,
|
|
126
|
+
endpoint?: AclEndpointContext,
|
|
127
|
+
): AccessLevel[] {
|
|
128
|
+
if (location.cluster === undefined) {
|
|
129
|
+
// Without a cluster, internal behaviors are only accessible internally, so this is an irrelevant placeholder
|
|
130
|
+
logger.warn("Access control check without cluster, returning View access level");
|
|
131
|
+
return [AccessLevel.View];
|
|
132
|
+
}
|
|
133
|
+
if (endpoint === undefined) {
|
|
134
|
+
// Without an endpoint, we can't determine access levels, ???
|
|
135
|
+
logger.warn("Access control check without endpoint, returning View access level");
|
|
136
|
+
return [AccessLevel.View];
|
|
137
|
+
}
|
|
96
138
|
|
|
97
|
-
|
|
98
|
-
* Get the Access Control List for a given fabric.
|
|
99
|
-
*/
|
|
100
|
-
#getAccessControlEntriesForFabric(fabricIndex: FabricIndex): AclList {
|
|
101
|
-
return this.#aclList.filter(entry => entry.fabricIndex === fabricIndex);
|
|
139
|
+
return this.#getGrantedPrivileges(context, endpoint, location.cluster);
|
|
102
140
|
}
|
|
103
141
|
|
|
104
142
|
/**
|
|
@@ -152,15 +190,13 @@ export class AccessControlManager {
|
|
|
152
190
|
/**
|
|
153
191
|
* Determines the granted privileges for the given session, endpoint, and cluster ID and returns them.
|
|
154
192
|
*/
|
|
155
|
-
getGrantedPrivileges(
|
|
193
|
+
#getGrantedPrivileges(
|
|
156
194
|
context: AccessControlContext.Session,
|
|
157
195
|
endpoint: AclEndpointContext,
|
|
158
196
|
clusterId: ClusterId,
|
|
159
197
|
): AccessLevel[] {
|
|
160
198
|
const endpointId = endpoint.id;
|
|
161
|
-
const fabric = context.fabric;
|
|
162
199
|
const subjectDesc = this.#getIsdFromMessage(context);
|
|
163
|
-
const acl = fabric ? this.#getAccessControlEntriesForFabric(fabric) : [ImplicitDefaultPaseAclEntry];
|
|
164
200
|
|
|
165
201
|
// Granted privileges set is initially empty
|
|
166
202
|
const grantedPrivileges = new Set<AccessLevel>();
|
|
@@ -170,7 +206,7 @@ export class AccessControlManager {
|
|
|
170
206
|
this.#addGrantedPrivilege(grantedPrivileges, AccessLevel.Administer);
|
|
171
207
|
}
|
|
172
208
|
|
|
173
|
-
for (const aclEntry of
|
|
209
|
+
for (const aclEntry of this.#aclList) {
|
|
174
210
|
if (grantedPrivileges.has(AccessLevel.Administer)) {
|
|
175
211
|
// End checking if highest privilege is granted
|
|
176
212
|
break;
|
|
@@ -254,7 +290,7 @@ export class AccessControlManager {
|
|
|
254
290
|
}
|
|
255
291
|
|
|
256
292
|
// Extensions processing must not fail
|
|
257
|
-
if (!this.#extensionEntryAccessCheck(
|
|
293
|
+
if (!this.#extensionEntryAccessCheck(this.#aclList, aclEntry, subjectDesc, endpoint, clusterId)) {
|
|
258
294
|
continue;
|
|
259
295
|
}
|
|
260
296
|
|
package/src/interaction/index.ts
CHANGED
|
@@ -4,10 +4,10 @@
|
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
export * from "./AccessControlManager.js";
|
|
8
7
|
export * from "./AttributeDataDecoder.js";
|
|
9
8
|
export * from "./AttributeDataEncoder.js";
|
|
10
9
|
export * from "./EventDataDecoder.js";
|
|
10
|
+
export * from "./FabricAccessControl.js";
|
|
11
11
|
export * from "./InteractionClient.js";
|
|
12
12
|
export * from "./InteractionMessenger.js";
|
|
13
13
|
export * from "./Subscription.js";
|
|
@@ -1274,10 +1274,8 @@ export class ControllerCommissioningFlow {
|
|
|
1274
1274
|
// Assume concurrent connections are supported if not know (which should not be the case when we came here)
|
|
1275
1275
|
isConcurrentFlow,
|
|
1276
1276
|
);
|
|
1277
|
-
} catch (
|
|
1278
|
-
|
|
1279
|
-
commError.cause = error;
|
|
1280
|
-
throw commError;
|
|
1277
|
+
} catch (cause) {
|
|
1278
|
+
throw new OperativeConnectionFailedError("Operative reconnection with device failed", { cause });
|
|
1281
1279
|
}
|
|
1282
1280
|
|
|
1283
1281
|
reArmFailsafeInterval.stop();
|
|
@@ -153,7 +153,7 @@ export class DeviceCommissioner {
|
|
|
153
153
|
this.#context.secureChannelProtocol.setPaseCommissioner(
|
|
154
154
|
await PaseServer.fromPin(this.#context.sessions, this.#context.commissioningConfig.values.passcode, {
|
|
155
155
|
iterations: 1000,
|
|
156
|
-
salt: Crypto.
|
|
156
|
+
salt: Crypto.getRandomData(32),
|
|
157
157
|
}),
|
|
158
158
|
);
|
|
159
159
|
|