You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by dk...@apache.org on 2008/09/22 20:51:10 UTC

svn commit: r697942 [2/2] - in /cxf/trunk: api/src/main/java/org/apache/cxf/service/model/ api/src/main/java/org/apache/cxf/ws/policy/ common/common/src/main/java/org/apache/cxf/helpers/ rt/ws/policy/src/main/java/org/apache/cxf/ws/policy/ rt/ws/policy...

Added: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/AsymmetricBindingHandler.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/AsymmetricBindingHandler.java?rev=697942&view=auto
==============================================================================
--- cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/AsymmetricBindingHandler.java (added)
+++ cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/AsymmetricBindingHandler.java Mon Sep 22 11:51:08 2008
@@ -0,0 +1,503 @@
+/**
+ * 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.cxf.ws.security.wss4j.policyhandlers;
+
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.Vector;
+
+import javax.xml.soap.SOAPMessage;
+
+import org.w3c.dom.Element;
+
+import org.apache.cxf.binding.soap.SoapMessage;
+import org.apache.cxf.ws.policy.AssertionInfo;
+import org.apache.cxf.ws.policy.AssertionInfoMap;
+import org.apache.cxf.ws.security.policy.SP12Constants;
+import org.apache.cxf.ws.security.policy.SPConstants;
+import org.apache.cxf.ws.security.policy.model.AlgorithmSuite;
+import org.apache.cxf.ws.security.policy.model.AsymmetricBinding;
+import org.apache.cxf.ws.security.policy.model.RecipientToken;
+import org.apache.cxf.ws.security.policy.model.SupportingToken;
+import org.apache.cxf.ws.security.policy.model.Token;
+import org.apache.cxf.ws.security.policy.model.TokenWrapper;
+import org.apache.cxf.ws.security.policy.model.Wss10;
+import org.apache.cxf.ws.security.policy.model.Wss11;
+import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.WSEncryptionPart;
+import org.apache.ws.security.WSSecurityEngineResult;
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.security.handler.WSHandlerConstants;
+import org.apache.ws.security.handler.WSHandlerResult;
+import org.apache.ws.security.message.WSSecBase;
+import org.apache.ws.security.message.WSSecDKEncrypt;
+import org.apache.ws.security.message.WSSecDKSign;
+import org.apache.ws.security.message.WSSecEncrypt;
+import org.apache.ws.security.message.WSSecEncryptedKey;
+import org.apache.ws.security.message.WSSecHeader;
+import org.apache.ws.security.message.WSSecSignature;
+import org.apache.ws.security.message.WSSecSignatureConfirmation;
+import org.apache.ws.security.message.WSSecTimestamp;
+import org.apache.ws.security.util.WSSecurityUtil;
+
+/**
+ * 
+ */
+public class AsymmetricBindingHandler extends BindingBuilder {
+    AsymmetricBinding abinding;
+    
+    private WSSecEncryptedKey encrKey;
+    private String encryptedKeyId;
+    private byte[] encryptedKeyValue;
+    
+    private Map<Token, WSSecBase> sigSuppTokMap;
+    private Map<Token, WSSecBase> sgndEndSuppTokMap;
+    private Map<Token, WSSecBase> sgndEncSuppTokMap;
+    private Map<Token, WSSecBase> sgndEndEncSuppTokMap;
+    private Map<Token, WSSecBase> endSuppTokMap;
+    private Map<Token, WSSecBase> endEncSuppTokMap;
+
+    
+    public AsymmetricBindingHandler(AsymmetricBinding binding,
+                                    SOAPMessage saaj,
+                                    WSSecHeader secHeader,
+                                    AssertionInfoMap aim,
+                                    SoapMessage message) {
+        super(binding, saaj, secHeader, aim, message);
+        this.abinding = binding;
+    }
+    
+    public void handleBinding() {
+        WSSecTimestamp timestamp = createTimestamp();
+        timestamp = handleLayout(timestamp);
+        
+        if (abinding.getProtectionOrder() == SPConstants.ProtectionOrder.EncryptBeforeSigning) {
+            doEncryptBeforeSign();
+        } else {
+            doSignBeforeEncrypt();
+        }
+
+        if (timestamp != null) {
+            timestamp.prependToHeader(secHeader);
+        }
+    }
+
+
+    private void doSignBeforeEncrypt() {
+        try {
+            Vector<WSEncryptionPart> sigs = getSignedParts();
+            if (isRequestor()) {
+                SupportingToken sgndSuppTokens = 
+                    (SupportingToken)findPolicy(SP12Constants.SIGNED_SUPPORTING_TOKENS);
+                
+                sigSuppTokMap = this.handleSupportingTokens(sgndSuppTokens);           
+                
+                SupportingToken endSuppTokens = 
+                    (SupportingToken)findPolicy(SP12Constants.ENDORSING_SUPPORTING_TOKENS);
+                
+                endSuppTokMap = this.handleSupportingTokens(endSuppTokens);
+                
+                SupportingToken sgndEndSuppTokens 
+                    = (SupportingToken)findPolicy(SP12Constants.SIGNED_ENDORSING_SUPPORTING_TOKENS);
+                sgndEndSuppTokMap = this.handleSupportingTokens(sgndEndSuppTokens);
+                
+                SupportingToken sgndEncryptedSuppTokens 
+                    = (SupportingToken)findPolicy(SP12Constants.SIGNED_ENCRYPTED_SUPPORTING_TOKENS);
+                sgndEncSuppTokMap = this.handleSupportingTokens(sgndEncryptedSuppTokens);
+                
+                SupportingToken endorsingEncryptedSuppTokens 
+                    = (SupportingToken)findPolicy(SP12Constants.ENDORSING_ENCRYPTED_SUPPORTING_TOKENS);
+                endEncSuppTokMap = this.handleSupportingTokens(endorsingEncryptedSuppTokens);
+                
+                SupportingToken sgndEndEncSuppTokens 
+                    = (SupportingToken)findPolicy(SP12Constants.SIGNED_ENDORSING_ENCRYPTED_SUPPORTING_TOKENS);
+                sgndEndEncSuppTokMap = this.handleSupportingTokens(sgndEndEncSuppTokens);
+                
+                SupportingToken supportingToks 
+                    = (SupportingToken)findPolicy(SP12Constants.SUPPORTING_TOKENS);
+                this.handleSupportingTokens(supportingToks);
+                
+                SupportingToken encryptedSupportingToks 
+                    = (SupportingToken)findPolicy(SP12Constants.ENCRYPTED_SUPPORTING_TOKENS);
+                this.handleSupportingTokens(encryptedSupportingToks);
+            
+                //Setup signature parts
+                addSignatureParts(sigSuppTokMap, sigs);
+                addSignatureParts(sgndEncSuppTokMap, sigs);
+                addSignatureParts(sgndEndSuppTokMap, sigs);
+                addSignatureParts(sgndEndEncSuppTokMap, sigs);
+
+                
+                //Add timestamp
+                if (timestampEl != null) {
+                    Element el = timestampEl.getElement();
+                    sigs.add(new WSEncryptionPart(addWsuIdToElement(el)));
+                }
+                doSignature(sigs);
+                doEndorse();
+                
+            } else {
+                //confirm sig
+                addSignatureConfirmation(sigs);
+                doSignature(sigs);
+            }
+
+            Vector<WSEncryptionPart> enc = getEncryptedParts();
+            doEncyption(enc);
+        } catch (Exception e) {
+            e.printStackTrace();
+            //REVISIT!!
+        }
+    }
+
+    private void doEncryptBeforeSign() {
+        // REVISIT 
+        
+    }
+    
+    
+    protected void addSignatureConfirmation(Vector<WSEncryptionPart> sigParts) {
+        Wss10 wss10 = getWss10();
+        
+        if (!(wss10 instanceof Wss11) 
+            || !((Wss11)wss10).isRequireSignatureConfirmation()) {
+            //If we don't require sig confirmation simply go back :-)
+            return;
+        }
+        
+        Vector results = (Vector)message.getExchange().getInMessage().get(WSHandlerConstants.RECV_RESULTS);
+        /*
+         * loop over all results gathered by all handlers in the chain. For each
+         * handler result get the various actions. After that loop we have all
+         * signature results in the signatureActions vector
+         */
+        Vector signatureActions = new Vector();
+        for (int i = 0; i < results.size(); i++) {
+            WSHandlerResult wshResult = (WSHandlerResult) results.get(i);
+
+            WSSecurityUtil.fetchAllActionResults(wshResult.getResults(),
+                    WSConstants.SIGN, signatureActions);
+            WSSecurityUtil.fetchAllActionResults(wshResult.getResults(),
+                    WSConstants.ST_SIGNED, signatureActions);
+            WSSecurityUtil.fetchAllActionResults(wshResult.getResults(),
+                    WSConstants.UT_SIGN, signatureActions);
+        }
+        
+        // prepare a SignatureConfirmation token
+        WSSecSignatureConfirmation wsc = new WSSecSignatureConfirmation();
+        if (signatureActions.size() > 0) {
+            for (int i = 0; i < signatureActions.size(); i++) {
+                WSSecurityEngineResult wsr = (WSSecurityEngineResult) signatureActions
+                        .get(i);
+                byte[] sigVal = (byte[]) wsr.get(WSSecurityEngineResult.TAG_SIGNATURE_VALUE);
+                wsc.setSignatureValue(sigVal);
+                wsc.prepare(saaj.getSOAPPart());
+                wsc.prependToHeader(secHeader);
+                if (sigParts != null) {
+                    sigParts.add(new WSEncryptionPart(wsc.getId()));
+                }
+            }
+        } else {
+            //No Sig value
+            wsc.prepare(saaj.getSOAPPart());
+            wsc.prependToHeader(secHeader);
+            if (sigParts != null) {
+                sigParts.add(new WSEncryptionPart(wsc.getId()));
+            }
+        }
+    }
+
+    
+    private void doEndorse() {
+        // Adding the endorsing encrypted supporting tokens to endorsing supporting tokens
+        endSuppTokMap.putAll(endEncSuppTokMap);
+        // Do endorsed signatures
+        doEndorsedSignatures(endSuppTokMap, abinding.isTokenProtection());
+
+        //Adding the signed endorsed encrypted tokens to signed endorsed supporting tokens
+        sgndEndSuppTokMap.putAll(sgndEndEncSuppTokMap);
+        // Do signed endorsing signatures
+        doEndorsedSignatures(sgndEndSuppTokMap, abinding.isTokenProtection());
+    }    
+    
+    private void doEncyption(Vector<WSEncryptionPart> encrParts) {
+        //Check for signature protection
+        if (abinding.isSignatureProtection() && mainSigId != null) {
+            encrParts.add(new WSEncryptionPart(mainSigId, "Element"));
+        }
+        
+        if (isRequestor()) {
+            for (String id : encryptedTokensIdList) {
+                encrParts.add(new WSEncryptionPart(id, "Element"));
+            }
+        }
+
+        //Do encryption
+        RecipientToken recToken = abinding.getRecipientToken();
+        if (recToken != null && recToken.getRecipientToken() != null && encrParts.size() > 0) {
+            Token encrToken = recToken.getRecipientToken();
+            policyAsserted(recToken);
+            policyAsserted(encrToken);
+            Element refList = null;
+            AlgorithmSuite algorithmSuite = abinding.getAlgorithmSuite();
+            if (encrToken.isDerivedKeys()) {
+                try {
+                    WSSecDKEncrypt dkEncr = new WSSecDKEncrypt();
+                    
+                    if (encrKey == null) {
+                        setupEncryptedKey(recToken, encrToken);
+                    }
+                    
+                    dkEncr.setExternalKey(this.encryptedKeyValue, this.encryptedKeyId);
+                    dkEncr.setCustomValueType(WSConstants.SOAPMESSAGE_NS11 + "#"
+                            + WSConstants.ENC_KEY_VALUE_TYPE);
+                    dkEncr.setSymmetricEncAlgorithm(algorithmSuite.getEncryption());
+                    dkEncr.setDerivedKeyLength(algorithmSuite.getEncryptionDerivedKeyLength() / 8);
+                    dkEncr.prepare(saaj.getSOAPPart());
+                    
+                    dkEncr.prependDKElementToHeader(secHeader);
+                    refList = dkEncr.encryptForExternalRef(null, encrParts);
+                    
+                } catch (Exception e) {
+                    policyNotAsserted(recToken, e);
+                }
+            } else {
+                try {
+                    WSSecEncrypt encr = new WSSecEncrypt();
+                    
+                    setKeyIdentifierType(encr, recToken, encrToken);
+                    
+                    encr.setDocument(saaj.getSOAPPart());
+                    setEncryptionUser(encr, encrToken, false);
+                    encr.setSymmetricEncAlgorithm(algorithmSuite.getEncryption());
+                    encr.setKeyEncAlgo(algorithmSuite.getAsymmetricKeyWrap());
+                    
+                    encr.prepare(saaj.getSOAPPart(),
+                                 getEncryptionCrypto(recToken));
+                    
+                    if (encr.getBSTTokenId() != null) {
+                        encr.appendBSTElementToHeader(secHeader);
+                    }
+                    
+                    
+                    Element encryptedKeyElement = encr.getEncryptedKeyElement();
+                                       
+                    //Encrypt, get hold of the ref list and add it
+                    refList = encr.encryptForInternalRef(null, encrParts);
+                    
+                    //Add internal refs
+                    encryptedKeyElement.appendChild(refList);
+                    
+                    encr.prependToHeader(secHeader);
+
+                } catch (WSSecurityException e) {
+                    policyNotAsserted(recToken, e.getMessage());
+                }    
+            }
+        }
+    }    
+    
+    private void assertUnusedTokens(TokenWrapper wrapper) {
+        Collection<AssertionInfo> ais = aim.getAssertionInfo(wrapper.getName());
+        for (AssertionInfo ai : ais) {
+            if (ai.getAssertion() == wrapper) {
+                ai.setAsserted(true);
+            }
+        }
+        ais = aim.getAssertionInfo(wrapper.getToken().getName());
+        for (AssertionInfo ai : ais) {
+            if (ai.getAssertion() == wrapper.getToken()) {
+                ai.setAsserted(true);
+            }
+        }
+    }
+    private void doSignature(Vector<WSEncryptionPart> sigParts) throws WSSecurityException {
+        Token sigToken = null;
+        TokenWrapper wrapper = null;
+        if (isRequestor()) {
+            wrapper = abinding.getInitiatorToken();
+        } else {
+            wrapper = abinding.getRecipientToken();
+            assertUnusedTokens(abinding.getInitiatorToken());
+        }
+        sigToken = wrapper.getToken();
+
+        if (sigToken.isDerivedKeys()) {
+            // Set up the encrypted key to use
+            setupEncryptedKey(wrapper, sigToken);
+            
+            WSSecDKSign dkSign = new WSSecDKSign();
+            dkSign.setExternalKey(this.encryptedKeyValue, this.encryptedKeyId);
+
+            // Set the algo info
+            dkSign.setSignatureAlgorithm(abinding.getAlgorithmSuite()
+                    .getSymmetricSignature());
+            dkSign.setDerivedKeyLength(abinding.getAlgorithmSuite()
+                    .getSignatureDerivedKeyLength() / 8);
+            dkSign.setCustomValueType(WSConstants.SOAPMESSAGE_NS11 + "#"
+                    + WSConstants.ENC_KEY_VALUE_TYPE);
+            
+            try {
+                dkSign.prepare(saaj.getSOAPPart(), secHeader);
+
+                if (abinding.isTokenProtection()) {
+                    sigParts.add(new WSEncryptionPart(encrKey.getId()));
+                }
+
+                dkSign.setParts(sigParts);
+
+                dkSign.addReferencesToSign(sigParts, secHeader);
+
+                // Do signature
+                dkSign.computeSignature();
+
+                // Add elements to header
+                dkSign.appendDKElementToHeader(secHeader);
+                dkSign.appendSigToHeader(secHeader);
+                
+                mainSigId = addWsuIdToElement(dkSign.getSignatureElement());
+            } catch (Exception e) {
+                //REVISIT
+                e.printStackTrace();
+            }
+        } else {
+            WSSecSignature sig = getSignatureBuider(wrapper, sigToken);
+            sig.prependBSTElementToHeader(secHeader);
+            
+            if (abinding.isTokenProtection()
+                    && sig.getBSTTokenId() != null) {
+                sigParts.add(new WSEncryptionPart(sig.getBSTTokenId()));
+            }
+
+            sig.addReferencesToSign(sigParts, secHeader);
+            sig.computeSignature();
+
+            sig.prependToHeader(secHeader);
+
+            mainSigId = addWsuIdToElement(sig.getSignatureElement());
+        }
+    }
+
+    private void setupEncryptedKey(TokenWrapper wrapper, Token token) throws WSSecurityException {
+        if (!isRequestor() && token.isDerivedKeys()) {
+            //If we already have them, simply return
+            if (encryptedKeyId != null && encryptedKeyValue != null) {
+                return;
+            }
+            
+            //Use the secret from the incoming EncryptedKey element
+            Object resultsObj = message.getExchange().getInMessage().get(WSHandlerConstants.RECV_RESULTS);
+            if (resultsObj != null) {
+                encryptedKeyId = getRequestEncryptedKeyId((Vector)resultsObj);
+                encryptedKeyValue = getRequestEncryptedKeyValue((Vector)resultsObj);
+                
+                //In the case where we don't have the EncryptedKey in the 
+                //request, for the control to have reached this state,
+                //the scenario MUST be a case where this is the response
+                //message by a listener created for an async client
+                //Therefor we will create a new EncryptedKey
+                if (encryptedKeyId == null && encryptedKeyValue == null) {
+                    createEncryptedKey(wrapper, token);
+                }
+            } else {
+                policyNotAsserted(token, "No security results found");
+            }
+        } else {
+            createEncryptedKey(wrapper, token);
+        }
+    }
+    public static String getRequestEncryptedKeyId(Vector results) {
+        
+        for (int i = 0; i < results.size(); i++) {
+            WSHandlerResult rResult =
+                    (WSHandlerResult) results.get(i);
+
+            Vector wsSecEngineResults = rResult.getResults();
+            /*
+            * Scan the results for the first Signature action. Use the
+            * certificate of this Signature to set the certificate for the
+            * encryption action :-).
+            */
+            for (int j = 0; j < wsSecEngineResults.size(); j++) {
+                WSSecurityEngineResult wser =
+                        (WSSecurityEngineResult) wsSecEngineResults.get(j);
+                Integer actInt = (Integer)wser.get(WSSecurityEngineResult.TAG_ACTION);
+                String encrKeyId = (String)wser.get(WSSecurityEngineResult.TAG_ENCRYPTED_KEY_ID);
+                if (actInt.intValue() == WSConstants.ENCR
+                    && encrKeyId != null) {
+                    return encrKeyId;
+                }
+            }
+        }
+        
+        return null;
+    }
+    
+    public static byte[] getRequestEncryptedKeyValue(Vector results) {
+        
+        for (int i = 0; i < results.size(); i++) {
+            WSHandlerResult rResult =
+                    (WSHandlerResult) results.get(i);
+
+            Vector wsSecEngineResults = rResult.getResults();
+            /*
+            * Scan the results for the first Signature action. Use the
+            * certificate of this Signature to set the certificate for the
+            * encryption action :-).
+            */
+            for (int j = 0; j < wsSecEngineResults.size(); j++) {
+                WSSecurityEngineResult wser =
+                        (WSSecurityEngineResult) wsSecEngineResults.get(j);
+                Integer actInt = (Integer)wser.get(WSSecurityEngineResult.TAG_ACTION);
+                byte[] decryptedKey = (byte[])wser.get(WSSecurityEngineResult.TAG_DECRYPTED_KEY);
+                if (actInt.intValue() == WSConstants.ENCR 
+                    && decryptedKey != null) {
+                    return decryptedKey;
+                }
+            }
+        }
+        
+        return null;
+    }
+    
+    private void createEncryptedKey(TokenWrapper wrapper, Token token)
+        throws WSSecurityException {
+        //Set up the encrypted key to use
+        encrKey = this.getEncryptedKeyBuilder(wrapper, token);
+        Element bstElem = encrKey.getBinarySecurityTokenElement();
+        if (bstElem != null) {
+            // If a BST is available then use it
+            encrKey.prependBSTElementToHeader(secHeader);
+        }
+        
+        // Add the EncryptedKey
+        encrKey.prependToHeader(secHeader);
+        encryptedKeyValue = encrKey.getEphemeralKey();
+        encryptedKeyId = encrKey.getId();
+        
+        //Store the token for client - response verification 
+        // and server - response creation
+        message.put(WSSecEncryptedKey.class.getName(), encrKey);
+    }
+
+
+
+}

