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/06/07 17:41:54 UTC
svn commit: r1490690 - in /webservices/wss4j/trunk:
ws-security-common/src/main/java/org/apache/wss4j/common/util/
ws-security-dom/src/main/java/org/apache/wss4j/dom/
ws-security-dom/src/main/java/org/apache/wss4j/dom/message/
ws-security-dom/src/main/...
Author: coheigea
Date: Fri Jun 7 15:41:53 2013
New Revision: 1490690
URL: http://svn.apache.org/r1490690
Log:
[WSS-441] - Allow the date/time in the security headers to be spoofed
Added:
webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/wss4j/common/util/WSCurrentTimeSource.java
webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/wss4j/common/util/WSTimeSource.java
Modified:
webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/WSSConfig.java
webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/message/WSSecTimestamp.java
webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/message/WSSecUsernameToken.java
webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/message/token/Timestamp.java
webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/message/token/UsernameToken.java
webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/wss4j/dom/message/TimestampTest.java
webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/wss4j/dom/message/UsernameTokenTest.java
Added: webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/wss4j/common/util/WSCurrentTimeSource.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/wss4j/common/util/WSCurrentTimeSource.java?rev=1490690&view=auto
==============================================================================
--- webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/wss4j/common/util/WSCurrentTimeSource.java (added)
+++ webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/wss4j/common/util/WSCurrentTimeSource.java Fri Jun 7 15:41:53 2013
@@ -0,0 +1,34 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.wss4j.common.util;
+
+import java.util.Date;
+
+public class WSCurrentTimeSource implements WSTimeSource {
+
+ /**
+ * Get the current date time
+ * @return the current date/time as a date object
+ */
+ public Date now() {
+ return new Date();
+ }
+
+}
\ No newline at end of file
Added: webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/wss4j/common/util/WSTimeSource.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/wss4j/common/util/WSTimeSource.java?rev=1490690&view=auto
==============================================================================
--- webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/wss4j/common/util/WSTimeSource.java (added)
+++ webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/wss4j/common/util/WSTimeSource.java Fri Jun 7 15:41:53 2013
@@ -0,0 +1,37 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.wss4j.common.util;
+
+import java.util.Date;
+
+/**
+ * This interface allows the Time Source used to set dates and times to be
+ * overridden by the application.
+ *
+ */
+public interface WSTimeSource {
+
+ /**
+ * Get the current date time
+ * @return the current date/time as a date object
+ */
+ public Date now();
+
+}
\ No newline at end of file
Modified: webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/WSSConfig.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/WSSConfig.java?rev=1490690&r1=1490689&r2=1490690&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/WSSConfig.java (original)
+++ webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/WSSConfig.java Fri Jun 7 15:41:53 2013
@@ -32,6 +32,8 @@ import javax.xml.namespace.QName;
import org.apache.wss4j.dom.action.Action;
import org.apache.wss4j.common.crypto.WSProviderConfig;
import org.apache.wss4j.common.ext.WSSecurityException;
+import org.apache.wss4j.common.util.WSCurrentTimeSource;
+import org.apache.wss4j.common.util.WSTimeSource;
import org.apache.wss4j.dom.processor.Processor;
import org.apache.wss4j.dom.validate.Validator;
import org.apache.xml.security.stax.impl.util.IDGenerator;
@@ -312,6 +314,11 @@ public class WSSConfig {
private boolean validateSamlSubjectConfirmation = true;
/**
+ * This allows the user to specify a different time than that of the current System time.
+ */
+ private WSTimeSource currentTime;
+
+ /**
* The default wsu:Id allocator is a simple "start at 1 and increment up"
* thing that is very fast.
*/
@@ -764,4 +771,14 @@ public class WSSConfig {
this.validateSamlSubjectConfirmation = validateSamlSubjectConfirmation;
}
+ public WSTimeSource getCurrentTime() {
+ if (currentTime != null) {
+ return currentTime;
+ }
+ return new WSCurrentTimeSource();
+ }
+
+ public void setCurrentTime(WSTimeSource currentTime) {
+ this.currentTime = currentTime;
+ }
}
Modified: webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/message/WSSecTimestamp.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/message/WSSecTimestamp.java?rev=1490690&r1=1490689&r2=1490690&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/message/WSSecTimestamp.java (original)
+++ webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/message/WSSecTimestamp.java Fri Jun 7 15:41:53 2013
@@ -68,7 +68,8 @@ public class WSSecTimestamp extends WSSe
* @param doc The SOAP envelope as W3C document
*/
public void prepare(Document doc) {
- ts = new Timestamp(getWsConfig().isPrecisionInMilliSeconds(), doc, timeToLive);
+ ts = new Timestamp(getWsConfig().isPrecisionInMilliSeconds(), doc,
+ getWsConfig().getCurrentTime(), timeToLive);
String tsId = getWsConfig().getIdAllocator().createId("TS-", ts);
ts.setID(tsId);
}
Modified: webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/message/WSSecUsernameToken.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/message/WSSecUsernameToken.java?rev=1490690&r1=1490689&r2=1490690&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/message/WSSecUsernameToken.java (original)
+++ webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/message/WSSecUsernameToken.java Fri Jun 7 15:41:53 2013
@@ -169,7 +169,8 @@ public class WSSecUsernameToken extends
* @param doc The SOAP envelope as W3C document
*/
public void prepare(Document doc) {
- ut = new UsernameToken(getWsConfig().isPrecisionInMilliSeconds(), doc, passwordType);
+ ut = new UsernameToken(getWsConfig().isPrecisionInMilliSeconds(), doc,
+ getWsConfig().getCurrentTime(), passwordType);
ut.setPasswordsAreEncoded(passwordsAreEncoded);
ut.setName(user);
if (useDerivedKey) {
@@ -182,7 +183,7 @@ public class WSSecUsernameToken extends
ut.addNonce(doc);
}
if (created) {
- ut.addCreated(getWsConfig().isPrecisionInMilliSeconds(), doc);
+ ut.addCreated(getWsConfig().isPrecisionInMilliSeconds(), getWsConfig().getCurrentTime(), doc);
}
ut.setID(getWsConfig().getIdAllocator().createId("UsernameToken-", ut));
}
Modified: webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/message/token/Timestamp.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/message/token/Timestamp.java?rev=1490690&r1=1490689&r2=1490690&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/message/token/Timestamp.java (original)
+++ webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/message/token/Timestamp.java Fri Jun 7 15:41:53 2013
@@ -33,6 +33,8 @@ import org.apache.wss4j.common.bsp.BSPRu
import org.apache.wss4j.common.ext.WSSecurityException;
import org.apache.wss4j.common.util.DOM2Writer;
import org.apache.wss4j.common.util.DateUtil;
+import org.apache.wss4j.common.util.WSCurrentTimeSource;
+import org.apache.wss4j.common.util.WSTimeSource;
import org.apache.wss4j.dom.WSConstants;
import org.apache.wss4j.dom.WSSConfig;
import org.apache.wss4j.dom.bsp.BSPEnforcer;
@@ -171,6 +173,17 @@ public class Timestamp {
* @param ttl the time to live (validity of the security semantics) in seconds
*/
public Timestamp(boolean milliseconds, Document doc, int ttl) {
+ this(milliseconds, doc, new WSCurrentTimeSource(), ttl);
+ }
+
+ /**
+ * Constructs a <code>Timestamp</code> object according
+ * to the defined parameters.
+ *
+ * @param doc the SOAP envelope as <code>Document</code>
+ * @param ttl the time to live (validity of the security semantics) in seconds
+ */
+ public Timestamp(boolean milliseconds, Document doc, WSTimeSource timeSource, int ttl) {
customElements = new ArrayList<Element>();
element =
@@ -189,11 +202,11 @@ public class Timestamp {
doc.createElementNS(
WSConstants.WSU_NS, WSConstants.WSU_PREFIX + ":" + WSConstants.CREATED_LN
);
- createdDate = new Date();
+ createdDate = timeSource.now();
elementCreated.appendChild(doc.createTextNode(zulu.format(createdDate)));
element.appendChild(elementCreated);
if (ttl != 0) {
- expiresDate = new Date();
+ expiresDate = timeSource.now();
expiresDate.setTime(createdDate.getTime() + ((long)ttl * 1000L));
Element elementExpires =
Modified: webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/message/token/UsernameToken.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/message/token/UsernameToken.java?rev=1490690&r1=1490689&r2=1490690&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/message/token/UsernameToken.java (original)
+++ webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/message/token/UsernameToken.java Fri Jun 7 15:41:53 2013
@@ -40,6 +40,8 @@ import org.apache.wss4j.common.principal
import org.apache.wss4j.common.util.DOM2Writer;
import org.apache.wss4j.common.util.DateUtil;
import org.apache.wss4j.common.util.UsernameTokenUtil;
+import org.apache.wss4j.common.util.WSCurrentTimeSource;
+import org.apache.wss4j.common.util.WSTimeSource;
import org.apache.wss4j.dom.WSConstants;
import org.apache.wss4j.dom.WSSConfig;
import org.apache.wss4j.dom.bsp.BSPEnforcer;
@@ -249,6 +251,10 @@ public class UsernameToken {
* password required
*/
public UsernameToken(boolean milliseconds, Document doc, String pwType) {
+ this(milliseconds, doc, new WSCurrentTimeSource(), pwType);
+ }
+
+ public UsernameToken(boolean milliseconds, Document doc, WSTimeSource timeSource, String pwType) {
element =
doc.createElementNS(WSConstants.WSSE_NS, "wsse:" + WSConstants.USERNAME_TOKEN_LN);
@@ -266,7 +272,7 @@ public class UsernameToken {
passwordType = pwType;
if (passwordType.equals(WSConstants.PASSWORD_DIGEST)) {
addNonce(doc);
- addCreated(milliseconds, doc);
+ addCreated(milliseconds, timeSource, doc);
} else {
hashed = false;
}
@@ -313,6 +319,13 @@ public class UsernameToken {
* Creates and adds a Created element to this UsernameToken
*/
public void addCreated(boolean milliseconds, Document doc) {
+ addCreated(milliseconds, new WSCurrentTimeSource(), doc);
+ }
+
+ /**
+ * Creates and adds a Created element to this UsernameToken
+ */
+ public void addCreated(boolean milliseconds, WSTimeSource timeSource, Document doc) {
if (elementCreated != null) {
return;
}
@@ -327,7 +340,7 @@ public class UsernameToken {
doc.createElementNS(
WSConstants.WSU_NS, WSConstants.WSU_PREFIX + ":" + WSConstants.CREATED_LN
);
- Date currentTime = new Date();
+ Date currentTime = timeSource.now();
elementCreated.appendChild(doc.createTextNode(zulu.format(currentTime)));
element.appendChild(elementCreated);
}
Modified: webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/wss4j/dom/message/TimestampTest.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/wss4j/dom/message/TimestampTest.java?rev=1490690&r1=1490689&r2=1490690&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/wss4j/dom/message/TimestampTest.java (original)
+++ webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/wss4j/dom/message/TimestampTest.java Fri Jun 7 15:41:53 2013
@@ -28,6 +28,7 @@ import org.apache.wss4j.dom.common.SOAPU
import org.apache.wss4j.dom.handler.RequestData;
import org.apache.wss4j.common.bsp.BSPRule;
import org.apache.wss4j.common.ext.WSSecurityException;
+import org.apache.wss4j.common.util.WSTimeSource;
import org.apache.wss4j.common.util.XMLUtils;
import org.apache.wss4j.dom.message.token.Timestamp;
import org.apache.wss4j.dom.util.WSSecurityUtil;
@@ -740,6 +741,51 @@ public class TimestampTest extends org.j
}
/**
+ * This is a test to create a "Spoofed" Timestamp (see WSS-441)
+ */
+ @org.junit.Test
+ public void testSpoofedTimestamp() throws Exception {
+
+ Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
+ WSSecHeader secHeader = new WSSecHeader();
+ secHeader.insertSecurityHeader(doc);
+
+ WSSecTimestamp timestamp = new WSSecTimestamp();
+ timestamp.setTimeToLive(300);
+
+ WSSConfig config = WSSConfig.getNewInstance();
+ WSTimeSource spoofedTimeSource = new WSTimeSource() {
+
+ public Date now() {
+ Date currentTime = new Date();
+ currentTime.setTime(currentTime.getTime() - (500L * 1000L));
+ return currentTime;
+ }
+
+ };
+ config.setCurrentTime(spoofedTimeSource);
+
+ timestamp.setWsConfig(config);
+ Document createdDoc = timestamp.build(doc, secHeader);
+
+ if (LOG.isDebugEnabled()) {
+ String outputString =
+ XMLUtils.PrettyDocumentToString(createdDoc);
+ LOG.debug(outputString);
+ }
+
+ //
+ // Do some processing
+ //
+ try {
+ verify(createdDoc, WSSConfig.getNewInstance());
+ fail("Expected failure on an expired timestamp");
+ } catch (WSSecurityException ex) {
+ assertTrue(ex.getErrorCode() == WSSecurityException.ErrorCode.MESSAGE_EXPIRED);
+ }
+ }
+
+ /**
* Verifies the soap envelope
*/
private List<WSSecurityEngineResult> verify(
Modified: webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/wss4j/dom/message/UsernameTokenTest.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/wss4j/dom/message/UsernameTokenTest.java?rev=1490690&r1=1490689&r2=1490690&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/wss4j/dom/message/UsernameTokenTest.java (original)
+++ webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/wss4j/dom/message/UsernameTokenTest.java Fri Jun 7 15:41:53 2013
@@ -31,6 +31,7 @@ import org.apache.wss4j.dom.common.SOAPU
import org.apache.wss4j.common.bsp.BSPRule;
import org.apache.wss4j.common.ext.WSPasswordCallback;
import org.apache.wss4j.common.ext.WSSecurityException;
+import org.apache.wss4j.common.util.WSTimeSource;
import org.apache.wss4j.common.util.XMLUtils;
import org.apache.wss4j.dom.handler.RequestData;
import org.apache.wss4j.dom.handler.WSHandlerConstants;
@@ -1061,6 +1062,48 @@ public class UsernameTokenTest extends o
}
}
+ /**
+ * This is a test to create a "Spoofed" UsernameToken (see WSS-441)
+ */
+ @org.junit.Test
+ public void testSpoofedUsernameToken() throws Exception {
+ WSSecUsernameToken builder = new WSSecUsernameToken();
+ builder.setUserInfo("wernerd", "verySecret");
+ Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
+ WSSecHeader secHeader = new WSSecHeader();
+ secHeader.insertSecurityHeader(doc);
+
+ WSSConfig config = WSSConfig.getNewInstance();
+ WSTimeSource spoofedTimeSource = new WSTimeSource() {
+
+ public Date now() {
+ Date currentTime = new Date();
+ currentTime.setTime(currentTime.getTime() - (500L * 1000L));
+ return currentTime;
+ }
+
+ };
+ config.setCurrentTime(spoofedTimeSource);
+
+ builder.setWsConfig(config);
+ Document signedDoc = builder.build(doc, secHeader);
+
+ if (LOG.isDebugEnabled()) {
+ String outputString =
+ XMLUtils.PrettyDocumentToString(signedDoc);
+ LOG.debug(outputString);
+ }
+
+ try {
+ WSSecurityEngine secEngine = new WSSecurityEngine();
+ secEngine.processSecurityHeader(doc, null, callbackHandler, null);
+ fail("The UsernameToken validation should have failed");
+ } catch (WSSecurityException ex) {
+ assertTrue(ex.getErrorCode() == WSSecurityException.ErrorCode.MESSAGE_EXPIRED);
+ }
+ }
+
+
private List<WSSecurityEngineResult> verify(Document doc) throws Exception {
return verify(doc, false);
}