PureBasic
PureBasic
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 PureBasic Downloads
IncludeFile "CkXml.pb"
IncludeFile "CkStringBuilder.pb"
IncludeFile "CkPrivateKey.pb"
IncludeFile "CkRsa.pb"
Procedure ChilkatExample()
success.i = 0
; 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
xml.i = CkXml::ckCreate()
If xml.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
; 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>
success = CkXml::ckLoadXmlFile(xml,"qa_data/xml_dsig/sii_cl/test_0.xml")
If success = 0
Debug "Failed to load initial XML file."
CkXml::ckDispose(xml)
ProcedureReturn
EndIf
; Get a reference to the "DA" element
daXml.i = CkXml::ckFindChild(xml,"Documento|TED|DD|CAF|DA")
If CkXml::ckLastMethodSuccess(xml) = 0
Debug "Failed to find DA element"
CkXml::ckDispose(xml)
ProcedureReturn
EndIf
; 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),
sbFlattened.i = CkStringBuilder::ckCreate()
If sbFlattened.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
CkXml::setCkEmitCompact(daXml, 1)
CkXml::setCkEmitXmlDecl(daXml, 0)
CkXml::ckGetXmlSb(daXml,sbFlattened)
; 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.
privKey.i = CkPrivateKey::ckCreate()
If privKey.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
success = CkPrivateKey::ckLoadAnyFormatFile(privKey,"qa_data/rsa/rsaPrivKey_pkcs8.pem","")
If success = 0
Debug CkPrivateKey::ckLastErrorText(privKey)
CkXml::ckDispose(xml)
CkStringBuilder::ckDispose(sbFlattened)
CkPrivateKey::ckDispose(privKey)
ProcedureReturn
EndIf
rsa.i = CkRsa::ckCreate()
If rsa.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
CkRsa::ckUsePrivateKey(rsa,privKey)
CkRsa::setCkEncodingMode(rsa, "base64")
CkRsa::setCkCharset(rsa, "iso-8859-1")
sig.s = CkRsa::ckSignStringENC(rsa,CkStringBuilder::ckGetAsString(sbFlattened),"sha1")
; Add the FRMA signature element to the XML.
CkXml::ckUpdateChildContent(xml,"Documento|TED|DD|CAF|FRMA",sig)
CkXml::ckUpdateAttrAt(xml,"Documento|TED|DD|CAF|FRMA",1,"algoritmo","SHA1withRSA")
CkXml::ckDispose(daXml)
; See what we have:
CkXml::setCkEmitCompact(xml, 0)
CkXml::setCkEmitXmlDecl(xml, 1)
Debug CkXml::ckGetXml(xml)
CkXml::ckSaveXml(xml,"qa_data/xml_dsig/sii_cl/test_1.xml")
CkXml::ckDispose(xml)
CkStringBuilder::ckDispose(sbFlattened)
CkPrivateKey::ckDispose(privKey)
CkRsa::ckDispose(rsa)
ProcedureReturn
EndProcedure