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



Reply via email to