/*
 *
 *    Copyright (c) 2026 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.
 */

/**
 *    @file
 *      FuzzTest harness for the X.509 helper surface of the crypto PAL
 *      (`CHIPCryptoPAL.h`): key-identifier, distinguished-name, VID/PID and
 *      CRL-distribution-point extraction, issuance-time comparison, resigned
 *      certificate matching, and CSR verification.
 *
 *      These helpers each parse a DER certificate independently of the chain
 *      validators, so they are covered here rather than in
 *      `FuzzChipCertPW.cpp`, which already drives
 *      `Crypto::ValidateCertificateChain` and
 *      `Crypto::VerifyAttestationCertificateFormat`.
 *
 *      Seeds come from the compiled attestation-certificate test vectors, not
 *      from a directory read, so they travel with the binary. They are attached
 *      to the individual domains, because only domain-level seeds are injected
 *      when the suite runs under the libFuzzer compatibility engine. Each pool
 *      leads with the coherent FFF1 chain (PAA_FFF1 -> PAI_FFF1_8000 ->
 *      DAC_FFF1_8000_0000): FuzzTest builds its pristine seed tuple from the
 *      first seed of each domain, so a mismatched lead would fail the parse and
 *      leave the helpers unreached.
 */

#include <cstddef>
#include <cstdint>
#include <string>
#include <vector>

#include <fuzztest/fuzztest_core.h>
#include <gtest/gtest.h>

#include <credentials/tests/CHIPAttCert_test_vectors.h>
#include <crypto/CHIPCryptoPAL.h>
#include <lib/support/CHIPMem.h>
#include <lib/support/CodeUtils.h>
#include <lib/support/Span.h>

#if CHIP_CRYPTO_PSA
#include <psa/crypto.h>
#endif

