| /** |
| * 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 |
| * |
| * DSIGTransformC14n := Class that performs C14n canonicalisation |
| * |
| * $Id$ |
| * |
| */ |
| |
| #include <xsec/dsig/DSIGSignature.hpp> |
| #include <xsec/dsig/DSIGTransformC14n.hpp> |
| #include <xsec/framework/XSECEnv.hpp> |
| #include <xsec/framework/XSECError.hpp> |
| #include <xsec/framework/XSECException.hpp> |
| #include <xsec/transformers/TXFMC14n.hpp> |
| #include <xsec/transformers/TXFMChain.hpp> |
| |
| #include "../utils/XSECAlgorithmSupport.hpp" |
| #include "../utils/XSECDOMUtils.hpp" |
| |
| XERCES_CPP_NAMESPACE_USE |
| |
| // -------------------------------------------------------------------------------- |
| // Constructors and Destructors |
| // -------------------------------------------------------------------------------- |
| |
| DSIGTransformC14n::DSIGTransformC14n(const XSECEnv* env, DOMNode* node) : |
| DSIGTransform(env, node) { |
| |
| m_cMethod = NULL; |
| mp_inclNSNode = NULL; |
| mp_inclNSStr = NULL; |
| m_exclusive = false; |
| m_comments = false; |
| m_onedotone = false; |
| } |
| |
| |
| DSIGTransformC14n::DSIGTransformC14n(const XSECEnv* env) : |
| DSIGTransform(env) { |
| |
| m_cMethod = NULL; |
| mp_inclNSNode = NULL; |
| mp_inclNSStr = NULL; |
| m_exclusive = false; |
| m_comments = false; |
| m_onedotone = false; |
| } |
| |
| DSIGTransformC14n::~DSIGTransformC14n() {}; |
| |
| // -------------------------------------------------------------------------------- |
| // Interface Methods |
| // -------------------------------------------------------------------------------- |
| |
| void DSIGTransformC14n::appendTransformer(TXFMChain* input) { |
| |
| TXFMC14n* c; |
| |
| XSECnew(c, TXFMC14n(mp_txfmNode->getOwnerDocument())); |
| input->appendTxfm(c); |
| |
| if (m_comments) |
| c->activateComments(); |
| else |
| c->stripComments(); |
| |
| // Check for exclusive and 1.1 |
| if (m_exclusive) { |
| if (mp_inclNSStr == NULL) { |
| c->setExclusive(); |
| } |
| else { |
| safeBuffer incl; |
| incl << (*(mp_env->getSBFormatter()) << mp_inclNSStr); |
| c->setExclusive(incl); |
| } |
| } |
| else if (m_onedotone) { |
| c->setInclusive11(); |
| } |
| } |
| |
| DOMElement* DSIGTransformC14n::createBlankTransform(DOMDocument* parentDoc) { |
| |
| safeBuffer str; |
| const XMLCh * prefix; |
| DOMElement *ret; |
| DOMDocument *doc = mp_env->getParentDocument(); |
| |
| prefix = mp_env->getDSIGNSPrefix(); |
| |
| // Create the transform node |
| makeQName(str, prefix, "Transform"); |
| ret = doc->createElementNS(DSIGConstants::s_unicodeStrURIDSIG, str.rawXMLChBuffer()); |
| ret->setAttributeNS(NULL,DSIGConstants::s_unicodeStrAlgorithm, DSIGConstants::s_unicodeStrURIC14N_NOC); |
| |
| m_cMethod = ret->getAttributeNS(NULL, DSIGConstants::s_unicodeStrAlgorithm); |
| m_comments = false; |
| m_exclusive = false; |
| m_onedotone = false; |
| |
| mp_txfmNode = ret; |
| mp_inclNSStr = NULL; |
| mp_inclNSNode = NULL; |
| |
| return ret; |
| } |
| |
| void DSIGTransformC14n::load() { |
| |
| DOMNamedNodeMap* atts; |
| DOMNode* att; |
| |
| // Read the URI for the type |
| if (mp_txfmNode == NULL) { |
| throw XSECException(XSECException::ExpectedDSIGChildNotFound, |
| "Expected <Transform> Node in DSIGTrasnformC14n::load"); |
| } |
| |
| atts = mp_txfmNode->getAttributes(); |
| |
| if (atts == NULL || |
| ((att = atts->getNamedItem(DSIGConstants::s_unicodeStrAlgorithm)) == NULL)) { |
| |
| throw XSECException(XSECException::ExpectedDSIGChildNotFound, |
| "Expected to find Algorithm attribute in <Transform> node"); |
| } |
| |
| m_cMethod = att->getNodeValue(); |
| |
| if (!XSECAlgorithmSupport::evalCanonicalizationMethod(m_cMethod, m_exclusive, m_comments, m_onedotone)) { |
| throw XSECException(XSECException::TransformError, |
| "Unexpected URI found in canonicalization <Transform>"); |
| } |
| |
| // Determine whether there is an InclusiveNamespaces list |
| |
| if (m_exclusive) { |
| |
| // Exclusive, so there may be an InclusiveNamespaces node |
| |
| DOMNode* inclNSNode = mp_txfmNode->getFirstChild(); |
| |
| while (inclNSNode != NULL && (inclNSNode->getNodeType() != DOMNode::ELEMENT_NODE || |
| !strEquals(getECLocalName(inclNSNode), "InclusiveNamespaces"))) |
| inclNSNode = inclNSNode->getNextSibling(); |
| |
| if (inclNSNode != 0) { |
| |
| mp_inclNSNode = static_cast<DOMElement *>(inclNSNode); |
| |
| // Have a prefix list |
| atts = mp_inclNSNode->getAttributes(); |
| safeBuffer inSB; |
| |
| if (atts == 0 || ((att = atts->getNamedItem(MAKE_UNICODE_STRING("PrefixList"))) == NULL)) { |
| throw XSECException(XSECException::ExpectedDSIGChildNotFound, |
| "Expected PrefixList in InclusiveNamespaces"); |
| } |
| |
| mp_inclNSStr = att->getNodeValue(); |
| } |
| } |
| } |
| |
| // -------------------------------------------------------------------------------- |
| // Canonicalization Specific Methods |
| // -------------------------------------------------------------------------------- |
| |
| |
| void DSIGTransformC14n::setCanonicalizationMethod(const XMLCh* uri) { |
| |
| bool exclusive; |
| bool comments; |
| bool onedotone; |
| |
| if (mp_txfmNode == NULL || !XSECAlgorithmSupport::evalCanonicalizationMethod(uri, exclusive, comments, onedotone)) { |
| throw XSECException(XSECException::TransformError, |
| "Either method unknown or Node not set in setCanonicalizationMethod"); |
| } |
| |
| // Switching from exclusive to inclusive? |
| if (!exclusive && m_exclusive) { |
| if (mp_inclNSNode != 0) { |
| |
| mp_txfmNode->removeChild(mp_inclNSNode); |
| mp_inclNSNode->release(); // No longer required |
| |
| mp_inclNSNode = NULL; |
| mp_inclNSStr = NULL; |
| } |
| } |
| |
| // Now do the set. |
| ((DOMElement *) mp_txfmNode)->setAttributeNS(NULL, DSIGConstants::s_unicodeStrAlgorithm, uri); |
| m_cMethod = ((DOMElement *) mp_txfmNode)->getAttributeNS(NULL, DSIGConstants::s_unicodeStrAlgorithm); |
| |
| m_exclusive = exclusive; |
| m_comments = comments; |
| m_onedotone = onedotone; |
| } |
| |
| const XMLCh* DSIGTransformC14n::getCanonicalizationMethod() const { |
| return m_cMethod; |
| } |
| |
| void DSIGTransformC14n::createInclusiveNamespaceNode() { |
| |
| // Creates an empty inclusiveNamespace node. Does _not_ set the prefixlist attribute |
| |
| if (mp_inclNSNode != NULL) |
| return; // Already exists |
| |
| safeBuffer str; |
| const XMLCh * prefix; |
| DOMDocument *doc = mp_env->getParentDocument(); |
| |
| // Use the Exclusive Canonicalisation prefix |
| prefix = mp_env->getECNSPrefix(); |
| |
| // Create the transform node |
| makeQName(str, prefix, "InclusiveNamespaces"); |
| mp_inclNSNode = doc->createElementNS(DSIGConstants::s_unicodeStrURIEC, str.rawXMLChBuffer()); |
| |
| // Add the node to the owner element |
| mp_env->doPrettyPrint(mp_txfmNode); |
| mp_txfmNode->appendChild(mp_inclNSNode); |
| mp_env->doPrettyPrint(mp_txfmNode); |
| |
| // Set the namespace attribute |
| if (prefix[0] == '\0') { |
| str.sbTranscodeIn("xmlns"); |
| } |
| else { |
| str.sbTranscodeIn("xmlns:"); |
| str.sbXMLChCat(prefix); |
| } |
| |
| mp_inclNSNode->setAttributeNS(DSIGConstants::s_unicodeStrURIXMLNS, |
| str.rawXMLChBuffer(), |
| DSIGConstants::s_unicodeStrURIEC); |
| } |
| |
| void DSIGTransformC14n::setInclusiveNamespaces(const XMLCh* ns) { |
| |
| // Set all the namespaces at once |
| |
| if (!m_exclusive) { |
| throw XSECException(XSECException::TransformError, |
| "Cannot set inclusive namespaces on non Exclusive Canonicalization"); |
| } |
| |
| if (mp_inclNSNode == NULL) { |
| // Create the transform node |
| createInclusiveNamespaceNode(); |
| } |
| |
| // Now create the prefix list |
| |
| mp_inclNSNode->setAttributeNS(NULL,MAKE_UNICODE_STRING("PrefixList"), ns); |
| mp_inclNSStr = mp_inclNSNode->getAttributes()->getNamedItem(MAKE_UNICODE_STRING("PrefixList"))->getNodeValue(); |
| } |
| |
| |
| void DSIGTransformC14n::addInclusiveNamespace(const char* ns) { |
| |
| if (!m_exclusive) { |
| throw XSECException(XSECException::TransformError, |
| "Cannot set inclusive namespaces on non Exclusive Canonicalization"); |
| } |
| |
| if (mp_inclNSNode == NULL) { |
| // Create the transform node |
| createInclusiveNamespaceNode(); |
| |
| // Now create the prefix list |
| |
| mp_inclNSNode->setAttributeNS(NULL,MAKE_UNICODE_STRING("PrefixList"), MAKE_UNICODE_STRING(ns)); |
| mp_inclNSStr = mp_inclNSNode->getAttributes()->getNamedItem(MAKE_UNICODE_STRING("PrefixList"))->getNodeValue(); |
| } |
| else { |
| // More tricky |
| safeBuffer str; |
| |
| str << (*(mp_env->getSBFormatter()) << mp_inclNSStr); |
| str.sbStrcatIn(" "); |
| str.sbStrcatIn((char *) ns); |
| mp_inclNSNode->setAttributeNS(NULL,MAKE_UNICODE_STRING("PrefixList"), str.sbStrToXMLCh()); |
| mp_inclNSStr = mp_inclNSNode->getAttributes()->getNamedItem(MAKE_UNICODE_STRING("PrefixList"))->getNodeValue(); |
| } |
| } |
| |
| const XMLCh* DSIGTransformC14n::getPrefixList() const { |
| return mp_inclNSStr; |
| } |
| |
| void DSIGTransformC14n::clearInclusiveNamespaces() { |
| |
| if (mp_inclNSNode != 0) { |
| mp_txfmNode->removeChild(mp_inclNSNode); |
| mp_inclNSNode->release(); // No longer required |
| |
| mp_inclNSNode = NULL; |
| mp_inclNSStr = NULL; |
| } |
| } |