/**
 * 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
 *
 * DSIGSignature := Class for checking and setting up signature nodes in a DSIG signature
 *
 * Author(s): Berin Lautenbach
 *
 * $Id$
 *
 */

#ifndef DSIGSIGNATURE_INCLUDE
#define DSIGSIGNATURE_INCLUDE

// XSEC Includes
#include <xsec/utils/XSECSafeBufferFormatter.hpp>
#include <xsec/dsig/DSIGTransform.hpp>
#include <xsec/dsig/DSIGKeyInfoList.hpp>
#include <xsec/dsig/DSIGConstants.hpp>
#include <xsec/dsig/DSIGSignedInfo.hpp>

// Xerces Includes

#include <xercesc/dom/DOM.hpp>

class XSECEnv;
class XSECBinTXFMInputStream;
class XSECURIResolver;
class XSECKeyInfoResolver;
class DSIGKeyInfoValue;
class DSIGKeyInfoX509;
class DSIGKeyInfoName;
class DSIGKeyInfoPGPData;
class DSIGKeyInfoSPKIData;
class DSIGKeyInfoMgmtData;
class DSIGObject;

/**
 * @ingroup pubsig
 */
/*\@{*/

/**
 * @brief The main class used for manipulating XML Digital Signatures.
 *
 * <p>The DSIGSignature class is used to manipulate and verify
 * \<signature\> blocks.  It should only ever be created via the 
 * XSECProvider class.</p>
 *
 */

class XSEC_EXPORT DSIGSignature {

protected:

    /** @name Constructors and Destructors */
    //@{

    /**
     * \brief Contructor for use with existing XML signatures or templates.
     *
     * <p>Create a DSIGSignature object based on an already existing
     * DSIG Signature XML node.  It is assumed that the underlying
     * DOM structure is in place and works correctly.</p>
     *
     * <p>It is required that the caller pass in the signature DOM Node
     * as there may be more than one signature in a document.  The caller
     * needs to specify which signature tree is to be used.</p>
     *
     * @param doc The DOM document node in which the signature is embedded.
     * @param sigNode The DOM node (within doc) that is to be used as the base of the signature.
     * @see #load
     */

    DSIGSignature(XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument* doc,
                  XERCES_CPP_NAMESPACE_QUALIFIER DOMNode* sigNode);

    virtual ~DSIGSignature();
    //@}

public:

    /** @name Load and Setup Functions */
    //@{

    /**
      * \brief Load the signature information from the DOM source.
      *
      * Used to tell the DSIGSignature object to read from the DOM tree
      * into local structures.  Will throw various exceptions if it finds that
      * the DOM structure is not in line with the XML Signature standard.
      *
      */

    void load();

    /**
      * \brief Externally set the signing/verification key
      *
      * Used prior to a verify or sign operation to set the signature key (public or
      * private respectively) to be used for the operation.
      *
      * @note Once passed in via this call, the key is owned by the Signature.  It will
      * deleted when a new key is loaded or the signature is released.
      *
      * @see #verify
      * @see #sign
      */

    void setSigningKey(XSECCryptoKey* k);

    //@}

    /** @name Signature Operations */
    //@{

    /**
      * \brief Verify that a signature is valid.
      *
      * <p>The <I>verify</I> function will validate the signature of an XML document
      * previously loaded into the DSIGSignature structure via a <I>load</I>.</p>
      *
      * <p>It performs the following operations : </p>
      * <ul>
      *        <li>Iterate through each reference and validate the hash;
      *        <li>Iterate through references contained in \<manifest\> elements;
      *        <li>Calculate the hash of the \<SignedInfo\> element; and
      *        <li>Validate the signature of the hash previously calculated.
      * </ul>
      *
      * @returns true/false
      *        <ul>
      *        <li><b>true</b> = Signature (and all references) validated correctly.
      *           <li><b>false</b> = Signature validation failed.  An error list can be found via a
      *          call to #getErrMsgs.
      *        </ul>
      * @see #load
      * @see #getErrMsgs
      */

