Sample code for 30+ languages & platforms
Lua

XML-DSig Add Reference with Transforms Specified Explicitly

Demonstrates how to use the new AddSameDocRef2 method to explicitly specify the XML Transforms fragment.

Chilkat Lua Downloads

Lua
local chilkat = require("chilkat")

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

local success = true

-- Create the following XML to be signed:

-- <doc>
--     <s id="s1">Some text...</s>
--     <p>Some text...</p>
--     <p class="note">A note...</p>
-- </doc>

-- Use this online tool to generate code from sample XML:
-- Generate Code to Create XML

local xmlToSign = chilkat.Xml.new()
xmlToSign.tag = "doc"
xmlToSign:update_attr_at("s", true, "id", "s1")
xmlToSign:update_child_content("s", "Some text...")
xmlToSign:update_child_content("p", "Some text...")
xmlToSign:update_attr_at("p[1]", true, "class", "note")
xmlToSign:update_child_content("p[1]", "A note...")

print(xmlToSign:get_xml())

local gen = chilkat.XmlDSigGen.new()

gen.sig_location = "doc"
gen.sig_location_mod = 0
gen.sig_id = "Signature-78f29839-06af-448f-b479-ca46457fab1b-Signature"
gen.sig_namespace_prefix = "ds"
gen.sig_namespace_uri = "http://www.w3.org/2000/09/xmldsig#"
gen.sig_value_id = "Signature-78f29839-06af-448f-b479-ca46457fab1b-SignatureValue"
gen.signed_info_canon_alg = "C14N"
gen.signed_info_digest_method = "sha1"

-- Set the KeyInfoId before adding references..
gen.key_info_id = "Signature-78f29839-06af-448f-b479-ca46457fab1b-KeyInfo"

-- The following XML to be added as an Object to the Signature

-- Use this online tool to generate code from sample XML:
-- Generate Code to Create XML

-- <xades:QualifyingProperties Id="Signature-78f29839-06af-448f-b479-ca46457fab1b-QualifyingProperties" Target="#Signature-78f29839-06af-448f-b479-ca46457fab1b-Signature" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:xades="http://uri.etsi.org/01903/v1.3.2#">
--     <xades:SignedProperties Id="Signature-78f29839-06af-448f-b479-ca46457fab1b-SignedProperties">
--         <xades:SignedSignatureProperties>
--             <xades:SigningTime>TO BE GENERATED BY CHILKAT</xades:SigningTime>
--             <xades:SigningCertificate>
--                 <xades:Cert>
--                     <xades:CertDigest>
--                         <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
--                         <ds:DigestValue>TO BE GENERATED BY CHILKAT</ds:DigestValue>
--                     </xades:CertDigest>
--                     <xades:IssuerSerial>
--                         <ds:X509IssuerName>TO BE GENERATED BY CHILKAT</ds:X509IssuerName>
--                         <ds:X509SerialNumber>TO BE GENERATED BY CHILKAT</ds:X509SerialNumber>
--                     </xades:IssuerSerial>
--                 </xades:Cert>
--             </xades:SigningCertificate>
--         </xades:SignedSignatureProperties>
--         <xades:SignedDataObjectProperties>
--             <xades:DataObjectFormat ObjectReference="#Reference-24eb6003-d41c-442c-a731-d4c58f94790b">
--                 <xades:Description/>
--                 <xades:ObjectIdentifier>
--                     <xades:Identifier Qualifier="OIDAsURN">urn:oid:1.2.840.10003.5.109.10</xades:Identifier>
--                     <xades:Description/>
--                 </xades:ObjectIdentifier>
--                 <xades:MimeType>text/xml</xades:MimeType>
--                 <xades:Encoding/>
--             </xades:DataObjectFormat>
--         </xades:SignedDataObjectProperties>
--     </xades:SignedProperties>
-- </xades:QualifyingProperties>

