Hi,

I create a signature with a C14N transform applied. Signing works. The 
signature is valid if I apply the checkSignatureValue() method directly on 
the result Document object.

However, if I write the Document out to the file system and parse it in back 
again later, the signature is invalid. So I canonicalise the Document again:

Canonicalizer c14n = Canonicalizer.getInstance(
"http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments";);
byte[] outputBytes = c14n.canonicalizeSubtree(document);

And build a fresh one from the bytes:

DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance();
dfactory.setNamespaceAware(true);
DocumentBuilder documentBuilder = dfactory.newDocumentBuilder();                
Document doc = documentBuilder.parse(new ByteArrayInputStream(outputBytes));

And do

String BaseURI = "";
signature = new XMLSignature(sigElement, BaseURI);
verified = signature.checkSignatureValue(myPublicKey);

However, the signature is still not valid. My guess is this happens because I 
use a parser to build the Document from the bytes - which is the standard 
javax.xml.parsers from JDK 1.5.

Looking at my document with kdiff3, I can see that only one line is different:

Original signed XML is
<env:Body xmlns:pdpa="http://da.ralphholz.de/PDP-A_1"; 
xmlns:pdpc="http://da.ralphholz.de/PDP-C"; 
xmlns:env="http://www.w3.org/2003/05/soap-envelope";>

Read-in and canonicalised XML is
<env:Body xmlns:pdpa="http://da.ralphholz.de/PDP-A_1"; 
xmlns:pdpc="http://da.ralphholz.de/PDP-C";>

Although this should not matter because only nodes further down the tree are 
signed, but not env:Body.

Where am I going wrong?

Thanks,
Ralph

PS:
The code for write out/read in is the following, although it should not 
matter:

<write out>
File file = new File(filename);
FileOutputStream f = new FileOutputStream(file);
TransformerFactory factory = TransformerFactory.newInstance();
Transformer transformer = factory.newTransformer();
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION,
"yes");
transformer.setOutputProperty("indent", "yes");
DOMSource source = new DOMSource(document);
StreamResult result = new StreamResult(f);
transformer.transform(source, result);
f.close();
</write out>

<read in>
dbfFactory.setNamespaceAware(true);
dbfFactory.setValidating(false);
dbfFactory.setAttribute("http://xml.org/sax/features/namespaces";, 
Boolean.TRUE);
builder = dbfFactory.newDocumentBuilder();
File f = new File(filename);
Document doc = builder.parse(new java.io.FileInputStream(f));
</read in>

-- 
For contact details, please see www.ralphholz.de.

Reply via email to