Sample code for 30+ languages & platforms
Pascal (Lazarus/Delphi)

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 Pascal (Lazarus/Delphi) Downloads

Pascal (Lazarus/Delphi)
program ChilkatDemo;

// Demonstrates using the Chilkat Pascal wrapper via the C bridge DLL.
// Builds as a console application under Lazarus (FPC) or Delphi.

{$IFDEF FPC}
  {$MODE DELPHI}
{$ENDIF}
{$APPTYPE CONSOLE}

uses
  {$IFDEF UNIX}
  cthreads,
  {$ENDIF}
  SysUtils,
  CkDllLoader,
  Chilkat.StringBuilder,
  Chilkat.XmlDSig,
  Chilkat.JsonObject;

// ---------------------------------------------------------------------------

procedure RunDemo;
var
  success: Boolean;
  sbXml: TStringBuilder;
  dsig: TXmlDSig;
  json: TJsonObject;
  sbOut: TStringBuilder;
  verifier: TXmlDSig;
  numSigs: Integer;
  verifyIdx: Integer;
  verified: Boolean;

begin
  success := False;

  //  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 := TStringBuilder.Create;
  success := sbXml.LoadFile('qa_data/xml_dsig_valid_samples/encapsulatedTimestamp_not_yet_added.xml','utf-8');
  if (success = False) then
    begin
      WriteLn('Failed to load the XML file.');
      Exit;
    end;

  dsig := TXmlDSig.Create;
  success := dsig.LoadSignatureSb(sbXml);
  if (success = False) then
    begin
      WriteLn(dsig.LastErrorText);
      Exit;
    end;

  if (dsig.HasEncapsulatedTimeStamp() = True) then
    begin
      WriteLn('This signed XML already has an EncapsulatedTimeStamp');
      Exit;
    end;

  //  Specify the timestamping authority URL
  json := TJsonObject.Create;
  json.UpdateString('timestampToken.tsaUrl','http://timestamp.digicert.com');
  json.UpdateBool('timestampToken.requestTsaCert',True);

  //  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 := TStringBuilder.Create;
  success := dsig.AddEncapsulatedTimeStamp(json,sbOut);
  if (success = False) then
    begin
      WriteLn(dsig.LastErrorText);
      Exit;
    end;

  sbOut.WriteFile('qa_output/addedEncapsulatedTimeStamp.xml','utf-8',False);

  //  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 := TXmlDSig.Create;
  success := verifier.LoadSignatureSb(sbOut);
  if (success <> True) then
    begin
      WriteLn(verifier.LastErrorText);
      Exit;
    end;

  //  Add "VerifyEncapsulatedTimeStamp" to the UncommonOptions to also verify any EncapsulatedTimeStamps
  verifier.UncommonOptions := 'VerifyEncapsulatedTimeStamp';

  numSigs := verifier.NumSignatures;
  verifyIdx := 0;
  while verifyIdx < numSigs do
    begin
      verifier.Selector := verifyIdx;
      verified := verifier.VerifySignature(True);
      if (verified <> True) then
        begin
          WriteLn(verifier.LastErrorText);
          Exit;
        end;
      verifyIdx := verifyIdx + 1;
    end;

  WriteLn('All signatures were successfully verified.');


  sbXml.Free;
  dsig.Free;
  json.Free;
  sbOut.Free;
  verifier.Free;

end;

// ---------------------------------------------------------------------------

begin

  try
    RunDemo;
  except
    on E: Exception do
      WriteLn('Unhandled exception: ', E.ClassName, ': ', E.Message);
  end;

  WriteLn;
  {$IFDEF MSWINDOWS}
  WriteLn('Press Enter to exit...');
  ReadLn;
  {$ENDIF}
end.