Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chip-tool now builds the core as a static library (chip-tool-utils) #18

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 32 additions & 9 deletions examples/chip-tool/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -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/CHIPCommand.cpp",
Expand All @@ -45,15 +57,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",
Expand All @@ -62,10 +88,7 @@ executable("chip-tool") {

cflags = [ "-Wconversion" ]

include_dirs = [
".",
"${chip_root}/zzz_generated/chip-tool",
]
public_configs = [ ":config" ]

output_dir = root_out_dir
}
16 changes: 15 additions & 1 deletion examples/chip-tool/commands/common/Command.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

#pragma once

#include "controller/ExampleOperationalCredentialsIssuer.h"
#include "controller/OperationalCredentialsDelegate.h"
#include <controller/CHIPDeviceController.h>
#include <inet/InetInterface.h>
#include <lib/support/Span.h>
Expand Down Expand Up @@ -83,6 +83,20 @@ class Command
::chip::Inet::InterfaceId interfaceId;
};

/**
* @brief
* Encapsulates key objects in the CHIP stack that need continued
* access, so wrapping it in here makes it nice and compactly encapsulated.
*/
struct ExecutionContext
{
ChipDeviceCommissioner * commissioner;
chip::Controller::OperationalCredentialsDelegate * opCredsIssuer;
PersistentStorage * storage;
chip::NodeId localId;
chip::NodeId remoteId;
};

Command(const char * commandName) : mName(commandName) {}
virtual ~Command() {}

Expand Down
109 changes: 106 additions & 3 deletions examples/chip-tool/commands/common/Commands.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@
#include <algorithm>
#include <string>

#if CONFIG_DEVICE_LAYER
#include <platform/CHIPDeviceLayer.h>
#endif

#include <controller/CHIPDeviceControllerFactory.h>
#include <lib/support/CHIPMem.h>
#include <lib/support/CodeUtils.h>

Expand All @@ -45,9 +50,68 @@ int Commands::Run(int argc, char ** argv)
VerifyOrExit(err == CHIP_NO_ERROR, ChipLogError(Controller, "Init Storage failure: %s", chip::ErrorStr(err)));

chip::Logging::SetLogFilter(mStorage.GetLoggingLevel());
localId = mStorage.GetLocalNodeId();
remoteId = mStorage.GetRemoteNodeId();

ChipLogProgress(Controller, "Read local id 0x" ChipLogFormatX64 ", remote id 0x" ChipLogFormatX64, ChipLogValueX64(localId),
ChipLogValueX64(remoteId));

factoryInitParams.storageDelegate = &mStorage;
factoryInitParams.listenPort = mStorage.GetListenPort();

err = InitializeCredentialsIssuer(mStorage);
VerifyOrExit(err == CHIP_NO_ERROR, ChipLogError(Controller, "Init failure! Operational Cred Issuer: %s", chip::ErrorStr(err)));

commissionerParams.operationalCredentialsDelegate = GetCredentialIssuer();

VerifyOrExit(err == CHIP_NO_ERROR, ChipLogError(Controller, "Init failure! Commissioner: %s", chip::ErrorStr(err)));

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);
VerifyOrExit(icac.Alloc(chip::Controller::kMaxCHIPDERCertLength), err = CHIP_ERROR_NO_MEMORY);

{
chip::MutableByteSpan nocSpan(noc.Get(), chip::Controller::kMaxCHIPDERCertLength);
chip::MutableByteSpan icacSpan(icac.Get(), chip::Controller::kMaxCHIPDERCertLength);
chip::MutableByteSpan rcacSpan(rcac.Get(), chip::Controller::kMaxCHIPDERCertLength);

chip::Crypto::P256Keypair ephemeralKey;
SuccessOrExit(err = ephemeralKey.Initialize());

// TODO - OpCreds should only be generated for pairing command
// store the credentials in persistent storage, and
// generate when not available in the storage.
err = GenerateControllerNOCChain(localId, 0, ephemeralKey, rcacSpan, icacSpan, nocSpan);
SuccessOrExit(err);

commissionerParams.ephemeralKeypair = &ephemeralKey;
commissionerParams.controllerRCAC = rcacSpan;
commissionerParams.controllerICAC = icacSpan;
commissionerParams.controllerNOC = nocSpan;

// init the factory, then setup the Controller
err = DeviceControllerFactory::GetInstance().Init(factoryInitParams);
VerifyOrExit(err == CHIP_NO_ERROR, ChipLogError(Controller, "Controller Factory failed to initialize"));
err = DeviceControllerFactory::GetInstance().SetupCommissioner(commissionerParams, mController);
VerifyOrExit(err == CHIP_NO_ERROR, ChipLogError(Controller, "Init failure! Commissioner: %s", chip::ErrorStr(err)));
}

