/*
 *
 *    Copyright (c) 2021-2022 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
 *      This file implements the command handler for the 'chip-cert' tool
 *      that generates a CHIP Certification Declaration.
 *
 */

#include "chip-cert.h"

#include <credentials/CertificationDeclaration.h>

#include <string>

namespace {

using namespace chip;
using namespace chip::ASN1;
using namespace chip::ArgParser;
using namespace chip::Credentials;
using namespace chip::Crypto;
using namespace chip::TLV;

#define CMD_NAME "chip-cert gen-cd"

bool HandleOption(const char * progName, OptionSet * optSet, int id, const char * name, const char * arg);

// clang-format off
OptionDef gCmdOptionDefs[] =
{
    { "key",                   kArgumentRequired, 'K' },
    { "cert",                  kArgumentRequired, 'C' },
    { "out",                   kArgumentRequired, 'O' },
    { "format-version",        kArgumentRequired, 'f' },
    { "vendor-id",             kArgumentRequired, 'V' },
    { "product-id",            kArgumentRequired, 'p' },
    { "device-type-id",        kArgumentRequired, 'd' },
    { "certificate-id",        kArgumentRequired, 'c' },
    { "security-level",        kArgumentRequired, 'l' },
    { "security-info",         kArgumentRequired, 'i' },
    { "version-number",        kArgumentRequired, 'n' },
    { "certification-type",    kArgumentRequired, 't' },
    { "dac-origin-vendor-id",  kArgumentRequired, 'o' },
    { "dac-origin-product-id", kArgumentRequired, 'r' },
    { "authorized-paa-cert",   kArgumentRequired, 'a' },
#if CHIP_CONFIG_INTERNAL_FLAG_GENERATE_DA_TEST_CASES
    { "ignore-error",          kNoArgument,       'I' },
    { "error-type",            kArgumentRequired, 'E' },
#endif
    { }
};

const char * const gCmdOptionHelp =
    "   -K, --key <file/str>\n"
    "\n"
    "       File or string containing private key to be used to sign the Certification Declaration.\n"
    "\n"
    "   -C, --cert <file/str>\n"
    "\n"
    "       File or string containing certificate associated with the private key that is used\n"
    "       to sign the Certification Declaration. The Subject Key Identifier in the\n"
    "       certificate will be included in the signed Certification Declaration message.\n"
    "\n"
    "   -O, --out <file/stdout>\n"
    "\n"
    "       File to contain the signed Certification Declaration message.\n"
    "       If specified '-' then output is written to stdout.\n"
    "\n"
    "   -f, --format-version <int>\n"
    "\n"
    "       Format Version.\n"
    "\n"
    "   -V, --vendor-id <hex-digits>\n"
    "\n"
    "       Vendor Id (VID) in hex.\n"
    "\n"
    "   -p, --product-id <hex-digits>\n"
    "\n"
    "       Product Id (PID) in hex. Maximum 100 PID values can be specified.\n"
    "       Each PID value should have it's own -p or --product-id option selector.\n"
    "\n"
    "   -d, --device-type-id <hex-digits>\n"
    "\n"
    "       Device Type Id in hex.\n"
    "\n"
    "   -c, --certificate-id <string>\n"
    "\n"
    "       Certificate Id encoded as UTF8 string.\n"
    "\n"
    "   -l, --security-level <hex-digits>\n"
    "\n"
    "       Security Level in hex.\n"
    "\n"
    "   -i, --security-info <hex-digits>\n"
    "\n"
    "       Security Information in hex.\n"
    "\n"
    "   -n, --version-number <hex-digits>\n"
    "\n"
    "       Version Number in hex.\n"
    "\n"
    "   -t, --certification-type <int>\n"
    "\n"
    "       Certification Type. Valid values are:\n"
    "           0 - Development and Test (default)\n"
    "           1 - Provisional\n"
    "           2 - Official\n"
    "\n"
    "   -o, --dac-origin-vendor-id <hex-digits>\n"
    "\n"
    "       DAC Origin Vendor Id in hex.\n"
    "\n"
    "   -r, --dac-origin-product-id <hex-digits>\n"
    "\n"
    "       DAC Origin Product Id in hex.\n"
    "\n"
    "   -a, --authorized-paa-cert <file/str>\n"
    "\n"
    "       File or string containing PAA certificate authorized to sign PAI which signs the DAC\n"
    "       for a product carrying this CD. This field is optional and if present, only specified\n"
    "       PAAs will be authorized to sign device's PAI for the lifetime of the generated CD.\n"
    "       Maximum 10 authorized PAA certificates can be specified.\n"
    "       Each PAA should have its own -a (--authorized-paa-cert) option selector.\n"
    "       The certificate can be in DER or PEM Form.\n"
    "       Note that only the Subject Key Identifier (SKID) value will be extracted\n"
    "       from the PAA certificate and put into CD Structure.\n"
    "\n"
#if CHIP_CONFIG_INTERNAL_FLAG_GENERATE_DA_TEST_CASES
    "   -I, --ignore-error\n"
    "\n"
    "       Ignore some input parameters error.\n"
    "       WARNING: This option makes it possible to circumvent Certification Declaration\n"
    "       structure/parameter requirement. This is required for negative testing of the attestation flow.\n"
    "       Because of this it SHOULD NEVER BE ENABLED IN PRODUCTION BUILDS.\n"
    "\n"
    "   -E, --error-type <error-type>\n"
    "\n"
    "       When specified injects specific error into the structure of generated Certification Declaration.\n"
    "       Note that 'ignore-error' option MUST be specified for this error injection to take effect.\n"
    "       Supported error types that can be injected are:\n"
    "           no-error                           - No error to inject.\n"
    "           format-version-missing             - The CD TLV structure won't have format version field.\n"
    "           format-version-wrong               - Format version will be set to 2 instead of required 1.\n"
    "           vid-missing                        - The CD TLV structure won't have vedor_id field.\n"
    "           vid-mismatch                       - The vendor_id field will have value that doesn't match the VID in DAC.\n"
    "           pid-array-missing                  - The CD TLV structure won't have product_id_array field.\n"
    "           pid-array-count0                   - The product_id_array will be empty.\n"
    "           pid-array-count01-valid            - The product_id_array field will have one valid PID value.\n"
    "           pid-array-count01-mismatch         - The product_id_array field will have one PID value that doesn't match PID in DAC.\n"
    "           pid-array-count10-valid            - The product_id_array field will have 10 PID values one of which is valid matches PID in DAC.\n"
    "           pid-array-count10-mismatch         - The product_id_array field will have 10 PID values none of which matches the PID in DAC.\n"
    "           pid-array-count100-valid           - The product_id_array field will have 100 PID values one of which is valid matches PID in DAC.\n"
    "           pid-array-count100-mismatch        - The product_id_array field will have 100 PID values none of which matches the PID in DAC.\n"
    "           device-type-id-missing             - The CD TLV structure won't have device_type_id field.\n"
    "           device-type-id-mismatch            - device_type_id field won't match the value in the DCL entries associated with the VID and PID.\n"
    "           cert-id-missing                    - The CD TLV structure won't have certificate_id field.\n"
    "           cert-id-mismatch                   - The certificate_id field will contain value NOT allocated by the CSA.\n"
    "           cert-id-len-wrong                  - The certificate_id field will be truncated to have invalid length.\n"
    "           security-level-missing             - The CD TLV structure won't have security_level field.\n"
    "           security-level-wrong               - The security_level field will be set to invalid value (different from 0).\n"
    "           security-info-missing              - The CD TLV structure won't have security_information field.\n"
    "           security-info-wrong                - The security_information field will be set to invalid value (different from 0).\n"
    "           version-number-missing             - The CD TLV structure won't have version_number field.\n"
    "           version-number-wrong               - The version_number field will contain value NOT assigned by the CSA.\n"
    "           cert-type-missing                  - The CD TLV structure won't have certification_type field.\n"
    "           cert-type-wrong                    - The certification_type field will contain invalue value.\n"
    "           dac-origin-vid-present             - The CD TLV structure will include optional dac_origin_vid field.\n"
    "           dac-origin-pid-present             - The CD TLV structure will include optional dac_origin_pid field.\n"
    "           dac-origin-vid-pid-present         - The CD TLV structure will include optional dac_origin_vid and dac_origin_pid fields.\n"
    "           dac-origin-vid-mismatch            - The optional dac_origin_vid field will be present and won't match the VID in DAC.\n"
    "           dac-origin-pid-mismatch            - The optional dac_origin_pid field will be present and won't match the PID in DAC.\n"
    "           authorized-paa-list-count0         - The authorized_paa_list will be empty TLV list.\n"
    "           authorized-paa-list-count1-valid   - The authorized_paa_list will have one valid value.\n"
    "           authorized-paa-list-count2-valid   - The authorized_paa_list will have two elements one of which is valid.\n"
    "           authorized-paa-list-count3-invalid - The authorized_paa_list will have three elements none of which is valid.\n"
    "           authorized-paa-list-count10-valid  - The authorized_paa_list will have ten elements one of which is valid.\n"
    "           authorized-paa-list-count10-invalid- The authorized_paa_list will have ten elements none of which is valid.\n"
    "           signer-info-v2                     - Signer Info version will be set to v2 instead of required v3.\n"
    "           signer-info-digest-algo            - Use Signer Info SHA1 digest algorithm instead of required SHA256.\n"
    "           signer-info-skid                   - Inject error into SKID of a Signer Info signing certificate.\n"
    "           cms-v2                             - CMS version will be set to v2 instead of required v3.\n"
    "           cms-digest-algo                    - Use SHA1 digest algorithm instead of required SHA256.\n"
    "           cms-sig-algo                       - Use ecdsa-with-SHA1 signature algorithm instead of required ecdsa-with-SHA256.\n"
    "                                                required secp256r1 (aka prime256v1).\n"
    "           cms-econtent-type                  - CMS eContentType is set to Microsoft Authenticode [MSAC] ( OID = { 1.3.6.1.4.1.311.2.1.4 } )\n"
    "                                                instead of required pkcs7_data.\n"
    "           cms-sig                            - Inject error into CMS signature.\n"
    "\n"
#endif
    ;

OptionSet gCmdOptions =
{
    HandleOption,
    gCmdOptionDefs,
    "COMMAND OPTIONS",
    gCmdOptionHelp
};

HelpOptions gHelpOptions(
    CMD_NAME,
    "Usage: " CMD_NAME " [ <options...> ]\n",
    CHIP_VERSION_STRING "\n" COPYRIGHT_STRING,
    "Generate CD CMS Signed Message"
);

OptionSet *gCmdOptionSets[] =
{
    &gCmdOptions,
    &gHelpOptions,
    nullptr
};
// clang-format on

/** Certification Declaration Error and Configuration Flags
 *
 * By default all methods (if none of the class setters were used) return valid
 * certification declaration configuration parameter as described in the spec.
 * These parameters can be modified to inject errors into cd structure.
 */
class CDStructConfig
{
public:
    void EnableErrorTestCase() { mEnabled = true; }
    void SetFormatVersionMissing() { mFlags.Set(CDConfigFlags::kFormatVersionMissing); }
    void SetFormatVersionWrong() { mFlags.Set(CDConfigFlags::kFormatVersionWrong); }
    void SetVIDMissing() { mFlags.Set(CDConfigFlags::kVIDMissing); }
    void SetVIDWrong() { mFlags.Set(CDConfigFlags::kVIDWrong); }
    void SetPIDArrayMissing() { mFlags.Set(CDConfigFlags::kPIDArrayMissing); }
    void SetPIDArrayWrong() { mFlags.Set(CDConfigFlags::kPIDArrayWrong); }
    void SetPIDArrayCount(uint8_t pidArrayCount) { mPIDArrayCount = pidArrayCount; }
    void SetDeviceTypeIdMissing() { mFlags.Set(CDConfigFlags::kDeviceTypeIdMissing); }
    void SetDeviceTypeIdWrong() { mFlags.Set(CDConfigFlags::kDeviceTypeIdWrong); }
    void SetCertIdMissing() { mFlags.Set(CDConfigFlags::kCertIdMissing); }
    void SetCertIdWrong() { mFlags.Set(CDConfigFlags::kCertIdWrong); }
    void SetCertIdLenWrong() { mFlags.Set(CDConfigFlags::kCertIdLenWrong); }
    void SetSecurityLevelMissing() { mFlags.Set(CDConfigFlags::kSecurityLevelMissing); }
    void SetSecurityLevelWrong() { mFlags.Set(CDConfigFlags::kSecurityLevelWrong); }
    void SetSecurityInfoMissing() { mFlags.Set(CDConfigFlags::kSecurityInfoMissing); }
    void SetSecurityInfoWrong() { mFlags.Set(CDConfigFlags::kSecurityInfoWrong); }
    void SetVersionNumberMissing() { mFlags.Set(CDConfigFlags::kVersionNumberMissing); }
    void SetVersionNumberWrong() { mFlags.Set(CDConfigFlags::kVersionNumberWrong); }
    void SetCertTypeMissing() { mFlags.Set(CDConfigFlags::kCertTypeMissing); }
    void SetCertTypeWrong() { mFlags.Set(CDConfigFlags::kCertTypeWrong); }
    void SetDACOriginVIDWrong() { mFlags.Set(CDConfigFlags::kDACOriginVID); }
    void SetDACOriginPIDWrong() { mFlags.Set(CDConfigFlags::kDACOriginPID); }
    void SetDACOriginVIDPresent() { mFlags.Set(CDConfigFlags::kDACOriginVIDPresent); }
    void SetDACOriginPIDPresent() { mFlags.Set(CDConfigFlags::kDACOriginPIDPresent); }
    void SetAuthPAAListPresent() { mFlags.Set(CDConfigFlags::kAuthPAAListPresent); }
    void SetAuthPAAListWrong() { mFlags.Set(CDConfigFlags::kAuthPAAListWrong); }
    void SetAuthPAAListCount(uint8_t authPAAListCount) { mAuthPAAListCount = authPAAListCount; }
    void SetSignerInfoVersionWrong() { mFlags.Set(CDConfigFlags::kSignerInfoVersion); }
    void SetSignerInfoDigestAlgoWrong() { mFlags.Set(CDConfigFlags::kSignerInfoDigestAlgo); }
    void SetSignerInfoSKIDWrong() { mFlags.Set(CDConfigFlags::kSignerInfoSKID); }
    void SetCMSVersionWrong() { mFlags.Set(CDConfigFlags::kCMSVersion); }
    void SetCMSDigestAlgoWrong() { mFlags.Set(CDConfigFlags::kCMSDigestAlgo); }
    void SetCMSSigAlgoWrong() { mFlags.Set(CDConfigFlags::kCMSSigAlgo); }
    void SetCMSEContentTypeWrong() { mFlags.Set(CDConfigFlags::kCMSEContentType); }
    void SetCMSSignatureWrong() { mFlags.Set(CDConfigFlags::kCMSSignature); }

