You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-dev@axis.apache.org by ru...@apache.org on 2005/08/18 14:28:02 UTC

svn commit: r233313 - in /webservices/axis/trunk/java/modules/security/src/org/apache/axis2/security: WSDoAllReceiver.java WSDoAllSender.java handler/WSDoAllHandler.java util/ util/Axis2Util.java

Author: ruchithf
Date: Thu Aug 18 05:27:49 2005
New Revision: 233313

URL: http://svn.apache.org/viewcvs?rev=233313&view=rev
Log:
porting the wss4j axis handlers to axis2

Added:
    webservices/axis/trunk/java/modules/security/src/org/apache/axis2/security/util/
    webservices/axis/trunk/java/modules/security/src/org/apache/axis2/security/util/Axis2Util.java
Modified:
    webservices/axis/trunk/java/modules/security/src/org/apache/axis2/security/WSDoAllReceiver.java
    webservices/axis/trunk/java/modules/security/src/org/apache/axis2/security/WSDoAllSender.java
    webservices/axis/trunk/java/modules/security/src/org/apache/axis2/security/handler/WSDoAllHandler.java

Modified: webservices/axis/trunk/java/modules/security/src/org/apache/axis2/security/WSDoAllReceiver.java
URL: http://svn.apache.org/viewcvs/webservices/axis/trunk/java/modules/security/src/org/apache/axis2/security/WSDoAllReceiver.java?rev=233313&r1=233312&r2=233313&view=diff
==============================================================================
--- webservices/axis/trunk/java/modules/security/src/org/apache/axis2/security/WSDoAllReceiver.java (original)
+++ webservices/axis/trunk/java/modules/security/src/org/apache/axis2/security/WSDoAllReceiver.java Thu Aug 18 05:27:49 2005
@@ -18,11 +18,277 @@
 
 package org.apache.axis2.security;
 
+import java.security.cert.X509Certificate;
+import java.util.Iterator;
+import java.util.Vector;
+
+import javax.security.auth.callback.CallbackHandler;
+
 import org.apache.axis2.AxisFault;
 import org.apache.axis2.context.MessageContext;
+import org.apache.axis2.om.OMException;
 import org.apache.axis2.security.handler.WSDoAllHandler;
