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  * XENCCipherReference := Implementation for CipherReference element
24  *
25  * $Id: XENCCipherReferenceImpl.cpp 1833341 2018-06-11 16:25:41Z scantor $
26  *
27  */
28 
29 #include <xsec/dsig/DSIGTransformList.hpp>
30 #include <xsec/dsig/DSIGReference.hpp>
31 #include <xsec/dsig/DSIGTransformList.hpp>
32 #include <xsec/dsig/DSIGTransformBase64.hpp>
33 #include <xsec/dsig/DSIGTransformXPath.hpp>
34 #include <xsec/dsig/DSIGTransformXPathFilter.hpp>
35 #include <xsec/dsig/DSIGTransformXSL.hpp>
36 #include <xsec/dsig/DSIGTransformC14n.hpp>
37 #include <xsec/framework/XSECDefs.hpp>
38 #include <xsec/framework/XSECEnv.hpp>
39 #include <xsec/framework/XSECError.hpp>
40 #include <xsec/utils/XSECSafeBufferFormatter.hpp>
41 
42 #include "XENCCipherReferenceImpl.hpp"
43 #include "../../utils/XSECDOMUtils.hpp"
44 
45 #include <xercesc/util/XMLUniDefs.hpp>
46 #include <xercesc/util/Janitor.hpp>
47 
48 
49 XERCES_CPP_NAMESPACE_USE
50 
51 // --------------------------------------------------------------------------------
52 //			String Constants
53 // --------------------------------------------------------------------------------
54 
55 static XMLCh s_CipherReference[] = {
56 
57 	chLatin_C,
58 	chLatin_i,
59 	chLatin_p,
60 	chLatin_h,
61 	chLatin_e,
62 	chLatin_r,
63 	chLatin_R,
64 	chLatin_e,
65 	chLatin_f,
66 	chLatin_e,
67 	chLatin_r,
68 	chLatin_e,
69 	chLatin_n,
70 	chLatin_c,
71 	chLatin_e,
72 	chNull
73 };
74 
75 static XMLCh s_Transforms[] = {
76 
77 	chLatin_T,
78 	chLatin_r,
79 	chLatin_a,
80 	chLatin_n,
81 	chLatin_s,
82 	chLatin_f,
83 	chLatin_o,
84 	chLatin_r,
85 	chLatin_m,
86 	chLatin_s,
87 	chNull
88 };
89 
create(const XSECEnv * env,const XMLCh * URI)90 XENCCipherReference* XENCCipherReference::create(const XSECEnv* env, const XMLCh * URI)
91 {
92 
93 	XENCCipherReferenceImpl* ret = new XENCCipherReferenceImpl(env);
94 	if (!ret)
95 		throw XSECException(XSECException::MemoryAllocationFail);
96 	ret->createBlankCipherReference(URI);
97 	return ret;
98 }
99 
100 // --------------------------------------------------------------------------------
101 //			Constructors/Destructors
102 // --------------------------------------------------------------------------------
103 
XENCCipherReferenceImpl(const XSECEnv * env)104 XENCCipherReferenceImpl::XENCCipherReferenceImpl(const XSECEnv * env) :
105 mp_env(env),
106 mp_cipherReferenceElement(NULL),
107 mp_uriAttr(NULL),
108 mp_transformsElement(NULL),
109 mp_transformList(NULL) {
110 
111 }
112 
XENCCipherReferenceImpl(const XSECEnv * env,DOMElement * node)113 XENCCipherReferenceImpl::XENCCipherReferenceImpl(const XSECEnv * env, DOMElement * node) :
114 mp_env(env),
115 mp_cipherReferenceElement(node),
116 mp_uriAttr(NULL),
117 mp_transformsElement(NULL),
118 mp_transformList(NULL) {
119 
120 }
121 
122 
~XENCCipherReferenceImpl()123 XENCCipherReferenceImpl::~XENCCipherReferenceImpl() {
124 
125 	if (mp_transformList != NULL)
126 		delete mp_transformList;
127 
128 }
129 
130 // --------------------------------------------------------------------------------
131 //           Creation of Transforms
132 // --------------------------------------------------------------------------------
133 
createTransformList(void)134 void XENCCipherReferenceImpl::createTransformList(void) {
135 
136 	// Creates the transforms list
137 	safeBuffer str;
138 	const XMLCh * prefix;
139 	DOMDocument *doc = mp_env->getParentDocument();
140 
141 	prefix = mp_env->getXENCNSPrefix();
142 
143 	if (mp_transformsElement == NULL) {
144 
145 		// Need to create a transforms node
146 		makeQName(str, prefix, "Transforms");
147 		mp_transformsElement = doc->createElementNS(DSIGConstants::s_unicodeStrURIXENC, str.rawXMLChBuffer());
148 		mp_env->doPrettyPrint(mp_cipherReferenceElement);
149 		mp_cipherReferenceElement->appendChild(mp_transformsElement);
150 		mp_env->doPrettyPrint(mp_transformsElement);
151 		mp_env->doPrettyPrint(mp_cipherReferenceElement);
152 
153 		// Create the list
154 		XSECnew(mp_transformList, DSIGTransformList());
155 	}
156 
157 }
158 
addTransform(DSIGTransform * txfm,DOMElement * txfmElt)159 void XENCCipherReferenceImpl::addTransform(DSIGTransform * txfm, DOMElement * txfmElt) {
160 
161 	if (mp_transformList == NULL)
162 		createTransformList();
163 
164 	mp_transformsElement->appendChild(txfmElt);
165 	mp_env->doPrettyPrint(mp_transformsElement);
166 
167 	mp_transformList->addTransform(txfm);
168 }
169 
170 
appendBase64Transform()171 DSIGTransformBase64 * XENCCipherReferenceImpl::appendBase64Transform() {
172 
173 	DOMElement *txfmElt;
174 	DSIGTransformBase64 * txfm;
175 
176 	XSECnew(txfm, DSIGTransformBase64(mp_env));
177 	txfmElt = txfm->createBlankTransform(mp_env->getParentDocument());
178 
179 	addTransform(txfm, txfmElt);
180 
181 	return txfm;
182 
183 }
184 
appendXSLTransform(DOMNode * stylesheet)185 DSIGTransformXSL * XENCCipherReferenceImpl::appendXSLTransform(DOMNode * stylesheet) {
186 
187 	DOMElement *txfmElt;
188 	DSIGTransformXSL * txfm;
189 
190 	XSECnew(txfm, DSIGTransformXSL(mp_env));
191 	txfmElt = txfm->createBlankTransform(mp_env->getParentDocument());
192 	txfm->setStylesheet(stylesheet);
193 
194 	addTransform(txfm, txfmElt);
195 
196 	return txfm;
197 
198 }
199 
appendCanonicalizationTransform(const XMLCh * uri)200 DSIGTransformC14n * XENCCipherReferenceImpl::appendCanonicalizationTransform(const XMLCh* uri) {
201 
202 	DOMElement *txfmElt;
203 	DSIGTransformC14n * txfm;
204 
205 	XSECnew(txfm, DSIGTransformC14n(mp_env));
206 	txfmElt = txfm->createBlankTransform(mp_env->getParentDocument());
207 	txfm->setCanonicalizationMethod(uri);
208 
209 	addTransform(txfm, txfmElt);
210 
211 	return txfm;
212 
213 }
214 
appendXPathTransform(const char * expr)215 DSIGTransformXPath * XENCCipherReferenceImpl::appendXPathTransform(const char * expr) {
216 
217 	DOMElement *txfmElt;
218 	DSIGTransformXPath * txfm;
219 
220 	XSECnew(txfm, DSIGTransformXPath(mp_env));
221 	txfmElt = txfm->createBlankTransform(mp_env->getParentDocument());
222 	txfm->setExpression(expr);
223 
224 	addTransform(txfm, txfmElt);
225 
226 	return txfm;
227 }
228 
appendXPathFilterTransform(void)229 DSIGTransformXPathFilter * XENCCipherReferenceImpl::appendXPathFilterTransform(void) {
230 
231 	DOMElement *txfmElt;
232 	DSIGTransformXPathFilter * txfm;
233 
234 	XSECnew(txfm, DSIGTransformXPathFilter(mp_env));
235 	txfmElt = txfm->createBlankTransform(mp_env->getParentDocument());
236 
237 	addTransform(txfm, txfmElt);
238 	mp_env->doPrettyPrint(txfmElt);
239 
240 	return txfm;
241 }
242 
243 // --------------------------------------------------------------------------------
244 //			Load
245 // --------------------------------------------------------------------------------
246 
load(void)247 void XENCCipherReferenceImpl::load(void) {
248 
249 	if (mp_cipherReferenceElement == NULL) {
250 
251 		// Attempt to load an empty encryptedType element
252 		throw XSECException(XSECException::CipherReferenceError,
253 			"XENCCipherReference::load - called on empty DOM");
254 
255 	}
256 
257 	if (!strEquals(getXENCLocalName(mp_cipherReferenceElement), s_CipherReference)) {
258 
259 		throw XSECException(XSECException::CipherReferenceError,
260 			"XENCCipherReference::load - called incorrect node");
261 
262 	}
263 
264 	// Find the URI attribute
265 	mp_uriAttr = mp_cipherReferenceElement->getAttributeNodeNS(NULL, DSIGConstants::s_unicodeStrURI);
266 
267 	if (mp_uriAttr == NULL) {
268 
269 		throw XSECException(XSECException::CipherReferenceError,
270 			"XENCCipherReference::load - URI attribute not found");
271 
272 	}
273 
274 	// See if there are any transforms
275 	DOMElement * c = findFirstElementChild(mp_cipherReferenceElement);
276 	if (c != NULL) {
277 
278 		if (!strEquals(getXENCLocalName(c), s_Transforms)) {
279 
280 			throw XSECException(XSECException::CipherReferenceError,
281 				"XENCCipherReference::load - Expected Transforms, found something else");
282 
283 		}
284 
285 		mp_transformsElement = c;
286 
287 		XSECSafeBufferFormatter * formatter;
288 		XSECnew(formatter, XSECSafeBufferFormatter("UTF-8",XMLFormatter::NoEscapes,
289 												XMLFormatter::UnRep_CharRef));
290 		Janitor<XSECSafeBufferFormatter> j_formatter(formatter);
291 
292 		mp_transformList = DSIGReference::loadTransforms(c, formatter, mp_env);
293 
294 	}
295 
296 
297 }
298 
299 // --------------------------------------------------------------------------------
300 //			Create a blank structure
301 // --------------------------------------------------------------------------------
302 
createBlankCipherReference(const XMLCh * URI)303 DOMElement * XENCCipherReferenceImpl::createBlankCipherReference(
304 						const XMLCh * URI) {
305 
306 	// Clean up
307 	if (mp_transformList != NULL) {
308 		delete mp_transformList;
309 		mp_transformList = NULL;
310 	}
311 
312 	mp_uriAttr = NULL;
313 
314 	// Get some setup values
315 	safeBuffer str;
316 	DOMDocument *doc = mp_env->getParentDocument();
317 	const XMLCh * prefix = mp_env->getXENCNSPrefix();
318 
319 	makeQName(str, prefix, s_CipherReference);
320 
321 	mp_cipherReferenceElement = doc->createElementNS(DSIGConstants::s_unicodeStrURIXENC, str.rawXMLChBuffer());
322 
323 	// Set the URI Attribute
324 	mp_cipherReferenceElement->setAttributeNS(NULL, DSIGConstants::s_unicodeStrURI, URI);
325 
326 	// Find the URI
327 	mp_uriAttr = mp_cipherReferenceElement->getAttributeNodeNS(NULL, DSIGConstants::s_unicodeStrURI);
328 
329 	if (mp_uriAttr == NULL) {
330 
331 		throw XSECException(XSECException::CipherReferenceError,
332 			"XENCCipherReference::createBlankReference - URI attribute not found after creation");
333 
334 	}
335 
336 	return mp_cipherReferenceElement;
337 
338 }
339 
340 // --------------------------------------------------------------------------------
341 //			Get Interface methods
342 // --------------------------------------------------------------------------------
343 
getTransforms(void) const344 DSIGTransformList * XENCCipherReferenceImpl::getTransforms(void) const {
345 
346 	return mp_transformList;
347 
348 }
349 
getURI(void) const350 const XMLCh * XENCCipherReferenceImpl::getURI (void) const {
351 
352 	if (mp_uriAttr != NULL)
353 		return mp_uriAttr->getNodeValue();
354 
355 	return NULL;
356 
357 }
358 
getElement(void) const359 DOMElement * XENCCipherReferenceImpl::getElement(void) const {
360 
361 	return mp_cipherReferenceElement;
362 
363 }
364