    bool IsErrorTestCaseEnabled() { return mEnabled; }
    bool IsFormatVersionPresent() { return (!mEnabled || !mFlags.Has(CDConfigFlags::kFormatVersionMissing)); }
    uint8_t GetFormatVersion() { return (mEnabled && mFlags.Has(CDConfigFlags::kFormatVersionWrong)) ? 2 : 1; }
    bool IsVIDPresent() { return (!mEnabled || !mFlags.Has(CDConfigFlags::kVIDMissing)); }
    bool IsVIDCorrect() { return (!mEnabled || !mFlags.Has(CDConfigFlags::kVIDWrong)); }
    bool IsPIDArrayPresent() { return (!mEnabled || !mFlags.Has(CDConfigFlags::kPIDArrayMissing)); }
    bool IsPIDArrayCorrect() { return (!mEnabled || !mFlags.Has(CDConfigFlags::kPIDArrayWrong)); }
    uint8_t GetPIDArrayCount() const { return mPIDArrayCount; }
    bool IsDeviceTypeIdPresent() { return (!mEnabled || !mFlags.Has(CDConfigFlags::kDeviceTypeIdMissing)); }
    bool IsDeviceTypeIdCorrect() { return (!mEnabled || !mFlags.Has(CDConfigFlags::kDeviceTypeIdWrong)); }
    bool IsCertIdPresent() { return (!mEnabled || !mFlags.Has(CDConfigFlags::kCertIdMissing)); }
    bool IsCertIdCorrect() { return (!mEnabled || !mFlags.Has(CDConfigFlags::kCertIdWrong)); }
    bool IsCertIdLenCorrect() { return (!mEnabled || !mFlags.Has(CDConfigFlags::kCertIdLenWrong)); }
    bool IsSecurityLevelPresent() { return (!mEnabled || !mFlags.Has(CDConfigFlags::kSecurityLevelMissing)); }
    bool IsSecurityLevelCorrect() { return (!mEnabled || !mFlags.Has(CDConfigFlags::kSecurityLevelWrong)); }
    bool IsSecurityInfoPresent() { return (!mEnabled || !mFlags.Has(CDConfigFlags::kSecurityInfoMissing)); }
    bool IsSecurityInfoCorrect() { return (!mEnabled || !mFlags.Has(CDConfigFlags::kSecurityInfoWrong)); }
    bool IsVersionNumberPresent() { return (!mEnabled || !mFlags.Has(CDConfigFlags::kVersionNumberMissing)); }
    bool IsVersionNumberCorrect() { return (!mEnabled || !mFlags.Has(CDConfigFlags::kVersionNumberWrong)); }
    bool IsCertTypePresent() { return (!mEnabled || !mFlags.Has(CDConfigFlags::kCertTypeMissing)); }
    bool IsCertTypeCorrect() { return (!mEnabled || !mFlags.Has(CDConfigFlags::kCertTypeWrong)); }
    bool IsDACOriginVIDCorrect() { return (!mEnabled || !mFlags.Has(CDConfigFlags::kDACOriginVID)); }
    bool IsDACOriginPIDCorrect() { return (!mEnabled || !mFlags.Has(CDConfigFlags::kDACOriginPID)); }
    bool IsDACOriginVIDPresent() { return (mEnabled && mFlags.Has(CDConfigFlags::kDACOriginVIDPresent)); }
    bool IsDACOriginPIDPresent() { return (mEnabled && mFlags.Has(CDConfigFlags::kDACOriginPIDPresent)); }
    bool IsAuthPAAListPresent() { return (mFlags.Has(CDConfigFlags::kAuthPAAListPresent)); }
    bool IsAuthPAAListCorrect() { return (!mEnabled || !mFlags.Has(CDConfigFlags::kAuthPAAListWrong)); }
    uint8_t GetAuthPAAListCount() const { return mAuthPAAListCount; }
    bool IsSignerInfoVersionCorrect() { return (!mEnabled || !mFlags.Has(CDConfigFlags::kSignerInfoVersion)); }
    bool IsSignerInfoDigestAlgoCorrect() { return (!mEnabled || !mFlags.Has(CDConfigFlags::kSignerInfoDigestAlgo)); }
    bool IsSignerInfoSKIDCorrect() { return (!mEnabled || !mFlags.Has(CDConfigFlags::kSignerInfoSKID)); }
    bool IsCMSVersionCorrect() { return (!mEnabled || !mFlags.Has(CDConfigFlags::kCMSVersion)); }
    bool IsCMSDigestAlgoCorrect() { return (!mEnabled || !mFlags.Has(CDConfigFlags::kCMSDigestAlgo)); }
    bool IsCMSSigAlgoCorrect() { return (!mEnabled || !mFlags.Has(CDConfigFlags::kCMSSigAlgo)); }
    bool IsCMSEContentTypeCorrect() { return (!mEnabled || !mFlags.Has(CDConfigFlags::kCMSEContentType)); }
    bool IsCMSSignatureCorrect() { return (!mEnabled || !mFlags.Has(CDConfigFlags::kCMSSignature)); }

private:
    enum class CDConfigFlags : uint64_t
    {
        kFormatVersionMissing = 0x0000000000000001,
        kFormatVersionWrong   = 0x0000000000000002,
        kVIDMissing           = 0x0000000000000004,
        kVIDWrong             = 0x0000000000000008,
        kPIDArrayMissing      = 0x0000000000000010,
        kPIDArrayWrong        = 0x0000000000000020,
        kDeviceTypeIdMissing  = 0x0000000000000040,
        kDeviceTypeIdWrong    = 0x0000000000000080,
        kCertIdMissing        = 0x0000000000000100,
        kCertIdWrong          = 0x0000000000000200,
        kCertIdLenWrong       = 0x0000000000000400,
        kSecurityLevelMissing = 0x0000000000000800,
        kSecurityLevelWrong   = 0x0000000000001000,
        kSecurityInfoMissing  = 0x0000000000002000,
        kSecurityInfoWrong    = 0x0000000000004000,
        kVersionNumberMissing = 0x0000000000008000,
        kVersionNumberWrong   = 0x0000000000010000,
        kCertTypeMissing      = 0x0000000000020000,
        kCertTypeWrong        = 0x0000000000040000,
        kDACOriginVID         = 0x0000000000080000,
        kDACOriginPID         = 0x0000000000100000,
        kDACOriginVIDPresent  = 0x0000000000200000,
        kDACOriginPIDPresent  = 0x0000000000400000,
        kAuthPAAListPresent   = 0x0000000000800000,
        kAuthPAAListWrong     = 0x0000000001000000,
        kSignerInfoVersion    = 0x0000000002000000,
        kSignerInfoDigestAlgo = 0x0000000004000000,
        kSignerInfoSKID       = 0x0000000008000000,
        kCMSVersion           = 0x0000000010000000,
        kCMSDigestAlgo        = 0x0000000020000000,
        kCMSSigAlgo           = 0x0000000040000000,
        kCMSEContentType      = 0x0000000080000000,
        kCMSSignature         = 0x0000000100000000,
    };

