/*
 *
 *    Copyright (c) 2025 Project CHIP Authors
 *    All rights reserved.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

#include <pw_unit_test/framework.h>

#include <app/tests/suites/credentials/TestHarnessDACProvider.h>
#include <controller/CommissioneeDeviceProxy.h>
#include <controller/OperationalCredentialsDelegate.h>
#include <credentials/DeviceAttestationConstructor.h>
#include <credentials/attestation_verifier/DacOnlyPartialAttestationVerifier.h>
#include <credentials/attestation_verifier/DeviceAttestationVerifier.h>
#include <credentials/tests/CHIPAttCert_test_vectors.h>
#include <credentials/tests/CHIPCert_unit_test_vectors.h>
#include <crypto/CHIPCryptoPAL.h>
#include <lib/core/CHIPError.h>
#include <lib/core/CHIPVendorIdentifiers.hpp>
#include <lib/support/BufferWriter.h>
#include <lib/support/CHIPMem.h>
#include <lib/support/Span.h>
#include <lib/support/tests/ExtraPwTestMacros.h>

using namespace chip;
using namespace chip::Credentials;
using namespace chip::TestCerts;
using chip::Credentials::Examples::TestHarnessDACProvider;

struct TestDacOnlyPartialAttestationVerifier : public ::testing::Test
{
    static void SetUpTestSuite() { ASSERT_EQ(chip::Platform::MemoryInit(), CHIP_NO_ERROR); }
    static void TearDownTestSuite() { chip::Platform::MemoryShutdown(); }

    static constexpr VendorId kTestVendorId  = static_cast<VendorId>(0xFFF1);
    static constexpr uint16_t kTestProductId = 0x8000;

    // The following test data uses arbitrary values solely for test structure;
    // the actual contents do not represent real or meaningful data.
    static constexpr uint8_t kTestAttestationElements[32]                                       = { 0x01, 0x02, 0x03 };
    static constexpr uint8_t kTestChallengeData[32]                                             = { 0x04, 0x05, 0x06 };
    static constexpr uint8_t kTestSignatureData[chip::Crypto::kP256_ECDSA_Signature_Length_Raw] = { 0x07, 0x08, 0x09 };
    static constexpr uint8_t kTestNonceData[kAttestationNonceLength]                            = { 0x0A, 0x0B, 0x0C };
    static constexpr uint8_t kTestCDData[32]                                                    = { 0x11, 0x22, 0x33 };

private:
    static void OnAttestationInformationVerificationCallback(void * context,
                                                             const DeviceAttestationVerifier::AttestationInfo & info,
                                                             AttestationVerificationResult result);

    static CHIP_ERROR ConstructAttestationElementsTLV(uint8_t * tlvBuffer, size_t bufferSize, const ByteSpan & cdData,
                                                      const ByteSpan & nonceData, size_t & tlvLen);

    static CHIP_ERROR CreateSignedAttestationData(uint8_t * tlvBuffer, size_t tlvBufferSize, size_t & tlvLen,
                                                  chip::Crypto::P256ECDSASignature & signature, const ByteSpan & cdData,
                                                  const ByteSpan & nonceData, const ByteSpan & privateKey,
                                                  const ByteSpan & publicKey, const uint8_t * challengeData,
                                                  size_t challengeDataLen);

protected:
    CHIP_ERROR CreateSignedAttestationDataForTest(uint8_t * tlvBuffer, size_t tlvBufferSize, size_t & tlvLen,
                                                  chip::Crypto::P256ECDSASignature & signature, const ByteSpan & cdData,
                                                  const ByteSpan & nonceData, const ByteSpan & privateKey,
                                                  const ByteSpan & publicKey, const uint8_t * challengeData,
                                                  size_t challengeDataLen)
    {
        return CreateSignedAttestationData(tlvBuffer, tlvBufferSize, tlvLen, signature, cdData, nonceData, privateKey, publicKey,
                                           challengeData, challengeDataLen);
    }

public:
    void SetUp() override { attestationResult = AttestationVerificationResult::kSuccess; }

    // Create attestation verification result variable
    // This will be used to capture the result of the verification callback
    PartialDACVerifier verifier;
    AttestationVerificationResult attestationResult = AttestationVerificationResult::kSuccess;
    Callback::Callback<DeviceAttestationVerifier::OnAttestationInformationVerification> attestationCallback{
        &TestDacOnlyPartialAttestationVerifier::OnAttestationInformationVerificationCallback, &attestationResult
    };

    // Helper method to run a DAC validity test with specified keys and certificate.
    void RunDACValidityTest(const ByteSpan & privateKey, const ByteSpan & publicKey, const ByteSpan & dacCert,
                            const ByteSpan & cdData, const ByteSpan & nonceData, const uint8_t * challengeData,
                            size_t challengeDataLen)
    {
        uint8_t tlvBuf[128];
        size_t tlvLen = 0;
        chip::Crypto::P256ECDSASignature signature;

        // Create signed attestation data
        CHIP_ERROR err = CreateSignedAttestationData(tlvBuf, sizeof(tlvBuf), tlvLen, signature, cdData, nonceData, privateKey,
                                                     publicKey, challengeData, challengeDataLen);
        ASSERT_EQ(err, CHIP_NO_ERROR);

        // Set up attestation info with the generated TLV and signature
        DeviceAttestationVerifier::AttestationInfo info(ByteSpan(tlvBuf, tlvLen), ByteSpan(challengeData, challengeDataLen),
                                                        ByteSpan(signature.ConstBytes(), signature.Length()),
                                                        TestCerts::sTestCert_PAI_FFF2_8004_FB_Cert, dacCert, nonceData,
                                                        static_cast<VendorId>(0xFFF2), 8004);

        // Call the verifier and check for expired DAC result
        verifier.VerifyAttestationInformation(info, &attestationCallback);
        EXPECT_EQ(attestationResult, AttestationVerificationResult::kDacExpired);
    }
};

// Callback function to capture attestation verification results
void TestDacOnlyPartialAttestationVerifier::OnAttestationInformationVerificationCallback(
    void * context, const DeviceAttestationVerifier::AttestationInfo & info, AttestationVerificationResult result)
{
    AttestationVerificationResult * pResult = reinterpret_cast<AttestationVerificationResult *>(context);
    *pResult                                = result;
}

// Helper function to construct TLV attestation elements structure
CHIP_ERROR TestDacOnlyPartialAttestationVerifier::ConstructAttestationElementsTLV(uint8_t * tlvBuffer, size_t bufferSize,
                                                                                  const ByteSpan & cdData,
                                                                                  const ByteSpan & nonceData, size_t & tlvLen)
{
    // Construct TLV structure representing attestation elements that would be signed by device
    chip::TLV::TLVWriter writer;
    writer.Init(tlvBuffer, bufferSize);
    chip::TLV::TLVType outerType;

    // Add attestation elements to the TLV structure

    // Attestation Elements TLV
    // attestation-elements => STRUCTURE [ tag-order ]
    // {
    //   certification_declaration[1]      : OCTET STRING,
    //   attestation_nonce[2]              : OCTET STRING [ length 32 ],
    //   timestamp[3]                      : UNSIGNED INTEGER [ range 32-bits ],
    //   firmware_information[4, optional] : OCTET STRING,
    // }
    // Reference: Matter 1.4 Core Specification — 11.18.4.6. Attestation Elements

    ReturnErrorOnFailure(writer.StartContainer(chip::TLV::AnonymousTag(), chip::TLV::kTLVType_Structure, outerType));
    EXPECT_SUCCESS(writer.Put(chip::TLV::ContextTag(1), cdData));
    EXPECT_SUCCESS(writer.Put(chip::TLV::ContextTag(2), nonceData));
    EXPECT_SUCCESS(writer.Put(chip::TLV::ContextTag(3), static_cast<uint32_t>(0)));
    EXPECT_SUCCESS(writer.Put(chip::TLV::ContextTag(4), ByteSpan()));
    EXPECT_SUCCESS(writer.Put(chip::TLV::ContextTag(5), ByteSpan()));
    ReturnErrorOnFailure(writer.EndContainer(outerType));

    tlvLen = writer.GetLengthWritten();
    return CHIP_NO_ERROR;
}

// Helper function to create signed attestation data using standard test parameters.
CHIP_ERROR TestDacOnlyPartialAttestationVerifier::CreateSignedAttestationData(
    uint8_t * tlvBuffer, size_t tlvBufferSize, size_t & tlvLen, chip::Crypto::P256ECDSASignature & signature,
    const ByteSpan & cdData, const ByteSpan & nonceData, const ByteSpan & privateKey, const ByteSpan & publicKey,
    const uint8_t * challengeData, size_t challengeDataLen)
{
    // Construct TLV attestation elements
    ReturnErrorOnFailure(ConstructAttestationElementsTLV(tlvBuffer, tlvBufferSize, cdData, nonceData, tlvLen));

    // Concatenate TLV and challenge data for signing
    constexpr size_t kMaxToSignSize = 128 + 64; // 128 for TLV, 64 for challengeData
    uint8_t toSign[kMaxToSignSize]  = { 0 };
    chip::Encoding::BufferWriter writer(toSign, sizeof(toSign));
    writer.Put(tlvBuffer, tlvLen).Put(challengeData, challengeDataLen);
    if (!writer.Fit())
    {
        return CHIP_ERROR_BUFFER_TOO_SMALL;
    }

    // Load keypair and sign the data
    chip::Crypto::P256Keypair keypair;
    ReturnErrorOnFailure(keypair.HazardousOperationLoadKeypairFromRaw(privateKey, publicKey));
    ReturnErrorOnFailure(keypair.ECDSA_sign_msg(toSign, writer.Needed(), signature));

    return CHIP_NO_ERROR;
}

// Test verifier behavior with empty parameters
TEST_F(TestDacOnlyPartialAttestationVerifier, TestWithInvalidParameters)
{
    // Create AttestationInfo with empty buffers
    DeviceAttestationVerifier::AttestationInfo invalidInfo(ByteSpan(), // attestationElements
                                                           ByteSpan(), // attestationChallenge
                                                           ByteSpan(), // attestationSignature
                                                           ByteSpan(), // paiDer
                                                           ByteSpan(), // dacDer
                                                           ByteSpan(), // attestationNonce
                                                           kTestVendorId, kTestProductId);

    // Call the verifier with invalid info
    verifier.VerifyAttestationInformation(invalidInfo, &attestationCallback);
    EXPECT_EQ(attestationResult, AttestationVerificationResult::kInvalidArgument);
}

// Test verifier behavior with oversized attestationElements buffer - verifies handling of large data
TEST_F(TestDacOnlyPartialAttestationVerifier, TestWithLargeAttestationElementsBuffer)
{
    // Create a buffer larger than kMaxResponseLength (900 bytes)
    constexpr size_t kLargeBufferSize = 1024;
    uint8_t largeBuffer[kLargeBufferSize];

    // Fill the buffer with some test data
    for (size_t i = 0; i < kLargeBufferSize; i++)
    {
        largeBuffer[i] = static_cast<uint8_t>(i % 256); // Fill with repeating pattern 0-255
    }

    // Create ByteSpan from the large buffer
    ByteSpan largeAttestationElements(largeBuffer);

    // The following test data uses arbitrary values solely for test structure;
    // the actual contents do not represent real or meaningful data.
    uint8_t paiData[256] = { 0x01, 0x02, 0x03 };
    uint8_t dacData[256] = { 0x0D, 0x0E, 0x0F };

    DeviceAttestationVerifier::AttestationInfo infoWithLargeBuffer(
        largeAttestationElements, ByteSpan(kTestChallengeData), ByteSpan(kTestSignatureData), ByteSpan(paiData), ByteSpan(dacData),
        ByteSpan(kTestNonceData), kTestVendorId, kTestProductId);

    // Call the verifier with large buffer
    verifier.VerifyAttestationInformation(infoWithLargeBuffer, &attestationCallback);
    EXPECT_EQ(attestationResult, AttestationVerificationResult::kInvalidArgument);
}

// Test with invalid DAC certificate format
TEST_F(TestDacOnlyPartialAttestationVerifier, TestWithInvalidDACFormat)
{
    // The actual contents do not represent real or meaningful data.
    uint8_t invalidDacData[64] = { 0xFF, 0xEE, 0xDD, 0xCC };

    DeviceAttestationVerifier::AttestationInfo info(
        ByteSpan(kTestAttestationElements), ByteSpan(kTestChallengeData), ByteSpan(kTestSignatureData),
        TestCerts::sTestCert_PAI_FFF1_8000_Cert, ByteSpan(invalidDacData), ByteSpan(kTestNonceData), kTestVendorId, kTestProductId);

    // Call the verifier with the invalid DAC information
    verifier.VerifyAttestationInformation(info, &attestationCallback);
    EXPECT_EQ(attestationResult, AttestationVerificationResult::kDacFormatInvalid);
}

// Test with DAC certificate where VID/PID can be extracted but public key extraction fails
TEST_F(TestDacOnlyPartialAttestationVerifier, TestWithDACMissingPublicKey)
{
    // Use a DAC certificate with valid VID/PID but a missing or corrupted public key.
    // For this test, we take the first 16 bytes of a valid DAC certificate to simulate a broken public key field.
    uint8_t brokenDacData[16];
    memcpy(brokenDacData, TestCerts::sTestCert_DAC_FFF1_8000_0004_Cert.data(), sizeof(brokenDacData));

    DeviceAttestationVerifier::AttestationInfo info(
        ByteSpan(kTestAttestationElements), ByteSpan(kTestChallengeData), ByteSpan(kTestSignatureData),
        TestCerts::sTestCert_PAI_FFF1_8000_Cert, ByteSpan(brokenDacData), ByteSpan(kTestNonceData), kTestVendorId, kTestProductId);

    verifier.VerifyAttestationInformation(info, &attestationCallback);
    EXPECT_EQ(attestationResult, AttestationVerificationResult::kDacFormatInvalid);
}

// Test with valid DAC but invalid PAI
TEST_F(TestDacOnlyPartialAttestationVerifier, TestWithValidDACButInvalidPAI)
{
    // The actual contents do not represent real or meaningful data.
    uint8_t invalidPaiData[64] = { 0xFF, 0xEE, 0xDD, 0xCC };

    DeviceAttestationVerifier::AttestationInfo dacValidPaiInvalidInfo(
        ByteSpan(kTestAttestationElements), ByteSpan(kTestChallengeData), ByteSpan(kTestSignatureData),
        ByteSpan(invalidPaiData),                     // Invalid PAI certificate
        TestCerts::sTestCert_DAC_FFF1_8000_0004_Cert, // Valid DAC certificate
        ByteSpan(kTestNonceData), kTestVendorId, kTestProductId);

    // Call the verifier with the invalid information
    verifier.VerifyAttestationInformation(dacValidPaiInvalidInfo, &attestationCallback);
    EXPECT_EQ(attestationResult, AttestationVerificationResult::kPaiFormatInvalid);
}

// Test with mismatched Vendor IDs
TEST_F(TestDacOnlyPartialAttestationVerifier, TestWithMismatchedVendorIDs)
{
    DeviceAttestationVerifier::AttestationInfo mismatchedVidInfo(ByteSpan(kTestAttestationElements), ByteSpan(kTestChallengeData),
                                                                 ByteSpan(kTestSignatureData),
                                                                 TestCerts::sTestCert_PAI_FFF2_8001_Cert,      // PAI with VID=FFF2
                                                                 TestCerts::sTestCert_DAC_FFF1_8000_0004_Cert, // DAC with VID=FFF1
                                                                 ByteSpan(kTestNonceData), kTestVendorId, kTestProductId);

    // Call the verifier with the mismatched VID information
    verifier.VerifyAttestationInformation(mismatchedVidInfo, &attestationCallback);
    EXPECT_EQ(attestationResult, AttestationVerificationResult::kDacVendorIdMismatch);
}

// Test with mismatched PAI and DAC Product IDs
TEST_F(TestDacOnlyPartialAttestationVerifier, TestWithMismatchedPAIAndDACProductIDs)
{
    DeviceAttestationVerifier::AttestationInfo mismatchedPidInfo(
        ByteSpan(kTestAttestationElements), ByteSpan(kTestChallengeData), ByteSpan(kTestSignatureData),
        TestCerts::sTestCert_PAI_FFF2_8004_FB_Cert,   // PAI with VID=FFF2, PID=8004
        TestCerts::sTestCert_DAC_FFF2_8001_0008_Cert, // DAC with VID=FFF2, PID=8001
        ByteSpan(kTestNonceData), static_cast<VendorId>(0xFFF2), 0x8001);

    // Call the verifier with the mismatched PAI and DAC information
    verifier.VerifyAttestationInformation(mismatchedPidInfo, &attestationCallback);
    EXPECT_EQ(attestationResult, AttestationVerificationResult::kDacProductIdMismatch);
}

// Test with invalid attestation signature format
TEST_F(TestDacOnlyPartialAttestationVerifier, TestWithInvalidAttestationSignatureFormat)
{
    // Create oversized signature data that exceeds maximum allowed signature size
    constexpr size_t kOversizedSignatureSize = chip::Crypto::kP256_ECDSA_Signature_Length_Raw + 1;
    uint8_t oversizedSignatureData[kOversizedSignatureSize];
    memset(oversizedSignatureData, 0xAA, sizeof(oversizedSignatureData));

    DeviceAttestationVerifier::AttestationInfo oversizedSignatureInfo(
        ByteSpan(kTestAttestationElements), ByteSpan(kTestChallengeData),
        ByteSpan(oversizedSignatureData),             // Oversized signature
        TestCerts::sTestCert_PAI_FFF2_8001_Cert,      // Valid PAI certificate
        TestCerts::sTestCert_DAC_FFF2_8001_0008_Cert, // Valid DAC certificate
        ByteSpan(kTestNonceData), kTestVendorId, kTestProductId);

    // Call the verifier with the oversized signature information
    verifier.VerifyAttestationInformation(oversizedSignatureInfo, &attestationCallback);
    EXPECT_EQ(attestationResult, AttestationVerificationResult::kAttestationSignatureInvalidFormat);
}

// Test with matching PAI and DAC Product IDs
TEST_F(TestDacOnlyPartialAttestationVerifier, TestWithMatchingPAIAndDACProductIDs)
{
    DeviceAttestationVerifier::AttestationInfo matchingPidInfo(
        ByteSpan(kTestAttestationElements), ByteSpan(kTestChallengeData), ByteSpan(kTestSignatureData),
        TestCerts::sTestCert_PAI_FFF2_8001_Cert,      // PAI with VID=FFF2, PID=8001
        TestCerts::sTestCert_DAC_FFF2_8001_0008_Cert, // DAC with VID=FFF2, PID=8001 (same as PAI)
        ByteSpan(kTestNonceData), kTestVendorId, kTestProductId);

    // Call the verifier with the matching PAI and DAC information
    verifier.VerifyAttestationInformation(matchingPidInfo, &attestationCallback);
    EXPECT_EQ(attestationResult, AttestationVerificationResult::kAttestationSignatureInvalid);
}

// Test case validates that the verifier correctly rejects DAC certificates that have expired
TEST_F(TestDacOnlyPartialAttestationVerifier, TestWithExpiredDACCertificate)
{
// This check is only valid if the platform supports current time retrieval
// This is necessary to determine if the certificate is not yet valid
#if defined(CURRENT_TIME_NOT_IMPLEMENTED) || !(CHIP_SYSTEM_CONFIG_PLATFORM_PROVIDES_TIME)
    GTEST_SKIP() << "Skipping test: platform does not support current time.";
#else
    RunDACValidityTest(TestCerts::sTestCert_DAC_FFF2_8004_0020_ValInPast_PrivateKey,
                       TestCerts::sTestCert_DAC_FFF2_8004_0020_ValInPast_PublicKey,
                       TestCerts::sTestCert_DAC_FFF2_8004_0020_ValInPast_Cert, ByteSpan(kTestCDData), ByteSpan(kTestNonceData),
                       kTestChallengeData, sizeof(kTestChallengeData));
#endif
}

// Test case verifies that certificates with future validity periods are properly rejected
TEST_F(TestDacOnlyPartialAttestationVerifier, TestWithValidInFutureDACCertificate)
{
// This check is only valid if the platform supports current time retrieval
// This is necessary to determine if the certificate is not yet valid
#if defined(CURRENT_TIME_NOT_IMPLEMENTED) || !(CHIP_SYSTEM_CONFIG_PLATFORM_PROVIDES_TIME)
    GTEST_SKIP() << "Skipping test: platform does not support current time.";
#else
    RunDACValidityTest(TestCerts::sTestCert_DAC_FFF2_8004_0021_ValInFuture_PrivateKey,
                       TestCerts::sTestCert_DAC_FFF2_8004_0021_ValInFuture_PublicKey,
                       TestCerts::sTestCert_DAC_FFF2_8004_0021_ValInFuture_Cert, ByteSpan(kTestCDData), ByteSpan(kTestNonceData),
                       kTestChallengeData, sizeof(kTestChallengeData));
#endif
}

// Test case verifies that wrong formats for attestation elements are properly rejected
TEST_F(TestDacOnlyPartialAttestationVerifier, TestWithMalformedAttestationElements)
{
    // Create a malformed attestationElements buffer
    uint8_t malformedAttestationElements[32] = { 0xFF, 0xEE, 0xDD, 0xCC, 0xBB, 0xAA, 0x99, 0x88, 0x77, 0x66, 0x55,
                                                 0x44, 0x33, 0x22, 0x11, 0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60,
                                                 0x70, 0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0, 0x0F };

    // Concatenate attestationElements + attestationChallenge for signing
    uint8_t toSign[sizeof(malformedAttestationElements) + sizeof(kTestChallengeData)] = { 0 };
    chip::Encoding::BufferWriter writer(toSign, sizeof(toSign));
    writer.Put(malformedAttestationElements, sizeof(malformedAttestationElements))
        .Put(kTestChallengeData, sizeof(kTestChallengeData));
    ASSERT_TRUE(writer.Fit());

    // Load a valid keypair for signing
    chip::Crypto::P256Keypair keypair;
    CHIP_ERROR err = keypair.HazardousOperationLoadKeypairFromRaw(ByteSpan(TestCerts::sTestCert_DAC_FFF1_8000_0004_PrivateKey),
                                                                  ByteSpan(TestCerts::sTestCert_DAC_FFF1_8000_0004_PublicKey));
    ASSERT_EQ(err, CHIP_NO_ERROR);

    // Sign the concatenated data
    chip::Crypto::P256ECDSASignature signature;
    err = keypair.ECDSA_sign_msg(toSign, writer.Needed(), signature);
    ASSERT_EQ(err, CHIP_NO_ERROR);

    // Prepare AttestationInfo with valid certificates and keys, but malformed attestationElements
    DeviceAttestationVerifier::AttestationInfo malformedInfo(
        ByteSpan(malformedAttestationElements), ByteSpan(kTestChallengeData), ByteSpan(signature.ConstBytes(), signature.Length()),
        TestCerts::sTestCert_PAI_FFF1_8000_Cert, TestCerts::sTestCert_DAC_FFF1_8000_0004_Cert, ByteSpan(kTestNonceData),
        kTestVendorId, kTestProductId);

    verifier.VerifyAttestationInformation(malformedInfo, &attestationCallback);
    EXPECT_EQ(attestationResult, AttestationVerificationResult::kAttestationElementsMalformed);
}

// Test case verifies that nonce in attestation elements does not match the expected nonce
TEST_F(TestDacOnlyPartialAttestationVerifier, TestWithMismatchedNonce)
{
    // The actual contents do not represent real or meaningful data.
    uint8_t nonceInElements[kAttestationNonceLength] = { 0x55, 0x66, 0x77, 0x88 };
    uint8_t expectedNonce[kAttestationNonceLength]   = { 0x99, 0x88, 0x77 };

    uint8_t tlvBuf[128];
    size_t tlvLen = 0;
    chip::Crypto::P256ECDSASignature signature;

    // Create signed attestation data with mismatched nonce in elements
    CHIP_ERROR err = CreateSignedAttestationDataForTest(
        tlvBuf, sizeof(tlvBuf), tlvLen, signature, ByteSpan(kTestCDData), ByteSpan(nonceInElements),
        ByteSpan(TestCerts::sTestCert_DAC_FFF1_8000_0004_PrivateKey), ByteSpan(TestCerts::sTestCert_DAC_FFF1_8000_0004_PublicKey),
        kTestChallengeData, sizeof(kTestChallengeData));
    ASSERT_EQ(err, CHIP_NO_ERROR);

    // Prepare AttestationInfo with valid certificates and keys, but mismatched nonce
    DeviceAttestationVerifier::AttestationInfo mismatchedNonceInfo(
        ByteSpan(tlvBuf, tlvLen), ByteSpan(kTestChallengeData), ByteSpan(signature.ConstBytes(), signature.Length()),
        TestCerts::sTestCert_PAI_FFF1_8000_Cert, TestCerts::sTestCert_DAC_FFF1_8000_0004_Cert, ByteSpan(expectedNonce),
        kTestVendorId, kTestProductId);

    verifier.VerifyAttestationInformation(mismatchedNonceInfo, &attestationCallback);
    EXPECT_EQ(attestationResult, AttestationVerificationResult::kAttestationNonceMismatch);
}

// Test case verifies that the verifier handles cases where PAA certificate lookup fails
TEST_F(TestDacOnlyPartialAttestationVerifier, TestWithInvalidPAAFormat)
{
    uint8_t tlvBuf[128];
    size_t tlvLen = 0;
    chip::Crypto::P256ECDSASignature signature;

    CHIP_ERROR err = CreateSignedAttestationDataForTest(
        tlvBuf, sizeof(tlvBuf), tlvLen, signature, ByteSpan(kTestCDData), ByteSpan(kTestNonceData),
        ByteSpan(TestCerts::sTestCert_DAC_FFF1_8000_0004_PrivateKey), ByteSpan(TestCerts::sTestCert_DAC_FFF1_8000_0004_PublicKey),
        kTestChallengeData, sizeof(kTestChallengeData));
    ASSERT_EQ(err, CHIP_NO_ERROR);

    // Prepare AttestationInfo with valid DAC and PAI, but invalid PAA
    DeviceAttestationVerifier::AttestationInfo validInfo(
        ByteSpan(tlvBuf, tlvLen), ByteSpan(kTestChallengeData), ByteSpan(signature.ConstBytes(), signature.Length()),
        TestCerts::sTestCert_PAI_FFF1_8000_Cert, TestCerts::sTestCert_DAC_FFF1_8000_0004_Cert, ByteSpan(kTestNonceData),
        kTestVendorId, kTestProductId);

    verifier.VerifyAttestationInformation(validInfo, &attestationCallback);
    EXPECT_EQ(attestationResult, AttestationVerificationResult::kPaaFormatInvalid);
}
