Sample code for 30+ languages & platforms
Rust

TicketBAI Sign XML Example 2

See more TicketBAI Examples

Second example to demonstrate how to sign XML for TicketBAI.

Chilkat Rust Downloads

Rust

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

let _ = true;
// Create the XML to be signed...
let xml_to_sign = chilkat::Xml::new();
xml_to_sign.set_tag("T:TicketBai");
let _ = xml_to_sign.add_attribute("xmlns:T", "urn:ticketbai:emision");
xml_to_sign.update_child_content("Cabecera|IDVersionTBAI", "1.2");
xml_to_sign.update_child_content("Sujetos|Emisor|NIF", "79732487C");
xml_to_sign.update_child_content("Sujetos|Emisor|ApellidosNombreRazonSocial", "ARRIOLA LEJARDI ANE");
xml_to_sign.update_child_content("Sujetos|Destinatarios|IDDestinatario|NIF", "A48012363");
xml_to_sign.update_child_content("Sujetos|Destinatarios|IDDestinatario|ApellidosNombreRazonSocial", "ACADEMIA ESKOLA");
xml_to_sign.update_child_content("Factura|CabeceraFactura|SerieFactura", "A2022");
xml_to_sign.update_child_content("Factura|CabeceraFactura|NumFactura", "0400");
xml_to_sign.update_child_content("Factura|CabeceraFactura|FechaExpedicionFactura", "12-05-2022");
xml_to_sign.update_child_content("Factura|CabeceraFactura|HoraExpedicionFactura", "12:20:15");
xml_to_sign.update_child_content("Factura|DatosFactura|DescripcionFactura", "Venta maquinaria y existencias");
xml_to_sign.update_child_content("Factura|DatosFactura|ImporteTotalFactura", "1936.00");
xml_to_sign.update_child_content("Factura|DatosFactura|Claves|IDClave|ClaveRegimenIvaOpTrascendencia", "01");
xml_to_sign.update_child_content("Factura|TipoDesglose|DesgloseFactura|Sujeta|NoExenta|DetalleNoExenta|TipoNoExenta", "S1");
xml_to_sign.update_child_content("Factura|TipoDesglose|DesgloseFactura|Sujeta|NoExenta|DetalleNoExenta|DesgloseIVA|DetalleIVA|BaseImponible", "1600.00");
xml_to_sign.update_child_content("Factura|TipoDesglose|DesgloseFactura|Sujeta|NoExenta|DetalleNoExenta|DesgloseIVA|DetalleIVA|TipoImpositivo", "21.00");
xml_to_sign.update_child_content("Factura|TipoDesglose|DesgloseFactura|Sujeta|NoExenta|DetalleNoExenta|DesgloseIVA|DetalleIVA|CuotaImpuesto", "336.00");
xml_to_sign.update_child_content("HuellaTBAI|EncadenamientoFacturaAnterior|SerieFacturaAnterior", "A2022");
xml_to_sign.update_child_content("HuellaTBAI|EncadenamientoFacturaAnterior|NumFacturaAnterior", "0399");
xml_to_sign.update_child_content("HuellaTBAI|EncadenamientoFacturaAnterior|FechaExpedicionFacturaAnterior", "06-05-2022");
xml_to_sign.update_child_content("HuellaTBAI|EncadenamientoFacturaAnterior|SignatureValueFirmaFacturaAnterior", "KdxKFNXeNJuBZNjgvKEa9lICamXs9MHuin6R+yuFHZw9aMewuBvdhaMr7g0eUz8aNYEa1elpCTr7aLgVZjQrFQK/TjIg353iAVxA");
xml_to_sign.update_child_content("HuellaTBAI|Software|LicenciaTBAI", "TBAIPRUEBA");
xml_to_sign.update_child_content("HuellaTBAI|Software|EntidadDesarrolladora|NIF", "A48119820");
xml_to_sign.update_child_content("HuellaTBAI|Software|Nombre", "DFBTBAI");
xml_to_sign.update_child_content("HuellaTBAI|Software|Version", "1.04.00");
xml_to_sign.update_child_content("HuellaTBAI|NumSerieDispositivo", "GP4FC5J");