    bool mEnabled = false;
    chip::BitFlags<CDConfigFlags> mFlags;
    uint8_t mPIDArrayCount    = 1;
    uint8_t mAuthPAAListCount = 1;
};

CertificationElements gCertElements;
const char * gCertFileNameOrStr = nullptr;
const char * gKeyFileNameOrStr  = nullptr;
const char * gSignedCDFileName  = nullptr;
CDStructConfig gCDConfig;

bool ExtractSKIDFromX509Cert(X509 * cert, ByteSpan & skid)
{
    const ASN1_OCTET_STRING * skidString = X509_get0_subject_key_id(cert);
    VerifyOrReturnError(skidString != nullptr, false);
    VerifyOrReturnError(skidString->length == kKeyIdentifierLength, false);
    VerifyOrReturnError(CanCastTo<size_t>(skidString->length), false);
    skid = ByteSpan(skidString->data, static_cast<size_t>(skidString->length));
    return true;
};

bool HandleOption(const char * progName, OptionSet * optSet, int id, const char * name, const char * arg)
{
    switch (id)
    {
    case 'C':
        gCertFileNameOrStr = arg;
        break;
    case 'K':
        gKeyFileNameOrStr = arg;
        break;
    case 'O':
        gSignedCDFileName = arg;
        break;
    case 'f':
        if (!ParseInt(arg, gCertElements.FormatVersion, 16))
        {
            PrintArgError("%s: Invalid value specified for Format Version: %s\n", progName, arg);
            return false;
        }
        break;
    case 'V':
        if (!ParseInt(arg, gCertElements.VendorId, 16) || gCertElements.VendorId == 0)
        {
            PrintArgError("%s: Invalid value specified for Vendor Id: %s\n", progName, arg);
            return false;
        }
        break;
    case 'p':
        if (gCertElements.ProductIdsCount == ArraySize(gCertElements.ProductIds))
        {
            PrintArgError("%s: Too many Product Ids are specified: %s\n", progName, arg);
            return false;
        }
        if (!ParseInt(arg, gCertElements.ProductIds[gCertElements.ProductIdsCount], 16) ||
            gCertElements.ProductIds[gCertElements.ProductIdsCount] == 0)
        {
            PrintArgError("%s: Invalid value specified for Product Id: %s\n", progName, arg);
            return false;
        }
        gCertElements.ProductIdsCount++;
        break;
    case 'd':
        if (!ParseInt(arg, gCertElements.DeviceTypeId, 16))
        {
            PrintArgError("%s: Invalid value specified for Device Type Id: %s\n", progName, arg);
            return false;
        }
        break;
    case 'c':
        if (strlen(arg) != kCertificateIdLength)
        {
            PrintArgError("%s: Invalid value specified for Certificate Id: %s\n", progName, arg);
            return false;
        }
        memcpy(gCertElements.CertificateId, arg, strlen(arg));
        gCertElements.CertificateId[kCertificateIdLength] = '\0';
        break;
    case 'l':
        if (!ParseInt(arg, gCertElements.SecurityLevel, 16))
        {
            PrintArgError("%s: Invalid value specified for Security Level: %s\n", progName, arg);
            return false;
        }
        break;
    case 'i':
        if (!ParseInt(arg, gCertElements.SecurityInformation, 16))
        {
            PrintArgError("%s: Invalid value specified for Security Information: %s\n", progName, arg);
            return false;
        }
        break;
    case 'n':
        if (!ParseInt(arg, gCertElements.VersionNumber, 16))
        {
            PrintArgError("%s: Invalid value specified for Version Number: %s\n", progName, arg);
            return false;
        }
        break;
    case 't':
        if (!ParseInt(arg, gCertElements.CertificationType) || gCertElements.CertificationType > 2)
        {
            PrintArgError("%s: Invalid value specified for Certification Type: %s\n", progName, arg);
            return false;
        }
        break;
    case 'o':
        if (!ParseInt(arg, gCertElements.DACOriginVendorId, 16) || gCertElements.DACOriginVendorId == 0)
        {
            PrintArgError("%s: Invalid value specified for DAC Origin Vendor Id: %s\n", progName, arg);
            return false;
        }
        gCertElements.DACOriginVIDandPIDPresent = true;
        break;
    case 'r':
        if (!ParseInt(arg, gCertElements.DACOriginProductId, 16) || gCertElements.DACOriginProductId == 0)
        {
            PrintArgError("%s: Invalid value specified for DAC Origin Product Id: %s\n", progName, arg);
            return false;
        }
        gCertElements.DACOriginVIDandPIDPresent = true;
        break;
    case 'a':
        if (gCertElements.AuthorizedPAAListCount >= ArraySize(gCertElements.AuthorizedPAAList))
        {
            PrintArgError("%s: Too many Authorized PAA Certificates are specified: %s\n", progName, arg);
            return false;
        }
        {
            const char * fileNameOrStr = arg;
            std::unique_ptr<X509, void (*)(X509 *)> cert(nullptr, &X509_free);
            VerifyOrReturnError(ReadCert(fileNameOrStr, cert), false);

            ByteSpan skid;
            VerifyOrReturnError(ExtractSKIDFromX509Cert(cert.get(), skid), false);
            memcpy(gCertElements.AuthorizedPAAList[gCertElements.AuthorizedPAAListCount++], skid.data(), skid.size());
        }
        break;
#if CHIP_CONFIG_INTERNAL_FLAG_GENERATE_DA_TEST_CASES
    case 'I':
        gCDConfig.EnableErrorTestCase();
        break;
    case 'E':
        if (strcmp(arg, "format-version-missing") == 0)
        {
            gCDConfig.SetFormatVersionMissing();
        }
        else if (strcmp(arg, "format-version-wrong") == 0)
        {
            gCDConfig.SetFormatVersionWrong();
        }
        else if (strcmp(arg, "vid-missing") == 0)
        {
            gCDConfig.SetVIDMissing();
        }
        else if (strcmp(arg, "vid-mismatch") == 0)
        {
            gCDConfig.SetVIDWrong();
        }
        else if (strcmp(arg, "pid-array-missing") == 0)
        {
            gCDConfig.SetPIDArrayMissing();
        }
        else if (strcmp(arg, "pid-array-count0") == 0)
        {
            gCDConfig.SetPIDArrayCount(0);
        }
        else if (strcmp(arg, "pid-array-count01-valid") == 0)
        {
            gCDConfig.SetPIDArrayCount(1);
        }
        else if (strcmp(arg, "pid-array-count01-mismatch") == 0)
        {
            gCDConfig.SetPIDArrayCount(1);
            gCDConfig.SetPIDArrayWrong();
        }
        else if (strcmp(arg, "pid-array-count10-valid") == 0)
        {
            gCDConfig.SetPIDArrayCount(10);
        }
        else if (strcmp(arg, "pid-array-count10-mismatch") == 0)
        {
            gCDConfig.SetPIDArrayCount(10);
            gCDConfig.SetPIDArrayWrong();
        }
        else if (strcmp(arg, "pid-array-count100-valid") == 0)
        {
            gCDConfig.SetPIDArrayCount(100);
        }
        else if (strcmp(arg, "pid-array-count100-mismatch") == 0)
        {
            gCDConfig.SetPIDArrayCount(100);
            gCDConfig.SetPIDArrayWrong();
        }
        else if (strcmp(arg, "device-type-id-missing") == 0)
        {
            gCDConfig.SetDeviceTypeIdMissing();
        }
        else if (strcmp(arg, "device-type-id-mismatch") == 0)
        {
            gCDConfig.SetDeviceTypeIdWrong();
        }
        else if (strcmp(arg, "cert-id-missing") == 0)
        {
            gCDConfig.SetCertIdMissing();
        }
        else if (strcmp(arg, "cert-id-mismatch") == 0)
        {
            gCDConfig.SetCertIdWrong();
        }
        else if (strcmp(arg, "cert-id-len-wrong") == 0)
        {
            gCDConfig.SetCertIdLenWrong();
        }
        else if (strcmp(arg, "security-level-missing") == 0)
        {
            gCDConfig.SetSecurityLevelMissing();
        }
        else if (strcmp(arg, "security-level-wrong") == 0)
        {
            gCDConfig.SetSecurityLevelWrong();
        }
        else if (strcmp(arg, "security-info-missing") == 0)
        {
            gCDConfig.SetSecurityInfoMissing();
        }
        else if (strcmp(arg, "security-info-wrong") == 0)
        {
            gCDConfig.SetSecurityInfoWrong();
        }
        else if (strcmp(arg, "version-number-missing") == 0)
        {
            gCDConfig.SetVersionNumberMissing();
        }
        else if (strcmp(arg, "version-number-wrong") == 0)
        {
            gCDConfig.SetVersionNumberWrong();
        }
        else if (strcmp(arg, "cert-type-missing") == 0)
        {
            gCDConfig.SetCertTypeMissing();
        }
        else if (strcmp(arg, "cert-type-wrong") == 0)
        {
            gCDConfig.SetCertTypeWrong();
        }
        else if (strcmp(arg, "dac-origin-vid-present") == 0)
        {
            gCDConfig.SetDACOriginVIDPresent();
        }
        else if (strcmp(arg, "dac-origin-pid-present") == 0)
        {
            gCDConfig.SetDACOriginPIDPresent();
        }
        else if (strcmp(arg, "dac-origin-vid-pid-present") == 0)
        {
            gCDConfig.SetDACOriginVIDPresent();
            gCDConfig.SetDACOriginPIDPresent();
        }
        else if (strcmp(arg, "dac-origin-vid-mismatch") == 0)
        {
            gCDConfig.SetDACOriginVIDPresent();
            gCDConfig.SetDACOriginPIDPresent();
            gCDConfig.SetDACOriginVIDWrong();
        }
        else if (strcmp(arg, "dac-origin-pid-mismatch") == 0)
        {
            gCDConfig.SetDACOriginVIDPresent();
            gCDConfig.SetDACOriginPIDPresent();
            gCDConfig.SetDACOriginPIDWrong();
        }
        else if (strcmp(arg, "different-origin") == 0)
        {
            gCDConfig.SetDACOriginVIDPresent();
            gCDConfig.SetDACOriginPIDPresent();
        }
        else if (strcmp(arg, "authorized-paa-list-count0") == 0)
        {
            gCDConfig.SetAuthPAAListPresent();
            gCDConfig.SetAuthPAAListCount(0);
        }
        else if (strcmp(arg, "authorized-paa-list-count1-valid") == 0)
        {
            gCDConfig.SetAuthPAAListPresent();
            gCDConfig.SetAuthPAAListCount(1);
        }
        else if (strcmp(arg, "authorized-paa-list-count2-valid") == 0)
        {
            gCDConfig.SetAuthPAAListPresent();
            gCDConfig.SetAuthPAAListCount(2);
        }
        else if (strcmp(arg, "authorized-paa-list-count3-invalid") == 0)
        {
            gCDConfig.SetAuthPAAListCount(3);
            gCDConfig.SetAuthPAAListPresent();
            gCDConfig.SetAuthPAAListWrong();
        }
        else if (strcmp(arg, "authorized-paa-list-count10-valid") == 0)
        {
            gCDConfig.SetAuthPAAListPresent();
            gCDConfig.SetAuthPAAListCount(10);
        }
        else if (strcmp(arg, "authorized-paa-list-count10-invalid") == 0)
        {
            gCDConfig.SetAuthPAAListCount(10);
            gCDConfig.SetAuthPAAListPresent();
            gCDConfig.SetAuthPAAListWrong();
        }
        else if (strcmp(arg, "signer-info-v2") == 0)
        {
            gCDConfig.SetSignerInfoVersionWrong();
        }
        else if (strcmp(arg, "signer-info-digest-algo") == 0)
        {
            gCDConfig.SetSignerInfoDigestAlgoWrong();
        }
        else if (strcmp(arg, "signer-info-skid") == 0)
        {
            gCDConfig.SetSignerInfoSKIDWrong();
        }
        else if (strcmp(arg, "cms-v2") == 0)
        {
            gCDConfig.SetCMSVersionWrong();
        }
        else if (strcmp(arg, "cms-digest-algo") == 0)
        {
            gCDConfig.SetCMSDigestAlgoWrong();
        }
        else if (strcmp(arg, "cms-sig-algo") == 0)
        {
            gCDConfig.SetCMSSigAlgoWrong();
        }
        else if (strcmp(arg, "cms-econtent-type") == 0)
        {
            gCDConfig.SetCMSEContentTypeWrong();
        }
        else if (strcmp(arg, "cms-sig") == 0)
        {
            gCDConfig.SetCMSSignatureWrong();
        }
        else if (strcmp(arg, "no-error") != 0)
        {
            PrintArgError("%s: Invalid value specified for the error type: %s\n", progName, arg);
            return false;
        }
        break;
#endif
    default:
        PrintArgError("%s: Unhandled option: %s\n", progName, name);
        return false;
    }

    return true;
}

static constexpr uint8_t sOID_ContentType_PKCS7Data[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x01 };
static constexpr uint8_t sOID_ContentType_MSAC[]      = { 0x06, 0x0A, 0x2B, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x02, 0x01, 0x04 };
static constexpr uint8_t sOID_ContentType_PKCS7SignedData[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x02 };
static constexpr uint8_t sOID_DigestAlgo_SHA256[]           = { 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01 };
static constexpr uint8_t sOID_DigestAlgo_SHA1[]             = { 0x2B, 0x0E, 0x03, 0x02, 0x1A };
static constexpr uint8_t sOID_SigAlgo_ECDSAWithSHA1[]       = { 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x01 };

/** Certification Declaration Element TLV Tags
 */
enum
{
    kTag_FormatVersion       = 0,  /**< [ unsigned int ] Format version. */
    kTag_VendorId            = 1,  /**< [ unsigned int ] Vedor identifier. */
    kTag_ProductIdArray      = 2,  /**< [ array ] Product identifiers (each is unsigned int). */
    kTag_DeviceTypeId        = 3,  /**< [ unsigned int ] Device Type identifier. */
    kTag_CertificateId       = 4,  /**< [ UTF-8 string, length 19 ] Certificate identifier. */
    kTag_SecurityLevel       = 5,  /**< [ unsigned int ] Security level. */
    kTag_SecurityInformation = 6,  /**< [ unsigned int ] Security information. */
    kTag_VersionNumber       = 7,  /**< [ unsigned int ] Version number. */
    kTag_CertificationType   = 8,  /**< [ unsigned int ] Certification Type. */
    kTag_DACOriginVendorId   = 9,  /**< [ unsigned int, optional ] DAC origin vendor identifier. */
    kTag_DACOriginProductId  = 10, /**< [ unsigned int, optional ] DAC origin product identifier. */
    kTag_AuthorizedPAAList   = 11, /**< [ array, optional ] Authorized PAA List. */
};

CHIP_ERROR EncodeCertificationElements_Ignore_Error(const CertificationElements & certElements,
                                                    MutableByteSpan & encodedCertElements, CDStructConfig & cdConfig)
{
    TLVWriter writer;
    TLVType outerContainer1, outerContainer2;

    writer.Init(encodedCertElements);

    ReturnErrorOnFailure(writer.StartContainer(AnonymousTag(), kTLVType_Structure, outerContainer1));

    if (cdConfig.IsFormatVersionPresent())
    {
        ReturnErrorOnFailure(writer.Put(ContextTag(kTag_FormatVersion), cdConfig.GetFormatVersion()));
    }
    if (cdConfig.IsVIDPresent())
    {
        if (cdConfig.IsVIDCorrect())
        {
            ReturnErrorOnFailure(writer.Put(ContextTag(kTag_VendorId), certElements.VendorId));
        }
        else
        {
            ReturnErrorOnFailure(writer.Put(ContextTag(kTag_VendorId), static_cast<uint16_t>(certElements.VendorId ^ UINT16_MAX)));
        }
    }
    if (cdConfig.IsPIDArrayPresent())
    {
        ReturnErrorOnFailure(writer.StartContainer(ContextTag(kTag_ProductIdArray), kTLVType_Array, outerContainer2));
        uint16_t pid =
            cdConfig.IsPIDArrayCorrect() ? certElements.ProductIds[0] : static_cast<uint16_t>(certElements.ProductIds[0] + 1);
        for (uint8_t i = 0; i < cdConfig.GetPIDArrayCount(); i++)
        {
            ReturnErrorOnFailure(writer.Put(AnonymousTag(), static_cast<uint16_t>(pid++)));
        }
        ReturnErrorOnFailure(writer.EndContainer(outerContainer2));
    }
    if (cdConfig.IsDeviceTypeIdPresent())
    {
        if (cdConfig.IsDeviceTypeIdCorrect())
        {
            ReturnErrorOnFailure(writer.Put(ContextTag(kTag_DeviceTypeId), certElements.DeviceTypeId));
        }
        else
        {
            ReturnErrorOnFailure(
                writer.Put(ContextTag(kTag_DeviceTypeId), static_cast<uint32_t>(certElements.DeviceTypeId ^ UINT32_MAX)));
        }
    }
    if (cdConfig.IsCertIdPresent())
    {
        if (cdConfig.IsCertIdCorrect() && cdConfig.IsCertIdLenCorrect())
        {
            ReturnErrorOnFailure(writer.PutString(ContextTag(kTag_CertificateId), certElements.CertificateId));
        }
        else if (!cdConfig.IsCertIdCorrect())
        {
            ReturnErrorOnFailure(writer.PutString(ContextTag(kTag_CertificateId), "INV20141ZB330001-24"));
        }
        else
        {
            std::string cert_id(certElements.CertificateId);
            cert_id += "1234";
            ReturnErrorOnFailure(writer.PutString(ContextTag(kTag_CertificateId), cert_id.c_str()));
        }
    }
    if (cdConfig.IsSecurityLevelPresent())
    {
        if (cdConfig.IsSecurityLevelCorrect())
        {
            ReturnErrorOnFailure(writer.Put(ContextTag(kTag_SecurityLevel), certElements.SecurityLevel));
        }
        else
        {
            ReturnErrorOnFailure(
                writer.Put(ContextTag(kTag_SecurityLevel), static_cast<uint8_t>(certElements.SecurityLevel ^ UINT8_MAX)));
        }
    }
    if (cdConfig.IsSecurityInfoPresent())
    {
        if (cdConfig.IsSecurityInfoCorrect())
        {
            ReturnErrorOnFailure(writer.Put(ContextTag(kTag_SecurityInformation), certElements.SecurityInformation));
        }
        else
        {
            ReturnErrorOnFailure(writer.Put(ContextTag(kTag_SecurityInformation),
                                            static_cast<uint16_t>(certElements.SecurityInformation ^ UINT16_MAX)));
        }
    }
    if (cdConfig.IsVersionNumberPresent())
    {
        if (cdConfig.IsVersionNumberCorrect())
        {
            ReturnErrorOnFailure(writer.Put(ContextTag(kTag_VersionNumber), certElements.VersionNumber));
        }
        else
        {
            ReturnErrorOnFailure(
                writer.Put(ContextTag(kTag_VersionNumber), static_cast<uint16_t>(certElements.VersionNumber ^ UINT16_MAX)));
        }
    }
    if (cdConfig.IsCertTypePresent())
    {
        if (cdConfig.IsCertTypeCorrect())
        {
            ReturnErrorOnFailure(writer.Put(ContextTag(kTag_CertificationType), certElements.CertificationType));
        }
        else
        {
            ReturnErrorOnFailure(
                writer.Put(ContextTag(kTag_CertificationType), static_cast<uint8_t>(certElements.CertificationType ^ UINT8_MAX)));
        }
    }
    if (cdConfig.IsDACOriginVIDPresent())
    {
        if (cdConfig.IsDACOriginVIDCorrect() && certElements.DACOriginVIDandPIDPresent)
        {
            ReturnErrorOnFailure(writer.Put(ContextTag(kTag_DACOriginVendorId), certElements.DACOriginVendorId));
        }
        else
        {
            uint16_t wrong_dac_origin_vid = 0x8008;
            ReturnErrorOnFailure(writer.Put(ContextTag(kTag_DACOriginVendorId), wrong_dac_origin_vid));
        }
    }
    if (cdConfig.IsDACOriginPIDPresent())
    {
        if (cdConfig.IsDACOriginPIDCorrect() && certElements.DACOriginVIDandPIDPresent)
        {
            ReturnErrorOnFailure(writer.Put(ContextTag(kTag_DACOriginProductId), certElements.DACOriginProductId));
        }
        else
        {
            uint16_t wrong_dac_origin_pid = 0xFF00;
            ReturnErrorOnFailure(writer.Put(ContextTag(kTag_DACOriginProductId), wrong_dac_origin_pid));
        }
    }
    if (cdConfig.IsAuthPAAListPresent())
    {
        ReturnErrorOnFailure(writer.StartContainer(ContextTag(kTag_AuthorizedPAAList), kTLVType_Array, outerContainer2));
        uint8_t wrong_kid[kKeyIdentifierLength] = { 0xF4, 0x44, 0xCA, 0xBB, 0xC5, 0x01, 0x65, 0x77, 0xAA, 0x8B,
                                                    0x44, 0xFF, 0xB9, 0x0F, 0xCC, 0xA1, 0x40, 0xFE, 0x66, 0x20 };
        for (uint8_t i = 0; i < cdConfig.GetAuthPAAListCount(); i++)
        {
            if (cdConfig.IsAuthPAAListCorrect() && (i < certElements.AuthorizedPAAListCount))
            {
                ReturnErrorOnFailure(writer.Put(AnonymousTag(), ByteSpan(certElements.AuthorizedPAAList[i])));
            }
            else
            {
                wrong_kid[(i % kKeyIdentifierLength)] ^= 0xFF;
                ReturnErrorOnFailure(writer.Put(AnonymousTag(), ByteSpan(wrong_kid)));
            }
        }
        ReturnErrorOnFailure(writer.EndContainer(outerContainer2));
    }

    ReturnErrorOnFailure(writer.EndContainer(outerContainer1));

    ReturnErrorOnFailure(writer.Finalize());

    encodedCertElements.reduce_size(writer.GetLengthWritten());

    return CHIP_NO_ERROR;
}

CHIP_ERROR EncodeEncapsulatedContent_Ignor_Error(const ByteSpan & cdContent, ASN1Writer & writer, CDStructConfig & cdConfig)
{
    /**
     * EncapsulatedContentInfo ::= SEQUENCE {
     *   eContentType OBJECT IDENTIFIER pkcs7-data (1.2.840.113549.1.7.1),
     *   eContent [0] EXPLICIT OCTET STRING cd_content }
     */
    CHIP_ERROR err = CHIP_NO_ERROR;

    ASN1_START_SEQUENCE
    {
        // eContentType OBJECT IDENTIFIER pkcs7-data (1.2.840.113549.1.7.1)
        if (cdConfig.IsCMSEContentTypeCorrect())
        {
            ReturnErrorOnFailure(writer.PutObjectId(sOID_ContentType_PKCS7Data, sizeof(sOID_ContentType_PKCS7Data)));
        }
        else
        {
            ReturnErrorOnFailure(writer.PutObjectId(sOID_ContentType_MSAC, sizeof(sOID_ContentType_MSAC)));
        }

        // eContent [0] EXPLICIT OCTET STRING cd_content
        ASN1_START_CONSTRUCTED(kASN1TagClass_ContextSpecific, 0)
        {
            // OCTET STRING cd_content
            ReturnErrorOnFailure(writer.PutOctetString(cdContent.data(), static_cast<uint16_t>(cdContent.size())));
        }
        ASN1_END_CONSTRUCTED;
    }
    ASN1_END_SEQUENCE;

exit:
    return err;
}

CHIP_ERROR EncodeSignerInfo_Ignor_Error(const ByteSpan & signerKeyId, const P256ECDSASignature & signature, ASN1Writer & writer,
                                        CDStructConfig & cdConfig)
{
    /**
     * SignerInfo ::= SEQUENCE {
     *   version INTEGER ( v3(3) ),
     *   subjectKeyIdentifier OCTET STRING,
     *   digestAlgorithm OBJECT IDENTIFIER sha256 (2.16.840.1.101.3.4.2.1),
     *   signatureAlgorithm OBJECT IDENTIFIER ecdsa-with-SHA256 (1.2.840.10045.4.3.2),
     *   signature OCTET STRING }
     */
    CHIP_ERROR err = CHIP_NO_ERROR;

    ASN1_START_SET
    {
        ASN1_START_SEQUENCE
        {
            // version INTEGER ( v3(3) )
            ASN1_ENCODE_INTEGER(cdConfig.IsSignerInfoVersionCorrect() ? 3 : 2);

            // subjectKeyIdentifier OCTET STRING
            if (cdConfig.IsSignerInfoSKIDCorrect())
            {
                ReturnErrorOnFailure(writer.PutOctetString(kASN1TagClass_ContextSpecific, 0, signerKeyId.data(),
                                                           static_cast<uint16_t>(signerKeyId.size())));
            }
            else
            {
                uint8_t wrong_skid[kKeyIdentifierLength];
                memcpy(wrong_skid, signerKeyId.data(), signerKeyId.size());
                wrong_skid[7] ^= 0xFF;
                ReturnErrorOnFailure(writer.PutOctetString(kASN1TagClass_ContextSpecific, 0, wrong_skid, sizeof(wrong_skid)));
            }

            // digestAlgorithm OBJECT IDENTIFIER sha256 (2.16.840.1.101.3.4.2.1)
            ASN1_START_SEQUENCE
            {
                if (cdConfig.IsSignerInfoDigestAlgoCorrect())
                {
                    ReturnErrorOnFailure(writer.PutObjectId(sOID_DigestAlgo_SHA256, sizeof(sOID_DigestAlgo_SHA256)));
                }
                else
                {
                    ReturnErrorOnFailure(writer.PutObjectId(sOID_DigestAlgo_SHA1, sizeof(sOID_DigestAlgo_SHA1)));
                }
            }
            ASN1_END_SEQUENCE;

            // signatureAlgorithm OBJECT IDENTIFIER ecdsa-with-SHA256 (1.2.840.10045.4.3.2)
            ASN1_START_SEQUENCE
            {
                if (cdConfig.IsCMSSigAlgoCorrect())
                {
                    ASN1_ENCODE_OBJECT_ID(kOID_SigAlgo_ECDSAWithSHA256);
                }
                else
                {
                    ReturnErrorOnFailure(writer.PutObjectId(sOID_SigAlgo_ECDSAWithSHA1, sizeof(sOID_SigAlgo_ECDSAWithSHA1)));
                }
            }
            ASN1_END_SEQUENCE;

            uint8_t asn1SignatureBuf[kMax_ECDSA_Signature_Length_Der];
            MutableByteSpan asn1Signature(asn1SignatureBuf);
            ReturnErrorOnFailure(ConvertECDSASignatureRawToDER(P256ECDSASignatureSpan(signature.ConstBytes()), asn1Signature));

            if (!cdConfig.IsCMSSignatureCorrect())
            {
                asn1SignatureBuf[10] ^= 0xFF;
            }

            // signature OCTET STRING
            ReturnErrorOnFailure(writer.PutOctetString(asn1Signature.data(), static_cast<uint16_t>(asn1Signature.size())));
        }
        ASN1_END_SEQUENCE;
    }
    ASN1_END_SET;

exit:
    return err;
}

CHIP_ERROR CMS_Sign_Ignore_Error(const ByteSpan & cdContent, const ByteSpan & signerKeyId, Crypto::P256Keypair & signerKeypair,
                                 MutableByteSpan & signedMessage, CDStructConfig & cdConfig)
{
    /**
     * CertificationDeclaration ::= SEQUENCE {
     *   version INTEGER ( v3(3) ),
     *   digestAlgorithm OBJECT IDENTIFIER sha256 (2.16.840.1.101.3.4.2.1),
     *   encapContentInfo EncapsulatedContentInfo,
     *   signerInfo SignerInfo }
     */
    CHIP_ERROR err = CHIP_NO_ERROR;
    ASN1Writer writer;
    uint32_t size = static_cast<uint32_t>(std::min(static_cast<size_t>(UINT32_MAX), signedMessage.size()));

    writer.Init(signedMessage.data(), size);

    ASN1_START_SEQUENCE
    {
        // OID identifies the CMS signed-data content type
        ReturnErrorOnFailure(writer.PutObjectId(sOID_ContentType_PKCS7SignedData, sizeof(sOID_ContentType_PKCS7SignedData)));

        ASN1_START_CONSTRUCTED(kASN1TagClass_ContextSpecific, 0)
        {
            ASN1_START_SEQUENCE
            {
                // version INTEGER ( v3(3) )
                ASN1_ENCODE_INTEGER(cdConfig.IsCMSVersionCorrect() ? 3 : 2);

                // digestAlgorithm OBJECT IDENTIFIER sha256 (2.16.840.1.101.3.4.2.1)
                ASN1_START_SET
                {
                    ASN1_START_SEQUENCE
                    {
                        if (cdConfig.IsCMSDigestAlgoCorrect())
                        {
                            ReturnErrorOnFailure(writer.PutObjectId(sOID_DigestAlgo_SHA256, sizeof(sOID_DigestAlgo_SHA256)));
                        }
                        else
                        {
                            ReturnErrorOnFailure(writer.PutObjectId(sOID_DigestAlgo_SHA1, sizeof(sOID_DigestAlgo_SHA1)));
                        }
                    }
                    ASN1_END_SEQUENCE;
                }
                ASN1_END_SET;

                // encapContentInfo EncapsulatedContentInfo
                ReturnErrorOnFailure(EncodeEncapsulatedContent_Ignor_Error(cdContent, writer, cdConfig));

                Crypto::P256ECDSASignature signature;
                ReturnErrorOnFailure(signerKeypair.ECDSA_sign_msg(cdContent.data(), cdContent.size(), signature));

                // signerInfo SignerInfo
                ReturnErrorOnFailure(EncodeSignerInfo_Ignor_Error(signerKeyId, signature, writer, cdConfig));
            }
            ASN1_END_SEQUENCE;
        }
        ASN1_END_CONSTRUCTED;
    }
    ASN1_END_SEQUENCE;

    signedMessage.reduce_size(writer.GetLengthWritten());

exit:
    return err;
}

} // namespace

