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.lang.reflect.Field;
25  import java.nio.charset.StandardCharsets;
26  import java.security.KeyStore;
27  import java.security.Security;
28  import java.security.cert.X509Certificate;
29  import java.util.ArrayList;
30  import java.util.HashMap;
31  import java.util.List;
32  import java.util.Map;
33  import java.util.Properties;
34  
35  import javax.crypto.KeyGenerator;
36  import javax.crypto.SecretKey;
37  import javax.xml.namespace.QName;
38  import javax.xml.stream.XMLStreamException;
39  import javax.xml.stream.XMLStreamReader;
40  import javax.xml.stream.XMLStreamWriter;
41  import javax.xml.transform.Transformer;
42  import javax.xml.transform.TransformerFactory;
43  import javax.xml.transform.dom.DOMSource;
44  import javax.xml.transform.stream.StreamResult;
45  import javax.xml.transform.stream.StreamSource;
46  import javax.xml.xpath.XPathConstants;
47  import javax.xml.xpath.XPathExpression;
48  
49  import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream;
50  import org.apache.commons.compress.compressors.gzip.GzipCompressorOutputStream;
51  import org.apache.wss4j.common.ConfigurationConstants;
52  import org.apache.wss4j.common.WSEncryptionPart;
53  import org.apache.wss4j.common.bsp.BSPRule;
54  import org.apache.wss4j.common.crypto.Crypto;
55  import org.apache.wss4j.common.crypto.CryptoFactory;
56  import org.apache.wss4j.common.ext.WSSecurityException;
57  import org.apache.wss4j.common.util.KeyUtils;
58  import org.apache.wss4j.dom.WSConstants;
59  import org.apache.wss4j.dom.handler.WSHandlerConstants;
60  import org.apache.wss4j.dom.message.WSSecEncrypt;
61  import org.apache.wss4j.dom.message.WSSecHeader;
62  import org.apache.wss4j.stax.ext.WSSConstants;
63  import org.apache.wss4j.stax.ext.WSSSecurityProperties;
64  import org.apache.wss4j.stax.securityEvent.EncryptedPartSecurityEvent;
65  import org.apache.wss4j.stax.securityEvent.OperationSecurityEvent;
66  import org.apache.wss4j.stax.securityEvent.WSSecurityEventConstants;
67  import org.apache.wss4j.stax.securityToken.WSSecurityTokenConstants;
68  import org.apache.wss4j.stax.setup.ConfigurationConverter;
69  import org.apache.wss4j.stax.setup.InboundWSSec;
70  import org.apache.wss4j.stax.setup.OutboundWSSec;
71  import org.apache.wss4j.stax.setup.WSSec;
72  import org.apache.wss4j.stax.test.utils.StAX2DOM;
73  import org.apache.wss4j.stax.test.utils.XmlReaderToWriter;
74  import org.apache.xml.security.exceptions.XMLSecurityException;
75  import org.apache.xml.security.stax.config.Init;
76  import org.apache.xml.security.stax.config.TransformerAlgorithmMapper;
77  import org.apache.xml.security.stax.ext.SecurePart;
78  import org.apache.xml.security.stax.securityEvent.ContentEncryptedElementSecurityEvent;
79  import org.apache.xml.security.stax.securityEvent.EncryptedElementSecurityEvent;
80  import org.apache.xml.security.stax.securityEvent.SecurityEvent;
81  import org.apache.xml.security.stax.securityEvent.SecurityEventConstants;
82  import org.apache.xml.security.utils.XMLUtils;
83  import org.bouncycastle.jce.provider.BouncyCastleProvider;
84  import org.junit.jupiter.api.Test;
85  import org.w3c.dom.Document;
86  import org.w3c.dom.Element;
87  import org.w3c.dom.Node;
88  import org.w3c.dom.NodeList;
89  
90  import static org.junit.jupiter.api.Assertions.assertEquals;
91  import static org.junit.jupiter.api.Assertions.assertNotNull;
92  import static org.junit.jupiter.api.Assertions.assertTrue;
93  import static org.junit.jupiter.api.Assertions.fail;
94  import static org.junit.jupiter.api.Assumptions.assumeFalse;
95  
96  public class EncDecryptionTest extends AbstractTestBase {
97  
98      private boolean isIBMJdK = System.getProperty("java.vendor").contains("IBM");
99  
100     @Test
101     public void testEncDecryptionDefaultConfigurationOutbound() throws Exception {
102 
103         ByteArrayOutputStream baos;
104         {
105             WSSSecurityProperties securityProperties = new WSSSecurityProperties();
106             List<WSSConstants.Action> actions = new ArrayList<>();
107             actions.add(WSSConstants.ENCRYPTION);
108             securityProperties.setActions(actions);
109             securityProperties.loadEncryptionKeystore(this.getClass().getClassLoader().getResource("transmitter.jks"), "default".toCharArray());
110             securityProperties.setEncryptionUser("receiver");
111 
112             InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
113             baos = doOutboundSecurity(securityProperties, sourceDocument);
114 
115             Document document = documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray()));
116             NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedKey.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedKey.getLocalPart());
117             assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_WSSE_SECURITY.getLocalPart());
118 
119             XPathExpression xPathExpression = getXPath("/soap:Envelope/soap:Header/wsse:Security/xenc:EncryptedKey/xenc:EncryptionMethod[@Algorithm='http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p']");
120             Node node = (Node) xPathExpression.evaluate(document, XPathConstants.NODE);
121             assertNotNull(node);
122 
123             nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_DataReference.getNamespaceURI(), WSSConstants.TAG_xenc_DataReference.getLocalPart());
124             assertEquals(nodeList.getLength(), 1);
125 
126             nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedData.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedData.getLocalPart());
127             assertEquals(nodeList.getLength(), 1);
128 
129             xPathExpression = getXPath("/soap:Envelope/soap:Body/xenc:EncryptedData/xenc:EncryptionMethod[@Algorithm='http://www.w3.org/2001/04/xmlenc#aes256-cbc']");
130             node = (Node) xPathExpression.evaluate(document, XPathConstants.NODE);
131             assertNotNull(node);
132 
133             assertEquals(node.getParentNode().getParentNode().getLocalName(), "Body");
134             NodeList childNodes = node.getParentNode().getParentNode().getChildNodes();
135             for (int i = 0; i < childNodes.getLength(); i++) {
136                 Node child = childNodes.item(i);
137                 if (child.getNodeType() == Node.TEXT_NODE) {
138                     assertEquals(child.getTextContent().trim(), "");
139                 } else if (child.getNodeType() == Node.ELEMENT_NODE) {
140                     assertEquals(child, nodeList.item(0));
141                 } else {
142                     fail("Unexpected Node encountered");
143                 }
144             }
145         }
146 
147         //done encryption; now test decryption:
148         {
149             String action = WSHandlerConstants.ENCRYPTION;
150             doInboundSecurityWithWSS4J(documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray())), action);
151         }
152     }
153 
154     @Test
155     public void testEncDecryptionDefaultConfigurationInbound() throws Exception {
156 
157         ByteArrayOutputStream baos = new ByteArrayOutputStream();
158 
159         {
160             InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
161             String action = WSHandlerConstants.ENCRYPTION;
162             Document securedDocument = doOutboundSecurityWithWSS4J(sourceDocument, action, new Properties());
163 
164             //some test that we can really sure we get what we want from WSS4J
165             XPathExpression xPathExpression = getXPath("/soap:Envelope/soap:Header/wsse:Security/xenc:EncryptedKey/xenc:EncryptionMethod[@Algorithm='http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p']");
166             Node node = (Node) xPathExpression.evaluate(securedDocument, XPathConstants.NODE);
167             assertNotNull(node);
168 
169             Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
170             transformer.transform(new DOMSource(securedDocument), new StreamResult(baos));
171         }
172         //test streaming decryption
173         {
174             WSSSecurityProperties securityProperties = new WSSSecurityProperties();
175             securityProperties.loadDecryptionKeystore(this.getClass().getClassLoader().getResource("receiver.jks"), "default".toCharArray());
176             securityProperties.setCallbackHandler(new CallbackHandlerImpl());
177 
178             WSSecurityEventConstants.Event[] expectedSecurityEvents = new WSSecurityEventConstants.Event[]{
179                     WSSecurityEventConstants.AlgorithmSuite,
180                     WSSecurityEventConstants.AlgorithmSuite,
181                     WSSecurityEventConstants.X509Token,
182                     WSSecurityEventConstants.ENCRYPTED_PART,
183                     WSSecurityEventConstants.OPERATION,
184             };
185             final TestSecurityEventListener securityEventListener = new TestSecurityEventListener(expectedSecurityEvents);
186 
187             Document document = doInboundSecurity(securityProperties, xmlInputFactory.createXMLStreamReader(new ByteArrayInputStream(baos.toByteArray())), securityEventListener);
188 
189             //header element must still be there
190             NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedKey.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedKey.getLocalPart());
191             assertEquals(nodeList.getLength(), 1);
192             assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_WSSE_SECURITY.getLocalPart());
193 
194             //no encrypted content
195             nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedData.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedData.getLocalPart());
196             assertEquals(nodeList.getLength(), 0);
197 
198             securityEventListener.compare();
199 
200             List<SecurityEvent> receivedSecurityEvents = securityEventListener.getReceivedSecurityEvents();
201             for (int i = 0; i < receivedSecurityEvents.size(); i++) {
202                 SecurityEvent securityEvent = receivedSecurityEvents.get(i);
203                 if (securityEvent.getSecurityEventType() == WSSecurityEventConstants.OPERATION) {
204                     OperationSecurityEvent operationSecurityEvent = (OperationSecurityEvent) securityEvent;
205                     assertEquals(operationSecurityEvent.getOperation(), new QName("http://schemas.xmlsoap.org/wsdl/", "definitions"));
206                 } else if (securityEvent.getSecurityEventType() == WSSecurityEventConstants.ENCRYPTED_PART) {
207                     EncryptedPartSecurityEvent encryptedPartSecurityEvent = (EncryptedPartSecurityEvent) securityEvent;
208                     assertNotNull(encryptedPartSecurityEvent.getXmlSecEvent());
209                     assertNotNull(encryptedPartSecurityEvent.getSecurityToken());
210                     assertNotNull(encryptedPartSecurityEvent.getElementPath());
211                     final QName expectedElementName = new QName("http://schemas.xmlsoap.org/soap/envelope/", "Body");
212                     assertEquals(encryptedPartSecurityEvent.getXmlSecEvent().asStartElement().getName(), expectedElementName);
213                     assertEquals(encryptedPartSecurityEvent.getElementPath().size(), 2);
214                     assertEquals(encryptedPartSecurityEvent.getElementPath().get(encryptedPartSecurityEvent.getElementPath().size() - 1), expectedElementName);
215                 }
216             }
217 
218             EncryptedPartSecurityEvent encryptedPartSecurityEvent = securityEventListener.getSecurityEvent(WSSecurityEventConstants.ENCRYPTED_PART);
219             OperationSecurityEvent operationSecurityEvent = securityEventListener.getSecurityEvent(WSSecurityEventConstants.OPERATION);
220             String encryptedPartCorrelationID = encryptedPartSecurityEvent.getCorrelationID();
221             String operationCorrelationID = operationSecurityEvent.getCorrelationID();
222 
223             List<SecurityEvent> operationSecurityEvents = new ArrayList<>();
224             List<SecurityEvent> encryptedPartSecurityEvents = new ArrayList<>();
225 
226             List<SecurityEvent> securityEvents = securityEventListener.getReceivedSecurityEvents();
227             for (int i = 0; i < securityEvents.size(); i++) {
228                 SecurityEvent securityEvent = securityEvents.get(i);
229                 if (securityEvent.getCorrelationID().equals(encryptedPartCorrelationID)) {
230                     encryptedPartSecurityEvents.add(securityEvent);
231                 } else if (securityEvent.getCorrelationID().equals(operationCorrelationID)) {
232                     operationSecurityEvents.add(securityEvent);
233                 }
234             }
235 
236             assertEquals(4, encryptedPartSecurityEvents.size());
237             assertEquals(securityEventListener.getReceivedSecurityEvents().size(),
238                     operationSecurityEvents.size() + encryptedPartSecurityEvents.size());
239         }
240     }
241 
242     @Test
243     public void testEncDecryptionCryptoPropertiesOutbound() throws Exception {
244 
245         ByteArrayOutputStream baos;
246         {
247             WSSSecurityProperties securityProperties = new WSSSecurityProperties();
248             List<WSSConstants.Action> actions = new ArrayList<>();
249             actions.add(WSSConstants.ENCRYPTION);
250             securityProperties.setActions(actions);
251             Properties properties =
252                 CryptoFactory.getProperties("transmitter-crypto.properties", this.getClass().getClassLoader());
253             securityProperties.setEncryptionCryptoProperties(properties);
254             securityProperties.setEncryptionUser("receiver");
255 
256             InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
257             baos = doOutboundSecurity(securityProperties, sourceDocument);
258 
259             Document document = documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray()));
260             NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedKey.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedKey.getLocalPart());
261             assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_WSSE_SECURITY.getLocalPart());
262 
263             XPathExpression xPathExpression = getXPath("/soap:Envelope/soap:Header/wsse:Security/xenc:EncryptedKey/xenc:EncryptionMethod[@Algorithm='http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p']");
264             Node node = (Node) xPathExpression.evaluate(document, XPathConstants.NODE);
265             assertNotNull(node);
266 
267             nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_DataReference.getNamespaceURI(), WSSConstants.TAG_xenc_DataReference.getLocalPart());
268             assertEquals(nodeList.getLength(), 1);
269 
270             nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedData.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedData.getLocalPart());
271             assertEquals(nodeList.getLength(), 1);
272 
273             xPathExpression = getXPath("/soap:Envelope/soap:Body/xenc:EncryptedData/xenc:EncryptionMethod[@Algorithm='http://www.w3.org/2001/04/xmlenc#aes256-cbc']");
274             node = (Node) xPathExpression.evaluate(document, XPathConstants.NODE);
275             assertNotNull(node);
276 
277             assertEquals(node.getParentNode().getParentNode().getLocalName(), "Body");
278             NodeList childNodes = node.getParentNode().getParentNode().getChildNodes();
279             for (int i = 0; i < childNodes.getLength(); i++) {
280                 Node child = childNodes.item(i);
281                 if (child.getNodeType() == Node.TEXT_NODE) {
282                     assertEquals(child.getTextContent().trim(), "");
283                 } else if (child.getNodeType() == Node.ELEMENT_NODE) {
284                     assertEquals(child, nodeList.item(0));
285                 } else {
286                     fail("Unexpected Node encountered");
287                 }
288             }
289         }
290 
291         //done encryption; now test decryption:
292         {
293             String action = WSHandlerConstants.ENCRYPTION;
294             doInboundSecurityWithWSS4J(documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray())), action);
295         }
296     }
297 
298     @Test
299     public void testEncDecryptionCryptoPropertiesInbound() throws Exception {
300 
301         ByteArrayOutputStream baos = new ByteArrayOutputStream();
302 
303         {
304             InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
305             String action = WSHandlerConstants.ENCRYPTION;
306             Document securedDocument = doOutboundSecurityWithWSS4J(sourceDocument, action, new Properties());
307 
308             //some test that we can really sure we get what we want from WSS4J
309             XPathExpression xPathExpression = getXPath("/soap:Envelope/soap:Header/wsse:Security/xenc:EncryptedKey/xenc:EncryptionMethod[@Algorithm='http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p']");
310             Node node = (Node) xPathExpression.evaluate(securedDocument, XPathConstants.NODE);
311             assertNotNull(node);
312 
313             Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
314             transformer.transform(new DOMSource(securedDocument), new StreamResult(baos));
315         }
316         //test streaming decryption
317         {
318             WSSSecurityProperties securityProperties = new WSSSecurityProperties();
319             Properties properties =
320                 CryptoFactory.getProperties("receiver-crypto.properties", this.getClass().getClassLoader());
321             securityProperties.setDecryptionCryptoProperties(properties);
322             securityProperties.setCallbackHandler(new CallbackHandlerImpl());
323 
324             WSSecurityEventConstants.Event[] expectedSecurityEvents = new WSSecurityEventConstants.Event[]{
325                     WSSecurityEventConstants.AlgorithmSuite,
326                     WSSecurityEventConstants.AlgorithmSuite,
327                     WSSecurityEventConstants.X509Token,
328                     WSSecurityEventConstants.ENCRYPTED_PART,
329                     WSSecurityEventConstants.OPERATION,
330             };
331             final TestSecurityEventListener securityEventListener = new TestSecurityEventListener(expectedSecurityEvents);
332 
333             Document document = doInboundSecurity(securityProperties, xmlInputFactory.createXMLStreamReader(new ByteArrayInputStream(baos.toByteArray())), securityEventListener);
334 
335             //header element must still be there
336             NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedKey.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedKey.getLocalPart());
337             assertEquals(nodeList.getLength(), 1);
338             assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_WSSE_SECURITY.getLocalPart());
339 
340             //no encrypted content
341             nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedData.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedData.getLocalPart());
342             assertEquals(nodeList.getLength(), 0);
343 
344             securityEventListener.compare();
345 
346             List<SecurityEvent> receivedSecurityEvents = securityEventListener.getReceivedSecurityEvents();
347             for (int i = 0; i < receivedSecurityEvents.size(); i++) {
348                 SecurityEvent securityEvent = receivedSecurityEvents.get(i);
349                 if (securityEvent.getSecurityEventType() == WSSecurityEventConstants.OPERATION) {
350                     OperationSecurityEvent operationSecurityEvent = (OperationSecurityEvent) securityEvent;
351                     assertEquals(operationSecurityEvent.getOperation(), new QName("http://schemas.xmlsoap.org/wsdl/", "definitions"));
352                 } else if (securityEvent.getSecurityEventType() == WSSecurityEventConstants.ENCRYPTED_PART) {
353                     EncryptedPartSecurityEvent encryptedPartSecurityEvent = (EncryptedPartSecurityEvent) securityEvent;
354                     assertNotNull(encryptedPartSecurityEvent.getXmlSecEvent());
355                     assertNotNull(encryptedPartSecurityEvent.getSecurityToken());
356                     assertNotNull(encryptedPartSecurityEvent.getElementPath());
357                     final QName expectedElementName = new QName("http://schemas.xmlsoap.org/soap/envelope/", "Body");
358                     assertEquals(encryptedPartSecurityEvent.getXmlSecEvent().asStartElement().getName(), expectedElementName);
359                     assertEquals(encryptedPartSecurityEvent.getElementPath().size(), 2);
360                     assertEquals(encryptedPartSecurityEvent.getElementPath().get(encryptedPartSecurityEvent.getElementPath().size() - 1), expectedElementName);
361                 }
362             }
363 
364             EncryptedPartSecurityEvent encryptedPartSecurityEvent = securityEventListener.getSecurityEvent(WSSecurityEventConstants.ENCRYPTED_PART);
365             OperationSecurityEvent operationSecurityEvent = securityEventListener.getSecurityEvent(WSSecurityEventConstants.OPERATION);
366             String encryptedPartCorrelationID = encryptedPartSecurityEvent.getCorrelationID();
367             String operationCorrelationID = operationSecurityEvent.getCorrelationID();
368 
369             List<SecurityEvent> operationSecurityEvents = new ArrayList<>();
370             List<SecurityEvent> encryptedPartSecurityEvents = new ArrayList<>();
371 
372             List<SecurityEvent> securityEvents = securityEventListener.getReceivedSecurityEvents();
373             for (int i = 0; i < securityEvents.size(); i++) {
374                 SecurityEvent securityEvent = securityEvents.get(i);
375                 if (securityEvent.getCorrelationID().equals(encryptedPartCorrelationID)) {
376                     encryptedPartSecurityEvents.add(securityEvent);
377                 } else if (securityEvent.getCorrelationID().equals(operationCorrelationID)) {
378                     operationSecurityEvents.add(securityEvent);
379                 }
380             }
381 
382             assertEquals(4, encryptedPartSecurityEvents.size());
383             assertEquals(securityEventListener.getReceivedSecurityEvents().size(),
384                     operationSecurityEvents.size() + encryptedPartSecurityEvents.size());
385         }
386     }
387 
388     @Test
389     public void testEncDecryptionPartsContentOutbound() throws Exception {
390 
391         ByteArrayOutputStream baos;
392         {
393             WSSSecurityProperties securityProperties = new WSSSecurityProperties();
394             List<WSSConstants.Action> actions = new ArrayList<>();
395             actions.add(WSSConstants.ENCRYPTION);
396             securityProperties.setActions(actions);
397             securityProperties.loadEncryptionKeystore(this.getClass().getClassLoader().getResource("transmitter.jks"), "default".toCharArray());
398             securityProperties.setEncryptionUser("receiver");
399             securityProperties.addEncryptionPart(new SecurePart(new QName("http://www.w3.org/1999/XMLSchema", "complexType"), SecurePart.Modifier.Content));
400 
401             InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
402             baos = doOutboundSecurity(securityProperties, sourceDocument);
403 
404             Document document = documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray()));
405             NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedKey.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedKey.getLocalPart());
406             assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_WSSE_SECURITY.getLocalPart());
407 
408             nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_DataReference.getNamespaceURI(), WSSConstants.TAG_xenc_DataReference.getLocalPart());
409             assertEquals(nodeList.getLength(), 25);
410 
411             nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedData.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedData.getLocalPart());
412             assertEquals(nodeList.getLength(), 25);
413 
414             for (int i = 0; i < nodeList.getLength(); i++) {
415                 assertEquals(nodeList.item(i).getParentNode().getLocalName(), "complexType");
416                 assertEquals(nodeList.item(i).getParentNode().getNamespaceURI(), "http://www.w3.org/1999/XMLSchema");
417                 NodeList childNodes = nodeList.item(i).getParentNode().getChildNodes();
418                 for (int j = 0; j < childNodes.getLength(); j++) {
419                     Node child = childNodes.item(j);
420                     if (child.getNodeType() == Node.TEXT_NODE) {
421                         assertEquals(child.getTextContent().trim(), "");
422                     } else if (child.getNodeType() == Node.ELEMENT_NODE) {
423                         assertEquals(child, nodeList.item(i));
424                     } else {
425                         fail("Unexpected Node encountered");
426                     }
427                 }
428             }
429         }
430 
431         //done encryption; now test decryption:
432         {
433             String action = WSHandlerConstants.ENCRYPTION;
434             doInboundSecurityWithWSS4J(documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray())), action);
435         }
436     }
437 
438     @Test
439     public void testEncDecryptionPartsContentInbound() throws Exception {
440 
441         ByteArrayOutputStream baos = new ByteArrayOutputStream();
442 
443         {
444             InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
445             String action = WSHandlerConstants.ENCRYPTION;
446             Properties properties = new Properties();
447             properties.setProperty(WSHandlerConstants.ENCRYPTION_PARTS, "{Content}{http://www.w3.org/1999/XMLSchema}simpleType;");
448             Document securedDocument = doOutboundSecurityWithWSS4J(sourceDocument, action, properties);
449 
450             //some test that we can really sure we get what we want from WSS4J
451             NodeList nodeList = securedDocument.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedKey.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedKey.getLocalPart());
452             assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_WSSE_SECURITY.getLocalPart());
453 
454             Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
455             transformer.transform(new DOMSource(securedDocument), new StreamResult(baos));
456         }
457         //test streaming decryption
458         {
459             WSSSecurityProperties securityProperties = new WSSSecurityProperties();
460             securityProperties.loadDecryptionKeystore(this.getClass().getClassLoader().getResource("receiver.jks"), "default".toCharArray());
461             securityProperties.setCallbackHandler(new CallbackHandlerImpl());
462 
463             WSSecurityEventConstants.Event[] expectedSecurityEvents = new WSSecurityEventConstants.Event[]{
464                     WSSecurityEventConstants.X509Token,
465                     WSSecurityEventConstants.OPERATION,
466                     WSSecurityEventConstants.X509Token,
467                     WSSecurityEventConstants.ContentEncrypted,
468                     WSSecurityEventConstants.AlgorithmSuite,
469                     WSSecurityEventConstants.AlgorithmSuite,
470                     WSSecurityEventConstants.EncryptedKeyToken,
471                     WSSecurityEventConstants.ContentEncrypted,
472                     WSSecurityEventConstants.AlgorithmSuite,
473                     WSSecurityEventConstants.EncryptedKeyToken,
474                     WSSecurityEventConstants.ContentEncrypted,
475                     WSSecurityEventConstants.AlgorithmSuite,
476                     WSSecurityEventConstants.EncryptedKeyToken,
477                     WSSecurityEventConstants.ContentEncrypted,
478                     WSSecurityEventConstants.AlgorithmSuite,
479                     WSSecurityEventConstants.EncryptedKeyToken,
480                     WSSecurityEventConstants.ContentEncrypted,
481                     WSSecurityEventConstants.AlgorithmSuite,
482                     WSSecurityEventConstants.EncryptedKeyToken,
483                     WSSecurityEventConstants.ContentEncrypted,
484                     WSSecurityEventConstants.AlgorithmSuite,
485                     WSSecurityEventConstants.EncryptedKeyToken,
486                     WSSecurityEventConstants.ContentEncrypted,
487                     WSSecurityEventConstants.AlgorithmSuite,
488                     WSSecurityEventConstants.EncryptedKeyToken,
489                     WSSecurityEventConstants.ContentEncrypted,
490                     WSSecurityEventConstants.AlgorithmSuite,
491                     WSSecurityEventConstants.EncryptedKeyToken,
492                     WSSecurityEventConstants.ContentEncrypted,
493                     WSSecurityEventConstants.AlgorithmSuite,
494                     WSSecurityEventConstants.EncryptedKeyToken,
495                     WSSecurityEventConstants.ContentEncrypted,
496                     WSSecurityEventConstants.AlgorithmSuite,
497                     WSSecurityEventConstants.EncryptedKeyToken,
498                     WSSecurityEventConstants.ContentEncrypted,
499                     WSSecurityEventConstants.AlgorithmSuite,
500                     WSSecurityEventConstants.EncryptedKeyToken,
501                     WSSecurityEventConstants.ContentEncrypted,
502                     WSSecurityEventConstants.AlgorithmSuite,
503                     WSSecurityEventConstants.EncryptedKeyToken,
504                     WSSecurityEventConstants.ContentEncrypted,
505                     WSSecurityEventConstants.AlgorithmSuite,
506                     WSSecurityEventConstants.EncryptedKeyToken,
507                     WSSecurityEventConstants.ContentEncrypted,
508                     WSSecurityEventConstants.AlgorithmSuite,
509                     WSSecurityEventConstants.EncryptedKeyToken,
510                     WSSecurityEventConstants.ContentEncrypted,
511                     WSSecurityEventConstants.AlgorithmSuite,
512                     WSSecurityEventConstants.EncryptedKeyToken,
513                     WSSecurityEventConstants.ContentEncrypted,
514                     WSSecurityEventConstants.AlgorithmSuite,
515                     WSSecurityEventConstants.EncryptedKeyToken,
516                     WSSecurityEventConstants.ContentEncrypted,
517                     WSSecurityEventConstants.AlgorithmSuite,
518             };
519             final TestSecurityEventListener securityEventListener = new TestSecurityEventListener(expectedSecurityEvents);
520 
521             Document document = doInboundSecurity(securityProperties, xmlInputFactory.createXMLStreamReader(new ByteArrayInputStream(baos.toByteArray())), securityEventListener);
522 
523             //header element must still be there
524             NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedKey.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedKey.getLocalPart());
525             assertEquals(nodeList.getLength(), 1);
526             assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_WSSE_SECURITY.getLocalPart());
527 
528             //no encrypted content
529             nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedData.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedData.getLocalPart());
530             assertEquals(nodeList.getLength(), 0);
531 
532             securityEventListener.compare();
533 
534             List<SecurityEvent> receivedSecurityEvents = securityEventListener.getReceivedSecurityEvents();
535             for (int i = 0; i < receivedSecurityEvents.size(); i++) {
536                 SecurityEvent securityEvent = receivedSecurityEvents.get(i);
537                 if (securityEvent.getSecurityEventType() == WSSecurityEventConstants.OPERATION) {
538                     OperationSecurityEvent operationSecurityEvent = (OperationSecurityEvent) securityEvent;
539                     assertEquals(operationSecurityEvent.getOperation(), new QName("http://schemas.xmlsoap.org/wsdl/", "definitions"));
540                 } else if (securityEvent.getSecurityEventType() == WSSecurityEventConstants.ContentEncrypted) {
541                     ContentEncryptedElementSecurityEvent contentEncryptedElementSecurityEvent = (ContentEncryptedElementSecurityEvent) securityEvent;
542                     assertNotNull(contentEncryptedElementSecurityEvent.getXmlSecEvent());
543                     assertNotNull(contentEncryptedElementSecurityEvent.getSecurityToken());
544                     assertNotNull(contentEncryptedElementSecurityEvent.getElementPath());
545                     final QName expectedElementName = new QName("http://www.w3.org/1999/XMLSchema", "simpleType");
546                     assertEquals(contentEncryptedElementSecurityEvent.getXmlSecEvent().asStartElement().getName(), expectedElementName);
547                     assertEquals(contentEncryptedElementSecurityEvent.getElementPath().size(), 6);
548                     assertEquals(contentEncryptedElementSecurityEvent.getElementPath().get(contentEncryptedElementSecurityEvent.getElementPath().size() - 1), expectedElementName);
549                 }
550             }
551 
552             List<ContentEncryptedElementSecurityEvent> contentEncryptedElementSecurityEventList = securityEventListener.getSecurityEvents(SecurityEventConstants.ContentEncrypted);
553             OperationSecurityEvent operationSecurityEvent = securityEventListener.getSecurityEvent(WSSecurityEventConstants.OPERATION);
554             String encryptedPartCorrelationID1 = contentEncryptedElementSecurityEventList.get(0).getCorrelationID();
555             String encryptedPartCorrelationID2 = contentEncryptedElementSecurityEventList.get(1).getCorrelationID();
556             String encryptedPartCorrelationID3 = contentEncryptedElementSecurityEventList.get(2).getCorrelationID();
557             String encryptedPartCorrelationID4 = contentEncryptedElementSecurityEventList.get(3).getCorrelationID();
558             String encryptedPartCorrelationID5 = contentEncryptedElementSecurityEventList.get(4).getCorrelationID();
559             String encryptedPartCorrelationID6 = contentEncryptedElementSecurityEventList.get(5).getCorrelationID();
560             String encryptedPartCorrelationID7 = contentEncryptedElementSecurityEventList.get(6).getCorrelationID();
561             String encryptedPartCorrelationID8 = contentEncryptedElementSecurityEventList.get(7).getCorrelationID();
562             String encryptedPartCorrelationID9 = contentEncryptedElementSecurityEventList.get(8).getCorrelationID();
563             String encryptedPartCorrelationID10 = contentEncryptedElementSecurityEventList.get(9).getCorrelationID();
564             String encryptedPartCorrelationID11 = contentEncryptedElementSecurityEventList.get(10).getCorrelationID();
565             String encryptedPartCorrelationID12 = contentEncryptedElementSecurityEventList.get(11).getCorrelationID();
566             String encryptedPartCorrelationID13 = contentEncryptedElementSecurityEventList.get(12).getCorrelationID();
567             String encryptedPartCorrelationID14 = contentEncryptedElementSecurityEventList.get(13).getCorrelationID();
568             String encryptedPartCorrelationID15 = contentEncryptedElementSecurityEventList.get(14).getCorrelationID();
569             String encryptedPartCorrelationID16 = contentEncryptedElementSecurityEventList.get(15).getCorrelationID();
570             String encryptedPartCorrelationID17 = contentEncryptedElementSecurityEventList.get(16).getCorrelationID();
571             String operationCorrelationID = operationSecurityEvent.getCorrelationID();
572 
573             List<SecurityEvent> operationSecurityEvents = new ArrayList<>();
574             List<SecurityEvent> encryptedPartSecurityEvents1 = new ArrayList<>();
575             List<SecurityEvent> encryptedPartSecurityEvents2 = new ArrayList<>();
576             List<SecurityEvent> encryptedPartSecurityEvents3 = new ArrayList<>();
577             List<SecurityEvent> encryptedPartSecurityEvents4 = new ArrayList<>();
578             List<SecurityEvent> encryptedPartSecurityEvents5 = new ArrayList<>();
579             List<SecurityEvent> encryptedPartSecurityEvents6 = new ArrayList<>();
580             List<SecurityEvent> encryptedPartSecurityEvents7 = new ArrayList<>();
581             List<SecurityEvent> encryptedPartSecurityEvents8 = new ArrayList<>();
582             List<SecurityEvent> encryptedPartSecurityEvents9 = new ArrayList<>();
583             List<SecurityEvent> encryptedPartSecurityEvents10 = new ArrayList<>();
584             List<SecurityEvent> encryptedPartSecurityEvents11 = new ArrayList<>();
585             List<SecurityEvent> encryptedPartSecurityEvents12 = new ArrayList<>();
586             List<SecurityEvent> encryptedPartSecurityEvents13 = new ArrayList<>();
587             List<SecurityEvent> encryptedPartSecurityEvents14 = new ArrayList<>();
588             List<SecurityEvent> encryptedPartSecurityEvents15 = new ArrayList<>();
589             List<SecurityEvent> encryptedPartSecurityEvents16 = new ArrayList<>();
590             List<SecurityEvent> encryptedPartSecurityEvents17 = new ArrayList<>();
591 
592             List<SecurityEvent> securityEvents = securityEventListener.getReceivedSecurityEvents();
593             for (int i = 0; i < securityEvents.size(); i++) {
594                 SecurityEvent securityEvent = securityEvents.get(i);
595                 if (securityEvent.getCorrelationID().equals(operationCorrelationID)) {
596                     operationSecurityEvents.add(securityEvent);
597                 } else if (securityEvent.getCorrelationID().equals(encryptedPartCorrelationID1)) {
598                     encryptedPartSecurityEvents1.add(securityEvent);
599                 } else if (securityEvent.getCorrelationID().equals(encryptedPartCorrelationID2)) {
600                     encryptedPartSecurityEvents2.add(securityEvent);
601                 } else if (securityEvent.getCorrelationID().equals(encryptedPartCorrelationID3)) {
602                     encryptedPartSecurityEvents3.add(securityEvent);
603                 } else if (securityEvent.getCorrelationID().equals(encryptedPartCorrelationID4)) {
604                     encryptedPartSecurityEvents4.add(securityEvent);
605                 } else if (securityEvent.getCorrelationID().equals(encryptedPartCorrelationID5)) {
606                     encryptedPartSecurityEvents5.add(securityEvent);
607                 } else if (securityEvent.getCorrelationID().equals(encryptedPartCorrelationID6)) {
608                     encryptedPartSecurityEvents6.add(securityEvent);
609                 } else if (securityEvent.getCorrelationID().equals(encryptedPartCorrelationID7)) {
610                     encryptedPartSecurityEvents7.add(securityEvent);
611                 } else if (securityEvent.getCorrelationID().equals(encryptedPartCorrelationID8)) {
612                     encryptedPartSecurityEvents8.add(securityEvent);
613                 } else if (securityEvent.getCorrelationID().equals(encryptedPartCorrelationID9)) {
614                     encryptedPartSecurityEvents9.add(securityEvent);
615                 } else if (securityEvent.getCorrelationID().equals(encryptedPartCorrelationID10)) {
616                     encryptedPartSecurityEvents10.add(securityEvent);
617                 } else if (securityEvent.getCorrelationID().equals(encryptedPartCorrelationID11)) {
618                     encryptedPartSecurityEvents11.add(securityEvent);
619                 } else if (securityEvent.getCorrelationID().equals(encryptedPartCorrelationID12)) {
620                     encryptedPartSecurityEvents12.add(securityEvent);
621                 } else if (securityEvent.getCorrelationID().equals(encryptedPartCorrelationID13)) {
622                     encryptedPartSecurityEvents13.add(securityEvent);
623                 } else if (securityEvent.getCorrelationID().equals(encryptedPartCorrelationID14)) {
624                     encryptedPartSecurityEvents14.add(securityEvent);
625                 } else if (securityEvent.getCorrelationID().equals(encryptedPartCorrelationID15)) {
626                     encryptedPartSecurityEvents15.add(securityEvent);
627                 } else if (securityEvent.getCorrelationID().equals(encryptedPartCorrelationID16)) {
628                     encryptedPartSecurityEvents16.add(securityEvent);
629                 } else if (securityEvent.getCorrelationID().equals(encryptedPartCorrelationID17)) {
630                     encryptedPartSecurityEvents17.add(securityEvent);
631                 }
632             }
633 
634             assertEquals(4, encryptedPartSecurityEvents1.size());
635             assertEquals(3, encryptedPartSecurityEvents2.size());
636             assertEquals(3, encryptedPartSecurityEvents3.size());
637             assertEquals(3, encryptedPartSecurityEvents4.size());
638             assertEquals(3, encryptedPartSecurityEvents5.size());
639             assertEquals(3, encryptedPartSecurityEvents6.size());
640             assertEquals(3, encryptedPartSecurityEvents7.size());
641             assertEquals(3, encryptedPartSecurityEvents8.size());
642             assertEquals(3, encryptedPartSecurityEvents9.size());
643             assertEquals(3, encryptedPartSecurityEvents10.size());
644             assertEquals(3, encryptedPartSecurityEvents11.size());
645             assertEquals(3, encryptedPartSecurityEvents12.size());
646             assertEquals(3, encryptedPartSecurityEvents13.size());
647             assertEquals(3, encryptedPartSecurityEvents14.size());
648             assertEquals(3, encryptedPartSecurityEvents15.size());
649             assertEquals(3, encryptedPartSecurityEvents16.size());
650             assertEquals(3, encryptedPartSecurityEvents17.size());
651             assertEquals(securityEventListener.getReceivedSecurityEvents().size(),
652                     operationSecurityEvents.size() +
653                     encryptedPartSecurityEvents1.size() +
654                     encryptedPartSecurityEvents2.size() +
655                     encryptedPartSecurityEvents3.size() +
656                     encryptedPartSecurityEvents4.size() +
657                     encryptedPartSecurityEvents5.size() +
658                     encryptedPartSecurityEvents6.size() +
659                     encryptedPartSecurityEvents7.size() +
660                     encryptedPartSecurityEvents8.size() +
661                     encryptedPartSecurityEvents9.size() +
662                     encryptedPartSecurityEvents10.size() +
663                     encryptedPartSecurityEvents11.size() +
664                     encryptedPartSecurityEvents12.size() +
665                     encryptedPartSecurityEvents13.size() +
666                     encryptedPartSecurityEvents14.size() +
667                     encryptedPartSecurityEvents15.size() +
668                     encryptedPartSecurityEvents16.size() +
669                     encryptedPartSecurityEvents17.size() + 1 //plus one because of the
670                     // X509TokenEvent which can't be correlated that easy for this use case
671             );
672         }
673     }
674 
675     @Test
676     public void testEncDecryptionPartsElementOutbound() throws Exception {
677 
678         ByteArrayOutputStream baos;
679         {
680             WSSSecurityProperties securityProperties = new WSSSecurityProperties();
681             List<WSSConstants.Action> actions = new ArrayList<>();
682             actions.add(WSSConstants.ENCRYPTION);
683             securityProperties.setActions(actions);
684             securityProperties.loadEncryptionKeystore(this.getClass().getClassLoader().getResource("transmitter.jks"), "default".toCharArray());
685             securityProperties.setEncryptionUser("receiver");
686             securityProperties.addEncryptionPart(new SecurePart(new QName("http://www.w3.org/1999/XMLSchema", "complexType"), SecurePart.Modifier.Element));
687 
688             InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
689 
690             baos = doOutboundSecurity(securityProperties, sourceDocument);
691 
692             Document document = documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray()));
693             NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedKey.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedKey.getLocalPart());
694             assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_WSSE_SECURITY.getLocalPart());
695 
696             nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedData.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedData.getLocalPart());
697             assertEquals(nodeList.getLength(), 25);
698 
699             nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_DataReference.getNamespaceURI(), WSSConstants.TAG_xenc_DataReference.getLocalPart());
700             assertEquals(nodeList.getLength(), 25);
701 
702             nodeList = document.getElementsByTagNameNS("http://www.w3.org/1999/XMLSchema", "complexType");
703             assertEquals(nodeList.getLength(), 0);
704         }
705 
706         //done encryption; now test decryption:
707         {
708             String action = WSHandlerConstants.ENCRYPTION;
709             doInboundSecurityWithWSS4J(documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray())), action);
710         }
711     }
712 
713     @Test
714     public void testEncDecryptionPartsHeaderOutbound() throws Exception {
715 
716         ByteArrayOutputStream baos;
717         {
718             WSSSecurityProperties securityProperties = new WSSSecurityProperties();
719             List<WSSConstants.Action> actions = new ArrayList<>();
720             actions.add(WSSConstants.ENCRYPTION);
721             securityProperties.setActions(actions);
722             securityProperties.loadEncryptionKeystore(this.getClass().getClassLoader().getResource("transmitter.jks"), "default".toCharArray());
723             securityProperties.setEncryptionUser("receiver");
724             securityProperties.addEncryptionPart(new SecurePart(new QName("http://www.w3.org/1999/XMLSchema", "complexType"), SecurePart.Modifier.Element));
725             securityProperties.addEncryptionPart(new SecurePart(new QName("http://www.example.com", "testEncryptedHeader"), SecurePart.Modifier.Element));
726 
727             InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-encryptedHeader.xml");
728 
729             baos = doOutboundSecurity(securityProperties, sourceDocument);
730 
731             Document document = documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray()));
732             NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedKey.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedKey.getLocalPart());
733             assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_WSSE_SECURITY.getLocalPart());
734 
735             nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedData.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedData.getLocalPart());
736             assertEquals(nodeList.getLength(), 27);
737 
738             nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_DataReference.getNamespaceURI(), WSSConstants.TAG_xenc_DataReference.getLocalPart());
739             assertEquals(nodeList.getLength(), 26);
740 
741             nodeList = document.getElementsByTagNameNS("http://www.w3.org/1999/XMLSchema", "complexType");
742             assertEquals(nodeList.getLength(), 0);
743         }
744 
745         //done encryption; now test decryption:
746         {
747             String action = WSHandlerConstants.ENCRYPTION;
748             doInboundSecurityWithWSS4J(documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray())), action);
749         }
750     }
751 
752     @Test
753     public void testEncDecryptionPartsElementInbound() throws Exception {
754 
755         ByteArrayOutputStream baos = new ByteArrayOutputStream();
756         {
757             InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
758             String action = WSHandlerConstants.ENCRYPTION;
759             Properties properties = new Properties();
760 
761             properties.setProperty(WSHandlerConstants.ENCRYPTION_PARTS, "{Element}{http://www.w3.org/1999/XMLSchema}simpleType;");
762             Document securedDocument = doOutboundSecurityWithWSS4J(sourceDocument, action, properties);
763 
764             //some test that we can really sure we get what we want from WSS4J
765             NodeList nodeList = securedDocument.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedKey.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedKey.getLocalPart());
766             assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_WSSE_SECURITY.getLocalPart());
767 
768             Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
769             transformer.transform(new DOMSource(securedDocument), new StreamResult(baos));
770         }
771 
772         //done encryption; now test decryption:
773         {
774             WSSSecurityProperties securityProperties = new WSSSecurityProperties();
775             securityProperties.loadDecryptionKeystore(this.getClass().getClassLoader().getResource("receiver.jks"), "default".toCharArray());
776             securityProperties.setCallbackHandler(new CallbackHandlerImpl());
777 
778             WSSecurityEventConstants.Event[] expectedSecurityEvents = new WSSecurityEventConstants.Event[]{
779                     WSSecurityEventConstants.X509Token,
780                     WSSecurityEventConstants.OPERATION,
781                     WSSecurityEventConstants.X509Token,
782                     WSSecurityEventConstants.AlgorithmSuite,
783                     WSSecurityEventConstants.AlgorithmSuite,
784                     WSSecurityEventConstants.EncryptedElement,
785                     WSSecurityEventConstants.EncryptedKeyToken,
786                     WSSecurityEventConstants.AlgorithmSuite,
787                     WSSecurityEventConstants.EncryptedElement,
788                     WSSecurityEventConstants.EncryptedKeyToken,
789                     WSSecurityEventConstants.AlgorithmSuite,
790                     WSSecurityEventConstants.EncryptedElement,
791                     WSSecurityEventConstants.EncryptedKeyToken,
792                     WSSecurityEventConstants.AlgorithmSuite,
793                     WSSecurityEventConstants.EncryptedElement,
794                     WSSecurityEventConstants.EncryptedKeyToken,
795                     WSSecurityEventConstants.AlgorithmSuite,
796                     WSSecurityEventConstants.EncryptedElement,
797                     WSSecurityEventConstants.EncryptedKeyToken,
798                     WSSecurityEventConstants.AlgorithmSuite,
799                     WSSecurityEventConstants.EncryptedElement,
800                     WSSecurityEventConstants.EncryptedKeyToken,
801                     WSSecurityEventConstants.AlgorithmSuite,
802                     WSSecurityEventConstants.EncryptedElement,
803                     WSSecurityEventConstants.EncryptedKeyToken,
804                     WSSecurityEventConstants.AlgorithmSuite,
805                     WSSecurityEventConstants.EncryptedElement,
806                     WSSecurityEventConstants.EncryptedKeyToken,
807                     WSSecurityEventConstants.AlgorithmSuite,
808                     WSSecurityEventConstants.EncryptedElement,
809                     WSSecurityEventConstants.EncryptedKeyToken,
810                     WSSecurityEventConstants.AlgorithmSuite,
811                     WSSecurityEventConstants.EncryptedElement,
812                     WSSecurityEventConstants.EncryptedKeyToken,
813                     WSSecurityEventConstants.AlgorithmSuite,
814                     WSSecurityEventConstants.EncryptedElement,
815                     WSSecurityEventConstants.EncryptedKeyToken,
816                     WSSecurityEventConstants.AlgorithmSuite,
817                     WSSecurityEventConstants.EncryptedElement,
818                     WSSecurityEventConstants.EncryptedKeyToken,
819                     WSSecurityEventConstants.AlgorithmSuite,
820                     WSSecurityEventConstants.EncryptedElement,
821                     WSSecurityEventConstants.EncryptedKeyToken,
822                     WSSecurityEventConstants.AlgorithmSuite,
823                     WSSecurityEventConstants.EncryptedElement,
824                     WSSecurityEventConstants.EncryptedKeyToken,
825                     WSSecurityEventConstants.AlgorithmSuite,
826                     WSSecurityEventConstants.EncryptedElement,
827                     WSSecurityEventConstants.EncryptedKeyToken,
828                     WSSecurityEventConstants.AlgorithmSuite,
829                     WSSecurityEventConstants.EncryptedElement,
830                     WSSecurityEventConstants.EncryptedKeyToken,
831                     WSSecurityEventConstants.AlgorithmSuite,
832                     WSSecurityEventConstants.EncryptedElement,
833             };
834             final TestSecurityEventListener securityEventListener = new TestSecurityEventListener(expectedSecurityEvents);
835 
836             Document document = doInboundSecurity(securityProperties, xmlInputFactory.createXMLStreamReader(new ByteArrayInputStream(baos.toByteArray())), securityEventListener);
837 
838             //header element must still be there
839             NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedKey.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedKey.getLocalPart());
840             assertEquals(nodeList.getLength(), 1);
841             assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_WSSE_SECURITY.getLocalPart());
842 
843             //no encrypted content
844             nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedData.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedData.getLocalPart());
845             assertEquals(nodeList.getLength(), 0);
846 
847             securityEventListener.compare();
848 
849             List<SecurityEvent> receivedSecurityEvents = securityEventListener.getReceivedSecurityEvents();
850             for (int i = 0; i < receivedSecurityEvents.size(); i++) {
851                 SecurityEvent securityEvent = receivedSecurityEvents.get(i);
852                 if (securityEvent.getSecurityEventType() == WSSecurityEventConstants.OPERATION) {
853                     OperationSecurityEvent operationSecurityEvent = (OperationSecurityEvent) securityEvent;
854                     assertEquals(operationSecurityEvent.getOperation(), new QName("http://schemas.xmlsoap.org/wsdl/", "definitions"));
855                 } else if (securityEvent.getSecurityEventType() == WSSecurityEventConstants.EncryptedElement) {
856                     EncryptedElementSecurityEvent encryptedElementSecurityEvent = (EncryptedElementSecurityEvent) securityEvent;
857                     assertNotNull(encryptedElementSecurityEvent.getXmlSecEvent());
858                     assertNotNull(encryptedElementSecurityEvent.getSecurityToken());
859                     assertNotNull(encryptedElementSecurityEvent.getElementPath());
860                     final QName expectedElementName = new QName("http://www.w3.org/1999/XMLSchema", "simpleType");
861                     assertEquals(encryptedElementSecurityEvent.getXmlSecEvent().asStartElement().getName(), expectedElementName);
862                     assertEquals(encryptedElementSecurityEvent.getElementPath().size(), 6);
863                     assertEquals(encryptedElementSecurityEvent.getElementPath().get(encryptedElementSecurityEvent.getElementPath().size() - 1), expectedElementName);
864                 }
865             }
866         }
867     }
868 
869     @Test
870     public void testEncDecryptionPartsHeaderInbound() throws Exception {
871 
872         ByteArrayOutputStream baos = new ByteArrayOutputStream();
873         {
874             InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-encryptedHeader.xml");
875             String action = WSHandlerConstants.ENCRYPTION;
876             Properties properties = new Properties();
877 
878             properties.setProperty(WSHandlerConstants.ENCRYPTION_PARTS, "{Header}{http://www.example.com}testEncryptedHeader;");
879             Document securedDocument = doOutboundSecurityWithWSS4J(sourceDocument, action, properties);
880 
881             //some test that we can really sure we get what we want from WSS4J
882             NodeList nodeList = securedDocument.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedKey.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedKey.getLocalPart());
883             assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_WSSE_SECURITY.getLocalPart());
884 
885             Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
886             transformer.transform(new DOMSource(securedDocument), new StreamResult(baos));
887         }
888 
889         //done encryption; now test decryption:
890         {
891             WSSSecurityProperties securityProperties = new WSSSecurityProperties();
892             securityProperties.loadDecryptionKeystore(this.getClass().getClassLoader().getResource("receiver.jks"), "default".toCharArray());
893             securityProperties.setCallbackHandler(new CallbackHandlerImpl());
894 
895             WSSecurityEventConstants.Event[] expectedSecurityEvents = new WSSecurityEventConstants.Event[]{
896                     WSSecurityEventConstants.AlgorithmSuite,
897                     WSSecurityEventConstants.AlgorithmSuite,
898                     WSSecurityEventConstants.X509Token,
899                     WSSecurityEventConstants.ENCRYPTED_PART,
900                     WSSecurityEventConstants.OPERATION,
901             };
902             final TestSecurityEventListener securityEventListener = new TestSecurityEventListener(expectedSecurityEvents);
903 
904             Document document = doInboundSecurity(securityProperties, xmlInputFactory.createXMLStreamReader(new ByteArrayInputStream(baos.toByteArray())), securityEventListener);
905 
906             //header element must still be there
907             NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedKey.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedKey.getLocalPart());
908             assertEquals(nodeList.getLength(), 1);
909             assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_WSSE_SECURITY.getLocalPart());
910 
911             //no encrypted content
912             nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_wsse11_EncryptedHeader.getNamespaceURI(), WSSConstants.TAG_wsse11_EncryptedHeader.getLocalPart());
913             assertEquals(nodeList.getLength(), 1);
914 
915             securityEventListener.compare();
916 
917             List<SecurityEvent> receivedSecurityEvents = securityEventListener.getReceivedSecurityEvents();
918             for (int i = 0; i < receivedSecurityEvents.size(); i++) {
919                 SecurityEvent securityEvent = receivedSecurityEvents.get(i);
920                 if (securityEvent.getSecurityEventType() == WSSecurityEventConstants.OPERATION) {
921                     OperationSecurityEvent operationSecurityEvent = (OperationSecurityEvent) securityEvent;
922                     assertEquals(operationSecurityEvent.getOperation(), new QName("http://schemas.xmlsoap.org/wsdl/", "definitions"));
923                 } else if (securityEvent.getSecurityEventType() == WSSecurityEventConstants.ENCRYPTED_PART) {
924                     EncryptedPartSecurityEvent encryptedPartSecurityEvent = (EncryptedPartSecurityEvent) securityEvent;
925                     assertNotNull(encryptedPartSecurityEvent.getXmlSecEvent());
926                     assertNotNull(encryptedPartSecurityEvent.getSecurityToken());
927                     assertNotNull(encryptedPartSecurityEvent.getElementPath());
928                     final QName expectedElementName = new QName("http://www.example.com", "testEncryptedHeader");
929                     assertEquals(encryptedPartSecurityEvent.getXmlSecEvent().asStartElement().getName(), expectedElementName);
930                     assertEquals(encryptedPartSecurityEvent.getElementPath().size(), 3);
931                     assertEquals(encryptedPartSecurityEvent.getElementPath().get(encryptedPartSecurityEvent.getElementPath().size() - 1), expectedElementName);
932                 }
933             }
934 
935             EncryptedPartSecurityEvent encryptedPartSecurityEvent = securityEventListener.getSecurityEvent(WSSecurityEventConstants.ENCRYPTED_PART);
936             OperationSecurityEvent operationSecurityEvent = securityEventListener.getSecurityEvent(WSSecurityEventConstants.OPERATION);
937             String encryptedPartCorrelationID = encryptedPartSecurityEvent.getCorrelationID();
938             String operationCorrelationID = operationSecurityEvent.getCorrelationID();
939 
940             List<SecurityEvent> operationSecurityEvents = new ArrayList<>();
941             List<SecurityEvent> encryptedPartSecurityEvents = new ArrayList<>();
942 
943             List<SecurityEvent> securityEvents = securityEventListener.getReceivedSecurityEvents();
944             for (int i = 0; i < securityEvents.size(); i++) {
945                 SecurityEvent securityEvent = securityEvents.get(i);
946                 if (securityEvent.getCorrelationID().equals(encryptedPartCorrelationID)) {
947                     encryptedPartSecurityEvents.add(securityEvent);
948                 } else if (securityEvent.getCorrelationID().equals(operationCorrelationID)) {
949                     operationSecurityEvents.add(securityEvent);
950                 }
951             }
952 
953             assertEquals(4, encryptedPartSecurityEvents.size());
954             assertEquals(securityEventListener.getReceivedSecurityEvents().size(),
955                     operationSecurityEvents.size() + encryptedPartSecurityEvents.size());
956         }
957     }
958 
959     @Test
960     public void testExceptionOnElementToEncryptNotFound() throws Exception {
961 
962         {
963             WSSSecurityProperties securityProperties = new WSSSecurityProperties();
964             List<WSSConstants.Action> actions = new ArrayList<>();
965             actions.add(WSSConstants.ENCRYPTION);
966             securityProperties.setActions(actions);
967             securityProperties.loadEncryptionKeystore(this.getClass().getClassLoader().getResource("transmitter.jks"), "default".toCharArray());
968             securityProperties.setEncryptionUser("receiver");
969             securityProperties.addEncryptionPart(new SecurePart(new QName("http://www.wrongnamespace.org", "complexType"), SecurePart.Modifier.Content));
970 
971             InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
972             try {
973                 doOutboundSecurity(securityProperties, sourceDocument);
974                 fail("Exception expected");
975             } catch (XMLStreamException e) {
976                 assertTrue(e.getCause() instanceof XMLSecurityException);
977                 assertEquals("Part to encrypt not found: {http://www.wrongnamespace.org}complexType", e.getCause().getMessage());
978             }
979         }
980     }
981 
982     @Test
983     public void testEncDecryptionUseThisCert() throws Exception {
984 
985         ByteArrayOutputStream baos;
986         {
987             WSSSecurityProperties securityProperties = new WSSSecurityProperties();
988             List<WSSConstants.Action> actions = new ArrayList<>();
989             actions.add(WSSConstants.ENCRYPTION);
990             securityProperties.setActions(actions);
991 
992             KeyStore keyStore = KeyStore.getInstance("jks");
993             keyStore.load(this.getClass().getClassLoader().getResourceAsStream("transmitter.jks"), "default".toCharArray());
994             securityProperties.setEncryptionUseThisCertificate((X509Certificate) keyStore.getCertificate("receiver"));
995 
996             InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
997 
998             baos = doOutboundSecurity(securityProperties, sourceDocument);
999 
1000             Document document = documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray()));
1001             NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedKey.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedKey.getLocalPart());
1002             assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_WSSE_SECURITY.getLocalPart());
1003 
1004             nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_DataReference.getNamespaceURI(), WSSConstants.TAG_xenc_DataReference.getLocalPart());
1005             assertEquals(nodeList.getLength(), 1);
1006 
1007             nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedData.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedData.getLocalPart());
1008             assertEquals(nodeList.getLength(), 1);
1009 
1010             assertEquals(nodeList.item(0).getParentNode().getLocalName(), "Body");
1011             NodeList childNodes = nodeList.item(0).getParentNode().getChildNodes();
1012             for (int i = 0; i < childNodes.getLength(); i++) {
1013                 Node child = childNodes.item(i);
1014                 if (child.getNodeType() == Node.TEXT_NODE) {
1015                     assertEquals(child.getTextContent().trim(), "");
1016                 } else if (child.getNodeType() == Node.ELEMENT_NODE) {
1017                     assertEquals(child, nodeList.item(0));
1018                 } else {
1019                     fail("Unexpected Node encountered");
1020                 }
1021             }
1022         }
1023 
1024         //done encryption; now test decryption:
1025         {
1026             WSSSecurityProperties securityProperties = new WSSSecurityProperties();
1027             securityProperties.loadDecryptionKeystore(this.getClass().getClassLoader().getResource("receiver.jks"), "default".toCharArray());
1028             securityProperties.setCallbackHandler(new CallbackHandlerImpl());
1029             Document document = doInboundSecurity(securityProperties, new ByteArrayInputStream(baos.toByteArray()));
1030 
1031             //header element must still be there
1032             NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedKey.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedKey.getLocalPart());
1033             assertEquals(nodeList.getLength(), 1);
1034             assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_WSSE_SECURITY.getLocalPart());
1035 
1036             //no encrypted content
1037             nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedData.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedData.getLocalPart());
1038             assertEquals(nodeList.getLength(), 0);
1039         }
1040     }
1041 
1042     @Test
1043     public void testEncDecryptionKeyIdentifierIssuerSerialOutbound() throws Exception {
1044 
1045         ByteArrayOutputStream baos;
1046         {
1047             WSSSecurityProperties securityProperties = new WSSSecurityProperties();
1048             List<WSSConstants.Action> actions = new ArrayList<>();
1049             actions.add(WSSConstants.ENCRYPTION);
1050             securityProperties.setActions(actions);
1051             securityProperties.loadEncryptionKeystore(this.getClass().getClassLoader().getResource("transmitter.jks"), "default".toCharArray());
1052             securityProperties.setEncryptionUser("receiver");
1053             securityProperties.setEncryptionKeyIdentifier(WSSecurityTokenConstants.KeyIdentifier_IssuerSerial);
1054 
1055             InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
1056 
1057             baos = doOutboundSecurity(securityProperties, sourceDocument);
1058 
1059             Document document = documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray()));
1060             NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedKey.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedKey.getLocalPart());
1061             assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_WSSE_SECURITY.getLocalPart());
1062 
1063             XPathExpression xPathExpression = getXPath("/soap:Envelope/soap:Header/wsse:Security/xenc:EncryptedKey/dsig:KeyInfo/wsse:SecurityTokenReference/dsig:X509Data/dsig:X509IssuerSerial/dsig:X509SerialNumber");
1064             Node node = (Node) xPathExpression.evaluate(document, XPathConstants.NODE);
1065             assertNotNull(node);
1066 
1067             nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_DataReference.getNamespaceURI(), WSSConstants.TAG_xenc_DataReference.getLocalPart());
1068             assertEquals(nodeList.getLength(), 1);
1069 
1070             nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedData.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedData.getLocalPart());
1071             assertEquals(nodeList.getLength(), 1);
1072         }
1073 
1074         //done encryption; now test decryption:
1075         {
1076             String action = WSHandlerConstants.ENCRYPTION;
1077             doInboundSecurityWithWSS4J(documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray())), action);
1078         }
1079     }
1080 
1081     @Test
1082     public void testEncDecryptionKeyIdentifierIssuerSerialInbound() throws Exception {
1083 
1084         ByteArrayOutputStream baos = new ByteArrayOutputStream();
1085         {
1086             InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
1087             String action = WSHandlerConstants.ENCRYPTION;
1088             Properties properties = new Properties();
1089             properties.setProperty(WSHandlerConstants.ENC_KEY_ID, "IssuerSerial");
1090             Document securedDocument = doOutboundSecurityWithWSS4J(sourceDocument, action, properties);
1091 
1092             //some test that we can really sure we get what we want from WSS4J
1093             XPathExpression xPathExpression = getXPath("/soap:Envelope/soap:Header/wsse:Security/xenc:EncryptedKey/dsig:KeyInfo/wsse:SecurityTokenReference/dsig:X509Data/dsig:X509IssuerSerial/dsig:X509SerialNumber");
1094             Node node = (Node) xPathExpression.evaluate(securedDocument, XPathConstants.NODE);
1095             assertNotNull(node);
1096 
1097             Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
1098             transformer.transform(new DOMSource(securedDocument), new StreamResult(baos));
1099         }
1100 
1101         //done encryption; now test decryption:
1102         {
1103             WSSSecurityProperties securityProperties = new WSSSecurityProperties();
1104             securityProperties.loadDecryptionKeystore(this.getClass().getClassLoader().getResource("receiver.jks"), "default".toCharArray());
1105             securityProperties.setCallbackHandler(new CallbackHandlerImpl());
1106             Document document = doInboundSecurity(securityProperties, xmlInputFactory.createXMLStreamReader(new ByteArrayInputStream(baos.toByteArray())));
1107 
1108             //header element must still be there
1109             NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedKey.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedKey.getLocalPart());
1110             assertEquals(nodeList.getLength(), 1);
1111             assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_WSSE_SECURITY.getLocalPart());
1112 
1113             //no encrypted content
1114             nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedData.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedData.getLocalPart());
1115             assertEquals(nodeList.getLength(), 0);
1116         }
1117     }
1118 
1119     @Test
1120     public void testEncDecryptionKeyIdentifierBinarySecurityTokenDirectReferenceOutbound() throws Exception {
1121 
1122         ByteArrayOutputStream baos;
1123         {
1124             WSSSecurityProperties securityProperties = new WSSSecurityProperties();
1125             List<WSSConstants.Action> actions = new ArrayList<>();
1126             actions.add(WSSConstants.ENCRYPTION);
1127             securityProperties.setActions(actions);
1128             securityProperties.loadEncryptionKeystore(this.getClass().getClassLoader().getResource("transmitter.jks"), "default".toCharArray());
1129             securityProperties.setEncryptionUser("receiver");
1130             securityProperties.setEncryptionKeyIdentifier(WSSecurityTokenConstants.KEYIDENTIFIER_SECURITY_TOKEN_DIRECT_REFERENCE);
1131 
1132             InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
1133 
1134             baos = doOutboundSecurity(securityProperties, sourceDocument);
1135 
1136             Document document = documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray()));
1137             NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedKey.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedKey.getLocalPart());
1138             assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_WSSE_SECURITY.getLocalPart());
1139 
1140             XPathExpression xPathExpression = getXPath("/soap:Envelope/soap:Header/wsse:Security/wsse:BinarySecurityToken");
1141             Node node = (Node) xPathExpression.evaluate(document, XPathConstants.NODE);
1142             assertNotNull(node);
1143 
1144             nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_DataReference.getNamespaceURI(), WSSConstants.TAG_xenc_DataReference.getLocalPart());
1145             assertEquals(nodeList.getLength(), 1);
1146 
1147             nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedData.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedData.getLocalPart());
1148             assertEquals(nodeList.getLength(), 1);
1149         }
1150 
1151         //done encryption; now test decryption:
1152         {
1153             String action = WSHandlerConstants.ENCRYPTION;
1154             doInboundSecurityWithWSS4J(documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray())), action);
1155         }
1156     }
1157 
1158     @Test
1159     public void testEncDecryptionKeyIdentifierBinarySecurityTokenDirectReferenceInbound() throws Exception {
1160 
1161         ByteArrayOutputStream baos = new ByteArrayOutputStream();
1162         {
1163             InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
1164             String action = WSHandlerConstants.ENCRYPTION;
1165             Properties properties = new Properties();
1166             properties.setProperty(WSHandlerConstants.ENC_KEY_ID, "DirectReference");
1167             Document securedDocument = doOutboundSecurityWithWSS4J(sourceDocument, action, properties);
1168 
1169             //some test that we can really sure we get what we want from WSS4J
1170             XPathExpression xPathExpression = getXPath("/soap:Envelope/soap:Header/wsse:Security/wsse:BinarySecurityToken");
1171             Node node = (Node) xPathExpression.evaluate(securedDocument, XPathConstants.NODE);
1172             assertNotNull(node);
1173 
1174             Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
1175             transformer.transform(new DOMSource(securedDocument), new StreamResult(baos));
1176         }
1177 
1178         //done encryption; now test decryption:
1179         {
1180             WSSSecurityProperties securityProperties = new WSSSecurityProperties();
1181             securityProperties.loadDecryptionKeystore(this.getClass().getClassLoader().getResource("receiver.jks"), "default".toCharArray());
1182             securityProperties.setCallbackHandler(new CallbackHandlerImpl());
1183             Document document = doInboundSecurity(securityProperties, xmlInputFactory.createXMLStreamReader(new ByteArrayInputStream(baos.toByteArray())));
1184 
1185             //header element must still be there
1186             NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedKey.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedKey.getLocalPart());
1187             assertEquals(nodeList.getLength(), 1);
1188             assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_WSSE_SECURITY.getLocalPart());
1189 
1190             //no encrypted content
1191             nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedData.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedData.getLocalPart());
1192             assertEquals(nodeList.getLength(), 0);
1193         }
1194     }
1195 
1196     /**
1197      * not possible with swssf atm
1198      *
1199      * @Test public void testEncDecryptionKeyIdentifierBinarySecurityTokenDirectReferenceAtTheEndOfTheSecurityHeaderInbound() throws Exception {
1200      * <p/>
1201      * ByteArrayOutputStream baos = new ByteArrayOutputStream();
1202      * {
1203      * InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
1204      * String action = WSHandlerConstants.ENCRYPTION;
1205      * Properties properties = new Properties();
1206      * properties.setProperty(WSHandlerConstants.ENC_KEY_ID, "DirectReference");
1207      * Document securedDocument = doOutboundSecurityWithWSS4J(sourceDocument, action, properties);
1208      * <p/>
1209      * //some test that we can really sure we get what we want from WSS4J
1210      * XPathExpression xPathExpression = getXPath("/soap:Envelope/soap:Header/wsse:Security/wsse:BinarySecurityToken");
1211      * Node node = (Node) xPathExpression.evaluate(securedDocument, XPathConstants.NODE);
1212      * assertNotNull(node);
1213      * Element parentElement = (Element) node.getParentNode();
1214      * parentElement.removeChild(node);
1215      * parentElement.appendChild(node);
1216      * <p/>
1217      * Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
1218      * transformer.transform(new DOMSource(securedDocument), new StreamResult(baos));
1219      * }
1220      * <p/>
1221      * //done encryption; now test decryption:
1222      * {
1223      * WSSSecurityProperties securityProperties = new WSSSecurityProperties();
1224      * securityProperties.loadDecryptionKeystore(this.getClass().getClassLoader().getResource("receiver.jks"), "default".toCharArray());
1225      * securityProperties.setCallbackHandler(new org.apache.wss4j.test.CallbackHandlerImpl());
1226      * Document document = doInboundSecurity(securityProperties, xmlInputFactory.createXMLStreamReader(new ByteArrayInputStream(baos.toByteArray())));
1227      * <p/>
1228      * //header element must still be there
1229      * NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedKey.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedKey.getLocalPart());
1230      * assertEquals(nodeList.getLength(), 1);
1231      * assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_WSSE_SECURITY.getLocalPart());
1232      * <p/>
1233      * //no encrypted content
1234      * nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedData.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedData.getLocalPart());
1235      * assertEquals(nodeList.getLength(), 0);
1236      * }
1237      * }
1238      */
1239 
1240 /*  Not spec conform and therefore not supported!:
1241     public void testEncDecryptionKeyIdentifierBinarySecurityTokenEmbedded() throws Exception {
1242 
1243         ByteArrayOutputStream baos;
1244         {
1245             WSSSecurityProperties securityProperties = new WSSSecurityProperties();
1246             WSSConstants.Action[] actions = new WSSConstants.Action[]{WSSConstants.ENCRYPTION};
1247             securityProperties.setActions(actions);
1248             securityProperties.loadEncryptionKeystore(this.getClass().getClassLoader().getResource("transmitter.jks"), "default".toCharArray());
1249             securityProperties.setEncryptionUser("receiver");
1250             securityProperties.setEncryptionKeyIdentifierType(WSSConstants.WSSKeyIdentifierType.BST_EMBEDDED);
1251 
1252             InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
1253 
1254             baos = doOutboundSecurity(securityProperties, sourceDocument);
1255 
1256             Document document = documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray()));
1257             NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedKey.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedKey.getLocalPart());
1258             assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_WSSE_SECURITY.getLocalPart());
1259 
1260             XPathExpression xPathExpression = getXPath("/soap:Envelope/soap:Header/wsse:Security/xenc:EncryptedKey/dsig:KeyInfo/wsse:SecurityTokenReference/wsse:Reference/wsse:BinarySecurityToken");
1261             Node node = (Node) xPathExpression.evaluate(document, XPathConstants.NODE);
1262             assertNotNull(node);
1263 
1264             nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_DataReference.getNamespaceURI(), WSSConstants.TAG_xenc_DataReference.getLocalPart());
1265             assertEquals(nodeList.getLength(), 1);
1266 
1267             nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedData.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedData.getLocalPart());
1268             assertEquals(nodeList.getLength(), 1);
1269         }
1270 
1271         //done encryption; now test decryption:
1272         {
1273             WSSSecurityProperties securityProperties = new WSSSecurityProperties();
1274             securityProperties.loadDecryptionKeystore(this.getClass().getClassLoader().getResource("receiver.jks"), "default".toCharArray());
1275             securityProperties.setCallbackHandler(new CallbackHandlerImpl());
1276             Document document = doInboundSecurity(securityProperties, new ByteArrayInputStream(baos.toByteArray()));
1277 
1278             //header element must still be there
1279             NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedKey.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedKey.getLocalPart());
1280             assertEquals(nodeList.getLength(), 1);
1281             assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_WSSE_SECURITY.getLocalPart());
1282 
1283             //no encrypted content
1284             nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedData.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedData.getLocalPart());
1285             assertEquals(nodeList.getLength(), 0);
1286         }
1287     }*/
1288 
1289     @Test
1290     public void testEncDecryptionKeyIdentifierX509KeyOutbound() throws Exception {
1291 
1292         ByteArrayOutputStream baos;
1293         {
1294             WSSSecurityProperties securityProperties = new WSSSecurityProperties();
1295             List<WSSConstants.Action> actions = new ArrayList<>();
1296             actions.add(WSSConstants.ENCRYPTION);
1297             securityProperties.setActions(actions);
1298             securityProperties.loadEncryptionKeystore(this.getClass().getClassLoader().getResource("transmitter.jks"), "default".toCharArray());
1299             securityProperties.setEncryptionUser("receiver");
1300             securityProperties.setEncryptionKeyIdentifier(WSSecurityTokenConstants.KeyIdentifier_X509KeyIdentifier);
1301             InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
1302 
1303             baos = doOutboundSecurity(securityProperties, sourceDocument);
1304 
1305             Document document = documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray()));
1306             NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedKey.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedKey.getLocalPart());
1307             assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_WSSE_SECURITY.getLocalPart());
1308 
1309             XPathExpression xPathExpression = getXPath("/soap:Envelope/soap:Header/wsse:Security/xenc:EncryptedKey/dsig:KeyInfo/wsse:SecurityTokenReference/wsse:KeyIdentifier[@ValueType='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3']");
1310             Node node = (Node) xPathExpression.evaluate(document, XPathConstants.NODE);
1311             assertNotNull(node);
1312 
1313             nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_DataReference.getNamespaceURI(), WSSConstants.TAG_xenc_DataReference.getLocalPart());
1314             assertEquals(nodeList.getLength(), 1);
1315 
1316             nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedData.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedData.getLocalPart());
1317             assertEquals(nodeList.getLength(), 1);
1318         }
1319 
1320         //done encryption; now test decryption:
1321         {
1322             String action = WSHandlerConstants.ENCRYPTION;
1323             Properties properties = new Properties();
1324             doInboundSecurityWithWSS4J_1(documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray())), action, properties, false);
1325         }
1326     }
1327 
1328     @Test
1329     public void testEncDecryptionKeyIdentifierX509KeyInbound() throws Exception {
1330 
1331         ByteArrayOutputStream baos = new ByteArrayOutputStream();
1332         {
1333             InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
1334             String action = WSHandlerConstants.ENCRYPTION;
1335             Properties properties = new Properties();
1336             properties.setProperty(WSHandlerConstants.ENC_KEY_ID, "X509KeyIdentifier");
1337             Document securedDocument = doOutboundSecurityWithWSS4J(sourceDocument, action, properties);
1338 
1339             //some test that we can really sure we get what we want from WSS4J
1340             XPathExpression xPathExpression = getXPath("/soap:Envelope/soap:Header/wsse:Security/xenc:EncryptedKey/dsig:KeyInfo/wsse:SecurityTokenReference/wsse:KeyIdentifier[@ValueType='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3']");
1341             Node node = (Node) xPathExpression.evaluate(securedDocument, XPathConstants.NODE);
1342             assertNotNull(node);
1343 
1344             Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
1345             transformer.transform(new DOMSource(securedDocument), new StreamResult(baos));
1346         }
1347 
1348         //done encryption; now test decryption:
1349         {
1350             WSSSecurityProperties securityProperties = new WSSSecurityProperties();
1351             securityProperties.loadDecryptionKeystore(this.getClass().getClassLoader().getResource("receiver.jks"), "default".toCharArray());
1352             securityProperties.setCallbackHandler(new CallbackHandlerImpl());
1353             Document document = doInboundSecurity(securityProperties, xmlInputFactory.createXMLStreamReader(new ByteArrayInputStream(baos.toByteArray())));
1354 
1355             //header element must still be there
1356             NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedKey.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedKey.getLocalPart());
1357             assertEquals(nodeList.getLength(), 1);
1358             assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_WSSE_SECURITY.getLocalPart());
1359 
1360             //no encrypted content
1361             nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedData.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedData.getLocalPart());
1362             assertEquals(nodeList.getLength(), 0);
1363         }
1364     }
1365 
1366     @Test
1367     public void testEncDecryptionKeyIdentifierSubjectKeyOutbound() throws Exception {
1368 
1369         ByteArrayOutputStream baos;
1370         {
1371             WSSSecurityProperties securityProperties = new WSSSecurityProperties();
1372             List<WSSConstants.Action> actions = new ArrayList<>();
1373             actions.add(WSSConstants.ENCRYPTION);
1374             securityProperties.setActions(actions);
1375             securityProperties.loadEncryptionKeystore(this.getClass().getClassLoader().getResource("transmitter.jks"), "default".toCharArray());
1376             securityProperties.setEncryptionUser("receiver");
1377             securityProperties.setEncryptionKeyIdentifier(WSSecurityTokenConstants.KeyIdentifier_SkiKeyIdentifier);
1378 
1379             InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
1380 
1381             baos = doOutboundSecurity(securityProperties, sourceDocument);
1382 
1383             Document document = documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray()));
1384             NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedKey.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedKey.getLocalPart());
1385             assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_WSSE_SECURITY.getLocalPart());
1386 
1387             XPathExpression xPathExpression = getXPath("/soap:Envelope/soap:Header/wsse:Security/xenc:EncryptedKey/dsig:KeyInfo/wsse:SecurityTokenReference/wsse:KeyIdentifier[@ValueType='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509SubjectKeyIdentifier']");
1388             Node node = (Node) xPathExpression.evaluate(document, XPathConstants.NODE);
1389             assertNotNull(node);
1390 
1391             nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_DataReference.getNamespaceURI(), WSSConstants.TAG_xenc_DataReference.getLocalPart());
1392             assertEquals(nodeList.getLength(), 1);
1393 
1394             nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedData.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedData.getLocalPart());
1395             assertEquals(nodeList.getLength(), 1);
1396         }
1397 
1398         //done encryption; now test decryption:
1399         {
1400             String action = WSHandlerConstants.ENCRYPTION;
1401             doInboundSecurityWithWSS4J(documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray())), action);
1402         }
1403     }
1404 
1405     @Test
1406     public void testEncDecryptionKeyIdentifierSubjectKeyInbound() throws Exception {
1407 
1408         ByteArrayOutputStream baos = new ByteArrayOutputStream();
1409         {
1410             InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
1411             String action = WSHandlerConstants.ENCRYPTION;
1412             Properties properties = new Properties();
1413             properties.setProperty(WSHandlerConstants.ENC_KEY_ID, "SKIKeyIdentifier");
1414             Document securedDocument = doOutboundSecurityWithWSS4J(sourceDocument, action, properties);
1415 
1416             //some test that we can really sure we get what we want from WSS4J
1417             XPathExpression xPathExpression = getXPath("/soap:Envelope/soap:Header/wsse:Security/xenc:EncryptedKey/dsig:KeyInfo/wsse:SecurityTokenReference/wsse:KeyIdentifier[@ValueType='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509SubjectKeyIdentifier']");
1418             Node node = (Node) xPathExpression.evaluate(securedDocument, XPathConstants.NODE);
1419             assertNotNull(node);
1420 
1421             Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
1422             transformer.transform(new DOMSource(securedDocument), new StreamResult(baos));
1423         }
1424 
1425         //done encryption; now test decryption:
1426         {
1427             WSSSecurityProperties securityProperties = new WSSSecurityProperties();
1428             securityProperties.loadDecryptionKeystore(this.getClass().getClassLoader().getResource("receiver.jks"), "default".toCharArray());
1429             securityProperties.setCallbackHandler(new CallbackHandlerImpl());
1430             Document document = doInboundSecurity(securityProperties, xmlInputFactory.createXMLStreamReader(new ByteArrayInputStream(baos.toByteArray())));
1431 
1432             //header element must still be there
1433             NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedKey.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedKey.getLocalPart());
1434             assertEquals(nodeList.getLength(), 1);
1435             assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_WSSE_SECURITY.getLocalPart());
1436 
1437             //no encrypted content
1438             nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedData.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedData.getLocalPart());
1439             assertEquals(nodeList.getLength(), 0);
1440         }
1441     }
1442 
1443     @Test
1444     public void testEncDecryptionKeyIdentifierThumbprintOutbound() throws Exception {
1445 
1446         ByteArrayOutputStream baos;
1447         {
1448             WSSSecurityProperties securityProperties = new WSSSecurityProperties();
1449             List<WSSConstants.Action> actions = new ArrayList<>();
1450             actions.add(WSSConstants.ENCRYPTION);
1451             securityProperties.setActions(actions);
1452             securityProperties.loadEncryptionKeystore(this.getClass().getClassLoader().getResource("transmitter.jks"), "default".toCharArray());
1453             securityProperties.setEncryptionUser("receiver");
1454             securityProperties.setEncryptionKeyIdentifier(WSSecurityTokenConstants.KEYIDENTIFIER_THUMBPRINT_IDENTIFIER);
1455 
1456             InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
1457 
1458             baos = doOutboundSecurity(securityProperties, sourceDocument);
1459 
1460             Document document = documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray()));
1461             NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedKey.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedKey.getLocalPart());
1462             assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_WSSE_SECURITY.getLocalPart());
1463 
1464             XPathExpression xPathExpression = getXPath("/soap:Envelope/soap:Header/wsse:Security/xenc:EncryptedKey/dsig:KeyInfo/wsse:SecurityTokenReference/wsse:KeyIdentifier[@ValueType='http://docs.oasis-open.org/wss/oasis-wss-soap-message-security-1.1#ThumbprintSHA1']");
1465             Node node = (Node) xPathExpression.evaluate(document, XPathConstants.NODE);
1466             assertNotNull(node);
1467 
1468             nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_DataReference.getNamespaceURI(), WSSConstants.TAG_xenc_DataReference.getLocalPart());
1469             assertEquals(nodeList.getLength(), 1);
1470 
1471             nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedData.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedData.getLocalPart());
1472             assertEquals(nodeList.getLength(), 1);
1473         }
1474 
1475         //done encryption; now test decryption:
1476         {
1477             String action = WSHandlerConstants.ENCRYPTION;
1478             doInboundSecurityWithWSS4J(documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray())), action);
1479         }
1480     }
1481 
1482     @Test
1483     public void testEncDecryptionKeyIdentifierThumbprintInbound() throws Exception {
1484 
1485         ByteArrayOutputStream baos = new ByteArrayOutputStream();
1486         {
1487             InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
1488             String action = WSHandlerConstants.ENCRYPTION;
1489             Properties properties = new Properties();
1490             properties.setProperty(WSHandlerConstants.ENC_KEY_ID, "Thumbprint");
1491             Document securedDocument = doOutboundSecurityWithWSS4J(sourceDocument, action, properties);
1492 
1493             //some test that we can really sure we get what we want from WSS4J
1494             XPathExpression xPathExpression = getXPath("/soap:Envelope/soap:Header/wsse:Security/xenc:EncryptedKey/dsig:KeyInfo/wsse:SecurityTokenReference/wsse:KeyIdentifier[@ValueType='http://docs.oasis-open.org/wss/oasis-wss-soap-message-security-1.1#ThumbprintSHA1']");
1495             Node node = (Node) xPathExpression.evaluate(securedDocument, XPathConstants.NODE);
1496             assertNotNull(node);
1497 
1498             Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
1499             transformer.transform(new DOMSource(securedDocument), new StreamResult(baos));
1500         }
1501 
1502         //done encryption; now test decryption:
1503         {
1504             WSSSecurityProperties securityProperties = new WSSSecurityProperties();
1505             securityProperties.loadDecryptionKeystore(this.getClass().getClassLoader().getResource("receiver.jks"), "default".toCharArray());
1506             securityProperties.setCallbackHandler(new CallbackHandlerImpl());
1507             Document document = doInboundSecurity(securityProperties, xmlInputFactory.createXMLStreamReader(new ByteArrayInputStream(baos.toByteArray())));
1508 
1509             //header element must still be there
1510             NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedKey.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedKey.getLocalPart());
1511             assertEquals(nodeList.getLength(), 1);
1512             assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_WSSE_SECURITY.getLocalPart());
1513 
1514             //no encrypted content
1515             nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedData.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedData.getLocalPart());
1516             assertEquals(nodeList.getLength(), 0);
1517         }
1518     }
1519 
1520     @Test
1521     public void testEncDecryptionKeyIdentifierSHA1Outbound() throws Exception {
1522 
1523         ByteArrayOutputStream baos;
1524         {
1525             WSSSecurityProperties securityProperties = new WSSSecurityProperties();
1526             List<WSSConstants.Action> actions = new ArrayList<>();
1527             actions.add(WSSConstants.ENCRYPTION);
1528             securityProperties.setActions(actions);
1529             securityProperties.loadEncryptionKeystore(this.getClass().getClassLoader().getResource("transmitter.jks"), "default".toCharArray());
1530             securityProperties.setEncryptionUser("receiver");
1531             securityProperties.setEncryptionKeyIdentifier(WSSecurityTokenConstants.KEYIDENTIFIER_ENCRYPTED_KEY_SHA1_IDENTIFIER);
1532 
1533             InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
1534 
1535             baos = doOutboundSecurity(securityProperties, sourceDocument);
1536 
1537             Document document = documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray()));
1538             NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedKey.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedKey.getLocalPart());
1539             assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_WSSE_SECURITY.getLocalPart());
1540 
1541             XPathExpression xPathExpression = getXPath("/soap:Envelope/soap:Header/wsse:Security/xenc:EncryptedKey/dsig:KeyInfo/wsse:SecurityTokenReference/wsse:KeyIdentifier[@ValueType='http://docs.oasis-open.org/wss/oasis-wss-soap-message-security-1.1#ThumbprintSHA1']");
1542             Node node = (Node) xPathExpression.evaluate(document, XPathConstants.NODE);
1543             assertNotNull(node);
1544 
1545             xPathExpression = getXPath("/soap:Envelope/soap:Body/xenc:EncryptedData/dsig:KeyInfo/wsse:SecurityTokenReference/wsse:KeyIdentifier[@ValueType='http://docs.oasis-open.org/wss/oasis-wss-soap-message-security-1.1#EncryptedKeySHA1']");
1546             node = (Node) xPathExpression.evaluate(document, XPathConstants.NODE);
1547             assertNotNull(node);
1548 
1549             nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_DataReference.getNamespaceURI(), WSSConstants.TAG_xenc_DataReference.getLocalPart());
1550             assertEquals(nodeList.getLength(), 1);
1551 
1552             nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedData.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedData.getLocalPart());
1553             assertEquals(nodeList.getLength(), 1);
1554         }
1555 
1556         //done encryption; now test decryption:
1557         {
1558             String action = WSHandlerConstants.ENCRYPTION;
1559             doInboundSecurityWithWSS4J(documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray())), action);
1560         }
1561     }
1562 
1563     @Test
1564     public void testEncDecryptionKeyIdentifierSHA1Inbound() throws Exception {
1565 
1566         KeyGenerator keyGen = KeyGenerator.getInstance("AES");
1567         keyGen.init(128);
1568         SecretKey key = keyGen.generateKey();
1569 
1570         ByteArrayOutputStream baos = new ByteArrayOutputStream();
1571         {
1572             InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
1573 
1574             Document doc = documentBuilderFactory.newDocumentBuilder().parse(sourceDocument);
1575 
1576             WSSecHeader secHeader = new WSSecHeader(doc);
1577             secHeader.insertSecurityHeader();
1578 
1579             WSSecEncrypt builder = new WSSecEncrypt(secHeader);
1580             builder.setKeyIdentifierType(WSConstants.ENCRYPTED_KEY_SHA1_IDENTIFIER);
1581             builder.setEncryptSymmKey(false);
1582             Document securedDocument = builder.build(null, key);
1583 
1584             XPathExpression xPathExpression = getXPath("/soap:Envelope/soap:Body/xenc:EncryptedData/dsig:KeyInfo/wsse:SecurityTokenReference/wsse:KeyIdentifier[@ValueType='http://docs.oasis-open.org/wss/oasis-wss-soap-message-security-1.1#EncryptedKeySHA1']");
1585             Node node = (Node) xPathExpression.evaluate(securedDocument, XPathConstants.NODE);
1586             assertNotNull(node);
1587 
1588             Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
1589             transformer.transform(new DOMSource(securedDocument), new StreamResult(baos));
1590         }
1591 
1592         //done encryption; now test decryption:
1593         {
1594             WSSSecurityProperties securityProperties = new WSSSecurityProperties();
1595             securityProperties.loadDecryptionKeystore(this.getClass().getClassLoader().getResource("receiver.jks"), "default".toCharArray());
1596             securityProperties.setCallbackHandler(new CallbackHandlerImpl(key.getEncoded()));
1597             Document document = doInboundSecurity(securityProperties, xmlInputFactory.createXMLStreamReader(new ByteArrayInputStream(baos.toByteArray())));
1598 
1599             //no encrypted content
1600             NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedData.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedData.getLocalPart());
1601             assertEquals(nodeList.getLength(), 0);
1602         }
1603     }
1604 
1605     @Test
1606     public void testDecryptionReferenceListOutsideEncryptedKey() throws Exception {
1607 
1608         ByteArrayOutputStream baos;
1609         {
1610             WSSSecurityProperties securityProperties = new WSSSecurityProperties();
1611             List<WSSConstants.Action> actions = new ArrayList<>();
1612             actions.add(WSSConstants.ENCRYPTION);
1613             securityProperties.setActions(actions);
1614             securityProperties.loadEncryptionKeystore(this.getClass().getClassLoader().getResource("transmitter.jks"), "default".toCharArray());
1615             securityProperties.setEncryptionUser("receiver");
1616             securityProperties.setEncryptionKeyIdentifier(WSSecurityTokenConstants.KeyIdentifier_IssuerSerial);
1617 
1618             InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
1619 
1620             baos = doOutboundSecurity(securityProperties, sourceDocument);
1621 
1622             Document document = documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray()));
1623             NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedKey.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedKey.getLocalPart());
1624             assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_WSSE_SECURITY.getLocalPart());
1625 
1626             XPathExpression xPathExpression = getXPath("/soap:Envelope/soap:Header/wsse:Security/xenc:EncryptedKey/dsig:KeyInfo/wsse:SecurityTokenReference/dsig:X509Data/dsig:X509IssuerSerial/dsig:X509SerialNumber");
1627             Node node = (Node) xPathExpression.evaluate(document, XPathConstants.NODE);
1628             assertNotNull(node);
1629 
1630             nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_DataReference.getNamespaceURI(), WSSConstants.TAG_xenc_DataReference.getLocalPart());
1631             assertEquals(nodeList.getLength(), 1);
1632 
1633             nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedData.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedData.getLocalPart());
1634             assertEquals(nodeList.getLength(), 1);
1635 
1636             //move ReferenceList...
1637             TransformerFactory transFact = TransformerFactory.newInstance();
1638             Transformer trans = transFact.newTransformer(new StreamSource(this.getClass().getClassLoader().getResourceAsStream("xsl/testDecryptionReferenceListOutsideEncryptedKey.xsl")));
1639             baos.reset();
1640             trans.transform(new DOMSource(document), new StreamResult(baos));
1641 
1642         }
1643 
1644         //done encryption; now test decryption:
1645         {
1646             WSSSecurityProperties securityProperties = new WSSSecurityProperties();
1647             securityProperties.loadDecryptionKeystore(this.getClass().getClassLoader().getResource("receiver.jks"), "default".toCharArray());
1648             securityProperties.setCallbackHandler(new CallbackHandlerImpl());
1649             Document document = doInboundSecurity(securityProperties, new ByteArrayInputStream(baos.toByteArray()));
1650 
1651             //header element must still be there
1652             NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedKey.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedKey.getLocalPart());
1653             assertEquals(nodeList.getLength(), 1);
1654             assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_WSSE_SECURITY.getLocalPart());
1655 
1656             //no encrypted content
1657             nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedData.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedData.getLocalPart());
1658             assertEquals(nodeList.getLength(), 0);
1659         }
1660     }
1661 
1662     @Test
1663     public void testEncDecryptionSuperEncryptionInbound() throws Exception {
1664 
1665         ByteArrayOutputStream baos = new ByteArrayOutputStream();
1666 
1667         {
1668             InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
1669             String action = WSHandlerConstants.ENCRYPTION;
1670             Document securedDocument = doOutboundSecurityWithWSS4J(sourceDocument, action, new Properties());
1671 
1672             Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
1673             transformer.transform(new DOMSource(securedDocument), new StreamResult(baos));
1674 
1675             securedDocument = doOutboundSecurityWithWSS4J(new ByteArrayInputStream(baos.toByteArray()), action, new Properties());
1676 
1677             //some test that we can really sure we get what we want from WSS4J
1678             XPathExpression xPathExpression = getXPath("/soap:Envelope/soap:Header/wsse:Security/xenc:EncryptedKey/xenc:EncryptionMethod[@Algorithm='http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p']");
1679             NodeList nodeList = (NodeList) xPathExpression.evaluate(securedDocument, XPathConstants.NODESET);
1680             assertEquals(nodeList.getLength(), 2);
1681 
1682             transformer = TRANSFORMER_FACTORY.newTransformer();
1683             baos.reset();
1684             transformer.transform(new DOMSource(securedDocument), new StreamResult(baos));
1685         }
1686         //test streaming decryption
1687         {
1688             WSSSecurityProperties securityProperties = new WSSSecurityProperties();
1689             securityProperties.loadDecryptionKeystore(this.getClass().getClassLoader().getResource("receiver.jks"), "default".toCharArray());
1690             securityProperties.setCallbackHandler(new CallbackHandlerImpl());
1691             Document document = doInboundSecurity(securityProperties, xmlInputFactory.createXMLStreamReader(new ByteArrayInputStream(baos.toByteArray())));
1692 
1693             //header element must still be there
1694             NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedKey.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedKey.getLocalPart());
1695             assertEquals(nodeList.getLength(), 2);
1696             assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_WSSE_SECURITY.getLocalPart());
1697 
1698             //no encrypted content
1699             nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedData.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedData.getLocalPart());
1700             assertEquals(nodeList.getLength(), 0);
1701         }
1702     }
1703 
1704     @Test
1705     @SuppressWarnings("unchecked")
1706     public void testCompressedEncDecryption() throws Exception {
1707 
1708         Init.init(WSSec.class.getClassLoader().getResource("wss/wss-config.xml").toURI(), WSSec.class);
1709         Field algorithmsClassMapField = TransformerAlgorithmMapper.class.getDeclaredField("algorithmsClassMapOut");
1710         algorithmsClassMapField.setAccessible(true);
1711         Map<String, Class<?>> map = (Map<String, Class<?>>)algorithmsClassMapField.get(null);
1712         map.put("http://www.apache.org/2012/04/xmlsec/gzip", GzipCompressorOutputStream.class);
1713         algorithmsClassMapField = TransformerAlgorithmMapper.class.getDeclaredField("algorithmsClassMapIn");
1714         algorithmsClassMapField.setAccessible(true);
1715         map = (Map<String, Class<?>>)algorithmsClassMapField.get(null);
1716         map.put("http://www.apache.org/2012/04/xmlsec/gzip", GzipCompressorInputStream.class);
1717 
1718         ByteArrayOutputStream baos;
1719         {
1720             WSSSecurityProperties securityProperties = new WSSSecurityProperties();
1721             List<WSSConstants.Action> actions = new ArrayList<>();
1722             actions.add(WSSConstants.ENCRYPTION);
1723             securityProperties.setActions(actions);
1724             securityProperties.loadEncryptionKeystore(this.getClass().getClassLoader().getResource("transmitter.jks"), "default".toCharArray());
1725             securityProperties.setEncryptionUser("receiver");
1726             securityProperties.setEncryptionCompressionAlgorithm("http://www.apache.org/2012/04/xmlsec/gzip");
1727 
1728             InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
1729             baos = doOutboundSecurity(securityProperties, sourceDocument);
1730 
1731             Document document = documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray()));
1732             NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedKey.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedKey.getLocalPart());
1733             assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_WSSE_SECURITY.getLocalPart());
1734 
1735             XPathExpression xPathExpression = getXPath("/soap:Envelope/soap:Header/wsse:Security/xenc:EncryptedKey/xenc:EncryptionMethod[@Algorithm='http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p']");
1736             Node node = (Node) xPathExpression.evaluate(document, XPathConstants.NODE);
1737             assertNotNull(node);
1738 
1739             nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_DataReference.getNamespaceURI(), WSSConstants.TAG_xenc_DataReference.getLocalPart());
1740             assertEquals(nodeList.getLength(), 1);
1741 
1742             nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedData.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedData.getLocalPart());
1743             assertEquals(nodeList.getLength(), 1);
1744 
1745             xPathExpression = getXPath("/soap:Envelope/soap:Body/xenc:EncryptedData/xenc:EncryptionMethod[@Algorithm='http://www.w3.org/2001/04/xmlenc#aes256-cbc']");
1746             node = (Node) xPathExpression.evaluate(document, XPathConstants.NODE);
1747             assertNotNull(node);
1748 
1749             assertEquals(node.getParentNode().getParentNode().getLocalName(), "Body");
1750             NodeList childNodes = node.getParentNode().getParentNode().getChildNodes();
1751             for (int i = 0; i < childNodes.getLength(); i++) {
1752                 Node child = childNodes.item(i);
1753                 if (child.getNodeType() == Node.TEXT_NODE) {
1754                     assertEquals(child.getTextContent().trim(), "");
1755                 } else if (child.getNodeType() == Node.ELEMENT_NODE) {
1756                     assertEquals(child, nodeList.item(0));
1757                 } else {
1758                     fail("Unexpected Node encountered");
1759                 }
1760             }
1761         }
1762 
1763         //done encryption; now test decryption:
1764         {
1765             WSSSecurityProperties securityProperties = new WSSSecurityProperties();
1766             securityProperties.loadDecryptionKeystore(this.getClass().getClassLoader().getResource("receiver.jks"), "default".toCharArray());
1767             securityProperties.setCallbackHandler(new CallbackHandlerImpl());
1768 
1769             WSSecurityEventConstants.Event[] expectedSecurityEvents = new WSSecurityEventConstants.Event[]{
1770                     WSSecurityEventConstants.AlgorithmSuite,
1771                     WSSecurityEventConstants.AlgorithmSuite,
1772                     WSSecurityEventConstants.X509Token,
1773                     WSSecurityEventConstants.ENCRYPTED_PART,
1774                     WSSecurityEventConstants.OPERATION,
1775             };
1776             final TestSecurityEventListener securityEventListener = new TestSecurityEventListener(expectedSecurityEvents);
1777 
1778             Document document = doInboundSecurity(securityProperties, xmlInputFactory.createXMLStreamReader(new ByteArrayInputStream(baos.toByteArray())), securityEventListener);
1779 
1780             //header element must still be there
1781             NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedKey.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedKey.getLocalPart());
1782             assertEquals(nodeList.getLength(), 1);
1783             assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_WSSE_SECURITY.getLocalPart());
1784 
1785             //no encrypted content
1786             nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedData.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedData.getLocalPart());
1787             assertEquals(nodeList.getLength(), 0);
1788 
1789             securityEventListener.compare();
1790 
1791             List<SecurityEvent> receivedSecurityEvents = securityEventListener.getReceivedSecurityEvents();
1792             for (int i = 0; i < receivedSecurityEvents.size(); i++) {
1793                 SecurityEvent securityEvent = receivedSecurityEvents.get(i);
1794                 if (securityEvent.getSecurityEventType() == WSSecurityEventConstants.OPERATION) {
1795                     OperationSecurityEvent operationSecurityEvent = (OperationSecurityEvent) securityEvent;
1796                     assertEquals(operationSecurityEvent.getOperation(), new QName("http://schemas.xmlsoap.org/wsdl/", "definitions"));
1797                 } else if (securityEvent.getSecurityEventType() == WSSecurityEventConstants.ENCRYPTED_PART) {
1798                     EncryptedPartSecurityEvent encryptedPartSecurityEvent = (EncryptedPartSecurityEvent) securityEvent;
1799                     assertNotNull(encryptedPartSecurityEvent.getXmlSecEvent());
1800                     assertNotNull(encryptedPartSecurityEvent.getSecurityToken());
1801                     assertNotNull(encryptedPartSecurityEvent.getElementPath());
1802                     final QName expectedElementName = new QName("http://schemas.xmlsoap.org/soap/envelope/", "Body");
1803                     assertEquals(encryptedPartSecurityEvent.getXmlSecEvent().asStartElement().getName(), expectedElementName);
1804                     assertEquals(encryptedPartSecurityEvent.getElementPath().size(), 2);
1805                     assertEquals(encryptedPartSecurityEvent.getElementPath().get(encryptedPartSecurityEvent.getElementPath().size() - 1), expectedElementName);
1806                 }
1807             }
1808 
1809             EncryptedPartSecurityEvent encryptedPartSecurityEvent = securityEventListener.getSecurityEvent(WSSecurityEventConstants.ENCRYPTED_PART);
1810             OperationSecurityEvent operationSecurityEvent = securityEventListener.getSecurityEvent(WSSecurityEventConstants.OPERATION);
1811             String encryptedPartCorrelationID = encryptedPartSecurityEvent.getCorrelationID();
1812             String operationCorrelationID = operationSecurityEvent.getCorrelationID();
1813 
1814             List<SecurityEvent> operationSecurityEvents = new ArrayList<>();
1815             List<SecurityEvent> encryptedPartSecurityEvents = new ArrayList<>();
1816 
1817             List<SecurityEvent> securityEvents = securityEventListener.getReceivedSecurityEvents();
1818             for (int i = 0; i < securityEvents.size(); i++) {
1819                 SecurityEvent securityEvent = securityEvents.get(i);
1820                 if (securityEvent.getCorrelationID().equals(encryptedPartCorrelationID)) {
1821                     encryptedPartSecurityEvents.add(securityEvent);
1822                 } else if (securityEvent.getCorrelationID().equals(operationCorrelationID)) {
1823                     operationSecurityEvents.add(securityEvent);
1824                 }
1825             }
1826 
1827             assertEquals(4, encryptedPartSecurityEvents.size());
1828             assertEquals(securityEventListener.getReceivedSecurityEvents().size(),
1829                     operationSecurityEvents.size() + encryptedPartSecurityEvents.size());
1830         }
1831     }
1832 
1833     /**
1834      * rsa-oaep-mgf1p, Digest:SHA256, MGF:SHA1, PSource: None
1835      */
1836     @Test
1837     public void testKeyWrappingRSAOAEPMGF1AESGCM128Outbound() throws Exception {
1838         assumeFalse(isIBMJdK);
1839         try {
1840             Security.addProvider(new BouncyCastleProvider());
1841             ByteArrayOutputStream baos;
1842             {
1843                 WSSSecurityProperties securityProperties = new WSSSecurityProperties();
1844                 List<WSSConstants.Action> actions = new ArrayList<>();
1845                 actions.add(WSSConstants.ENCRYPTION);
1846                 securityProperties.setActions(actions);
1847                 securityProperties.loadEncryptionKeystore(this.getClass().getClassLoader().getResource("transmitter.jks"), "default".toCharArray());
1848                 securityProperties.setEncryptionUser("receiver");
1849                 securityProperties.setEncryptionSymAlgorithm("http://www.w3.org/2009/xmlenc11#aes128-gcm");
1850                 securityProperties.setEncryptionKeyTransportAlgorithm("http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p");
1851 
1852                 InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
1853                 baos = doOutboundSecurity(securityProperties, sourceDocument);
1854 
1855                 Document document = documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray()));
1856                 NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedKey.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedKey.getLocalPart());
1857                 assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_WSSE_SECURITY.getLocalPart());
1858 
1859                 XPathExpression xPathExpression = getXPath("/soap:Envelope/soap:Header/wsse:Security/xenc:EncryptedKey/xenc:EncryptionMethod[@Algorithm='http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p']");
1860                 Node node = (Node) xPathExpression.evaluate(document, XPathConstants.NODE);
1861                 assertNotNull(node);
1862 
1863                 nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_DataReference.getNamespaceURI(), WSSConstants.TAG_xenc_DataReference.getLocalPart());
1864                 assertEquals(nodeList.getLength(), 1);
1865 
1866                 nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedData.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedData.getLocalPart());
1867                 assertEquals(nodeList.getLength(), 1);
1868 
1869                 xPathExpression = getXPath("/soap:Envelope/soap:Body/xenc:EncryptedData/xenc:EncryptionMethod[@Algorithm='http://www.w3.org/2009/xmlenc11#aes128-gcm']");
1870                 node = (Node) xPathExpression.evaluate(document, XPathConstants.NODE);
1871                 assertNotNull(node);
1872 
1873                 assertEquals(node.getParentNode().getParentNode().getLocalName(), "Body");
1874                 NodeList childNodes = node.getParentNode().getParentNode().getChildNodes();
1875                 for (int i = 0; i < childNodes.getLength(); i++) {
1876                     Node child = childNodes.item(i);
1877                     if (child.getNodeType() == Node.TEXT_NODE) {
1878                         assertEquals(child.getTextContent().trim(), "");
1879                     } else if (child.getNodeType() == Node.ELEMENT_NODE) {
1880                         assertEquals(child, nodeList.item(0));
1881                     } else {
1882                         fail("Unexpected Node encountered");
1883                     }
1884                 }
1885             }
1886 
1887             //done encryption; now test decryption:
1888             {
1889                 String action = WSHandlerConstants.ENCRYPTION;
1890                 doInboundSecurityWithWSS4J(documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray())), action);
1891             }
1892         } finally {
1893             Security.removeProvider(BouncyCastleProvider.PROVIDER_NAME);
1894         }
1895     }
1896 
1897     @Test
1898     public void testKeyWrappingRSAOAEPMGF1AESGCM128Inbound() throws Exception {
1899         assumeFalse(isIBMJdK);
1900         ByteArrayOutputStream baos = new ByteArrayOutputStream();
1901         {
1902             InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
1903             String action = WSHandlerConstants.ENCRYPTION;
1904             Properties properties = new Properties();
1905             properties.put(WSHandlerConstants.ENC_SYM_ALGO, "http://www.w3.org/2009/xmlenc11#aes128-gcm");
1906             properties.put(WSHandlerConstants.ENC_KEY_TRANSPORT, "http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p");
1907             Document securedDocument = doOutboundSecurityWithWSS4J(sourceDocument, action, properties);
1908 
1909             //some test that we can really sure we get what we want from WSS4J
1910             XPathExpression xPathExpression = getXPath("/soap:Envelope/soap:Header/wsse:Security/xenc:EncryptedKey/xenc:EncryptionMethod[@Algorithm='http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p']");
1911             Node node = (Node) xPathExpression.evaluate(securedDocument, XPathConstants.NODE);
1912             assertNotNull(node);
1913 
1914             xPathExpression = getXPath("/soap:Envelope/soap:Body/xenc:EncryptedData/xenc:EncryptionMethod[@Algorithm='http://www.w3.org/2009/xmlenc11#aes128-gcm']");
1915             node = (Node) xPathExpression.evaluate(securedDocument, XPathConstants.NODE);
1916             assertNotNull(node);
1917 
1918             Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
1919             transformer.transform(new DOMSource(securedDocument), new StreamResult(baos));
1920         }
1921         //test streaming decryption
1922         {
1923             WSSSecurityProperties securityProperties = new WSSSecurityProperties();
1924             securityProperties.loadDecryptionKeystore(this.getClass().getClassLoader().getResource("receiver.jks"), "default".toCharArray());
1925             securityProperties.setCallbackHandler(new CallbackHandlerImpl());
1926 
1927             Document document = doInboundSecurity(securityProperties, xmlInputFactory.createXMLStreamReader(new ByteArrayInputStream(baos.toByteArray())));
1928 
1929             //header element must still be there
1930             NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedKey.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedKey.getLocalPart());
1931             assertEquals(nodeList.getLength(), 1);
1932             assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_WSSE_SECURITY.getLocalPart());
1933 
1934             //no encrypted content
1935             nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedData.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedData.getLocalPart());
1936             assertEquals(nodeList.getLength(), 0);
1937         }
1938     }
1939 
1940     /**
1941     * rsa-oaep-mgf1p, Digest:SHA256, MGF:SHA1, PSource: None
1942     */
1943     @Test
1944     public void testKeyWrappingRSAOAEPAESGCM192SHA256Outbound() throws Exception {
1945         assumeFalse(isIBMJdK);
1946         try {
1947             Security.addProvider(new BouncyCastleProvider());
1948             ByteArrayOutputStream baos;
1949             {
1950                 WSSSecurityProperties securityProperties = new WSSSecurityProperties();
1951                 List<WSSConstants.Action> actions = new ArrayList<>();
1952                 actions.add(WSSConstants.ENCRYPTION);
1953                 securityProperties.setActions(actions);
1954                 securityProperties.loadEncryptionKeystore(this.getClass().getClassLoader().getResource("transmitter.jks"), "default".toCharArray());
1955                 securityProperties.setEncryptionUser("receiver");
1956                 securityProperties.setEncryptionSymAlgorithm("http://www.w3.org/2009/xmlenc11#aes192-gcm");
1957                 securityProperties.setEncryptionKeyTransportAlgorithm("http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p");
1958                 securityProperties.setEncryptionKeyTransportDigestAlgorithm("http://www.w3.org/2001/04/xmlenc#sha256");
1959 
1960                 InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
1961                 baos = doOutboundSecurity(securityProperties, sourceDocument);
1962 
1963                 Document document = documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray()));
1964                 NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedKey.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedKey.getLocalPart());
1965                 assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_WSSE_SECURITY.getLocalPart());
1966 
1967                 XPathExpression xPathExpression = getXPath("/soap:Envelope/soap:Header/wsse:Security/xenc:EncryptedKey/xenc:EncryptionMethod[@Algorithm='http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p']");
1968                 Node node = (Node) xPathExpression.evaluate(document, XPathConstants.NODE);
1969                 assertNotNull(node);
1970 
1971                 xPathExpression = getXPath("/soap:Envelope/soap:Header/wsse:Security/xenc:EncryptedKey/xenc:EncryptionMethod/dsig:DigestMethod[@Algorithm='http://www.w3.org/2001/04/xmlenc#sha256']");
1972                 node = (Node) xPathExpression.evaluate(document, XPathConstants.NODE);
1973                 assertNotNull(node);
1974 
1975                 nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_DataReference.getNamespaceURI(), WSSConstants.TAG_xenc_DataReference.getLocalPart());
1976                 assertEquals(nodeList.getLength(), 1);
1977 
1978                 nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedData.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedData.getLocalPart());
1979                 assertEquals(nodeList.getLength(), 1);
1980 
1981                 xPathExpression = getXPath("/soap:Envelope/soap:Body/xenc:EncryptedData/xenc:EncryptionMethod[@Algorithm='http://www.w3.org/2009/xmlenc11#aes192-gcm']");
1982                 node = (Node) xPathExpression.evaluate(document, XPathConstants.NODE);
1983                 assertNotNull(node);
1984 
1985                 assertEquals(node.getParentNode().getParentNode().getLocalName(), "Body");
1986                 NodeList childNodes = node.getParentNode().getParentNode().getChildNodes();
1987                 for (int i = 0; i < childNodes.getLength(); i++) {
1988                     Node child = childNodes.item(i);
1989                     if (child.getNodeType() == Node.TEXT_NODE) {
1990                         assertEquals(child.getTextContent().trim(), "");
1991                     } else if (child.getNodeType() == Node.ELEMENT_NODE) {
1992                         assertEquals(child, nodeList.item(0));
1993                     } else {
1994                         fail("Unexpected Node encountered");
1995                     }
1996                 }
1997             }
1998             //done encryption; now test decryption:
1999             {
2000                 String action = WSHandlerConstants.ENCRYPTION;
2001                 doInboundSecurityWithWSS4J(documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray())), action);
2002             }
2003         } finally {
2004             Security.removeProvider(BouncyCastleProvider.PROVIDER_NAME);
2005         }
2006     }
2007 
2008     @Test
2009     public void testKeyWrappingRSAOAEPAESGCM192SHA256Inbound() throws Exception {
2010         assumeFalse(isIBMJdK);
2011         ByteArrayOutputStream baos = new ByteArrayOutputStream();
2012         {
2013             InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
2014             String action = WSHandlerConstants.ENCRYPTION;
2015             Properties properties = new Properties();
2016             properties.put(WSHandlerConstants.ENC_SYM_ALGO, "http://www.w3.org/2009/xmlenc11#aes192-gcm");
2017             properties.put(WSHandlerConstants.ENC_KEY_TRANSPORT, "http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p");
2018             properties.put(WSHandlerConstants.ENC_DIGEST_ALGO, "http://www.w3.org/2001/04/xmlenc#sha256");
2019             Document securedDocument = doOutboundSecurityWithWSS4J(sourceDocument, action, properties);
2020 
2021             //some test that we can really sure we get what we want from WSS4J
2022             XPathExpression xPathExpression = getXPath("/soap:Envelope/soap:Header/wsse:Security/xenc:EncryptedKey/xenc:EncryptionMethod[@Algorithm='http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p']");
2023             Node node = (Node) xPathExpression.evaluate(securedDocument, XPathConstants.NODE);
2024             assertNotNull(node);
2025 
2026             xPathExpression = getXPath("/soap:Envelope/soap:Header/wsse:Security/xenc:EncryptedKey/xenc:EncryptionMethod/dsig:DigestMethod[@Algorithm='http://www.w3.org/2001/04/xmlenc#sha256']");
2027             node = (Node) xPathExpression.evaluate(securedDocument, XPathConstants.NODE);
2028             assertNotNull(node);
2029 
2030             xPathExpression = getXPath("/soap:Envelope/soap:Body/xenc:EncryptedData/xenc:EncryptionMethod[@Algorithm='http://www.w3.org/2009/xmlenc11#aes192-gcm']");
2031             node = (Node) xPathExpression.evaluate(securedDocument, XPathConstants.NODE);
2032             assertNotNull(node);
2033 
2034             Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
2035             transformer.transform(new DOMSource(securedDocument), new StreamResult(baos));
2036         }
2037         //test streaming decryption
2038         {
2039             WSSSecurityProperties securityProperties = new WSSSecurityProperties();
2040             securityProperties.loadDecryptionKeystore(this.getClass().getClassLoader().getResource("receiver.jks"), "default".toCharArray());
2041             securityProperties.setCallbackHandler(new CallbackHandlerImpl());
2042             securityProperties.addIgnoreBSPRule(BSPRule.R5620);
2043 
2044             Document document = doInboundSecurity(securityProperties, xmlInputFactory.createXMLStreamReader(new ByteArrayInputStream(baos.toByteArray())));
2045 
2046             //header element must still be there
2047             NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedKey.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedKey.getLocalPart());
2048             assertEquals(nodeList.getLength(), 1);
2049             assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_WSSE_SECURITY.getLocalPart());
2050 
2051             //no encrypted content
2052             nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedData.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedData.getLocalPart());
2053             assertEquals(nodeList.getLength(), 0);
2054         }
2055     }
2056 
2057     /**
2058      * rsa-oaep, Digest:SHA384, MGF:SHA1, PSource: None
2059      */
2060     @Test
2061     public void testKeyWrappingRSAOAEPAES192GCMSHA384MGF1sha384Outbound() throws Exception {
2062         assumeFalse(isIBMJdK);
2063         try {
2064             Security.addProvider(new BouncyCastleProvider());
2065 
2066             ByteArrayOutputStream baos;
2067             {
2068                 WSSSecurityProperties securityProperties = new WSSSecurityProperties();
2069                 List<WSSConstants.Action> actions = new ArrayList<>();
2070                 actions.add(WSSConstants.ENCRYPTION);
2071                 securityProperties.setActions(actions);
2072                 securityProperties.loadEncryptionKeystore(this.getClass().getClassLoader().getResource("transmitter.jks"), "default".toCharArray());
2073                 securityProperties.setEncryptionUser("receiver");
2074                 securityProperties.setEncryptionSymAlgorithm("http://www.w3.org/2009/xmlenc11#aes192-gcm");
2075                 securityProperties.setEncryptionKeyTransportAlgorithm("http://www.w3.org/2009/xmlenc11#rsa-oaep");
2076                 securityProperties.setEncryptionKeyTransportDigestAlgorithm("http://www.w3.org/2001/04/xmldsig-more#sha384");
2077                 securityProperties.setEncryptionKeyTransportMGFAlgorithm("http://www.w3.org/2009/xmlenc11#mgf1sha384");
2078 
2079                 InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
2080                 baos = doOutboundSecurity(securityProperties, sourceDocument);
2081 
2082                 Document document = documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray()));
2083                 NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedKey.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedKey.getLocalPart());
2084                 assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_WSSE_SECURITY.getLocalPart());
2085 
2086                 XPathExpression xPathExpression = getXPath("/soap:Envelope/soap:Header/wsse:Security/xenc:EncryptedKey/xenc:EncryptionMethod[@Algorithm='http://www.w3.org/2009/xmlenc11#rsa-oaep']");
2087                 Node node = (Node) xPathExpression.evaluate(document, XPathConstants.NODE);
2088                 assertNotNull(node);
2089 
2090                 xPathExpression = getXPath("/soap:Envelope/soap:Header/wsse:Security/xenc:EncryptedKey/xenc:EncryptionMethod/dsig:DigestMethod[@Algorithm='http://www.w3.org/2001/04/xmldsig-more#sha384']");
2091                 node = (Node) xPathExpression.evaluate(document, XPathConstants.NODE);
2092                 assertNotNull(node);
2093 
2094                 xPathExpression = getXPath("/soap:Envelope/soap:Header/wsse:Security/xenc:EncryptedKey/xenc:EncryptionMethod/xenc11:MGF[@Algorithm='http://www.w3.org/2009/xmlenc11#mgf1sha384']");
2095                 node = (Node) xPathExpression.evaluate(document, XPathConstants.NODE);
2096                 assertNotNull(node);
2097 
2098                 nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_DataReference.getNamespaceURI(), WSSConstants.TAG_xenc_DataReference.getLocalPart());
2099                 assertEquals(nodeList.getLength(), 1);
2100 
2101                 nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedData.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedData.getLocalPart());
2102                 assertEquals(nodeList.getLength(), 1);
2103 
2104                 xPathExpression = getXPath("/soap:Envelope/soap:Body/xenc:EncryptedData/xenc:EncryptionMethod[@Algorithm='http://www.w3.org/2009/xmlenc11#aes192-gcm']");
2105                 node = (Node) xPathExpression.evaluate(document, XPathConstants.NODE);
2106                 assertNotNull(node);
2107 
2108                 assertEquals(node.getParentNode().getParentNode().getLocalName(), "Body");
2109                 NodeList childNodes = node.getParentNode().getParentNode().getChildNodes();
2110                 for (int i = 0; i < childNodes.getLength(); i++) {
2111                     Node child = childNodes.item(i);
2112                     if (child.getNodeType() == Node.TEXT_NODE) {
2113                         assertEquals(child.getTextContent().trim(), "");
2114                     } else if (child.getNodeType() == Node.ELEMENT_NODE) {
2115                         assertEquals(child, nodeList.item(0));
2116                     } else {
2117                         fail("Unexpected Node encountered");
2118                     }
2119                 }
2120             }
2121             //done encryption; now test decryption:
2122             {
2123                 String action = WSHandlerConstants.ENCRYPT;
2124                 doInboundSecurityWithWSS4J_1(documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray())), action);
2125             }
2126         } finally {
2127             Security.removeProvider(BouncyCastleProvider.PROVIDER_NAME);
2128         }
2129     }
2130 
2131     @Test
2132     public void testKeyWrappingRSAOAEPAES192GCMSHA384MGF1sha1Inbound() throws Exception {
2133 
2134         assumeFalse(isIBMJdK);
2135         ByteArrayOutputStream baos = new ByteArrayOutputStream();
2136         {
2137             InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
2138             String action = WSHandlerConstants.ENCRYPT;
2139             Properties properties = new Properties();
2140             properties.put(WSHandlerConstants.ENC_SYM_ALGO, "http://www.w3.org/2009/xmlenc11#aes192-gcm");
2141             properties.put(WSHandlerConstants.ENC_KEY_TRANSPORT, "http://www.w3.org/2009/xmlenc11#rsa-oaep");
2142             properties.put(WSHandlerConstants.ENC_DIGEST_ALGO, "http://www.w3.org/2001/04/xmldsig-more#sha384");
2143             properties.put(WSHandlerConstants.ENC_MGF_ALGO, "http://www.w3.org/2009/xmlenc11#mgf1sha1");
2144 
2145             Document securedDocument = doOutboundSecurityWithWSS4J(sourceDocument, action, properties);
2146 
2147             //some test that we can really sure we get what we want from WSS4J
2148             XPathExpression xPathExpression = getXPath("/soap:Envelope/soap:Header/wsse:Security/xenc:EncryptedKey/xenc:EncryptionMethod[@Algorithm='http://www.w3.org/2009/xmlenc11#rsa-oaep']");
2149             Node node = (Node) xPathExpression.evaluate(securedDocument, XPathConstants.NODE);
2150             assertNotNull(node);
2151 
2152             xPathExpression = getXPath("/soap:Envelope/soap:Header/wsse:Security/xenc:EncryptedKey/xenc:EncryptionMethod/dsig:DigestMethod[@Algorithm='http://www.w3.org/2001/04/xmldsig-more#sha384']");
2153             node = (Node) xPathExpression.evaluate(securedDocument, XPathConstants.NODE);
2154             assertNotNull(node);
2155 
2156             xPathExpression = getXPath("/soap:Envelope/soap:Body/xenc:EncryptedData/xenc:EncryptionMethod[@Algorithm='http://www.w3.org/2009/xmlenc11#aes192-gcm']");
2157             node = (Node) xPathExpression.evaluate(securedDocument, XPathConstants.NODE);
2158             assertNotNull(node);
2159 
2160             Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
2161             transformer.transform(new DOMSource(securedDocument), new StreamResult(baos));
2162         }
2163         //test streaming decryption
2164         {
2165             WSSSecurityProperties securityProperties = new WSSSecurityProperties();
2166             securityProperties.loadDecryptionKeystore(this.getClass().getClassLoader().getResource("receiver.jks"), "default".toCharArray());
2167             securityProperties.setCallbackHandler(new CallbackHandlerImpl());
2168             securityProperties.addIgnoreBSPRule(BSPRule.R5620);
2169             securityProperties.addIgnoreBSPRule(BSPRule.R5621);
2170 
2171             Document document = doInboundSecurity(securityProperties, xmlInputFactory.createXMLStreamReader(new ByteArrayInputStream(baos.toByteArray())));
2172 
2173             //header element must still be there
2174             NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedKey.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedKey.getLocalPart());
2175             assertEquals(nodeList.getLength(), 1);
2176             assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_WSSE_SECURITY.getLocalPart());
2177 
2178             //no encrypted content
2179             nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedData.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedData.getLocalPart());
2180             assertEquals(nodeList.getLength(), 0);
2181         }
2182     }
2183 
2184     /**
2185      * rsa-oaep, Digest:SHA512, MGF:SHA1, PSource: Specified 8 bytes
2186      */
2187 
2188     @Test
2189     public void testKeyWrappingRSAOAEPAESGCM192SHA384MGF1SHA384PSourceOutbound() throws Exception {
2190         assumeFalse(isIBMJdK);
2191         try {
2192             Security.addProvider(new BouncyCastleProvider());
2193             ByteArrayOutputStream baos;
2194             {
2195                 WSSSecurityProperties securityProperties = new WSSSecurityProperties();
2196                 List<WSSConstants.Action> actions = new ArrayList<>();
2197                 actions.add(WSSConstants.ENCRYPTION);
2198                 securityProperties.setActions(actions);
2199                 securityProperties.loadEncryptionKeystore(this.getClass().getClassLoader().getResource("transmitter.jks"), "default".toCharArray());
2200                 securityProperties.setEncryptionUser("receiver");
2201                 securityProperties.setEncryptionSymAlgorithm("http://www.w3.org/2009/xmlenc11#aes192-gcm");
2202                 securityProperties.setEncryptionKeyTransportAlgorithm("http://www.w3.org/2009/xmlenc11#rsa-oaep");
2203                 securityProperties.setEncryptionKeyTransportDigestAlgorithm("http://www.w3.org/2001/04/xmldsig-more#sha384");
2204                 securityProperties.setEncryptionKeyTransportMGFAlgorithm("http://www.w3.org/2009/xmlenc11#mgf1sha384");
2205                 securityProperties.setEncryptionKeyTransportOAEPParams(XMLUtils.decode("ZHVtbXkxMjM=".getBytes(StandardCharsets.UTF_8)));
2206 
2207                 InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
2208                 baos = doOutboundSecurity(securityProperties, sourceDocument);
2209 
2210                 Document document = documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray()));
2211                 NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedKey.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedKey.getLocalPart());
2212                 assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_WSSE_SECURITY.getLocalPart());
2213 
2214                 XPathExpression xPathExpression = getXPath("/soap:Envelope/soap:Header/wsse:Security/xenc:EncryptedKey/xenc:EncryptionMethod[@Algorithm='http://www.w3.org/2009/xmlenc11#rsa-oaep']");
2215                 Node node = (Node) xPathExpression.evaluate(document, XPathConstants.NODE);
2216                 assertNotNull(node);
2217 
2218                 xPathExpression = getXPath("/soap:Envelope/soap:Header/wsse:Security/xenc:EncryptedKey/xenc:EncryptionMethod/xenc:OAEPparams");
2219                 node = (Node) xPathExpression.evaluate(document, XPathConstants.NODE);
2220                 assertNotNull(node);
2221 
2222                 xPathExpression = getXPath("/soap:Envelope/soap:Header/wsse:Security/xenc:EncryptedKey/xenc:EncryptionMethod/dsig:DigestMethod[@Algorithm='http://www.w3.org/2001/04/xmldsig-more#sha384']");
2223                 node = (Node) xPathExpression.evaluate(document, XPathConstants.NODE);
2224                 assertNotNull(node);
2225 
2226                 xPathExpression = getXPath("/soap:Envelope/soap:Header/wsse:Security/xenc:EncryptedKey/xenc:EncryptionMethod/xenc11:MGF[@Algorithm='http://www.w3.org/2009/xmlenc11#mgf1sha384']");
2227                 node = (Node) xPathExpression.evaluate(document, XPathConstants.NODE);
2228                 assertNotNull(node);
2229 
2230                 nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_DataReference.getNamespaceURI(), WSSConstants.TAG_xenc_DataReference.getLocalPart());
2231                 assertEquals(nodeList.getLength(), 1);
2232 
2233                 nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedData.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedData.getLocalPart());
2234                 assertEquals(nodeList.getLength(), 1);
2235 
2236                 xPathExpression = getXPath("/soap:Envelope/soap:Body/xenc:EncryptedData/xenc:EncryptionMethod[@Algorithm='http://www.w3.org/2009/xmlenc11#aes192-gcm']");
2237                 node = (Node) xPathExpression.evaluate(document, XPathConstants.NODE);
2238                 assertNotNull(node);
2239 
2240                 assertEquals(node.getParentNode().getParentNode().getLocalName(), "Body");
2241                 NodeList childNodes = node.getParentNode().getParentNode().getChildNodes();
2242                 for (int i = 0; i < childNodes.getLength(); i++) {
2243                     Node child = childNodes.item(i);
2244                     if (child.getNodeType() == Node.TEXT_NODE) {
2245                         assertEquals(child.getTextContent().trim(), "");
2246                     } else if (child.getNodeType() == Node.ELEMENT_NODE) {
2247                         assertEquals(child, nodeList.item(0));
2248                     } else {
2249                         fail("Unexpected Node encountered");
2250                     }
2251                 }
2252             }
2253             //done encryption; now test decryption:
2254             {
2255                 String action = WSHandlerConstants.ENCRYPT;
2256                 doInboundSecurityWithWSS4J_1(documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray())), action);
2257             }
2258         } finally {
2259             Security.removeProvider(BouncyCastleProvider.PROVIDER_NAME);
2260         }
2261     }
2262 
2263     @Test
2264     @org.junit.jupiter.api.Disabled //WSS4J does not support OAEPParams atm
2265     public void testKeyWrappingRSAOAEPAESGCM192SHA384MGF1SHA384PSourceInbound() throws Exception {
2266         assumeFalse(isIBMJdK);
2267 
2268         ByteArrayOutputStream baos = new ByteArrayOutputStream();
2269         {
2270             InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
2271             String action = WSHandlerConstants.ENCRYPT;
2272             Properties properties = new Properties();
2273             properties.put(WSHandlerConstants.ENC_SYM_ALGO, "http://www.w3.org/2009/xmlenc11#aes192-gcm");
2274             properties.put(WSHandlerConstants.ENC_KEY_TRANSPORT, "http://www.w3.org/2009/xmlenc11#rsa-oaep");
2275             properties.put(WSHandlerConstants.ENC_DIGEST_ALGO, "http://www.w3.org/2001/04/xmldsig-more#sha384");
2276             properties.put(WSHandlerConstants.ENC_MGF_ALGO, "http://www.w3.org/2009/xmlenc11#mgf1sha384");
2277             //properties.put(WSHandlerConstants.ENC_OAEP_PARAMS, Base64.decode("ZHVtbXkxMjM=".getBytes(StandardCharsets.UTF_8)));
2278 
2279             Document securedDocument = doOutboundSecurityWithWSS4J(sourceDocument, action, properties);
2280 
2281             //some test that we can really sure we get what we want from WSS4J
2282             XPathExpression xPathExpression = getXPath("/soap:Envelope/soap:Header/wsse:Security/xenc:EncryptedKey/xenc:EncryptionMethod[@Algorithm='http://www.w3.org/2009/xmlenc11#rsa-oaep']");
2283             Node node = (Node) xPathExpression.evaluate(securedDocument, XPathConstants.NODE);
2284             assertNotNull(node);
2285 
2286             xPathExpression = getXPath("/soap:Envelope/soap:Header/wsse:Security/xenc:EncryptedKey/xenc:EncryptionMethod/xenc:OAEPparams");
2287             node = (Node) xPathExpression.evaluate(securedDocument, XPathConstants.NODE);
2288             assertNotNull(node);
2289 
2290             xPathExpression = getXPath("/soap:Envelope/soap:Header/wsse:Security/xenc:EncryptedKey/xenc:EncryptionMethod/dsig:DigestMethod[@Algorithm='http://www.w3.org/2001/04/xmldsig-more#sha384']");
2291             node = (Node) xPathExpression.evaluate(securedDocument, XPathConstants.NODE);
2292             assertNotNull(node);
2293 
2294             xPathExpression = getXPath("/soap:Envelope/soap:Header/wsse:Security/xenc:EncryptedKey/xenc:EncryptionMethod/dsig:MGF[@Algorithm='http://www.w3.org/2009/xmlenc11#mgf1sha384']");
2295             node = (Node) xPathExpression.evaluate(securedDocument, XPathConstants.NODE);
2296             assertNotNull(node);
2297 
2298             xPathExpression = getXPath("/soap:Envelope/soap:Body/xenc:EncryptedData/xenc:EncryptionMethod[@Algorithm='http://www.w3.org/2009/xmlenc11#aes192-gcm']");
2299             node = (Node) xPathExpression.evaluate(securedDocument, XPathConstants.NODE);
2300             assertNotNull(node);
2301 
2302             Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
2303             transformer.transform(new DOMSource(securedDocument), new StreamResult(baos));
2304         }
2305         //test streaming decryption
2306         {
2307             WSSSecurityProperties securityProperties = new WSSSecurityProperties();
2308             securityProperties.loadDecryptionKeystore(this.getClass().getClassLoader().getResource("receiver.jks"), "default".toCharArray());
2309             securityProperties.setCallbackHandler(new CallbackHandlerImpl());
2310             securityProperties.addIgnoreBSPRule(BSPRule.R5620);
2311             securityProperties.addIgnoreBSPRule(BSPRule.R5621);
2312 
2313             Document document = doInboundSecurity(securityProperties, xmlInputFactory.createXMLStreamReader(new ByteArrayInputStream(baos.toByteArray())));
2314 
2315             //header element must still be there
2316             NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedKey.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedKey.getLocalPart());
2317             assertEquals(nodeList.getLength(), 1);
2318             assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_WSSE_SECURITY.getLocalPart());
2319 
2320             //no encrypted content
2321             nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedData.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedData.getLocalPart());
2322             assertEquals(nodeList.getLength(), 0);
2323         }
2324     }
2325 
2326     @Test
2327     public void testInboundRequiredAlgorithms() throws Exception {
2328 
2329         ByteArrayOutputStream baos = new ByteArrayOutputStream();
2330 
2331         {
2332             InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
2333             String action = WSHandlerConstants.ENCRYPT;
2334             Document securedDocument = doOutboundSecurityWithWSS4J(sourceDocument, action, new Properties());
2335 
2336             //some test that we can really sure we get what we want from WSS4J
2337             XPathExpression xPathExpression = getXPath("/soap:Envelope/soap:Header/wsse:Security/xenc:EncryptedKey/xenc:EncryptionMethod[@Algorithm='http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p']");
2338             Node node = (Node) xPathExpression.evaluate(securedDocument, XPathConstants.NODE);
2339             assertNotNull(node);
2340 
2341             Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
2342             transformer.transform(new DOMSource(securedDocument), new StreamResult(baos));
2343         }
2344         //test streaming decryption
2345         {
2346             WSSSecurityProperties securityProperties = new WSSSecurityProperties();
2347             securityProperties.setEncryptionKeyTransportAlgorithm(WSSConstants.NS_XENC_RSAOAEPMGF1P);
2348             securityProperties.setEncryptionSymAlgorithm(WSSConstants.NS_XENC_AES128);
2349             securityProperties.loadDecryptionKeystore(this.getClass().getClassLoader().getResource("receiver.jks"), "default".toCharArray());
2350             securityProperties.setCallbackHandler(new CallbackHandlerImpl());
2351 
2352             doInboundSecurity(securityProperties, xmlInputFactory.createXMLStreamReader(new ByteArrayInputStream(baos.toByteArray())), null);
2353         }
2354         // This should fail as we are requiring another key transport algorithm
2355         {
2356             WSSSecurityProperties securityProperties = new WSSSecurityProperties();
2357             securityProperties.setEncryptionKeyTransportAlgorithm(WSSConstants.NS_XENC_RSA15);
2358             securityProperties.loadDecryptionKeystore(this.getClass().getClassLoader().getResource("receiver.jks"), "default".toCharArray());
2359             securityProperties.setCallbackHandler(new CallbackHandlerImpl());
2360 
2361             try {
2362                 doInboundSecurity(securityProperties, xmlInputFactory.createXMLStreamReader(new ByteArrayInputStream(baos.toByteArray())), null);
2363                 fail("Failure expected on the wrong key transport algorithm");
2364             }  catch (XMLStreamException e) {
2365                 assertTrue(e.getCause() instanceof WSSecurityException);
2366             }
2367         }
2368         // This should fail as we are requiring another symmetric encryption algorithm
2369         {
2370             WSSSecurityProperties securityProperties = new WSSSecurityProperties();
2371             securityProperties.setEncryptionSymAlgorithm(WSSConstants.NS_XENC_TRIPLE_DES);
2372             securityProperties.loadDecryptionKeystore(this.getClass().getClassLoader().getResource("receiver.jks"), "default".toCharArray());
2373             securityProperties.setCallbackHandler(new CallbackHandlerImpl());
2374 
2375             try {
2376                 doInboundSecurity(securityProperties, xmlInputFactory.createXMLStreamReader(new ByteArrayInputStream(baos.toByteArray())), null);
2377                 fail("Failure expected on the wrong key transport algorithm");
2378             }  catch (XMLStreamException e) {
2379                 assertTrue(e.getCause() instanceof WSSecurityException);
2380             }
2381         }
2382     }
2383 
2384     @Test
2385     public void testEncDecryptionPropertiesOutbound() throws Exception {
2386 
2387         ByteArrayOutputStream baos;
2388         {
2389             Map<String, Object> config = new HashMap<>();
2390             config.put(ConfigurationConstants.ACTION, ConfigurationConstants.ENCRYPTION);
2391             config.put(ConfigurationConstants.ENCRYPTION_USER, "receiver");
2392             config.put(ConfigurationConstants.ENC_PROP_FILE, "transmitter-crypto.properties");
2393 
2394             InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
2395             baos = doOutboundSecurity(config, sourceDocument);
2396 
2397             Document document = documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray()));
2398             NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedKey.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedKey.getLocalPart());
2399             assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_WSSE_SECURITY.getLocalPart());
2400 
2401             XPathExpression xPathExpression = getXPath("/soap:Envelope/soap:Header/wsse:Security/xenc:EncryptedKey/xenc:EncryptionMethod[@Algorithm='http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p']");
2402             Node node = (Node) xPathExpression.evaluate(document, XPathConstants.NODE);
2403             assertNotNull(node);
2404 
2405             nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_DataReference.getNamespaceURI(), WSSConstants.TAG_xenc_DataReference.getLocalPart());
2406             assertEquals(nodeList.getLength(), 1);
2407 
2408             nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedData.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedData.getLocalPart());
2409             assertEquals(nodeList.getLength(), 1);
2410 
2411             xPathExpression = getXPath("/soap:Envelope/soap:Body/xenc:EncryptedData/xenc:EncryptionMethod[@Algorithm='http://www.w3.org/2001/04/xmlenc#aes256-cbc']");
2412             node = (Node) xPathExpression.evaluate(document, XPathConstants.NODE);
2413             assertNotNull(node);
2414 
2415             assertEquals(node.getParentNode().getParentNode().getLocalName(), "Body");
2416             NodeList childNodes = node.getParentNode().getParentNode().getChildNodes();
2417             for (int i = 0; i < childNodes.getLength(); i++) {
2418                 Node child = childNodes.item(i);
2419                 if (child.getNodeType() == Node.TEXT_NODE) {
2420                     assertEquals(child.getTextContent().trim(), "");
2421                 } else if (child.getNodeType() == Node.ELEMENT_NODE) {
2422                     assertEquals(child, nodeList.item(0));
2423                 } else {
2424                     fail("Unexpected Node encountered");
2425                 }
2426             }
2427         }
2428 
2429         //done encryption; now test decryption:
2430         {
2431             String action = WSHandlerConstants.ENCRYPT;
2432             doInboundSecurityWithWSS4J(documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray())), action);
2433         }
2434     }
2435 
2436     @Test
2437     public void testEncDecryptionPropertiesInbound() throws Exception {
2438 
2439         ByteArrayOutputStream baos = new ByteArrayOutputStream();
2440 
2441         {
2442             InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
2443             String action = WSHandlerConstants.ENCRYPT;
2444             Document securedDocument = doOutboundSecurityWithWSS4J(sourceDocument, action, new Properties());
2445 
2446             //some test that we can really sure we get what we want from WSS4J
2447             XPathExpression xPathExpression = getXPath("/soap:Envelope/soap:Header/wsse:Security/xenc:EncryptedKey/xenc:EncryptionMethod[@Algorithm='http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p']");
2448             Node node = (Node) xPathExpression.evaluate(securedDocument, XPathConstants.NODE);
2449             assertNotNull(node);
2450 
2451             Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
2452             transformer.transform(new DOMSource(securedDocument), new StreamResult(baos));
2453         }
2454         //test streaming decryption
2455         {
2456             Map<String, Object> config = new HashMap<>();
2457             config.put(ConfigurationConstants.ACTION, ConfigurationConstants.ENCRYPTION);
2458             config.put(ConfigurationConstants.DEC_PROP_FILE, "receiver-crypto.properties");
2459             config.put(ConfigurationConstants.PW_CALLBACK_REF, new CallbackHandlerImpl());
2460 
2461             WSSecurityEventConstants.Event[] expectedSecurityEvents = new WSSecurityEventConstants.Event[]{
2462                     WSSecurityEventConstants.AlgorithmSuite,
2463                     WSSecurityEventConstants.AlgorithmSuite,
2464                     WSSecurityEventConstants.X509Token,
2465                     WSSecurityEventConstants.ENCRYPTED_PART,
2466                     WSSecurityEventConstants.OPERATION,
2467             };
2468             final TestSecurityEventListener securityEventListener = new TestSecurityEventListener(expectedSecurityEvents);
2469 
2470             WSSSecurityProperties securityProperties = ConfigurationConverter.convert(config);
2471             InboundWSSec wsSecIn = WSSec.getInboundWSSec(securityProperties);
2472             XMLStreamReader outXmlStreamReader =
2473                 wsSecIn.processInMessage(
2474                     xmlInputFactory.createXMLStreamReader(new ByteArrayInputStream(baos.toByteArray())),
2475                     new ArrayList<SecurityEvent>(),
2476                     securityEventListener);
2477             Document document = StAX2DOM.readDoc(documentBuilderFactory.newDocumentBuilder(), outXmlStreamReader);
2478 
2479             //header element must still be there
2480             NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedKey.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedKey.getLocalPart());
2481             assertEquals(nodeList.getLength(), 1);
2482             assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_WSSE_SECURITY.getLocalPart());
2483 
2484             //no encrypted content
2485             nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedData.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedData.getLocalPart());
2486             assertEquals(nodeList.getLength(), 0);
2487 
2488             securityEventListener.compare();
2489 
2490             List<SecurityEvent> receivedSecurityEvents = securityEventListener.getReceivedSecurityEvents();
2491             for (int i = 0; i < receivedSecurityEvents.size(); i++) {
2492                 SecurityEvent securityEvent = receivedSecurityEvents.get(i);
2493                 if (securityEvent.getSecurityEventType() == WSSecurityEventConstants.OPERATION) {
2494                     OperationSecurityEvent operationSecurityEvent = (OperationSecurityEvent) securityEvent;
2495                     assertEquals(operationSecurityEvent.getOperation(), new QName("http://schemas.xmlsoap.org/wsdl/", "definitions"));
2496                 } else if (securityEvent.getSecurityEventType() == WSSecurityEventConstants.ENCRYPTED_PART) {
2497                     EncryptedPartSecurityEvent encryptedPartSecurityEvent = (EncryptedPartSecurityEvent) securityEvent;
2498                     assertNotNull(encryptedPartSecurityEvent.getXmlSecEvent());
2499                     assertNotNull(encryptedPartSecurityEvent.getSecurityToken());
2500                     assertNotNull(encryptedPartSecurityEvent.getElementPath());
2501                     final QName expectedElementName = new QName("http://schemas.xmlsoap.org/soap/envelope/", "Body");
2502                     assertEquals(encryptedPartSecurityEvent.getXmlSecEvent().asStartElement().getName(), expectedElementName);
2503                     assertEquals(encryptedPartSecurityEvent.getElementPath().size(), 2);
2504                     assertEquals(encryptedPartSecurityEvent.getElementPath().get(encryptedPartSecurityEvent.getElementPath().size() - 1), expectedElementName);
2505                 }
2506             }
2507 
2508             EncryptedPartSecurityEvent encryptedPartSecurityEvent = securityEventListener.getSecurityEvent(WSSecurityEventConstants.ENCRYPTED_PART);
2509             OperationSecurityEvent operationSecurityEvent = securityEventListener.getSecurityEvent(WSSecurityEventConstants.OPERATION);
2510             String encryptedPartCorrelationID = encryptedPartSecurityEvent.getCorrelationID();
2511             String operationCorrelationID = operationSecurityEvent.getCorrelationID();
2512 
2513             List<SecurityEvent> operationSecurityEvents = new ArrayList<>();
2514             List<SecurityEvent> encryptedPartSecurityEvents = new ArrayList<>();
2515 
2516             List<SecurityEvent> securityEvents = securityEventListener.getReceivedSecurityEvents();
2517             for (int i = 0; i < securityEvents.size(); i++) {
2518                 SecurityEvent securityEvent = securityEvents.get(i);
2519                 if (securityEvent.getCorrelationID().equals(encryptedPartCorrelationID)) {
2520                     encryptedPartSecurityEvents.add(securityEvent);
2521                 } else if (securityEvent.getCorrelationID().equals(operationCorrelationID)) {
2522                     operationSecurityEvents.add(securityEvent);
2523                 }
2524             }
2525 
2526             assertEquals(4, encryptedPartSecurityEvents.size());
2527             assertEquals(securityEventListener.getReceivedSecurityEvents().size(),
2528                     operationSecurityEvents.size() + encryptedPartSecurityEvents.size());
2529         }
2530     }
2531 
2532     @Test
2533     public void testElementoEncryptNotFound() throws Exception {
2534 
2535         ByteArrayOutputStream baos = new ByteArrayOutputStream();
2536         {
2537             WSSSecurityProperties securityProperties = new WSSSecurityProperties();
2538             List<WSSConstants.Action> actions = new ArrayList<>();
2539             actions.add(WSSConstants.ENCRYPTION);
2540             securityProperties.setActions(actions);
2541             securityProperties.loadEncryptionKeystore(this.getClass().getClassLoader().getResource("transmitter.jks"), "default".toCharArray());
2542             securityProperties.setEncryptionUser("receiver");
2543             securityProperties.setTokenUser("transmitter");
2544             securityProperties.setCallbackHandler(new CallbackHandlerImpl());
2545             securityProperties.addEncryptionPart(
2546                     new SecurePart(new QName(WSSConstants.NS_WSSE10, "UsernameToken"), SecurePart.Modifier.Element)
2547             );
2548             securityProperties.addEncryptionPart(
2549                     new SecurePart(new QName(WSSConstants.NS_SOAP11, "Body"), SecurePart.Modifier.Content)
2550             );
2551 
2552             OutboundWSSec wsSecOut = WSSec.getOutboundWSSec(securityProperties);
2553             XMLStreamWriter xmlStreamWriter = wsSecOut.processOutMessage(baos, StandardCharsets.UTF_8.name(), new ArrayList<SecurityEvent>());
2554             XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml"));
2555 
2556             try {
2557                 XmlReaderToWriter.writeAll(xmlStreamReader, xmlStreamWriter);
2558                 xmlStreamWriter.close();
2559                 fail("Exception expected");
2560             } catch (XMLStreamException e) {
2561                 assertTrue(e.getCause() instanceof XMLSecurityException);
2562                 assertEquals("Part to encrypt not found: {http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd}UsernameToken", e.getCause().getMessage());
2563             }
2564         }
2565     }
2566 
2567     @Test
2568     public void testEncryptedDataSecurityHeaderWithoutReferenceInbound() throws Exception {
2569         ByteArrayOutputStream baos = new ByteArrayOutputStream();
2570         {
2571             InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
2572 
2573             Document doc = documentBuilderFactory.newDocumentBuilder().parse(sourceDocument);
2574 
2575             WSSecHeader secHeader = new WSSecHeader(doc);
2576             secHeader.insertSecurityHeader();
2577             Element securityHeaderElement = secHeader.getSecurityHeaderElement();
2578             securityHeaderElement.appendChild(doc.getElementsByTagNameNS("http://schemas.xmlsoap.org/wsdl/", "definitions").item(0));
2579 
2580             WSSecEncrypt builder = new WSSecEncrypt(secHeader);
2581             builder.setKeyIdentifierType(WSConstants.THUMBPRINT_IDENTIFIER);
2582             builder.setUserInfo("receiver");
2583             Crypto crypto = CryptoFactory.getInstance("transmitter-crypto.properties");
2584 
2585             KeyGenerator keyGen = KeyUtils.getKeyGenerator(WSConstants.AES_128);
2586             SecretKey symmetricKey = keyGen.generateKey();
2587             builder.prepare(crypto, symmetricKey);
2588 
2589             WSEncryptionPart encP = new WSEncryptionPart("definitions", "http://schemas.xmlsoap.org/wsdl/", "Element");
2590             List<WSEncryptionPart> encryptionParts = new ArrayList<>();
2591             encryptionParts.add(encP);
2592             Element ref = builder.encryptForRef(null, encryptionParts, symmetricKey);
2593             ref.removeChild(ref.getElementsByTagNameNS("http://www.w3.org/2001/04/xmlenc#", "DataReference").item(0));
2594             builder.addExternalRefElement(ref);
2595             builder.prependToHeader();
2596 
2597             Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
2598             transformer.transform(new DOMSource(doc), new StreamResult(baos));
2599         }
2600 
2601         //done encryption; now test decryption:
2602         {
2603             WSSSecurityProperties securityProperties = new WSSSecurityProperties();
2604             securityProperties.loadDecryptionKeystore(this.getClass().getClassLoader().getResource("receiver.jks"), "default".toCharArray());
2605             securityProperties.setCallbackHandler(new CallbackHandlerImpl());
2606             Document document = doInboundSecurity(securityProperties, xmlInputFactory.createXMLStreamReader(new ByteArrayInputStream(baos.toByteArray())));
2607 
2608             //no encrypted content
2609             NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedData.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedData.getLocalPart());
2610             assertEquals(nodeList.getLength(), 0);
2611         }
2612     }
2613 
2614     @Test
2615     public void testEncryptedDataSecurityHeaderPrependedReferenceInbound() throws Exception {
2616         ByteArrayOutputStream baos = new ByteArrayOutputStream();
2617         {
2618             InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
2619 
2620             Document doc = documentBuilderFactory.newDocumentBuilder().parse(sourceDocument);
2621 
2622             WSSecHeader secHeader = new WSSecHeader(doc);
2623             secHeader.insertSecurityHeader();
2624             Element securityHeaderElement = secHeader.getSecurityHeaderElement();
2625             securityHeaderElement.appendChild(doc.getElementsByTagNameNS("http://schemas.xmlsoap.org/wsdl/", "definitions").item(0));
2626 
2627             WSSecEncrypt builder = new WSSecEncrypt(secHeader);
2628             builder.setKeyIdentifierType(WSConstants.THUMBPRINT_IDENTIFIER);
2629             builder.setUserInfo("receiver");
2630             Crypto crypto = CryptoFactory.getInstance("transmitter-crypto.properties");
2631 
2632             KeyGenerator keyGen = KeyUtils.getKeyGenerator(WSConstants.AES_128);
2633             SecretKey symmetricKey = keyGen.generateKey();
2634             builder.prepare(crypto, symmetricKey);
2635 
2636             WSEncryptionPart encP = new WSEncryptionPart("definitions", "http://schemas.xmlsoap.org/wsdl/", "Element");
2637             List<WSEncryptionPart> encryptionParts = new ArrayList<>();
2638             encryptionParts.add(encP);
2639             Element ref = builder.encryptForRef(null, encryptionParts, symmetricKey);
2640             builder.addExternalRefElement(ref);
2641             builder.prependToHeader();
2642 
2643             Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
2644             transformer.transform(new DOMSource(doc), new StreamResult(baos));
2645         }
2646 
2647         //done encryption; now test decryption:
2648         {
2649             WSSSecurityProperties securityProperties = new WSSSecurityProperties();
2650             securityProperties.loadDecryptionKeystore(this.getClass().getClassLoader().getResource("receiver.jks"), "default".toCharArray());
2651             securityProperties.setCallbackHandler(new CallbackHandlerImpl());
2652             Document document = doInboundSecurity(securityProperties, xmlInputFactory.createXMLStreamReader(new ByteArrayInputStream(baos.toByteArray())));
2653 
2654             //no encrypted content
2655             NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedData.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedData.getLocalPart());
2656             assertEquals(nodeList.getLength(), 0);
2657         }
2658     }
2659 
2660     @Test
2661     public void testEncryptedDataSecurityHeaderAppendedReferenceInbound() throws Exception {
2662         ByteArrayOutputStream baos = new ByteArrayOutputStream();
2663         {
2664             InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
2665 
2666             Document doc = documentBuilderFactory.newDocumentBuilder().parse(sourceDocument);
2667 
2668             WSSecHeader secHeader = new WSSecHeader(doc);
2669             secHeader.insertSecurityHeader();
2670             Element securityHeaderElement = secHeader.getSecurityHeaderElement();
2671             securityHeaderElement.appendChild(doc.getElementsByTagNameNS("http://schemas.xmlsoap.org/wsdl/", "definitions").item(0));
2672 
2673             WSSecEncrypt builder = new WSSecEncrypt(secHeader);
2674             builder.setKeyIdentifierType(WSConstants.THUMBPRINT_IDENTIFIER);
2675             builder.setUserInfo("receiver");
2676             Crypto crypto = CryptoFactory.getInstance("transmitter-crypto.properties");
2677 
2678             KeyGenerator keyGen = KeyUtils.getKeyGenerator(WSConstants.AES_128);
2679             SecretKey symmetricKey = keyGen.generateKey();
2680             builder.prepare(crypto, symmetricKey);
2681 
2682             WSEncryptionPart encP = new WSEncryptionPart("definitions", "http://schemas.xmlsoap.org/wsdl/", "Element");
2683             List<WSEncryptionPart> encryptionParts = new ArrayList<>();
2684             encryptionParts.add(encP);
2685             Element ref = builder.encryptForRef(null, encryptionParts, symmetricKey);
2686             builder.prependToHeader();
2687             //builder.addExternalRefElement(ref, secHeader);
2688             securityHeaderElement.appendChild(ref);
2689 
2690             Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
2691             transformer.transform(new DOMSource(doc), new StreamResult(baos));
2692         }
2693 
2694         //done encryption; now test decryption:
2695         {
2696             WSSSecurityProperties securityProperties = new WSSSecurityProperties();
2697             securityProperties.loadDecryptionKeystore(this.getClass().getClassLoader().getResource("receiver.jks"), "default".toCharArray());
2698             securityProperties.setCallbackHandler(new CallbackHandlerImpl());
2699             Document document = doInboundSecurity(securityProperties, xmlInputFactory.createXMLStreamReader(new ByteArrayInputStream(baos.toByteArray())));
2700 
2701             //no encrypted content
2702             NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedData.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedData.getLocalPart());
2703             assertEquals(nodeList.getLength(), 0);
2704         }
2705     }
2706 }