    bool verify() const;

    /**
      * \brief Verify a signature is valid (skip references).
      *
      * <p>This function is almost the same as #verify except it will skip the
      * reference checks.
      *
      * @see #load
      * @see #verify
      */

    bool verifySignatureOnly() const;

    /**
      * \brief Sign a DSIGSignature DOM structure.
      *
      * <p>The #sign function will create the reference hash values and signature
      * value in a DOM structure previously created via a #load or #createBlankSignature
      * call </p>
      *
      * <p>It performs the following operations : </p>
      * <ul>
      *        <li>Iterate through each reference, calculate and set the hash value;
      *        <li>Iterate through references contained in \<manifest\> elements and set their values;
      *        <li>Calculate the hash of the \<SignedInfo\> element; and
      *        <li>Calculate (and set) the signature value given the hash previously calculated.
      * </ul>
      *
      * @note The key to use for signing must have been set prior to call to sign using #setSigningKey
      *
      * @throws XSECException (for errors during the XML formatting and loading)
      * @throws XSECCryptoException (for errors during the cryptographic operations)
      *
      * @see #setSigningKey
      * @see #load
      * @see #getErrMsgs
      */

    void sign();
    //@}

    /** @name Functions to create and manipulate signature elements. */
    //@{

    /**
      * \brief Set the prefix be used for the DSIG namespace.
      *
      * <p>When the XSEC library creates XML Element nodes, it uses the prefix here
      * for all nodes created.  By default, the library assumes that the default
      * namespace is used.</p>
      *
      * <p>The #createBlankSignature function will use this prefix to setup the
      * dsig namespace.  E.g. (assuming a call has been made to set the prefix to "ds")
      * the \<Signature\> element will have a namespace attribute added of</p>
      *
      * <p>xmlns:ds="http://www.w3.org/2000/09/xmldsig#"</p>
      *
      * <p>If no prefix has been set, this attribute will be set as the default namespace</p>
      *
      * @see #createBlankSignature
      * @param prefix The UTF-16 encoided NS prefix to use for the XML
      * Digital Signature nodes
      */

    void setDSIGNSPrefix(const XMLCh* prefix);

    /**
      * \brief Set the prefix be used for the Exclusive Canonicalisation namespace.
      *
      * The Exclusive Canonicalisation specification defines a new namespace for the
      * InclusiveNamespaces node.  This function can be used to set the prefix
      * that the library will use when creating nodes within this namespace.
      *
      * <p>xmlns:ds="http://www.w3.org/2001/10/xml-exc-c14n#"</p>
      *
      * If no prefix is set, the default namespace will be used
      *
      * @see #createBlankSignature
      * @param prefix The UTF-16 encoided NS prefix to use for the XML
      * Exclusive Canonicalisation nodes
      */

    void setECNSPrefix(const XMLCh* prefix);

    /**
      * \brief Set the prefix be used for the XPath-Filter2 namespace.
      *
      * The XPathFilter definition uses its own namespace.  This
      * method can be used to set the prefix that the library will use
      * when creating elements in this namespace
      *
      * <p>xmlns:ds="http://www.w3.org/2002/06/xmldsig-filter2"</p>
      *
      * If no prefix is set, the default namespace will be used
      *
      * @see #createBlankSignature
      * @param prefix The UTF-16 encoided NS prefix to use for the XPath
      * filter nodes
      */

    void setXPFNSPrefix(const XMLCh* prefix);

    /**
     * \brief Set Pretty Print
     *
     * The pretty print functions controls whether the library will output
     * CR/LF after the elements it adds to a document
     *
     * By default the library will do pretty printing (flag is true)
     *
     * @param flag Value to set for Pretty Printing (true = do pretty printing)
     */

    void setPrettyPrint(bool flag);

