View Javadoc
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  package org.apache.wss4j.stax.test;
20  
21  import java.io.ByteArrayInputStream;
22  import java.io.ByteArrayOutputStream;
23  import java.io.InputStream;
24  import java.nio.charset.StandardCharsets;
25  import java.util.ArrayList;
26  import java.util.List;
27  import java.util.Map;
28  import java.util.Properties;
29  import java.util.Set;
30  
31  import javax.xml.namespace.QName;
32  import javax.xml.stream.XMLStreamReader;
33  import javax.xml.stream.XMLStreamWriter;
34  import javax.xml.transform.dom.DOMSource;
35  import javax.xml.transform.stream.StreamResult;
36  
37  import org.apache.wss4j.common.ext.WSSecurityException;
38  import org.apache.wss4j.dom.WSConstants;
39  import org.apache.wss4j.dom.handler.WSHandlerConstants;
40  import org.apache.wss4j.stax.ext.WSSConstants;
41  import org.apache.wss4j.stax.ext.WSSSecurityProperties;
42  import org.apache.wss4j.stax.securityToken.WSSecurityTokenConstants;
43  import org.apache.wss4j.stax.setup.InboundWSSec;
44  import org.apache.wss4j.stax.setup.OutboundWSSec;
45  import org.apache.wss4j.stax.setup.WSSec;
46  import org.apache.wss4j.stax.test.utils.StAX2DOM;
47  import org.apache.wss4j.stax.test.utils.XmlReaderToWriter;
48  import org.apache.xml.security.stax.ext.SecurePart;
49  import org.apache.xml.security.stax.securityEvent.SecurityEvent;
50  import org.apache.xml.security.stax.securityEvent.SecurityEventListener;
51  import org.junit.jupiter.api.Test;
52  import org.w3c.dom.Document;
53  import org.w3c.dom.NodeList;
54  
55  import static org.junit.jupiter.api.Assertions.assertEquals;
56  
57  public class HeaderOrderingTest extends AbstractTestBase {
58  
59      @Test
60      public void testUsernameTokenSignedStrictHeaderOrdering() throws Exception {
61          ByteArrayOutputStream baos = new ByteArrayOutputStream();
62  
63          {
64              WSSSecurityProperties securityProperties = new WSSSecurityProperties();
65              List<WSSConstants.Action> actions = new ArrayList<>();
66              actions.add(WSSConstants.SIGNATURE);
67              actions.add(WSSConstants.USERNAMETOKEN);
68              securityProperties.setActions(actions);
69              securityProperties.loadSignatureKeyStore(this.getClass().getClassLoader().getResource("transmitter.jks"), "default".toCharArray());
70              securityProperties.setSignatureUser("transmitter");
71              securityProperties.setTokenUser("transmitter");
72              securityProperties.setCallbackHandler(new CallbackHandlerImpl());
73              securityProperties.addSignaturePart(
74                      new SecurePart(new QName(WSSConstants.NS_WSSE10, "UsernameToken"), SecurePart.Modifier.Element)
75              );
76              securityProperties.addSignaturePart(
77                      new SecurePart(new QName(WSSConstants.NS_SOAP11, "Body"), SecurePart.Modifier.Element)
78              );
79  
80              OutboundWSSec wsSecOut = WSSec.getOutboundWSSec(securityProperties);
81              XMLStreamWriter xmlStreamWriter = wsSecOut.processOutMessage(baos, StandardCharsets.UTF_8.name(), new ArrayList<SecurityEvent>());
82              XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml"));
83              XmlReaderToWriter.writeAll(xmlStreamReader, xmlStreamWriter);
84              xmlStreamWriter.close();
85  
86              Document document = documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray()));
87  
88              NodeList securityHeaderElement = document.getElementsByTagNameNS(WSConstants.WSSE_NS, "Security");
89              assertEquals(1, securityHeaderElement.getLength());
90              NodeList childs = securityHeaderElement.item(0).getChildNodes();
91  
92              assertEquals(childs.getLength(), 2);
93              assertEquals(childs.item(0).getLocalName(), "UsernameToken");
94              assertEquals(childs.item(1).getLocalName(), "Signature");
95  
96              NodeList sigReferences = document.getElementsByTagNameNS(WSConstants.SIG_NS, "Reference");
97              assertEquals(2, sigReferences.getLength());
98          }
99  
100         //done UsernameToken; now verification:
101         {
102             String action = WSHandlerConstants.SIGNATURE + " " + WSHandlerConstants.USERNAME_TOKEN;
103             doInboundSecurityWithWSS4J(documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray())), action);
104         }
105     }
106 
107     @Test
108     public void testUsernameTokenSignedLaxHeaderOrdering() throws Exception {
109         ByteArrayOutputStream baos = new ByteArrayOutputStream();
110 
111         {
112             WSSSecurityProperties securityProperties = new WSSSecurityProperties();
113             List<WSSConstants.Action> actions = new ArrayList<>();
114             actions.add(WSSConstants.USERNAMETOKEN);
115             actions.add(WSSConstants.SIGNATURE);
116             securityProperties.setActions(actions);
117             securityProperties.loadSignatureKeyStore(this.getClass().getClassLoader().getResource("transmitter.jks"), "default".toCharArray());
118             securityProperties.setSignatureUser("transmitter");
119             securityProperties.setTokenUser("transmitter");
120             securityProperties.setCallbackHandler(new CallbackHandlerImpl());
121             securityProperties.addSignaturePart(
122                     new SecurePart(new QName(WSSConstants.NS_WSSE10, "UsernameToken"), SecurePart.Modifier.Element)
123             );
124             securityProperties.addSignaturePart(
125                     new SecurePart(new QName(WSSConstants.NS_SOAP11, "Body"), SecurePart.Modifier.Element)
126             );
127 
128             OutboundWSSec wsSecOut = WSSec.getOutboundWSSec(securityProperties);
129             XMLStreamWriter xmlStreamWriter = wsSecOut.processOutMessage(baos, StandardCharsets.UTF_8.name(), new ArrayList<SecurityEvent>());
130             XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml"));
131             XmlReaderToWriter.writeAll(xmlStreamReader, xmlStreamWriter);
132             xmlStreamWriter.close();
133 
134             Document document = documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray()));
135 
136             NodeList securityHeaderElement = document.getElementsByTagNameNS(WSConstants.WSSE_NS, "Security");
137             assertEquals(1, securityHeaderElement.getLength());
138             NodeList childs = securityHeaderElement.item(0).getChildNodes();
139 
140             assertEquals(childs.getLength(), 2);
141             assertEquals(childs.item(0).getLocalName(), "Signature");
142             assertEquals(childs.item(1).getLocalName(), "UsernameToken");
143 
144             NodeList sigReferences = document.getElementsByTagNameNS(WSConstants.SIG_NS, "Reference");
145             assertEquals(2, sigReferences.getLength());
146         }
147 
148         //done UsernameToken; now verification:
149         {
150             String action = WSHandlerConstants.USERNAME_TOKEN + " " + WSHandlerConstants.SIGNATURE;
151             doInboundSecurityWithWSS4J(documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray())), action);
152         }
153     }
154 
155     @Test
156     public void testUsernameTokenSignedWithBSTStrictHeaderOrdering() throws Exception {
157         ByteArrayOutputStream baos = new ByteArrayOutputStream();
158 
159         {
160             WSSSecurityProperties securityProperties = new WSSSecurityProperties();
161             List<WSSConstants.Action> actions = new ArrayList<>();
162             actions.add(WSSConstants.SIGNATURE);
163             actions.add(WSSConstants.USERNAMETOKEN);
164             securityProperties.setActions(actions);
165             securityProperties.loadSignatureKeyStore(this.getClass().getClassLoader().getResource("transmitter.jks"), "default".toCharArray());
166             securityProperties.setSignatureUser("transmitter");
167             securityProperties.setTokenUser("transmitter");
168             securityProperties.setCallbackHandler(new CallbackHandlerImpl());
169             securityProperties.setSignatureKeyIdentifier(WSSecurityTokenConstants.KEYIDENTIFIER_SECURITY_TOKEN_DIRECT_REFERENCE);
170             securityProperties.addSignaturePart(
171                     new SecurePart(new QName(WSSConstants.NS_WSSE10, "UsernameToken"), SecurePart.Modifier.Element)
172             );
173             securityProperties.addSignaturePart(
174                     new SecurePart(new QName(WSSConstants.NS_SOAP11, "Body"), SecurePart.Modifier.Element)
175             );
176 
177             OutboundWSSec wsSecOut = WSSec.getOutboundWSSec(securityProperties);
178             XMLStreamWriter xmlStreamWriter = wsSecOut.processOutMessage(baos, StandardCharsets.UTF_8.name(), new ArrayList<SecurityEvent>());
179             XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml"));
180             XmlReaderToWriter.writeAll(xmlStreamReader, xmlStreamWriter);
181             xmlStreamWriter.close();
182 
183             Document document = documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray()));
184 
185             NodeList securityHeaderElement = document.getElementsByTagNameNS(WSConstants.WSSE_NS, "Security");
186             assertEquals(1, securityHeaderElement.getLength());
187             NodeList childs = securityHeaderElement.item(0).getChildNodes();
188 
189             assertEquals(childs.getLength(), 3);
190             assertEquals(childs.item(0).getLocalName(), "UsernameToken");
191             assertEquals(childs.item(1).getLocalName(), "BinarySecurityToken");
192             assertEquals(childs.item(2).getLocalName(), "Signature");
193 
194             NodeList sigReferences = document.getElementsByTagNameNS(WSConstants.SIG_NS, "Reference");
195             assertEquals(2, sigReferences.getLength());
196         }
197 
198         //done UsernameToken; now verification:
199         {
200             String action = WSHandlerConstants.SIGNATURE + " " + WSHandlerConstants.USERNAME_TOKEN;
201             doInboundSecurityWithWSS4J(documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray())), action);
202         }
203     }
204 
205     @Test
206     public void testTimestampSignedStrictHeaderOrdering() throws Exception {
207         ByteArrayOutputStream baos = new ByteArrayOutputStream();
208 
209         {
210             WSSSecurityProperties securityProperties = new WSSSecurityProperties();
211             List<WSSConstants.Action> actions = new ArrayList<>();
212             actions.add(WSSConstants.SIGNATURE);
213             actions.add(WSSConstants.TIMESTAMP);
214             securityProperties.setActions(actions);
215             securityProperties.loadSignatureKeyStore(this.getClass().getClassLoader().getResource("transmitter.jks"), "default".toCharArray());
216             securityProperties.setSignatureUser("transmitter");
217             securityProperties.setTokenUser("transmitter");
218             securityProperties.setCallbackHandler(new CallbackHandlerImpl());
219             securityProperties.addSignaturePart(
220                     new SecurePart(new QName(WSSConstants.NS_WSU10, "Timestamp"), SecurePart.Modifier.Element)
221             );
222             securityProperties.addSignaturePart(
223                     new SecurePart(new QName(WSSConstants.NS_SOAP11, "Body"), SecurePart.Modifier.Element)
224             );
225 
226             OutboundWSSec wsSecOut = WSSec.getOutboundWSSec(securityProperties);
227             XMLStreamWriter xmlStreamWriter = wsSecOut.processOutMessage(baos, StandardCharsets.UTF_8.name(), new ArrayList<SecurityEvent>());
228             XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml"));
229             XmlReaderToWriter.writeAll(xmlStreamReader, xmlStreamWriter);
230             xmlStreamWriter.close();
231 
232             Document document = documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray()));
233 
234             NodeList securityHeaderElement = document.getElementsByTagNameNS(WSConstants.WSSE_NS, "Security");
235             assertEquals(1, securityHeaderElement.getLength());
236             NodeList childs = securityHeaderElement.item(0).getChildNodes();
237 
238             assertEquals(childs.getLength(), 2);
239             assertEquals(childs.item(0).getLocalName(), "Timestamp");
240             assertEquals(childs.item(1).getLocalName(), "Signature");
241 
242             NodeList sigReferences = document.getElementsByTagNameNS(WSConstants.SIG_NS, "Reference");
243             assertEquals(2, sigReferences.getLength());
244         }
245 
246         //done UsernameToken; now verification:
247         {
248             String action = WSHandlerConstants.SIGNATURE + " " + WSHandlerConstants.TIMESTAMP;
249             doInboundSecurityWithWSS4J(documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray())), action);
250         }
251     }
252 
253     @Test
254     public void testTimestampSignedLaxHeaderOrdering() throws Exception {
255         ByteArrayOutputStream baos = new ByteArrayOutputStream();
256 
257         {
258             WSSSecurityProperties securityProperties = new WSSSecurityProperties();
259             List<WSSConstants.Action> actions = new ArrayList<>();
260             actions.add(WSSConstants.TIMESTAMP);
261             actions.add(WSSConstants.SIGNATURE);
262             securityProperties.setActions(actions);
263             securityProperties.loadSignatureKeyStore(this.getClass().getClassLoader().getResource("transmitter.jks"), "default".toCharArray());
264             securityProperties.setSignatureUser("transmitter");
265             securityProperties.setTokenUser("transmitter");
266             securityProperties.setCallbackHandler(new CallbackHandlerImpl());
267             securityProperties.addSignaturePart(
268                     new SecurePart(new QName(WSSConstants.NS_WSU10, "Timestamp"), SecurePart.Modifier.Element)
269             );
270             securityProperties.addSignaturePart(
271                     new SecurePart(new QName(WSSConstants.NS_SOAP11, "Body"), SecurePart.Modifier.Element)
272             );
273 
274             OutboundWSSec wsSecOut = WSSec.getOutboundWSSec(securityProperties);
275             XMLStreamWriter xmlStreamWriter = wsSecOut.processOutMessage(baos, StandardCharsets.UTF_8.name(), new ArrayList<SecurityEvent>());
276             XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml"));
277             XmlReaderToWriter.writeAll(xmlStreamReader, xmlStreamWriter);
278             xmlStreamWriter.close();
279 
280             Document document = documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray()));
281 
282             NodeList securityHeaderElement = document.getElementsByTagNameNS(WSConstants.WSSE_NS, "Security");
283             assertEquals(1, securityHeaderElement.getLength());
284             NodeList childs = securityHeaderElement.item(0).getChildNodes();
285 
286             assertEquals(childs.getLength(), 2);
287             assertEquals(childs.item(0).getLocalName(), "Signature");
288             assertEquals(childs.item(1).getLocalName(), "Timestamp");
289 
290             NodeList sigReferences = document.getElementsByTagNameNS(WSConstants.SIG_NS, "Reference");
291             assertEquals(2, sigReferences.getLength());
292         }
293 
294         //done UsernameToken; now verification:
295         {
296             String action = WSHandlerConstants.TIMESTAMP + " " + WSHandlerConstants.SIGNATURE;
297             doInboundSecurityWithWSS4J(documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray())), action);
298         }
299     }
300 
301     @Test
302     public void testUsernameTokenPlusTimestampSignedStrictHeaderOrdering() throws Exception {
303         ByteArrayOutputStream baos = new ByteArrayOutputStream();
304 
305         {
306             WSSSecurityProperties securityProperties = new WSSSecurityProperties();
307             List<WSSConstants.Action> actions = new ArrayList<>();
308             actions.add(WSSConstants.SIGNATURE);
309             actions.add(WSSConstants.USERNAMETOKEN);
310             actions.add(WSSConstants.TIMESTAMP);
311             securityProperties.setActions(actions);
312             securityProperties.loadSignatureKeyStore(this.getClass().getClassLoader().getResource("transmitter.jks"), "default".toCharArray());
313             securityProperties.setSignatureUser("transmitter");
314             securityProperties.setTokenUser("transmitter");
315             securityProperties.setCallbackHandler(new CallbackHandlerImpl());
316             securityProperties.addSignaturePart(
317                     new SecurePart(new QName(WSSConstants.NS_WSSE10, "UsernameToken"), SecurePart.Modifier.Element)
318             );
319             securityProperties.addSignaturePart(
320                     new SecurePart(new QName(WSSConstants.NS_WSU10, "Timestamp"), SecurePart.Modifier.Element)
321             );
322             securityProperties.addSignaturePart(
323                     new SecurePart(new QName(WSSConstants.NS_SOAP11, "Body"), SecurePart.Modifier.Element)
324             );
325 
326             OutboundWSSec wsSecOut = WSSec.getOutboundWSSec(securityProperties);
327             XMLStreamWriter xmlStreamWriter = wsSecOut.processOutMessage(baos, StandardCharsets.UTF_8.name(), new ArrayList<SecurityEvent>());
328             XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml"));
329             XmlReaderToWriter.writeAll(xmlStreamReader, xmlStreamWriter);
330             xmlStreamWriter.close();
331 
332             Document document = documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray()));
333 
334             NodeList securityHeaderElement = document.getElementsByTagNameNS(WSConstants.WSSE_NS, "Security");
335             assertEquals(1, securityHeaderElement.getLength());
336             NodeList childs = securityHeaderElement.item(0).getChildNodes();
337 
338             assertEquals(childs.getLength(), 3);
339             assertEquals(childs.item(0).getLocalName(), "Timestamp");
340             assertEquals(childs.item(1).getLocalName(), "UsernameToken");
341             assertEquals(childs.item(2).getLocalName(), "Signature");
342 
343             NodeList sigReferences = document.getElementsByTagNameNS(WSConstants.SIG_NS, "Reference");
344             assertEquals(3, sigReferences.getLength());
345         }
346 
347         //done UsernameToken; now verification:
348         {
349             String action = WSHandlerConstants.SIGNATURE + " " + WSHandlerConstants.USERNAME_TOKEN + " " + WSHandlerConstants.TIMESTAMP;
350             doInboundSecurityWithWSS4J(documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray())), action);
351         }
352     }
353 
354     @Test
355     public void testTimestampPlusUsernameTokenSignedStrictHeaderOrdering() throws Exception {
356         ByteArrayOutputStream baos = new ByteArrayOutputStream();
357 
358         {
359             WSSSecurityProperties securityProperties = new WSSSecurityProperties();
360             List<WSSConstants.Action> actions = new ArrayList<>();
361             actions.add(WSSConstants.SIGNATURE);
362             actions.add(WSSConstants.TIMESTAMP);
363             actions.add(WSSConstants.USERNAMETOKEN);
364             securityProperties.setActions(actions);
365             securityProperties.loadSignatureKeyStore(this.getClass().getClassLoader().getResource("transmitter.jks"), "default".toCharArray());
366             securityProperties.setSignatureUser("transmitter");
367             securityProperties.setTokenUser("transmitter");
368             securityProperties.setCallbackHandler(new CallbackHandlerImpl());
369             securityProperties.addSignaturePart(
370                     new SecurePart(new QName(WSSConstants.NS_WSSE10, "UsernameToken"), SecurePart.Modifier.Element)
371             );
372             securityProperties.addSignaturePart(
373                     new SecurePart(new QName(WSSConstants.NS_WSU10, "Timestamp"), SecurePart.Modifier.Element)
374             );
375             securityProperties.addSignaturePart(
376                     new SecurePart(new QName(WSSConstants.NS_SOAP11, "Body"), SecurePart.Modifier.Element)
377             );
378 
379             OutboundWSSec wsSecOut = WSSec.getOutboundWSSec(securityProperties);
380             XMLStreamWriter xmlStreamWriter = wsSecOut.processOutMessage(baos, StandardCharsets.UTF_8.name(), new ArrayList<SecurityEvent>());
381             XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml"));
382             XmlReaderToWriter.writeAll(xmlStreamReader, xmlStreamWriter);
383             xmlStreamWriter.close();
384 
385             Document document = documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray()));
386 
387             NodeList securityHeaderElement = document.getElementsByTagNameNS(WSConstants.WSSE_NS, "Security");
388             assertEquals(1, securityHeaderElement.getLength());
389             NodeList childs = securityHeaderElement.item(0).getChildNodes();
390 
391             assertEquals(childs.getLength(), 3);
392             assertEquals(childs.item(0).getLocalName(), "UsernameToken");
393             assertEquals(childs.item(1).getLocalName(), "Timestamp");
394             assertEquals(childs.item(2).getLocalName(), "Signature");
395 
396             NodeList sigReferences = document.getElementsByTagNameNS(WSConstants.SIG_NS, "Reference");
397             assertEquals(3, sigReferences.getLength());
398         }
399 
400         //done UsernameToken; now verification:
401         {
402             String action = WSHandlerConstants.SIGNATURE + " " + WSHandlerConstants.TIMESTAMP + " " + WSHandlerConstants.USERNAME_TOKEN;
403             doInboundSecurityWithWSS4J(documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray())), action);
404         }
405     }
406 
407     @Test
408     public void testUsernameTokenPlusTimestampWithBSTSignedStrictHeaderOrdering() throws Exception {
409         ByteArrayOutputStream baos = new ByteArrayOutputStream();
410 
411         {
412             WSSSecurityProperties securityProperties = new WSSSecurityProperties();
413             List<WSSConstants.Action> actions = new ArrayList<>();
414             actions.add(WSSConstants.SIGNATURE);
415             actions.add(WSSConstants.USERNAMETOKEN);
416             actions.add(WSSConstants.TIMESTAMP);
417             securityProperties.setActions(actions);
418             securityProperties.loadSignatureKeyStore(this.getClass().getClassLoader().getResource("transmitter.jks"), "default".toCharArray());
419             securityProperties.setSignatureUser("transmitter");
420             securityProperties.setTokenUser("transmitter");
421             securityProperties.setCallbackHandler(new CallbackHandlerImpl());
422             securityProperties.setSignatureKeyIdentifier(WSSecurityTokenConstants.KEYIDENTIFIER_SECURITY_TOKEN_DIRECT_REFERENCE);
423             securityProperties.addSignaturePart(
424                     new SecurePart(new QName(WSSConstants.NS_WSSE10, "UsernameToken"), SecurePart.Modifier.Element)
425             );
426             securityProperties.addSignaturePart(
427                     new SecurePart(new QName(WSSConstants.NS_WSU10, "Timestamp"), SecurePart.Modifier.Element)
428             );
429             securityProperties.addSignaturePart(
430                     new SecurePart(new QName(WSSConstants.NS_SOAP11, "Body"), SecurePart.Modifier.Element)
431             );
432 
433             OutboundWSSec wsSecOut = WSSec.getOutboundWSSec(securityProperties);
434             XMLStreamWriter xmlStreamWriter = wsSecOut.processOutMessage(baos, StandardCharsets.UTF_8.name(), new ArrayList<SecurityEvent>());
435             XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml"));
436             XmlReaderToWriter.writeAll(xmlStreamReader, xmlStreamWriter);
437             xmlStreamWriter.close();
438 
439             Document document = documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray()));
440 
441             NodeList securityHeaderElement = document.getElementsByTagNameNS(WSConstants.WSSE_NS, "Security");
442             assertEquals(1, securityHeaderElement.getLength());
443             NodeList childs = securityHeaderElement.item(0).getChildNodes();
444 
445             assertEquals(childs.getLength(), 4);
446             assertEquals(childs.item(0).getLocalName(), "Timestamp");
447             assertEquals(childs.item(1).getLocalName(), "UsernameToken");
448             assertEquals(childs.item(2).getLocalName(), "BinarySecurityToken");
449             assertEquals(childs.item(3).getLocalName(), "Signature");
450 
451             NodeList sigReferences = document.getElementsByTagNameNS(WSConstants.SIG_NS, "Reference");
452             assertEquals(3, sigReferences.getLength());
453         }
454 
455         //done UsernameToken; now verification:
456         {
457             String action = WSHandlerConstants.SIGNATURE + " " + WSHandlerConstants.USERNAME_TOKEN + " " + WSHandlerConstants.TIMESTAMP;
458             doInboundSecurityWithWSS4J(documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray())), action);
459         }
460     }
461 
462     @Test
463     public void testUsernameTokenPlusTimestampSignedAndEncryptedStrictHeaderOrdering() throws Exception {
464         ByteArrayOutputStream baos = new ByteArrayOutputStream();
465 
466         {
467             WSSSecurityProperties securityProperties = new WSSSecurityProperties();
468             List<WSSConstants.Action> actions = new ArrayList<>();
469             actions.add(WSSConstants.SIGNATURE);
470             actions.add(WSSConstants.ENCRYPTION);
471             actions.add(WSSConstants.USERNAMETOKEN);
472             actions.add(WSSConstants.TIMESTAMP);
473             securityProperties.setActions(actions);
474             securityProperties.loadSignatureKeyStore(this.getClass().getClassLoader().getResource("transmitter.jks"), "default".toCharArray());
475             securityProperties.setSignatureUser("transmitter");
476             securityProperties.setTokenUser("transmitter");
477             securityProperties.setCallbackHandler(new CallbackHandlerImpl());
478             securityProperties.addSignaturePart(
479                     new SecurePart(new QName(WSSConstants.NS_WSSE10, "UsernameToken"), SecurePart.Modifier.Element)
480             );
481             securityProperties.addSignaturePart(
482                     new SecurePart(new QName(WSSConstants.NS_WSU10, "Timestamp"), SecurePart.Modifier.Element)
483             );
484             securityProperties.addSignaturePart(
485                     new SecurePart(new QName(WSSConstants.NS_SOAP11, "Body"), SecurePart.Modifier.Element)
486             );
487 
488             securityProperties.setEncryptionUser("receiver");
489             securityProperties.loadEncryptionKeystore(this.getClass().getClassLoader().getResource("transmitter.jks"), "default".toCharArray());
490             securityProperties.addEncryptionPart(
491                     new SecurePart(new QName(WSSConstants.NS_WSSE10, "UsernameToken"), SecurePart.Modifier.Element)
492             );
493             securityProperties.addEncryptionPart(
494                     new SecurePart(new QName(WSSConstants.NS_WSU10, "Timestamp"), SecurePart.Modifier.Element)
495             );
496             securityProperties.addEncryptionPart(
497                     new SecurePart(new QName(WSSConstants.NS_SOAP11, "Body"), SecurePart.Modifier.Content)
498             );
499 
500             OutboundWSSec wsSecOut = WSSec.getOutboundWSSec(securityProperties);
501             XMLStreamWriter xmlStreamWriter = wsSecOut.processOutMessage(baos, StandardCharsets.UTF_8.name(), new ArrayList<SecurityEvent>());
502             XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml"));
503             XmlReaderToWriter.writeAll(xmlStreamReader, xmlStreamWriter);
504             xmlStreamWriter.close();
505 
506             Document document = documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray()));
507 
508             NodeList securityHeaderElement = document.getElementsByTagNameNS(WSConstants.WSSE_NS, "Security");
509             assertEquals(1, securityHeaderElement.getLength());
510             NodeList childs = securityHeaderElement.item(0).getChildNodes();
511 
512             assertEquals(childs.getLength(), 4);
513             assertEquals(childs.item(0).getLocalName(), "EncryptedKey");
514             assertEquals(childs.item(1).getLocalName(), "EncryptedData");
515             assertEquals(childs.item(2).getLocalName(), "EncryptedData");
516             assertEquals(childs.item(3).getLocalName(), "Signature");
517 
518             NodeList sigReferences = document.getElementsByTagNameNS(WSConstants.SIG_NS, "Reference");
519             assertEquals(3, sigReferences.getLength());
520         }
521 
522         //done UsernameToken; now verification:
523         {
524             String action = WSHandlerConstants.SIGNATURE  + " " + WSHandlerConstants.USERNAME_TOKEN + " " + WSHandlerConstants.TIMESTAMP + " " + WSHandlerConstants.ENCRYPTION;
525             doInboundSecurityWithWSS4J(documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray())), action);
526         }
527     }
528 
529     @Test
530     public void testUsernameTokenPlusTimestampWithBSTSignedAndEncryptedStrictHeaderOrdering() throws Exception {
531         ByteArrayOutputStream baos = new ByteArrayOutputStream();
532 
533         {
534             WSSSecurityProperties securityProperties = new WSSSecurityProperties();
535             List<WSSConstants.Action> actions = new ArrayList<>();
536             actions.add(WSSConstants.SIGNATURE);
537             actions.add(WSSConstants.ENCRYPTION);
538             actions.add(WSSConstants.USERNAMETOKEN);
539             actions.add(WSSConstants.TIMESTAMP);
540             securityProperties.setActions(actions);
541             securityProperties.loadSignatureKeyStore(this.getClass().getClassLoader().getResource("transmitter.jks"), "default".toCharArray());
542             securityProperties.setSignatureUser("transmitter");
543             securityProperties.setTokenUser("transmitter");
544             securityProperties.setCallbackHandler(new CallbackHandlerImpl());
545             securityProperties.setSignatureKeyIdentifier(WSSecurityTokenConstants.KEYIDENTIFIER_SECURITY_TOKEN_DIRECT_REFERENCE);
546             securityProperties.addSignaturePart(
547                     new SecurePart(new QName(WSSConstants.NS_WSSE10, "UsernameToken"), SecurePart.Modifier.Element)
548             );
549             securityProperties.addSignaturePart(
550                     new SecurePart(new QName(WSSConstants.NS_WSU10, "Timestamp"), SecurePart.Modifier.Element)
551             );
552             securityProperties.addSignaturePart(
553                     new SecurePart(new QName(WSSConstants.NS_SOAP11, "Body"), SecurePart.Modifier.Element)
554             );
555 
556             securityProperties.setEncryptionUser("receiver");
557             securityProperties.loadEncryptionKeystore(this.getClass().getClassLoader().getResource("transmitter.jks"), "default".toCharArray());
558             securityProperties.setEncryptionKeyIdentifier(WSSecurityTokenConstants.KEYIDENTIFIER_SECURITY_TOKEN_DIRECT_REFERENCE);
559             securityProperties.addEncryptionPart(
560                     new SecurePart(new QName(WSSConstants.NS_WSSE10, "UsernameToken"), SecurePart.Modifier.Element)
561             );
562             securityProperties.addEncryptionPart(
563                     new SecurePart(new QName(WSSConstants.NS_WSU10, "Timestamp"), SecurePart.Modifier.Element)
564             );
565             securityProperties.addEncryptionPart(
566                     new SecurePart(new QName(WSSConstants.NS_SOAP11, "Body"), SecurePart.Modifier.Content)
567             );
568 
569             OutboundWSSec wsSecOut = WSSec.getOutboundWSSec(securityProperties);
570             XMLStreamWriter xmlStreamWriter = wsSecOut.processOutMessage(baos, StandardCharsets.UTF_8.name(), new ArrayList<SecurityEvent>());
571             XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml"));
572             XmlReaderToWriter.writeAll(xmlStreamReader, xmlStreamWriter);
573             xmlStreamWriter.close();
574 
575             Document document = documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray()));
576 
577             NodeList securityHeaderElement = document.getElementsByTagNameNS(WSConstants.WSSE_NS, "Security");
578             assertEquals(1, securityHeaderElement.getLength());
579             NodeList childs = securityHeaderElement.item(0).getChildNodes();
580 
581             assertEquals(childs.getLength(), 6);
582             assertEquals(childs.item(0).getLocalName(), "BinarySecurityToken");
583             assertEquals(childs.item(1).getLocalName(), "EncryptedKey");
584             assertEquals(childs.item(2).getLocalName(), "EncryptedData");
585             assertEquals(childs.item(3).getLocalName(), "EncryptedData");
586             assertEquals(childs.item(4).getLocalName(), "BinarySecurityToken");
587             assertEquals(childs.item(5).getLocalName(), "Signature");
588 
589             NodeList sigReferences = document.getElementsByTagNameNS(WSConstants.SIG_NS, "Reference");
590             assertEquals(3, sigReferences.getLength());
591         }
592 
593         //done UsernameToken; now verification:
594         {
595             String action = WSHandlerConstants.SIGNATURE  + " " + WSHandlerConstants.USERNAME_TOKEN + " " + WSHandlerConstants.TIMESTAMP + " " + WSHandlerConstants.ENCRYPTION;
596             doInboundSecurityWithWSS4J(documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray())), action);
597         }
598     }
599 
600     @SuppressWarnings("unchecked")
601     @Test
602     public void testSignatureConfirmationUsernameTokenTimestampStrictHeaderOrdering() throws Exception {
603 
604         Set<Integer> sigv;
605         ByteArrayOutputStream baos = new ByteArrayOutputStream();
606         {
607             InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
608             String action = WSHandlerConstants.SIGNATURE;
609             Properties properties = new Properties();
610             properties.setProperty(WSHandlerConstants.ENABLE_SIGNATURE_CONFIRMATION, "true");
611             Map<String, Object> messageContext = doOutboundSecurityWithWSS4J_1(sourceDocument, action, properties);
612             sigv = (Set<Integer>) messageContext.get(WSHandlerConstants.SEND_SIGV);
613             Document securedDocument = (Document) messageContext.get(SECURED_DOCUMENT);
614 
615             //some test that we can really sure we get what we want from WSS4J
616             NodeList nodeList = securedDocument.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
617             assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_WSSE_SECURITY.getLocalPart());
618 
619             javax.xml.transform.Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
620             transformer.transform(new DOMSource(securedDocument), new StreamResult(baos));
621         }
622 
623         final List<SecurityEvent> securityEventList = new ArrayList<>();
624         //done signature; now test sig-verification:
625         {
626             WSSSecurityProperties securityProperties = new WSSSecurityProperties();
627             securityProperties.loadSignatureVerificationKeystore(this.getClass().getClassLoader().getResource("receiver.jks"), "default".toCharArray());
628             InboundWSSec wsSecIn = WSSec.getInboundWSSec(securityProperties);
629 
630             SecurityEventListener securityEventListener = new SecurityEventListener() {
631                 @Override
632                 public void registerSecurityEvent(SecurityEvent securityEvent) throws WSSecurityException {
633                     securityEventList.add(securityEvent);
634                 }
635             };
636 
637             XMLStreamReader xmlStreamReader = wsSecIn.processInMessage(xmlInputFactory.createXMLStreamReader(new ByteArrayInputStream(baos.toByteArray())), new ArrayList<SecurityEvent>(), securityEventListener);
638 
639             Document document = StAX2DOM.readDoc(documentBuilderFactory.newDocumentBuilder(), xmlStreamReader);
640 
641             //header element must still be there
642             NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
643             assertEquals(nodeList.getLength(), 1);
644             assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_WSSE_SECURITY.getLocalPart());
645         }
646 
647         //so we have a request generated, now do the response:
648         baos = new ByteArrayOutputStream();
649         {
650             WSSSecurityProperties securityProperties = new WSSSecurityProperties();
651             List<WSSConstants.Action> actions = new ArrayList<>();
652             actions.add(WSSConstants.SIGNATURE);
653             actions.add(WSSConstants.SIGNATURE_CONFIRMATION);
654             actions.add(WSSConstants.USERNAMETOKEN);
655             actions.add(WSSConstants.TIMESTAMP);
656             securityProperties.setActions(actions);
657             securityProperties.setSignatureKeyIdentifier(WSSecurityTokenConstants.KEYIDENTIFIER_SECURITY_TOKEN_DIRECT_REFERENCE);
658             securityProperties.addSignaturePart(
659                     new SecurePart(new QName(WSSConstants.NS_WSSE10, "UsernameToken"), SecurePart.Modifier.Element)
660             );
661             securityProperties.addSignaturePart(
662                     new SecurePart(new QName(WSSConstants.NS_WSU10, "Timestamp"), SecurePart.Modifier.Element)
663             );
664             securityProperties.addSignaturePart(
665                     new SecurePart(WSSConstants.TAG_WSSE11_SIG_CONF, SecurePart.Modifier.Element)
666             );
667             securityProperties.addSignaturePart(
668                     new SecurePart(new QName(WSSConstants.NS_SOAP11, "Body"), SecurePart.Modifier.Element)
669             );
670             securityProperties.loadSignatureKeyStore(this.getClass().getClassLoader().getResource("receiver.jks"), "default".toCharArray());
671             securityProperties.setSignatureUser("receiver");
672             securityProperties.setTokenUser("transmitter");
673             securityProperties.setCallbackHandler(new CallbackHandlerImpl());
674 
675             OutboundWSSec wsSecOut = WSSec.getOutboundWSSec(securityProperties);
676             XMLStreamWriter xmlStreamWriter = wsSecOut.processOutMessage(baos, StandardCharsets.UTF_8.name(), securityEventList);
677             XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml"));
678             XmlReaderToWriter.writeAll(xmlStreamReader, xmlStreamWriter);
679             xmlStreamWriter.close();
680 
681             Document document = documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray()));
682             NodeList securityHeaderElement = document.getElementsByTagNameNS(WSConstants.WSSE_NS, "Security");
683             assertEquals(1, securityHeaderElement.getLength());
684             NodeList childs = securityHeaderElement.item(0).getChildNodes();
685 
686             assertEquals(childs.getLength(), 5);
687             assertEquals(childs.item(0).getLocalName(), "Timestamp");
688             assertEquals(childs.item(1).getLocalName(), "UsernameToken");
689             assertEquals(childs.item(2).getLocalName(), "SignatureConfirmation");
690             assertEquals(childs.item(3).getLocalName(), "BinarySecurityToken");
691             assertEquals(childs.item(4).getLocalName(), "Signature");
692 
693             NodeList sigReferences = document.getElementsByTagNameNS(WSConstants.SIG_NS, "Reference");
694             assertEquals(4, sigReferences.getLength());
695         }
696 
697         //verify SigConf response:
698         {
699             String action = WSHandlerConstants.SIGNATURE  + " " + WSHandlerConstants.USERNAME_TOKEN + " " + WSHandlerConstants.TIMESTAMP;
700             Properties properties = new Properties();
701             properties.put(WSHandlerConstants.SEND_SIGV, sigv);
702             doInboundSecurityWithWSS4J_1(documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray())), action, properties, true);
703         }
704     }
705 
706     @Test
707     public void testUsernameTokenPlusTimestampPlusSignatureWithBSTSignedAndEncryptedStrictHeaderOrdering() throws Exception {
708         ByteArrayOutputStream baos = new ByteArrayOutputStream();
709 
710         {
711             WSSSecurityProperties securityProperties = new WSSSecurityProperties();
712             List<WSSConstants.Action> actions = new ArrayList<>();
713             actions.add(WSSConstants.SIGNATURE);
714             actions.add(WSSConstants.ENCRYPTION);
715             actions.add(WSSConstants.USERNAMETOKEN);
716             actions.add(WSSConstants.TIMESTAMP);
717             securityProperties.setActions(actions);
718             securityProperties.loadSignatureKeyStore(this.getClass().getClassLoader().getResource("transmitter.jks"), "default".toCharArray());
719             securityProperties.setSignatureUser("transmitter");
720             securityProperties.setTokenUser("transmitter");
721             securityProperties.setCallbackHandler(new CallbackHandlerImpl());
722             securityProperties.setSignatureKeyIdentifier(WSSecurityTokenConstants.KEYIDENTIFIER_SECURITY_TOKEN_DIRECT_REFERENCE);
723             securityProperties.addSignaturePart(
724                     new SecurePart(new QName(WSSConstants.NS_WSSE10, "UsernameToken"), SecurePart.Modifier.Element)
725             );
726             securityProperties.addSignaturePart(
727                     new SecurePart(new QName(WSSConstants.NS_WSU10, "Timestamp"), SecurePart.Modifier.Element)
728             );
729             securityProperties.addSignaturePart(
730                     new SecurePart(new QName(WSSConstants.NS_SOAP11, "Body"), SecurePart.Modifier.Element)
731             );
732 
733             securityProperties.setEncryptionUser("receiver");
734             securityProperties.loadEncryptionKeystore(this.getClass().getClassLoader().getResource("transmitter.jks"), "default".toCharArray());
735             securityProperties.setEncryptionKeyIdentifier(WSSecurityTokenConstants.KEYIDENTIFIER_SECURITY_TOKEN_DIRECT_REFERENCE);
736             securityProperties.addEncryptionPart(
737                     new SecurePart(new QName(WSSConstants.NS_DSIG, "Signature"), SecurePart.Modifier.Element)
738             );
739             securityProperties.addEncryptionPart(
740                     new SecurePart(new QName(WSSConstants.NS_WSSE10, "UsernameToken"), SecurePart.Modifier.Element)
741             );
742             securityProperties.addEncryptionPart(
743                     new SecurePart(new QName(WSSConstants.NS_WSU10, "Timestamp"), SecurePart.Modifier.Element)
744             );
745             securityProperties.addEncryptionPart(
746                     new SecurePart(new QName(WSSConstants.NS_SOAP11, "Body"), SecurePart.Modifier.Content)
747             );
748 
749             OutboundWSSec wsSecOut = WSSec.getOutboundWSSec(securityProperties);
750             XMLStreamWriter xmlStreamWriter = wsSecOut.processOutMessage(baos, StandardCharsets.UTF_8.name(), new ArrayList<SecurityEvent>());
751             XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml"));
752             XmlReaderToWriter.writeAll(xmlStreamReader, xmlStreamWriter);
753             xmlStreamWriter.close();
754 
755             Document document = documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray()));
756 
757             NodeList securityHeaderElement = document.getElementsByTagNameNS(WSConstants.WSSE_NS, "Security");
758             assertEquals(1, securityHeaderElement.getLength());
759             NodeList childs = securityHeaderElement.item(0).getChildNodes();
760 
761             assertEquals(childs.getLength(), 6);
762             assertEquals(childs.item(0).getLocalName(), "BinarySecurityToken");
763             assertEquals(childs.item(1).getLocalName(), "EncryptedKey");
764             assertEquals(childs.item(2).getLocalName(), "EncryptedData");
765             assertEquals(childs.item(3).getLocalName(), "EncryptedData");
766             assertEquals(childs.item(4).getLocalName(), "BinarySecurityToken");
767             assertEquals(childs.item(5).getLocalName(), "EncryptedData");
768 
769             NodeList sigReferences = document.getElementsByTagNameNS(WSConstants.SIG_NS, "Reference");
770             assertEquals(0, sigReferences.getLength()); //0 because the signature is encrypted
771         }
772 
773         //done UsernameToken; now verification:
774         {
775             String action = WSHandlerConstants.SIGNATURE  + " " + WSHandlerConstants.USERNAME_TOKEN + " " + WSHandlerConstants.TIMESTAMP + " " + WSHandlerConstants.ENCRYPTION;
776             doInboundSecurityWithWSS4J(documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray())), action);
777         }
778     }
779 }