Sample code for 30+ languages & platforms
Lazarus Pascal

Extract SignatureValue from Signed XML

See more XML Digital Signatures Examples

Demonstrates how to extract the signature value from signed XML.

Chilkat Lazarus Pascal Downloads

Lazarus Pascal
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.Xml,
  Chilkat.StringBuilder;

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

procedure RunDemo;
var
  success: Boolean;
  filePath: string;
  sb: TStringBuilder;
  base64Sig: string;
  xml: TXml;
  xSigVal: TXml;

begin
  success := False;

  //  This example will work with the following signed XML, which as been reformatted for readability.

  //  <?xml version="1.0" encoding="utf-8"?>
  //  <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
  //      <SOAP-ENV:Header>
  //          <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" SOAP-ENV:mustUnderstand="1">
  //              <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
  //                  <ds:SignedInfo>
  //                      <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
  //                          <InclusiveNamespaces xmlns="http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList="wsse SOAP-ENV"/>
  //                      </ds:CanonicalizationMethod>
  //                      <ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
  //                      <ds:Reference URI="#Body">
  //                          <ds:Transforms>
  //                              <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
  //                          </ds:Transforms>
  //                          <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
  //                          <ds:DigestValue>OwgHPZNfDkXnZsjpfzXqAcT3RV3HzmTsEy2bP44FJ0M=</ds:DigestValue>
  //                      </ds:Reference>
  //                  </ds:SignedInfo>
  //                  <ds:SignatureValue>C+7FWngU....DJFBcdg==</ds:SignatureValue>
  //                  <ds:KeyInfo>
  //                      <ds:KeyValue>
  //                          <ds:RSAKeyValue>
  //                              <ds:Modulus>sXeRhM55P13.....NAcibRw==</ds:Modulus>
  //                              <ds:Exponent>AQAB</ds:Exponent>
  //                          </ds:RSAKeyValue>
  //                      </ds:KeyValue>
  //                  </ds:KeyInfo>
  //              </ds:Signature>
  //          </wsse:Security>
  //      </SOAP-ENV:Header>
  //      <SOAP-ENV:Body xmlns:SOAP-SEC="http://schemas.xmlsoap.org/soap/security/2000-12" SOAP-SEC:id="Body">
  //          <z:FooBar xmlns:z="http://example.com"/>
  //      </SOAP-ENV:Body>
  //  </SOAP-ENV:Envelope>

  //  -----------------------------------------------------------------------------------------
  //  There are a number of ways we can get the contents of the  <ds:SignatureValue>...</ds:SignatureValue>

  filePath := 'qa_data/xml_dsig_testing/sample_to_show_how_to_extract_sig.xml';

  //  If you know there will only be a single SignatureValue in the XML, you don't need to parse XML.
  //  Just do quick and simple string search..
  //  For example:
  sb := TStringBuilder.Create;
  success := sb.LoadFile(filePath,'utf-8');
  if (success = False) then
    begin
      WriteLn('Failed to load file.');
      Exit;
    end;

  base64Sig := sb.GetBetween('SignatureValue>','</');
  WriteLn('base64Sig = ' + base64Sig);

  //  -----------------------------------------------------------------------------------------
  //  If the XML might contain multiple signatures, but the signatures will always be located in the 
  //  same place, then you can (beforehand) copy a sample signed XML into Chilkat's online tool
  //  at Generate Parsing Code from XML
  //  to get the path to the SignatureValue.  For example, the line of code generated for the SignatureValue
  //  for the above XML is:
  //  string ds_SignatureValue = xml.GetChildContent("SOAP-ENV:Header|wsse:Security|ds:Signature|ds:SignatureValue");

  //  So you can simply use that path..
  xml := TXml.Create;
  success := xml.LoadXmlFile(filePath);
  //  Assume success..

  base64Sig := xml.GetChildContent('SOAP-ENV:Header|wsse:Security|ds:Signature|ds:SignatureValue');
  WriteLn('base64Sig = ' + base64Sig);

  //  -----------------------------------------------------------------------------------------
  //  Or perhaps you don't know where the signature is located in the XML.
  //  You can search for the tag..
  xSigVal := xml.SearchForTag(xml,'*:SignatureValue');
  if (xml.LastMethodSuccess = True) then
    begin
      WriteLn('base64Sig = ' + xSigVal.Content);
      xSigVal.Free;
    end
  else
    begin
      WriteLn('No SignatureValue found.');
    end;


  sb.Free;
  xml.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.