Sample code for 30+ languages & platforms
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

PureBasic
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