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  * XSECEnv := Configuration class - used by the other classes to retrieve
24  *            information on the environment they are working under
25  *
26  * $Id: XSECEnv.cpp 1833341 2018-06-11 16:25:41Z scantor $
27  *
28  */
29 
30 // XSEC Includes
31 #include <xsec/dsig/DSIGConstants.hpp>
32 #include <xsec/framework/XSECEnv.hpp>
33 #include <xsec/framework/XSECError.hpp>
34 #include <xsec/framework/XSECURIResolver.hpp>
35 
36 #include "../utils/XSECDOMUtils.hpp"
37 
38 #include <xercesc/util/XMLUniDefs.hpp>
39 
40 struct XSECEnv::IdAttributeStruct {
41 	bool		m_useNamespace;		/* Was this defined with a namespace? */
42 	XMLCh		* mp_namespace;		/* Namespace of attribute */
43 	XMLCh		* mp_name;			/* Name of attribute */
44 };
45 
46 XERCES_CPP_NAMESPACE_USE
47 
48 
49 // --------------------------------------------------------------------------------
50 //           Default prefix strings
51 // --------------------------------------------------------------------------------
52 
53 const XMLCh s_default11Prefix[] = {
54 
55 	chLatin_d,
56 	chLatin_s,
57     chDigit_1,
58     chDigit_1,
59 	chNull
60 
61 };
62 
63 const XMLCh s_defaultECPrefix[] = {
64 
65 	chLatin_e,
66 	chLatin_c,
67 	chNull
68 
69 };
70 
71 const XMLCh s_defaultXPFPrefix[] = {
72 
73 	chLatin_x,
74 	chLatin_p,
75 	chLatin_f,
76 	chNull
77 
78 };
79 
80 const XMLCh s_defaultXENCPrefix[] = {
81 
82 	chLatin_x,
83 	chLatin_e,
84 	chLatin_n,
85 	chLatin_c,
86 	chNull
87 
88 };
89 
90 const XMLCh s_defaultXENC11Prefix[] = {
91 
92 	chLatin_x,
93 	chLatin_e,
94 	chLatin_n,
95 	chLatin_c,
96     chDigit_1,
97     chDigit_1,
98 	chNull
99 
100 };
101 
102 #ifdef XSEC_XKMS_ENABLED
103 const XMLCh s_defaultXKMSPrefix[] = {
104 
105 	chLatin_x,
106 	chLatin_k,
107 	chLatin_m,
108 	chLatin_s,
109 	chNull
110 
111 };
112 #endif
113 
114 // --------------------------------------------------------------------------------
115 //           Default Id names
116 // --------------------------------------------------------------------------------
117 
118 const XMLCh s_Id[] = {
119 
120 	chLatin_I,
121 	chLatin_d,
122 	chNull
123 
124 };
125 
126 const XMLCh s_id[] = {
127 
128 	chLatin_i,
129 	chLatin_d,
130 	chNull
131 
132 };
133 
134 
135 // --------------------------------------------------------------------------------
136 //           Env
137 // --------------------------------------------------------------------------------
138 
139 // Constructors and Destructors
140 
XSECEnv(DOMDocument * doc)141 XSECEnv::XSECEnv(DOMDocument *doc) {
142 
143 	mp_doc = doc;
144 
145 	mp_prefixNS = XMLString::replicate(DSIGConstants::s_unicodeStrEmpty);
146     mp_11PrefixNS = XMLString::replicate(s_default11Prefix);
147 	mp_ecPrefixNS = XMLString::replicate(s_defaultECPrefix);
148 	mp_xpfPrefixNS = XMLString::replicate(s_defaultXPFPrefix);
149 	mp_xencPrefixNS = XMLString::replicate(s_defaultXENCPrefix);
150     mp_xenc11PrefixNS = XMLString::replicate(s_defaultXENC11Prefix);
151 #ifdef XSEC_XKMS_ENABLED
152 	mp_xkmsPrefixNS = XMLString::replicate(s_defaultXKMSPrefix);
153 #endif
154 	m_prettyPrintFlag = true;
155 
156 	mp_URIResolver = NULL;
157 
158 	// Set up our formatter
159 	XSECnew(mp_formatter, XSECSafeBufferFormatter("UTF-8",XMLFormatter::NoEscapes,
160 												XMLFormatter::UnRep_CharRef));
161 
162 	// Set up IDs
163 	m_idByAttributeNameFlag = false;		// Now off by default.
164 	// Register "Id" and "id" as valid Attribute names
165 	registerIdAttributeName(s_Id);
166 	registerIdAttributeName(s_id);
167 
168 }
169 
XSECEnv(const XSECEnv & theOther)170 XSECEnv::XSECEnv(const XSECEnv & theOther) {
171 
172 	mp_doc = theOther.mp_doc;
173 
174 	mp_prefixNS = XMLString::replicate(theOther.mp_prefixNS);
175     mp_11PrefixNS = XMLString::replicate(theOther.mp_11PrefixNS);
176 	mp_ecPrefixNS = XMLString::replicate(theOther.mp_ecPrefixNS);
177 	mp_xpfPrefixNS = XMLString::replicate(theOther.mp_xpfPrefixNS);
178 	mp_xencPrefixNS = XMLString::replicate(theOther.mp_xencPrefixNS);
179     mp_xenc11PrefixNS = XMLString::replicate(s_defaultXENC11Prefix);
180 #ifdef XSEC_XKMS_ENABLED
181 	mp_xkmsPrefixNS = XMLString::replicate(theOther.mp_xkmsPrefixNS);
182 #endif
183 	m_prettyPrintFlag = theOther.m_prettyPrintFlag;
184 
185 	if (theOther.mp_URIResolver != NULL)
186 		mp_URIResolver = theOther.mp_URIResolver->clone();
187 	else
188 		mp_URIResolver = NULL;
189 
190 	// Set up our formatter
191 	XSECnew(mp_formatter, XSECSafeBufferFormatter("UTF-8",XMLFormatter::NoEscapes,
192 												XMLFormatter::UnRep_CharRef));
193 
194 	// Set up IDs
195 	m_idByAttributeNameFlag = theOther.m_idByAttributeNameFlag;
196 
197 	for (int i = 0; i < theOther.getIdAttributeNameListSize() ; ++i) {
198 		registerIdAttributeName(theOther.getIdAttributeNameListItem(i));
199 	}
200 
201 }
202 
~XSECEnv()203 XSECEnv::~XSECEnv() {
204 
205 	if (mp_formatter != NULL) {
206 		delete mp_formatter;
207 	}
208 
209 	if (mp_prefixNS != NULL) {
210 		XSEC_RELEASE_XMLCH(mp_prefixNS);
211 	}
212 
213     if (mp_11PrefixNS != NULL) {
214         XSEC_RELEASE_XMLCH(mp_11PrefixNS);
215     }
216 
217 	if (mp_ecPrefixNS != NULL) {
218 		XSEC_RELEASE_XMLCH(mp_ecPrefixNS);
219 	}
220 
221 	if (mp_xpfPrefixNS != NULL) {
222 		XSEC_RELEASE_XMLCH(mp_xpfPrefixNS);
223 	}
224 
225 	if (mp_xencPrefixNS != NULL) {
226 		XSEC_RELEASE_XMLCH(mp_xencPrefixNS);
227 	}
228 
229 	if (mp_xenc11PrefixNS != NULL) {
230 		XSEC_RELEASE_XMLCH(mp_xenc11PrefixNS);
231 	}
232 
233 #ifdef XSEC_XKMS_ENABLED
234 	if (mp_xkmsPrefixNS != NULL) {
235 		XSEC_RELEASE_XMLCH(mp_xkmsPrefixNS);
236 	}
237 #endif
238 
239 	if (mp_URIResolver != NULL) {
240 		delete mp_URIResolver;
241 	}
242 
243 	// Clean up Id attribute names
244 	IdNameVectorType::iterator it;
245 
246 	for (it = m_idAttributeNameList.begin(); it != m_idAttributeNameList.end(); it++) {
247 		IdAttributeType * i = *it;
248 		if (i->mp_namespace != NULL)
249 			XSEC_RELEASE_XMLCH((i->mp_namespace));
250 		if (i->mp_name)
251 			XSEC_RELEASE_XMLCH((i->mp_name));
252 
253 		delete *it;
254 	}
255 
256 	m_idAttributeNameList.empty();
257 
258 
259 }
260 
261 // --------------------------------------------------------------------------------
262 //           Set and Get Resolvers
263 // --------------------------------------------------------------------------------
264 
265 
setURIResolver(XSECURIResolver * resolver)266 void XSECEnv::setURIResolver(XSECURIResolver * resolver) {
267 
268 	if (mp_URIResolver != 0)
269 		delete mp_URIResolver;
270 
271 	mp_URIResolver = resolver->clone();
272 
273 }
274 
getURIResolver(void) const275 XSECURIResolver * XSECEnv::getURIResolver(void) const {
276 
277 	return mp_URIResolver;
278 
279 }
280 
281 // --------------------------------------------------------------------------------
282 //           Set and Get Prefixes
283 // --------------------------------------------------------------------------------
284 
setDSIGNSPrefix(const XMLCh * prefix)285 void XSECEnv::setDSIGNSPrefix(const XMLCh * prefix) {
286 
287 	if (mp_prefixNS != NULL)
288 		XSEC_RELEASE_XMLCH(mp_prefixNS);
289 
290 	mp_prefixNS = XMLString::replicate(prefix);
291 
292 }
293 
setDSIG11NSPrefix(const XMLCh * prefix)294 void XSECEnv::setDSIG11NSPrefix(const XMLCh * prefix) {
295 
296 	if (mp_11PrefixNS != NULL)
297 		XSEC_RELEASE_XMLCH(mp_11PrefixNS);
298 
299 	mp_11PrefixNS = XMLString::replicate(prefix);
300 
301 }
302 
setECNSPrefix(const XMLCh * prefix)303 void XSECEnv::setECNSPrefix(const XMLCh * prefix) {
304 
305 	if (mp_ecPrefixNS != NULL)
306 		XSEC_RELEASE_XMLCH(mp_ecPrefixNS);
307 
308 	mp_ecPrefixNS = XMLString::replicate(prefix);
309 
310 }
311 
setXPFNSPrefix(const XMLCh * prefix)312 void XSECEnv::setXPFNSPrefix(const XMLCh * prefix) {
313 
314 	if (mp_xpfPrefixNS != NULL)
315 		XSEC_RELEASE_XMLCH(mp_xpfPrefixNS);
316 
317 	mp_xpfPrefixNS = XMLString::replicate(prefix);
318 
319 }
320 
setXENCNSPrefix(const XMLCh * prefix)321 void XSECEnv::setXENCNSPrefix(const XMLCh * prefix) {
322 
323 	if (mp_xencPrefixNS != NULL)
324 		XSEC_RELEASE_XMLCH(mp_xencPrefixNS);
325 
326 	mp_xencPrefixNS = XMLString::replicate(prefix);
327 
328 }
329 
setXENC11NSPrefix(const XMLCh * prefix)330 void XSECEnv::setXENC11NSPrefix(const XMLCh * prefix) {
331 
332 	if (mp_xenc11PrefixNS != NULL)
333 		XSEC_RELEASE_XMLCH(mp_xenc11PrefixNS);
334 
335 	mp_xenc11PrefixNS = XMLString::replicate(prefix);
336 
337 }
338 
339 #ifdef XSEC_XKMS_ENABLED
setXKMSNSPrefix(const XMLCh * prefix)340 void XSECEnv::setXKMSNSPrefix(const XMLCh * prefix) {
341 
342 	if (mp_xkmsPrefixNS != NULL)
343 		XSEC_RELEASE_XMLCH(mp_xkmsPrefixNS);
344 
345 	mp_xkmsPrefixNS = XMLString::replicate(prefix);
346 
347 }
348 #endif
349 
350 // --------------------------------------------------------------------------------
351 //           Id Attribute Names Handling
352 // --------------------------------------------------------------------------------
353 
setIdByAttributeName(bool flag)354 void XSECEnv::setIdByAttributeName(bool flag) {
355 
356 	m_idByAttributeNameFlag = flag;
357 
358 }
359 
getIdByAttributeName(void) const360 bool XSECEnv::getIdByAttributeName(void) const {
361 
362 	return m_idByAttributeNameFlag;
363 
364 }
365 
isRegisteredIdAttributeName(const XMLCh * name) const366 bool XSECEnv::isRegisteredIdAttributeName(const XMLCh * name) const {
367 
368 	int sz = (int) m_idAttributeNameList.size();
369 
370 	for (int i = 0; i < sz; ++i) {
371 		if (!m_idAttributeNameList[i]->m_useNamespace &&
372 			strEquals(m_idAttributeNameList[i]->mp_name, name))
373 			return true;
374 	}
375 
376 	return false;
377 
378 }
379 
registerIdAttributeName(const XMLCh * name)380 void XSECEnv::registerIdAttributeName(const XMLCh * name) {
381 
382 	if (isRegisteredIdAttributeName(name))
383 		return;
384 
385 	IdAttributeType * iat;
386 
387 	iat = new IdAttributeType;
388 	m_idAttributeNameList.push_back(iat);
389 
390 	iat->m_useNamespace = false;
391 	iat->mp_namespace = NULL;
392 	iat->mp_name = XMLString::replicate(name);
393 
394 }
395 
deregisterIdAttributeName(const XMLCh * name)396 bool XSECEnv::deregisterIdAttributeName(const XMLCh * name) {
397 
398 	IdNameVectorType::iterator it;
399 
400 	for (it = m_idAttributeNameList.begin(); it != m_idAttributeNameList.end(); it++) {
401 		if (!((*it)->m_useNamespace) && strEquals((*it)->mp_name, name)) {
402 
403 			// Remove this item
404 			XSEC_RELEASE_XMLCH(((*it)->mp_name));
405 			delete *it;
406 			m_idAttributeNameList.erase(it);
407 			return true;
408 		}
409 	}
410 
411 	return false;
412 }
413 
isRegisteredIdAttributeNameNS(const XMLCh * ns,const XMLCh * name) const414 bool XSECEnv::isRegisteredIdAttributeNameNS(const XMLCh * ns, const XMLCh * name) const {
415 
416 	int sz = (int) m_idAttributeNameList.size();
417 
418 	for (int i = 0; i < sz; ++i) {
419 		if (m_idAttributeNameList[i]->m_useNamespace &&
420 			strEquals(m_idAttributeNameList[i]->mp_namespace, ns) &&
421 			strEquals(m_idAttributeNameList[i]->mp_name, name))
422 			return true;
423 	}
424 
425 	return false;
426 
427 }
428 
registerIdAttributeNameNS(const XMLCh * ns,const XMLCh * name)429 void XSECEnv::registerIdAttributeNameNS(const XMLCh * ns, const XMLCh * name) {
430 
431 	if (isRegisteredIdAttributeNameNS(ns, name))
432 		return;
433 
434 	IdAttributeType * iat;
435 
436 	iat = new IdAttributeType;
437 	m_idAttributeNameList.push_back(iat);
438 
439 	iat->m_useNamespace = true;
440 	iat->mp_namespace = XMLString::replicate(ns);;
441 	iat->mp_name = XMLString::replicate(name);
442 
443 }
444 
deregisterIdAttributeNameNS(const XMLCh * ns,const XMLCh * name)445 bool XSECEnv::deregisterIdAttributeNameNS(const XMLCh * ns, const XMLCh * name) {
446 
447 	IdNameVectorType::iterator it;
448 
449 	for (it = m_idAttributeNameList.begin(); it != m_idAttributeNameList.end(); it++) {
450 		if (((*it)->m_useNamespace) &&
451 			strEquals((*it)->mp_namespace, ns) &&
452 			strEquals((*it)->mp_name, name)) {
453 
454 			// Remove this item
455 			XSEC_RELEASE_XMLCH(((*it)->mp_name));
456 			delete *it;
457 			m_idAttributeNameList.erase(it);
458 			return true;
459 		}
460 	}
461 
462 	return false;
463 }
464 
getIdAttributeNameListSize() const465 int XSECEnv::getIdAttributeNameListSize() const {
466 
467 	return (int) m_idAttributeNameList.size();
468 
469 }
470 
getIdAttributeNameListItem(int index) const471 const XMLCh * XSECEnv::getIdAttributeNameListItem(int index) const {
472 
473 	if (index >= 0 && index < (int) m_idAttributeNameList.size())
474 		return m_idAttributeNameList[index]->mp_name;
475 
476 	return NULL;
477 
478 }
479 
getIdAttributeNameListItemNS(int index) const480 const XMLCh * XSECEnv::getIdAttributeNameListItemNS(int index) const {
481 
482 	if (index >= 0 && index < (int) m_idAttributeNameList.size())
483 		return m_idAttributeNameList[index]->mp_namespace;
484 
485 	return NULL;
486 
487 }
488 
getIdAttributeNameListItemIsNS(int index) const489 bool XSECEnv::getIdAttributeNameListItemIsNS(int index) const {
490 
491 	if (index >= 0 && index < (int) m_idAttributeNameList.size())
492 		return m_idAttributeNameList[index]->m_useNamespace;
493 
494 	return false;
495 
496 }
497 
498 // --------------------------------------------------------------------------------
499 //           Set and Get Resolvers
500 // --------------------------------------------------------------------------------
501 
doPrettyPrint(XERCES_CPP_NAMESPACE_QUALIFIER DOMNode * node) const502 void XSECEnv::doPrettyPrint(XERCES_CPP_NAMESPACE_QUALIFIER DOMNode * node) const {
503 
504 	// Very simple
505 	if (m_prettyPrintFlag)
506 		node->appendChild(mp_doc->createTextNode(DSIGConstants::s_unicodeStrNL));
507 
508 }
509 
510