Error in simulation mode and code review

my config file is oid_section = OIDs
[OIDs]
certificateTemplateName = 1.3.6.1.4.1.311.20.2
[req]
default_bits = 2048
emailAddress = ahmedtarekya100@email.com
req_extensions = req_ext
prompt = no
default_md = sha256
distinguished_name = dn

[v3_req]
basicConstraints = CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment

[req_ext]
certificateTemplateName = ASN1:PRINTABLESTRING:SET_PRODUCTION_VALUE
subjectAltName = dirName:alt_names

[ dir_sect ]
SN = SET_EGS_SERIAL_NUMBER
UID = SET_VAT_REGISTRATION_NUMBER
title = 0100
registeredAddress = SET_BRANCH_LOCATION
businessCategory = SET_BRANCH_INDUSTRY

[alt_names]
SN = 1-solution_name|2-IOS|3-6f4d20e0-6bfe-4a80-9389-7dabe6620f12
UID = 302217339400003
title = 0100
registeredAddress = 3192 صاري فرعي, الخيبر
businessCategory = Food

[dn]
commonName = SET_COMMON_NAME
organizationalUnitName = SET_BRANCH_NAME
organizationName = SET_TAXPAYER_NAME
countryName = SA and code to update the config and sign the invoice public function generateNewKeysAndCSR(string $solution_name) // توليد الشهادة وتتم عن طريق خطوتين
{
$private_key = $this->generateSecp256k1KeyPair();
return [$private_key, $this->generateCSR($solution_name, $private_key)];
}

private function generateSecp256k1KeyPair() // انشاء برايفت كي علشان اقدر اطلب توقيع شهادة
{
    // Run the OpenSSL command to generate the private key
    $output = PHP_OS_FAMILY === 'Windows'
        ? shell_exec('openssl ecparam -name secp256k1 -genkey')
        : $this->runOpenSslProcess();

    // Extract the private key from the OpenSSL output
    return $this->extractPrivateKey($output);
}

private function runOpenSslProcess(): string
{
    $process = Process::fromShellCommandline('openssl ecparam -name secp256k1 -genkey');
    $process->run();

    // Check if the process was successful
    if (!$process->isSuccessful()) {
        throw new Exception('Failed to generate private key: ' . $process->getErrorOutput());
    }

    return $process->getOutput();
}

private function extractPrivateKey(string $output): string
{
    $result = explode('-----BEGIN EC PRIVATE KEY-----', $output);
    if (!isset($result[1])) {
        throw new Exception('No private key found in OpenSSL output.');
    }

    return "-----BEGIN EC PRIVATE KEY-----\n" . trim($result[1]);
}

private function generateCSR(string $solution_name, $private_key)
{
    if (!$private_key) {
        throw new Exception('EGS has no private key');
    }

    // Ensure the temporary directory exists
    $tmp_dir = base_path('public/tmp');
    if (!is_dir($tmp_dir)) {
        mkdir($tmp_dir, 0775, true); // Recursive directory creation
    }

    // Generate unique file names for private key and CSR config
    $private_key_file_name = $tmp_dir . '/' . $this->uuid() . '.pem';
    $csr_config_file_name = $tmp_dir . '/' . $this->uuid() . '.cnf';

    // Write the private key and CSR configuration to temporary files
    file_put_contents($private_key_file_name, $private_key);
    file_put_contents($csr_config_file_name, $this->defaultCSRConfig($solution_name));

    // Generate the CSR using OpenSSL
    $csr = PHP_OS_FAMILY === 'Windows'
        ? $this->generateCSRWindows($private_key_file_name, $csr_config_file_name)
        : $this->generateCSRProcess($private_key_file_name, $csr_config_file_name);

    // Directory where CSR will be stored
    $csr_dir = base_path('public/csr');
    if (!is_dir($csr_dir)) {
        mkdir($csr_dir, 0775, true); // Recursive directory creation
    }

    // Generate unique file name for the CSR
    $csr_file_name = $csr_dir . '/' . $this->uuid() . '.csr';

    // Save the CSR to the file
    file_put_contents($csr_file_name, $csr);

    return $csr;
}

private function generateCSRWindows(string $private_key_file_name, string $csr_config_file_name): string
{
    $output = shell_exec("openssl req -new -sha256 -key $private_key_file_name -config $csr_config_file_name 2>&1");
    return $this->extractCSR($output);
}

private function generateCSRProcess(string $private_key_file_name, string $csr_config_file_name): string
{
    $process = Process::fromShellCommandline("openssl req -new -sha256 -key $private_key_file_name -config $csr_config_file_name");
    $process->run();

    // Check if the process was successful
    if (!$process->isSuccessful()) {
        throw new Exception('Failed to generate CSR: ' . $process->getErrorOutput());
    }

    return $this->extractCSR($process->getOutput());
}

