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.policy.stax.test;
20  
21  import java.util.ArrayList;
22  import java.util.Iterator;
23  import java.util.LinkedList;
24  import java.util.List;
25  
26  import javax.xml.namespace.QName;
27  
28  import org.apache.wss4j.common.ext.WSSecurityException;
29  import org.apache.wss4j.policy.stax.PolicyViolationException;
30  import org.apache.wss4j.policy.stax.enforcer.PolicyEnforcer;
31  import org.apache.wss4j.stax.ext.WSSConstants;
32  import org.apache.wss4j.stax.impl.securityToken.X509SecurityTokenImpl;
33  import org.apache.wss4j.stax.securityEvent.OperationSecurityEvent;
34  import org.apache.wss4j.stax.securityToken.WSSecurityTokenConstants;
35  import org.apache.xml.security.stax.ext.XMLSecurityConstants;
36  import org.apache.xml.security.stax.impl.securityToken.AbstractInboundSecurityToken;
37  import org.apache.xml.security.stax.impl.util.IDGenerator;
38  import org.apache.xml.security.stax.securityEvent.EncryptedKeyTokenSecurityEvent;
39  import org.apache.xml.security.stax.securityEvent.SignedElementSecurityEvent;
40  import org.apache.xml.security.stax.securityEvent.X509TokenSecurityEvent;
41  import org.apache.xml.security.stax.securityToken.InboundSecurityToken;
42  import org.apache.xml.security.stax.securityToken.SecurityToken;
43  import org.apache.xml.security.stax.securityToken.SecurityTokenConstants;
44  import org.junit.jupiter.api.Test;
45  
46  import static org.junit.jupiter.api.Assertions.assertEquals;
47  import static org.junit.jupiter.api.Assertions.assertTrue;
48  import static org.junit.jupiter.api.Assertions.fail;
49  
50  public class TokenProtectionTest extends AbstractPolicyTestBase {
51  
52      private static List<WSSecurityTokenConstants.TokenUsage> tokenUsages = new ArrayList<>();
53  
54      static {
55          tokenUsages.add(WSSecurityTokenConstants.TokenUsage_Signature);
56          tokenUsages.add(WSSecurityTokenConstants.TokenUsage_Encryption);
57          tokenUsages.add(WSSecurityTokenConstants.TOKENUSAGE_MAIN_SIGNATURE);
58          tokenUsages.add(WSSecurityTokenConstants.TOKENUSAGE_MAIN_ENCRYPTION);
59          tokenUsages.add(WSSecurityTokenConstants.TOKENUSAGE_SUPPORTING_TOKENS);
60          tokenUsages.add(WSSecurityTokenConstants.TOKENUSAGE_SIGNED_SUPPORTING_TOKENS);
61          tokenUsages.add(WSSecurityTokenConstants.TOKENUSAGE_SIGNED_ENDORSING_SUPPORTING_TOKENS);
62          tokenUsages.add(WSSecurityTokenConstants.TOKENUSAGE_SIGNED_ENCRYPTED_SUPPORTING_TOKENS);
63          tokenUsages.add(WSSecurityTokenConstants.TOKENUSAGE_SIGNED_ENDORSING_ENCRYPTED_SUPPORTING_TOKENS);
64          tokenUsages.add(WSSecurityTokenConstants.TOKENUSAGE_ENDORSING_ENCRYPTED_SUPPORTING_TOKENS);
65          tokenUsages.add(WSSecurityTokenConstants.TOKENUSAGE_ENDORSING_SUPPORTING_TOKENS);
66          tokenUsages.add(WSSecurityTokenConstants.TOKENUSAGE_ENCRYPTED_SUPPORTING_TOKENS);
67      }
68  
69      @Test
70      public void testPolicy() throws Exception {
71          String policyString =
72                  "<sp:AsymmetricBinding xmlns:sp=\"http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702\" xmlns:sp3=\"http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200802\">\n" +
73                          "<wsp:Policy xmlns:wsp=\"http://schemas.xmlsoap.org/ws/2004/09/policy\">\n" +
74                          "   <sp:AlgorithmSuite>\n" +
75                          "       <wsp:Policy>\n" +
76                          "           <sp:Basic256/>\n" +
77                          "       </wsp:Policy>\n" +
78                          "   </sp:AlgorithmSuite>\n" +
79                          "<sp:ProtectTokens/>\n" +
80                          "</wsp:Policy>\n" +
81                          "</sp:AsymmetricBinding>";
82          PolicyEnforcer policyEnforcer = buildAndStartPolicyEngine(policyString);
83  
84          List<XMLSecurityConstants.ContentType> protectionOrder = new LinkedList<>();
85          protectionOrder.add(XMLSecurityConstants.ContentType.SIGNATURE);
86  
87          List<QName> bstPath = new ArrayList<>();
88          bstPath.addAll(WSSConstants.SOAP_11_WSSE_SECURITY_HEADER_PATH);
89          bstPath.add(WSSConstants.TAG_WSSE_BINARY_SECURITY_TOKEN);
90  
91          List<QName> sigPath = new ArrayList<>();
92          sigPath.addAll(WSSConstants.SOAP_11_WSSE_SECURITY_HEADER_PATH);
93          sigPath.add(WSSConstants.TAG_dsig_Signature);
94  
95          List<SecurityToken> securityTokens = new LinkedList<>();
96  
97          for (int i = 0; i < tokenUsages.size(); i++) {
98              WSSecurityTokenConstants.TokenUsage tokenUsage = tokenUsages.get(i);
99              X509TokenSecurityEvent x509TokenSecurityEvent = new X509TokenSecurityEvent();
100             X509SecurityTokenImpl securityToken = getX509Token(WSSecurityTokenConstants.X509V3Token);
101             securityTokens.add(securityToken);
102 
103             securityToken.setElementPath(bstPath);
104             securityToken.addTokenUsage(tokenUsage);
105             x509TokenSecurityEvent.setSecurityToken(securityToken);
106             policyEnforcer.registerSecurityEvent(x509TokenSecurityEvent);
107 
108             if (tokenUsage.getName().contains("Signature") || tokenUsage.getName().contains("Endorsing")) {
109                 SignedElementSecurityEvent signedElementSecurityEvent = new SignedElementSecurityEvent(securityToken, true, protectionOrder);
110                 signedElementSecurityEvent.setElementPath(bstPath);
111                 policyEnforcer.registerSecurityEvent(signedElementSecurityEvent);
112             }
113 
114             if (tokenUsage.getName().contains("Endorsing")) {
115                 SignedElementSecurityEvent signedElementSecurityEvent = new SignedElementSecurityEvent(securityToken, true, protectionOrder);
116                 signedElementSecurityEvent.setElementPath(sigPath);
117                 policyEnforcer.registerSecurityEvent(signedElementSecurityEvent);
118             }
119         }
120 
121         SecurityToken mainSignatureToken = null;
122         Iterator<SecurityToken> securityTokenIterator = securityTokens.iterator();
123         while (securityTokenIterator.hasNext()) {
124             SecurityToken securityToken = securityTokenIterator.next();
125             if (securityToken.getTokenUsages().contains(WSSecurityTokenConstants.TOKENUSAGE_MAIN_SIGNATURE)) {
126                 mainSignatureToken = securityToken;
127                 break;
128             }
129         }
130 
131         securityTokenIterator = securityTokens.iterator();
132         while (securityTokenIterator.hasNext()) {
133             SecurityToken securityToken = securityTokenIterator.next();
134             if (securityToken.getTokenUsages().get(0).getName().contains("Signed")) {
135                 SignedElementSecurityEvent signedElementSecurityEvent =
136                         new SignedElementSecurityEvent((InboundSecurityToken)mainSignatureToken, true, protectionOrder);
137                 signedElementSecurityEvent.setElementPath(bstPath);
138                 policyEnforcer.registerSecurityEvent(signedElementSecurityEvent);
139             }
140         }
141 
142         OperationSecurityEvent operationSecurityEvent = new OperationSecurityEvent();
143         operationSecurityEvent.setOperation(new QName("definitions"));
144         policyEnforcer.registerSecurityEvent(operationSecurityEvent);
145 
146         policyEnforcer.doFinal();
147     }
148 
149     @Test
150     public void testPolicyNoTokenProtection() throws Exception {
151         String policyString =
152                 "<sp:AsymmetricBinding xmlns:sp=\"http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702\" xmlns:sp3=\"http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200802\">\n" +
153                         "<wsp:Policy xmlns:wsp=\"http://schemas.xmlsoap.org/ws/2004/09/policy\">\n" +
154                         "   <sp:AlgorithmSuite>\n" +
155                         "       <wsp:Policy>\n" +
156                         "           <sp:Basic256/>\n" +
157                         "       </wsp:Policy>\n" +
158                         "   </sp:AlgorithmSuite>\n" +
159                         "</wsp:Policy>\n" +
160                         "</sp:AsymmetricBinding>";
161         PolicyEnforcer policyEnforcer = buildAndStartPolicyEngine(policyString);
162 
163         List<XMLSecurityConstants.ContentType> protectionOrder = new LinkedList<>();
164         protectionOrder.add(XMLSecurityConstants.ContentType.SIGNATURE);
165 
166         List<QName> bstPath = new ArrayList<>();
167         bstPath.addAll(WSSConstants.SOAP_11_WSSE_SECURITY_HEADER_PATH);
168         bstPath.add(WSSConstants.TAG_WSSE_BINARY_SECURITY_TOKEN);
169 
170         List<QName> sigPath = new ArrayList<>();
171         sigPath.addAll(WSSConstants.SOAP_11_WSSE_SECURITY_HEADER_PATH);
172         sigPath.add(WSSConstants.TAG_dsig_Signature);
173 
174         List<SecurityToken> securityTokens = new LinkedList<>();
175 
176         for (int i = 0; i < tokenUsages.size(); i++) {
177             WSSecurityTokenConstants.TokenUsage tokenUsage = tokenUsages.get(i);
178             X509TokenSecurityEvent x509TokenSecurityEvent = new X509TokenSecurityEvent();
179             X509SecurityTokenImpl securityToken = getX509Token(WSSecurityTokenConstants.X509V3Token);
180             securityTokens.add(securityToken);
181 
182             securityToken.setElementPath(bstPath);
183             securityToken.addTokenUsage(tokenUsage);
184             x509TokenSecurityEvent.setSecurityToken(securityToken);
185             policyEnforcer.registerSecurityEvent(x509TokenSecurityEvent);
186 
187             if (tokenUsage.getName().contains("Endorsing")) {
188                 SignedElementSecurityEvent signedElementSecurityEvent = new SignedElementSecurityEvent(securityToken, true, protectionOrder);
189                 signedElementSecurityEvent.setElementPath(sigPath);
190                 policyEnforcer.registerSecurityEvent(signedElementSecurityEvent);
191             }
192         }
193 
194         SecurityToken mainSignatureToken = null;
195         Iterator<SecurityToken> securityTokenIterator = securityTokens.iterator();
196         while (securityTokenIterator.hasNext()) {
197             SecurityToken securityToken = securityTokenIterator.next();
198             if (securityToken.getTokenUsages().contains(WSSecurityTokenConstants.TOKENUSAGE_MAIN_SIGNATURE)) {
199                 mainSignatureToken = securityToken;
200                 break;
201             }
202         }
203 
204         securityTokenIterator = securityTokens.iterator();
205         while (securityTokenIterator.hasNext()) {
206             SecurityToken securityToken = securityTokenIterator.next();
207             if (securityToken.getTokenUsages().get(0).getName().contains("Signed")) {
208                 SignedElementSecurityEvent signedElementSecurityEvent =
209                         new SignedElementSecurityEvent((InboundSecurityToken)mainSignatureToken, true, protectionOrder);
210                 signedElementSecurityEvent.setElementPath(bstPath);
211                 policyEnforcer.registerSecurityEvent(signedElementSecurityEvent);
212             }
213         }
214 
215         OperationSecurityEvent operationSecurityEvent = new OperationSecurityEvent();
216         operationSecurityEvent.setOperation(new QName("definitions"));
217         try {
218             policyEnforcer.registerSecurityEvent(operationSecurityEvent);
219         } catch (WSSecurityException e) {
220             assertTrue(e.getCause() instanceof PolicyViolationException);
221             assertEquals(e.getCause().getMessage(),
222                     "Token /{http://schemas.xmlsoap.org/soap/envelope/}Envelope/{http://schemas.xmlsoap.org/soap/envelope/}Header/{http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd}Security/{http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd}BinarySecurityToken must not be signed by its signature.");
223             assertEquals(e.getFaultCode(), WSSecurityException.INVALID_SECURITY);
224         }
225     }
226 
227     @Test
228     public void testPolicyElementNotSigned() throws Exception {
229         String policyString =
230                 "<sp:AsymmetricBinding xmlns:sp=\"http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702\" xmlns:sp3=\"http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200802\">\n" +
231                         "<wsp:Policy xmlns:wsp=\"http://schemas.xmlsoap.org/ws/2004/09/policy\">\n" +
232                         "   <sp:AlgorithmSuite>\n" +
233                         "       <wsp:Policy>\n" +
234                         "           <sp:Basic256/>\n" +
235                         "       </wsp:Policy>\n" +
236                         "   </sp:AlgorithmSuite>\n" +
237                         "<sp:ProtectTokens/>\n" +
238                         "</wsp:Policy>\n" +
239                         "</sp:AsymmetricBinding>";
240         PolicyEnforcer policyEnforcer = buildAndStartPolicyEngine(policyString);
241 
242         X509TokenSecurityEvent x509TokenSecurityEvent = new X509TokenSecurityEvent();
243         X509SecurityTokenImpl securityToken = getX509Token(WSSecurityTokenConstants.X509V3Token);
244         List<QName> path = new ArrayList<>();
245         path.addAll(WSSConstants.SOAP_11_WSSE_SECURITY_HEADER_PATH);
246         path.add(WSSConstants.TAG_WSSE_BINARY_SECURITY_TOKEN);
247         securityToken.setElementPath(path);
248         securityToken.addTokenUsage(WSSecurityTokenConstants.TOKENUSAGE_MAIN_SIGNATURE);
249         x509TokenSecurityEvent.setSecurityToken(securityToken);
250         policyEnforcer.registerSecurityEvent(x509TokenSecurityEvent);
251 
252         List<XMLSecurityConstants.ContentType> protectionOrder = new LinkedList<>();
253         protectionOrder.add(XMLSecurityConstants.ContentType.SIGNATURE);
254 
255         SignedElementSecurityEvent signedElementSecurityEvent = new SignedElementSecurityEvent(securityToken, false, protectionOrder);
256         signedElementSecurityEvent.setElementPath(path);
257         policyEnforcer.registerSecurityEvent(signedElementSecurityEvent);
258 
259         OperationSecurityEvent operationSecurityEvent = new OperationSecurityEvent();
260         operationSecurityEvent.setOperation(new QName("definitions"));
261 
262         try {
263             policyEnforcer.registerSecurityEvent(operationSecurityEvent);
264             fail("Exception expected");
265         } catch (WSSecurityException e) {
266             assertTrue(e.getCause() instanceof PolicyViolationException);
267             assertEquals(e.getCause().getMessage(),
268                     "Token /{http://schemas.xmlsoap.org/soap/envelope/}Envelope/{http://schemas.xmlsoap.org/soap/envelope/}Header/{http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd}Security/{http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd}BinarySecurityToken must be signed by its signature.");
269             assertEquals(e.getFaultCode(), WSSecurityException.INVALID_SECURITY);
270         }
271     }
272 
273     @Test
274     public void testPolicyElementSignedByOtherSignature() throws Exception {
275         String policyString =
276                 "<sp:AsymmetricBinding xmlns:sp=\"http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702\" xmlns:sp3=\"http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200802\">\n" +
277                         "<wsp:Policy xmlns:wsp=\"http://schemas.xmlsoap.org/ws/2004/09/policy\">\n" +
278                         "   <sp:AlgorithmSuite>\n" +
279                         "       <wsp:Policy>\n" +
280                         "           <sp:Basic256/>\n" +
281                         "       </wsp:Policy>\n" +
282                         "   </sp:AlgorithmSuite>\n" +
283                         "<sp:ProtectTokens/>\n" +
284                         "</wsp:Policy>\n" +
285                         "</sp:AsymmetricBinding>";
286         PolicyEnforcer policyEnforcer = buildAndStartPolicyEngine(policyString);
287 
288         X509TokenSecurityEvent x509TokenSecurityEvent = new X509TokenSecurityEvent();
289         X509SecurityTokenImpl securityToken = getX509Token(WSSecurityTokenConstants.X509V3Token);
290         List<QName> path = new ArrayList<>();
291         path.addAll(WSSConstants.SOAP_11_WSSE_SECURITY_HEADER_PATH);
292         path.add(WSSConstants.TAG_WSSE_BINARY_SECURITY_TOKEN);
293         securityToken.setElementPath(path);
294         securityToken.addTokenUsage(WSSecurityTokenConstants.TOKENUSAGE_MAIN_SIGNATURE);
295         x509TokenSecurityEvent.setSecurityToken(securityToken);
296         policyEnforcer.registerSecurityEvent(x509TokenSecurityEvent);
297 
298         List<XMLSecurityConstants.ContentType> protectionOrder = new LinkedList<>();
299         protectionOrder.add(XMLSecurityConstants.ContentType.SIGNATURE);
300 
301         SignedElementSecurityEvent signedElementSecurityEvent = new SignedElementSecurityEvent(getX509Token(WSSecurityTokenConstants.X509V3Token), false, protectionOrder);
302         signedElementSecurityEvent.setElementPath(path);
303         policyEnforcer.registerSecurityEvent(signedElementSecurityEvent);
304 
305         OperationSecurityEvent operationSecurityEvent = new OperationSecurityEvent();
306         operationSecurityEvent.setOperation(new QName("definitions"));
307 
308         try {
309             policyEnforcer.registerSecurityEvent(operationSecurityEvent);
310             fail("Exception expected");
311         } catch (WSSecurityException e) {
312             assertTrue(e.getCause() instanceof PolicyViolationException);
313             assertEquals(e.getCause().getMessage(),
314                     "Token /{http://schemas.xmlsoap.org/soap/envelope/}Envelope/{http://schemas.xmlsoap.org/soap/envelope/}Header/{http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd}Security/{http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd}BinarySecurityToken must be signed by its signature.");
315             assertEquals(e.getFaultCode(), WSSecurityException.INVALID_SECURITY);
316         }
317     }
318 
319     @Test
320     public void testPolicyElementSignedByOtherSignatureReverseSecurityEventOrder() throws Exception {
321         String policyString =
322                 "<sp:AsymmetricBinding xmlns:sp=\"http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702\" xmlns:sp3=\"http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200802\">\n" +
323                         "<wsp:Policy xmlns:wsp=\"http://schemas.xmlsoap.org/ws/2004/09/policy\">\n" +
324                         "   <sp:AlgorithmSuite>\n" +
325                         "       <wsp:Policy>\n" +
326                         "           <sp:Basic256/>\n" +
327                         "       </wsp:Policy>\n" +
328                         "   </sp:AlgorithmSuite>\n" +
329                         "<sp:ProtectTokens/>\n" +
330                         "</wsp:Policy>\n" +
331                         "</sp:AsymmetricBinding>";
332         PolicyEnforcer policyEnforcer = buildAndStartPolicyEngine(policyString);
333 
334         X509TokenSecurityEvent x509TokenSecurityEvent = new X509TokenSecurityEvent();
335         X509SecurityTokenImpl securityToken = getX509Token(WSSecurityTokenConstants.X509V3Token);
336         List<QName> path = new ArrayList<>();
337         path.addAll(WSSConstants.SOAP_11_WSSE_SECURITY_HEADER_PATH);
338         path.add(WSSConstants.TAG_WSSE_BINARY_SECURITY_TOKEN);
339         securityToken.setElementPath(path);
340         securityToken.addTokenUsage(WSSecurityTokenConstants.TOKENUSAGE_MAIN_SIGNATURE);
341         x509TokenSecurityEvent.setSecurityToken(securityToken);
342 
343         List<XMLSecurityConstants.ContentType> protectionOrder = new LinkedList<>();
344         protectionOrder.add(XMLSecurityConstants.ContentType.SIGNATURE);
345 
346         SignedElementSecurityEvent signedElementSecurityEvent = new SignedElementSecurityEvent(getX509Token(WSSecurityTokenConstants.X509V3Token), false, protectionOrder);
347         signedElementSecurityEvent.setElementPath(path);
348         policyEnforcer.registerSecurityEvent(signedElementSecurityEvent);
349 
350         policyEnforcer.registerSecurityEvent(x509TokenSecurityEvent);
351 
352         OperationSecurityEvent operationSecurityEvent = new OperationSecurityEvent();
353         operationSecurityEvent.setOperation(new QName("definitions"));
354 
355         try {
356             policyEnforcer.registerSecurityEvent(operationSecurityEvent);
357             fail("Exception expected");
358         } catch (WSSecurityException e) {
359             assertTrue(e.getCause() instanceof PolicyViolationException);
360             assertEquals(e.getCause().getMessage(),
361                     "Token /{http://schemas.xmlsoap.org/soap/envelope/}Envelope/{http://schemas.xmlsoap.org/soap/envelope/}Header/{http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd}Security/{http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd}BinarySecurityToken must be signed by its signature.");
362             assertEquals(e.getFaultCode(), WSSecurityException.INVALID_SECURITY);
363         }
364     }
365 
366     @Test
367     public void testPolicyEndorsingTokenNotSigningMainSignatureToken() throws Exception {
368         String policyString =
369                 "<sp:AsymmetricBinding xmlns:sp=\"http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702\" xmlns:sp3=\"http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200802\">\n" +
370                         "<wsp:Policy xmlns:wsp=\"http://schemas.xmlsoap.org/ws/2004/09/policy\">\n" +
371                         "   <sp:AlgorithmSuite>\n" +
372                         "       <wsp:Policy>\n" +
373                         "           <sp:Basic256/>\n" +
374                         "       </wsp:Policy>\n" +
375                         "   </sp:AlgorithmSuite>\n" +
376                         "<sp:ProtectTokens/>\n" +
377                         "</wsp:Policy>\n" +
378                         "</sp:AsymmetricBinding>";
379         PolicyEnforcer policyEnforcer = buildAndStartPolicyEngine(policyString);
380 
381         List<XMLSecurityConstants.ContentType> protectionOrder = new LinkedList<>();
382         protectionOrder.add(XMLSecurityConstants.ContentType.SIGNATURE);
383 
384         List<QName> bstPath = new ArrayList<>();
385         bstPath.addAll(WSSConstants.SOAP_11_WSSE_SECURITY_HEADER_PATH);
386         bstPath.add(WSSConstants.TAG_WSSE_BINARY_SECURITY_TOKEN);
387 
388         List<SecurityToken> securityTokens = new LinkedList<>();
389 
390         for (int i = 0; i < tokenUsages.size(); i++) {
391             WSSecurityTokenConstants.TokenUsage tokenUsage = tokenUsages.get(i);
392             X509TokenSecurityEvent x509TokenSecurityEvent = new X509TokenSecurityEvent();
393             X509SecurityTokenImpl securityToken = getX509Token(WSSecurityTokenConstants.X509V3Token);
394 
395             securityTokens.add(securityToken);
396 
397             securityToken.setElementPath(bstPath);
398             securityToken.addTokenUsage(tokenUsage);
399             x509TokenSecurityEvent.setSecurityToken(securityToken);
400             policyEnforcer.registerSecurityEvent(x509TokenSecurityEvent);
401 
402             if (tokenUsage.getName().contains("Signature") || tokenUsage.getName().contains("Endorsing")) {
403                 SignedElementSecurityEvent signedElementSecurityEvent = new SignedElementSecurityEvent(securityToken, true, protectionOrder);
404                 signedElementSecurityEvent.setElementPath(bstPath);
405                 policyEnforcer.registerSecurityEvent(signedElementSecurityEvent);
406             }
407         }
408 
409         SecurityToken mainSignatureToken = null;
410         Iterator<SecurityToken> securityTokenIterator = securityTokens.iterator();
411         while (securityTokenIterator.hasNext()) {
412             SecurityToken securityToken = securityTokenIterator.next();
413             if (securityToken.getTokenUsages().contains(WSSecurityTokenConstants.TOKENUSAGE_MAIN_SIGNATURE)) {
414                 mainSignatureToken = securityToken;
415                 break;
416             }
417         }
418 
419         securityTokenIterator = securityTokens.iterator();
420         while (securityTokenIterator.hasNext()) {
421             SecurityToken securityToken = securityTokenIterator.next();
422             if (securityToken.getTokenUsages().get(0).getName().contains("Signed")) {
423                 SignedElementSecurityEvent signedElementSecurityEvent =
424                         new SignedElementSecurityEvent((InboundSecurityToken)mainSignatureToken, true, protectionOrder);
425                 signedElementSecurityEvent.setElementPath(bstPath);
426                 policyEnforcer.registerSecurityEvent(signedElementSecurityEvent);
427             }
428         }
429 
430         OperationSecurityEvent operationSecurityEvent = new OperationSecurityEvent();
431         operationSecurityEvent.setOperation(new QName("definitions"));
432         try {
433             policyEnforcer.registerSecurityEvent(operationSecurityEvent);
434         } catch (WSSecurityException e) {
435             assertTrue(e.getCause() instanceof PolicyViolationException);
436             assertEquals(e.getCause().getMessage(),
437                     "Token /{http://schemas.xmlsoap.org/soap/envelope/}Envelope/{http://schemas.xmlsoap.org/soap/envelope/}Header/{http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd}Security/{http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd}BinarySecurityToken must sign the main signature.");
438             assertEquals(e.getFaultCode(), WSSecurityException.INVALID_SECURITY);
439         }
440     }
441 
442     @Test
443     public void testPolicyMainSignatureNotSigningEndorsingSignatureTokens() throws Exception {
444         String policyString =
445                 "<sp:AsymmetricBinding xmlns:sp=\"http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702\" xmlns:sp3=\"http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200802\">\n" +
446                         "<wsp:Policy xmlns:wsp=\"http://schemas.xmlsoap.org/ws/2004/09/policy\">\n" +
447                         "   <sp:AlgorithmSuite>\n" +
448                         "       <wsp:Policy>\n" +
449                         "           <sp:Basic256/>\n" +
450                         "       </wsp:Policy>\n" +
451                         "   </sp:AlgorithmSuite>\n" +
452                         "<sp:ProtectTokens/>\n" +
453                         "</wsp:Policy>\n" +
454                         "</sp:AsymmetricBinding>";
455         PolicyEnforcer policyEnforcer = buildAndStartPolicyEngine(policyString);
456 
457         List<XMLSecurityConstants.ContentType> protectionOrder = new LinkedList<>();
458         protectionOrder.add(XMLSecurityConstants.ContentType.SIGNATURE);
459 
460         List<QName> bstPath = new ArrayList<>();
461         bstPath.addAll(WSSConstants.SOAP_11_WSSE_SECURITY_HEADER_PATH);
462         bstPath.add(WSSConstants.TAG_WSSE_BINARY_SECURITY_TOKEN);
463 
464         List<QName> sigPath = new ArrayList<>();
465         sigPath.addAll(WSSConstants.SOAP_11_WSSE_SECURITY_HEADER_PATH);
466         sigPath.add(WSSConstants.TAG_dsig_Signature);
467 
468         for (int i = 0; i < tokenUsages.size(); i++) {
469             WSSecurityTokenConstants.TokenUsage tokenUsage = tokenUsages.get(i);
470             X509TokenSecurityEvent x509TokenSecurityEvent = new X509TokenSecurityEvent();
471             X509SecurityTokenImpl securityToken = getX509Token(WSSecurityTokenConstants.X509V3Token);
472 
473             securityToken.setElementPath(bstPath);
474             securityToken.addTokenUsage(tokenUsage);
475             x509TokenSecurityEvent.setSecurityToken(securityToken);
476             policyEnforcer.registerSecurityEvent(x509TokenSecurityEvent);
477 
478             if (tokenUsage.getName().contains("Signature") || tokenUsage.getName().contains("Endorsing")) {
479                 SignedElementSecurityEvent signedElementSecurityEvent = new SignedElementSecurityEvent(securityToken, true, protectionOrder);
480                 signedElementSecurityEvent.setElementPath(bstPath);
481                 policyEnforcer.registerSecurityEvent(signedElementSecurityEvent);
482             }
483 
484             if (tokenUsage.getName().contains("Endorsing")) {
485                 SignedElementSecurityEvent signedElementSecurityEvent = new SignedElementSecurityEvent(securityToken, true, protectionOrder);
486                 signedElementSecurityEvent.setElementPath(sigPath);
487                 policyEnforcer.registerSecurityEvent(signedElementSecurityEvent);
488             }
489         }
490 
491         OperationSecurityEvent operationSecurityEvent = new OperationSecurityEvent();
492         operationSecurityEvent.setOperation(new QName("definitions"));
493 
494         try {
495             policyEnforcer.registerSecurityEvent(operationSecurityEvent);
496         } catch (WSSecurityException e) {
497             assertTrue(e.getCause() instanceof PolicyViolationException);
498             assertEquals(e.getCause().getMessage(),
499                     "Main signature must sign the Signed*Supporting-Tokens.");
500             assertEquals(e.getFaultCode(), WSSecurityException.INVALID_SECURITY);
501         }
502     }
503 
504     @Test
505     public void testPolicySymmetricBindingProtectSignatureToken() throws Exception {
506         String policyString =
507                 "<sp:SymmetricBinding xmlns:sp=\"http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702\" xmlns:sp3=\"http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200802\">\n" +
508                         "<wsp:Policy xmlns:wsp=\"http://schemas.xmlsoap.org/ws/2004/09/policy\">\n" +
509                         "   <sp:AlgorithmSuite>\n" +
510                         "       <wsp:Policy>\n" +
511                         "           <sp:Basic256/>\n" +
512                         "       </wsp:Policy>\n" +
513                         "   </sp:AlgorithmSuite>\n" +
514                         "<sp:ProtectTokens/>\n" +
515                         "</wsp:Policy>\n" +
516                         "</sp:SymmetricBinding>";
517         PolicyEnforcer policyEnforcer = buildAndStartPolicyEngine(policyString);
518 
519         List<XMLSecurityConstants.ContentType> protectionOrder = new LinkedList<>();
520         protectionOrder.add(XMLSecurityConstants.ContentType.SIGNATURE);
521 
522         List<QName> bstPath = new ArrayList<>();
523         bstPath.addAll(WSSConstants.SOAP_11_WSSE_SECURITY_HEADER_PATH);
524         bstPath.add(WSSConstants.TAG_WSSE_BINARY_SECURITY_TOKEN);
525 
526         List<QName> ekPath = new ArrayList<>();
527         ekPath.addAll(WSSConstants.SOAP_11_WSSE_SECURITY_HEADER_PATH);
528         ekPath.add(WSSConstants.TAG_xenc_EncryptedKey);
529 
530         List<QName> sigPath = new ArrayList<>();
531         sigPath.addAll(WSSConstants.SOAP_11_WSSE_SECURITY_HEADER_PATH);
532         sigPath.add(WSSConstants.TAG_dsig_Signature);
533 
534         X509SecurityTokenImpl x509SecurityToken = getX509Token(WSSecurityTokenConstants.X509V3Token);
535         x509SecurityToken.addTokenUsage(WSSecurityTokenConstants.TOKENUSAGE_MAIN_SIGNATURE);
536         x509SecurityToken.setElementPath(bstPath);
537 
538         AbstractInboundSecurityToken ekSecurityToken = new AbstractInboundSecurityToken(
539                 null, IDGenerator.generateID(null),
540                 SecurityTokenConstants.KeyIdentifier_EncryptedKey, true) {
541             @Override
542             public SecurityTokenConstants.TokenType getTokenType() {
543                 return SecurityTokenConstants.EncryptedKeyToken;
544             }
545         };
546         ekSecurityToken.addTokenUsage(WSSecurityTokenConstants.TokenUsage_Signature);
547         ekSecurityToken.setKeyWrappingToken(x509SecurityToken);
548         ekSecurityToken.setElementPath(ekPath);
549 
550         x509SecurityToken.addWrappedToken(ekSecurityToken);
551 
552         X509TokenSecurityEvent x509TokenSecurityEvent = new X509TokenSecurityEvent();
553         x509TokenSecurityEvent.setSecurityToken(x509SecurityToken);
554         policyEnforcer.registerSecurityEvent(x509TokenSecurityEvent);
555 
556         EncryptedKeyTokenSecurityEvent encryptedKeyTokenSecurityEvent = new EncryptedKeyTokenSecurityEvent();
557         encryptedKeyTokenSecurityEvent.setSecurityToken(ekSecurityToken);
558         policyEnforcer.registerSecurityEvent(encryptedKeyTokenSecurityEvent);
559 
560         SignedElementSecurityEvent signedElementSecurityEvent = new SignedElementSecurityEvent(ekSecurityToken, true, protectionOrder);
561         signedElementSecurityEvent.setElementPath(ekPath);
562         policyEnforcer.registerSecurityEvent(signedElementSecurityEvent);
563 
564         OperationSecurityEvent operationSecurityEvent = new OperationSecurityEvent();
565         operationSecurityEvent.setOperation(new QName("definitions"));
566 
567         policyEnforcer.registerSecurityEvent(operationSecurityEvent);
568         policyEnforcer.doFinal();
569     }
570 
571     @Test
572     public void testPolicySymmetricBindingProtectRootToken() throws Exception {
573         String policyString =
574                 "<sp:SymmetricBinding xmlns:sp=\"http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702\" xmlns:sp3=\"http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200802\">\n" +
575                         "<wsp:Policy xmlns:wsp=\"http://schemas.xmlsoap.org/ws/2004/09/policy\">\n" +
576                         "   <sp:AlgorithmSuite>\n" +
577                         "       <wsp:Policy>\n" +
578                         "           <sp:Basic256/>\n" +
579                         "       </wsp:Policy>\n" +
580                         "   </sp:AlgorithmSuite>\n" +
581                         "<sp:ProtectTokens/>\n" +
582                         "</wsp:Policy>\n" +
583                         "</sp:SymmetricBinding>";
584         PolicyEnforcer policyEnforcer = buildAndStartPolicyEngine(policyString);
585 
586         List<XMLSecurityConstants.ContentType> protectionOrder = new LinkedList<>();
587         protectionOrder.add(XMLSecurityConstants.ContentType.SIGNATURE);
588 
589         List<QName> bstPath = new ArrayList<>();
590         bstPath.addAll(WSSConstants.SOAP_11_WSSE_SECURITY_HEADER_PATH);
591         bstPath.add(WSSConstants.TAG_WSSE_BINARY_SECURITY_TOKEN);
592 
593         List<QName> ekPath = new ArrayList<>();
594         ekPath.addAll(WSSConstants.SOAP_11_WSSE_SECURITY_HEADER_PATH);
595         ekPath.add(WSSConstants.TAG_xenc_EncryptedKey);
596 
597         List<QName> sigPath = new ArrayList<>();
598         sigPath.addAll(WSSConstants.SOAP_11_WSSE_SECURITY_HEADER_PATH);
599         sigPath.add(WSSConstants.TAG_dsig_Signature);
600 
601         X509SecurityTokenImpl x509SecurityToken = getX509Token(WSSecurityTokenConstants.X509V3Token);
602         x509SecurityToken.addTokenUsage(WSSecurityTokenConstants.TOKENUSAGE_MAIN_SIGNATURE);
603         x509SecurityToken.setElementPath(bstPath);
604 
605         AbstractInboundSecurityToken ekSecurityToken = new AbstractInboundSecurityToken(
606                 null, IDGenerator.generateID(null),
607                 SecurityTokenConstants.KeyIdentifier_EncryptedKey, true) {
608             @Override
609             public SecurityTokenConstants.TokenType getTokenType() {
610                 return SecurityTokenConstants.EncryptedKeyToken;
611             }
612         };
613         ekSecurityToken.addTokenUsage(WSSecurityTokenConstants.TokenUsage_Signature);
614         ekSecurityToken.setKeyWrappingToken(x509SecurityToken);
615         ekSecurityToken.setElementPath(ekPath);
616 
617         x509SecurityToken.addWrappedToken(ekSecurityToken);
618 
619         X509TokenSecurityEvent x509TokenSecurityEvent = new X509TokenSecurityEvent();
620         x509TokenSecurityEvent.setSecurityToken(x509SecurityToken);
621         policyEnforcer.registerSecurityEvent(x509TokenSecurityEvent);
622 
623         EncryptedKeyTokenSecurityEvent encryptedKeyTokenSecurityEvent = new EncryptedKeyTokenSecurityEvent();
624         encryptedKeyTokenSecurityEvent.setSecurityToken(ekSecurityToken);
625         policyEnforcer.registerSecurityEvent(encryptedKeyTokenSecurityEvent);
626 
627         SignedElementSecurityEvent signedElementSecurityEvent = new SignedElementSecurityEvent(x509SecurityToken, true, protectionOrder);
628         signedElementSecurityEvent.setElementPath(bstPath);
629         policyEnforcer.registerSecurityEvent(signedElementSecurityEvent);
630 
631         OperationSecurityEvent operationSecurityEvent = new OperationSecurityEvent();
632         operationSecurityEvent.setOperation(new QName("definitions"));
633 
634         try {
635             policyEnforcer.registerSecurityEvent(operationSecurityEvent);
636         } catch (WSSecurityException e) {
637             assertTrue(e.getCause() instanceof PolicyViolationException);
638             assertEquals(e.getCause().getMessage(),
639                     "Token /{http://schemas.xmlsoap.org/soap/envelope/}Envelope/{http://schemas.xmlsoap.org/soap/envelope/}Header/{http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd}Security/{http://www.w3.org/2001/04/xmlenc#}EncryptedKey must be signed by its signature.");
640             assertEquals(e.getFaultCode(), WSSecurityException.INVALID_SECURITY);
641         }
642     }
643 
644     @Test
645     public void testPolicySymmetricBindingProtectAllToken() throws Exception {
646         String policyString =
647                 "<sp:SymmetricBinding xmlns:sp=\"http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702\" xmlns:sp3=\"http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200802\">\n" +
648                         "<wsp:Policy xmlns:wsp=\"http://schemas.xmlsoap.org/ws/2004/09/policy\">\n" +
649                         "   <sp:AlgorithmSuite>\n" +
650                         "       <wsp:Policy>\n" +
651                         "           <sp:Basic256/>\n" +
652                         "       </wsp:Policy>\n" +
653                         "   </sp:AlgorithmSuite>\n" +
654                         "<sp:ProtectTokens/>\n" +
655                         "</wsp:Policy>\n" +
656                         "</sp:SymmetricBinding>";
657         PolicyEnforcer policyEnforcer = buildAndStartPolicyEngine(policyString);
658 
659         List<XMLSecurityConstants.ContentType> protectionOrder = new LinkedList<>();
660         protectionOrder.add(XMLSecurityConstants.ContentType.SIGNATURE);
661 
662         List<QName> bstPath = new ArrayList<>();
663         bstPath.addAll(WSSConstants.SOAP_11_WSSE_SECURITY_HEADER_PATH);
664         bstPath.add(WSSConstants.TAG_WSSE_BINARY_SECURITY_TOKEN);
665 
666         List<QName> ekPath = new ArrayList<>();
667         ekPath.addAll(WSSConstants.SOAP_11_WSSE_SECURITY_HEADER_PATH);
668         ekPath.add(WSSConstants.TAG_xenc_EncryptedKey);
669 
670         List<QName> sigPath = new ArrayList<>();
671         sigPath.addAll(WSSConstants.SOAP_11_WSSE_SECURITY_HEADER_PATH);
672         sigPath.add(WSSConstants.TAG_dsig_Signature);
673 
674         X509SecurityTokenImpl x509SecurityToken = getX509Token(WSSecurityTokenConstants.X509V3Token);
675         x509SecurityToken.addTokenUsage(WSSecurityTokenConstants.TOKENUSAGE_MAIN_SIGNATURE);
676         x509SecurityToken.setElementPath(bstPath);
677 
678         AbstractInboundSecurityToken ekSecurityToken = new AbstractInboundSecurityToken(
679                 null, IDGenerator.generateID(null),
680                 SecurityTokenConstants.KeyIdentifier_EncryptedKey, true) {
681             @Override
682             public SecurityTokenConstants.TokenType getTokenType() {
683                 return SecurityTokenConstants.EncryptedKeyToken;
684             }
685         };
686         ekSecurityToken.addTokenUsage(WSSecurityTokenConstants.TokenUsage_Signature);
687         ekSecurityToken.setKeyWrappingToken(x509SecurityToken);
688         ekSecurityToken.setElementPath(ekPath);
689 
690         x509SecurityToken.addWrappedToken(ekSecurityToken);
691 
692         X509TokenSecurityEvent x509TokenSecurityEvent = new X509TokenSecurityEvent();
693         x509TokenSecurityEvent.setSecurityToken(x509SecurityToken);
694         policyEnforcer.registerSecurityEvent(x509TokenSecurityEvent);
695 
696         EncryptedKeyTokenSecurityEvent encryptedKeyTokenSecurityEvent = new EncryptedKeyTokenSecurityEvent();
697         encryptedKeyTokenSecurityEvent.setSecurityToken(ekSecurityToken);
698         policyEnforcer.registerSecurityEvent(encryptedKeyTokenSecurityEvent);
699 
700         SignedElementSecurityEvent signedElementSecurityEvent = new SignedElementSecurityEvent(x509SecurityToken, true, protectionOrder);
701         signedElementSecurityEvent.setElementPath(bstPath);
702         policyEnforcer.registerSecurityEvent(signedElementSecurityEvent);
703 
704         signedElementSecurityEvent = new SignedElementSecurityEvent(ekSecurityToken, true, protectionOrder);
705         signedElementSecurityEvent.setElementPath(ekPath);
706         policyEnforcer.registerSecurityEvent(signedElementSecurityEvent);
707 
708         OperationSecurityEvent operationSecurityEvent = new OperationSecurityEvent();
709         operationSecurityEvent.setOperation(new QName("definitions"));
710 
711         policyEnforcer.registerSecurityEvent(operationSecurityEvent);
712         policyEnforcer.doFinal();
713     }
714 }