0

I have to sign and then countersign some xml with signature. This is my code:

private String singXadesEnveloped(String mode, Document document, Certificate[]    certificateChain, PrivateKey signingKey, String mimeType, String encoding)
        throws XAdES4jException, ClassCastException, UnsupportedEncodingException, ClassNotFoundException,
        InstantiationException, IllegalAccessException {

    try {
    DataObjectDesc desc = null; 
    KeyingDataProvider kp = new StaticKeyingDataProvider(certificateChain, signingKey);
    BasicSignatureOptionsProvider bop=new BasicSignatureOptionsProvider() {

        public boolean signSigningCertificate() {
            // TODO Auto-generated method stub
            return false;
        }

        public boolean includeSigningCertificate() {
            // TODO Auto-generated method stub
            return true;
        }

        public boolean includePublicKey() {
            // TODO Auto-generated method stub
            return true;
        }
    };
    //System.out.println("bop.includePublic="+bop.includePublicKey());
    XadesSigningProfile sp = new XadesBesSigningProfile(kp).withTimeStampTokenProvider(CertumFreeTimeStampProvider.class).withBasicSignatureOptionsProvider(bop);
    XadesSigner signer = sp.newSigner(); 

    desc = new DataObjectReference("")
    .withDataObjectFormat(new DataObjectFormatProperty(mimeType, encoding))
    .withTransform(new EnvelopedSignatureTransform());


    SignedDataObjects dataObjects = new SignedDataObjects(desc)
    .withCommitmentType(AllDataObjsCommitmentTypeProperty.proofOfOrigin());

    Element el = document.getDocumentElement();
    //System.out.println("element="+el.getNodeName());
    XadesSignatureResult sign = signer.sign(dataObjects, el);
    String signed_xml = serializeDocument(document);
    //System.out.println("\n\nPodpisany xml:\n"+signed_xml+"\n\n");


    XadesSignatureFormatExtender extender = new XadesFormatExtenderProfile().getFormatExtender();
    Element sigElem = sign.getSignature().getElement();
    //System.out.println("\n\nTag do podpisu:"+sigElem.getNodeName()+"\n\n");
    XMLSignature sig = new XMLSignature(sigElem, sigElem.getOwnerDocument().getBaseURI());
    XadesSigningProfile profile = new XadesBesSigningProfile(kp).withTimeStampTokenProvider(CertumFreeTimeStampProvider.class).withBasicSignatureOptionsProvider(bop);
    final XadesSigner counterSigner = profile.newSigner();


   // .withTransform(new ExclusiveCanonicalXMLWithoutComments());


    //System.out.println("\n\nNode sygnatury: "+sig.getElement().getNodeName()+"\n\n");


         Collection<UnsignedSignatureProperty> usp = new ArrayList(1);
            usp.add(new CounterSignatureProperty(counterSigner));

            extender.enrichSignature(sig, new UnsignedProperties(usp));

    } catch (XMLSignatureException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    } catch (XMLSecurityException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    /*-----------------------------------------------------*/

    //alternatywny sposób realizowania podpisu
    //new Enveloped(signer).sign(document.getDocumentElement());
    DOMSource domSource = new DOMSource(document);
    StringWriter writer = new StringWriter();
    StreamResult result = new StreamResult(writer);
    TransformerFactory tf = TransformerFactory.newInstance();
    Transformer transformer;
    try {
        transformer = tf.newTransformer();
        transformer.transform(domSource, result);
    } catch (TransformerConfigurationException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (TransformerException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    //System.out.println("\n\nsignXades signed before serializedocument: \n\n" + writer.toString());
    //return serializeDocument(signed_document);
    return writer.toString();
}

It signs my xml and adds counter signature. Unfortunatelly when I verify my xml, the signature veryfies OK, but counter signature not (The digest of signature is not equal with digest from file data).

What is wrong with my code? This is XML with signature and counter signature:

Signed and countersigned xml file

Tomi
  • 23
  • 5
  • The code seems correct. Can you provide the certificates needed to verify the signature and the included TS tokens so I can try to reproduce the problem? – lgoncalves Sep 02 '14 at 21:21
  • I verify my signed XML in external program so I really don't know what should I send to you (shame on me...). If it could help this is link to page where you can download the program from (it installs some certificates in system too). [First or second link on the page][1] [1]: http://sigillum.pl/pliki_do_pobrania.html How can I get "included TS tokens" to send them to you? – Tomi Sep 03 '14 at 05:46
  • I'd just need the certificate authorities certificates to verify the signature. Maybe they are publicly available? – lgoncalves Sep 03 '14 at 15:12

2 Answers2

0

If the problem is "The digest of signature is not equal with digest from file data", certificates do not help. However, I verified your signature with some other software. The digests and the signature value in the counter signature seem ok. Could you get the hashed values used in the verification application ?

The hashed blob for the signature value signed in the counter signature :

<ds:SignatureValue xmlns:adr="http://crd.gov.pl/xml/schematy/adres/2008/05/09/" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:inst="http://crd.gov.pl/xml/schematy/instytucja/2008/05/09/" xmlns:iso639-2="http://lcweb.loc.gov/standards/iso639-2/" xmlns:meta="http://crd.gov.pl/xml/schematy/meta/2008/05/09/" xmlns:oso="http://crd.gov.pl/xml/schematy/osoba/2008/05/09/" xmlns:str="http://crd.gov.pl/xml/schematy/struktura/2008/05/09/" xmlns:wnio="http://epuap.gov.pl/FeResourceServlet/wzor_lokalny/twmud37012/Wniosek_odpowiedzi/" Id="xmldsig-2d270d0c-76d2-4638-9e5a-fc149b383552-sigvalue">
orHos56IR77hfwBp2bas3L9E9X4K/oVAyRCkW/00gxon5ZEKCmmT5GhT/Bty6AOC5MsMwDKSgFbe
ysO7kqg5DuSOFPGocR3cBszH4w25Uoouk/0mxKU6BdTKl8Ud/N2RA/rUhvYBvH+JDjOrp+mtEmym
skBfxHssfzecGXQFtzskJLCMaxIhBQIw8RIOkREzFNozCCEw8uo9GEuzyfRC3EypVy8hL1p/qG2z
Ytf2lEJ4EastuCN5etHQSSVT4I9yeJulTj58e4d2IjtcVjJlpV1yetysv0R7E3cJ9YWaL4vH3Yhx
DtVIepegelZa37omW3GMtvIEDa6bdBx8WyMJLA==
</ds:SignatureValue>

A possible reason for the failure with the validation application is that you are not using canonicalization algorithms in the counter signature. I'm not familiar with xades4J but I think its API does not allow adding canonicalization algorithm to the counter signature.

Moez
  • 134
  • 7
  • This is xml file countersigned in application I use to verify my countersigned file. Of course it verifies... [File][1] [1]: https://www.dropbox.com/s/uwjiiuy6ai7z489/02_09_test_sig_kontr%20%282%29.xades?dl=0 – Tomi Sep 03 '14 at 12:23
  • The software I'm using see this second signature as invalid and I believe this is correct. The hash of the reference signed by the main signature (URI="") is invalid. Your both signatures are ENVELOPED (means the complete XML file containing the ds:Signature is signed). The second signature contains the same hash value as in your first signature; however the signed blob is not the same (in the first file you have a " – Moez Sep 03 '14 at 14:05
  • The counter signature has canonicalization algortihms specified. And even if they weren't, XML-DSIG defines the defaults. – lgoncalves Sep 03 '14 at 15:17
  • Nice catch Moez. This indicates that the application is not considering the whole XML resource. I'm not sure if those control tags should be included, but since xades4j delegates the reference handling on Apache Santuario, I'm assuming it's correct. – lgoncalves Sep 03 '14 at 15:24
  • Verifying this second signature on xades4j should also fail. Can you test it? – lgoncalves Sep 03 '14 at 15:25
  • From the XML-DSIG spec: URI="" Identifies the node-set (minus any comment nodes) of the XML resource containing the signature – lgoncalves Sep 03 '14 at 15:30
  • Here's another question that indicates the same problem: http://stackoverflow.com/questions/24642904/incorrect-reference-in-signature – lgoncalves Sep 03 '14 at 15:58
  • I tried my code with very simple xml without namespaces and stylesheet definition and the result is the same - first signature verified but counter signature not (in external verification program) [Simple xml][1] [1]: https://www.dropbox.com/s/5lurdp3me0pnnh5/simple.xades?dl=0 – Tomi Sep 04 '14 at 05:25
  • Can you try to generate an identical signature on the external application and verify it on xades4j? Having the two simple signatures allows us to compare the digests and so on. – lgoncalves Sep 04 '14 at 18:48
  • This is the simple file signed and countersigned in external program. I'm new in xades4j so writing verifier could take some time, but if you can have a look to attached file for some tests or comparison you wrote in your comment, it will be appreciated by me :-) [Signed and countersigned xml file with external program][1] [1]: https://www.dropbox.com/s/zthvpw01r3gp2jq/simple_xml.xml.xades?dl=0 – Tomi Sep 05 '14 at 06:48
  • I'll try to analyse this and do some tests. – lgoncalves Sep 05 '14 at 18:49
  • The external signature has an invalid structure: DataObjectformat property has an empty ObjectReference and this is invalid according to XAdES spec (section 7.2.5). On the signature created on xades4j, it seems that you're supplying more certificates than the ones in the singing chain, hence creating an invalid SigningCertificate property. Check the contents of "certificateChain". It should contain only certificates in the chain or even only the signing certificate (it must be the one on the first position). I worked around these 2 issues in debug and I was able to verify both signatures.. – lgoncalves Sep 05 '14 at 20:48
  • On further contact with the developer that posted the question above (http://stackoverflow.com/questions/24642904/incorrect-reference-in-signature), he seemed to be using the same third party tool. I think he was having problems because he wasn't using the latest version of xades4j. Which version are you using? also make sure you have the latest version of the third party tool. – lgoncalves Sep 06 '14 at 19:05
  • I have information from third party verification tools developers that the reason of this verification error is missing Type="h t t p://uri.etsi.org/01903#CountersignedSignature" in ds:Reference of counter signature. They event send me a simple line of code that is checking it: foundElement = getReferenceElementFromSignatureElement(countersignature, "h t t p://uri.etsi.org/01903#CountersignedSignature"); Is it possible to create such a counter signature with mentioned type in current version of xades4j? – Tomi Sep 12 '14 at 06:21
0

The information is scattered on the comments, so I'm posting the final answer here. The third party tool in use (likely Sigilum Sign, can you confirm?) needs the http://uri.etsi.org/01903#CountersignedSignature value on the Type of the main Reference in the counter signature. XAdES spec states that this reference is not mandatory on this use case of counter signatures, which means the third party tool should accept them. Nevertheless, the latest version of xades4j always includes the element.

If you get the latest version of xades4j on maven this should be fixed. If you got the binaries on the downloads section of xades4j website, please get them again, as the package had a small incoherence.

lgoncalves
  • 2,040
  • 1
  • 14
  • 12
  • That's good info, beacause I used 1.3.0 to create counter signature. I'll try 1.3.1 now :-) Actually after 10 minutes of work on it (uploading 1.3.1 to repository and rebuild applet), it... works (signature and countersignature verified)! Thank you very much Igoncalves ! :-) – Tomi Sep 15 '14 at 05:44