private function extractCSR(string $output): string
{
    $result = explode('-----BEGIN CERTIFICATE REQUEST-----', $output);
    if (!isset($result[1])) {
        throw new Exception('No CSR found in OpenSSL output.');
    }

    return "-----BEGIN CERTIFICATE REQUEST-----" . $result[1];
}


public static function uuid(): string // انشاء رقم فريد لكل عملية
{
    return sprintf('%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
        // 32 bits for "time_low"
        random_int(0, 0xffff), random_int(0, 0xffff),

        // 16 bits for "time_mid"
        random_int(0, 0xffff),

        // 16 bits for "time_hi_and_version",
        // four most significant bits holds version number 4
        random_int(0, 0x0fff) | 0x4000,

        // 16 bits, 8 bits for "clk_seq_hi_res",
        // 8 bits for "clk_seq_low",
        // two most significant bits holds zero and one for variant DCE1.1
        random_int(0, 0x3fff) | 0x8000,

        // 48 bits for "node"
        random_int(0, 0xffff), random_int(0, 0xffff), random_int(0, 0xffff)
    );
}

private function defaultCSRConfig(string $solution_name)
{
    $egs_unit = $this->egs_info();
    $config = [
        'egs_model' => $egs_unit['model'] ?? 'IOS',
        'egs_serial_number' => $egs_unit['uuid'] ?? $this->uuid(),
        'solution_name' => $solution_name,
        'vat_number' => $egs_unit['VAT_number'],
        'branch_location' => $egs_unit['location']['building'] . ' ' . $egs_unit['location']['street'] . ', ' . $egs_unit['location']['city'],
        'branch_industry' => $egs_unit['branch_industry'],
        'branch_name' => $egs_unit['branch_name'],
        'taxpayer_name' => $egs_unit['VAT_name'],
        'taxpayer_provided_id' => $egs_unit['custom_id'] ?? 'EGS1-886431145',
        'production' => $egs_unit['production']
    ];

    $template_csr = require base_path('public/ZATCA/templates/csr_template.php');;
    if ($config['production'] == 1){
        $sign = "ZATCA-Code-Signing";
    }
    else if ($config['production'] == 0){
        $sign = "TSTZATCA-Code-Signing";
    }
    else{
        $sign = "PREZATCA-Code-Signing";
    }

// dd($sign);
$template_csr = str_replace(‘SET_PRIVATE_KEY_PASS’, ($config[‘private_key_pass’] ?? ‘SET_PRIVATE_KEY_PASS’), $template_csr);
$template_csr = str_replace(‘SET_PRODUCTION_VALUE’, $sign, $template_csr);
$template_csr = str_replace(‘SET_EGS_SERIAL_NUMBER’, “1-{$config[‘solution_name’]}|2-{$config[‘egs_model’]}|3-{$config[‘egs_serial_number’]}”, $template_csr);
$template_csr = str_replace(‘SET_VAT_REGISTRATION_NUMBER’, $config[‘vat_number’], $template_csr);
$template_csr = str_replace(‘SET_BRANCH_LOCATION’, $config[‘branch_location’], $template_csr);
$template_csr = str_replace(‘SET_BRANCH_INDUSTRY’, $config[‘branch_industry’], $template_csr);
$template_csr = str_replace(‘SET_COMMON_NAME’, $config[‘taxpayer_provided_id’] ?? $config[‘vat_number’], $template_csr);
$template_csr = str_replace(‘SET_BRANCH_NAME’, $config[‘branch_name’], $template_csr);
$template_csr = str_replace(‘SET_TAXPAYER_NAME’, $config[‘taxpayer_name’], $template_csr);

    return $template_csr;
}

public function issueComplianceCertificate(string $otp, $csr) // اصدار شهادة التوقيع
{
    if (!$csr) throw new Exception('EGS needs to generate a CSR first.');
    list($issueCertificate, $checkInvoiceCompliance) = $this->compliance();
    $issued_data = $issueCertificate($csr, $otp);
    return [$issued_data->requestID, $issued_data->binarySecurityToken, $issued_data->secret];
}

