EldoS | Feel safer!

Software components for data protection, secure storage and transfer

SelectNodes - Canonicalization

Also by EldoS: BizCrypto
Components for BizTalk® and SQL Server® Integration Services that let you securely store and transfer information in your business automation solutions.
#11466
Posted: 10/26/2009 10:12:38
by David MICHEL (Standard support level)
Joined: 09/23/2009
Posts: 48

Hello,

Here for example my XML file before applying the signature :

Code
<?xml version="1.0" encoding="UTF-8"?>
<ebicsRequest xmlns="http://www.ebics.org/H003" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.ebics.org/H003 http://www.ebics.org/H003/ebics_request.xsd" Version="H003" Revision="1">
  <header authenticate="true">
    <static>
      <HostID>EBIXQUAL</HostID>
      <TransactionID>8306F45EAFB68951D8D3C9D2DB1F0333</TransactionID>
    </static>
    <mutable>
      <TransactionPhase>Receipt</TransactionPhase>
    </mutable>
  </header>
  <body>
    <TransferReceipt authenticate="true">
      <ReceiptCode>0</ReceiptCode>
    </TransferReceipt>
  </body>
</ebicsRequest>


Before canonizing, how to make so that canonization applies to the nodes with for attribute "authenticate = true".

Result desired of canonization before the calculation of the hash :

Code
<header authenticate="true">
    <static>
      <HostID>EBIXQUAL</HostID>
      <TransactionID>8306F45EAFB68951D8D3C9D2DB1F0333</TransactionID>
    </static>
    <mutable>
      <TransactionPhase>Receipt</TransactionPhase>
    </mutable>
  </header>
    <TransferReceipt authenticate="true">
      <ReceiptCode>0</ReceiptCode>
    </TransferReceipt>


Here my code :

Code
  RefList := TElXMLReferenceList.Create;
  try//1
    Ref  := TElXMLReference.Create;
    try
      //Algo du Hash
      Ref.DigestMethod := xdmSHA256;
      //URINode = XPath
      Ref.URI := '#xpointer(//*[@authenticate=''true''])';
      ExtractURINode('//*[@authenticate]','http://www.ebics.org/H003');
      Ref.URINode := FURINode;
      //C14N Transform = 'Canonical transform'
      C14N := TElXMLC14NTransform.Create;
      try
        C14N.CanonicalizationMethod := xcmCanon;
        Ref.TransformChain.Add(C14N);
      except
      end;

      Ref.UpdateDigestValue;
      RefList.Add(Ref);
    except
    end;

.....



Code
//Extract XPath
procedure TfrmMainGestion.ExtractURINode(XPath,NameSpaces:String);
var
  NodeSet : TElXMLNodeSet;
  NSMap   : TElXMLNamespaceMap;
  s, t    : XMLString;
  i       : Integer;
begin

  if (NameSpaces = '') then
    NodeSet := FXMLDocument.SelectNodes(XPath)
  else begin
    NSMap := TElXMLNamespaceMap.Create;
    try
      s := Trim(NameSpaces);
      while s <> '' do
      begin
        i := Pos(',', s);
        if i > 0 then
        begin
          t := Trim(Copy(s, 1, i - 1));
          s := Trim(Copy(s, i + 1, MaxInt));
        end
        else
        begin
          t := s;
          s := '';
        end;

        i := Pos('=', t);
        if i > 0 then
          NSMap.AddNamespace(Trim(Copy(t, 1, i - 1)), Trim(Copy(t, i + 1, MaxInt)));
      end;

      NodeSet := FXMLDocument.SelectNodes(XPath, NSMap);
    finally
      FreeAndNil(NSMap);
    end;
  end;

  try
    if (NodeSet.Count > 0) then
      FURINode := NodeSet.Node[0]
      
      {
      for i := 0 to NodeSet.Count-1 do
      begin
      
        FURINode := NodeSet.Node[i]  // => Addition nodes ?
      
      end;
      }
    else
      FURINode := nil;

  finally
    FreeAndNil(NodeSet);
  end;

end;


Thank you.


Sincerely yours,
David MICHEL.
#11467
Posted: 10/26/2009 10:33:03
by Eugene Mayevski (EldoS Corp.)

xpointer is not supported by XMLBlackbox. It's your job to find the node(s), put them to NodeList if necessary and pass this node or nodes where appropriate.


Sincerely yours
Eugene Mayevski
#11489
Posted: 10/27/2009 09:18:08
by David MICHEL (Standard support level)
Joined: 09/23/2009
Posts: 48

Must one use the element TElXMLDOMNodeList ?

I do not see how to add my various nodes in the list.


Sincerely yours,
David MICHEL.
#11491
Posted: 10/27/2009 09:53:57
by Eugene Mayevski (EldoS Corp.)

I am afraid I won't be able to help you right now. Dmytro will be back from vacation on Thursday and he will assist you.

Meanwhile please assign the license ticket to your user account. The procedure is described in the registration e-mail. Only the license ticket gives the right for standard support.


