Author: coheigea
Date: Thu Mar  3 18:26:57 2011
New Revision: 1076716

URL: http://svn.apache.org/viewvc?rev=1076716&view=rev
Log:
[WSS-256] - Some BSP work for UsernameTokens and tests.

Modified:
    
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/WSConstants.java
    
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/token/DerivedKeyToken.java
    
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/token/SecurityContextToken.java
    
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/token/SecurityTokenReference.java
    
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/token/UsernameToken.java
    
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/UsernameTokenProcessor.java
    
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/str/DerivedKeyTokenSTRParser.java
    
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/str/SignatureSTRParser.java
    
webservices/wss4j/trunk/src/main/resources/org/apache/ws/security/errors.properties
    
webservices/wss4j/trunk/src/test/java/org/apache/ws/security/message/UTDerivedKeyTest.java
    
webservices/wss4j/trunk/src/test/java/org/apache/ws/security/message/UsernameTokenTest.java
    
webservices/wss4j/trunk/src/test/java/org/apache/ws/security/message/token/WCFUsernameTokenTest.java

Modified: 
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/WSConstants.java
URL: 
http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/main/java/org/apache/ws/security/WSConstants.java?rev=1076716&r1=1076715&r2=1076716&view=diff
==============================================================================
--- 
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/WSConstants.java 
(original)
+++ 
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/WSConstants.java 
Thu Mar  3 18:26:57 2011
@@ -242,6 +242,8 @@ public class WSConstants {
     public static final String WSS_ENC_KEY_VALUE_TYPE = SOAPMESSAGE_NS11 + "#" 
+ ENC_KEY_VALUE_TYPE;
     public static final String PASSWORD_DIGEST = USERNAMETOKEN_NS + 
"#PasswordDigest";
     public static final String PASSWORD_TEXT = USERNAMETOKEN_NS + 
"#PasswordText";
+    public static final String WSS_USERNAME_TOKEN_VALUE_TYPE = 
+        USERNAMETOKEN_NS + "#" + USERNAME_TOKEN_LN;
 
     public static final String[] URIS_SOAP_ENV = {
         URI_SOAP11_ENV,

Modified: 
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/token/DerivedKeyToken.java
URL: 
http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/token/DerivedKeyToken.java?rev=1076716&r1=1076715&r2=1076716&view=diff
==============================================================================
--- 
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/token/DerivedKeyToken.java
 (original)
+++ 
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/token/DerivedKeyToken.java
 Thu Mar  3 18:26:57 2011
@@ -111,9 +111,7 @@ public class DerivedKeyToken {
         if (!(el.equals(ConversationConstants.DERIVED_KEY_TOKEN_QNAME_05_02) ||
             el.equals(ConversationConstants.DERIVED_KEY_TOKEN_QNAME_05_12))) {
             throw new WSSecurityException(
-                WSSecurityException.INVALID_SECURITY_TOKEN,
-                "badTokenType00", 
-                new Object[]{el}
+                WSSecurityException.INVALID_SECURITY_TOKEN
             );
         }
         elementSecurityTokenReference = 

Modified: 
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/token/SecurityContextToken.java
URL: 
http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/token/SecurityContextToken.java?rev=1076716&r1=1076715&r2=1076716&view=diff
==============================================================================
--- 
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/token/SecurityContextToken.java
 (original)
+++ 
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/token/SecurityContextToken.java
 Thu Mar  3 18:26:57 2011
@@ -133,11 +133,7 @@ public class SecurityContextToken {
         if (!(el.equals(ConversationConstants.SECURITY_CTX_TOKEN_QNAME_05_02) 
||
             el.equals(ConversationConstants.SECURITY_CTX_TOKEN_QNAME_05_12))
         ) {
-            throw new WSSecurityException(
-                WSSecurityException.INVALID_SECURITY_TOKEN, 
-                "badTokenType00",
-                new Object[]{el}
-            );
+            throw new 
WSSecurityException(WSSecurityException.INVALID_SECURITY_TOKEN);
         }
 
         elementIdentifier = 

Modified: 
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/token/SecurityTokenReference.java
URL: 
http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/token/SecurityTokenReference.java?rev=1076716&r1=1076715&r2=1076716&view=diff
==============================================================================
--- 
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/token/SecurityTokenReference.java
 (original)
+++ 
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/token/SecurityTokenReference.java
 Thu Mar  3 18:26:57 2011
@@ -424,8 +424,13 @@ public class SecurityTokenReference {
     }
     
     public void setKeyIdentifier(String valueType, String keyIdVal) throws 
WSSecurityException {
+        setKeyIdentifier(valueType, keyIdVal, false);
+    }
+    
+    public void setKeyIdentifier(String valueType, String keyIdVal, boolean 
base64) 
+        throws WSSecurityException {
         Document doc = element.getOwnerDocument();
-        createKeyIdentifier(doc, valueType, doc.createTextNode(keyIdVal), 
false);
+        createKeyIdentifier(doc, valueType, doc.createTextNode(keyIdVal), 
base64);
     }
 
     private void createKeyIdentifier(Document doc, String uri, Node node, 
boolean base64) {

Modified: 
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/token/UsernameToken.java
URL: 
http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/token/UsernameToken.java?rev=1076716&r1=1076715&r2=1076716&view=diff
==============================================================================
--- 
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/token/UsernameToken.java
 (original)
+++ 
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/token/UsernameToken.java
 Thu Mar  3 18:26:57 2011
@@ -47,6 +47,7 @@ import java.security.NoSuchAlgorithmExce
 import java.security.Principal;
 import java.text.SimpleDateFormat;
 import java.util.Date;
+import java.util.List;
 import java.text.DateFormat;
 import java.util.TimeZone;
 
@@ -80,6 +81,7 @@ public class UsernameToken {
     protected boolean hashed = true;
     private String rawPassword;        // enhancement by Alberto Coletti
     private boolean passwordsAreEncoded = false;
+    private boolean bspCompliantDerivedKey = true;
     
     /**
      * Constructs a <code>UsernameToken</code> object and parses the
@@ -90,7 +92,7 @@ public class UsernameToken {
      * @throws WSSecurityException
      */
     public UsernameToken(Element elem) throws WSSecurityException {
-        this (elem, false);
+        this (elem, false, true);
     }
 
     /**
@@ -101,19 +103,20 @@ public class UsernameToken {
      *             the UsernameToken data
      * @param allowNamespaceQualifiedPasswordTypes whether to allow (wsse)
      *        namespace qualified password types or not (for interop with WCF)
+     * @param bspCompliant whether the UsernameToken processing complies with 
the BSP spec
      * @throws WSSecurityException
      */
     public UsernameToken(
         Element elem, 
-        boolean allowNamespaceQualifiedPasswordTypes
+        boolean allowNamespaceQualifiedPasswordTypes,
+        boolean bspCompliant
     ) throws WSSecurityException {
         element = elem;
         QName el = new QName(element.getNamespaceURI(), 
element.getLocalName());
         if (!el.equals(TOKEN)) {
             throw new WSSecurityException(
                 WSSecurityException.INVALID_SECURITY_TOKEN,
-                "badTokenType00", 
-                new Object[] {el}
+                "badUsernameToken"
             );
         }
         elementUsername = 
@@ -143,10 +146,14 @@ public class UsernameToken {
         if (elementUsername == null) {
             throw new WSSecurityException(
                 WSSecurityException.INVALID_SECURITY_TOKEN,
-                "badTokenType01", 
-                new Object[] {el}
+                "badUsernameToken"
             );
         }
+        
+        if (bspCompliant) {
+            checkBSPCompliance();
+        }
+        
         hashed = false;
         if (elementSalt != null) {
             //
@@ -157,12 +164,12 @@ public class UsernameToken {
             if (elementPassword != null || elementIteration == null) {
                 throw new WSSecurityException(
                     WSSecurityException.INVALID_SECURITY_TOKEN,
-                    "badTokenType01", 
-                    new Object[] {el}
+                    "badUsernameToken"
                 );
             }
             return;
         }
+        
         if (elementPassword != null) {
             if (elementPassword.hasAttribute(WSConstants.PASSWORD_TYPE_ATTR)) {
                 passwordType = 
elementPassword.getAttribute(WSConstants.PASSWORD_TYPE_ATTR);
@@ -177,8 +184,7 @@ public class UsernameToken {
                 } else {
                     throw new WSSecurityException(
                         WSSecurityException.INVALID_SECURITY_TOKEN,
-                        "badTokenType01", 
-                        new Object[] {el}
+                        "badUsernameToken"
                     );
                 }
             }
@@ -189,8 +195,7 @@ public class UsernameToken {
             if (elementNonce == null || elementCreated == null) {
                 throw new WSSecurityException(
                     WSSecurityException.INVALID_SECURITY_TOKEN,
-                    "badTokenType01", 
-                    new Object[] {el}
+                    "badUsernameToken"
                 );
             }
         }
@@ -789,7 +794,8 @@ public class UsernameToken {
      * @throws WSSecurityException
      */
     public byte[] getDerivedKey() throws WSSecurityException {
-        if (rawPassword == null) {
+        if (rawPassword == null || !bspCompliantDerivedKey) {
+            LOG.debug("The raw password was null or the Username Token is not 
BSP compliant");
             throw new 
WSSecurityException(WSSecurityException.FAILED_AUTHENTICATION);
         }
         int iteration = getIteration();
@@ -899,4 +905,96 @@ public class UsernameToken {
     private static int min(int a, int b) {
         return (a > b) ? b : a;
     }
+    
+    /**
+     * A method to check that the UsernameToken is compliant with the BSP spec.
+     * @throws WSSecurityException
+     */
+    private void checkBSPCompliance() throws WSSecurityException {
+        List<Element> passwordElements = 
+            WSSecurityUtil.getDirectChildElements(
+                element, WSConstants.PASSWORD_LN, WSConstants.WSSE_NS
+            );
+        // We can only have one password element
+        if (passwordElements.size() > 1) {
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("The Username Token had more than one password 
element");
+            }
+            throw new WSSecurityException(
+                WSSecurityException.INVALID_SECURITY_TOKEN, "badUsernameToken"
+            );
+        }
+        
+        // We must have a password type
+        if (passwordElements.size() == 1) {
+            Element passwordChild = passwordElements.get(0);
+            String type = passwordChild.getAttributeNS(null, 
WSConstants.PASSWORD_TYPE_ATTR);
+            if (type == null || "".equals(type)) {
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug("The Username Token password does not have a 
Type attribute");
+                }
+                throw new WSSecurityException(
+                    WSSecurityException.INVALID_SECURITY_TOKEN, 
"badUsernameToken"
+                );
+            }
+        }
+        
+        if (elementSalt == null) {
+            // We must have a salt element to use this token for a derived key
+            bspCompliantDerivedKey = false;
+        }
+        if (elementIteration == null) {
+            // we must have an iteration element to use this token for a 
derived key
+            bspCompliantDerivedKey = false;
+        } else {
+            String iter = nodeString(elementIteration);
+            if (iter == null || Integer.parseInt(iter) < 1000) {
+                bspCompliantDerivedKey = false;
+            }
+        }
+        
+        List<Element> createdElements = 
+            WSSecurityUtil.getDirectChildElements(
+                element, WSConstants.CREATED_LN, WSConstants.WSU_NS
+            );
+        // We can only have one created element
+        if (createdElements.size() > 1) {
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("The Username Token has more than one created 
element");
+            }
+            throw new WSSecurityException(
+                WSSecurityException.INVALID_SECURITY_TOKEN, "badUsernameToken"
+            );
+        }
+        
+        List<Element> nonceElements = 
+            WSSecurityUtil.getDirectChildElements(
+                element, WSConstants.NONCE_LN, WSConstants.WSSE_NS
+            );
+        // We can only have one nonce element
+        if (nonceElements.size() > 1) {
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("The Username Token has more than one nonce 
element");
+            }
+            throw new WSSecurityException(
+                WSSecurityException.INVALID_SECURITY_TOKEN, "badUsernameToken"
+            );
+        }
+        
+        if (nonceElements.size() == 1) {
+            Element nonce = nonceElements.get(0);
+            String encodingType = nonce.getAttribute("EncodingType");
+            // Encoding Type must be equal to Base64Binary
+            if (encodingType == null || "".equals(encodingType)
+                || !BinarySecurity.BASE64_ENCODING.equals(encodingType)) {
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug("The Username Token's nonce element has a bad 
encoding type");
+                }
+                throw new WSSecurityException(
+                    WSSecurityException.INVALID_SECURITY_TOKEN, 
+                    "badUsernameToken" 
+                );
+            }
+        }
+    }
 }

Modified: 
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/UsernameTokenProcessor.java
URL: 
http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/UsernameTokenProcessor.java?rev=1076716&r1=1076715&r2=1076716&view=diff
==============================================================================
--- 
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/UsernameTokenProcessor.java
 (original)
+++ 
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/processor/UsernameTokenProcessor.java
 Thu Mar  3 18:26:57 2011
@@ -95,15 +95,18 @@ public class UsernameTokenProcessor impl
         WSSConfig wssConfig
     ) throws WSSecurityException {
         boolean allowNamespaceQualifiedPasswordTypes = false;
+        boolean bspCompliant = true;
         if (wssConfig != null) {
             allowNamespaceQualifiedPasswordTypes = 
                 wssConfig.getAllowNamespaceQualifiedPasswordTypes();
+            bspCompliant = wssConfig.isWsiBSPCompliant();
         }
         
         //
         // Parse and validate the UsernameToken element
         //
-        UsernameToken ut = new UsernameToken(token, 
allowNamespaceQualifiedPasswordTypes);
+        UsernameToken ut = 
+            new UsernameToken(token, allowNamespaceQualifiedPasswordTypes, 
bspCompliant);
         Credential credential = new Credential();
         credential.setUsernametoken(ut);
         validator.validate(credential);

Modified: 
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/str/DerivedKeyTokenSTRParser.java
URL: 
http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/main/java/org/apache/ws/security/str/DerivedKeyTokenSTRParser.java?rev=1076716&r1=1076715&r2=1076716&view=diff
==============================================================================
--- 
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/str/DerivedKeyTokenSTRParser.java
 (original)
+++ 
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/str/DerivedKeyTokenSTRParser.java
 Thu Mar  3 18:26:57 2011
@@ -100,6 +100,9 @@ public class DerivedKeyTokenSTRParser im
         if (result != null) {
             int action = 
((Integer)result.get(WSSecurityEngineResult.TAG_ACTION)).intValue();
             if (WSConstants.UT_NOPASSWORD == action || WSConstants.UT == 
action) {
+                if (bspCompliant) {
+                    checkUTBSPCompliance(secRef);
+                }
                 UsernameToken usernameToken = 
                     
(UsernameToken)result.get(WSSecurityEngineResult.TAG_USERNAME_TOKEN);
                 usernameToken.setRawPassword(cb);
@@ -176,6 +179,30 @@ public class DerivedKeyTokenSTRParser im
     }
 
     /**
+     * Check the BSP compliance for a reference to a UsernameToken
+     * @param secRef the SecurityTokenReference element
+     * @throws WSSecurityException
+     */
+    private void checkUTBSPCompliance(SecurityTokenReference secRef) throws 
WSSecurityException {
+        if (!secRef.containsReference()) {
+            // BSP does not permit using a KeyIdentifier to refer to a U/T
+            throw new WSSecurityException(
+                WSSecurityException.FAILED_CHECK, "unsupportedKeyId"
+            );
+        }
+        String valueType = secRef.getReference().getValueType();
+        
+        if (!WSConstants.WSS_USERNAME_TOKEN_VALUE_TYPE.equals(valueType)) {
+            // BSP says the Reference must have a ValueType of UsernameToken
+            throw new WSSecurityException(
+                WSSecurityException.INVALID_SECURITY,
+                "invalidValueType", 
+                new Object[]{valueType}
+            );
+        }
+    }
+    
+    /**
      * Get the Secret Key from a CallbackHandler
      * @param id The id of the element
      * @param type The type of the element (may be null)

Modified: 
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/str/SignatureSTRParser.java
URL: 
http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/main/java/org/apache/ws/security/str/SignatureSTRParser.java?rev=1076716&r1=1076715&r2=1076716&view=diff
==============================================================================
--- 
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/str/SignatureSTRParser.java
 (original)
+++ 
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/str/SignatureSTRParser.java
 Thu Mar  3 18:26:57 2011
@@ -154,6 +154,15 @@ public class SignatureSTRParser implemen
             } else {
                 int action = 
((Integer)result.get(WSSecurityEngineResult.TAG_ACTION)).intValue();
                 if (WSConstants.UT_NOPASSWORD == action || WSConstants.UT == 
action) {
+                    String valueType = ref.getValueType();
+                    if (bspCompliant && 
!WSConstants.WSS_USERNAME_TOKEN_VALUE_TYPE.equals(valueType)) {
+                        // BSP says the Reference must have a ValueType of 
UsernameToken
+                        throw new WSSecurityException(
+                            WSSecurityException.INVALID_SECURITY,
+                            "invalidValueType", 
+                            new Object[]{valueType}
+                        );
+                    }
                     UsernameToken usernameToken = 
                         
(UsernameToken)result.get(WSSecurityEngineResult.TAG_USERNAME_TOKEN);
 

Modified: 
webservices/wss4j/trunk/src/main/resources/org/apache/ws/security/errors.properties
URL: 
http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/main/resources/org/apache/ws/security/errors.properties?rev=1076716&r1=1076715&r2=1076716&view=diff
==============================================================================
--- 
webservices/wss4j/trunk/src/main/resources/org/apache/ws/security/errors.properties
 (original)
+++ 
webservices/wss4j/trunk/src/main/resources/org/apache/ws/security/errors.properties
 Thu Mar  3 18:26:57 2011
@@ -36,8 +36,7 @@ invalidDataRef = Cannot handle multiple 
 invalidEmbeddedRef = The embedded Reference is invalid
 noEncryptedData = Referenced encrypted data could not be retrieved. Reference 
\"{0}\"
 badElement = Bad element, expected \"{0}\" while got \"{1}\"
-badTokenType00 = Bad UsernameToken Type
-badTokenType01 = Bad UsernameToken Values
+badUsernameToken = An error happened processing a Username Token
 badC14nAlgo = A bad canonicalization algorithm was specified
 failedAuthentication = User ({0}) not authenticated
 missingUsernameToken = UsernameToken is missing

Modified: 
webservices/wss4j/trunk/src/test/java/org/apache/ws/security/message/UTDerivedKeyTest.java
URL: 
http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/test/java/org/apache/ws/security/message/UTDerivedKeyTest.java?rev=1076716&r1=1076715&r2=1076716&view=diff
==============================================================================
--- 
webservices/wss4j/trunk/src/test/java/org/apache/ws/security/message/UTDerivedKeyTest.java
 (original)
+++ 
webservices/wss4j/trunk/src/test/java/org/apache/ws/security/message/UTDerivedKeyTest.java
 Thu Mar  3 18:26:57 2011
@@ -22,6 +22,7 @@ package org.apache.ws.security.message;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.WSSConfig;
 import org.apache.ws.security.WSSecurityEngineResult;
 import org.apache.ws.security.WSSecurityException;
 import org.apache.ws.security.WSSecurityEngine;
@@ -30,6 +31,7 @@ import org.apache.ws.security.common.SOA
 import org.apache.ws.security.common.UsernamePasswordCallbackHandler;
 import org.apache.ws.security.components.crypto.Crypto;
 import org.apache.ws.security.components.crypto.CryptoFactory;
+import org.apache.ws.security.message.token.SecurityTokenReference;
 import org.apache.ws.security.message.token.UsernameToken;
 import org.apache.ws.security.util.Base64;
 import org.apache.ws.security.util.WSSecurityUtil;
@@ -136,6 +138,7 @@ public class UTDerivedKeyTest extends or
         WSSecDKEncrypt encrBuilder = new WSSecDKEncrypt();
         encrBuilder.setSymmetricEncAlgorithm(WSConstants.AES_128);
         encrBuilder.setExternalKey(derivedKey, tokenIdentifier);
+        
encrBuilder.setCustomValueType(WSConstants.WSS_USERNAME_TOKEN_VALUE_TYPE);
         Document encryptedDoc = encrBuilder.build(doc, secHeader);
         
         builder.prependToHeader(secHeader);
@@ -179,6 +182,7 @@ public class UTDerivedKeyTest extends or
         WSSecDKEncrypt encrBuilder = new WSSecDKEncrypt();
         encrBuilder.setSymmetricEncAlgorithm(WSConstants.AES_128);
         encrBuilder.setExternalKey(derivedKey, tokenIdentifier);
+        
encrBuilder.setCustomValueType(WSConstants.WSS_USERNAME_TOKEN_VALUE_TYPE);
         Document encryptedDoc = encrBuilder.build(doc, secHeader);
         
         builder.prependToHeader(secHeader);
@@ -232,6 +236,7 @@ public class UTDerivedKeyTest extends or
         WSSecDKEncrypt encrBuilder = new WSSecDKEncrypt();
         encrBuilder.setSymmetricEncAlgorithm(WSConstants.AES_128);
         encrBuilder.setExternalKey(derivedKey, tokenIdentifier);
+        
encrBuilder.setCustomValueType(WSConstants.WSS_USERNAME_TOKEN_VALUE_TYPE);
         Document encryptedDoc = encrBuilder.build(doc, secHeader);
         
         builder.prependToHeader(secHeader);
@@ -282,6 +287,7 @@ public class UTDerivedKeyTest extends or
         WSSecDKEncrypt encrBuilder = new WSSecDKEncrypt();
         encrBuilder.setSymmetricEncAlgorithm(WSConstants.AES_128);
         encrBuilder.setExternalKey(derivedKey, tokenIdentifier);
+        
encrBuilder.setCustomValueType(WSConstants.WSS_USERNAME_TOKEN_VALUE_TYPE);
         Document encryptedDoc = encrBuilder.build(doc, secHeader);
         
         builder.prependToHeader(secHeader);
@@ -331,6 +337,7 @@ public class UTDerivedKeyTest extends or
         WSSecDKSign sigBuilder = new WSSecDKSign();
         sigBuilder.setExternalKey(derivedKey, tokenIdentifier);
         sigBuilder.setSignatureAlgorithm(WSConstants.HMAC_SHA1);
+        
sigBuilder.setCustomValueType(WSConstants.WSS_USERNAME_TOKEN_VALUE_TYPE);
         Document signedDoc = sigBuilder.build(doc, secHeader);
         
         builder.prependToHeader(secHeader);
@@ -380,6 +387,7 @@ public class UTDerivedKeyTest extends or
         WSSecDKSign sigBuilder = new WSSecDKSign();
         sigBuilder.setExternalKey(derivedKey, tokenIdentifier);
         sigBuilder.setSignatureAlgorithm(WSConstants.HMAC_SHA1);
+        
sigBuilder.setCustomValueType(WSConstants.WSS_USERNAME_TOKEN_VALUE_TYPE);
         Document signedDoc = sigBuilder.build(doc, secHeader);
         
         builder.prependToHeader(secHeader);
@@ -435,6 +443,7 @@ public class UTDerivedKeyTest extends or
         WSSecDKSign sigBuilder = new WSSecDKSign();
         sigBuilder.setExternalKey(derivedKey, tokenIdentifier);
         sigBuilder.setSignatureAlgorithm(WSConstants.HMAC_SHA1);
+        
sigBuilder.setCustomValueType(WSConstants.WSS_USERNAME_TOKEN_VALUE_TYPE);
         Document signedDoc = sigBuilder.build(doc, secHeader);
         
         builder.prependToHeader(secHeader);
@@ -480,6 +489,7 @@ public class UTDerivedKeyTest extends or
         WSSecDKSign sigBuilder = new WSSecDKSign();
         sigBuilder.setExternalKey(derivedKey, tokenIdentifier);
         sigBuilder.setSignatureAlgorithm(WSConstants.HMAC_SHA1);
+        
sigBuilder.setCustomValueType(WSConstants.WSS_USERNAME_TOKEN_VALUE_TYPE);
         Document signedDoc = sigBuilder.build(doc, secHeader);
         
         builder.prependToHeader(secHeader);
@@ -500,6 +510,285 @@ public class UTDerivedKeyTest extends or
     }
     
     /**
+     * Unit test for creating a Username Token with no salt element that is 
used for
+     * deriving a key for encryption.
+     */
+    @org.junit.Test
+    public void testNoSaltEncryption() throws Exception {
+        Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
+        WSSecHeader secHeader = new WSSecHeader();
+        secHeader.insertSecurityHeader(doc);
+        
+        UsernameToken usernameToken = new UsernameToken(true, doc, null);
+        usernameToken.setName("bob");
+        WSSConfig config = WSSConfig.getNewInstance();
+        usernameToken.setID(config.getIdAllocator().createId("UsernameToken-", 
usernameToken));
+        
+        byte[] salt = UsernameToken.generateSalt(false);
+        usernameToken.addIteration(doc, 1000);
+        
+        byte[] derivedKey = UsernameToken.generateDerivedKey("security", salt, 
1000);
+        
+        //
+        // Derived key encryption
+        //
+        WSSecDKEncrypt encrBuilder = new WSSecDKEncrypt();
+        encrBuilder.setSymmetricEncAlgorithm(WSConstants.AES_128);
+        encrBuilder.setExternalKey(derivedKey, usernameToken.getID());
+        
encrBuilder.setCustomValueType(WSConstants.WSS_USERNAME_TOKEN_VALUE_TYPE);
+        Document encryptedDoc = encrBuilder.build(doc, secHeader);
+        
+        WSSecurityUtil.prependChildElement(
+            secHeader.getSecurityHeader(), usernameToken.getElement()
+        );
+        
+        String outputString = 
+            org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(doc);
+        assertTrue(outputString.indexOf("wsse:Username") != -1);
+        assertTrue(outputString.indexOf("wsse:Password") == -1);
+        assertTrue(outputString.indexOf("wsse11:Salt") == -1);
+        assertTrue(outputString.indexOf("wsse11:Iteration") != -1);
+        if (LOG.isDebugEnabled()) {
+            LOG.debug(outputString);
+        }
+        
+        try {
+            verify(encryptedDoc);
+            fail("Failure expected on no salt element");
+        } catch (WSSecurityException ex) {
+            // expected
+        }
+    }
+    
+    /**
+     * Unit test for creating a Username Token with no iteration element that 
is used for
+     * deriving a key for encryption.
+     */
+    @org.junit.Test
+    public void testNoIterationEncryption() throws Exception {
+        Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
+        WSSecHeader secHeader = new WSSecHeader();
+        secHeader.insertSecurityHeader(doc);
+        
+        UsernameToken usernameToken = new UsernameToken(true, doc, null);
+        usernameToken.setName("bob");
+        WSSConfig config = WSSConfig.getNewInstance();
+        usernameToken.setID(config.getIdAllocator().createId("UsernameToken-", 
usernameToken));
+        
+        byte[] salt = usernameToken.addSalt(doc, null, false);
+        byte[] derivedKey = UsernameToken.generateDerivedKey("security", salt, 
1000);
+        
+        //
+        // Derived key encryption
+        //
+        WSSecDKEncrypt encrBuilder = new WSSecDKEncrypt();
+        encrBuilder.setSymmetricEncAlgorithm(WSConstants.AES_128);
+        encrBuilder.setExternalKey(derivedKey, usernameToken.getID());
+        
encrBuilder.setCustomValueType(WSConstants.WSS_USERNAME_TOKEN_VALUE_TYPE);
+        Document encryptedDoc = encrBuilder.build(doc, secHeader);
+        
+        WSSecurityUtil.prependChildElement(
+            secHeader.getSecurityHeader(), usernameToken.getElement()
+        );
+        
+        String outputString = 
+            org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(doc);
+        assertTrue(outputString.indexOf("wsse:Username") != -1);
+        assertTrue(outputString.indexOf("wsse:Password") == -1);
+        assertTrue(outputString.indexOf("wsse11:Salt") != -1);
+        assertTrue(outputString.indexOf("wsse11:Iteration") == -1);
+        if (LOG.isDebugEnabled()) {
+            LOG.debug(outputString);
+        }
+        
+        try {
+            verify(encryptedDoc);
+            fail("Failure expected on no iteration element");
+        } catch (WSSecurityException ex) {
+            // expected
+        }
+    }
+    
+    /**
+     * Unit test for creating a Username Token with an iteration value < 1000 
that is used for
+     * deriving a key for encryption.
+     */
+    @org.junit.Test
+    public void testLowIterationEncryption() throws Exception {
+        Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
+        WSSecHeader secHeader = new WSSecHeader();
+        secHeader.insertSecurityHeader(doc);
+        
+        UsernameToken usernameToken = new UsernameToken(true, doc, null);
+        usernameToken.setName("bob");
+        WSSConfig config = WSSConfig.getNewInstance();
+        usernameToken.setID(config.getIdAllocator().createId("UsernameToken-", 
usernameToken));
+        
+        usernameToken.addIteration(doc, 500);
+        byte[] salt = usernameToken.addSalt(doc, null, false);
+        byte[] derivedKey = UsernameToken.generateDerivedKey("security", salt, 
500);
+        
+        //
+        // Derived key encryption
+        //
+        WSSecDKEncrypt encrBuilder = new WSSecDKEncrypt();
+        encrBuilder.setSymmetricEncAlgorithm(WSConstants.AES_128);
+        encrBuilder.setExternalKey(derivedKey, usernameToken.getID());
+        
encrBuilder.setCustomValueType(WSConstants.WSS_USERNAME_TOKEN_VALUE_TYPE);
+        Document encryptedDoc = encrBuilder.build(doc, secHeader);
+        
+        WSSecurityUtil.prependChildElement(
+            secHeader.getSecurityHeader(), usernameToken.getElement()
+        );
+        
+        String outputString = 
+            org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(doc);
+        assertTrue(outputString.indexOf("wsse:Username") != -1);
+        assertTrue(outputString.indexOf("wsse:Password") == -1);
+        assertTrue(outputString.indexOf("wsse11:Salt") != -1);
+        assertTrue(outputString.indexOf("wsse11:Iteration") != -1);
+        if (LOG.isDebugEnabled()) {
+            LOG.debug(outputString);
+        }
+        
+        try {
+            verify(encryptedDoc);
+            fail("Failure expected on a low iteration value");
+        } catch (WSSecurityException ex) {
+            // expected
+        }
+        
+        // Turn off BSP compliance and it should work
+        config.setWsiBSPCompliant(false);
+        WSSecurityEngine newEngine = new WSSecurityEngine();
+        newEngine.setWssConfig(config);
+        newEngine.processSecurityHeader(doc, null, callbackHandler, crypto);
+    }
+
+    
+    /**
+     * Test using a UsernameToken derived key for encrypting a SOAP body. The 
Reference to the
+     * UsernameToken contains a non-standard value type, which is rejected 
when BSP compliance
+     * is turned on.
+     */
+    @org.junit.Test
+    public void testBadValueType() throws Exception {
+        Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
+        WSSecHeader secHeader = new WSSecHeader();
+        secHeader.insertSecurityHeader(doc);
+        
+        WSSecUsernameToken builder = new WSSecUsernameToken();
+        builder.setUserInfo("bob", "security");
+        builder.addDerivedKey(false, null, 1000);
+        builder.prepare(doc);
+        
+        byte[] derivedKey = builder.getDerivedKey();
+        assertTrue(derivedKey.length == 20);
+        
+        String tokenIdentifier = builder.getId();
+        
+        //
+        // Derived key encryption
+        //
+        WSSecDKEncrypt encrBuilder = new WSSecDKEncrypt();
+        encrBuilder.setSymmetricEncAlgorithm(WSConstants.AES_128);
+        encrBuilder.setExternalKey(derivedKey, tokenIdentifier);
+        encrBuilder.setCustomValueType(WSConstants.WSS_SAML_TOKEN_TYPE);
+        Document encryptedDoc = encrBuilder.build(doc, secHeader);
+        
+        builder.prependToHeader(secHeader);
+        
+        String outputString = 
+            
org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(encryptedDoc);
+        assertTrue(outputString.indexOf("wsse:Username") != -1);
+        assertTrue(outputString.indexOf("wsse:Password") == -1);
+        assertTrue(outputString.indexOf("wsse11:Salt") != -1);
+        assertTrue(outputString.indexOf("wsse11:Iteration") != -1);
+        assertTrue(outputString.indexOf("testMethod") == -1);
+        if (LOG.isDebugEnabled()) {
+            LOG.debug(outputString);
+        }
+        
+        try {
+            verify(encryptedDoc);
+            fail("Failure expected on a bad value type");
+        } catch (WSSecurityException ex) {
+            // expected
+        }
+        
+        // Turn off BSP compliance and it should work
+        WSSConfig config = WSSConfig.getNewInstance();
+        config.setWsiBSPCompliant(false);
+        WSSecurityEngine newEngine = new WSSecurityEngine();
+        newEngine.setWssConfig(config);
+        newEngine.processSecurityHeader(doc, null, callbackHandler, crypto);
+    }
+
+    
+    /**
+     * Test using a UsernameToken derived key for encrypting a SOAP body. A 
KeyIdentifier is
+     * used to refer to the UsernameToken, which is forbidden by the BSP.
+     */
+    @org.junit.Test
+    public void testKeyIdentifier() throws Exception {
+        Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
+        WSSecHeader secHeader = new WSSecHeader();
+        secHeader.insertSecurityHeader(doc);
+        
+        WSSecUsernameToken builder = new WSSecUsernameToken();
+        builder.setUserInfo("bob", "security");
+        builder.addDerivedKey(false, null, 1000);
+        builder.prepare(doc);
+        
+        byte[] derivedKey = builder.getDerivedKey();
+        assertTrue(derivedKey.length == 20);
+        
+        String tokenIdentifier = builder.getId();
+        
+        //
+        // Derived key encryption
+        //
+        WSSecDKEncrypt encrBuilder = new WSSecDKEncrypt();
+        encrBuilder.setSymmetricEncAlgorithm(WSConstants.AES_128);
+        
+        SecurityTokenReference strEncKey = new SecurityTokenReference(doc);
+        strEncKey.setKeyIdentifier(
+            WSConstants.WSS_USERNAME_TOKEN_VALUE_TYPE, tokenIdentifier, true
+        );
+        encrBuilder.setExternalKey(derivedKey, strEncKey.getElement());
+        
+        Document encryptedDoc = encrBuilder.build(doc, secHeader);
+        
+        builder.prependToHeader(secHeader);
+        
+        String outputString = 
+            
org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(encryptedDoc);
+        assertTrue(outputString.indexOf("wsse:Username") != -1);
+        assertTrue(outputString.indexOf("wsse:Password") == -1);
+        assertTrue(outputString.indexOf("wsse11:Salt") != -1);
+        assertTrue(outputString.indexOf("wsse11:Iteration") != -1);
+        assertTrue(outputString.indexOf("testMethod") == -1);
+        if (LOG.isDebugEnabled()) {
+            LOG.debug(outputString);
+        }
+        
+        try {
+            verify(encryptedDoc);
+            fail("Failure expected on a key identifier");
+        } catch (WSSecurityException ex) {
+            // expected
+        }
+        
+        // Turn off BSP compliance and it should work
+        WSSConfig config = WSSConfig.getNewInstance();
+        config.setWsiBSPCompliant(false);
+        WSSecurityEngine newEngine = new WSSecurityEngine();
+        newEngine.setWssConfig(config);
+        newEngine.processSecurityHeader(doc, null, callbackHandler, crypto);
+    }
+
+    
+    /**
      * Verifies the soap envelope.
      * 
      * @param env soap envelope

Modified: 
webservices/wss4j/trunk/src/test/java/org/apache/ws/security/message/UsernameTokenTest.java
URL: 
http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/test/java/org/apache/ws/security/message/UsernameTokenTest.java?rev=1076716&r1=1076715&r2=1076716&view=diff
==============================================================================
--- 
webservices/wss4j/trunk/src/test/java/org/apache/ws/security/message/UsernameTokenTest.java
 (original)
+++ 
webservices/wss4j/trunk/src/test/java/org/apache/ws/security/message/UsernameTokenTest.java
 Thu Mar  3 18:26:57 2011
@@ -78,7 +78,7 @@ public class UsernameTokenTest extends o
         + 
"xmlns:wsse=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd\";>"
         + "<wsse:UsernameToken wsu:Id=\"UsernameToken-29477163\" 
xmlns:wsu=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd\";>"
         + "<wsse:Username></wsse:Username>"
-        + "<wsse:Password></wsse:Password>"
+        + "<wsse:Password 
Type=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText\";></wsse:Password>"
         + "</wsse:UsernameToken></wsse:Security></SOAP-ENV:Header>"
         + "<SOAP-ENV:Body>" 
         + "<add xmlns=\"http://ws.apache.org/counter/counter_port_type\";>" 
@@ -329,7 +329,18 @@ public class UsernameTokenTest extends o
                 
org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(doc);
             LOG.debug(outputString);
         }
-        verify(doc);
+        
+        WSSecurityEngine newEngine = new WSSecurityEngine();
+        try {
+            newEngine.processSecurityHeader(doc, null, callbackHandler, null);
+            fail("Expected failure as it is not BSP compliant");
+        } catch (WSSecurityException ex) {
+            // expected
+        }
+        WSSConfig config = WSSConfig.getNewInstance();
+        config.setWsiBSPCompliant(false);
+        newEngine.setWssConfig(config);
+        newEngine.processSecurityHeader(doc, null, callbackHandler, null);
     }
     
     /**

Modified: 
webservices/wss4j/trunk/src/test/java/org/apache/ws/security/message/token/WCFUsernameTokenTest.java
URL: 
http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/test/java/org/apache/ws/security/message/token/WCFUsernameTokenTest.java?rev=1076716&r1=1076715&r2=1076716&view=diff
==============================================================================
--- 
webservices/wss4j/trunk/src/test/java/org/apache/ws/security/message/token/WCFUsernameTokenTest.java
 (original)
+++ 
webservices/wss4j/trunk/src/test/java/org/apache/ws/security/message/token/WCFUsernameTokenTest.java
 Thu Mar  3 18:26:57 2011
@@ -59,6 +59,12 @@ public class WCFUsernameTokenTest extend
     
     private WSSecurityEngine secEngine = new WSSecurityEngine();
     private CallbackHandler callbackHandler = new 
UsernamePasswordCallbackHandler();
+    
+    public WCFUsernameTokenTest() {
+        WSSConfig config = WSSConfig.getNewInstance();
+        config.setWsiBSPCompliant(false);
+        secEngine.setWssConfig(config);
+    }
 
     /**
      * Test that adds a UserNameToken with a namespace qualified type. This 
should fail


Reply via email to