err = RunCommand(argc, argv);
VerifyOrExit(err == CHIP_NO_ERROR, ChipLogError(chipTool, "Run command failure: %s", chip::ErrorStr(err)));
#if CONFIG_USE_SEPARATE_EVENTLOOP
// ServiceEvents() calls StartEventLoopTask(), which is paired with the
// StopEventLoopTask() below.
err = DeviceControllerFactory::GetInstance().ServiceEvents();
VerifyOrExit(err == CHIP_NO_ERROR, ChipLogError(Controller, "Init failure! Run Loop: %s", chip::ErrorStr(err)));
#endif // CONFIG_USE_SEPARATE_EVENTLOOP

err = RunCommand(localId, remoteId, argc, argv, &command);
SuccessOrExit(err);

#if !CONFIG_USE_SEPARATE_EVENTLOOP
chip::DeviceLayer::PlatformMgr().RunEventLoop();
#endif // !CONFIG_USE_SEPARATE_EVENTLOOP

exit:
return (err == CHIP_NO_ERROR) ? EXIT_SUCCESS : EXIT_FAILURE;
Expand Down Expand Up @@ -114,7 +178,46 @@ CHIP_ERROR Commands::RunCommand(int argc, char ** argv)
return CHIP_ERROR_INVALID_ARGUMENT;
}

return command->Run();
{
Command::ExecutionContext execContext;

execContext.commissioner = &mController;
execContext.opCredsIssuer = GetCredentialIssuer();
execContext.storage = &mStorage;
execContext.localId = localId;
execContext.remoteId = remoteId;

command->SetExecutionContext(execContext);
*ranCommand = command;

//
// Set this to true first BEFORE we send commands to ensure we don't end
// up in a situation where the response comes back faster than we can
// set the variable to true, which will cause it to block indefinitely.
//
command->UpdateWaitForResponse(true);
#if CONFIG_USE_SEPARATE_EVENTLOOP
chip::DeviceLayer::PlatformMgr().ScheduleWork(RunQueuedCommand, reinterpret_cast<intptr_t>(command));
command->WaitForResponse(command->GetWaitDurationInSeconds());
#else // CONFIG_USE_SEPARATE_EVENTLOOP
err = command->Run();
SuccessOrExit(err);
command->ScheduleWaitForResponse(command->GetWaitDurationInSeconds());
#endif // CONFIG_USE_SEPARATE_EVENTLOOP
}

exit:
return err;
}

void Commands::RunQueuedCommand(intptr_t commandArg)
{
auto * command = reinterpret_cast<Command *>(commandArg);
CHIP_ERROR err = command->Run();
if (err != CHIP_NO_ERROR)
{
command->SetCommandExitStatus(err);
}
}

std::map<std::string, Commands::CommandsVector>::iterator Commands::GetCluster(std::string clusterName)
Expand Down
15 changes: 14 additions & 1 deletion examples/chip-tool/commands/common/Commands.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,22 @@

#include "../../config/PersistentStorage.h"
#include "Command.h"
#include <controller/ExampleOperationalCredentialsIssuer.h>
#include <controller/OperationalCredentialsDelegate.h>
#include <crypto/CHIPCryptoPAL.h>
#include <map>

class Commands
{
public:
using NodeId = ::chip::NodeId;
using FabricId = ::chip::FabricId;
using CommandsVector = ::std::vector<std::unique_ptr<Command>>;

void Register(const char * clusterName, commands_list commandsList);
int Run(int argc, char ** argv);

virtual ~Commands() {}

private:
CHIP_ERROR RunCommand(int argc, char ** argv);
std::map<std::string, CommandsVector>::iterator GetCluster(std::string clusterName);
Expand All @@ -43,6 +48,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<std::string, CommandsVector> mClusters;
chip::Controller::DeviceCommissioner mController;
PersistentStorage mStorage;
};
Original file line number Diff line number Diff line change
@@ -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 <commands/common/Commands.h>
#include <controller/ExampleOperationalCredentialsIssuer.h>
#include <credentials/DeviceAttestationCredsProvider.h>
#include <credentials/DeviceAttestationVerifier.h>
#include <credentials/examples/DeviceAttestationCredsExample.h>
#include <credentials/examples/DeviceAttestationVerifierExample.h>

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;
};
4 changes: 2 additions & 2 deletions examples/chip-tool/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
*
*/

#include "commands/common/Commands.h"
#include "commands/example/ExampleCredentialIssuerCommands.h"

#include "commands/discover/Commands.h"
#include "commands/pairing/Commands.h"
Expand All @@ -31,7 +31,7 @@
// ================================================================================
int main(int argc, char * argv[])
{
Commands commands;
ExampleCredentialIssuerCommands commands;
registerCommandsDiscover(commands);
registerCommandsPayload(commands);
registerCommandsPairing(commands);
Expand Down
1 change: 1 addition & 0 deletions src/controller/CHIPDevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down
4 changes: 3 additions & 1 deletion src/controller/CHIPDeviceController.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down Expand Up @@ -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);
}

Expand Down
6 changes: 6 additions & 0 deletions src/controller/OperationalCredentialsDelegate.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down