PureBasic
PureBasic
Add EncapsulatedTimestamp to Already-Signed XML
See more XML Digital Signatures Examples
Demonstrates how to add an EncapsulatedTimestamp to an existing XML signature.Note: This example requires Chilkat v9.5.0.90 or greater.
Chilkat PureBasic Downloads
IncludeFile "CkStringBuilder.pb"
IncludeFile "CkXmlDSig.pb"
IncludeFile "CkJsonObject.pb"
Procedure ChilkatExample()
success.i = 0
; This example requires the Chilkat API to have been previously unlocked.
; See Global Unlock Sample for sample code.
; Note: We cannot load the already-signed XML into a Chilkat XML object because it would re-format the XML when re-emitted.
; (i.e. indentation and whitespace could change, and it would invalidate the existing signature.)
; We must use a StringBuilder.
sbXml.i = CkStringBuilder::ckCreate()
If sbXml.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
success = CkStringBuilder::ckLoadFile(sbXml,"qa_data/xml_dsig_valid_samples/encapsulatedTimestamp_not_yet_added.xml","utf-8")
If success = 0
Debug "Failed to load the XML file."
CkStringBuilder::ckDispose(sbXml)
ProcedureReturn
EndIf
dsig.i = CkXmlDSig::ckCreate()
If dsig.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
success = CkXmlDSig::ckLoadSignatureSb(dsig,sbXml)
If success = 0
Debug CkXmlDSig::ckLastErrorText(dsig)
CkStringBuilder::ckDispose(sbXml)
CkXmlDSig::ckDispose(dsig)
ProcedureReturn
EndIf
If CkXmlDSig::ckHasEncapsulatedTimeStamp(dsig) = 1
Debug "This signed XML already has an EncapsulatedTimeStamp"
CkStringBuilder::ckDispose(sbXml)
CkXmlDSig::ckDispose(dsig)
ProcedureReturn
EndIf
; Specify the timestamping authority URL
json.i = CkJsonObject::ckCreate()
If json.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
CkJsonObject::ckUpdateString(json,"timestampToken.tsaUrl","http://timestamp.digicert.com")
CkJsonObject::ckUpdateBool(json,"timestampToken.requestTsaCert",1)
; Call AddEncapsulatedTimeStamp to add the EncapsulatedTimeStamp to the signature.
; Note: If the signed XML contains multiple signatures, the signature modified is the one
; indicated by the dsig.Selector property.
sbOut.i = CkStringBuilder::ckCreate()
If sbOut.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
success = CkXmlDSig::ckAddEncapsulatedTimeStamp(dsig,json,sbOut)
If success = 0
Debug CkXmlDSig::ckLastErrorText(dsig)
CkStringBuilder::ckDispose(sbXml)
CkXmlDSig::ckDispose(dsig)
CkJsonObject::ckDispose(json)
CkStringBuilder::ckDispose(sbOut)
ProcedureReturn
EndIf
CkStringBuilder::ckWriteFile(sbOut,"qa_output/addedEncapsulatedTimeStamp.xml","utf-8",0)
; The EncapsulatedTimeStamp can be validated when validating the signature by adding the VerifyEncapsulatedTimeStamp
; keyword to UncommonOptions. See here:
; ----------------------------------------
; Verify the signatures we just produced...
verifier.i = CkXmlDSig::ckCreate()
If verifier.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
success = CkXmlDSig::ckLoadSignatureSb(verifier,sbOut)
If success <> 1
Debug CkXmlDSig::ckLastErrorText(verifier)
CkStringBuilder::ckDispose(sbXml)
CkXmlDSig::ckDispose(dsig)
CkJsonObject::ckDispose(json)
CkStringBuilder::ckDispose(sbOut)
CkXmlDSig::ckDispose(verifier)
ProcedureReturn
EndIf
; Add "VerifyEncapsulatedTimeStamp" to the UncommonOptions to also verify any EncapsulatedTimeStamps
CkXmlDSig::setCkUncommonOptions(verifier, "VerifyEncapsulatedTimeStamp")
numSigs.i = CkXmlDSig::ckNumSignatures(verifier)
verifyIdx.i = 0
While verifyIdx < numSigs
CkXmlDSig::setCkSelector(verifier, verifyIdx)
verified.i = CkXmlDSig::ckVerifySignature(verifier,1)
If verified <> 1
Debug CkXmlDSig::ckLastErrorText(verifier)
CkStringBuilder::ckDispose(sbXml)
CkXmlDSig::ckDispose(dsig)
CkJsonObject::ckDispose(json)
CkStringBuilder::ckDispose(sbOut)
CkXmlDSig::ckDispose(verifier)
ProcedureReturn
EndIf
verifyIdx = verifyIdx + 1
Wend
Debug "All signatures were successfully verified."
CkStringBuilder::ckDispose(sbXml)
CkXmlDSig::ckDispose(dsig)
CkJsonObject::ckDispose(json)
CkStringBuilder::ckDispose(sbOut)
CkXmlDSig::ckDispose(verifier)
ProcedureReturn
EndProcedure