/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

/*
 * XSEC
 *
 * DSIG_Reference := Class for handling a DSIG reference element
 *
 * $Id$
 *
 */

// XSEC includes

#include <xsec/dsig/DSIGReference.hpp>
#include <xsec/transformers/TXFMChain.hpp>
#include <xsec/transformers/TXFMURL.hpp>
#include <xsec/transformers/TXFMDocObject.hpp>
#include <xsec/transformers/TXFMOutputFile.hpp>
#include <xsec/transformers/TXFMHash.hpp>
#include <xsec/transformers/TXFMBase64.hpp>
#include <xsec/transformers/TXFMSB.hpp>
#include <xsec/transformers/TXFMXPath.hpp>
#include <xsec/transformers/TXFMC14n.hpp>
#include <xsec/transformers/TXFMXSL.hpp>
#include <xsec/transformers/TXFMEnvelope.hpp>
#include <xsec/dsig/DSIGConstants.hpp>
#include <xsec/dsig/DSIGSignature.hpp>
#include <xsec/dsig/DSIGTransformList.hpp>
#include <xsec/dsig/DSIGTransformBase64.hpp>
#include <xsec/dsig/DSIGTransformEnvelope.hpp>
#include <xsec/dsig/DSIGTransformXPath.hpp>
#include <xsec/dsig/DSIGTransformXPathFilter.hpp>
#include <xsec/dsig/DSIGTransformXSL.hpp>
#include <xsec/dsig/DSIGTransformC14n.hpp>

#include <xsec/framework/XSECError.hpp>
#include <xsec/framework/XSECEnv.hpp>
#include <xsec/framework/XSECAlgorithmHandler.hpp>
#include <xsec/framework/XSECAlgorithmMapper.hpp>
#include <xsec/utils/XSECPlatformUtils.hpp>
#include <xsec/utils/XSECDOMUtils.hpp>
#include <xsec/utils/XSECBinTXFMInputStream.hpp>

// Xerces

#include <xercesc/util/XMLNetAccessor.hpp>
#include <xercesc/util/XMLUniDefs.hpp>
#include <xercesc/util/Janitor.hpp>

XERCES_CPP_NAMESPACE_USE

#include <iostream>

// --------------------------------------------------------------------------------
//           Some useful strings
// --------------------------------------------------------------------------------


static const XMLCh  s_unicodeStrURI[] =
{
        XERCES_CPP_NAMESPACE_QUALIFIER chLatin_U,
        XERCES_CPP_NAMESPACE_QUALIFIER chLatin_R,
        XERCES_CPP_NAMESPACE_QUALIFIER chLatin_I,
        XERCES_CPP_NAMESPACE_QUALIFIER chNull
};

static const XMLCh  s_unicodeStrxpointer[] =
{
        XERCES_CPP_NAMESPACE_QUALIFIER chLatin_x,
        XERCES_CPP_NAMESPACE_QUALIFIER chLatin_p,
        XERCES_CPP_NAMESPACE_QUALIFIER chLatin_o,
        XERCES_CPP_NAMESPACE_QUALIFIER chLatin_i,
        XERCES_CPP_NAMESPACE_QUALIFIER chLatin_n,
        XERCES_CPP_NAMESPACE_QUALIFIER chLatin_t,
        XERCES_CPP_NAMESPACE_QUALIFIER chLatin_e,
        XERCES_CPP_NAMESPACE_QUALIFIER chLatin_r,
        XERCES_CPP_NAMESPACE_QUALIFIER chNull
};

static const XMLCh s_unicodeStrRootNode[] =
{
        XERCES_CPP_NAMESPACE_QUALIFIER chOpenParen,
        XERCES_CPP_NAMESPACE_QUALIFIER chForwardSlash,
        XERCES_CPP_NAMESPACE_QUALIFIER chCloseParen,
        XERCES_CPP_NAMESPACE_QUALIFIER chNull
};

// --------------------------------------------------------------------------------
//           Constructors and Destructors
// --------------------------------------------------------------------------------


DSIGReference::DSIGReference(const XSECEnv * env, DOMNode *dom) :
    mp_formatter(NULL),
    mp_referenceNode(dom),
    mp_preHash(NULL),
    mp_manifestList(NULL),
    mp_URI(NULL),
    m_isManifest(false),
    mp_transformsNode(NULL),
    mp_hashValueNode(NULL),
    mp_env(env),
    mp_transformList(NULL),
    mp_algorithmURI(NULL),
    m_loaded(false) {

    // Should throw an exception if the node is not a REFERENCE element

    XSECnew(mp_formatter, XSECSafeBufferFormatter("UTF-8",XMLFormatter::NoEscapes,
                                                XMLFormatter::UnRep_CharRef));
}

DSIGReference::DSIGReference(const XSECEnv * env) :
    mp_formatter(NULL),
    mp_referenceNode(NULL),
    mp_preHash(NULL),
    mp_manifestList(NULL),
    mp_URI(NULL),
    m_isManifest(false),
    mp_transformsNode(NULL),
    mp_hashValueNode(NULL),
    mp_env(env),
    mp_transformList(NULL),
    mp_algorithmURI(NULL),
    m_loaded(false) {

    XSECnew(mp_formatter, XSECSafeBufferFormatter("UTF-8",XMLFormatter::NoEscapes,
                                            XMLFormatter::UnRep_CharRef));
};

