1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.wss4j.dom.message;
21
22 import java.time.Instant;
23 import java.time.ZoneOffset;
24 import java.time.ZonedDateTime;
25 import java.util.ArrayList;
26 import java.util.Collections;
27 import java.util.List;
28 import java.util.Locale;
29
30 import org.apache.wss4j.common.bsp.BSPEnforcer;
31 import org.apache.wss4j.common.bsp.BSPRule;
32 import org.apache.wss4j.common.ext.WSSecurityException;
33 import org.apache.wss4j.common.util.DateUtil;
34 import org.apache.wss4j.common.util.SOAPUtil;
35 import org.apache.wss4j.common.util.WSTimeSource;
36 import org.apache.wss4j.common.util.XMLUtils;
37 import org.apache.wss4j.dom.WSConstants;
38
39 import org.apache.wss4j.dom.engine.WSSConfig;
40 import org.apache.wss4j.dom.engine.WSSecurityEngine;
41 import org.apache.wss4j.dom.engine.WSSecurityEngineResult;
42 import org.apache.wss4j.dom.handler.RequestData;
43 import org.apache.wss4j.dom.handler.WSHandlerResult;
44 import org.apache.wss4j.dom.message.token.Timestamp;
45 import org.apache.wss4j.dom.validate.NoOpValidator;
46
47 import org.junit.jupiter.api.Test;
48 import org.w3c.dom.Document;
49 import org.w3c.dom.Element;
50
51 import static org.junit.jupiter.api.Assertions.assertNotNull;
52 import static org.junit.jupiter.api.Assertions.assertTrue;
53 import static org.junit.jupiter.api.Assertions.fail;
54
55
56
57
58 public class TimestampTest {
59 private static final org.slf4j.Logger LOG =
60 org.slf4j.LoggerFactory.getLogger(TimestampTest.class);
61
62
63
64
65 @Test
66 public void testValidTimestamp() throws Exception {
67
68 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
69 WSSecHeader secHeader = new WSSecHeader(doc);
70 secHeader.insertSecurityHeader();
71
72 WSSecTimestamp timestamp = new WSSecTimestamp(secHeader);
73 timestamp.setTimeToLive(300);
74 Document createdDoc = timestamp.build();
75
76 if (LOG.isDebugEnabled()) {
77 String outputString =
78 XMLUtils.prettyDocumentToString(createdDoc);
79 LOG.debug(outputString);
80 }
81
82
83
84
85 WSHandlerResult wsResult = verify(createdDoc);
86 WSSecurityEngineResult actionResult =
87 wsResult.getActionResults().get(WSConstants.TS).get(0);
88 assertNotNull(actionResult);
89
90 Timestamp receivedTimestamp =
91 (Timestamp)actionResult.get(WSSecurityEngineResult.TAG_TIMESTAMP);
92 assertNotNull(receivedTimestamp);
93
94 Timestamp clone = new Timestamp(receivedTimestamp.getElement(), new BSPEnforcer(true));
95 assertTrue(clone.equals(receivedTimestamp));
96 assertTrue(clone.hashCode() == receivedTimestamp.hashCode());
97 }
98
99
100
101
102
103 @Test
104 public void testValidTimestampNoExpires() throws Exception {
105
106 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
107 WSSecHeader secHeader = new WSSecHeader(doc);
108 secHeader.insertSecurityHeader();
109
110 WSSecTimestamp timestamp = new WSSecTimestamp(secHeader);
111 timestamp.setTimeToLive(0);
112 Document createdDoc = timestamp.build();
113
114 if (LOG.isDebugEnabled()) {
115 String outputString =
116 XMLUtils.prettyDocumentToString(createdDoc);
117 LOG.debug(outputString);
118 }
119
120
121
122
123 WSHandlerResult wsResult = verify(createdDoc);
124 WSSecurityEngineResult actionResult =
125 wsResult.getActionResults().get(WSConstants.TS).get(0);
126 assertNotNull(actionResult);
127
128 Timestamp receivedTimestamp =
129 (Timestamp)actionResult.get(WSSecurityEngineResult.TAG_TIMESTAMP);
130 assertNotNull(receivedTimestamp);
131 }
132
133 @Test
134 public void testInvalidTimestampNoExpires() throws Exception {
135
136 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
137 WSSecHeader secHeader = new WSSecHeader(doc);
138 secHeader.insertSecurityHeader();
139
140 WSSecTimestamp timestamp = new WSSecTimestamp(secHeader);
141 timestamp.setTimeToLive(0);
142 Document createdDoc = timestamp.build();
143
144 if (LOG.isDebugEnabled()) {
145 String outputString =
146 XMLUtils.prettyDocumentToString(createdDoc);
147 LOG.debug(outputString);
148 }
149
150
151
152
153 WSSecurityEngine secEngine = new WSSecurityEngine();
154 RequestData requestData = new RequestData();
155 requestData.setWssConfig(WSSConfig.getNewInstance());
156 requestData.setRequireTimestampExpires(true);
157 try {
158 secEngine.processSecurityHeader(doc, requestData);
159 fail("Failure expected on no Expires Element");
160 } catch (WSSecurityException ex) {
161 assertTrue(ex.getErrorCode() == WSSecurityException.ErrorCode.SECURITY_ERROR);
162 }
163
164 requestData.setWssConfig(WSSConfig.getNewInstance());
165 requestData.setRequireTimestampExpires(false);
166 WSHandlerResult wsResult = secEngine.processSecurityHeader(doc, requestData);
167 WSSecurityEngineResult actionResult =
168 wsResult.getActionResults().get(WSConstants.TS).get(0);
169 assertNotNull(actionResult);
170
171 Timestamp receivedTimestamp =
172 (Timestamp)actionResult.get(WSSecurityEngineResult.TAG_TIMESTAMP);
173 assertNotNull(receivedTimestamp);
174 }
175
176
177
178
179
180 @Test
181 public void testExpiredTimestamp() throws Exception {
182
183 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
184 WSSecHeader secHeader = new WSSecHeader(doc);
185 secHeader.insertSecurityHeader();
186
187 WSSecTimestamp timestamp = new WSSecTimestamp(secHeader);
188 timestamp.setTimeToLive(-1);
189 Document createdDoc = timestamp.build();
190
191 if (LOG.isDebugEnabled()) {
192 String outputString =
193 XMLUtils.prettyDocumentToString(createdDoc);
194 LOG.debug(outputString);
195 }
196
197 try {
198 verify(createdDoc);
199 fail("Expected failure on an expired timestamp");
200 } catch (WSSecurityException ex) {
201 assertTrue(ex.getErrorCode() == WSSecurityException.ErrorCode.MESSAGE_EXPIRED);
202 }
203 }
204
205
206
207
208
209
210 @Test
211 public void testOldTimestamp() throws Exception {
212
213 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
214 WSSecHeader secHeader = new WSSecHeader(doc);
215 secHeader.insertSecurityHeader();
216
217 WSSecTimestamp timestamp = new WSSecTimestamp(secHeader);
218 Document createdDoc = timestamp.build();
219
220 if (LOG.isDebugEnabled()) {
221 String outputString =
222 XMLUtils.prettyDocumentToString(createdDoc);
223 LOG.debug(outputString);
224 }
225
226
227
228
229 RequestData requestData = new RequestData();
230 requestData.setWssConfig(WSSConfig.getNewInstance());
231 requestData.setTimeStampTTL(-1);
232 try {
233 verify(createdDoc, requestData);
234 fail("The timestamp validation should have failed");
235 } catch (WSSecurityException ex) {
236 assertTrue(ex.getErrorCode() == WSSecurityException.ErrorCode.MESSAGE_EXPIRED);
237 }
238 }
239
240
241
242
243
244
245
246 @Test
247 public void testNearFutureCreated() throws Exception {
248
249 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
250 WSSecHeader secHeader = new WSSecHeader(doc);
251 secHeader.insertSecurityHeader();
252
253 Element timestampElement =
254 doc.createElementNS(
255 WSConstants.WSU_NS, WSConstants.WSU_PREFIX + ":" + WSConstants.TIMESTAMP_TOKEN_LN
256 );
257
258 Element elementCreated =
259 doc.createElementNS(
260 WSConstants.WSU_NS, WSConstants.WSU_PREFIX + ":" + WSConstants.CREATED_LN
261 );
262 ZonedDateTime now = ZonedDateTime.now(ZoneOffset.UTC).plusSeconds(30L);
263 elementCreated.appendChild(doc.createTextNode(DateUtil.getDateTimeFormatter(true).format(now)));
264 timestampElement.appendChild(elementCreated);
265
266 secHeader.getSecurityHeaderElement().appendChild(timestampElement);
267
268 if (LOG.isDebugEnabled()) {
269 String outputString =
270 XMLUtils.prettyDocumentToString(doc);
271 LOG.debug(outputString);
272 }
273
274
275
276 RequestData requestData = new RequestData();
277 requestData.setWssConfig(WSSConfig.getNewInstance());
278 requestData.setTimeStampFutureTTL(0);
279 try {
280 verify(doc, requestData);
281 fail("The timestamp validation should have failed");
282 } catch (WSSecurityException ex) {
283 assertTrue(ex.getErrorCode() == WSSecurityException.ErrorCode.MESSAGE_EXPIRED);
284 }
285 }
286
287
288
289
290
291 @Test
292 public void testFutureCreated() throws Exception {
293
294 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
295 WSSecHeader secHeader = new WSSecHeader(doc);
296 secHeader.insertSecurityHeader();
297
298 Element timestampElement =
299 doc.createElementNS(
300 WSConstants.WSU_NS, WSConstants.WSU_PREFIX + ":" + WSConstants.TIMESTAMP_TOKEN_LN
301 );
302
303 Element elementCreated =
304 doc.createElementNS(
305 WSConstants.WSU_NS, WSConstants.WSU_PREFIX + ":" + WSConstants.CREATED_LN
306 );
307 ZonedDateTime now = ZonedDateTime.now(ZoneOffset.UTC).plusSeconds(120L);
308 elementCreated.appendChild(doc.createTextNode(DateUtil.getDateTimeFormatter(true).format(now)));
309 timestampElement.appendChild(elementCreated);
310
311 secHeader.getSecurityHeaderElement().appendChild(timestampElement);
312
313 if (LOG.isDebugEnabled()) {
314 String outputString =
315 XMLUtils.prettyDocumentToString(doc);
316 LOG.debug(outputString);
317 }
318
319
320
321 try {
322 verify(doc);
323 fail("The timestamp validation should have failed");
324 } catch (WSSecurityException ex) {
325 assertTrue(ex.getErrorCode() == WSSecurityException.ErrorCode.MESSAGE_EXPIRED);
326 }
327 }
328
329
330
331
332
333
334 @Test
335 public void testExpiresBeforeCreated() throws Exception {
336
337 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
338 WSSecHeader secHeader = new WSSecHeader(doc);
339 secHeader.insertSecurityHeader();
340
341 Element timestampElement =
342 doc.createElementNS(
343 WSConstants.WSU_NS, WSConstants.WSU_PREFIX + ":" + WSConstants.TIMESTAMP_TOKEN_LN
344 );
345
346 Element elementCreated =
347 doc.createElementNS(
348 WSConstants.WSU_NS, WSConstants.WSU_PREFIX + ":" + WSConstants.CREATED_LN
349 );
350 ZonedDateTime now = ZonedDateTime.now(ZoneOffset.UTC);
351 elementCreated.appendChild(doc.createTextNode(DateUtil.getDateTimeFormatter(true).format(now)));
352 timestampElement.appendChild(elementCreated);
353
354 Element elementExpires =
355 doc.createElementNS(
356 WSConstants.WSU_NS, WSConstants.WSU_PREFIX + ":" + WSConstants.EXPIRES_LN
357 );
358 now = now.minusSeconds(300L);
359 elementExpires.appendChild(doc.createTextNode(DateUtil.getDateTimeFormatter(true).format(now)));
360 timestampElement.appendChild(elementExpires);
361
362 secHeader.getSecurityHeaderElement().appendChild(timestampElement);
363
364 if (LOG.isDebugEnabled()) {
365 String outputString =
366 XMLUtils.prettyDocumentToString(doc);
367 LOG.debug(outputString);
368 }
369
370
371
372 try {
373 verify(doc);
374 fail("The timestamp validation should have failed");
375 } catch (WSSecurityException ex) {
376 assertTrue(ex.getErrorCode() == WSSecurityException.ErrorCode.MESSAGE_EXPIRED);
377 }
378 }
379
380
381
382
383 @Test
384 public void testMultipleTimestamps() throws Exception {
385
386 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
387 WSSecHeader secHeader = new WSSecHeader(doc);
388 secHeader.insertSecurityHeader();
389
390 WSSecTimestamp timestamp = new WSSecTimestamp(secHeader);
391 timestamp.setTimeToLive(300);
392 Document createdDoc = timestamp.build();
393
394 timestamp = new WSSecTimestamp(secHeader);
395 timestamp.setTimeToLive(60);
396 createdDoc = timestamp.build();
397
398 if (LOG.isDebugEnabled()) {
399 String outputString =
400 XMLUtils.prettyDocumentToString(createdDoc);
401 LOG.debug(outputString);
402 }
403
404
405
406
407 try {
408 verify(createdDoc);
409 fail("Expected failure on multiple timestamps");
410 } catch (WSSecurityException ex) {
411 assertTrue(ex.getErrorCode() == WSSecurityException.ErrorCode.INVALID_SECURITY);
412 }
413
414 verify(createdDoc, Collections.singletonList(BSPRule.R3227));
415 }
416
417
418
419
420
421 @Test
422 public void testMultipleCreated() throws Exception {
423
424 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
425 WSSecHeader secHeader = new WSSecHeader(doc);
426 secHeader.insertSecurityHeader();
427
428 Element timestampElement =
429 doc.createElementNS(
430 WSConstants.WSU_NS, WSConstants.WSU_PREFIX + ":" + WSConstants.TIMESTAMP_TOKEN_LN
431 );
432
433 Element elementCreated =
434 doc.createElementNS(
435 WSConstants.WSU_NS, WSConstants.WSU_PREFIX + ":" + WSConstants.CREATED_LN
436 );
437 ZonedDateTime now = ZonedDateTime.now(ZoneOffset.UTC);
438 elementCreated.appendChild(doc.createTextNode(DateUtil.getDateTimeFormatter(true).format(now)));
439 timestampElement.appendChild(elementCreated);
440 timestampElement.appendChild(elementCreated.cloneNode(true));
441
442 secHeader.getSecurityHeaderElement().appendChild(timestampElement);
443
444 if (LOG.isDebugEnabled()) {
445 String outputString =
446 XMLUtils.prettyDocumentToString(doc);
447 LOG.debug(outputString);
448 }
449
450
451
452 try {
453 verify(doc);
454 fail("The timestamp validation should have failed on multiple Created elements");
455 } catch (WSSecurityException ex) {
456 assertTrue(ex.getErrorCode() == WSSecurityException.ErrorCode.INVALID_SECURITY);
457 }
458
459 verify(doc, Collections.singletonList(BSPRule.R3203));
460 }
461
462
463
464
465
466 @Test
467 public void testNoCreated() throws Exception {
468
469 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
470 WSSecHeader secHeader = new WSSecHeader(doc);
471 secHeader.insertSecurityHeader();
472
473 Element timestampElement =
474 doc.createElementNS(
475 WSConstants.WSU_NS, WSConstants.WSU_PREFIX + ":" + WSConstants.TIMESTAMP_TOKEN_LN
476 );
477
478 Element elementExpires =
479 doc.createElementNS(
480 WSConstants.WSU_NS, WSConstants.WSU_PREFIX + ":" + WSConstants.EXPIRES_LN
481 );
482 ZonedDateTime now = ZonedDateTime.now(ZoneOffset.UTC).plusSeconds(300L);
483 elementExpires.appendChild(doc.createTextNode(DateUtil.getDateTimeFormatter(true).format(now)));
484 timestampElement.appendChild(elementExpires);
485
486 secHeader.getSecurityHeaderElement().appendChild(timestampElement);
487
488 if (LOG.isDebugEnabled()) {
489 String outputString =
490 XMLUtils.prettyDocumentToString(doc);
491 LOG.debug(outputString);
492 }
493
494
495
496 try {
497 verify(doc);
498 fail("The timestamp validation should have failed on no Created element");
499 } catch (WSSecurityException ex) {
500 assertTrue(ex.getErrorCode() == WSSecurityException.ErrorCode.INVALID_SECURITY);
501 }
502
503 List<BSPRule> rules = new ArrayList<>();
504 rules.add(BSPRule.R3203);
505 rules.add(BSPRule.R3221);
506 verify(doc, rules);
507 }
508
509
510
511
512
513 @Test
514 public void testMultipleExpires() throws Exception {
515
516 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
517 WSSecHeader secHeader = new WSSecHeader(doc);
518 secHeader.insertSecurityHeader();
519
520 Element timestampElement =
521 doc.createElementNS(
522 WSConstants.WSU_NS, WSConstants.WSU_PREFIX + ":" + WSConstants.TIMESTAMP_TOKEN_LN
523 );
524
525 Element elementCreated =
526 doc.createElementNS(
527 WSConstants.WSU_NS, WSConstants.WSU_PREFIX + ":" + WSConstants.CREATED_LN
528 );
529 ZonedDateTime now = ZonedDateTime.now(ZoneOffset.UTC);
530 elementCreated.appendChild(doc.createTextNode(DateUtil.getDateTimeFormatter(true).format(now)));
531 timestampElement.appendChild(elementCreated);
532
533 Element elementExpires =
534 doc.createElementNS(
535 WSConstants.WSU_NS, WSConstants.WSU_PREFIX + ":" + WSConstants.EXPIRES_LN
536 );
537 now = now.plusSeconds(300L);
538 elementExpires.appendChild(doc.createTextNode(DateUtil.getDateTimeFormatter(true).format(now)));
539 timestampElement.appendChild(elementExpires);
540 timestampElement.appendChild(elementExpires.cloneNode(true));
541
542 secHeader.getSecurityHeaderElement().appendChild(timestampElement);
543
544 if (LOG.isDebugEnabled()) {
545 String outputString =
546 XMLUtils.prettyDocumentToString(doc);
547 LOG.debug(outputString);
548 }
549
550
551
552 try {
553 verify(doc);
554 fail("The timestamp validation should have failed on multiple Expires elements");
555 } catch (WSSecurityException ex) {
556 assertTrue(ex.getErrorCode() == WSSecurityException.ErrorCode.INVALID_SECURITY);
557 }
558
559 verify(doc, Collections.singletonList(BSPRule.R3224));
560 }
561
562
563
564
565
566 @Test
567 public void testExpiresInFrontOfCreated() throws Exception {
568
569 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
570 WSSecHeader secHeader = new WSSecHeader(doc);
571 secHeader.insertSecurityHeader();
572
573 Element timestampElement =
574 doc.createElementNS(
575 WSConstants.WSU_NS, WSConstants.WSU_PREFIX + ":" + WSConstants.TIMESTAMP_TOKEN_LN
576 );
577
578 Element elementCreated =
579 doc.createElementNS(
580 WSConstants.WSU_NS, WSConstants.WSU_PREFIX + ":" + WSConstants.EXPIRES_LN
581 );
582 ZonedDateTime now = ZonedDateTime.now(ZoneOffset.UTC).plusSeconds(300L);
583 elementCreated.appendChild(doc.createTextNode(DateUtil.getDateTimeFormatter(true).format(now)));
584 timestampElement.appendChild(elementCreated);
585
586 Element elementExpires =
587 doc.createElementNS(
588 WSConstants.WSU_NS, WSConstants.WSU_PREFIX + ":" + WSConstants.CREATED_LN
589 );
590 now = ZonedDateTime.now(ZoneOffset.UTC);
591 elementExpires.appendChild(doc.createTextNode(DateUtil.getDateTimeFormatter(true).format(now)));
592 timestampElement.appendChild(elementExpires);
593
594 secHeader.getSecurityHeaderElement().appendChild(timestampElement);
595
596 if (LOG.isDebugEnabled()) {
597 String outputString =
598 XMLUtils.prettyDocumentToString(doc);
599 LOG.debug(outputString);
600 }
601
602
603
604 try {
605 verify(doc);
606 fail("The timestamp validation should have failed");
607 } catch (WSSecurityException ex) {
608 assertTrue(ex.getErrorCode() == WSSecurityException.ErrorCode.INVALID_SECURITY);
609 }
610
611 verify(doc, Collections.singletonList(BSPRule.R3221));
612 }
613
614
615
616
617
618
619 @Test
620 public void testCreatedSeconds() throws Exception {
621
622 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
623 WSSecHeader secHeader = new WSSecHeader(doc);
624 secHeader.insertSecurityHeader();
625
626 Element timestampElement =
627 doc.createElementNS(
628 WSConstants.WSU_NS, WSConstants.WSU_PREFIX + ":" + WSConstants.TIMESTAMP_TOKEN_LN
629 );
630
631 Element elementCreated =
632 doc.createElementNS(
633 WSConstants.WSU_NS, WSConstants.WSU_PREFIX + ":" + WSConstants.CREATED_LN
634 );
635 elementCreated.appendChild(doc.createTextNode("2011-02-08T13:13:84.535Z"));
636 timestampElement.appendChild(elementCreated);
637
638 secHeader.getSecurityHeaderElement().appendChild(timestampElement);
639
640 if (LOG.isDebugEnabled()) {
641 String outputString =
642 XMLUtils.prettyDocumentToString(doc);
643 LOG.debug(outputString);
644 }
645
646
647
648
649 WSSConfig wssConfig = WSSConfig.getNewInstance();
650 wssConfig.setValidator(WSConstants.TIMESTAMP, new NoOpValidator());
651 try {
652 verify(doc, wssConfig, new ArrayList<>());
653 fail("The timestamp validation should have failed");
654 } catch (WSSecurityException ex) {
655 assertTrue(ex.getErrorCode() == WSSecurityException.ErrorCode.INVALID_SECURITY);
656 }
657 }
658
659
660
661
662
663
664 @Test
665 public void testCreatedValueType() throws Exception {
666
667 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
668 WSSecHeader secHeader = new WSSecHeader(doc);
669 secHeader.insertSecurityHeader();
670
671 Element timestampElement =
672 doc.createElementNS(
673 WSConstants.WSU_NS, WSConstants.WSU_PREFIX + ":" + WSConstants.TIMESTAMP_TOKEN_LN
674 );
675
676 Element elementCreated =
677 doc.createElementNS(
678 WSConstants.WSU_NS, WSConstants.WSU_PREFIX + ":" + WSConstants.CREATED_LN
679 );
680 ZonedDateTime now = ZonedDateTime.now(ZoneOffset.UTC);
681 elementCreated.appendChild(doc.createTextNode(DateUtil.getDateTimeFormatter(true).format(now)));
682 elementCreated.setAttributeNS(null, "ValueType", WSConstants.WSS_SAML_KI_VALUE_TYPE);
683 timestampElement.appendChild(elementCreated);
684
685 secHeader.getSecurityHeaderElement().appendChild(timestampElement);
686
687 if (LOG.isDebugEnabled()) {
688 String outputString =
689 XMLUtils.prettyDocumentToString(doc);
690 LOG.debug(outputString);
691 }
692
693
694
695 try {
696 verify(doc);
697 fail("The timestamp validation should have failed");
698 } catch (WSSecurityException ex) {
699 assertTrue(ex.getErrorCode() == WSSecurityException.ErrorCode.INVALID_SECURITY);
700 }
701
702
703 WSSConfig wssConfig = WSSConfig.getNewInstance();
704 wssConfig.setValidator(WSConstants.TIMESTAMP, new NoOpValidator());
705 verify(doc, wssConfig, Collections.singletonList(BSPRule.R3225));
706 }
707
708
709
710
711
712
713
714 @Test
715 public void testCustomElement() throws Exception {
716
717 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
718 WSSecHeader secHeader = new WSSecHeader(doc);
719 secHeader.insertSecurityHeader();
720
721 Element timestampElement =
722 doc.createElementNS(
723 WSConstants.WSU_NS, WSConstants.WSU_PREFIX + ":" + WSConstants.TIMESTAMP_TOKEN_LN
724 );
725
726 Element elementCreated =
727 doc.createElementNS(
728 WSConstants.WSU_NS, WSConstants.WSU_PREFIX + ":" + WSConstants.CREATED_LN
729 );
730 ZonedDateTime now = ZonedDateTime.now(ZoneOffset.UTC);
731 elementCreated.appendChild(doc.createTextNode(DateUtil.getDateTimeFormatter(true).format(now)));
732 timestampElement.appendChild(elementCreated);
733
734 Element elementExpires =
735 doc.createElementNS(
736 WSConstants.WSU_NS, WSConstants.WSU_PREFIX + ":" + WSConstants.EXPIRES_LN
737 );
738 now = now.plusSeconds(300L);
739 elementExpires.appendChild(doc.createTextNode(DateUtil.getDateTimeFormatter(true).format(now)));
740 timestampElement.appendChild(elementExpires);
741
742 Element elementCustom =
743 doc.createElementNS(
744 WSConstants.WSU_NS, WSConstants.WSU_PREFIX + ":" + "Custom"
745 );
746 timestampElement.appendChild(elementCustom);
747
748 secHeader.getSecurityHeaderElement().appendChild(timestampElement);
749
750 if (LOG.isDebugEnabled()) {
751 String outputString =
752 XMLUtils.prettyDocumentToString(doc);
753 LOG.debug(outputString);
754 }
755
756
757
758 try {
759 verify(doc);
760 fail("The timestamp validation should have failed");
761 } catch (WSSecurityException ex) {
762 assertTrue(ex.getErrorCode() == WSSecurityException.ErrorCode.INVALID_SECURITY);
763 }
764
765
766 verify(doc, Collections.singletonList(BSPRule.R3222));
767 }
768
769
770
771
772 @Test
773 public void testSpoofedTimestamp() throws Exception {
774
775 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
776 WSSecHeader secHeader = new WSSecHeader(doc);
777 secHeader.insertSecurityHeader();
778
779 WSSecTimestamp timestamp = new WSSecTimestamp(secHeader);
780 timestamp.setTimeToLive(300);
781
782 WSTimeSource spoofedTimeSource = new WSTimeSource() {
783
784 public Instant now() {
785 return Instant.now().minusSeconds(500L);
786 }
787
788 };
789 timestamp.setWsTimeSource(spoofedTimeSource);
790
791 Document createdDoc = timestamp.build();
792
793 if (LOG.isDebugEnabled()) {
794 String outputString =
795 XMLUtils.prettyDocumentToString(createdDoc);
796 LOG.debug(outputString);
797 }
798
799
800
801
802 try {
803 verify(createdDoc);
804 fail("Expected failure on an expired timestamp");
805 } catch (WSSecurityException ex) {
806 assertTrue(ex.getErrorCode() == WSSecurityException.ErrorCode.MESSAGE_EXPIRED);
807 }
808 }
809
810 @Test
811 public void testTimestampNoMilliseconds() throws Exception {
812
813 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
814 WSSecHeader secHeader = new WSSecHeader(doc);
815 secHeader.insertSecurityHeader();
816
817 WSSecTimestamp timestamp = new WSSecTimestamp(secHeader);
818 timestamp.setPrecisionInMilliSeconds(false);
819 timestamp.setTimeToLive(300);
820 Document createdDoc = timestamp.build();
821
822 if (LOG.isDebugEnabled()) {
823 String outputString =
824 XMLUtils.prettyDocumentToString(createdDoc);
825 LOG.debug(outputString);
826 }
827
828
829
830
831 WSHandlerResult wsResult = verify(createdDoc);
832 WSSecurityEngineResult actionResult =
833 wsResult.getActionResults().get(WSConstants.TS).get(0);
834 assertNotNull(actionResult);
835 }
836
837 @Test
838 public void testThaiLocaleVerification() throws Exception {
839
840 Locale defaultLocale = Locale.getDefault();
841 try {
842 Locale.setDefault(new Locale("th", "TH"));
843
844 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
845 WSSecHeader secHeader = new WSSecHeader(doc);
846 secHeader.insertSecurityHeader();
847
848 WSSecTimestamp timestamp = new WSSecTimestamp(secHeader);
849 timestamp.setTimeToLive(300);
850 Document createdDoc = timestamp.build();
851
852
853
854
855 WSHandlerResult wsResult = verify(createdDoc);
856 WSSecurityEngineResult actionResult =
857 wsResult.getActionResults().get(WSConstants.TS).get(0);
858 assertNotNull(actionResult);
859 } finally {
860 Locale.setDefault(defaultLocale);
861 }
862 }
863
864
865
866
867 private WSHandlerResult verify(
868 Document doc
869 ) throws Exception {
870 WSSecurityEngine secEngine = new WSSecurityEngine();
871 RequestData requestData = new RequestData();
872 requestData.setWssConfig(WSSConfig.getNewInstance());
873 return secEngine.processSecurityHeader(doc, requestData);
874 }
875
876 private WSHandlerResult verify(
877 Document doc, RequestData requestData
878 ) throws Exception {
879 WSSecurityEngine secEngine = new WSSecurityEngine();
880 return secEngine.processSecurityHeader(doc, requestData);
881 }
882
883
884
885
886 private WSHandlerResult verify(
887 Document doc, List<BSPRule> ignoredRules
888 ) throws Exception {
889 WSSecurityEngine secEngine = new WSSecurityEngine();
890 RequestData requestData = new RequestData();
891 requestData.setIgnoredBSPRules(ignoredRules);
892 return secEngine.processSecurityHeader(doc, requestData);
893 }
894
895
896
897
898 private WSHandlerResult verify(
899 Document doc, WSSConfig wssConfig, List<BSPRule> ignoredRules
900 ) throws Exception {
901 WSSecurityEngine secEngine = new WSSecurityEngine();
902 RequestData requestData = new RequestData();
903 requestData.setWssConfig(wssConfig);
904 requestData.setIgnoredBSPRules(ignoredRules);
905 return secEngine.processSecurityHeader(doc, requestData);
906 }
907
908
909 }