    /**
     * \brief Tell caller whether PrettyPrinting is active
     *
     * @returns True if Pretty Printing is active, false if not
     */

    bool getPrettyPrint() const;

    /**
     * \brief Create a \<Signature\> DOM structure.
     *
     * <p>The DOM structure created is still divorced from the document.  The callee
     * needs to take the returned \<Signature\> Element node and insert it at the
     * appropriate place in their document.</p>
     *
     * <p>The signature is a skeleton only.  There are no references or KeyInfo
     * elements inserted.  However the DSIGSignature structures are set up with the
     * new information, so once an element has been created and a signing key has been
     * set, a call to #sign will sign appropriately.
     *
     * @note The digest method (hash method) set here is for the signing function only.
     * Different hash methods can be used for reference elements.
     *
     * @param doc The document the Signature DOM structure will be inserted into.
     * @param canonicalizationAlgorithmURI The canonicalisation method to use.
     * @param signatureAlgorithmURI The Signature algorithm (defined by URI) to use
     * @returns The newly created \<Signature\> element that the caller should insert in
     * the document.
     */

    XERCES_CPP_NAMESPACE_QUALIFIER DOMElement* createBlankSignature(
        XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument* doc,
        const XMLCh* canonicalizationAlgorithmURI,
        const XMLCh* signatureAlgorithmURI
    );

    /**
     * \brief Add a new reference to the end of the list of \<Reference\> nodes.
     *
     * <p>Creates a new DSIGReference, adds it to the list of references handled
     * by the owning DSIGSignature and also creates the skeleton DOM structure into
     * the document.</p>
     *
     * @note The XSEC Library currently makes very little use of <em>type</em>
     * attributes in \<Reference\> Elements.  However this may of use to calling
     * applications.
     *
     * @see DSIGReference
     * @param URI The Data that this Reference node refers to.
     * @param hm The hashing (digest) method to be used for this reference
     * @param type A "type" string (as defined in XML Signature).
     * @returns The newly created DSIGReference element.
     * @deprecated Use the URI based creation method instead
     *
     */

    DSIGReference* createReference(
        const XMLCh* URI,
        const XMLCh* hashAlgorithmURI,
        const XMLCh* type = NULL
    );

    /**
     * \brief Remove a reference from the signature
     *
     * Removes the reference at the index point and returns a pointer
     * to the reference removed.
     *
     * @note This also releases ownership.  It is the responsibility of
     * the caller to ensure the reference is deleted.
     *
     * @note This removes the reference from the Signature
     *
     * @param index Point in the list to remove
     */

    DSIGReference* removeReference(DSIGReferenceList::size_type index);
    //@}

    /** @name General and Information functions. */
    //@{

    /**
     * \brief Get the hash of the Signed Value
     *
     * Function to calculate and return the hash of the \<SignedInfo\>
     * structures (after the canonicalization defined by
     * \<CanonicalizationMethod\> and the reference hashes have been performed).
     *
     * @param hashBuf Buffer to place the raw hash in.
     * @param hashBufLen The length of the buffer
     * @returns The length of the hash that was placed in hashBuf
     *
     */

    unsigned int calculateSignedInfoAndReferenceHash(unsigned char* hashBuf,
                                                    unsigned int hashBufLen) const;

    /**
     * \brief Get the hash of the Signed Value
     *
     * Function to calculate and return the hash of the \<SignedInfo\>
     * structures (after the canonicalization defined by
     * \<CanonicalizationMethod\> has been performed).
     *
     * @param hashBuf Buffer to place the raw hash in.
     * @param hashBufLen The length of the buffer
     * @returns The length of the hash that was placed in hashBuf
     *
     */

    unsigned int calculateSignedInfoHash(unsigned char* hashBuf,
                                        unsigned int hashBufLen) const;

    /**
     * \brief Return the reference list for outside use.
     *
     * Returns a pointer to the list of references which can
     * then be read by the caller.
     *
     * @returns The referenceList
     */

