Skip to content

Commit

Permalink
Introduce CommissionableDataProvider for discriminator and verifier (#…
Browse files Browse the repository at this point in the history
…16020)

* Introduce CommissionableDataProvider for discriminator and verifier

- Current API in ConfigurationManager makes it very hard to provide
  spec-mandated per-device SPAKE2+ parameters (verifier, salt, iteration
  counts) and discovery discriminator, since it expects "in-app" common
  SDK handling of the data for something that actually usually
  comes from the factory.

This PR does the following:

- Adds CommissionableDataProvider interface, of which an instance
  is known to the ConfigurationManager.
- Adds a legacy path to avoid requiring setting a
  CommissionableDataProvider in the short term
- A linux implementation of CommissionableDataProvider showcasing
  providing externally generated SPAKE2+ verifier/salt/iterations
- Refactoring of all direct usage of ConfigurationManager to
  get discriminator/SPAKE2+ parameters

Testing done:
- Cert tests still pass with no change
- All unit tests still pass, including those modified
- Setting GN arg `chip_use_transitional_commissionable_data_provider=0`
  properly causes targets that don't provide an implementation
  from running.
- Manually verified the new Linux command-line arguments to
  all-clusters-app allow passing custom version of verifier or iteration
  counts.

Fixes #15543

* Restyled by clang-format

* Restyled by gn

* Fix PRIu32

* Fix more presubmit rework failures

* Fix one missing override

* Address review comments

* Restyled by clang-format

* Fix more CI, do more renames

* Restyled by clang-format

* Address review comments

* Restyled by clang-format

* Restyled by gn

* Fix doxygen stuff

* Fix fake ConfigurationaManagerImpl.h

* Fix cirque

* Address review comments from PR #16020

* Fix CI after refactor based on review comments

Co-authored-by: Restyled.io <commits@restyled.io>
  • Loading branch information
2 people authored and pull[bot] committed Feb 13, 2024
1 parent 7b2f714 commit 8ae80e6
Show file tree
Hide file tree
Showing 38 changed files with 1,161 additions and 285 deletions.
5 changes: 3 additions & 2 deletions examples/bridge-app/linux/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include <lib/core/CHIPError.h>
#include <lib/support/CHIPMem.h>
#include <lib/support/ZclString.h>
#include <platform/CommissionableDataProvider.h>
#include <setup_payload/QRCodeSetupPayloadGenerator.h>
#include <setup_payload/SetupPayload.h>

Expand Down Expand Up @@ -550,10 +551,10 @@ CHIP_ERROR PrintQRCodeContent()
uint16_t productId;
std::string result;

err = ConfigurationMgr().GetSetupPinCode(setUpPINCode);
err = GetCommissionableDataProvider()->GetSetupPasscode(setUpPINCode);
SuccessOrExit(err);

err = ConfigurationMgr().GetSetupDiscriminator(setUpDiscriminator);
err = GetCommissionableDataProvider()->GetSetupDiscriminator(setUpDiscriminator);
SuccessOrExit(err);

err = ConfigurationMgr().GetVendorId(vendorId);
Expand Down
6 changes: 3 additions & 3 deletions examples/chip-tool/commands/common/CredentialIssuerCommands.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,9 @@ class CredentialIssuerCommands
* @param[in] nodeId The desired NodeId for the generated NOC Chain - May be optional/unused in some implementations.
* @param[in] fabricId The desired FabricId for the generated NOC Chain - May be optional/unused in some implementations.
* @param[in] keypair The desired Keypair for the generated NOC Chain - May be optional/unused in some implementations.
* @param[inout] rcac Buffer to hold the Root Certificate of the generated NOC Chain.
* @param[inout] icac Buffer to hold the Intermediate Certificate of the generated NOC Chain.
* @param[inout] noc Buffer to hold the Leaf Certificate of the generated NOC Chain.
* @param[in,out] rcac Buffer to hold the Root Certificate of the generated NOC Chain.
* @param[in,out] icac Buffer to hold the Intermediate Certificate of the generated NOC Chain.
* @param[in,out] noc Buffer to hold the Leaf Certificate of the generated NOC Chain.
*
* @return CHIP_ERROR CHIP_NO_ERROR on success, or corresponding error code.
*/
Expand Down
10 changes: 6 additions & 4 deletions examples/common/pigweed/rpc_services/Device.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#pragma once

#include <platform/CHIPDeviceConfig.h>
#include <platform/CommissionableDataProvider.h>

#include "app/server/OnboardingCodesUtil.h"
#include "app/server/Server.h"
Expand Down Expand Up @@ -126,14 +127,14 @@ class Device : public pw_rpc::nanopb::Device::Service<Device>
}

uint32_t code;
if (DeviceLayer::ConfigurationMgr().GetSetupPinCode(code) == CHIP_NO_ERROR)
if (DeviceLayer::GetCommissionableDataProvider()->GetSetupPasscode(code) == CHIP_NO_ERROR)
{
response.pairing_info.code = code;
response.has_pairing_info = true;
}

