Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

da_revocation: option to load test data from the test without using file #36759

Merged
merged 3 commits into from
Dec 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,23 @@ CHIP_ERROR TestDACRevocationDelegateImpl::SetDeviceAttestationRevocationSetPath(
return CHIP_NO_ERROR;
}

CHIP_ERROR TestDACRevocationDelegateImpl::SetDeviceAttestationRevocationData(const std::string & jsonData)
{
mRevocationData = jsonData;
return CHIP_NO_ERROR;
}

void TestDACRevocationDelegateImpl::ClearDeviceAttestationRevocationSetPath()
{
// clear the string_view
mDeviceAttestationRevocationSetPath = mDeviceAttestationRevocationSetPath.substr(0, 0);
}

void TestDACRevocationDelegateImpl::ClearDeviceAttestationRevocationData()
{
mRevocationData.clear();
}

// Check if issuer and AKID matches with the crl signer OR crl signer delegator's subject and SKID
bool TestDACRevocationDelegateImpl::CrossValidateCert(const Json::Value & revokedSet, const std::string & akidHexStr,
const std::string & issuerNameBase64Str)
Expand Down Expand Up @@ -115,26 +126,42 @@ bool TestDACRevocationDelegateImpl::CrossValidateCert(const Json::Value & revoke
bool TestDACRevocationDelegateImpl::IsEntryInRevocationSet(const std::string & akidHexStr, const std::string & issuerNameBase64Str,
const std::string & serialNumberHexStr)
{
std::ifstream file(mDeviceAttestationRevocationSetPath.c_str());
if (!file.is_open())
{
ChipLogError(NotSpecified, "Failed to open file: %s", mDeviceAttestationRevocationSetPath.c_str());
return false;
}

// Parse the JSON data incrementally
Json::CharReaderBuilder readerBuilder;
Json::Value jsonData;
std::string errs;

bool parsingSuccessful = Json::parseFromStream(readerBuilder, file, &jsonData, &errs);
// Try direct data first, then fall back to file
if (!mRevocationData.empty())
{
std::string errs;
std::istringstream jsonStream(!mRevocationData.empty() ? mRevocationData : "[]");
if (!Json::parseFromStream(Json::CharReaderBuilder(), jsonStream, &jsonData, &errs))
{
ChipLogError(NotSpecified, "Failed to parse JSON data: %s", errs.c_str());
return false;
}
}
else if (!mDeviceAttestationRevocationSetPath.empty())
{
std::string errs;
std::ifstream file(mDeviceAttestationRevocationSetPath.c_str());
if (!file.is_open())
{
ChipLogError(NotSpecified, "Failed to open file: %s", mDeviceAttestationRevocationSetPath.c_str());
return false;
}

// Close the file as it's no longer needed
file.close();
bool parsingSuccessful = Json::parseFromStream(Json::CharReaderBuilder(), file, &jsonData, &errs);
file.close();

if (!parsingSuccessful)
if (!parsingSuccessful)
{
ChipLogError(NotSpecified, "Failed to parse JSON from file: %s", errs.c_str());
return false;
}
}
else
{
ChipLogError(NotSpecified, "Failed to parse JSON: %s", errs.c_str());
ChipLogDetail(NotSpecified, "No revocation data available");
// No revocation data available
return false;
}

Expand Down Expand Up @@ -278,7 +305,7 @@ void TestDACRevocationDelegateImpl::CheckForRevokedDACChain(
{
AttestationVerificationResult attestationError = AttestationVerificationResult::kSuccess;

if (mDeviceAttestationRevocationSetPath.empty())
if (mDeviceAttestationRevocationSetPath.empty() && mRevocationData.empty())
{
onCompletion->mCall(onCompletion->mContext, info, attestationError);
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ class TestDACRevocationDelegateImpl : public DeviceAttestationRevocationDelegate
// This can be used to skip the revocation check
void ClearDeviceAttestationRevocationSetPath();

// Set JSON data directly for unit test purposes.
CHIP_ERROR SetDeviceAttestationRevocationData(const std::string & jsonData);
void ClearDeviceAttestationRevocationData();

private:
enum class KeyIdType : uint8_t
{
Expand Down Expand Up @@ -83,6 +87,7 @@ class TestDACRevocationDelegateImpl : public DeviceAttestationRevocationDelegate
bool IsCertificateRevoked(const ByteSpan & certDer);

std::string mDeviceAttestationRevocationSetPath;
std::string mRevocationData; // Stores direct JSON data
};

} // namespace Credentials
Expand Down
49 changes: 23 additions & 26 deletions src/credentials/tests/TestDeviceAttestationCredentials.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -417,17 +417,6 @@ TEST_F(TestDeviceAttestationCredentials, TestAttestationTrustStore)
}
}

static void WriteTestRevokedData(const char * jsonData, const char * fileName)
{
// TODO: Add option to load test data from the test without using file. #34588

// write data to /tmp/sample_revoked_set.json using fstream APIs
std::ofstream file;
file.open(fileName, std::ofstream::out | std::ofstream::trunc);
file << jsonData;
file.close();
}

TEST_F(TestDeviceAttestationCredentials, TestDACRevocationDelegateImpl)
{
uint8_t attestationElementsTestVector[] = { 0 };
Expand Down Expand Up @@ -456,16 +445,14 @@ TEST_F(TestDeviceAttestationCredentials, TestDACRevocationDelegateImpl)

TestDACRevocationDelegateImpl revocationDelegateImpl;

// Test without revocation set
// Test without revocation data
revocationDelegateImpl.CheckForRevokedDACChain(info, &attestationInformationVerificationCallback);
EXPECT_EQ(attestationResult, AttestationVerificationResult::kSuccess);

const char * tmpJsonFile = "/tmp/sample_revoked_set.json";
revocationDelegateImpl.SetDeviceAttestationRevocationSetPath(tmpJsonFile);

// Test empty json
WriteTestRevokedData("", tmpJsonFile);
revocationDelegateImpl.SetDeviceAttestationRevocationData("");
revocationDelegateImpl.CheckForRevokedDACChain(info, &attestationInformationVerificationCallback);
revocationDelegateImpl.ClearDeviceAttestationRevocationData();
EXPECT_EQ(attestationResult, AttestationVerificationResult::kSuccess);

// Test DAC is revoked, crl signer is PAI itself
Expand All @@ -478,8 +465,9 @@ TEST_F(TestDeviceAttestationCredentials, TestDACRevocationDelegateImpl)
"revoked_serial_numbers": ["0C694F7F866067B2"]
}]
)";
WriteTestRevokedData(jsonData, tmpJsonFile);
revocationDelegateImpl.SetDeviceAttestationRevocationData(jsonData);
revocationDelegateImpl.CheckForRevokedDACChain(info, &attestationInformationVerificationCallback);
revocationDelegateImpl.ClearDeviceAttestationRevocationData();
EXPECT_EQ(attestationResult, AttestationVerificationResult::kDacRevoked);

