Author: coheigea
Date: Fri Mar  6 17:58:38 2009
New Revision: 751008

URL: http://svn.apache.org/viewvc?rev=751008&view=rev
Log:
[WSS-156] - Better testing + added a "PublicKeyCallback" for trust verification 
of sorts.

Added:
    webservices/wss4j/trunk/src/org/apache/ws/security/PublicKeyCallback.java   
(with props)
Modified:
    
webservices/wss4j/trunk/src/org/apache/ws/security/processor/SignatureProcessor.java
    
webservices/wss4j/trunk/src/org/apache/ws/security/processor/UsernameTokenProcessor.java
    webservices/wss4j/trunk/test/wssec/SignatureKeyValueTest.java
    webservices/wss4j/trunk/test/wssec/TestWSSecurityWSS86.java

Added: webservices/wss4j/trunk/src/org/apache/ws/security/PublicKeyCallback.java
URL: 
http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/org/apache/ws/security/PublicKeyCallback.java?rev=751008&view=auto
==============================================================================
--- webservices/wss4j/trunk/src/org/apache/ws/security/PublicKeyCallback.java 
(added)
+++ webservices/wss4j/trunk/src/org/apache/ws/security/PublicKeyCallback.java 
Fri Mar  6 17:58:38 2009
@@ -0,0 +1,93 @@
+/*
+ * 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.ws.security;
+
+import java.security.KeyStoreException;
+import java.security.cert.Certificate;
+import java.security.cert.X509Certificate;
+import java.util.Enumeration;
+
+import javax.security.auth.callback.Callback;
+
+
+/**
+ */
+public class PublicKeyCallback implements Callback {
+
+    private java.security.PublicKey publicKey;
+    
+    public PublicKeyCallback(java.security.PublicKey publicKey) {
+        this.publicKey = publicKey;
+    }
+    
+    public void setPublicKey(java.security.PublicKey publicKey) {
+        this.publicKey = publicKey;
+    }
+    
+    public java.security.PublicKey getPublicKey() {
+        return publicKey;
+    }
+    
+    /**
+     * Evaluate whether a given public key should be trusted.
+     * Essentially, this amounts to checking to see if there is a certificate 
in the keystore,
+     * whose public key matches the transmitted public key.
+     */
+    public boolean verifyTrust(
+        java.security.KeyStore keyStore
+    ) throws WSSecurityException {
+        //
+        // If the public key is null, do not trust the signature
+        //
+        if (publicKey == null || keyStore == null) {
+            return false;
+        }
+        
+        //
+        // Search the keystore for the transmitted public key (direct trust)
+        //
+        try {
+            for (Enumeration e = keyStore.aliases(); e.hasMoreElements();) {
+                String alias = (String) e.nextElement();
+                Certificate[] certs = keyStore.getCertificateChain(alias);
+                Certificate cert;
+                if (certs == null || certs.length == 0) {
+                    // no cert chain, so lets check if getCertificate gives us 
a result.
+                    cert = keyStore.getCertificate(alias);
+                    if (cert == null) {
+                        continue;
+                    }
+                } else {
+                    cert = certs[0];
+                }
+                if (!(cert instanceof X509Certificate)) {
+                    continue;
+                }
+                X509Certificate x509cert = (X509Certificate) cert;
+                if (publicKey.equals(x509cert.getPublicKey())) {
+                    return true;
+                }
+            }
+        } catch (KeyStoreException e) {
+            return false;
+        }
+        return false;
+    }
+}
+
+

Propchange: 
webservices/wss4j/trunk/src/org/apache/ws/security/PublicKeyCallback.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
webservices/wss4j/trunk/src/org/apache/ws/security/PublicKeyCallback.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Modified: 
webservices/wss4j/trunk/src/org/apache/ws/security/processor/SignatureProcessor.java
URL: 
http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/org/apache/ws/security/processor/SignatureProcessor.java?rev=751008&r1=751007&r2=751008&view=diff
==============================================================================
--- 
webservices/wss4j/trunk/src/org/apache/ws/security/processor/SignatureProcessor.java
 (original)
+++ 
webservices/wss4j/trunk/src/org/apache/ws/security/processor/SignatureProcessor.java
 Fri Mar  6 17:58:38 2009
