Persist keypair used by example opcert signer (#6821)
* Persist keypair used by example opcert signer
* Fix Android build
diff --git a/examples/chip-tool/commands/clusters/ModelCommand.cpp b/examples/chip-tool/commands/clusters/ModelCommand.cpp
index 0bd0f29..c556197 100644
--- a/examples/chip-tool/commands/clusters/ModelCommand.cpp
+++ b/examples/chip-tool/commands/clusters/ModelCommand.cpp
@@ -41,10 +41,12 @@
{
CHIP_ERROR err = CHIP_NO_ERROR;
- mOpCredsIssuer.Initialize();
-
chip::Controller::CommissionerInitParams initParams;
- initParams.storageDelegate = &storage;
+ initParams.storageDelegate = &storage;
+
+ err = mOpCredsIssuer.Initialize(storage);
+ VerifyOrExit(err == CHIP_NO_ERROR, ChipLogError(Controller, "Init failure! Operational Cred Issuer: %s", ErrorStr(err)));
+
initParams.operationalCredentialsDelegate = &mOpCredsIssuer;
err = mCommissioner.SetUdpListenPort(storage.GetListenPort());
diff --git a/examples/chip-tool/commands/pairing/PairingCommand.cpp b/examples/chip-tool/commands/pairing/PairingCommand.cpp
index 7521c39..ff54619 100644
--- a/examples/chip-tool/commands/pairing/PairingCommand.cpp
+++ b/examples/chip-tool/commands/pairing/PairingCommand.cpp
@@ -31,12 +31,14 @@
{
CHIP_ERROR err = CHIP_NO_ERROR;
- mOpCredsIssuer.Initialize();
-
chip::Controller::CommissionerInitParams params;
- params.storageDelegate = &storage;
- params.mDeviceAddressUpdateDelegate = this;
- params.pairingDelegate = this;
+ params.storageDelegate = &storage;
+ params.mDeviceAddressUpdateDelegate = this;
+ params.pairingDelegate = this;
+
+ err = mOpCredsIssuer.Initialize(storage);
+ VerifyOrExit(err == CHIP_NO_ERROR, ChipLogError(Controller, "Init failure! Operational Cred Issuer: %s", ErrorStr(err)));
+
params.operationalCredentialsDelegate = &mOpCredsIssuer;
err = mCommissioner.SetUdpListenPort(storage.GetListenPort());
diff --git a/examples/chip-tool/commands/pairing/PairingCommand.h b/examples/chip-tool/commands/pairing/PairingCommand.h
index 871186e..d5e1222 100644
--- a/examples/chip-tool/commands/pairing/PairingCommand.h
+++ b/examples/chip-tool/commands/pairing/PairingCommand.h
@@ -93,7 +93,6 @@
AddArgument("device-remote-port", 0, UINT16_MAX, &mRemotePort);
break;
}
- mOpCredsIssuer.Initialize();
}
/////////// Command Interface /////////
diff --git a/examples/chip-tool/commands/reporting/ReportingCommand.cpp b/examples/chip-tool/commands/reporting/ReportingCommand.cpp
index 29d43c7..447c1c8 100644
--- a/examples/chip-tool/commands/reporting/ReportingCommand.cpp
+++ b/examples/chip-tool/commands/reporting/ReportingCommand.cpp
@@ -32,12 +32,14 @@
{
CHIP_ERROR err = CHIP_NO_ERROR;
- mOpCredsIssuer.Initialize();
-
chip::Controller::BasicCluster cluster;
chip::Controller::CommissionerInitParams initParams;
- initParams.storageDelegate = &storage;
+ initParams.storageDelegate = &storage;
+
+ err = mOpCredsIssuer.Initialize(storage);
+ VerifyOrExit(err == CHIP_NO_ERROR, ChipLogError(Controller, "Init failure! Operational Cred Issuer: %s", ErrorStr(err)));
+
initParams.operationalCredentialsDelegate = &mOpCredsIssuer;
err = mCommissioner.SetUdpListenPort(storage.GetListenPort());
diff --git a/src/controller/ExampleOperationalCredentialsIssuer.cpp b/src/controller/ExampleOperationalCredentialsIssuer.cpp
index f0680b1..88da5d8 100644
--- a/src/controller/ExampleOperationalCredentialsIssuer.cpp
+++ b/src/controller/ExampleOperationalCredentialsIssuer.cpp
@@ -22,9 +22,35 @@
namespace chip {
namespace Controller {
+constexpr const char kOperationalCredentialsIssuerKeypairStorage[] = "ExampleOpCredsCAKey";
+
using namespace Credentials;
using namespace Crypto;
+CHIP_ERROR ExampleOperationalCredentialsIssuer::Initialize(PersistentStorageDelegate & storage)
+{
+ Crypto::P256SerializedKeypair serializedKey;
+ uint16_t keySize = static_cast<uint16_t>(serializedKey.Capacity());
+
+ if (storage.SyncGetKeyValue(kOperationalCredentialsIssuerKeypairStorage, serializedKey, keySize) != CHIP_NO_ERROR)
+ {
+ // Storage doesn't have an existing keypair. Let's create one and add it to the storage.
+ ReturnErrorOnFailure(mIssuer.Initialize());
+ ReturnErrorOnFailure(mIssuer.Serialize(serializedKey));
+
+ keySize = static_cast<uint16_t>(serializedKey.Length());
+ ReturnErrorOnFailure(storage.SyncSetKeyValue(kOperationalCredentialsIssuerKeypairStorage, serializedKey, keySize));
+ }
+ else
+ {
+ // Use the keypair from the storage
+ ReturnErrorOnFailure(mIssuer.Deserialize(serializedKey));
+ }
+
+ mInitialized = true;
+ return CHIP_NO_ERROR;
+}
+
CHIP_ERROR ExampleOperationalCredentialsIssuer::GenerateNodeOperationalCertificate(const PeerId & peerId, const ByteSpan & csr,
int64_t serialNumber, uint8_t * certBuf,
uint32_t certBufSize, uint32_t & outCertLen)
diff --git a/src/controller/ExampleOperationalCredentialsIssuer.h b/src/controller/ExampleOperationalCredentialsIssuer.h
index 00eba94..a8ae6a8 100644
--- a/src/controller/ExampleOperationalCredentialsIssuer.h
+++ b/src/controller/ExampleOperationalCredentialsIssuer.h
@@ -22,12 +22,16 @@
* issuer for CHIP devices. The class can be used as a guideline on how to
* construct your own certificate issuer. It can also be used in tests and tools
* if a specific signing authority is not required.
+ *
+ * NOTE: This class stores the encryption key in clear storage. This is not suited
+ * for production use. This should only be used in test tools.
*/
#pragma once
#include <controller/OperationalCredentialsDelegate.h>
#include <core/CHIPError.h>
+#include <core/CHIPPersistentStorageDelegate.h>
#include <crypto/CHIPCryptoPAL.h>
#include <support/CodeUtils.h>
@@ -45,36 +49,17 @@
CHIP_ERROR GetRootCACertificate(FabricId fabricId, uint8_t * certBuf, uint32_t certBufSize, uint32_t & outCertLen) override;
/**
- * @brief Serialize the issuer's keypair.
+ * @brief Initialize the issuer with the keypair in the storage.
+ * If the storage doesn't have one, it'll create one, and it to the storage.
+ *
+ * @param[in] storage A reference to the storage, where the keypair is stored.
+ * The object of ExampleOperationalCredentialsIssuer doesn't hold
+ * on the reference of storage.
+ *
* @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
**/
- CHIP_ERROR Serialize(Crypto::P256SerializedKeypair & issuer)
- {
- VerifyOrReturnError(mInitialized, CHIP_ERROR_INCORRECT_STATE);
- return mIssuer.Serialize(issuer);
- }
-
- /**
- * @brief Deserialize the keypair as issuer's keypair.
- * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
- **/
- CHIP_ERROR Deserialize(Crypto::P256SerializedKeypair & issuer)
- {
- ReturnErrorOnFailure(mIssuer.Deserialize(issuer));
- mInitialized = true;
- return CHIP_NO_ERROR;
- }
-
- /**
- * @brief Initialize the issuer with a new keypair.
- * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
- **/
- CHIP_ERROR Initialize()
- {
- ReturnErrorOnFailure(mIssuer.Initialize());
- mInitialized = true;
- return CHIP_NO_ERROR;
- }
+ [[deprecated("This class stores the encryption key in clear storage. Don't use it for production code.")]] CHIP_ERROR
+ Initialize(PersistentStorageDelegate & storage);
void SetIssuerId(uint32_t id) { mIssuerId = id; }
diff --git a/src/controller/java/AndroidDeviceControllerWrapper.cpp b/src/controller/java/AndroidDeviceControllerWrapper.cpp
index bb061f5..f40e519 100644
--- a/src/controller/java/AndroidDeviceControllerWrapper.cpp
+++ b/src/controller/java/AndroidDeviceControllerWrapper.cpp
@@ -143,7 +143,7 @@
initParams.inetLayer = inetLayer;
initParams.bleLayer = GetJNIBleLayer();
- *errInfoOnFailure = wrapper->OpCredsIssuer().Initialize();
+ *errInfoOnFailure = wrapper->OpCredsIssuer().Initialize(*initParams.storageDelegate);
if (*errInfoOnFailure != CHIP_NO_ERROR)
{
return nullptr;
diff --git a/src/controller/python/ChipDeviceController-ScriptBinding.cpp b/src/controller/python/ChipDeviceController-ScriptBinding.cpp
index dcc5f3e..f497c37 100644
--- a/src/controller/python/ChipDeviceController-ScriptBinding.cpp
+++ b/src/controller/python/ChipDeviceController-ScriptBinding.cpp
@@ -143,7 +143,7 @@
localDeviceId = kDefaultLocalDeviceId;
}
- ReturnErrorOnFailure(sOperationalCredentialsIssuer.Initialize());
+ ReturnErrorOnFailure(sOperationalCredentialsIssuer.Initialize(sStorageDelegate));
initParams.storageDelegate = &sStorageDelegate;
initParams.mDeviceAddressUpdateDelegate = &sDeviceAddressUpdateDelegate;
diff --git a/src/controller/python/chip/internal/CommissionerImpl.cpp b/src/controller/python/chip/internal/CommissionerImpl.cpp
index bc1b7c6..0f72231 100644
--- a/src/controller/python/chip/internal/CommissionerImpl.cpp
+++ b/src/controller/python/chip/internal/CommissionerImpl.cpp
@@ -101,8 +101,7 @@
params.inetLayer = &chip::DeviceLayer::InetLayer;
params.pairingDelegate = &gPairingDelegate;
- err = gOperationalCredentialsIssuer.Initialize();
-
+ err = gOperationalCredentialsIssuer.Initialize(gServerStorage);
if (err != CHIP_NO_ERROR)
{
ChipLogError(Controller, "Operational credentials issuer initialization failed: %s", chip::ErrorStr(err));