1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.wss4j.stax.test;
20
21 import java.io.ByteArrayInputStream;
22 import java.io.ByteArrayOutputStream;
23 import java.io.InputStream;
24 import java.nio.charset.StandardCharsets;
25 import java.util.ArrayList;
26 import java.util.List;
27 import java.util.Properties;
28
29 import javax.xml.crypto.dsig.SignatureMethod;
30 import javax.xml.stream.XMLStreamReader;
31 import javax.xml.stream.XMLStreamWriter;
32 import javax.xml.transform.dom.DOMSource;
33 import javax.xml.transform.stream.StreamResult;
34
35 import org.apache.wss4j.binding.wssc.AbstractSecurityContextTokenType;
36 import org.apache.wss4j.common.bsp.BSPRule;
37 import org.apache.wss4j.common.crypto.Crypto;
38 import org.apache.wss4j.common.crypto.CryptoFactory;
39 import org.apache.wss4j.common.derivedKey.ConversationConstants;
40 import org.apache.wss4j.common.ext.WSSecurityException;
41 import org.apache.wss4j.common.util.SOAPUtil;
42 import org.apache.wss4j.dom.WSConstants;
43 import org.apache.wss4j.dom.engine.WSSConfig;
44 import org.apache.wss4j.dom.handler.WSHandlerConstants;
45 import org.apache.wss4j.dom.message.WSSecDKEncrypt;
46 import org.apache.wss4j.dom.message.WSSecDKSign;
47 import org.apache.wss4j.dom.message.WSSecHeader;
48 import org.apache.wss4j.dom.message.WSSecSecurityContextToken;
49 import org.apache.wss4j.dom.message.WSSecSignature;
50 import org.apache.wss4j.stax.ext.WSSConstants;
51 import org.apache.wss4j.stax.ext.WSSSecurityProperties;
52 import org.apache.wss4j.stax.securityEvent.EncryptedPartSecurityEvent;
53 import org.apache.wss4j.stax.securityEvent.OperationSecurityEvent;
54 import org.apache.wss4j.stax.securityEvent.SignedPartSecurityEvent;
55 import org.apache.wss4j.stax.securityEvent.WSSecurityEventConstants;
56 import org.apache.wss4j.stax.setup.InboundWSSec;
57 import org.apache.wss4j.stax.setup.OutboundWSSec;
58 import org.apache.wss4j.stax.setup.WSSec;
59 import org.apache.wss4j.stax.test.utils.SecretKeyCallbackHandler;
60 import org.apache.wss4j.stax.test.utils.StAX2DOM;
61 import org.apache.wss4j.stax.test.utils.XmlReaderToWriter;
62 import org.apache.wss4j.stax.validate.SecurityContextTokenValidator;
63 import org.apache.wss4j.stax.validate.SecurityContextTokenValidatorImpl;
64 import org.apache.wss4j.stax.validate.TokenContext;
65 import org.apache.xml.security.stax.ext.XMLSecurityConstants;
66 import org.apache.xml.security.stax.securityEvent.SecurityEvent;
67 import org.apache.xml.security.stax.securityEvent.SignatureValueSecurityEvent;
68 import org.apache.xml.security.stax.securityToken.InboundSecurityToken;
69 import org.junit.jupiter.api.BeforeAll;
70 import org.junit.jupiter.params.ParameterizedTest;
71 import org.junit.jupiter.params.provider.ValueSource;
72 import org.w3c.dom.Document;
73 import org.w3c.dom.NodeList;
74
75 import static org.junit.jupiter.api.Assertions.assertEquals;
76 import static org.junit.jupiter.api.Assertions.assertTrue;
77
78 public class SecurityContextTokenTest extends AbstractTestBase {
79
80 @BeforeAll
81 public static void setUp() throws Exception {
82 WSSConfig.init();
83 }
84
85 @ParameterizedTest
86 @ValueSource(ints = {ConversationConstants.VERSION_05_02, ConversationConstants.VERSION_05_12})
87 public void testSCTDKTEncryptOutbound(int version) throws Exception {
88 byte[] secret = WSSConstants.generateBytes(128 / 8);
89
90 ByteArrayOutputStream baos = new ByteArrayOutputStream();
91 {
92 WSSSecurityProperties securityProperties = new WSSSecurityProperties();
93 List<WSSConstants.Action> actions = new ArrayList<>();
94 actions.add(WSSConstants.ENCRYPTION_WITH_DERIVED_KEY);
95 securityProperties.setActions(actions);
96 CallbackHandlerImpl callbackHandler = new CallbackHandlerImpl(secret);
97 securityProperties.setCallbackHandler(callbackHandler);
98 securityProperties.loadEncryptionKeystore(this.getClass().getClassLoader().getResource("transmitter.jks"), "default".toCharArray());
99 securityProperties.setEncryptionUser("receiver");
100 securityProperties.setEncryptionSymAlgorithm("http://www.w3.org/2001/04/xmlenc#aes128-cbc");
101 securityProperties.setDerivedKeyTokenReference(WSSConstants.DerivedKeyTokenReference.SecurityContextToken);
102
103 OutboundWSSec wsSecOut = WSSec.getOutboundWSSec(securityProperties);
104 XMLStreamWriter xmlStreamWriter = wsSecOut.processOutMessage(baos, StandardCharsets.UTF_8.name(), new ArrayList<SecurityEvent>());
105 XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml"));
106 XmlReaderToWriter.writeAll(xmlStreamReader, xmlStreamWriter);
107 xmlStreamWriter.close();
108
109 Document document = documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray()));
110 NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedData.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedData.getLocalPart());
111 assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_SOAP11_BODY.getLocalPart());
112 nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_WSC0512_SCT.getNamespaceURI(), WSSConstants.TAG_WSC0512_SCT.getLocalPart());
113 assertEquals(nodeList.getLength(), 1);
114 nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_WSC0512_DKT.getNamespaceURI(), WSSConstants.TAG_WSC0512_DKT.getLocalPart());
115 assertEquals(nodeList.getLength(), 1);
116 nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_ReferenceList.getNamespaceURI(), WSSConstants.TAG_xenc_ReferenceList.getLocalPart());
117 assertEquals(nodeList.getLength(), 1);
118 nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedKey.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedKey.getLocalPart());
119 assertEquals(nodeList.getLength(), 0);
120 }
121 {
122 String action = WSHandlerConstants.ENCRYPTION;
123 Properties properties = new Properties();
124 WSS4JCallbackHandlerImpl callbackHandler = new WSS4JCallbackHandlerImpl(secret);
125 properties.put(WSHandlerConstants.PW_CALLBACK_REF, callbackHandler);
126 doInboundSecurityWithWSS4J_1(documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray())), action, properties, false);
127 }
128 }
129
130 @ParameterizedTest
131 @ValueSource(ints = {ConversationConstants.VERSION_05_02, ConversationConstants.VERSION_05_12})
132 public void testSCTDKTEncryptInbound(int version) throws Exception {
133
134 byte[] tempSecret = XMLSecurityConstants.generateBytes(16);
135 ByteArrayOutputStream baos = new ByteArrayOutputStream();
136 {
137 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
138 WSSecHeader secHeader = new WSSecHeader(doc);
139 secHeader.insertSecurityHeader();
140
141 WSSecSecurityContextToken sctBuilder = new WSSecSecurityContextToken(secHeader, null);
142 sctBuilder.setWscVersion(version);
143 Crypto crypto = CryptoFactory.getInstance("transmitter-crypto.properties");
144 sctBuilder.prepare(crypto);
145
146
147 SecretKeyCallbackHandler callbackHandler = new SecretKeyCallbackHandler();
148 callbackHandler.addSecretKey(sctBuilder.getIdentifier(), tempSecret);
149
150 String tokenId = sctBuilder.getSctId();
151
152
153 WSSecDKEncrypt encrBuilder = new WSSecDKEncrypt(secHeader);
154 encrBuilder.setWscVersion(version);
155 encrBuilder.setSymmetricEncAlgorithm(WSConstants.AES_128);
156 encrBuilder.setTokenIdentifier(tokenId);
157 encrBuilder.build(tempSecret);
158
159 sctBuilder.prependSCTElementToHeader();
160
161 javax.xml.transform.Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
162 transformer.transform(new DOMSource(doc), new StreamResult(baos));
163 }
164
165 {
166 WSSSecurityProperties securityProperties = new WSSSecurityProperties();
167 securityProperties.loadDecryptionKeystore(this.getClass().getClassLoader().getResource("receiver.jks"), "default".toCharArray());
168 CallbackHandlerImpl callbackHandler = new CallbackHandlerImpl(tempSecret);
169 securityProperties.setCallbackHandler(callbackHandler);
170 InboundWSSec wsSecIn = WSSec.getInboundWSSec(securityProperties);
171
172 WSSecurityEventConstants.Event[] expectedSecurityEvents = new WSSecurityEventConstants.Event[]{
173 WSSecurityEventConstants.AlgorithmSuite,
174 WSSecurityEventConstants.AlgorithmSuite,
175 WSSecurityEventConstants.AlgorithmSuite,
176 WSSecurityEventConstants.SECURITY_CONTEXT_TOKEN,
177 WSSecurityEventConstants.ENCRYPTED_PART,
178 WSSecurityEventConstants.OPERATION,
179 };
180 final TestSecurityEventListener securityEventListener = new TestSecurityEventListener(expectedSecurityEvents);
181
182 XMLStreamReader xmlStreamReader = wsSecIn.processInMessage(xmlInputFactory.createXMLStreamReader(new ByteArrayInputStream(baos.toByteArray())), null, securityEventListener);
183
184 Document document = StAX2DOM.readDoc(documentBuilderFactory.newDocumentBuilder(), xmlStreamReader);
185
186 NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedData.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedData.getLocalPart());
187 assertEquals(nodeList.getLength(), 0);
188
189 securityEventListener.compare();
190
191 EncryptedPartSecurityEvent encryptedPartSecurityEvent = securityEventListener.getSecurityEvent(WSSecurityEventConstants.ENCRYPTED_PART);
192 OperationSecurityEvent operationSecurityEvent = securityEventListener.getSecurityEvent(WSSecurityEventConstants.OPERATION);
193 String encryptedPartCorrelationID = encryptedPartSecurityEvent.getCorrelationID();
194 String operationCorrelationID = operationSecurityEvent.getCorrelationID();
195
196 List<SecurityEvent> operationSecurityEvents = new ArrayList<>();
197 List<SecurityEvent> encryptedPartSecurityEvents = new ArrayList<>();
198
199 List<SecurityEvent> securityEvents = securityEventListener.getReceivedSecurityEvents();
200 for (SecurityEvent securityEvent : securityEvents) {
201 if (securityEvent.getCorrelationID().equals(encryptedPartCorrelationID)) {
202 encryptedPartSecurityEvents.add(securityEvent);
203 } else if (securityEvent.getCorrelationID().equals(operationCorrelationID)) {
204 operationSecurityEvents.add(securityEvent);
205 }
206 }
207
208 assertEquals(5, encryptedPartSecurityEvents.size());
209 assertEquals(securityEventListener.getReceivedSecurityEvents().size(),
210 operationSecurityEvents.size() +
211 encryptedPartSecurityEvents.size()
212 );
213 }
214 }
215
216 @ParameterizedTest
217 @ValueSource(ints = {ConversationConstants.VERSION_05_02, ConversationConstants.VERSION_05_12})
218 public void testSCTDKTEncryptInboundAction(int version) throws Exception {
219
220 byte[] tempSecret = XMLSecurityConstants.generateBytes(16);
221 ByteArrayOutputStream baos = new ByteArrayOutputStream();
222 {
223 InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
224 String action = WSHandlerConstants.ENCRYPTION_DERIVED;
225
226 Properties properties = new Properties();
227 CallbackHandlerImpl callbackHandler = new CallbackHandlerImpl(tempSecret);
228 properties.put(WSHandlerConstants.PW_CALLBACK_REF, callbackHandler);
229 properties.put(WSHandlerConstants.DERIVED_TOKEN_REFERENCE, "SecurityContextToken");
230 if (version == ConversationConstants.VERSION_05_02) {
231 properties.put(WSHandlerConstants.USE_2005_12_NAMESPACE, "false");
232 }
233 properties.put(WSHandlerConstants.USER, "receiver");
234 properties.put(WSHandlerConstants.ENC_SYM_ALGO,
235 "http://www.w3.org/2001/04/xmlenc#aes128-cbc");
236 Document securedDocument = doOutboundSecurityWithWSS4J(sourceDocument, action, properties);
237
238
239 NodeList nodeList = securedDocument.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedData.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedData.getLocalPart());
240 assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_SOAP11_BODY.getLocalPart());
241
242 javax.xml.transform.Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
243 transformer.transform(new DOMSource(securedDocument), new StreamResult(baos));
244 }
245
246 {
247 WSSSecurityProperties securityProperties = new WSSSecurityProperties();
248 securityProperties.loadDecryptionKeystore(this.getClass().getClassLoader().getResource("receiver.jks"), "default".toCharArray());
249 CallbackHandlerImpl callbackHandler = new CallbackHandlerImpl(tempSecret);
250 securityProperties.setCallbackHandler(callbackHandler);
251 InboundWSSec wsSecIn = WSSec.getInboundWSSec(securityProperties);
252
253 WSSecurityEventConstants.Event[] expectedSecurityEvents = new WSSecurityEventConstants.Event[]{
254 WSSecurityEventConstants.AlgorithmSuite,
255 WSSecurityEventConstants.AlgorithmSuite,
256 WSSecurityEventConstants.AlgorithmSuite,
257 WSSecurityEventConstants.SECURITY_CONTEXT_TOKEN,
258 WSSecurityEventConstants.ENCRYPTED_PART,
259 WSSecurityEventConstants.OPERATION,
260 };
261 final TestSecurityEventListener securityEventListener = new TestSecurityEventListener(expectedSecurityEvents);
262
263 XMLStreamReader xmlStreamReader = wsSecIn.processInMessage(xmlInputFactory.createXMLStreamReader(new ByteArrayInputStream(baos.toByteArray())), null, securityEventListener);
264
265 Document document = StAX2DOM.readDoc(documentBuilderFactory.newDocumentBuilder(), xmlStreamReader);
266
267 NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedData.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedData.getLocalPart());
268 assertEquals(nodeList.getLength(), 0);
269
270 securityEventListener.compare();
271
272 EncryptedPartSecurityEvent encryptedPartSecurityEvent = securityEventListener.getSecurityEvent(WSSecurityEventConstants.ENCRYPTED_PART);
273 OperationSecurityEvent operationSecurityEvent = securityEventListener.getSecurityEvent(WSSecurityEventConstants.OPERATION);
274 String encryptedPartCorrelationID = encryptedPartSecurityEvent.getCorrelationID();
275 String operationCorrelationID = operationSecurityEvent.getCorrelationID();
276
277 List<SecurityEvent> operationSecurityEvents = new ArrayList<>();
278 List<SecurityEvent> encryptedPartSecurityEvents = new ArrayList<>();
279
280 List<SecurityEvent> securityEvents = securityEventListener.getReceivedSecurityEvents();
281 for (SecurityEvent securityEvent : securityEvents) {
282 if (securityEvent.getCorrelationID().equals(encryptedPartCorrelationID)) {
283 encryptedPartSecurityEvents.add(securityEvent);
284 } else if (securityEvent.getCorrelationID().equals(operationCorrelationID)) {
285 operationSecurityEvents.add(securityEvent);
286 }
287 }
288
289 assertEquals(5, encryptedPartSecurityEvents.size());
290 assertEquals(securityEventListener.getReceivedSecurityEvents().size(),
291 operationSecurityEvents.size() +
292 encryptedPartSecurityEvents.size()
293 );
294 }
295 }
296
297 @ParameterizedTest
298 @ValueSource(ints = {ConversationConstants.VERSION_05_02, ConversationConstants.VERSION_05_12})
299 public void testSCTKDKTSignOutbound(int version) throws Exception {
300 byte[] secret = WSSConstants.generateBytes(128 / 8);
301
302 ByteArrayOutputStream baos = new ByteArrayOutputStream();
303 {
304 WSSSecurityProperties securityProperties = new WSSSecurityProperties();
305 List<WSSConstants.Action> actions = new ArrayList<>();
306 actions.add(WSSConstants.SIGNATURE_WITH_DERIVED_KEY);
307 securityProperties.setActions(actions);
308 CallbackHandlerImpl callbackHandler = new CallbackHandlerImpl(secret);
309 securityProperties.setCallbackHandler(callbackHandler);
310 securityProperties.loadSignatureKeyStore(this.getClass().getClassLoader().getResource("transmitter.jks"), "default".toCharArray());
311 securityProperties.setSignatureUser("transmitter");
312 securityProperties.setDerivedKeyTokenReference(WSSConstants.DerivedKeyTokenReference.SecurityContextToken);
313
314 OutboundWSSec wsSecOut = WSSec.getOutboundWSSec(securityProperties);
315 XMLStreamWriter xmlStreamWriter = wsSecOut.processOutMessage(baos, StandardCharsets.UTF_8.name(), new ArrayList<SecurityEvent>());
316 XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml"));
317 XmlReaderToWriter.writeAll(xmlStreamReader, xmlStreamWriter);
318 xmlStreamWriter.close();
319
320 Document document = documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray()));
321 NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
322 assertEquals(nodeList.getLength(), 1);
323 nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_WSC0512_SCT.getNamespaceURI(), WSSConstants.TAG_WSC0512_SCT.getLocalPart());
324 assertEquals(nodeList.getLength(), 1);
325 nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_WSC0512_DKT.getNamespaceURI(), WSSConstants.TAG_WSC0512_DKT.getLocalPart());
326 assertEquals(nodeList.getLength(), 1);
327 nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_ReferenceList.getNamespaceURI(), WSSConstants.TAG_xenc_ReferenceList.getLocalPart());
328 assertEquals(nodeList.getLength(), 0);
329 nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedKey.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedKey.getLocalPart());
330 assertEquals(nodeList.getLength(), 0);
331 }
332 {
333 String action = WSHandlerConstants.SIGNATURE;
334 Properties properties = new Properties();
335 WSS4JCallbackHandlerImpl callbackHandler = new WSS4JCallbackHandlerImpl(secret);
336 properties.put(WSHandlerConstants.PW_CALLBACK_REF, callbackHandler);
337 doInboundSecurityWithWSS4J_1(documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray())), action, properties, false);
338 }
339 }
340
341 @ParameterizedTest
342 @ValueSource(ints = {ConversationConstants.VERSION_05_02, ConversationConstants.VERSION_05_12})
343 public void testSCTKDKTSignInbound(int version) throws Exception {
344
345 byte[] tempSecret = XMLSecurityConstants.generateBytes(16);
346 ByteArrayOutputStream baos = new ByteArrayOutputStream();
347 {
348 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
349 WSSecHeader secHeader = new WSSecHeader(doc);
350 secHeader.insertSecurityHeader();
351
352 WSSecSecurityContextToken sctBuilder = new WSSecSecurityContextToken(secHeader, null);
353 sctBuilder.setWscVersion(version);
354 Crypto crypto = CryptoFactory.getInstance("transmitter-crypto.properties");
355 sctBuilder.prepare(crypto);
356
357
358 SecretKeyCallbackHandler callbackHandler = new SecretKeyCallbackHandler();
359 callbackHandler.addSecretKey(sctBuilder.getIdentifier(), tempSecret);
360
361 String tokenId = sctBuilder.getSctId();
362
363
364 WSSecDKSign sigBuilder = new WSSecDKSign(secHeader);
365 sigBuilder.setWscVersion(version);
366 sigBuilder.setTokenIdentifier(tokenId);
367 sigBuilder.setSignatureAlgorithm(WSConstants.HMAC_SHA1);
368 sigBuilder.build(tempSecret);
369
370 sctBuilder.prependSCTElementToHeader();
371
372 javax.xml.transform.Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
373 transformer.transform(new DOMSource(doc), new StreamResult(baos));
374 }
375
376 {
377 WSSSecurityProperties securityProperties = new WSSSecurityProperties();
378 securityProperties.loadSignatureVerificationKeystore(this.getClass().getClassLoader().getResource("receiver.jks"), "default".toCharArray());
379 securityProperties.loadDecryptionKeystore(this.getClass().getClassLoader().getResource("receiver.jks"), "default".toCharArray());
380 CallbackHandlerImpl callbackHandler = new CallbackHandlerImpl(tempSecret);
381 securityProperties.setCallbackHandler(callbackHandler);
382 InboundWSSec wsSecIn = WSSec.getInboundWSSec(securityProperties);
383
384 WSSecurityEventConstants.Event[] expectedSecurityEvents = new WSSecurityEventConstants.Event[]{
385 WSSecurityEventConstants.AlgorithmSuite,
386 WSSecurityEventConstants.AlgorithmSuite,
387 WSSecurityEventConstants.AlgorithmSuite,
388 WSSecurityEventConstants.AlgorithmSuite,
389 WSSecurityEventConstants.AlgorithmSuite,
390 WSSecurityEventConstants.AlgorithmSuite,
391 WSSecurityEventConstants.SECURITY_CONTEXT_TOKEN,
392 WSSecurityEventConstants.SignatureValue,
393 WSSecurityEventConstants.SIGNED_PART,
394 WSSecurityEventConstants.OPERATION,
395 };
396 final TestSecurityEventListener securityEventListener = new TestSecurityEventListener(expectedSecurityEvents);
397
398 XMLStreamReader xmlStreamReader = wsSecIn.processInMessage(xmlInputFactory.createXMLStreamReader(new ByteArrayInputStream(baos.toByteArray())), null, securityEventListener);
399
400 StAX2DOM.readDoc(documentBuilderFactory.newDocumentBuilder(), xmlStreamReader);
401
402 securityEventListener.compare();
403
404 SignedPartSecurityEvent signedPartSecurityEvent = securityEventListener.getSecurityEvent(WSSecurityEventConstants.SIGNED_PART);
405 SignatureValueSecurityEvent signatureValueSecurityEvent = securityEventListener.getSecurityEvent(WSSecurityEventConstants.SignatureValue);
406 OperationSecurityEvent operationSecurityEvent = securityEventListener.getSecurityEvent(WSSecurityEventConstants.OPERATION);
407 String signedElementCorrelationID = signedPartSecurityEvent.getCorrelationID();
408 String signatureValueCorrelationID = signatureValueSecurityEvent.getCorrelationID();
409 String operationCorrelationID = operationSecurityEvent.getCorrelationID();
410
411 List<SecurityEvent> operationSecurityEvents = new ArrayList<>();
412 List<SecurityEvent> signedElementSecurityEvents = new ArrayList<>();
413 List<SecurityEvent> signatureValueSecurityEvents = new ArrayList<>();
414
415 List<SecurityEvent> securityEvents = securityEventListener.getReceivedSecurityEvents();
416 for (SecurityEvent securityEvent : securityEvents) {
417 if (securityEvent.getCorrelationID().equals(signedElementCorrelationID)) {
418 signedElementSecurityEvents.add(securityEvent);
419 } else if (securityEvent.getCorrelationID().equals(signatureValueCorrelationID)) {
420 signatureValueSecurityEvents.add(securityEvent);
421 } else if (securityEvent.getCorrelationID().equals(operationCorrelationID)) {
422 operationSecurityEvents.add(securityEvent);
423 }
424 }
425
426 assertEquals(3, signedElementSecurityEvents.size());
427 assertEquals(6, signatureValueSecurityEvents.size());
428 assertEquals(securityEventListener.getReceivedSecurityEvents().size(),
429 operationSecurityEvents.size() +
430 signedElementSecurityEvents.size() + signatureValueSecurityEvents.size()
431 );
432 }
433 }
434
435 @ParameterizedTest
436 @ValueSource(ints = {ConversationConstants.VERSION_05_02, ConversationConstants.VERSION_05_12})
437 public void testSCTKDKTSignInboundAction(int version) throws Exception {
438
439 byte[] tempSecret = XMLSecurityConstants.generateBytes(16);
440 ByteArrayOutputStream baos = new ByteArrayOutputStream();
441 {
442 InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
443 String action = WSHandlerConstants.SIGNATURE_DERIVED;
444
445 Properties properties = new Properties();
446 CallbackHandlerImpl callbackHandler = new CallbackHandlerImpl(tempSecret);
447 properties.put(WSHandlerConstants.PW_CALLBACK_REF, callbackHandler);
448 properties.put(WSHandlerConstants.DERIVED_TOKEN_REFERENCE, "SecurityContextToken");
449 if (version == ConversationConstants.VERSION_05_02) {
450 properties.put(WSHandlerConstants.USE_2005_12_NAMESPACE, "false");
451 }
452 properties.put(WSHandlerConstants.USER, "transmitter");
453 properties.put(WSHandlerConstants.ENC_SYM_ALGO,
454 "http://www.w3.org/2001/04/xmlenc#aes128-cbc");
455 Document securedDocument = doOutboundSecurityWithWSS4J(sourceDocument, action, properties);
456
457
458 NodeList nodeList = securedDocument.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
459 assertEquals(nodeList.getLength(), 1);
460
461 javax.xml.transform.Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
462 transformer.transform(new DOMSource(securedDocument), new StreamResult(baos));
463 }
464
465 {
466 WSSSecurityProperties securityProperties = new WSSSecurityProperties();
467 securityProperties.loadSignatureVerificationKeystore(this.getClass().getClassLoader().getResource("receiver.jks"), "default".toCharArray());
468 securityProperties.loadDecryptionKeystore(this.getClass().getClassLoader().getResource("receiver.jks"), "default".toCharArray());
469 CallbackHandlerImpl callbackHandler = new CallbackHandlerImpl(tempSecret);
470 securityProperties.setCallbackHandler(callbackHandler);
471 InboundWSSec wsSecIn = WSSec.getInboundWSSec(securityProperties);
472
473 WSSecurityEventConstants.Event[] expectedSecurityEvents = new WSSecurityEventConstants.Event[]{
474 WSSecurityEventConstants.AlgorithmSuite,
475 WSSecurityEventConstants.AlgorithmSuite,
476 WSSecurityEventConstants.AlgorithmSuite,
477 WSSecurityEventConstants.AlgorithmSuite,
478 WSSecurityEventConstants.AlgorithmSuite,
479 WSSecurityEventConstants.AlgorithmSuite,
480 WSSecurityEventConstants.SECURITY_CONTEXT_TOKEN,
481 WSSecurityEventConstants.SignatureValue,
482 WSSecurityEventConstants.SIGNED_PART,
483 WSSecurityEventConstants.OPERATION,
484 };
485 final TestSecurityEventListener securityEventListener = new TestSecurityEventListener(expectedSecurityEvents);
486
487 XMLStreamReader xmlStreamReader = wsSecIn.processInMessage(xmlInputFactory.createXMLStreamReader(new ByteArrayInputStream(baos.toByteArray())), null, securityEventListener);
488
489 StAX2DOM.readDoc(documentBuilderFactory.newDocumentBuilder(), xmlStreamReader);
490
491 securityEventListener.compare();
492
493 SignedPartSecurityEvent signedPartSecurityEvent = securityEventListener.getSecurityEvent(WSSecurityEventConstants.SIGNED_PART);
494 SignatureValueSecurityEvent signatureValueSecurityEvent = securityEventListener.getSecurityEvent(WSSecurityEventConstants.SignatureValue);
495 OperationSecurityEvent operationSecurityEvent = securityEventListener.getSecurityEvent(WSSecurityEventConstants.OPERATION);
496 String signedElementCorrelationID = signedPartSecurityEvent.getCorrelationID();
497 String signatureValueCorrelationID = signatureValueSecurityEvent.getCorrelationID();
498 String operationCorrelationID = operationSecurityEvent.getCorrelationID();
499
500 List<SecurityEvent> operationSecurityEvents = new ArrayList<>();
501 List<SecurityEvent> signedElementSecurityEvents = new ArrayList<>();
502 List<SecurityEvent> signatureValueSecurityEvents = new ArrayList<>();
503
504 List<SecurityEvent> securityEvents = securityEventListener.getReceivedSecurityEvents();
505 for (SecurityEvent securityEvent : securityEvents) {
506 if (securityEvent.getCorrelationID().equals(signedElementCorrelationID)) {
507 signedElementSecurityEvents.add(securityEvent);
508 } else if (securityEvent.getCorrelationID().equals(signatureValueCorrelationID)) {
509 signatureValueSecurityEvents.add(securityEvent);
510 } else if (securityEvent.getCorrelationID().equals(operationCorrelationID)) {
511 operationSecurityEvents.add(securityEvent);
512 }
513 }
514
515 assertEquals(3, signedElementSecurityEvents.size());
516 assertEquals(6, signatureValueSecurityEvents.size());
517 assertEquals(securityEventListener.getReceivedSecurityEvents().size(),
518 operationSecurityEvents.size() +
519 signedElementSecurityEvents.size() + signatureValueSecurityEvents.size()
520 );
521 }
522 }
523
524 @ParameterizedTest
525 @ValueSource(ints = {ConversationConstants.VERSION_05_02, ConversationConstants.VERSION_05_12})
526 public void testSCTKDKTSignAbsoluteInbound(int version) throws Exception {
527
528 byte[] tempSecret = XMLSecurityConstants.generateBytes(16);
529 ByteArrayOutputStream baos = new ByteArrayOutputStream();
530 {
531 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
532 WSSecHeader secHeader = new WSSecHeader(doc);
533 secHeader.insertSecurityHeader();
534
535 WSSecSecurityContextToken sctBuilder = new WSSecSecurityContextToken(secHeader, null);
536 sctBuilder.setWscVersion(version);
537 Crypto crypto = CryptoFactory.getInstance("transmitter-crypto.properties");
538 sctBuilder.prepare(crypto);
539
540
541 SecretKeyCallbackHandler callbackHandler = new SecretKeyCallbackHandler();
542 callbackHandler.addSecretKey(sctBuilder.getIdentifier(), tempSecret);
543
544
545 WSSecDKSign sigBuilder = new WSSecDKSign(secHeader);
546 sigBuilder.setWscVersion(version);
547 sigBuilder.setTokenIdDirectId(true);
548 sigBuilder.setTokenIdentifier(sctBuilder.getIdentifier());
549 sigBuilder.setSignatureAlgorithm(WSConstants.HMAC_SHA1);
550 sigBuilder.build(tempSecret);
551
552 sctBuilder.prependSCTElementToHeader();
553
554 javax.xml.transform.Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
555 transformer.transform(new DOMSource(doc), new StreamResult(baos));
556 }
557
558 {
559 WSSSecurityProperties securityProperties = new WSSSecurityProperties();
560 securityProperties.loadSignatureVerificationKeystore(this.getClass().getClassLoader().getResource("receiver.jks"), "default".toCharArray());
561 securityProperties.loadDecryptionKeystore(this.getClass().getClassLoader().getResource("receiver.jks"), "default".toCharArray());
562 CallbackHandlerImpl callbackHandler = new CallbackHandlerImpl(tempSecret);
563 securityProperties.setCallbackHandler(callbackHandler);
564 securityProperties.addIgnoreBSPRule(BSPRule.R5204);
565 InboundWSSec wsSecIn = WSSec.getInboundWSSec(securityProperties);
566 XMLStreamReader xmlStreamReader = wsSecIn.processInMessage(xmlInputFactory.createXMLStreamReader(new ByteArrayInputStream(baos.toByteArray())));
567
568 StAX2DOM.readDoc(documentBuilderFactory.newDocumentBuilder(), xmlStreamReader);
569 }
570 }
571
572 @ParameterizedTest
573 @ValueSource(ints = {ConversationConstants.VERSION_05_02, ConversationConstants.VERSION_05_12})
574 public void testSCTKDKTSignEncrypt(int version) throws Exception {
575
576 byte[] tempSecret = XMLSecurityConstants.generateBytes(16);
577 ByteArrayOutputStream baos = new ByteArrayOutputStream();
578 {
579 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
580 WSSecHeader secHeader = new WSSecHeader(doc);
581 secHeader.insertSecurityHeader();
582
583 WSSecSecurityContextToken sctBuilder = new WSSecSecurityContextToken(secHeader, null);
584 sctBuilder.setWscVersion(version);
585 Crypto crypto = CryptoFactory.getInstance("transmitter-crypto.properties");
586 sctBuilder.prepare(crypto);
587
588
589 SecretKeyCallbackHandler callbackHandler = new SecretKeyCallbackHandler();
590 callbackHandler.addSecretKey(sctBuilder.getIdentifier(), tempSecret);
591
592 String tokenId = sctBuilder.getSctId();
593
594
595 WSSecDKSign sigBuilder = new WSSecDKSign(secHeader);
596 sigBuilder.setWscVersion(version);
597 if (version == ConversationConstants.VERSION_05_12) {
598 sigBuilder.setCustomValueType(WSConstants.WSC_SCT_05_12);
599 } else {
600 sigBuilder.setCustomValueType(WSConstants.WSC_SCT);
601 }
602 sigBuilder.setTokenIdentifier(tokenId);
603 sigBuilder.setSignatureAlgorithm(WSConstants.HMAC_SHA1);
604 sigBuilder.build(tempSecret);
605
606
607 WSSecDKEncrypt encrBuilder = new WSSecDKEncrypt(secHeader);
608 encrBuilder.setWscVersion(version);
609 if (version == ConversationConstants.VERSION_05_12) {
610 encrBuilder.setCustomValueType(WSConstants.WSC_SCT_05_12);
611 } else {
612 encrBuilder.setCustomValueType(WSConstants.WSC_SCT);
613 }
614 encrBuilder.setSymmetricEncAlgorithm(WSConstants.AES_128);
615 encrBuilder.setTokenIdentifier(tokenId);
616 encrBuilder.build(tempSecret);
617
618 sctBuilder.prependSCTElementToHeader();
619
620 javax.xml.transform.Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
621 transformer.transform(new DOMSource(doc), new StreamResult(baos));
622 }
623
624 {
625 WSSSecurityProperties securityProperties = new WSSSecurityProperties();
626 securityProperties.loadDecryptionKeystore(this.getClass().getClassLoader().getResource("receiver.jks"), "default".toCharArray());
627 securityProperties.loadSignatureVerificationKeystore(this.getClass().getClassLoader().getResource("receiver.jks"), "default".toCharArray());
628 CallbackHandlerImpl callbackHandler = new CallbackHandlerImpl(tempSecret);
629 securityProperties.setCallbackHandler(callbackHandler);
630 InboundWSSec wsSecIn = WSSec.getInboundWSSec(securityProperties);
631
632 WSSecurityEventConstants.Event[] expectedSecurityEvents = new WSSecurityEventConstants.Event[]{
633 WSSecurityEventConstants.AlgorithmSuite,
634 WSSecurityEventConstants.AlgorithmSuite,
635 WSSecurityEventConstants.AlgorithmSuite,
636 WSSecurityEventConstants.AlgorithmSuite,
637 WSSecurityEventConstants.AlgorithmSuite,
638 WSSecurityEventConstants.AlgorithmSuite,
639 WSSecurityEventConstants.AlgorithmSuite,
640 WSSecurityEventConstants.AlgorithmSuite,
641 WSSecurityEventConstants.AlgorithmSuite,
642 WSSecurityEventConstants.SECURITY_CONTEXT_TOKEN,
643 WSSecurityEventConstants.SignatureValue,
644 WSSecurityEventConstants.SIGNED_PART,
645 WSSecurityEventConstants.ENCRYPTED_PART,
646 WSSecurityEventConstants.OPERATION,
647 };
648 final TestSecurityEventListener securityEventListener = new TestSecurityEventListener(expectedSecurityEvents);
649
650 XMLStreamReader xmlStreamReader = wsSecIn.processInMessage(xmlInputFactory.createXMLStreamReader(new ByteArrayInputStream(baos.toByteArray())), null, securityEventListener);
651
652 Document document = StAX2DOM.readDoc(documentBuilderFactory.newDocumentBuilder(), xmlStreamReader);
653
654 NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedData.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedData.getLocalPart());
655 assertEquals(nodeList.getLength(), 0);
656
657 securityEventListener.compare();
658
659 SignedPartSecurityEvent signedPartSecurityEvent = securityEventListener.getSecurityEvent(WSSecurityEventConstants.SIGNED_PART);
660 SignatureValueSecurityEvent signatureValueSecurityEvent = securityEventListener.getSecurityEvent(WSSecurityEventConstants.SignatureValue);
661 EncryptedPartSecurityEvent encryptedPartSecurityEvent = securityEventListener.getSecurityEvent(WSSecurityEventConstants.ENCRYPTED_PART);
662 OperationSecurityEvent operationSecurityEvent = securityEventListener.getSecurityEvent(WSSecurityEventConstants.OPERATION);
663 String signedElementCorrelationID = signedPartSecurityEvent.getCorrelationID();
664 String signatureValueCorrelationID = signatureValueSecurityEvent.getCorrelationID();
665 String encryptedPartCorrelationID = encryptedPartSecurityEvent.getCorrelationID();
666 String operationCorrelationID = operationSecurityEvent.getCorrelationID();
667
668 List<SecurityEvent> operationSecurityEvents = new ArrayList<>();
669 List<SecurityEvent> signedElementSecurityEvents = new ArrayList<>();
670 List<SecurityEvent> signatureValueSecurityEvents = new ArrayList<>();
671 List<SecurityEvent> encryptedPartSecurityEvents = new ArrayList<>();
672
673 List<SecurityEvent> securityEvents = securityEventListener.getReceivedSecurityEvents();
674 for (SecurityEvent securityEvent : securityEvents) {
675 if (securityEvent.getCorrelationID().equals(signedElementCorrelationID)) {
676 signedElementSecurityEvents.add(securityEvent);
677 } else if (securityEvent.getCorrelationID().equals(signatureValueCorrelationID)) {
678 signatureValueSecurityEvents.add(securityEvent);
679 } else if (securityEvent.getCorrelationID().equals(encryptedPartCorrelationID)) {
680 encryptedPartSecurityEvents.add(securityEvent);
681 } else if (securityEvent.getCorrelationID().equals(operationCorrelationID)) {
682 operationSecurityEvents.add(securityEvent);
683 }
684 }
685
686 assertEquals(3, signedElementSecurityEvents.size());
687 assertEquals(5, signatureValueSecurityEvents.size());
688 assertEquals(5, encryptedPartSecurityEvents.size());
689 assertEquals(securityEventListener.getReceivedSecurityEvents().size(),
690 operationSecurityEvents.size() +
691 signedElementSecurityEvents.size() + signatureValueSecurityEvents.size() + encryptedPartSecurityEvents.size()
692 );
693 }
694 }
695
696 @ParameterizedTest
697 @ValueSource(ints = {ConversationConstants.VERSION_05_02, ConversationConstants.VERSION_05_12})
698 public void testSCTKDKTSignEncryptAction(int version) throws Exception {
699
700 byte[] tempSecret = XMLSecurityConstants.generateBytes(16);
701 ByteArrayOutputStream baos = new ByteArrayOutputStream();
702 {
703 InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
704 String action =
705 WSHandlerConstants.SIGNATURE_DERIVED + " " + WSHandlerConstants.ENCRYPTION_DERIVED;
706
707 Properties properties = new Properties();
708 CallbackHandlerImpl callbackHandler = new CallbackHandlerImpl(tempSecret);
709 properties.put(WSHandlerConstants.PW_CALLBACK_REF, callbackHandler);
710 properties.put(WSHandlerConstants.DERIVED_TOKEN_REFERENCE, "SecurityContextToken");
711 if (version == ConversationConstants.VERSION_05_02) {
712 properties.put(WSHandlerConstants.USE_2005_12_NAMESPACE, "false");
713 }
714 properties.put(WSHandlerConstants.USER, "transmitter");
715 properties.put(WSHandlerConstants.ENC_SYM_ALGO,
716 "http://www.w3.org/2001/04/xmlenc#aes128-cbc");
717 Document securedDocument = doOutboundSecurityWithWSS4J(sourceDocument, action, properties);
718
719 javax.xml.transform.Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
720 transformer.transform(new DOMSource(securedDocument), new StreamResult(baos));
721 }
722
723 {
724 WSSSecurityProperties securityProperties = new WSSSecurityProperties();
725 securityProperties.loadDecryptionKeystore(this.getClass().getClassLoader().getResource("receiver.jks"), "default".toCharArray());
726 securityProperties.loadSignatureVerificationKeystore(this.getClass().getClassLoader().getResource("receiver.jks"), "default".toCharArray());
727 CallbackHandlerImpl callbackHandler = new CallbackHandlerImpl(tempSecret);
728 securityProperties.setCallbackHandler(callbackHandler);
729 InboundWSSec wsSecIn = WSSec.getInboundWSSec(securityProperties);
730
731 WSSecurityEventConstants.Event[] expectedSecurityEvents = new WSSecurityEventConstants.Event[]{
732 WSSecurityEventConstants.AlgorithmSuite,
733 WSSecurityEventConstants.AlgorithmSuite,
734 WSSecurityEventConstants.AlgorithmSuite,
735 WSSecurityEventConstants.AlgorithmSuite,
736 WSSecurityEventConstants.AlgorithmSuite,
737 WSSecurityEventConstants.AlgorithmSuite,
738 WSSecurityEventConstants.AlgorithmSuite,
739 WSSecurityEventConstants.AlgorithmSuite,
740 WSSecurityEventConstants.AlgorithmSuite,
741 WSSecurityEventConstants.SECURITY_CONTEXT_TOKEN,
742 WSSecurityEventConstants.SignatureValue,
743 WSSecurityEventConstants.SIGNED_PART,
744 WSSecurityEventConstants.ENCRYPTED_PART,
745 WSSecurityEventConstants.OPERATION,
746 };
747 final TestSecurityEventListener securityEventListener = new TestSecurityEventListener(expectedSecurityEvents);
748
749 XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(new ByteArrayInputStream(baos.toByteArray()));
750 XMLStreamReader secureXmlStreamReader = wsSecIn.processInMessage(xmlStreamReader, null, securityEventListener);
751
752 Document document = StAX2DOM.readDoc(documentBuilderFactory.newDocumentBuilder(), secureXmlStreamReader);
753
754 NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedData.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedData.getLocalPart());
755 assertEquals(nodeList.getLength(), 0);
756
757 securityEventListener.compare();
758
759 SignedPartSecurityEvent signedPartSecurityEvent = securityEventListener.getSecurityEvent(WSSecurityEventConstants.SIGNED_PART);
760 SignatureValueSecurityEvent signatureValueSecurityEvent = securityEventListener.getSecurityEvent(WSSecurityEventConstants.SignatureValue);
761 EncryptedPartSecurityEvent encryptedPartSecurityEvent = securityEventListener.getSecurityEvent(WSSecurityEventConstants.ENCRYPTED_PART);
762 OperationSecurityEvent operationSecurityEvent = securityEventListener.getSecurityEvent(WSSecurityEventConstants.OPERATION);
763 String signedElementCorrelationID = signedPartSecurityEvent.getCorrelationID();
764 String signatureValueCorrelationID = signatureValueSecurityEvent.getCorrelationID();
765 String encryptedPartCorrelationID = encryptedPartSecurityEvent.getCorrelationID();
766 String operationCorrelationID = operationSecurityEvent.getCorrelationID();
767
768 List<SecurityEvent> operationSecurityEvents = new ArrayList<>();
769 List<SecurityEvent> signedElementSecurityEvents = new ArrayList<>();
770 List<SecurityEvent> signatureValueSecurityEvents = new ArrayList<>();
771 List<SecurityEvent> encryptedPartSecurityEvents = new ArrayList<>();
772
773 List<SecurityEvent> securityEvents = securityEventListener.getReceivedSecurityEvents();
774 for (SecurityEvent securityEvent : securityEvents) {
775 if (securityEvent.getCorrelationID().equals(signedElementCorrelationID)) {
776 signedElementSecurityEvents.add(securityEvent);
777 } else if (securityEvent.getCorrelationID().equals(signatureValueCorrelationID)) {
778 signatureValueSecurityEvents.add(securityEvent);
779 } else if (securityEvent.getCorrelationID().equals(encryptedPartCorrelationID)) {
780 encryptedPartSecurityEvents.add(securityEvent);
781 } else if (securityEvent.getCorrelationID().equals(operationCorrelationID)) {
782 operationSecurityEvents.add(securityEvent);
783 }
784 }
785
786 assertEquals(3, signedElementSecurityEvents.size());
787 assertEquals(5, signatureValueSecurityEvents.size());
788 assertEquals(5, encryptedPartSecurityEvents.size());
789 assertEquals(securityEventListener.getReceivedSecurityEvents().size(),
790 operationSecurityEvents.size() +
791 signedElementSecurityEvents.size() + signatureValueSecurityEvents.size() + encryptedPartSecurityEvents.size()
792 );
793 }
794 }
795
796 @ParameterizedTest
797 @ValueSource(ints = {ConversationConstants.VERSION_05_02, ConversationConstants.VERSION_05_12})
798 public void testSCTKDKTEncryptSign(int version) throws Exception {
799
800 byte[] tempSecret = XMLSecurityConstants.generateBytes(16);
801 ByteArrayOutputStream baos = new ByteArrayOutputStream();
802 {
803 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
804 WSSecHeader secHeader = new WSSecHeader(doc);
805 secHeader.insertSecurityHeader();
806
807 WSSecSecurityContextToken sctBuilder = new WSSecSecurityContextToken(secHeader, null);
808 sctBuilder.setWscVersion(version);
809 Crypto crypto = CryptoFactory.getInstance("transmitter-crypto.properties");
810 sctBuilder.prepare(crypto);
811
812
813 SecretKeyCallbackHandler callbackHandler = new SecretKeyCallbackHandler();
814 callbackHandler.addSecretKey(sctBuilder.getIdentifier(), tempSecret);
815
816 String tokenId = sctBuilder.getSctId();
817
818
819 WSSecDKEncrypt encrBuilder = new WSSecDKEncrypt(secHeader);
820 encrBuilder.setWscVersion(version);
821 if (version == ConversationConstants.VERSION_05_12) {
822 encrBuilder.setCustomValueType(WSConstants.WSC_SCT_05_12);
823 } else {
824 encrBuilder.setCustomValueType(WSConstants.WSC_SCT);
825 }
826 encrBuilder.setSymmetricEncAlgorithm(WSConstants.AES_128);
827 encrBuilder.setTokenIdentifier(tokenId);
828 encrBuilder.build(tempSecret);
829
830
831 WSSecDKSign sigBuilder = new WSSecDKSign(secHeader);
832 sigBuilder.setWscVersion(version);
833 if (version == ConversationConstants.VERSION_05_12) {
834 sigBuilder.setCustomValueType(WSConstants.WSC_SCT_05_12);
835 } else {
836 sigBuilder.setCustomValueType(WSConstants.WSC_SCT);
837 }
838 sigBuilder.setTokenIdentifier(tokenId);
839 sigBuilder.setSignatureAlgorithm(WSConstants.HMAC_SHA1);
840 sigBuilder.build(tempSecret);
841
842 sctBuilder.prependSCTElementToHeader();
843
844 javax.xml.transform.Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
845 transformer.transform(new DOMSource(doc), new StreamResult(baos));
846 }
847
848 {
849 WSSSecurityProperties securityProperties = new WSSSecurityProperties();
850 securityProperties.loadDecryptionKeystore(this.getClass().getClassLoader().getResource("receiver.jks"), "default".toCharArray());
851 securityProperties.loadSignatureVerificationKeystore(this.getClass().getClassLoader().getResource("receiver.jks"), "default".toCharArray());
852 CallbackHandlerImpl callbackHandler = new CallbackHandlerImpl(tempSecret);
853 securityProperties.setCallbackHandler(callbackHandler);
854 InboundWSSec wsSecIn = WSSec.getInboundWSSec(securityProperties);
855
856 WSSecurityEventConstants.Event[] expectedSecurityEvents = new WSSecurityEventConstants.Event[]{
857 WSSecurityEventConstants.AlgorithmSuite,
858 WSSecurityEventConstants.AlgorithmSuite,
859 WSSecurityEventConstants.AlgorithmSuite,
860 WSSecurityEventConstants.AlgorithmSuite,
861 WSSecurityEventConstants.AlgorithmSuite,
862 WSSecurityEventConstants.AlgorithmSuite,
863 WSSecurityEventConstants.AlgorithmSuite,
864 WSSecurityEventConstants.AlgorithmSuite,
865 WSSecurityEventConstants.AlgorithmSuite,
866 WSSecurityEventConstants.SECURITY_CONTEXT_TOKEN,
867 WSSecurityEventConstants.SignatureValue,
868 WSSecurityEventConstants.SIGNED_PART,
869 WSSecurityEventConstants.ENCRYPTED_PART,
870 WSSecurityEventConstants.OPERATION,
871 };
872 final TestSecurityEventListener securityEventListener = new TestSecurityEventListener(expectedSecurityEvents);
873
874 XMLStreamReader xmlStreamReader = wsSecIn.processInMessage(xmlInputFactory.createXMLStreamReader(new ByteArrayInputStream(baos.toByteArray())), null, securityEventListener);
875
876 Document document = StAX2DOM.readDoc(documentBuilderFactory.newDocumentBuilder(), xmlStreamReader);
877
878 NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedData.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedData.getLocalPart());
879 assertEquals(nodeList.getLength(), 0);
880
881 securityEventListener.compare();
882
883 SignedPartSecurityEvent signedPartSecurityEvent = securityEventListener.getSecurityEvent(WSSecurityEventConstants.SIGNED_PART);
884 SignatureValueSecurityEvent signatureValueSecurityEvent = securityEventListener.getSecurityEvent(WSSecurityEventConstants.SignatureValue);
885 EncryptedPartSecurityEvent encryptedPartSecurityEvent = securityEventListener.getSecurityEvent(WSSecurityEventConstants.ENCRYPTED_PART);
886 OperationSecurityEvent operationSecurityEvent = securityEventListener.getSecurityEvent(WSSecurityEventConstants.OPERATION);
887 String signedElementCorrelationID = signedPartSecurityEvent.getCorrelationID();
888 String signatureValueCorrelationID = signatureValueSecurityEvent.getCorrelationID();
889 String encryptedPartCorrelationID = encryptedPartSecurityEvent.getCorrelationID();
890 String operationCorrelationID = operationSecurityEvent.getCorrelationID();
891
892 List<SecurityEvent> operationSecurityEvents = new ArrayList<>();
893 List<SecurityEvent> signedElementSecurityEvents = new ArrayList<>();
894 List<SecurityEvent> signatureValueSecurityEvents = new ArrayList<>();
895 List<SecurityEvent> encryptedPartSecurityEvents = new ArrayList<>();
896
897 List<SecurityEvent> securityEvents = securityEventListener.getReceivedSecurityEvents();
898 for (SecurityEvent securityEvent : securityEvents) {
899 if (securityEvent.getCorrelationID().equals(signedElementCorrelationID)) {
900 signedElementSecurityEvents.add(securityEvent);
901 } else if (securityEvent.getCorrelationID().equals(signatureValueCorrelationID)) {
902 signatureValueSecurityEvents.add(securityEvent);
903 } else if (securityEvent.getCorrelationID().equals(encryptedPartCorrelationID)) {
904 encryptedPartSecurityEvents.add(securityEvent);
905 } else if (securityEvent.getCorrelationID().equals(operationCorrelationID)) {
906 operationSecurityEvents.add(securityEvent);
907 }
908 }
909
910 assertEquals(3, signedElementSecurityEvents.size());
911 assertEquals(5, signatureValueSecurityEvents.size());
912 assertEquals(5, encryptedPartSecurityEvents.size());
913 assertEquals(securityEventListener.getReceivedSecurityEvents().size(),
914 operationSecurityEvents.size() +
915 signedElementSecurityEvents.size() + signatureValueSecurityEvents.size() + encryptedPartSecurityEvents.size()
916 );
917 }
918 }
919
920 @ParameterizedTest
921 @ValueSource(ints = {ConversationConstants.VERSION_05_02, ConversationConstants.VERSION_05_12})
922 public void testSCTKDKTEncryptSignAction(int version) throws Exception {
923
924 byte[] tempSecret = XMLSecurityConstants.generateBytes(16);
925 ByteArrayOutputStream baos = new ByteArrayOutputStream();
926 {
927 InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
928 String action =
929 WSHandlerConstants.ENCRYPTION_DERIVED + " " + WSHandlerConstants.SIGNATURE_DERIVED;
930
931 Properties properties = new Properties();
932 CallbackHandlerImpl callbackHandler = new CallbackHandlerImpl(tempSecret);
933 properties.put(WSHandlerConstants.PW_CALLBACK_REF, callbackHandler);
934 properties.put(WSHandlerConstants.DERIVED_TOKEN_REFERENCE, "SecurityContextToken");
935 if (version == ConversationConstants.VERSION_05_02) {
936 properties.put(WSHandlerConstants.USE_2005_12_NAMESPACE, "false");
937 }
938 properties.put(WSHandlerConstants.USER, "transmitter");
939 properties.put(WSHandlerConstants.ENC_SYM_ALGO,
940 "http://www.w3.org/2001/04/xmlenc#aes128-cbc");
941 Document securedDocument = doOutboundSecurityWithWSS4J(sourceDocument, action, properties);
942
943 javax.xml.transform.Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
944 transformer.transform(new DOMSource(securedDocument), new StreamResult(baos));
945 }
946
947 {
948 WSSSecurityProperties securityProperties = new WSSSecurityProperties();
949 securityProperties.loadDecryptionKeystore(this.getClass().getClassLoader().getResource("receiver.jks"), "default".toCharArray());
950 securityProperties.loadSignatureVerificationKeystore(this.getClass().getClassLoader().getResource("receiver.jks"), "default".toCharArray());
951 CallbackHandlerImpl callbackHandler = new CallbackHandlerImpl(tempSecret);
952 securityProperties.setCallbackHandler(callbackHandler);
953 InboundWSSec wsSecIn = WSSec.getInboundWSSec(securityProperties);
954
955 WSSecurityEventConstants.Event[] expectedSecurityEvents = new WSSecurityEventConstants.Event[]{
956 WSSecurityEventConstants.AlgorithmSuite,
957 WSSecurityEventConstants.AlgorithmSuite,
958 WSSecurityEventConstants.AlgorithmSuite,
959 WSSecurityEventConstants.AlgorithmSuite,
960 WSSecurityEventConstants.AlgorithmSuite,
961 WSSecurityEventConstants.AlgorithmSuite,
962 WSSecurityEventConstants.AlgorithmSuite,
963 WSSecurityEventConstants.AlgorithmSuite,
964 WSSecurityEventConstants.AlgorithmSuite,
965 WSSecurityEventConstants.SECURITY_CONTEXT_TOKEN,
966 WSSecurityEventConstants.SignatureValue,
967 WSSecurityEventConstants.SIGNED_PART,
968 WSSecurityEventConstants.ENCRYPTED_PART,
969 WSSecurityEventConstants.OPERATION,
970 };
971 final TestSecurityEventListener securityEventListener = new TestSecurityEventListener(expectedSecurityEvents);
972
973 XMLStreamReader xmlStreamReader = wsSecIn.processInMessage(xmlInputFactory.createXMLStreamReader(new ByteArrayInputStream(baos.toByteArray())), null, securityEventListener);
974
975 Document document = StAX2DOM.readDoc(documentBuilderFactory.newDocumentBuilder(), xmlStreamReader);
976
977 NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedData.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedData.getLocalPart());
978 assertEquals(nodeList.getLength(), 0);
979
980 securityEventListener.compare();
981
982 SignedPartSecurityEvent signedPartSecurityEvent = securityEventListener.getSecurityEvent(WSSecurityEventConstants.SIGNED_PART);
983 SignatureValueSecurityEvent signatureValueSecurityEvent = securityEventListener.getSecurityEvent(WSSecurityEventConstants.SignatureValue);
984 EncryptedPartSecurityEvent encryptedPartSecurityEvent = securityEventListener.getSecurityEvent(WSSecurityEventConstants.ENCRYPTED_PART);
985 OperationSecurityEvent operationSecurityEvent = securityEventListener.getSecurityEvent(WSSecurityEventConstants.OPERATION);
986 String signedElementCorrelationID = signedPartSecurityEvent.getCorrelationID();
987 String signatureValueCorrelationID = signatureValueSecurityEvent.getCorrelationID();
988 String encryptedPartCorrelationID = encryptedPartSecurityEvent.getCorrelationID();
989 String operationCorrelationID = operationSecurityEvent.getCorrelationID();
990
991 List<SecurityEvent> operationSecurityEvents = new ArrayList<>();
992 List<SecurityEvent> signedElementSecurityEvents = new ArrayList<>();
993 List<SecurityEvent> signatureValueSecurityEvents = new ArrayList<>();
994 List<SecurityEvent> encryptedPartSecurityEvents = new ArrayList<>();
995
996 List<SecurityEvent> securityEvents = securityEventListener.getReceivedSecurityEvents();
997 for (SecurityEvent securityEvent : securityEvents) {
998 if (securityEvent.getCorrelationID().equals(signedElementCorrelationID)) {
999 signedElementSecurityEvents.add(securityEvent);
1000 } else if (securityEvent.getCorrelationID().equals(signatureValueCorrelationID)) {
1001 signatureValueSecurityEvents.add(securityEvent);
1002 } else if (securityEvent.getCorrelationID().equals(encryptedPartCorrelationID)) {
1003 encryptedPartSecurityEvents.add(securityEvent);
1004 } else if (securityEvent.getCorrelationID().equals(operationCorrelationID)) {
1005 operationSecurityEvents.add(securityEvent);
1006 }
1007 }
1008
1009 assertEquals(3, signedElementSecurityEvents.size());
1010 assertEquals(5, signatureValueSecurityEvents.size());
1011 assertEquals(5, encryptedPartSecurityEvents.size());
1012 assertEquals(securityEventListener.getReceivedSecurityEvents().size(),
1013 operationSecurityEvents.size() +
1014 signedElementSecurityEvents.size() + signatureValueSecurityEvents.size() + encryptedPartSecurityEvents.size()
1015 );
1016 }
1017 }
1018
1019
1020 @ParameterizedTest
1021 @ValueSource(ints = {ConversationConstants.VERSION_05_02, ConversationConstants.VERSION_05_12})
1022 public void testSCTSign(int version) throws Exception {
1023
1024 byte[] tempSecret = XMLSecurityConstants.generateBytes(16);
1025 ByteArrayOutputStream baos = new ByteArrayOutputStream();
1026 {
1027 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
1028 WSSecHeader secHeader = new WSSecHeader(doc);
1029 secHeader.insertSecurityHeader();
1030
1031 WSSecSecurityContextToken sctBuilder = new WSSecSecurityContextToken(secHeader, null);
1032 sctBuilder.setWscVersion(version);
1033 Crypto crypto = CryptoFactory.getInstance("transmitter-crypto.properties");
1034 sctBuilder.prepare(crypto);
1035
1036
1037 SecretKeyCallbackHandler callbackHandler = new SecretKeyCallbackHandler();
1038 callbackHandler.addSecretKey(sctBuilder.getIdentifier(), tempSecret);
1039
1040 String tokenId = sctBuilder.getSctId();
1041
1042 WSSecSignature builder = new WSSecSignature(secHeader);
1043 builder.setSecretKey(tempSecret);
1044 builder.setKeyIdentifierType(WSConstants.CUSTOM_SYMM_SIGNING);
1045 builder.setCustomTokenValueType(WSConstants.WSC_SCT);
1046 builder.setCustomTokenId(tokenId);
1047 builder.setSignatureAlgorithm(SignatureMethod.HMAC_SHA1);
1048 builder.build(crypto);
1049
1050 sctBuilder.prependSCTElementToHeader();
1051
1052 javax.xml.transform.Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
1053 transformer.transform(new DOMSource(doc), new StreamResult(baos));
1054 }
1055
1056 {
1057 WSSSecurityProperties securityProperties = new WSSSecurityProperties();
1058 securityProperties.loadSignatureVerificationKeystore(this.getClass().getClassLoader().getResource("receiver.jks"), "default".toCharArray());
1059 CallbackHandlerImpl callbackHandler = new CallbackHandlerImpl(tempSecret);
1060 securityProperties.setCallbackHandler(callbackHandler);
1061 InboundWSSec wsSecIn = WSSec.getInboundWSSec(securityProperties);
1062
1063 WSSecurityEventConstants.Event[] expectedSecurityEvents = new WSSecurityEventConstants.Event[]{
1064 WSSecurityEventConstants.AlgorithmSuite,
1065 WSSecurityEventConstants.AlgorithmSuite,
1066 WSSecurityEventConstants.AlgorithmSuite,
1067 WSSecurityEventConstants.AlgorithmSuite,
1068 WSSecurityEventConstants.SECURITY_CONTEXT_TOKEN,
1069 WSSecurityEventConstants.SignatureValue,
1070 WSSecurityEventConstants.SIGNED_PART,
1071 WSSecurityEventConstants.OPERATION,
1072 };
1073 final TestSecurityEventListener securityEventListener = new TestSecurityEventListener(expectedSecurityEvents);
1074
1075 XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(new ByteArrayInputStream(baos.toByteArray()));
1076 XMLStreamReader secureXmlStreamReader = wsSecIn.processInMessage(xmlStreamReader, null, securityEventListener);
1077
1078 StAX2DOM.readDoc(documentBuilderFactory.newDocumentBuilder(), secureXmlStreamReader);
1079
1080 securityEventListener.compare();
1081
1082 SignedPartSecurityEvent signedPartSecurityEvent = securityEventListener.getSecurityEvent(WSSecurityEventConstants.SIGNED_PART);
1083 SignatureValueSecurityEvent signatureValueSecurityEvent = securityEventListener.getSecurityEvent(WSSecurityEventConstants.SignatureValue);
1084 OperationSecurityEvent operationSecurityEvent = securityEventListener.getSecurityEvent(WSSecurityEventConstants.OPERATION);
1085 String signedElementCorrelationID = signedPartSecurityEvent.getCorrelationID();
1086 String signatureValueCorrelationID = signatureValueSecurityEvent.getCorrelationID();
1087 String operationCorrelationID = operationSecurityEvent.getCorrelationID();
1088
1089 List<SecurityEvent> operationSecurityEvents = new ArrayList<>();
1090 List<SecurityEvent> signedElementSecurityEvents = new ArrayList<>();
1091 List<SecurityEvent> signatureValueSecurityEvents = new ArrayList<>();
1092
1093 List<SecurityEvent> securityEvents = securityEventListener.getReceivedSecurityEvents();
1094 for (SecurityEvent securityEvent : securityEvents) {
1095 if (securityEvent.getCorrelationID().equals(signedElementCorrelationID)) {
1096 signedElementSecurityEvents.add(securityEvent);
1097 } else if (securityEvent.getCorrelationID().equals(signatureValueCorrelationID)) {
1098 signatureValueSecurityEvents.add(securityEvent);
1099 } else if (securityEvent.getCorrelationID().equals(operationCorrelationID)) {
1100 operationSecurityEvents.add(securityEvent);
1101 }
1102 }
1103
1104 assertEquals(3, signedElementSecurityEvents.size());
1105 assertEquals(4, signatureValueSecurityEvents.size());
1106 assertEquals(securityEventListener.getReceivedSecurityEvents().size(),
1107 operationSecurityEvents.size() +
1108 signedElementSecurityEvents.size() + signatureValueSecurityEvents.size()
1109 );
1110 }
1111 }
1112
1113 @ParameterizedTest
1114 @ValueSource(ints = {ConversationConstants.VERSION_05_02, ConversationConstants.VERSION_05_12})
1115 public void testSCTCustomValidator(int version) throws Exception {
1116 byte[] tempSecret = XMLSecurityConstants.generateBytes(16);
1117 ByteArrayOutputStream baos = new ByteArrayOutputStream();
1118 {
1119 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
1120 WSSecHeader secHeader = new WSSecHeader(doc);
1121 secHeader.insertSecurityHeader();
1122
1123 WSSecSecurityContextToken sctBuilder = new WSSecSecurityContextToken(secHeader, null);
1124 sctBuilder.setWscVersion(version);
1125 Crypto crypto = CryptoFactory.getInstance("transmitter-crypto.properties");
1126 sctBuilder.prepare(crypto);
1127
1128
1129 SecretKeyCallbackHandler callbackHandler = new SecretKeyCallbackHandler();
1130 callbackHandler.addSecretKey(sctBuilder.getIdentifier(), tempSecret);
1131
1132 String tokenId = sctBuilder.getSctId();
1133
1134 WSSecSignature builder = new WSSecSignature(secHeader);
1135 builder.setSecretKey(tempSecret);
1136 builder.setKeyIdentifierType(WSConstants.CUSTOM_SYMM_SIGNING);
1137 builder.setCustomTokenValueType(WSConstants.WSC_SCT);
1138 builder.setCustomTokenId(tokenId);
1139 builder.setSignatureAlgorithm(SignatureMethod.HMAC_SHA1);
1140 builder.build(crypto);
1141
1142 sctBuilder.prependSCTElementToHeader();
1143
1144 javax.xml.transform.Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
1145 transformer.transform(new DOMSource(doc), new StreamResult(baos));
1146 }
1147
1148 {
1149 WSSSecurityProperties securityProperties = new WSSSecurityProperties();
1150 securityProperties.loadSignatureVerificationKeystore(this.getClass().getClassLoader().getResource("receiver.jks"), "default".toCharArray());
1151 CallbackHandlerImpl callbackHandler = new CallbackHandlerImpl(tempSecret);
1152 securityProperties.setCallbackHandler(callbackHandler);
1153
1154 final boolean[] validatorCalled = {false};
1155 SecurityContextTokenValidator validator = new SecurityContextTokenValidatorImpl() {
1156 @Override
1157 public InboundSecurityToken validate(AbstractSecurityContextTokenType securityContextTokenType, String identifier, TokenContext tokenContext) throws WSSecurityException {
1158 validatorCalled[0] = true;
1159 return super.validate(securityContextTokenType, identifier, tokenContext);
1160 }
1161 };
1162
1163 if (version == ConversationConstants.VERSION_05_02) {
1164 securityProperties.addValidator(WSSConstants.TAG_WSC0502_SCT, validator);
1165 } else {
1166 securityProperties.addValidator(WSSConstants.TAG_WSC0512_SCT, validator);
1167 }
1168
1169 InboundWSSec wsSecIn = WSSec.getInboundWSSec(securityProperties);
1170
1171 XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(new ByteArrayInputStream(baos.toByteArray()));
1172 XMLStreamReader secureXmlStreamReader = wsSecIn.processInMessage(xmlStreamReader);
1173
1174 StAX2DOM.readDoc(documentBuilderFactory.newDocumentBuilder(), secureXmlStreamReader);
1175
1176 assertTrue(validatorCalled[0], "Validator should be called when configured");
1177 }
1178 }
1179 }