DSIGReference::~DSIGReference() {

    // Destroy any associated transforms

    if (mp_transformList != NULL) {

        delete mp_transformList;
        mp_transformList = NULL;

    }

    if (mp_formatter != NULL)
        delete mp_formatter;

    if (mp_manifestList != NULL)
        delete mp_manifestList;

};

// --------------------------------------------------------------------------------
//           Creation of Transforms
// --------------------------------------------------------------------------------

void DSIGReference::createTransformList(void) {

    // Creates the transforms list
    safeBuffer str;
    const XMLCh * prefix;
    DOMDocument *doc = mp_env->getParentDocument();

    prefix = mp_env->getDSIGNSPrefix();

    if (mp_transformsNode == NULL) {

        // Need to create a transforms node
        makeQName(str, prefix, "Transforms");
        mp_transformsNode = doc->createElementNS(DSIGConstants::s_unicodeStrURIDSIG, str.rawXMLChBuffer());
        mp_referenceNode->insertBefore(mp_transformsNode, mp_referenceNode->getFirstChild());
        if (mp_env->getPrettyPrintFlag() == true)
            mp_referenceNode->insertBefore(doc->createTextNode(DSIGConstants::s_unicodeStrNL), mp_transformsNode);
        mp_env->doPrettyPrint(mp_transformsNode);

        // Create the list
        XSECnew(mp_transformList, DSIGTransformList());
    }

}

void DSIGReference::addTransform(DSIGTransform * txfm, DOMElement * txfmElt) {

    if (mp_transformList == NULL)
        createTransformList();

    mp_transformsNode->appendChild(txfmElt);
    mp_env->doPrettyPrint(mp_transformsNode);

    mp_transformList->addTransform(txfm);
}


DSIGTransformEnvelope * DSIGReference::appendEnvelopedSignatureTransform() {

    DOMElement *txfmElt;
    DSIGTransformEnvelope * txfm;

    XSECnew(txfm, DSIGTransformEnvelope(mp_env));
    txfmElt = txfm->createBlankTransform(mp_env->getParentDocument());

    addTransform(txfm, txfmElt);

    return txfm;

}

DSIGTransformBase64 * DSIGReference::appendBase64Transform() {

    DOMElement *txfmElt;
    DSIGTransformBase64 * txfm;

    XSECnew(txfm, DSIGTransformBase64(mp_env));
    txfmElt = txfm->createBlankTransform(mp_env->getParentDocument());

    addTransform(txfm, txfmElt);

    return txfm;

}

DSIGTransformXSL * DSIGReference::appendXSLTransform(DOMNode * stylesheet) {

    DOMElement *txfmElt;
    DSIGTransformXSL * txfm;

    XSECnew(txfm, DSIGTransformXSL(mp_env));
    txfmElt = txfm->createBlankTransform(mp_env->getParentDocument());
    txfm->setStylesheet(stylesheet);

    addTransform(txfm, txfmElt);

    return txfm;

}

DSIGTransformC14n * DSIGReference::appendCanonicalizationTransform(
        const XMLCh * canonicalizationAlgorithmURI) {

    DOMElement *txfmElt;
    DSIGTransformC14n * txfm;

    XSECnew(txfm, DSIGTransformC14n(mp_env));
    txfmElt = txfm->createBlankTransform(mp_env->getParentDocument());
    txfm->setCanonicalizationMethod(canonicalizationAlgorithmURI);

    addTransform(txfm, txfmElt);

    return txfm;

}

DSIGTransformXPath * DSIGReference::appendXPathTransform(const char * expr) {

    DOMElement *txfmElt;
    DSIGTransformXPath * txfm;

    XSECnew(txfm, DSIGTransformXPath(mp_env));
    txfmElt = txfm->createBlankTransform(mp_env->getParentDocument());
    txfm->setExpression(expr);

    addTransform(txfm, txfmElt);

    return txfm;
}

DSIGTransformXPathFilter * DSIGReference::appendXPathFilterTransform(void) {

    DOMElement *txfmElt;
    DSIGTransformXPathFilter * txfm;

    XSECnew(txfm, DSIGTransformXPathFilter(mp_env));
    txfmElt = txfm->createBlankTransform(mp_env->getParentDocument());

    addTransform(txfm, txfmElt);
    mp_env->doPrettyPrint(txfmElt);

    return txfm;
}



// --------------------------------------------------------------------------------
//           Creation of blanks
// --------------------------------------------------------------------------------


