1   /**
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements. See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership. The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License. You may obtain a copy of the License at
9    *
10   * http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied. See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  
20  package org.apache.ws.security.message;
21  
22  import org.apache.ws.security.WSConstants;
23  import org.apache.ws.security.WSSConfig;
24  import org.apache.ws.security.WSSecurityEngineResult;
25  import org.apache.ws.security.WSSecurityException;
26  import org.apache.ws.security.WSSecurityEngine;
27  import org.apache.ws.security.common.SOAPUtil;
28  import org.apache.ws.security.message.token.Timestamp;
29  import org.apache.ws.security.util.WSSecurityUtil;
30  import org.apache.ws.security.util.XmlSchemaDateFormat;
31  import org.apache.ws.security.validate.NoOpValidator;
32  import org.w3c.dom.Document;
33  import org.w3c.dom.Element;
34  
35  import java.text.DateFormat;
36  import java.util.Date;
37  import java.util.List;
38  
39  /**
40   * WS-Security Test Case for Timestamps.
41   */
42  public class TimestampTest extends org.junit.Assert {
43      private static final org.apache.commons.logging.Log LOG = 
44          org.apache.commons.logging.LogFactory.getLog(TimestampTest.class);
45  
46      /**
47       * This is a test for processing a valid Timestamp.
48       */
49      @org.junit.Test
50      public void testValidTimestamp() throws Exception {
51  
52          Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
53          WSSecHeader secHeader = new WSSecHeader();
54          secHeader.insertSecurityHeader(doc);
55          
56          WSSecTimestamp timestamp = new WSSecTimestamp();
57          timestamp.setTimeToLive(300);
58          Document createdDoc = timestamp.build(doc, secHeader);
59  
60          if (LOG.isDebugEnabled()) {
61              String outputString = 
62                  org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(createdDoc);
63              LOG.debug(outputString);
64          }
65          
66          //
67          // Do some processing
68          //
69          List<WSSecurityEngineResult> wsResult = verify(createdDoc, WSSConfig.getNewInstance());
70          WSSecurityEngineResult actionResult = 
71              WSSecurityUtil.fetchActionResult(wsResult, WSConstants.TS);
72          assertTrue(actionResult != null);
73          
74          Timestamp receivedTimestamp = 
75              (Timestamp)actionResult.get(WSSecurityEngineResult.TAG_TIMESTAMP);
76          assertTrue(receivedTimestamp != null);
77          
78          Timestamp clone = new Timestamp(receivedTimestamp.getElement());
79          assertTrue(clone.equals(receivedTimestamp));
80          assertTrue(clone.hashCode() == receivedTimestamp.hashCode());
81      }
82      
83      
84      /**
85       * This is a test for processing a valid Timestamp with no expires element
86       */
87      @org.junit.Test
88      public void testValidTimestampNoExpires() throws Exception {
89  
90          Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
91          WSSecHeader secHeader = new WSSecHeader();
92          secHeader.insertSecurityHeader(doc);
93          
94          WSSecTimestamp timestamp = new WSSecTimestamp();
95          timestamp.setTimeToLive(0);
96          Document createdDoc = timestamp.build(doc, secHeader);
97  
98          if (LOG.isDebugEnabled()) {
99              String outputString = 
100                 org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(createdDoc);
101             LOG.debug(outputString);
102         }
103         
104         //
105         // Do some processing
106         //
107         List<WSSecurityEngineResult> wsResult = verify(createdDoc, WSSConfig.getNewInstance());
108         WSSecurityEngineResult actionResult = 
109             WSSecurityUtil.fetchActionResult(wsResult, WSConstants.TS);
110         assertTrue(actionResult != null);
111         
112         Timestamp receivedTimestamp = 
113             (Timestamp)actionResult.get(WSSecurityEngineResult.TAG_TIMESTAMP);
114         assertTrue(receivedTimestamp != null);
115     }
116     
117     
118     /**
119      * This is a test for processing an expired Timestamp.
120      */
121     @org.junit.Test
122     public void testExpiredTimestamp() throws Exception {
123 
124         Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
125         WSSecHeader secHeader = new WSSecHeader();
126         secHeader.insertSecurityHeader(doc);
127         
128         WSSecTimestamp timestamp = new WSSecTimestamp();
129         timestamp.setTimeToLive(-1);
130         Document createdDoc = timestamp.build(doc, secHeader);
131 
132         if (LOG.isDebugEnabled()) {
133             String outputString = 
134                 org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(createdDoc);
135             LOG.debug(outputString);
136         }
137         
138         try {
139             verify(createdDoc, WSSConfig.getNewInstance());
140             fail("Expected failure on an expired timestamp");
141         } catch (WSSecurityException ex) {
142             assertTrue(ex.getErrorCode() == WSSecurityException.MESSAGE_EXPIRED); 
143         }        
144     }
145     
146     
147     /**
148      * This is a test for processing an "old" Timestamp, i.e. one with a "Created" element that is
149      * out of date
150      */
151     @org.junit.Test
152     public void testOldTimestamp() throws Exception {
153         
154         Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
155         WSSecHeader secHeader = new WSSecHeader();
156         secHeader.insertSecurityHeader(doc);
157         
158         WSSecTimestamp timestamp = new WSSecTimestamp();
159         Document createdDoc = timestamp.build(doc, secHeader);
160 
161         if (LOG.isDebugEnabled()) {
162             String outputString = 
163                 org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(createdDoc);
164             LOG.debug(outputString);
165         }
166         
167         //
168         // Do some processing
169         //
170         WSSConfig wssConfig = WSSConfig.getNewInstance();
171         wssConfig.setTimeStampTTL(-1);
172         try {
173             verify(createdDoc, wssConfig);
174             fail("The timestamp validation should have failed");
175         } catch (WSSecurityException ex) {
176             assertTrue(ex.getErrorCode() == WSSecurityException.MESSAGE_EXPIRED); 
177         }  
178     }
179     
180     
181     /**
182      * This is a test for processing an Timestamp where the "Created" element is in the (near)
183      * future. It should be accepted by default when it is created 30 seconds in the future, 
184      * and then rejected once we configure "0 seconds" for future-time-to-live.
185      */
186     @org.junit.Test
187     public void testNearFutureCreated() throws Exception {
188         
189         Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
190         WSSecHeader secHeader = new WSSecHeader();
191         secHeader.insertSecurityHeader(doc);
192         
193         Element timestampElement = 
194             doc.createElementNS(
195                 WSConstants.WSU_NS, WSConstants.WSU_PREFIX + ":" + WSConstants.TIMESTAMP_TOKEN_LN
196             );
197 
198         DateFormat zulu = new XmlSchemaDateFormat();
199         Element elementCreated =
200             doc.createElementNS(
201                 WSConstants.WSU_NS, WSConstants.WSU_PREFIX + ":" + WSConstants.CREATED_LN
202             );
203         Date createdDate = new Date();
204         long currentTime = createdDate.getTime() + 30000;
205         createdDate.setTime(currentTime);
206         elementCreated.appendChild(doc.createTextNode(zulu.format(createdDate)));
207         timestampElement.appendChild(elementCreated);
208 
209         secHeader.getSecurityHeader().appendChild(timestampElement);
210         
211         if (LOG.isDebugEnabled()) {
212             String outputString = 
213                 org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(doc);
214             LOG.debug(outputString);
215         }
216         //
217         // Do some processing
218         //
219         WSSConfig config = WSSConfig.getNewInstance();
220         verify(doc, config);
221         try {
222             config.setTimeStampFutureTTL(0);
223             verify(doc, config);
224             fail("The timestamp validation should have failed");
225         } catch (WSSecurityException ex) {
226             assertTrue(ex.getErrorCode() == WSSecurityException.MESSAGE_EXPIRED); 
227         }
228     }
229     
230     /**
231      * This is a test for processing an Timestamp where the "Created" element is in the future.
232      * A Timestamp that is 120 seconds in the future should be rejected by default.
233      */
234     @org.junit.Test
235     public void testFutureCreated() throws Exception {
236         
237         Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
238         WSSecHeader secHeader = new WSSecHeader();
239         secHeader.insertSecurityHeader(doc);
240         
241         Element timestampElement = 
242             doc.createElementNS(
243                 WSConstants.WSU_NS, WSConstants.WSU_PREFIX + ":" + WSConstants.TIMESTAMP_TOKEN_LN
244             );
245 
246         DateFormat zulu = new XmlSchemaDateFormat();
247         Element elementCreated =
248             doc.createElementNS(
249                 WSConstants.WSU_NS, WSConstants.WSU_PREFIX + ":" + WSConstants.CREATED_LN
250             );
251         Date createdDate = new Date();
252         long currentTime = createdDate.getTime() + 120000;
253         createdDate.setTime(currentTime);
254         elementCreated.appendChild(doc.createTextNode(zulu.format(createdDate)));
255         timestampElement.appendChild(elementCreated);
256 
257         secHeader.getSecurityHeader().appendChild(timestampElement);
258         
259         if (LOG.isDebugEnabled()) {
260             String outputString = 
261                 org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(doc);
262             LOG.debug(outputString);
263         }
264         //
265         // Do some processing
266         //
267         WSSConfig config = WSSConfig.getNewInstance();
268         try {
269             verify(doc, config);
270             fail("The timestamp validation should have failed");
271         } catch (WSSecurityException ex) {
272             assertTrue(ex.getErrorCode() == WSSecurityException.MESSAGE_EXPIRED); 
273         }
274     }
275     
276     
277     /**
278      * This is a test for processing an Timestamp where the "Created" element is greater than
279      * the expiration time.
280      */
281     @org.junit.Test
282     public void testExpiresBeforeCreated() throws Exception {
283         
284         Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
285         WSSecHeader secHeader = new WSSecHeader();
286         secHeader.insertSecurityHeader(doc);
287         
288         Element timestampElement = 
289             doc.createElementNS(
290                 WSConstants.WSU_NS, WSConstants.WSU_PREFIX + ":" + WSConstants.TIMESTAMP_TOKEN_LN
291             );
292 
293         DateFormat zulu = new XmlSchemaDateFormat();
294         Element elementCreated =
295             doc.createElementNS(
296                 WSConstants.WSU_NS, WSConstants.WSU_PREFIX + ":" + WSConstants.CREATED_LN
297             );
298         Date createdDate = new Date();
299         long currentTime = createdDate.getTime() + 300000;
300         createdDate.setTime(currentTime);
301         elementCreated.appendChild(doc.createTextNode(zulu.format(createdDate)));
302         timestampElement.appendChild(elementCreated);
303         
304         Date expiresDate = new Date();
305         expiresDate.setTime(expiresDate.getTime() -300000);
306 
307         Element elementExpires =
308             doc.createElementNS(
309                 WSConstants.WSU_NS, WSConstants.WSU_PREFIX + ":" + WSConstants.EXPIRES_LN
310             );
311         elementExpires.appendChild(doc.createTextNode(zulu.format(expiresDate)));
312         timestampElement.appendChild(elementExpires);
313 
314         secHeader.getSecurityHeader().appendChild(timestampElement);
315         
316         if (LOG.isDebugEnabled()) {
317             String outputString = 
318                 org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(doc);
319             LOG.debug(outputString);
320         }
321         //
322         // Do some processing
323         //
324         try {
325             verify(doc, WSSConfig.getNewInstance());
326             fail("The timestamp validation should have failed");
327         } catch (WSSecurityException ex) {
328             assertTrue(ex.getErrorCode() == WSSecurityException.MESSAGE_EXPIRED); 
329         }
330     }
331     
332     /**
333      * This is a test for processing multiple Timestamps in the security header
334      */
335     @org.junit.Test
336     public void testMultipleTimestamps() throws Exception {
337 
338         Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
339         WSSecHeader secHeader = new WSSecHeader();
340         secHeader.insertSecurityHeader(doc);
341         
342         WSSecTimestamp timestamp = new WSSecTimestamp();
343         timestamp.setTimeToLive(300);
344         Document createdDoc = timestamp.build(doc, secHeader);
345         
346         timestamp = new WSSecTimestamp();
347         timestamp.setTimeToLive(60);
348         createdDoc = timestamp.build(doc, secHeader);
349 
350         if (LOG.isDebugEnabled()) {
351             String outputString = 
352                 org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(createdDoc);
353             LOG.debug(outputString);
354         }
355         
356         //
357         // Do some processing
358         //
359         WSSConfig wssConfig = WSSConfig.getNewInstance();
360         wssConfig.setWsiBSPCompliant(true);
361         try {
362             verify(createdDoc, wssConfig);
363             fail("Expected failure on multiple timestamps");
364         } catch (WSSecurityException ex) {
365             // expected
366         }
367         
368         // Turn off BSP compliance and the test should pass
369         wssConfig.setWsiBSPCompliant(false);
370         verify(createdDoc, wssConfig);
371     }
372     
373     /**
374      * This is a test for processing an Timestamp where it contains multiple "Created" elements.
375      * This Timestamp should be rejected.
376      */
377     @org.junit.Test
378     public void testMultipleCreated() throws Exception {
379         
380         Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
381         WSSecHeader secHeader = new WSSecHeader();
382         secHeader.insertSecurityHeader(doc);
383         
384         Element timestampElement = 
385             doc.createElementNS(
386                 WSConstants.WSU_NS, WSConstants.WSU_PREFIX + ":" + WSConstants.TIMESTAMP_TOKEN_LN
387             );
388 
389         DateFormat zulu = new XmlSchemaDateFormat();
390         Element elementCreated =
391             doc.createElementNS(
392                 WSConstants.WSU_NS, WSConstants.WSU_PREFIX + ":" + WSConstants.CREATED_LN
393             );
394         Date createdDate = new Date();
395         long currentTime = createdDate.getTime() + 300000;
396         createdDate.setTime(currentTime);
397         elementCreated.appendChild(doc.createTextNode(zulu.format(createdDate)));
398         timestampElement.appendChild(elementCreated);
399         timestampElement.appendChild(elementCreated.cloneNode(true));
400 
401         secHeader.getSecurityHeader().appendChild(timestampElement);
402         
403         if (LOG.isDebugEnabled()) {
404             String outputString = 
405                 org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(doc);
406             LOG.debug(outputString);
407         }
408         //
409         // Do some processing
410         //
411         try {
412             verify(doc, WSSConfig.getNewInstance());
413             fail("The timestamp validation should have failed on multiple Created elements");
414         } catch (WSSecurityException ex) {
415             // expected
416         }
417     }
418     
419     /**
420      * This is a test for processing an Timestamp where it contains no "Created" element.
421      * This Timestamp should be rejected.
422      */
423     @org.junit.Test
424     public void testNoCreated() throws Exception {
425         
426         Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
427         WSSecHeader secHeader = new WSSecHeader();
428         secHeader.insertSecurityHeader(doc);
429         
430         Element timestampElement = 
431             doc.createElementNS(
432                 WSConstants.WSU_NS, WSConstants.WSU_PREFIX + ":" + WSConstants.TIMESTAMP_TOKEN_LN
433             );
434 
435         DateFormat zulu = new XmlSchemaDateFormat();
436         Element elementCreated =
437             doc.createElementNS(
438                 WSConstants.WSU_NS, WSConstants.WSU_PREFIX + ":" + WSConstants.EXPIRES_LN
439             );
440         Date createdDate = new Date();
441         long currentTime = createdDate.getTime() + 300000;
442         createdDate.setTime(currentTime);
443         elementCreated.appendChild(doc.createTextNode(zulu.format(createdDate)));
444         timestampElement.appendChild(elementCreated);
445 
446         secHeader.getSecurityHeader().appendChild(timestampElement);
447         
448         if (LOG.isDebugEnabled()) {
449             String outputString = 
450                 org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(doc);
451             LOG.debug(outputString);
452         }
453         //
454         // Do some processing
455         //
456         WSSConfig wssConfig = WSSConfig.getNewInstance();
457         wssConfig.setWsiBSPCompliant(true);
458         try {
459             verify(doc, wssConfig);
460             fail("The timestamp validation should have failed on no Created element");
461         } catch (WSSecurityException ex) {
462             // expected
463         }
464     }
465     
466     /**
467      * This is a test for processing an Timestamp where it contains multiple "Expires" elements.
468      * This Timestamp should be rejected.
469      */
470     @org.junit.Test
471     public void testMultipleExpires() throws Exception {
472         
473         Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
474         WSSecHeader secHeader = new WSSecHeader();
475         secHeader.insertSecurityHeader(doc);
476         
477         Element timestampElement = 
478             doc.createElementNS(
479                 WSConstants.WSU_NS, WSConstants.WSU_PREFIX + ":" + WSConstants.TIMESTAMP_TOKEN_LN
480             );
481 
482         DateFormat zulu = new XmlSchemaDateFormat();
483         Element elementCreated =
484             doc.createElementNS(
485                 WSConstants.WSU_NS, WSConstants.WSU_PREFIX + ":" + WSConstants.EXPIRES_LN
486             );
487         Date createdDate = new Date();
488         long currentTime = createdDate.getTime() + 300000;
489         createdDate.setTime(currentTime);
490         elementCreated.appendChild(doc.createTextNode(zulu.format(createdDate)));
491         timestampElement.appendChild(elementCreated);
492         timestampElement.appendChild(elementCreated.cloneNode(true));
493 
494         secHeader.getSecurityHeader().appendChild(timestampElement);
495         
496         if (LOG.isDebugEnabled()) {
497             String outputString = 
498                 org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(doc);
499             LOG.debug(outputString);
500         }
501         //
502         // Do some processing
503         //
504         try {
505             verify(doc, WSSConfig.getNewInstance());
506             fail("The timestamp validation should have failed on multiple Expires elements");
507         } catch (WSSecurityException ex) {
508             // expected
509         }
510     }
511     
512     /**
513      * This is a test for processing an Timestamp where it contains an "Expires" element before
514      * the Created element. This Timestamp should be rejected as per the BSP spec.
515      */
516     @org.junit.Test
517     public void testExpiresInFrontOfCreated() throws Exception {
518         
519         Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
520         WSSecHeader secHeader = new WSSecHeader();
521         secHeader.insertSecurityHeader(doc);
522         
523         Element timestampElement = 
524             doc.createElementNS(
525                 WSConstants.WSU_NS, WSConstants.WSU_PREFIX + ":" + WSConstants.TIMESTAMP_TOKEN_LN
526             );
527 
528         DateFormat zulu = new XmlSchemaDateFormat();
529         Element elementCreated =
530             doc.createElementNS(
531                 WSConstants.WSU_NS, WSConstants.WSU_PREFIX + ":" + WSConstants.EXPIRES_LN
532             );
533         Date createdDate = new Date();
534         long currentTime = createdDate.getTime() + 300000;
535         createdDate.setTime(currentTime);
536         elementCreated.appendChild(doc.createTextNode(zulu.format(createdDate)));
537         timestampElement.appendChild(elementCreated);
538         
539         Element elementExpires =
540             doc.createElementNS(
541                 WSConstants.WSU_NS, WSConstants.WSU_PREFIX + ":" + WSConstants.CREATED_LN
542             );
543         elementExpires.appendChild(doc.createTextNode(zulu.format(createdDate)));
544         timestampElement.appendChild(elementExpires);
545 
546         secHeader.getSecurityHeader().appendChild(timestampElement);
547         
548         if (LOG.isDebugEnabled()) {
549             String outputString = 
550                 org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(doc);
551             LOG.debug(outputString);
552         }
553         //
554         // Do some processing
555         //
556         WSSConfig wssConfig = WSSConfig.getNewInstance();
557         wssConfig.setWsiBSPCompliant(true);
558         try {
559             verify(doc, wssConfig);
560             fail("The timestamp validation should have failed");
561         } catch (WSSecurityException ex) {
562             // expected
563         }
564     }
565     
566     
567     /**
568      * This is a test for processing an Timestamp where it contains a Created element with
569      * seconds > 60. This should be rejected as per the BSP spec.
570      */
571     @org.junit.Test
572     public void testCreatedSeconds() throws Exception {
573         
574         Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
575         WSSecHeader secHeader = new WSSecHeader();
576         secHeader.insertSecurityHeader(doc);
577         
578         Element timestampElement = 
579             doc.createElementNS(
580                 WSConstants.WSU_NS, WSConstants.WSU_PREFIX + ":" + WSConstants.TIMESTAMP_TOKEN_LN
581             );
582 
583         Element elementCreated =
584             doc.createElementNS(
585                 WSConstants.WSU_NS, WSConstants.WSU_PREFIX + ":" + WSConstants.CREATED_LN
586             );
587         elementCreated.appendChild(doc.createTextNode("2011-02-08T13:13:84.535Z"));
588         timestampElement.appendChild(elementCreated);
589 
590         secHeader.getSecurityHeader().appendChild(timestampElement);
591         
592         if (LOG.isDebugEnabled()) {
593             String outputString = 
594                 org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(doc);
595             LOG.debug(outputString);
596         }
597         //
598         // Do some processing - disable the validator to make sure that the Timestamp processor
599         // is rejecting the Timestamp
600         //
601         WSSConfig wssConfig = WSSConfig.getNewInstance();
602         wssConfig.setWsiBSPCompliant(true);
603         wssConfig.setValidator(WSSecurityEngine.TIMESTAMP, new NoOpValidator());
604         try {
605             verify(doc, wssConfig);
606             fail("The timestamp validation should have failed");
607         } catch (WSSecurityException ex) {
608             //assertTrue(ex.getMessage().contains("Unparseable date"));
609         }
610     }
611     
612     
613     /**
614      * This is a test for processing an Timestamp where it contains a Created element with
615      * a ValueType. This should be rejected as per the BSP spec.
616      */
617     @org.junit.Test
618     public void testCreatedValueType() throws Exception {
619         
620         Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
621         WSSecHeader secHeader = new WSSecHeader();
622         secHeader.insertSecurityHeader(doc);
623         
624         Element timestampElement = 
625             doc.createElementNS(
626                 WSConstants.WSU_NS, WSConstants.WSU_PREFIX + ":" + WSConstants.TIMESTAMP_TOKEN_LN
627             );
628 
629         DateFormat zulu = new XmlSchemaDateFormat();
630         Element elementCreated =
631             doc.createElementNS(
632                 WSConstants.WSU_NS, WSConstants.WSU_PREFIX + ":" + WSConstants.CREATED_LN
633             );
634         Date createdDate = new Date();
635         long currentTime = createdDate.getTime() + 300000;
636         createdDate.setTime(currentTime);
637         elementCreated.appendChild(doc.createTextNode(zulu.format(createdDate)));
638         elementCreated.setAttributeNS(null, "ValueType", WSConstants.WSS_SAML_KI_VALUE_TYPE);
639         timestampElement.appendChild(elementCreated);
640 
641         secHeader.getSecurityHeader().appendChild(timestampElement);
642         
643         if (LOG.isDebugEnabled()) {
644             String outputString = 
645                 org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(doc);
646             LOG.debug(outputString);
647         }
648         //
649         // Do some processing
650         //
651         WSSConfig wssConfig = WSSConfig.getNewInstance();
652         wssConfig.setWsiBSPCompliant(true);
653         wssConfig.setValidator(WSSecurityEngine.TIMESTAMP, new NoOpValidator());
654         try {
655             verify(doc, wssConfig);
656             fail("The timestamp validation should have failed");
657         } catch (WSSecurityException ex) {
658             //
659         }
660         
661         // Now it should pass...
662         wssConfig.setWsiBSPCompliant(false);
663         verify(doc, wssConfig);
664     }
665     
666 
667 
668     /**
669      * This is a test for processing an Timestamp where it contains a CustomElement. This should
670      * be rejected as per the BSP spec.
671      */
672     @org.junit.Test
673     public void testCustomElement() throws Exception {
674         
675         Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
676         WSSecHeader secHeader = new WSSecHeader();
677         secHeader.insertSecurityHeader(doc);
678         
679         Element timestampElement = 
680             doc.createElementNS(
681                 WSConstants.WSU_NS, WSConstants.WSU_PREFIX + ":" + WSConstants.TIMESTAMP_TOKEN_LN
682             );
683 
684         DateFormat zulu = new XmlSchemaDateFormat();
685         Element elementCreated =
686             doc.createElementNS(
687                 WSConstants.WSU_NS, WSConstants.WSU_PREFIX + ":" + WSConstants.EXPIRES_LN
688             );
689         Date createdDate = new Date();
690         long currentTime = createdDate.getTime() + 300000;
691         createdDate.setTime(currentTime);
692         elementCreated.appendChild(doc.createTextNode(zulu.format(createdDate)));
693         timestampElement.appendChild(elementCreated);
694         
695         Element elementCustom =
696             doc.createElementNS(
697                 WSConstants.WSU_NS, WSConstants.WSU_PREFIX + ":" + "Custom"
698             );
699         timestampElement.appendChild(elementCustom);
700 
701         secHeader.getSecurityHeader().appendChild(timestampElement);
702         
703         if (LOG.isDebugEnabled()) {
704             String outputString = 
705                 org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(doc);
706             LOG.debug(outputString);
707         }
708         //
709         // Do some processing
710         //
711         WSSConfig wssConfig = WSSConfig.getNewInstance();
712         wssConfig.setWsiBSPCompliant(true);
713         try {
714             verify(doc, wssConfig);
715             fail("The timestamp validation should have failed");
716         } catch (WSSecurityException ex) {
717             //
718         }
719         
720         // Now it should pass...
721         wssConfig.setWsiBSPCompliant(false);
722         verify(doc, wssConfig);
723     }
724     
725     /**
726      * Verifies the soap envelope
727      * 
728      * @param env soap envelope
729      * @param wssConfig
730      * @throws java.lang.Exception Thrown when there is a problem in verification
731      */
732     private List<WSSecurityEngineResult> verify(
733         Document doc, WSSConfig wssConfig
734     ) throws Exception {
735         WSSecurityEngine secEngine = new WSSecurityEngine();
736         secEngine.setWssConfig(wssConfig);
737         return secEngine.processSecurityHeader(doc, null, null, null);
738     }
739     
740     
741 }