Skip to content

Commit e06d1bc

Browse files
[Darwin][AttestationVerifier] Expose a mechanism to customise cd signing keys and use it in darwin (#22338)
* Add AttestationTrustStore::GetCertificationDeclarationCert virtual method to allow controllers passing in some CD certs * Add cdCerts member to MTRControllerFactoryparams and override AttestationTrustStore::GetCertificationDeclarationCert * Implement ArrayTrustStore::GetCertificationDeclarationSigningKey and initialize the test ArrayTrustStore store with the test CD cert * Update the FileAttestationTrustStore to read a directory with der certs for certification declaration verification * Add credentials/development/cd-certs/ and update chip-tool to use it if desired * Update API to match conversation - Remove CD stuff from FileAttestationTrustStore - Refactor FileAttestationTrustStore to allow loading of any X.509 cert directory - Add a command line to chip-tool to disallow test keys (`only-allow-trusted-cd-keys`) - Add plumbing to enable CD keys lookup properly without mixing-up with PAA semantics - Add official CD verifying key and official SDK CD test key in the default CD trust store as-is * Update src/darwin to take into account the proposed changes * Add unit test for `CsaCdKeysTrustStore` Co-authored-by: Tennessee Carmel-Veilleux <[email protected]>
1 parent 89f5c8a commit e06d1bc

15 files changed

+569
-130
lines changed
Binary file not shown.

examples/chip-tool/commands/common/CHIPCommand.cpp

+56-32
Original file line numberDiff line numberDiff line change
@@ -36,27 +36,47 @@ std::set<CHIPCommand *> CHIPCommand::sDeferredCleanups;
3636

3737
using DeviceControllerFactory = chip::Controller::DeviceControllerFactory;
3838

39-
constexpr chip::FabricId kIdentityNullFabricId = chip::kUndefinedFabricId;
40-
constexpr chip::FabricId kIdentityAlphaFabricId = 1;
41-
constexpr chip::FabricId kIdentityBetaFabricId = 2;
42-
constexpr chip::FabricId kIdentityGammaFabricId = 3;
43-
constexpr chip::FabricId kIdentityOtherFabricId = 4;
44-
constexpr const char * kTrustStorePathVariable = "CHIPTOOL_PAA_TRUST_STORE_PATH";
45-
46-
const chip::Credentials::AttestationTrustStore * CHIPCommand::sPaaTrustStore = nullptr;
39+
constexpr chip::FabricId kIdentityNullFabricId = chip::kUndefinedFabricId;
40+
constexpr chip::FabricId kIdentityAlphaFabricId = 1;
41+
constexpr chip::FabricId kIdentityBetaFabricId = 2;
42+
constexpr chip::FabricId kIdentityGammaFabricId = 3;
43+
constexpr chip::FabricId kIdentityOtherFabricId = 4;
44+
constexpr const char * kPAATrustStorePathVariable = "CHIPTOOL_PAA_TRUST_STORE_PATH";
45+
constexpr const char * kCDTrustStorePathVariable = "CHIPTOOL_CD_TRUST_STORE_PATH";
46+
47+
const chip::Credentials::AttestationTrustStore * CHIPCommand::sTrustStore = nullptr;
4748
chip::Credentials::GroupDataProviderImpl CHIPCommand::sGroupDataProvider{ kMaxGroupsPerFabric, kMaxGroupKeysPerFabric };
4849

4950
namespace {
50-
const chip::Credentials::AttestationTrustStore * GetTestFileAttestationTrustStore(const char * paaTrustStorePath)
51+
const CHIP_ERROR GetAttestationTrustStore(const char * paaTrustStorePath,
52+
const chip::Credentials::AttestationTrustStore ** trustStore)
5153
{
54+
if (paaTrustStorePath == nullptr)
55+
{
56+
paaTrustStorePath = getenv(kPAATrustStorePathVariable);
57+
}
58+
59+
if (paaTrustStorePath == nullptr)
60+
{
61+
*trustStore = chip::Credentials::GetTestAttestationTrustStore();
62+
return CHIP_NO_ERROR;
63+
}
64+
5265
static chip::Credentials::FileAttestationTrustStore attestationTrustStore{ paaTrustStorePath };
5366

54-
if (attestationTrustStore.IsInitialized())
67+
if (paaTrustStorePath != nullptr && attestationTrustStore.paaCount() == 0)
5568
{
56-
return &attestationTrustStore;
69+
ChipLogError(chipTool, "No PAAs found in path: %s", paaTrustStorePath);
70+
ChipLogError(chipTool,
71+
"Please specify a valid path containing trusted PAA certificates using "
72+
"the argument [--paa-trust-store-path paa/file/path] "
73+
"or environment variable [%s=paa/file/path]",
74+
kPAATrustStorePathVariable);
75+
return CHIP_ERROR_INVALID_ARGUMENT;
5776
}
5877

59-
return nullptr;
78+
*trustStore = &attestationTrustStore;
79+
return CHIP_NO_ERROR;
6080
}
6181
} // namespace
6282

@@ -103,29 +123,33 @@ CHIP_ERROR CHIPCommand::MaybeSetUpStack()
103123
factoryInitParams.listenPort = port;
104124
ReturnLogErrorOnFailure(DeviceControllerFactory::GetInstance().Init(factoryInitParams));
105125

106-
if (!mPaaTrustStorePath.HasValue())
126+
ReturnErrorOnFailure(GetAttestationTrustStore(mPaaTrustStorePath.ValueOr(nullptr), &sTrustStore));
127+
128+
ReturnLogErrorOnFailure(InitializeCommissioner(kIdentityNull, kIdentityNullFabricId));
129+
130+
// After initializing first commissioner, add the additional CD certs once
107131
{
108-
char * const trust_store_path = getenv(kTrustStorePathVariable);
109-
if (trust_store_path != nullptr)
132+
const char * cdTrustStorePath = mCDTrustStorePath.ValueOr(nullptr);
133+
if (cdTrustStorePath == nullptr)
110134
{
111-
mPaaTrustStorePath.SetValue(trust_store_path);
135+
cdTrustStorePath = getenv(kCDTrustStorePathVariable);
112136
}
113-
}
114-
sPaaTrustStore = mPaaTrustStorePath.HasValue() ? GetTestFileAttestationTrustStore(mPaaTrustStorePath.Value())
115-
: chip::Credentials::GetTestAttestationTrustStore();
116-
;
117-
if (mPaaTrustStorePath.HasValue() && sPaaTrustStore == nullptr)
118-
{
119-
ChipLogError(chipTool, "No PAAs found in path: %s", mPaaTrustStorePath.Value());
120-
ChipLogError(chipTool,
121-
"Please specify a valid path containing trusted PAA certificates using"
122-
"the argument [--paa-trust-store-path paa/file/path]"
123-
"or environment variable [%s=paa/file/path]",
124-
kTrustStorePathVariable);
125-
return CHIP_ERROR_INVALID_ARGUMENT;
126-
}
127137

128-
ReturnLogErrorOnFailure(InitializeCommissioner(kIdentityNull, kIdentityNullFabricId));
138+
auto additionalCdCerts = chip::Credentials::LoadAllX509DerCerts(cdTrustStorePath);
139+
if (cdTrustStorePath != nullptr && additionalCdCerts.size() == 0)
140+
{
141+
ChipLogError(chipTool, "Warning: no CD signing certs found in path: %s, only defaults will be used", cdTrustStorePath);
142+
ChipLogError(chipTool,
143+
"Please specify a path containing trusted CD verifying key certificates using "
144+
"the argument [--cd-trust-store-path cd/file/path] "
145+
"or environment variable [%s=cd/file/path]",
146+
kCDTrustStorePathVariable);
147+
}
148+
ReturnErrorOnFailure(mCredIssuerCmds->AddAdditionalCDVerifyingCerts(additionalCdCerts));
149+
}
150+
bool allowTestCdSigningKey = !mOnlyAllowTrustedCdKeys.ValueOr(false);
151+
mCredIssuerCmds->SetCredentialIssuerOption(CredentialIssuerCommands::CredentialIssuerOptions::kAllowTestCdSigningKey,
152+
allowTestCdSigningKey);
129153

