| /** |
| * 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/DSIGTransformC14n.hpp> |
| #include <xsec/framework/XSECException.hpp> |
| #include <xsec/transformers/TXFMC14n.hpp> |
| #include <xsec/transformers/TXFMChain.hpp> |
| #include <xsec/framework/XSECError.hpp> |
| #include <xsec/framework/XSECEnv.hpp> |
| #include <xsec/dsig/DSIGSignature.hpp> |
| |
| #include <xercesc/util/Janitor.hpp> |
| |
| XERCES_CPP_NAMESPACE_USE |
| |
| // -------------------------------------------------------------------------------- |
| // Constructors and Destructors |
| // -------------------------------------------------------------------------------- |
| |
| DSIGTransformC14n::DSIGTransformC14n(const XSECEnv * env, DOMNode * node) : |
| DSIGTransform(env, node) { |
| |
| m_cMethod = CANON_NONE; |
| mp_inclNSNode = NULL; |
| mp_inclNSStr = NULL; |
| } |
| |
| |
| DSIGTransformC14n::DSIGTransformC14n(const XSECEnv * env) : |
| DSIGTransform(env) { |
| |
| m_cMethod = CANON_NONE; |
| mp_inclNSNode = NULL; |
| mp_inclNSStr = NULL; |
| |
| } |
| |
| DSIGTransformC14n::~DSIGTransformC14n() {}; |
| |
| // -------------------------------------------------------------------------------- |
| // Interface Methods |
| // -------------------------------------------------------------------------------- |
| |
| transformType DSIGTransformC14n::getTransformType() { |
| |
| if ((m_cMethod == CANON_C14NE_NOC) || (m_cMethod == CANON_C14NE_COM)) |
| return TRANSFORM_EXC_C14N; |
| else if ((m_cMethod == CANON_C14N11_NOC) || (m_cMethod == CANON_C14N11_COM)) |
| return TRANSFORM_C14N11; |
| return TRANSFORM_C14N; |
| |
| } |
| |
| void DSIGTransformC14n::appendTransformer(TXFMChain * input) { |
| |
| TXFMC14n * c; |
| |
| XSECnew(c, TXFMC14n(mp_txfmNode->getOwnerDocument())); |
| input->appendTxfm(c); |
| |
| switch (m_cMethod) { |
| |
| case (CANON_C14N_NOC) : |
| case (CANON_C14N11_NOC) : |
| case (CANON_C14NE_NOC) : |
| c->stripComments(); |
| break; |
| case (CANON_C14N_COM) : |
| case (CANON_C14N11_COM) : |
| case (CANON_C14NE_COM) : |
| c->activateComments(); |
| break; |
| default: |
| break; |
| } |
| |
| // Check for exclusive and 1.1 |
| if (m_cMethod == CANON_C14NE_COM || m_cMethod == CANON_C14NE_NOC) { |
| |
| if (mp_inclNSStr == NULL) { |
| |
| c->setExclusive(); |
| |
| } |
| else { |
| |
| safeBuffer incl; |
| incl << (*(mp_env->getSBFormatter()) << mp_inclNSStr); |
| c->setExclusive(incl); |
| |
| } |
| |
| } |
| else if (m_cMethod == CANON_C14N11_COM || m_cMethod == CANON_C14N11_NOC) { |
| 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); |
| |
| mp_txfmNode = ret; |
| mp_inclNSStr = NULL; |
| mp_inclNSNode = NULL; |
| |
| return ret; |
| |
| } |
| |
| void DSIGTransformC14n::load(void) { |
| |
| const XMLCh * uri; |
| 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"); |
| |
| } |
| |
| uri = att->getNodeValue(); |
| |
| if (strEquals(uri, DSIGConstants::s_unicodeStrURIC14N_COM)) { |
| m_cMethod = CANON_C14N_COM; |
| } |
| else if (strEquals(uri, DSIGConstants::s_unicodeStrURIC14N_NOC)) { |
| m_cMethod = CANON_C14N_NOC; |
| } |
| else if (strEquals(uri, DSIGConstants::s_unicodeStrURIC14N11_COM)) { |
| m_cMethod = CANON_C14N11_COM; |
| } |
| else if (strEquals(uri, DSIGConstants::s_unicodeStrURIC14N11_NOC)) { |
| m_cMethod = CANON_C14N11_NOC; |
| } |
| else if (strEquals(uri, DSIGConstants::s_unicodeStrURIEXC_C14N_COM)) { |
| m_cMethod = CANON_C14NE_COM; |
| } |
| else if (strEquals(uri, DSIGConstants::s_unicodeStrURIEXC_C14N_NOC)) { |
| m_cMethod = CANON_C14NE_NOC; |
| } |
| else { |
| throw XSECException(XSECException::ExpectedDSIGChildNotFound, |
| "Unexpected URI found in canonicalisation <Transform>"); |
| } |
| |
| // Determine whether there is an InclusiveNamespaces list |
| |
| if (m_cMethod == CANON_C14NE_NOC || m_cMethod == CANON_C14NE_COM) { |
| |
| // 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(canonicalizationMethod method) { |
| |
| const XMLCh * m = canonicalizationMethod2UNICODEURI(method); |
| |
| if (strEquals(m, DSIGConstants::s_unicodeStrEmpty) || mp_txfmNode == NULL) { |
| |
| throw XSECException(XSECException::TransformError, |
| "Either method unknown or Node not set in setCanonicalizationMethod"); |
| |
| } |
| |
| if (method == CANON_C14N_NOC || method == CANON_C14N_COM || method == CANON_C14N11_NOC || method == CANON_C14N11_COM) { |
| |
| if (m_cMethod == CANON_C14NE_NOC || m_cMethod == CANON_C14NE_COM) { |
| |
| 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,MAKE_UNICODE_STRING("Algorithm"), m); |
| m_cMethod = method; |
| |
| } |
| |
| canonicalizationMethod DSIGTransformC14n::getCanonicalizationMethod(void) { |
| |
| return m_cMethod; |
| |
| } |
| |
| void DSIGTransformC14n::createInclusiveNamespaceNode(void) { |
| |
| // 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_cMethod != CANON_C14NE_COM && m_cMethod != CANON_C14NE_NOC) { |
| |
| throw XSECException(XSECException::TransformError, |
| "Cannot set inclusive namespaces on non Exclusive Canonicalisation"); |
| |
| } |
| |
| 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_cMethod != CANON_C14NE_COM && m_cMethod != CANON_C14NE_NOC) { |
| |
| throw XSECException(XSECException::TransformError, |
| "Cannot set inclusive namespaces on non Exclusive Canonicalisation"); |
| |
| } |
| |
| 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(void) { |
| |
| return mp_inclNSStr; |
| |
| } |
| |
| void DSIGTransformC14n::clearInclusiveNamespaces(void) { |
| |
| if (mp_inclNSNode != 0) { |
| |
| mp_txfmNode->removeChild(mp_inclNSNode); |
| mp_inclNSNode->release(); // No longer required |
| |
| mp_inclNSNode = NULL; |
| mp_inclNSStr = NULL; |
| |
| } |
| } |