DOMElement *DSIGReference::createBlankReference(const XMLCh * URI,
                                                const XMLCh * hashAlgorithmURI,
                                                const XMLCh * type) {

    // Reset this Reference just in case

    m_isManifest = false;
    mp_preHash = NULL;
    mp_manifestList = NULL;
    mp_transformsNode = NULL;
    mp_transformList = NULL;

    safeBuffer str;
    DOMDocument *doc = mp_env->getParentDocument();
    const XMLCh * prefix = mp_env->getDSIGNSPrefix();

    makeQName(str, prefix, "Reference");

    DOMElement *ret = doc->createElementNS(DSIGConstants::s_unicodeStrURIDSIG, str.rawXMLChBuffer());
    mp_referenceNode = ret;

    // Set type
    if (type != NULL)
        ret->setAttributeNS(NULL, MAKE_UNICODE_STRING("Type"), type);

    // Set URI
    if (URI != NULL) {
        ret->setAttributeNS(NULL, s_unicodeStrURI, URI);
        mp_URI = ret->getAttributeNS(NULL, s_unicodeStrURI); // Used later on as a pointer
    }
    else {
        // Anonymous reference
        mp_URI = NULL;
    }

    // Create hash and hashValue nodes
    makeQName(str, prefix, "DigestMethod");
    DOMElement *digestMethod = doc->createElementNS(DSIGConstants::s_unicodeStrURIDSIG, str.rawXMLChBuffer());
    mp_env->doPrettyPrint(ret);
    ret->appendChild(digestMethod);
    mp_env->doPrettyPrint(ret);

    digestMethod->setAttributeNS(NULL, DSIGConstants::s_unicodeStrAlgorithm,
        hashAlgorithmURI);

    // Retrieve the attribute value for later use
    mp_algorithmURI =
        digestMethod->getAttributeNS(NULL, DSIGConstants::s_unicodeStrAlgorithm);


    // DigestValue

    makeQName(str, prefix, "DigestValue");
    mp_hashValueNode = doc->createElementNS(DSIGConstants::s_unicodeStrURIDSIG, str.rawXMLChBuffer());
    ret->appendChild(mp_hashValueNode);
    mp_env->doPrettyPrint(ret);
    mp_hashValueNode->appendChild(doc->createTextNode(MAKE_UNICODE_STRING("Not yet calculated")));

    m_loaded = true;
    return ret;

}

// --------------------------------------------------------------------------------
//           setPreHashTransform - to set a transform to be used pre-hash
// --------------------------------------------------------------------------------


void DSIGReference::setPreHashTXFM(TXFMBase * t) {

    mp_preHash = t;

}

//           setId
// --------------------------------------------------------------------------------

void DSIGReference::setId(const XMLCh *id) {

    if (mp_referenceNode)
        ((DOMElement*)mp_referenceNode)->setAttributeNS(NULL, MAKE_UNICODE_STRING("Id"), id);

}

// --------------------------------------------------------------------------------
//           setType
// --------------------------------------------------------------------------------

void DSIGReference::setType(const XMLCh *type) {

    if (mp_referenceNode)
        ((DOMElement*)mp_referenceNode)->setAttributeNS(NULL, MAKE_UNICODE_STRING("Type"), type);

}

// --------------------------------------------------------------------------------

// --------------------------------------------------------------------------------
//           isManifest
// --------------------------------------------------------------------------------

bool DSIGReference::isManifest() const {

    return m_isManifest;

}

// --------------------------------------------------------------------------------
//           getURI
// --------------------------------------------------------------------------------

const XMLCh * DSIGReference::getURI() const {

    return mp_URI;

}

// --------------------------------------------------------------------------------
//           getManifestReferenceList
// --------------------------------------------------------------------------------

DSIGReferenceList * DSIGReference::getManifestReferenceList() const {

    return mp_manifestList;

}

// --------------------------------------------------------------------------------
//           getURIBaseTransform
// --------------------------------------------------------------------------------

TXFMBase * DSIGReference::getURIBaseTXFM(DOMDocument * doc,
                                         const XMLCh * URI,
                                         const XSECEnv * env) {

    // Determine if this is a full URL or a pointer to a URL

    if (URI == NULL || (URI[0] != 0 &&
        URI[0] != XERCES_CPP_NAMESPACE_QUALIFIER chPound)) {

        TXFMURL * retTransform;

        // Have a URL!

        XSECnew(retTransform, TXFMURL(doc, env->getURIResolver()));

        try {
            ((TXFMURL *) retTransform)->setInput(URI);
        }
        catch (...) {

            delete retTransform;
            throw;

        }

        return retTransform;

    }

    // Have a fragment URI from the local document
    TXFMDocObject * to;
    XSECnew(to, TXFMDocObject(doc));
    Janitor<TXFMDocObject> j_to(to);
    to->setEnv(env);

    // Find out what sort of object pointer this is.

    if (URI[0] == 0) {

        // empty pointer - use the document itself
        to->setInput(doc);
        to->stripComments();

    }

    else if (XMLString::compareNString(&URI[1], s_unicodeStrxpointer, 8) == 0) {

        // Have an xpointer
        if (strEquals(s_unicodeStrRootNode, &URI[9]) == true) {
            // Root node
            to->setInput(doc);

        }

        else if (URI[9] == XERCES_CPP_NAMESPACE_QUALIFIER chOpenParen &&
                URI[10] == XERCES_CPP_NAMESPACE_QUALIFIER chLatin_i &&
                URI[11] == XERCES_CPP_NAMESPACE_QUALIFIER chLatin_d &&
                URI[12] == XERCES_CPP_NAMESPACE_QUALIFIER chOpenParen &&
                URI[13] == XERCES_CPP_NAMESPACE_QUALIFIER chSingleQuote) {

            XMLSize_t len = XMLString::stringLen(&URI[14]);

            XMLCh* tmp = new XMLCh[len + 1];
            ArrayJanitor<XMLCh> j_tmp(tmp);

            XMLSize_t j = 14, i = 0;

            // Have an ID
            while (i < len && URI[j] != '\'') {
                tmp[i++] = URI[j++];
            }

            tmp[i] = XERCES_CPP_NAMESPACE_QUALIFIER chNull;

            if (URI[j] != '\'') {
                throw XSECException(XSECException::UnsupportedXpointerExpr);
            }

            to->setInput(doc, tmp);

        }

        else {

            throw XSECException(XSECException::UnsupportedXpointerExpr);

        }

        // Keep comments in these situations
        to->activateComments();
    }

    else {

        to->setInput(doc, &URI[1]);

        // Remove comments
        to->stripComments();

    }

    j_to.release();
    return to;

}

