EldoS | Feel safer!

Software components for data protection, secure storage and transfer

XML Signature

Also by EldoS: CallbackDisk
Create virtual disks backed by memory or custom location, expose disk images as disks and more.
#16111
Posted: 03/23/2011 11:02:44
by Bruno Gaufier (Standard support level)
Joined: 03/17/2011
Posts: 6

Hi,

I'm currently working with TElXMLSigner, to implement the EBICS protocol (client side).

Here is my question : I'd like to know if your implementation of TElXMLSigner::Sign and TElXMLSigner::Save are using References[].URINode.

I ask this, because I'm having a weird problem ; I've two signed queries, very similar :
- The first is working.
- The second is not, and the server returns an "EBICS_AUTHENTICATION_FAILED" error.
The only difference between the two queries are the source XML content (Both only have one node with the authenticate attribute set to true).

I'm seeing three things that can lead to my problem :
- The Sign or the Save method are using the URINode content to build the signature : As I've already calculated the Hash, and put it in a TElXMLReference's DigestValue, I Think they shouldn't.
- Something is not working properly during the Canonicalization part (It seems that the TElXMLSigner is only working with ONE node, so I'm building the final C14N'd byte array and it's hash manually).
- If the answer to my question is "No", It'll mean that I've borked something else.

TIA for any suggestion.
#16114
Posted: 03/23/2011 14:20:28
by Dmytro Bogatskyy (EldoS Corp.)

Quote
I'd like to know if your implementation of TElXMLSigner::Sign and TElXMLSigner::Save are using References[].URINode.
- The Sign or the Save method are using the URINode content to build the signature : As I've already calculated the Hash, and put it in a TElXMLReference's DigestValue, I Think they shouldn't.

No.
References DigestValue could be updated in methods ElXMLSigner.UpdateReferencesDigest or References[].UpdateDigestValue. Also it could be updated in Save method only if it is empty or References[].URI points inside a Signature/AuthSignature element.
Did you check a value of a reference's DigestValue? Is it the same to the value you set?

Quote
- Something is not working properly during the Canonicalization part (It seems that the TElXMLSigner is only working with ONE node, so I'm building the final C14N'd byte array and it's hash manually).

Yes, URINode accept only one node. We are working on extending this. At the moment the only way is to calculate digest value manually.

Quote
I ask this, because I'm having a weird problem ; I've two signed queries, very similar :

Could you post them here or to helpdesk.

P.S. Did you set ElXMLSigner.SignatureCompliance property to xscEBICS ?
#16122
Posted: 03/25/2011 04:07:45
by Bruno Gaufier (Standard support level)
Joined: 03/17/2011
Posts: 6

Quote
ElXMLSigner.UpdateReferencesDigest or References[].UpdateDigestValue. Also it could be updated in Save method only if it is empty or References[].URI points inside a Signature/AuthSignature element.

So, it should be OK ; I'm neither calling UpdateReferencesDigest nor UpdateDigestValue.

Quote
Did you check a value of a reference's DigestValue? Is it the same to the value you set?

I just checked : Yes, the DigestValue node content is equal to the value I set by code.
To be sure I hadn't missed something I also checked that the Digest value calculated when calling "UpdateReferencesDigest" is the same that I'm calculating manually (When working with only one node @authenticate=true).

Quote
Yes, URINode accept only one node. We are working on extending this. At the moment the only way is to calculate digest value manually.

That would be nice... but as it's easy to work-around, there's no hurry.

Quote
P.S. Did you set ElXMLSigner.SignatureCompliance property to xscEBICS ?

Yes :-)

Quote
Could you post them here or to helpdesk.

I've attached the XML files before/after signing and a PFX file to this post (The PFX is not password protected).


[ Download ]
#16123
Posted: 03/25/2011 05:13:40
by Dmytro Bogatskyy (EldoS Corp.)

Quote
I've attached the XML files before/after signing and a PFX file to this post (The PFX is not password protected).

I could verify references in both signed file and a signature for "HPB_request_signed.xml", but not a signature for "FDL_request_signed.xml" (possible I need different certificate).
As I understand you've created "HPB_request_signed.xml" document?
Do you have more sample xml document with ebicsNoPubKeyDigestsRequest document element so we could compare them?
#16157
Posted: 03/30/2011 09:07:09
by Bruno Gaufier (Standard support level)
Joined: 03/17/2011
Posts: 6

Quote
I could verify references in both signed file and a signature for "HPB_request_signed.xml", but not a signature for "FDL_request_signed.xml" (possible I need different certificate).

Both files are build using the same test procedure :
  • Create the initial XML file (FDL_request.xml / HPB_request.xml)
  • Sign it using the same method.
  • Save it to the xxx_signed_xxx.xml file.


Quote
As I understand you've created "HPB_request_signed.xml" document?

The procedure to sign both files is the following :
  • Load the TElXMLDOMDocument
  • Build the TElXMLReference : With C14N Canonicalization.
  • Build a TElXMLSigner : RSA/SHA256 with EBICS compliance.
  • Build a Nodeset containing the result of the evaluation of the xpath expression used as reference (Can be multiple nodes).
  • Build a byte array containing the result of the C14N transform (Byte by byte concatenation) of the this nodeset (This is done by calling TransformData on the TransformChain in a loop, for each Node of the NodeSet).
  • Evaluate the SHA256 hash of the resulting array and assign this value to TElXMLReference.DigestValue.
  • Save the signature (TElXMLReference.Save)
  • Save the resulting document.


That's because both file are similary signed, that I do not understand why one of them is good, and the other is not.
Although I've checked everything, and as I'm not a cryptography pro, I may have overlooked something (I've RTFM'd some docs, but it appears it's not enough).
  • Do I need to do any padding, somewhere (Before or after the canonicalization) ?
  • Is there something specific to do before (or after) manually calculating the SHA256 digest (I do put it into TElXMLReference.DigestValue, and do not call TElXMLSigner.UpdateReferencesDigest)?


Quote
Do you have more sample xml document with ebicsNoPubKeyDigestsRequest document element so we could compare them?

Sadly, this is for now the only message using this class.
#16159
Posted: 03/30/2011 13:48:23
by Dmytro Bogatskyy (EldoS Corp.)

Quote
The procedure to sign both files is the following :

Your procedure looks like okay.
Quote
That's because both file are similary signed, that I do not understand why one of them is good, and the other is not.
Do I need to do any padding, somewhere (Before or after the canonicalization) ?
Is there something specific to do before (or after) manually calculating the SHA256 digest (I do put it into TElXMLReference.DigestValue, and do not call TElXMLSigner.UpdateReferencesDigest)?

No, and no. Your digest value for a reference in both xml documents are okay.
But not a signature value for "FDL_request_signed.xml", I can't say exactly what is wrong here it could be either SignedInfo element was modified after signing, or SignatureValue itself was modified, or you signed this document not with "X002.pfx" certificate.
I have attached signed "FDL_request.xml" with "X002.pfx" certificate, could you test it. (It is exactly the same as "FDL_request_signed.xml" document except a SignatureValue.)
By the way, could you specify which file passes validation on server and which one fails?
Also could you post your code.


[ Download ]
#16163
Posted: 03/31/2011 08:04:39
by Bruno Gaufier (Standard support level)
Joined: 03/17/2011
Posts: 6

Here's a cleaned-up version of the method I call to sign the XML files :
  • I've rewriten the method (Removed exception handling and anything not directly related to XML signing).
  • I tried to make this snippet a little more readable than the original (It's also a bit larger)
  • I've checked that it gives the same result than my original method.
  • I've also checked that the resulting XML FDL XML file is rejected by the server (The HPB query is passing their validation, but not the FDL one)

Code
        
static void SignXmlFile(String pSource, String pDest, string pCertPath) {
   TElXMLDOMDocument lDocument = new TElXMLDOMDocument();
      using (Stream lReader = new FileStream(pSource, FileMode.Open)) {
      lDocument.LoadFromStream(lReader);
   }

   // Build the references
   TElXMLNodeSet lNodeSet = lDocument.SelectNodes("//*[@authenticate='true']");

   TElXMLReference lReference = new TElXMLReference();
   lReference.URINode = lNodeSet[0];
   lReference.URI = "#xpointer(//*[@authenticate='true'])";
   lReference.DigestMethod = SBXMLSec.Unit.xdmSHA256;

   TElXMLC14NTransform lC14NTransform = new TElXMLC14NTransform();
   lC14NTransform.CanonicalizationMethod = SBXMLDefs.Unit.xcmCanon;
   lReference.TransformChain.Add(lC14NTransform);
   
   TElXMLReferenceList lReferenceList = new TElXMLReferenceList();
   lReferenceList.Add(lReference);

   // Load the certificate
   TElX509Certificate lX509Cert = new TElX509Certificate();
   lX509Cert.LoadFromFileAuto(pCertPath,"");
   TElXMLKeyInfoX509Data lKeyInfo = new TElXMLKeyInfoX509Data(false);
   lKeyInfo.Certificate = lX509Cert;
   lKeyInfo.Update();

   // Build the TElXMLSigner
   TElXMLSigner lSigner = new TElXMLSigner();
   lSigner.SignatureType = SBXMLSec.Unit.xstEnveloped; // Detached signature should give the same result
   lSigner.CanonicalizationMethod = SBXMLDefs.Unit.xcmCanon;
   lSigner.SignatureMethodType = SBXMLSec.Unit.xmtSig;
   lSigner.SignatureMethod = SBXMLSec.Unit.xsmRSA_SHA256;
   lSigner.References = lReferenceList;
   lSigner.IncludeKey = false;
   lSigner.KeyData = lKeyInfo;
   lSigner.SignatureCompliance = SBXMLSec.Unit.xscEBICS;

   // Canonicalize the NodeSet content.
   byte[][] lTransformedNodes = new byte[lNodeSet.Count][];
   int lTransLen = 0;
   for (int i = 0; i < lNodeSet.Count; lTransLen += lTransformedNodes[i].Length, i++) {
      lTransformedNodes[i] = lReference.TransformChain.TransformData(lNodeSet[i]);
   }
   byte[] lTransformedSet = new byte[lTransLen];
   for (int i = 0, k = 0; i < lNodeSet.Count; k += lTransformedNodes[i].Length, i++) {
      Array.ConstrainedCopy(lTransformedNodes[i], 0, lTransformedSet, k, lTransformedNodes[i].Length);
   }

   // Set the digest value and sign the document
   lReference.DigestValue = HashData(lTransformedSet); // The HashData function return a SHA256 Hash.
   lSigner.Sign();

   // Save the Signature and rewrites the <body /> node after <AuthSignature />
   TElXMLDOMNode lOldBodyNode = lDocument.LastChild.FindNode("body");
   TElXMLDOMNode lNewBodyNode = lOldBodyNode.CloneNode(true);
   lDocument.LastChild.RemoveChild(lOldBodyNode);
   TElXMLDOMNode lSignatureNode = lDocument.LastChild;
   lSigner.Save(ref lSignatureNode);
   lDocument.LastChild.AppendChild(lNewBodyNode);

   // output to a file
   using (Stream lOutStream = new FileStream(pDest, FileMode.Create)) {
      lDocument.SaveToStream(lOutStream, 0, "");
   }

   // Cleanup
   lSigner.Dispose();
   if (lKeyInfo != null)
      lKeyInfo.Dispose();
}


PS :
- Btw, I've re-checked the file I send you, and although I do not know how I did it, I've messed something.
- The problem is the same : The HPB query is valid... but not the FDL one.
- Just to be sure, I've also attached to this post the unsigned XML files, the signed ones, the server answers and the CER + PFX files.


[ Download ]
#16165
Posted: 03/31/2011 14:55:36
by Dmytro Bogatskyy (EldoS Corp.)

Quote
I've re-checked the file I send you, and although I do not know how I did it, I've messed something.

Now I can successfully verify your FDL signed request with "X002.pfx" certificate.
Quote
- The problem is the same : The HPB query is valid... but not the FDL one.

I don't see anything special in signatures that could make verifier to process them differently.
From the EBICS 2.4.1 standard:
Quote

In error situations that result from an invalid combination of customer ID / subscriber ID or an inadmissible subscriber state, the sender receives the technical return code EBICS_AUTHENTICATION_FAILED.

Maybe something wrong in the data you specify in the header?
Quote

- Just to be sure, I've also attached to this post the unsigned XML files, the signed ones, the server answers and the CER + PFX files.

Could you please attach a server public key, it seems the server answer is signed with it.

Also could you try to add (somewhere before signing):
lDocument.DocumentElement.SetAttributeNS("", "xmlns:ds", "http://www.w3.org/2000/09/xmldsig#");
to make the signature to look the same as in the server answer.
#16170
Posted: 04/04/2011 03:53:35
by Bruno Gaufier (Standard support level)
Joined: 03/17/2011
Posts: 6

Quote
Maybe something wrong in the data you specify in the header?

- I've checked HostID, PartnerID & UserID : They are the same in HPB and HDL queries.
- Concerning the subscriber state, I can not directly check it. But after the HPB query it should be correctly initialized.
- Whataver, I'm going to re-check everything, just in case.

Quote
Could you please attach a server public key, it seems the server answer is signed with it.

I've attached a BankAuth.zip file to this message.

Quote
Also could you try to add (somewhere before signing):
lDocument.DocumentElement.SetAttributeNS("", "xmlns:ds", "http://www.w3.org/2000/09/xmldsig#");
to make the signature to look the same as in the server answer.

- I've already tried something like this (to mimics the bank / example from the documentation - usage of the "ds:" prefix, amongst other thing).
- As I'm not certain I exactly proceed the way you're suggesting, I'm going to try it now.


[ Download ]
#16171
Posted: 04/04/2011 05:29:55
by Dmytro Bogatskyy (EldoS Corp.)

Quote
I've attached a BankAuth.zip file to this message.

XML document "FDL_response.xml" is verified correctly with this certificate. As we can verify correctly signatures created by you and the bank, I think, a problem most likely in the EBICS specific data.
Also by EldoS: CallbackFilter
A component to monitor and control disk activity, track file and directory operations (create, read, write, rename etc.), alter file data, encrypt files, create virtual files.

Reply

Statistics

Topic viewed 5380 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!