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  
20  package org.apache.wss4j.dom.saml;
21  
22  import java.io.ByteArrayInputStream;
23  import java.io.InputStream;
24  import java.security.Key;
25  import java.security.Principal;
26  import java.security.cert.X509Certificate;
27  import java.time.Duration;
28  import java.time.Instant;
29  import java.util.ArrayList;
30  import java.util.Collections;
31  import java.util.List;
32  
33  import javax.crypto.KeyGenerator;
34  import javax.crypto.SecretKey;
35  import javax.security.auth.callback.CallbackHandler;
36  import javax.xml.parsers.DocumentBuilderFactory;
37  
38  import org.apache.wss4j.common.bsp.BSPRule;
39  import org.apache.wss4j.common.crypto.Crypto;
40  import org.apache.wss4j.common.crypto.CryptoFactory;
41  import org.apache.wss4j.common.crypto.CryptoType;
42  import org.apache.wss4j.common.ext.WSSecurityException;
43  import org.apache.wss4j.common.saml.SAMLCallback;
44  import org.apache.wss4j.common.saml.SAMLUtil;
45  import org.apache.wss4j.common.saml.SamlAssertionWrapper;
46  import org.apache.wss4j.common.saml.bean.NameIDBean;
47  import org.apache.wss4j.common.saml.bean.SubjectConfirmationDataBean;
48  import org.apache.wss4j.common.saml.builder.SAML1Constants;
49  import org.apache.wss4j.common.saml.builder.SAML2Constants;
50  import org.apache.wss4j.common.token.SecurityTokenReference;
51  import org.apache.wss4j.common.util.DOM2Writer;
52  import org.apache.wss4j.common.util.SOAPUtil;
53  import org.apache.wss4j.common.util.XMLUtils;
54  import org.apache.wss4j.dom.WSConstants;
55  import org.apache.wss4j.dom.common.CustomHandler;
56  import org.apache.wss4j.dom.common.CustomSamlAssertionValidator;
57  import org.apache.wss4j.dom.common.KeystoreCallbackHandler;
58  import org.apache.wss4j.dom.common.SAML1CallbackHandler;
59  import org.apache.wss4j.dom.common.SAML2CallbackHandler;
60  import org.apache.wss4j.dom.common.SAMLElementCallbackHandler;
61  
62  import org.apache.wss4j.dom.engine.WSSConfig;
63  import org.apache.wss4j.dom.engine.WSSecurityEngine;
64  import org.apache.wss4j.dom.engine.WSSecurityEngineResult;
65  import org.apache.wss4j.dom.handler.HandlerAction;
66  import org.apache.wss4j.dom.handler.RequestData;
67  import org.apache.wss4j.dom.handler.WSHandlerConstants;
68  import org.apache.wss4j.dom.handler.WSHandlerResult;
69  import org.apache.wss4j.dom.message.WSSecHeader;
70  import org.apache.wss4j.dom.message.WSSecSAMLToken;
71  import org.apache.wss4j.dom.validate.SamlAssertionValidator;
72  import org.apache.xml.security.encryption.EncryptedData;
73  import org.apache.xml.security.encryption.EncryptedKey;
74  import org.apache.xml.security.encryption.Reference;
75  import org.apache.xml.security.encryption.ReferenceList;
76  import org.apache.xml.security.encryption.XMLCipher;
77  import org.apache.xml.security.keys.KeyInfo;
78  import org.apache.xml.security.keys.content.RetrievalMethod;
79  import org.apache.xml.security.keys.content.X509Data;
80  import org.apache.xml.security.stax.impl.util.IDGenerator;
81  
82  import org.junit.jupiter.api.Test;
83  import org.opensaml.core.xml.XMLObjectBuilder;
84  import org.opensaml.core.xml.XMLObjectBuilderFactory;
85  import org.opensaml.core.xml.config.XMLObjectProviderRegistrySupport;
86  import org.opensaml.core.xml.schema.XSAny;
87  import org.opensaml.core.xml.schema.XSInteger;
88  import org.opensaml.saml.common.SAMLObjectBuilder;
89  import org.opensaml.saml.saml2.core.AttributeValue;
90  import org.opensaml.saml.saml2.core.Conditions;
91  import org.w3c.dom.Document;
92  import org.w3c.dom.Element;
93  
94  import static org.junit.jupiter.api.Assertions.assertEquals;
95  import static org.junit.jupiter.api.Assertions.assertFalse;
96  import static org.junit.jupiter.api.Assertions.assertNotNull;
97  import static org.junit.jupiter.api.Assertions.assertNull;
98  import static org.junit.jupiter.api.Assertions.assertTrue;
99  import static org.junit.jupiter.api.Assertions.fail;
100 
101 /**
102  * Test-case for sending and processing an unsigned (sender vouches) SAML Assertion.
103  */
104 public class SamlTokenTest {
105     private static final org.slf4j.Logger LOG =
106         org.slf4j.LoggerFactory.getLogger(SamlTokenTest.class);
107     private WSSecurityEngine secEngine = new WSSecurityEngine();
108     private static final String IP_ADDRESS = "12.34.56.78"; //NOPMD
109 
110     public SamlTokenTest() {
111         WSSConfig config = WSSConfig.getNewInstance();
112         config.setValidator(WSConstants.SAML_TOKEN, new CustomSamlAssertionValidator());
113         config.setValidator(WSConstants.SAML2_TOKEN, new CustomSamlAssertionValidator());
114         secEngine.setWssConfig(config);
115     }
116 
117     /**
118      * Test that creates, sends and processes an unsigned SAML 1.1 authentication assertion.
119      */
120     @Test
121     public void testSAML1AuthnAssertion() throws Exception {
122         SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
123         callbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHN);
124         callbackHandler.setIssuer("www.example.com");
125 
126         WSHandlerResult results =
127             createAndVerifyMessage(callbackHandler, true);
128         WSSecurityEngineResult actionResult =
129             results.getActionResults().get(WSConstants.ST_UNSIGNED).get(0);
130 
131         SamlAssertionWrapper receivedSamlAssertion =
132             (SamlAssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
133         assertNotNull(receivedSamlAssertion);
134         assertFalse(receivedSamlAssertion.isSigned());
135         assertTrue(receivedSamlAssertion.getSignatureValue().length == 0);
136     }
137 
138     /**
139      * Test that creates, sends and processes an unsigned SAML 1.1 authentication assertion.
140      * It set a DOM Element on the CallbackHandler rather than creating a set of beans for
141      * SamlAssertionWrapper to parse.
142      */
143     @Test
144     public void testSAML1AuthnAssertionViaElement() throws Exception {
145         SAMLElementCallbackHandler callbackHandler = new SAMLElementCallbackHandler();
146         callbackHandler.setIssuer("www.example.com");
147 
148         WSHandlerResult results =
149             createAndVerifyMessage(callbackHandler, true);
150         WSSecurityEngineResult actionResult =
151             results.getActionResults().get(WSConstants.ST_UNSIGNED).get(0);
152 
153         SamlAssertionWrapper receivedSamlAssertion =
154             (SamlAssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
155         assertNotNull(receivedSamlAssertion);
156         assertFalse(receivedSamlAssertion.isSigned());
157         assertTrue(receivedSamlAssertion.getSignatureValue().length == 0);
158     }
159 
160     /**
161      * Test that creates, sends and processes an unsigned SAML 1.1 attribute assertion.
162      */
163     @Test
164     public void testSAML1AttrAssertion() throws Exception {
165         SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
166         callbackHandler.setStatement(SAML1CallbackHandler.Statement.ATTR);
167         callbackHandler.setIssuer("www.example.com");
168 
169         WSHandlerResult results =
170             createAndVerifyMessage(callbackHandler, true);
171         WSSecurityEngineResult actionResult =
172             results.getActionResults().get(WSConstants.ST_UNSIGNED).get(0);
173 
174         SamlAssertionWrapper receivedSamlAssertion =
175             (SamlAssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
176         assertNotNull(receivedSamlAssertion);
177         assertFalse(receivedSamlAssertion.isSigned());
178     }
179 
180     /**
181      * Test that creates, sends and processes an unsigned SAML 1.1 authorization assertion.
182      */
183     @Test
184     public void testSAML1AuthzAssertion() throws Exception {
185         SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
186         callbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHZ);
187         callbackHandler.setIssuer("www.example.com");
188         callbackHandler.setResource("http://resource.org");
189 
190         WSHandlerResult results =
191             createAndVerifyMessage(callbackHandler, true);
192         WSSecurityEngineResult actionResult =
193             results.getActionResults().get(WSConstants.ST_UNSIGNED).get(0);
194 
195         SamlAssertionWrapper receivedSamlAssertion =
196             (SamlAssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
197         assertNotNull(receivedSamlAssertion);
198         assertFalse(receivedSamlAssertion.isSigned());
199     }
200 
201     /**
202      * Test that creates, sends and processes an unsigned SAML 2 authentication assertion.
203      */
204     @Test
205     public void testSAML2AuthnAssertion() throws Exception {
206         SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
207         callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
208         callbackHandler.setIssuer("www.example.com");
209 
210         WSHandlerResult results =
211             createAndVerifyMessage(callbackHandler, true);
212         WSSecurityEngineResult actionResult =
213             results.getActionResults().get(WSConstants.ST_UNSIGNED).get(0);
214 
215         SamlAssertionWrapper receivedSamlAssertion =
216             (SamlAssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
217         assertNotNull(receivedSamlAssertion);
218         assertFalse(receivedSamlAssertion.isSigned());
219     }
220 
221     /**
222      * Test that creates, sends and processes an unsigned SAML 2 attribute assertion.
223      */
224     @Test
225     public void testSAML2AttrAssertion() throws Exception {
226         SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
227         callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
228         callbackHandler.setIssuer("www.example.com");
229 
230         WSHandlerResult results =
231             createAndVerifyMessage(callbackHandler, true);
232         WSSecurityEngineResult actionResult =
233             results.getActionResults().get(WSConstants.ST_UNSIGNED).get(0);
234 
235         SamlAssertionWrapper receivedSamlAssertion =
236             (SamlAssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
237         assertNotNull(receivedSamlAssertion);
238         assertFalse(receivedSamlAssertion.isSigned());
239     }
240 
241     /**
242      * Test that creates, sends and processes an unsigned SAML 2 authorization assertion.
243      */
244     @Test
245     public void testSAML2AuthzAssertion() throws Exception {
246         SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
247         callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHZ);
248         callbackHandler.setIssuer("www.example.com");
249         callbackHandler.setResource("http://resource.org");
250 
251         WSHandlerResult results =
252             createAndVerifyMessage(callbackHandler, true);
253         WSSecurityEngineResult actionResult =
254             results.getActionResults().get(WSConstants.ST_UNSIGNED).get(0);
255 
256         SamlAssertionWrapper receivedSamlAssertion =
257             (SamlAssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
258         assertNotNull(receivedSamlAssertion);
259         assertFalse(receivedSamlAssertion.isSigned());
260     }
261 
262     /**
263      * This test checks that an unsigned SAML1 sender-vouches authentication assertion
264      * can be created by the WSHandler implementation
265      */
266     @Test
267     public void testSaml1Action() throws Exception {
268         final WSSConfig cfg = WSSConfig.getNewInstance();
269         final RequestData reqData = new RequestData();
270         reqData.setWssConfig(cfg);
271         java.util.Map<String, Object> config = new java.util.TreeMap<>();
272         config.put(WSHandlerConstants.SAML_CALLBACK_REF, new SAML1CallbackHandler());
273         reqData.setMsgContext(config);
274 
275         final Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
276         CustomHandler handler = new CustomHandler();
277         HandlerAction action = new HandlerAction(WSConstants.ST_UNSIGNED);
278         handler.send(
279             doc,
280             reqData,
281             Collections.singletonList(action),
282             true
283         );
284         String outputString =
285             XMLUtils.prettyDocumentToString(doc);
286         if (LOG.isDebugEnabled()) {
287             LOG.debug("Unsigned SAML 1.1 authentication assertion via an Action:");
288             LOG.debug(outputString);
289         }
290         assertFalse(outputString.contains("Signature"));
291 
292         WSHandlerResult results = verify(doc);
293         WSSecurityEngineResult actionResult =
294             results.getActionResults().get(WSConstants.ST_UNSIGNED).get(0);
295 
296         SamlAssertionWrapper receivedSamlAssertion =
297             (SamlAssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
298         assertNotNull(receivedSamlAssertion);
299         assertFalse(receivedSamlAssertion.isSigned());
300     }
301 
302     /**
303      * Test that creates, sends and processes an unsigned SAML 1.1 authentication assertion.
304      * The issuer is different from what the custom Validator is expecting, so it throws an
305      * exception.
306      */
307     @Test
308     public void testSAML1AuthnBadIssuerAssertion() throws Exception {
309         SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
310         callbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHN);
311         callbackHandler.setIssuer("www.example2.com");
312 
313         createAndVerifyMessage(callbackHandler, false);
314     }
315 
316     /**
317      * Test that creates, sends and processes an unsigned SAML 2 authentication assertion.
318      * The issuer is different from what the custom Validator is expecting, so it throws an
319      * exception.
320      */
321     @Test
322     public void testSAML2AuthnBadIssuerAssertion() throws Exception {
323         SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
324         callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
325         callbackHandler.setIssuer("www.example2.com");
326 
327         createAndVerifyMessage(callbackHandler, false);
328     }
329 
330     /**
331      * Test that creates, sends and processes an unsigned SAML 1.1 authentication assertion with
332      * a user-specified SubjectNameIDFormat.
333      */
334     @Test
335     public void testSAML1SubjectNameIDFormat() throws Exception {
336         SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
337         callbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHN);
338         callbackHandler.setIssuer("www.example.com");
339         callbackHandler.setSubjectNameIDFormat(SAML1Constants.NAMEID_FORMAT_EMAIL_ADDRESS);
340 
341         SAMLCallback samlCallback = new SAMLCallback();
342         SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
343         SamlAssertionWrapper samlAssertion = new SamlAssertionWrapper(samlCallback);
344 
345         Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
346         WSSecHeader secHeader = new WSSecHeader(doc);
347         secHeader.insertSecurityHeader();
348 
349         WSSecSAMLToken wsSign = new WSSecSAMLToken(secHeader);
350 
351         Document unsignedDoc = wsSign.build(samlAssertion);
352 
353         String outputString =
354             XMLUtils.prettyDocumentToString(unsignedDoc);
355         if (LOG.isDebugEnabled()) {
356             LOG.debug("SAML 1.1 Authn Assertion (sender vouches):");
357             LOG.debug(outputString);
358         }
359         assertTrue(outputString.contains(SAML1Constants.NAMEID_FORMAT_EMAIL_ADDRESS));
360 
361         WSHandlerResult results = verify(unsignedDoc);
362         WSSecurityEngineResult actionResult =
363             results.getActionResults().get(WSConstants.ST_UNSIGNED).get(0);
364 
365         SamlAssertionWrapper receivedSamlAssertion =
366             (SamlAssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
367         assertNotNull(receivedSamlAssertion);
368         assertFalse(receivedSamlAssertion.isSigned());
369     }
370 
371     /**
372      * Test that creates, sends and processes an unsigned SAML 2 authentication assertion with
373      * a user-specified SubjectNameIDFormat.
374      */
375     @Test
376     public void testSAML2SubjectNameIDFormat() throws Exception {
377         SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
378         callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
379         callbackHandler.setIssuer("www.example.com");
380         callbackHandler.setSubjectNameIDFormat(SAML1Constants.NAMEID_FORMAT_EMAIL_ADDRESS);
381 
382         SAMLCallback samlCallback = new SAMLCallback();
383         SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
384         SamlAssertionWrapper samlAssertion = new SamlAssertionWrapper(samlCallback);
385 
386         Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
387         WSSecHeader secHeader = new WSSecHeader(doc);
388         secHeader.insertSecurityHeader();
389 
390         WSSecSAMLToken wsSign = new WSSecSAMLToken(secHeader);
391 
392         Document unsignedDoc = wsSign.build(samlAssertion);
393 
394         String outputString =
395             XMLUtils.prettyDocumentToString(unsignedDoc);
396         if (LOG.isDebugEnabled()) {
397             LOG.debug("SAML 2 Authn Assertion (sender vouches):");
398             LOG.debug(outputString);
399         }
400         assertTrue(outputString.contains(SAML1Constants.NAMEID_FORMAT_EMAIL_ADDRESS));
401 
402         WSHandlerResult results = verify(unsignedDoc);
403         WSSecurityEngineResult actionResult =
404             results.getActionResults().get(WSConstants.ST_UNSIGNED).get(0);
405 
406         SamlAssertionWrapper receivedSamlAssertion =
407             (SamlAssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
408         assertNotNull(receivedSamlAssertion);
409         assertFalse(receivedSamlAssertion.isSigned());
410     }
411 
412     /**
413      * Test that creates, sends and processes an unsigned SAML 1.1 authentication assertion with
414      * a user-specified SubjectLocality statement.
415      */
416     @Test
417     public void testSAML1SubjectLocality() throws Exception {
418         SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
419         callbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHN);
420         callbackHandler.setIssuer("www.example.com");
421         callbackHandler.setSubjectLocality(IP_ADDRESS, "test-dns");
422 
423         SAMLCallback samlCallback = new SAMLCallback();
424         SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
425         SamlAssertionWrapper samlAssertion = new SamlAssertionWrapper(samlCallback);
426 
427         Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
428         WSSecHeader secHeader = new WSSecHeader(doc);
429         secHeader.insertSecurityHeader();
430 
431         WSSecSAMLToken wsSign = new WSSecSAMLToken(secHeader);
432 
433         Document unsignedDoc = wsSign.build(samlAssertion);
434 
435         String outputString =
436             XMLUtils.prettyDocumentToString(unsignedDoc);
437         if (LOG.isDebugEnabled()) {
438             LOG.debug("SAML 1.1 Authn Assertion (sender vouches):");
439             LOG.debug(outputString);
440         }
441         assertTrue(outputString.contains(IP_ADDRESS));
442         assertTrue(outputString.contains("test-dns"));
443 
444         WSHandlerResult results = verify(unsignedDoc);
445         WSSecurityEngineResult actionResult =
446             results.getActionResults().get(WSConstants.ST_UNSIGNED).get(0);
447 
448         SamlAssertionWrapper receivedSamlAssertion =
449             (SamlAssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
450         assertNotNull(receivedSamlAssertion);
451         assertFalse(receivedSamlAssertion.isSigned());
452     }
453 
454     /**
455      * Test that creates, sends and processes an unsigned SAML 2.0 authentication assertion with
456      * a user-specified SessionNotOnOrAfter DateTime.
457      */
458     @Test
459     public void testSAML2SessionNotOnOrAfter() throws Exception {
460         SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
461         callbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHN);
462         callbackHandler.setSessionNotOnOrAfter(Instant.now().plus(Duration.ofHours(1)));
463         callbackHandler.setIssuer("www.example.com");
464 
465         SAMLCallback samlCallback = new SAMLCallback();
466         SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
467         SamlAssertionWrapper samlAssertion = new SamlAssertionWrapper(samlCallback);
468 
469         Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
470         WSSecHeader secHeader = new WSSecHeader(doc);
471         secHeader.insertSecurityHeader();
472 
473         WSSecSAMLToken wsSign = new WSSecSAMLToken(secHeader);
474 
475         Document unsignedDoc = wsSign.build(samlAssertion);
476 
477         String outputString =
478             XMLUtils.prettyDocumentToString(unsignedDoc);
479         if (LOG.isDebugEnabled()) {
480             LOG.debug("SAML 2.0 Authn Assertion (sender vouches):");
481             LOG.debug(outputString);
482         }
483         assertTrue(outputString.contains("SessionNotOnOrAfter"));
484 
485         WSHandlerResult results = verify(unsignedDoc);
486         WSSecurityEngineResult actionResult =
487             results.getActionResults().get(WSConstants.ST_UNSIGNED).get(0);
488 
489         SamlAssertionWrapper receivedSamlAssertion =
490             (SamlAssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
491         assertNotNull(receivedSamlAssertion);
492         assertFalse(receivedSamlAssertion.isSigned());
493     }
494 
495     /**
496      * Test that creates, sends and processes an unsigned SAML 2 authentication assertion with
497      * a user-specified SubjectLocality statement.
498      */
499     @Test
500     public void testSAML2SubjectLocality() throws Exception {
501         SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
502         callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
503         callbackHandler.setIssuer("www.example.com");
504         callbackHandler.setSubjectLocality(IP_ADDRESS, "test-dns");
505 
506         SAMLCallback samlCallback = new SAMLCallback();
507         SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
508         SamlAssertionWrapper samlAssertion = new SamlAssertionWrapper(samlCallback);
509 
510         Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
511         WSSecHeader secHeader = new WSSecHeader(doc);
512         secHeader.insertSecurityHeader();
513 
514         WSSecSAMLToken wsSign = new WSSecSAMLToken(secHeader);
515 
516         Document unsignedDoc = wsSign.build(samlAssertion);
517 
518         String outputString =
519             XMLUtils.prettyDocumentToString(unsignedDoc);
520         if (LOG.isDebugEnabled()) {
521             LOG.debug("SAML 2 Authn Assertion (sender vouches):");
522             LOG.debug(outputString);
523         }
524         assertTrue(outputString.contains(IP_ADDRESS));
525         assertTrue(outputString.contains("test-dns"));
526 
527         WSHandlerResult results = verify(unsignedDoc);
528         WSSecurityEngineResult actionResult =
529             results.getActionResults().get(WSConstants.ST_UNSIGNED).get(0);
530 
531         SamlAssertionWrapper receivedSamlAssertion =
532             (SamlAssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
533         assertNotNull(receivedSamlAssertion);
534         assertFalse(receivedSamlAssertion.isSigned());
535     }
536 
537     /**
538      * Test that creates, sends and processes an unsigned SAML 1.1 authorization assertion
539      * with a Resource URI.
540      */
541     @Test
542     public void testSAML1Resource() throws Exception {
543         SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
544         callbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHZ);
545         callbackHandler.setIssuer("www.example.com");
546         callbackHandler.setResource("http://resource.org");
547 
548         SAMLCallback samlCallback = new SAMLCallback();
549         SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
550         SamlAssertionWrapper samlAssertion = new SamlAssertionWrapper(samlCallback);
551 
552         Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
553         WSSecHeader secHeader = new WSSecHeader(doc);
554         secHeader.insertSecurityHeader();
555 
556         WSSecSAMLToken wsSign = new WSSecSAMLToken(secHeader);
557 
558         Document unsignedDoc = wsSign.build(samlAssertion);
559 
560         String outputString =
561             XMLUtils.prettyDocumentToString(unsignedDoc);
562         if (LOG.isDebugEnabled()) {
563             LOG.debug("SAML 1.1 Authz Assertion (sender vouches):");
564             LOG.debug(outputString);
565         }
566         assertTrue(outputString.contains("http://resource.org"));
567 
568         WSHandlerResult results = verify(unsignedDoc);
569         WSSecurityEngineResult actionResult =
570             results.getActionResults().get(WSConstants.ST_UNSIGNED).get(0);
571 
572         SamlAssertionWrapper receivedSamlAssertion =
573             (SamlAssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
574         assertNotNull(receivedSamlAssertion);
575         assertFalse(receivedSamlAssertion.isSigned());
576     }
577 
578     /**
579      * Test that creates, sends and processes an unsigned SAML 2 attribute assertion. The attributeValue
580      * has a custom XMLObject (not a String) value.
581      */
582     @Test
583     @SuppressWarnings("unchecked")
584     public void testSAML2AttrAssertionCustomAttribute() throws Exception {
585         SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
586         callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
587         callbackHandler.setIssuer("www.example.com");
588 
589         // Create and add a custom Attribute (conditions Object)
590         XMLObjectBuilderFactory builderFactory =
591             XMLObjectProviderRegistrySupport.getBuilderFactory();
592 
593         SAMLObjectBuilder<Conditions> conditionsV2Builder =
594                 (SAMLObjectBuilder<Conditions>)builderFactory.getBuilder(Conditions.DEFAULT_ELEMENT_NAME);
595         Conditions conditions = conditionsV2Builder.buildObject();
596         Instant newNotBefore = Instant.now();
597         conditions.setNotBefore(newNotBefore);
598         conditions.setNotOnOrAfter(newNotBefore.plus(Duration.ofMinutes(5)));
599 
600         XMLObjectBuilder<XSAny> xsAnyBuilder =
601             (XMLObjectBuilder<XSAny>)builderFactory.getBuilder(XSAny.TYPE_NAME);
602         XSAny attributeValue = xsAnyBuilder.buildObject(AttributeValue.DEFAULT_ELEMENT_NAME);
603         attributeValue.getUnknownXMLObjects().add(conditions);
604 
605         List<Object> attributeValues = new ArrayList<>();
606         attributeValues.add(attributeValue);
607         callbackHandler.setCustomAttributeValues(attributeValues);
608 
609         SAMLCallback samlCallback = new SAMLCallback();
610         SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
611         SamlAssertionWrapper samlAssertion = new SamlAssertionWrapper(samlCallback);
612 
613         Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
614         WSSecHeader secHeader = new WSSecHeader(doc);
615         secHeader.insertSecurityHeader();
616 
617         WSSecSAMLToken wsSign = new WSSecSAMLToken(secHeader);
618 
619         Document unsignedDoc = wsSign.build(samlAssertion);
620 
621         if (LOG.isDebugEnabled()) {
622             LOG.debug("SAML 2 Attr Assertion (sender vouches):");
623             String outputString =
624                 XMLUtils.prettyDocumentToString(unsignedDoc);
625             LOG.debug(outputString);
626         }
627 
628         WSHandlerResult results = verify(unsignedDoc);
629         WSSecurityEngineResult actionResult =
630             results.getActionResults().get(WSConstants.ST_UNSIGNED).get(0);
631 
632         SamlAssertionWrapper receivedSamlAssertion =
633             (SamlAssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
634         assertNotNull(receivedSamlAssertion);
635         assertFalse(receivedSamlAssertion.isSigned());
636     }
637 
638     /**
639      * Test that creates, sends and processes an unsigned SAML 2 attribute assertion. The attributeValue
640      * has a custom XMLObject (xsd:type="xsd:int") value.
641      */
642     @Test
643     @SuppressWarnings("unchecked")
644     public void testSAML2AttrAssertionIntegerAttribute() throws Exception {
645         SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
646         callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
647         callbackHandler.setIssuer("www.example.com");
648 
649         // Create and add a custom Attribute (Integer)
650         XMLObjectBuilderFactory builderFactory = XMLObjectProviderRegistrySupport.getBuilderFactory();
651 
652         XMLObjectBuilder<XSInteger> xsIntegerBuilder =
653             (XMLObjectBuilder<XSInteger>)builderFactory.getBuilder(XSInteger.TYPE_NAME);
654         XSInteger attributeValue =
655             xsIntegerBuilder.buildObject(AttributeValue.DEFAULT_ELEMENT_NAME, XSInteger.TYPE_NAME);
656         attributeValue.setValue(5);
657 
658         List<Object> attributeValues = new ArrayList<>();
659         attributeValues.add(attributeValue);
660         callbackHandler.setCustomAttributeValues(attributeValues);
661 
662         WSHandlerResult results = createAndVerifyMessage(callbackHandler, true);
663         WSSecurityEngineResult actionResult =
664             results.getActionResults().get(WSConstants.ST_UNSIGNED).get(0);
665 
666         SamlAssertionWrapper receivedSamlAssertion =
667             (SamlAssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
668         assertNotNull(receivedSamlAssertion);
669         assertFalse(receivedSamlAssertion.isSigned());
670     }
671 
672     /**
673      * Test that creates, sends and processes an unsigned SAML 2 authentication assertion with
674      * SubjectConfirmationData information.
675      */
676     @Test
677     public void testSAML2SubjectConfirmationData() throws Exception {
678         SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
679         callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
680         callbackHandler.setIssuer("www.example.com");
681 
682         SubjectConfirmationDataBean subjectConfirmationData = new SubjectConfirmationDataBean();
683         subjectConfirmationData.setAddress("http://apache.org");
684         subjectConfirmationData.setInResponseTo("12345");
685         subjectConfirmationData.setNotAfter(Instant.now().plus(Duration.ofMinutes(5)));
686         subjectConfirmationData.setRecipient("http://recipient.apache.org");
687         callbackHandler.setSubjectConfirmationData(subjectConfirmationData);
688 
689         SAMLCallback samlCallback = new SAMLCallback();
690         SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
691         SamlAssertionWrapper samlAssertion = new SamlAssertionWrapper(samlCallback);
692 
693         Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
694         WSSecHeader secHeader = new WSSecHeader(doc);
695         secHeader.insertSecurityHeader();
696 
697         WSSecSAMLToken wsSign = new WSSecSAMLToken(secHeader);
698 
699         Document unsignedDoc = wsSign.build(samlAssertion);
700 
701         String outputString =
702             XMLUtils.prettyDocumentToString(unsignedDoc);
703         if (LOG.isDebugEnabled()) {
704             LOG.debug("SAML 2 Authn Assertion (sender vouches):");
705             LOG.debug(outputString);
706         }
707         assertTrue(outputString.contains("http://recipient.apache.org"));
708 
709         WSHandlerResult results = createAndVerifyMessage(callbackHandler, true);
710         WSSecurityEngineResult actionResult =
711             results.getActionResults().get(WSConstants.ST_UNSIGNED).get(0);
712 
713         SamlAssertionWrapper receivedSamlAssertion =
714             (SamlAssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
715         assertNotNull(receivedSamlAssertion);
716         assertFalse(receivedSamlAssertion.isSigned());
717     }
718 
719     /**
720      * Test that creates, sends and processes an unsigned SAML 2 authentication assertion with
721      * a NameID in the Subject (see https://issues.apache.org/jira/browse/WSS-622)
722      */
723     @Test
724     public void testSAML2SubjectConfirmationNameID() throws Exception {
725         SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
726         callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
727         callbackHandler.setIssuer("www.example.com");
728 
729         NameIDBean nameID = new NameIDBean();
730         nameID.setNameIDFormat("urn:oasis:names:tc:SAML:2.0:nameid-format:unspecified");
731         nameID.setNameQualifier("confirmationNameQualifier");
732         nameID.setNameValue("confirmationNameQualifierValue");
733         nameID.setSPNameQualifier("spNameQualifier");
734         callbackHandler.setSubjectConfirmationNameID(nameID);
735 
736         SAMLCallback samlCallback = new SAMLCallback();
737         SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
738         SamlAssertionWrapper samlAssertion = new SamlAssertionWrapper(samlCallback);
739 
740         Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
741         WSSecHeader secHeader = new WSSecHeader(doc);
742         secHeader.insertSecurityHeader();
743 
744         WSSecSAMLToken wsSign = new WSSecSAMLToken(secHeader);
745 
746         Document unsignedDoc = wsSign.build(samlAssertion);
747 
748         String outputString =
749             XMLUtils.prettyDocumentToString(unsignedDoc);
750         if (LOG.isDebugEnabled()) {
751             LOG.debug("SAML 2 Authn Assertion (sender vouches):");
752             LOG.debug(outputString);
753         }
754         assertTrue(outputString.contains("confirmationNameQualifierValue"));
755 
756         WSHandlerResult results = createAndVerifyMessage(callbackHandler, true);
757         WSSecurityEngineResult actionResult =
758             results.getActionResults().get(WSConstants.ST_UNSIGNED).get(0);
759 
760         SamlAssertionWrapper receivedSamlAssertion =
761             (SamlAssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
762         assertNotNull(receivedSamlAssertion);
763         assertFalse(receivedSamlAssertion.isSigned());
764     }
765 
766     /**
767      * Test that creates, sends and processes an unsigned SAML 2 authentication assertion, which
768      * is encrypted in a saml2:EncryptedAssertion Element in the security header
769      */
770     @Test
771     public void testSAML2EncryptedAssertion() throws Exception {
772         SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
773         callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
774         callbackHandler.setIssuer("www.example.com");
775 
776         SAMLCallback samlCallback = new SAMLCallback();
777         SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
778         SamlAssertionWrapper samlAssertion = new SamlAssertionWrapper(samlCallback);
779 
780         Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
781         WSSecHeader secHeader = new WSSecHeader(doc);
782         secHeader.insertSecurityHeader();
783 
784         WSSecSAMLToken wsSign = new WSSecSAMLToken(secHeader);
785 
786         wsSign.prepare(samlAssertion);
787 
788         // Get the Element + add it to the security header as an EncryptedAssertion
789         Element assertionElement = wsSign.getElement();
790         Element encryptedAssertionElement =
791             doc.createElementNS(WSConstants.SAML2_NS, WSConstants.ENCRYPED_ASSERTION_LN);
792         encryptedAssertionElement.appendChild(assertionElement);
793         secHeader.getSecurityHeaderElement().appendChild(encryptedAssertionElement);
794 
795         // Encrypt the Assertion
796         KeyGenerator keygen = KeyGenerator.getInstance("AES");
797         keygen.init(128);
798         SecretKey secretKey = keygen.generateKey();
799         Crypto crypto = CryptoFactory.getInstance("wss40.properties");
800         CryptoType cryptoType = new CryptoType(CryptoType.TYPE.ALIAS);
801         cryptoType.setAlias("wss40");
802         X509Certificate[] certs = crypto.getX509Certificates(cryptoType);
803         assertTrue(certs != null && certs.length > 0 && certs[0] != null);
804 
805         encryptElement(doc, assertionElement, WSConstants.AES_128, secretKey,
806                 WSConstants.KEYTRANSPORT_RSAOAEP, certs[0], false, true);
807 
808         if (LOG.isDebugEnabled()) {
809             String outputString =
810                 XMLUtils.prettyDocumentToString(doc);
811             LOG.debug(outputString);
812         }
813 
814         RequestData requestData = new RequestData();
815         requestData.setValidateSamlSubjectConfirmation(false);
816         requestData.setCallbackHandler(new KeystoreCallbackHandler());
817         requestData.setDecCrypto(crypto);
818         requestData.setSigVerCrypto(crypto);
819         WSHandlerResult results = secEngine.processSecurityHeader(doc, requestData);
820 
821         WSSecurityEngineResult actionResult =
822             results.getActionResults().get(WSConstants.ST_UNSIGNED).get(0);
823 
824         SamlAssertionWrapper receivedSamlAssertion =
825             (SamlAssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
826         assertNotNull(receivedSamlAssertion);
827         assertNotNull(receivedSamlAssertion.getElement());
828         assertTrue("Assertion".equals(receivedSamlAssertion.getElement().getLocalName()));
829 
830         actionResult = results.getActionResults().get(WSConstants.ENCR).get(0);
831         assertNotNull(actionResult);
832     }
833 
834     @Test
835     public void testSAML2EncryptedAssertionViaSeparateEncryptedKey() throws Exception {
836         SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
837         callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
838         callbackHandler.setIssuer("www.example.com");
839 
840         SAMLCallback samlCallback = new SAMLCallback();
841         SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
842         SamlAssertionWrapper samlAssertion = new SamlAssertionWrapper(samlCallback);
843 
844         Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
845         WSSecHeader secHeader = new WSSecHeader(doc);
846         secHeader.insertSecurityHeader();
847 
848         WSSecSAMLToken wsSign = new WSSecSAMLToken(secHeader);
849 
850         wsSign.prepare(samlAssertion);
851 
852         // Get the Element + add it to the security header as an EncryptedAssertion
853         Element assertionElement = wsSign.getElement();
854         Element encryptedAssertionElement =
855             doc.createElementNS(WSConstants.SAML2_NS, WSConstants.ENCRYPED_ASSERTION_LN);
856         encryptedAssertionElement.appendChild(assertionElement);
857         secHeader.getSecurityHeaderElement().appendChild(encryptedAssertionElement);
858 
859         // Encrypt the Assertion
860         KeyGenerator keygen = KeyGenerator.getInstance("AES");
861         keygen.init(128);
862         SecretKey secretKey = keygen.generateKey();
863         Crypto crypto = CryptoFactory.getInstance("wss40.properties");
864         CryptoType cryptoType = new CryptoType(CryptoType.TYPE.ALIAS);
865         cryptoType.setAlias("wss40");
866         X509Certificate[] certs = crypto.getX509Certificates(cryptoType);
867         assertTrue(certs != null && certs.length > 0 && certs[0] != null);
868 
869         XMLCipher cipher = XMLCipher.getInstance(WSConstants.AES_128);
870         cipher.init(XMLCipher.ENCRYPT_MODE, secretKey);
871 
872         // Create a KeyInfo for the EncryptedData
873         EncryptedData builder = cipher.getEncryptedData();
874         KeyInfo builderKeyInfo = builder.getKeyInfo();
875         if (builderKeyInfo == null) {
876             builderKeyInfo = new KeyInfo(doc);
877             builderKeyInfo.getElement().setAttributeNS(
878                 "http://www.w3.org/2000/xmlns/", "xmlns:dsig",
879                 "http://www.w3.org/2000/09/xmldsig#"
880             );
881             builder.setKeyInfo(builderKeyInfo);
882         }
883         String encryptedKeyId = IDGenerator.generateID(null);
884         RetrievalMethod retrievalMethod = new RetrievalMethod(doc, "#" + encryptedKeyId,
885                                                               null, "http://www.w3.org/2001/04/xmlenc#EncryptedKey");
886         builderKeyInfo.add(retrievalMethod);
887 
888         cipher.doFinal(doc, assertionElement, false);
889 
890         String id = IDGenerator.generateID(null);
891         Element encryptedData =
892             (Element)encryptedAssertionElement.getElementsByTagNameNS(WSConstants.ENC_NS, "EncryptedData").item(0);
893         encryptedData.setAttributeNS(null, "Id", id);
894 
895         XMLCipher newCipher = XMLCipher.getInstance(WSConstants.KEYTRANSPORT_RSAOAEP);
896         newCipher.init(XMLCipher.WRAP_MODE, certs[0].getPublicKey());
897         EncryptedKey encryptedKey = newCipher.encryptKey(doc, secretKey);
898 
899         KeyInfo encryptedKeyKeyInfo = encryptedKey.getKeyInfo();
900         if (encryptedKeyKeyInfo == null) {
901             encryptedKeyKeyInfo = new KeyInfo(doc);
902             encryptedKeyKeyInfo.getElement().setAttributeNS(
903                 "http://www.w3.org/2000/xmlns/", "xmlns:dsig", "http://www.w3.org/2000/09/xmldsig#"
904             );
905             encryptedKey.setKeyInfo(encryptedKeyKeyInfo);
906         }
907         X509Data x509Data = new X509Data(doc);
908         x509Data.addIssuerSerial(certs[0].getIssuerX500Principal().getName(),
909                                  certs[0].getSerialNumber());
910         encryptedKeyKeyInfo.add(x509Data);
911 
912         ReferenceList referenceList = newCipher.createReferenceList(ReferenceList.DATA_REFERENCE);
913         Reference reference = referenceList.newDataReference("#" + id);
914         referenceList.add(reference);
915         encryptedKey.setReferenceList(referenceList);
916         Element encryptedKeyElement = newCipher.martial(encryptedKey);
917         encryptedKeyElement.setAttributeNS(null, "Id", encryptedKeyId);
918         encryptedAssertionElement.appendChild(encryptedKeyElement);
919 
920         if (LOG.isDebugEnabled()) {
921             String outputString =
922                 XMLUtils.prettyDocumentToString(doc);
923             LOG.debug(outputString);
924         }
925 
926         RequestData requestData = new RequestData();
927         requestData.setValidateSamlSubjectConfirmation(false);
928         requestData.setCallbackHandler(new KeystoreCallbackHandler());
929         requestData.setDecCrypto(crypto);
930         requestData.setSigVerCrypto(crypto);
931         requestData.setDisableBSPEnforcement(true);
932         WSHandlerResult results = secEngine.processSecurityHeader(doc, requestData);
933 
934         WSSecurityEngineResult actionResult =
935             results.getActionResults().get(WSConstants.ST_UNSIGNED).get(0);
936 
937         SamlAssertionWrapper receivedSamlAssertion =
938             (SamlAssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
939         assertNotNull(receivedSamlAssertion);
940         assertNotNull(receivedSamlAssertion.getElement());
941         assertTrue("Assertion".equals(receivedSamlAssertion.getElement().getLocalName()));
942 
943         actionResult = results.getActionResults().get(WSConstants.ENCR).get(0);
944         assertNotNull(actionResult);
945     }
946 
947     @Test
948     public void testSAML2EncryptedAssertionNoSTR() throws Exception {
949         SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
950         callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
951         callbackHandler.setIssuer("www.example.com");
952 
953         SAMLCallback samlCallback = new SAMLCallback();
954         SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
955         SamlAssertionWrapper samlAssertion = new SamlAssertionWrapper(samlCallback);
956 
957         Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
958         WSSecHeader secHeader = new WSSecHeader(doc);
959         secHeader.insertSecurityHeader();
960 
961         WSSecSAMLToken wsSign = new WSSecSAMLToken(secHeader);
962 
963         wsSign.prepare(samlAssertion);
964 
965         // Get the Element + add it to the security header as an EncryptedAssertion
966         Element assertionElement = wsSign.getElement();
967         Element encryptedAssertionElement =
968             doc.createElementNS(WSConstants.SAML2_NS, WSConstants.ENCRYPED_ASSERTION_LN);
969         encryptedAssertionElement.appendChild(assertionElement);
970         secHeader.getSecurityHeaderElement().appendChild(encryptedAssertionElement);
971 
972         // Encrypt the Assertion
973         KeyGenerator keygen = KeyGenerator.getInstance("AES");
974         keygen.init(128);
975         SecretKey secretKey = keygen.generateKey();
976         Crypto crypto = CryptoFactory.getInstance("wss40.properties");
977         CryptoType cryptoType = new CryptoType(CryptoType.TYPE.ALIAS);
978         cryptoType.setAlias("wss40");
979         X509Certificate[] certs = crypto.getX509Certificates(cryptoType);
980         assertTrue(certs != null && certs.length > 0 && certs[0] != null);
981 
982         encryptElement(doc, assertionElement, WSConstants.AES_128, secretKey,
983                 WSConstants.KEYTRANSPORT_RSAOAEP, certs[0], false, false);
984 
985         if (LOG.isDebugEnabled()) {
986             String outputString =
987                 XMLUtils.prettyDocumentToString(doc);
988             LOG.debug(outputString);
989         }
990 
991         RequestData data = new RequestData();
992         data.setDecCrypto(crypto);
993         List<BSPRule> ignoredRules = new ArrayList<>();
994         ignoredRules.add(BSPRule.R5426);
995         data.setIgnoredBSPRules(ignoredRules);
996         data.setCallbackHandler(new KeystoreCallbackHandler());
997         data.setValidateSamlSubjectConfirmation(false);
998 
999         WSSecurityEngine newEngine = new WSSecurityEngine();
1000 
1001         WSSConfig config = WSSConfig.getNewInstance();
1002         config.setValidator(WSConstants.SAML_TOKEN, new CustomSamlAssertionValidator());
1003         config.setValidator(WSConstants.SAML2_TOKEN, new CustomSamlAssertionValidator());
1004         newEngine.setWssConfig(config);
1005 
1006         WSHandlerResult results = newEngine.processSecurityHeader(doc, data);
1007 
1008         WSSecurityEngineResult actionResult =
1009             results.getActionResults().get(WSConstants.ST_UNSIGNED).get(0);
1010 
1011         SamlAssertionWrapper receivedSamlAssertion =
1012             (SamlAssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
1013         assertNotNull(receivedSamlAssertion);
1014         assertNotNull(receivedSamlAssertion.getElement());
1015         assertTrue("Assertion".equals(receivedSamlAssertion.getElement().getLocalName()));
1016 
1017         actionResult = results.getActionResults().get(WSConstants.ENCR).get(0);
1018         assertNotNull(actionResult);
1019     }
1020 
1021     @Test
1022     public void testAssertionWrapper() throws Exception {
1023         SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
1024         callbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHN);
1025         callbackHandler.setIssuer("www.example.com");
1026 
1027         SAMLCallback samlCallback = new SAMLCallback();
1028         SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
1029         SamlAssertionWrapper samlAssertion = new SamlAssertionWrapper(samlCallback);
1030 
1031         DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
1032         dbf.setNamespaceAware(true);
1033         Document doc = dbf.newDocumentBuilder().newDocument();
1034         String assertionString = DOM2Writer.nodeToString(samlAssertion.toDOM(doc));
1035 
1036         // Convert String to DOM + into an assertionWrapper
1037         InputStream in = new ByteArrayInputStream(assertionString.getBytes());
1038         Document newDoc = dbf.newDocumentBuilder().parse(in);
1039 
1040         SamlAssertionWrapper newAssertion =
1041             new SamlAssertionWrapper(newDoc.getDocumentElement());
1042         String secondAssertionString = newAssertion.assertionToString();
1043         assertEquals(assertionString, secondAssertionString);
1044     }
1045 
1046     @Test
1047     public void testAssertionWrapperNoDocument() throws Exception {
1048         SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
1049         callbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHN);
1050         callbackHandler.setIssuer("www.example.com");
1051 
1052         SAMLCallback samlCallback = new SAMLCallback();
1053         SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
1054         SamlAssertionWrapper samlAssertion = new SamlAssertionWrapper(samlCallback);
1055 
1056         String assertionString = DOM2Writer.nodeToString(samlAssertion.toDOM(null));
1057 
1058         // Convert String to DOM + into an assertionWrapper
1059         InputStream in = new ByteArrayInputStream(assertionString.getBytes());
1060 
1061         DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
1062         dbf.setNamespaceAware(true);
1063         Document newDoc = dbf.newDocumentBuilder().parse(in);
1064 
1065         SamlAssertionWrapper newAssertion =
1066             new SamlAssertionWrapper(newDoc.getDocumentElement());
1067         String secondAssertionString = newAssertion.assertionToString();
1068         assertEquals(assertionString, secondAssertionString);
1069     }
1070 
1071     @Test
1072     public void testRequiredSubjectConfirmationMethod() throws Exception {
1073         SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
1074         callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
1075         callbackHandler.setIssuer("www.example.com");
1076 
1077         SAMLCallback samlCallback = new SAMLCallback();
1078         SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
1079         SamlAssertionWrapper samlAssertion = new SamlAssertionWrapper(samlCallback);
1080 
1081         Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
1082         WSSecHeader secHeader = new WSSecHeader(doc);
1083         secHeader.insertSecurityHeader();
1084 
1085         WSSecSAMLToken wsSign = new WSSecSAMLToken(secHeader);
1086 
1087         Document unsignedDoc = wsSign.build(samlAssertion);
1088 
1089         WSSConfig config = WSSConfig.getNewInstance();
1090         SamlAssertionValidator assertionValidator = new SamlAssertionValidator();
1091         assertionValidator.setRequiredSubjectConfirmationMethod(SAML2Constants.CONF_SENDER_VOUCHES);
1092         config.setValidator(WSConstants.SAML_TOKEN, assertionValidator);
1093         config.setValidator(WSConstants.SAML2_TOKEN, assertionValidator);
1094 
1095         WSSecurityEngine newEngine = new WSSecurityEngine();
1096         newEngine.setWssConfig(config);
1097         RequestData requestData = new RequestData();
1098         requestData.setValidateSamlSubjectConfirmation(false);
1099 
1100         newEngine.processSecurityHeader(doc, requestData);
1101 
1102         // Now create a Bearer assertion
1103         callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
1104 
1105         samlCallback = new SAMLCallback();
1106         SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
1107         samlAssertion = new SamlAssertionWrapper(samlCallback);
1108 
1109         doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
1110         secHeader = new WSSecHeader(doc);
1111         secHeader.insertSecurityHeader();
1112 
1113         wsSign = new WSSecSAMLToken(secHeader);
1114 
1115         unsignedDoc = wsSign.build(samlAssertion);
1116         try {
1117             newEngine.processSecurityHeader(unsignedDoc, null, null, null);
1118             fail("Failure expected on an incorrect subject confirmation method");
1119         } catch (WSSecurityException ex) {
1120             assertTrue(ex.getErrorCode() == WSSecurityException.ErrorCode.FAILURE);
1121         }
1122     }
1123 
1124     @Test
1125     public void testStandardSubjectConfirmationMethod() throws Exception {
1126         SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
1127         callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
1128         callbackHandler.setIssuer("www.example.com");
1129         callbackHandler.setConfirmationMethod("urn:oasis:names:tc:SAML:2.0:cm:custom");
1130 
1131         SAMLCallback samlCallback = new SAMLCallback();
1132         SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
1133         SamlAssertionWrapper samlAssertion = new SamlAssertionWrapper(samlCallback);
1134 
1135         Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
1136         WSSecHeader secHeader = new WSSecHeader(doc);
1137         secHeader.insertSecurityHeader();
1138 
1139         WSSecSAMLToken wsSign = new WSSecSAMLToken(secHeader);
1140 
1141         Document unsignedDoc = wsSign.build(samlAssertion);
1142 
1143         WSSecurityEngine newEngine = new WSSecurityEngine();
1144         try {
1145             newEngine.processSecurityHeader(unsignedDoc, null, null, null);
1146             fail("Failure expected on an unknown subject confirmation method");
1147         } catch (WSSecurityException ex) {
1148             assertTrue(ex.getErrorCode() == WSSecurityException.ErrorCode.FAILURE);
1149         }
1150 
1151         // Now disable this check
1152         WSSConfig config = WSSConfig.getNewInstance();
1153         SamlAssertionValidator assertionValidator = new SamlAssertionValidator();
1154         assertionValidator.setRequireStandardSubjectConfirmationMethod(false);
1155         config.setValidator(WSConstants.SAML_TOKEN, assertionValidator);
1156         config.setValidator(WSConstants.SAML2_TOKEN, assertionValidator);
1157 
1158         newEngine.setWssConfig(config);
1159 
1160         RequestData requestData = new RequestData();
1161         requestData.setValidateSamlSubjectConfirmation(false);
1162 
1163         newEngine.processSecurityHeader(doc, requestData);
1164     }
1165 
1166     @Test
1167     public void testUnsignedBearer() throws Exception {
1168         SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
1169         callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
1170         callbackHandler.setIssuer("www.example.com");
1171         callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
1172 
1173         SAMLCallback samlCallback = new SAMLCallback();
1174         SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
1175         SamlAssertionWrapper samlAssertion = new SamlAssertionWrapper(samlCallback);
1176 
1177         Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
1178         WSSecHeader secHeader = new WSSecHeader(doc);
1179         secHeader.insertSecurityHeader();
1180 
1181         WSSecSAMLToken wsSign = new WSSecSAMLToken(secHeader);
1182 
1183         Document unsignedDoc = wsSign.build(samlAssertion);
1184 
1185         WSSecurityEngine newEngine = new WSSecurityEngine();
1186         try {
1187             newEngine.processSecurityHeader(unsignedDoc, null, null, null);
1188             fail("Failure expected on an unsigned bearer token");
1189         } catch (WSSecurityException ex) {
1190             assertTrue(ex.getErrorCode() == WSSecurityException.ErrorCode.FAILURE);
1191         }
1192 
1193         // Now disable this check
1194         WSSConfig config = WSSConfig.getNewInstance();
1195         SamlAssertionValidator assertionValidator = new SamlAssertionValidator();
1196         assertionValidator.setRequireBearerSignature(false);
1197         config.setValidator(WSConstants.SAML_TOKEN, assertionValidator);
1198         config.setValidator(WSConstants.SAML2_TOKEN, assertionValidator);
1199 
1200         newEngine.setWssConfig(config);
1201 
1202         RequestData requestData = new RequestData();
1203         requestData.setValidateSamlSubjectConfirmation(false);
1204 
1205         newEngine.processSecurityHeader(doc, requestData);
1206     }
1207 
1208     @Test
1209     public void testSAML2Advice() throws Exception {
1210         // Create a "Advice" Element first
1211         SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
1212         callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
1213         callbackHandler.setIssuer("www.example.com");
1214 
1215         SAMLCallback samlCallback = new SAMLCallback();
1216         SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
1217         SamlAssertionWrapper samlAssertion = new SamlAssertionWrapper(samlCallback);
1218 
1219         Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
1220         Element adviceElement = samlAssertion.toDOM(doc);
1221 
1222         // Now create a SAML Assertion that uses the advice Element
1223         callbackHandler = new SAML2CallbackHandler();
1224         callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
1225         callbackHandler.setIssuer("www.example.com");
1226         callbackHandler.setAssertionAdviceElement(adviceElement);
1227 
1228         samlCallback = new SAMLCallback();
1229         SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
1230         samlAssertion = new SamlAssertionWrapper(samlCallback);
1231 
1232         WSSecHeader secHeader = new WSSecHeader(doc);
1233         secHeader.insertSecurityHeader();
1234 
1235         WSSecSAMLToken wsSign = new WSSecSAMLToken(secHeader);
1236 
1237         Document unsignedDoc = wsSign.build(samlAssertion);
1238 
1239         String outputString =
1240             XMLUtils.prettyDocumentToString(unsignedDoc);
1241         if (LOG.isDebugEnabled()) {
1242             LOG.debug(outputString);
1243         }
1244         assertTrue(outputString.contains("Advice"));
1245 
1246         WSHandlerResult results = verify(unsignedDoc);
1247         WSSecurityEngineResult actionResult =
1248             results.getActionResults().get(WSConstants.ST_UNSIGNED).get(0);
1249 
1250         SamlAssertionWrapper receivedSamlAssertion =
1251             (SamlAssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
1252         assertNotNull(receivedSamlAssertion);
1253         assertFalse(receivedSamlAssertion.isSigned());
1254     }
1255 
1256     @Test
1257     public void testSAML2SpecialCharacter() throws Exception {
1258         SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
1259         callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
1260         callbackHandler.setIssuer("www.example.com");
1261         // Test an "umlaut"
1262         String newSubjectName = "uid=j\u00f6e,ou=people,ou=saml-demo,o=example.com";
1263         callbackHandler.setSubjectName(newSubjectName);
1264         List<Object> customAttributeValue = new ArrayList<>(1);
1265         customAttributeValue.add("j\u00f6an");
1266         callbackHandler.setCustomAttributeValues(customAttributeValue);
1267 
1268         SAMLCallback samlCallback = new SAMLCallback();
1269         SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
1270         SamlAssertionWrapper samlAssertion = new SamlAssertionWrapper(samlCallback);
1271 
1272         Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
1273         WSSecHeader secHeader = new WSSecHeader(doc);
1274         secHeader.insertSecurityHeader();
1275 
1276         WSSecSAMLToken wsSign = new WSSecSAMLToken(secHeader);
1277 
1278         Document unsignedDoc = wsSign.build(samlAssertion);
1279 
1280         String outputString = XMLUtils.prettyDocumentToString(unsignedDoc);
1281         // assertTrue(outputString.contains("j\u00f6e") && outputString.contains("j\u00f6an"));
1282         if (LOG.isDebugEnabled()) {
1283             LOG.debug(outputString);
1284         }
1285 
1286         RequestData requestData = new RequestData();
1287         requestData.setValidateSamlSubjectConfirmation(false);
1288 
1289         WSSecurityEngine newEngine = new WSSecurityEngine();
1290         WSHandlerResult results = newEngine.processSecurityHeader(doc, requestData);
1291 
1292         WSSecurityEngineResult actionResult =
1293             results.getActionResults().get(WSConstants.ST_UNSIGNED).get(0);
1294 
1295         SamlAssertionWrapper receivedSamlAssertion =
1296             (SamlAssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
1297         assertNotNull(receivedSamlAssertion);
1298         assertFalse(receivedSamlAssertion.isSigned());
1299     }
1300 
1301     @Test
1302     public void testSAML2IssuerFormat() throws Exception {
1303         SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
1304         callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
1305         callbackHandler.setIssuer("www.example.com");
1306         callbackHandler.setIssuerFormat("urn:oasis:names:tc:SAML:2.0:nameid-format:persistent");
1307 
1308         SAMLCallback samlCallback = new SAMLCallback();
1309         SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
1310         SamlAssertionWrapper samlAssertion = new SamlAssertionWrapper(samlCallback);
1311 
1312         Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
1313         WSSecHeader secHeader = new WSSecHeader(doc);
1314         secHeader.insertSecurityHeader();
1315 
1316         WSSecSAMLToken wsSign = new WSSecSAMLToken(secHeader);
1317 
1318         Document unsignedDoc = wsSign.build(samlAssertion);
1319 
1320         String outputString =
1321             XMLUtils.prettyDocumentToString(unsignedDoc);
1322         if (LOG.isDebugEnabled()) {
1323             LOG.debug(outputString);
1324         }
1325         assertTrue(outputString.contains("urn:oasis:names:tc:SAML:2.0:nameid-format:persistent"));
1326 
1327         WSHandlerResult results = createAndVerifyMessage(callbackHandler, true);
1328         WSSecurityEngineResult actionResult =
1329             results.getActionResults().get(WSConstants.ST_UNSIGNED).get(0);
1330 
1331         SamlAssertionWrapper receivedSamlAssertion =
1332             (SamlAssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
1333         assertNotNull(receivedSamlAssertion);
1334         assertFalse(receivedSamlAssertion.isSigned());
1335     }
1336 
1337     @Test
1338     public void testSAML2SubjectWithComment() throws Exception {
1339         SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
1340         callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
1341         callbackHandler.setIssuer("www.example.com");
1342         String principal = "uid=joe,ou=people<!---->o=example.com";
1343         callbackHandler.setSubjectName(principal);
1344 
1345         WSHandlerResult results =
1346             createAndVerifyMessage(callbackHandler, true);
1347         WSSecurityEngineResult actionResult =
1348             results.getActionResults().get(WSConstants.ST_UNSIGNED).get(0);
1349 
1350         SamlAssertionWrapper receivedSamlAssertion =
1351             (SamlAssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
1352         assertNotNull(receivedSamlAssertion);
1353         assertFalse(receivedSamlAssertion.isSigned());
1354 
1355         Principal receivedPrincipal = (Principal)actionResult.get(WSSecurityEngineResult.TAG_PRINCIPAL);
1356         assertEquals(principal, receivedPrincipal.getName());
1357     }
1358 
1359     private void encryptElement(
1360         Document document,
1361         Element elementToEncrypt,
1362         String algorithm,
1363         Key encryptingKey,
1364         String keyTransportAlgorithm,
1365         X509Certificate wrappingCert,
1366         boolean content,
1367         boolean useSecurityTokenReference
1368     ) throws Exception {
1369         XMLCipher cipher = XMLCipher.getInstance(algorithm);
1370         cipher.init(XMLCipher.ENCRYPT_MODE, encryptingKey);
1371 
1372         if (wrappingCert != null) {
1373             XMLCipher newCipher = XMLCipher.getInstance(keyTransportAlgorithm);
1374             newCipher.init(XMLCipher.WRAP_MODE, wrappingCert.getPublicKey());
1375 
1376             EncryptedKey encryptedKey = newCipher.encryptKey(document, encryptingKey);
1377             // Create a KeyInfo for the EncryptedKey
1378             KeyInfo encryptedKeyKeyInfo = encryptedKey.getKeyInfo();
1379             if (encryptedKeyKeyInfo == null) {
1380                 encryptedKeyKeyInfo = new KeyInfo(document);
1381                 encryptedKeyKeyInfo.getElement().setAttributeNS(
1382                     "http://www.w3.org/2000/xmlns/", "xmlns:dsig", "http://www.w3.org/2000/09/xmldsig#"
1383                 );
1384                 encryptedKey.setKeyInfo(encryptedKeyKeyInfo);
1385             }
1386 
1387             if (useSecurityTokenReference) {
1388                 SecurityTokenReference securityTokenReference = new SecurityTokenReference(document);
1389                 securityTokenReference.addWSSENamespace();
1390                 securityTokenReference.setKeyIdentifierSKI(wrappingCert, null);
1391                 encryptedKeyKeyInfo.addUnknownElement(securityTokenReference.getElement());
1392             } else {
1393                 X509Data x509Data = new X509Data(document);
1394                 // x509Data.addCertificate(wrappingCert);
1395                 x509Data.addIssuerSerial(wrappingCert.getIssuerX500Principal().getName(),
1396                                          wrappingCert.getSerialNumber());
1397                 encryptedKeyKeyInfo.add(x509Data);
1398             }
1399 
1400             // Create a KeyInfo for the EncryptedData
1401             EncryptedData builder = cipher.getEncryptedData();
1402             KeyInfo builderKeyInfo = builder.getKeyInfo();
1403             if (builderKeyInfo == null) {
1404                 builderKeyInfo = new KeyInfo(document);
1405                 builderKeyInfo.getElement().setAttributeNS(
1406                     "http://www.w3.org/2000/xmlns/", "xmlns:dsig", "http://www.w3.org/2000/09/xmldsig#"
1407                 );
1408                 builder.setKeyInfo(builderKeyInfo);
1409             }
1410 
1411             builderKeyInfo.add(encryptedKey);
1412         }
1413 
1414         cipher.doFinal(document, elementToEncrypt, content);
1415     }
1416 
1417     private WSHandlerResult createAndVerifyMessage( //NOPMD - It incorrectly thinks this method isn't called
1418         CallbackHandler samlCallbackHandler, boolean success
1419     ) throws Exception {
1420         SAMLCallback samlCallback = new SAMLCallback();
1421         SAMLUtil.doSAMLCallback(samlCallbackHandler, samlCallback);
1422         SamlAssertionWrapper samlAssertion = new SamlAssertionWrapper(samlCallback);
1423 
1424         Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
1425         WSSecHeader secHeader = new WSSecHeader(doc);
1426         secHeader.insertSecurityHeader();
1427 
1428         WSSecSAMLToken wsSign = new WSSecSAMLToken(secHeader);
1429 
1430         Document unsignedDoc = wsSign.build(samlAssertion);
1431 
1432         if (LOG.isDebugEnabled()) {
1433             String outputString =
1434                 XMLUtils.prettyDocumentToString(unsignedDoc);
1435             LOG.debug(outputString);
1436         }
1437 
1438         try {
1439             WSHandlerResult results = verify(unsignedDoc);
1440             if (!success) {
1441                 fail("Failure expected in processing the SAML assertion");
1442             }
1443             return results;
1444         } catch (WSSecurityException ex) {
1445             assertFalse(success);
1446             assertTrue(ex.getMessage().contains("SAML token security failure"));
1447             return null;
1448         }
1449     }
1450 
1451     /**
1452      * Verifies the soap envelope
1453      * <p/>
1454      *
1455      * @param doc
1456      * @throws Exception Thrown when there is a problem in verification
1457      */
1458     private WSHandlerResult verify(Document doc) throws Exception {
1459         RequestData requestData = new RequestData();
1460         requestData.setValidateSamlSubjectConfirmation(false);
1461 
1462         WSHandlerResult results = secEngine.processSecurityHeader(doc, requestData);
1463         String outputString =
1464                 XMLUtils.prettyDocumentToString(doc);
1465         assertTrue(outputString.indexOf("counter_port_type") > 0 ? true : false);
1466         return results;
1467     }
1468 
1469 }