let gen_ = chilkat::XmlDSigGen::new();

gen_.set_sig_location("T:TicketBai");
gen_.set_sig_location_mod(0);
gen_.set_sig_id("Signature-43861174-a0e6-45f9-afbf-8b48c46c6c13-Signature");
gen_.set_sig_namespace_prefix("ds");
gen_.set_sig_namespace_uri("http://www.w3.org/2000/09/xmldsig#");
gen_.set_sig_value_id("Signature-43861174-a0e6-45f9-afbf-8b48c46c6c13-SignatureValue");
gen_.set_signed_info_canon_alg("C14N");
gen_.set_signed_info_digest_method("sha256");

// Set the KeyInfoId before adding references..
gen_.set_key_info_id("Signature-43861174-a0e6-45f9-afbf-8b48c46c6c13-KeyInfo");

// Create an Object to be added to the Signature.
let object1 = chilkat::Xml::new();
object1.set_tag("xades:QualifyingProperties");
let _ = object1.add_attribute("xmlns:xades", "http://uri.etsi.org/01903/v1.3.2#");
let _ = object1.add_attribute("Id", "Signature-43861174-a0e6-45f9-afbf-8b48c46c6c13-QualifyingProperties");
let _ = object1.add_attribute("Target", "#Signature-43861174-a0e6-45f9-afbf-8b48c46c6c13-Signature");
let _ = object1.add_attribute("xmlns:ds", "http://www.w3.org/2000/09/xmldsig#");
let _ = object1.update_attr_at("xades:SignedProperties", true, "Id", "Signature-43861174-a0e6-45f9-afbf-8b48c46c6c13-SignedProperties");
object1.update_child_content("xades:SignedProperties|xades:SignedSignatureProperties|xades:SigningTime", "TO BE GENERATED BY CHILKAT");
let _ = object1.update_attr_at("xades:SignedProperties|xades:SignedSignatureProperties|xades:SigningCertificateV2|xades:Cert|xades:CertDigest|ds:DigestMethod", true, "Algorithm", "http://www.w3.org/2001/04/xmlenc#sha512");
object1.update_child_content("xades:SignedProperties|xades:SignedSignatureProperties|xades:SigningCertificateV2|xades:Cert|xades:CertDigest|ds:DigestValue", "TO BE GENERATED BY CHILKAT");
object1.update_child_content("xades:SignedProperties|xades:SignedSignatureProperties|xades:SigningCertificateV2|xades:Cert|xades:IssuerSerialV2", "TO BE GENERATED BY CHILKAT");
object1.update_child_content("xades:SignedProperties|xades:SignedSignatureProperties|xades:SignaturePolicyIdentifier|xades:SignaturePolicyId|xades:SigPolicyId|xades:Identifier", "https://www.batuz.eus/fitxategiak/batuz/ticketbai/sinadura_elektronikoaren_zehaztapenak_especificaciones_de_la_firma_electronica_v1_0.pdf");
object1.update_child_content("xades:SignedProperties|xades:SignedSignatureProperties|xades:SignaturePolicyIdentifier|xades:SignaturePolicyId|xades:SigPolicyId|xades:Description", "");
let _ = object1.update_attr_at("xades:SignedProperties|xades:SignedSignatureProperties|xades:SignaturePolicyIdentifier|xades:SignaturePolicyId|xades:SigPolicyHash|ds:DigestMethod", true, "Algorithm", "http://www.w3.org/2001/04/xmlenc#sha256");
object1.update_child_content("xades:SignedProperties|xades:SignedSignatureProperties|xades:SignaturePolicyIdentifier|xades:SignaturePolicyId|xades:SigPolicyHash|ds:DigestValue", "Quzn98x3PMbSHwbUzaj5f5KOpiH0u8bvmwbbbNkO9Es=");
object1.update_child_content("xades:SignedProperties|xades:SignedSignatureProperties|xades:SignaturePolicyIdentifier|xades:SignaturePolicyId|xades:SigPolicyQualifiers|xades:SigPolicyQualifier|xades:SPURI", "https://www.batuz.eus/fitxategiak/batuz/ticketbai/sinadura_elektronikoaren_zehaztapenak_especificaciones_de_la_firma_electronica_v1_0.pdf");
let _ = object1.update_attr_at("xades:SignedProperties|xades:SignedDataObjectProperties|xades:DataObjectFormat", true, "ObjectReference", "#Reference-43b5c8a3-7ce0-4056-bdbe-d2076d8ac825");
object1.update_child_content("xades:SignedProperties|xades:SignedDataObjectProperties|xades:DataObjectFormat|xades:Description", "");
let _ = object1.update_attr_at("xades:SignedProperties|xades:SignedDataObjectProperties|xades:DataObjectFormat|xades:ObjectIdentifier|xades:Identifier", true, "Qualifier", "OIDAsURN");
object1.update_child_content("xades:SignedProperties|xades:SignedDataObjectProperties|xades:DataObjectFormat|xades:ObjectIdentifier|xades:Identifier", "urn:oid:1.2.840.10003.5.109.10");
object1.update_child_content("xades:SignedProperties|xades:SignedDataObjectProperties|xades:DataObjectFormat|xades:ObjectIdentifier|xades:Description", "");
object1.update_child_content("xades:SignedProperties|xades:SignedDataObjectProperties|xades:DataObjectFormat|xades:MimeType", "text/xml");
object1.update_child_content("xades:SignedProperties|xades:SignedDataObjectProperties|xades:DataObjectFormat|xades:Encoding", "");

