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

Verify XML Signature with External URL References

See more XML Digital Signatures Examples

Demonstrates how to verify an XML digital signature that includes references to URLs where the data to be digested is on a web server.

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.Http,
  Chilkat.StringBuilder,
  Chilkat.BinData,
  Chilkat.XmlDSig;

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

procedure RunDemo;
var
  success: Boolean;
  verifier: TXmlDSig;
  http: THttp;
  sbSignedXml: TStringBuilder;
  sbRefUri: TStringBuilder;
  bd: TBinData;
  numRefs: Integer;
  i: Integer;
  bVerified: Boolean;

begin
  success := False;

  //  This example requires the Chilkat API to have been previously unlocked.
  //  See Global Unlock Sample for sample code.

  //  The signed XML we wish to verify contains external references such as this:

  //      <ds:Reference Id="xmldsig-e7ae7ce2-9133-4d56-bd97-0a6aef738cc2-ref0" URI="https://www.chilkatsoft.com/images/starfish.jpg">
  //        <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
  //        <ds:DigestValue>AOU810yJV5Np/DnO29qpObqiTSTTCDvxGsX5ayiTYXI=</ds:DigestValue>
  //      </ds:Reference>
  //      <ds:Reference Id="xmldsig-e7ae7ce2-9133-4d56-bd97-0a6aef738cc2-ref1" URI="https://www.chilkatsoft.com/hamlet.xml">
  //        <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
  //        <ds:DigestValue>4sRRyWOzC7EOic4fQ9+Op1pa10DbgoBGjBvkq09LZmE=</ds:DigestValue>
  //      </ds:Reference>

  verifier := TXmlDSig.Create;
  http := THttp.Create;

  //  First load the signed XML
  sbSignedXml := TStringBuilder.Create;
  success := sbSignedXml.LoadFile('qa_data/xml_dsig_verify/signedWithExternalUrlRefs.xml','utf-8');
  if (success = False) then
    begin
      WriteLn('Failed to load signed XML.');
      Exit;
    end;

  success := verifier.LoadSignatureSb(sbSignedXml);
  if (success = False) then
    begin
      WriteLn(verifier.LastErrorText);
      Exit;
    end;

  //  Iterate over each reference.  If it is an external URL reference, download the data and provide it to the verifier.
  sbRefUri := TStringBuilder.Create;
  bd := TBinData.Create;
  numRefs := verifier.NumReferences;
  i := 0;
  while i < numRefs do
    begin
      if (verifier.IsReferenceExternal(i) = True) then
        begin
          sbRefUri.Clear();
          sbRefUri.Append(verifier.ReferenceUri(i));
          if (sbRefUri.StartsWith('https://',False) = True) then
            begin
              WriteLn('External URL Reference: ' + sbRefUri.GetAsString());

              //  Download the data at the URL and provide to the verifier.
              success := http.DownloadBd(sbRefUri.GetAsString(),bd);
              if (success = False) then
                begin
                  WriteLn(http.LastErrorText);
                  Exit;
                end;
              success := verifier.SetRefDataBd(i,bd);
              if (success = False) then
                begin
                  WriteLn(verifier.LastErrorText);
                  Exit;
                end;
            end;
        end;
      i := i + 1;
    end;

  //  Now that we have the external data, verify the signature..
  bVerified := verifier.VerifySignature(True);
  if (bVerified = False) then
    begin
      WriteLn(verifier.LastErrorText);
    end;
  WriteLn('Signature verified = ' + bVerified);


  verifier.Free;
  http.Free;
  sbSignedXml.Free;
  sbRefUri.Free;
  bd.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.