@@ -21,6 +21,7 @@
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.ws.security.CustomTokenPrincipal;
+import org.apache.ws.security.PublicKeyCallback;
 import org.apache.ws.security.PublicKeyPrincipal;
 import org.apache.ws.security.WSConstants;
 import org.apache.ws.security.WSDerivedKeyTokenPrincipal;
@@ -89,6 +90,7 @@
         Set protectedElements = new java.util.TreeSet();
         byte[][] signatureValue = new byte[1][];
         Principal lastPrincipalFound = null;
+        
         try {
             lastPrincipalFound = 
                 verifyXMLSignature(
@@ -387,6 +389,21 @@
                 );
             }
         }
+        //
+        // Delegate verification of a public key to a Callback Handler
+        //
+        if (publicKey != null) {
+            PublicKeyCallback pwcb = 
+                new PublicKeyCallback(publicKey);
+            try {
+                Callback[] callbacks = new Callback[]{pwcb};
+                cb.handle(callbacks);
+            } catch (Exception e) {
+                throw new WSSecurityException(
+                    WSSecurityException.FAILED_AUTHENTICATION, null, null, e
+                );
+            }
+        }
         try {
             boolean signatureOk = false;
             if (certs != null) {
@@ -422,7 +439,7 @@
                         );
                     }
                     String uri = siRef.getURI();
