From dafba6938bc7da9a1fe3d920363f41483555090a Mon Sep 17 00:00:00 2001 From: Marty Leisner Date: Wed, 13 Oct 2021 07:20:29 -0400 Subject: [PATCH] chip-tool now builds the core as a static library (chip-tool-utils) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added set of pure virtual methods PKI-related to Commands class Added example implementation of Matter’s example PKI Added DAC to GenerateNOCChain method call Added GenerateNOCSR method to OperationalCredentialsDelegate class so every PKI-vendor can override the nonce generation to follow a custom set of rules. Random example added. --- examples/chip-tool/BUILD.gn | 41 +++++++++++---- examples/chip-tool/commands/common/Command.h | 4 +- .../chip-tool/commands/common/Commands.cpp | 16 +++--- examples/chip-tool/commands/common/Commands.h | 14 +++++- .../example/ExampleCredentialIssuerCommands.h | 50 +++++++++++++++++++ examples/chip-tool/main.cpp | 4 +- src/controller/CHIPDevice.h | 1 + src/controller/CHIPDeviceController.cpp | 4 +- .../OperationalCredentialsDelegate.h | 6 +++ 9 files changed, 114 insertions(+), 26 deletions(-) create mode 100644 examples/chip-tool/commands/example/ExampleCredentialIssuerCommands.h diff --git a/examples/chip-tool/BUILD.gn b/examples/chip-tool/BUILD.gn index 345cb85988fcf4..2d7947d5033915 100644 --- a/examples/chip-tool/BUILD.gn +++ b/examples/chip-tool/BUILD.gn @@ -29,7 +29,19 @@ declare_args() { config_pair_with_random_id = true } -executable("chip-tool") { +config("config") { + include_dirs = [ + ".", + "${chip_root}/zzz_generated/chip-tool", + ] + + defines = [ + "CONFIG_USE_SEPARATE_EVENTLOOP=${config_use_separate_eventloop}", + "CONFIG_PAIR_WITH_RANDOM_ID=${config_pair_with_random_id}", + ] +} + +static_library("chip-tool-utils") { sources = [ "commands/clusters/ModelCommand.cpp", "commands/common/Command.cpp", @@ -43,15 +55,29 @@ executable("chip-tool") { "commands/reporting/ReportingCommand.cpp", "commands/tests/TestCommand.cpp", "config/PersistentStorage.cpp", - "main.cpp", ] - defines = [ - "CONFIG_USE_SEPARATE_EVENTLOOP=${config_use_separate_eventloop}", - "CONFIG_PAIR_WITH_RANDOM_ID=${config_pair_with_random_id}", + deps = [ + "${chip_root}/src/controller/data_model", + "${chip_root}/src/lib", + "${chip_root}/src/platform", + "${chip_root}/third_party/inipp", + ] + + cflags = [ "-Wconversion" ] + + public_configs = [ ":config" ] + + output_dir = root_out_dir +} + +executable("chip-tool") { + sources = [ + "main.cpp", ] deps = [ + ":chip-tool-utils", "${chip_root}/src/controller/data_model", "${chip_root}/src/lib", "${chip_root}/src/platform", @@ -60,10 +86,7 @@ executable("chip-tool") { cflags = [ "-Wconversion" ] - include_dirs = [ - ".", - "${chip_root}/zzz_generated/chip-tool", - ] + public_configs = [ ":config" ] output_dir = root_out_dir } diff --git a/examples/chip-tool/commands/common/Command.h b/examples/chip-tool/commands/common/Command.h index a1e3cfe9e788f4..fa3a6076456b53 100644 --- a/examples/chip-tool/commands/common/Command.h +++ b/examples/chip-tool/commands/common/Command.h @@ -18,7 +18,7 @@ #pragma once -#include "controller/ExampleOperationalCredentialsIssuer.h" +#include "controller/OperationalCredentialsDelegate.h" #include #include #include @@ -100,7 +100,7 @@ class Command struct ExecutionContext { ChipDeviceCommissioner * commissioner; - chip::Controller::ExampleOperationalCredentialsIssuer * opCredsIssuer; + chip::Controller::OperationalCredentialsDelegate * opCredsIssuer; PersistentStorage * storage; chip::NodeId localId; chip::NodeId remoteId; diff --git a/examples/chip-tool/commands/common/Commands.cpp b/examples/chip-tool/commands/common/Commands.cpp index 2d4fb5b90649ef..108ab78b9f8043 100644 --- a/examples/chip-tool/commands/common/Commands.cpp +++ b/examples/chip-tool/commands/common/Commands.cpp @@ -28,10 +28,6 @@ #endif #include -#include -#include -#include -#include #include #include #include @@ -80,15 +76,15 @@ int Commands::Run(int argc, char ** argv) factoryInitParams.storageDelegate = &mStorage; factoryInitParams.listenPort = mStorage.GetListenPort(); - err = mOpCredsIssuer.Initialize(mStorage); + err = InitializeCredentialsIssuer(mStorage); VerifyOrExit(err == CHIP_NO_ERROR, ChipLogError(Controller, "Init failure! Operational Cred Issuer: %s", chip::ErrorStr(err))); - commissionerParams.operationalCredentialsDelegate = &mOpCredsIssuer; + commissionerParams.operationalCredentialsDelegate = GetCredentialIssuer(); VerifyOrExit(err == CHIP_NO_ERROR, ChipLogError(Controller, "Init failure! Commissioner: %s", chip::ErrorStr(err))); - chip::Credentials::SetDeviceAttestationCredentialsProvider(chip::Credentials::Examples::GetExampleDACProvider()); - chip::Credentials::SetDeviceAttestationVerifier(chip::Credentials::Examples::GetExampleDACVerifier()); + err = SetupDeviceAttestation(); + VerifyOrExit(err == CHIP_NO_ERROR, ChipLogError(Controller, "Init failure! Device Attestation Setup: %s", chip::ErrorStr(err))); VerifyOrExit(rcac.Alloc(chip::Controller::kMaxCHIPDERCertLength), err = CHIP_ERROR_NO_MEMORY); VerifyOrExit(noc.Alloc(chip::Controller::kMaxCHIPDERCertLength), err = CHIP_ERROR_NO_MEMORY); @@ -105,7 +101,7 @@ int Commands::Run(int argc, char ** argv) // TODO - OpCreds should only be generated for pairing command // store the credentials in persistent storage, and // generate when not available in the storage. - err = mOpCredsIssuer.GenerateNOCChainAfterValidation(localId, 0, ephemeralKey.Pubkey(), rcacSpan, icacSpan, nocSpan); + err = GenerateControllerNOCChain(localId, 0, ephemeralKey, rcacSpan, icacSpan, nocSpan); SuccessOrExit(err); commissionerParams.ephemeralKeypair = &ephemeralKey; @@ -229,7 +225,7 @@ CHIP_ERROR Commands::RunCommand(NodeId localId, NodeId remoteId, int argc, char Command::ExecutionContext execContext; execContext.commissioner = &mController; - execContext.opCredsIssuer = &mOpCredsIssuer; + execContext.opCredsIssuer = GetCredentialIssuer(); execContext.storage = &mStorage; execContext.localId = localId; execContext.remoteId = remoteId; diff --git a/examples/chip-tool/commands/common/Commands.h b/examples/chip-tool/commands/common/Commands.h index 56ccf1047b3a25..e0ba57511fc7d3 100644 --- a/examples/chip-tool/commands/common/Commands.h +++ b/examples/chip-tool/commands/common/Commands.h @@ -20,18 +20,22 @@ #include "../../config/PersistentStorage.h" #include "Command.h" -#include +#include +#include #include class Commands { public: using NodeId = ::chip::NodeId; + using FabricId = ::chip::FabricId; using CommandsVector = ::std::vector>; void Register(const char * clusterName, commands_list commandsList); int Run(int argc, char ** argv); + virtual ~Commands() {} + private: // *ranCommand will be set to the command we ran if we get as far as running // it. If it's not null, we need to call Shutdown() on the command after we @@ -48,8 +52,14 @@ class Commands void ShowClusterAttributes(std::string executable, std::string clusterName, std::string commandName, CommandsVector & commands); void ShowCommand(std::string executable, std::string clusterName, Command * command); + virtual CHIP_ERROR InitializeCredentialsIssuer(chip::PersistentStorageDelegate & storage) = 0; + virtual CHIP_ERROR SetupDeviceAttestation() = 0; + virtual chip::Controller::OperationalCredentialsDelegate * GetCredentialIssuer() = 0; + virtual CHIP_ERROR GenerateControllerNOCChain(NodeId nodeId, FabricId fabricId, chip::Crypto::P256Keypair & keypair, + chip::MutableByteSpan & rcac, chip::MutableByteSpan & icac, + chip::MutableByteSpan & noc) = 0; + std::map mClusters; chip::Controller::DeviceCommissioner mController; - chip::Controller::ExampleOperationalCredentialsIssuer mOpCredsIssuer; PersistentStorage mStorage; }; diff --git a/examples/chip-tool/commands/example/ExampleCredentialIssuerCommands.h b/examples/chip-tool/commands/example/ExampleCredentialIssuerCommands.h new file mode 100644 index 00000000000000..7e80264ed0d86f --- /dev/null +++ b/examples/chip-tool/commands/example/ExampleCredentialIssuerCommands.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2021 Project CHIP Authors + * All rights reserved. + * + * 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 +#include +#include + +class ExampleCredentialIssuerCommands : public Commands +{ +private: + CHIP_ERROR InitializeCredentialsIssuer(chip::PersistentStorageDelegate & storage) override + { + return mOpCredsIssuer.Initialize(storage); + } + CHIP_ERROR SetupDeviceAttestation() override + { + chip::Credentials::SetDeviceAttestationCredentialsProvider(chip::Credentials::Examples::GetExampleDACProvider()); + chip::Credentials::SetDeviceAttestationVerifier(chip::Credentials::Examples::GetExampleDACVerifier()); + return CHIP_NO_ERROR; + } + chip::Controller::OperationalCredentialsDelegate * GetCredentialIssuer() override { return &mOpCredsIssuer; } + CHIP_ERROR GenerateControllerNOCChain(NodeId nodeId, FabricId fabricId, chip::Crypto::P256Keypair & keypair, + chip::MutableByteSpan & rcac, chip::MutableByteSpan & icac, + chip::MutableByteSpan & noc) override + { + return mOpCredsIssuer.GenerateNOCChainAfterValidation(nodeId, fabricId, keypair.Pubkey(), rcac, icac, noc); + } + + chip::Controller::ExampleOperationalCredentialsIssuer mOpCredsIssuer; +}; diff --git a/examples/chip-tool/main.cpp b/examples/chip-tool/main.cpp index c767020c72d160..19e068b6239d24 100644 --- a/examples/chip-tool/main.cpp +++ b/examples/chip-tool/main.cpp @@ -16,7 +16,7 @@ * */ -#include "commands/common/Commands.h" +#include "commands/example/ExampleCredentialIssuerCommands.h" #include "commands/discover/Commands.h" #include "commands/pairing/Commands.h" @@ -31,7 +31,7 @@ // ================================================================================ int main(int argc, char * argv[]) { - Commands commands; + ExampleCredentialIssuerCommands commands; registerCommandsDiscover(commands); registerCommandsPayload(commands); registerCommandsPairing(commands); diff --git a/src/controller/CHIPDevice.h b/src/controller/CHIPDevice.h index 91a20aa27e339d..6696f96267c41a 100644 --- a/src/controller/CHIPDevice.h +++ b/src/controller/CHIPDevice.h @@ -398,6 +398,7 @@ class DLL_EXPORT Device : public Messaging::ExchangeDelegate, public SessionEsta } ByteSpan GetCSRNonce() const { return ByteSpan(mCSRNonce, sizeof(mCSRNonce)); } + MutableByteSpan GetCSRNonce() { return MutableByteSpan(mCSRNonce, sizeof(mCSRNonce)); } CHIP_ERROR SetAttestationNonce(ByteSpan attestationNonce) { diff --git a/src/controller/CHIPDeviceController.cpp b/src/controller/CHIPDeviceController.cpp index 14492862e051ff..55e12c403ba380 100644 --- a/src/controller/CHIPDeviceController.cpp +++ b/src/controller/CHIPDeviceController.cpp @@ -1274,6 +1274,8 @@ CHIP_ERROR DeviceCommissioner::SendOperationalCertificateSigningRequestCommand(D Callback::Cancelable * successCallback = mOpCSRResponseCallback.Cancel(); Callback::Cancelable * failureCallback = mOnCSRFailureCallback.Cancel(); + MutableByteSpan csrNonce = device->GetCSRNonce(); + ReturnErrorOnFailure(mOperationalCredentialsDelegate->GenerateNOCSR(csrNonce)); ReturnErrorOnFailure(cluster.OpCSRRequest(successCallback, failureCallback, device->GetCSRNonce())); ChipLogDetail(Controller, "Sent OpCSR request, waiting for the CSR"); @@ -1379,7 +1381,7 @@ CHIP_ERROR DeviceCommissioner::ProcessOpCSR(const ByteSpan & NOCSRElements, cons mOperationalCredentialsDelegate->SetNodeIdForNextNOCRequest(device->GetDeviceId()); mOperationalCredentialsDelegate->SetFabricIdForNextNOCRequest(0); - return mOperationalCredentialsDelegate->GenerateNOCChain(NOCSRElements, AttestationSignature, ByteSpan(), ByteSpan(), + return mOperationalCredentialsDelegate->GenerateNOCChain(NOCSRElements, AttestationSignature, device->GetDAC(), ByteSpan(), ByteSpan(), &mDeviceNOCChainCallback); } diff --git a/src/controller/OperationalCredentialsDelegate.h b/src/controller/OperationalCredentialsDelegate.h index fed605aab208b4..b8353313fdc71a 100644 --- a/src/controller/OperationalCredentialsDelegate.h +++ b/src/controller/OperationalCredentialsDelegate.h @@ -76,6 +76,12 @@ class DLL_EXPORT OperationalCredentialsDelegate * fabric ID. */ virtual void SetFabricIdForNextNOCRequest(FabricId fabricId) {} + + virtual CHIP_ERROR GenerateNOCSR(MutableByteSpan & csrNonce) + { + ReturnErrorOnFailure(Crypto::DRBG_get_bytes(csrNonce.data(), csrNonce.size())); + return CHIP_NO_ERROR; + } }; } // namespace Controller