let _ = gen_.add_object("", &object1.get_xml().unwrap_or_default(), "", "");

// -------- Reference 1 --------
let _ = gen_.add_same_doc_ref("", "sha512", "C14N", "", "http://www.w3.org/2000/09/xmldsig#Object");
let _ = gen_.set_ref_id_attr("", "Reference-43b5c8a3-7ce0-4056-bdbe-d2076d8ac825");

// -------- Reference 2 --------
let _ = gen_.add_object_ref("Signature-43861174-a0e6-45f9-afbf-8b48c46c6c13-SignedProperties", "sha512", "", "", "http://uri.etsi.org/01903#SignedProperties");

// -------- Reference 3 --------
let _ = gen_.add_same_doc_ref("Signature-43861174-a0e6-45f9-afbf-8b48c46c6c13-KeyInfo", "sha512", "", "", "");

// Provide a certificate + private key. (PFX password is test123)
let cert = chilkat::Cert::new();
if cert.load_pfx_file("qa_data/pfx/cert_test123.pfx", "test123").is_err() {
    println!("{}", cert.last_error_text());
    return;
}

let _ = gen_.set_x509_cert(&cert, true);

gen_.set_key_info_type("X509Data+KeyValue");
gen_.set_x509_type("Certificate");

// Load XML to be signed...
let sb_xml = chilkat::StringBuilder::new();
let _ = xml_to_sign.get_xml_sb(&sb_xml);

gen_.set_behaviors("IndentedSignature,TransformSignatureXPath");

// Sign the XML...
if gen_.create_xml_d_sig_sb(&sb_xml).is_err() {
    println!("{}", gen_.last_error_text());
    return;
}

// -----------------------------------------------

// Save the signed XML to a file.
let _ = sb_xml.write_file("qa_output/signedXml_2.xml", "utf-8", false).is_ok();

println!("{}", sb_xml.get_as_string().unwrap_or_default());

// ----------------------------------------
// Verify the signatures we just produced...
let verifier = chilkat::XmlDSig::new();
if verifier.load_signature_sb(&sb_xml).is_err() {
    println!("{}", verifier.last_error_text());
    return;
}

let num_sigs = verifier.num_signatures();
let mut verify_idx = 0;
while verify_idx < num_sigs {
    verifier.set_selector(verify_idx);
    if verifier.verify_signature(true).is_err() {
        println!("{}", verifier.last_error_text());
        return;
    }

    verify_idx = verify_idx + 1;
}

println!("All signatures were successfully verified.");