// --------------------------------------------------------------------------------
//           load
// --------------------------------------------------------------------------------

void DSIGReference::load(void) {

    // Load reference info from XML

    DOMNamedNodeMap *atts = mp_referenceNode->getAttributes();
    DOMNode *tmpElt;

    const XMLCh * name;
    safeBuffer sbName;

    if (atts != 0) {

        XMLSize_t size = atts->getLength();

        for (XMLSize_t i = 0; i < size; ++i) {

            name = atts->item(i)->getNodeName();
            sbName << (*mp_formatter << atts->item(i)->getNodeName());

            if (strEquals(name, s_unicodeStrURI)) {
                mp_URI = atts->item(i)->getNodeValue();
            }

            else if (strEquals(name, "Type")) {

                // Check if a manifest, otherwise ignore for now
                if (strEquals(atts->item(i)->getNodeValue(), DSIGConstants::s_unicodeStrURIMANIFEST))
                    m_isManifest = true;

            }

            else if (strEquals(name, "Id")) {

                // For now ignore

            }

            else if (sbName.sbStrncmp("xmlns", 5) == 0) {

                // Ignore name spaces

            }

            else {
                //safeBuffer tmp, error;

                //error << (*mp_formatter << name);
                //tmp.sbStrcpyIn("Unknown attribute in <Reference> Element : ");
                //tmp.sbStrcatIn(error);

                throw XSECException(XSECException::UnknownDSIGAttribute,
                    "Unknown attribute in <Reference> Element");

            }

        }

    }

    // Now check for Transforms
    tmpElt = mp_referenceNode->getFirstChild();

    while (tmpElt != 0 && (tmpElt->getNodeType() != DOMNode::ELEMENT_NODE)) {
        if (tmpElt->getNodeType() == DOMNode::ENTITY_REFERENCE_NODE) {
            throw XSECException(XSECException::ExpectedDSIGChildNotFound,
                "EntityReference nodes in <Reference> are unsupported.");
        }
        // Skip text and comments
        tmpElt = tmpElt->getNextSibling();
    }

    if (tmpElt == 0) {

            throw XSECException(XSECException::ExpectedDSIGChildNotFound,
                    "Expected <Transforms> or <DigestMethod> within <Reference>");

    }

    if (strEquals(getDSIGLocalName(tmpElt), "Transforms")) {

        // Store node for later use
        mp_transformsNode = tmpElt;

        // Load the transforms
        mp_transformList = loadTransforms(tmpElt, mp_formatter, mp_env);

        // Find next node
        tmpElt = tmpElt->getNextSibling();
        while (tmpElt != 0 && (tmpElt->getNodeType() != DOMNode::ELEMENT_NODE)) {
            if (tmpElt->getNodeType() == DOMNode::ENTITY_REFERENCE_NODE) {
                throw XSECException(XSECException::ExpectedDSIGChildNotFound,
                    "EntityReference nodes in <Reference> are unsupported.");
            }
            tmpElt = tmpElt->getNextSibling();
        }


    } /* if tmpElt node type = transforms */
    else {
        mp_transformList = NULL;
    }


    if (tmpElt == NULL || !strEquals(getDSIGLocalName(tmpElt), "DigestMethod")) {

        throw XSECException(XSECException::ExpectedDSIGChildNotFound,
                            "Expected <DigestMethod> element");

    }

    // Determine what the digest method actually is

    atts = tmpElt->getAttributes();
    unsigned int i;

    for (i = 0; i < atts->getLength() &&
        !strEquals(atts->item(i)->getNodeName(), DSIGConstants::s_unicodeStrAlgorithm); ++i);


    if (i == atts->getLength()) {

        throw XSECException(XSECException::ExpectedDSIGChildNotFound,
                            "Expected 'Algorithm' attribute in <DigestMethod>");

    }

    mp_algorithmURI = atts->item(i)->getNodeValue();

    // Find the hash value node

    tmpElt = tmpElt->getNextSibling();

    while (tmpElt != 0 &&
        (tmpElt->getNodeType() != DOMNode::ELEMENT_NODE || !strEquals(getDSIGLocalName(tmpElt), "DigestValue"))) {
        if (tmpElt->getNodeType() == DOMNode::ENTITY_REFERENCE_NODE) {
            throw XSECException(XSECException::ExpectedDSIGChildNotFound,
                "EntityReference nodes in <Reference> are unsupported.");
        }
        tmpElt = tmpElt->getNextSibling();
    }

    if (tmpElt == 0) {

        throw XSECException(XSECException::ExpectedDSIGChildNotFound,
            "Expected <DigestValue> within <Reference>");

    }

    mp_hashValueNode = tmpElt;

    // If we are a manifest, then we need to load the manifest references

    if (m_isManifest) {

        // Find the manifest node - we cheat and use a transform
        TXFMBase                * docObject;
        DOMNode                    * manifestNode, * referenceNode;

        docObject = getURIBaseTXFM(mp_referenceNode->getOwnerDocument(), mp_URI,
            mp_env);

        manifestNode = docObject->getFragmentNode();
        delete docObject;

        // Now search downwards to find a <Manifest>
        if (manifestNode == 0 || manifestNode->getNodeType() != DOMNode::ELEMENT_NODE ||
            (!strEquals(getDSIGLocalName(manifestNode), "Object") && !strEquals(getDSIGLocalName(manifestNode), "Manifest"))) {

            throw XSECException(XSECException::ExpectedDSIGChildNotFound,
                "Expected <Manifest> or <Object> URI for Manifest Type <Reference>");

        }

        if (strEquals(getDSIGLocalName(manifestNode), "Object")) {

            // Find Manifest child
            manifestNode = manifestNode->getFirstChild();
            while (manifestNode != 0 && manifestNode->getNodeType() != DOMNode::ELEMENT_NODE) {
                if (manifestNode->getNodeType() == DOMNode::ENTITY_REFERENCE_NODE) {
                    throw XSECException(XSECException::ExpectedDSIGChildNotFound,
                        "EntityReference nodes in <Reference> are unsupported.");
                }
                manifestNode = manifestNode->getNextSibling();
            }

            if (manifestNode == 0 || !strEquals(getDSIGLocalName(manifestNode), "Manifest"))
                throw XSECException(XSECException::ExpectedDSIGChildNotFound,
                "Expected <Manifest> as child of <Object> for Manifest Type <Reference>");

        }

        // Now have the manifest node, find the first reference and load!
        referenceNode = manifestNode->getFirstChild();

        while (referenceNode != 0 &&
            (referenceNode->getNodeType() != DOMNode::ELEMENT_NODE || !strEquals(getDSIGLocalName(referenceNode), "Reference"))) {
            if (referenceNode->getNodeType() == DOMNode::ENTITY_REFERENCE_NODE) {
                throw XSECException(XSECException::ExpectedDSIGChildNotFound,
                    "EntityReference nodes in <Reference> are unsupported.");
            }
            referenceNode = referenceNode->getNextSibling();
        }

        if (referenceNode == 0)
            throw XSECException(XSECException::ExpectedDSIGChildNotFound,
            "Expected <Reference> as child of <Manifest>");

        // Have reference node, so lets create a list!
        mp_manifestList = DSIGReference::loadReferenceListFromXML(mp_env, referenceNode);

    } /* m_isManifest */

    m_loaded = true;

}