+import org.apache.axis2.security.util.Axis2Util;
+import org.apache.axis2.soap.SOAPEnvelope;
+import org.apache.axis2.soap.SOAPHeader;
+import org.apache.axis2.soap.SOAPHeaderBlock;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ws.security.SOAPConstants;
+import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.WSSecurityEngineResult;
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.security.handler.RequestData;
+import org.apache.ws.security.handler.WSHandlerConstants;
+import org.apache.ws.security.handler.WSHandlerResult;
+import org.apache.ws.security.message.token.Timestamp;
+import org.apache.ws.security.util.WSSecurityUtil;
+import org.w3c.dom.Document;
 
 public class WSDoAllReceiver extends WSDoAllHandler {
-    public void invoke(MessageContext msgContext) throws AxisFault {
+
+    protected static Log log = LogFactory.getLog(WSDoAllReceiver.class.getName());
+
+	
+	public void invoke(MessageContext msgContext) throws AxisFault {
+    	doDebug = log.isDebugEnabled();
+
+        if (doDebug) {
+            log.debug("WSDoAllReceiver: enter invoke() ");
+        }
+
+        RequestData reqData = new RequestData();
+        
+        try {
+        	reqData.setMsgContext(msgContext);
+
+            Vector actions = new Vector();
+            String action = null;
+            if ((action = (String) getOption(WSHandlerConstants.ACTION)) == null) {
+                action = (String) msgContext
+                        .getProperty(WSHandlerConstants.ACTION);
+            }
+            if (action == null) {
+                throw new AxisFault("WSDoAllReceiver: No action defined");
+            }
+            int doAction = WSSecurityUtil.decodeAction(action, actions);
+
+            String actor = (String) getOption(WSHandlerConstants.ACTOR);
+
+            Document doc = null;
+
+            try {
+            doc = Axis2Util.getDocumentFromSOAPEnvelope(msgContext.getEnvelope());
+            } catch (WSSecurityException wssEx) {
+            	throw new AxisFault("WSDoAllReceiver: Error in converting to Document", wssEx);
+            }
+        	
+            //Do not process faults
+            SOAPConstants soapConstants = WSSecurityUtil.getSOAPConstants(doc.getDocumentElement());
+            if (WSSecurityUtil.findElement(doc.getDocumentElement(), "Fault",
+					soapConstants.getEnvelopeURI()) != null) {
+				return;
+			}
+            
+
+            /*
+            * To check a UsernameToken or to decrypt an encrypted message we
+            * need a password.
+            */
+            CallbackHandler cbHandler = null;
+            if ((doAction & (WSConstants.ENCR | WSConstants.UT)) != 0) {
+                cbHandler = getPasswordCB(reqData);
+            }
+
+            /*
+            * Get and check the Signature specific parameters first because
+            * they may be used for encryption too.
+            */
+
+            if ((doAction & WSConstants.SIGN) == WSConstants.SIGN) {
+                decodeSignatureParameter2(reqData);
+            }
+
+            if ((doAction & WSConstants.ENCR) == WSConstants.ENCR) {
+                decodeDecryptionParameter(reqData);
+            }
+
+            Vector wsResult = null;
+            try {
+                wsResult = secEngine.processSecurityHeader(doc, actor,
+                        cbHandler, reqData.getSigCrypto(), reqData.getDecCrypto());
+            } catch (WSSecurityException ex) {
+                ex.printStackTrace();
+                throw new AxisFault(
+                        "WSDoAllReceiver: security processing failed", ex);
+            }
+            if (wsResult == null) { // no security header found
+                if (doAction == WSConstants.NO_SECURITY) {
+                    return;
+                } else {
+                    throw new AxisFault(
+                            "WSDoAllReceiver: Request does not contain required Security header");
+                }
+            }
+            
+            //TODO: Copy the processed headers
+            
+            
+            /**
+             * Set the new SOAPEnvelope
+             */
+            
+            try {
+            	SOAPEnvelope envelope = Axis2Util.getSOAPEnvelopeFromDocument(doc,soapConstants.getEnvelopeURI());
+            	msgContext.setEnvelope(envelope);
+            } catch (WSSecurityException e) {
+            	throw new AxisFault(
+						"WSDoAllReceiver: Error in converting into a SOAPEnvelope",e);            	
+            }
+            
+            /*
+             * After setting the new current message, probably modified because
+             * of decryption, we need to locate the security header. That is, we
+             * force Axis (with getSOAPEnvelope()) to parse the string, build
+             * the new header. Then we examine, look up the security header and
+             * set the header as processed.
+             *
+             * Please note: find all header elements that contain the same actor
+             * that was given to processSecurityHeader(). Then check if there is
+             * a security header with this actor.
+             */
+            SOAPHeader header = null;
+            try {
+				header = msgContext.getEnvelope().getHeader();
+			} catch (OMException ex) {
+                throw new AxisFault(
+                        "WSDoAllReceiver: cannot get SOAP header after security processing",
+                        ex);
+			}
+			
+			Iterator headers = header.examineHeaderBlocks(actor);
+			
+			SOAPHeaderBlock headerBlock = null;
+			while(headers.hasNext()) { //Find the wsse header
+				SOAPHeaderBlock hb = (SOAPHeaderBlock)headers.next();
+                if (hb.getLocalName().equals(WSConstants.WSSE_LN)
+                        && hb.getNamespace().getName().equals(WSConstants.WSSE_NS)) {
+                    headerBlock = hb;
+                    break;
+                }
+			}
+            
+			headerBlock.setProcessed();
+			
+
+            /*
+            * Now we can check the certificate used to sign the message. In the
+            * following implementation the certificate is only trusted if
+            * either it itself or the certificate of the issuer is installed in
+            * the keystore.
+            *
+            * Note: the method verifyTrust(X509Certificate) allows custom
+            * implementations with other validation algorithms for subclasses.
+            */
+
+            // Extract the signature action result from the action vector
+            WSSecurityEngineResult actionResult = WSSecurityUtil
+                    .fetchActionResult(wsResult, WSConstants.SIGN);
+
+            if (actionResult != null) {
+                X509Certificate returnCert = actionResult.getCertificate();
+
+                if (returnCert != null) {
+                    if (!verifyTrust(returnCert, reqData)) {
+                        throw new AxisFault(
+                                "WSDoAllReceiver: The certificate used for the signature is not trusted");
+                    }
+                }
+            }
+            
+            /*
+             * Perform further checks on the timestamp that was transmitted in
+             * the header. In the following implementation the timestamp is
+             * valid if it was created after (now-ttl), where ttl is set on
+             * server side, not by the client.
+             *
+             * Note: the method verifyTimestamp(Timestamp) allows custom
+             * implementations with other validation algorithms for subclasses.
+             */
+
+             // Extract the timestamp action result from the action vector
+             actionResult = WSSecurityUtil.fetchActionResult(wsResult,
+                     WSConstants.TS);
+
+             if (actionResult != null) {
+                 Timestamp timestamp = actionResult.getTimestamp();
+
+                 if (timestamp != null) {
+                     String ttl = null;
+                     if ((ttl = (String) getOption(WSHandlerConstants.TTL_TIMESTAMP)) == null) {
+                         ttl = (String) msgContext
+                                 .getProperty(WSHandlerConstants.TTL_TIMESTAMP);
+                     }
+                     int ttl_i = 0;
+                     if (ttl != null) {
+                         try {
+                             ttl_i = Integer.parseInt(ttl);
+                         } catch (NumberFormatException e) {
+                             ttl_i = reqData.getTimeToLive();
+                         }
+                     }
+                     if (ttl_i <= 0) {
+                         ttl_i = reqData.getTimeToLive();
+                     }
+
+                     if (!verifyTimestamp(timestamp, reqData.getTimeToLive())) {
+                         throw new AxisFault(
+                                 "WSDoAllReceiver: The timestamp could not be validated");
+                     }
+                 }
+             }
+       
+
+             /*
+             * now check the security actions: do they match, in right order?
+             */
+             int resultActions = wsResult.size();
+             int size = actions.size();
+             if (size != resultActions) {
+                 throw new AxisFault(
+                         "WSDoAllReceiver: security processing failed (actions number mismatch)");
+             }
+             for (int i = 0; i < size; i++) {
+                 if (((Integer) actions.get(i)).intValue() != ((WSSecurityEngineResult) wsResult
+                         .get(i)).getAction()) {
+                     throw new AxisFault(
+                             "WSDoAllReceiver: security processing failed (actions mismatch)");
+                 }
+             }
+
+             /*
+             * All ok up to this point. Now construct and setup the security
+             * result structure. The service may fetch this and check it.
+             */
+             Vector results = null;
+             if ((results = (Vector) msgContext
+                     .getProperty(WSHandlerConstants.RECV_RESULTS)) == null) {
+                 results = new Vector();
+                 msgContext
+                         .setProperty(WSHandlerConstants.RECV_RESULTS, results);
+             }
+             WSHandlerResult rResult = new WSHandlerResult(actor, wsResult);
+             results.add(0, rResult);
+             if (doDebug) {
+                 log.debug("WSDoAllReceiver: exit invoke()");
+             }
+        } catch (WSSecurityException wssEx) {
+        	throw new AxisFault(wssEx);
+        } finally {
+            reqData.clear();
+            reqData = null;
+        }
+        
+    	
     }
 }

Modified: webservices/axis/trunk/java/modules/security/src/org/apache/axis2/security/WSDoAllSender.java
URL: http://svn.apache.org/viewcvs/webservices/axis/trunk/java/modules/security/src/org/apache/axis2/security/WSDoAllSender.java?rev=233313&r1=233312&r2=233313&view=diff
==============================================================================
--- webservices/axis/trunk/java/modules/security/src/org/apache/axis2/security/WSDoAllSender.java (original)
+++ webservices/axis/trunk/java/modules/security/src/org/apache/axis2/security/WSDoAllSender.java Thu Aug 18 05:27:49 2005
@@ -1,29 +1,255 @@
 /*
  * Copyright 2004,2005 The Apache Software Foundation.
- *
- * Licensed 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
- *
+ * 
+ * Licensed 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.
- *
- *
+ * 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.axis2.security;
 
+import java.util.Vector;
+
 import org.apache.axis2.AxisFault;
 import org.apache.axis2.context.MessageContext;
 import org.apache.axis2.security.handler.WSDoAllHandler;
+import org.apache.axis2.security.util.Axis2Util;
+import org.apache.axis2.soap.SOAPEnvelope;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.security.handler.RequestData;
+import org.apache.ws.security.handler.WSHandlerConstants;
+import org.apache.ws.security.util.WSSecurityUtil;
+import org.w3c.dom.Document;
 
 public class WSDoAllSender extends WSDoAllHandler {
-    public void invoke(MessageContext msgContext) throws AxisFault {
+
+	protected static Log log = LogFactory.getLog(WSDoAllSender.class.getName());
+	
+	public void invoke(MessageContext msgContext) throws AxisFault {
+		
+        doDebug = log.isDebugEnabled();
+        if (doDebug) {
+            log.debug("WSDoAllSender: enter invoke()");
+        }
+
+        RequestData reqData = new RequestData();
+
+        reqData.setNoSerialization(false);
+        reqData.setMsgContext(msgContext);
+        try {
+	        Vector actions = new Vector();
+	        String action = null;
+	        if ((action = (String) getOption(WSHandlerConstants.ACTION)) == null) {
+	            action = (String) ((MessageContext)reqData.getMsgContext())
+	                    .getProperty(WSHandlerConstants.ACTION);
+	        }
+	        if (action == null) {
+	            throw new AxisFault("WSDoAllSender: No action defined");
+	        }
+	        int doAction = WSSecurityUtil.decodeAction(action, actions);
+	        if (doAction == WSConstants.NO_SECURITY) {
+	            return;
+	        }
+	
+	        boolean mu = decodeMustUnderstand(reqData);
+	
+	        secEngine.setPrecisionInMilliSeconds(decodeTimestampPrecision(reqData));
+	
+	        String actor = null;
+	        if ((actor = (String) getOption(WSHandlerConstants.ACTOR)) == null) {
+	            actor = (String)
+	                    getProperty(reqData.getMsgContext(), WSHandlerConstants.ACTOR);
+	        }
+	        reqData.setActor(actor);
+		
+            /*
+             * For every action we need a username, so get this now. The
+             * username defined in the deployment descriptor takes precedence.
+             */
+         reqData.setUsername((String) getOption(WSHandlerConstants.USER));
+         if (reqData.getUsername() == null || reqData.getUsername().equals("")) {
+             String username = (String) getProperty(reqData.getMsgContext(), WSHandlerConstants.USER);
+             if (username != null) {
+                 reqData.setUsername(username);
+             }
+         }
+         
+         /*
+             * Now we perform some set-up for UsernameToken and Signature
+             * functions. No need to do it for encryption only. Check if
+             * username is available and then get a passowrd.
+             */
+         if ((doAction & (WSConstants.SIGN | WSConstants.UT | WSConstants.UT_SIGN)) != 0) {
+             /*
+                  * We need a username - if none throw an AxisFault. For
+                  * encryption there is a specific parameter to get a username.
+                  */
+             if (reqData.getUsername() == null || reqData.getUsername().equals("")) {
+                 throw new AxisFault(
+                         "WSDoAllSender: Empty username for specified action");
+             }
+         }
+         
+         if (doDebug) {
+             log.debug("Action: " + doAction);
+             log.debug("Actor: " + reqData.getActor() + ", mu: " + mu);
+         }
+         /*
+		  * Now get the SOAPEvelope from the message context and convert it into
+		  * a Document
+		  * 
+		  * Now we can perform our security operations on this request.
+		  */
+	     	
+         
+         Document doc = null;
+            /*
+             * If the message context property conatins a document then this is
+             * a chained handler.
+             */
+            if ((doc = (Document) ((MessageContext)reqData.getMsgContext())
+                    .getProperty(WSHandlerConstants.SND_SECURITY)) == null) {
+            	try {
+            	doc = Axis2Util.getDocumentFromSOAPEnvelope(msgContext.getEnvelope());
+            	} catch (WSSecurityException wssEx) {
+            		throw new AxisFault("WSDoAllReceiver: Error in converting to Document", wssEx);
+            	}
+            }
+	     	
+            reqData.setSoapConstants(WSSecurityUtil.getSOAPConstants(doc
+                    .getDocumentElement()));
+            /*
+                * Here we have action, username, password, and actor,
+                * mustUnderstand. Now get the action specific parameters.
+                */
+            if ((doAction & WSConstants.UT) == WSConstants.UT) {
+                decodeUTParameter(reqData);
+            }
+            /*
+                * Here we have action, username, password, and actor,
+                * mustUnderstand. Now get the action specific parameters.
+                */
+            if ((doAction & WSConstants.UT_SIGN) == WSConstants.UT_SIGN) {
+                decodeUTParameter(reqData);
+                decodeSignatureParameter(reqData);
+            }
+            /*
+                * Get and check the Signature specific parameters first because
+                * they may be used for encryption too.
+                */
+            if ((doAction & WSConstants.SIGN) == WSConstants.SIGN) {
+                reqData.setSigCrypto(loadSignatureCrypto(reqData));
+                decodeSignatureParameter(reqData);
+            }
+            /*
+                * If we need to handle signed SAML token then we need may of the
+                * Signature parameters. The handle procedure loads the signature
+                * crypto file on demand, thus don't do it here.
+                */
+            if ((doAction & WSConstants.ST_SIGNED) == WSConstants.ST_SIGNED) {
+                decodeSignatureParameter(reqData);
+            }
+            /*
+                * Set and check the encryption specific parameters, if necessary
+                * take over signature parameters username and crypto instance.
+                */
+            if ((doAction & WSConstants.ENCR) == WSConstants.ENCR) {
+                reqData.setEncCrypto(loadEncryptionCrypto(reqData));
+                decodeEncryptionParameter(reqData);
+            }
+            /*
+                * Here we have all necessary information to perform the requested
+                * action(s).
+                */
+            for (int i = 0; i < actions.size(); i++) {
+
+                int actionToDo = ((Integer) actions.get(i)).intValue();
+                if (doDebug) {
+                    log.debug("Performing Action: " + actionToDo);
+                }
+
+                String password = null;
+                switch (actionToDo) {
+                case WSConstants.UT:
+                    performUTAction(actionToDo, mu, doc, reqData);
+                    break;
+
+                case WSConstants.ENCR:
+                    performENCRAction(mu, actionToDo, doc, reqData);
+                    break;
+
+                case WSConstants.SIGN:
+                    performSIGNAction(actionToDo, mu, doc, reqData);
+                    break;
+
+                case WSConstants.ST_SIGNED:
+                    performST_SIGNAction(actionToDo, mu, doc, reqData);
+                    break;
+
+                case WSConstants.ST_UNSIGNED:
+                    performSTAction(actionToDo, mu, doc, reqData);
+                    break;
+
+                case WSConstants.TS:
+                    performTSAction(actionToDo, mu, doc, reqData);
+                    break;
+
+                case WSConstants.UT_SIGN:
+                    performUT_SIGNAction(actionToDo, mu, doc, reqData);
+                    break;
+
+                case WSConstants.NO_SERIALIZE:
+                    reqData.setNoSerialization(true);
+                    break;
+                }
+            }
+
+
+            /*
+                * If required convert the resulting document into a message first.
+                * The outputDOM() method performs the necessary c14n call. After
+                * that we extract it as a string for further processing.
+                *
+                * Set the resulting byte array as the new SOAP message.
+                *
+                * If noSerialization is false, this handler shall be the last (or
+                * only) one in a handler chain. If noSerialization is true, just
+                * set the processed Document in the transfer property. The next
+                * Axis WSS4J handler takes it and performs additional security
+                * processing steps.
+                *
+                */
+            if (reqData.isNoSerialization()) {
+                ((MessageContext)reqData.getMsgContext()).setProperty(WSHandlerConstants.SND_SECURITY,
+                        doc);
+            } else {
+            	SOAPEnvelope processedEnv = Axis2Util.getSOAPEnvelopeFromDocument(doc, reqData.getSoapConstants().getEnvelopeURI());
+            	msgContext.setEnvelope(processedEnv);
+            	((MessageContext)reqData.getMsgContext()).setProperty(WSHandlerConstants.SND_SECURITY, null);
+            }
+            
+            if (doDebug) {
+                log.debug("WSDoAllSender: exit invoke()");
+            }
+        } catch (WSSecurityException e) {
+            throw new AxisFault(e.getMessage(), e);
+        } finally {
+            reqData.clear();
+            reqData = null;
+        }        
     }
 }
 