    DSIGReferenceList* getReferenceList();

    /**
     * \brief Return the reference list for outside use.
     *
     * Returns a pointer to the list of references which can
     * then be read by the caller.
     *
     * @returns The referenceList
     */

    const DSIGReferenceList* getReferenceList() const;

    /**
     * \brief Create an input stream from SignedInfo.
     *
     * This method allows applications to read the fully canonicalised
     * byte stream that is hashed and signed.
     *
     * All transforms are performed up to the point where they would
     * normally be fed into the Digest function.
     *
     * @returns A BinInputSource of the canonicalised SignedInfo
     */


    XSECBinTXFMInputStream* makeBinInputStream() const;


    /**
     * \brief Get the Error messages from the last #verify.
     *
     * Returns a list of text error messages from the last Signature
     * operation.  Each error that occurred is in the buffer, separated
     * by new-lines.
     *
     * @note The buffer is owned by the DSIGSignature object - do not delete it
     *
     * @returns A pointer to the buffer containing the error strings.
     *
     */

    const XMLCh* getErrMsgs() const;

    /**
     * \brief Get the NS Prefix being used for DSIG elements.
     *
     * @returns A pointer to the buffer holding the prefix
     * @see #setDSIGNSPrefix
     *
     */

    const XMLCh* getDSIGNSPrefix() const;

    /**
     * \brief Get the NS being used for EC nodes
     *
     * @returns A pointer to the buffer holding the prefix
     * @see #setECNSPrefix
     */

    const XMLCh* getECNSPrefix() const;

    /**
     * \brief Get the NS being used for XPath Filter2 nodes
     *
     * @returns A pointer to the buffer holding the prefix
     * @see #setXPFNSPrefix
     */

    const XMLCh* getXPFNSPrefix() const;

    /**
     * \brief
     *
     * Get the DOM_Document that this Signature is operating within.
     *
     * Mainly used by the library itself.
     *
     * @returns The DOM_Document node.
     */

    XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument* getParentDocument() const
        {return mp_doc;}

    /**
     * \brief Get canonicalisation algorithm
     *
     * Returns the canonicalisation algorithm that will be/is used
     * to canonicalise the \<SignedInfo\> element prior to hash/sign
     *
     * @returns The canonicalisation method
     */

    const XMLCh* getCanonicalizationMethod() const
        {return mp_signedInfo != NULL ? mp_signedInfo->getCanonicalizationMethod() : NULL;}


    /**
     * \brief Get the Algorithm URI
     *
     * @returns the URI associated with the Algorithm used to generate
     * the signature
     */

    const XMLCh* getAlgorithmURI() const;

    /**
     * \brief Get the Signature Value
     *
     * Returns the base64 string holding the signature value for this signature
     *
     * @returns the signature value string
     */

    const XMLCh* getSignatureValue(void) const;

    /**
     * \brief Helper function for sub Classes.
     *
     * Returns the pointer to the formatter being used within the Signature
     *
     */

    XSECSafeBufferFormatter* getSBFormatter(void) const {return mp_formatter;}

    /**
     * \brief Set the interlocking references flag
     *
     * This flag controls whether the library will cater for "interlocking"
     * Reference nodes - where the hash of one reference depends on the
     * hash of another.
     *
     * As of Version 1.3, this is, by default, set to false, as it is
     * fairly unusual to find a Reference node that has as an input the
     * digest value of another reference node.  By setting this value to
     * true, the library will first calculate all hash values, and then
     * verify the hash values.  If any are incorrect (caused by one
     * the value of one reference being changed *after* it was used as
     * the input to another), then the hash values are recalculated.  This
     * is repeated until the reference list "settles".
     *
     * @param flag true for interlocking references, false for standalone
     */

    void setInterlockingReferences(bool flag) {m_interlockingReferences = flag;}


