| /* |
| * |
| * Copyright (c) 2022 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. |
| */ |
| |
| #include <map> |
| #include <string> |
| |
| #include <controller/CHIPDeviceController.h> |
| #include <controller/python/chip/native/PyChipError.h> |
| #include <lib/core/CHIPError.h> |
| #include <lib/support/Span.h> |
| |
| using namespace chip; |
| using namespace chip::Credentials; |
| |
| typedef void PyObject; |
| |
| using namespace chip; |
| |
| extern "C" { |
| |
| typedef void (*pychip_DeviceController_IssueNOCChainCallbackPythonCallback)( |
| PyObject * context, PyChipError status, const uint8_t * noc, size_t nocLen, const uint8_t * icac, size_t icacLen, |
| const uint8_t * rcac, size_t rcacLen, const uint8_t * ipk, size_t ipkLen, NodeId adminSubject); |
| |
| static pychip_DeviceController_IssueNOCChainCallbackPythonCallback pychip_DeviceController_IssueNOCChainCallbackPythonCallbackFunct; |
| |
| void pychip_DeviceController_SetIssueNOCChainCallbackPythonCallback( |
| pychip_DeviceController_IssueNOCChainCallbackPythonCallback callback) |
| { |
| pychip_DeviceController_IssueNOCChainCallbackPythonCallbackFunct = callback; |
| } |
| |
| PyChipError pychip_DeviceController_IssueNOCChain(chip::Controller::DeviceCommissioner * devCtrl, PyObject * pythonContext, |
| uint8_t * NOCSRElements, size_t NOCSRElementsLen, NodeId nodeId); |
| } |
| |
| void pychip_DeviceController_IssueNOCChainCallback(void * context, CHIP_ERROR status, const ByteSpan & noc, const ByteSpan & icac, |
| const ByteSpan & rcac, Optional<Crypto::IdentityProtectionKeySpan> ipk, |
| Optional<NodeId> adminSubject) |
| { |
| if (pychip_DeviceController_IssueNOCChainCallbackPythonCallbackFunct == nullptr) |
| { |
| return; |
| } |
| |
| chip::Platform::ScopedMemoryBuffer<uint8_t> chipNoc; |
| chip::Platform::ScopedMemoryBuffer<uint8_t> chipIcac; |
| chip::Platform::ScopedMemoryBuffer<uint8_t> chipRcac; |
| MutableByteSpan chipNocSpan; |
| MutableByteSpan chipIcacSpan; |
| MutableByteSpan chipRcacSpan; |
| |
| Crypto::IdentityProtectionKeySpan ipkData; |
| ipkData = ipk.ValueOr(Crypto::IdentityProtectionKeySpan()); |
| |
| CHIP_ERROR err = status; |
| if (err != CHIP_NO_ERROR) |
| { |
| ExitNow(); |
| } |
| VerifyOrExit(chipNoc.Alloc(Credentials::kMaxCHIPCertLength), err = CHIP_ERROR_NO_MEMORY); |
| chipNocSpan = MutableByteSpan(chipNoc.Get(), Credentials::kMaxCHIPCertLength); |
| |
| VerifyOrExit(chipIcac.Alloc(Credentials::kMaxCHIPCertLength), err = CHIP_ERROR_NO_MEMORY); |
| chipIcacSpan = MutableByteSpan(chipIcac.Get(), Credentials::kMaxCHIPCertLength); |
| |
| VerifyOrExit(chipRcac.Alloc(Credentials::kMaxCHIPCertLength), err = CHIP_ERROR_NO_MEMORY); |
| chipRcacSpan = MutableByteSpan(chipRcac.Get(), Credentials::kMaxCHIPCertLength); |
| |
| SuccessOrExit(err = ConvertX509CertToChipCert(noc, chipNocSpan)); |
| SuccessOrExit(err = ConvertX509CertToChipCert(icac, chipIcacSpan)); |
| SuccessOrExit(err = ConvertX509CertToChipCert(rcac, chipRcacSpan)); |
| |
| exit: |
| if (err == CHIP_NO_ERROR) |
| { |
| pychip_DeviceController_IssueNOCChainCallbackPythonCallbackFunct( |
| context, ToPyChipError(err), chipNocSpan.data(), chipNocSpan.size(), chipIcacSpan.data(), chipIcacSpan.size(), |
| chipRcacSpan.data(), chipRcacSpan.size(), ipkData.data(), ipk.HasValue() ? ipkData.size() : 0, |
| adminSubject.ValueOr(kUndefinedNodeId)); |
| } |
| else |
| { |
| pychip_DeviceController_IssueNOCChainCallbackPythonCallbackFunct(context, ToPyChipError(err), nullptr, 0, nullptr, 0, |
| nullptr, 0, nullptr, 0, 0); |
| } |
| } |
| |
| PyChipError pychip_DeviceController_IssueNOCChain(chip::Controller::DeviceCommissioner * devCtrl, PyObject * pythonContext, |
| uint8_t * NOCSRElements, size_t NOCSRElementsLen, NodeId nodeId) |
| { |
| return ToPyChipError(devCtrl->IssueNOCChain( |
| ByteSpan(NOCSRElements, NOCSRElementsLen), nodeId, |
| /* Note: Memory leak here. This is a quick and a bit dirty PoC */ |
| new Callback::Callback<Controller::OnNOCChainGeneration>(pychip_DeviceController_IssueNOCChainCallback, pythonContext))); |
| } |