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

Verify Multiple Signatures in XML

See more XML Digital Signatures Examples

Demonstrates how to verify multiple signatures within a single XML document.

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.Xml,
  Chilkat.XmlDSig;

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

procedure RunDemo;
var
  success: Boolean;
  http: THttp;
  sbXml: TStringBuilder;
  verifier: TXmlDSig;
  i: Integer;
  verifyReferenceDigests: Boolean;
  verified: Boolean;
  numReferences: Integer;
  j: Integer;
  keyInfoXml: TXml;

begin
  success := False;

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

  //  A sample XML file containing multiple signatures is available at:
  //  https://www.chilkatsoft.com/exampleData/document.signed.bes.cs.xml

  http := THttp.Create;
  sbXml := TStringBuilder.Create;
  success := http.QuickGetSb('https://www.chilkatsoft.com/exampleData/document.signed.bes.cs.xml',sbXml);
  if (success <> True) then
    begin
      WriteLn(http.LastErrorText);
      Exit;
    end;

  //  Load the XML containing the signature to be verified.
  verifier := TXmlDSig.Create;
  success := verifier.LoadSignatureSb(sbXml);
  if (success <> True) then
    begin
      WriteLn(verifier.LastErrorText);
      Exit;
    end;

  //  How many Signatures exist in this XML?
  WriteLn('Number of XML signatures = ' + verifier.NumSignatures);

  //  Let's show the XML nicely indented, so we can make sense of it.
  //  Loading the XML into an XML parser and re-emitting with nice formatting
  //  changes whitespace that breaks the signatures.  We're only doing this
  //  for the example to examine this XML, which contains 2 ds:Signature's
  //  and each signature has multiple references.

  //  This is what we have:
  //  (scroll down to continue with this example..)

  //  <?xml version="1.0" encoding="UTF-8" ?>
  //  <collection Id="root">
  //      <album>
  //          <title>Questions, unanswered</title>
  //          <artist>Steve and the flubberblubs</artist>
  //          <year>1989</year>
  //          <t:tracks xmlns:t="http://test.xades4j/tracks">
  //              <t:song length="4:05" tracknumber="1">
  //                  <t:title>What do you know?</t:title>
  //                  <t:artist>Steve and the flubberblubs</t:artist>
  //                  <t:lastplayed>2006-10-17-08:31</t:lastplayed>
  //              </t:song>
  //              <t:song length="3:45" tracknumber="2">
  //                  <t:title>Who do you know?</t:title>
  //                  <t:artist>Steve and the flubberblubs</t:artist>
  //                  <t:lastplayed>2006-10-17-08:35</t:lastplayed>
  //              </t:song>
  //              <t:song length="5:14" tracknumber="3">
  //                  <t:title>When do you know?</t:title>
  //                  <t:artist>Steve and the flubberblubs</t:artist>
  //                  <t:lastplayed>2006-10-17-08:39</t:lastplayed>
  //              </t:song>
  //              <t:song length="4:19" tracknumber="4">
  //                  <t:title>Do you know?</t:title>
  //                  <t:artist>Steve and the flubberblubs</t:artist>
  //                  <t:lastplayed>2006-10-17-08:44</t:lastplayed>
  //              </t:song>
  //          </t:tracks>
  //      </album>
  //      <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#" Id="xmldsig-ff7d9ad7-f36d-4af0-b21a-7db2e840efad">
  //          <ds:SignedInfo>
  //              <ds:CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" />
  //              <ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" />
  //              <ds:Reference Id="xmldsig-ff7d9ad7-f36d-4af0-b21a-7db2e840efad-ref0" URI="#root">
  //                  <ds:Transforms>
  //                      <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
  //                  </ds:Transforms>
  //                  <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
  //                  <ds:DigestValue>rD/g8soqKz8EiPUBhEWfcQacS0ta4ULHX3dKMEH6ZoQ=</ds:DigestValue>
  //              </ds:Reference>
  //              <ds:Reference Type="http://uri.etsi.org/01903#SignedProperties" URI="#xmldsig-ff7d9ad7-f36d-4af0-b21a-7db2e840efad-signedprops">
  //                  <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
  //                  <ds:DigestValue>pfrrRjkGNPiRF2Bjuj3IJTGSEFYc2PDs6FCNAUJOu8E=</ds:DigestValue>
  //              </ds:Reference>
  //          </ds:SignedInfo>
  //          <ds:SignatureValue Id="xmldsig-ff7d9ad7-f36d-4af0-b21a-7db2e840efad-sigvalue">Vb/2ay4rX9cytiRCmBkgRkE4d0E05nkM412CwOHvTagCXPZZ2B2ifbmrQznTEU6Jz0dF65j5kU7C
  //  bYK+9fMKB0lmqx2kUdWeBa30Rl/3ELKWKOLeDFN91zC3q4a6dtzQGwBidWex+2dO8Z69sBd2aTS6
  //  S6nyGs53kTspDHfBeyg=</ds:SignatureValue>
  //          <ds:KeyInfo>
  //              <ds:X509Data>
  //                  <ds:X509Certificate>MIICbTCCAdqgAwIBAgIQpkK0uals+ItHxBlpJuypOTAJBgUrDgMCHQUAMD8xCzAJBgNVBAYTAlBU
  //  MQ0wCwYDVQQKEwRJU0VMMQswCQYDVQQLEwJDQzEUMBIGA1UEAxMLSXRlcm1lZGlhdGUwHhcNMTAw
  //  NjI1MTc1ODQ5WhcNMzkxMjMxMjM1OTU5WjBCMQswCQYDVQQGEwJQVDENMAsGA1UEChMESVNFTDEL
  //  MAkGA1UECxMCQ0MxFzAVBgNVBAMTDkx1aXMgR29uY2FsdmVzMIGfMA0GCSqGSIb3DQEBAQUAA4GN
  //  ADCBiQKBgQCpP9acMX69Dbg9ciMLFc5dm1tlpTY9OTNZ/EaCYoGVhh/3+DFgyIbEer6SA24hpREm
  //  AhNG9+Ca0AurDPPgb3aKWFY9pj1WcOctis0VsR0YvzqP+2IGFqKDCd7bXFvv2tI0dEvpdc0oO6PF
  //  Q02xvJG0kxQf44XljOCjUBU43jkJawIDAQABo28wbTBrBgNVHQEEZDBigBBdbbL4pDKLT56PpOpA
  //  /56toTwwOjELMAkGA1UEBhMCUFQxDTALBgNVBAoTBElTRUwxCzAJBgNVBAsTAkNDMQ8wDQYDVQQD
  //  EwZUZXN0Q0GCEN00x9qe7SuWQvpLK0/oay8wCQYFKw4DAh0FAAOBgQBSma8g9dQjiQo4WUljRRuG
  //  yMUVRyCqW/9oRz8+0EoLNR/AhrIlGqdNbqQ1BkncgNNdqMAus5VD34v/EhgrkgWN5fZajMpYsmcR
  //  Ahu4PzJ6hggAlWWMy245JwIYuV0s1Oi39GVTxVNOBIX//AONZlGWO4S2Psb1mqdZ99b/MugsaA==</ds:X509Certificate>
  //              </ds:X509Data>
  //          </ds:KeyInfo>
  //          <ds:Object>
  //              <xades:QualifyingProperties xmlns:xades="http://uri.etsi.org/01903/v1.3.2#" xmlns:xades141="http://uri.etsi.org/01903/v1.4.1#" Target="#xmldsig-ff7d9ad7-f36d-4af0-b21a-7db2e840efad">
  //                  <xades:SignedProperties Id="xmldsig-ff7d9ad7-f36d-4af0-b21a-7db2e840efad-signedprops">
  //                      <xades:SignedSignatureProperties>
  //                          <xades:SigningCertificate>
  //                              <xades:Cert>
  //                                  <xades:CertDigest>
  //                                      <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
  //                                      <ds:DigestValue>4btVb5gQ5cdcNhGpvDSWQZabPQrR9jf1x8e3YF9Ajss=</ds:DigestValue>
  //                                  </xades:CertDigest>
  //                                  <xades:IssuerSerial>
  //                                      <ds:X509IssuerName>CN=Itermediate,OU=CC,O=ISEL,C=PT</ds:X509IssuerName>
  //                                      <ds:X509SerialNumber>-119284162484605703133798696662099777223</ds:X509SerialNumber>
  //                                  </xades:IssuerSerial>
  //                              </xades:Cert>
  //                              <xades:Cert>
  //                                  <xades:CertDigest>
  //                                      <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
  //                                      <ds:DigestValue>vm5QpbblsWV7fCYXotPhNTeCt4nk8cLFuF36L5RJ4Ok=</ds:DigestValue>
  //                                  </xades:CertDigest>
  //                                  <xades:IssuerSerial>
  //                                      <ds:X509IssuerName>CN=TestCA,OU=CC,O=ISEL,C=PT</ds:X509IssuerName>
  //                                      <ds:X509SerialNumber>-46248926895392336918291885380930606289</ds:X509SerialNumber>
  //                                  </xades:IssuerSerial>
  //                              </xades:Cert>
  //                              <xades:Cert>
  //                                  <xades:CertDigest>
  //                                      <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
  //                                      <ds:DigestValue>AUaN+IdhKQqxIVmEOrFwq+Dn22ebTkXJqD3BoOP/x8E=</ds:DigestValue>
  //                                  </xades:CertDigest>
  //                                  <xades:IssuerSerial>
  //                                      <ds:X509IssuerName>CN=TestCA,OU=CC,O=ISEL,C=PT</ds:X509IssuerName>
  //                                      <ds:X509SerialNumber>-99704378678639105802976522062798066869</ds:X509SerialNumber>
  //                                  </xades:IssuerSerial>
  //                              </xades:Cert>
  //                          </xades:SigningCertificate>
  //                          <xades:SignerRole>
  //                              <xades:ClaimedRoles>
  //                                  <xades:ClaimedRole>CounterSignature maniac</xades:ClaimedRole>
  //                              </xades:ClaimedRoles>
  //                          </xades:SignerRole>
  //                      </xades:SignedSignatureProperties>
  //                  </xades:SignedProperties>
  //                  <xades:UnsignedProperties>
  //                      <xades:UnsignedSignatureProperties>
  //                          <xades:CounterSignature>
  //                              <ds:Signature Id="xmldsig-7479045c-8083-49eb-9043-1ac2af4a759c" xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
  //                                  <ds:SignedInfo>
  //                                      <ds:CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" />
  //                                      <ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" />
  //                                      <ds:Reference Id="xmldsig-7479045c-8083-49eb-9043-1ac2af4a759c-ref0" URI="#xmldsig-ff7d9ad7-f36d-4af0-b21a-7db2e840efad-sigvalue">
  //                                          <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
  //                                          <ds:DigestValue>Nr5JKCScyqjKWneJw2AC6YmdU/2JZA5Pj40fkVCFbL4=</ds:DigestValue>
  //                                      </ds:Reference>
  //                                      <ds:Reference Type="http://uri.etsi.org/01903#SignedProperties" URI="#xmldsig-7479045c-8083-49eb-9043-1ac2af4a759c-signedprops">
  //                                          <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
  //                                          <ds:DigestValue>PJWDlPFdx4TJ5AXT3nIbFa2euboYGM7bpuBmol4nKSQ=</ds:DigestValue>
  //                                      </ds:Reference>
  //                                  </ds:SignedInfo>
  //                                  <ds:SignatureValue Id="xmldsig-7479045c-8083-49eb-9043-1ac2af4a759c-sigvalue">MCcli4l5rAsGeJX2gOmoYDIAXnbszmRwOH94y7kHnpxCwGwoVrCaLSONtgKEy8mj9Ehqa/R5Dj5g
  //  DgC77VkNIaRKD613JMnbsaqZ7PD0iVivLvBkasTch4PX92UEbk8EvCgzxvhlgN+L6zSLsv65sFcR
  //  lFUGluMtzrqlDKvts38=</ds:SignatureValue>
  //                                  <ds:KeyInfo>
  //                                      <ds:X509Data>
  //                                          <ds:X509Certificate>MIICbTCCAdqgAwIBAgIQpkK0uals+ItHxBlpJuypOTAJBgUrDgMCHQUAMD8xCzAJBgNVBAYTAlBU
  //  MQ0wCwYDVQQKEwRJU0VMMQswCQYDVQQLEwJDQzEUMBIGA1UEAxMLSXRlcm1lZGlhdGUwHhcNMTAw
  //  NjI1MTc1ODQ5WhcNMzkxMjMxMjM1OTU5WjBCMQswCQYDVQQGEwJQVDENMAsGA1UEChMESVNFTDEL
  //  MAkGA1UECxMCQ0MxFzAVBgNVBAMTDkx1aXMgR29uY2FsdmVzMIGfMA0GCSqGSIb3DQEBAQUAA4GN
  //  ADCBiQKBgQCpP9acMX69Dbg9ciMLFc5dm1tlpTY9OTNZ/EaCYoGVhh/3+DFgyIbEer6SA24hpREm
  //  AhNG9+Ca0AurDPPgb3aKWFY9pj1WcOctis0VsR0YvzqP+2IGFqKDCd7bXFvv2tI0dEvpdc0oO6PF
  //  Q02xvJG0kxQf44XljOCjUBU43jkJawIDAQABo28wbTBrBgNVHQEEZDBigBBdbbL4pDKLT56PpOpA
  //  /56toTwwOjELMAkGA1UEBhMCUFQxDTALBgNVBAoTBElTRUwxCzAJBgNVBAsTAkNDMQ8wDQYDVQQD
  //  EwZUZXN0Q0GCEN00x9qe7SuWQvpLK0/oay8wCQYFKw4DAh0FAAOBgQBSma8g9dQjiQo4WUljRRuG
  //  yMUVRyCqW/9oRz8+0EoLNR/AhrIlGqdNbqQ1BkncgNNdqMAus5VD34v/EhgrkgWN5fZajMpYsmcR
  //  Ahu4PzJ6hggAlWWMy245JwIYuV0s1Oi39GVTxVNOBIX//AONZlGWO4S2Psb1mqdZ99b/MugsaA==</ds:X509Certificate>
  //                                      </ds:X509Data>
  //                                  </ds:KeyInfo>
  //                                  <ds:Object>
  //                                      <xades:QualifyingProperties Target="#xmldsig-7479045c-8083-49eb-9043-1ac2af4a759c" xmlns:xades="http://uri.etsi.org/01903/v1.3.2#" xmlns:xades141="http://uri.etsi.org/01903/v1.4.1#">
  //                                          <xades:SignedProperties Id="xmldsig-7479045c-8083-49eb-9043-1ac2af4a759c-signedprops">
  //                                              <xades:SignedSignatureProperties>
  //                                                  <xades:SigningTime>2012-10-13T14:26:18.783+01:00</xades:SigningTime>
  //                                                  <xades:SigningCertificate>
  //                                                      <xades:Cert>
  //                                                          <xades:CertDigest>
  //                                                              <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
  //                                                              <ds:DigestValue>4btVb5gQ5cdcNhGpvDSWQZabPQrR9jf1x8e3YF9Ajss=</ds:DigestValue>
  //                                                          </xades:CertDigest>
  //                                                          <xades:IssuerSerial>
  //                                                              <ds:X509IssuerName>CN=Itermediate,OU=CC,O=ISEL,C=PT</ds:X509IssuerName>
  //                                                              <ds:X509SerialNumber>-119284162484605703133798696662099777223</ds:X509SerialNumber>
  //                                                          </xades:IssuerSerial>
  //                                                      </xades:Cert>
  //                                                      <xades:Cert>
  //                                                          <xades:CertDigest>
  //                                                              <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
  //                                                              <ds:DigestValue>vm5QpbblsWV7fCYXotPhNTeCt4nk8cLFuF36L5RJ4Ok=</ds:DigestValue>
  //                                                          </xades:CertDigest>
  //                                                          <xades:IssuerSerial>
  //                                                              <ds:X509IssuerName>CN=TestCA,OU=CC,O=ISEL,C=PT</ds:X509IssuerName>
  //                                                              <ds:X509SerialNumber>-46248926895392336918291885380930606289</ds:X509SerialNumber>
  //                                                          </xades:IssuerSerial>
  //                                                      </xades:Cert>
  //                                                      <xades:Cert>
  //                                                          <xades:CertDigest>
  //                                                              <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
  //                                                              <ds:DigestValue>AUaN+IdhKQqxIVmEOrFwq+Dn22ebTkXJqD3BoOP/x8E=</ds:DigestValue>
  //                                                          </xades:CertDigest>
  //                                                          <xades:IssuerSerial>
  //                                                              <ds:X509IssuerName>CN=TestCA,OU=CC,O=ISEL,C=PT</ds:X509IssuerName>
  //                                                              <ds:X509SerialNumber>-99704378678639105802976522062798066869</ds:X509SerialNumber>
  //                                                          </xades:IssuerSerial>
  //                                                      </xades:Cert>
  //                                                  </xades:SigningCertificate>
  //                                              </xades:SignedSignatureProperties>
  //                                          </xades:SignedProperties>
  //                                      </xades:QualifyingProperties>
  //                                  </ds:Object>
  //                              </ds:Signature>
  //                          </xades:CounterSignature>
  //                      </xades:UnsignedSignatureProperties>
  //                  </xades:UnsignedProperties>
  //              </xades:QualifyingProperties>
  //          </ds:Object>
  //      </ds:Signature>
  //  </collection>
  //  

  //  When I look at the complicated XML above, there are specific things I look at to get a handle
  //  on the situation.
  //  
  //  1) Does the signature already embed the public keys required for verification?  
  //     Within each <ds:Signature>, look for the <ds:KeyInfo>.  In this case, I can see that
  //     each signature contains the full X.509 certificate needed to verify (<ds:KeyInfo><ds:X509Data><ds:X509Certificate>).
  //     This means that Chilkat will automatically use the public keys contained within the base64 certificates
  //     already present in the signature. 
  //  
  //   2) Look at each <ds:Reference> within each <ds:Signature>.  Do the URI attribute values begin with "#"?
  //      If so, then these are same-document references, and there's no need to explicitly fetch external data for reference verification.
  //      Chilkat can automatically validate each same-document Reference.
  //  
  //  So it turns out that this seemingly formidable XML document is easy to verify...
  //  Here we go...

  i := 0;
  while i < verifier.NumSignatures do
    begin
      //  The Selector property is used to set our context to the Nth signature.
      //  For example, if VerifySignature is called when Selector = 0, then the 1st signature is verified.
      //  If VerifySignature is called when Selector = 1, then the 2nd signature is verified, and so on.
      verifier.Selector := i;

      verifyReferenceDigests := True;

      //  The quick way to validate all references and the signature over the SignedInfo
      //  is to call VerifySignature with verifyReferenceDigests equal to True.
      verified := verifier.VerifySignature(verifyReferenceDigests);
      WriteLn('Signature ' + i + 1 + ' and all reference digests verified = ' + verified);

      //  We can also get information about each signature.
      //  For example, we could get information about each Reference...
      //  The NumReferences property returns the number of references for the Signature indicated by the Selector property.
      numReferences := verifier.NumReferences;
      WriteLn('  number of references: ' + numReferences);

      j := 0;
      while j < numReferences do
        begin
          //  Get information about the Jth reference in the Ith signature.
          WriteLn('  reference ' + j + ':');
          //  Is this a same-document or external reference?
          WriteLn('      is external: ' + verifier.IsReferenceExternal(j));
          //  For external references, the URI could be used by an application to fetch the referenced data...
          WriteLn('      uri: ' + verifier.ReferenceUri(j));
          j := j + 1;
        end;

      //  We could also get the KeyInfo for each Signature, which might be needed if we need to 
      //  load and set a public key that is not physically present within the KeyInfo already.
      keyInfoXml := verifier.GetKeyInfo();
      WriteLn('  key info: ' + keyInfoXml.GetXml());
      keyInfoXml.Free;

      i := i + 1;

    end;

  //  Here's the output of this example:

  //  Number of XML signatures = 2
  //  Signature 1 and all reference digests verified = True
  //    number of references: 2
  //    reference 0:
  //        is external: False
  //        uri: #root
  //    reference 1:
  //        is external: False
  //        uri: #xmldsig-ff7d9ad7-f36d-4af0-b21a-7db2e840efad-signedprops
  //    key info: 
  //  <ds:KeyInfo>
  //      <ds:X509Data>
  //          <ds:X509Certificate>
  //  MIICbTCCAdqgAwIBAgIQpkK0uals+ItHxBlpJuypOTAJBgUrDgMCHQUAMD8xCzAJBgNVBAYTAlBU
  //  MQ0wCwYDVQQKEwRJU0VMMQswCQYDVQQLEwJDQzEUMBIGA1UEAxMLSXRlcm1lZGlhdGUwHhcNMTAw
  //  NjI1MTc1ODQ5WhcNMzkxMjMxMjM1OTU5WjBCMQswCQYDVQQGEwJQVDENMAsGA1UEChMESVNFTDEL
  //  MAkGA1UECxMCQ0MxFzAVBgNVBAMTDkx1aXMgR29uY2FsdmVzMIGfMA0GCSqGSIb3DQEBAQUAA4GN
  //  ADCBiQKBgQCpP9acMX69Dbg9ciMLFc5dm1tlpTY9OTNZ/EaCYoGVhh/3+DFgyIbEer6SA24hpREm
  //  AhNG9+Ca0AurDPPgb3aKWFY9pj1WcOctis0VsR0YvzqP+2IGFqKDCd7bXFvv2tI0dEvpdc0oO6PF
  //  Q02xvJG0kxQf44XljOCjUBU43jkJawIDAQABo28wbTBrBgNVHQEEZDBigBBdbbL4pDKLT56PpOpA
  //  /56toTwwOjELMAkGA1UEBhMCUFQxDTALBgNVBAoTBElTRUwxCzAJBgNVBAsTAkNDMQ8wDQYDVQQD
  //  EwZUZXN0Q0GCEN00x9qe7SuWQvpLK0/oay8wCQYFKw4DAh0FAAOBgQBSma8g9dQjiQo4WUljRRuG
  //  yMUVRyCqW/9oRz8+0EoLNR/AhrIlGqdNbqQ1BkncgNNdqMAus5VD34v/EhgrkgWN5fZajMpYsmcR
  //  Ahu4PzJ6hggAlWWMy245JwIYuV0s1Oi39GVTxVNOBIX//AONZlGWO4S2Psb1mqdZ99b/MugsaA==
  //  </ds:X509Certificate>
  //      </ds:X509Data>
  //  </ds:KeyInfo>
  //  
  //  Signature 2 and all reference digests verified = True
  //    number of references: 2
  //    reference 0:
  //        is external: False
  //        uri: #xmldsig-ff7d9ad7-f36d-4af0-b21a-7db2e840efad-sigvalue
  //    reference 1:
  //        is external: False
  //        uri: #xmldsig-7479045c-8083-49eb-9043-1ac2af4a759c-signedprops
  //    key info: 
  //  <ds:KeyInfo>
  //      <ds:X509Data>
  //          <ds:X509Certificate>
  //  MIICbTCCAdqgAwIBAgIQpkK0uals+ItHxBlpJuypOTAJBgUrDgMCHQUAMD8xCzAJBgNVBAYTAlBU
  //  MQ0wCwYDVQQKEwRJU0VMMQswCQYDVQQLEwJDQzEUMBIGA1UEAxMLSXRlcm1lZGlhdGUwHhcNMTAw
  //  NjI1MTc1ODQ5WhcNMzkxMjMxMjM1OTU5WjBCMQswCQYDVQQGEwJQVDENMAsGA1UEChMESVNFTDEL
  //  MAkGA1UECxMCQ0MxFzAVBgNVBAMTDkx1aXMgR29uY2FsdmVzMIGfMA0GCSqGSIb3DQEBAQUAA4GN
  //  ADCBiQKBgQCpP9acMX69Dbg9ciMLFc5dm1tlpTY9OTNZ/EaCYoGVhh/3+DFgyIbEer6SA24hpREm
  //  AhNG9+Ca0AurDPPgb3aKWFY9pj1WcOctis0VsR0YvzqP+2IGFqKDCd7bXFvv2tI0dEvpdc0oO6PF
  //  Q02xvJG0kxQf44XljOCjUBU43jkJawIDAQABo28wbTBrBgNVHQEEZDBigBBdbbL4pDKLT56PpOpA
  //  /56toTwwOjELMAkGA1UEBhMCUFQxDTALBgNVBAoTBElTRUwxCzAJBgNVBAsTAkNDMQ8wDQYDVQQD
  //  EwZUZXN0Q0GCEN00x9qe7SuWQvpLK0/oay8wCQYFKw4DAh0FAAOBgQBSma8g9dQjiQo4WUljRRuG
  //  yMUVRyCqW/9oRz8+0EoLNR/AhrIlGqdNbqQ1BkncgNNdqMAus5VD34v/EhgrkgWN5fZajMpYsmcR
  //  Ahu4PzJ6hggAlWWMy245JwIYuV0s1Oi39GVTxVNOBIX//AONZlGWO4S2Psb1mqdZ99b/MugsaA==
  //  </ds:X509Certificate>
  //      </ds:X509Data>
  //  </ds:KeyInfo>
  //  
  //  


  http.Free;
  sbXml.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.