// Test PAI is revoked, crl signer is PAA itself
Expand All @@ -492,8 +480,9 @@ TEST_F(TestDeviceAttestationCredentials, TestDACRevocationDelegateImpl)
"revoked_serial_numbers": ["3E6CE6509AD840CD"]
}]
)";
WriteTestRevokedData(jsonData, tmpJsonFile);
revocationDelegateImpl.SetDeviceAttestationRevocationData(jsonData);
revocationDelegateImpl.CheckForRevokedDACChain(info, &attestationInformationVerificationCallback);
revocationDelegateImpl.ClearDeviceAttestationRevocationData();
EXPECT_EQ(attestationResult, AttestationVerificationResult::kPaiRevoked);

// Test DAC and PAI both revoked, crl signers are PAI and PAA respectively
Expand All @@ -513,7 +502,7 @@ TEST_F(TestDeviceAttestationCredentials, TestDACRevocationDelegateImpl)
"revoked_serial_numbers": ["3E6CE6509AD840CD"]
}]
)";
WriteTestRevokedData(jsonData, tmpJsonFile);
revocationDelegateImpl.SetDeviceAttestationRevocationData(jsonData);
revocationDelegateImpl.CheckForRevokedDACChain(info, &attestationInformationVerificationCallback);
EXPECT_EQ(attestationResult, AttestationVerificationResult::kPaiAndDacRevoked);

Expand All @@ -523,6 +512,7 @@ TEST_F(TestDeviceAttestationCredentials, TestDACRevocationDelegateImpl)
TestCerts::sTestCert_PAI_FFF2_8001_Cert, TestCerts::sTestCert_DAC_FFF2_8001_0008_Cert, ByteSpan(attestationNonceTestVector),
static_cast<VendorId>(0xFFF2), 0x8001);
revocationDelegateImpl.CheckForRevokedDACChain(FFF2_8001_info, &attestationInformationVerificationCallback);
revocationDelegateImpl.ClearDeviceAttestationRevocationData();
EXPECT_EQ(attestationResult, AttestationVerificationResult::kSuccess);

