/**
 * 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/XSECBinTXFMInputStream.hpp>

#include "../utils/XSECDOMUtils.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;
}