-                    if(uri != null && !"".equals(uri)) {
+                    if (uri != null && !"".equals(uri)) {
                         Element se = 
WSSecurityUtil.getElementByWsuId(elem.getOwnerDocument(), uri);
                         if (se == null) {
                             se = 
WSSecurityUtil.getElementByGenId(elem.getOwnerDocument(), uri);
@@ -517,6 +534,7 @@
         return null;
     }
 
+
     /**
      * Checks the <code>element</code> and creates appropriate binary security 
object.
      *

Modified: 
webservices/wss4j/trunk/src/org/apache/ws/security/processor/UsernameTokenProcessor.java
URL: 
http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/org/apache/ws/security/processor/UsernameTokenProcessor.java?rev=751008&r1=751007&r2=751008&view=diff
==============================================================================
--- 
webservices/wss4j/trunk/src/org/apache/ws/security/processor/UsernameTokenProcessor.java
 (original)
+++ 
webservices/wss4j/trunk/src/org/apache/ws/security/processor/UsernameTokenProcessor.java
 Fri Mar  6 17:58:38 2009
@@ -52,8 +52,10 @@
         handleCustomPasswordTypes = wsc.getHandleCustomPasswordTypes();
         
         Principal lastPrincipalFound = handleUsernameToken((Element) elem, cb);
-        returnResults.add(0, new WSSecurityEngineResult(WSConstants.UT,
-                lastPrincipalFound, null, null, null));
+        returnResults.add(
+            0, 
+            new WSSecurityEngineResult(WSConstants.UT, lastPrincipalFound, 
null, null, null)
+        );
         utId = ut.getID();
     }
 

Modified: webservices/wss4j/trunk/test/wssec/SignatureKeyValueTest.java
URL: 
http://svn.apache.org/viewvc/webservices/wss4j/trunk/test/wssec/SignatureKeyValueTest.java?rev=751008&r1=751007&r2=751008&view=diff
==============================================================================
--- webservices/wss4j/trunk/test/wssec/SignatureKeyValueTest.java (original)
+++ webservices/wss4j/trunk/test/wssec/SignatureKeyValueTest.java Fri Mar  6 
17:58:38 2009
@@ -27,9 +27,9 @@
 import org.apache.axis.message.SOAPEnvelope;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.apache.ws.security.PublicKeyCallback;
 import org.apache.ws.security.PublicKeyPrincipal;
 import org.apache.ws.security.WSConstants;
-import org.apache.ws.security.WSPasswordCallback;
 import org.apache.ws.security.WSSecurityEngine;
 import org.apache.ws.security.WSSecurityEngineResult;
 import org.apache.ws.security.components.crypto.Crypto;
@@ -39,13 +39,14 @@
 import org.apache.ws.security.util.WSSecurityUtil;
 import org.w3c.dom.Document;
 
-import javax.security.auth.callback.Callback;
-import javax.security.auth.callback.CallbackHandler;
-import javax.security.auth.callback.UnsupportedCallbackException;
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.UnsupportedCallbackException;
+
 /**
  * This class tests signing where the the public key is transmitted in the 
message via
  * a ds:KeyInfo/ds:KeyValue element. Although this isn't strictly recommended 
for use in
@@ -68,6 +69,7 @@
     
     private WSSecurityEngine secEngine = new WSSecurityEngine();
     private Crypto crypto = CryptoFactory.getInstance("cryptoSKI.properties");
+    private java.security.KeyStore keyStore = null;
     private MessageContext msgContext;
     private SOAPEnvelope unsignedEnvelope;
 
@@ -79,6 +81,7 @@
      */
     public SignatureKeyValueTest(String name) {
         super(name);
+        keyStore = crypto.getKeyStore();
     }
 
     /**
@@ -147,8 +150,41 @@
         java.security.PublicKey publicKey = 
             ((PublicKeyPrincipal)principal).getPublicKey();
         assertTrue(publicKey instanceof java.security.interfaces.RSAPublicKey);
+        
+    }
+    
+    
+    /**
+     * Failed RSAKeyValue test, where a message is signed using a key-pair 
which doesn't
+     * correspond to the public key in the "trust"-store.
+     */
+    public void testBadRSAKeyValue() throws Exception {
+        WSSecSignature builder = new WSSecSignature();
+        builder.setUserInfo("wss86", "security");
+        builder.setKeyIdentifierType(WSConstants.KEY_VALUE);
+        Document doc = unsignedEnvelope.getAsDocument();
+        WSSecHeader secHeader = new WSSecHeader();
+        secHeader.insertSecurityHeader(doc);
+        Document signedDoc = 
+            builder.build(doc, CryptoFactory.getInstance("wss86.properties"), 
secHeader);
+
+        String outputString = 
+            
org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(signedDoc);
+        if (LOG.isDebugEnabled()) {
+            LOG.debug(outputString);
+        }
+        assertTrue(outputString.indexOf("RSAKeyValue") != -1);
+        
+        try {
+            verify(signedDoc);
+            fail("Failure expected on bad public key");
+        } catch (Exception ex) {
+            // expected
+        }
+        
     }
     
+    
     /**
      * Successful DSAKeyValue test.
      */
@@ -192,22 +228,20 @@
     private java.util.Vector verify(Document doc) throws Exception {
         return secEngine.processSecurityHeader(doc, null, this, null);
     }
-
-    public void handle(Callback[] callbacks)
+    
+    public void handle(Callback[] callbacks) 
         throws IOException, UnsupportedCallbackException {
         for (int i = 0; i < callbacks.length; i++) {
-            if (callbacks[i] instanceof WSPasswordCallback) {
-                WSPasswordCallback pc = (WSPasswordCallback) callbacks[i];
-                /*
-                 * here call a function/method to lookup the password for
-                 * the given identifier (e.g. a user name or keystore alias)
-                 * e.g.: 
pc.setPassword(passStore.getPassword(pc.getIdentfifier))
-                 * for Testing we supply a fixed name here.
-                 */
-                pc.setPassword("password");
+            if (callbacks[i] instanceof PublicKeyCallback) {
+                PublicKeyCallback pc = (PublicKeyCallback) callbacks[i];
+                java.security.PublicKey publicKey = pc.getPublicKey();
+                if (publicKey == null || !pc.verifyTrust(keyStore)) {
+                    throw new IOException("Authentication of public key 
failed");
+                }
             } else {
                 throw new UnsupportedCallbackException(callbacks[i], 
"Unrecognized Callback");
             }
         }
     }
+
 }

Modified: webservices/wss4j/trunk/test/wssec/TestWSSecurityWSS86.java
URL: 
http://svn.apache.org/viewvc/webservices/wss4j/trunk/test/wssec/TestWSSecurityWSS86.java?rev=751008&r1=751007&r2=751008&view=diff
==============================================================================
--- webservices/wss4j/trunk/test/wssec/TestWSSecurityWSS86.java (original)
+++ webservices/wss4j/trunk/test/wssec/TestWSSecurityWSS86.java Fri Mar  6 
17:58:38 2009
@@ -35,7 +35,6 @@
 import org.apache.ws.security.message.WSSecEncrypt;
 import org.apache.ws.security.message.WSSecSignature;
 import org.apache.ws.security.message.WSSecHeader;
-import org.apache.xml.security.utils.RFC2253Parser;
 import org.w3c.dom.Document;
 
 import javax.security.auth.callback.Callback;



---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to