// Test issuer does not match
Expand All @@ -536,8 +526,9 @@ TEST_F(TestDeviceAttestationCredentials, TestDACRevocationDelegateImpl)
"revoked_serial_numbers": ["0C694F7F866067B2"]
}]
)";
WriteTestRevokedData(jsonData, tmpJsonFile);
revocationDelegateImpl.SetDeviceAttestationRevocationData(jsonData);
revocationDelegateImpl.CheckForRevokedDACChain(info, &attestationInformationVerificationCallback);
revocationDelegateImpl.ClearDeviceAttestationRevocationData();
EXPECT_EQ(attestationResult, AttestationVerificationResult::kSuccess);

// Test subject key ID does not match
Expand All @@ -551,8 +542,9 @@ TEST_F(TestDeviceAttestationCredentials, TestDACRevocationDelegateImpl)
"revoked_serial_numbers": ["0C694F7F866067B2"]
}]
)";
WriteTestRevokedData(jsonData, tmpJsonFile);
revocationDelegateImpl.SetDeviceAttestationRevocationData(jsonData);
revocationDelegateImpl.CheckForRevokedDACChain(info, &attestationInformationVerificationCallback);
revocationDelegateImpl.ClearDeviceAttestationRevocationData();
EXPECT_EQ(attestationResult, AttestationVerificationResult::kSuccess);

// Test serial number does not match
Expand All @@ -566,8 +558,9 @@ TEST_F(TestDeviceAttestationCredentials, TestDACRevocationDelegateImpl)
"revoked_serial_numbers": ["3E6CE6509AD840CD1", "BC694F7F866067B1"]
}]
)";
WriteTestRevokedData(jsonData, tmpJsonFile);
revocationDelegateImpl.SetDeviceAttestationRevocationData(jsonData);
revocationDelegateImpl.CheckForRevokedDACChain(info, &attestationInformationVerificationCallback);
revocationDelegateImpl.ClearDeviceAttestationRevocationData();
EXPECT_EQ(attestationResult, AttestationVerificationResult::kSuccess);

// Test starting serial number bytes match but not all,
Expand All @@ -581,8 +574,9 @@ TEST_F(TestDeviceAttestationCredentials, TestDACRevocationDelegateImpl)
"revoked_serial_numbers": ["0C694F7F866067B21234"]
}]
)";
WriteTestRevokedData(jsonData, tmpJsonFile);
revocationDelegateImpl.SetDeviceAttestationRevocationData(jsonData);
revocationDelegateImpl.CheckForRevokedDACChain(info, &attestationInformationVerificationCallback);
revocationDelegateImpl.ClearDeviceAttestationRevocationData();
EXPECT_EQ(attestationResult, AttestationVerificationResult::kSuccess);

// Test DAC is revoked, and crl signer delegator is present
Expand All @@ -597,8 +591,9 @@ TEST_F(TestDeviceAttestationCredentials, TestDACRevocationDelegateImpl)
"revoked_serial_numbers": ["0C694F7F866067B2"]
}]
)";
WriteTestRevokedData(jsonData, tmpJsonFile);
revocationDelegateImpl.SetDeviceAttestationRevocationData(jsonData);
revocationDelegateImpl.CheckForRevokedDACChain(info, &attestationInformationVerificationCallback);
revocationDelegateImpl.ClearDeviceAttestationRevocationData();
EXPECT_EQ(attestationResult, AttestationVerificationResult::kDacRevoked);

// Test with invalid crl signer cert missing begin and end cert markers
Expand All @@ -612,8 +607,9 @@ TEST_F(TestDeviceAttestationCredentials, TestDACRevocationDelegateImpl)
}]
)";

WriteTestRevokedData(jsonData, tmpJsonFile);
revocationDelegateImpl.SetDeviceAttestationRevocationData(jsonData);
revocationDelegateImpl.CheckForRevokedDACChain(info, &attestationInformationVerificationCallback);
revocationDelegateImpl.ClearDeviceAttestationRevocationData();
EXPECT_EQ(attestationResult, AttestationVerificationResult::kSuccess);

// test with malformed crl signer certificate
Expand All @@ -627,7 +623,8 @@ TEST_F(TestDeviceAttestationCredentials, TestDACRevocationDelegateImpl)
}]
)";

WriteTestRevokedData(jsonData, tmpJsonFile);
revocationDelegateImpl.SetDeviceAttestationRevocationData(jsonData);
revocationDelegateImpl.CheckForRevokedDACChain(info, &attestationInformationVerificationCallback);
revocationDelegateImpl.ClearDeviceAttestationRevocationData();
EXPECT_EQ(attestationResult, AttestationVerificationResult::kSuccess);
}
Loading