diff --git a/src/credentials/attestation_verifier/DefaultDeviceAttestationVerifier.cpp b/src/credentials/attestation_verifier/DefaultDeviceAttestationVerifier.cpp index 708a723d58411b..2966fb4b047420 100644 --- a/src/credentials/attestation_verifier/DefaultDeviceAttestationVerifier.cpp +++ b/src/credentials/attestation_verifier/DefaultDeviceAttestationVerifier.cpp @@ -172,6 +172,7 @@ void DefaultDACVerifier::VerifyAttestationInformation(const DeviceAttestationVer uint8_t akidBuf[Crypto::kAuthorityKeyIdentifierLength]; MutableByteSpan akid(akidBuf); constexpr size_t paaCertAllocatedLen = kMaxDERCertLength; + CHIP_ERROR err = CHIP_NO_ERROR; VerifyOrExit(ExtractAKIDFromX509Cert(info.paiDerBuffer, akid) == CHIP_NO_ERROR, attestationError = AttestationVerificationResult::kPaiFormatInvalid); @@ -179,9 +180,16 @@ void DefaultDACVerifier::VerifyAttestationInformation(const DeviceAttestationVer VerifyOrExit(paaCert.Alloc(paaCertAllocatedLen), attestationError = AttestationVerificationResult::kNoMemory); paaDerBuffer = MutableByteSpan(paaCert.Get(), paaCertAllocatedLen); - VerifyOrExit(mAttestationTrustStore->GetProductAttestationAuthorityCert(akid, paaDerBuffer) == CHIP_NO_ERROR, + err = mAttestationTrustStore->GetProductAttestationAuthorityCert(akid, paaDerBuffer); + VerifyOrExit(err == CHIP_NO_ERROR || err == CHIP_ERROR_NOT_IMPLEMENTED, attestationError = AttestationVerificationResult::kPaaNotFound); + if (err == CHIP_ERROR_NOT_IMPLEMENTED) + { + VerifyOrExit(kTestAttestationTrustStore.GetProductAttestationAuthorityCert(akid, paaDerBuffer) == CHIP_NO_ERROR, + attestationError = AttestationVerificationResult::kPaaNotFound); + } + VerifyOrExit(ExtractVIDPIDFromX509Cert(paaDerBuffer, paaVidPid) == CHIP_NO_ERROR, attestationError = AttestationVerificationResult::kPaaFormatInvalid); diff --git a/src/credentials/attestation_verifier/FileAttestationTrustStore.cpp b/src/credentials/attestation_verifier/FileAttestationTrustStore.cpp index 922f2c9521de0a..714344b1626165 100644 --- a/src/credentials/attestation_verifier/FileAttestationTrustStore.cpp +++ b/src/credentials/attestation_verifier/FileAttestationTrustStore.cpp @@ -39,11 +39,31 @@ const char * GetFilenameExtension(const char * filename) } } // namespace -FileAttestationTrustStore::FileAttestationTrustStore(const char * paaTrustStorePath) +FileAttestationTrustStore::FileAttestationTrustStore(const char * paaTrustStorePath, const char * cdTrustStorePath) +{ + VerifyOrReturn(paaTrustStorePath != nullptr || cdTrustStorePath != nullptr); + + if (paaTrustStorePath != nullptr) + { + LoadTrustStore(paaTrustStorePath, mPAADerCerts); + VerifyOrReturn(paaCount()); + } + + if (cdTrustStorePath != nullptr) + { + LoadTrustStore(cdTrustStorePath, mCDDerCerts); + VerifyOrReturn(cdCount()); + } + + mIsInitialized = true; +} + +void FileAttestationTrustStore::LoadTrustStore(const char * trustStorePath, + std::vector> & certs) { DIR * dir; - dir = opendir(paaTrustStorePath); + dir = opendir(trustStorePath); if (dir != nullptr) { // Nested directories are not handled. @@ -56,7 +76,7 @@ FileAttestationTrustStore::FileAttestationTrustStore(const char * paaTrustStoreP FILE * file; std::array certificate; - std::string filename(paaTrustStorePath); + std::string filename(trustStorePath); filename += std::string("/") + std::string(entry->d_name); @@ -66,14 +86,13 @@ FileAttestationTrustStore::FileAttestationTrustStore(const char * paaTrustStoreP uint32_t certificateLength = fread(certificate.data(), sizeof(uint8_t), kMaxDERCertLength, file); if (certificateLength > 0) { - mDerCerts.push_back(certificate); - mIsInitialized = true; + certs.push_back(certificate); } fclose(file); } else { - Cleanup(); + certs.clear(); break; } } @@ -89,18 +108,26 @@ FileAttestationTrustStore::~FileAttestationTrustStore() void FileAttestationTrustStore::Cleanup() { - mDerCerts.clear(); + mPAADerCerts.clear(); + mCDDerCerts.clear(); mIsInitialized = false; } CHIP_ERROR FileAttestationTrustStore::GetProductAttestationAuthorityCert(const ByteSpan & skid, MutableByteSpan & outPaaDerBuffer) const { - VerifyOrReturnError(!mDerCerts.empty(), CHIP_ERROR_CA_CERT_NOT_FOUND); + // If the constructor has not tried to initialize the PAA certificates database, return CHIP_ERROR_NOT_IMPLEMENTED to use the + // testing trust store if the DefaultAttestationVerifier is in use. + if (mIsInitialized && paaCount() == 0) + { + return CHIP_ERROR_NOT_IMPLEMENTED; + } + + VerifyOrReturnError(!mPAADerCerts.empty(), CHIP_ERROR_CA_CERT_NOT_FOUND); VerifyOrReturnError(!skid.empty() && (skid.data() != nullptr), CHIP_ERROR_INVALID_ARGUMENT); VerifyOrReturnError(skid.size() == Crypto::kSubjectKeyIdentifierLength, CHIP_ERROR_INVALID_ARGUMENT); - for (auto candidate : mDerCerts) + for (auto candidate : mPAADerCerts) { uint8_t skidBuf[Crypto::kSubjectKeyIdentifierLength] = { 0 }; MutableByteSpan candidateSkidSpan{ skidBuf }; @@ -118,5 +145,37 @@ CHIP_ERROR FileAttestationTrustStore::GetProductAttestationAuthorityCert(const B return CHIP_ERROR_CA_CERT_NOT_FOUND; } +CHIP_ERROR FileAttestationTrustStore::GetCertificationDeclarationSigningKey(const ByteSpan & skid, + Crypto::P256PublicKey & pubKey) const +{ + // If the constructor has not tried to initialize the certification declaration certificates database, return + // CHIP_ERROR_NOT_IMPLEMENTED to use the testing trust store if the DefaultAttestationVerifier is in use. + if (mIsInitialized && cdCount() == 0) + { + return CHIP_ERROR_NOT_IMPLEMENTED; + } + + VerifyOrReturnError(!mCDDerCerts.empty(), CHIP_ERROR_CA_CERT_NOT_FOUND); + VerifyOrReturnError(!skid.empty() && (skid.data() != nullptr), CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(skid.size() == Crypto::kSubjectKeyIdentifierLength, CHIP_ERROR_INVALID_ARGUMENT); + + for (auto candidate : mCDDerCerts) + { + uint8_t skidBuf[Crypto::kSubjectKeyIdentifierLength] = { 0 }; + MutableByteSpan candidateSkidSpan{ skidBuf }; + VerifyOrReturnError(CHIP_NO_ERROR == + Crypto::ExtractSKIDFromX509Cert(ByteSpan{ candidate.data(), candidate.size() }, candidateSkidSpan), + CHIP_ERROR_INTERNAL); + + if (skid.data_equal(candidateSkidSpan)) + { + // Found a match + return Crypto::ExtractPubkeyFromX509Cert(ByteSpan{ candidate.data(), candidate.size() }, pubKey); + } + } + + return CHIP_ERROR_CA_CERT_NOT_FOUND; +} + } // namespace Credentials } // namespace chip diff --git a/src/credentials/attestation_verifier/FileAttestationTrustStore.h b/src/credentials/attestation_verifier/FileAttestationTrustStore.h index 090be169367c63..c78d56b6353219 100644 --- a/src/credentials/attestation_verifier/FileAttestationTrustStore.h +++ b/src/credentials/attestation_verifier/FileAttestationTrustStore.h @@ -28,18 +28,23 @@ namespace Credentials { class FileAttestationTrustStore : public AttestationTrustStore { public: - FileAttestationTrustStore(const char * paaTrustStorePath); + FileAttestationTrustStore(const char * paaTrustStorePath = nullptr, const char * cdTrustStoreKey = nullptr); ~FileAttestationTrustStore(); - bool IsInitialized() { return mIsInitialized; } - CHIP_ERROR GetProductAttestationAuthorityCert(const ByteSpan & skid, MutableByteSpan & outPaaDerBuffer) const override; - size_t size() const { return mDerCerts.size(); } + CHIP_ERROR GetCertificationDeclarationSigningKey(const ByteSpan & skid, Crypto::P256PublicKey & pubKey) const override; + + bool IsInitialized() const { return mIsInitialized; } + size_t paaCount() const { return mPAADerCerts.size(); }; + size_t cdCount() const { return mCDDerCerts.size(); }; protected: - std::vector> mDerCerts; + std::vector> mPAADerCerts; + std::vector> mCDDerCerts; private: + void LoadTrustStore(const char * trustStorePath, std::vector> & certs); + bool mIsInitialized = false; void Cleanup();