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 2013/04/05 13:18:30 UTC

svn commit: r1464926 - in /webservices/wss4j/trunk: cxf-integration/ parent/ ws-security-dom/ ws-security-policy-stax/src/main/java/org/apache/wss4j/policy/stax/ ws-security-stax/ ws-security-stax/src/main/java/org/apache/wss4j/stax/ext/ ws-security-st...

Author: coheigea
Date: Fri Apr  5 11:18:29 2013
New Revision: 1464926

URL: http://svn.apache.org/r1464926
Log:
[WSS-348] - Switched StaX layer to use common ReplayCache functionaltiy

Modified:
    webservices/wss4j/trunk/cxf-integration/pom.xml
    webservices/wss4j/trunk/parent/pom.xml
    webservices/wss4j/trunk/ws-security-dom/pom.xml
    webservices/wss4j/trunk/ws-security-policy-stax/src/main/java/org/apache/wss4j/policy/stax/PolicyUtils.java
    webservices/wss4j/trunk/ws-security-stax/pom.xml
    webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/wss4j/stax/ext/WSSSecurityProperties.java
    webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/wss4j/stax/impl/processor/input/UsernameTokenInputHandler.java
    webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/wss4j/stax/impl/processor/input/WSSSignatureReferenceVerifyInputProcessor.java

Modified: webservices/wss4j/trunk/cxf-integration/pom.xml
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/cxf-integration/pom.xml?rev=1464926&r1=1464925&r2=1464926&view=diff
==============================================================================
--- webservices/wss4j/trunk/cxf-integration/pom.xml (original)
+++ webservices/wss4j/trunk/cxf-integration/pom.xml Fri Apr  5 11:18:29 2013
@@ -51,6 +51,12 @@
             <version>${cxf.version}</version>
             <scope>compile</scope>
         </dependency>
+        <dependency>
+            <groupId>commons-lang</groupId>
+            <artifactId>commons-lang</artifactId>
+            <version>2.6</version>
+            <scope>compile</scope>
+        </dependency>
 
         <dependency>
             <groupId>org.apache.santuario</groupId>

Modified: webservices/wss4j/trunk/parent/pom.xml
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/parent/pom.xml?rev=1464926&r1=1464925&r2=1464926&view=diff
==============================================================================
--- webservices/wss4j/trunk/parent/pom.xml (original)
+++ webservices/wss4j/trunk/parent/pom.xml Fri Apr  5 11:18:29 2013
@@ -45,7 +45,6 @@
         <xerces.version>2.9.1</xerces.version>
         <xmlsec.version>2.0.0-SNAPSHOT</xmlsec.version>
         <opensaml.version>2.5.3</opensaml.version>
-        <jcs.version>1.3</jcs.version>
         <testng.version>6.5.2</testng.version>
         <junit.version>4.8.2</junit.version>
         <xml.apis.version>1.3.04</xml.apis.version>
@@ -76,11 +75,6 @@
                 <version>${woodstox.core.asl.version}</version>
             </dependency>
             <dependency>
-                <groupId>jcs</groupId>
-                <artifactId>jcs</artifactId>
-                <version>${jcs.version}</version>
-            </dependency>
-            <dependency>
                 <groupId>org.opensaml</groupId>
                 <artifactId>opensaml</artifactId>
                 <version>${opensaml.version}</version>

Modified: webservices/wss4j/trunk/ws-security-dom/pom.xml
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-dom/pom.xml?rev=1464926&r1=1464925&r2=1464926&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-dom/pom.xml (original)
+++ webservices/wss4j/trunk/ws-security-dom/pom.xml Fri Apr  5 11:18:29 2013
@@ -209,7 +209,7 @@
                 </exclusion>
             </exclusions>
         </dependency>
-         <dependency>
+        <dependency>
             <groupId>net.sf.ehcache</groupId>
             <artifactId>ehcache-core</artifactId>
             <scope>runtime</scope>

Modified: webservices/wss4j/trunk/ws-security-policy-stax/src/main/java/org/apache/wss4j/policy/stax/PolicyUtils.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-policy-stax/src/main/java/org/apache/wss4j/policy/stax/PolicyUtils.java?rev=1464926&r1=1464925&r2=1464926&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-policy-stax/src/main/java/org/apache/wss4j/policy/stax/PolicyUtils.java (original)
+++ webservices/wss4j/trunk/ws-security-policy-stax/src/main/java/org/apache/wss4j/policy/stax/PolicyUtils.java Fri Apr  5 11:18:29 2013
@@ -18,7 +18,6 @@
  */
 package org.apache.wss4j.policy.stax;
 
