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

SII Chile - FRMT Signature Computation and Add to XML

See more XML Digital Signatures Examples

Compute the FRMT signature and add to the XML. This is the RSA signature of the SHA-1 digest of the "flattened" DD element.

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

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

procedure RunDemo;
var
  success: Boolean;
  xml: TXml;
  ddXml: TXml;
  sbFlattened: TStringBuilder;
  privKey: TPrivateKey;
  rsa: TRsa;
  sig: string;

begin
  success := False;

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

  //  Also see:  Compute the FRMA Signature and Add to XML

  xml := TXml.Create;

  //  Load the unsigned XML that contains the following:

  //  <DTE version="1.0">
  //    <Documento ID="F60T33">
  //          <TED version="1.0">
  //              <DD>
  //  		...
  //                  <CAF version="1.0">
  //                      <DA>
  //  			...
  //                      </DA>
  //                      <FRMA algoritmo="SHA1withRSA">...</FRMA>
  //                  </CAF>
  //                  ...
  //              </DD>
  //              ... The FRMT will be added here in another example ...
  //          </TED>
  //    </Documento>
  //  </DTE>

  success := xml.LoadXmlFile('qa_data/xml_dsig/sii_cl/test_1.xml');
  if (success = False) then
    begin
      WriteLn('Failed to load initial XML file.');
      Exit;
    end;

  //  Get a reference to the "DD" element
  ddXml := xml.FindChild('Documento|TED|DD');
  if (xml.LastMethodSuccess = False) then
    begin
      WriteLn('Failed to find DD element');
      Exit;
    end;

  //   We need to get the "flattened" DD XML where:
  //     - No whitespace between elements.
  //     - The 5 pre-defined entities are converted.
  //     - The text is encoded in the ISO-8859-1 character set (Latin-1), 
  sbFlattened := TStringBuilder.Create;
  ddXml.EmitCompact := True;
  ddXml.EmitXmlDecl := False;
  ddXml.GetXmlSb(sbFlattened);

  //  Compute the SHA-1 message digest of the iso-8859-1 byte representation, 
  //  and sign it with our RSA private key, getting the result in base64 format.

  privKey := TPrivateKey.Create;
  success := privKey.LoadAnyFormatFile('qa_data/rsa/rsaPrivKey_pkcs8.pem','');
  if (success = False) then
    begin
      WriteLn(privKey.LastErrorText);
      Exit;
    end;

  rsa := TRsa.Create;
  rsa.UsePrivateKey(privKey);

  rsa.EncodingMode := 'base64';
  rsa.Charset := 'iso-8859-1';
  sig := rsa.SignStringENC(sbFlattened.GetAsString(),'sha1');

  //  Add the FRMT signature element to the XML.
  xml.UpdateChildContent('Documento|TED|FRMT',sig);
  xml.UpdateAttrAt('Documento|TED|FRMT',True,'algoritmo','SHA1withRSA');

  ddXml.Free;

  //  See what we have:
  xml.EmitCompact := False;
  xml.EmitXmlDecl := True;
  WriteLn(xml.GetXml());


  xml.Free;
  sbFlattened.Free;
  privKey.Free;
  rsa.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.