Sincerely yours
Eugene Mayevski
#11493
Posted: 10/27/2009 10:41:07
by David MICHEL (Standard support level)
Joined: 09/23/2009
Posts: 48

Ok, Thank you.

Just for information, I proceeded as follows :

Code
...
TElXMLReference.URIData := BytesOfString(FURINodeData);


Or FURINodeData is XMLString =

Code
<header xmlns="http://www.ebics.org/H003" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" authenticate="true">
  <static>
    <HostID>EBIXQUAL</HostID>
    <TransactionID>8306F45EAFB68951D8D3C9D2DB1F0333</TransactionID>
  </static>
  <mutable>
    <TransactionPhase>Receipt</TransactionPhase>
  </mutable>
</header>
<TransferReceipt xmlns="http://www.ebics.org/H003" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" authenticate="true">
  <ReceiptCode>0</ReceiptCode>
</TransferReceipt>


however after canonization, I find myself with his data canonized before the hash with TElXMLReference.TransformChain.TransformData(Ref.URIData); :

Code
<header xmlns="http://www.ebics.org/H003" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" authenticate="true">
  <static>
    <HostID>EBIXQUAL</HostID>
    <TransactionID>8306F45EAFB68951D8D3C9D2DB1F0333</TransactionID>
  </static>
  <mutable>
    <TransactionPhase>Receipt</TransactionPhase>
  </mutable>
</header>


The following node is not took into account :

<TransferReceipt xmlns="http://www.ebics.org/H003" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" authenticate="true">
<ReceiptCode>0</ReceiptCode>
</TransferReceipt>


Sincerely yours,
David MICHEL.
#11499
Posted: 10/28/2009 03:37:19
by Dmytro Bogatskyy (EldoS Corp.)

We'll add URINodes property to the ElXMLReference class to support this.
At the moment you can use ElXMLReference.TransformChain.TransformData(TElXMLDOMNodeList Nodes) method to transform nodes. And then calculate a digest (for example, using SBXMLSec.Unit.CalculateDigest method) and set ElXMLReference.DigestValue
Quote
TElXMLReference.URIData := BytesOfString(FURINodeData);
Or FURINodeData is XMLString =
...
however after canonization, I find myself with his data canonized before the hash with TElXMLReference.TransformChain.TransformData(Ref.URIData); :

In this case, the data is expected to be a well-formed xml document (with one document element, so the second element is omitted). I'll check if it should support a list of elements.
#11504
Posted: 10/29/2009 03:28:21
by David MICHEL (Standard support level)
Joined: 09/23/2009
Posts: 48

Thank you for the precise details.
I followed this method by using a list.

Code
      var
        FURINodeList : TElXMLDOMNodeList;
        
      ...
      Ref.DigestMethod := xdmSHA256;
      Ref.URI := '#xpointer(//*[@authenticate=''true''])';
      ExtractURINode('//*[@authenticate]','http://www.ebics.org/H003',fichReqXml);
      Ref.URIData := nil;
      Ref.TransformChain.TransformData(FURINodeList);

      //C14N Transform = 'Canonical transform'
      C14N := TElXMLC14NTransform.Create;
      try
        C14N.CanonicalizationMethod := xcmCanon;
        Ref.TransformChain.Add(C14N);
      except
      end;
      ...
      
      //Calculate Digest value
      Buffer := Ref.TransformChain.TransformData(FURINodeList);
      Ref.DigestValue := CalculateDigest(Buffer,length(Buffer),xdmSHA256);      
      ...
      
      RefList.Add(Ref);


However, calculated the Ref.DigestValue value does not have any more the same value in the element xml <ds: DigestValue></ds: DigestValue> of the signature.

In input :
Ref.DigestValue := CalculateDigest(Buffer,length(Buffer),xdmSHA256);
=> C446C5...D867

In output :
<ds:DigestValue>...</ds:DigestValue> => E3B0C4...B855

Why is there this difference ?


Sincerely yours,
David MICHEL.
#11506
Posted: 10/29/2009 05:40:51
by David MICHEL (Standard support level)
Joined: 09/23/2009
Posts: 48

I found the problem.

In my code, before the signature, the Signer.UpdateReferencesDigest method to modify my Ref.DigestValue value.

Code
      ....
      //Signer.UpdateReferencesDigest;  //Comment

      //Sign
      Signer.Sign;
      Signer.Signature.SignaturePrefix := 'ds';
      ....


Sincerely yours,
David MICHEL.
#11507
Posted: 10/29/2009 05:47:56
by Dmytro Bogatskyy (EldoS Corp.)

Quote

I found the problem.
In my code, before the signature, the Signer.UpdateReferencesDigest method to modify my Ref.DigestValue value.

That's right. You shouldn't call UpdateReferencesDigest method if you modify DigestValue manually.
Also by EldoS: Callback File System
Create virtual file systems and disks, expose and manage remote data as if they were files on the local disk.

Reply

Statistics

Topic viewed 2971 times

Number of guests: 1, registered members: 0, in total hidden: 0




|

Back to top

As of July 15, 2016 EldoS Corporation will operate as a division of /n software inc. For more information, please read the announcement.

Got it!