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/15 18:03:59 UTC

svn commit: r1468135 - 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/action/ ws-security-dom/src/main/j...

Author: coheigea
Date: Mon Apr 15 16:03:58 2013
New Revision: 1468135

URL: http://svn.apache.org/r1468135
Log:
Removed WSE key derivation stuff. Changed StaX UsernameToken outbound to use the standard approach

Added:
    webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/wss4j/common/util/UsernameTokenUtil.java
Removed:
    webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/wss4j/dom/message/UTWseSignatureTest.java
Modified:
    webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/WSConstants.java
    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/action/UsernameTokenSignedAction.java
    webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/handler/RequestData.java
    webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/handler/WSHandler.java
    webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/handler/WSHandlerConstants.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/UsernameToken.java
    webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/SignatureProcessor.java
    webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/str/SignatureSTRParser.java
    webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/util/WSSecurityUtil.java
    webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/wss4j/dom/message/UTDerivedKeyTest.java
    webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/wss4j/dom/message/UTSignatureTest.java
    webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/wss4j/stax/ext/WSSConstants.java
    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/output/UsernameTokenOutputProcessor.java
    webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/wss4j/stax/impl/securityToken/OutboundUsernameSecurityToken.java
    webservices/wss4j/trunk/ws-security-stax/src/test/java/org/apache/wss4j/stax/test/AbstractTestBase.java
    webservices/wss4j/trunk/ws-security-stax/src/test/java/org/apache/wss4j/stax/test/UsernameTokenTest.java

Added: webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/wss4j/common/util/UsernameTokenUtil.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/wss4j/common/util/UsernameTokenUtil.java?rev=1468135&view=auto
==============================================================================
--- webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/wss4j/common/util/UsernameTokenUtil.java (added)
+++ webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/wss4j/common/util/UsernameTokenUtil.java Mon Apr 15 16:03:58 2013
@@ -0,0 +1,151 @@
+/**
+ * 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.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+import org.apache.wss4j.common.ext.WSSecurityException;
+import org.apache.xml.security.stax.ext.XMLSecurityConstants;
+
+public final class UsernameTokenUtil {
+    public static final int DEFAULT_ITERATION = 1000;
+    
+    private static org.slf4j.Logger LOG =
+            org.slf4j.LoggerFactory.getLogger(UsernameTokenUtil.class);
+    
+    /**
+     * This static method generates a derived key as defined in WSS Username
+     * Token Profile.
+     * 
+     * @param password The password to include in the key generation
+     * @param salt The Salt value
+     * @param iteration The Iteration value. If zero (0) is given the method uses the
+     *                  default value
+     * @return Returns the derived key a byte array
+     * @throws WSSecurityException
+     */
+    public static byte[] generateDerivedKey(
+        byte[] password, 
+        byte[] salt, 
+        int iteration
+    ) throws WSSecurityException {
+        if (iteration == 0) {
+            iteration = DEFAULT_ITERATION;
+        }
+
+        byte[] pwSalt = new byte[salt.length + password.length];
+        System.arraycopy(password, 0, pwSalt, 0, password.length);
+        System.arraycopy(salt, 0, pwSalt, password.length, salt.length);
+
+        MessageDigest sha = null;
+        try {
+            sha = MessageDigest.getInstance("SHA1");
+        } catch (NoSuchAlgorithmException e) {
+            if (LOG.isDebugEnabled()) {
+                LOG.debug(e.getMessage(), e);
+            }
+            throw new WSSecurityException(
+                WSSecurityException.ErrorCode.FAILURE, "noSHA1availabe", e
+            );
+        }
+        //
+        // Make the first hash round with start value
+        //
+        byte[] k = sha.digest(pwSalt);
+        //
+        // Perform the 1st up to iteration-1 hash rounds
+        //
+        for (int i = 1; i < iteration; i++) {
+            k = sha.digest(k);
+        }
+        return k;
+    }
+    
+    /**
+     * This static method generates a derived key as defined in WSS Username
+     * Token Profile.
+     * 
+     * @param password The password to include in the key generation
+     * @param salt The Salt value
+     * @param iteration The Iteration value. If zero (0) is given the method uses the
+     *                  default value
+     * @return Returns the derived key a byte array
+     * @throws WSSecurityException
+     */
+    public static byte[] generateDerivedKey(
+        String password, 
+        byte[] salt, 
+        int iteration
+    ) throws WSSecurityException {
+        try {
+            return generateDerivedKey(password.getBytes("UTF-8"), salt, iteration);
+        } catch (final java.io.UnsupportedEncodingException e) {
+            if (LOG.isDebugEnabled()) {
+                LOG.debug(e.getMessage(), e);
+            }
+            throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE,
+                    "empty", e, "Unable to convert password to UTF-8");
+        }
+    }
+    
+    /**
+     * This static method generates a 128 bit salt value as defined in WSS
+     * Username Token Profile.
+     * 
+     * @param useForMac If <code>true</code> define the Salt for use in a MAC
+     * @return Returns the 128 bit salt value as byte array
+     */
+    public static byte[] generateSalt(boolean useForMac) {
+        byte[] saltValue = null;
+        try {
+            saltValue = generateNonce(16);
+        } catch (WSSecurityException ex) {
+            LOG.debug(ex.getMessage(), ex);
+            return null;
+        }
+        if (useForMac) {
+            saltValue[0] = 0x01;
+        } else {
+            saltValue[0] = 0x02;
+        }
+        return saltValue;
+    }
+
+    /**
+     * Generate a nonce of the given length using the SHA1PRNG algorithm. The SecureRandom
+     * instance that backs this method is cached for efficiency.
+     * 
+     * @return a nonce of the given length
+     * @throws WSSecurityException
+     */
+    private static byte[] generateNonce(int length) throws WSSecurityException {
+        try {
+            byte[] temp = new byte[length];
+            XMLSecurityConstants.secureRandom.nextBytes(temp);
+            return temp;
+        } catch (Exception ex) {
+            throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE,
+                    "empty", ex,
+                    "Error in generating nonce of length " + length
+            );
+        }
+    }
+}

