Skip to content

Commit

Permalink
Make PAA store configurable
Browse files Browse the repository at this point in the history
PAA store used by DefaultDeviceAttestationVerifier could not be
replaced, forcing a few fixed test roots to always be used and
nothing else, unless completely forking the
DefaultDeviceAttestationVerifier.

- This PR introduces the `PaaRootStore` interface, which the
  default `DeviceAttestationVerifier` expects to get configured
  at in constructor.
- Examples were modified to use the default test PAA root store
- Unit tests updated to use the testing root store
- Refactored simple array-based Root store to self-extract
  the SKID

Testing done: added new units tests which pass, ran cert tests,
validated attestation succeeds the same as before with test keys.

Fixed project-chip#11913
  • Loading branch information
tcarmelveilleux committed Nov 25, 2021
1 parent 2ef08db commit 83591d7
Show file tree
Hide file tree
Showing 16 changed files with 253 additions and 83 deletions.
5 changes: 4 additions & 1 deletion examples/chip-tool/commands/common/CHIPCommand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,10 @@ CHIP_ERROR CHIPCommand::Run()
chip::Platform::ScopedMemoryBuffer<uint8_t> rcac;

chip::Credentials::SetDeviceAttestationCredentialsProvider(chip::Credentials::Examples::GetExampleDACProvider());
chip::Credentials::SetDeviceAttestationVerifier(chip::Credentials::GetDefaultDACVerifier());

// TODO: Replace testingRootStore with a PaaRootStore that has the necessary official PAA roots available
const chip::Credentials::PaaRootStore * testingRootStore = chip::Credentials::GetTestPaaRootStore();
chip::Credentials::SetDeviceAttestationVerifier(chip::Credentials::GetDefaultDACVerifier(testingRootStore));

VerifyOrReturnError(noc.Alloc(chip::Controller::kMaxCHIPDERCertLength), CHIP_ERROR_NO_MEMORY);
VerifyOrReturnError(icac.Alloc(chip::Controller::kMaxCHIPDERCertLength), CHIP_ERROR_NO_MEMORY);
Expand Down
4 changes: 3 additions & 1 deletion examples/platform/linux/AppMain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,9 @@ CHIP_ERROR InitCommissioner()
ReturnErrorOnFailure(gCommissioner.SetUdcListenPort(LinuxDeviceOptions::GetInstance().unsecuredCommissionerPort));

// Initialize device attestation verifier
SetDeviceAttestationVerifier(GetDefaultDACVerifier());
// TODO: Replace testingRootStore with a PaaRootStore that has the necessary official PAA roots available
const chip::Credentials::PaaRootStore * testingRootStore = chip::Credentials::GetTestPaaRootStore();
SetDeviceAttestationVerifier(GetDefaultDACVerifier(testingRootStore));

chip::Platform::ScopedMemoryBuffer<uint8_t> noc;
VerifyOrReturnError(noc.Alloc(chip::Controller::kMaxCHIPDERCertLength), CHIP_ERROR_NO_MEMORY);
Expand Down
4 changes: 3 additions & 1 deletion examples/tv-casting-app/linux/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,9 @@ int main(int argc, char * argv[])
SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider());

// Initialize device attestation verifier
SetDeviceAttestationVerifier(GetDefaultDACVerifier());
// TODO: Replace testingRootStore with a PaaRootStore that has the necessary official PAA roots available
const chip::Credentials::PaaRootStore * testingRootStore = chip::Credentials::GetTestPaaRootStore();
SetDeviceAttestationVerifier(GetDefaultDACVerifier(testingRootStore));