// --------------------------------------------------------------------------------
//           createReferenceListFromXML
// --------------------------------------------------------------------------------

DSIGReferenceList *DSIGReference::loadReferenceListFromXML(const XSECEnv * env, DOMNode *firstReference) {

    // Have the first reference element in the document,
    // so want to find and load them all

    DOMNode *tmpRef = firstReference;
    DSIGReferenceList * refList;
    DSIGReference * r;

    XSECnew(refList, DSIGReferenceList());
    Janitor<DSIGReferenceList> j_refList(refList);

    while (tmpRef != 0) {

        // Must be an element node

        if (tmpRef->getNodeType() != DOMNode::ELEMENT_NODE ||
            !strEquals(getDSIGLocalName(tmpRef), "Reference")) {

            throw XSECException(XSECException::ExpectedDSIGChildNotFound,
                "Expected <Reference> as child of <SignedInfo>");

        }

        XSECnew(r, DSIGReference(env, tmpRef));

        refList->addReference(r);

        // Load the reference before moving on
        r->load();

        // Find next element Node
        tmpRef = tmpRef->getNextSibling();

        while (tmpRef != 0 && tmpRef->getNodeType() != DOMNode::ELEMENT_NODE) {
            if (tmpRef->getNodeType() == DOMNode::ENTITY_REFERENCE_NODE) {
                throw XSECException(XSECException::ExpectedDSIGChildNotFound,
                    "EntityReference nodes in <Reference> are unsupported.");
            }
            tmpRef = tmpRef->getNextSibling();
        }

    }

    j_refList.release();
    return refList;

}
// --------------------------------------------------------------------------------
//           Get the Canonicalised BYTE_STREAM of the reference data (and TXFMS)
// --------------------------------------------------------------------------------

XSECBinTXFMInputStream * DSIGReference::makeBinInputStream(void) const {

    // First set up for input

    TXFMChain * txfmChain;
    TXFMBase * currentTxfm;

    if (m_loaded == false) {

        throw XSECException(XSECException::NotLoaded,
            "calculateHash() called in DSIGReference before load()");

    }

    // Find base transform
    currentTxfm = getURIBaseTXFM(mp_referenceNode->getOwnerDocument(), mp_URI,
        mp_env);

    // Set up the transform chain

    txfmChain = createTXFMChainFromList(currentTxfm, mp_transformList);
    Janitor<TXFMChain> j_txfmChain(txfmChain);

    DOMDocument *d = mp_referenceNode->getOwnerDocument();

    // All transforms done.  If necessary, change the type from nodes to bytes

    if (txfmChain->getLastTxfm()->getOutputType() == TXFMBase::DOM_NODES) {

        TXFMC14n * c14n;
        XSECnew(c14n, TXFMC14n(d));
        txfmChain->appendTxfm(c14n);

    }

    // Now create the InputStream

    XSECBinTXFMInputStream * ret;
    ret = new XSECBinTXFMInputStream(txfmChain);    // Probs with MSVC++ mean no XSECnew
    j_txfmChain.release();        // Now owned by "ret"

    return ret;

}

// --------------------------------------------------------------------------------
//           Hash a reference list
// --------------------------------------------------------------------------------