    /**
     * \brief Get the interlocking references flag
     *
     * This flag controls whether the library will cater for "interlocking"
     * Reference nodes - where the hash of one reference depends on the
     * hash of another.
     *
     * As of Version 1.3, this is, by default, set to false, as it is
     * fairly unusual to find a Reference node that has as an input the
     * digest value of another reference node.  By setting this value to
     * true, the library will first calculate all hash values, and then
     * verify the hash values.  If any are incorrect (caused by one
     * the value of one reference being changed *after* it was used as
     * the input to another), then the hash values are recalculated.  This
     * is repeated until the reference list "settles".
     *
     * @return Value of flag - true for interlocking references, false for standalone
     */

    bool getInterlockingReferences() const {return m_interlockingReferences;}

    //@}

    /** @name Resolver manipulation */
    //@{

    /**
     * \brief Register a URIResolver
     *
     * Registers a URIResolver to be used by the Signature when dereferencing
     * a URI in a Reference element
     *
     */

    void setURIResolver(XSECURIResolver* resolver);

    /**
     * \brief Return a pointer to the resolver being used
     *
     * @returns A pointer to the URIResolver registered in this signature
     */

    XSECURIResolver* getURIResolver() const;

    /**
     * \brief Register a KeyInfoResolver
     *
     * Registers a KeyInfoResolver to be used by the Signature when
     * it needs to find a key to be used to validate a signature
     *
     */

    void setKeyInfoResolver(XSECKeyInfoResolver* resolver);

    /**
     * \brief Return a pointer to the resolver being used
     *
     * @returns A pointer to the KeyInfoResolver registered in this signature
     */

    XSECKeyInfoResolver* getKeyInfoResolver() const;

    //@}

    /** @name KeyInfo Element Manipulation */

    //@{

    /**
     * \brief Get the list of \<KeyInfo\> elements.
     *
     * <p>This function recovers list that contains the KeyInfo elements
     * read in from the DOM document.</p>
     *
     * <p>This list should be used by calling applications to determine what key
     * is appropriate for validating (or even signing) the Signature.</p>
     *
     * @todo The KeyInfo process is very primitive.  An interface needs to be
     * created to allow application developers to install an object into the Signature
     * that the Signature can call on to translate KeyInfo lists into a Key.
     * @returns A pointer to the DSIGKeyInfoList object held by the DSIGSignature
     */

    DSIGKeyInfoList* getKeyInfoList() {return &m_keyInfoList;}

    /**
     * \brief Get the list of \<KeyInfo\> elements.
     *
     * <p>This function recovers list that contains the KeyInfo elements
     * read in from the DOM document.</p>
     *
     * <p>This list should be used by calling applications to determine what key
     * is appropriate for validating (or even signing) the Signature.</p>
     *
     * @todo The KeyInfo process is very primitive.  An interface needs to be
     * created to allow application developers to install an object into the Signature
     * that the Signature can call on to translate KeyInfo lists into a Key.
     * @returns A pointer to the DSIGKeyInfoList object held by the DSIGSignature
     */

    const DSIGKeyInfoList* getKeyInfoList() const {return &m_keyInfoList;}

    /**
     * \brief Clear out all KeyInfo elements in the signature.
     *
     * This function will delete all KeyInfo elements from both the DSIGSignature
     * object <em>and the associated DOM</em>.
     *
     */

    void clearKeyInfo();

    /**
     * \brief Append a DSA KeyValue element
     *
     * Add a new KeyInfo element for a DSA Value
     *
     * @param P Base64 encoded value of P
     * @param Q Base64 encoded value of Q
     * @param G Base64 encoded value of G
     * @param Y Base64 encoded value of Y
     * @returns A pointer to the created object.
     */

    DSIGKeyInfoValue* appendDSAKeyValue(const XMLCh* P,
                           const XMLCh* Q,
                           const XMLCh* G,
                           const XMLCh* Y);