public function signInvoice(array $invoice, array $egs_unit, string $certificate, string $private_key) // توقيع الشهادة
{
    require base_path('public/ZATCA/ZATCASimplifiedTaxInvoice.php');
    $zatca_simplified_tax_invoice = new ZATCASimplifiedTaxInvoice();
    $invoice_xml = $zatca_simplified_tax_invoice->simplifiedTaxInvoice($invoice, $egs_unit);
    $invoice_hash = $zatca_simplified_tax_invoice->getInvoiceHash($invoice_xml);
    list($hash, $issuer, $serialNumber, $public_key, $signature)
        = $zatca_simplified_tax_invoice->getCertificateInfo($certificate);
    $digital_signature = $zatca_simplified_tax_invoice->createInvoiceDigitalSignature($invoice_hash, $private_key);

    $qr = $zatca_simplified_tax_invoice->generateQR(
        $invoice_xml,
        $digital_signature,
        $public_key,
        $signature,
        $invoice_hash
    );

    $signed_properties_props = [
        'sign_timestamp' => date('Y-m-d\TH:i:s\Z'),
        'certificate_hash' => $hash, // SignedSignatureProperties/SigningCertificate/CertDigest/<ds:DigestValue>SET_CERTIFICATE_HASH</ds:DigestValue>
        'certificate_issuer' => $issuer,
        'certificate_serial_number' => $serialNumber
    ];
    $ubl_signature_signed_properties_xml_string_for_signing = $zatca_simplified_tax_invoice->defaultUBLExtensionsSignedPropertiesForSigning($signed_properties_props);
    $ubl_signature_signed_properties_xml_string = $zatca_simplified_tax_invoice->defaultUBLExtensionsSignedProperties($signed_properties_props);

    $signed_properties_hash = base64_encode(openssl_digest($ubl_signature_signed_properties_xml_string_for_signing, 'sha256'));
    // UBL Extensions



    $ubl_signature_xml_string = $zatca_simplified_tax_invoice->defaultUBLExtensions(
        $invoice_hash, // <ds:DigestValue>SET_INVOICE_HASH</ds:DigestValue>
        $signed_properties_hash, // SignatureInformation/Signature/SignedInfo/Reference/<ds:DigestValue>SET_SIGNED_PROPERTIES_HASH</ds:DigestValue>
        $digital_signature,
        $certificate,
        $ubl_signature_signed_properties_xml_string
    );

    // Set signing elements
    $unsigned_invoice_str = $invoice_xml->saveXML();

    $unsigned_invoice_str = str_replace('SET_UBL_EXTENSIONS_STRING', $ubl_signature_xml_string, $unsigned_invoice_str);
    $unsigned_invoice_str = str_replace('SET_QR_CODE_DATA', $qr, $unsigned_invoice_str);

    $signed_invoice = new DOMDocument();
    $signed_invoice->loadXML($unsigned_invoice_str);

    $signed_invoice_string = $signed_invoice->saveXML();
    //$signed_invoice_string = $zatca_simplified_tax_invoice->signedPropertiesIndentationFix($signed_invoice_string);

    // Define the directory and file path
    $directory_path = storage_path('invoices');
    $name = $invoice['invoice_serial_number'];
    $file_path = $directory_path . "/invoice{$name}.xml";

    // Create the directory if it doesn't exist
    if (!file_exists($directory_path)) {
        mkdir($directory_path, 0777, true);
    }

    // Save the signed invoice XML to a file
    file_put_contents($file_path, $signed_invoice_string);


    return [$signed_invoice_string, $invoice_hash, $qr,"/invoice{$name}.xml"];
} what is wrong in simulation mode ?

Dear @AhmedTarekYA

Thanks for reaching out,

Can I kindly ask you to collaborate more in the specific tag in your .cnf file “certificateTemplateName = ASN1:PRINTABLESTRING:SET_PRODUCTION_VALUE”, to ensure comprehensive support as usual.

Thanks,
Ibrahem Daoud.

SET_PRODUCTION_VALUE is a php placeholder so when i create the csr it will be PREZATCA-Code-Signing

so my config file will be like oid_section = OIDs\r\n [OIDs]\r\n certificateTemplateName = 1.3.6.1.4.1.311.20.2\r\n [req]\r\n default_bits = 2048\r\n emailAddress = ahmedtarekya100@email.com\r\n req_extensions = req_ext\r\n x509_extensions =v3_ca\r\n prompt = no\r\n default_md = sha256\r\n distinguished_name = dn\r\n \r\n [v3_ca]\r\n # Extensions for a typical CA\r\n subjectKeyIdentifier=hash\r\n authorityKeyIdentifier=keyid,issuer\r\n basicConstraints = CA:true\r\n keyUsage = digitalSignature, keyCertSign, cRLSign\r\n \r\n [v3_req]\r\n basicConstraints = CA:FALSE\r\n keyUsage = digitalSignature, nonRepudiation, keyEncipherment\r\n \r\n [req_ext]\r\n certificateTemplateName = ASN1:PRINTABLESTRING:PREZATCA-Code-Signing\r\n subjectAltName = dirName:alt_names\r\n \r\n [ dir_sect ]\r\n SN = 1-solution_name|2-IOS|3-6f4d20e0-6bfe-4a80-9389-7dabe6620f12\r\n UID = 302217339400003\r\n title = 0100\r\n registeredAddress = 3192 صاري فرعي, الخيبر\r\n businessCategory = Food\r\n \r\n [alt_names]\r\n SN = 1-solution_name|2-IOS|3-6f4d20e0-6bfe-4a80-9389-7dabe6620f12\r\n UID = 302217339400003\r\n title = 0100\r\n registeredAddress = 3192 صاري فرعي, الخيبر\r\n businessCategory = Food\r\n \r\n [dn]\r\n commonName = EGS1-886431145\r\n organizationalUnitName = فرع الامير محمد\r\n organizationName = مؤسسة شبكات رموز لتقنية المعلومات\r\n countryName = SA