1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.ws.security.message;
21
22 import java.util.Iterator;
23 import java.util.LinkedList;
24 import java.util.List;
25
26 import javax.xml.namespace.QName;
27
28 import org.w3c.dom.Document;
29 import org.w3c.dom.Element;
30 import org.w3c.dom.Node;
31 import org.w3c.dom.NodeList;
32
33
34
35
36
37
38
39 public class TestMessageTransformer extends org.junit.Assert {
40 private static final org.apache.commons.logging.Log LOG = org.apache.commons.logging.LogFactory
41 .getLog(TestMessageTransformer.class);
42
43 public static Element duplicateEncryptedDataInWsseHeader(Element saaj, boolean moveReferenceList) {
44 if (moveReferenceList) {
45 moveReferenceList(saaj);
46 }
47 Element body = getFirstChildElement(saaj, new QName("http://schemas.xmlsoap.org/soap/envelope/",
48 "Body"), true);
49 Element encData = getFirstChildElement(body, new QName("http://www.w3.org/2001/04/xmlenc#",
50 "EncryptedData"), true);
51 Element newEncData = createNewEncryptedData(encData);
52 Element sh = getFirstChildElement(saaj, new QName("http://schemas.xmlsoap.org/soap/envelope/",
53 "Header"), true);
54 Element wsseHeader = getFirstChildElement(sh,
55 new QName(
56 "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd",
57 "Security"), true);
58
59 Node newWsseHeader = wsseHeader.cloneNode(false);
60 Node cur = wsseHeader.getFirstChild();
61
62 String newId = newEncData.getAttributeNS(null, "Id");
63 while (cur != null) {
64 cur = copyHeadersAndUpdateRefList(cur, newWsseHeader, newId);
65 }
66 newWsseHeader.appendChild(newEncData);
67
68 if (!moveReferenceList) {
69 updateEncryptedKeyRefList(newWsseHeader, newId);
70 }
71
72 Node parent = wsseHeader.getParentNode();
73 parent.removeChild(wsseHeader);
74 parent.appendChild(newWsseHeader);
75 print(saaj.getOwnerDocument());
76 return newEncData;
77 }
78
79 public static Element duplicateEncryptedDataInWsseWrapperHeader(Element saaj, boolean moveReferenceList) {
80 if (moveReferenceList) {
81 moveReferenceList(saaj);
82 }
83 Element body = getFirstChildElement(saaj, new QName("http://schemas.xmlsoap.org/soap/envelope/",
84 "Body"), true);
85 Element encData = getFirstChildElement(body, new QName("http://www.w3.org/2001/04/xmlenc#",
86 "EncryptedData"), true);
87 Element newEncData = createNewEncryptedData(encData);
88 Element sh = getFirstChildElement(saaj, new QName("http://schemas.xmlsoap.org/soap/envelope/",
89 "Header"), true);
90 Element signature = getFirstChildElement(sh, new QName("http://www.w3.org/2000/09/xmldsig#",
91 "Signature"), true);
92
93 Node wsseHeader = signature.getParentNode();
94 Node newWsseHeader = wsseHeader.cloneNode(false);
95 Node cur = wsseHeader.getFirstChild();
96 String newId = newEncData.getAttributeNS(null, "Id");
97 while (!cur.isSameNode(signature)) {
98 cur = copyHeadersAndUpdateRefList(cur, newWsseHeader, newId);
99 }
100 Element wrapper = encData.getOwnerDocument().createElementNS(null, "a");
101 wrapper.appendChild(newEncData);
102 newWsseHeader.appendChild(wrapper);
103 while (cur != null) {
104 cur = copyHeadersAndUpdateRefList(cur, newWsseHeader, newId);
105 }
106
107 if (!moveReferenceList) {
108 updateEncryptedKeyRefList(newWsseHeader, newId);
109 }
110
111 Node parent = wsseHeader.getParentNode();
112 parent.removeChild(wsseHeader);
113 parent.appendChild(newWsseHeader);
114 print(saaj.getOwnerDocument());
115 return newEncData;
116 }
117
118 public static Element duplicateEncryptedDataInExternalWrapperElement(Element saaj,
119 boolean moveReferenceList) {
120 if (moveReferenceList) {
121 moveReferenceList(saaj);
122 }
123 Element body = getFirstChildElement(saaj, new QName("http://schemas.xmlsoap.org/soap/envelope/",
124 "Body"), true);
125 Element encData = getFirstChildElement(body, new QName("http://www.w3.org/2001/04/xmlenc#",
126 "EncryptedData"), true);
127 Element newEncData = createNewEncryptedData(encData);
128 Element sh = getFirstChildElement(saaj, new QName("http://schemas.xmlsoap.org/soap/envelope/",
129 "Header"), true);
130 Element wsseHeader = getFirstChildElement(sh,
131 new QName(
132 "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd",
133 "Security"), true);
134
135 Node newWsseHeader = wsseHeader.cloneNode(false);
136 Node cur = wsseHeader.getFirstChild();
137 String newId = newEncData.getAttributeNS(null, "Id");
138 while (cur != null) {
139 cur = copyHeadersAndUpdateRefList(cur, newWsseHeader, newId);
140 }
141 sh.removeChild(wsseHeader);
142 sh.appendChild(newWsseHeader);
143
144 if (!moveReferenceList) {
145 updateEncryptedKeyRefList(newWsseHeader, newId);
146 }
147
148 Element wrapper = encData.getOwnerDocument().createElementNS(null, "a");
149 wrapper.setAttributeNS("http://schemas.xmlsoap.org/soap/envelope/", "mustUnderstand", "0");
150 wrapper.setAttributeNS("http://schemas.xmlsoap.org/soap/envelope/", "actor", "foo");
151 wrapper.appendChild(newEncData);
152 sh.appendChild(wrapper);
153 print(saaj.getOwnerDocument());
154 return newEncData;
155 }
156
157 public static Element addEncryptedDataWithEmbeddedEncryptedKeyInWsseHeader(Element saaj) {
158 moveReferenceList(saaj);
159 Element body = getFirstChildElement(saaj, new QName("http://schemas.xmlsoap.org/soap/envelope/",
160 "Body"), true);
161 Element encData = getFirstChildElement(body, new QName("http://www.w3.org/2001/04/xmlenc#",
162 "EncryptedData"), true);
163
164 Element newEncData = (Element)encData.cloneNode(true);
165 String newId = newEncData.getAttributeNS(null, "Id") + "b";
166 newEncData.setAttributeNS(null, "Id", newId);
167
168 Element encKey = getFirstChildElement(saaj, new QName("http://www.w3.org/2001/04/xmlenc#",
169 "EncryptedKey"), true);
170 Element newEncKey = (Element)encKey.cloneNode(true);
171 String newEcId = newEncKey.getAttributeNS(null, "Id") + "b";
172 newEncKey.setAttributeNS(null, "Id", newEcId);
173
174 Element keyInfo = getFirstChildElement(newEncData, new QName("http://www.w3.org/2000/09/xmldsig#",
175 "KeyInfo"), true);
176 Element str = getFirstChildElement(newEncData,
177 new QName(
178 "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd",
179 "SecurityTokenReference"), true);
180 keyInfo.replaceChild(newEncKey, str);
181
182 Element wsseHeader = getFirstChildElement(saaj,
183 new QName(
184 "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd",
185 "Security"), true);
186
187 Node newWsseHeader = wsseHeader.cloneNode(false);
188 Node cur = wsseHeader.getFirstChild();
189
190 while (cur != null) {
191 cur = copyHeadersAndUpdateRefList(cur, newWsseHeader, newId);
192 }
193 newWsseHeader.appendChild(newEncData);
194
195 Node parent = wsseHeader.getParentNode();
196 parent.removeChild(wsseHeader);
197 parent.appendChild(newWsseHeader);
198 print(saaj.getOwnerDocument());
199 return newEncData;
200
201 }
202
203 private static void moveReferenceList(Element saaj) {
204 Element sh = getFirstChildElement(saaj, new QName("http://schemas.xmlsoap.org/soap/envelope/",
205 "Header"), true);
206 Element encKey = getFirstChildElement(sh, new QName("http://www.w3.org/2001/04/xmlenc#",
207 "EncryptedKey"), true);
208 Element refList = getFirstChildElement(encKey, new QName("http://www.w3.org/2001/04/xmlenc#",
209 "ReferenceList"), true);
210
211 Node wsseHeader = encKey.getParentNode();
212 encKey.removeChild(refList);
213 wsseHeader.appendChild(refList);
214 }
215
216 private static void updateEncryptedKeyRefList(Node wsseHeader, String newId) {
217 Element encryptedKey = getFirstChildElement(wsseHeader,
218 new QName("http://www.w3.org/2001/04/xmlenc#",
219 "EncryptedKey"), true);
220 Element ref = getFirstChildElement(encryptedKey, new QName("http://www.w3.org/2001/04/xmlenc#",
221 "DataReference"), true);
222 Element newRef = (Element)ref.cloneNode(true);
223 newRef.setAttributeNS(null, "URI", "#" + newId);
224 ref.getParentNode().appendChild(newRef);
225 }
226
227 private static void print(Document doc) {
228 if (LOG.isDebugEnabled()) {
229 LOG.debug("After transformation....");
230 String outputString = org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(doc);
231 LOG.debug(outputString);
232 }
233 }
234
235 private static Element createNewEncryptedData(Element encData) {
236 Element newEncData = (Element)encData.cloneNode(true);
237 String id = newEncData.getAttributeNS(null, "Id");
238 String newId = id + "b";
239 newEncData.setAttributeNS(null, "Id", newId);
240 return newEncData;
241 }
242
243 private static Node copyHeadersAndUpdateRefList(Node cur, Node dest, String newId) {
244 Node temp = cur.cloneNode(true);
245 dest.appendChild(temp);
246 if (newId != null && temp.getNodeType() == Node.ELEMENT_NODE) {
247 Element t = (Element)temp;
248 if (t.getLocalName().equals("ReferenceList")) {
249 Element ref = getFirstChildElement(t, new QName("http://www.w3.org/2001/04/xmlenc#",
250 "DataReference"), true);
251 Element newRef = (Element)ref.cloneNode(true);
252 newRef.setAttributeNS(null, "URI", "#" + newId);
253 t.appendChild(newRef);
254 }
255 }
256 return cur.getNextSibling();
257 }
258
259 private static Element getFirstChildElement(Node node, QName nodeName, boolean recursive) {
260 Element childElement = null;
261 Iterator<Element> it = getChildElements(node, nodeName, recursive).iterator();
262 if (it.hasNext()) {
263 childElement = (Element)it.next();
264 }
265 return childElement;
266 }
267
268 private static List<Element> getChildElements(Node node, QName nodeName, boolean recursive) {
269 List<Element> list = new LinkedList<Element>();
270
271 NodeList nlist = node.getChildNodes();
272 int len = nlist.getLength();
273 for (int i = 0; i < len; i++) {
274 Node child = nlist.item(i);
275 if (child.getNodeType() == Node.ELEMENT_NODE) {
276 search(list, (Element)child, nodeName, recursive);
277 }
278 }
279 return list;
280 }
281
282 private static void search(List<Element> list, Element baseElement, QName nodeName, boolean recursive) {
283 if (nodeName == null) {
284 list.add(baseElement);
285 } else {
286 QName qname;
287 if (nodeName.getNamespaceURI().length() > 0) {
288 qname = new QName(baseElement.getNamespaceURI(), baseElement.getLocalName());
289 } else {
290 qname = new QName(baseElement.getLocalName());
291 }
292 if (qname.equals(nodeName)) {
293 list.add(baseElement);
294 }
295 }
296 if (recursive) {
297 NodeList nlist = baseElement.getChildNodes();
298 int len = nlist.getLength();
299 for (int i = 0; i < len; i++) {
300 Node child = nlist.item(i);
301 if (child.getNodeType() == Node.ELEMENT_NODE) {
302 search(list, (Element)child, nodeName, recursive);
303 }
304 }
305 }
306 }
307
308 }