    /**
     * \brief Append a RSA KeyValue element
     *
     * Add a new KeyInfo element for a RSA Value
     *
     * @param modulus Base64 encoded value of the modulus
     * @param exponent Base64 encoded value of exponent
     * @returns A pointer to the created object.
     */

    DSIGKeyInfoValue* appendRSAKeyValue(const XMLCh* modulus,
                           const XMLCh* exponent);

    /**
     * \brief Append a X509Data element.
     *
     * Add a new KeyInfo element for X509 data.
     *
     * @note The added element is empty.  The caller must make use of the
     * returned object to set the required values.
     *
     * @returns A pointer to the created object.
     */

    DSIGKeyInfoX509* appendX509Data();

    /**
     * \brief Append a KeyName element.
     *
     * Add a new KeyInfo element for a key name.
     *
     * @param name The name of the key to set in the XML
     * @param isDName Treat the name as a Distinguished name and encode accordingly
     * @returns A pointer to the created object
     */

    DSIGKeyInfoName* appendKeyName(const XMLCh* name, bool isDName = false);

    /**
     * \brief Append a PGPData element.
     *
     * Add a new KeyInfo element for a PGP key.
     *
     * @param id The ID of the key to set in the XML (base64 encoded - NULL if none)
     * @param packet The Packet information to set in the XML (base64 encoded -
     * NULL if none)
     * @returns A pointer to the created object
     */

    DSIGKeyInfoPGPData* appendPGPData(const XMLCh* id, const XMLCh* packet);

    /**
     * \brief Append a SPKIData element
     *
     * Add a new KeyInfo element for a set of SPKI S-expressions
     *
     * @param sexp The initial S-expression to set in the SPKIData element
     * @returns A pointer to the created object
     */

    DSIGKeyInfoSPKIData* appendSPKIData(const XMLCh* sexp);

    /**
     * \brief Append a MgmtData element
     *
     * Add a new KeyInfo element for Management Data
     *
     * @param data The string to set in the MgmtData element
     * @returns A pointer to the created object
     */

    DSIGKeyInfoMgmtData* appendMgmtData(const XMLCh* data);

    //@}

    /** @name Object handling */
    //@{

    /**
     * \brief Append an object container
     *
     * Create a new Object (i.e. a Signature \<Object\> which is a container
     * element used to hold information that needs to be signed within the
     * signature - i.e. in enveloping mode
     *
     * @returns the newly created DSIGObject
     */

    DSIGObject* appendObject();

    /**
     * \brief Find the number of ds:Object nodes within the Signature
     *
     * @returns the number of ds:Object nodes held in the Signature, 0 if none
     */

    int getObjectLength() const;

    /**
     * \brief Get a particular ds:Object from within the Signature
     *
     * @returns the ith Object from the list of ds:Object nodes in the signature.
     * Items are ordered in tree order.
     */

    DSIGObject* getObjectItem(int i);

    /**
     * \brief Get a particular ds:Object from within the Signature
     *
     * @returns the ith Object from the list of ds:Object nodes in the signature.
     * Items are ordered in tree order.
     */

    const DSIGObject* getObjectItem(int i) const;

    //@}

    /** @name ID handling */

    //@{

    /**
     * \brief Set Id finding behaviour
     *
     * The library de-references "#obj" URI references to ID attributes within
     * a DOM document.  Currently, the library first uses DOM calls to find if
     * the Id has been properly set within the document via the parser or one
     * of the DOM Level 3 calls to set an Id.
     *
     * If no Id is found of the correct name, the library then starts searching
     * for attributes of a given name with the required value.  This list defaults
     * to "id" and "Id", but can be modified via a call to addIdAttributeName()
     *
     * The setIdByAttributeName call enables or disables the second part of the Id
     * search.  I.e. when the Id doesn't exist as an attribute of Type=ID, whether or
     * not to search for an attribute of a name in the list of names.  By default
     * this behaviour is disabled.
     *
     * @warning The default has been changed from earlier versions of the library
     * to address the security risk of assuming IDness based on name.
     *
     * @param flag Enable (true) or Disable (false) searching for Id attributes by name
     */

