Sample code for 30+ languages & platforms
Zig Requires Chilkat v11.0.0+

SII Chile - FRMA Signature Computation and Add to XML

See more XML Digital Signatures Examples

Compute the FRMA signature of a <DA> element enclosed inside a <CAF> element of the XML to be signed.

Chilkat Zig Downloads

Zig
const std = @import("std");
const chilkat = @import("chilkat");

pub fn main(init: std.process.Init) !void {
    const alloc = init.arena.allocator();

    // This example assumes the Chilkat API to have been previously unlocked.
    // See Global Unlock Sample for sample code.

    // Also see:  Compute the FRMT Signature and Add to XML

    const xml = try chilkat.Xml.init();
    defer xml.deinit();

    // Load the unsigned XML that contains the following:

    // <DTE version="1.0">
    //   <Documento ID="F60T33">
    //         <TED version="1.0">
    //             <DD>
    //         ...
    //                 <CAF version="1.0">
    //                     <DA>
    //             ...
    //                     </DA>
    //             ... The FRMA will be added here ...
    //                 </CAF>
    //                 ...
    //             </DD>
    //             ... The FRMT will be added here in another example ...
    //         </TED>
    //   </Documento>
    // </DTE>

    xml.loadXmlFile("qa_data/xml_dsig/sii_cl/test_0.xml") catch {
        std.debug.print("Failed to load initial XML file.\n", .{});
        return;
    };

    // Get a reference to the "DA" element
    const da_xml = xml.findChild("Documento|TED|DD|CAF|DA") catch {
        std.debug.print("Failed to find DA element\n", .{});
        return;
    };
    defer da_xml.deinit();

    //  We need to get the "flattened" DA XML where:
    //    - No whitespace between elements.
    //    - The 5 pre-defined entities are converted.
    //    - The text is encoded in the ISO-8859-1 character set (Latin-1),
    const sb_flattened = try chilkat.StringBuilder.init();
    defer sb_flattened.deinit();
    da_xml.setEmitCompact(true);
    da_xml.setEmitXmlDecl(false);
    da_xml.getXmlSb(sb_flattened) catch {};

    // Compute the SHA-1 message digest of the iso-8859-1 byte representation,
    // and sign it with our RSA private key, getting the result in base64 format.

    const priv_key = try chilkat.PrivateKey.init();
    defer priv_key.deinit();
    priv_key.loadAnyFormatFile("qa_data/rsa/rsaPrivKey_pkcs8.pem", "") catch {
        std.debug.print("{s}\n", .{try priv_key.getLastErrorText(alloc)});
        return;
    };

    const rsa = try chilkat.Rsa.init();
    defer rsa.deinit();
    rsa.usePrivateKey(priv_key) catch {};

    rsa.setEncodingMode("base64");
    rsa.setCharset("iso-8859-1");
    const sig = try rsa.signStringENC(alloc, try sb_flattened.getAsString(alloc), "sha1");

    // Add the FRMA signature element to the XML.
    xml.updateChildContent("Documento|TED|DD|CAF|FRMA", sig);
    xml.updateAttrAt("Documento|TED|DD|CAF|FRMA", true, "algoritmo", "SHA1withRSA") catch {};

    // See what we have:
    xml.setEmitCompact(false);
    xml.setEmitXmlDecl(true);
    std.debug.print("{s}\n", .{try xml.getXml(alloc)});

    xml.saveXml("qa_data/xml_dsig/sii_cl/test_1.xml") catch {};
}