Milan Tomic wrote:
I've run into strange things in DSIGReference class:
1. There is errStr variable of safeBuffer type declared in hashReferenceList(), but never used. It is used to keep the text "Reference URI="myReference" failed to verify\n", but then this variable is not used in any other way. Proper way would be to raise an exception with this text, but even if verification of URI fails, during signing, exception is not raised and signing completes. This is peace of verifyReferenceList():
... if (!r->checkHash()) { // Failed errStr.sbXMLChCat("Reference URI=\""); errStr.sbXMLChCat(r->getURI()); errStr.sbXMLChCat("\" failed to verify\n");
res = false; }
The library doesn't throw an exception here because a failed reference is not really an "error" in a sense that would cause an exception. So it returns 0 and uses errStr to allow a calling application to output error messages direct from the library.
Probably there should be an error handler that users can install to output errors as they occur. I've been meaning to do that, but ....
...
but there is no any exception to be raised nor anything else bad will happen. This is because this peace of code in hashReferenceList():
do {
for (int j = 0; j < i; ++j) {
r = lst->item(j);
r->setHash();
// If this is a manifest we need to set all the references in the manifest as well
if (r->isManifest())
hashReferenceList(r->getManifestReferenceList());
}
} while (interlocking && !DSIGReference::verifyReferenceList(lst, errStr) && (i-- >= 0));
this peace of code calculates and verifies hash 100 (10*10) times if you have 10 references.
Hmm. Yes. One of my little nasty quick fixes. But you should only get 100 iterations if the reference handling does not converge. (Actually it's 200 iterations as we also verify in the while check :<.)
The problem is that a manifest can have interlocking references. So something like ref1->ref2->ref3. If you go through once, ref3 will validate OK, but because ref2 refers to ref3 it will fail, as ref3 changed after ref2 was calculated (it changed because a new digest was set). So you have to run through a few times.
The idea of the interlocking variable was to allow a calling app to inform the library that there are no interlocking references, so only one pass through will occur. But I have this nasty feeling I've never put a call in anywhere to allow a calling app to change it.
Cheers,
Berin