xsec/dsig/DSIGReference.hpp (96 lines of code) (raw):

/** * 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 checking and setting up reference nodes in a DSIG signature * * $Id$ * */ #ifndef DSIGREFERENCE_INCLUDE #define DSIGREFERENCE_INCLUDE // High level include #include <xsec/framework/XSECDefs.hpp> // Xerces INcludes #include <xercesc/dom/DOM.hpp> #include <xercesc/dom/DOMNamedNodeMap.hpp> // XSEC Includes #include <xsec/utils/XSECSafeBufferFormatter.hpp> #include <xsec/dsig/DSIGTransform.hpp> #include <xsec/dsig/DSIGReferenceList.hpp> #include <xsec/dsig/DSIGConstants.hpp> class DSIGTransformList; class DSIGTransformBase64; class DSIGTransformC14n; class DSIGTransformEnvelope; class DSIGTransformXPath; class DSIGTransformXPathFilter; class DSIGTransformXSL; class DSIGSignature; class DSIGSignedInfo; class TXFMBase; class TXFMChain; class XSECBinTXFMInputStream; class XSECURIResolver; class XSECEnv; /** * @ingroup pubsig */ /** * @brief The class used for manipulating Reference Elements within a signature. * * <p>The DSIGReference class creates and manipulates (including hashing and validating) * \<Reference\> elements.</p> * */ class XSEC_EXPORT DSIGReference { public: /** @name Constructors and Destructors */ //@{ /** * \brief Contructor for use with existing XML signatures or templates. * * <p>Create a DSIGReference object based on an already existing * DSIG Reference XML node. It is assumed that the underlying * DOM structure is in place and works correctly.</p> * * @note DSIGReference structures should only ever be created via calls to a * DSIGSignature object. * * @param env The operating environment in which the Reference is operating * @param dom The DOM node (within doc) that is to be used as the base of the reference. * @see #load * @see DSIGSignature#createReference */ DSIGReference(const XSECEnv * env, XERCES_CPP_NAMESPACE_QUALIFIER DOMNode *dom); /** * \brief Contructor for use when creating new Reference structures. * * <p>Create a DSIGReference object that can later be used to create * a new Reference structure in the DOM document.</p> * * @note DSIGReference structures should only ever be created via calls to a * DSIGSignature object. * * @param env The environment object for this reference. * @see #load * @see DSIGSignature#createReference */ DSIGReference(const XSECEnv * env); /** * \brief Destructor. * * @note Does not impact any created DOM structures when destroyed. * * @note DSIGReferences should <em>never</em> be destroyed/deleted by * applications. They are owned and managed by DSIGSignature structures. */ ~DSIGReference(); //@} /** @name Reference Construction and Manipulation */ //@{ /** * \brief Load a DSIGReference from an existing DOM structure. * * <p>This function will load a Reference structure from the owner * document.</p> * */ void load(); /** * \brief Create a Reference structure in the document. * * <p>This function will create a Reference structure in the owner * document. In some cases, a call to this function will be sufficient * to put the required Reference in place. In other cases, calls will * also need to be made to the various append*Transform methods.</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. * * @param URI The URI (data source) for this reference. Set to NULL for * an anonymous reference. * @param hashAlgorithmURI The type of Digest to be used (generally SHA-1) * @param type A type string (as defined by XML Signature). * @returns The root Reference element of the newly created DOM structure. */ XERCES_CPP_NAMESPACE_QUALIFIER DOMElement * createBlankReference(const XMLCh * URI, const XMLCh * hashAlgorithmURI, const XMLCh * type); /** * \brief Append an Enveloped Signature Transform to the Reference. * * Appends a simple enveloped-signature transform to the list of transforms * in this element. * * @returns The newly created envelope transform. * */ DSIGTransformEnvelope * appendEnvelopedSignatureTransform(); /** * \brief Append a Base64 Transform to the Reference. * * @returns The newly created Base64 transform. */ DSIGTransformBase64 * appendBase64Transform(); /** * \brief Append an XPath Transform to the Reference. * * <p> Append an XPath transform. Namespaces can be added to the * transform directly using the returned <em>DSIGTransformXPath</em> * structure</p> * * @param expr The XPath expression to be placed in the transform. * @returns The newly created XPath transform */ DSIGTransformXPath * appendXPathTransform(const char * expr); /** * \brief Append an XPath-Filter2 Transform to the Reference. * * The returned DSIGTransformXPathFilter will have no actual filter * expressions loaded, but calls can be made to * DSIGTransformXPathFilter::appendTransform to add them. * * @returns The newly created XPath Filter transform */ DSIGTransformXPathFilter * appendXPathFilterTransform(void); /** * \brief Append an XSLT Transform to the Reference. * * <p>The caller must have already create the stylesheet and turned it into * a DOM structure that is passed in as the stylesheet parameter.</p> * * @param stylesheet The stylesheet DOM structure to be placed in the reference. * @returns The newly create XSLT transform */ DSIGTransformXSL * appendXSLTransform(XERCES_CPP_NAMESPACE_QUALIFIER DOMNode *stylesheet); /** * \brief Append a Canonicalization Transform to the Reference. * * @param canonicalizationAlgorithmURI The type of canonicalisation to be added. * @returns The newly create canonicalisation transform */ DSIGTransformC14n * appendCanonicalizationTransform( const XMLCh * canonicalizationAlgorithmURI ); /** * \brief Append a "debug" transformer. * * This method allows applications to provide a TXFM that will be appended * to the transform chain just prior to the application of the hash * algorithm. * * @note This is primarily for debugging. It should not be used to modify the * contents of the byte stream. * * @param t The TXFM element to insert. */ void setPreHashTXFM(TXFMBase * t); /** * \brief Set the Id attribute of the DSIGReference * * This method allows applications to set the Id attribute of the DSIGReference * as described in http://www.w3.org/TR/xmldsig-core/#sec-Reference. * * * @param id The value for this reference. */ void setId(const XMLCh *id); /** * \brief Set the Type attribute of the DSIGReference * * This method allows applications to set the Type attribute of the DSIGReference * as described in http://www.w3.org/TR/xmldsig-core/#sec-Reference. * * * @param type The value for this reference. */ void setType(const XMLCh *type); //@} /** @name Getting Information */ //@{ /** * \brief Create an input stream based on the digested byte stream. * * This method allows applications to read the fully canonicalised * byte stream that is hashed for a reference. * * 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(void) const; /** * \brief Return the URI string of the Reference. * * @returns A pointer to the buffer (owned by the Reference) containing * the value of the URI stored inthe reference */ const XMLCh * getURI() const; /** * \brief Get the Digest Algorithm URI * * @returns the URI associated with the Algorithm used to generate * the digest */ const XMLCh * getAlgorithmURI() const { return mp_algorithmURI; } /** * \brief Obtain the transforms for this reference * * Get the DSIGTransformList object for this reference. Can be used to * obtain information about the transforms and also change the the transforms */ DSIGTransformList * getTransforms(void) const { return mp_transformList; } /** * \brief Determine whether the reference is a manifest * * @returns true iff the Reference element is a Manifest reference */ bool isManifest() const; /** * \brief Get the Manifest * * @returns The ReferenceList containing the references in the Manifest * list of this reference element. */ DSIGReferenceList * getManifestReferenceList() const; // Return list of references for a manifest object //@} /** @name Message Digest/Hash manipulation */ //@{ /** * \brief Calculate the Hash value of a reference * * Takes the Reference URI, performs all the transforms and finally * calculates the Hash value of the data using the Digest algorithm * indicated in the reference * * @param toFill A Buffer that the raw hash will be copied into. * @param maxToFill Maximum number of bytes to place in the buffer * @returns The number of bytes copied into the buffer */ unsigned int calculateHash(XMLByte * toFill, unsigned int maxToFill) const; /** * \brief Read the hash from the Reference element. * * Reads the Base64 encoded element from the Reference element. * The hash is then translated from Base64 back into raw form and * written into the indicated buffer. * * @param toFill Pointer to the buffer where the raw hash will be written * @param maxToFill Maximum bytes to write to the buffer * @returns Number of bytes written */ unsigned int readHash(XMLByte *toFill, unsigned int maxToFill) const; /** * \brief Validate the Reference element * * Performs a #calculateHash() and a #readHash() and then compares the * results. * * @returns true iff the hash of the data matches the hash stored * in the reference. */ bool checkHash() const; /** * \brief Set the value of the hash in the Reference * * Hashes the data referenced by the element and then writes * the Base64 encoded hash value into the Reference. * */ void setHash(); //@} /** @name Helper (static) Functions */ //@{ /** * \brief Create a Transformer chain * * Given a TransformList create the corresponding TXFM chain to allow * the caller to read the reference byte stream * * @note This method is primarily for use within the XSEC library. * Users wishing to get the byte stream should use the #makeBinInputStream * method instead. * * @param input The input transformer to which the TXFMs will be applied to * This is generally created from the URI attribute of the reference. * @param lst The list of Transform elements from which to build the * transformer list. * @returns The <B>end</B> of the newly build TXFM chain. This can be * read from using TXFMBase::readBytes() to give the end result of the * transforms. */ static TXFMChain * createTXFMChainFromList(TXFMBase * input, DSIGTransformList * lst); /** * \brief Load a Transforms list from the \<Transforms\> DOMNode. * * Reads the data from the XML data stored in the DOM and create * the associated DSIGTrasnformList. * * @param transformsNode Starting node in the DOM * @param formatter The formatter to be used to move from XMLCh to strings * @param env Environment in which to operate * @returns A pointer to the created list. */ static DSIGTransformList * loadTransforms( XERCES_CPP_NAMESPACE_QUALIFIER DOMNode *transformsNode, XSECSafeBufferFormatter * formatter, const XSECEnv * env); /** * \brief Create a starting point for a TXFM Chain. * * Uses the provided URI to find the base data that the Transformer chain * will be built upon. * * @param doc The document that the signature is based on (used for local URIs) * @param URI The URI to build the base from * @param env The environment the signature is operating in * @returns A base TXFM element. */ static TXFMBase * getURIBaseTXFM(XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument * doc, const XMLCh * URI, const XSECEnv * env); /** * \brief Load a series of references. * * Takes a series of \<Reference\> elements in a DOM structure * and creates the corresponding ReferenceList object. * * @note Internal function - meant for use by the library * * @param env The environment in which this reference resides * @param firstReference First reference in DOM structure * @returns the created list. */ static DSIGReferenceList *loadReferenceListFromXML(const XSECEnv * env, XERCES_CPP_NAMESPACE_QUALIFIER DOMNode *firstReference); /** * \brief Validate a list of references. * * Runs through a reference list, calling verify() on each and * setting the ErrroStrings for any errors found * * @param lst The list to verify * @param errorStr The string to append any errors found to * @returns true iff all the references validate successfully. */ static bool verifyReferenceList(const DSIGReferenceList * lst, safeBuffer &errorStr); /** * \brief Hash a reference list * * Run through a list of references and calculate the hash value of each * element. Finally set the Base64 encoded string according to the newly * calcuated hash. * * @note This is an internal library function and should not be called directly. * * @param list The list of references * @param interlocking If set to false, the library will assume there * are no inter-related references. The algorithm for determining this * internally is very primitive and CPU intensive, so this is a method to * bypass the checks. */ static void hashReferenceList(const DSIGReferenceList * list, bool interlocking = true); //@} private: // Internal functions void createTransformList(void); void addTransform( DSIGTransform * txfm, XERCES_CPP_NAMESPACE_QUALIFIER DOMElement * txfmElt ); XSECSafeBufferFormatter * mp_formatter; XERCES_CPP_NAMESPACE_QUALIFIER DOMNode * mp_referenceNode; // Points to start of document where reference node is mutable TXFMBase * mp_preHash; // To be used pre-hash DSIGReferenceList * mp_manifestList; // The list of references in a manifest const XMLCh * mp_URI; // The URI String bool m_isManifest; // Does this reference a manifest? XERCES_CPP_NAMESPACE_QUALIFIER DOMNode * mp_transformsNode; XERCES_CPP_NAMESPACE_QUALIFIER DOMNode * mp_hashValueNode; // Node where the Hash value is stored const XSECEnv * mp_env; DSIGTransformList * mp_transformList; // List of transforms const XMLCh * mp_algorithmURI; // Hash algorithm for this reference bool m_loaded; DSIGReference(); /*\@}*/ friend class DSIGSignedInfo; }; #endif /* #define DSIGREFERENCE_INCLUDE */