You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ws.apache.org by co...@apache.org on 2011/03/14 14:09:04 UTC

svn commit: r1081361 - in /webservices/wss4j/trunk/src: main/java/org/apache/ws/security/ main/java/org/apache/ws/security/handler/ main/java/org/apache/ws/security/message/token/ main/java/org/apache/ws/security/validate/ test/java/org/apache/ws/secur...

Author: coheigea
Date: Mon Mar 14 13:09:03 2011
New Revision: 1081361

URL: http://svn.apache.org/viewvc?rev=1081361&view=rev
Log:
[WSS-274] - Add support for future-dated Timestamps.

Modified:
    webservices/wss4j/trunk/src/main/java/org/apache/ws/security/WSSConfig.java
    webservices/wss4j/trunk/src/main/java/org/apache/ws/security/handler/WSHandler.java
    webservices/wss4j/trunk/src/main/java/org/apache/ws/security/handler/WSHandlerConstants.java
    webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/token/Timestamp.java
    webservices/wss4j/trunk/src/main/java/org/apache/ws/security/validate/TimestampValidator.java
    webservices/wss4j/trunk/src/test/java/org/apache/ws/security/message/TimestampTest.java

Modified: webservices/wss4j/trunk/src/main/java/org/apache/ws/security/WSSConfig.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/main/java/org/apache/ws/security/WSSConfig.java?rev=1081361&r1=1081360&r2=1081361&view=diff
==============================================================================
--- webservices/wss4j/trunk/src/main/java/org/apache/ws/security/WSSConfig.java (original)
+++ webservices/wss4j/trunk/src/main/java/org/apache/ws/security/WSSConfig.java Mon Mar 14 13:09:03 2011
@@ -236,6 +236,13 @@ public class WSSConfig {
     protected int timeStampTTL = 300;
     
     /**
+     * The time in seconds in the future within which the Created time of an incoming 
+     * Timestamp is valid. The default is 0 seconds, meaning that no future-dated
+     * timestamps are allowed.
+     */
+    protected int timeStampFutureTTL = 0;
+    
+    /**
      * This variable controls whether types other than PasswordDigest or PasswordText
      * are allowed when processing UsernameTokens. 
      * 
@@ -501,6 +508,20 @@ public class WSSConfig {
     }
     
     /**
+     * @return Returns the Future TTL of a Timestamp in seconds
+     */
+    public int getTimeStampFutureTTL() {
+        return timeStampFutureTTL;
+    }
+
+    /**
+     * @param timeStampFutureTTL he new value for timeStampFutureTTL
+     */
+    public void setTimeStampFutureTTL(int timeStampFutureTTL) {
+        this.timeStampFutureTTL = timeStampFutureTTL;
+    }
+    
+    /**
      * Set the secret key length to be used for UT_SIGN.
      */
     public void setSecretKeyLength(int length) {

Modified: webservices/wss4j/trunk/src/main/java/org/apache/ws/security/handler/WSHandler.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/main/java/org/apache/ws/security/handler/WSHandler.java?rev=1081361&r1=1081360&r2=1081361&view=diff
==============================================================================
--- webservices/wss4j/trunk/src/main/java/org/apache/ws/security/handler/WSHandler.java (original)
+++ webservices/wss4j/trunk/src/main/java/org/apache/ws/security/handler/WSHandler.java Mon Mar 14 13:09:03 2011
@@ -33,7 +33,6 @@ import org.apache.ws.security.components
 import org.apache.ws.security.components.crypto.CryptoFactory;
 import org.apache.ws.security.message.WSSecHeader;
 import org.apache.ws.security.message.token.SignatureConfirmation;
-import org.apache.ws.security.message.token.Timestamp;
 import org.apache.ws.security.util.Loader;
 import org.apache.ws.security.util.StringUtil;
 import org.apache.ws.security.util.WSSecurityUtil;
@@ -256,6 +255,7 @@ public abstract class WSHandler {
             wssConfig.setRequiredPasswordType(passwordType);
         }
         wssConfig.setTimeStampTTL(decodeTimeToLive(reqData));
+        wssConfig.setTimeStampFutureTTL(decodeFutureTimeToLive(reqData));
         wssConfig.setHandleCustomPasswordTypes(decodeCustomPasswordTypes(reqData));
         wssConfig.setPasswordsAreEncoded(decodeUseEncodedPasswords(reqData));
         wssConfig.setAllowNamespaceQualifiedPasswordTypes(
@@ -671,18 +671,35 @@ public abstract class WSHandler {
     public int decodeTimeToLive(RequestData reqData) {
         String ttl = 
             getString(WSHandlerConstants.TTL_TIMESTAMP, reqData.getMsgContext());
-        int ttl_i = 0;
+        int ttlI = 0;
         if (ttl != null) {
             try {
-                ttl_i = Integer.parseInt(ttl);
+                ttlI = Integer.parseInt(ttl);
             } catch (NumberFormatException e) {
-                ttl_i = reqData.getTimeToLive();
+                ttlI = reqData.getTimeToLive();
             }
         }
-        if (ttl_i <= 0) {
-            ttl_i = reqData.getTimeToLive();
+        if (ttlI <= 0) {
+            ttlI = reqData.getTimeToLive();
         }
-        return ttl_i;
+        return ttlI;
+    }
+    
+    protected int decodeFutureTimeToLive(RequestData reqData) {
+        String ttl = 
+            getString(WSHandlerConstants.TTL_FUTURE_TIMESTAMP, reqData.getMsgContext());
+        if (ttl != null) {
+            try {
+                int ttlI = Integer.parseInt(ttl);
+                if (ttlI < 0) {
+                    return 0;
+                }
+                return ttlI;
+            } catch (NumberFormatException e) {
+                return 0;
+            }
+        }
+        return 0;
     }
     
     protected boolean decodeBSPCompliance(RequestData reqData)
@@ -1096,29 +1113,6 @@ public abstract class WSHandler {
     }
 
     /**
-     * Evaluate whether a timestamp is considered valid on the receivers' side. Hook to
-     * allow subclasses to implement custom validation methods however they see fit.
-     * 
-     * Policy used in this implementation:
-     * 
-     * 1. The receiver can set its own time to live (besides from that set on
-     * sender side)
-     * 
-     * 2. If the message was created before (now-ttl) the message is rejected
-     * 
-     * @param timestamp
-     *            the timestamp that is validated
-     * @param timeToLive
-     *            the limit on the receivers' side, that the timestamp is validated against
-     * @return true if the timestamp is before (now-timeToLive), false otherwise
-     * @deprecated TTL validation is now done by default in the TimestampProcessor
-     * @throws WSSecurityException
-     */
-    protected boolean verifyTimestamp(Timestamp timestamp, int timeToLive) throws WSSecurityException {
-        return timestamp.verifyCreated(timeToLive);
-    }
-
-    /**
      * Looks up key first via {@link #getOption(String)} and if not found
      * there, via {@link #getProperty(Object, String)}
      *

Modified: webservices/wss4j/trunk/src/main/java/org/apache/ws/security/handler/WSHandlerConstants.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/main/java/org/apache/ws/security/handler/WSHandlerConstants.java?rev=1081361&r1=1081360&r2=1081361&view=diff
==============================================================================
--- webservices/wss4j/trunk/src/main/java/org/apache/ws/security/handler/WSHandlerConstants.java (original)
+++ webservices/wss4j/trunk/src/main/java/org/apache/ws/security/handler/WSHandlerConstants.java Mon Mar 14 13:09:03 2011
@@ -814,6 +814,16 @@ public class WSHandlerConstants {
      * 300 seconds (5 minutes).
      */
     public static final String TTL_TIMESTAMP = "timeToLive";
+    
+    /**
+     * This configuration tag specifies the time in seconds in the future within which
+     * the Created time of an incoming Timestamp is valid. WSS4J rejects by default any
+     * timestamp which is "Created" in the future, and so there could potentially be
+     * problems in a scenario where a client's clock is slightly askew. The default
+     * value for this parameter is "0", meaning that no future-created Timestamps are
+     * allowed.
+     */
+    public static final String TTL_FUTURE_TIMESTAMP = "futureTimeToLive";
 
     /*
      * internally used property names to store values inside the message context

Modified: webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/token/Timestamp.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/token/Timestamp.java?rev=1081361&r1=1081360&r2=1081361&view=diff
==============================================================================
--- webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/token/Timestamp.java (original)
+++ webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/token/Timestamp.java Mon Mar 14 13:09:03 2011
@@ -306,14 +306,20 @@ public class Timestamp {
      * Return true if the "Created" value is before the current time minus the timeToLive
      * argument, and if the Created value is not "in the future".
      * 
-     * @param timeToLive
-     *            the limit on the receivers' side, that the timestamp is validated against
+     * @param timeToLive the value in seconds for the validity of the Created time
+     * @param futureTimeToLive the value in seconds for the future validity of the Created time
      * @return true if the timestamp is before (now-timeToLive), false otherwise
+     * @param futureTimeToLive
      */
     public boolean verifyCreated(
-        int timeToLive
+        int timeToLive,
+        int futureTimeToLive
     ) {
         Date validCreation = new Date();
+        long currentTime = validCreation.getTime();
+        if (futureTimeToLive > 0) {
+            validCreation.setTime(currentTime + futureTimeToLive * 1000);
+        }
         // Check to see if the created time is in the future
         if (createdDate != null && createdDate.after(validCreation)) {
             if (LOG.isDebugEnabled()) {
@@ -323,7 +329,7 @@ public class Timestamp {
         }
         
         // Calculate the time that is allowed for the message to travel
-        long currentTime = validCreation.getTime() - timeToLive * 1000;
+        currentTime -= timeToLive * 1000;
         validCreation.setTime(currentTime);
 
         // Validate the time it took the message to travel

Modified: webservices/wss4j/trunk/src/main/java/org/apache/ws/security/validate/TimestampValidator.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/main/java/org/apache/ws/security/validate/TimestampValidator.java?rev=1081361&r1=1081360&r2=1081361&view=diff
==============================================================================
--- webservices/wss4j/trunk/src/main/java/org/apache/ws/security/validate/TimestampValidator.java (original)
+++ webservices/wss4j/trunk/src/main/java/org/apache/ws/security/validate/TimestampValidator.java Mon Mar 14 13:09:03 2011
@@ -48,15 +48,17 @@ public class TimestampValidator implemen
         WSSConfig wssConfig = data.getWssConfig();
         boolean timeStampStrict = true;
         int timeStampTTL = 300;
+        int futureTimeToLive = 0;
         if (wssConfig != null) {
             timeStampStrict = wssConfig.isTimeStampStrict();
             timeStampTTL = wssConfig.getTimeStampTTL();
+            futureTimeToLive = wssConfig.getTimeStampFutureTTL();
         }
         
         Timestamp timeStamp = credential.getTimestamp();
         // Validate whether the security semantics have expired
         if ((timeStampStrict && timeStamp.isExpired()) 
-            || !timeStamp.verifyCreated(timeStampTTL)) {
+            || !timeStamp.verifyCreated(timeStampTTL, futureTimeToLive)) {
             throw new WSSecurityException(
                 WSSecurityException.MESSAGE_EXPIRED,
                 "invalidTimestamp",

Modified: webservices/wss4j/trunk/src/test/java/org/apache/ws/security/message/TimestampTest.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/test/java/org/apache/ws/security/message/TimestampTest.java?rev=1081361&r1=1081360&r2=1081361&view=diff
==============================================================================
--- webservices/wss4j/trunk/src/test/java/org/apache/ws/security/message/TimestampTest.java (original)
+++ webservices/wss4j/trunk/src/test/java/org/apache/ws/security/message/TimestampTest.java Mon Mar 14 13:09:03 2011
@@ -177,7 +177,8 @@ public class TimestampTest extends org.j
     
     /**
      * This is a test for processing an Timestamp where the "Created" element is in the future.
-     * This Timestamp should be rejected.
+     * This Timestamp should be rejected by default, and then accepted once the future 
+     * time-to-live configuration is enabled.
      */
     @org.junit.Test
     public void testFutureCreated() throws Exception {
@@ -197,7 +198,7 @@ public class TimestampTest extends org.j
                 WSConstants.WSU_NS, WSConstants.WSU_PREFIX + ":" + WSConstants.CREATED_LN
             );
         Date createdDate = new Date();
-        long currentTime = createdDate.getTime() + 300000;
+        long currentTime = createdDate.getTime() + 30000;
         createdDate.setTime(currentTime);
         elementCreated.appendChild(doc.createTextNode(zulu.format(createdDate)));
         timestampElement.appendChild(elementCreated);
@@ -212,12 +213,15 @@ public class TimestampTest extends org.j
         //
         // Do some processing
         //
+        WSSConfig config = WSSConfig.getNewInstance();
         try {
-            verify(doc, WSSConfig.getNewInstance());
+            verify(doc, config);
             fail("The timestamp validation should have failed");
         } catch (WSSecurityException ex) {
             assertTrue(ex.getErrorCode() == WSSecurityException.MESSAGE_EXPIRED); 
         }
+        config.setTimeStampFutureTTL(60);
+        verify(doc, config);
     }