Modified: webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/WSConstants.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/WSConstants.java?rev=1468135&r1=1468134&r2=1468135&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/WSConstants.java (original)
+++ webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/WSConstants.java Mon Apr 15 16:03:58 2013
@@ -474,12 +474,6 @@ public final class WSConstants {
     public static final int BST = 0x1000; //BinarySecurityToken
     public static final int UT_NOPASSWORD = 0x2000; // perform UsernameToken
 
-    /**
-     * Length of UsernameToken derived key used by .NET WSE to sign a message.
-     */
-    public static final int WSE_DERIVED_KEY_LEN = 16;
-    public static final String LABEL_FOR_DERIVED_KEY = "WS-Security";
-    
     private WSConstants() {
         // Complete
     }

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=1468135&r1=1468134&r2=1468135&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 Mon Apr 15 16:03:58 2013
@@ -293,11 +293,6 @@ public class WSSConfig {
     private boolean allowNamespaceQualifiedPasswordTypes;
     
     /**
-     * The secret key length to be used for UT_SIGN.
-     */
-    private int secretKeyLength = WSConstants.WSE_DERIVED_KEY_LEN;
-
-    /**
      * Whether the password should be treated as a binary value.  This
      * is needed to properly handle password equivalence for UsernameToken
      * passwords.  Binary passwords are Base64 encoded so they can be
@@ -509,20 +504,6 @@ public class WSSConfig {
     }
     
     /**
-     * Set the secret key length to be used for UT_SIGN.
-     */
-    public void setSecretKeyLength(int length) {
-        secretKeyLength = length;
-    }
-    
-    /**
-     * Get the secret key length to be used for UT_SIGN.
-     */
-    public int getSecretKeyLength() {
-        return secretKeyLength;
-    }
-    
-    /**
      * @param passwordsAreEncoded
      * whether passwords are encoded
      */

Modified: webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/action/UsernameTokenSignedAction.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/action/UsernameTokenSignedAction.java?rev=1468135&r1=1468134&r2=1468135&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/action/UsernameTokenSignedAction.java (original)
+++ webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/action/UsernameTokenSignedAction.java Mon Apr 15 16:03:58 2013
@@ -53,14 +53,9 @@ public class UsernameTokenSignedAction i
 
         WSSecUsernameToken builder = new WSSecUsernameToken(reqData.getWssConfig());
         
-        if (reqData.isUseDerivedKey()) {
-            int iterations = reqData.getDerivedKeyIterations();
-            boolean useMac = reqData.isUseDerivedKeyForMAC();
-            builder.addDerivedKey(useMac, null, iterations);
-        } else {
-            builder.setPasswordType(reqData.getPwType());  // enhancement by Alberto Coletti
-            builder.setSecretKeyLength(reqData.getSecretKeyLength());
-        }
+        int iterations = reqData.getDerivedKeyIterations();
+        boolean useMac = reqData.isUseDerivedKeyForMAC();
+        builder.addDerivedKey(useMac, null, iterations);
         
         builder.setUserInfo(reqData.getUsername(), passwordCallback.getPassword());
         builder.addCreated();
@@ -86,7 +81,7 @@ public class UsernameTokenSignedAction i
         WSSecSignature sign = new WSSecSignature(reqData.getWssConfig());
         sign.setCustomTokenValueType(WSConstants.USERNAMETOKEN_NS + "#UsernameToken");
         sign.setCustomTokenId(builder.getId());
-        sign.setSecretKey(builder.getSecretKey());
+        sign.setSecretKey(builder.getDerivedKey());
         sign.setKeyIdentifierType(WSConstants.CUSTOM_SYMM_SIGNING);
         if (reqData.getSigDigestAlgorithm() != null) {
             sign.setDigestAlgo(reqData.getSigDigestAlgorithm());

Modified: webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/handler/RequestData.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/handler/RequestData.java?rev=1468135&r1=1468134&r2=1468135&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/handler/RequestData.java (original)
+++ webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/handler/RequestData.java Mon Apr 15 16:03:58 2013
@@ -81,8 +81,6 @@ public class RequestData {
     private List<byte[]> signatureValues = new ArrayList<byte[]>();
     private WSSecHeader secHeader;
     private boolean encSymmetricEncryptionKey = true;
-    private int secretKeyLength = WSConstants.WSE_DERIVED_KEY_LEN;
-    private boolean useDerivedKey = true;
     private int derivedKeyIterations = UsernameToken.DEFAULT_ITERATION;
     private boolean useDerivedKeyForMAC = true;
     private boolean useSingleCert = true;
@@ -113,9 +111,7 @@ public class RequestData {
         signatureDigestAlgorithm = null;
         encryptionDigestAlgorithm = null;
         encSymmetricEncryptionKey = true;
-        secretKeyLength = WSConstants.WSE_DERIVED_KEY_LEN;
         signatureUser = null;
-        useDerivedKey = true;
         derivedKeyIterations = UsernameToken.DEFAULT_ITERATION;
         useDerivedKeyForMAC = true;
         useSingleCert = true;
@@ -165,14 +161,6 @@ public class RequestData {
         this.actor = actor;
     }
     
-    public void setSecretKeyLength(int length) {
-        secretKeyLength = length;
-    }
-    
-    public int getSecretKeyLength() {
-        return secretKeyLength;
-    }
-
     public String getUsername() {
         return username;
     }
@@ -377,22 +365,6 @@ public class RequestData {
     }
     
     /**
-     * @param derivedKey Set whether to derive keys as per the 
-     *        UsernameTokenProfile 1.1 spec. Default is true.
-     */
-    public void setUseDerivedKey(boolean derivedKey) {
-        useDerivedKey = derivedKey;
-    }
-    
-    /**
-     * Return whether to derive keys as per the UsernameTokenProfile 
-     * 1.1 spec. Default is true.
-     */
-    public boolean isUseDerivedKey() {
-        return useDerivedKey;
-    }
-    
-    /**
      * Set the derived key iterations. Default is 1000.
      * @param iterations The number of iterations to use when deriving a key
      */

Modified: webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/handler/WSHandler.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/handler/WSHandler.java?rev=1468135&r1=1468134&r2=1468135&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/handler/WSHandler.java (original)
+++ webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/handler/WSHandler.java Mon Apr 15 16:03:58 2013
@@ -295,7 +295,6 @@ public abstract class WSHandler {
             decodeAllowUsernameTokenNoPassword(reqData)
         );
         
-        wssConfig.setSecretKeyLength(reqData.getSecretKeyLength());
         boolean bspCompliant = decodeBSPCompliance(reqData);
         if (!bspCompliant) {
             reqData.setDisableBSPEnforcement(true);
@@ -470,12 +469,6 @@ public abstract class WSHandler {
             reqData.setUtElements(StringUtil.split(add, ' '));
         }
         
-        String derived = getString(WSHandlerConstants.USE_DERIVED_KEY, mc);
-        if (derived != null) {
-            boolean useDerivedKey = Boolean.parseBoolean(derived);
-            reqData.setUseDerivedKey(useDerivedKey);
-        }
-        
         String derivedMAC = getString(WSHandlerConstants.USE_DERIVED_KEY_FOR_MAC, mc);
         boolean useDerivedKeyForMAC = Boolean.parseBoolean(derivedMAC);
         if (useDerivedKeyForMAC) {
@@ -535,12 +528,6 @@ public abstract class WSHandler {
             splitEncParts(parts, reqData.getSignatureParts(), reqData);
         }
         
-        String secretKeyLength = getString(WSHandlerConstants.WSE_SECRET_KEY_LENGTH, mc);
-        if (secretKeyLength != null) {
-            int iSecretKeyLength = Integer.parseInt(secretKeyLength);
-            reqData.setSecretKeyLength(iSecretKeyLength);
-        }
-        
         boolean useSingleCert = decodeUseSingleCertificate(reqData);
         reqData.setUseSingleCert(useSingleCert);
     }

Modified: webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/handler/WSHandlerConstants.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/handler/WSHandlerConstants.java?rev=1468135&r1=1468134&r2=1468135&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/handler/WSHandlerConstants.java (original)
+++ webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/handler/WSHandlerConstants.java Mon Apr 15 16:03:58 2013
@@ -60,6 +60,11 @@ public final class WSHandlerConstants {
     public static final String USERNAME_TOKEN = "UsernameToken";
     
     /**
+     * Perform a UsernameTokenSignature action.
+     */
+    public static final String USERNAME_TOKEN_SIGNATURE = "UsernameTokenSignature";
+    
+    /**
      * Perform a UsernameToken action with no password.
      */
     public static final String USERNAME_TOKEN_NO_PASSWORD = "UsernameTokenNoPassword";
@@ -91,13 +96,6 @@ public final class WSHandlerConstants {
      */
     public static final String TIMESTAMP = "Timestamp";
     
-    /**
-     * Use this to use a specific signature mechanism for .Net. This signature mechanism 
-     * uses data from the username token and  a well defined constant string and constructs
-     * a signature key. Please note that this action is NOT spec-compliant.
-     */
-    public static final String SIGN_WITH_UT_KEY = "UsernameTokenSignature";
-    
     //
     // User properties
     //
@@ -424,13 +422,6 @@ public final class WSHandlerConstants {
     public static final String USE_SINGLE_CERTIFICATE = "useSingleCertificate";
     
     /**
-     * This parameter sets whether to use UsernameToken Key Derivation, as defined 
-     * in the UsernameTokenProfile 1.1 specification. The default is "true". If false,
-     * then it falls back to the old behaviour of WSE derived key functionality.
-     */
-    public static final String USE_DERIVED_KEY = "useDerivedKey";
-    
-    /**
      * This parameter sets whether to use the Username Token derived key for a MAC
      * or not. The default is "true".
      */
@@ -590,14 +581,6 @@ public final class WSHandlerConstants {
     public static final String SIGNATURE_PARTS = "signatureParts";
     
     /**
-     * This parameter sets the length of the secret (derived) key to use for the
-     * WSE UT_SIGN functionality.
-     * 
-     * The default value is 16 bytes.
-     */
-    public static final String WSE_SECRET_KEY_LENGTH = "wseSecretKeyLength";
-    
-    /**
      * This parameter sets the number of iterations to use when deriving a key
      * from a Username Token. The default is 1000. 
      */

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=1468135&r1=1468134&r2=1468135&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 Mon Apr 15 16:03:58 2013
@@ -22,6 +22,7 @@ package org.apache.wss4j.dom.message;
 import org.apache.wss4j.dom.WSConstants;
 import org.apache.wss4j.dom.WSSConfig;
 import org.apache.wss4j.common.ext.WSSecurityException;
+import org.apache.wss4j.common.util.UsernameTokenUtil;
 import org.apache.wss4j.dom.message.token.UsernameToken;
 import org.apache.wss4j.dom.util.WSSecurityUtil;
 import org.apache.xml.security.exceptions.Base64DecodingException;
@@ -46,7 +47,6 @@ public class WSSecUsernameToken extends 
     private boolean useMac;
     private byte[] saltValue;
     private int iteration = UsernameToken.DEFAULT_ITERATION;
-    private int secretKeyLength = WSConstants.WSE_DERIVED_KEY_LEN;
     private boolean passwordsAreEncoded;
 
     public WSSecUsernameToken() {
@@ -85,20 +85,6 @@ public class WSSecUsernameToken extends 
     }
     
     /**
-     * Set the secret key length
-     */
-    public void setSecretKeyLength(int length) {
-        secretKeyLength = length;
-    }
-    
-    /**
-     * Get the secret key length
-     */
-    public int getSecretKeyLength() {
-        return secretKeyLength;
-    }
-    
-    /**
      * Add a derived key to the UsernameToken
      * @param useMac whether the derived key is to be used for a MAC or not
      * @param saltValue The salt value to use
@@ -114,38 +100,6 @@ public class WSSecUsernameToken extends 
         }
     }
 
-    
-    /**
-     * Get the derived secret key.
-     * 
-     * After the <code>prepare()</code> method was called use this method
-     * to compute a derived secret key. If "useDerivedKey" is set, then the returned secret
-     * key is derived as per the UsernameToken 1.1 specification. Otherwise, the generation 
-     * of this secret key is according to the WS-Trust specifications.
-     * 
-     * @return Return the derived secret key of this token or null if <code>prepare()</code>
-     * was not called before.
-     */
-    public byte[] getSecretKey() throws WSSecurityException {
-        if (ut == null) {
-            return null;
-        }
-        if (useDerivedKey) {
-            if (passwordsAreEncoded) {
-                try {
-                    return UsernameToken.generateDerivedKey(Base64.decode(password), saltValue, iteration);
-                } catch (Base64DecodingException e) {
-                    throw new WSSecurityException(
-                        WSSecurityException.ErrorCode.FAILURE, "decoding.general", e
-                    );
-                }
-            } else {
-                return UsernameToken.generateDerivedKey(password, saltValue, iteration);
-            }
-        }
-        return ut.getSecretKey(secretKeyLength);
-    }
-    
     /**
      * Get the derived key.
      * 
@@ -162,14 +116,14 @@ public class WSSecUsernameToken extends 
         }
         if (passwordsAreEncoded) {
             try {
-                return UsernameToken.generateDerivedKey(Base64.decode(password), saltValue, iteration);
+                return UsernameTokenUtil.generateDerivedKey(Base64.decode(password), saltValue, iteration);
             } catch (Base64DecodingException e) {
                 throw new WSSecurityException(
                     WSSecurityException.ErrorCode.FAILURE, "decoding.general", e
                 );
             }
         } else {
-            return UsernameToken.generateDerivedKey(password, saltValue, iteration);
+            return UsernameTokenUtil.generateDerivedKey(password, saltValue, iteration);
         }
     }
 

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=1468135&r1=1468134&r2=1468135&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 Mon Apr 15 16:03:58 2013
@@ -21,8 +21,6 @@ package org.apache.wss4j.dom.message.tok
 
 import java.io.IOException;
 import java.io.UnsupportedEncodingException;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
 import java.security.Principal;
 import java.text.DateFormat;
 import java.text.SimpleDateFormat;
@@ -36,12 +34,6 @@ import javax.security.auth.callback.Unsu
 import javax.xml.datatype.XMLGregorianCalendar;
 import javax.xml.namespace.QName;
 
-import org.apache.wss4j.common.principal.WSUsernameTokenPrincipalImpl;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-import org.w3c.dom.Text;
-
 import org.apache.wss4j.common.bsp.BSPRule;
 import org.apache.wss4j.common.derivedKey.AlgoFactory;
 import org.apache.wss4j.common.derivedKey.ConversationConstants;
@@ -49,8 +41,10 @@ import org.apache.wss4j.common.derivedKe
 import org.apache.wss4j.common.derivedKey.DerivationAlgorithm;
 import org.apache.wss4j.common.ext.WSPasswordCallback;
 import org.apache.wss4j.common.ext.WSSecurityException;
+import org.apache.wss4j.common.principal.WSUsernameTokenPrincipalImpl;
 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.dom.WSConstants;
 import org.apache.wss4j.dom.WSSConfig;
 import org.apache.wss4j.dom.bsp.BSPEnforcer;
@@ -59,6 +53,10 @@ import org.apache.wss4j.dom.util.WSSecur
 import org.apache.wss4j.dom.util.XmlSchemaDateFormat;
 import org.apache.xml.security.exceptions.Base64DecodingException;
 import org.apache.xml.security.utils.Base64;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.Text;
 
 /**
  * UsernameToken according to WS Security specifications, UsernameToken profile.
@@ -353,7 +351,7 @@ public class UsernameToken {
      */
     public byte[] addSalt(Document doc, byte[] saltValue, boolean mac) {
         if (saltValue == null) {
-            saltValue = generateSalt(mac);
+            saltValue = UsernameTokenUtil.generateSalt(mac);
         }
         elementSalt = 
             doc.createElementNS(
@@ -707,30 +705,6 @@ public class UsernameToken {
     }
 
     /**
-     * Gets the secret key as per WS-Trust spec. This method uses default setting
-     * to generate the secret key. These default values are suitable for .NET
-     * WSE.
-     * 
-     * @return a secret key constructed from information contained in this
-     *         username token
-     */
-    public byte[] getSecretKey() throws WSSecurityException {
-        return getSecretKey(WSConstants.WSE_DERIVED_KEY_LEN, WSConstants.LABEL_FOR_DERIVED_KEY);
-    }
-    
-    /**
-     * Gets the secret key as per WS-Trust spec. This method uses default setting
-     * to generate the secret key. These default values are suitable for .NET
-     * WSE.
-     * 
-     * @return a secret key constructed from information contained in this
-     *         username token
-     */
-    public byte[] getSecretKey(int keylen) throws WSSecurityException {
-        return getSecretKey(keylen, WSConstants.LABEL_FOR_DERIVED_KEY);
-    }
-
-    /**
      * Gets the secret key as per WS-Trust spec.
      * 
      * @param keylen How many bytes to generate for the key
@@ -783,81 +757,6 @@ public class UsernameToken {
     }
     
     
-    /**
-     * This static method generates a derived key as defined in WSS Username
-     * Token Profile.
-     * 
-     * @param password The password to include in the key generation
-     * @param salt The Salt value
-     * @param iteration The Iteration value. If zero (0) is given the method uses the
-     *                  default value
-     * @return Returns the derived key a byte array
-     * @throws WSSecurityException
-     */
-    public static byte[] generateDerivedKey(
-        byte[] password, 
-        byte[] salt, 
-        int iteration
-    ) throws WSSecurityException {
-        if (iteration == 0) {
-            iteration = DEFAULT_ITERATION;
-        }
-
-        byte[] pwSalt = new byte[salt.length + password.length];
-        System.arraycopy(password, 0, pwSalt, 0, password.length);
-        System.arraycopy(salt, 0, pwSalt, password.length, salt.length);
-
-        MessageDigest sha = null;
-        try {
-            sha = MessageDigest.getInstance("SHA1");
-        } catch (NoSuchAlgorithmException e) {
-            if (DO_DEBUG) {
-                LOG.debug(e.getMessage(), e);
-            }
-            throw new WSSecurityException(
-                WSSecurityException.ErrorCode.FAILURE, "noSHA1availabe", e
-            );
-        }
-        //
-        // Make the first hash round with start value
-        //
-        byte[] k = sha.digest(pwSalt);
-        //
-        // Perform the 1st up to iteration-1 hash rounds
-        //
-        for (int i = 1; i < iteration; i++) {
-            k = sha.digest(k);
-        }
-        return k;
-    }
-    
-    /**
-     * This static method generates a derived key as defined in WSS Username
-     * Token Profile.
-     * 
-     * @param password The password to include in the key generation
-     * @param salt The Salt value
-     * @param iteration The Iteration value. If zero (0) is given the method uses the
-     *                  default value
-     * @return Returns the derived key a byte array
-     * @throws WSSecurityException
-     */
-    public static byte[] generateDerivedKey(
-        String password, 
-        byte[] salt, 
-        int iteration
-    ) throws WSSecurityException {
-        try {
-            return generateDerivedKey(password.getBytes("UTF-8"), salt, iteration);
-        } catch (final java.io.UnsupportedEncodingException e) {
-            if (DO_DEBUG) {
-                LOG.debug(e.getMessage(), e);
-            }
-            throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE,
-                    "empty", e, "Unable to convert password to UTF-8");
-        }
-    }
-    
     
     /**
      * This method gets a derived key as defined in WSS Username Token Profile.
@@ -889,14 +788,14 @@ public class UsernameToken {
         byte[] salt = getSalt();
         if (passwordsAreEncoded) {
             try {
-                return generateDerivedKey(Base64.decode(rawPassword), salt, iteration);
+                return UsernameTokenUtil.generateDerivedKey(Base64.decode(rawPassword), salt, iteration);
             } catch (Base64DecodingException e) {
                 throw new WSSecurityException(
                     WSSecurityException.ErrorCode.FAILURE, "decoding.general", e
                 );
             }
         } else {
-            return generateDerivedKey(rawPassword, salt, iteration);
+            return UsernameTokenUtil.generateDerivedKey(rawPassword, salt, iteration);
         }
     }
     
@@ -947,29 +846,6 @@ public class UsernameToken {
         return DateUtil.verifyCreated(createdDate, timeToLive, futureTimeToLive);
     }
     
-    /**
-     * This static method generates a 128 bit salt value as defined in WSS
-     * Username Token Profile.
-     * 
-     * @param useForMac If <code>true</code> define the Salt for use in a MAC
-     * @return Returns the 128 bit salt value as byte array
-     */
-    public static byte[] generateSalt(boolean useForMac) {
-        byte[] saltValue = null;
-        try {
-            saltValue = WSSecurityUtil.generateNonce(16);
-        } catch (WSSecurityException ex) {
-            LOG.debug(ex.getMessage(), ex);
-            return null;
-        }
-        if (useForMac) {
-            saltValue[0] = 0x01;
-        } else {
-            saltValue[0] = 0x02;
-        }
-        return saltValue;
-    }
-
     @Override
     public int hashCode() {
         int result = 17;

Modified: webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/SignatureProcessor.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/SignatureProcessor.java?rev=1468135&r1=1468134&r2=1468135&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/SignatureProcessor.java (original)
+++ webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/SignatureProcessor.java Mon Apr 15 16:03:58 2013
@@ -165,9 +165,6 @@ public class SignatureProcessor implemen
                 STRParser strParser = new SignatureSTRParser();
                 Map<String, Object> parameters = new HashMap<String, Object>();
                 parameters.put(SignatureSTRParser.SIGNATURE_METHOD, signatureMethod);
-                parameters.put(
-                    SignatureSTRParser.SECRET_KEY_LENGTH, data.getWssConfig().getSecretKeyLength()
-                );
                 strParser.parseSecurityTokenReference(
                     child, data, wsDocInfo, parameters
                 );

Modified: webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/str/SignatureSTRParser.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/str/SignatureSTRParser.java?rev=1468135&r1=1468134&r2=1468135&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/str/SignatureSTRParser.java (original)
+++ webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/str/SignatureSTRParser.java Mon Apr 15 16:03:58 2013
@@ -70,12 +70,6 @@ public class SignatureSTRParser implemen
      */
     public static final String SIGNATURE_METHOD = "signature_method";
     
-    /**
-     * The secret key length. This is used when deriving a key from a Username token for the
-     * non-standard WSE implementation.
-     */
-    public static final String SECRET_KEY_LENGTH = "secret_key_length";
-    
     private X509Certificate[] certs;
     
     private byte[] secretKey;
@@ -468,12 +462,8 @@ public class SignatureSTRParser implemen
                 (UsernameToken)result.get(WSSecurityEngineResult.TAG_USERNAME_TOKEN);
 
             usernameToken.setRawPassword(data);
-            if (usernameToken.isDerivedKey()) {
-                secretKey = (byte[])result.get(WSSecurityEngineResult.TAG_SECRET);
-            } else {
-                int keyLength = (Integer) parameters.get(SECRET_KEY_LENGTH);
-                secretKey = usernameToken.getSecretKey(keyLength);
-            }
+            secretKey = (byte[])result.get(WSSecurityEngineResult.TAG_SECRET);
+           
             principal = usernameToken.createPrincipal();
         } else if (WSConstants.BST == action) {
             BinarySecurity token = 

Modified: webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/util/WSSecurityUtil.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/util/WSSecurityUtil.java?rev=1468135&r1=1468134&r2=1468135&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/util/WSSecurityUtil.java (original)
+++ webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/util/WSSecurityUtil.java Mon Apr 15 16:03:58 2013
@@ -970,7 +970,7 @@ public final class WSSecurityUtil {
             } else if (single[i].equals(WSHandlerConstants.TIMESTAMP)) {
                 doAction |= WSConstants.TS;
                 actions.add(WSConstants.TS);
-            } else if (single[i].equals(WSHandlerConstants.SIGN_WITH_UT_KEY)) {
+            } else if (single[i].equals(WSHandlerConstants.USERNAME_TOKEN_SIGNATURE)) {
                 doAction |= WSConstants.UT_SIGN;
                 actions.add(WSConstants.UT_SIGN);
             } else if (single[i].equals(WSHandlerConstants.ENABLE_SIGNATURE_CONFIRMATION)) {
@@ -1027,7 +1027,7 @@ public final class WSSecurityUtil {
             } else if (single[i].equals(WSHandlerConstants.TIMESTAMP)) {
                 doAction |= WSConstants.TS;
                 actions.add(WSConstants.TS);
-            } else if (single[i].equals(WSHandlerConstants.SIGN_WITH_UT_KEY)) {
+            } else if (single[i].equals(WSHandlerConstants.USERNAME_TOKEN_SIGNATURE)) {
                 doAction |= WSConstants.UT_SIGN;
                 actions.add(WSConstants.UT_SIGN);
             } else if (single[i].equals(WSHandlerConstants.ENABLE_SIGNATURE_CONFIRMATION)) {

Modified: webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/wss4j/dom/message/UTDerivedKeyTest.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/wss4j/dom/message/UTDerivedKeyTest.java?rev=1468135&r1=1468134&r2=1468135&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/wss4j/dom/message/UTDerivedKeyTest.java (original)
+++ webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/wss4j/dom/message/UTDerivedKeyTest.java Mon Apr 15 16:03:58 2013
@@ -31,6 +31,7 @@ import org.apache.wss4j.common.bsp.BSPRu
 import org.apache.wss4j.common.crypto.Crypto;
 import org.apache.wss4j.common.crypto.CryptoFactory;
 import org.apache.wss4j.common.ext.WSSecurityException;
+import org.apache.wss4j.common.util.UsernameTokenUtil;
 import org.apache.wss4j.common.util.XMLUtils;
 import org.apache.wss4j.dom.message.token.SecurityTokenReference;
 import org.apache.wss4j.dom.message.token.UsernameToken;
@@ -95,11 +96,11 @@ public class UTDerivedKeyTest extends or
         assertTrue(outputString.contains("wsse11:Salt"));
         assertTrue(outputString.contains("wsse11:Iteration"));
         
-        byte[] derivedKey = UsernameToken.generateDerivedKey("security", salt, 500);
+        byte[] derivedKey = UsernameTokenUtil.generateDerivedKey("security", salt, 500);
         assertTrue(derivedKey.length == 20);
         
         // "c2VjdXJpdHk=" is the Base64 encoding of "security"
-        derivedKey = UsernameToken.generateDerivedKey(Base64.decode("c2VjdXJpdHk="), salt, 500);
+        derivedKey = UsernameTokenUtil.generateDerivedKey(Base64.decode("c2VjdXJpdHk="), salt, 500);
         assertTrue(derivedKey.length == 20);
     }
 
@@ -115,7 +116,7 @@ public class UTDerivedKeyTest extends or
         byte[] salt = Base64.decode("LKpycbfgRzwDnBz6kkhAAQ==");
         int iteration = 1049;
         byte[] expectedDerivedKey = Base64.decode("C7Ll/OY4TECb6hZuMMiX/5hzszo=");
-        byte[] derivedKey = UsernameToken.generateDerivedKey(passwordHash, salt, iteration);
+        byte[] derivedKey = UsernameTokenUtil.generateDerivedKey(passwordHash, salt, iteration);
         assertTrue("the derived key is not as expected", Arrays.equals(expectedDerivedKey, derivedKey));
     }
 
@@ -540,10 +541,10 @@ public class UTDerivedKeyTest extends or
         WSSConfig config = WSSConfig.getNewInstance();
         usernameToken.setID(config.getIdAllocator().createId("UsernameToken-", usernameToken));
         
-        byte[] salt = UsernameToken.generateSalt(false);
+        byte[] salt = UsernameTokenUtil.generateSalt(false);
         usernameToken.addIteration(doc, 1000);
         
-        byte[] derivedKey = UsernameToken.generateDerivedKey("security", salt, 1000);
+        byte[] derivedKey = UsernameTokenUtil.generateDerivedKey("security", salt, 1000);
         
         //
         // Derived key encryption
@@ -592,7 +593,7 @@ public class UTDerivedKeyTest extends or
         usernameToken.setID(config.getIdAllocator().createId("UsernameToken-", usernameToken));
         
         byte[] salt = usernameToken.addSalt(doc, null, false);
-        byte[] derivedKey = UsernameToken.generateDerivedKey("security", salt, 1000);
+        byte[] derivedKey = UsernameTokenUtil.generateDerivedKey("security", salt, 1000);
         
         //
         // Derived key encryption
@@ -642,7 +643,7 @@ public class UTDerivedKeyTest extends or
         
         usernameToken.addIteration(doc, 500);
         byte[] salt = usernameToken.addSalt(doc, null, false);
-        byte[] derivedKey = UsernameToken.generateDerivedKey("security", salt, 500);
+        byte[] derivedKey = UsernameTokenUtil.generateDerivedKey("security", salt, 500);
         
         //
         // Derived key encryption

Modified: webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/wss4j/dom/message/UTSignatureTest.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/wss4j/dom/message/UTSignatureTest.java?rev=1468135&r1=1468134&r2=1468135&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/wss4j/dom/message/UTSignatureTest.java (original)
+++ webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/wss4j/dom/message/UTSignatureTest.java Mon Apr 15 16:03:58 2013
@@ -74,7 +74,7 @@ public class UTSignatureTest extends org
         WSSecSignature sign = new WSSecSignature();
         sign.setCustomTokenValueType(WSConstants.USERNAMETOKEN_NS + "#UsernameToken");
         sign.setCustomTokenId(builder.getId());
-        sign.setSecretKey(builder.getSecretKey());
+        sign.setSecretKey(builder.getDerivedKey());
         sign.setKeyIdentifierType(WSConstants.CUSTOM_SYMM_SIGNING);
         sign.setSignatureAlgorithm(WSConstants.HMAC_SHA1);
         
@@ -125,7 +125,7 @@ public class UTSignatureTest extends org
         WSSecSignature sign = new WSSecSignature();
         sign.setCustomTokenValueType(WSConstants.USERNAMETOKEN_NS + "#UsernameToken");
         sign.setCustomTokenId(builder.getId());
-        sign.setSecretKey(builder.getSecretKey());
+        sign.setSecretKey(builder.getDerivedKey());
         sign.setKeyIdentifierType(WSConstants.CUSTOM_SYMM_SIGNING);
         sign.setSignatureAlgorithm(WSConstants.HMAC_SHA1);
         
@@ -158,7 +158,6 @@ public class UTSignatureTest extends org
         reqData.setWssConfig(cfg);
         java.util.Map<String, Object> messageContext = new java.util.TreeMap<String, Object>();
         messageContext.put(WSHandlerConstants.PW_CALLBACK_REF, callbackHandler);
-        messageContext.put(WSHandlerConstants.USE_DERIVED_KEY, "true");
         reqData.setMsgContext(messageContext);
         reqData.setUsername("bob");
         
@@ -204,7 +203,6 @@ public class UTSignatureTest extends org
         reqData.setWssConfig(cfg);
         java.util.Map<String, Object> messageContext = new java.util.TreeMap<String, Object>();
         messageContext.put(WSHandlerConstants.PW_CALLBACK_REF, callbackHandler);
-        messageContext.put(WSHandlerConstants.USE_DERIVED_KEY, "true");
         messageContext.put(WSHandlerConstants.DERIVED_KEY_ITERATIONS, "1234");
         reqData.setMsgContext(messageContext);
         reqData.setUsername("bob");

Modified: webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/wss4j/stax/ext/WSSConstants.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/wss4j/stax/ext/WSSConstants.java?rev=1468135&r1=1468134&r2=1468135&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/wss4j/stax/ext/WSSConstants.java (original)
+++ webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/wss4j/stax/ext/WSSConstants.java Mon Apr 15 16:03:58 2013
@@ -266,12 +266,6 @@ public class WSSConstants extends XMLSec
 
     public static final String PROP_TIMESTAMP_SECURITYEVENT = "PROP_TIMESTAMP";
 
-    /**
-     * Length of UsernameToken derived key used by .NET WSE to sign a message.
-     */
-    public static final int WSE_DERIVED_KEY_LEN = 16;
-    public static final String LABEL_FOR_DERIVED_KEY = "WS-Security";
-
     public static final Action TIMESTAMP = new Action("TIMESTAMP");
     public static final Action USERNAMETOKEN = new Action("USERNAMETOKEN");
     public static final Action USERNAMETOKEN_SIGNED = new Action("USERNAMETOKEN_SIGNED");

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=1468135&r1=1468134&r2=1468135&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 Mon Apr 15 16:03:58 2013
@@ -63,6 +63,7 @@ public class WSSSecurityProperties exten
     private boolean strictTimestampCheck = true;
     private Integer utTTL = 300;
     private Integer utFutureTTL = 60;
+    private Integer derivedKeyIterations = 1000;
 
     /**
      * This variable controls whether types other than PasswordDigest or PasswordText
@@ -74,6 +75,7 @@ public class WSSSecurityProperties exten
     private boolean handleCustomPasswordTypes = false;
     private boolean allowUsernameTokenNoPassword = false;
     private boolean allowRSA15KeyTransportAlgorithm = false;
+    private boolean useDerivedKeyForMAC = true;
     private WSSConstants.UsernameTokenPasswordType usernameTokenPasswordType;
     private String tokenUser;
 
@@ -134,6 +136,8 @@ public class WSSSecurityProperties exten
         this.timestampReplayCache = wssSecurityProperties.timestampReplayCache;
         this.nonceReplayCache = wssSecurityProperties.nonceReplayCache;
         this.allowRSA15KeyTransportAlgorithm = wssSecurityProperties.allowRSA15KeyTransportAlgorithm;
+        this.derivedKeyIterations = wssSecurityProperties.derivedKeyIterations;
+        this.useDerivedKeyForMAC = wssSecurityProperties.useDerivedKeyForMAC;
     }
 
     /**
@@ -701,5 +705,21 @@ public class WSSSecurityProperties exten
     public void setAllowRSA15KeyTransportAlgorithm(boolean allowRSA15KeyTransportAlgorithm) {
         this.allowRSA15KeyTransportAlgorithm = allowRSA15KeyTransportAlgorithm;
     }
+
+    public Integer getDerivedKeyIterations() {
+        return derivedKeyIterations;
+    }
+
+    public void setDerivedKeyIterations(Integer derivedKeyIterations) {
+        this.derivedKeyIterations = derivedKeyIterations;
+    }
+
+    public boolean isUseDerivedKeyForMAC() {
+        return useDerivedKeyForMAC;
+    }
+
+    public void setUseDerivedKeyForMAC(boolean useDerivedKeyForMAC) {
+        this.useDerivedKeyForMAC = useDerivedKeyForMAC;
+    }
     
 }

Modified: webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/wss4j/stax/impl/processor/output/UsernameTokenOutputProcessor.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/wss4j/stax/impl/processor/output/UsernameTokenOutputProcessor.java?rev=1468135&r1=1468134&r2=1468135&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/wss4j/stax/impl/processor/output/UsernameTokenOutputProcessor.java (original)
+++ webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/wss4j/stax/impl/processor/output/UsernameTokenOutputProcessor.java Mon Apr 15 16:03:58 2013
@@ -21,6 +21,7 @@ package org.apache.wss4j.stax.impl.proce
 import org.apache.commons.codec.binary.Base64;
 import org.apache.wss4j.common.ext.WSPasswordCallback;
 import org.apache.wss4j.common.ext.WSSecurityException;
+import org.apache.wss4j.common.util.UsernameTokenUtil;
 import org.apache.wss4j.stax.ext.WSSConstants;
 import org.apache.wss4j.stax.ext.WSSSecurityProperties;
 import org.apache.wss4j.stax.ext.WSSUtils;
@@ -38,7 +39,6 @@ import javax.xml.datatype.XMLGregorianCa
 import javax.xml.stream.XMLStreamConstants;
 import javax.xml.stream.XMLStreamException;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.GregorianCalendar;
 import java.util.List;
 
@@ -60,13 +60,23 @@ public class UsernameTokenOutputProcesso
             if (password == null && usernameTokenPasswordType != null) {
                 throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE);
             }
-
-            byte[] nonceValue = new byte[16];
-            WSSConstants.secureRandom.nextBytes(nonceValue);
-
+            
             XMLGregorianCalendar created = WSSConstants.datatypeFactory.newXMLGregorianCalendar(new GregorianCalendar());
 
             final String wsuId = IDGenerator.generateID(null);
+            
+            boolean useDerivedKeyForMAC = 
+                ((WSSSecurityProperties)getSecurityProperties()).isUseDerivedKeyForMAC();
+            int derivedIterations = 
+                ((WSSSecurityProperties)getSecurityProperties()).getDerivedKeyIterations();
+            byte[] salt = null;
+            byte[] nonceValue = null;
+            if (WSSConstants.USERNAMETOKEN_SIGNED.equals(getAction())) {
+                salt = UsernameTokenUtil.generateSalt(useDerivedKeyForMAC);
+            } else {
+                nonceValue = new byte[16];
+                WSSConstants.secureRandom.nextBytes(nonceValue);
+            }
 
             final OutputProcessor outputProcessor = this;
 
@@ -75,7 +85,9 @@ public class UsernameTokenOutputProcesso
                             password,
                             created.toXMLFormat(),
                             nonceValue,
-                            wsuId
+                            wsuId,
+                            salt,
+                            derivedIterations
                     );
             usernameSecurityToken.setProcessor(outputProcessor);
 
@@ -97,7 +109,8 @@ public class UsernameTokenOutputProcesso
                 outputProcessorChain.getSecurityContext().put(WSSConstants.PROP_USE_THIS_TOKEN_ID_FOR_SIGNATURE, wsuId);
                 outputProcessorChain.getSecurityContext().put(WSSConstants.PROP_APPEND_SIGNATURE_ON_THIS_ID, wsuId);
             }
-            final FinalUsernameTokenOutputProcessor finalUsernameTokenOutputProcessor = new FinalUsernameTokenOutputProcessor(wsuId, nonceValue, password, created);
+            final FinalUsernameTokenOutputProcessor finalUsernameTokenOutputProcessor = 
+                new FinalUsernameTokenOutputProcessor(wsuId, nonceValue, password, created, salt, derivedIterations, getAction());
             finalUsernameTokenOutputProcessor.setXMLSecurityProperties(getSecurityProperties());
             finalUsernameTokenOutputProcessor.setAction(getAction());
             finalUsernameTokenOutputProcessor.init(outputProcessorChain);
@@ -114,8 +127,13 @@ public class UsernameTokenOutputProcesso
         private byte[] nonceValue = null;
         private String password = null;
         private XMLGregorianCalendar created = null;
-
-        FinalUsernameTokenOutputProcessor(String wsuId, byte[] nonceValue, String password, XMLGregorianCalendar created)
+        private byte[] salt;
+        private int iterations;
+        private XMLSecurityConstants.Action action;
+
+        FinalUsernameTokenOutputProcessor(String wsuId, byte[] nonceValue, String password, 
+                                          XMLGregorianCalendar created, byte[] salt,
+                                          int iterations, XMLSecurityConstants.Action action)
                 throws XMLSecurityException {
             super();
             this.addAfterProcessor(UsernameTokenOutputProcessor.class.getName());
@@ -124,6 +142,9 @@ public class UsernameTokenOutputProcesso
             this.nonceValue = nonceValue;
             this.password = password;
             this.created = created;
+            this.salt = salt;
+            this.iterations = iterations;
+            this.action = action;
         }
 
         @Override
@@ -141,7 +162,8 @@ public class UsernameTokenOutputProcesso
                     createStartElementAndOutputAsEvent(subOutputProcessorChain, WSSConstants.TAG_wsse_Username, false, null);
                     createCharactersAndOutputAsEvent(subOutputProcessorChain, ((WSSSecurityProperties) getSecurityProperties()).getTokenUser());
                     createEndElementAndOutputAsEvent(subOutputProcessorChain, WSSConstants.TAG_wsse_Username);
-                    if (((WSSSecurityProperties) getSecurityProperties()).getUsernameTokenPasswordType() != WSSConstants.UsernameTokenPasswordType.PASSWORD_NONE) {
+                    if (((WSSSecurityProperties) getSecurityProperties()).getUsernameTokenPasswordType() != WSSConstants.UsernameTokenPasswordType.PASSWORD_NONE
+                        && !WSSConstants.USERNAMETOKEN_SIGNED.equals(action)) {
                         attributes = new ArrayList<XMLSecAttribute>(1);
                         attributes.add(createAttribute(WSSConstants.ATT_NULL_Type,
                                 ((WSSSecurityProperties) getSecurityProperties()).getUsernameTokenPasswordType() == WSSConstants.UsernameTokenPasswordType.PASSWORD_DIGEST
@@ -154,9 +176,21 @@ public class UsernameTokenOutputProcesso
                                         : this.password);
                         createEndElementAndOutputAsEvent(subOutputProcessorChain, WSSConstants.TAG_wsse_Password);
                     }
+                    
+                    if (salt != null) {
+                        createStartElementAndOutputAsEvent(subOutputProcessorChain, WSSConstants.TAG_wsse11_Salt, true, null);
+                        createCharactersAndOutputAsEvent(subOutputProcessorChain, new Base64(76, new byte[]{'\n'}).encodeToString(this.salt));
+                        createEndElementAndOutputAsEvent(subOutputProcessorChain, WSSConstants.TAG_wsse11_Salt);
+                    
+                        if (iterations > 0) {
+                            createStartElementAndOutputAsEvent(subOutputProcessorChain, WSSConstants.TAG_wsse11_Iteration, true, null);
+                            createCharactersAndOutputAsEvent(subOutputProcessorChain, "" + iterations);
+                            createEndElementAndOutputAsEvent(subOutputProcessorChain, WSSConstants.TAG_wsse11_Iteration);
+                        }
+                    }
 
                     if (((WSSSecurityProperties) getSecurityProperties()).getUsernameTokenPasswordType() == WSSConstants.UsernameTokenPasswordType.PASSWORD_DIGEST
-                            || Arrays.binarySearch(getSecurityProperties().getOutAction(), WSSConstants.USERNAMETOKEN_SIGNED) >= 0) {
+                        && !WSSConstants.USERNAMETOKEN_SIGNED.equals(action)) {
                         attributes = new ArrayList<XMLSecAttribute>(1);
                         attributes.add(createAttribute(WSSConstants.ATT_NULL_EncodingType, WSSConstants.SOAPMESSAGE_NS10_BASE64_ENCODING));
                         createStartElementAndOutputAsEvent(subOutputProcessorChain, WSSConstants.TAG_wsse_Nonce, false, attributes);

Modified: webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/wss4j/stax/impl/securityToken/OutboundUsernameSecurityToken.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/wss4j/stax/impl/securityToken/OutboundUsernameSecurityToken.java?rev=1468135&r1=1468134&r2=1468135&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/wss4j/stax/impl/securityToken/OutboundUsernameSecurityToken.java (original)
+++ webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/wss4j/stax/impl/securityToken/OutboundUsernameSecurityToken.java Mon Apr 15 16:03:58 2013
@@ -18,34 +18,34 @@
  */
 package org.apache.wss4j.stax.impl.securityToken;
 
-import org.apache.wss4j.common.derivedKey.AlgoFactory;
-import org.apache.wss4j.common.derivedKey.ConversationConstants;
-import org.apache.wss4j.common.derivedKey.ConversationException;
-import org.apache.wss4j.common.derivedKey.DerivationAlgorithm;
-import org.apache.wss4j.common.ext.WSSecurityException;
-import org.apache.wss4j.stax.ext.WSSConstants;
+import java.security.Key;
+
+import javax.crypto.spec.SecretKeySpec;
+
+import org.apache.wss4j.common.util.UsernameTokenUtil;
 import org.apache.wss4j.stax.securityToken.WSSecurityTokenConstants;
 import org.apache.xml.security.exceptions.XMLSecurityException;
 import org.apache.xml.security.stax.config.JCEAlgorithmMapper;
 import org.apache.xml.security.stax.impl.securityToken.GenericOutboundSecurityToken;
 
-import javax.crypto.spec.SecretKeySpec;
-import java.io.UnsupportedEncodingException;
-import java.security.Key;
-
 public class OutboundUsernameSecurityToken extends GenericOutboundSecurityToken {
 
     private String username;
     private String password;
     private String createdTime;
     private byte[] nonce;
+    private byte[] salt;
+    private int iterations;
 
-    public OutboundUsernameSecurityToken(String username, String password, String createdTime, byte[] nonce, String id) {
+    public OutboundUsernameSecurityToken(String username, String password, String createdTime, 
+                                         byte[] nonce, String id, byte[] salt, int iterations) {
         super(id, WSSecurityTokenConstants.UsernameToken);
         this.username = username;
         this.password = password;
         this.createdTime = createdTime;
         this.nonce = nonce;
+        this.salt = salt;
+        this.iterations = iterations;
     }
 
     public String getUsername() {
@@ -70,47 +70,15 @@ public class OutboundUsernameSecurityTok
         if (key != null) {
             return key;
         }
-
-        byte[] secretToken = getSecretKey(getPassword(), WSSConstants.WSE_DERIVED_KEY_LEN, WSSConstants.LABEL_FOR_DERIVED_KEY);
+        
+        byte[] secretToken = 
+            UsernameTokenUtil.generateDerivedKey(getPassword(), salt, iterations);
+        
         String algoFamily = JCEAlgorithmMapper.getJCERequiredKeyFromURI(algorithmURI);
         key = new SecretKeySpec(secretToken, algoFamily);
         setSecretKey(algorithmURI, key);
         return key;
-    }
 
-    /**
-     * Gets the secret key as per WS-Trust spec.
-     *
-     * @param keylen      How many bytes to generate for the key
-     * @param labelString the label used to generate the seed
-     * @return a secret key constructed from information contained in this
-     *         username token
-     */
-    protected byte[] getSecretKey(String rawPassword, int keylen, String labelString) throws WSSecurityException {
-        try {
-            byte[] password = rawPassword.getBytes("UTF-8");
-            byte[] label = labelString.getBytes("UTF-8");
-            byte[] nonce = getNonce();
-            byte[] created = getCreated().getBytes("UTF-8");
-            byte[] seed = new byte[label.length + nonce.length + created.length];
-
-            int offset = 0;
-            System.arraycopy(label, 0, seed, offset, label.length);
-            offset += label.length;
-
-            System.arraycopy(nonce, 0, seed, offset, nonce.length);
-            offset += nonce.length;
-
-            System.arraycopy(created, 0, seed, offset, created.length);
-
-            DerivationAlgorithm algo =
-                    AlgoFactory.getInstance(ConversationConstants.DerivationAlgorithm.P_SHA_1);
-            return algo.createKey(password, seed, 0, keylen);
-
-        } catch (UnsupportedEncodingException e) {
-            throw new WSSecurityException(WSSecurityException.ErrorCode.INVALID_SECURITY, e);
-        } catch (ConversationException e) {
-            throw new WSSecurityException(WSSecurityException.ErrorCode.INVALID_SECURITY, e);
-        }
     }
+
 }

Modified: webservices/wss4j/trunk/ws-security-stax/src/test/java/org/apache/wss4j/stax/test/AbstractTestBase.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-stax/src/test/java/org/apache/wss4j/stax/test/AbstractTestBase.java?rev=1468135&r1=1468134&r2=1468135&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-stax/src/test/java/org/apache/wss4j/stax/test/AbstractTestBase.java (original)
+++ webservices/wss4j/trunk/ws-security-stax/src/test/java/org/apache/wss4j/stax/test/AbstractTestBase.java Mon Apr 15 16:03:58 2013
@@ -241,6 +241,8 @@ public abstract class AbstractTestBase {
         if (properties.get(WSHandlerConstants.ALLOW_USERNAMETOKEN_NOPASSWORD) != null) {
             messageContext.put(WSHandlerConstants.ALLOW_USERNAMETOKEN_NOPASSWORD, 
                                properties.get(WSHandlerConstants.ALLOW_USERNAMETOKEN_NOPASSWORD));
+        } else if (WSHandlerConstants.USERNAME_TOKEN_SIGNATURE.equals(action)) {
+            messageContext.put(WSHandlerConstants.ALLOW_USERNAMETOKEN_NOPASSWORD, "true");
         }
 
         // Disable PrefixList checking as the stax code doesn't support this yet

Modified: webservices/wss4j/trunk/ws-security-stax/src/test/java/org/apache/wss4j/stax/test/UsernameTokenTest.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-stax/src/test/java/org/apache/wss4j/stax/test/UsernameTokenTest.java?rev=1468135&r1=1468134&r2=1468135&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-stax/src/test/java/org/apache/wss4j/stax/test/UsernameTokenTest.java (original)
+++ webservices/wss4j/trunk/ws-security-stax/src/test/java/org/apache/wss4j/stax/test/UsernameTokenTest.java Mon Apr 15 16:03:58 2013
@@ -18,37 +18,41 @@
  */
 package org.apache.wss4j.stax.test;
 
-import org.apache.wss4j.dom.WSConstants;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.GregorianCalendar;
+import java.util.Properties;
+
+import javax.xml.datatype.XMLGregorianCalendar;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.stream.XMLStreamWriter;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
 import org.apache.wss4j.common.ext.WSSecurityException;
+import org.apache.wss4j.dom.WSConstants;
 import org.apache.wss4j.dom.handler.WSHandlerConstants;
-import org.apache.wss4j.stax.securityEvent.WSSecurityEventConstants;
-import org.apache.xml.security.stax.securityEvent.SecurityEvent;
-import org.apache.xml.security.stax.securityEvent.SecurityEventListener;
 import org.apache.wss4j.stax.WSSec;
-import org.apache.wss4j.stax.ext.*;
+import org.apache.wss4j.stax.ext.InboundWSSec;
+import org.apache.wss4j.stax.ext.OutboundWSSec;
+import org.apache.wss4j.stax.ext.WSSConstants;
+import org.apache.wss4j.stax.ext.WSSSecurityProperties;
 import org.apache.wss4j.stax.securityEvent.UsernameTokenSecurityEvent;
+import org.apache.wss4j.stax.securityEvent.WSSecurityEventConstants;
 import org.apache.wss4j.stax.test.utils.StAX2DOM;
 import org.apache.wss4j.stax.test.utils.XmlReaderToWriter;
+import org.apache.xml.security.stax.securityEvent.SecurityEvent;
+import org.apache.xml.security.stax.securityEvent.SecurityEventListener;
 import org.testng.Assert;
 import org.testng.annotations.Test;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.NodeList;
 
-import javax.xml.datatype.XMLGregorianCalendar;
-import javax.xml.stream.XMLStreamException;
-import javax.xml.stream.XMLStreamReader;
-import javax.xml.stream.XMLStreamWriter;
-import javax.xml.transform.dom.DOMSource;
-import javax.xml.transform.stream.StreamResult;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.GregorianCalendar;
-import java.util.Properties;
-
 public class UsernameTokenTest extends AbstractTestBase {
 
     @Test
@@ -538,8 +542,7 @@ public class UsernameTokenTest extends A
             Assert.assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_wsse_Security.getLocalPart());
 
             nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_wsse_Password.getNamespaceURI(), WSSConstants.TAG_wsse_Password.getLocalPart());
-            Assert.assertEquals(nodeList.getLength(), 1);
-            Assert.assertEquals(((Element) nodeList.item(0)).getAttributeNS(null, WSSConstants.ATT_NULL_Type.getLocalPart()), WSSConstants.UsernameTokenPasswordType.PASSWORD_DIGEST.getNamespace());
+            Assert.assertEquals(nodeList.getLength(), 0);
 
             nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_dsig_Reference.getNamespaceURI(), WSSConstants.TAG_dsig_Reference.getLocalPart());
             Assert.assertEquals(nodeList.getLength(), 1);
@@ -553,7 +556,7 @@ public class UsernameTokenTest extends A
 
         //done UsernameToken; now verification:
         {
-            String action = WSHandlerConstants.SIGN_WITH_UT_KEY + " " + WSHandlerConstants.USERNAME_TOKEN;
+            String action = WSHandlerConstants.USERNAME_TOKEN_SIGNATURE;
             doInboundSecurityWithWSS4J(documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray())), action);
         }
     }