You are viewing a plain text version of this content. The canonical link for it is here.
Posted to wss4j-dev@ws.apache.org by co...@apache.org on 2009/04/23 12:50:48 UTC

svn commit: r767887 - in /webservices/wss4j/trunk: src/org/apache/ws/security/ src/org/apache/ws/security/util/ test/wssec/

Author: coheigea
Date: Thu Apr 23 10:50:48 2009
New Revision: 767887

URL: http://svn.apache.org/viewvc?rev=767887&view=rev
Log:
Added a method to WSSecurityUtil to verify that required QName's are protected in the WSSecurityEngineResults according to a specified action
 - Added some tests as well.

Modified:
    webservices/wss4j/trunk/src/org/apache/ws/security/SOAPConstants.java
    webservices/wss4j/trunk/src/org/apache/ws/security/errors.properties
    webservices/wss4j/trunk/src/org/apache/ws/security/util/WSSecurityUtil.java
    webservices/wss4j/trunk/test/wssec/TestWSSecurityEncryptionParts.java
    webservices/wss4j/trunk/test/wssec/TestWSSecuritySignatureParts.java

Modified: webservices/wss4j/trunk/src/org/apache/ws/security/SOAPConstants.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/org/apache/ws/security/SOAPConstants.java?rev=767887&r1=767886&r2=767887&view=diff
==============================================================================
--- webservices/wss4j/trunk/src/org/apache/ws/security/SOAPConstants.java (original)
+++ webservices/wss4j/trunk/src/org/apache/ws/security/SOAPConstants.java Thu Apr 23 10:50:48 2009
@@ -23,7 +23,7 @@
 import java.io.Serializable;
 
 /**
- * An interface definining SOAP constants.  This allows various parts of the
+ * An interface defining SOAP constants.  This allows various parts of the
  * engine to avoid hardcoding dependence on a particular SOAP version and its
  * associated URIs, etc.
  * <p/>

Modified: webservices/wss4j/trunk/src/org/apache/ws/security/errors.properties
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/org/apache/ws/security/errors.properties?rev=767887&r1=767886&r2=767887&view=diff
==============================================================================
--- webservices/wss4j/trunk/src/org/apache/ws/security/errors.properties (original)
+++ webservices/wss4j/trunk/src/org/apache/ws/security/errors.properties Thu Apr 23 10:50:48 2009
@@ -85,5 +85,6 @@
 requiredElementNoID=Element {0} is not signed; it does not have a wsu:Id attribute
 noSignResult=No SIGN result in WSS4J result vector
 requiredElementNotSigned=Element {0} is not included in the signature
+requiredElementNotProtected=Element {0} is not protected
 
 invalidKeySize=Invalid keysize
\ No newline at end of file

Modified: webservices/wss4j/trunk/src/org/apache/ws/security/util/WSSecurityUtil.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/org/apache/ws/security/util/WSSecurityUtil.java?rev=767887&r1=767886&r2=767887&view=diff
==============================================================================
--- webservices/wss4j/trunk/src/org/apache/ws/security/util/WSSecurityUtil.java (original)
+++ webservices/wss4j/trunk/src/org/apache/ws/security/util/WSSecurityUtil.java Thu Apr 23 10:50:48 2009
@@ -29,7 +29,6 @@
 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.xml.security.algorithms.JCEMapper;
 import org.apache.xml.security.signature.XMLSignature;
 import org.w3c.dom.Attr;
@@ -48,7 +47,6 @@
 
 import java.security.NoSuchAlgorithmException;
 import java.security.SecureRandom;
-import java.security.cert.X509Certificate;
 import java.util.Iterator;
 import java.util.Vector;
 
@@ -797,87 +795,54 @@
             );
         }
     }
-
+    
     /**
-     * Search through a WSS4J results vector for a single signature covering all
-     * these elements.
-     * 
-     * NOTE: it is important that the given elements are those that are 
-     * referenced using wsu:Id. When the signed element is referenced using a
-     * transformation such as XPath filtering the validation is carried out 
-     * in signature verification itself.
-     * 
-     * @param results results (e.g., as stored as WSHandlerConstants.RECV_RESULTS on
-     *                an Axis MessageContext)
-     * @param elements the elements to check
-     * @return the identity of the signer
-     * @throws WSSecurityException if no suitable signature could be found or if any element
-     *                             didn't have a wsu:Id attribute
-     */
-    public static X509Certificate ensureSignedTogether(Iterator results, Element[] elements) 
-        throws WSSecurityException {
-        log.debug("ensureSignedTogether()");
-
-        if (results == null) {
-            throw new IllegalArgumentException("No results vector");
-        }
-        if (elements == null || elements.length == 0) {
-            throw new IllegalArgumentException("No elements to check!");
-        }
-
-        // Turn the list of required elements into a list of required wsu:Id
-        // strings
-        String[] requiredIDs = new String[elements.length];
-        for (int i = 0; i < elements.length; i++) {
-            Element e = (Element) elements[i];
-            if (e == null) {
-                throw new IllegalArgumentException("elements[" + i + "] is null!");
-            }
-            requiredIDs[i] = e.getAttributeNS(WSConstants.WSU_NS, "Id");
-            if (requiredIDs[i] == null) {
-                throw new WSSecurityException(
-                    WSSecurityException.FAILED_CHECK,
-                    "requiredElementNoID", 
-                    new Object[] {e.getNodeName()}
-                );
-            }
-            log.debug("Required element " + e.getNodeName() + " has wsu:Id " + requiredIDs[i]);
-        }
-
-        WSSecurityException fault = null;
-
-        // Search through the results for a SIGN result
-        while (results.hasNext()) {
-            WSHandlerResult result = (WSHandlerResult) results.next();
-            Iterator actions = result.getResults().iterator();
-
-            while (actions.hasNext()) {
-                WSSecurityEngineResult resultItem = 
-                    (WSSecurityEngineResult) actions.next();
-                int resultAction = 
-                    ((java.lang.Integer)resultItem.get(WSSecurityEngineResult.TAG_ACTION)).intValue();
+     * Check that all of the QName[] requiredParts are protected by a specified action in the
+     * results vector.
+     * @param results The Vector of WSSecurityEngineResults from processing
+     * @param action The action that is required (e.g. WSConstants.SIGN)
+     * @param requiredParts An array of QNames that correspond to the required elements
+     */
+    public static void checkAllElementsProtected(
+        Vector results,
+        int action,
+        QName[] requiredParts
+    ) throws WSSecurityException {
+        
+        if (requiredParts != null) {
+            for (int i = 0; i < requiredParts.length; i++) {
+                QName requiredPart = requiredParts[i];
                 
-                if (resultAction == WSConstants.SIGN) {
-                    try {
-                        checkSignsAllElements(resultItem, requiredIDs);
-                        return 
-                            (X509Certificate)resultItem.get(
-                                WSSecurityEngineResult.TAG_X509_CERTIFICATE
-                            );
-                    } catch (WSSecurityException ex) {
-                        // Store the exception but keep going... there may be a
-                        // better signature later
-                        log.debug("SIGN result does not sign all required elements", ex);
-                        fault = ex;
+                boolean found = false;
+                for (Iterator iter = results.iterator(); iter.hasNext() && !found;) {
+                    WSSecurityEngineResult result = (WSSecurityEngineResult)iter.next();
+                    int resultAction = 
+                        ((java.lang.Integer)result.get(WSSecurityEngineResult.TAG_ACTION)).intValue();
+                    if (resultAction != action) {
+                        continue;
+                    }
+                    java.util.List refList = 
+                        (java.util.List)result.get(WSSecurityEngineResult.TAG_DATA_REF_URIS);
+                    if (refList != null) {
+                        for (int k = 0; k < refList.size(); k++) {
+                            WSDataRef dataRef = (WSDataRef)refList.get(k);
+                            if (dataRef.getName().equals(requiredPart)) {
+                                found = true;
+                                break;
+                            }
+                        }
                     }
                 }
+                if (!found) {
+                    throw new WSSecurityException(
+                        WSSecurityException.FAILED_CHECK,
+                        "requiredElementNotProtected",
+                        new Object[] {requiredPart}
+                    );
+                }
             }
+            log.debug("All required elements are protected");
         }
-
-        if (fault != null)
-            throw fault;
-
-        throw new WSSecurityException(WSSecurityException.FAILED_CHECK, "noSignResult");
     }
 
     /**
@@ -888,7 +853,7 @@
      * @param requiredIDs the list of wsu:Id values that must be covered
      * @throws WSSecurityException if any required element is not included
      */
-    private static void checkSignsAllElements(
+    public static void checkSignsAllElements(
         WSSecurityEngineResult resultItem, 
         String[] requiredIDs
     ) throws WSSecurityException {

Modified: webservices/wss4j/trunk/test/wssec/TestWSSecurityEncryptionParts.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/test/wssec/TestWSSecurityEncryptionParts.java?rev=767887&r1=767886&r2=767887&view=diff
==============================================================================
--- webservices/wss4j/trunk/test/wssec/TestWSSecurityEncryptionParts.java (original)
+++ webservices/wss4j/trunk/test/wssec/TestWSSecurityEncryptionParts.java Thu Apr 23 10:50:48 2009
@@ -45,6 +45,8 @@
 import javax.security.auth.callback.Callback;
 import javax.security.auth.callback.CallbackHandler;
 import javax.security.auth.callback.UnsupportedCallbackException;
+import javax.xml.namespace.QName;
+
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.io.InputStream;
@@ -147,7 +149,24 @@
             LOG.debug(outputString);
         }
         
-        verify(encryptedDoc);
+        Vector results = verify(encryptedDoc);
+        
+        QName name = new QName("urn:foo.bar", "foobar");
+        WSSecurityUtil.checkAllElementsProtected(results, WSConstants.ENCR, new QName[]{name});
+        try {
+            name = new QName("urn:foo.bar", "foobar2");
+            WSSecurityUtil.checkAllElementsProtected(results, WSConstants.ENCR, new QName[]{name});
+            fail("Failure expected on a wrong protected part");
+        } catch (WSSecurityException ex) {
+            // expected
+        }
+        try {
+            name = new QName("urn:foo.bar", "foobar");
+            WSSecurityUtil.checkAllElementsProtected(results, WSConstants.SIGN, new QName[]{name});
+            fail("Failure expected on a wrong action");
+        } catch (WSSecurityException ex) {
+            // expected
+        }
     }
     
     
@@ -289,7 +308,43 @@
             LOG.debug(outputString);
         }
         
-        verify(encryptedDoc);
+        Vector results = verify(encryptedDoc);
+        
+        QName fooName = new QName("urn:foo.bar", "foobar");
+        QName bodyName = new QName(soapConstants.getEnvelopeURI(), "Body");
+        WSSecurityUtil.checkAllElementsProtected(results, WSConstants.ENCR, new QName[]{fooName});
+        WSSecurityUtil.checkAllElementsProtected(results, WSConstants.ENCR, new QName[]{bodyName});
+        WSSecurityUtil.checkAllElementsProtected(
+            results, 
+            WSConstants.ENCR, 
+            new QName[]{bodyName, fooName}
+        );
+        WSSecurityUtil.checkAllElementsProtected(
+            results, 
+            WSConstants.ENCR, 
+            new QName[]{fooName, bodyName}
+        );
+        try {
+            WSSecurityUtil.checkAllElementsProtected(
+                results, 
+                WSConstants.SIGN, 
+                new QName[]{fooName, bodyName}
+            );
+            fail("Failure expected on a wrong action");
+        } catch (WSSecurityException ex) {
+            // expected
+        }
+        try {
+            QName headerName = new QName(soapConstants.getEnvelopeURI(), "Header");
+            WSSecurityUtil.checkAllElementsProtected(
+                results, 
+                WSConstants.ENCR, 
+                new QName[]{fooName, bodyName, headerName}
+            );
+            fail("Failure expected on an unsatisfied requirement");
+        } catch (WSSecurityException ex) {
+            // expected
+        }
     }
     
 
@@ -300,14 +355,15 @@
      * @param doc 
      * @throws Exception Thrown when there is a problem in verification
      */
-    private void verify(Document doc) throws Exception {
-        secEngine.processSecurityHeader(doc, null, this, crypto);
+    private Vector verify(Document doc) throws Exception {
+        Vector results = secEngine.processSecurityHeader(doc, null, this, crypto);
         if (LOG.isDebugEnabled()) {
             LOG.debug("Verified and decrypted message:");
             String outputString = 
                 org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(doc);
             LOG.debug(outputString);
         }
+        return results;
     }
 
     public void handle(Callback[] callbacks)

Modified: webservices/wss4j/trunk/test/wssec/TestWSSecuritySignatureParts.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/test/wssec/TestWSSecuritySignatureParts.java?rev=767887&r1=767886&r2=767887&view=diff
==============================================================================
--- webservices/wss4j/trunk/test/wssec/TestWSSecuritySignatureParts.java (original)
+++ webservices/wss4j/trunk/test/wssec/TestWSSecuritySignatureParts.java Thu Apr 23 10:50:48 2009
@@ -49,6 +49,7 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.Vector;
+import javax.xml.namespace.QName;
 
 /**
  * This is some unit tests for signing using signature parts. Note that the "soapMsg" below
@@ -148,7 +149,24 @@
             LOG.debug(outputString);
         }
         
-        verify(signedDoc);
+        Vector results = verify(signedDoc);
+        
+        QName name = new QName("urn:foo.bar", "foobar");
+        WSSecurityUtil.checkAllElementsProtected(results, WSConstants.SIGN, new QName[]{name});
+        try {
+            name = new QName("urn:foo.bar", "foobar2");
+            WSSecurityUtil.checkAllElementsProtected(results, WSConstants.SIGN, new QName[]{name});
+            fail("Failure expected on a wrong protected part");
+        } catch (WSSecurityException ex) {
+            // expected
+        }
+        try {
+            name = new QName("urn:foo.bar", "foobar");
+            WSSecurityUtil.checkAllElementsProtected(results, WSConstants.ENCR, new QName[]{name});
+            fail("Failure expected on a wrong action");
+        } catch (WSSecurityException ex) {
+            // expected
+        }
     }
     
     /**
@@ -252,7 +270,43 @@
             LOG.debug(outputString);
         }
         
-        verify(signedDoc);
+        Vector results = verify(signedDoc);
+        
+        QName fooName = new QName("urn:foo.bar", "foobar");
+        QName bodyName = new QName(soapConstants.getEnvelopeURI(), "Body");
+        WSSecurityUtil.checkAllElementsProtected(results, WSConstants.SIGN, new QName[]{fooName});
+        WSSecurityUtil.checkAllElementsProtected(results, WSConstants.SIGN, new QName[]{bodyName});
+        WSSecurityUtil.checkAllElementsProtected(
+            results, 
+            WSConstants.SIGN, 
+            new QName[]{bodyName, fooName}
+        );
+        WSSecurityUtil.checkAllElementsProtected(
+            results, 
+            WSConstants.SIGN, 
+            new QName[]{fooName, bodyName}
+        );
+        try {
+            WSSecurityUtil.checkAllElementsProtected(
+                results, 
+                WSConstants.ENCR, 
+                new QName[]{fooName, bodyName}
+            );
+            fail("Failure expected on a wrong action");
+        } catch (WSSecurityException ex) {
+            // expected
+        }
+        try {
+            QName headerName = new QName(soapConstants.getEnvelopeURI(), "Header");
+            WSSecurityUtil.checkAllElementsProtected(
+                results, 
+                WSConstants.SIGN, 
+                new QName[]{fooName, bodyName, headerName}
+            );
+            fail("Failure expected on an unsatisfied requirement");
+        } catch (WSSecurityException ex) {
+            // expected
+        }
     }
     
 
@@ -263,14 +317,15 @@
      * @param doc 
      * @throws Exception Thrown when there is a problem in verification
      */
-    private void verify(Document doc) throws Exception {
-        secEngine.processSecurityHeader(doc, null, this, crypto);
+    private Vector verify(Document doc) throws Exception {
+        Vector results = secEngine.processSecurityHeader(doc, null, this, crypto);
         if (LOG.isDebugEnabled()) {
             LOG.debug("Verfied and decrypted message:");
             String outputString = 
                 org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(doc);
             LOG.debug(outputString);
         }
+        return results;
     }
 
     public void handle(Callback[] callbacks)



---------------------------------------------------------------------
To unsubscribe, e-mail: wss4j-dev-unsubscribe@ws.apache.org
For additional commands, e-mail: wss4j-dev-help@ws.apache.org