Propchange: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/AsymmetricBindingHandler.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/AsymmetricBindingHandler.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Propchange: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/AsymmetricBindingHandler.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/BindingBuilder.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/BindingBuilder.java?rev=697942&r1=697941&r2=697942&view=diff
==============================================================================
--- cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/BindingBuilder.java (original)
+++ cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/BindingBuilder.java Mon Sep 22 11:51:08 2008
@@ -19,35 +19,99 @@
 
 package org.apache.cxf.ws.security.wss4j.policyhandlers;
 
+import java.io.IOException;
+import java.net.URL;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
 import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.Vector;
+import java.util.logging.Level;
+import java.util.logging.Logger;
 
 import javax.security.auth.callback.CallbackHandler;
+import javax.xml.namespace.QName;
+import javax.xml.soap.SOAPException;
+import javax.xml.soap.SOAPHeader;
 import javax.xml.soap.SOAPMessage;
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpressionException;
+import javax.xml.xpath.XPathFactory;
 
+import org.w3c.dom.Attr;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
+import org.apache.cxf.Bus;
 import org.apache.cxf.binding.soap.SoapMessage;
+import org.apache.cxf.common.classloader.ClassLoaderUtils;
+import org.apache.cxf.common.logging.LogUtils;
 import org.apache.cxf.common.util.StringUtils;
