EldoS | Feel safer!

Software components for data protection, secure storage and transfer

[Java] Reference validation - verifying external binary data

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.
#34352
Posted: 09/02/2015 07:58:52
by Mickaël Bénès (Standard support level)
Joined: 02/26/2013
Posts: 74

Hello.

I'm trying to validate a detached XAdES signature of a PDF file (I tried with a PDF but I could do the same with a txt or other).
I tried what was indicated here : https://www.eldos.com/documentation/sbb/documentation/ref_howto_xml_sign_verifyref.html
and thought that the URIData must be the signed file, but apparently I was wrong because the TElXMLVerifier.ValidateReference() returns false.

I checked in the C# samples and couldn't find how to do this so I need your help.

Here is the reference validation code, I placed it after the verification of the signature, as mentionned in the documentation.
Code
TElXMLReferenceList xmlRefsList = xmlVerifier.GetReferences();
for ( int i = 0; i < xmlRefsList.GetCount(); i++ ) {
   TElXMLReference ref   = xmlRefsList.GetReference( i );
   String refURI      = ref.GetURI();
   
   AppletAWS.println( "- Ref n°" + (i + 1) );
   AppletAWS.println( "\t- URI : " + refURI );
   
   if ( refURI.startsWith("file") ) {
      File fileSigned   = new File( URLDecoder.decode(refURI, "UTF-8") );
      String fileName   = fileSigned.getName();
      fileSigned      = new File( this._fileSigned.getParent() + System.getProperty("file.separator") + fileName );
      
      AppletAWS.println( "\t- file name : " + fileName );
      
      TElFileStream fs   = new TElFileStream( fileSigned.getAbsolutePath(), "r", true );
      byte[] uriData      = new byte[ (int) fs.GetLength() ];
      
      fs.Read( uriData, 0, uriData.length );
      ref.SetURIData( uriData );
   }
   else {
      if ( ref.GetURINode() == null ) {
         if ( refURI.compareTo("") == 0 ) {
            ref.SetURINode( xml.GetDocumentElement() );
         }
         else {
            try {
               String s = SBXMLUtils.ExtractIdFromLocalURI( refURI );
               if ( s.compareTo("") != 0 ) {
                  ref.SetURINode( SBXMLUtils.FindElementById(xml.GetDocumentElement(), s) );
               }
            }
            catch ( Exception e ) { }
         }
      }
   }
   
   boolean verifResult = xmlVerifier.ValidateReference( ref );
   
   AppletAWS.println( "\t- result : " + verifResult );
}


And here is the reference :
Quote
<ds:Reference URI="file:/Z:/Mickael/Sauvergarde/C_Users_Micka%C3%ABl/Desktop/fichiers_tests/Applets/DC1%20sign%C3%A9.pdf">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<ds:DigestValue>Nsdr+LYu1pDVc7inYR9XeOLjHx4=</ds:DigestValue>
</ds:Reference>

One more thing, the signing code isn't from us, we used an external application to sign the file but we would like to be abble to verify their detached XAdES signatures.

Thanks for your help.
#34353
Posted: 09/02/2015 08:25:05
by Dmytro Bogatskyy (EldoS Corp.)

Thank you for contacting us.

Quote
and thought that the URIData must be the signed file, but apparently I was wrong because the TElXMLVerifier.ValidateReference() returns false.

Yes, if URI is a file then you need to set URIData property with its contents, also you can set URIStream, URIStreamOffset and URIStreamCount properties that are used to specify the file stream (if URIStreamCount property is 0 then Stream.Size is used).
Quote
<ds:Reference URI="file:/Z:/Mickael/Sauvergarde/C_Users_Micka%C3%ABl/Desktop/fichiers_tests/Applets/DC1%20sign%C3%A9.pdf">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</ds:Transforms>

I think, the problem is that the reference contains an exclusive canonicalization transform that can't be applied to non-xml files. As verifying application should load the data contents as xml then canonicalize it.
Please try to remove this transform before verifying the reference, to do this call ref.GetTransformChain().Clear() method. It will help to understand how the signer application process it (possible it simply ignores this transform).
#34354
Posted: 09/02/2015 08:33:31
by Mickaël Bénès (Standard support level)
Joined: 02/26/2013
Posts: 74

New code :
Code
ref.SetURIData( uriData );
ref.SetURIStream( fs );
ref.SetURIStreamOffset( 0 );
ref.SetURIStreamCount( fs.GetLength() );
ref.GetTransformChain().Clear();
And now the reference is validated correctly. Does this mean that the signer application just ignores the transform ? Or is there something else ? Hard to tell I guess...
#34355
Posted: 09/02/2015 08:49:31
by Dmytro Bogatskyy (EldoS Corp.)

Hi,

Quote
Does this mean that the signer application just ignores the transform ?

Yes, I think, it just ignores this transform when failed to load this file as xml.
Anyway, the correct way would be not to include this transform for such files.
#34356
Posted: 09/02/2015 09:11:23
by Mickaël Bénès (Standard support level)
Joined: 02/26/2013
Posts: 74

OK thanks for the help.

While I'm at it, is there a way to know why a reference insn't validated ? The TElXMLVerifier.ValidateReference() method only returns FALSE in case of a unvalid reference.

EDIT : I think I know : the only possibility is if the signed data is altered.
#34359
Posted: 09/02/2015 10:49:36
by Dmytro Bogatskyy (EldoS Corp.)

Hi,

Quote
While I'm at it, is there a way to know why a reference insn't validated ? The TElXMLVerifier.ValidateReference() method only returns FALSE in case of a unvalid reference.

EDIT : I think I know : the only possibility is if the signed data is altered.

Usually, yes, the only possibility is that referenced data is altered.
ValidateReference() method is equivalent to caching Reference.DigestValue value then calling Reference.UpdateDigestValue() method that could throw an exception (this exception is caught inside ValidateReference() method) then comparing cached DigestValue with new Reference.DigestValue, and then restoring Reference.DigestValue. So, you can replace ValidateReference() method in this way and then if exception is thrown try to remove a transform and recalculate a digest value.
#34362
Posted: 09/02/2015 11:26:46
by Mickaël Bénès (Standard support level)
Joined: 02/26/2013
Posts: 74

All right, thank you.
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.

Reply

Statistics

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