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

SII Chile - FRMT Signature Computation and Add to XML

See more XML Digital Signatures Examples

Compute the FRMT signature and add to the XML. This is the RSA signature of the SHA-1 digest of the "flattened" DD element.

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 FRMA 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>
    //                     <FRMA algoritmo="SHA1withRSA">...</FRMA>
    //                 </CAF>
    //                 ...
    //             </DD>
    //             ... The FRMT will be added here in another example ...
    //         </TED>
    //   </Documento>
    // </DTE>

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

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

    //  We need to get the "flattened" DD 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();
    dd_xml.setEmitCompact(true);
    dd_xml.setEmitXmlDecl(false);
    dd_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 FRMT signature element to the XML.
    xml.updateChildContent("Documento|TED|FRMT", sig);
    xml.updateAttrAt("Documento|TED|FRMT", true, "algoritmo", "SHA1withRSA") catch {};

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