+import org.apache.cxf.helpers.DOMUtils;
+import org.apache.cxf.helpers.MapNamespaceContext;
+import org.apache.cxf.resource.ResourceManager;
 import org.apache.cxf.ws.policy.AssertionInfo;
 import org.apache.cxf.ws.policy.AssertionInfoMap;
+import org.apache.cxf.ws.policy.PolicyAssertion;
+import org.apache.cxf.ws.policy.PolicyConstants;
 import org.apache.cxf.ws.security.SecurityConstants;
+import org.apache.cxf.ws.security.policy.SP12Constants;
+import org.apache.cxf.ws.security.policy.SPConstants;
 import org.apache.cxf.ws.security.policy.model.Binding;
+import org.apache.cxf.ws.security.policy.model.Header;
+import org.apache.cxf.ws.security.policy.model.IssuedToken;
+import org.apache.cxf.ws.security.policy.model.Layout;
+import org.apache.cxf.ws.security.policy.model.SignedEncryptedElements;
+import org.apache.cxf.ws.security.policy.model.SignedEncryptedParts;
 import org.apache.cxf.ws.security.policy.model.SupportingToken;
 import org.apache.cxf.ws.security.policy.model.Token;
+import org.apache.cxf.ws.security.policy.model.TokenWrapper;
 import org.apache.cxf.ws.security.policy.model.UsernameToken;
+import org.apache.cxf.ws.security.policy.model.Wss10;
+import org.apache.cxf.ws.security.policy.model.Wss11;
+import org.apache.cxf.ws.security.policy.model.X509Token;
+import org.apache.cxf.wsdl.WSDLConstants;
 import org.apache.velocity.util.ClassUtils;
 import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.WSEncryptionPart;
 import org.apache.ws.security.WSPasswordCallback;
+import org.apache.ws.security.WSSecurityEngineResult;
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.security.WSUsernameTokenPrincipal;
+import org.apache.ws.security.components.crypto.Crypto;
+import org.apache.ws.security.components.crypto.CryptoFactory;
+import org.apache.ws.security.handler.WSHandlerConstants;
+import org.apache.ws.security.handler.WSHandlerResult;
+import org.apache.ws.security.message.WSSecBase;
+import org.apache.ws.security.message.WSSecEncryptedKey;
 import org.apache.ws.security.message.WSSecHeader;
