diff --git a/credentials/development/fetch-development-paa-certs-from-dcl.py b/credentials/development/fetch-development-paa-certs-from-dcl.py new file mode 100644 index 00000000000000..7ac67b275c220f --- /dev/null +++ b/credentials/development/fetch-development-paa-certs-from-dcl.py @@ -0,0 +1,131 @@ +#!/usr/bin/python + +# +# Copyright (c) 2022 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# Script that was used to fetch CHIP Development Product Attestation Authority (PAA) +# certificates from DCL. +# The script expects the path to the dcld tool binary as an input argument. +# +# Usage example when the script is run from the CHIP SDK root directory: +# python ./credentials/development/fetch-development-paa-certs-from-dcl.py /path/to/dcld +# +# The result will be stored in: +# credentials/development/paa-root-certs +# + +import os +import sys +import subprocess +import copy +import re +from cryptography.hazmat.primitives import serialization +from cryptography import x509 + + +def parse_paa_root_certs(cmdpipe, paa_list): + """ + example output of a query to all x509 root certs in DCL: + + certs: + - subject: CN=Non Production ONLY - XFN PAA Class 3 + subject_key_id: F8:99:A9:D5:AD:71:71:E4:C3:81:7F:14:10:7F:78:F0:D9:F7:62:E9 + - subject: CN=Matter Development PAA + subject_key_id: FA:92:CF:9:5E:FA:42:E1:14:30:65:16:32:FE:FE:1B:2C:77:A7:C8 + - subject: CN=Matter PAA 1,O=Google,C=US,1.3.6.1.4.1.37244.2.1=#130436303036 + subject_key_id: B0:0:56:81:B8:88:62:89:62:80:E1:21:18:A1:A8:BE:9:DE:93:21 + - subject: CN=Matter Test PAA,1.3.6.1.4.1.37244.2.1=#130431323544 + subject_key_id: E2:90:8D:36:9C:3C:A3:C1:13:BB:9:E2:4D:C1:CC:C5:A6:66:91:D4 + + Brief: + This method will search for the first line that contains ': ' char sequence. + From there, it assumes every 2 lines contain subject and subject key id info of + a valid PAA root certificate. + The paa_list parameter will contain a list of all valid PAA Root certificates + from DCL. + """ + + result = {} + + while True: + line = cmdpipe.stdout.readline() + if not line: + break + else: + if b': ' in line: + key, value = line.split(b': ') + result[key.strip(b' -')] = value.strip() + parse_paa_root_certs.counter += 1 + if parse_paa_root_certs.counter % 2 == 0: + paa_list.append(copy.deepcopy(result)) + + +def write_paa_root_cert(cmdpipe, subject): + filename = 'paa-root-certs/dcld_mirror_' + \ + re.sub('[^a-zA-Z0-9_-]', '', re.sub('[=, ]', '_', subject)) + with open(filename + '.pem', 'wb+') as outfile: + while True: + line = cmdpipe.stdout.readline() + if not line: + break + else: + if b'pem_cert: |' in line: + while True: + line = cmdpipe.stdout.readline() + outfile.write(line.strip(b' \t')) + if b'-----END CERTIFICATE-----' in line: + break + # convert pem file to der + with open(filename + '.pem', 'rb') as infile: + pem_certificate = x509.load_pem_x509_certificate(infile.read()) + with open(filename + '.der', 'wb+') as outfile: + der_certificate = pem_certificate.public_bytes( + serialization.Encoding.DER) + outfile.write(der_certificate) + + +def main(): + if len(sys.argv) == 2: + dcld = sys.argv[1] + else: + sys.exit( + "Error: Please specify exactly one input argument; the path to the dcld tool binary") + + previous_dir = os.getcwd() + abspath = os.path.dirname(sys.argv[0]) + os.chdir(abspath) + + os.makedirs('paa-root-certs', exist_ok=True) + + cmdpipe = subprocess.Popen([dcld, 'query', 'pki', 'all-x509-root-certs'], + stdout=subprocess.PIPE, stderr=subprocess.PIPE) + + paa_list = [] + parse_paa_root_certs.counter = 0 + parse_paa_root_certs(cmdpipe, paa_list) + + for paa in paa_list: + cmdpipe = subprocess.Popen( + [dcld, 'query', 'pki', 'x509-cert', '-u', + paa[b'subject'].decode("utf-8"), '-k', paa[b'subject_key_id'].decode("utf-8")], + stdout=subprocess.PIPE, stderr=subprocess.PIPE) + write_paa_root_cert(cmdpipe, paa[b'subject'].decode("utf-8")) + + os.chdir(previous_dir) + + +if __name__ == "__main__": + main() diff --git a/credentials/development/paa-root-certs/Chip-Test-PAA-FFF1-Cert.der b/credentials/development/paa-root-certs/Chip-Test-PAA-FFF1-Cert.der new file mode 100644 index 00000000000000..cb287bf8862bd4 Binary files /dev/null and b/credentials/development/paa-root-certs/Chip-Test-PAA-FFF1-Cert.der differ diff --git a/credentials/development/paa-root-certs/Chip-Test-PAA-FFF1-Cert.pem b/credentials/development/paa-root-certs/Chip-Test-PAA-FFF1-Cert.pem new file mode 100644 index 00000000000000..04c5822162ee48 --- /dev/null +++ b/credentials/development/paa-root-certs/Chip-Test-PAA-FFF1-Cert.pem @@ -0,0 +1,12 @@ +-----BEGIN CERTIFICATE----- +MIIBvTCCAWSgAwIBAgIITqjoMYLUHBwwCgYIKoZIzj0EAwIwMDEYMBYGA1UEAwwP +TWF0dGVyIFRlc3QgUEFBMRQwEgYKKwYBBAGConwCAQwERkZGMTAgFw0yMTA2Mjgx +NDIzNDNaGA85OTk5MTIzMTIzNTk1OVowMDEYMBYGA1UEAwwPTWF0dGVyIFRlc3Qg +UEFBMRQwEgYKKwYBBAGConwCAQwERkZGMTBZMBMGByqGSM49AgEGCCqGSM49AwEH +A0IABLbLY3KIfyko9brIGqnZOuJDHK2p154kL2UXfvnO2TKijs0Duq9qj8oYShpQ +NUKWDUU/MD8fGUIddR6Pjxqam3WjZjBkMBIGA1UdEwEB/wQIMAYBAf8CAQEwDgYD +VR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRq/SJ3H1Ef7L8WQZdnENzcMaFxfjAfBgNV +HSMEGDAWgBRq/SJ3H1Ef7L8WQZdnENzcMaFxfjAKBggqhkjOPQQDAgNHADBEAiBQ +qoAC9NkyqaAFOPZTaK0P/8jvu8m+t9pWmDXPmqdRDgIgI7rI/g8j51RFtlM5CBpH +mUkpxyqvChVI1A0DTVFLJd4= +-----END CERTIFICATE----- diff --git a/credentials/development/paa-root-certs/Chip-Test-PAA-NoVID-Cert.der b/credentials/development/paa-root-certs/Chip-Test-PAA-NoVID-Cert.der new file mode 100644 index 00000000000000..44898404bc0a27 Binary files /dev/null and b/credentials/development/paa-root-certs/Chip-Test-PAA-NoVID-Cert.der differ diff --git a/credentials/development/paa-root-certs/Chip-Test-PAA-NoVID-Cert.pem b/credentials/development/paa-root-certs/Chip-Test-PAA-NoVID-Cert.pem new file mode 100644 index 00000000000000..119b901d2b128e --- /dev/null +++ b/credentials/development/paa-root-certs/Chip-Test-PAA-NoVID-Cert.pem @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE----- +MIIBkTCCATegAwIBAgIHC4+6qN2G7jAKBggqhkjOPQQDAjAaMRgwFgYDVQQDDA9N +YXR0ZXIgVGVzdCBQQUEwIBcNMjEwNjI4MTQyMzQzWhgPOTk5OTEyMzEyMzU5NTla +MBoxGDAWBgNVBAMMD01hdHRlciBUZXN0IFBBQTBZMBMGByqGSM49AgEGCCqGSM49 +AwEHA0IABBDvAqgah7aBIfuo0xl4+AejF+UKqKgoRGgokUuTPejt1KXDnJ/3Gkzj +ZH/X9iZTt9JJX8ukwPR/h2iAA54HIEqjZjBkMBIGA1UdEwEB/wQIMAYBAf8CAQEw +DgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBR4XOcFuGuPTm/Hk6pgy0PqaWiC1TAf +BgNVHSMEGDAWgBR4XOcFuGuPTm/Hk6pgy0PqaWiC1TAKBggqhkjOPQQDAgNIADBF +AiEAue/bPqBqUuwL8B5h2u0sLRVt22zwFBAdq3mPrAX6R+UCIGAGHT411g2dSw1E +ja12EvfoXFguP8MS3Bh5TdNzcV5d +-----END CERTIFICATE----- diff --git a/credentials/development/paa-root-certs/dcld_mirror_CN_Matter_Development_PAA.der b/credentials/development/paa-root-certs/dcld_mirror_CN_Matter_Development_PAA.der new file mode 100644 index 00000000000000..56f4e1d436ec53 Binary files /dev/null and b/credentials/development/paa-root-certs/dcld_mirror_CN_Matter_Development_PAA.der differ diff --git a/credentials/development/paa-root-certs/dcld_mirror_CN_Matter_Development_PAA.pem b/credentials/development/paa-root-certs/dcld_mirror_CN_Matter_Development_PAA.pem new file mode 100644 index 00000000000000..b55bd3978d74d2 --- /dev/null +++ b/credentials/development/paa-root-certs/dcld_mirror_CN_Matter_Development_PAA.pem @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE----- +MIIBoDCCAUagAwIBAgIIV9Oi0B4xgZAwCgYIKoZIzj0EAwIwITEfMB0GA1UEAwwW +TWF0dGVyIERldmVsb3BtZW50IFBBQTAgFw0yMTA2MjgxNDIzNDNaGA85OTk5MTIz +MTIzNTk1OVowITEfMB0GA1UEAwwWTWF0dGVyIERldmVsb3BtZW50IFBBQTBZMBMG +ByqGSM49AgEGCCqGSM49AwEHA0IABBsPJZQuPZKr1nBMGieBoDjsUyEsTatYsL48 +QL37SSMjQhx53MetcBgQBxINyG8KiSU9iZPrN6tlLvjbE3XlsUWjZjBkMBIGA1Ud +EwEB/wQIMAYBAf8CAQEwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBT6ks8JXvpC +4RQwZRYy/v4bLHenyDAfBgNVHSMEGDAWgBT6ks8JXvpC4RQwZRYy/v4bLHenyDAK +BggqhkjOPQQDAgNIADBFAiBQp5AzZLZT/w6kY9xoSobdJccxo57+s8IM0t7RtmB+ +LwIhAK/U7UtqmeX4xVIdcB68+f1TuTlP2A/FmZL/Plu7tgo1 +-----END CERTIFICATE----- diff --git a/credentials/development/paa-root-certs/dcld_mirror_CN_Matter_PAA_1_O_Google_C_US_1361413724421_130436303036.der b/credentials/development/paa-root-certs/dcld_mirror_CN_Matter_PAA_1_O_Google_C_US_1361413724421_130436303036.der new file mode 100644 index 00000000000000..9b018d8fe77a3d Binary files /dev/null and b/credentials/development/paa-root-certs/dcld_mirror_CN_Matter_PAA_1_O_Google_C_US_1361413724421_130436303036.der differ diff --git a/credentials/development/paa-root-certs/dcld_mirror_CN_Matter_PAA_1_O_Google_C_US_1361413724421_130436303036.pem b/credentials/development/paa-root-certs/dcld_mirror_CN_Matter_PAA_1_O_Google_C_US_1361413724421_130436303036.pem new file mode 100644 index 00000000000000..a22831feda63f3 --- /dev/null +++ b/credentials/development/paa-root-certs/dcld_mirror_CN_Matter_PAA_1_O_Google_C_US_1361413724421_130436303036.pem @@ -0,0 +1,13 @@ +-----BEGIN CERTIFICATE----- +MIIB7TCCAZOgAwIBAgIBATAKBggqhkjOPQQDAjBLMQswCQYDVQQGEwJVUzEPMA0G +A1UECgwGR29vZ2xlMRUwEwYDVQQDDAxNYXR0ZXIgUEFBIDExFDASBgorBgEEAYKi +fAIBDAQ2MDA2MCAXDTIxMTIwODIwMjYwM1oYDzIxMjExMjA4MjAyNjAzWjBLMQsw +CQYDVQQGEwJVUzEPMA0GA1UECgwGR29vZ2xlMRUwEwYDVQQDDAxNYXR0ZXIgUEFB +IDExFDASBgorBgEEAYKifAIBDAQ2MDA2MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcD +QgAE8iZX+exx8NDV7jYKorx3EcsD1gessexUTSimIfvFI2PySlReMjJDVCGIzXor +hTYFOzwMAx4b6ogNMIUmcW7uT6NmMGQwEgYDVR0TAQH/BAgwBgEB/wIBATAOBgNV +HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFLAAVoG4iGKJYoDhIRihqL4J3pMhMB8GA1Ud +IwQYMBaAFLAAVoG4iGKJYoDhIRihqL4J3pMhMAoGCCqGSM49BAMCA0gAMEUCIQCV +c26cVlyqjhQfcgN3udpne6zZQdyVMNLRWZn3EENBkAIgasUeFU8zaUt8bKNWd0k+ +4RQp5Cp5wYzrE8AxJ9BiA/E= +-----END CERTIFICATE----- diff --git a/credentials/development/paa-root-certs/dcld_mirror_CN_Non_Production_ONLY_-_XFN_PAA_Class_3.der b/credentials/development/paa-root-certs/dcld_mirror_CN_Non_Production_ONLY_-_XFN_PAA_Class_3.der new file mode 100644 index 00000000000000..388fe3b6594076 Binary files /dev/null and b/credentials/development/paa-root-certs/dcld_mirror_CN_Non_Production_ONLY_-_XFN_PAA_Class_3.der differ diff --git a/credentials/development/paa-root-certs/dcld_mirror_CN_Non_Production_ONLY_-_XFN_PAA_Class_3.pem b/credentials/development/paa-root-certs/dcld_mirror_CN_Non_Production_ONLY_-_XFN_PAA_Class_3.pem new file mode 100644 index 00000000000000..bf9fa469f7397c --- /dev/null +++ b/credentials/development/paa-root-certs/dcld_mirror_CN_Non_Production_ONLY_-_XFN_PAA_Class_3.pem @@ -0,0 +1,12 @@ +-----BEGIN CERTIFICATE----- +MIIByjCCAXCgAwIBAgIUFkdW6XaPDQDsJ3530eRkiOtYbWQwCgYIKoZIzj0EAwIw +MDEuMCwGA1UEAwwlTm9uIFByb2R1Y3Rpb24gT05MWSAtIFhGTiBQQUEgQ2xhc3Mg +MzAgFw0yMTEyMTQwMzI3MzZaGA8yMDUxMTIwNzAzMjczNlowMDEuMCwGA1UEAwwl +Tm9uIFByb2R1Y3Rpb24gT05MWSAtIFhGTiBQQUEgQ2xhc3MgMzBZMBMGByqGSM49 +AgEGCCqGSM49AwEHA0IABB+Unq8KdMuQ6xWFKtAVGreDGzDlyLrpuSIZ86eMswgu +4xvjijYN6iljia1HjxVTTRdieROa7mpoLD7qEUC5yjmjZjBkMBIGA1UdEwEB/wQI +MAYBAf8CAQEwHwYDVR0jBBgwFoAU+Jmp1a1xceTDgX8UEH948Nn3YukwHQYDVR0O +BBYEFPiZqdWtcXHkw4F/FBB/ePDZ92LpMA4GA1UdDwEB/wQEAwIBhjAKBggqhkjO +PQQDAgNIADBFAiBYIsjeauI2nDknU1ThEDzyGfg4F9tLSkiuTrTJGr5EqQIhAMFX +bxTzgOfx0RPgpEU8syFEYyXCBcv4hV14rWddc08G +-----END CERTIFICATE----- diff --git a/examples/chip-tool/BUILD.gn b/examples/chip-tool/BUILD.gn index 8f0be3b24f0b2d..03f97a667ad84a 100644 --- a/examples/chip-tool/BUILD.gn +++ b/examples/chip-tool/BUILD.gn @@ -76,6 +76,7 @@ static_library("chip-tool-utils") { "${chip_root}/src/app/tests/suites/commands/system", "${chip_root}/src/app/tests/suites/pics", "${chip_root}/src/controller/data_model", + "${chip_root}/src/credentials:file_attestation_trust_store", "${chip_root}/src/lib", "${chip_root}/src/platform", "${chip_root}/third_party/inipp", diff --git a/examples/chip-tool/commands/common/CHIPCommand.cpp b/examples/chip-tool/commands/common/CHIPCommand.cpp index fe981615def3b8..90dc5bf8c2cb27 100644 --- a/examples/chip-tool/commands/common/CHIPCommand.cpp +++ b/examples/chip-tool/commands/common/CHIPCommand.cpp @@ -20,6 +20,7 @@ #include #include +#include #include #include #include @@ -36,6 +37,22 @@ constexpr chip::FabricId kIdentityAlphaFabricId = 1; constexpr chip::FabricId kIdentityBetaFabricId = 2; constexpr chip::FabricId kIdentityGammaFabricId = 3; +namespace { +const chip::Credentials::AttestationTrustStore * GetTestFileAttestationTrustStore(const char * paaTrustStorePath) +{ + static chip::Credentials::FileAttestationTrustStore attestationTrustStore{ paaTrustStorePath }; + + if (attestationTrustStore.IsInitialized()) + { + return &attestationTrustStore; + } + else + { + return nullptr; + } +} +} // namespace + CHIP_ERROR CHIPCommand::Run() { StartTracing(); @@ -58,8 +75,17 @@ CHIP_ERROR CHIPCommand::Run() factoryInitParams.listenPort = port; ReturnLogErrorOnFailure(DeviceControllerFactory::GetInstance().Init(factoryInitParams)); - // TODO(issue #15209): Replace this trust store with file-based trust store - const chip::Credentials::AttestationTrustStore * trustStore = chip::Credentials::GetTestAttestationTrustStore(); + const chip::Credentials::AttestationTrustStore * trustStore = + GetTestFileAttestationTrustStore(mPaaTrustStorePath.HasValue() ? mPaaTrustStorePath.Value() : "."); + if (trustStore == nullptr) + { + ChipLogError(chipTool, "No PAAs found in path: %s", mPaaTrustStorePath.HasValue() ? mPaaTrustStorePath.Value() : "."); + ChipLogError(chipTool, + "Please specify a valid path containing trusted PAA certificates using [--paa-trust-store-path paa/file/path] " + "argument"); + + return CHIP_ERROR_INVALID_ARGUMENT; + } ReturnLogErrorOnFailure(InitializeCommissioner(kIdentityNull, kIdentityNullFabricId, trustStore)); ReturnLogErrorOnFailure(InitializeCommissioner(kIdentityAlpha, kIdentityAlphaFabricId, trustStore)); diff --git a/scripts/requirements.txt b/scripts/requirements.txt index 0ed83234cb9126..b232e413e8a5bd 100644 --- a/scripts/requirements.txt +++ b/scripts/requirements.txt @@ -51,3 +51,5 @@ click # scripts/idl lark stringcase + +cryptography diff --git a/scripts/tests/chiptest/test_definition.py b/scripts/tests/chiptest/test_definition.py index 0642c7a4513424..f9a6463a80984e 100644 --- a/scripts/tests/chiptest/test_definition.py +++ b/scripts/tests/chiptest/test_definition.py @@ -24,6 +24,7 @@ from random import randrange TEST_NODE_ID = '0x12344321' +DEVELOPMENT_PAA_LIST = './credentials/development/paa-root-certs' class App: @@ -240,11 +241,13 @@ def Run(self, runner, apps_register, paths: ApplicationPaths): app.start(str(randrange(1, 4096))) runner.RunSubprocess( - tool_cmd + ['pairing', 'qrcode', TEST_NODE_ID, app.setupCode], + tool_cmd + ['pairing', 'qrcode', TEST_NODE_ID, app.setupCode] + + ['--paa-trust-store-path', DEVELOPMENT_PAA_LIST], name='PAIR', dependencies=[apps_register]) runner.RunSubprocess( - tool_cmd + ['tests', self.run_name], + tool_cmd + ['tests', self.run_name] + + ['--paa-trust-store-path', DEVELOPMENT_PAA_LIST], name='TEST', dependencies=[apps_register]) except Exception: diff --git a/scripts/tools/check_includes_config.py b/scripts/tools/check_includes_config.py index 8b7b2e152b0d37..55b27e9e03e304 100644 --- a/scripts/tools/check_includes_config.py +++ b/scripts/tools/check_includes_config.py @@ -128,6 +128,9 @@ 'src/app/clusters/media-playback-server/media-playback-delegate.h': {'list'}, 'src/app/clusters/target-navigator-server/target-navigator-delegate.h': {'list'}, + 'src/credentials/attestation_verifier/FileAttestationTrustStore.h': {'vector'}, + 'src/credentials/attestation_verifier/FileAttestationTrustStore.cpp': {'string'}, + 'src/setup_payload/AdditionalDataPayload.h': {'string'}, 'src/setup_payload/AdditionalDataPayloadParser.cpp': {'vector'}, 'src/setup_payload/Base38Decode.h': {'string', 'vector'}, diff --git a/src/controller/python/BUILD.gn b/src/controller/python/BUILD.gn index 833b5860ecfa35..46e67a6bc98896 100644 --- a/src/controller/python/BUILD.gn +++ b/src/controller/python/BUILD.gn @@ -99,7 +99,10 @@ shared_library("ChipDeviceCtrl") { ] if (chip_controller) { - public_deps += [ "${chip_root}/src/controller/data_model" ] + public_deps += [ + "${chip_root}/src/controller/data_model", + "${chip_root}/src/credentials:file_attestation_trust_store", + ] } else { public_deps += [ "$chip_data_model" ] } diff --git a/src/controller/python/OpCredsBinding.cpp b/src/controller/python/OpCredsBinding.cpp index 5dbf928dd7e2a9..464b10097129e5 100644 --- a/src/controller/python/OpCredsBinding.cpp +++ b/src/controller/python/OpCredsBinding.cpp @@ -37,6 +37,7 @@ #include #include +#include using namespace chip; @@ -48,6 +49,15 @@ using Py_GenerateNOCChainFunc = void (*)(void * pyContext, const char * using Py_SetNodeIdForNextNOCRequest = void (*)(void * pyContext, NodeId nodeId); using Py_SetFabricIdForNextNOCRequest = void (*)(void * pyContext, FabricId fabricId); +namespace { +const chip::Credentials::AttestationTrustStore * GetTestFileAttestationTrustStore(const char * paaTrustStorePath) +{ + static chip::Credentials::FileAttestationTrustStore attestationTrustStore{ paaTrustStorePath }; + + return &attestationTrustStore; +} +} // namespace + namespace chip { namespace Controller { namespace Python { @@ -129,7 +139,8 @@ void * pychip_OpCreds_InitializeDelegate(void * pyContext, uint32_t fabricCreden ChipError::StorageType pychip_OpCreds_AllocateController(OpCredsContext * context, chip::Controller::DeviceCommissioner ** outDevCtrl, uint8_t fabricIndex, - FabricId fabricId, chip::NodeId nodeId, bool useTestCommissioner) + FabricId fabricId, chip::NodeId nodeId, const char * paaTrustStorePath, + bool useTestCommissioner) { ChipLogDetail(Controller, "Creating New Device Controller"); @@ -139,8 +150,8 @@ ChipError::StorageType pychip_OpCreds_AllocateController(OpCredsContext * contex VerifyOrReturnError(devCtrl != nullptr, CHIP_ERROR_NO_MEMORY.AsInteger()); // Initialize device attestation verifier - // TODO: Replace testingRootStore with a AttestationTrustStore that has the necessary official PAA roots available - const chip::Credentials::AttestationTrustStore * testingRootStore = chip::Credentials::GetTestAttestationTrustStore(); + const chip::Credentials::AttestationTrustStore * testingRootStore = GetTestFileAttestationTrustStore( + paaTrustStorePath == nullptr ? "./credentials/development/paa-root-certs" : paaTrustStorePath); SetDeviceAttestationVerifier(GetDefaultDACVerifier(testingRootStore)); chip::Crypto::P256Keypair ephemeralKey; diff --git a/src/controller/python/chip-device-ctrl.py b/src/controller/python/chip-device-ctrl.py index cfd79eb1272d0b..7d8a5f245db57c 100755 --- a/src/controller/python/chip-device-ctrl.py +++ b/src/controller/python/chip-device-ctrl.py @@ -182,7 +182,8 @@ def __init__(self, rendezvousAddr=None, controllerNodeId=1, bluetoothAdapter=Non self.chipStack = ChipStack.ChipStack( bluetoothAdapter=bluetoothAdapter, persistentStoragePath='/tmp/chip-device-ctrl-storage.json') self.fabricAdmin = FabricAdmin.FabricAdmin() - self.devCtrl = self.fabricAdmin.NewController(controllerNodeId, True) + self.devCtrl = self.fabricAdmin.NewController( + nodeId=controllerNodeId, useTestCommissioner=True) self.commissionableNodeCtrl = ChipCommissionableNodeCtrl.ChipCommissionableNodeController( self.chipStack) diff --git a/src/controller/python/chip/ChipDeviceCtrl.py b/src/controller/python/chip/ChipDeviceCtrl.py index 00645dd03ef8ad..c44e1a43f3e9f5 100644 --- a/src/controller/python/chip/ChipDeviceCtrl.py +++ b/src/controller/python/chip/ChipDeviceCtrl.py @@ -84,7 +84,7 @@ class DCState(enum.IntEnum): class ChipDeviceController(): activeList = set() - def __init__(self, opCredsContext: ctypes.c_void_p, fabricId: int, fabricIndex: int, nodeId: int, useTestCommissioner: bool = False): + def __init__(self, opCredsContext: ctypes.c_void_p, fabricId: int, fabricIndex: int, nodeId: int, paaTrustStorePath: str = None, useTestCommissioner: bool = False): self.state = DCState.NOT_INITIALIZED self.devCtrl = None self._ChipStack = builtins.chipStack @@ -96,7 +96,7 @@ def __init__(self, opCredsContext: ctypes.c_void_p, fabricId: int, fabricIndex: res = self._ChipStack.Call( lambda: self._dmLib.pychip_OpCreds_AllocateController(ctypes.c_void_p( - opCredsContext), pointer(devCtrl), fabricIndex, fabricId, nodeId, useTestCommissioner) + opCredsContext), pointer(devCtrl), fabricIndex, fabricId, nodeId, ctypes.c_char_p(str.encode(paaTrustStorePath)), useTestCommissioner) ) if res != 0: diff --git a/src/controller/python/chip/FabricAdmin.py b/src/controller/python/chip/FabricAdmin.py index 63e6c897a452c4..c0591d950096cc 100644 --- a/src/controller/python/chip/FabricAdmin.py +++ b/src/controller/python/chip/FabricAdmin.py @@ -152,7 +152,7 @@ def __init__(self, rcac: bytes = None, icac: bytes = None, fabricIndex: int = No FabricAdmin.activeAdmins.add(self) - def NewController(self, nodeId: int = None, useTestCommissioner: bool = False): + def NewController(self, nodeId: int = None, paaTrustStorePath: str = None, useTestCommissioner: bool = False): ''' Vend a new controller on this fabric seeded with the right fabric details. ''' if (not(self._isActive)): @@ -166,7 +166,7 @@ def NewController(self, nodeId: int = None, useTestCommissioner: bool = False): print( f"Allocating new controller with FabricId: {self._fabricId}({self._fabricIndex}), NodeId: {nodeId}") controller = ChipDeviceCtrl.ChipDeviceController( - self.closure, self._fabricId, self._fabricIndex, nodeId, useTestCommissioner) + self.closure, self._fabricId, self._fabricIndex, nodeId, paaTrustStorePath, useTestCommissioner) return controller def ShutdownAll(): diff --git a/src/controller/python/chip/internal/CommissionerImpl.cpp b/src/controller/python/chip/internal/CommissionerImpl.cpp index 94fe9b1dd27673..709c1bd595e8c7 100644 --- a/src/controller/python/chip/internal/CommissionerImpl.cpp +++ b/src/controller/python/chip/internal/CommissionerImpl.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -34,6 +35,13 @@ using DeviceControllerFactory = chip::Controller::DeviceControllerFactory; namespace { +const chip::Credentials::AttestationTrustStore * GetTestFileAttestationTrustStore(const char * paaTrustStorePath) +{ + static chip::Credentials::FileAttestationTrustStore attestationTrustStore{ paaTrustStorePath }; + + return &attestationTrustStore; +} + class ServerStorageDelegate : public chip::PersistentStorageDelegate { public: @@ -111,8 +119,9 @@ extern "C" chip::Controller::DeviceCommissioner * pychip_internal_Commissioner_N chip::Crypto::P256Keypair ephemeralKey; // Initialize device attestation verifier - // TODO: Replace testingRootStore with a AttestationTrustStore that has the necessary official PAA roots available - const chip::Credentials::AttestationTrustStore * testingRootStore = chip::Credentials::GetTestAttestationTrustStore(); + // TODO: add option to pass in custom PAA Trust Store path to the python controller app + const chip::Credentials::AttestationTrustStore * testingRootStore = + GetTestFileAttestationTrustStore("./credentials/development/paa-root-certs"); chip::Credentials::SetDeviceAttestationVerifier(chip::Credentials::GetDefaultDACVerifier(testingRootStore)); factoryParams.fabricIndependentStorage = &gServerStorage; diff --git a/src/controller/python/test/test_scripts/base.py b/src/controller/python/test/test_scripts/base.py index c06431411da516..a942b891183c58 100644 --- a/src/controller/python/test/test_scripts/base.py +++ b/src/controller/python/test/test_scripts/base.py @@ -167,13 +167,15 @@ def assertValueEqual(self, expected): class BaseTestHelper: - def __init__(self, nodeid: int, testCommissioner: bool = False): + def __init__(self, nodeid: int, paaTrustStorePath: str, testCommissioner: bool = False): self.chipStack = ChipStack('/tmp/repl_storage.json') self.fabricAdmin = chip.FabricAdmin.FabricAdmin( fabricId=1, fabricIndex=1) - self.devCtrl = self.fabricAdmin.NewController(nodeid, testCommissioner) + self.devCtrl = self.fabricAdmin.NewController( + nodeid, paaTrustStorePath, testCommissioner) self.controllerNodeId = nodeid self.logger = logger + self.paaTrustStorePath = paaTrustStorePath def _WaitForOneDiscoveredDevice(self, timeoutSeconds: int = 2): print("Waiting for device responses...") @@ -253,7 +255,8 @@ async def TestMultiFabric(self, ip: str, setuppin: int, nodeid: int): fabricAdmin2 = chip.FabricAdmin.FabricAdmin(fabricId=2, fabricIndex=2) self.logger.info("Creating Device Controller on 2nd Fabric") - devCtrl2 = fabricAdmin2.NewController(self.controllerNodeId) + devCtrl2 = fabricAdmin2.NewController( + self.controllerNodeId, self.paaTrustStorePath) if not devCtrl2.CommissionIP(ip.encode("utf-8"), setuppin, nodeid): self.logger.info( @@ -280,8 +283,10 @@ async def TestMultiFabric(self, ip: str, setuppin: int, nodeid: int): fabricId=1, fabricIndex=1) fabricAdmin2 = chip.FabricAdmin.FabricAdmin(fabricId=2, fabricIndex=2) - self.devCtrl = self.fabricAdmin.NewController(self.controllerNodeId) - self.devCtrl2 = fabricAdmin2.NewController(self.controllerNodeId) + self.devCtrl = self.fabricAdmin.NewController( + self.controllerNodeId, self.paaTrustStorePath) + self.devCtrl2 = fabricAdmin2.NewController( + self.controllerNodeId, self.paaTrustStorePath) data1 = await self.devCtrl.ReadAttribute(nodeid, [(Clusters.OperationalCredentials.Attributes.NOCs)], fabricFiltered=False) data2 = await self.devCtrl2.ReadAttribute(nodeid, [(Clusters.OperationalCredentials.Attributes.NOCs)], fabricFiltered=False) diff --git a/src/controller/python/test/test_scripts/commissioning_test.py b/src/controller/python/test/test_scripts/commissioning_test.py index 198de12b9c9f4a..3a0ecbb2b9f60f 100755 --- a/src/controller/python/test/test_scripts/commissioning_test.py +++ b/src/controller/python/test/test_scripts/commissioning_test.py @@ -68,13 +68,24 @@ def main(): help="Address of the device", metavar="", ) + optParser.add_option( + "-p", + "--paa-trust-store-path", + action="store", + dest="paaTrustStorePath", + default='', + type='str', + help="Path that contains valid and trusted PAA Root Certificates.", + metavar="" + ) (options, remainingArgs) = optParser.parse_args(sys.argv[1:]) timeoutTicker = TestTimeout(options.testTimeout) timeoutTicker.start() - test = BaseTestHelper(nodeid=112233, testCommissioner=True) + test = BaseTestHelper( + nodeid=112233, paaTrustStorePath=options.paaTrustStorePath, testCommissioner=True) logger.info("Testing discovery") FailIfNot(test.TestDiscovery(discriminator=TEST_DISCRIMINATOR), diff --git a/src/controller/python/test/test_scripts/mobile-device-test.py b/src/controller/python/test/test_scripts/mobile-device-test.py index 4c8a137dc7afe0..140633e0af0fa2 100755 --- a/src/controller/python/test/test_scripts/mobile-device-test.py +++ b/src/controller/python/test/test_scripts/mobile-device-test.py @@ -153,11 +153,12 @@ def TestDatamodel(test: BaseTestHelper, device_nodeid: int): # asyncio.run(test.TestFabricSensitive(nodeid=device_nodeid)) -def do_tests(controller_nodeid, device_nodeid, address, timeout, discriminator, setup_pin): +def do_tests(controller_nodeid, device_nodeid, address, timeout, discriminator, setup_pin, paa_trust_store_path): timeoutTicker = TestTimeout(timeout) timeoutTicker.start() - test = BaseTestHelper(nodeid=controller_nodeid) + test = BaseTestHelper(nodeid=controller_nodeid, + paaTrustStorePath=paa_trust_store_path) chip.logging.RedirectToPythonLogging() @@ -198,7 +199,8 @@ def do_tests(controller_nodeid, device_nodeid, address, timeout, discriminator, @click.option('--log-level', default='WARN', type=click.Choice(['ERROR', 'WARN', 'INFO', 'DEBUG']), help="The log level of the test.") @click.option('--log-format', default=None, type=str, help="Override logging format") @click.option('--print-test-list', is_flag=True, help="Print a list of test cases and test sets that can be toggled via --enable-test and --disable-test, then exit") -def run(controller_nodeid, device_nodeid, address, timeout, discriminator, setup_pin, enable_test, disable_test, log_level, log_format, print_test_list): +@click.option('--paa-trust-store-path', default='', type=str, help="Path that contains valid and trusted PAA Root Certificates.") +def run(controller_nodeid, device_nodeid, address, timeout, discriminator, setup_pin, enable_test, disable_test, log_level, log_format, print_test_list, paa_trust_store_path): coloredlogs.install(level=log_level, fmt=log_format, logger=logger) if print_test_list: @@ -219,7 +221,7 @@ def run(controller_nodeid, device_nodeid, address, timeout, discriminator, setup logger.info(f"\tDisabled Tests: {disable_test}") SetTestSet(enable_test, disable_test) do_tests(controller_nodeid, device_nodeid, address, timeout, - discriminator, setup_pin) + discriminator, setup_pin, paa_trust_store_path) if __name__ == "__main__": diff --git a/src/controller/python/test/test_scripts/split_commissioning_test.py b/src/controller/python/test/test_scripts/split_commissioning_test.py index 37f4dfd3478899..35794b15420ce0 100755 --- a/src/controller/python/test/test_scripts/split_commissioning_test.py +++ b/src/controller/python/test/test_scripts/split_commissioning_test.py @@ -74,13 +74,24 @@ def main(): type='str', help="Address of the second device", ) + optParser.add_option( + "-p", + "--paa-trust-store-path", + action="store", + dest="paaTrustStorePath", + default='', + type='str', + help="Path that contains valid and trusted PAA Root Certificates.", + metavar="" + ) (options, remainingArgs) = optParser.parse_args(sys.argv[1:]) timeoutTicker = TestTimeout(options.testTimeout) timeoutTicker.start() - test = BaseTestHelper(nodeid=112233, testCommissioner=False) + test = BaseTestHelper( + nodeid=112233, paaTrustStorePath=options.paaTrustStorePath, testCommissioner=False) FailIfNot(test.SetNetworkCommissioningParameters(dataset=TEST_THREAD_NETWORK_DATASET_TLV), "Failed to finish network commissioning") diff --git a/src/credentials/BUILD.gn b/src/credentials/BUILD.gn index d715ce595d8f4e..0d74130a061ec4 100644 --- a/src/credentials/BUILD.gn +++ b/src/credentials/BUILD.gn @@ -97,3 +97,17 @@ static_library("default_attestation_verifier") { "${nlassert_root}:nlassert", ] } + +static_library("file_attestation_trust_store") { + output_name = "libFileAttestationTrustStore" + + sources = [ + "attestation_verifier/FileAttestationTrustStore.cpp", + "attestation_verifier/FileAttestationTrustStore.h", + ] + + public_deps = [ + ":credentials", + "${nlassert_root}:nlassert", + ] +} diff --git a/src/credentials/attestation_verifier/DefaultDeviceAttestationVerifier.cpp b/src/credentials/attestation_verifier/DefaultDeviceAttestationVerifier.cpp index 0f084cb50d28e3..459bf8f64aca6a 100644 --- a/src/credentials/attestation_verifier/DefaultDeviceAttestationVerifier.cpp +++ b/src/credentials/attestation_verifier/DefaultDeviceAttestationVerifier.cpp @@ -28,7 +28,6 @@ #include #include -// TODO: Remove once the Attestation Credentials storage mechanism is updated. namespace chip { namespace TestCerts { extern const ByteSpan sTestCert_PAA_FFF1_Cert; diff --git a/src/credentials/attestation_verifier/FileAttestationTrustStore.cpp b/src/credentials/attestation_verifier/FileAttestationTrustStore.cpp new file mode 100644 index 00000000000000..2f990f989a182f --- /dev/null +++ b/src/credentials/attestation_verifier/FileAttestationTrustStore.cpp @@ -0,0 +1,122 @@ +/* + * + * Copyright (c) 2022 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "FileAttestationTrustStore.h" + +#include +#include +#include + +extern "C" { +#include +} + +namespace chip { +namespace Credentials { + +namespace { +const char * GetFilenameExtension(const char * filename) +{ + const char * dot = strrchr(filename, '.'); + if (!dot || dot == filename) + { + return ""; + } + return dot + 1; +} +} // namespace + +FileAttestationTrustStore::FileAttestationTrustStore(const char * paaTrustStorePath) +{ + DIR * dir; + + dir = opendir(paaTrustStorePath); + if (dir != NULL) + { + // Nested directories are not handled. + dirent * entry; + while ((entry = readdir(dir)) != NULL) + { + const char * fileExtension = GetFilenameExtension(entry->d_name); + if (strncmp(fileExtension, "der", strlen("der")) == 0) + { + FILE * file; + + std::array certificate; + std::string filename(paaTrustStorePath); + + filename += std::string("/") + std::string(entry->d_name); + + file = fopen(filename.c_str(), "rb"); + if (file != NULL) + { + uint32_t certificateLength = fread(certificate.data(), sizeof(uint8_t), kMaxDERCertLength, file); + if (certificateLength > 0) + { + mDerCerts.push_back(certificate); + mIsInitialized = true; + } + fclose(file); + } + else + { + Cleanup(); + break; + } + } + } + closedir(dir); + } +} + +FileAttestationTrustStore::~FileAttestationTrustStore() +{ + Cleanup(); +} + +void FileAttestationTrustStore::Cleanup() +{ + mDerCerts.clear(); + mIsInitialized = false; +} + +CHIP_ERROR FileAttestationTrustStore::GetProductAttestationAuthorityCert(const ByteSpan & skid, + MutableByteSpan & outPaaDerBuffer) const +{ + VerifyOrReturnError(!mDerCerts.empty(), CHIP_ERROR_CA_CERT_NOT_FOUND); + VerifyOrReturnError(!skid.empty() && (skid.data() != nullptr), CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(skid.size() == Crypto::kSubjectKeyIdentifierLength, CHIP_ERROR_INVALID_ARGUMENT); + + for (auto candidate : mDerCerts) + { + uint8_t skidBuf[Crypto::kSubjectKeyIdentifierLength] = { 0 }; + MutableByteSpan candidateSkidSpan{ skidBuf }; + VerifyOrReturnError(CHIP_NO_ERROR == + Crypto::ExtractSKIDFromX509Cert(ByteSpan{ candidate.data(), candidate.size() }, candidateSkidSpan), + CHIP_ERROR_INTERNAL); + + if (skid.data_equal(candidateSkidSpan)) + { + // Found a match + return CopySpanToMutableSpan(ByteSpan{ candidate.data(), candidate.size() }, outPaaDerBuffer); + } + } + + return CHIP_ERROR_CA_CERT_NOT_FOUND; +} + +} // namespace Credentials +} // namespace chip diff --git a/src/credentials/attestation_verifier/FileAttestationTrustStore.h b/src/credentials/attestation_verifier/FileAttestationTrustStore.h new file mode 100644 index 00000000000000..090be169367c63 --- /dev/null +++ b/src/credentials/attestation_verifier/FileAttestationTrustStore.h @@ -0,0 +1,49 @@ +/* + * + * Copyright (c) 2022 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#pragma once + +#include +#include + +#include +#include + +namespace chip { +namespace Credentials { + +class FileAttestationTrustStore : public AttestationTrustStore +{ +public: + FileAttestationTrustStore(const char * paaTrustStorePath); + ~FileAttestationTrustStore(); + + bool IsInitialized() { return mIsInitialized; } + + CHIP_ERROR GetProductAttestationAuthorityCert(const ByteSpan & skid, MutableByteSpan & outPaaDerBuffer) const override; + size_t size() const { return mDerCerts.size(); } + +protected: + std::vector> mDerCerts; + +private: + bool mIsInitialized = false; + + void Cleanup(); +}; + +} // namespace Credentials +} // namespace chip diff --git a/src/credentials/examples/DeviceAttestationCredsExample.cpp b/src/credentials/examples/DeviceAttestationCredsExample.cpp index 92ee5a89881f96..617e3463bf0d07 100644 --- a/src/credentials/examples/DeviceAttestationCredsExample.cpp +++ b/src/credentials/examples/DeviceAttestationCredsExample.cpp @@ -57,7 +57,7 @@ CHIP_ERROR ExampleDACProvider::GetDeviceAttestationCert(MutableByteSpan & out_da CHIP_ERROR ExampleDACProvider::GetProductAttestationIntermediateCert(MutableByteSpan & out_pai_buffer) { - return CopySpanToMutableSpan(ByteSpan(DevelopmentCerts::kDevelopmentPAI_Cert_FFF1), out_pai_buffer); + return CopySpanToMutableSpan(ByteSpan(DevelopmentCerts::kPaiCert), out_pai_buffer); } CHIP_ERROR ExampleDACProvider::GetCertificationDeclaration(MutableByteSpan & out_cd_buffer) diff --git a/src/test_driver/linux-cirque/CommissioningTest.py b/src/test_driver/linux-cirque/CommissioningTest.py index e9e311d17daf4b..1c65dd0d3d4c74 100755 --- a/src/test_driver/linux-cirque/CommissioningTest.py +++ b/src/test_driver/linux-cirque/CommissioningTest.py @@ -38,6 +38,7 @@ CHIP_REPO = os.path.join(os.path.abspath( os.path.dirname(__file__)), "..", "..", "..") TEST_EXTPANID = "fedcba9876543210" +MATTER_DEVELOPMENT_PAA_ROOT_CERTS = "credentials/development/paa-root-certs" DEVICE_CONFIG = { 'device0': { @@ -91,10 +92,11 @@ def run_controller_test(self): self.execute_device_cmd(req_device_id, "pip3 install {}".format(os.path.join( CHIP_REPO, "out/debug/linux_x64_gcc/controller/python/chip-0.0-cp37-abi3-linux_x86_64.whl"))) - command = "gdb -return-child-result -q -ex run -ex bt --args python3 {} -t 150 -a {}".format( + command = "gdb -return-child-result -q -ex run -ex bt --args python3 {} -t 150 -a {} --paa-trust-store-path {}".format( os.path.join( CHIP_REPO, "src/controller/python/test/test_scripts/commissioning_test.py"), - ethernet_ip) + ethernet_ip, + os.path.join(CHIP_REPO, MATTER_DEVELOPMENT_PAA_ROOT_CERTS)) ret = self.execute_device_cmd(req_device_id, command) self.assertEqual(ret['return_code'], '0', diff --git a/src/test_driver/linux-cirque/MobileDeviceTest.py b/src/test_driver/linux-cirque/MobileDeviceTest.py index 9af296978b760d..136b2a09c6a17d 100755 --- a/src/test_driver/linux-cirque/MobileDeviceTest.py +++ b/src/test_driver/linux-cirque/MobileDeviceTest.py @@ -38,6 +38,7 @@ CHIP_REPO = os.path.join(os.path.abspath( os.path.dirname(__file__)), "..", "..", "..") TEST_EXTPANID = "fedcba9876543210" +MATTER_DEVELOPMENT_PAA_ROOT_CERTS = "credentials/development/paa-root-certs" DEVICE_CONFIG = { 'device0': { @@ -91,9 +92,10 @@ def run_controller_test(self): self.execute_device_cmd(req_device_id, "pip3 install {}".format(os.path.join( CHIP_REPO, "out/debug/linux_x64_gcc/controller/python/chip-0.0-cp37-abi3-linux_x86_64.whl"))) - command = "gdb -return-child-result -q -ex run -ex bt --args python3 {} -t 150 -a {}".format( + command = "gdb -return-child-result -q -ex run -ex bt --args python3 {} -t 150 -a {} --paa-trust-store-path {}".format( os.path.join( - CHIP_REPO, "src/controller/python/test/test_scripts/mobile-device-test.py"), ethernet_ip) + CHIP_REPO, "src/controller/python/test/test_scripts/mobile-device-test.py"), ethernet_ip, + os.path.join(CHIP_REPO, MATTER_DEVELOPMENT_PAA_ROOT_CERTS)) ret = self.execute_device_cmd(req_device_id, command) self.assertEqual(ret['return_code'], '0', diff --git a/src/test_driver/linux-cirque/SplitCommissioningTest.py b/src/test_driver/linux-cirque/SplitCommissioningTest.py index 9527cff2293f80..69235b86339d07 100755 --- a/src/test_driver/linux-cirque/SplitCommissioningTest.py +++ b/src/test_driver/linux-cirque/SplitCommissioningTest.py @@ -38,6 +38,7 @@ CHIP_REPO = os.path.join(os.path.abspath( os.path.dirname(__file__)), "..", "..", "..") TEST_EXTPANID = "fedcba9876543210" +MATTER_DEVELOPMENT_PAA_ROOT_CERTS = "credentials/development/paa-root-certs" DEVICE_CONFIG = { 'device0': { @@ -100,10 +101,10 @@ def run_controller_test(self): self.execute_device_cmd(req_device_id, "pip3 install {}".format(os.path.join( CHIP_REPO, "out/debug/linux_x64_gcc/controller/python/chip-0.0-cp37-abi3-linux_x86_64.whl"))) - command = "gdb -return-child-result -q -ex run -ex bt --args python3 {} -t 150 --address1 {} --address2 {}".format( + command = "gdb -return-child-result -q -ex run -ex bt --args python3 {} -t 150 --address1 {} --address2 {} --paa-trust-store-path {}".format( os.path.join( CHIP_REPO, "src/controller/python/test/test_scripts/split_commissioning_test.py"), - ethernet_ips[0], ethernet_ips[1]) + ethernet_ips[0], ethernet_ips[1], os.path.join(CHIP_REPO, MATTER_DEVELOPMENT_PAA_ROOT_CERTS)) ret = self.execute_device_cmd(req_device_id, command) self.assertEqual(ret['return_code'], '0',