void DSIGReference::hashReferenceList(const DSIGReferenceList *lst, bool interlocking) {

// Run through a list of hashes and checkHash for each one

    DSIGReference * r;
    int i = (int) lst->getSize();
    safeBuffer errStr;
    errStr.sbXMLChIn(DSIGConstants::s_unicodeStrEmpty);

    // Run a VERY naieve process at the moment that assumes the list will "settle"
    // after N iterations through the list.  This will settle any inter-locking references
    // Where a hash in a later calculated reference could impact an already calculated hash
    // in a previous references
    //
    // If interlocking is set to false, assume there are no interacting <Reference> nodes

    do {

        for (int j = 0; j < i; ++j) {

            r = lst->item(j);

            // If this is a manifest we need to set all the references in the manifest as well

            if (r->isManifest())
                hashReferenceList(r->getManifestReferenceList());

            // Re-ordered as per suggestion by Peter Gubis to make it more likely
            // that hashes are correct on first pass when manifests are involved

            r->setHash();

        }

    } while (interlocking && !DSIGReference::verifyReferenceList(lst, errStr) && i-- >= 0);
}

// --------------------------------------------------------------------------------
//           Verify reference list
// --------------------------------------------------------------------------------

bool DSIGReference::verifyReferenceList(const DSIGReferenceList * lst, safeBuffer &errStr) {

    // Run through a list of hashes and checkHash for each one

    XSEC_USING_XERCES(NetAccessorException);

    DSIGReference * r;
    bool res = true;

    int size = (lst ? (int) lst->getSize() : 0);

    for (int i = 0; i < size; ++i) {

        r = lst->item(i);

        try {
            if (!r->checkHash()) {

                // Failed
                errStr.sbXMLChCat("Reference URI=\"");
                errStr.sbXMLChCat(r->getURI());
                errStr.sbXMLChCat("\" failed to verify\n");

                res = false;

            }
        }
        catch (const NetAccessorException&) {

            res = false;

            errStr.sbXMLChCat("Error accessing network URI=\"");
            errStr.sbXMLChCat(r->getURI());
            errStr.sbXMLChCat("\".  Reference failed to verify\n");

        }
        catch (const XSECException& e) {

            if (e.getType() != XSECException::HTTPURIInputStreamError)
                throw;

            res = false;

            errStr.sbXMLChCat("Error accessing network URI=\"");
            errStr.sbXMLChCat(r->getURI());
            errStr.sbXMLChCat("\".  Reference failed to verify\n");

        }

        // if a manifest, check the manifest list
        if (r->isManifest())
            res = res & verifyReferenceList(r->getManifestReferenceList(), errStr);

    }

    return res;
}

// --------------------------------------------------------------------------------
//           processTransforms
// --------------------------------------------------------------------------------

TXFMChain * DSIGReference::createTXFMChainFromList(TXFMBase * input,
                            DSIGTransformList * lst) {

    TXFMChain * ret;
    XSECnew(ret, TXFMChain(input));

    if (lst == NULL)
        return ret;

    Janitor<TXFMChain> j_ret(ret);

    DSIGTransformList::TransformListVectorType::size_type size, i;

    size = lst->getSize();

    if (size > 0) {

        // Iterate through the list

        for (i = 0; i < size; ++i) {

            lst->item(i)->appendTransformer(ret);

        }

    }

    j_ret.release();
    return ret;

}

// --------------------------------------------------------------------------------
//           loadTransforms
// --------------------------------------------------------------------------------