+import org.apache.ws.security.message.WSSecSignature;
+import org.apache.ws.security.message.WSSecTimestamp;
 import org.apache.ws.security.message.WSSecUsernameToken;
 
 /**
  * 
  */
 public class BindingBuilder {
-    SOAPMessage saaj;
-    WSSecHeader secHeader;
-    AssertionInfoMap aim;
-    Binding binding;
-    SoapMessage message;
+    private static final Logger LOG = LogUtils.getL7dLogger(BindingBuilder.class); 
+    
+    protected SOAPMessage saaj;
+    protected WSSecHeader secHeader;
+    protected AssertionInfoMap aim;
+    protected Binding binding;
+    protected SoapMessage message;
+    protected WSSecTimestamp timestampEl;
+    protected String mainSigId;
+    
+    protected Set<String> encryptedTokensIdList = new HashSet<String>();
+
+
     
     public BindingBuilder(Binding binding,
                            SOAPMessage saaj,
@@ -62,25 +126,156 @@
     }
 
     
-    private boolean isRequestor() {
+    protected boolean isRequestor() {
         return Boolean.TRUE.equals(message.containsKey(
             org.apache.cxf.message.Message.REQUESTOR_ROLE));
     }  
+    protected void policyNotAsserted(PolicyAssertion assertion, Exception reason) {
+        LOG.log(Level.INFO, "Not asserting " + assertion.getName(), reason);
+        Collection<AssertionInfo> ais;
+        ais = aim.get(assertion.getName());
+        if (ais != null) {
+            for (AssertionInfo ai : ais) {
+                if (ai.getAssertion() == assertion) {
+                    ai.setNotAsserted(reason.getMessage());
+                }
+            }
+        }
+    }
+    protected void policyNotAsserted(PolicyAssertion assertion, String reason) {
+        Collection<AssertionInfo> ais;
+        ais = aim.get(assertion.getName());
+        if (ais != null) {
+            for (AssertionInfo ai : ais) {
+                if (ai.getAssertion() == assertion) {
+                    ai.setNotAsserted(reason);
+                }
+            }
+        }
+    }
+    protected void policyAsserted(PolicyAssertion assertion) {
+        Collection<AssertionInfo> ais;
+        ais = aim.get(assertion.getName());
+        if (ais != null) {
+            for (AssertionInfo ai : ais) {
+                if (ai.getAssertion() == assertion) {
+                    ai.setAsserted(true);
+                }
+            }
+        }
+    }
     
+    protected PolicyAssertion findPolicy(QName n) {
+        Collection<AssertionInfo> ais = aim.getAssertionInfo(n);
+        if (ais != null && !ais.isEmpty()) {
+            return ais.iterator().next().getAssertion();
+        }
+        return null;
+    }
+        
+    protected WSSecTimestamp createTimestamp() {
+        Collection<AssertionInfo> ais;
+        ais = aim.get(SP12Constants.INCLUDE_TIMESTAMP);
+        if (ais != null) {
+            for (AssertionInfo ai : ais) {
+                timestampEl = new WSSecTimestamp();
+                timestampEl.prepare(saaj.getSOAPPart());
+                ai.setAsserted(true);
+            }                    
+        }
+        return timestampEl;
+    }
     
-    protected void handleSupportingTokens(SupportingToken suppTokens) {
+    protected WSSecTimestamp handleLayout(WSSecTimestamp timestamp) {
+        Collection<AssertionInfo> ais;
+        ais = aim.get(SP12Constants.LAYOUT);
+        if (ais != null) {
+            for (AssertionInfo ai : ais) {
+                Layout layout = (Layout)ai.getAssertion();
+                if (SPConstants.Layout.LaxTimestampLast == layout.getValue()) {
+                    if (timestamp == null) {
+                        ai.setNotAsserted(SPConstants.Layout.LaxTimestampLast + " requires a timestamp");
+                    } else {
+                        ai.setAsserted(true);
+                        //get the timestamp into the header first before anything else
+                        timestamp.prependToHeader(secHeader);
+                        timestamp = null;
+                    }
+                } else if (SPConstants.Layout.Strict == layout.getValue()) {
+                    //FIXME - don't have strict writing working yet
+                    ai.setAsserted(false);
+                } else if (SPConstants.Layout.Lax == layout.getValue()) {
+                    ai.setAsserted(true);                            
+                    //go ahead and put the timestamp in
+                    timestamp.prependToHeader(secHeader);
+                    timestamp = null;
+                } else {
+                    ai.setAsserted(true);                            
+                }
+            }                    
+        }
+        return timestamp;
+    }
+    
+    protected Map<Token, WSSecBase> handleSupportingTokens(SupportingToken suppTokens) {
+        Map<Token, WSSecBase> ret = new HashMap<Token, WSSecBase>();
+        if (suppTokens == null) {
+            return ret;
+        }
         for (Token token : suppTokens.getTokens()) {
             if (token instanceof UsernameToken) {
                 WSSecUsernameToken utBuilder = addUsernameToken((UsernameToken)token);
                 if (utBuilder != null) {
                     utBuilder.prepare(saaj.getSOAPPart());
                     utBuilder.appendToHeader(secHeader);
+                    ret.put(token, utBuilder);
+                    encryptedTokensIdList.add(utBuilder.getId());
                 }
-            }
+            } else if (token instanceof IssuedToken && isRequestor()) {
+                //ws-trust stuff.......
+                //REVISIT
+                policyNotAsserted(token, "Issued token not yet supported");
+            } else if (token instanceof X509Token) {
+
+                //We have to use a cert
+                //Prepare X509 signature
+                WSSecSignature sig = getSignatureBuider(suppTokens, token);
+                Element bstElem = sig.getBinarySecurityTokenElement();
+                if (bstElem != null) {
+                    sig.appendBSTElementToHeader(secHeader);
+                }
+                if (suppTokens.isEncryptedToken()) {
+                    encryptedTokensIdList.add(sig.getBSTTokenId());
+                }
+                ret.put(token, sig);
+            }         
+            
         }
+        return ret;
     }
     
-    
+    protected void addSignatureParts(Map<Token, WSSecBase> tokenMap,
+                                                         List<WSEncryptionPart> sigParts) {
+        
+        for (Map.Entry<Token, WSSecBase> entry : tokenMap.entrySet()) {
+            
+            Object tempTok =  entry.getValue();
+            WSEncryptionPart part = null;
+            
+            if (tempTok instanceof WSSecSignature) {
+                WSSecSignature tempSig = (WSSecSignature) tempTok;
+                if (tempSig.getBSTTokenId() != null) {
+                    part = new WSEncryptionPart(tempSig.getBSTTokenId());
+                }
+            } else {
+                policyNotAsserted(entry.getKey(), "UnsupportedTokenInSupportingToken");  
+            }
+            if (part != null) {
+                sigParts.add(part);
+            }
+        }
+    }
+
     
     protected WSSecUsernameToken addUsernameToken(UsernameToken token) {
         
@@ -110,35 +305,7 @@
             
             String password = (String)message.getContextualProperty(SecurityConstants.PASSWORD);
             if (StringUtils.isEmpty(password)) {
-                
-                //Then try to get the password from the given callback handler
-                Object o = message.getContextualProperty(SecurityConstants.CALLBACK_HANDLER);
-            
-                CallbackHandler handler = null;
-                if (o instanceof CallbackHandler) {
-                    handler = (CallbackHandler)o;
-                } else if (o instanceof String) {
-                    try {
-                        handler = (CallbackHandler)ClassUtils.getNewInstance(o.toString());
-                    } catch (Exception e) {
-                        handler = null;
-                    }
-                }
-                if (handler == null) {
-                    info.setNotAsserted("No callback handler and not password available");
-                    return null;
-                }
-                
-                WSPasswordCallback[] cb = {new WSPasswordCallback(userName,
-                                                                  WSPasswordCallback.USERNAME_TOKEN)};
-                try {
-                    handler.handle(cb);
-                } catch (Exception e) {
-                    //REVISIT - Exception?
-                }
-                
-                //get the password
-                password = cb[0].getPassword();
+                password = getPassword(userName, token, WSPasswordCallback.USERNAME_TOKEN);
             }
             
             if (!StringUtils.isEmpty(password)) {
@@ -161,5 +328,528 @@
         }
         return null;
     }
+    public String getPassword(String userName, PolicyAssertion info, int type) {
+      //Then try to get the password from the given callback handler
+        Object o = message.getContextualProperty(SecurityConstants.CALLBACK_HANDLER);
+    
+        CallbackHandler handler = null;
+        if (o instanceof CallbackHandler) {
+            handler = (CallbackHandler)o;
+        } else if (o instanceof String) {
+            try {
+                handler = (CallbackHandler)ClassUtils.getNewInstance(o.toString());
+            } catch (Exception e) {
+                handler = null;
+            }
+        }
+        if (handler == null) {
+            policyNotAsserted(info, "No callback handler and no password available");
+            return null;
+        }
+        
+        WSPasswordCallback[] cb = {new WSPasswordCallback(userName,
+                                                          type)};
+        try {
+            handler.handle(cb);
+        } catch (Exception e) {
+            policyNotAsserted(info, e);
+        }
+        
+        //get the password
+        return cb[0].getPassword();
+    }
+
+    public String addWsuIdToElement(Element elem) {
+        String id;
+        
+        //first try to get the Id attr
+        Attr idAttr = elem.getAttributeNode("Id");
+        if (idAttr == null) {
+            //then try the wsu:Id value
+            idAttr = elem.getAttributeNodeNS(PolicyConstants.WSU_NAMESPACE_URI, "Id");
+        }
+        
+        if (idAttr != null) {
+            id = idAttr.getValue();
+        } else {
+            //Add an id
+            id = "Id-" + elem.hashCode();
+            String pfx = elem.lookupPrefix(PolicyConstants.WSU_NAMESPACE_URI);
+            boolean found = !StringUtils.isEmpty(pfx);
+            int cnt = 0;
+            while (StringUtils.isEmpty(pfx)) {
+                pfx = "wsu" + (cnt == 0 ? "" : cnt);
+                if (!StringUtils.isEmpty(elem.lookupNamespaceURI(pfx))) {
+                    pfx = null;
+                    cnt++;
+                }
+            }
+            if (!found) {
+                idAttr = elem.getOwnerDocument().createAttributeNS(WSDLConstants.NS_XMLNS, "xmlns:" + pfx);
+                idAttr.setValue(PolicyConstants.WSU_NAMESPACE_URI);
+                elem.setAttributeNodeNS(idAttr);
+            }
+            idAttr = elem.getOwnerDocument().createAttributeNS(PolicyConstants.WSU_NAMESPACE_URI, 
+                                                               pfx + ":Id");
+            idAttr.setValue(id);
+            elem.setAttributeNodeNS(idAttr);
+        }
+        
+        return id;
+    }
+
+    public Vector<WSEncryptionPart> getEncryptedParts() 
+        throws SOAPException {
+        
+        boolean isBody = false;
+        
+        SignedEncryptedParts parts = null;
+        SignedEncryptedElements elements = null;
+        
+        Collection<AssertionInfo> ais = aim.getAssertionInfo(SP12Constants.ENCRYPTED_PARTS);
+        if (ais != null) {
+            for (AssertionInfo ai : ais) {
+                parts = (SignedEncryptedParts)ai.getAssertion();
+                ai.setAsserted(true);
+            }            
+        }
+        ais = aim.getAssertionInfo(SP12Constants.ENCRYPTED_ELEMENTS);
+        if (ais != null) {
+            for (AssertionInfo ai : ais) {
+                elements = (SignedEncryptedElements)ai.getAssertion();
+                ai.setAsserted(true);
+            }            
+        }
+        
+        List<WSEncryptionPart> signedParts = new ArrayList<WSEncryptionPart>();
+        if (parts != null) {
+            isBody = parts.isBody();
+            for (Header head : parts.getHeaders()) {
+                WSEncryptionPart wep = new WSEncryptionPart(head.getName(),
+                                                            head.getNamespace(),
+                                                            "Content");
+                signedParts.add(wep);
+            }
+        }
+    
+        
+        return getPartsAndElements(false, 
+                                   isBody,
+                                   signedParts,
+                                   elements == null ? null : elements.getXPathExpressions(),
+                                   elements == null ? null : elements.getDeclaredNamespaces());
+    }    
+    
+    public Vector<WSEncryptionPart> getSignedParts() 
+        throws SOAPException {
+        
+        boolean isSignBody = false;
+        
+        SignedEncryptedParts parts = null;
+        SignedEncryptedElements elements = null;
+        
+        Collection<AssertionInfo> ais = aim.getAssertionInfo(SP12Constants.SIGNED_PARTS);
+        if (ais != null) {
+            for (AssertionInfo ai : ais) {
+                parts = (SignedEncryptedParts)ai.getAssertion();
+                ai.setAsserted(true);
+            }            
+        }
+        ais = aim.getAssertionInfo(SP12Constants.SIGNED_ELEMENTS);
+        if (ais != null) {
+            for (AssertionInfo ai : ais) {
+                elements = (SignedEncryptedElements)ai.getAssertion();
+                ai.setAsserted(true);
+            }            
+        }
+        
+        List<WSEncryptionPart> signedParts = new ArrayList<WSEncryptionPart>();
+        if (parts != null) {
+            isSignBody = parts.isBody();
+            for (Header head : parts.getHeaders()) {
+                WSEncryptionPart wep = new WSEncryptionPart(head.getName(),
+                                                            head.getNamespace(),
+                                                            "Content");
+                signedParts.add(wep);
+            }
+        }
+
+        
+        return getPartsAndElements(true, 
+                                   isSignBody,
+                                   signedParts,
+                                   elements == null ? null : elements.getXPathExpressions(),
+                                   elements == null ? null : elements.getDeclaredNamespaces());
+    }
+    public Vector<WSEncryptionPart> getPartsAndElements(boolean sign, 
+                                                    boolean includeBody,
+                                                    List<WSEncryptionPart> parts,
+                                                    List<String> xpaths, 
+                                                    Map<String, String> namespaces) 
+        throws SOAPException {
+        
+        Vector<WSEncryptionPart> result = new Vector<WSEncryptionPart>();
+        List<Element> found = new ArrayList<Element>();
+        if (includeBody) {
+            if (sign) {
+                result.add(new WSEncryptionPart(addWsuIdToElement(saaj.getSOAPBody())));
+            } else {
+                result.add(new WSEncryptionPart(addWsuIdToElement(saaj.getSOAPBody()),
+                                                "Content", WSConstants.PART_TYPE_BODY));
+            }
+            found.add(saaj.getSOAPBody());
+        }
+        SOAPHeader header = saaj.getSOAPHeader();
+        for (WSEncryptionPart part : parts) {
+            if (StringUtils.isEmpty(part.getName())) {
+                //an entire namespace
+                Element el = DOMUtils.getFirstElement(header);
+                while (el != null) {
+                    if (part.getNamespace().equals(el.getNamespaceURI())
+                        && !found.contains(el)) {
+                        found.add(el);
+                        
+                        if (sign) {
+                            result.add(new WSEncryptionPart(el.getLocalName(), 
+                                                            part.getNamespace(),
+                                                            "Content"));
+                        } else {
+                            WSEncryptionPart encryptedHeader 
+                                = new WSEncryptionPart(el.getLocalName(),
+                                                       part.getNamespace(), 
+                                                       "Element",
+                                                       WSConstants.PART_TYPE_HEADER);
+                            String wsuId = el.getAttributeNS(WSConstants.WSU_NS, "Id");
+                            
+                            if (!StringUtils.isEmpty(wsuId)) {
+                                encryptedHeader.setEncId(wsuId);
+                            }
+                            result.add(encryptedHeader);
+                        }
+                    }
+                }
+                el = DOMUtils.getNextElement(el);
+            } else {
+                Element el = DOMUtils.getFirstElement(header);
+                while (el != null) {
+                    if (part.getName().equals(el.getLocalName())
+                        && part.getNamespace().equals(el.getNamespaceURI())
+                        && !found.contains(el)) {
+                        found.add(el);          
+                        part.setType(WSConstants.PART_TYPE_HEADER);
+                        String wsuId = el.getAttributeNS(WSConstants.WSU_NS, "Id");
+                        
+                        if (!StringUtils.isEmpty(wsuId)) {
+                            part.setEncId(wsuId);
+                        }
+                        
+                        result.add(part);
+                    }
+                    el = DOMUtils.getNextElement(el);
+                }
+            }
+        }
+        if (xpaths != null && !xpaths.isEmpty()) {
+            XPathFactory factory = XPathFactory.newInstance();
+            for (String expression : xpaths) {
+                XPath xpath = factory.newXPath();
+                if (namespaces != null) {
+                    xpath.setNamespaceContext(new MapNamespaceContext(namespaces));
+                }
+                try {
+                    NodeList list = (NodeList)xpath.evaluate(expression, saaj.getSOAPPart().getEnvelope(),
+                                                   XPathConstants.NODESET);
+                    for (int x = 0; x < list.getLength(); x++) {
+                        Element el = (Element)list.item(x);
+                        if (sign) {
+                            result.add(new WSEncryptionPart(el.getLocalName(),
+                                                            el.getNamespaceURI(), 
+                                                            "Content"));
+                        } else {
+                            WSEncryptionPart encryptedElem = new WSEncryptionPart(el.getLocalName(),
+                                                                                  el.getNamespaceURI(),
+                                                                                  "Element");
+                            String wsuId = el.getAttributeNS(WSConstants.WSU_NS, "Id");
+                            
+                            if (!StringUtils.isEmpty(wsuId)) {
+                                encryptedElem.setEncId(wsuId);
+                            }
+                            result.add(encryptedElem);
+                        }
+                    }
+                } catch (XPathExpressionException e) {
+                    //REVISIT!!!!
+                }
+            }
+        }
+        return result;
+    }
+    
+    
+    protected WSSecEncryptedKey getEncryptedKeyBuilder(TokenWrapper wrapper, 
+                                                       Token token) throws WSSecurityException {
+        WSSecEncryptedKey encrKey = new WSSecEncryptedKey();
+        
+        setKeyIdentifierType(encrKey, wrapper, token);
+        setEncryptionUser(encrKey, token, false);
+        encrKey.setKeySize(binding.getAlgorithmSuite().getMaximumSymmetricKeyLength());
+        encrKey.setKeyEncAlgo(binding.getAlgorithmSuite().getAsymmetricKeyWrap());
+        
+        encrKey.prepare(saaj.getSOAPPart(), getEncryptionCrypto(wrapper));
+        
+        return encrKey;
+    }
+    public Crypto getSignatureCrypto(TokenWrapper wrapper) {
+        return getCrypto(wrapper, true);
+    }
+    public Crypto getEncryptionCrypto(TokenWrapper wrapper) {
+        return getCrypto(wrapper, false);
+    }
+    public Crypto getCrypto(TokenWrapper wrapper, boolean sign) {
+        Object o = message.getContextualProperty(sign 
+                                                 ? SecurityConstants.SIGNATURE_PROPERTIES 
+                                                 : SecurityConstants.ENCRYPT_PROPERTIES);
+        Properties properties = null;
+        if (o instanceof Properties) {
+            properties = (Properties)o;
+        } else if (o instanceof String) {
+            ResourceManager rm = message.getExchange().get(Bus.class).getExtension(ResourceManager.class);
+            URL url = rm.resolveResource((String)o, URL.class);
+            try {
+                if (url == null) {
+                    url = ClassLoaderUtils.getResource((String)o, this.getClass());
+                }
+                if (url != null) {
+                    properties = new Properties();
+                    properties.load(url.openStream());
+                } else {
+                    policyNotAsserted(wrapper, "Could not find properties file " + o);
+                }
+            } catch (IOException e) {
+                policyNotAsserted(wrapper, e);
+            }
+        } else if (o instanceof URL) {
+            properties = new Properties();
+            try {
+                properties.load(((URL)o).openStream());
+            } catch (IOException e) {
+                policyNotAsserted(wrapper, e);
+            }            
+        }
+        
+        if (properties != null) {
+            return CryptoFactory.getInstance(properties);
+        }
+        return null;
+    }
+    
+    public void setKeyIdentifierType(WSSecBase secBase, TokenWrapper wrapper, Token token) {
+        
+        if (token.getInclusion() == SPConstants.IncludeTokenType.INCLUDE_TOKEN_NEVER) {
+            boolean tokenTypeSet = false;
+            
+            if (token instanceof X509Token) {
+                X509Token x509Token = (X509Token)token;
+                if (x509Token.isRequireIssuerSerialReference()) {
+                    secBase.setKeyIdentifierType(WSConstants.ISSUER_SERIAL);
+                    tokenTypeSet = true;
+                } else if (x509Token.isRequireKeyIdentifierReference()) {
+                    secBase.setKeyIdentifierType(WSConstants.SKI_KEY_IDENTIFIER);
+                    tokenTypeSet = true;
+                } else if (x509Token.isRequireThumbprintReference()) {
+                    secBase.setKeyIdentifierType(WSConstants.THUMBPRINT_IDENTIFIER);
+                    tokenTypeSet = true;
+                }
+            } 
+            
+            if (!tokenTypeSet) {
+                policyAsserted(token);
+                policyAsserted(wrapper);
+                
+                Wss10 wss = getWss10();
+                policyAsserted(wss);
+                if (wss.isMustSupportRefKeyIdentifier()) {
+                    secBase.setKeyIdentifierType(WSConstants.SKI_KEY_IDENTIFIER);
+                } else if (wss.isMustSupportRefIssuerSerial()) {
+                    secBase.setKeyIdentifierType(WSConstants.ISSUER_SERIAL);
+                } else if (wss instanceof Wss11
+                                && ((Wss11) wss).isMustSupportRefThumbprint()) {
+                    secBase.setKeyIdentifierType(WSConstants.THUMBPRINT_IDENTIFIER);
+                }
+            }
+            
+        } else {
+            policyAsserted(token);
+            policyAsserted(wrapper);
+            secBase.setKeyIdentifierType(WSConstants.BST_DIRECT_REFERENCE);
+        }
+    }
+    public void setEncryptionUser(WSSecEncryptedKey encrKeyBuilder, Token token, boolean sign) {
+        String encrUser = (String)message.getContextualProperty(sign 
+                                                                ? SecurityConstants.USERNAME
+                                                                : SecurityConstants.ENCRYPT_USERNAME);
+        if (encrUser == null || "".equals(encrUser)) {
+            policyNotAsserted(token, "No " + (sign ? "signature" : "encryption") + " username found.");
+        }
+        if (encrUser.equals(WSHandlerConstants.USE_REQ_SIG_CERT)) {
+            Object resultsObj = message.getExchange().getInMessage().get(WSHandlerConstants.RECV_RESULTS);
+            if (resultsObj != null) {
+                encrKeyBuilder.setUseThisCert(getReqSigCert((Vector)resultsObj));
+                 
+                //TODO This is a hack, this should not come under USE_REQ_SIG_CERT
+                if (encrKeyBuilder.isCertSet()) {
+                    encrKeyBuilder.setUserInfo(getUsername((Vector)resultsObj));
+                }
+            } else {
+                policyNotAsserted(token, "No security results in incoming message");
+            }
+        } else {
+            encrKeyBuilder.setUserInfo(encrUser);
+        }
+    }
+    private static X509Certificate getReqSigCert(Vector results) {
+        /*
+        * Scan the results for a matching actor. Use results only if the
+        * receiving Actor and the sending Actor match.
+        */
+        for (int i = 0; i < results.size(); i++) {
+            WSHandlerResult rResult =
+                    (WSHandlerResult) results.get(i);
+
+            Vector wsSecEngineResults = rResult.getResults();
+            /*
+            * Scan the results for the first Signature action. Use the
+            * certificate of this Signature to set the certificate for the
+            * encryption action :-).
+            */
+            for (int j = 0; j < wsSecEngineResults.size(); j++) {
+                WSSecurityEngineResult wser =
+                        (WSSecurityEngineResult) wsSecEngineResults.get(j);
+                Integer actInt = (Integer)wser.get(WSSecurityEngineResult.TAG_ACTION);
+                if (actInt.intValue() == WSConstants.SIGN) {
+                    return (X509Certificate)wser.get(WSSecurityEngineResult.TAG_X509_CERTIFICATE);
+                }
+            }
+        }
+        
+        return null;
+    }
+    
+    /**
+     * Scan through <code>WSHandlerResult<code> vector for a Username token and return
+     * the username if a Username Token found 
+     * @param results
+     * @return
+     */
+    
+    public static String getUsername(Vector results) {
+        /*
+         * Scan the results for a matching actor. Use results only if the
+         * receiving Actor and the sending Actor match.
+         */
+        for (int i = 0; i < results.size(); i++) {
+            WSHandlerResult rResult =
+                     (WSHandlerResult) results.get(i);
+
+            Vector wsSecEngineResults = rResult.getResults();
+            /*
+             * Scan the results for a username token. Use the username
+             * of this token to set the alias for the encryption user
+             */
+            for (int j = 0; j < wsSecEngineResults.size(); j++) {
+                WSSecurityEngineResult wser =
+                         (WSSecurityEngineResult) wsSecEngineResults.get(j);
+                Integer actInt = (Integer)wser.get(WSSecurityEngineResult.TAG_ACTION);
+                if (actInt.intValue() == WSConstants.UT) {
+                    WSUsernameTokenPrincipal principal 
+                        = (WSUsernameTokenPrincipal)wser.get(WSSecurityEngineResult.TAG_PRINCIPAL);
+                    return principal.getName();
+                }
+            }
+        }
+         
+        return null;
+    }
+    protected Wss10 getWss10() {
+        Collection<AssertionInfo> ais = aim.getAssertionInfo(SP12Constants.WSS10);
+        if (ais != null) {
+            for (AssertionInfo ai : ais) {
+                return (Wss10)ai.getAssertion();
+            }            
+        }        
+        ais = aim.getAssertionInfo(SP12Constants.WSS11);
+        if (ais != null) {
+            for (AssertionInfo ai : ais) {
+                return (Wss10)ai.getAssertion();
+            }            
+        }   
+        return null;
+    }
+
+    private void checkForX509PkiPath(WSSecSignature sig, Token token) {
+        if (token instanceof X509Token) {
+            X509Token x509Token = (X509Token) token;
+            if (x509Token.getTokenVersionAndType().equals(SPConstants.WSS_X509_PKI_PATH_V1_TOKEN10)
+                    || x509Token.getTokenVersionAndType().equals(SPConstants.WSS_X509_PKI_PATH_V1_TOKEN11)) {
+                sig.setUseSingleCertificate(false);
+            }
+        }
+    }
+    protected WSSecSignature getSignatureBuider(TokenWrapper wrapper, Token token) {
+        WSSecSignature sig = new WSSecSignature();
+        checkForX509PkiPath(sig, token);
+        
+        setKeyIdentifierType(sig, wrapper, token);
+        
+        String user = (String)message.getContextualProperty(SecurityConstants.USERNAME);
+        if (StringUtils.isEmpty(user)) {
+            policyNotAsserted(token, "No signature username found.");
+        }
+
+        String password = getPassword(user, token, WSPasswordCallback.SIGNATURE);
+        if (StringUtils.isEmpty(password)) {
+            policyNotAsserted(token, "No password found.");
+        }
+
+        sig.setUserInfo(user, password);
+        sig.setSignatureAlgorithm(binding.getAlgorithmSuite().getAsymmetricSignature());
+        sig.setSigCanonicalization(binding.getAlgorithmSuite().getInclusiveC14n());
+        
+        try {
+            sig.prepare(saaj.getSOAPPart(),
+                        getSignatureCrypto(wrapper), 
+                        secHeader);
+        } catch (WSSecurityException e) {
+            policyNotAsserted(token, e);
+        }
+        
+        return sig;
+    }
+
+    protected void doEndorsedSignatures(Map<Token, WSSecBase> tokenMap,
+                                          boolean isTokenProtection) {
+        
+        for (Map.Entry<Token, WSSecBase> ent : tokenMap.entrySet()) {
+            WSSecBase tempTok = ent.getValue();
+            
+            Vector<WSEncryptionPart> sigParts = new Vector<WSEncryptionPart>();
+            sigParts.add(new WSEncryptionPart(mainSigId));
+            
+            if (tempTok instanceof WSSecSignature) {
+                WSSecSignature sig = (WSSecSignature)tempTok;
+                if (isTokenProtection && sig.getBSTTokenId() != null) {
+                    sigParts.add(new WSEncryptionPart(sig.getBSTTokenId()));
+                }
+                try {
+                    sig.addReferencesToSign(sigParts, secHeader);
+                    sig.computeSignature();
+                    sig.appendToHeader(secHeader);
+                } catch (WSSecurityException e) {
+                    policyNotAsserted(ent.getKey(), e);
+                }
+                
+            }
+        } 
+    }
 
 }

Modified: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/TransportBindingHandler.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/TransportBindingHandler.java?rev=697942&r1=697941&r2=697942&view=diff
==============================================================================
--- cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/TransportBindingHandler.java (original)
+++ cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/TransportBindingHandler.java Mon Sep 22 11:51:08 2008
@@ -27,8 +27,6 @@
 import org.apache.cxf.ws.policy.AssertionInfo;
 import org.apache.cxf.ws.policy.AssertionInfoMap;
 import org.apache.cxf.ws.security.policy.SP12Constants;
-import org.apache.cxf.ws.security.policy.SPConstants;
-import org.apache.cxf.ws.security.policy.model.Layout;
 import org.apache.cxf.ws.security.policy.model.SupportingToken;
 import org.apache.cxf.ws.security.policy.model.TransportBinding;
 import org.apache.ws.security.message.WSSecHeader;
@@ -51,36 +49,9 @@
     
     public void handleBinding() {
         Collection<AssertionInfo> ais;
-        WSSecTimestamp timestamp = null;
-        ais = aim.get(SP12Constants.INCLUDE_TIMESTAMP);
-        if (ais != null) {
-            for (AssertionInfo ai : ais) {
-                timestamp = new WSSecTimestamp();
-                timestamp.prepare(saaj.getSOAPPart());
-                ai.setAsserted(true);
-            }                    
-        }
-        ais = aim.get(SP12Constants.LAYOUT);
-        if (ais != null) {
-            for (AssertionInfo ai : ais) {
-                Layout layout = (Layout)ai.getAssertion();
-                if (SPConstants.Layout.LaxTimestampLast == layout.getValue()) {
-                    if (timestamp == null) {
-                        ai.setAsserted(false);
-                    } else {
-                        ai.setAsserted(true);
-                        //get the timestamp into the header first before anything else
-                        timestamp.prependToHeader(secHeader);
-                        timestamp = null;
-                    }
-                } else if (SPConstants.Layout.Strict == layout.getValue()) {
-                    //FIXME - don't have strict writing working yet
-                    ai.setAsserted(false);
-                } else {
-                    ai.setAsserted(true);                            
-                }
-            }                    
-        }
+        WSSecTimestamp timestamp = createTimestamp();
+        timestamp = handleLayout(timestamp);
+        
         ais = aim.get(SP12Constants.SIGNED_SUPPORTING_TOKENS);
         if (ais != null) {
             SupportingToken sgndSuppTokens = null;

Modified: cxf/trunk/systests/src/test/java/org/apache/cxf/systest/ws/security/SecurityPolicyTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/src/test/java/org/apache/cxf/systest/ws/security/SecurityPolicyTest.java?rev=697942&r1=697941&r2=697942&view=diff
==============================================================================
--- cxf/trunk/systests/src/test/java/org/apache/cxf/systest/ws/security/SecurityPolicyTest.java (original)
+++ cxf/trunk/systests/src/test/java/org/apache/cxf/systest/ws/security/SecurityPolicyTest.java Mon Sep 22 11:51:08 2008
@@ -33,6 +33,7 @@
 import org.apache.cxf.jaxws.EndpointImpl;
 import org.apache.cxf.policytest.doubleit.DoubleItPortType;
 import org.apache.cxf.policytest.doubleit.DoubleItService;
+import org.apache.cxf.service.model.EndpointInfo;
 import org.apache.cxf.testutil.common.AbstractBusClientServerTestBase;
 import org.apache.cxf.ws.policy.PolicyEngine;
 import org.apache.cxf.ws.security.SecurityConstants;
@@ -44,6 +45,7 @@
 public class SecurityPolicyTest extends AbstractBusClientServerTestBase  {
     public static final String POLICY_ADDRESS = "http://localhost:9010/SecPolTest";
     public static final String POLICY_HTTPS_ADDRESS = "https://localhost:9009/SecPolTest";
+    public static final String POLICY_ENC_ADDRESS = "http://localhost:9010/SecPolTestEncrypt";
 
     
     public static class ServerPasswordCallback implements CallbackHandler {
@@ -73,6 +75,20 @@
                                                                    new ServerPasswordCallback());
         Endpoint.publish(POLICY_ADDRESS,
                          new DoubleItImpl());
+        
+        ep = (EndpointImpl)Endpoint.publish(POLICY_ENC_ADDRESS,
+                                            new DoubleItImplEncrypt());
+        
+        EndpointInfo ei = ep.getServer().getEndpoint().getEndpointInfo(); 
+        ei.setProperty(SecurityConstants.CALLBACK_HANDLER, new ServerPasswordCallback());
+        
+        ei.setProperty(SecurityConstants.USERNAME, "alice");
+        ei.setProperty(SecurityConstants.CALLBACK_HANDLER, new KeystorePasswordCallback());
+        ei.setProperty(SecurityConstants.SIGNATURE_PROPERTIES, 
+                       SecurityPolicyTest.class.getResource("alice.properties").toString());
+        ei.setProperty(SecurityConstants.ENCRYPT_USERNAME, "bob");
+        ei.setProperty(SecurityConstants.ENCRYPT_PROPERTIES, 
+                       SecurityPolicyTest.class.getResource("bob.properties").toString());
     }
     
     @Test
@@ -80,6 +96,17 @@
         DoubleItService service = new DoubleItService();
         DoubleItPortType pt;
 
+        pt = service.getDoubleItPortEncrypt();
+        ((BindingProvider)pt).getRequestContext().put(SecurityConstants.USERNAME, "alice");
+        ((BindingProvider)pt).getRequestContext().put(SecurityConstants.CALLBACK_HANDLER, 
+                                                      new KeystorePasswordCallback());
+        ((BindingProvider)pt).getRequestContext().put(SecurityConstants.SIGNATURE_PROPERTIES,
+                                                      getClass().getResource("alice.properties"));
+        ((BindingProvider)pt).getRequestContext().put(SecurityConstants.ENCRYPT_USERNAME, "Bob");
+        ((BindingProvider)pt).getRequestContext().put(SecurityConstants.ENCRYPT_PROPERTIES, 
+                                                      getClass().getResource("bob.properties"));
+        pt.doubleIt(BigInteger.valueOf(5));
+        
         pt = service.getDoubleItPortHttps();
         try {
             pt.doubleIt(BigInteger.valueOf(25));
@@ -131,4 +158,15 @@
             return numberToDouble.multiply(new BigInteger("2"));
         }
     }
+    @WebService(targetNamespace = "http://cxf.apache.org/policytest/DoubleIt", 
+                portName = "DoubleItPortEncrypt",
+                serviceName = "DoubleItService", 
+                endpointInterface = "org.apache.cxf.policytest.doubleit.DoubleItPortType",
+                wsdlLocation = "classpath:/wsdl_systest/DoubleIt.wsdl")
+    public static class DoubleItImplEncrypt implements DoubleItPortType {
+        /** {@inheritDoc}*/
+        public BigInteger doubleIt(BigInteger numberToDouble) {
+            return numberToDouble.multiply(new BigInteger("2"));
+        }
+    }
 }

Modified: cxf/trunk/systests/src/test/resources/wsdl_systest/DoubleIt.wsdl
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/src/test/resources/wsdl_systest/DoubleIt.wsdl?rev=697942&r1=697941&r2=697942&view=diff
==============================================================================
--- cxf/trunk/systests/src/test/resources/wsdl_systest/DoubleIt.wsdl (original)
+++ cxf/trunk/systests/src/test/resources/wsdl_systest/DoubleIt.wsdl Mon Sep 22 11:51:08 2008
@@ -68,6 +68,16 @@
          <wsdl:output><soap:body use="literal"/></wsdl:output>
       </wsdl:operation>
    </wsdl:binding>
+   <wsdl:binding name="DoubleItBindingEncrypt" type="tns:DoubleItPortType">
+      <wsp:PolicyReference URI="#DoubleItEncryptPolicy"/>
+      <soap:binding style="document"
+         transport="http://schemas.xmlsoap.org/soap/http" />
+      <wsdl:operation name="DoubleIt">
+         <soap:operation soapAction=""/>
+         <wsdl:input><soap:body use="literal"/></wsdl:input>
+         <wsdl:output><soap:body use="literal"/></wsdl:output>
+      </wsdl:operation>
+   </wsdl:binding>
    <wsdl:service name="DoubleItService">
       <wsdl:port name="DoubleItPortHttps" binding="tns:DoubleItBinding">
          <soap:address 
@@ -77,6 +87,10 @@
          <soap:address 
             location="http://localhost:9010/SecPolTest"/>
       </wsdl:port>
+      <wsdl:port name="DoubleItPortEncrypt" binding="tns:DoubleItBindingEncrypt">
+         <soap:address 
+            location="http://localhost:9010/SecPolTestEncrypt"/>
+      </wsdl:port>
    </wsdl:service>
    
    <wsp:Policy wsu:Id="DoubleItBindingPolicy">
@@ -123,5 +137,58 @@
          </wsp:All>
       </wsp:ExactlyOne>
    </wsp:Policy>
+  <wsp:Policy wsu:Id="DoubleItEncryptPolicy">
+    <wsp:ExactlyOne>
+      <wsp:All>
+        <sp:AsymmetricBinding xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
+          <wsp:Policy>
+            <sp:InitiatorToken>
+              <wsp:Policy>
+                <sp:X509Token sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/AlwaysToRecipient">
+                  <wsp:Policy>
+                    <sp:WssX509V1Token11/>
+                  </wsp:Policy>
+                  </sp:X509Token>
+              </wsp:Policy>
+            </sp:InitiatorToken>
+            <sp:RecipientToken>
+              <wsp:Policy>
+                <sp:X509Token sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/Never">
+                  <wsp:Policy>
+                    <sp:WssX509V1Token11/>
+                  </wsp:Policy>
+                </sp:X509Token>
+              </wsp:Policy>
+            </sp:RecipientToken>
+            <sp:AlgorithmSuite>
+              <wsp:Policy>
+                <sp:TripleDesRsa15/>
+              </wsp:Policy>
+            </sp:AlgorithmSuite>
+            <sp:Layout>
+              <wsp:Policy>
+                <sp:Lax/>
+              </wsp:Policy>
+            </sp:Layout>
+            <sp:IncludeTimestamp/>
+            <sp:EncryptSignature/>
+            <sp:OnlySignEntireHeadersAndBody/>
+          </wsp:Policy>
+        </sp:AsymmetricBinding>
+        <sp:SignedParts xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
+          <sp:Body/>
+        </sp:SignedParts>
+        <sp:EncryptedParts xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
+          <sp:Body/>
+        </sp:EncryptedParts>
+        <sp:Wss10 xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
+          <wsp:Policy>
+            <!-- sp:MustSupportRefKeyIdentifier/-->
+            <sp:MustSupportRefIssuerSerial/>
+          </wsp:Policy>
+        </sp:Wss10>
+      </wsp:All>
+    </wsp:ExactlyOne>
+  </wsp:Policy>
 
 </wsdl:definitions>

Modified: cxf/trunk/testutils/src/main/java/org/apache/cxf/testutil/common/ServerLauncher.java
URL: http://svn.apache.org/viewvc/cxf/trunk/testutils/src/main/java/org/apache/cxf/testutil/common/ServerLauncher.java?rev=697942&r1=697941&r2=697942&view=diff
==============================================================================
--- cxf/trunk/testutils/src/main/java/org/apache/cxf/testutil/common/ServerLauncher.java (original)
+++ cxf/trunk/testutils/src/main/java/org/apache/cxf/testutil/common/ServerLauncher.java Mon Sep 22 11:51:08 2008
@@ -174,7 +174,7 @@
                 }
                 inProcessServer.startInProcess();
                 serverIsReady = true;
-            } catch (Exception ex) {
+            } catch (Throwable ex) {
                 ex.printStackTrace();
                 serverLaunchFailed = true;
             }