1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.wss4j.dom.message;
20
21 import java.io.ByteArrayInputStream;
22 import java.io.ByteArrayOutputStream;
23 import java.io.IOException;
24 import java.io.InputStream;
25 import java.net.URLEncoder;
26 import java.nio.charset.StandardCharsets;
27 import java.util.ArrayList;
28 import java.util.Base64;
29 import java.util.Collections;
30 import java.util.List;
31 import java.util.UUID;
32
33 import javax.crypto.KeyGenerator;
34 import javax.crypto.SecretKey;
35 import javax.security.auth.callback.CallbackHandler;
36
37 import org.apache.wss4j.common.WSEncryptionPart;
38 import org.apache.wss4j.common.WSS4JConstants;
39 import org.apache.wss4j.common.crypto.Crypto;
40 import org.apache.wss4j.common.crypto.CryptoFactory;
41 import org.apache.wss4j.common.ext.Attachment;
42 import org.apache.wss4j.common.util.KeyUtils;
43 import org.apache.wss4j.common.util.SOAPUtil;
44 import org.apache.wss4j.common.util.XMLUtils;
45 import org.apache.wss4j.dom.WSConstants;
46 import org.apache.wss4j.dom.common.CustomHandler;
47 import org.apache.wss4j.dom.common.KeystoreCallbackHandler;
48 import org.apache.wss4j.dom.engine.WSSConfig;
49 import org.apache.wss4j.dom.engine.WSSecurityEngine;
50 import org.apache.wss4j.dom.handler.HandlerAction;
51 import org.apache.wss4j.dom.handler.RequestData;
52 import org.apache.wss4j.dom.handler.WSHandlerConstants;
53 import org.apache.wss4j.dom.handler.WSHandlerResult;
54 import org.apache.wss4j.dom.util.WSSecurityUtil;
55 import org.junit.jupiter.api.Test;
56 import org.w3c.dom.Document;
57 import org.w3c.dom.Element;
58 import org.w3c.dom.Node;
59
60 import static org.junit.jupiter.api.Assertions.assertNotNull;
61 import static org.junit.jupiter.api.Assertions.assertTrue;
62
63
64
65
66 public class XOPAttachmentTest {
67
68 private static final String SOAP_BODY =
69 "<add xmlns=\"http://ws.apache.org/counter/counter_port_type\">"
70 + "<value xmlns=\"\">15</value>"
71 + "</add>";
72
73 private static final String SOAP_HEADER_MSG = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
74 "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">" +
75 " <soapenv:Header>" +
76 " <foo:bar1 xmlns:foo=\"urn:foo.bar\" >baz1</foo:bar1>" +
77 " <foo:foobar xmlns:foo=\"urn:foo.bar\" >baz</foo:foobar>" +
78 " <foo:bar2 xmlns:foo=\"urn:foo.bar\" >baz2</foo:bar2>" +
79 " </soapenv:Header>" +
80 " <soapenv:Body>" +
81 " <ns1:testMethod xmlns:ns1=\"http://axis/service/security/test6/LogTestService8\"></ns1:testMethod>" +
82 " </soapenv:Body>" +
83 "</soapenv:Envelope>";
84
85 private static final org.slf4j.Logger LOG =
86 org.slf4j.LoggerFactory.getLogger(XOPAttachmentTest.class);
87
88 private WSSecurityEngine secEngine = new WSSecurityEngine();
89 private Crypto crypto;
90
91 public XOPAttachmentTest() throws Exception {
92 WSSConfig.init();
93 crypto = CryptoFactory.getInstance();
94 }
95
96 protected byte[] readInputStream(InputStream inputStream) throws IOException {
97 try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) {
98 int read = 0;
99 byte[] buf = new byte[4096];
100 while ((read = inputStream.read(buf)) != -1) {
101 byteArrayOutputStream.write(buf, 0, read);
102 }
103 return byteArrayOutputStream.toByteArray();
104 }
105 }
106
107
108
109
110
111 @Test
112 public void testManualEncryptedSOAPBody() throws Exception {
113 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
114 WSSecHeader secHeader = new WSSecHeader(doc);
115 secHeader.insertSecurityHeader();
116
117 WSSecEncrypt encrypt = new WSSecEncrypt(secHeader);
118 encrypt.setUserInfo("16c73ab6-b892-458f-abf5-2f875f74882e", "security");
119 encrypt.setKeyIdentifierType(WSConstants.ISSUER_SERIAL);
120
121 encrypt.getParts().add(new WSEncryptionPart("Body", "http://schemas.xmlsoap.org/soap/envelope/", "Content"));
122 encrypt.getParts().add(new WSEncryptionPart("cid:Attachments", "Content"));
123
124 String attachmentId = UUID.randomUUID().toString();
125 final Attachment attachment = new Attachment();
126 attachment.setId(attachmentId);
127 attachment.setSourceStream(new ByteArrayInputStream(SOAP_BODY.getBytes(StandardCharsets.UTF_8)));
128
129 AttachmentCallbackHandler attachmentCallbackHandler =
130 new AttachmentCallbackHandler(Collections.singletonList(attachment));
131 encrypt.setAttachmentCallbackHandler(attachmentCallbackHandler);
132 List<Attachment> encryptedAttachments = attachmentCallbackHandler.getResponseAttachments();
133
134 KeyGenerator keyGen = KeyUtils.getKeyGenerator(WSConstants.AES_128);
135 SecretKey symmetricKey = keyGen.generateKey();
136 Document encryptedDoc = encrypt.build(crypto, symmetricKey);
137
138
139 Element soapBody = WSSecurityUtil.findBodyElement(encryptedDoc);
140 assertNotNull(soapBody);
141 Element encryptedData =
142 XMLUtils.getDirectChildElement(soapBody, "EncryptedData", WSConstants.ENC_NS);
143 encryptedData.removeAttributeNS(null, "Type");
144 Element cipherData =
145 XMLUtils.getDirectChildElement(encryptedData, "CipherData", WSConstants.ENC_NS);
146 assertNotNull(cipherData);
147 Element cipherValue =
148 XMLUtils.getDirectChildElement(cipherData, "CipherValue", WSConstants.ENC_NS);
149 assertNotNull(cipherValue);
150
151 XMLUtils.setNamespace(cipherValue, WSS4JConstants.XOP_NS, "xop");
152
153 Element cipherValueChild = encryptedDoc.createElementNS(WSConstants.XOP_NS, "Include");
154 cipherValueChild.setAttributeNS(null, "href", "cid:" + encryptedAttachments.get(0).getId());
155 cipherValue.replaceChild(cipherValueChild, cipherValue.getFirstChild());
156
157
158
159 Element securityHeader =
160 WSSecurityUtil.findWsseSecurityHeaderBlock(encryptedDoc, encryptedDoc.getDocumentElement(), false);
161 Element encryptedAttachmentData =
162 XMLUtils.getDirectChildElement(securityHeader, "EncryptedData", WSConstants.ENC_NS);
163 assertNotNull(encryptedAttachmentData);
164 String encryptedDataId = encryptedAttachmentData.getAttributeNS(null, "Id");
165 securityHeader.removeChild(encryptedAttachmentData);
166
167
168 Element encryptedKey =
169 XMLUtils.getDirectChildElement(securityHeader, "EncryptedKey", WSConstants.ENC_NS);
170 assertNotNull(encryptedKey);
171 Element referenceList =
172 XMLUtils.getDirectChildElement(encryptedKey, "ReferenceList", WSConstants.ENC_NS);
173 assertNotNull(referenceList);
174 Node child = referenceList.getFirstChild();
175 while (child != null) {
176 if (child instanceof Element && "DataReference".equals(child.getLocalName())
177 && WSConstants.ENC_NS.equals(child.getNamespaceURI())) {
178 String uri = ((Element)child).getAttributeNS(null, "URI");
179 if (uri.equals("#" + encryptedDataId)) {
180 referenceList.removeChild(child);
181 break;
182 }
183 }
184 child = child.getNextSibling();
185 }
186
187 if (LOG.isDebugEnabled()) {
188 String outputString = XMLUtils.prettyDocumentToString(encryptedDoc);
189 LOG.debug(outputString);
190
191 }
192
193 attachmentCallbackHandler = new AttachmentCallbackHandler(encryptedAttachments);
194 verify(encryptedDoc, attachmentCallbackHandler);
195
196 String processedDoc = XMLUtils.prettyDocumentToString(encryptedDoc);
197 assertTrue(processedDoc.contains(SOAP_BODY));
198 }
199
200 @Test
201 public void testEncryptedSOAPBody() throws Exception {
202 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
203 WSSecHeader secHeader = new WSSecHeader(doc);
204 secHeader.insertSecurityHeader();
205
206 WSSecEncrypt encrypt = new WSSecEncrypt(secHeader);
207 encrypt.setUserInfo("16c73ab6-b892-458f-abf5-2f875f74882e", "security");
208 encrypt.setKeyIdentifierType(WSConstants.ISSUER_SERIAL);
209
210 AttachmentCallbackHandler outboundAttachmentCallback = new AttachmentCallbackHandler();
211 encrypt.setAttachmentCallbackHandler(outboundAttachmentCallback);
212 encrypt.setStoreBytesInAttachment(true);
213
214 encrypt.getParts().add(new WSEncryptionPart("Body", "http://schemas.xmlsoap.org/soap/envelope/", "Content"));
215
216 KeyGenerator keyGen = KeyUtils.getKeyGenerator(WSConstants.AES_128);
217 SecretKey symmetricKey = keyGen.generateKey();
218 Document encryptedDoc = encrypt.build(crypto, symmetricKey);
219
220 List<Attachment> encryptedAttachments = outboundAttachmentCallback.getResponseAttachments();
221 assertNotNull(encryptedAttachments);
222
223 assertTrue(encryptedAttachments.size() == 2);
224
225 if (LOG.isDebugEnabled()) {
226 String outputString = XMLUtils.prettyDocumentToString(encryptedDoc);
227 LOG.debug(outputString);
228
229 }
230
231 AttachmentCallbackHandler inboundAttachmentCallback =
232 new AttachmentCallbackHandler(encryptedAttachments);
233 verify(encryptedDoc, inboundAttachmentCallback);
234
235 String processedDoc = XMLUtils.prettyDocumentToString(encryptedDoc);
236 assertTrue(processedDoc.contains(SOAP_BODY));
237 }
238
239
240 @Test
241 public void testEncryptedSOAPBodyURLEncoding() throws Exception {
242 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
243 WSSecHeader secHeader = new WSSecHeader(doc);
244 secHeader.insertSecurityHeader();
245
246 WSSecEncrypt encrypt = new WSSecEncrypt(secHeader);
247 encrypt.setUserInfo("16c73ab6-b892-458f-abf5-2f875f74882e", "security");
248 encrypt.setKeyIdentifierType(WSConstants.ISSUER_SERIAL);
249
250 AttachmentCallbackHandler outboundAttachmentCallback = new AttachmentCallbackHandler();
251 encrypt.setAttachmentCallbackHandler(outboundAttachmentCallback);
252 encrypt.setStoreBytesInAttachment(true);
253
254 encrypt.getParts().add(new WSEncryptionPart("Body", "http://schemas.xmlsoap.org/soap/envelope/", "Content"));
255
256 KeyGenerator keyGen = KeyUtils.getKeyGenerator(WSConstants.AES_128);
257 SecretKey symmetricKey = keyGen.generateKey();
258 Document encryptedDoc = encrypt.build(crypto, symmetricKey);
259
260 List<Attachment> encryptedAttachments = outboundAttachmentCallback.getResponseAttachments();
261 assertNotNull(encryptedAttachments);
262
263 assertTrue(encryptedAttachments.size() == 2);
264
265
266
267 String newId = "http://tempuri.org/1/636966400494014846";
268 String oldId = encryptedAttachments.get(1).getId();
269 encryptedAttachments.get(1).setId(newId);
270 List<Element> xopElements =
271 XMLUtils.findElements(doc.getDocumentElement(), "Include", "http://www.w3.org/2004/08/xop/include");
272 for (Element xop : xopElements) {
273 if (xop.hasAttribute("href") && xop.getAttributeNS(null, "href").equals("cid:" + oldId)) {
274 xop.setAttributeNS(null, "href", "cid:" + URLEncoder.encode(newId, StandardCharsets.UTF_8.name()));
275 }
276 }
277
278 if (LOG.isDebugEnabled()) {
279 String outputString = XMLUtils.prettyDocumentToString(encryptedDoc);
280 LOG.debug(outputString);
281
282 }
283
284 AttachmentCallbackHandler inboundAttachmentCallback =
285 new AttachmentCallbackHandler(encryptedAttachments);
286 verify(encryptedDoc, inboundAttachmentCallback);
287
288 String processedDoc = XMLUtils.prettyDocumentToString(encryptedDoc);
289 assertTrue(processedDoc.contains(SOAP_BODY));
290 }
291
292
293 @Test
294 public void testSignedSOAPBody() throws Exception {
295 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
296 WSSecHeader secHeader = new WSSecHeader(doc);
297 secHeader.insertSecurityHeader();
298
299 WSSecSignature builder = new WSSecSignature(secHeader);
300 builder.setUserInfo("16c73ab6-b892-458f-abf5-2f875f74882e", "security");
301 builder.setKeyIdentifierType(WSConstants.BST_DIRECT_REFERENCE);
302
303 AttachmentCallbackHandler outboundAttachmentCallback = new AttachmentCallbackHandler();
304 builder.setAttachmentCallbackHandler(outboundAttachmentCallback);
305 builder.setStoreBytesInAttachment(true);
306
307 Document signedDoc = builder.build(crypto);
308
309 List<Attachment> signedAttachments = outboundAttachmentCallback.getResponseAttachments();
310 assertNotNull(signedAttachments);
311 assertTrue(signedAttachments.size() == 1);
312
313 if (LOG.isDebugEnabled()) {
314 LOG.debug("After Signing....");
315 String outputString =
316 XMLUtils.prettyDocumentToString(signedDoc);
317 LOG.debug(outputString);
318 }
319
320 AttachmentCallbackHandler inboundAttachmentCallback =
321 new AttachmentCallbackHandler(signedAttachments);
322 verify(signedDoc, inboundAttachmentCallback);
323 }
324
325 @Test
326 public void testSignedSOAPBodyAndBinarySecurityToken() throws Exception {
327 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
328 WSSecHeader secHeader = new WSSecHeader(doc);
329 secHeader.insertSecurityHeader();
330
331 WSSecSignature builder = new WSSecSignature(secHeader);
332 builder.setUserInfo("16c73ab6-b892-458f-abf5-2f875f74882e", "security");
333 builder.setKeyIdentifierType(WSConstants.ISSUER_SERIAL);
334 builder.setIncludeSignatureToken(true);
335
336 AttachmentCallbackHandler outboundAttachmentCallback = new AttachmentCallbackHandler();
337 builder.setAttachmentCallbackHandler(outboundAttachmentCallback);
338 builder.setStoreBytesInAttachment(true);
339
340 Document signedDoc = builder.build(crypto);
341
342 List<Attachment> signedAttachments = outboundAttachmentCallback.getResponseAttachments();
343 assertNotNull(signedAttachments);
344 assertTrue(signedAttachments.size() == 1);
345
346 if (LOG.isDebugEnabled()) {
347 LOG.debug("After Signing....");
348 String outputString =
349 XMLUtils.prettyDocumentToString(signedDoc);
350 LOG.debug(outputString);
351 }
352
353 AttachmentCallbackHandler inboundAttachmentCallback =
354 new AttachmentCallbackHandler(signedAttachments);
355 verify(signedDoc, inboundAttachmentCallback);
356 }
357
358 @Test
359 public void testEncryptedHeaderAsEncryptedData() throws Exception {
360 Document doc = SOAPUtil.toSOAPPart(SOAP_HEADER_MSG);
361 WSSecHeader secHeader = new WSSecHeader(doc);
362 secHeader.insertSecurityHeader();
363
364 WSSecEncrypt encrypt = new WSSecEncrypt(secHeader);
365 encrypt.setUserInfo("16c73ab6-b892-458f-abf5-2f875f74882e", "security");
366 encrypt.setKeyIdentifierType(WSConstants.ISSUER_SERIAL);
367
368 AttachmentCallbackHandler outboundAttachmentCallback = new AttachmentCallbackHandler();
369 encrypt.setAttachmentCallbackHandler(outboundAttachmentCallback);
370 encrypt.setStoreBytesInAttachment(true);
371
372 WSEncryptionPart encP =
373 new WSEncryptionPart(
374 "foobar", "urn:foo.bar", "");
375 encrypt.getParts().add(new WSEncryptionPart("Body", "http://schemas.xmlsoap.org/soap/envelope/", "Content"));
376 encrypt.getParts().add(encP);
377
378 KeyGenerator keyGen = KeyUtils.getKeyGenerator(WSConstants.AES_128);
379 SecretKey symmetricKey = keyGen.generateKey();
380 Document encryptedDoc = encrypt.build(crypto, symmetricKey);
381
382 List<Attachment> encryptedAttachments = outboundAttachmentCallback.getResponseAttachments();
383 assertNotNull(encryptedAttachments);
384
385 assertTrue(encryptedAttachments.size() == 3);
386
387 if (LOG.isDebugEnabled()) {
388 String outputString = XMLUtils.prettyDocumentToString(encryptedDoc);
389 LOG.debug(outputString);
390
391 }
392
393 AttachmentCallbackHandler inboundAttachmentCallback =
394 new AttachmentCallbackHandler(encryptedAttachments);
395 verify(encryptedDoc, inboundAttachmentCallback);
396 }
397
398 @Test
399 public void testEncryptedHeaderasEncryptedHeader() throws Exception {
400 Document doc = SOAPUtil.toSOAPPart(SOAP_HEADER_MSG);
401 WSSecHeader secHeader = new WSSecHeader(doc);
402 secHeader.insertSecurityHeader();
403
404 WSSecEncrypt encrypt = new WSSecEncrypt(secHeader);
405 encrypt.setUserInfo("16c73ab6-b892-458f-abf5-2f875f74882e", "security");
406 encrypt.setKeyIdentifierType(WSConstants.ISSUER_SERIAL);
407
408 AttachmentCallbackHandler outboundAttachmentCallback = new AttachmentCallbackHandler();
409 encrypt.setAttachmentCallbackHandler(outboundAttachmentCallback);
410 encrypt.setStoreBytesInAttachment(true);
411
412 WSEncryptionPart encP =
413 new WSEncryptionPart(
414 "foobar", "urn:foo.bar", "Header");
415 encrypt.getParts().add(new WSEncryptionPart("Body", "http://schemas.xmlsoap.org/soap/envelope/", "Content"));
416 encrypt.getParts().add(encP);
417
418 KeyGenerator keyGen = KeyUtils.getKeyGenerator(WSConstants.AES_128);
419 SecretKey symmetricKey = keyGen.generateKey();
420 Document encryptedDoc = encrypt.build(crypto, symmetricKey);
421
422 List<Attachment> encryptedAttachments = outboundAttachmentCallback.getResponseAttachments();
423 assertNotNull(encryptedAttachments);
424
425 assertTrue(encryptedAttachments.size() == 3);
426
427 if (LOG.isDebugEnabled()) {
428 String outputString = XMLUtils.prettyDocumentToString(encryptedDoc);
429 LOG.debug(outputString);
430 }
431
432 AttachmentCallbackHandler inboundAttachmentCallback =
433 new AttachmentCallbackHandler(encryptedAttachments);
434 verify(encryptedDoc, inboundAttachmentCallback);
435 }
436
437 @Test
438 public void testDerivedEncryptedSOAPBody() throws Exception {
439 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
440 WSSecHeader secHeader = new WSSecHeader(doc);
441 secHeader.insertSecurityHeader();
442
443 AttachmentCallbackHandler outboundAttachmentCallback = new AttachmentCallbackHandler();
444
445
446 WSSecEncryptedKey encrKeyBuilder = new WSSecEncryptedKey(secHeader);
447 encrKeyBuilder.setUserInfo("16c73ab6-b892-458f-abf5-2f875f74882e");
448 encrKeyBuilder.setKeyIdentifierType(WSConstants.THUMBPRINT_IDENTIFIER);
449 encrKeyBuilder.setAttachmentCallbackHandler(outboundAttachmentCallback);
450 encrKeyBuilder.setStoreBytesInAttachment(true);
451
452 KeyGenerator keyGen = KeyUtils.getKeyGenerator(WSConstants.AES_128);
453 SecretKey symmetricKey = keyGen.generateKey();
454 encrKeyBuilder.prepare(crypto, symmetricKey);
455
456
457 byte[] ek = symmetricKey.getEncoded();
458 String tokenIdentifier = encrKeyBuilder.getId();
459
460
461 WSSecDKEncrypt encrBuilder = new WSSecDKEncrypt(secHeader);
462 encrBuilder.setSymmetricEncAlgorithm(WSConstants.AES_128);
463 encrBuilder.setTokenIdentifier(tokenIdentifier);
464 encrBuilder.setAttachmentCallbackHandler(outboundAttachmentCallback);
465 encrBuilder.setStoreBytesInAttachment(true);
466 Document encryptedDoc = encrBuilder.build(ek);
467
468 encrKeyBuilder.prependToHeader();
469 encrKeyBuilder.prependBSTElementToHeader();
470
471 List<Attachment> encryptedAttachments = outboundAttachmentCallback.getResponseAttachments();
472 assertNotNull(encryptedAttachments);
473
474 assertTrue(encryptedAttachments.size() == 2);
475
476 if (LOG.isDebugEnabled()) {
477 String outputString = XMLUtils.prettyDocumentToString(encryptedDoc);
478 LOG.debug(outputString);
479
480 }
481
482 AttachmentCallbackHandler inboundAttachmentCallback =
483 new AttachmentCallbackHandler(encryptedAttachments);
484 verify(encryptedDoc, inboundAttachmentCallback);
485
486 String processedDoc = XMLUtils.prettyDocumentToString(encryptedDoc);
487 assertTrue(processedDoc.contains(SOAP_BODY));
488 }
489
490 @Test
491 public void testDerivedSignedSOAPBody() throws Exception {
492 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
493 WSSecHeader secHeader = new WSSecHeader(doc);
494 secHeader.insertSecurityHeader();
495
496 AttachmentCallbackHandler outboundAttachmentCallback = new AttachmentCallbackHandler();
497
498
499 WSSecEncryptedKey encrKeyBuilder = new WSSecEncryptedKey(secHeader);
500 encrKeyBuilder.setUserInfo("16c73ab6-b892-458f-abf5-2f875f74882e");
501 encrKeyBuilder.setKeyIdentifierType(WSConstants.THUMBPRINT_IDENTIFIER);
502 encrKeyBuilder.setAttachmentCallbackHandler(outboundAttachmentCallback);
503 encrKeyBuilder.setStoreBytesInAttachment(true);
504
505 KeyGenerator keyGen = KeyUtils.getKeyGenerator(WSConstants.AES_128);
506 SecretKey symmetricKey = keyGen.generateKey();
507 encrKeyBuilder.prepare(crypto, symmetricKey);
508
509
510 byte[] ek = symmetricKey.getEncoded();
511 String tokenIdentifier = encrKeyBuilder.getId();
512
513
514 WSSecDKSign sigBuilder = new WSSecDKSign(secHeader);
515 sigBuilder.setTokenIdentifier(tokenIdentifier);
516 sigBuilder.setSignatureAlgorithm(WSConstants.HMAC_SHA1);
517 sigBuilder.setAttachmentCallbackHandler(outboundAttachmentCallback);
518 sigBuilder.setStoreBytesInAttachment(true);
519 Document signedDoc = sigBuilder.build(ek);
520
521 encrKeyBuilder.prependToHeader();
522 encrKeyBuilder.prependBSTElementToHeader();
523
524 List<Attachment> signedAttachments = outboundAttachmentCallback.getResponseAttachments();
525 assertNotNull(signedAttachments);
526 assertTrue(signedAttachments.size() == 1);
527
528 if (LOG.isDebugEnabled()) {
529 String outputString = XMLUtils.prettyDocumentToString(signedDoc);
530 LOG.debug(outputString);
531 }
532
533 AttachmentCallbackHandler inboundAttachmentCallback =
534 new AttachmentCallbackHandler(signedAttachments);
535 verify(signedDoc, inboundAttachmentCallback);
536
537 String processedDoc = XMLUtils.prettyDocumentToString(signedDoc);
538 assertTrue(processedDoc.contains(SOAP_BODY));
539 }
540
541 @Test
542 public void testSignedEncryptedSOAPBody() throws Exception {
543 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
544 WSSecHeader secHeader = new WSSecHeader(doc);
545 secHeader.insertSecurityHeader();
546
547 AttachmentCallbackHandler outboundAttachmentCallback = new AttachmentCallbackHandler();
548
549 WSSecSignature builder = new WSSecSignature(secHeader);
550 builder.setUserInfo("16c73ab6-b892-458f-abf5-2f875f74882e", "security");
551 builder.setKeyIdentifierType(WSConstants.BST_DIRECT_REFERENCE);
552
553 builder.setAttachmentCallbackHandler(outboundAttachmentCallback);
554 builder.setStoreBytesInAttachment(true);
555 builder.getParts().add(new WSEncryptionPart("Body", "http://schemas.xmlsoap.org/soap/envelope/", "Content"));
556 builder.build(crypto);
557
558 WSSecEncrypt encrypt = new WSSecEncrypt(secHeader);
559 encrypt.setUserInfo("16c73ab6-b892-458f-abf5-2f875f74882e", "security");
560 encrypt.setKeyIdentifierType(WSConstants.ISSUER_SERIAL);
561
562 encrypt.setAttachmentCallbackHandler(outboundAttachmentCallback);
563 encrypt.setStoreBytesInAttachment(true);
564 encrypt.getParts().add(new WSEncryptionPart("Body", "http://schemas.xmlsoap.org/soap/envelope/", "Content"));
565
566 KeyGenerator keyGen = KeyUtils.getKeyGenerator(WSConstants.AES_128);
567 SecretKey symmetricKey = keyGen.generateKey();
568 Document encryptedDoc = encrypt.build(crypto, symmetricKey);
569
570 List<Attachment> encryptedAttachments = outboundAttachmentCallback.getResponseAttachments();
571 assertNotNull(encryptedAttachments);
572 assertTrue(encryptedAttachments.size() == 3);
573
574 if (LOG.isDebugEnabled()) {
575 String outputString = XMLUtils.prettyDocumentToString(encryptedDoc);
576 LOG.debug(outputString);
577
578 }
579
580 AttachmentCallbackHandler inboundAttachmentCallback =
581 new AttachmentCallbackHandler(encryptedAttachments);
582 verify(encryptedDoc, inboundAttachmentCallback);
583
584 String processedDoc = XMLUtils.prettyDocumentToString(encryptedDoc);
585 assertTrue(processedDoc.contains(SOAP_BODY));
586 }
587
588 @Test
589 public void testSignedEncryptedSOAPBodyViaHandler() throws Exception {
590 final WSSConfig cfg = WSSConfig.getNewInstance();
591 final RequestData reqData = new RequestData();
592 reqData.setWssConfig(cfg);
593 reqData.setUsername("16c73ab6-b892-458f-abf5-2f875f74882e");
594
595 AttachmentCallbackHandler outboundAttachmentCallback = new AttachmentCallbackHandler();
596 reqData.setAttachmentCallbackHandler(outboundAttachmentCallback);
597
598
599 java.util.Map<String, Object> config = new java.util.TreeMap<>();
600 config.put(WSHandlerConstants.SIG_PROP_FILE, "crypto.properties");
601 config.put(WSHandlerConstants.ENC_PROP_FILE, "crypto.properties");
602 config.put(WSHandlerConstants.SIG_KEY_ID, "DirectReference");
603 config.put("password", "security");
604 config.put(WSHandlerConstants.STORE_BYTES_IN_ATTACHMENT, "true");
605 reqData.setMsgContext(config);
606
607 final Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
608 CustomHandler handler = new CustomHandler();
609 List<HandlerAction> actions = new ArrayList<>();
610 actions.add(new HandlerAction(WSConstants.SIGN));
611 actions.add(new HandlerAction(WSConstants.ENCR));
612
613 handler.send(
614 doc,
615 reqData,
616 actions,
617 true
618 );
619 String outputString =
620 XMLUtils.prettyDocumentToString(doc);
621 if (LOG.isDebugEnabled()) {
622 LOG.debug("Signed message:");
623 LOG.debug(outputString);
624 }
625
626 List<Attachment> encryptedAttachments = outboundAttachmentCallback.getResponseAttachments();
627 assertNotNull(encryptedAttachments);
628 assertTrue(encryptedAttachments.size() == 3);
629
630 AttachmentCallbackHandler inboundAttachmentCallback =
631 new AttachmentCallbackHandler(encryptedAttachments);
632 verify(doc, inboundAttachmentCallback);
633
634 String processedDoc = XMLUtils.prettyDocumentToString(doc);
635 assertTrue(processedDoc.contains(SOAP_BODY));
636 }
637
638 @Test
639 public void testEncryptedSignedSOAPBodyViaHandler() throws Exception {
640 final WSSConfig cfg = WSSConfig.getNewInstance();
641 final RequestData reqData = new RequestData();
642 reqData.setWssConfig(cfg);
643 reqData.setUsername("16c73ab6-b892-458f-abf5-2f875f74882e");
644
645 AttachmentCallbackHandler outboundAttachmentCallback = new AttachmentCallbackHandler();
646 reqData.setAttachmentCallbackHandler(outboundAttachmentCallback);
647
648
649 java.util.Map<String, Object> config = new java.util.TreeMap<>();
650 config.put(WSHandlerConstants.SIG_PROP_FILE, "crypto.properties");
651 config.put(WSHandlerConstants.ENC_PROP_FILE, "crypto.properties");
652 config.put(WSHandlerConstants.SIG_KEY_ID, "DirectReference");
653 config.put("password", "security");
654 config.put(WSHandlerConstants.STORE_BYTES_IN_ATTACHMENT, "true");
655 reqData.setMsgContext(config);
656
657 final Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
658 CustomHandler handler = new CustomHandler();
659 List<HandlerAction> actions = new ArrayList<>();
660 actions.add(new HandlerAction(WSConstants.ENCR));
661 actions.add(new HandlerAction(WSConstants.SIGN));
662
663 handler.send(
664 doc,
665 reqData,
666 actions,
667 true
668 );
669 String outputString =
670 XMLUtils.prettyDocumentToString(doc);
671 if (LOG.isDebugEnabled()) {
672 LOG.debug("Signed message:");
673 LOG.debug(outputString);
674 }
675
676 List<Attachment> encryptedAttachments = outboundAttachmentCallback.getResponseAttachments();
677 assertNotNull(encryptedAttachments);
678 assertTrue(encryptedAttachments.isEmpty());
679
680 AttachmentCallbackHandler inboundAttachmentCallback =
681 new AttachmentCallbackHandler(encryptedAttachments);
682 verify(doc, inboundAttachmentCallback);
683
684 String processedDoc = XMLUtils.prettyDocumentToString(doc);
685 assertTrue(processedDoc.contains(SOAP_BODY));
686 }
687
688
689
690 @Test
691 public void testSignatureValueInAttachment() throws Exception {
692 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
693 WSSecHeader secHeader = new WSSecHeader(doc);
694 secHeader.insertSecurityHeader();
695
696 WSSecSignature builder = new WSSecSignature(secHeader);
697 builder.setUserInfo("16c73ab6-b892-458f-abf5-2f875f74882e", "security");
698 builder.setKeyIdentifierType(WSConstants.BST_DIRECT_REFERENCE);
699
700 AttachmentCallbackHandler outboundAttachmentCallback = new AttachmentCallbackHandler();
701 builder.setAttachmentCallbackHandler(outboundAttachmentCallback);
702 builder.setStoreBytesInAttachment(true);
703
704 Document signedDoc = builder.build(crypto);
705
706 List<Attachment> signedAttachments = outboundAttachmentCallback.getResponseAttachments();
707 assertNotNull(signedAttachments);
708 assertTrue(signedAttachments.size() == 1);
709
710
711 Element signatureValue = XMLUtils.findElement(signedDoc.getDocumentElement(), "SignatureValue", WSConstants.SIG_NS);
712 assertNotNull(signatureValue);
713
714 String attachmentId = UUID.randomUUID().toString();
715 final Attachment attachment = new Attachment();
716 attachment.setId(attachmentId);
717 byte[] decodedBytes = Base64.getMimeDecoder().decode(signatureValue.getTextContent());
718 attachment.setSourceStream(new ByteArrayInputStream(decodedBytes));
719 signedAttachments.add(attachment);
720
721 XMLUtils.setNamespace(signatureValue, WSS4JConstants.XOP_NS, "xop");
722
723 Element signatureValueChild = signedDoc.createElementNS(WSConstants.XOP_NS, "xop:Include");
724 signatureValueChild.setAttributeNS(null, "href", "cid:" + attachmentId);
725 signatureValue.replaceChild(signatureValueChild, signatureValue.getFirstChild());
726
727 if (LOG.isDebugEnabled()) {
728 LOG.debug("After Signing....");
729 String outputString =
730 XMLUtils.prettyDocumentToString(signedDoc);
731 LOG.debug(outputString);
732 }
733
734 AttachmentCallbackHandler inboundAttachmentCallback =
735 new AttachmentCallbackHandler(signedAttachments);
736 verify(signedDoc, inboundAttachmentCallback);
737 }
738
739
740
741
742
743
744
745 private WSHandlerResult verify(Document doc, CallbackHandler attachmentCallbackHandler) throws Exception {
746 RequestData requestData = new RequestData();
747 requestData.setAttachmentCallbackHandler(attachmentCallbackHandler);
748 requestData.setSigVerCrypto(crypto);
749 requestData.setDecCrypto(crypto);
750 requestData.setCallbackHandler(new KeystoreCallbackHandler());
751 requestData.setExpandXopInclude(true);
752 return secEngine.processSecurityHeader(doc, requestData);
753 }
754 }