Skip to content

Commit

Permalink
Integrate commissioner and device clusters with operational credentia…
Browse files Browse the repository at this point in the history
…ls (#6705)

* Integrate commissioner and device clusters with operational credentials

* fix check

* fix tests

* fix tests

* some error handling and cleanup

* address review comments

* some cleanup

* disable early return for message counter verification failure

* Integrate root cert provisioning

* restyled.

* Address review comments

* cleanup comments
  • Loading branch information
pan-apple authored and pull[bot] committed Aug 11, 2021
1 parent 4f56baa commit 1726800
Show file tree
Hide file tree
Showing 15 changed files with 1,044 additions and 61 deletions.
2 changes: 1 addition & 1 deletion src/app/InteractionModelEngine.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ namespace chip {
namespace app {

constexpr size_t kMaxSecureSduLengthBytes = 1024;
constexpr uint32_t kImMessageTimeoutMsec = 3000;
constexpr uint32_t kImMessageTimeoutMsec = 6000;
constexpr FieldId kRootFieldId = 0;
/**
* @class InteractionModelEngine
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include <lib/core/PeerId.h>
#include <platform/CHIPDeviceLayer.h>
#include <support/CodeUtils.h>
#include <support/ScopedBuffer.h>
#include <support/logging/CHIPLogging.h>
#include <transport/AdminPairingTable.h>

Expand Down Expand Up @@ -145,7 +146,7 @@ CHIP_ERROR writeAdminsIntoFabricsListAttribute()
* fields to find the current admin. Once addOptCert and fabric index are implemented, remove all this and use fabricIndex.
*/

AdminPairingInfo * retrieveCurrentAdmin()
static AdminPairingInfo * retrieveCurrentAdmin()
{
uint64_t fabricId = emberAfCurrentCommand()->SourceNodeId();
// TODO: Figure out how to get device node id so we can do FindAdminForNode(fabricId, nodeId)...
Expand Down Expand Up @@ -314,15 +315,98 @@ bool emberAfOperationalCredentialsClusterAddOpCertCallback(chip::app::Command *
chip::ByteSpan ICACertificate, chip::ByteSpan IPKValue,
chip::NodeId CaseAdminNode, uint16_t AdminVendorId)
{
EmberAfStatus status = EMBER_ZCL_STATUS_FAILURE;
EmberAfStatus status = EMBER_ZCL_STATUS_SUCCESS;

chip::Platform::ScopedMemoryBuffer<uint8_t> cert;

uint8_t * certBuf = nullptr;

emberAfPrintln(EMBER_AF_PRINT_DEBUG, "OpCreds: commissioner has added an Op Cert");

AdminPairingInfo * admin = retrieveCurrentAdmin();
VerifyOrExit(admin != nullptr, status = EMBER_ZCL_STATUS_FAILURE);

// TODO - Update ZAP to use 16 bit length for OCTET_STRING. This is a temporary hack, as OCTET_STRING only supports 8 bit
// strings. We are currently spilling over NOC into ICACertificate argument.
VerifyOrExit(cert.Alloc(NOC.size() + ICACertificate.size()), status = EMBER_ZCL_STATUS_FAILURE);
certBuf = cert.Get();
memcpy(certBuf, NOC.data(), NOC.size());
memcpy(&certBuf[NOC.size()], ICACertificate.data(), ICACertificate.size());

VerifyOrExit(admin->SetOperationalCert(ByteSpan(certBuf, NOC.size() + ICACertificate.size())) == CHIP_NO_ERROR,
status = EMBER_ZCL_STATUS_FAILURE);

exit:
emberAfSendImmediateDefaultResponse(status);
if (status == EMBER_ZCL_STATUS_FAILURE)
{
emberAfPrintln(EMBER_AF_PRINT_DEBUG, "OpCreds: Failed AddOpCert request.");
}

return true;
}

bool emberAfOperationalCredentialsClusterOpCSRRequestCallback(chip::app::Command * commandObj, chip::ByteSpan CSRNonce)
{
EmberAfStatus status = EMBER_ZCL_STATUS_FAILURE;
emberAfSendImmediateDefaultResponse(status);
EmberAfStatus status = EMBER_ZCL_STATUS_SUCCESS;
EmberStatus sendStatus = EMBER_SUCCESS;
CHIP_ERROR err = CHIP_NO_ERROR;

chip::Platform::ScopedMemoryBuffer<uint8_t> csr;
size_t csrLength = Crypto::kMAX_CSR_Length;

emberAfPrintln(EMBER_AF_PRINT_DEBUG, "OpCreds: commissioner has requested an OpCSR");

app::CommandPathParams cmdParams = { emberAfCurrentEndpoint(), /* group id */ 0, ZCL_OPERATIONAL_CREDENTIALS_CLUSTER_ID,
ZCL_OP_CSR_RESPONSE_COMMAND_ID, (chip::app::CommandPathFlags::kEndpointIdValid) };

TLV::TLVWriter * writer = nullptr;

// Fetch current admin
AdminPairingInfo * admin = retrieveCurrentAdmin();
VerifyOrExit(admin != nullptr, status = EMBER_ZCL_STATUS_FAILURE);

VerifyOrExit(csr.Alloc(Crypto::kMAX_CSR_Length), status = EMBER_ZCL_STATUS_FAILURE);

if (admin->GetOperationalKey() == nullptr)
{
Crypto::P256Keypair keypair;
keypair.Initialize();
VerifyOrExit(admin->SetOperationalKey(keypair) == CHIP_NO_ERROR, status = EMBER_ZCL_STATUS_FAILURE);
}

err = admin->GetOperationalKey()->NewCertificateSigningRequest(csr.Get(), csrLength);
emberAfPrintln(EMBER_AF_PRINT_DEBUG, "OpCreds: NewCertificateSigningRequest returned %d", err);
VerifyOrExit(err == CHIP_NO_ERROR, status = EMBER_ZCL_STATUS_FAILURE);
VerifyOrExit(csrLength < UINT8_MAX, status = EMBER_ZCL_STATUS_FAILURE);

VerifyOrExit(commandObj != nullptr, err = CHIP_ERROR_INCORRECT_STATE);

SuccessOrExit(err = commandObj->PrepareCommand(&cmdParams));
writer = commandObj->GetCommandDataElementTLVWriter();
SuccessOrExit(err = writer->Put(TLV::ContextTag(0), ByteSpan(csr.Get(), csrLength)));
SuccessOrExit(err = writer->Put(TLV::ContextTag(1), CSRNonce));
SuccessOrExit(err = writer->Put(TLV::ContextTag(2), ByteSpan(nullptr, 0)));
SuccessOrExit(err = writer->Put(TLV::ContextTag(3), ByteSpan(nullptr, 0)));
SuccessOrExit(err = writer->Put(TLV::ContextTag(4), ByteSpan(nullptr, 0)));
SuccessOrExit(err = writer->Put(TLV::ContextTag(5), ByteSpan(nullptr, 0)));
SuccessOrExit(err = commandObj->FinishCommand());

exit:
if (status == EMBER_ZCL_STATUS_FAILURE)
{
emberAfPrintln(EMBER_AF_PRINT_DEBUG, "OpCreds: Failed OpCSRRequest.");
emberAfSendImmediateDefaultResponse(status);
}
if (sendStatus != EMBER_SUCCESS)
{
emberAfPrintln(EMBER_AF_PRINT_DEBUG, "OpCreds: Failed to send OpCSRRequest: 0x%x", sendStatus);
}
if (err != CHIP_NO_ERROR)
{
ChipLogError(Zcl, "Failed to encode response command: %s", ErrorStr(err));
}

return true;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,34 @@
#include "gen/cluster-id.h"
#include "gen/command-id.h"

using namespace chip;
using namespace ::chip::Transport;

static AdminPairingInfo * retrieveCurrentAdmin()
{
uint64_t fabricId = emberAfCurrentCommand()->SourceNodeId();
return GetGlobalAdminPairingTable().FindAdminForNode(fabricId);
}

bool emberAfTrustedRootCertificatesClusterAddTrustedRootCertificateCallback(chip::app::Command * commandObj,
chip::ByteSpan RootCertificate)
{
EmberAfStatus status = EMBER_ZCL_STATUS_FAILURE;
EmberAfStatus status = EMBER_ZCL_STATUS_SUCCESS;

emberAfPrintln(EMBER_AF_PRINT_DEBUG, "OpCreds: commissioner has added a trusted root Cert");

// Fetch current admin
AdminPairingInfo * admin = retrieveCurrentAdmin();
VerifyOrExit(admin != nullptr, status = EMBER_ZCL_STATUS_FAILURE);
VerifyOrExit(admin->SetRootCert(RootCertificate) == CHIP_NO_ERROR, status = EMBER_ZCL_STATUS_FAILURE);

exit:
emberAfSendImmediateDefaultResponse(status);
if (status == EMBER_ZCL_STATUS_FAILURE)
{
emberAfPrintln(EMBER_AF_PRINT_DEBUG, "OpCreds: Failed AddTrustedRootCert request.");
}

return true;
}

Expand Down
2 changes: 2 additions & 0 deletions src/controller/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ static_library("controller") {
"CHIPDevice.h",
"CHIPDeviceController.cpp",
"CHIPDeviceController.h",
"CHIPOperationalCredentialsProvisioner.cpp",
"CHIPOperationalCredentialsProvisioner.h",
"DeviceAddressUpdateDelegate.h",
"EmptyDataModelHandler.cpp",
"ExampleOperationalCredentialsIssuer.cpp",
Expand Down
Loading

0 comments on commit 1726800

Please sign in to comment.