Great stuff. Do you mind if I add to XSECDOMUtils?
Cheers (and thanks!) Berin
John Moore wrote:
I dont know if it is of any help, but I have written a small C routine to walk
a DOM tree looking for signature elements and returning them one by one. Here
is the source:
// -----------------------------------------------------------------------------
---
// Find a nominated DSIG node in a document
//
// Repeated calls to this routine with "n" set to a node will walk the DOM tree
in a
// depth first, left to right order, stopping when it gets to the root node.
// It is assumed that the "n" node is in the tree starting at the "root" node.
// The routine does not use recursion, to allow it to be called repeatedly.
// -----------------------------------------------------------------------------
---
DOMNode * findNextDSIGNode(DOMNode * root, DOMNode * n, const char * nodeName) {
const XMLCh * name;
DOMNode * last;
DOMNode * next;
bool finish;
// either use the passed in parameter or (if null) the root node as the
starting point
if (n == NULL) {
last = root;
name = getDSIGLocalName(last);
}
else {
//dont test the passed in node, as it probably was tested in the last
call
last = n;
name = NULL;
}
finish = false;
while ((!atsStrEquals(name, nodeName)) && (!finish)) {
// is there a child?
next = last->getFirstChild();
if (next == NULL) {
// no, is there a sibling?
next = last->getNextSibling();
if (next == NULL) {
//no, so move back up the tree
while ((next == NULL) && (!finish)) {
last = last->getParentNode();
if ((last == root) || (last == NULL)) {
//got back up to the root node (or the DOM tree root -
shouldnt but...)
//so finish
finish = true;
}
else {
next = last->getNextSibling();
}
}
}
}
if (!finish) {
name = getDSIGLocalName(next);
last = next;
}
}
return next;
}
Routine is used like this:
sigNode = findNextDSIGNode(theDOM, NULL, "Signature");
sigcnt = 0;
result = true;
// Create the signature checker
while ((result) && (sigNode != NULL)) {
sig = prov.newSignatureFromDOM(theDOM, sigNode);
// use your favourite Resolver
xxxKeyResolver ires(NULL);
sig->setKeyInfoResolver(&ires);
try {
sig->load();
result = sig->verify();
}
catch (XSECException &e) {
// your favourite catch code
result = false;
}
catch (XSECCryptoException &e) {
// your favourite catch code
result = false;
}
sigcnt += 1;
sigNode = findNextDSIGNode(theDOM, sigNode, "Signature");
}
// if result is still true, then all dsigs verified. If result is false,
// then sigcnt contains the index of which dsig failed to verify.
ta john