3

We would like to create a java web application which verify "XADES" signature, this application should take two files : the original file and his detached signature.

I'm using the XADES4j library which is great project. with XADES4j is there a way to verify signature without verifying the Reference for URI file ? because the given reference File in xml signature could not be accessible.

For reference validation : I'm looking to compare the digest Value calculated from the given orignal file and the digestValue extracted from the signature file.

Here is the exception

Exception in thread "main" xades4j.XAdES4jXMLSigException: Error verifying the signature
    at xades4j.verification.XadesVerifierImpl.doCoreVerification(XadesVerifierImpl.java:285)
    at xades4j.verification.XadesVerifierImpl.verify(XadesVerifierImpl.java:188)
    at com.wct.VerifyXades.main(VerifyXades.java:33)
Caused by: org.apache.xml.security.signature.MissingResourceFailureException: The Reference for URI file:/D:/workspace/xades4j-487d7a9bb9e5/data_to_sign/test.txt has no XMLSignatureInput
Original Exception was org.apache.xml.security.signature.ReferenceNotInitializedException: D:\workspace\xades4j-487d7a9bb9e5\data_to_sign\test.txt (Le fichier spécifié est introuvable)
Original Exception was org.apache.xml.security.signature.ReferenceNotInitializedException: D:\workspace\xades4j-487d7a9bb9e5\data_to_sign\test.txt (Le fichier spécifié est introuvable)
Original Exception was org.apache.xml.security.signature.ReferenceNotInitializedException: D:\workspace\xades4j-487d7a9bb9e5\data_to_sign\test.txt (Le fichier spécifié est introuvable)
Original Exception was org.apache.xml.security.utils.resolver.ResourceResolverException: D:\workspace\xades4j-487d7a9bb9e5\data_to_sign\test.txt (Le fichier spécifié est introuvable)
Original Exception was java.io.FileNotFoundException: D:\workspace\xades4j-487d7a9bb9e5\data_to_sign\test.txt (Le fichier spécifié est introuvable)
    at org.apache.xml.security.signature.Manifest.verifyReferences(Manifest.java:412)
    at org.apache.xml.security.signature.SignedInfo.verify(SignedInfo.java:256)
    at org.apache.xml.security.signature.XMLSignature.checkSignatureValue(XMLSignature.java:764)
    at org.apache.xml.security.signature.XMLSignature.checkSignatureValue(XMLSignature.java:696)
    at xades4j.verification.XadesVerifierImpl.doCoreVerification(XadesVerifierImpl.java:278)
    ... 2 more

Here is the source code i am using to verify XADES signature :

package com.wct;

import java.io.FileInputStream;
import java.security.cert.X509CertSelector;
import java.security.cert.X509Certificate;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import xades4j.providers.CertificateValidationException;
import xades4j.providers.CertificateValidationProvider;
import xades4j.providers.ValidationData;
import xades4j.verification.UnexpectedJCAException;
import xades4j.verification.XAdESVerificationResult;
import xades4j.verification.XadesVerificationProfile;
import xades4j.verification.XadesVerifier;

public class VerifyXades {

    public static void main(String[] args) throws Exception {
        CertificateValidationProvider certValidator = new CertificateValidationProviderImpl();
        XadesVerificationProfile p = new XadesVerificationProfile(certValidator);
        p.acceptUnknownProperties(true);
        XadesVerifier v = p.newVerifier();
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        dbf.setNamespaceAware(true);
        DocumentBuilder db = dbf.newDocumentBuilder();
        Document doc = db.parse(new FileInputStream("data_signed/detachedTestSignature.xml"));
        XAdESVerificationResult vr = v.verify(doc.getDocumentElement(), null);
    }
}

class CertificateValidationProviderImpl implements CertificateValidationProvider {
    @Override
    public ValidationData validate(X509CertSelector certSelector,
            Date validationDate, Collection<X509Certificate> otherCerts)
            throws CertificateValidationException, UnexpectedJCAException {
        return new ValidationData((List<X509Certificate>) otherCerts);
    }
}

I am new in signature/verify development and i have not good experience. please help

Thanks in advance for your helps

Khalilos
  • 721
  • 2
  • 9
  • 17

1 Answers1

2

You shouldn't be doing digests comparison of whatsoever. The file must be accessible somehow, so that the Reference can be checked as part of signature verification.

Are you in control of signature generation? IF so, you should change the URI for a relative URI or maybe use an anonymous reference (more info below). Anyway, all your options will be based on SignatureSpecificVerificationOptions.

If you can change signature verification:

  • Use a relative file uri on the Reference and specify a base URI on both signature production and verification. There are examples on xades4j tests.
  • Use an anonymous Reference (no URI attribute) and specify the data using an AnonymousDataObjectReference on signature production and the corresponding input on verification.

If you cannot change signature production:

lgoncalves
  • 2,040
  • 1
  • 14
  • 12
  • In our case we cannot change the signature production. in fact our program should take the detached signature and the original file. I'm looking to use the "ResourceResolver" but unfortunately the "XadesVerifier" always check the file's uri from the detached signature. here is the source code used to instantiate the "ResourceResolver" `ResourceResolver resolver = ResourceResolver.getInstance(doc.createAttribute("URI"), "file:/D:/workspace/xades4j-487d7a9bb9e5/data_to_sign/test11.txt", false); options.useResourceResolver(resolver);` – Khalilos Dec 09 '14 at 15:42
  • I don't understand your code. It is trying to get an existing resolver. I suggested using a custom resolver that has your logic of ignoring the actual URI. You actually need to implement a ResourceResolverSpi and pass it to ResourceResolver. You can probably look to the implementation of ResolverLocalFilesystem. – lgoncalves Dec 09 '14 at 15:59