-import org.apache.commons.lang.StringUtils;
 import org.apache.wss4j.policy.model.XPath;
 
 import javax.xml.namespace.QName;
@@ -32,7 +31,7 @@ public class PolicyUtils {
         String[] xPathElements = xPath.getXPath().split("/");
         for (int j = 0; j < xPathElements.length; j++) {
             String xPathElement = xPathElements[j];
-            if (StringUtils.isEmpty(xPathElement)) {
+            if (xPathElement == null || "".equals(xPathElement)) {
                 continue;
             }
             String[] elementParts = xPathElement.split(":");

Modified: webservices/wss4j/trunk/ws-security-stax/pom.xml
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-stax/pom.xml?rev=1464926&r1=1464925&r2=1464926&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-stax/pom.xml (original)
+++ webservices/wss4j/trunk/ws-security-stax/pom.xml Fri Apr  5 11:18:29 2013
@@ -64,73 +64,6 @@
             <scope>compile</scope>
         </dependency>
         <dependency>
-            <groupId>jcs</groupId>
-            <artifactId>jcs</artifactId>
-            <scope>compile</scope>
-            <exclusions>
-                <exclusion>
-                    <groupId>javax.sql</groupId>
-                    <artifactId>jdbc-stdext</artifactId>
-                </exclusion>
-                <exclusion>
-                    <groupId>commons-dbcp</groupId>
-                    <artifactId>commons-dbcp</artifactId>
-                </exclusion>
-                <exclusion>
-                    <groupId>commons-logging</groupId>
-                    <artifactId>commons-logging-api</artifactId>
-                </exclusion>
-                <exclusion>
-                    <groupId>commons-pool</groupId>
-                    <artifactId>commons-pool</artifactId>
-                </exclusion>
-                <exclusion>
-                    <groupId>mysql</groupId>
-                    <artifactId>mysql-connector-java</artifactId>
-                </exclusion>
-                <exclusion>
-                    <groupId>hsqldb</groupId>
-                    <artifactId>hsqldb</artifactId>
-                </exclusion>
-                <exclusion>
-                    <groupId>log4j</groupId>
-                    <artifactId>log4j</artifactId>
-                </exclusion>
-                <exclusion>
-                    <groupId>servletapi</groupId>
-                    <artifactId>servletapi</artifactId>
-                </exclusion>
-                <exclusion>
-                    <groupId>tomcat</groupId>
-                    <artifactId>tomcat-util</artifactId>
-                </exclusion>
-                <exclusion>
-                    <groupId>velocity</groupId>
-                    <artifactId>velocity</artifactId>
-                </exclusion>
-                <exclusion>
-                    <groupId>junit</groupId>
-                    <artifactId>junit</artifactId>
-                </exclusion>
-                <exclusion>
-                    <groupId>xmlrpc</groupId>
-                    <artifactId>xmlrpc</artifactId>
-                </exclusion>
-                <exclusion>
-                    <groupId>xerces</groupId>
-                    <artifactId>xerces</artifactId>
-                </exclusion>
-                <exclusion>
-                    <groupId>xml-apis</groupId>
-                    <artifactId>xml-apis</artifactId>
-                </exclusion>
-                <exclusion>
-                    <groupId>berkeleydb</groupId>
-                    <artifactId>berkeleydb</artifactId>
-                </exclusion>
-            </exclusions>
-        </dependency>
-        <dependency>
             <groupId>org.apache.santuario</groupId>
             <artifactId>xmlsec</artifactId>
             <scope>compile</scope>
@@ -207,6 +140,11 @@
             </exclusions>
         </dependency>
         <dependency>
+            <groupId>net.sf.ehcache</groupId>
+            <artifactId>ehcache-core</artifactId>
+            <scope>runtime</scope>
+        </dependency>
+        <dependency>
             <groupId>org.apache.wss4j</groupId>
             <artifactId>wss4j-ws-security-dom</artifactId>
             <version>${project.version}</version>

Modified: webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/wss4j/stax/ext/WSSSecurityProperties.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/wss4j/stax/ext/WSSSecurityProperties.java?rev=1464926&r1=1464925&r2=1464926&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/wss4j/stax/ext/WSSSecurityProperties.java (original)
+++ webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/wss4j/stax/ext/WSSSecurityProperties.java Fri Apr  5 11:18:29 2013
@@ -35,11 +35,15 @@ import javax.security.auth.callback.Call
 import javax.xml.namespace.QName;
 
 import org.apache.wss4j.common.bsp.BSPRule;
+import org.apache.wss4j.common.cache.ReplayCache;
+import org.apache.wss4j.common.cache.ReplayCacheFactory;
 import org.apache.wss4j.common.crypto.Crypto;
 import org.apache.wss4j.common.crypto.Merlin;
+import org.apache.wss4j.common.ext.WSSecurityException;
 import org.apache.wss4j.stax.securityToken.WSSecurityTokenConstants;
 import org.apache.wss4j.stax.validate.Validator;
 import org.apache.xml.security.stax.ext.XMLSecurityProperties;
+import org.apache.xml.security.utils.Base64;
 
 /**
  * Main configuration class to supply keys etc.
@@ -86,6 +90,8 @@ public class WSSSecurityProperties exten
     private boolean useReqSigCertForEncryption = false;
     private String encryptionCompressionAlgorithm;
     private boolean enableRevocation = false;
+    private ReplayCache timestampReplayCache;
+    private ReplayCache nonceReplayCache;
 
     public WSSSecurityProperties() {
         super();
@@ -122,6 +128,8 @@ public class WSSSecurityProperties exten
         this.useReqSigCertForEncryption = wssSecurityProperties.useReqSigCertForEncryption;
         this.encryptionCompressionAlgorithm = wssSecurityProperties.encryptionCompressionAlgorithm;
         this.enableRevocation = wssSecurityProperties.enableRevocation;
+        this.timestampReplayCache = wssSecurityProperties.timestampReplayCache;
+        this.nonceReplayCache = wssSecurityProperties.nonceReplayCache;
     }
 
     /**
@@ -627,4 +635,51 @@ public class WSSSecurityProperties exten
     public void setUtFutureTTL(Integer utFutureTTL) {
         this.utFutureTTL = utFutureTTL;
     }
+    
+    /**
+     * Set the replay cache for Timestamps
+     */
+    public void setTimestampReplayCache(ReplayCache newCache) {
+        timestampReplayCache = newCache;
+    }
+
+    /**
+     * Get the replay cache for Timestamps
+     * @throws WSSecurityException 
+     */
+    public ReplayCache getTimestampReplayCache() throws WSSecurityException {
+        if (timestampReplayCache == null) {
+            timestampReplayCache = createCache("wss4j-timestamp-cache-");
+        }
+        
+        return timestampReplayCache;
+    }
+    
+    private synchronized ReplayCache createCache(String key) throws WSSecurityException {
+        ReplayCacheFactory replayCacheFactory = ReplayCacheFactory.newInstance();
+        byte[] nonceValue = new byte[10];
+        WSSConstants.secureRandom.nextBytes(nonceValue);
+        String cacheKey = key + Base64.encode(nonceValue);
+        return replayCacheFactory.newReplayCache(cacheKey, null);
+    }
+    
+    /**
+     * Set the replay cache for Nonces
+     */
+    public void setNonceReplayCache(ReplayCache newCache) {
+        nonceReplayCache = newCache;
+    }
+
+    /**
+     * Get the replay cache for Nonces
+     * @throws WSSecurityException 
+     */
+    public ReplayCache getNonceReplayCache() throws WSSecurityException {
+        if (nonceReplayCache == null) {
+            nonceReplayCache = createCache("wss4j-nonce-cache-");
+        }
+        
+        return nonceReplayCache;
+    }
+    
 }

Modified: webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/wss4j/stax/impl/processor/input/UsernameTokenInputHandler.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/wss4j/stax/impl/processor/input/UsernameTokenInputHandler.java?rev=1464926&r1=1464925&r2=1464926&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/wss4j/stax/impl/processor/input/UsernameTokenInputHandler.java (original)
+++ webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/wss4j/stax/impl/processor/input/UsernameTokenInputHandler.java Fri Apr  5 11:18:29 2013
@@ -18,14 +18,12 @@
  */
 package org.apache.wss4j.stax.impl.processor.input;
 
-import org.apache.jcs.JCS;
-import org.apache.jcs.access.exception.CacheException;
-import org.apache.jcs.engine.ElementAttributes;
 import org.apache.wss4j.binding.wss10.EncodedString;
 import org.apache.wss4j.binding.wss10.PasswordString;
 import org.apache.wss4j.binding.wss10.UsernameTokenType;
 import org.apache.wss4j.binding.wsu10.AttributedDateTime;
 import org.apache.wss4j.common.bsp.BSPRule;
+import org.apache.wss4j.common.cache.ReplayCache;
 import org.apache.wss4j.common.ext.WSSecurityException;
 import org.apache.wss4j.common.util.DateUtil;
 import org.apache.wss4j.stax.ext.WSInboundSecurityContext;
@@ -58,17 +56,6 @@ import java.util.List;
  */
 public class UsernameTokenInputHandler extends AbstractInputSecurityHeaderHandler {
 
-    private static final String cacheRegionName = "usernameToken";
-    private static final JCS cache;
-
-    static {
-        try {
-            cache = JCS.getInstance(cacheRegionName);
-        } catch (CacheException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
     @Override
     public void handle(final InputProcessorChain inputProcessorChain, final XMLSecurityProperties securityProperties,
                        Deque<XMLSecEvent> eventQueue, Integer index) throws XMLSecurityException {
@@ -84,35 +71,35 @@ public class UsernameTokenInputHandler e
         if (usernameTokenType.getId() == null) {
             usernameTokenType.setId(IDGenerator.generateID(null));
         }
+        
+        // Verify Created
+        final WSSSecurityProperties wssSecurityProperties = (WSSSecurityProperties) securityProperties;
+        Date createdDate = verifyCreated(wssSecurityProperties, usernameTokenType);
 
+        ReplayCache replayCache = wssSecurityProperties.getNonceReplayCache();
         final EncodedString encodedNonce =
                 XMLSecurityUtils.getQNameType(usernameTokenType.getAny(), WSSConstants.TAG_wsse_Nonce);
-        if (encodedNonce != null) {
+        if (encodedNonce != null && replayCache != null) {
+            // Check for replay attacks
             String nonce = encodedNonce.getValue();
-            /*
-                It is RECOMMENDED that used nonces be cached for a period at least as long as
-                the timestamp freshness limitation period, above, and that UsernameToken with
-                nonces that have already been used (and are thus in the cache) be rejected
-            */
-            if (cache.get(nonce) != null) {
+            if (replayCache.contains(nonce)) {
                 throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_AUTHENTICATION);
             }
-            ElementAttributes elementAttributes = new ElementAttributes();
-            elementAttributes.setMaxLifeSeconds(300);
-            try {
-                cache.put(nonce, nonce, elementAttributes);
-            } catch (CacheException e) {
-                throw new WSSecurityException(WSSecurityException.ErrorCode.INVALID_SECURITY, e);
+            
+            // If no Created, then just cache for the default time
+            // Otherwise, cache for the configured TTL of the UsernameToken Created time, as any
+            // older token will just get rejected anyway
+            int utTTL = wssSecurityProperties.getUtTTL();
+            if (createdDate == null || utTTL <= 0) {
+                replayCache.add(nonce);
+            } else {
+                replayCache.add(nonce, utTTL + 1L);
             }
         }
 
         final WSInboundSecurityContext wsInboundSecurityContext = (WSInboundSecurityContext) inputProcessorChain.getSecurityContext();
-        final WSSSecurityProperties wssSecurityProperties = (WSSSecurityProperties) securityProperties;
         final List<QName> elementPath = getElementPath(eventQueue);
         
-        // Verify Created
-        verifyCreated(wssSecurityProperties, usernameTokenType);
-        
         final TokenContext tokenContext = new TokenContext(wssSecurityProperties, wsInboundSecurityContext, xmlSecEvents, elementPath);
 
         UsernameTokenValidator usernameTokenValidator =
@@ -206,7 +193,7 @@ public class UsernameTokenInputHandler e
 
     }
     
-    private void verifyCreated(
+    private Date verifyCreated(
         WSSSecurityProperties wssSecurityProperties,
         UsernameTokenType usernameTokenType
     ) throws WSSecurityException {
@@ -231,6 +218,8 @@ public class UsernameTokenInputHandler e
             if (!DateUtil.verifyCreated(createdDate, ttl, futureTTL)) {
                 throw new WSSecurityException(WSSecurityException.ErrorCode.MESSAGE_EXPIRED);
             }
+            return createdDate;
         }
+        return null;
     }
 }

Modified: webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/wss4j/stax/impl/processor/input/WSSSignatureReferenceVerifyInputProcessor.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/wss4j/stax/impl/processor/input/WSSSignatureReferenceVerifyInputProcessor.java?rev=1464926&r1=1464925&r2=1464926&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/wss4j/stax/impl/processor/input/WSSSignatureReferenceVerifyInputProcessor.java (original)
+++ webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/wss4j/stax/impl/processor/input/WSSSignatureReferenceVerifyInputProcessor.java Fri Apr  5 11:18:29 2013
@@ -18,11 +18,9 @@
  */
 package org.apache.wss4j.stax.impl.processor.input;
 
-import org.apache.jcs.JCS;
-import org.apache.jcs.access.exception.CacheException;
-import org.apache.jcs.engine.ElementAttributes;
 import org.apache.wss4j.binding.wss10.TransformationParametersType;
 import org.apache.wss4j.common.bsp.BSPRule;
+import org.apache.wss4j.common.cache.ReplayCache;
 import org.apache.wss4j.common.ext.WSSecurityException;
 import org.apache.wss4j.stax.securityToken.SecurityTokenReference;
 import org.apache.xml.security.binding.excc14n.InclusiveNamespaces;
@@ -48,22 +46,13 @@ import javax.xml.namespace.QName;
 import javax.xml.stream.XMLStreamException;
 import java.io.OutputStream;
 import java.util.Arrays;
+import java.util.Calendar;
+import java.util.Date;
 import java.util.Iterator;
 import java.util.List;
 
 public class WSSSignatureReferenceVerifyInputProcessor extends AbstractSignatureReferenceVerifyInputProcessor {
 
-    private static final String cacheRegionName = "timestamp";
-    private static final JCS cache;
-
-    static {
-        try {
-            cache = JCS.getInstance(cacheRegionName);
-        } catch (CacheException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
     private boolean replayChecked = false;
 
     public WSSSignatureReferenceVerifyInputProcessor(InputProcessorChain inputProcessorChain,
@@ -179,24 +168,25 @@ public class WSSSignatureReferenceVerify
     private void detectReplayAttack(InputProcessorChain inputProcessorChain) throws WSSecurityException {
         TimestampSecurityEvent timestampSecurityEvent =
                 inputProcessorChain.getSecurityContext().get(WSSConstants.PROP_TIMESTAMP_SECURITYEVENT);
-        if (timestampSecurityEvent != null) {
+        ReplayCache replayCache = 
+            ((WSSSecurityProperties)getSecurityProperties()).getTimestampReplayCache();
+        if (timestampSecurityEvent != null && replayCache != null) {
             final String cacheKey = String.valueOf(
                     timestampSecurityEvent.getCreated().getTimeInMillis()) +
                     "" + Arrays.hashCode(getSignatureType().getSignatureValue().getValue());
-            if (cache.get(cacheKey) != null) {
+            if (replayCache.contains(cacheKey)) {
                 throw new WSSecurityException(WSSecurityException.ErrorCode.MESSAGE_EXPIRED);
             }
-            ElementAttributes elementAttributes = new ElementAttributes();
-            if (timestampSecurityEvent.getExpires() != null) {
-                long lifeTime = timestampSecurityEvent.getExpires().getTimeInMillis() - System.currentTimeMillis();
-                elementAttributes.setMaxLifeSeconds(lifeTime / 1000);
+            
+            // Store the Timestamp/SignatureValue combination in the cache
+            Calendar expiresCal = timestampSecurityEvent.getExpires();
+            if (expiresCal != null) {
+                Date rightNow = new Date();
+                long currentTime = rightNow.getTime();
+                long expiresTime = expiresCal.getTimeInMillis();
+                replayCache.add(cacheKey, ((expiresTime - currentTime) / 1000L));
             } else {
-                elementAttributes.setMaxLifeSeconds(300);
-            }
-            try {
-                cache.put(cacheKey, timestampSecurityEvent.getCreated(), elementAttributes);
-            } catch (CacheException e) {
-                throw new WSSecurityException(WSSecurityException.ErrorCode.INVALID_SECURITY, e);
+                replayCache.add(cacheKey);
             }
         }
     }