Modified: webservices/axis/trunk/java/modules/security/src/org/apache/axis2/security/handler/WSDoAllHandler.java
URL: http://svn.apache.org/viewcvs/webservices/axis/trunk/java/modules/security/src/org/apache/axis2/security/handler/WSDoAllHandler.java?rev=233313&r1=233312&r2=233313&view=diff
==============================================================================
--- webservices/axis/trunk/java/modules/security/src/org/apache/axis2/security/handler/WSDoAllHandler.java (original)
+++ webservices/axis/trunk/java/modules/security/src/org/apache/axis2/security/handler/WSDoAllHandler.java Thu Aug 18 05:27:49 2005
@@ -36,6 +36,10 @@
     private static HandlerDescription EMPTY_HANDLER_METADATA =
             new HandlerDescription(new QName("deafult Handler"));
 
+    private final static String WSS_PASSWORD = "password";
+    
+    private final static String WSS_USERNAME = "username";
+    
     /**
      * Field handlerDesc
      */
@@ -112,18 +116,28 @@
 
 
     public Object getOption(String key) {
-        throw new RuntimeException("Not yet implemented");
+        return this.handlerDesc.getParameter(key).getValue();
     }
 
     public Object getProperty(Object msgContext, String key) {
-        throw new RuntimeException("Not yet implemented");
+        return ((MessageContext)msgContext).getProperty(key);
     }
 
     public String getPassword(Object msgContext) {
-        throw new RuntimeException("Not yet implemented");
+        return (String)((MessageContext)msgContext).getProperty(WSS_PASSWORD);
     }
 
     public void setPassword(Object msgContext, String password) {
-        throw new RuntimeException("Not yet implemented");
+        ((MessageContext)msgContext).setProperty(WSS_PASSWORD,password);
     }