DSIGTransformList * DSIGReference::loadTransforms(
                            DOMNode *transformsNode,
                            XSECSafeBufferFormatter * formatter,
                            const XSECEnv * env) {

    // This is defined as a static function, not because it makes use of any static variables
    // in the DSIGReference class, but to neatly link it to the other users

    if (transformsNode == 0 || (!strEquals(getDSIGLocalName(transformsNode), "Transforms") &&
        !strEquals(getXENCLocalName(transformsNode), "Transforms"))) {

            throw XSECException(XSECException::ExpectedDSIGChildNotFound,
                    "Expected <Transforms> in function DSIGReference::processTransforms");

    }

    // Create the list
    DSIGTransformList * lst;
    XSECnew(lst, DSIGTransformList());
    Janitor<DSIGTransformList> j_lst(lst);

    // Find First transform

    DOMNode * transforms = transformsNode->getFirstChild();
    while (transforms != NULL && transforms->getNodeType() != DOMNode::ELEMENT_NODE)
        transforms = transforms->getNextSibling();

    while (transforms != NULL) {

        // Process each transform in turn
        if (!strEquals(getDSIGLocalName(transforms), "Transform")) {

            // Not what we expected to see!
            safeBuffer tmp, error;

            error << (*formatter << getDSIGLocalName(transforms));
            tmp.sbStrcpyIn("Unknown attribute in <Transforms> - Expected <Transform> found ");
            tmp.sbStrcatIn(error);
            tmp.sbStrcatIn(">.");

            throw XSECException(XSECException::ExpectedDSIGChildNotFound, error.rawCharBuffer());

        }

        DOMNamedNodeMap * transformAtts = transforms->getAttributes();

        unsigned int i;

        for (i = 0; i < transformAtts->getLength() &&
                !strEquals(transformAtts->item(i)->getNodeName(), DSIGConstants::s_unicodeStrAlgorithm); ++i);

        if (i == transformAtts->getLength()) {

            throw XSECException(XSECException::ExpectedDSIGChildNotFound,
                "Algorithm attribute not found in <Transform> element");

        }

        safeBuffer algorithm;
        algorithm << (*formatter << transformAtts->item(i)->getNodeValue());

        // Determine what the transform is

        if (algorithm.sbStrcmp(URI_ID_BASE64) == 0) {

            DSIGTransformBase64 * b;
            XSECnew(b, DSIGTransformBase64(env, transforms));
            lst->addTransform(b);
            b->load();
        }

        else if (algorithm.sbStrcmp(URI_ID_XPATH) == 0) {

            DSIGTransformXPath * x;
            XSECnew(x, DSIGTransformXPath(env, transforms));
            lst->addTransform(x);
            x->load();
        }

        else if (algorithm.sbStrcmp(URI_ID_XPF) == 0) {

            DSIGTransformXPathFilter * xpf;

            XSECnew(xpf, DSIGTransformXPathFilter(env, transforms));
            lst->addTransform(xpf);
            xpf->load();

        }

        else if (algorithm.sbStrcmp(URI_ID_ENVELOPE) == 0) {

            DSIGTransformEnvelope * e;
            XSECnew(e, DSIGTransformEnvelope(env, transforms));
            lst->addTransform(e);
            e->load();
        }

        else if (algorithm.sbStrcmp(URI_ID_XSLT) == 0) {

            DSIGTransformXSL * x;
            XSECnew(x, DSIGTransformXSL(env, transforms));
            lst->addTransform(x);
            x->load();

        }


        else if (algorithm.sbStrcmp(URI_ID_C14N_COM) == 0 ||
                 algorithm.sbStrcmp(URI_ID_C14N_NOC) == 0 ||
                 algorithm.sbStrcmp(URI_ID_C14N11_COM) == 0 ||
                 algorithm.sbStrcmp(URI_ID_C14N11_NOC) == 0 ||
                 algorithm.sbStrcmp(URI_ID_EXC_C14N_COM) == 0 ||
                 algorithm.sbStrcmp(URI_ID_EXC_C14N_NOC) == 0) {

            DSIGTransformC14n * c;
            XSECnew(c, DSIGTransformC14n(env, transforms));
            lst->addTransform(c);
            c->load();

        }

        else {

            // Not what we expected to see!
            safeBuffer tmp;

            tmp.sbStrcpyIn("Unknown transform : ");
            tmp.sbStrcatIn(algorithm);
            tmp.sbStrcatIn(" found.");

            throw XSECException(XSECException::UnknownTransform, tmp.rawCharBuffer());
        }

        // Now find next element

        transforms = transforms->getNextSibling();
        while (transforms != NULL && transforms->getNodeType() != DOMNode::ELEMENT_NODE)
            transforms = transforms->getNextSibling();

    } /* while (transforms != NULL) */

    j_lst.release();
    return lst;
}

// --------------------------------------------------------------------------------
//           Set hash
// --------------------------------------------------------------------------------

void DSIGReference::setHash() {

    // Set up

    if (mp_hashValueNode == 0) {
        throw XSECException(XSECException::NotLoaded,
            "setHash() called in DSIGReference before load()");
    }

    unsigned int maxHashSize = XSECPlatformUtils::g_cryptoProvider->getMaxHashSize();

    XSECCryptoBase64 *    b64 = XSECPlatformUtils::g_cryptoProvider->base64();
    if (!b64) {
        throw XSECException(XSECException::CryptoProviderError,
                "Error requesting Base64 object from Crypto Provider");
    }

    Janitor<XSECCryptoBase64> j_b64(b64);

    // First determine the hash value
    XMLByte* calculatedHashVal = new XMLByte[maxHashSize];
    XMLByte* base64Hash = new XMLByte[maxHashSize * 2];

    unsigned int base64HashLen = 0;

    try {
        unsigned int calculatedHashLen = calculateHash(calculatedHashVal, maxHashSize);

        // Calculate the base64 value
        b64->encodeInit();
        base64HashLen = b64->encode(calculatedHashVal,
            calculatedHashLen,
            base64Hash,
            maxHashSize * 2);
        base64HashLen += b64->encodeFinish(&base64Hash[base64HashLen],
            (maxHashSize * 2) - base64HashLen);
    }
    catch (...) {
        delete[] calculatedHashVal;
        delete[] base64Hash;
        throw;
    }

    delete[] calculatedHashVal;

    // Ensure the string is terminated
    if (base64Hash[base64HashLen-1] == '\n')
        base64Hash[base64HashLen-1] = '\0';
    else
        base64Hash[base64HashLen] = '\0';

    // Now find the correct text node to re-set

    DOMNode* tmpElt = mp_hashValueNode->getFirstChild();

    while (tmpElt != NULL && tmpElt->getNodeType() != DOMNode::TEXT_NODE)
        tmpElt = tmpElt->getNextSibling();

    if (tmpElt == NULL) {
        // Need to create the underlying TEXT_NODE
        DOMDocument *doc = mp_referenceNode->getOwnerDocument();
        tmpElt = doc->createTextNode(MAKE_UNICODE_STRING((char *) base64Hash));
        mp_hashValueNode->appendChild(tmpElt);
    }
    else {
        tmpElt->setNodeValue(MAKE_UNICODE_STRING((char *) base64Hash));
    }

    delete[] base64Hash;
}




// --------------------------------------------------------------------------------
//           Create hash
// --------------------------------------------------------------------------------

