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.saml;
20  
21  import java.io.ByteArrayInputStream;
22  import java.io.ByteArrayOutputStream;
23  import java.io.InputStream;
24  import java.nio.charset.StandardCharsets;
25  import java.security.KeyStore;
26  import java.util.ArrayList;
27  import java.util.List;
28  import java.util.Properties;
29  
30  import javax.xml.stream.XMLStreamReader;
31  import javax.xml.stream.XMLStreamWriter;
32  import javax.xml.transform.dom.DOMSource;
33  import javax.xml.transform.stream.StreamResult;
34  
35  import org.apache.wss4j.common.crypto.Crypto;
36  import org.apache.wss4j.common.crypto.CryptoFactory;
37  import org.apache.wss4j.common.crypto.CryptoType;
38  import org.apache.wss4j.common.crypto.Merlin;
39  import org.apache.wss4j.common.saml.SAMLCallback;
40  import org.apache.wss4j.common.saml.SAMLUtil;
41  import org.apache.wss4j.common.saml.SamlAssertionWrapper;
42  import org.apache.wss4j.common.saml.bean.KeyInfoBean;
43  import org.apache.wss4j.common.saml.bean.Version;
44  import org.apache.wss4j.common.saml.builder.SAML1Constants;
45  import org.apache.wss4j.common.saml.builder.SAML2Constants;
46  import org.apache.wss4j.common.util.SOAPUtil;
47  import org.apache.wss4j.dom.handler.WSHandlerConstants;
48  import org.apache.wss4j.dom.message.WSSecHeader;
49  import org.apache.wss4j.dom.message.WSSecSAMLToken;
50  import org.apache.wss4j.stax.ext.WSSConstants;
51  import org.apache.wss4j.stax.ext.WSSSecurityProperties;
52  import org.apache.wss4j.stax.impl.securityToken.HttpsSecurityTokenImpl;
53  import org.apache.wss4j.stax.securityEvent.HttpsTokenSecurityEvent;
54  import org.apache.wss4j.stax.securityToken.HttpsSecurityToken;
55  import org.apache.wss4j.stax.securityToken.WSSecurityTokenConstants;
56  import org.apache.wss4j.stax.setup.InboundWSSec;
57  import org.apache.wss4j.stax.setup.OutboundWSSec;
58  import org.apache.wss4j.stax.setup.WSSec;
59  import org.apache.wss4j.stax.test.AbstractTestBase;
60  import org.apache.wss4j.stax.test.CallbackHandlerImpl;
61  import org.apache.wss4j.stax.test.utils.StAX2DOM;
62  import org.apache.wss4j.stax.test.utils.XmlReaderToWriter;
63  import org.apache.xml.security.stax.securityEvent.SecurityEvent;
64  import org.junit.jupiter.api.Test;
65  import org.w3c.dom.Document;
66  import org.w3c.dom.Element;
67  import org.w3c.dom.NodeList;
68  
69  import static org.junit.jupiter.api.Assertions.assertEquals;
70  
71  public class SAMLTokenHOKTest extends AbstractTestBase {
72  
73      @Test
74      public void testSAML1AuthnAssertionOutbound() throws Exception {
75  
76          ByteArrayOutputStream baos = new ByteArrayOutputStream();
77          {
78              WSSSecurityProperties securityProperties = new WSSSecurityProperties();
79              List<WSSConstants.Action> actions = new ArrayList<>();
80              actions.add(WSSConstants.SAML_TOKEN_SIGNED);
81              securityProperties.setActions(actions);
82              SAMLCallbackHandlerImpl callbackHandler = new SAMLCallbackHandlerImpl();
83              callbackHandler.setStatement(SAMLCallbackHandlerImpl.Statement.AUTHN);
84              callbackHandler.setConfirmationMethod(SAML1Constants.CONF_HOLDER_KEY);
85              callbackHandler.setIssuer("www.example.com");
86              securityProperties.setSamlCallbackHandler(callbackHandler);
87              KeyStore keyStore = KeyStore.getInstance("jks");
88              keyStore.load(this.getClass().getClassLoader().getResourceAsStream("transmitter.jks"), "default".toCharArray());
89              Merlin crypto = new Merlin();
90              crypto.setKeyStore(keyStore);
91              CryptoType cryptoType = new CryptoType(CryptoType.TYPE.ALIAS);
92              cryptoType.setAlias("transmitter");
93              callbackHandler.setCerts(crypto.getX509Certificates(cryptoType));
94              securityProperties.loadSignatureKeyStore(this.getClass().getClassLoader().getResource("transmitter.jks"), "default".toCharArray());
95              securityProperties.setSignatureUser("transmitter");
96              securityProperties.setCallbackHandler(new CallbackHandlerImpl());
97  
98              OutboundWSSec wsSecOut = WSSec.getOutboundWSSec(securityProperties);
99              XMLStreamWriter xmlStreamWriter = wsSecOut.processOutMessage(baos, StandardCharsets.UTF_8.name(), new ArrayList<SecurityEvent>());
100             XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml"));
101             XmlReaderToWriter.writeAll(xmlStreamReader, xmlStreamWriter);
102             xmlStreamWriter.close();
103 
104             Document document = documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray()));
105             NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
106             assertEquals(nodeList.getLength(), 2);
107             assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_SAML_ASSERTION.getLocalPart());
108             assertEquals(nodeList.item(1).getParentNode().getLocalName(), WSSConstants.TAG_WSSE_SECURITY.getLocalPart());
109 
110             nodeList = document.getElementsByTagNameNS("urn:oasis:names:tc:SAML:1.0:assertion", "AuthenticationStatement");
111             assertEquals(nodeList.getLength(), 1);
112 
113             nodeList = document.getElementsByTagNameNS("urn:oasis:names:tc:SAML:1.0:assertion", "ConfirmationMethod");
114             assertEquals(nodeList.getLength(), 1);
115             assertEquals(nodeList.item(0).getTextContent().trim(), "urn:oasis:names:tc:SAML:1.0:cm:holder-of-key");
116         }
117 
118         //done signature; now test sig-verification:
119         {
120             String action = WSHandlerConstants.SIGNATURE + " " + WSHandlerConstants.SAML_TOKEN_SIGNED;
121             Properties properties = new Properties();
122             doInboundSecurityWithWSS4J_1(documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray())), action, properties, false);
123         }
124     }
125 
126     @Test
127     public void testSAML1AuthnAssertionInbound() throws Exception {
128 
129         ByteArrayOutputStream baos = new ByteArrayOutputStream();
130         {
131             SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
132             callbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHN);
133             callbackHandler.setConfirmationMethod(SAML1Constants.CONF_HOLDER_KEY);
134             callbackHandler.setIssuer("www.example.com");
135 
136             InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
137             String action = WSHandlerConstants.SAML_TOKEN_SIGNED;
138             Properties properties = new Properties();
139             properties.put(WSHandlerConstants.SAML_CALLBACK_REF, callbackHandler);
140             Document securedDocument = doOutboundSecurityWithWSS4J(sourceDocument, action, properties);
141 
142             //some test that we can really sure we get what we want from WSS4J
143             NodeList nodeList = securedDocument.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
144             assertEquals(nodeList.getLength(), 2);
145             assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_SAML_ASSERTION.getLocalPart());
146             assertEquals(nodeList.item(1).getParentNode().getLocalName(), WSSConstants.TAG_WSSE_SECURITY.getLocalPart());
147 
148             nodeList = securedDocument.getElementsByTagNameNS("urn:oasis:names:tc:SAML:1.0:assertion", "AuthenticationStatement");
149             assertEquals(nodeList.getLength(), 1);
150 
151             nodeList = securedDocument.getElementsByTagNameNS("urn:oasis:names:tc:SAML:1.0:assertion", "ConfirmationMethod");
152             assertEquals(nodeList.getLength(), 1);
153             assertEquals(nodeList.item(0).getTextContent().trim(), "urn:oasis:names:tc:SAML:1.0:cm:holder-of-key");
154 
155             javax.xml.transform.Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
156             transformer.transform(new DOMSource(securedDocument), new StreamResult(baos));
157         }
158 
159         //done signature; now test sig-verification:
160         {
161             WSSSecurityProperties securityProperties = new WSSSecurityProperties();
162             securityProperties.loadSignatureVerificationKeystore(this.getClass().getClassLoader().getResource("receiver.jks"), "default".toCharArray());
163             InboundWSSec wsSecIn = WSSec.getInboundWSSec(securityProperties);
164             XMLStreamReader xmlStreamReader = wsSecIn.processInMessage(xmlInputFactory.createXMLStreamReader(new ByteArrayInputStream(baos.toByteArray())));
165 
166             Document document = StAX2DOM.readDoc(documentBuilderFactory.newDocumentBuilder(), xmlStreamReader);
167 
168             //header element must still be there
169             NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
170             assertEquals(nodeList.getLength(), 2);
171             assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_SAML_ASSERTION.getLocalPart());
172             assertEquals(nodeList.item(1).getParentNode().getLocalName(), WSSConstants.TAG_WSSE_SECURITY.getLocalPart());
173         }
174     }
175 
176     @Test
177     public void testSAML1AuthnAssertionIssuerSerialOutbound() throws Exception {
178 
179         ByteArrayOutputStream baos = new ByteArrayOutputStream();
180         {
181             WSSSecurityProperties securityProperties = new WSSSecurityProperties();
182             List<WSSConstants.Action> actions = new ArrayList<>();
183             actions.add(WSSConstants.SAML_TOKEN_SIGNED);
184             securityProperties.setActions(actions);
185             SAMLCallbackHandlerImpl callbackHandler = new SAMLCallbackHandlerImpl();
186             callbackHandler.setStatement(SAMLCallbackHandlerImpl.Statement.AUTHN);
187             callbackHandler.setConfirmationMethod(SAML1Constants.CONF_HOLDER_KEY);
188             callbackHandler.setCertIdentifier(KeyInfoBean.CERT_IDENTIFIER.X509_ISSUER_SERIAL);
189             callbackHandler.setIssuer("www.example.com");
190             securityProperties.setSamlCallbackHandler(callbackHandler);
191             KeyStore keyStore = KeyStore.getInstance("jks");
192             keyStore.load(this.getClass().getClassLoader().getResourceAsStream("transmitter.jks"), "default".toCharArray());
193             Merlin crypto = new Merlin();
194             crypto.setKeyStore(keyStore);
195             CryptoType cryptoType = new CryptoType(CryptoType.TYPE.ALIAS);
196             cryptoType.setAlias("transmitter");
197             callbackHandler.setCerts(crypto.getX509Certificates(cryptoType));
198             securityProperties.loadSignatureKeyStore(this.getClass().getClassLoader().getResource("transmitter.jks"), "default".toCharArray());
199             securityProperties.setSignatureUser("transmitter");
200             securityProperties.setSignatureKeyIdentifier(WSSecurityTokenConstants.KEYIDENTIFIER_EMBEDDED_KEY_IDENTIFIER_REF);
201             securityProperties.setCallbackHandler(new CallbackHandlerImpl());
202 
203             OutboundWSSec wsSecOut = WSSec.getOutboundWSSec(securityProperties);
204             XMLStreamWriter xmlStreamWriter = wsSecOut.processOutMessage(baos, StandardCharsets.UTF_8.name(), new ArrayList<SecurityEvent>());
205             XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml"));
206             XmlReaderToWriter.writeAll(xmlStreamReader, xmlStreamWriter);
207             xmlStreamWriter.close();
208 
209             Document document = documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray()));
210             NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
211             assertEquals(nodeList.getLength(), 2);
212             assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_SAML_ASSERTION.getLocalPart());
213             assertEquals(nodeList.item(1).getParentNode().getLocalName(), WSSConstants.TAG_WSSE_SECURITY.getLocalPart());
214 
215             nodeList = document.getElementsByTagNameNS("http://www.w3.org/2000/09/xmldsig#", "X509IssuerSerial");
216             assertEquals(nodeList.getLength(), 1);
217 
218             nodeList = document.getElementsByTagNameNS("http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", "KeyIdentifier");
219             assertEquals(nodeList.getLength(), 1);
220 
221             nodeList = document.getElementsByTagNameNS("urn:oasis:names:tc:SAML:1.0:assertion", "AuthenticationStatement");
222             assertEquals(nodeList.getLength(), 1);
223 
224             nodeList = document.getElementsByTagNameNS("urn:oasis:names:tc:SAML:1.0:assertion", "ConfirmationMethod");
225             assertEquals(nodeList.getLength(), 1);
226             assertEquals(nodeList.item(0).getTextContent().trim(), "urn:oasis:names:tc:SAML:1.0:cm:holder-of-key");
227         }
228 
229         //done signature; now test sig-verification:
230         {
231             String action = WSHandlerConstants.SIGNATURE + " " + WSHandlerConstants.SAML_TOKEN_SIGNED;
232             Properties properties = new Properties();
233             doInboundSecurityWithWSS4J_1(documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray())), action, properties, false);
234         }
235     }
236 
237     @Test
238     public void testSAML1AuthnAssertionIssuerSerialInbound() throws Exception {
239 
240         ByteArrayOutputStream baos = new ByteArrayOutputStream();
241         {
242             SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
243             callbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHN);
244             callbackHandler.setConfirmationMethod(SAML1Constants.CONF_HOLDER_KEY);
245             callbackHandler.setCertIdentifier(KeyInfoBean.CERT_IDENTIFIER.X509_ISSUER_SERIAL);
246             callbackHandler.setIssuer("www.example.com");
247 
248             InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
249             String action = WSHandlerConstants.SAML_TOKEN_SIGNED;
250             Properties properties = new Properties();
251             properties.put(WSHandlerConstants.SAML_CALLBACK_REF, callbackHandler);
252             properties.put(WSHandlerConstants.SIG_KEY_ID, "DirectReference");
253             Document securedDocument = doOutboundSecurityWithWSS4J(sourceDocument, action, properties);
254 
255             //some test that we can really sure we get what we want from WSS4J
256             NodeList nodeList = securedDocument.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
257             assertEquals(nodeList.getLength(), 2);
258             assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_SAML_ASSERTION.getLocalPart());
259             assertEquals(nodeList.item(1).getParentNode().getLocalName(), WSSConstants.TAG_WSSE_SECURITY.getLocalPart());
260 
261             nodeList = securedDocument.getElementsByTagNameNS("http://www.w3.org/2000/09/xmldsig#", "X509IssuerSerial");
262             assertEquals(nodeList.getLength(), 1);
263 
264             nodeList = securedDocument.getElementsByTagNameNS("http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", "KeyIdentifier");
265             assertEquals(nodeList.getLength(), 1);
266 
267             nodeList = securedDocument.getElementsByTagNameNS("urn:oasis:names:tc:SAML:1.0:assertion", "AuthenticationStatement");
268             assertEquals(nodeList.getLength(), 1);
269 
270             nodeList = securedDocument.getElementsByTagNameNS("urn:oasis:names:tc:SAML:1.0:assertion", "ConfirmationMethod");
271             assertEquals(nodeList.getLength(), 1);
272             assertEquals(nodeList.item(0).getTextContent().trim(), "urn:oasis:names:tc:SAML:1.0:cm:holder-of-key");
273 
274             javax.xml.transform.Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
275             transformer.transform(new DOMSource(securedDocument), new StreamResult(baos));
276         }
277 
278         //done signature; now test sig-verification:
279         {
280             WSSSecurityProperties securityProperties = new WSSSecurityProperties();
281             securityProperties.loadSignatureVerificationKeystore(this.getClass().getClassLoader().getResource("receiver.jks"), "default".toCharArray());
282             InboundWSSec wsSecIn = WSSec.getInboundWSSec(securityProperties);
283             XMLStreamReader xmlStreamReader = wsSecIn.processInMessage(xmlInputFactory.createXMLStreamReader(new ByteArrayInputStream(baos.toByteArray())));
284 
285             Document document = StAX2DOM.readDoc(documentBuilderFactory.newDocumentBuilder(), xmlStreamReader);
286 
287             //header element must still be there
288             NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
289             assertEquals(nodeList.getLength(), 2);
290             assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_SAML_ASSERTION.getLocalPart());
291             assertEquals(nodeList.item(1).getParentNode().getLocalName(), WSSConstants.TAG_WSSE_SECURITY.getLocalPart());
292         }
293     }
294 
295     @Test
296     public void testSAML1AuthnAssertionKeyValueOutbound() throws Exception {
297 
298         ByteArrayOutputStream baos = new ByteArrayOutputStream();
299         {
300             WSSSecurityProperties securityProperties = new WSSSecurityProperties();
301             List<WSSConstants.Action> actions = new ArrayList<>();
302             actions.add(WSSConstants.SAML_TOKEN_SIGNED);
303             securityProperties.setActions(actions);
304             SAMLCallbackHandlerImpl callbackHandler = new SAMLCallbackHandlerImpl();
305             callbackHandler.setStatement(SAMLCallbackHandlerImpl.Statement.AUTHN);
306             callbackHandler.setConfirmationMethod(SAML1Constants.CONF_HOLDER_KEY);
307             callbackHandler.setCertIdentifier(KeyInfoBean.CERT_IDENTIFIER.KEY_VALUE);
308             callbackHandler.setIssuer("www.example.com");
309             securityProperties.setSamlCallbackHandler(callbackHandler);
310             KeyStore keyStore = KeyStore.getInstance("jks");
311             keyStore.load(this.getClass().getClassLoader().getResourceAsStream("transmitter.jks"), "default".toCharArray());
312             Merlin crypto = new Merlin();
313             crypto.setKeyStore(keyStore);
314             CryptoType cryptoType = new CryptoType(CryptoType.TYPE.ALIAS);
315             cryptoType.setAlias("transmitter");
316             callbackHandler.setCerts(crypto.getX509Certificates(cryptoType));
317             securityProperties.loadSignatureKeyStore(this.getClass().getClassLoader().getResource("transmitter.jks"), "default".toCharArray());
318             securityProperties.setSignatureUser("transmitter");
319             securityProperties.setSignatureKeyIdentifier(WSSecurityTokenConstants.KEYIDENTIFIER_EMBEDDED_KEY_IDENTIFIER_REF);
320             securityProperties.setCallbackHandler(new CallbackHandlerImpl());
321 
322             OutboundWSSec wsSecOut = WSSec.getOutboundWSSec(securityProperties);
323             XMLStreamWriter xmlStreamWriter = wsSecOut.processOutMessage(baos, StandardCharsets.UTF_8.name(), new ArrayList<SecurityEvent>());
324             XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml"));
325             XmlReaderToWriter.writeAll(xmlStreamReader, xmlStreamWriter);
326             xmlStreamWriter.close();
327 
328             Document document = documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray()));
329             NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
330             assertEquals(nodeList.getLength(), 2);
331             assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_SAML_ASSERTION.getLocalPart());
332             assertEquals(nodeList.item(1).getParentNode().getLocalName(), WSSConstants.TAG_WSSE_SECURITY.getLocalPart());
333 
334             nodeList = document.getElementsByTagNameNS("http://www.w3.org/2000/09/xmldsig#", "KeyValue");
335             assertEquals(nodeList.getLength(), 1);
336 
337             nodeList = document.getElementsByTagNameNS("http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", "KeyIdentifier");
338             assertEquals(nodeList.getLength(), 1);
339 
340             nodeList = document.getElementsByTagNameNS("urn:oasis:names:tc:SAML:1.0:assertion", "AuthenticationStatement");
341             assertEquals(nodeList.getLength(), 1);
342 
343             nodeList = document.getElementsByTagNameNS("urn:oasis:names:tc:SAML:1.0:assertion", "ConfirmationMethod");
344             assertEquals(nodeList.getLength(), 1);
345             assertEquals(nodeList.item(0).getTextContent().trim(), "urn:oasis:names:tc:SAML:1.0:cm:holder-of-key");
346         }
347 
348         //done signature; now test sig-verification:
349         {
350             String action = WSHandlerConstants.SIGNATURE + " " + WSHandlerConstants.SAML_TOKEN_SIGNED;
351             Properties properties = new Properties();
352             doInboundSecurityWithWSS4J_1(documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray())), action, properties, false);
353         }
354     }
355 
356     @Test
357     public void testSAML1AuthnAssertionKeyValueInbound() throws Exception {
358 
359         ByteArrayOutputStream baos = new ByteArrayOutputStream();
360         {
361             SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
362             callbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHN);
363             callbackHandler.setConfirmationMethod(SAML1Constants.CONF_HOLDER_KEY);
364             callbackHandler.setCertIdentifier(KeyInfoBean.CERT_IDENTIFIER.KEY_VALUE);
365             callbackHandler.setIssuer("www.example.com");
366 
367             InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
368             String action = WSHandlerConstants.SAML_TOKEN_SIGNED;
369             Properties properties = new Properties();
370             properties.put(WSHandlerConstants.SAML_CALLBACK_REF, callbackHandler);
371             properties.put(WSHandlerConstants.SIG_KEY_ID, "DirectReference");
372             Document securedDocument = doOutboundSecurityWithWSS4J(sourceDocument, action, properties);
373 
374             //some test that we can really sure we get what we want from WSS4J
375             NodeList nodeList = securedDocument.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
376             assertEquals(nodeList.getLength(), 2);
377             assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_SAML_ASSERTION.getLocalPart());
378             assertEquals(nodeList.item(1).getParentNode().getLocalName(), WSSConstants.TAG_WSSE_SECURITY.getLocalPart());
379 
380             nodeList = securedDocument.getElementsByTagNameNS("http://www.w3.org/2000/09/xmldsig#", "KeyValue");
381             assertEquals(nodeList.getLength(), 1);
382 
383             nodeList = securedDocument.getElementsByTagNameNS("http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", "KeyIdentifier");
384             assertEquals(nodeList.getLength(), 1);
385 
386             nodeList = securedDocument.getElementsByTagNameNS("urn:oasis:names:tc:SAML:1.0:assertion", "AuthenticationStatement");
387             assertEquals(nodeList.getLength(), 1);
388 
389             nodeList = securedDocument.getElementsByTagNameNS("urn:oasis:names:tc:SAML:1.0:assertion", "ConfirmationMethod");
390             assertEquals(nodeList.getLength(), 1);
391             assertEquals(nodeList.item(0).getTextContent().trim(), "urn:oasis:names:tc:SAML:1.0:cm:holder-of-key");
392 
393             javax.xml.transform.Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
394             transformer.transform(new DOMSource(securedDocument), new StreamResult(baos));
395         }
396 
397         //done signature; now test sig-verification:
398         {
399             WSSSecurityProperties securityProperties = new WSSSecurityProperties();
400             securityProperties.loadSignatureVerificationKeystore(this.getClass().getClassLoader().getResource("receiver.jks"), "default".toCharArray());
401             InboundWSSec wsSecIn = WSSec.getInboundWSSec(securityProperties);
402             XMLStreamReader xmlStreamReader = wsSecIn.processInMessage(xmlInputFactory.createXMLStreamReader(new ByteArrayInputStream(baos.toByteArray())));
403 
404             Document document = StAX2DOM.readDoc(documentBuilderFactory.newDocumentBuilder(), xmlStreamReader);
405 
406             //header element must still be there
407             NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
408             assertEquals(nodeList.getLength(), 2);
409             assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_SAML_ASSERTION.getLocalPart());
410             assertEquals(nodeList.item(1).getParentNode().getLocalName(), WSSConstants.TAG_WSSE_SECURITY.getLocalPart());
411         }
412     }
413 
414     @Test
415     public void testSAML1AttrAssertionOutbound() throws Exception {
416 
417         ByteArrayOutputStream baos = new ByteArrayOutputStream();
418         {
419             WSSSecurityProperties securityProperties = new WSSSecurityProperties();
420             List<WSSConstants.Action> actions = new ArrayList<>();
421             actions.add(WSSConstants.SAML_TOKEN_SIGNED);
422             securityProperties.setActions(actions);
423             SAMLCallbackHandlerImpl callbackHandler = new SAMLCallbackHandlerImpl();
424             callbackHandler.setStatement(SAMLCallbackHandlerImpl.Statement.ATTR);
425             callbackHandler.setConfirmationMethod(SAML1Constants.CONF_HOLDER_KEY);
426             callbackHandler.setIssuer("www.example.com");
427             securityProperties.setSamlCallbackHandler(callbackHandler);
428             KeyStore keyStore = KeyStore.getInstance("jks");
429             keyStore.load(this.getClass().getClassLoader().getResourceAsStream("receiver.jks"), "default".toCharArray());
430             Merlin crypto = new Merlin();
431             crypto.setKeyStore(keyStore);
432             CryptoType cryptoType = new CryptoType(CryptoType.TYPE.ALIAS);
433             cryptoType.setAlias("receiver");
434             callbackHandler.setCerts(crypto.getX509Certificates(cryptoType));
435             securityProperties.loadSignatureKeyStore(this.getClass().getClassLoader().getResource("transmitter.jks"), "default".toCharArray());
436             securityProperties.setSignatureUser("transmitter");
437             securityProperties.setSignatureAlgorithm("http://www.w3.org/2001/04/xmldsig-more#hmac-sha256");
438             securityProperties.setCallbackHandler(new CallbackHandlerImpl());
439 
440             OutboundWSSec wsSecOut = WSSec.getOutboundWSSec(securityProperties);
441             XMLStreamWriter xmlStreamWriter = wsSecOut.processOutMessage(baos, StandardCharsets.UTF_8.name(), new ArrayList<SecurityEvent>());
442             XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml"));
443             XmlReaderToWriter.writeAll(xmlStreamReader, xmlStreamWriter);
444             xmlStreamWriter.close();
445 
446             Document document = documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray()));
447             NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
448             assertEquals(nodeList.getLength(), 2);
449             assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_SAML_ASSERTION.getLocalPart());
450             assertEquals(nodeList.item(1).getParentNode().getLocalName(), WSSConstants.TAG_WSSE_SECURITY.getLocalPart());
451 
452             nodeList = document.getElementsByTagNameNS("urn:oasis:names:tc:SAML:1.0:assertion", "AttributeStatement");
453             assertEquals(nodeList.getLength(), 1);
454 
455             nodeList = document.getElementsByTagNameNS("urn:oasis:names:tc:SAML:1.0:assertion", "ConfirmationMethod");
456             assertEquals(nodeList.getLength(), 1);
457             assertEquals(nodeList.item(0).getTextContent().trim(), "urn:oasis:names:tc:SAML:1.0:cm:holder-of-key");
458         }
459 
460         //done signature; now test sig-verification:
461         {
462             String action = WSHandlerConstants.SIGNATURE + " " + WSHandlerConstants.SAML_TOKEN_SIGNED;
463             Properties properties = new Properties();
464             doInboundSecurityWithWSS4J_1(documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray())), action, properties, false);
465         }
466     }
467 
468     // TODO Not working with OpenSAML 3.0 upgrade
469     @Test
470     @org.junit.jupiter.api.Disabled
471     public void testSAML1AttrAssertionInbound() throws Exception {
472 
473         ByteArrayOutputStream baos = new ByteArrayOutputStream();
474         {
475             SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
476             callbackHandler.setStatement(SAML1CallbackHandler.Statement.ATTR);
477             callbackHandler.setConfirmationMethod(SAML1Constants.CONF_HOLDER_KEY);
478             callbackHandler.setIssuer("www.example.com");
479 
480             SAMLCallback samlCallback = new SAMLCallback();
481             SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
482             SamlAssertionWrapper samlAssertion = new SamlAssertionWrapper(samlCallback);
483 
484             Crypto crypto = CryptoFactory.getInstance("saml/saml-signed.properties");
485             samlAssertion.signAssertion("transmitter", "default", crypto, false);
486 
487             Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
488             WSSecHeader secHeader = new WSSecHeader(doc);
489             secHeader.insertSecurityHeader();
490 
491             WSSecSAMLToken wsSign = new WSSecSAMLToken(secHeader);
492 
493             Document securedDocument = wsSign.build(samlAssertion);
494 
495             //some test that we can really sure we get what we want from WSS4J
496             NodeList nodeList = securedDocument.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
497             assertEquals(nodeList.getLength(), 1);
498             assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_SAML_ASSERTION.getLocalPart());
499 
500             nodeList = securedDocument.getElementsByTagNameNS("urn:oasis:names:tc:SAML:1.0:assertion", "AttributeStatement");
501             assertEquals(nodeList.getLength(), 1);
502 
503             nodeList = securedDocument.getElementsByTagNameNS("urn:oasis:names:tc:SAML:1.0:assertion", "ConfirmationMethod");
504             assertEquals(nodeList.getLength(), 1);
505             assertEquals(nodeList.item(0).getTextContent().trim(), "urn:oasis:names:tc:SAML:1.0:cm:holder-of-key");
506 
507             javax.xml.transform.Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
508             transformer.transform(new DOMSource(securedDocument), new StreamResult(baos));
509         }
510 
511         //done signature; now test sig-verification:
512         {
513             WSSSecurityProperties securityProperties = new WSSSecurityProperties();
514             securityProperties.loadSignatureVerificationKeystore(this.getClass().getClassLoader().getResource("receiver.jks"), "default".toCharArray());
515             securityProperties.setValidateSamlSubjectConfirmation(false);
516             InboundWSSec wsSecIn = WSSec.getInboundWSSec(securityProperties);
517             XMLStreamReader xmlStreamReader = wsSecIn.processInMessage(xmlInputFactory.createXMLStreamReader(new ByteArrayInputStream(baos.toByteArray())));
518 
519             Document document = StAX2DOM.readDoc(documentBuilderFactory.newDocumentBuilder(), xmlStreamReader);
520 
521             //header element must still be there
522             NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
523             assertEquals(nodeList.getLength(), 1);
524             assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_SAML_ASSERTION.getLocalPart());
525         }
526     }
527 
528     @Test
529     public void testSAMLAssertionHOKTransportSecurityInbound() throws Exception {
530 
531         ByteArrayOutputStream baos = new ByteArrayOutputStream();
532         {
533             SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
534             callbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHN);
535             callbackHandler.setConfirmationMethod(SAML1Constants.CONF_HOLDER_KEY);
536             callbackHandler.setIssuer("www.example.com");
537             //callbackHandler.setResource("http://resource.org");
538 
539             InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
540             String action = WSHandlerConstants.SAML_TOKEN_SIGNED;
541             Properties properties = new Properties();
542             properties.put(WSHandlerConstants.SAML_CALLBACK_REF, callbackHandler);
543             Document securedDocument = doOutboundSecurityWithWSS4J(sourceDocument, action, properties);
544 
545             //some test that we can really sure we get what we want from WSS4J
546             NodeList nodeList = securedDocument.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
547             assertEquals(nodeList.getLength(), 2);
548 
549             Element messageSig = (Element)nodeList.item(1);
550             messageSig.getParentNode().removeChild(messageSig);
551 
552             javax.xml.transform.Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
553             transformer.transform(new DOMSource(securedDocument), new StreamResult(baos));
554         }
555 
556         //done signature; now test sig-verification:
557         {
558             WSSSecurityProperties securityProperties = new WSSSecurityProperties();
559             securityProperties.loadSignatureVerificationKeystore(this.getClass().getClassLoader().getResource("receiver.jks"), "default".toCharArray());
560             securityProperties.setSamlCallbackHandler(new SAMLCallbackHandlerImpl());
561             InboundWSSec wsSecIn = WSSec.getInboundWSSec(securityProperties);
562 
563             HttpsTokenSecurityEvent httpsTokenSecurityEvent = new HttpsTokenSecurityEvent();
564             httpsTokenSecurityEvent.setAuthenticationType(HttpsTokenSecurityEvent.AuthenticationType.HttpsClientCertificateAuthentication);
565             CryptoType cryptoType = new CryptoType(CryptoType.TYPE.ALIAS);
566             cryptoType.setAlias("transmitter");
567             HttpsSecurityToken httpsSecurityToken = new HttpsSecurityTokenImpl(
568                     securityProperties.getSignatureVerificationCrypto().getX509Certificates(cryptoType)[0]);
569             httpsTokenSecurityEvent.setSecurityToken(httpsSecurityToken);
570 
571             List<SecurityEvent> requestSecurityEvents = new ArrayList<>();
572             requestSecurityEvents.add(httpsTokenSecurityEvent);
573 
574             XMLStreamReader xmlStreamReader = wsSecIn.processInMessage(
575                     xmlInputFactory.createXMLStreamReader(new ByteArrayInputStream(baos.toByteArray())),
576                     requestSecurityEvents);
577 
578             Document document = StAX2DOM.readDoc(documentBuilderFactory.newDocumentBuilder(), xmlStreamReader);
579 
580             //header element must still be there
581             NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
582             assertEquals(nodeList.getLength(), 1);
583         }
584     }
585 
586     @Test
587     public void testSAML2AuthnOutbound() throws Exception {
588 
589         ByteArrayOutputStream baos = new ByteArrayOutputStream();
590         {
591             WSSSecurityProperties securityProperties = new WSSSecurityProperties();
592             List<WSSConstants.Action> actions = new ArrayList<>();
593             actions.add(WSSConstants.SAML_TOKEN_SIGNED);
594             securityProperties.setActions(actions);
595             SAMLCallbackHandlerImpl callbackHandler = new SAMLCallbackHandlerImpl();
596             callbackHandler.setSamlVersion(Version.SAML_20);
597             callbackHandler.setStatement(SAMLCallbackHandlerImpl.Statement.AUTHN);
598             callbackHandler.setConfirmationMethod(SAML2Constants.CONF_HOLDER_KEY);
599             callbackHandler.setIssuer("www.example.com");
600             securityProperties.setSamlCallbackHandler(callbackHandler);
601             KeyStore keyStore = KeyStore.getInstance("jks");
602             keyStore.load(this.getClass().getClassLoader().getResourceAsStream("transmitter.jks"), "default".toCharArray());
603             Merlin crypto = new Merlin();
604             crypto.setKeyStore(keyStore);
605             CryptoType cryptoType = new CryptoType(CryptoType.TYPE.ALIAS);
606             cryptoType.setAlias("transmitter");
607             callbackHandler.setCerts(crypto.getX509Certificates(cryptoType));
608             securityProperties.loadSignatureKeyStore(this.getClass().getClassLoader().getResource("transmitter.jks"), "default".toCharArray());
609             securityProperties.setSignatureUser("transmitter");
610             securityProperties.setCallbackHandler(new CallbackHandlerImpl());
611 
612             OutboundWSSec wsSecOut = WSSec.getOutboundWSSec(securityProperties);
613             XMLStreamWriter xmlStreamWriter = wsSecOut.processOutMessage(baos, StandardCharsets.UTF_8.name(), new ArrayList<SecurityEvent>());
614             XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml"));
615             XmlReaderToWriter.writeAll(xmlStreamReader, xmlStreamWriter);
616             xmlStreamWriter.close();
617 
618             Document document = documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray()));
619             NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
620             assertEquals(nodeList.getLength(), 2);
621         }
622 
623         //done signature; now test sig-verification:
624         {
625             String action = WSHandlerConstants.SIGNATURE + " " + WSHandlerConstants.SAML_TOKEN_SIGNED;
626             Properties properties = new Properties();
627             doInboundSecurityWithWSS4J_1(documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray())), action, properties, false);
628         }
629     }
630 
631     @Test
632     public void testSAML2AuthnAssertionInbound() throws Exception {
633         ByteArrayOutputStream baos = new ByteArrayOutputStream();
634         {
635             SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
636             callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
637             callbackHandler.setConfirmationMethod(SAML2Constants.CONF_HOLDER_KEY);
638             callbackHandler.setIssuer("www.example.com");
639 
640             InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
641             String action = WSHandlerConstants.SAML_TOKEN_SIGNED;
642             Properties properties = new Properties();
643             properties.put(WSHandlerConstants.SAML_CALLBACK_REF, callbackHandler);
644             Document securedDocument = doOutboundSecurityWithWSS4J(sourceDocument, action, properties);
645 
646             //some test that we can really sure we get what we want from WSS4J
647             NodeList nodeList = securedDocument.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
648             assertEquals(nodeList.getLength(), 2);
649             assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_SAML2_ASSERTION.getLocalPart());
650             assertEquals(nodeList.item(1).getParentNode().getLocalName(), WSSConstants.TAG_WSSE_SECURITY.getLocalPart());
651 
652             javax.xml.transform.Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
653             transformer.transform(new DOMSource(securedDocument), new StreamResult(baos));
654         }
655 
656         //done signature; now test sig-verification:
657         {
658             WSSSecurityProperties securityProperties = new WSSSecurityProperties();
659             securityProperties.loadSignatureVerificationKeystore(this.getClass().getClassLoader().getResource("receiver.jks"), "default".toCharArray());
660             InboundWSSec wsSecIn = WSSec.getInboundWSSec(securityProperties);
661             XMLStreamReader xmlStreamReader = wsSecIn.processInMessage(xmlInputFactory.createXMLStreamReader(new ByteArrayInputStream(baos.toByteArray())));
662 
663             Document document = StAX2DOM.readDoc(documentBuilderFactory.newDocumentBuilder(), xmlStreamReader);
664 
665             //header element must still be there
666             NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
667             assertEquals(nodeList.getLength(), 2);
668             assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_SAML2_ASSERTION.getLocalPart());
669             assertEquals(nodeList.item(1).getParentNode().getLocalName(), WSSConstants.TAG_WSSE_SECURITY.getLocalPart());
670         }
671     }
672 
673     @Test
674     public void testSAML2AuthnAssertionIssuerSerialOutbound() throws Exception {
675 
676         ByteArrayOutputStream baos = new ByteArrayOutputStream();
677         {
678             WSSSecurityProperties securityProperties = new WSSSecurityProperties();
679             List<WSSConstants.Action> actions = new ArrayList<>();
680             actions.add(WSSConstants.SAML_TOKEN_SIGNED);
681             securityProperties.setActions(actions);
682             SAMLCallbackHandlerImpl callbackHandler = new SAMLCallbackHandlerImpl();
683             callbackHandler.setSamlVersion(Version.SAML_20);
684             callbackHandler.setStatement(SAMLCallbackHandlerImpl.Statement.AUTHN);
685             callbackHandler.setConfirmationMethod(SAML2Constants.CONF_HOLDER_KEY);
686             callbackHandler.setCertIdentifier(KeyInfoBean.CERT_IDENTIFIER.X509_ISSUER_SERIAL);
687             callbackHandler.setIssuer("www.example.com");
688             securityProperties.setSamlCallbackHandler(callbackHandler);
689             KeyStore keyStore = KeyStore.getInstance("jks");
690             keyStore.load(this.getClass().getClassLoader().getResourceAsStream("transmitter.jks"), "default".toCharArray());
691             Merlin crypto = new Merlin();
692             crypto.setKeyStore(keyStore);
693             CryptoType cryptoType = new CryptoType(CryptoType.TYPE.ALIAS);
694             cryptoType.setAlias("transmitter");
695             callbackHandler.setCerts(crypto.getX509Certificates(cryptoType));
696             securityProperties.loadSignatureKeyStore(this.getClass().getClassLoader().getResource("transmitter.jks"), "default".toCharArray());
697             securityProperties.setSignatureUser("transmitter");
698             securityProperties.setSignatureKeyIdentifier(WSSecurityTokenConstants.KEYIDENTIFIER_EMBEDDED_KEY_IDENTIFIER_REF);
699             securityProperties.setCallbackHandler(new CallbackHandlerImpl());
700 
701             OutboundWSSec wsSecOut = WSSec.getOutboundWSSec(securityProperties);
702             XMLStreamWriter xmlStreamWriter = wsSecOut.processOutMessage(baos, StandardCharsets.UTF_8.name(), new ArrayList<SecurityEvent>());
703             XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml"));
704             XmlReaderToWriter.writeAll(xmlStreamReader, xmlStreamWriter);
705             xmlStreamWriter.close();
706 
707             Document document = documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray()));
708             NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
709             assertEquals(nodeList.getLength(), 2);
710             assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_SAML_ASSERTION.getLocalPart());
711             assertEquals(nodeList.item(1).getParentNode().getLocalName(), WSSConstants.TAG_WSSE_SECURITY.getLocalPart());
712 
713             nodeList = document.getElementsByTagNameNS("http://www.w3.org/2000/09/xmldsig#", "X509IssuerSerial");
714             assertEquals(nodeList.getLength(), 1);
715 
716             nodeList = document.getElementsByTagNameNS("http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", "KeyIdentifier");
717             assertEquals(nodeList.getLength(), 1);
718 
719             nodeList = document.getElementsByTagNameNS("urn:oasis:names:tc:SAML:2.0:assertion", "AuthnStatement");
720             assertEquals(nodeList.getLength(), 1);
721 
722             nodeList = document.getElementsByTagNameNS("urn:oasis:names:tc:SAML:2.0:assertion", "SubjectConfirmation");
723             assertEquals(nodeList.getLength(), 1);
724             assertEquals(((Element) nodeList.item(0)).getAttributeNS(null, "Method"), "urn:oasis:names:tc:SAML:2.0:cm:holder-of-key");
725         }
726 
727         //done signature; now test sig-verification:
728         {
729             String action = WSHandlerConstants.SIGNATURE + " " + WSHandlerConstants.SAML_TOKEN_SIGNED;
730             Properties properties = new Properties();
731             doInboundSecurityWithWSS4J_1(documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray())), action, properties, false);
732         }
733     }
734 
735     @Test
736     public void testSAML2AuthnAssertionIssuerSerialInbound() throws Exception {
737 
738         ByteArrayOutputStream baos = new ByteArrayOutputStream();
739         {
740             SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
741             callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
742             callbackHandler.setConfirmationMethod(SAML2Constants.CONF_HOLDER_KEY);
743             callbackHandler.setCertIdentifier(KeyInfoBean.CERT_IDENTIFIER.X509_ISSUER_SERIAL);
744             callbackHandler.setIssuer("www.example.com");
745 
746             InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
747             String action = WSHandlerConstants.SAML_TOKEN_SIGNED;
748             Properties properties = new Properties();
749             properties.put(WSHandlerConstants.SAML_CALLBACK_REF, callbackHandler);
750             properties.put(WSHandlerConstants.SIG_KEY_ID, "DirectReference");
751             Document securedDocument = doOutboundSecurityWithWSS4J(sourceDocument, action, properties);
752 
753             //some test that we can really sure we get what we want from WSS4J
754             NodeList nodeList = securedDocument.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
755             assertEquals(nodeList.getLength(), 2);
756             assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_SAML_ASSERTION.getLocalPart());
757             assertEquals(nodeList.item(1).getParentNode().getLocalName(), WSSConstants.TAG_WSSE_SECURITY.getLocalPart());
758 
759             nodeList = securedDocument.getElementsByTagNameNS("http://www.w3.org/2000/09/xmldsig#", "X509IssuerSerial");
760             assertEquals(nodeList.getLength(), 1);
761 
762             nodeList = securedDocument.getElementsByTagNameNS("http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", "KeyIdentifier");
763             assertEquals(nodeList.getLength(), 1);
764 
765             nodeList = securedDocument.getElementsByTagNameNS("urn:oasis:names:tc:SAML:2.0:assertion", "AuthnStatement");
766             assertEquals(nodeList.getLength(), 1);
767 
768             nodeList = securedDocument.getElementsByTagNameNS("urn:oasis:names:tc:SAML:2.0:assertion", "SubjectConfirmation");
769             assertEquals(nodeList.getLength(), 1);
770             assertEquals(((Element) nodeList.item(0)).getAttributeNS(null, "Method"), "urn:oasis:names:tc:SAML:2.0:cm:holder-of-key");
771 
772             javax.xml.transform.Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
773             transformer.transform(new DOMSource(securedDocument), new StreamResult(baos));
774         }
775 
776         //done signature; now test sig-verification:
777         {
778             WSSSecurityProperties securityProperties = new WSSSecurityProperties();
779             securityProperties.loadSignatureVerificationKeystore(this.getClass().getClassLoader().getResource("receiver.jks"), "default".toCharArray());
780             InboundWSSec wsSecIn = WSSec.getInboundWSSec(securityProperties);
781             XMLStreamReader xmlStreamReader = wsSecIn.processInMessage(xmlInputFactory.createXMLStreamReader(new ByteArrayInputStream(baos.toByteArray())));
782 
783             Document document = StAX2DOM.readDoc(documentBuilderFactory.newDocumentBuilder(), xmlStreamReader);
784 
785             //header element must still be there
786             NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
787             assertEquals(nodeList.getLength(), 2);
788             assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_SAML_ASSERTION.getLocalPart());
789             assertEquals(nodeList.item(1).getParentNode().getLocalName(), WSSConstants.TAG_WSSE_SECURITY.getLocalPart());
790         }
791     }
792 
793     @Test
794     public void testSAML2AuthnAssertionKeyValueOutbound() throws Exception {
795 
796         ByteArrayOutputStream baos = new ByteArrayOutputStream();
797         {
798             WSSSecurityProperties securityProperties = new WSSSecurityProperties();
799             List<WSSConstants.Action> actions = new ArrayList<>();
800             actions.add(WSSConstants.SAML_TOKEN_SIGNED);
801             securityProperties.setActions(actions);
802             SAMLCallbackHandlerImpl callbackHandler = new SAMLCallbackHandlerImpl();
803             callbackHandler.setSamlVersion(Version.SAML_20);
804             callbackHandler.setStatement(SAMLCallbackHandlerImpl.Statement.AUTHN);
805             callbackHandler.setConfirmationMethod(SAML2Constants.CONF_HOLDER_KEY);
806             callbackHandler.setCertIdentifier(KeyInfoBean.CERT_IDENTIFIER.KEY_VALUE);
807             callbackHandler.setIssuer("www.example.com");
808             securityProperties.setSamlCallbackHandler(callbackHandler);
809             KeyStore keyStore = KeyStore.getInstance("jks");
810             keyStore.load(this.getClass().getClassLoader().getResourceAsStream("transmitter.jks"), "default".toCharArray());
811             Merlin crypto = new Merlin();
812             crypto.setKeyStore(keyStore);
813             CryptoType cryptoType = new CryptoType(CryptoType.TYPE.ALIAS);
814             cryptoType.setAlias("transmitter");
815             callbackHandler.setCerts(crypto.getX509Certificates(cryptoType));
816             securityProperties.loadSignatureKeyStore(this.getClass().getClassLoader().getResource("transmitter.jks"), "default".toCharArray());
817             securityProperties.setSignatureUser("transmitter");
818             securityProperties.setSignatureKeyIdentifier(WSSecurityTokenConstants.KEYIDENTIFIER_EMBEDDED_KEY_IDENTIFIER_REF);
819             securityProperties.setCallbackHandler(new CallbackHandlerImpl());
820 
821             OutboundWSSec wsSecOut = WSSec.getOutboundWSSec(securityProperties);
822             XMLStreamWriter xmlStreamWriter = wsSecOut.processOutMessage(baos, StandardCharsets.UTF_8.name(), new ArrayList<SecurityEvent>());
823             XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml"));
824             XmlReaderToWriter.writeAll(xmlStreamReader, xmlStreamWriter);
825             xmlStreamWriter.close();
826 
827             Document document = documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray()));
828             NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
829             assertEquals(nodeList.getLength(), 2);
830             assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_SAML_ASSERTION.getLocalPart());
831             assertEquals(nodeList.item(1).getParentNode().getLocalName(), WSSConstants.TAG_WSSE_SECURITY.getLocalPart());
832 
833             nodeList = document.getElementsByTagNameNS("http://www.w3.org/2000/09/xmldsig#", "KeyValue");
834             assertEquals(nodeList.getLength(), 1);
835 
836             nodeList = document.getElementsByTagNameNS("http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", "KeyIdentifier");
837             assertEquals(nodeList.getLength(), 1);
838 
839             nodeList = document.getElementsByTagNameNS("urn:oasis:names:tc:SAML:2.0:assertion", "AuthnStatement");
840             assertEquals(nodeList.getLength(), 1);
841 
842             nodeList = document.getElementsByTagNameNS("urn:oasis:names:tc:SAML:2.0:assertion", "SubjectConfirmation");
843             assertEquals(nodeList.getLength(), 1);
844             assertEquals(((Element) nodeList.item(0)).getAttributeNS(null, "Method"), "urn:oasis:names:tc:SAML:2.0:cm:holder-of-key");
845         }
846 
847         //done signature; now test sig-verification:
848         {
849             String action = WSHandlerConstants.SIGNATURE + " " + WSHandlerConstants.SAML_TOKEN_SIGNED;
850             Properties properties = new Properties();
851             doInboundSecurityWithWSS4J_1(documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray())), action, properties, false);
852         }
853     }
854 
855     @Test
856     public void testSAML2AuthnAssertionKeyValueInbound() throws Exception {
857 
858         ByteArrayOutputStream baos = new ByteArrayOutputStream();
859         {
860             SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
861             callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
862             callbackHandler.setConfirmationMethod(SAML2Constants.CONF_HOLDER_KEY);
863             callbackHandler.setCertIdentifier(KeyInfoBean.CERT_IDENTIFIER.KEY_VALUE);
864             callbackHandler.setIssuer("www.example.com");
865 
866             InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
867             String action = WSHandlerConstants.SAML_TOKEN_SIGNED;
868             Properties properties = new Properties();
869             properties.put(WSHandlerConstants.SAML_CALLBACK_REF, callbackHandler);
870             properties.put(WSHandlerConstants.SIG_KEY_ID, "DirectReference");
871             Document securedDocument = doOutboundSecurityWithWSS4J(sourceDocument, action, properties);
872 
873             //some test that we can really sure we get what we want from WSS4J
874             NodeList nodeList = securedDocument.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
875             assertEquals(nodeList.getLength(), 2);
876             assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_SAML_ASSERTION.getLocalPart());
877             assertEquals(nodeList.item(1).getParentNode().getLocalName(), WSSConstants.TAG_WSSE_SECURITY.getLocalPart());
878 
879             nodeList = securedDocument.getElementsByTagNameNS("http://www.w3.org/2000/09/xmldsig#", "KeyValue");
880             assertEquals(nodeList.getLength(), 1);
881 
882             nodeList = securedDocument.getElementsByTagNameNS("http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", "KeyIdentifier");
883             assertEquals(nodeList.getLength(), 1);
884 
885             nodeList = securedDocument.getElementsByTagNameNS("urn:oasis:names:tc:SAML:2.0:assertion", "AuthnStatement");
886             assertEquals(nodeList.getLength(), 1);
887 
888             nodeList = securedDocument.getElementsByTagNameNS("urn:oasis:names:tc:SAML:2.0:assertion", "SubjectConfirmation");
889             assertEquals(nodeList.getLength(), 1);
890             assertEquals(((Element) nodeList.item(0)).getAttributeNS(null, "Method"), "urn:oasis:names:tc:SAML:2.0:cm:holder-of-key");
891 
892             javax.xml.transform.Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
893             transformer.transform(new DOMSource(securedDocument), new StreamResult(baos));
894         }
895 
896         //done signature; now test sig-verification:
897         {
898             WSSSecurityProperties securityProperties = new WSSSecurityProperties();
899             securityProperties.loadSignatureVerificationKeystore(this.getClass().getClassLoader().getResource("receiver.jks"), "default".toCharArray());
900             InboundWSSec wsSecIn = WSSec.getInboundWSSec(securityProperties);
901             XMLStreamReader xmlStreamReader = wsSecIn.processInMessage(xmlInputFactory.createXMLStreamReader(new ByteArrayInputStream(baos.toByteArray())));
902 
903             Document document = StAX2DOM.readDoc(documentBuilderFactory.newDocumentBuilder(), xmlStreamReader);
904 
905             //header element must still be there
906             NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
907             assertEquals(nodeList.getLength(), 2);
908             assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_SAML_ASSERTION.getLocalPart());
909             assertEquals(nodeList.item(1).getParentNode().getLocalName(), WSSConstants.TAG_WSSE_SECURITY.getLocalPart());
910         }
911     }
912 
913     @Test
914     public void testSAML2AttrAssertionOutbound() throws Exception {
915 
916         ByteArrayOutputStream baos = new ByteArrayOutputStream();
917         {
918             WSSSecurityProperties securityProperties = new WSSSecurityProperties();
919             List<WSSConstants.Action> actions = new ArrayList<>();
920             actions.add(WSSConstants.SAML_TOKEN_SIGNED);
921             securityProperties.setActions(actions);
922             SAMLCallbackHandlerImpl callbackHandler = new SAMLCallbackHandlerImpl();
923             callbackHandler.setSamlVersion(Version.SAML_20);
924             callbackHandler.setStatement(SAMLCallbackHandlerImpl.Statement.ATTR);
925             callbackHandler.setConfirmationMethod(SAML2Constants.CONF_HOLDER_KEY);
926             callbackHandler.setIssuer("www.example.com");
927             securityProperties.setSamlCallbackHandler(callbackHandler);
928             KeyStore keyStore = KeyStore.getInstance("jks");
929             keyStore.load(this.getClass().getClassLoader().getResourceAsStream("transmitter.jks"), "default".toCharArray());
930             Merlin crypto = new Merlin();
931             crypto.setKeyStore(keyStore);
932             CryptoType cryptoType = new CryptoType(CryptoType.TYPE.ALIAS);
933             cryptoType.setAlias("receiver");
934             callbackHandler.setCerts(crypto.getX509Certificates(cryptoType));
935             securityProperties.loadSignatureKeyStore(this.getClass().getClassLoader().getResource("transmitter.jks"), "default".toCharArray());
936             securityProperties.setSignatureUser("receiver");
937             securityProperties.setSignatureAlgorithm("http://www.w3.org/2001/04/xmldsig-more#hmac-sha256");
938             securityProperties.setCallbackHandler(new CallbackHandlerImpl());
939 
940             OutboundWSSec wsSecOut = WSSec.getOutboundWSSec(securityProperties);
941             XMLStreamWriter xmlStreamWriter = wsSecOut.processOutMessage(baos, StandardCharsets.UTF_8.name(), new ArrayList<SecurityEvent>());
942             XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml"));
943             XmlReaderToWriter.writeAll(xmlStreamReader, xmlStreamWriter);
944             xmlStreamWriter.close();
945 
946             Document document = documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray()));
947             NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
948             assertEquals(nodeList.getLength(), 2);
949             assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_SAML_ASSERTION.getLocalPart());
950             assertEquals(nodeList.item(1).getParentNode().getLocalName(), WSSConstants.TAG_WSSE_SECURITY.getLocalPart());
951 
952             nodeList = document.getElementsByTagNameNS("urn:oasis:names:tc:SAML:2.0:assertion", "AttributeStatement");
953             assertEquals(nodeList.getLength(), 1);
954 
955             nodeList = document.getElementsByTagNameNS("urn:oasis:names:tc:SAML:2.0:assertion", "SubjectConfirmation");
956             assertEquals(nodeList.getLength(), 1);
957             assertEquals(((Element)nodeList.item(0)).getAttributeNS(null, "Method"), "urn:oasis:names:tc:SAML:2.0:cm:holder-of-key");
958         }
959 
960         //done signature; now test sig-verification:
961         {
962             String action = WSHandlerConstants.SIGNATURE + " " + WSHandlerConstants.SAML_TOKEN_SIGNED;
963             Properties properties = new Properties();
964             doInboundSecurityWithWSS4J_1(documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray())), action, properties, false);
965         }
966     }
967 
968     // TODO Not working with OpenSAML 3.0 upgrade
969     @Test
970     @org.junit.jupiter.api.Disabled
971     public void testSAML2AttrAssertionInbound() throws Exception {
972 
973         ByteArrayOutputStream baos = new ByteArrayOutputStream();
974         {
975             SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
976             callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
977             callbackHandler.setConfirmationMethod(SAML2Constants.CONF_HOLDER_KEY);
978             callbackHandler.setIssuer("www.example.com");
979 
980             SAMLCallback samlCallback = new SAMLCallback();
981             SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
982             SamlAssertionWrapper samlAssertion = new SamlAssertionWrapper(samlCallback);
983 
984             Crypto crypto = CryptoFactory.getInstance("saml/saml-signed.properties");
985             samlAssertion.signAssertion("transmitter", "default", crypto, false);
986 
987             Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
988             WSSecHeader secHeader = new WSSecHeader(doc);
989             secHeader.insertSecurityHeader();
990 
991             WSSecSAMLToken wsSign = new WSSecSAMLToken(secHeader);
992 
993             Document securedDocument = wsSign.build(samlAssertion);
994 
995             //some test that we can really sure we get what we want from WSS4J
996             NodeList nodeList = securedDocument.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
997             assertEquals(nodeList.getLength(), 1);
998             assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_SAML_ASSERTION.getLocalPart());
999 
1000             nodeList = securedDocument.getElementsByTagNameNS("urn:oasis:names:tc:SAML:2.0:assertion", "AttributeStatement");
1001             assertEquals(nodeList.getLength(), 1);
1002 
1003             nodeList = securedDocument.getElementsByTagNameNS("urn:oasis:names:tc:SAML:2.0:assertion", "SubjectConfirmation");
1004             assertEquals(nodeList.getLength(), 1);
1005             assertEquals(((Element) nodeList.item(0)).getAttributeNS(null, "Method"), "urn:oasis:names:tc:SAML:2.0:cm:holder-of-key");
1006 
1007             javax.xml.transform.Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
1008             transformer.transform(new DOMSource(securedDocument), new StreamResult(baos));
1009         }
1010 
1011         //done signature; now test sig-verification:
1012         {
1013             WSSSecurityProperties securityProperties = new WSSSecurityProperties();
1014             securityProperties.setValidateSamlSubjectConfirmation(false);
1015             securityProperties.loadSignatureVerificationKeystore(this.getClass().getClassLoader().getResource("receiver.jks"), "default".toCharArray());
1016             InboundWSSec wsSecIn = WSSec.getInboundWSSec(securityProperties);
1017             XMLStreamReader xmlStreamReader = wsSecIn.processInMessage(xmlInputFactory.createXMLStreamReader(new ByteArrayInputStream(baos.toByteArray())));
1018 
1019             Document document = StAX2DOM.readDoc(documentBuilderFactory.newDocumentBuilder(), xmlStreamReader);
1020 
1021             //header element must still be there
1022             NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
1023             assertEquals(nodeList.getLength(), 1);
1024             assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_SAML_ASSERTION.getLocalPart());
1025         }
1026     }
1027 
1028 }