Sample code for 30+ languages & platforms
C

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 C Downloads

C
#include <C_CkBinData.h>
#include <C_CkAsn.h>
#include <C_CkXml.h>

void ChilkatSample(void)
    {
    BOOL success;
    HCkBinData bdTsr;
    HCkAsn asnTsr;
    HCkXml xmlTsr;
    HCkBinData bdContent;
    HCkXml xml;
    HCkXml xContext;
    HCkAsn tsd;
    const char *tsdBase64;

    success = FALSE;

    // 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 = CkBinData_Create();
    success = CkBinData_LoadFile(bdTsr,"qa_data/tsd/sample.tsr");
    if (success != TRUE) {
        printf("Failed to load timestamp reply file.\n");
        CkBinData_Dispose(bdTsr);
        return;
    }

    // Load the tsr into an ASN.1 object.
    asnTsr = CkAsn_Create();
    success = CkAsn_LoadEncoded(asnTsr,CkBinData_getEncoded(bdTsr,"base64"),"base64");
    if (success != TRUE) {
        printf("%s\n",CkAsn_lastErrorText(asnTsr));
        CkBinData_Dispose(bdTsr);
        CkAsn_Dispose(asnTsr);
        return;
    }

    // Get the timestamp reply as XML.
    xmlTsr = CkXml_Create();
    CkXml_LoadXml(xmlTsr,CkAsn_asnToXml(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_RemoveChildByIndex(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 = CkBinData_Create();
    success = CkBinData_LoadFile(bdContent,"qa_data/tsd/sample.p7m");
    if (success != TRUE) {
        printf("Failed to load content file.\n");
        CkBinData_Dispose(bdTsr);
        CkAsn_Dispose(asnTsr);
        CkXml_Dispose(xmlTsr);
        CkBinData_Dispose(bdContent);
        return;
    }

    // Begin building the TimeStampData.  
    // We'll build as XML and then convert to ASN.1
    xml = CkXml_Create();
    CkXml_putTag(xml,"sequence");
    CkXml_UpdateChildContent(xml,"oid","1.2.840.113549.1.9.16.1.31");
    CkXml_UpdateAttrAt(xml,"contextSpecific",TRUE,"tag","0");
    CkXml_UpdateAttrAt(xml,"contextSpecific",TRUE,"constructed","1");
    CkXml_UpdateChildContent(xml,"contextSpecific|sequence|int","01");
    CkXml_UpdateChildContent(xml,"contextSpecific|sequence|octets",CkBinData_getEncoded(bdContent,"base64"));
    CkXml_UpdateAttrAt(xml,"contextSpecific|sequence|contextSpecific",TRUE,"tag","0");
    CkXml_UpdateAttrAt(xml,"contextSpecific|sequence|contextSpecific",TRUE,"constructed","1");

    xContext = CkXml_GetChildWithTag(xml,"contextSpecific|sequence|contextSpecific");
    CkXml_AddChildTree(xContext,xmlTsr);
    CkXml_Dispose(xContext);

    // Convert the XML to ASN.1
    tsd = CkAsn_Create();
    CkAsn_LoadAsnXml(tsd,CkXml_getXml(xml));

    // Write the timestamped data to a file.
    success = CkAsn_WriteBinaryDer(tsd,"qa_output/sample.tsd");

    // Alternatively, get the tsd ASN.1 as base64..
    tsdBase64 = CkAsn_getEncodedDer(tsd,"base64_mime");
    printf("%s\n",tsdBase64);


    CkBinData_Dispose(bdTsr);
    CkAsn_Dispose(asnTsr);
    CkXml_Dispose(xmlTsr);
    CkBinData_Dispose(bdContent);
    CkXml_Dispose(xml);
    CkAsn_Dispose(tsd);

    }