uint16_t discriminator;
if (DeviceLayer::ConfigurationMgr().GetSetupDiscriminator(discriminator) == CHIP_NO_ERROR)
if (DeviceLayer::GetCommissionableDataProvider()->GetSetupDiscriminator(discriminator) == CHIP_NO_ERROR)
{
response.pairing_info.discriminator = static_cast<uint32_t>(discriminator);
response.has_pairing_info = true;
Expand All @@ -158,8 +159,9 @@ class Device : public pw_rpc::nanopb::Device::Service<Device>

virtual pw::Status SetPairingInfo(const chip_rpc_PairingInfo & request, pw_protobuf_Empty & response)
{
if (DeviceLayer::ConfigurationMgr().StoreSetupPinCode(request.code) != CHIP_NO_ERROR ||
DeviceLayer::ConfigurationMgr().StoreSetupDiscriminator(request.discriminator) != CHIP_NO_ERROR)
if (DeviceLayer::GetCommissionableDataProvider()->SetSetupPasscode(request.code) != CHIP_NO_ERROR ||
DeviceLayer::GetCommissionableDataProvider()->SetSetupDiscriminator(request.discriminator) !=
CHIP_NO_ERROR)
{
return pw::Status::Unknown();
}
Expand Down
60 changes: 54 additions & 6 deletions examples/platform/linux/AppMain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,10 @@
#include <app/clusters/network-commissioning/network-commissioning.h>
#include <app/server/OnboardingCodesUtil.h>
#include <app/server/Server.h>
#include <crypto/CHIPCryptoPAL.h>
#include <lib/core/CHIPError.h>
#include <lib/core/NodeId.h>
#include <lib/support/logging/CHIPLogging.h>

#include <credentials/DeviceAttestationCredsProvider.h>
#include <credentials/attestation_verifier/DefaultDeviceAttestationVerifier.h>
Expand All @@ -35,7 +37,9 @@
#include <setup_payload/QRCodeSetupPayloadGenerator.h>
#include <setup_payload/SetupPayload.h>

#include <platform/CommissionableDataProvider.h>
#include <platform/DiagnosticDataProvider.h>
#include <platform/TestOnlyCommissionableDataProvider.h>

#if CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE
#include <ControllerShellCommands.h>
Expand All @@ -58,6 +62,7 @@
#include <signal.h>

#include "AppMain.h"
#include "LinuxCommissionableDataProvider.h"

using namespace chip;
using namespace chip::ArgParser;
Expand Down Expand Up @@ -142,6 +147,50 @@ void SetupSignalHandlers()
signal(SIGIO, OnSignalHandler);
signal(SIGINT, OnSignalHandler);
}

CHIP_ERROR InitCommissionableDataProvider(LinuxCommissionableDataProvider & provider, LinuxDeviceOptions & options)
{
chip::Optional<uint32_t> setupPasscode;

if (options.payload.setUpPINCode != 0)
{
setupPasscode.SetValue(options.payload.setUpPINCode);
}
else if (!options.spake2pVerifier.HasValue())
{
uint32_t defaultTestPasscode = 0;
chip::DeviceLayer::TestOnlyCommissionableDataProvider TestOnlyCommissionableDataProvider;
VerifyOrDie(TestOnlyCommissionableDataProvider.GetSetupPasscode(defaultTestPasscode) == CHIP_NO_ERROR);

ChipLogError(Support,
"*** WARNING: Using temporary passcode %u due to no neither --passcode or --spake2p-verifier-base64 "
"given on command line. This is temporary and will disappear. Please update your scripts "
"to explicitly configure onboarding credentials. ***",
static_cast<unsigned>(defaultTestPasscode));
setupPasscode.SetValue(defaultTestPasscode);
options.payload.setUpPINCode = defaultTestPasscode;
}
else
{
// Passcode is 0, so will be ignored, and verifier will take over. Onboarding payload
// printed for debug will be invalid, but if the onboarding payload had been given
// properly to the commissioner later, PASE will succeed.
}

// Default to minimum PBKDF iterations
uint32_t spake2pIterationCount = chip::Crypto::kSpake2p_Min_PBKDF_Iterations;
if (options.spake2pIterations != 0)
{
spake2pIterationCount = options.spake2pIterations;
}
ChipLogError(Support, "PASE PBKDF iterations set to %u", static_cast<unsigned>(spake2pIterationCount));

return provider.Init(options.spake2pVerifier, options.spake2pSalt, spake2pIterationCount, setupPasscode,
options.payload.discriminator);
}

// To hold SPAKE2+ verifier, discriminator, passcode
LinuxCommissionableDataProvider gCommissionableDataProvider;
} // namespace

#if CHIP_DEVICE_CONFIG_ENABLE_WPA
Expand Down Expand Up @@ -195,12 +244,11 @@ int ChipLinuxAppInit(int argc, char ** argv, OptionSet * customOptions)
err = DeviceLayer::PlatformMgr().InitChipStack();
SuccessOrExit(err);

if (0 != LinuxDeviceOptions::GetInstance().payload.discriminator)
{
uint16_t discriminator = LinuxDeviceOptions::GetInstance().payload.discriminator;
err = DeviceLayer::ConfigurationMgr().StoreSetupDiscriminator(discriminator);
SuccessOrExit(err);
}
// Init the commissionable data provider based on command line options
// to handle custom verifiers, discriminators, etc.
err = InitCommissionableDataProvider(gCommissionableDataProvider, LinuxDeviceOptions::GetInstance());
SuccessOrExit(err);
DeviceLayer::SetCommissionableDataProvider(&gCommissionableDataProvider);

err = GetSetupPayload(LinuxDeviceOptions::GetInstance().payload, rendezvousFlags);
SuccessOrExit(err);
Expand Down
2 changes: 2 additions & 0 deletions examples/platform/linux/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ source_set("app-main") {
"CommissioneeShellCommands.h",
"ControllerShellCommands.cpp",
"ControllerShellCommands.h",
"LinuxCommissionableDataProvider.cpp",
"LinuxCommissionableDataProvider.h",
"Options.cpp",
"Options.h",
]
Expand Down
Loading

0 comments on commit 8ae80e6

Please sign in to comment.