namespace {

using namespace chip;
using namespace chip::Crypto;
using namespace chip::TestCerts;
using namespace fuzztest;

using Bytes = std::vector<uint8_t>;

// The mbedTLS and PSA certificate backends import keys through PSA, which
// rejects every operation until the driver is initialized -- without this the
// CSR case would pass without verifying anything.
void EnsureInitialized()
{
    static const bool sInitialized = [] {
        VerifyOrDie(Platform::MemoryInit() == CHIP_NO_ERROR);
#if CHIP_CRYPTO_PSA
        VerifyOrDie(psa_crypto_init() == PSA_SUCCESS);
#endif
        return true;
    }();
    (void) sInitialized;
}

Bytes ToBytes(const ByteSpan & span)
{
    return Bytes(span.begin(), span.end());
}

// Matches the DER cap used by the other certificate harnesses.
constexpr size_t kMaxDerCertLen = 8192;

// Distinguished-name attributes are bounded by kMaxCertificateDistinguishedNameLength;
// allow twice that so over-long values are still exercised.
constexpr size_t kMaxAttributeStringLen = 2 * kMaxCertificateDistinguishedNameLength;

std::vector<Bytes> ToSeeds(const std::vector<ByteSpan> & spans)
{
    std::vector<Bytes> seeds;
    seeds.reserve(spans.size());
    for (const ByteSpan & span : spans)
    {
        seeds.push_back(ToBytes(span));
    }
    return seeds;
}

// Device attestation certificates, leading with the FFF1 chain leaf and
// followed by variants covering other vendor/product ids and every validity
// edge case the test corpus provides.
auto AnyDacCert()
{
    return Arbitrary<Bytes>()
        .WithMaxSize(kMaxDerCertLen)
        .WithSeeds(ToSeeds({
            sTestCert_DAC_FFF1_8000_0000_Cert,
            sTestCert_DAC_FFF1_8000_0004_Cert,
            sTestCert_DAC_FFF2_8001_0008_Cert,
            sTestCert_DAC_FFF2_8002_0017_Cert,
            sTestCert_DAC_FFF2_8003_0018_FB_Cert,
            sTestCert_DAC_FFF2_8004_001C_FB_Cert,
            sTestCert_DAC_FFF2_8004_0020_ValInPast_Cert,
            sTestCert_DAC_FFF2_8004_0021_ValInFuture_Cert,
            sTestCert_DAC_FFF2_8004_0030_Val1SecBefore_Cert,
            sTestCert_DAC_FFF2_8006_0034_ValInFuture_Cert,
        }));
}

// Product attestation intermediates, leading with the FFF1 chain issuer.
auto AnyPaiCert()
{
    return Arbitrary<Bytes>()
        .WithMaxSize(kMaxDerCertLen)
        .WithSeeds(ToSeeds({
            sTestCert_PAI_FFF1_8000_Cert,
            sTestCert_PAI_FFF2_8001_Cert,
            sTestCert_PAI_FFF2_8001_Resigned_Cert,
            sTestCert_PAI_FFF2_8001_ResignedSKIDDiff_Cert,
            sTestCert_PAI_FFF2_8001_ResignedSubjectDiff_Cert,
            sTestCert_PAI_FFF2_8004_FB_Cert,
            sTestCert_PAI_FFF2_8005_ValInPast_Cert,
            sTestCert_PAI_FFF2_8006_ValInFuture_Cert,
            sTestCert_PAI_FFF2_NoPID_Cert,
        }));
}

// Certificates that actually carry a CRL distribution point, in every shape the
// corpus provides: single/multiple DPs, multiple URIs, an HTTPS scheme, an
// over-long URI, a wrong URI prefix, and one/two CRL issuers.
auto AnyCdpCert()
{
    return Arbitrary<Bytes>()
        .WithMaxSize(kMaxDerCertLen)
        .WithSeeds(ToSeeds({
            sTestCert_DAC_FFF1_8000_0000_CDP_Issuer_PAA_FFF1_Cert,
            sTestCert_DAC_FFF1_8000_0000_CDP_Cert,
            sTestCert_DAC_FFF1_8000_0000_CDP_2DPs_Cert,
            sTestCert_DAC_FFF1_8000_0000_CDP_2URIs_Cert,
            sTestCert_DAC_FFF1_8000_0000_CDP_HTTPS_Cert,
            sTestCert_DAC_FFF1_8000_0000_CDP_Long_Cert,
            sTestCert_DAC_FFF1_8000_0000_CDP_Wrong_Prefix_Cert,
            sTestCert_DAC_FFF1_8000_0000_CDP_2CRLIssuers_PAA_FFF1_Cert,
            sTestCert_DAC_FFF1_8000_0000_CDP_CRL_Issuer_PAA_FFF1_2DPs_Cert,
            sTestCert_DAC_FFF1_8000_0000_CDP_Issuer_PAA_NoVID_Cert,
            sTestCert_DAC_FFF1_8000_0000_CDP_Issuer_PAI_FFF2_8004_Cert,
            sTestCert_DAC_FFF1_8000_0000_CDP_Issuer_PAI_FFF2_8004_Long_Cert,
            sTestCert_DAC_FFF1_8000_0000_2CDPs_Cert,
            sTestCert_DAC_FFF1_8000_0000_2CDPs_Issuer_PAA_FFF1_Cert,
            sTestCert_DAC_FFF1_8000_0000_2CDPs_Issuer_PAI_FFF2_8004_Cert,
        }));
}

// IsCertificateValidAtCurrentTime reads the wall clock, so its result is not
// reproducible across runs; only the absence of a crash is checked here.
void IssuanceTimeComparison(const Bytes & candidate, const Bytes & issuer)
{
    EnsureInitialized();

    const ByteSpan candidateSpan(candidate.data(), candidate.size());

    RETURN_SAFELY_IGNORED IsCertificateValidAtIssuance(candidateSpan, ByteSpan(issuer.data(), issuer.size()));
    RETURN_SAFELY_IGNORED IsCertificateValidAtCurrentTime(candidateSpan);
}

FUZZ_TEST(ChipCryptoPal, IssuanceTimeComparison).WithDomains(AnyDacCert(), AnyPaiCert());

void SerialNumberExtraction(const Bytes & cert)
{
    EnsureInitialized();

    uint8_t serialNumberBuf[kMaxCertificateSerialNumberLength] = { 0 };
    MutableByteSpan serialNumber(serialNumberBuf);
    RETURN_SAFELY_IGNORED ExtractSerialNumberFromX509Cert(ByteSpan(cert.data(), cert.size()), serialNumber);
}

FUZZ_TEST(ChipCryptoPal, SerialNumberExtraction).WithDomains(AnyDacCert());

void KeyIdentifierExtraction(const Bytes & cert)
{
    EnsureInitialized();

    const ByteSpan certSpan(cert.data(), cert.size());

    uint8_t skidBuf[kSubjectKeyIdentifierLength];
    MutableByteSpan skid(skidBuf);
    RETURN_SAFELY_IGNORED ExtractSKIDFromX509Cert(certSpan, skid);

    uint8_t akidBuf[kAuthorityKeyIdentifierLength];
    MutableByteSpan akid(akidBuf);
    RETURN_SAFELY_IGNORED ExtractAKIDFromX509Cert(certSpan, akid);
}

FUZZ_TEST(ChipCryptoPal, KeyIdentifierExtraction).WithDomains(AnyDacCert());

void CrlDistributionPointUriExtraction(const Bytes & cert)
{
    EnsureInitialized();

    char cdpBuf[kMaxCRLDistributionPointURLLength] = { '\0' };
    MutableCharSpan cdpUrl(cdpBuf);
    RETURN_SAFELY_IGNORED ExtractCRLDistributionPointURIFromX509Cert(ByteSpan(cert.data(), cert.size()), cdpUrl);
}

FUZZ_TEST(ChipCryptoPal, CrlDistributionPointUriExtraction).WithDomains(AnyCdpCert());

void CrlIssuerExtraction(const Bytes & cert)
{
    EnsureInitialized();

    uint8_t crlIssuerBuf[kMaxCertificateDistinguishedNameLength] = { 0 };
    MutableByteSpan crlIssuer(crlIssuerBuf);
    RETURN_SAFELY_IGNORED ExtractCDPExtensionCRLIssuerFromX509Cert(ByteSpan(cert.data(), cert.size()), crlIssuer);
}

FUZZ_TEST(ChipCryptoPal, CrlIssuerExtraction).WithDomains(AnyCdpCert());

void VidPidExtractionFromCert(const Bytes & cert)
{
    EnsureInitialized();

    AttestationCertVidPid vidPid;
    RETURN_SAFELY_IGNORED ExtractVIDPIDFromX509Cert(ByteSpan(cert.data(), cert.size()), vidPid);
}

FUZZ_TEST(ChipCryptoPal, VidPidExtractionFromCert).WithDomains(AnyDacCert());

auto AnyDNAttrType()
{
    return ElementOf({ DNAttrType::kUnspecified, DNAttrType::kCommonName, DNAttrType::kMatterVID, DNAttrType::kMatterPID });
}

// The attribute string is parsed as text (including the "Mvid:"/"Mpid:" prefixes
// embedded in a common name), so it is fuzzed as a free-form string rather than
// seeded from certificates.
void VidPidExtractionFromAttributeString(DNAttrType attrType, const std::string & attrString)
{
    EnsureInitialized();

    AttestationCertVidPid vidPid;
    AttestationCertVidPid vidPidFromCN;

    const ByteSpan attrSpan(reinterpret_cast<const uint8_t *>(attrString.data()), attrString.size());
    RETURN_SAFELY_IGNORED ExtractVIDPIDFromAttributeString(attrType, attrSpan, vidPid, vidPidFromCN);
}

FUZZ_TEST(ChipCryptoPal, VidPidExtractionFromAttributeString)
    .WithDomains(AnyDNAttrType(),
                 Arbitrary<std::string>()
                     .WithMaxSize(kMaxAttributeStringLen)
                     .WithSeeds({ "Mvid:FFF1", "Mpid:8000", "Mvid:FFF1 Mpid:8000", "Matter Test DAC 0000",
                                  "Mvid:", "Mvid:FFFF Mpid:FFFF" }));

void SubjectAndIssuerExtraction(const Bytes & cert)
{
    EnsureInitialized();

    const ByteSpan certSpan(cert.data(), cert.size());

    uint8_t subjectBuf[kMaxCertificateDistinguishedNameLength] = { 0 };
    MutableByteSpan subject(subjectBuf);
    RETURN_SAFELY_IGNORED ExtractSubjectFromX509Cert(certSpan, subject);

    uint8_t issuerBuf[kMaxCertificateDistinguishedNameLength] = { 0 };
    MutableByteSpan issuer(issuerBuf);
    RETURN_SAFELY_IGNORED ExtractIssuerFromX509Cert(certSpan, issuer);
}

FUZZ_TEST(ChipCryptoPal, SubjectAndIssuerExtraction).WithDomains(AnyDacCert());

// The resigned-certificate lookup walks a caller-supplied candidate list, so the
// list length is fuzzed alongside the reference certificate. The candidates are
// the resigned PAI variants, which are what the helper exists to match.
const ByteSpan kResignedCandidates[] = {
    sTestCert_PAI_FFF2_8001_Resigned_Cert,
    sTestCert_PAI_FFF2_8001_ResignedSKIDDiff_Cert,
    sTestCert_PAI_FFF2_8001_ResignedSubjectDiff_Cert,
    sTestCert_PAI_FFF2_NoPID_Resigned_Cert,
};

void ResignedCertificateLookup(const Bytes & cert, size_t candidateCount)
{
    EnsureInitialized();

    ByteSpan replacement;
    RETURN_SAFELY_IGNORED ReplaceCertIfResignedCertFound(ByteSpan(cert.data(), cert.size()), kResignedCandidates, candidateCount,
                                                         replacement);
}

FUZZ_TEST(ChipCryptoPal, ResignedCertificateLookup)
    .WithDomains(AnyPaiCert(), InRange<size_t>(0, MATTER_ARRAY_SIZE(kResignedCandidates)));

// A well-formed CSR, used as the lead seed so that mutations start from a
// structurally valid request.
const uint8_t kGoodCsr[] = {
    0x30, 0x81, 0xca, 0x30, 0x70, 0x02, 0x01, 0x00, 0x30, 0x0e, 0x31, 0x0c, 0x30, 0x0a, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x03,
    0x43, 0x53, 0x52, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48,
    0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0xa3, 0xbe, 0xa1, 0xf5, 0x42, 0x01, 0x07, 0x3c, 0x4b, 0x75, 0x85, 0xd8,
    0xe2, 0x98, 0xac, 0x2f, 0xf6, 0x98, 0xdb, 0xd9, 0x5b, 0xe0, 0x7e, 0xc1, 0x04, 0xd5, 0x73, 0xc5, 0xb0, 0x90, 0x77, 0x27, 0x00,
    0x1e, 0x22, 0xc7, 0x89, 0x5e, 0x4d, 0x75, 0x07, 0x89, 0x82, 0x0f, 0x49, 0xb6, 0x59, 0xd5, 0xc5, 0x15, 0x7d, 0x93, 0xe6, 0x80,
    0x5c, 0x70, 0x89, 0x0a, 0x43, 0x10, 0x3d, 0xeb, 0x3d, 0x4a, 0xa0, 0x00, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d,
    0x04, 0x03, 0x02, 0x05, 0x00, 0x03, 0x48, 0x00, 0x30, 0x45, 0x02, 0x20, 0x1d, 0x86, 0x21, 0xb4, 0xc2, 0xe1, 0xa9, 0xf3, 0xbc,
    0xc8, 0x7c, 0xda, 0xb4, 0xb9, 0xc6, 0x8c, 0xd0, 0xe4, 0x9a, 0x9c, 0xef, 0x02, 0x93, 0x98, 0x27, 0x7e, 0x81, 0x21, 0x5d, 0x20,
    0x9d, 0x32, 0x02, 0x21, 0x00, 0x8b, 0x6b, 0x49, 0xb6, 0x7d, 0x3e, 0x67, 0x9e, 0xb1, 0x22, 0xd3, 0x63, 0x82, 0x40, 0x4f, 0x49,
    0xa4, 0xdc, 0x17, 0x35, 0xac, 0x4b, 0x7a, 0xbf, 0x52, 0x05, 0x58, 0x68, 0xe0, 0xaa, 0xd2, 0x8e,
};

void CertificateSigningRequestVerification(const Bytes & csr)
{
    EnsureInitialized();

    // The key is an output: on success it is filled in from the CSR.
    P256PublicKey csrPublicKey;
    RETURN_SAFELY_IGNORED VerifyCertificateSigningRequest(csr.data(), csr.size(), csrPublicKey);
}

FUZZ_TEST(ChipCryptoPal, CertificateSigningRequestVerification)
    .WithDomains(Arbitrary<Bytes>().WithMaxSize(kMaxDerCertLen).WithSeeds({ Bytes(kGoodCsr, kGoodCsr + sizeof(kGoodCsr)) }));

} // namespace