unsigned int DSIGReference::calculateHash(XMLByte *toFill, unsigned int maxToFill) const {

    // Determine the hash value of the element

    // First set up for input

    TXFMBase * currentTxfm;
    TXFMChain * chain;

    unsigned int size;

    if (m_loaded == false) {

        throw XSECException(XSECException::NotLoaded,
            "calculateHash() called in DSIGReference before load()");

    }

    // Find base transform
    currentTxfm = getURIBaseTXFM(mp_referenceNode->getOwnerDocument(), mp_URI,
        mp_env);

    // Now build the transforms list
    // Note this passes ownership of currentTxfm to the function, so it is the
    // responsibility of createTXFMChain to ensure it gets deleted if this throws.

    chain = createTXFMChainFromList(currentTxfm, mp_transformList);
    Janitor<TXFMChain> j_chain(chain);

    DOMDocument *d = mp_referenceNode->getOwnerDocument();

    // All transforms done.  If necessary, change the type from nodes to bytes

    if (chain->getLastTxfm()->getOutputType() == TXFMBase::DOM_NODES) {

        TXFMC14n * c14n;
        XSECnew(c14n, TXFMC14n(d));
        chain->appendTxfm(c14n);

    }

    // Check to see if there is a final "application" transform prior to the hash

    if (mp_preHash != NULL) {

        chain->appendTxfm(mp_preHash);
        mp_preHash = NULL;    // Can't be re-used

    }

    // Check for debugging sink for the data
    TXFMBase* sink = XSECPlatformUtils::GetReferenceLoggingSink(d);
    if (sink)
        chain->appendTxfm(sink);


    // Get the mapping for the hash transform

    const XSECAlgorithmHandler* handler =
        XSECPlatformUtils::g_algorithmMapper->mapURIToHandler(mp_algorithmURI);

    if (handler == NULL) {
        throw XSECException(XSECException::SigVfyError,
            "Hash method unknown in DSIGReference::calculateHash()");
    }

    if (!handler->appendHashTxfm(chain, mp_algorithmURI)) {
        throw XSECException(XSECException::SigVfyError,
            "Unexpected error in handler whilst appending Hash transform");
    }

    // Now we have the hashing transform, run it.

    size = chain->getLastTxfm()->readBytes(toFill, maxToFill);

    // Clean out document if necessary
    chain->getLastTxfm()->deleteExpandedNameSpaces();

    return size;

}

// --------------------------------------------------------------------------------
//           Read hash
// --------------------------------------------------------------------------------

unsigned int DSIGReference::readHash(XMLByte *toFill, unsigned int maxToFill) const {

    // Determine the hash value stored in the reference

    // First set up for input

    unsigned int size;
    DOMNode *tmpElt;
    //const XMLCh * stringHash;

    TXFMBase * nextInput;

    DOMDocument *d = mp_referenceNode->getOwnerDocument();

    safeBuffer b64HashVal;

    // Find the hash value

    tmpElt = mp_referenceNode->getFirstChild();

    while (tmpElt != 0 && !strEquals(getDSIGLocalName(tmpElt), "DigestValue"))
        tmpElt = tmpElt->getNextSibling();

    if (tmpElt == NULL)
        // ERROR
        return 0;

    // Now read the DOMString of the hash

    tmpElt = tmpElt->getFirstChild();
    while (tmpElt != NULL && tmpElt->getNodeType() != DOMNode::TEXT_NODE)
        tmpElt = tmpElt->getNextSibling();

    if (tmpElt == NULL)
        // Something wrong with the underlying XML if no text was found
        throw XSECException(XSECException::NoHashFoundInDigestValue);

    b64HashVal << (*mp_formatter << tmpElt->getNodeValue());

    // Now have the value of the string - create a transform around it

    XSECnew(nextInput, TXFMSB(d));
    ((TXFMSB *) nextInput)->setInput(b64HashVal);

    // Create a transform chain (really as a janitor for the entire list)
    TXFMChain * chain;
    XSECnew(chain, TXFMChain(nextInput));
    Janitor<TXFMChain> j_chain(chain);

    // Now create the base64 transform

    XSECnew(nextInput, TXFMBase64(d));
    chain->appendTxfm(nextInput);

    // Now get the value

    size = chain->getLastTxfm()->readBytes(toFill, maxToFill);

    // Clear any documentat modifications

    chain->getLastTxfm()->deleteExpandedNameSpaces();

    return size;

}



// --------------------------------------------------------------------------------
//           Check a reference
// --------------------------------------------------------------------------------

bool DSIGReference::checkHash() const {

    // Determine the hash value of the element and check if matches that stored in the
    // DigestValue part of the element

    // First set up for input

    unsigned int maxHashSize = XSECPlatformUtils::g_cryptoProvider->getMaxHashSize();

    XMLByte* calculatedHashVal = new XMLByte[maxHashSize];        // The hash that we determined

    unsigned int calculatedHashSize;

    try {
        if ((calculatedHashSize = calculateHash(calculatedHashVal, maxHashSize)) == 0)
            return false;
    }
    catch (...) {
        delete[] calculatedHashVal;
        throw;
    }

    XMLByte* readHashVal = new XMLByte [maxHashSize];            // The hash in the element

    if (readHash(readHashVal, maxHashSize) != calculatedHashSize) {
        delete[] calculatedHashVal;
        delete[] readHashVal;
        return false;
    }

    for (unsigned int i = 0; i < calculatedHashSize; ++i) {
        if (calculatedHashVal[i] != readHashVal[i]) {
            delete[] calculatedHashVal;
            delete[] readHashVal;
            return false;
        }

    }

    delete[] calculatedHashVal;
    delete[] readHashVal;

    // Got through with flying colours!
    return true;
}
