1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.wss4j.policy.stax.test;
20
21 import java.util.ArrayList;
22 import java.util.LinkedList;
23 import java.util.List;
24
25 import javax.xml.namespace.QName;
26
27 import org.apache.wss4j.common.ext.WSSecurityException;
28 import org.apache.wss4j.policy.stax.PolicyViolationException;
29 import org.apache.wss4j.policy.stax.enforcer.PolicyEnforcer;
30 import org.apache.wss4j.stax.ext.WSSConstants;
31 import org.apache.wss4j.stax.impl.securityToken.SecureConversationSecurityTokenImpl;
32 import org.apache.wss4j.stax.securityEvent.OperationSecurityEvent;
33 import org.apache.wss4j.stax.securityEvent.RequiredElementSecurityEvent;
34 import org.apache.wss4j.stax.securityEvent.SecurityContextTokenSecurityEvent;
35 import org.apache.wss4j.stax.securityEvent.SignedPartSecurityEvent;
36 import org.apache.wss4j.stax.securityEvent.TimestampSecurityEvent;
37 import org.apache.wss4j.stax.securityToken.WSSecurityTokenConstants;
38 import org.apache.xml.security.stax.ext.XMLSecurityConstants;
39 import org.apache.xml.security.stax.ext.stax.XMLSecEventFactory;
40 import org.apache.xml.security.stax.securityEvent.EncryptedElementSecurityEvent;
41 import org.junit.jupiter.api.Test;
42
43 import static org.junit.jupiter.api.Assertions.assertEquals;
44 import static org.junit.jupiter.api.Assertions.assertTrue;
45 import static org.junit.jupiter.api.Assertions.fail;
46
47 public class SymmetricBindingTest extends AbstractPolicyTestBase {
48
49 @Test
50 public void testPolicy() throws Exception {
51 String policyString =
52 "<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" +
53 "<wsp:Policy xmlns:wsp=\"http://schemas.xmlsoap.org/ws/2004/09/policy\">\n" +
54 " <sp:AlgorithmSuite>\n" +
55 " <wsp:Policy>\n" +
56 " <sp:Basic256/>\n" +
57 " </wsp:Policy>\n" +
58 " </sp:AlgorithmSuite>\n" +
59 "<sp:IncludeTimestamp/>\n" +
60 "<sp:EncryptSignature/>\n" +
61 "<sp:OnlySignEntireHeadersAndBody/>\n" +
62 "</wsp:Policy>\n" +
63 "</sp:SymmetricBinding>";
64 PolicyEnforcer policyEnforcer = buildAndStartPolicyEngine(policyString);
65
66 TimestampSecurityEvent timestampSecurityEvent = new TimestampSecurityEvent();
67 policyEnforcer.registerSecurityEvent(timestampSecurityEvent);
68
69 RequiredElementSecurityEvent requiredElementSecurityEvent = new RequiredElementSecurityEvent();
70 List<QName> headerPath = new ArrayList<>();
71 headerPath.addAll(WSSConstants.SOAP_11_WSSE_SECURITY_HEADER_PATH);
72 headerPath.add(WSSConstants.TAG_WSU_TIMESTAMP);
73 requiredElementSecurityEvent.setElementPath(headerPath);
74 policyEnforcer.registerSecurityEvent(requiredElementSecurityEvent);
75
76 SecurityContextTokenSecurityEvent initiatorTokenSecurityEvent = new SecurityContextTokenSecurityEvent();
77 SecureConversationSecurityTokenImpl securityToken =
78 new SecureConversationSecurityTokenImpl(
79 null, "1", WSSecurityTokenConstants.KEYIDENTIFIER_SECURITY_TOKEN_DIRECT_REFERENCE);
80 securityToken.addTokenUsage(WSSecurityTokenConstants.TOKENUSAGE_MAIN_SIGNATURE);
81 initiatorTokenSecurityEvent.setSecurityToken(securityToken);
82 policyEnforcer.registerSecurityEvent(initiatorTokenSecurityEvent);
83
84 SecurityContextTokenSecurityEvent recipientTokenSecurityEvent = new SecurityContextTokenSecurityEvent();
85 securityToken = new SecureConversationSecurityTokenImpl(
86 null, "1", WSSecurityTokenConstants.KEYIDENTIFIER_SECURITY_TOKEN_DIRECT_REFERENCE);
87 securityToken.addTokenUsage(WSSecurityTokenConstants.TOKENUSAGE_MAIN_ENCRYPTION);
88 recipientTokenSecurityEvent.setSecurityToken(securityToken);
89 policyEnforcer.registerSecurityEvent(recipientTokenSecurityEvent);
90
91 List<XMLSecurityConstants.ContentType> protectionOrder = new LinkedList<>();
92 protectionOrder.add(XMLSecurityConstants.ContentType.SIGNATURE);
93 protectionOrder.add(XMLSecurityConstants.ContentType.ENCRYPTION);
94 EncryptedElementSecurityEvent encryptedElementSecurityEvent = new EncryptedElementSecurityEvent(null, true, protectionOrder);
95 headerPath = new ArrayList<>();
96 headerPath.addAll(WSSConstants.SOAP_11_WSSE_SECURITY_HEADER_PATH);
97 headerPath.add(WSSConstants.TAG_dsig_Signature);
98 encryptedElementSecurityEvent.setElementPath(headerPath);
99 policyEnforcer.registerSecurityEvent(encryptedElementSecurityEvent);
100
101 encryptedElementSecurityEvent = new EncryptedElementSecurityEvent(null, true, protectionOrder);
102 headerPath = new ArrayList<>();
103 headerPath.addAll(WSSConstants.SOAP_11_WSSE_SECURITY_HEADER_PATH);
104 headerPath.add(WSSConstants.TAG_WSSE11_SIG_CONF);
105 encryptedElementSecurityEvent.setElementPath(headerPath);
106 policyEnforcer.registerSecurityEvent(encryptedElementSecurityEvent);
107
108 OperationSecurityEvent operationSecurityEvent = new OperationSecurityEvent();
109 operationSecurityEvent.setOperation(new QName("definitions"));
110 policyEnforcer.registerSecurityEvent(operationSecurityEvent);
111
112 SignedPartSecurityEvent signedPartSecurityEvent = new SignedPartSecurityEvent(null, true, protectionOrder);
113 signedPartSecurityEvent.setXmlSecEvent(XMLSecEventFactory.createXmlSecStartElement(WSSConstants.TAG_SOAP11_BODY, null, null));
114 signedPartSecurityEvent.setElementPath(WSSConstants.SOAP_11_BODY_PATH);
115 policyEnforcer.registerSecurityEvent(signedPartSecurityEvent);
116 policyEnforcer.doFinal();
117 }
118
119 @Test
120 public void testPolicyNotIncludeTimestamp() throws Exception {
121 String policyString =
122 "<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" +
123 "<wsp:Policy xmlns:wsp=\"http://schemas.xmlsoap.org/ws/2004/09/policy\">\n" +
124 " <sp:AlgorithmSuite>\n" +
125 " <wsp:Policy>\n" +
126 " <sp:Basic256/>\n" +
127 " </wsp:Policy>\n" +
128 " </sp:AlgorithmSuite>\n" +
129 "<sp:EncryptSignature/>\n" +
130 "<sp:ProtectTokens/>\n" +
131 "<sp:OnlySignEntireHeadersAndBody/>\n" +
132 "</wsp:Policy>\n" +
133 "</sp:SymmetricBinding>";
134 PolicyEnforcer policyEnforcer = buildAndStartPolicyEngine(policyString);
135
136 SecurityContextTokenSecurityEvent initiatorTokenSecurityEvent = new SecurityContextTokenSecurityEvent();
137 SecureConversationSecurityTokenImpl securityToken =
138 new SecureConversationSecurityTokenImpl(
139 null, "1", WSSecurityTokenConstants.KEYIDENTIFIER_SECURITY_TOKEN_DIRECT_REFERENCE);
140 securityToken.addTokenUsage(WSSecurityTokenConstants.TOKENUSAGE_MAIN_SIGNATURE);
141 initiatorTokenSecurityEvent.setSecurityToken(securityToken);
142 policyEnforcer.registerSecurityEvent(initiatorTokenSecurityEvent);
143
144 SecurityContextTokenSecurityEvent recipientTokenSecurityEvent = new SecurityContextTokenSecurityEvent();
145 securityToken = new SecureConversationSecurityTokenImpl(
146 null, "1", WSSecurityTokenConstants.KEYIDENTIFIER_SECURITY_TOKEN_DIRECT_REFERENCE);
147 securityToken.addTokenUsage(WSSecurityTokenConstants.TOKENUSAGE_MAIN_ENCRYPTION);
148 recipientTokenSecurityEvent.setSecurityToken(securityToken);
149 policyEnforcer.registerSecurityEvent(recipientTokenSecurityEvent);
150
151 TimestampSecurityEvent timestampSecurityEvent = new TimestampSecurityEvent();
152 policyEnforcer.registerSecurityEvent(timestampSecurityEvent);
153
154 OperationSecurityEvent operationSecurityEvent = new OperationSecurityEvent();
155 operationSecurityEvent.setOperation(new QName("definitions"));
156 try {
157 policyEnforcer.registerSecurityEvent(operationSecurityEvent);
158 fail("Exception expected");
159 } catch (WSSecurityException e) {
160 assertTrue(e.getCause() instanceof PolicyViolationException);
161 assertEquals(e.getCause().getMessage(),
162 "Timestamp must not be present");
163 assertEquals(e.getFaultCode(), WSSecurityException.INVALID_SECURITY);
164 }
165 }
166
167 @Test
168 public void testPolicyWrongProtectionOrder() throws Exception {
169 String policyString =
170 "<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" +
171 "<wsp:Policy xmlns:wsp=\"http://schemas.xmlsoap.org/ws/2004/09/policy\">\n" +
172 " <sp:AlgorithmSuite>\n" +
173 " <wsp:Policy>\n" +
174 " <sp:Basic256/>\n" +
175 " </wsp:Policy>\n" +
176 " </sp:AlgorithmSuite>\n" +
177 "<sp:IncludeTimestamp/>\n" +
178 "<sp:EncryptBeforeSigning/>\n" +
179 "<sp:EncryptSignature/>\n" +
180 "<sp:ProtectTokens/>\n" +
181 "<sp:OnlySignEntireHeadersAndBody/>\n" +
182 "</wsp:Policy>\n" +
183 "</sp:SymmetricBinding>";
184 PolicyEnforcer policyEnforcer = buildAndStartPolicyEngine(policyString);
185 SecurityContextTokenSecurityEvent SecurityContextTokenSecurityEvent = new SecurityContextTokenSecurityEvent();
186 SecureConversationSecurityTokenImpl securityToken =
187 new SecureConversationSecurityTokenImpl(
188 null, "1", WSSecurityTokenConstants.KEYIDENTIFIER_SECURITY_TOKEN_DIRECT_REFERENCE);
189 securityToken.addTokenUsage(WSSecurityTokenConstants.TOKENUSAGE_MAIN_ENCRYPTION);
190 SecurityContextTokenSecurityEvent.setSecurityToken(securityToken);
191 policyEnforcer.registerSecurityEvent(SecurityContextTokenSecurityEvent);
192
193 List<XMLSecurityConstants.ContentType> protectionOrder = new LinkedList<>();
194 protectionOrder.add(XMLSecurityConstants.ContentType.SIGNATURE);
195 protectionOrder.add(XMLSecurityConstants.ContentType.ENCRYPTION);
196 SignedPartSecurityEvent signedPartSecurityEvent = new SignedPartSecurityEvent(null, true, protectionOrder);
197 signedPartSecurityEvent.setElementPath(WSSConstants.SOAP_11_BODY_PATH);
198 policyEnforcer.registerSecurityEvent(signedPartSecurityEvent);
199
200 OperationSecurityEvent operationSecurityEvent = new OperationSecurityEvent();
201 operationSecurityEvent.setOperation(new QName("definitions"));
202 try {
203 policyEnforcer.registerSecurityEvent(operationSecurityEvent);
204 fail("Exception expected");
205 } catch (WSSecurityException e) {
206 assertTrue(e.getCause() instanceof PolicyViolationException);
207 assertEquals(e.getCause().getMessage(),
208 "Policy enforces EncryptBeforeSigning but the /{http://schemas.xmlsoap.org/soap/envelope/}Envelope/{http://schemas.xmlsoap.org/soap/envelope/}Body was signed and then encrypted");
209 assertEquals(e.getFaultCode(), WSSecurityException.INVALID_SECURITY);
210 }
211 }
212
213 @Test
214 public void testPolicySignatureNotEncrypted() throws Exception {
215 String policyString =
216 "<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" +
217 "<wsp:Policy xmlns:wsp=\"http://schemas.xmlsoap.org/ws/2004/09/policy\">\n" +
218 " <sp:AlgorithmSuite>\n" +
219 " <wsp:Policy>\n" +
220 " <sp:Basic256/>\n" +
221 " </wsp:Policy>\n" +
222 " </sp:AlgorithmSuite>\n" +
223 "<sp:IncludeTimestamp/>\n" +
224 "<sp:EncryptSignature/>\n" +
225 "<sp:ProtectTokens/>\n" +
226 "<sp:OnlySignEntireHeadersAndBody/>\n" +
227 "</wsp:Policy>\n" +
228 "</sp:SymmetricBinding>";
229 PolicyEnforcer policyEnforcer = buildAndStartPolicyEngine(policyString);
230 TimestampSecurityEvent timestampSecurityEvent = new TimestampSecurityEvent();
231 policyEnforcer.registerSecurityEvent(timestampSecurityEvent);
232
233 SecurityContextTokenSecurityEvent initiatorTokenSecurityEvent = new SecurityContextTokenSecurityEvent();
234 SecureConversationSecurityTokenImpl securityToken =
235 new SecureConversationSecurityTokenImpl(
236 null, "1", WSSecurityTokenConstants.KEYIDENTIFIER_SECURITY_TOKEN_DIRECT_REFERENCE);
237 securityToken.addTokenUsage(WSSecurityTokenConstants.TOKENUSAGE_MAIN_SIGNATURE);
238 initiatorTokenSecurityEvent.setSecurityToken(securityToken);
239 policyEnforcer.registerSecurityEvent(initiatorTokenSecurityEvent);
240
241 SecurityContextTokenSecurityEvent recipientTokenSecurityEvent = new SecurityContextTokenSecurityEvent();
242 securityToken = new SecureConversationSecurityTokenImpl(
243 null, "1", WSSecurityTokenConstants.KEYIDENTIFIER_SECURITY_TOKEN_DIRECT_REFERENCE);
244 securityToken.addTokenUsage(WSSecurityTokenConstants.TOKENUSAGE_MAIN_ENCRYPTION);
245 recipientTokenSecurityEvent.setSecurityToken(securityToken);
246 policyEnforcer.registerSecurityEvent(recipientTokenSecurityEvent);
247
248 List<XMLSecurityConstants.ContentType> protectionOrder = new LinkedList<>();
249 protectionOrder.add(XMLSecurityConstants.ContentType.SIGNATURE);
250 protectionOrder.add(XMLSecurityConstants.ContentType.ENCRYPTION);
251 EncryptedElementSecurityEvent encryptedElementSecurityEvent = new EncryptedElementSecurityEvent(null, false, protectionOrder);
252 List<QName> headerPath = new ArrayList<>();
253 headerPath.addAll(WSSConstants.SOAP_11_WSSE_SECURITY_HEADER_PATH);
254 headerPath.add(WSSConstants.TAG_dsig_Signature);
255 encryptedElementSecurityEvent.setElementPath(headerPath);
256 policyEnforcer.registerSecurityEvent(encryptedElementSecurityEvent);
257
258 OperationSecurityEvent operationSecurityEvent = new OperationSecurityEvent();
259 operationSecurityEvent.setOperation(new QName("definitions"));
260 try {
261 policyEnforcer.registerSecurityEvent(operationSecurityEvent);
262 fail("Exception expected");
263 } catch (WSSecurityException e) {
264 assertEquals(e.getCause().getMessage(),
265 "Element /{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/2000/09/xmldsig#}Signature must be encrypted");
266 assertEquals(e.getFaultCode(), WSSecurityException.INVALID_SECURITY);
267 }
268 }
269
270 @Test
271 public void testPolicyNotWholeBodySigned() throws Exception {
272 String policyString =
273 "<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" +
274 "<wsp:Policy xmlns:wsp=\"http://schemas.xmlsoap.org/ws/2004/09/policy\">\n" +
275 " <sp:AlgorithmSuite>\n" +
276 " <wsp:Policy>\n" +
277 " <sp:Basic256/>\n" +
278 " </wsp:Policy>\n" +
279 " </sp:AlgorithmSuite>\n" +
280 "<sp:IncludeTimestamp/>\n" +
281 "<sp:EncryptSignature/>\n" +
282 "<sp:OnlySignEntireHeadersAndBody/>\n" +
283 "</wsp:Policy>\n" +
284 "</sp:SymmetricBinding>";
285 PolicyEnforcer policyEnforcer = buildAndStartPolicyEngine(policyString);
286 TimestampSecurityEvent timestampSecurityEvent = new TimestampSecurityEvent();
287 policyEnforcer.registerSecurityEvent(timestampSecurityEvent);
288
289 SecurityContextTokenSecurityEvent initiatorTokenSecurityEvent = new SecurityContextTokenSecurityEvent();
290 SecureConversationSecurityTokenImpl securityToken =
291 new SecureConversationSecurityTokenImpl(
292 null, "1", WSSecurityTokenConstants.KEYIDENTIFIER_SECURITY_TOKEN_DIRECT_REFERENCE);
293 securityToken.addTokenUsage(WSSecurityTokenConstants.TOKENUSAGE_MAIN_SIGNATURE);
294 initiatorTokenSecurityEvent.setSecurityToken(securityToken);
295 policyEnforcer.registerSecurityEvent(initiatorTokenSecurityEvent);
296
297 SecurityContextTokenSecurityEvent recipientTokenSecurityEvent = new SecurityContextTokenSecurityEvent();
298 securityToken = new SecureConversationSecurityTokenImpl(
299 null, "1", WSSecurityTokenConstants.KEYIDENTIFIER_SECURITY_TOKEN_DIRECT_REFERENCE);
300 securityToken.addTokenUsage(WSSecurityTokenConstants.TOKENUSAGE_MAIN_ENCRYPTION);
301 recipientTokenSecurityEvent.setSecurityToken(securityToken);
302 policyEnforcer.registerSecurityEvent(recipientTokenSecurityEvent);
303
304 List<XMLSecurityConstants.ContentType> protectionOrder = new LinkedList<>();
305 protectionOrder.add(XMLSecurityConstants.ContentType.SIGNATURE);
306 protectionOrder.add(XMLSecurityConstants.ContentType.ENCRYPTION);
307 EncryptedElementSecurityEvent encryptedElementSecurityEvent = new EncryptedElementSecurityEvent(null, true, protectionOrder);
308 List<QName> headerPath = new ArrayList<>();
309 headerPath.addAll(WSSConstants.SOAP_11_WSSE_SECURITY_HEADER_PATH);
310 headerPath.add(WSSConstants.TAG_dsig_Signature);
311 encryptedElementSecurityEvent.setElementPath(headerPath);
312 policyEnforcer.registerSecurityEvent(encryptedElementSecurityEvent);
313
314 encryptedElementSecurityEvent = new EncryptedElementSecurityEvent(null, true, protectionOrder);
315 headerPath = new ArrayList<>();
316 headerPath.addAll(WSSConstants.SOAP_11_WSSE_SECURITY_HEADER_PATH);
317 headerPath.add(WSSConstants.TAG_WSSE11_SIG_CONF);
318 encryptedElementSecurityEvent.setElementPath(headerPath);
319 policyEnforcer.registerSecurityEvent(encryptedElementSecurityEvent);
320
321 OperationSecurityEvent operationSecurityEvent = new OperationSecurityEvent();
322 operationSecurityEvent.setOperation(new QName("definitions"));
323 policyEnforcer.registerSecurityEvent(operationSecurityEvent);
324
325 SignedPartSecurityEvent signedPartSecurityEvent = new SignedPartSecurityEvent(null, true, protectionOrder);
326 QName elementName = new QName("http://www.example.com", "bodyChildElement");
327 signedPartSecurityEvent.setXmlSecEvent(XMLSecEventFactory.createXmlSecStartElement(elementName, null, null));
328 List<QName> elementPath = new ArrayList<>();
329 elementPath.addAll(WSSConstants.SOAP_11_BODY_PATH);
330 elementPath.add(elementName);
331 signedPartSecurityEvent.setElementPath(elementPath);
332 try {
333 policyEnforcer.registerSecurityEvent(signedPartSecurityEvent);
334 fail("Exception expected");
335 } catch (WSSecurityException e) {
336 assertTrue(e.getCause() instanceof PolicyViolationException);
337 assertEquals(e.getCause().getMessage(),
338 "OnlySignEntireHeadersAndBody not fulfilled, offending element: " +
339 "/{http://schemas.xmlsoap.org/soap/envelope/}Envelope/{http://schemas.xmlsoap.org/soap/envelope/}Body/{http://www.example.com}bodyChildElement");
340 assertEquals(e.getFaultCode(), WSSecurityException.INVALID_SECURITY);
341 }
342 }
343 }