+    
+    public String getUsername(Object msgContext) {
+        return (String)((MessageContext)msgContext).getProperty(WSS_USERNAME);
+    }
+
+    public void setUsername(Object msgContext, String username) {
+        ((MessageContext)msgContext).setProperty(WSS_USERNAME,username);
+    }
+    
+        
 }

Added: webservices/axis/trunk/java/modules/security/src/org/apache/axis2/security/util/Axis2Util.java
URL: http://svn.apache.org/viewcvs/webservices/axis/trunk/java/modules/security/src/org/apache/axis2/security/util/Axis2Util.java?rev=233313&view=auto
==============================================================================
--- webservices/axis/trunk/java/modules/security/src/org/apache/axis2/security/util/Axis2Util.java (added)
+++ webservices/axis/trunk/java/modules/security/src/org/apache/axis2/security/util/Axis2Util.java Thu Aug 18 05:27:49 2005
@@ -0,0 +1,101 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  Licensed 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.axis2.security.util;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamReader;
+
+import org.apache.axis2.om.impl.OMOutputImpl;
+import org.apache.axis2.soap.SOAPEnvelope;
+import org.apache.axis2.soap.impl.llom.builder.StAXSOAPModelBuilder;
+import org.apache.ws.security.WSSecurityException;
+import org.apache.xml.security.utils.XMLUtils;
+import org.w3c.dom.Document;
+
+/**
+ * Utility class for the Axis2-WSS4J Module
+ * 
+ * @author Ruchith Fernando (ruchith.fernando@gmail.com)
+ */
+public class Axis2Util {
+
+	/**
+	 * Create a DOM Document using the SOAP Envelope
+	 * @param env An org.apache.axis2.soap.SOAPEnvelope instance 
+	 * @return the DOM Document of the given SOAP Envelope
+	 * @throws Exception
+	 */
+	public static Document getDocumentFromSOAPEnvelope(SOAPEnvelope env)
+			throws WSSecurityException {
+		try {
+			ByteArrayOutputStream baos = new ByteArrayOutputStream();
+
+			/**
+			 * There are plans to deprecate the OmNode.serialize(XMLStreamWriter)
+			 * method therefore using OMOutoutImpl to serialize the env
+			 */
+			OMOutputImpl output = new OMOutputImpl(baos, false);
+			env.serialize(output);
+			output.flush();
+
+			ByteArrayInputStream bais = new ByteArrayInputStream(baos
+					.toByteArray());
+
+			return DocumentBuilderFactory.newInstance().newDocumentBuilder()
+					.parse(bais);
+		} catch (Exception e) {
+			throw new WSSecurityException(
+					"Error in converting SOAP Envelope to Document", e);
+		}
+	}
+
+	/**
+	 * Covert a DOM Document containing a SOAP Envelope in to a
+	 * org.apache.axis2.soap.SOAPEnvelope 
+	 * @param doc DOM Document
+	 * @param envelopeNS SOAP Namespace of the the given Envelope
+	 * @return
+	 * @throws Exception
+	 */
+	public static SOAPEnvelope getSOAPEnvelopeFromDocument(Document doc,
+			String envelopeNS) throws WSSecurityException {
+		try {
+			//Set the new SOAPEnvelope
+			ByteArrayOutputStream os = new ByteArrayOutputStream();
+			XMLUtils.outputDOM(doc, os, true);
+
+			ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray());
+			XMLStreamReader reader = XMLInputFactory.newInstance()
+					.createXMLStreamReader(is);
+
+			StAXSOAPModelBuilder builder = new StAXSOAPModelBuilder(reader,
+					envelopeNS);
+
+			return builder.getSOAPEnvelope();
+
+		} catch (Exception e) {
+			throw new WSSecurityException(
+					"Error in converting document to SOAPEnvelope", e);
+		}
+
+	}
+
+}
\ No newline at end of file