130154
return CHIP_NO_ERROR;
131155
}
@@ -343,7 +367,7 @@ CHIP_ERROR CHIPCommand::InitializeCommissioner(std::string key, chip::FabricId f
343367
std::unique_ptr<ChipDeviceCommissioner> commissioner = std::make_unique<ChipDeviceCommissioner>();
344368
chip::Controller::SetupParams commissionerParams;
345369

346-
ReturnLogErrorOnFailure(mCredIssuerCmds->SetupDeviceAttestation(commissionerParams, sPaaTrustStore));
370+
ReturnLogErrorOnFailure(mCredIssuerCmds->SetupDeviceAttestation(commissionerParams, sTrustStore));
347371

348372
VerifyOrReturnError(noc.Alloc(chip::Controller::kMaxCHIPDERCertLength), CHIP_ERROR_NO_MEMORY);
349373
VerifyOrReturnError(icac.Alloc(chip::Controller::kMaxCHIPDERCertLength), CHIP_ERROR_NO_MEMORY);

examples/chip-tool/commands/common/CHIPCommand.h

+9-1
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,9 @@ class CHIPCommand : public Command
6565
AddArgument("paa-trust-store-path", &mPaaTrustStorePath,
6666
"Path to directory holding PAA certificate information. Can be absolute or relative to the current working "
6767
"directory.");
68+
AddArgument("cd-trust-store-path", &mCDTrustStorePath,
69+
"Path to directory holding CD certificate information. Can be absolute or relative to the current working "
70+
"directory.");
6871
AddArgument("commissioner-name", &mCommissionerName,
6972
"Name of fabric to use. Valid values are \"alpha\", \"beta\", \"gamma\", and integers greater than or equal to "
7073
"4. The default if not specified is \"alpha\".");
@@ -73,6 +76,9 @@ class CHIPCommand : public Command
7376
AddArgument("use-max-sized-certs", 0, 1, &mUseMaxSizedCerts,
7477
"Maximize the size of operational certificates. If not provided or 0 (\"false\"), normally sized operational "
7578
"certificates are generated.");
79+
AddArgument("only-allow-trusted-cd-keys", 0, 1, &mOnlyAllowTrustedCdKeys,
80+
"Only allow trusted CD verifying keys (disallow test keys). If not provided or 0 (\"false\"), untrusted CD "
81+
"verifying keys are allowed. If 1 (\"true\"), test keys are disallowed.");
7682
#if CHIP_CONFIG_TRANSPORT_TRACE_ENABLED
7783
AddArgument("trace_file", &mTraceFile);
7884
AddArgument("trace_log", 0, 1, &mTraceLog);
@@ -156,11 +162,13 @@ class CHIPCommand : public Command
156162
chip::Optional<chip::NodeId> mCommissionerNodeId;
157163
chip::Optional<uint16_t> mBleAdapterId;
158164
chip::Optional<char *> mPaaTrustStorePath;
165+
chip::Optional<char *> mCDTrustStorePath;
159166
chip::Optional<bool> mUseMaxSizedCerts;
167+
chip::Optional<bool> mOnlyAllowTrustedCdKeys;
160168

161169
// Cached trust store so commands other than the original startup command
162170
// can spin up commissioners as needed.
163-
static const chip::Credentials::AttestationTrustStore * sPaaTrustStore;
171+
static const chip::Credentials::AttestationTrustStore * sTrustStore;
164172

165173
static void RunQueuedCommand(intptr_t commandArg);
166174

examples/chip-tool/commands/common/CredentialIssuerCommands.h

+12
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include <credentials/attestation_verifier/DeviceAttestationVerifier.h>
2424
#include <lib/core/CHIPCore.h>
2525
#include <lib/core/CHIPPersistentStorageDelegate.h>
26+
#include <vector>
2627

2728
class CredentialIssuerCommands
2829
{
@@ -54,6 +55,16 @@ class CredentialIssuerCommands
5455
virtual CHIP_ERROR SetupDeviceAttestation(chip::Controller::SetupParams & setupParams,
5556
const chip::Credentials::AttestationTrustStore * trustStore) = 0;
5657

58+
/**
59+
* @brief Add a list of additional non-default CD verifying keys (by certificate)
60+
*
61+
* Must be called AFTER SetupDeviceAttestation.
62+
*
63+
* @param additionalCdCerts - vector of X.509 DER verifying cert bodies
64+
* @return CHIP_NO_ERROR on succes, another CHIP_ERROR on internal failures.
65+
*/
66+
virtual CHIP_ERROR AddAdditionalCDVerifyingCerts(const std::vector<std::vector<uint8_t>> & additionalCdCerts) = 0;
67+
5768
virtual chip::Controller::OperationalCredentialsDelegate * GetCredentialIssuer() = 0;
5869

5970
/**
@@ -79,6 +90,7 @@ class CredentialIssuerCommands
7990
enum CredentialIssuerOptions : uint8_t
8091
{
8192
kMaximizeCertificateSizes = 0, // If set, certificate chains will be maximized for testing via padding
93+
kAllowTestCdSigningKey = 1, // If set, allow development/test SDK CD verifying key to be used
8294
};
8395

8496
virtual void SetCredentialIssuerOption(CredentialIssuerOptions option, bool isEnabled)

examples/chip-tool/commands/example/ExampleCredentialIssuerCommands.h

+29-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,9 @@ class ExampleCredentialIssuerCommands : public CredentialIssuerCommands
3737
{
3838
chip::Credentials::SetDeviceAttestationCredentialsProvider(chip::Credentials::Examples::GetExampleDACProvider());
3939

40-
setupParams.deviceAttestationVerifier = chip::Credentials::GetDefaultDACVerifier(trustStore);
40+
mDacVerifier = chip::Credentials::GetDefaultDACVerifier(trustStore);
41+
setupParams.deviceAttestationVerifier = mDacVerifier;
42+
mDacVerifier->EnableCdTestKeySupport(mAllowTestCdSigningKey);
4143

4244
return CHIP_NO_ERROR;
4345
}
@@ -49,6 +51,20 @@ class ExampleCredentialIssuerCommands : public CredentialIssuerCommands
4951
return mOpCredsIssuer.GenerateNOCChainAfterValidation(nodeId, fabricId, cats, keypair.Pubkey(), rcac, icac, noc);
5052
}
5153

54+
CHIP_ERROR AddAdditionalCDVerifyingCerts(const std::vector<std::vector<uint8_t>> & additionalCdCerts) override
55+
{
56+
VerifyOrReturnError(mDacVerifier != nullptr, CHIP_ERROR_INCORRECT_STATE);
57+
58+
for (const auto & cert : additionalCdCerts)
59+
{
60+
auto cdTrustStore = mDacVerifier->GetCertificationDeclarationTrustStore();
61+
VerifyOrReturnError(cdTrustStore != nullptr, CHIP_ERROR_INCORRECT_STATE);
62+
ReturnErrorOnFailure(cdTrustStore->AddTrustedKey(chip::ByteSpan(cert.data(), cert.size())));
63+
}
64+
65+
return CHIP_NO_ERROR;
66+
}
67+
5268
void SetCredentialIssuerOption(CredentialIssuerOptions option, bool isEnabled) override
5369
{
5470
switch (option)
@@ -57,6 +73,13 @@ class ExampleCredentialIssuerCommands : public CredentialIssuerCommands
5773
mUsesMaxSizedCerts = isEnabled;
5874
mOpCredsIssuer.SetMaximallyLargeCertsUsed(mUsesMaxSizedCerts);
5975
break;
76+
case CredentialIssuerOptions::kAllowTestCdSigningKey:
77+
mAllowTestCdSigningKey = isEnabled;
78+
if (mDacVerifier != nullptr)
79+
{
80+
mDacVerifier->EnableCdTestKeySupport(isEnabled);
81+
}
82+
6083
default:
6184
break;
6285
}
@@ -68,14 +91,19 @@ class ExampleCredentialIssuerCommands : public CredentialIssuerCommands
6891
{
6992
case CredentialIssuerOptions::kMaximizeCertificateSizes:
7093
return mUsesMaxSizedCerts;
94+
case CredentialIssuerOptions::kAllowTestCdSigningKey:
95+
return mAllowTestCdSigningKey;
7196
default:
7297
return false;
7398
}
7499
}
75100

76101
protected:
77102
bool mUsesMaxSizedCerts = false;
103+
// Starts true for legacy purposes
104+
bool mAllowTestCdSigningKey = true;
78105

79106
private:
80107
chip::Controller::ExampleOperationalCredentialsIssuer mOpCredsIssuer;
108+
chip::Credentials::DeviceAttestationVerifier * mDacVerifier;
81109
};

0 commit comments

Comments
 (0)