local object1 = chilkat.Xml.new()
object1.tag = "xades:QualifyingProperties"
object1:add_attribute("Id", "Signature-78f29839-06af-448f-b479-ca46457fab1b-QualifyingProperties")
object1:add_attribute("Target", "#Signature-78f29839-06af-448f-b479-ca46457fab1b-Signature")
object1:add_attribute("xmlns:ds", "http://www.w3.org/2000/09/xmldsig#")
object1:add_attribute("xmlns:xades", "http://uri.etsi.org/01903/v1.3.2#")
object1:update_attr_at("xades:SignedProperties", true, "Id", "Signature-78f29839-06af-448f-b479-ca46457fab1b-SignedProperties")
object1:update_child_content("xades:SignedProperties|xades:SignedSignatureProperties|xades:SigningTime", "TO BE GENERATED BY CHILKAT")
-- Note: It may be that http://www.w3.org/2001/04/xmlenc#sha256 is needed in the following line instead of http://www.w3.org/2000/09/xmldsig#sha1
object1:update_attr_at("xades:SignedProperties|xades:SignedSignatureProperties|xades:SigningCertificateV2|xades:Cert|xades:CertDigest|ds:DigestMethod", true, "Algorithm", "http://www.w3.org/2000/09/xmldsig#sha1")
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_attr_at("xades:SignedProperties|xades:SignedDataObjectProperties|xades:DataObjectFormat", true, "ObjectReference", "#Reference-24eb6003-d41c-442c-a731-d4c58f94790b")
object1:update_child_content("xades:SignedProperties|xades:SignedDataObjectProperties|xades:DataObjectFormat|xades:Description", "")
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", "")

print(object1:get_xml())

gen:add_object("", object1:get_xml(), "", "")

-- -------- Reference 1 --------

-- Create the following Transforms fragment:

-- Use this online tool to generate code from sample XML:
-- Generate Code to Create XML

-- <ds:Transforms>
--     <ds:Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
--     <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
--     <ds:Transform Algorithm="http://www.w3.org/TR/1999/REC-xpath-19991116">
--         <ds:XPath xmlns:ds="http://www.w3.org/2000/09/xmldsig#">not(ancestor-or-self::ds:Signature)</ds:XPath>
--     </ds:Transform>
-- </ds:Transforms>

local xml1 = chilkat.Xml.new()
xml1.tag = "ds:Transforms"
xml1:update_attr_at("ds:Transform", true, "Algorithm", "http://www.w3.org/TR/2001/REC-xml-c14n-20010315")
xml1:update_attr_at("ds:Transform[1]", true, "Algorithm", "http://www.w3.org/2000/09/xmldsig#enveloped-signature")
xml1:update_attr_at("ds:Transform[2]", true, "Algorithm", "http://www.w3.org/TR/1999/REC-xpath-19991116")
xml1:update_attr_at("ds:Transform[2]|ds:XPath", true, "xmlns:ds", "http://www.w3.org/2000/09/xmldsig#")
xml1:update_child_content("ds:Transform[2]|ds:XPath", "not(ancestor-or-self::ds:Signature)")

-- This is the "Transforms" XML fragment passed to AddSameDocRef2.
print(xml1:get_xml())

gen:add_same_doc_ref2("", "sha1", xml1, "")

gen:set_ref_id_attr("", "Reference-24eb6003-d41c-442c-a731-d4c58f94790b")

-- -------- Reference 2 --------
gen:add_object_ref("Signature-78f29839-06af-448f-b479-ca46457fab1b-SignedProperties", "sha1", "", "", "http://uri.etsi.org/01903#SignedProperties")

-- -------- Reference 3 --------
gen:add_same_doc_ref("Signature-78f29839-06af-448f-b479-ca46457fab1b-KeyInfo", "sha1", "", "", "")

-- Provide a certificate + private key. (PFX password is test123)
local cert = chilkat.Cert.new()
success = cert:load_pfx_file("qa_data/pfx/cert_test123.pfx", "test123")
if not success then
    print(cert.last_error_text)
    return
end

gen:set_x509_cert(cert, true)

gen.key_info_type = "X509Data+KeyValue"
gen.x509_type = "CertChain"

-- Load XML to be signed...
local sbXml = chilkat.StringBuilder.new()
xmlToSign:get_xml_sb(sbXml)

gen.behaviors = "IndentedSignature"

-- Sign the XML...
success = gen:create_xml_dsig_sb(sbXml)
if not success then
    print(gen.last_error_text)
    return
end

-- -----------------------------------------------

-- Save the signed XML to a file.
success = sbXml:write_file("qa_output/signedXml.xml", "utf-8", false)

print(sbXml:get_as_string())

-- ----------------------------------------
-- Verify the signatures we just produced...
local verifier = chilkat.XmlDSig.new()
success = verifier:load_signature_sb(sbXml)
if not success then
    print(verifier.last_error_text)
    return
end

local numSigs = verifier.num_signatures
local verifyIdx = 0
while verifyIdx < numSigs do
    verifier.selector = verifyIdx
    local verified = verifier:verify_signature(true)
    if not verified then
        print(verifier.last_error_text)
        return
    end

    verifyIdx = verifyIdx + 1
end

print("All signatures were successfully verified.")