bool Cmd_GenCD(int argc, char * argv[])
{
    if (argc == 1)
    {
        gHelpOptions.PrintBriefUsage(stderr);
        return true;
    }

    VerifyOrReturnError(ParseArgs(CMD_NAME, argc, argv, gCmdOptionSets), false);

    if (gCDConfig.IsErrorTestCaseEnabled())
    {
        fprintf(stderr,
                "WARNING gen-cd: The ignor-error option is set. This option makes it possible to generate invalid certification "
                "declaration.\n");
    }

    if (gKeyFileNameOrStr == nullptr)
    {
        fprintf(stderr, "Please specify the signing private key using the --key option.\n");
        return false;
    }

    if (gCertFileNameOrStr == nullptr)
    {
        fprintf(stderr, "Please specify the signing certificate using the --cert option.\n");
        return false;
    }

    if (gSignedCDFileName == nullptr)
    {
        fprintf(stderr, "Please specify the file name for the signed Certification Declaration using the --out option.\n");
        return false;
    }

    if (strcmp(gSignedCDFileName, "-") != 0 && access(gSignedCDFileName, R_OK) == 0)
    {
        fprintf(stderr,
                "Output signed CD file already exists (%s)\n"
                "To replace the file, please remove it and re-run the command.\n",
                gSignedCDFileName);
        return false;
    }

    if (!gCDConfig.IsErrorTestCaseEnabled())
    {
        if (gCertElements.VendorId == 0 || gCertElements.ProductIdsCount == 0 || strlen(gCertElements.CertificateId) == 0 ||
            gCertElements.VersionNumber == 0)
        {
            fprintf(stderr, "Please specify all mandatory CD elements.\n");
            return false;
        }

        if (gCertElements.DACOriginVIDandPIDPresent &&
            (gCertElements.DACOriginVendorId == 0 || gCertElements.DACOriginProductId == 0))
        {
            fprintf(stderr, "The DAC Origin Vendor Id and Product Id SHALL be specified together.\n");
            return false;
        }
    }

    {
        std::unique_ptr<X509, void (*)(X509 *)> cert(nullptr, &X509_free);
        std::unique_ptr<EVP_PKEY, void (*)(EVP_PKEY *)> key(EVP_PKEY_new(), &EVP_PKEY_free);

        VerifyOrReturnError(ReadCert(gCertFileNameOrStr, cert), false);
        VerifyOrReturnError(ReadKey(gKeyFileNameOrStr, key), false);

        // Extract the subject key id from the X509 certificate.
        ByteSpan signerKeyId;
        VerifyOrReturnError(ExtractSKIDFromX509Cert(cert.get(), signerKeyId), false);

        // Initialize P256Keypair from EVP_PKEY.
        P256Keypair keypair;
        {
            P256SerializedKeypair serializedKeypair;
            VerifyOrReturnError(SerializeKeyPair(key.get(), serializedKeypair), false);
            VerifyOrReturnError(keypair.Deserialize(serializedKeypair) == CHIP_NO_ERROR, false);
        }

        // Encode CD TLV content.
        uint8_t encodedCDBuf[kCertificationElements_TLVEncodedMaxLength];
        MutableByteSpan encodedCD(encodedCDBuf);
        if (gCDConfig.IsErrorTestCaseEnabled())
        {
            VerifyOrReturnError(EncodeCertificationElements_Ignore_Error(gCertElements, encodedCD, gCDConfig) == CHIP_NO_ERROR,
                                false);
        }
        else
        {
            VerifyOrReturnError(EncodeCertificationElements(gCertElements, encodedCD) == CHIP_NO_ERROR, false);
        }

        // Sign CD.
        uint8_t signedMessageBuf[kMaxCMSSignedCDMessage];
        MutableByteSpan signedMessage(signedMessageBuf);
        if (gCDConfig.IsErrorTestCaseEnabled())
        {
            VerifyOrReturnError(CMS_Sign_Ignore_Error(encodedCD, signerKeyId, keypair, signedMessage, gCDConfig) == CHIP_NO_ERROR,
                                false);
        }
        else
        {
            VerifyOrReturnError(CMS_Sign(encodedCD, signerKeyId, keypair, signedMessage) == CHIP_NO_ERROR, false);
        }

        // Write to file.
        VerifyOrReturnError(WriteDataIntoFile(gSignedCDFileName, signedMessage.data(), static_cast<uint32_t>(signedMessage.size()),
                                              kDataFormat_Raw),
                            false);
    }
    return true;
}