if (!chip::ArgParser::ParseArgs(argv[0], argc, argv, allOptions))
{
Expand Down
4 changes: 3 additions & 1 deletion src/controller/java/AndroidDeviceControllerWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,9 @@ AndroidDeviceControllerWrapper * AndroidDeviceControllerWrapper::AllocateNew(Jav
wrapper->SetJavaObjectRef(vm, deviceControllerObj);

// Initialize device attestation verifier
SetDeviceAttestationVerifier(GetDefaultDACVerifier());
// TODO: Replace testingRootStore with a PaaRootStore that has the necessary official PAA roots available
const chip::Credentials::PaaRootStore * testingRootStore = chip::Credentials::GetTestPaaRootStore();
SetDeviceAttestationVerifier(GetDefaultDACVerifier(testingRootStore));

chip::Controller::FactoryInitParams initParams;
chip::Controller::SetupParams setupParams;
Expand Down
4 changes: 3 additions & 1 deletion src/controller/python/ChipDeviceController-ScriptBinding.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,9 @@ ChipError::StorageType pychip_DeviceController_NewDeviceController(chip::Control
}

// Initialize device attestation verifier
SetDeviceAttestationVerifier(GetDefaultDACVerifier());
// TODO: Replace testingRootStore with a PaaRootStore that has the necessary official PAA roots available
const chip::Credentials::PaaRootStore * testingRootStore = chip::Credentials::GetTestPaaRootStore();
SetDeviceAttestationVerifier(GetDefaultDACVerifier(testingRootStore));

CHIP_ERROR err = sOperationalCredentialsIssuer.Initialize(sStorageDelegate);
VerifyOrReturnError(err == CHIP_NO_ERROR, err.AsInteger());
Expand Down
4 changes: 3 additions & 1 deletion src/controller/python/chip/internal/CommissionerImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,9 @@ extern "C" chip::Controller::DeviceCommissioner * pychip_internal_Commissioner_N
commissionerParams.storageDelegate = &gServerStorage;

// Initialize device attestation verifier
chip::Credentials::SetDeviceAttestationVerifier(chip::Credentials::GetDefaultDACVerifier());
// TODO: Replace testingRootStore with a PaaRootStore that has the necessary official PAA roots available
const chip::Credentials::PaaRootStore * testingRootStore = chip::Credentials::GetTestPaaRootStore();
chip::Credentials::SetDeviceAttestationVerifier(chip::Credentials::GetDefaultDACVerifier(testingRootStore));

err = ephemeralKey.Initialize();
SuccessOrExit(err);
Expand Down
2 changes: 1 addition & 1 deletion src/credentials/CHIPCert.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
namespace chip {
namespace Credentials {

static constexpr uint32_t kKeyIdentifierLength = 20;
static constexpr uint32_t kKeyIdentifierLength = static_cast<uint32_t>(Crypto::kSubjectKeyIdentifierLength);
static constexpr uint32_t kChip32bitAttrUTF8Length = 8;
static constexpr uint32_t kChip64bitAttrUTF8Length = 16;
static constexpr uint16_t kX509NoWellDefinedExpirationDateYear = 9999;
Expand Down
74 changes: 74 additions & 0 deletions src/credentials/DeviceAttestationVerifier.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,80 @@ struct DeviceInfoForAttestation
uint16_t paaVendorId = VendorId::NotSpecified;
};

/**
* @brief Helper utility to model a PAA store.
*
* API is synchronous. Real commissioner implementations may entirely
* hide PAA lookup behind the DeviceAttestationVerifier and never use this
* interface at all. It is provided as a utility to help build DeviceAttestationVerifier
* implementations suitable for testing or examples.
*/
class PaaRootStore
{
public:
PaaRootStore() = default;
virtual ~PaaRootStore() = default;

// Not copyable
PaaRootStore(const PaaRootStore &) = delete;
PaaRootStore & operator=(const PaaRootStore &) = delete;

/**
* @brief Look-up a PAA cert by SKID
*
* The implementations of this interface must have access to a set of PAAs to trust.
*
* Interface is synchronous, and therefore this should not be used unless to expose a PAA
* store that is both fully local and quick to access.
*
* @param[in] skid Buffer containing the subject key identifier (SKID) of the PAA to look-up
* @param[inout] outPaaDerBuffer Buffer to receive the contents of the PAA root cert, if found.
* Size will be updated to match actual size.
*
* @returns CHIP_NO_ERROR on success, CHIP_INVALID_ARGUMENT if `skid` or `outPaaDerBuffer` arguments
* are not usable, CHIP_BUFFER_TOO_SMALL if certificate doesn't fit in `outPaaDerBuffer`
* span, CHIP_ERROR_CA_CERT_NOT_FOUND if no PAA found that matches `skid.
*
*/
virtual CHIP_ERROR GetProductAttestationAuthorityCert(const ByteSpan & skid, MutableByteSpan & outPaaDerBuffer) const = 0;
};

class ArrayPaaRootStore : public PaaRootStore
{
public:
explicit ArrayPaaRootStore(const ByteSpan *derCerts, size_t numCerts) : mDerCerts(derCerts), mNumCerts(numCerts) {}

CHIP_ERROR GetProductAttestationAuthorityCert(const ByteSpan & skid, MutableByteSpan & outPaaDerBuffer) const override
{
VerifyOrReturnError(!skid.empty() && (skid.data() != nullptr), CHIP_ERROR_INVALID_ARGUMENT);
VerifyOrReturnError(skid.size() == Crypto::kSubjectKeyIdentifierLength, CHIP_ERROR_INVALID_ARGUMENT);

size_t paaIdx;
ByteSpan candidate;

for (paaIdx = 0; paaIdx < mNumCerts; ++paaIdx)
{
uint8_t skidBuf[Crypto::kSubjectKeyIdentifierLength] = { 0 };
candidate = mDerCerts[paaIdx];
MutableByteSpan candidateSkidSpan{skidBuf};
VerifyOrReturnError(CHIP_NO_ERROR == Crypto::ExtractSKIDFromX509Cert(candidate, candidateSkidSpan), CHIP_ERROR_INTERNAL);

printf("data: %p, size: %zu\n", skid.data(), skid.size());
if (skid.data_equal(candidateSkidSpan))
{
// Found a match
return CopySpanToMutableSpan(candidate, outPaaDerBuffer);
}
}

return CHIP_ERROR_CA_CERT_NOT_FOUND;
}

protected:
const ByteSpan * mDerCerts;
size_t mNumCerts;
};

class DeviceAttestationVerifier
{
public:
Expand Down
124 changes: 60 additions & 64 deletions src/credentials/examples/DefaultDeviceAttestationVerifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,31 +34,21 @@ namespace Credentials {

namespace {

CHIP_ERROR GetProductAttestationAuthorityCert(const ByteSpan & skid, MutableByteSpan & outDacBuffer)
{
struct PAALookupTable
{
const uint8_t mPAACertificate[kMax_x509_Certificate_Length];
const uint8_t mSKID[kKeyIdentifierLength];
};

static PAALookupTable
sPAALookupTable[] = {
{ /*
credentials/test/attestation/Chip-Test-PAA-FFF1-Cert.pem
-----BEGIN CERTIFICATE-----
MIIBmTCCAT+gAwIBAgIIaDhPq7kZ/N8wCgYIKoZIzj0EAwIwHzEdMBsGA1UEAwwU
TWF0dGVyIFRlc3QgUEFBIEZGRjEwIBcNMjEwNjI4MTQyMzQzWhgPOTk5OTEyMzEy
MzU5NTlaMB8xHTAbBgNVBAMMFE1hdHRlciBUZXN0IFBBQSBGRkYxMFkwEwYHKoZI
zj0CAQYIKoZIzj0DAQcDQgAEG5isW7wR3GoXVaBbCsXha6AsRu5vwrvnb/fPbKeq
Tp/R15jcvvtP6uIl03c8kTSMwm1JMTHjCWMtXp7zHRLek6NjMGEwDwYDVR0TAQH/
BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFO8Y4OzUZgQ03w28kR7U
UhaZZoOfMB8GA1UdIwQYMBaAFO8Y4OzUZgQ03w28kR7UUhaZZoOfMAoGCCqGSM49
BAMCA0gAMEUCIQCn+l+nZv/3tf0VjNNPYl1IkSAOBYUO8SX23udWVPmXNgIgI7Ub
bkJTKCjbCZIDNwUNcPC2tyzNPLeB5nGsIl31Rys=
-----END CERTIFICATE-----
*/
{ 0x30, 0x82, 0x01, 0x99, 0x30, 0x82, 0x01, 0x3F, 0xA0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x08, 0x68, 0x38, 0x4F, 0xAB,
/*
credentials/test/attestation/Chip-Test-PAA-FFF1-Cert.pem
-----BEGIN CERTIFICATE-----
MIIBmTCCAT+gAwIBAgIIaDhPq7kZ/N8wCgYIKoZIzj0EAwIwHzEdMBsGA1UEAwwU
TWF0dGVyIFRlc3QgUEFBIEZGRjEwIBcNMjEwNjI4MTQyMzQzWhgPOTk5OTEyMzEy
MzU5NTlaMB8xHTAbBgNVBAMMFE1hdHRlciBUZXN0IFBBQSBGRkYxMFkwEwYHKoZI
zj0CAQYIKoZIzj0DAQcDQgAEG5isW7wR3GoXVaBbCsXha6AsRu5vwrvnb/fPbKeq
Tp/R15jcvvtP6uIl03c8kTSMwm1JMTHjCWMtXp7zHRLek6NjMGEwDwYDVR0TAQH/
BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFO8Y4OzUZgQ03w28kR7U
UhaZZoOfMB8GA1UdIwQYMBaAFO8Y4OzUZgQ03w28kR7UUhaZZoOfMAoGCCqGSM49
BAMCA0gAMEUCIQCn+l+nZv/3tf0VjNNPYl1IkSAOBYUO8SX23udWVPmXNgIgI7Ub
bkJTKCjbCZIDNwUNcPC2tyzNPLeB5nGsIl31Rys=
-----END CERTIFICATE-----
*/
const uint8_t kChipTestPaaFff1[] = { 0x30, 0x82, 0x01, 0x99, 0x30, 0x82, 0x01, 0x3F, 0xA0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x08, 0x68, 0x38, 0x4F, 0xAB,
0xB9, 0x19, 0xFC, 0xDF, 0x30, 0x0A, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x02, 0x30, 0x1F, 0x31,
0x1D, 0x30, 0x1B, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x14, 0x4D, 0x61, 0x74, 0x74, 0x65, 0x72, 0x20, 0x54, 0x65,
0x73, 0x74, 0x20, 0x50, 0x41, 0x41, 0x20, 0x46, 0x46, 0x46, 0x31, 0x30, 0x20, 0x17, 0x0D, 0x32, 0x31, 0x30, 0x36,
Expand All @@ -79,24 +69,23 @@ CHIP_ERROR GetProductAttestationAuthorityCert(const ByteSpan & skid, MutableByte
0x30, 0x45, 0x02, 0x21, 0x00, 0xA7, 0xFA, 0x5F, 0xA7, 0x66, 0xFF, 0xF7, 0xB5, 0xFD, 0x15, 0x8C, 0xD3, 0x4F, 0x62,
0x5D, 0x48, 0x91, 0x20, 0x0E, 0x05, 0x85, 0x0E, 0xF1, 0x25, 0xF6, 0xDE, 0xE7, 0x56, 0x54, 0xF9, 0x97, 0x36, 0x02,
0x20, 0x23, 0xB5, 0x1B, 0x6E, 0x42, 0x53, 0x28, 0x28, 0xDB, 0x09, 0x92, 0x03, 0x37, 0x05, 0x0D, 0x70, 0xF0, 0xB6,
0xB7, 0x2C, 0xCD, 0x3C, 0xB7, 0x81, 0xE6, 0x71, 0xAC, 0x22, 0x5D, 0xF5, 0x47, 0x2B },
{ 0xEF, 0x18, 0xE0, 0xEC, 0xD4, 0x66, 0x04, 0x34, 0xDF, 0x0D,
0xBC, 0x91, 0x1E, 0xD4, 0x52, 0x16, 0x99, 0x66, 0x83, 0x9F } },
{ /*
credentials/test/attestation/Chip-Test-PAA-FFF2-Cert.pem
-----BEGIN CERTIFICATE-----
MIIBnTCCAUKgAwIBAgIIA5KnZVo+bHcwCgYIKoZIzj0EAwIwHzEdMBsGA1UEAwwU
TWF0dGVyIFRlc3QgUEFBIEZGRjIwIBcNMjEwNjI4MTQyMzQzWhgPOTk5OTEyMzEy
MzU5NTlaMB8xHTAbBgNVBAMMFE1hdHRlciBUZXN0IFBBQSBGRkYyMFkwEwYHKoZI
zj0CAQYIKoZIzj0DAQcDQgAEdW4YkvnpULAOlQqilfM1sEhLh20i4m+WZZLKweUQ
1f6Zsx1cmIgWeorWUDd+dRD7dYI8fluYuMAG7F8Gz66FSqNmMGQwEgYDVR0TAQH/
BAgwBgEB/wIBATAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFOfv6sMzXF/Qw+Y0
Up8WcEbEvKVcMB8GA1UdIwQYMBaAFOfv6sMzXF/Qw+Y0Up8WcEbEvKVcMAoGCCqG
SM49BAMCA0kAMEYCIQCSUQ0dYCFfARvaLqeV/ssklO+QppeHrQr8IGxhjAnMUgIh
AKA2sK+D40VcCTi5S/9HdRlyuNy+cZyfYbVW7LTqF8xX
-----END CERTIFICATE-----
*/
{ 0x30, 0x82, 0x01, 0x9D, 0x30, 0x82, 0x01, 0x42, 0xA0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x08, 0x03, 0x92, 0xA7, 0x65,
0xB7, 0x2C, 0xCD, 0x3C, 0xB7, 0x81, 0xE6, 0x71, 0xAC, 0x22, 0x5D, 0xF5, 0x47, 0x2B };

/*
credentials/test/attestation/Chip-Test-PAA-FFF2-Cert.pem
-----BEGIN CERTIFICATE-----
MIIBnTCCAUKgAwIBAgIIA5KnZVo+bHcwCgYIKoZIzj0EAwIwHzEdMBsGA1UEAwwU
TWF0dGVyIFRlc3QgUEFBIEZGRjIwIBcNMjEwNjI4MTQyMzQzWhgPOTk5OTEyMzEy
MzU5NTlaMB8xHTAbBgNVBAMMFE1hdHRlciBUZXN0IFBBQSBGRkYyMFkwEwYHKoZI
zj0CAQYIKoZIzj0DAQcDQgAEdW4YkvnpULAOlQqilfM1sEhLh20i4m+WZZLKweUQ
1f6Zsx1cmIgWeorWUDd+dRD7dYI8fluYuMAG7F8Gz66FSqNmMGQwEgYDVR0TAQH/
BAgwBgEB/wIBATAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFOfv6sMzXF/Qw+Y0
Up8WcEbEvKVcMB8GA1UdIwQYMBaAFOfv6sMzXF/Qw+Y0Up8WcEbEvKVcMAoGCCqG
SM49BAMCA0kAMEYCIQCSUQ0dYCFfARvaLqeV/ssklO+QppeHrQr8IGxhjAnMUgIh
AKA2sK+D40VcCTi5S/9HdRlyuNy+cZyfYbVW7LTqF8xX
-----END CERTIFICATE-----
*/
const uint8_t kChipTestPaaFff2[] = { 0x30, 0x82, 0x01, 0x9D, 0x30, 0x82, 0x01, 0x42, 0xA0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x08, 0x03, 0x92, 0xA7, 0x65,
0x5A, 0x3E, 0x6C, 0x77, 0x30, 0x0A, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x02, 0x30, 0x1F, 0x31,
0x1D, 0x30, 0x1B, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x14, 0x4D, 0x61, 0x74, 0x74, 0x65, 0x72, 0x20, 0x54, 0x65,
0x73, 0x74, 0x20, 0x50, 0x41, 0x41, 0x20, 0x46, 0x46, 0x46, 0x32, 0x30, 0x20, 0x17, 0x0D, 0x32, 0x31, 0x30, 0x36,
Expand All @@ -117,31 +106,26 @@ CHIP_ERROR GetProductAttestationAuthorityCert(const ByteSpan & skid, MutableByte
0x03, 0x49, 0x00, 0x30, 0x46, 0x02, 0x21, 0x00, 0x92, 0x51, 0x0D, 0x1D, 0x60, 0x21, 0x5F, 0x01, 0x1B, 0xDA, 0x2E,
0xA7, 0x95, 0xFE, 0xCB, 0x24, 0x94, 0xEF, 0x90, 0xA6, 0x97, 0x87, 0xAD, 0x0A, 0xFC, 0x20, 0x6C, 0x61, 0x8C, 0x09,
0xCC, 0x52, 0x02, 0x21, 0x00, 0xA0, 0x36, 0xB0, 0xAF, 0x83, 0xE3, 0x45, 0x5C, 0x09, 0x38, 0xB9, 0x4B, 0xFF, 0x47,
0x75, 0x19, 0x72, 0xB8, 0xDC, 0xBE, 0x71, 0x9C, 0x9F, 0x61, 0xB5, 0x56, 0xEC, 0xB4, 0xEA, 0x17, 0xCC, 0x57 },
{ 0xE7, 0xEF, 0xEA, 0xC3, 0x33, 0x5C, 0x5F, 0xD0, 0xC3, 0xE6,
0x34, 0x52, 0x9F, 0x16, 0x70, 0x46, 0xC4, 0xBC, 0xA5, 0x5C } },
};

size_t paaLookupTableIdx;
for (paaLookupTableIdx = 0; paaLookupTableIdx < ArraySize(sPAALookupTable); ++paaLookupTableIdx)
{
if (skid.data_equal(ByteSpan(sPAALookupTable[paaLookupTableIdx].mSKID)))
{
break;
}
}
0x75, 0x19, 0x72, 0xB8, 0xDC, 0xBE, 0x71, 0x9C, 0x9F, 0x61, 0xB5, 0x56, 0xEC, 0xB4, 0xEA, 0x17, 0xCC, 0x57 };

VerifyOrReturnError(paaLookupTableIdx < ArraySize(sPAALookupTable), CHIP_ERROR_INVALID_ARGUMENT);
const ByteSpan kTestPaaRoots[] = {
ByteSpan{kChipTestPaaFff1},
ByteSpan{kChipTestPaaFff2},
};

return CopySpanToMutableSpan(ByteSpan{ sPAALookupTable[paaLookupTableIdx].mPAACertificate }, outDacBuffer);
}
const ArrayPaaRootStore kTestPaaRootStore{&kTestPaaRoots[0], ArraySize(kTestPaaRoots)};

/**
* @brief Look-up of well-known keys used for CD signing by CSA.
*
* Current version uses only test key/cert provided in spec.
*/
CHIP_ERROR GetCertificationDeclarationCertificate(const ByteSpan & skid, MutableByteSpan & outCertificate)
{
struct CertChainLookupTable
{
const uint8_t mCertificate[kMax_x509_Certificate_Length];
const uint8_t mSKID[kKeyIdentifierLength];
const uint8_t mSKID[Crypto::kSubjectKeyIdentifierLength];
};

static CertChainLookupTable
Expand Down Expand Up @@ -191,6 +175,8 @@ CHIP_ERROR GetCertificationDeclarationCertificate(const ByteSpan & skid, Mutable
class DefaultDACVerifier : public DeviceAttestationVerifier
{
public:
DefaultDACVerifier(const PaaRootStore *paaRootStore) : mPaaRootStore(paaRootStore) {}

AttestationVerificationResult VerifyAttestationInformation(const ByteSpan & attestationInfoBuffer,
const ByteSpan & attestationChallengeBuffer,
const ByteSpan & attestationSignatureBuffer,
Expand All @@ -203,6 +189,11 @@ class DefaultDACVerifier : public DeviceAttestationVerifier
AttestationVerificationResult ValidateCertificateDeclarationPayload(const ByteSpan & certDeclBuffer,
const ByteSpan & firmwareInfo,
const DeviceInfoForAttestation & deviceInfo) override;

protected:
DefaultDACVerifier() {}

const PaaRootStore * mPaaRootStore;
};

AttestationVerificationResult DefaultDACVerifier::VerifyAttestationInformation(const ByteSpan & attestationInfoBuffer,
Expand Down Expand Up @@ -246,15 +237,15 @@ AttestationVerificationResult DefaultDACVerifier::VerifyAttestationInformation(c
deviceSignature) == CHIP_NO_ERROR,
AttestationVerificationResult::kAttestationSignatureInvalid);

uint8_t akidBuf[Credentials::kKeyIdentifierLength];
uint8_t akidBuf[Crypto::kAuthorityKeyIdentifierLength];
MutableByteSpan akid(akidBuf);
ExtractAKIDFromX509Cert(paiCertDerBuffer, akid);

constexpr size_t paaCertAllocatedLen = kMaxDERCertLength;
chip::Platform::ScopedMemoryBuffer<uint8_t> paaCert;
VerifyOrReturnError(paaCert.Alloc(paaCertAllocatedLen), AttestationVerificationResult::kNoMemory);
MutableByteSpan paa(paaCert.Get(), paaCertAllocatedLen);
VerifyOrReturnError(GetProductAttestationAuthorityCert(akid, paa) == CHIP_NO_ERROR,
VerifyOrReturnError(mPaaRootStore->GetProductAttestationAuthorityCert(akid, paa) == CHIP_NO_ERROR,
AttestationVerificationResult::kPaaNotFound);

VerifyOrReturnError(ValidateCertificateChain(paa.data(), paa.size(), paiCertDerBuffer.data(), paiCertDerBuffer.size(),
Expand Down Expand Up @@ -397,9 +388,14 @@ AttestationVerificationResult DefaultDACVerifier::ValidateCertificateDeclaration

} // namespace

DeviceAttestationVerifier * GetDefaultDACVerifier()
const PaaRootStore * GetTestPaaRootStore()
{
return &kTestPaaRootStore;
}

DeviceAttestationVerifier * GetDefaultDACVerifier(const PaaRootStore * paaRootStore)
{
static DefaultDACVerifier defaultDACVerifier;
static DefaultDACVerifier defaultDACVerifier{paaRootStore};

return &defaultDACVerifier;
}
Expand Down
22 changes: 19 additions & 3 deletions src/credentials/examples/DefaultDeviceAttestationVerifier.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,30 @@
namespace chip {
namespace Credentials {

/**
* @brief Get implementation of a PAA root store containing a basic set of static PAA roots
* sufficient for *testing* only.
*
* WARNING: The PAA list known to this PAA root store is a reduced subset that will likely
* cause users of it to fail attestation procedure in some cases. This is provided
* to support tests and examples, not to be used by real commissioners, as it
* contains several test roots which are not trustworthy for certified product usage.
*
* @returns a singleton PaaRootStore that contains some well-known PAA test root certs.
*/
const PaaRootStore * GetTestPaaRootStore();

/**
* @brief Get implementation of a sample DAC verifier to validate device
* attestation procedure.
*
* @returns a singleton DeviceAttestationVerifier that relies on no
* storage abstractions.
* @param[in] paaRootStore Pointer to the PaaRootStore instance to be used by implementation
* of default DeviceAttestationVerifier. Caller must ensure storage is
* always available while the DeviceAttestationVerifier could be used.
*
* @returns a singleton DeviceAttestationVerifier that satisfies basic device attestation procedure requirements.
*/
DeviceAttestationVerifier * GetDefaultDACVerifier();
DeviceAttestationVerifier * GetDefaultDACVerifier(const PaaRootStore * paaRootStore);

} // namespace Credentials
} // namespace chip
Loading

0 comments on commit 83591d7

Please sign in to comment.