    void setIdByAttributeName(bool flag);

    /**
     * \brief Determine Id finding behaviour
     *
     * Allows a caller to determine whether the library is currently searching for
     * Id attributes by name
     *
     * @returns The value of the IdByAttributeName flag
     */

    bool getIdByAttributeName() const;

    /**
     * \brief Add an attribute name to be searched for when looking for Id attributes
     *
     * This allows a user to add an attribute name to be used to identify Id attributes
     * when they are not set to be of Type=ID in the DOM
     *
     * @note Two names are registered by default - "Id" and "id".  These can be
     * removed by calling deregisterIdAttributeName
     *
     * @param name Name to append to the list of those used to find Id attributes
     */

    void registerIdAttributeName(const XMLCh* name);

    /**
     * \brief Remove an attribute name to be searched for when looking for Id attributes
     *
     * This allows a user to de-register a particular name to be used to identify Id
     * attributes.
     *
     * @param name Name to remove from the list of those used to find Id attributes
     * @returns true if found and removed, false if was not in the list
     */

    bool deregisterIdAttributeName(const XMLCh* name);

    /**
     * \brief Add an attribute name within a particular Namespace
     * to be searched for when looking for Id attributes
     *
     * This allows a user to add an attribute name to be used to identify Id attributes
     * when they are not set to be of Type=ID in the DOM
     *
     * @note Two names are registered by default - "Id" and "id".  These can be
     * removed by calling deregisterIdAttributeName
     *
     * @param ns Namespace in which attribute will reside
     * @param name Name to append to the list of those used to find Id attributes
     */

    void registerIdAttributeNameNS(const XMLCh* ns, const XMLCh* name);

    /**
     * \brief Remove an attribute name and ns to be searched for when looking for Id attributes
     *
     * This allows a user to de-register a particular name to be used to identify Id
     * attributes.
     *
     * @param ns Namespace in which attribute will reside
     * @param name Name to remove from the list of those used to find Id attributes
     * @returns true if found and removed, false if was not in the list
     */

    bool deregisterIdAttributeNameNS(const XMLCh* ns, const XMLCh* name);

    //@}

    friend class XSECProvider;

private:

    // For holding DSIGObject nodes
#if defined(XSEC_NO_NAMESPACES)
    typedef vector<DSIGObject*> ObjectVectorType;
#else
    typedef std::vector<DSIGObject*> ObjectVectorType;
#endif


    // Internal functions
    void createKeyInfoElement();
    bool verifySignatureOnlyInternal() const;
    TXFMChain* getSignedInfoInput() const;

    // Initialisation
    static void Initialise();

    XSECSafeBufferFormatter* mp_formatter;
    bool m_loaded;                // Have we already loaded?
    XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument* mp_doc;
    XERCES_CPP_NAMESPACE_QUALIFIER DOMNode* mp_sigNode;
    DSIGSignedInfo* mp_signedInfo;
    XERCES_CPP_NAMESPACE_QUALIFIER DOMNode* mp_signatureValueNode;
    safeBuffer m_signatureValueSB;
    DSIGKeyInfoList m_keyInfoList;
    XERCES_CPP_NAMESPACE_QUALIFIER DOMNode* mp_KeyInfoNode;
    mutable safeBuffer m_errStr;

    // Environment
    XSECEnv* mp_env;

    // The signing/verifying key
    mutable XSECCryptoKey* mp_signingKey;

    // Resolvers
    XSECKeyInfoResolver* mp_KeyInfoResolver;

    // Objects
    ObjectVectorType m_objects;

    // Interlocking references
    bool m_interlockingReferences;

    // Not implemented constructors

    DSIGSignature();

    friend class XSECPlatformUtils;

    /*\@}*/
};

#endif /* DSIGSIGNATURE_INCLUDE */
