1 /**
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
20 /*
21 * XSEC
22 *
23 * TXFMEnvelope := Class that calculates an Envelope with an XPath evaluator
24 *
25 * $Id: TXFMEnvelope.cpp 1833341 2018-06-11 16:25:41Z scantor $
26 *
27 */
28
29 #include <xsec/framework/XSECException.hpp>
30 #include <xsec/transformers/TXFMEnvelope.hpp>
31
32 #include "../utils/XSECDOMUtils.hpp"
33
34 #include <xercesc/util/XMLString.hpp>
35 #include <xercesc/util/XMLUniDefs.hpp>
36
37 XERCES_CPP_NAMESPACE_USE
38
39
TXFMEnvelope(DOMDocument * doc)40 TXFMEnvelope::TXFMEnvelope(DOMDocument *doc) :
41 TXFMBase(doc) {
42
43
44 }
45
~TXFMEnvelope()46 TXFMEnvelope::~TXFMEnvelope() {
47
48
49 }
50
51 // Methods to set the inputs
52
setInput(TXFMBase * newInput)53 void TXFMEnvelope::setInput(TXFMBase *newInput) {
54
55 input = newInput;
56
57 if (newInput->getOutputType() != TXFMBase::DOM_NODES) {
58
59 throw XSECException(XSECException::TransformInputOutputFail, "XPath requires DOM_NODES input type");
60
61 }
62
63 // Expand if necessary
64 //this->expandNameSpaces();
65
66 keepComments = input->getCommentsStatus();
67
68 // Set up for the new document
69 mp_document = input->getDocument();
70
71 // Now work out what we have to set up in the new processing
72
73 TXFMBase::nodeType inputType = input->getNodeType();
74
75
76 switch (inputType) {
77
78 case DOM_NODE_DOCUMENT :
79
80 mp_startNode = mp_document;
81 break;
82
83 case DOM_NODE_DOCUMENT_FRAGMENT :
84
85 mp_startNode = input->getFragmentNode();
86 break;
87
88 default :
89
90 throw XSECException(XSECException::EnvelopeError); // Should never get here
91
92 }
93
94 // Ready to evaluate
95
96 }
97
98
99 // Methods to get tranform output type and input requirement
100
getInputType(void) const101 TXFMBase::ioType TXFMEnvelope::getInputType(void) const {
102
103 return TXFMBase::DOM_NODES;
104
105 }
106
getOutputType(void) const107 TXFMBase::ioType TXFMEnvelope::getOutputType(void) const {
108
109 return TXFMBase::DOM_NODES;
110
111 }
112
getNodeType(void) const113 TXFMBase::nodeType TXFMEnvelope::getNodeType(void) const {
114
115 return TXFMBase::DOM_NODE_XPATH_NODESET;
116
117 }
118
119 // Envelope (and XPath) unique
120
addEnvelopeNode(DOMNode * startNode,XSECXPathNodeList & XPathMap,DOMNode * sigNode)121 void addEnvelopeNode(DOMNode *startNode, XSECXPathNodeList & XPathMap, DOMNode * sigNode) {
122
123 XSEC_USING_XERCES(DOMNamedNodeMap);
124
125 DOMNode *tmp;
126 DOMNamedNodeMap *atts;
127 XMLSize_t attsSize, i;
128
129 if (startNode == sigNode)
130 return;
131
132 XPathMap.addNode(startNode);
133
134 if (startNode->getNodeType() == DOMNode::ELEMENT_NODE) {
135
136 atts = startNode->getAttributes();
137 if (atts != NULL)
138 attsSize = atts->getLength();
139 else
140 attsSize = 0;
141
142 for (i = 0; i < attsSize; ++i) {
143
144 tmp = atts->item(i);
145 XPathMap.addNode(tmp);
146
147 }
148
149 }
150
151 // Now do any childeren
152
153 tmp = startNode->getFirstChild();
154
155 while (tmp != NULL) {
156
157 addEnvelopeNode(tmp, XPathMap, sigNode);
158 tmp = tmp->getNextSibling();
159
160 }
161 }
162
addEnvelopeParentNSNodes(DOMNode * startNode,XSECXPathNodeList & XPathMap)163 void addEnvelopeParentNSNodes(DOMNode *startNode, XSECXPathNodeList & XPathMap) {
164
165 XSEC_USING_XERCES(DOMNamedNodeMap);
166
167 DOMNode *tmp;
168 DOMNamedNodeMap *atts;
169 XMLSize_t attsSize, i;
170
171 if (startNode == NULL)
172 return;
173
174 if (startNode->getNodeType() == DOMNode::ELEMENT_NODE) {
175
176 atts = startNode->getAttributes();
177 if (atts != NULL)
178 attsSize = atts->getLength();
179 else
180 attsSize = 0;
181
182 for (i = 0; i < attsSize; ++i) {
183
184 tmp = atts->item(i);
185 if (XMLString::compareNString(tmp->getNodeName(), DSIGConstants::s_unicodeStrXmlns, 5) == 0 &&
186 (tmp->getNodeName()[5] == chNull || tmp->getNodeName()[5] == chColon))
187 XPathMap.addNode(tmp);
188
189 }
190
191 }
192
193 // Now do parent
194 addEnvelopeParentNSNodes(startNode->getParentNode(), XPathMap);
195
196 }
197
evaluateEnvelope(DOMNode * t)198 void TXFMEnvelope::evaluateEnvelope(DOMNode *t) {
199
200 DOMNode *sigNode;
201
202 // Find the signature node
203 sigNode = t->getParentNode();
204
205 while (sigNode != NULL && !strEquals(getDSIGLocalName(sigNode), "Signature"))
206 sigNode = sigNode->getParentNode();
207
208 if (sigNode == NULL) {
209
210 throw XSECException(XSECException::EnvelopeError,
211 "Unable to find signature owner of node passed to Envelope Transform");
212
213 }
214
215 // Check if sigNode is an ancestor of mp_startNode - if so, just return
216 DOMNode * c = mp_startNode;
217 while (c != NULL) {
218
219 if (c == sigNode)
220 return;
221
222 c = c->getParentNode();
223
224 }
225
226 addEnvelopeNode(mp_startNode, m_XPathMap, sigNode);
227 addEnvelopeParentNSNodes(mp_startNode->getParentNode(), m_XPathMap);
228
229 }
230
231 // Methods to get output data
232
readBytes(XMLByte * const toFill,unsigned int maxToFill)233 unsigned int TXFMEnvelope::readBytes(XMLByte * const toFill, unsigned int maxToFill) {
234
235 return 0;
236
237 }
238
getDocument() const239 DOMDocument *TXFMEnvelope::getDocument() const {
240
241 return mp_document;
242
243 }
244