XAdES includes several time-stamp token containers, namely the IndividualDataObjectsTimeStamp and AllDataObjectsTimeStamp properties. Time-stamps are applied over the digest of an input that is property-dependant. For instance, for the AllDataObjectsTimeStamp the input is the concatenation of the octet-streams resulting from processing each XML-DSIG Reference, in order of appearance.
In the beginning of my project I was (you’ll understand soon why I was) using the Java XML Signatures API (with the reference implementation), since it wouldn’t add any external dependencies to the library. Thus, when implementing the time-stamp properties over data object references, my first thought was: “the Reference interface should supply the referenced data after all the transforms are applied!”. And it does, through the getDigestInputStream method, which returns an InputStream representing the content to be digested as part of the Reference generation/validation process.
Everything looked good until that method actually returned null. The scenario was something like this (the operation order is what’s relevant):
XMLSignatureFactory xmlSigFact = XMLSignatureFactory.getInstance();
Reference ref = xmlSigFact.newReference("#root", …);
InputStream data = ref.getDigestInputStream(); // null
XMLSignature signature = xmlSigFact.newXMLSignature(…);
And then I read the documentation again: “returns an input stream containing the pre-digested input, or
null if reference caching is not enabled or this reference has not been generated or validated”. Since the API is implementation-independent, one doesn’t have direct control of Reference generation. In this case, I’m using the Reference before creating the signature, so it isn’t generated yet. Actually, since the Reference in the example above is a same-document reference and the default Java XML-DSIG implementation is DOM-based, what is really needed is for the Reference to be marshaled, because the getHere method is used during dereferencing. This is done internally during the signature generation, hence being out of our control. The problem is that the properties that need the data are signed properties, meaning they have to be created before the signature to also be signed!
I needed to try all the options so I came with another hypothesis: explicitly dereference the Reference:
This was a last resort, doomed right after I thought of it; naturally, it also failed because the Reference isn’t marshaled. Bottom line is I couldn’t find a way to do this!
I ended up switching to Apache XML Security, which makes the needed data available. The drawback is that I’m not using the standard API and I add an external dependency. On the other hand, I get better API to handle the dereferenced data and some useful services, such as direct canonicalization of DOM (sub)trees. If anyone has a solution, please tell me about it!