PureBasic
PureBasic
Combine Timestamp Reply and Content File into a TimeStampData
See more ASN.1 Examples
Demonstrates how to combine a timestamp reply (RFC 3161) with a data file (any type of file) to create a TimeStampData structure (RFC 5544).Chilkat PureBasic Downloads
IncludeFile "CkBinData.pb"
IncludeFile "CkXml.pb"
IncludeFile "CkAsn.pb"
Procedure ChilkatExample()
success.i = 0
; This example requires the Chilkat API to have been previously unlocked.
; See Global Unlock Sample for sample code.
; Also see this example:
; Send a TimeStamp Request to a TimeStamp Authority and get the Response
; Load a timestamp reply file
bdTsr.i = CkBinData::ckCreate()
If bdTsr.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
success = CkBinData::ckLoadFile(bdTsr,"qa_data/tsd/sample.tsr")
If success <> 1
Debug "Failed to load timestamp reply file."
CkBinData::ckDispose(bdTsr)
ProcedureReturn
EndIf
; Load the tsr into an ASN.1 object.
asnTsr.i = CkAsn::ckCreate()
If asnTsr.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
success = CkAsn::ckLoadEncoded(asnTsr,CkBinData::ckGetEncoded(bdTsr,"base64"),"base64")
If success <> 1
Debug CkAsn::ckLastErrorText(asnTsr)
CkBinData::ckDispose(bdTsr)
CkAsn::ckDispose(asnTsr)
ProcedureReturn
EndIf
; Get the timestamp reply as XML.
xmlTsr.i = CkXml::ckCreate()
If xmlTsr.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
CkXml::ckLoadXml(xmlTsr,CkAsn::ckAsnToXml(asnTsr))
; The timestamp reply XML begins like this:
; We'll want to remove the 1st "sequence" subtree.
; <?xml version="1.0" encoding="utf-8"?>
; <sequence>
; <sequence> <---- Remove this sub-tree.
; <int>00</int>
; <sequence>
; <utf8>Operation Okay</utf8>
; </sequence>
; </sequence>
; <sequence>
; <oid>1.2.840.113549.1.7.2</oid>
; <contextSpecific tag="0" constructed="1">
; ...
; Remove the 1st sub-tree..
CkXml::ckRemoveChildByIndex(xmlTsr,0)
; In this example, the data file we're combining with the timestamp into a timestampData is a .p7m.
; However, it can be any type of file (text or binary), it doesn't matter..
bdContent.i = CkBinData::ckCreate()
If bdContent.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
success = CkBinData::ckLoadFile(bdContent,"qa_data/tsd/sample.p7m")
If success <> 1
Debug "Failed to load content file."
CkBinData::ckDispose(bdTsr)
CkAsn::ckDispose(asnTsr)
CkXml::ckDispose(xmlTsr)
CkBinData::ckDispose(bdContent)
ProcedureReturn
EndIf
; Begin building the TimeStampData.
; We'll build as XML and then convert to ASN.1
xml.i = CkXml::ckCreate()
If xml.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
CkXml::setCkTag(xml, "sequence")
CkXml::ckUpdateChildContent(xml,"oid","1.2.840.113549.1.9.16.1.31")
CkXml::ckUpdateAttrAt(xml,"contextSpecific",1,"tag","0")
CkXml::ckUpdateAttrAt(xml,"contextSpecific",1,"constructed","1")
CkXml::ckUpdateChildContent(xml,"contextSpecific|sequence|int","01")
CkXml::ckUpdateChildContent(xml,"contextSpecific|sequence|octets",CkBinData::ckGetEncoded(bdContent,"base64"))
CkXml::ckUpdateAttrAt(xml,"contextSpecific|sequence|contextSpecific",1,"tag","0")
CkXml::ckUpdateAttrAt(xml,"contextSpecific|sequence|contextSpecific",1,"constructed","1")
xContext.i = CkXml::ckGetChildWithTag(xml,"contextSpecific|sequence|contextSpecific")
CkXml::ckAddChildTree(xContext,xmlTsr)
CkXml::ckDispose(xContext)
; Convert the XML to ASN.1
tsd.i = CkAsn::ckCreate()
If tsd.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
CkAsn::ckLoadAsnXml(tsd,CkXml::ckGetXml(xml))
; Write the timestamped data to a file.
success = CkAsn::ckWriteBinaryDer(tsd,"qa_output/sample.tsd")
; Alternatively, get the tsd ASN.1 as base64..
tsdBase64.s = CkAsn::ckGetEncodedDer(tsd,"base64_mime")
Debug tsdBase64
CkBinData::ckDispose(bdTsr)
CkAsn::ckDispose(asnTsr)
CkXml::ckDispose(xmlTsr)
CkBinData::ckDispose(bdContent)
CkXml::ckDispose(xml)
CkAsn::ckDispose(tsd)
ProcedureReturn
EndProcedure