Author: coheigea
Date: Fri Nov 12 17:39:51 2010
New Revision: 1034489

URL: http://svn.apache.org/viewvc?rev=1034489&view=rev
Log:
[WSS-40] - Ported this to 1_5_x-fixes.

Added:
    webservices/wss4j/branches/1_5_x-fixes/keys/wss40CA.jks   (with props)
    webservices/wss4j/branches/1_5_x-fixes/keys/wss40badca.jks   (with props)
    webservices/wss4j/branches/1_5_x-fixes/keys/wss40badcatrust.jks   (with 
props)
    webservices/wss4j/branches/1_5_x-fixes/test/wss40CA.properties
    webservices/wss4j/branches/1_5_x-fixes/test/wss40badca.properties
    webservices/wss4j/branches/1_5_x-fixes/test/wss40badcatrust.properties
    webservices/wss4j/branches/1_5_x-fixes/test/wssec/TestWSSecurityWSS40.java
Modified:
    
webservices/wss4j/branches/1_5_x-fixes/src/org/apache/ws/security/WSDocInfo.java
    
webservices/wss4j/branches/1_5_x-fixes/src/org/apache/ws/security/action/SignatureAction.java
    
webservices/wss4j/branches/1_5_x-fixes/src/org/apache/ws/security/handler/RequestData.java
    
webservices/wss4j/branches/1_5_x-fixes/src/org/apache/ws/security/handler/WSHandler.java
    
webservices/wss4j/branches/1_5_x-fixes/src/org/apache/ws/security/handler/WSHandlerConstants.java
    
webservices/wss4j/branches/1_5_x-fixes/src/org/apache/ws/security/processor/SignatureProcessor.java
    webservices/wss4j/branches/1_5_x-fixes/test/wssec/MyHandler.java

Added: webservices/wss4j/branches/1_5_x-fixes/keys/wss40CA.jks
URL: 
http://svn.apache.org/viewvc/webservices/wss4j/branches/1_5_x-fixes/keys/wss40CA.jks?rev=1034489&view=auto
==============================================================================
Binary file - no diff available.

Propchange: webservices/wss4j/branches/1_5_x-fixes/keys/wss40CA.jks
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: webservices/wss4j/branches/1_5_x-fixes/keys/wss40badca.jks
URL: 
http://svn.apache.org/viewvc/webservices/wss4j/branches/1_5_x-fixes/keys/wss40badca.jks?rev=1034489&view=auto
==============================================================================
Binary file - no diff available.

Propchange: webservices/wss4j/branches/1_5_x-fixes/keys/wss40badca.jks
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: webservices/wss4j/branches/1_5_x-fixes/keys/wss40badcatrust.jks
URL: 
http://svn.apache.org/viewvc/webservices/wss4j/branches/1_5_x-fixes/keys/wss40badcatrust.jks?rev=1034489&view=auto
==============================================================================
Binary file - no diff available.

Propchange: webservices/wss4j/branches/1_5_x-fixes/keys/wss40badcatrust.jks
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Modified: 
webservices/wss4j/branches/1_5_x-fixes/src/org/apache/ws/security/WSDocInfo.java
URL: 
http://svn.apache.org/viewvc/webservices/wss4j/branches/1_5_x-fixes/src/org/apache/ws/security/WSDocInfo.java?rev=1034489&r1=1034488&r2=1034489&view=diff
==============================================================================
--- 
webservices/wss4j/branches/1_5_x-fixes/src/org/apache/ws/security/WSDocInfo.java
 (original)
+++ 
webservices/wss4j/branches/1_5_x-fixes/src/org/apache/ws/security/WSDocInfo.java
 Fri Nov 12 17:39:51 2010
@@ -118,18 +118,17 @@ public class WSDocInfo {
      */
     public Element getBst(String uri) {
         String id = uri.substring(1);
-        Element elem = null;
 
         if (bst != null) {
             for (Enumeration e = bst.elements(); e.hasMoreElements();) {
-                elem = (Element) e.nextElement();
-                String cId = elem.getAttribute("Id");
+                Element elem = (Element) e.nextElement();
+                String cId = elem.getAttributeNS(WSConstants.WSU_NS, "Id");
                 if (id.equals(cId)) {
-                    break;
+                    return elem;
                 }
             }
         }
-        return elem;
+        return null;
     }
 
     /**

Modified: 
webservices/wss4j/branches/1_5_x-fixes/src/org/apache/ws/security/action/SignatureAction.java
URL: 
http://svn.apache.org/viewvc/webservices/wss4j/branches/1_5_x-fixes/src/org/apache/ws/security/action/SignatureAction.java?rev=1034489&r1=1034488&r2=1034489&view=diff
==============================================================================
--- 
webservices/wss4j/branches/1_5_x-fixes/src/org/apache/ws/security/action/SignatureAction.java
 (original)
+++ 
webservices/wss4j/branches/1_5_x-fixes/src/org/apache/ws/security/action/SignatureAction.java
 Fri Nov 12 17:39:51 2010
@@ -52,6 +52,7 @@ public class SignatureAction implements 
         }
 
         wsSign.setUserInfo(reqData.getSignatureUser(), pwcb.getPassword());
+        wsSign.setUseSingleCertificate(reqData.isUseSingleCert());
         if (reqData.getSignatureParts().size() > 0) {
             wsSign.setParts(reqData.getSignatureParts());
         }

Modified: 
webservices/wss4j/branches/1_5_x-fixes/src/org/apache/ws/security/handler/RequestData.java
URL: 
http://svn.apache.org/viewvc/webservices/wss4j/branches/1_5_x-fixes/src/org/apache/ws/security/handler/RequestData.java?rev=1034489&r1=1034488&r2=1034489&view=diff
==============================================================================
--- 
webservices/wss4j/branches/1_5_x-fixes/src/org/apache/ws/security/handler/RequestData.java
 (original)
+++ 
webservices/wss4j/branches/1_5_x-fixes/src/org/apache/ws/security/handler/RequestData.java
 Fri Nov 12 17:39:51 2010
@@ -65,6 +65,7 @@ public class RequestData {
     private boolean useDerivedKey = false;
     private int derivedKeyIterations = UsernameToken.DEFAULT_ITERATION;
     private boolean useDerivedKeyForMAC = true;
+    private boolean useSingleCert = true;
 
     public void clear() {
         soapConstants = null;
@@ -83,6 +84,7 @@ public class RequestData {
         useDerivedKey = false;
         derivedKeyIterations = UsernameToken.DEFAULT_ITERATION;
         useDerivedKeyForMAC = true;
+        useSingleCert = true;
     }
 
     public Object getMsgContext() {
@@ -351,4 +353,21 @@ public class RequestData {
         return useDerivedKeyForMAC;
     }
     
+    /**
+     * Whether to use a single certificate or a whole certificate chain when
+     * constructing a BinarySecurityToken used for direct reference in 
Signature.
+     * @param useSingleCert true if only to use a single certificate
+     */
+    public void setUseSingleCert(boolean useSingleCert) {
+        this.useSingleCert = useSingleCert;
+    }
+    
+    /**
+     * Whether to use a single certificate or a whole certificate chain when
+     * constructing a BinarySecurityToken used for direct reference in 
Signature.
+     * @return whether to use a single certificate
+     */
+    public boolean isUseSingleCert() {
+        return useSingleCert;
+    }
 }

Modified: 
webservices/wss4j/branches/1_5_x-fixes/src/org/apache/ws/security/handler/WSHandler.java
URL: 
http://svn.apache.org/viewvc/webservices/wss4j/branches/1_5_x-fixes/src/org/apache/ws/security/handler/WSHandler.java?rev=1034489&r1=1034488&r2=1034489&view=diff
==============================================================================
--- 
webservices/wss4j/branches/1_5_x-fixes/src/org/apache/ws/security/handler/WSHandler.java
 (original)
+++ 
webservices/wss4j/branches/1_5_x-fixes/src/org/apache/ws/security/handler/WSHandler.java
 Fri Nov 12 17:39:51 2010
@@ -599,6 +599,9 @@ public abstract class WSHandler {
             int iSecretKeyLength = Integer.parseInt(secretKeyLength);
             reqData.setSecretKeyLength(iSecretKeyLength);
         }
+        
+        boolean useSingleCert = decodeUseSingleCertificate(reqData);
+        reqData.setUseSingleCert(useSingleCert);
     }
 
     protected void decodeEncryptionParameter(RequestData reqData) 
@@ -828,6 +831,26 @@ public abstract class WSHandler {
             "WSHandler: illegal timestampStrict parameter"
         );
     }
+    
+    protected boolean decodeUseSingleCertificate(RequestData reqData) 
+        throws WSSecurityException {
+        String useSingleCert = 
+            getString(WSHandlerConstants.USE_SINGLE_CERTIFICATE, 
reqData.getMsgContext());
+    
+        if (useSingleCert == null) {
+            return true;
+        }
+        if ("0".equals(useSingleCert) || "false".equals(useSingleCert)) {
+            return false;
+        } 
+        if ("1".equals(useSingleCert) || "true".equals(useSingleCert)) {
+            return true;
+        }
+    
+        throw new WSSecurityException(
+            "WSHandler: illegal useSingleCert parameter"
+        );
+    }
 
     /**
      * Get a password to construct a UsernameToken or sign a message.
@@ -1314,6 +1337,54 @@ public abstract class WSHandler {
         }
         return false;
     }
+    
+    /**
+     * Evaluate whether the given certificate chain should be trusted.
+     * 
+     * @param certificates the certificate chain that should be validated 
against the keystore
+     * @return true if the certificate chain is trusted, false if not
+     * @throws WSSecurityException
+     */
+    protected boolean verifyTrust(X509Certificate[] certificates, RequestData 
reqData) 
+        throws WSSecurityException {
+        
+        // If no certificate was transmitted, do not trust the signature
+        if (certificates == null) {
+            return false;
+        }
+        
+        String subjectString = 
certificates[0].getSubjectX500Principal().getName();
+        //
+        // Use the validation method from the crypto to check whether the 
subjects' 
+        // certificate was really signed by the issuer stated in the 
certificate
+        //
+        try {
+            if (certificates != null && certificates.length > 1
+                && reqData.getSigCrypto().validateCertPath(certificates)) {
+                if (log.isDebugEnabled()) {
+                    log.debug(
+                        "Certificate path has been verified for certificate 
with subject " 
+                        + subjectString
+                    );
+                }
+                return true;
+            }
+        } catch (WSSecurityException ex) {
+            throw new WSSecurityException(
+                "WSHandler: Certificate path verification failed for 
certificate "
+                + "with subject " + subjectString, ex
+            );
+        }
+        
+        if (log.isDebugEnabled()) {
+            log.debug(
+                "Certificate path could not be verified for certificate with 
subject " 
+                + subjectString
+            );
+        }
+            
+        return false;
+    }
 
     /**
      * Evaluate whether a timestamp is considered valid on the receivers' 
side. Hook to

Modified: 
webservices/wss4j/branches/1_5_x-fixes/src/org/apache/ws/security/handler/WSHandlerConstants.java
URL: 
http://svn.apache.org/viewvc/webservices/wss4j/branches/1_5_x-fixes/src/org/apache/ws/security/handler/WSHandlerConstants.java?rev=1034489&r1=1034488&r2=1034489&view=diff
==============================================================================
--- 
webservices/wss4j/branches/1_5_x-fixes/src/org/apache/ws/security/handler/WSHandlerConstants.java
 (original)
+++ 
webservices/wss4j/branches/1_5_x-fixes/src/org/apache/ws/security/handler/WSHandlerConstants.java
 Fri Nov 12 17:39:51 2010
@@ -596,6 +596,13 @@ public class WSHandlerConstants {
     public static final String SIGNATURE_PARTS = "signatureParts";
     
     /**
+     * This parameter sets whether to use a single certificate or a whole 
certificate
+     * chain when constructing a BinarySecurityToken used for direct reference 
in
+     * signature. The default is true, meaning that only a single certificate 
is used.
+     */
+    public static final String USE_SINGLE_CERTIFICATE = "useSingleCertificate";
+    
+    /**
      * This parameter sets the length of the secret (derived) key to use for 
the
      * WSE UT_SIGN functionality.
      * 

Modified: 
webservices/wss4j/branches/1_5_x-fixes/src/org/apache/ws/security/processor/SignatureProcessor.java
URL: 
http://svn.apache.org/viewvc/webservices/wss4j/branches/1_5_x-fixes/src/org/apache/ws/security/processor/SignatureProcessor.java?rev=1034489&r1=1034488&r2=1034489&view=diff
==============================================================================
--- 
webservices/wss4j/branches/1_5_x-fixes/src/org/apache/ws/security/processor/SignatureProcessor.java
 (original)
+++ 
webservices/wss4j/branches/1_5_x-fixes/src/org/apache/ws/security/processor/SignatureProcessor.java
 Fri Nov 12 17:39:51 2010
@@ -80,6 +80,8 @@ public class SignatureProcessor implemen
     
     private String signatureId;
     
+    private X509Certificate[] certificates;
+    
     private int secretKeyLength = WSConstants.WSE_DERIVED_KEY_LEN;
     
     private String signatureMethod;
@@ -106,6 +108,7 @@ public class SignatureProcessor implemen
         Principal lastPrincipalFound = null;
         secretKeyLength = wsc.getSecretKeyLength();
         signatureMethod = c14nMethod = null;
+        certificates = null;
         
         try {
             lastPrincipalFound = 
@@ -137,6 +140,7 @@ public class SignatureProcessor implemen
                     returnElements, protectedElements, signatureValue[0]);
             result.put(WSSecurityEngineResult.TAG_SIGNATURE_METHOD, 
signatureMethod);
             result.put(WSSecurityEngineResult.TAG_CANONICALIZATION_METHOD, 
c14nMethod);
+            result.put(WSSecurityEngineResult.TAG_X509_CERTIFICATES, 
certificates);
             returnResults.add(
                 0, 
                 result
@@ -213,7 +217,6 @@ public class SignatureProcessor implemen
 
         sig.addResourceResolver(EnvelopeIdResolver.getInstance());
 
-        X509Certificate[] certs = null;
         KeyInfo info = sig.getKeyInfo();
         byte[] secretKey = null;
         UsernameToken ut = null;
@@ -221,6 +224,8 @@ public class SignatureProcessor implemen
         SAMLKeyInfo samlKi = null;
         String customTokenId = null;
         java.security.PublicKey publicKey = null;
+        X509Certificate[] certs = null;
+        boolean validateCertificateChain = false;
         
         if (info != null && info.containsKeyValue()) {
             try {
@@ -262,6 +267,9 @@ public class SignatureProcessor implemen
                     QName el = new QName(token.getNamespaceURI(), 
token.getLocalName());
                     if (el.equals(WSSecurityEngine.binaryToken)) {
                         certs = getCertificatesTokenReference(token, crypto);
+                        if (certs != null && certs.length > 1) {
+                            validateCertificateChain = true;
+                        }
                     } else if (el.equals(WSSecurityEngine.SAML_TOKEN)) {
                         if (crypto == null) {
                             throw new WSSecurityException(
@@ -321,6 +329,9 @@ public class SignatureProcessor implemen
                     }
                 } else if (processor instanceof BinarySecurityTokenProcessor) {
                     certs = 
((BinarySecurityTokenProcessor)processor).getCertificates();
+                    if (certs != null && certs.length > 1) {
+                        validateCertificateChain = true;
+                    }
                 } else if (processor instanceof EncryptedKeyProcessor) {
                     EncryptedKeyProcessor ekProcessor = 
(EncryptedKeyProcessor)processor;
                     secretKey = ekProcessor.getDecryptedBytes();
@@ -420,7 +431,9 @@ public class SignatureProcessor implemen
         }
         if (certs != null) {
             try {
-                certs[0].checkValidity();
+                for (int i = 0; i < certs.length; i++) {
+                    certs[i].checkValidity();
+                }
             } catch (CertificateExpiredException e) {
                 throw new WSSecurityException(
                     WSSecurityException.FAILED_CHECK, "invalidCert", null, e
@@ -564,6 +577,9 @@ public class SignatureProcessor implemen
                 
                 if (certs != null) {
                     returnCert[0] = certs[0];
+                    if (validateCertificateChain) {
+                        certificates = certs;
+                    }
                     return certs[0].getSubjectX500Principal();
                 } else if (publicKey != null) {
                     return new PublicKeyPrincipal(publicKey);

Added: webservices/wss4j/branches/1_5_x-fixes/test/wss40CA.properties
URL: 
http://svn.apache.org/viewvc/webservices/wss4j/branches/1_5_x-fixes/test/wss40CA.properties?rev=1034489&view=auto
==============================================================================
--- webservices/wss4j/branches/1_5_x-fixes/test/wss40CA.properties (added)
+++ webservices/wss4j/branches/1_5_x-fixes/test/wss40CA.properties Fri Nov 12 
17:39:51 2010
@@ -0,0 +1,4 @@
+org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin
+org.apache.ws.security.crypto.merlin.keystore.type=jks
+org.apache.ws.security.crypto.merlin.keystore.password=security
+org.apache.ws.security.crypto.merlin.file=keys/wss40CA.jks

Added: webservices/wss4j/branches/1_5_x-fixes/test/wss40badca.properties
URL: 
http://svn.apache.org/viewvc/webservices/wss4j/branches/1_5_x-fixes/test/wss40badca.properties?rev=1034489&view=auto
==============================================================================
--- webservices/wss4j/branches/1_5_x-fixes/test/wss40badca.properties (added)
+++ webservices/wss4j/branches/1_5_x-fixes/test/wss40badca.properties Fri Nov 
12 17:39:51 2010
@@ -0,0 +1,4 @@
+org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin
+org.apache.ws.security.crypto.merlin.keystore.type=jks
+org.apache.ws.security.crypto.merlin.keystore.password=security
+org.apache.ws.security.crypto.merlin.file=keys/wss40badca.jks

Added: webservices/wss4j/branches/1_5_x-fixes/test/wss40badcatrust.properties
URL: 
http://svn.apache.org/viewvc/webservices/wss4j/branches/1_5_x-fixes/test/wss40badcatrust.properties?rev=1034489&view=auto
==============================================================================
--- webservices/wss4j/branches/1_5_x-fixes/test/wss40badcatrust.properties 
(added)
+++ webservices/wss4j/branches/1_5_x-fixes/test/wss40badcatrust.properties Fri 
Nov 12 17:39:51 2010
@@ -0,0 +1,4 @@
+org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin
+org.apache.ws.security.crypto.merlin.keystore.type=jks
+org.apache.ws.security.crypto.merlin.keystore.password=security
+org.apache.ws.security.crypto.merlin.file=keys/wss40badcatrust.jks

Modified: webservices/wss4j/branches/1_5_x-fixes/test/wssec/MyHandler.java
URL: 
http://svn.apache.org/viewvc/webservices/wss4j/branches/1_5_x-fixes/test/wssec/MyHandler.java?rev=1034489&r1=1034488&r2=1034489&view=diff
==============================================================================
--- webservices/wss4j/branches/1_5_x-fixes/test/wssec/MyHandler.java (original)
+++ webservices/wss4j/branches/1_5_x-fixes/test/wssec/MyHandler.java Fri Nov 12 
17:39:51 2010
@@ -19,10 +19,12 @@
 
 package wssec;
 
+import org.apache.ws.security.WSSecurityException;
 import org.apache.ws.security.handler.WSHandler;
 import org.apache.ws.security.handler.RequestData;
 import org.w3c.dom.Document;
 
+import java.security.cert.X509Certificate;
 import java.util.HashMap;
 import java.util.Map;
 
@@ -120,5 +122,13 @@ public class MyHandler extends WSHandler
         return checkReceiverResultsAnyOrder(results, actions);
     }
     
+    public boolean verifyTrust(
+        X509Certificate[] certificates, 
+        RequestData reqData
+    ) throws WSSecurityException {
+        return super.verifyTrust(certificates, reqData);
+    }
+    
+    
     
 }

Added: 
webservices/wss4j/branches/1_5_x-fixes/test/wssec/TestWSSecurityWSS40.java
URL: 
http://svn.apache.org/viewvc/webservices/wss4j/branches/1_5_x-fixes/test/wssec/TestWSSecurityWSS40.java?rev=1034489&view=auto
==============================================================================
--- webservices/wss4j/branches/1_5_x-fixes/test/wssec/TestWSSecurityWSS40.java 
(added)
+++ webservices/wss4j/branches/1_5_x-fixes/test/wssec/TestWSSecurityWSS40.java 
Fri Nov 12 17:39:51 2010
@@ -0,0 +1,370 @@
+/**
+ * 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 wssec;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+import org.apache.axis.Message;
+import org.apache.axis.MessageContext;
+import org.apache.axis.client.AxisClient;
+import org.apache.axis.configuration.NullProvider;
+import org.apache.axis.message.SOAPEnvelope;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ws.security.WSPasswordCallback;
+import org.apache.ws.security.WSSConfig;
+import org.apache.ws.security.WSSecurityEngine;
+import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.WSSecurityEngineResult;
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.security.components.crypto.Crypto;
+import org.apache.ws.security.components.crypto.CryptoFactory;
+import org.apache.ws.security.handler.RequestData;
+import org.apache.ws.security.handler.WSHandlerConstants;
+import org.apache.ws.security.message.WSSecSignature;
+import org.apache.ws.security.message.WSSecHeader;
+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 java.security.cert.X509Certificate;
+import java.util.Vector;
+
+/**
+ * This is a test for WSS-40. Essentially it just tests that a message is 
signed using a
+ * keyEntry from one keystore, and verified at the other end with a keystore 
with just the
+ * CA cert in it.
+ * 
+ * http://issues.apache.org/jira/browse/WSS-40
+ * 
+ * Generate the CA keys/certs + export the CA cert to a keystore
+ * 
+ * openssl req -x509 -newkey rsa:1024 -keyout wss40CAKey.pem -out wss40CA.pem 
+ * -config ca.config -days 3650
+ * openssl x509 -outform DER -in wss40CA.pem -out wss40CA.crt
+ * keytool -import -file wss40CA.crt -alias wss40CA -keystore wss40CA.jks
+ * 
+ * Generate the client keypair, make a csr, sign it with the CA key
+ * 
+ * keytool -genkey -validity 3650 -alias wss40 -keyalg RSA -keystore wss40.jks 
+ * -dname "CN=Colm,OU=WSS4J,O=Apache,L=Dublin,ST=Leinster,C=IE"
+ * keytool -certreq -alias wss40 -keystore wss40.jks -file wss40.cer
+ * openssl ca -config ca.config -policy policy_anything -days 3650 -out 
wss40.pem 
+ * -infiles wss40.cer
+ * openssl x509 -outform DER -in wss40.pem -out wss40.crt
+ * 
+ * Import the CA cert into wss40.jks and import the new signed certificate
+ * 
+ * keytool -import -file wss40CA.crt -alias wss40CA -keystore wss40.jks
+ * keytool -import -file wss40.crt -alias wss40 -keystore wss40.jks
+ * 
+ */
+public class TestWSSecurityWSS40 extends TestCase implements CallbackHandler {
+    private static final Log LOG = 
LogFactory.getLog(TestWSSecurityWSS40.class);
+    private static final String SOAPMSG = 
+        "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" 
+        + "<SOAP-ENV:Envelope "
+        +   "xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\"; "
+        +   "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"; "
+        +   "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\";>" 
+        +   "<SOAP-ENV:Body>" 
+        +       "<add 
xmlns=\"http://ws.apache.org/counter/counter_port_type\";>" 
+        +           "<value xmlns=\"\">15</value>" 
+        +       "</add>" 
+        +   "</SOAP-ENV:Body>" 
+        + "</SOAP-ENV:Envelope>";
+    private WSSecurityEngine secEngine = new WSSecurityEngine();
+    private Crypto crypto = CryptoFactory.getInstance("wss40.properties");
+    private Crypto cryptoCA = CryptoFactory.getInstance("wss40CA.properties");
+    private MessageContext msgContext;
+    private SOAPEnvelope unsignedEnvelope;
+
+    /**
+     * TestWSSecurity constructor
+     * 
+     * @param name name of the test
+     */
+    public TestWSSecurityWSS40(String name) {
+        super(name);
+    }
+
+    /**
+     * JUnit suite
+     * 
+     * @return a junit test suite
+     */
+    public static Test suite() {
+        return new TestSuite(TestWSSecurityWSS40.class);
+    }
+    
+    /**
+     * Setup method
+     * <p/>
+     * 
+     * @throws java.lang.Exception Thrown when there is a problem in setup
+     */
+    protected void setUp() throws Exception {
+        AxisClient tmpEngine = new AxisClient(new NullProvider());
+        msgContext = new MessageContext(tmpEngine);
+        unsignedEnvelope = getSOAPEnvelope();
+    }
+    
+    /**
+     * Constructs a soap envelope
+     * <p/>
+     * 
+     * @return soap envelope
+     * @throws java.lang.Exception if there is any problem constructing the 
soap envelope
+     */
+    protected SOAPEnvelope getSOAPEnvelope() throws Exception {
+        InputStream in = new ByteArrayInputStream(SOAPMSG.getBytes());
+        Message msg = new Message(in);
+        msg.setMessageContext(msgContext);
+        return msg.getSOAPEnvelope();
+    }
+
+    /**
+     * Test signing a SOAP message using a BST.
+     */
+    public void testSignatureDirectReference() throws Exception {
+        WSSecSignature sign = new WSSecSignature();
+        sign.setUserInfo("wss40", "security");
+        sign.setKeyIdentifierType(WSConstants.BST_DIRECT_REFERENCE);
+
+        Document doc = unsignedEnvelope.getAsDocument();
+
+        WSSecHeader secHeader = new WSSecHeader();
+        secHeader.insertSecurityHeader(doc);
+        Document signedDoc = sign.build(doc, crypto, secHeader);
+        
+        if (LOG.isDebugEnabled()) {
+            String outputString = 
+                
org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(signedDoc);
+            LOG.debug(outputString);
+        }
+        //
+        // Verify the signature
+        //
+        Vector results = verify(signedDoc, cryptoCA);
+        WSSecurityEngineResult result = 
+            WSSecurityUtil.fetchActionResult(results, WSConstants.SIGN);
+        X509Certificate cert = 
+            
(X509Certificate)result.get(WSSecurityEngineResult.TAG_X509_CERTIFICATE);
+        assertTrue (cert != null);
+        
+        // There should be no certificate chain for this example
+        X509Certificate[] certs = 
+            
(X509Certificate[])result.get(WSSecurityEngineResult.TAG_X509_CERTIFICATES);
+        assertTrue (certs == null);
+    }
+    
+    /**
+     * Test signing a SOAP message using a BST, sending the CA cert as well in 
the
+     * message.
+     */
+    public void testSignatureDirectReferenceCACert() throws Exception {
+        WSSecSignature sign = new WSSecSignature();
+        sign.setUserInfo("wss40", "security");
+        sign.setKeyIdentifierType(WSConstants.BST_DIRECT_REFERENCE);
+        sign.setUseSingleCertificate(false);
+
+        Document doc = unsignedEnvelope.getAsDocument();
+
+        WSSecHeader secHeader = new WSSecHeader();
+        secHeader.insertSecurityHeader(doc);
+        Document signedDoc = sign.build(doc, crypto, secHeader);
+        
+        if (LOG.isDebugEnabled()) {
+            String outputString = 
+                
org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(signedDoc);
+            LOG.debug("BST CA Cert");
+            LOG.debug(outputString);
+        }
+        //
+        // Verify the signature
+        //
+        Vector results = verify(signedDoc, cryptoCA);
+        WSSecurityEngineResult result = 
+            WSSecurityUtil.fetchActionResult(results, WSConstants.SIGN);
+        X509Certificate cert = 
+            
(X509Certificate)result.get(WSSecurityEngineResult.TAG_X509_CERTIFICATE);
+        assertTrue (cert != null);
+        X509Certificate[] certs = 
+            
(X509Certificate[])result.get(WSSecurityEngineResult.TAG_X509_CERTIFICATES);
+        assertTrue (certs != null && certs.length == 2);
+    }
+    
+    
+    /**
+     * Test signing a SOAP message using Issuer Serial. Note that this should 
fail, as the
+     * trust-store does not contain the cert corresponding to wss40, only the 
CA cert
+     * wss40CA.
+     */
+    public void testSignatureIssuerSerial() throws Exception {
+        WSSecSignature sign = new WSSecSignature();
+        sign.setUserInfo("wss40", "security");
+        sign.setKeyIdentifierType(WSConstants.ISSUER_SERIAL);
+
+        Document doc = unsignedEnvelope.getAsDocument();
+
+        WSSecHeader secHeader = new WSSecHeader();
+        secHeader.insertSecurityHeader(doc);
+        Document signedDoc = sign.build(doc, crypto, secHeader);
+        
+        if (LOG.isDebugEnabled()) {
+            String outputString = 
+                
org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(signedDoc);
+            LOG.debug(outputString);
+        }
+        
+        try {
+            verify(signedDoc, cryptoCA);
+            throw new Exception("Failure expected on issuer serial");
+        } catch (WSSecurityException ex) {
+            assertTrue(ex.getErrorCode() == WSSecurityException.FAILED_CHECK);
+            // expected
+        }
+    }
+    
+    
+    /**
+     * Test signing a SOAP message using a BST. The signature verification 
passes, but the trust
+     * verification will fail as the CA cert is out of date.
+     */
+    public void testSignatureBadCACert() throws Exception {
+        WSSecSignature sign = new WSSecSignature();
+        sign.setUserInfo("wss4jcertdsa", "security");
+        sign.setKeyIdentifierType(WSConstants.BST_DIRECT_REFERENCE);
+
+        Document doc = unsignedEnvelope.getAsDocument();
+
+        WSSecHeader secHeader = new WSSecHeader();
+        secHeader.insertSecurityHeader(doc);
+        Document signedDoc = 
+            sign.build(doc, 
CryptoFactory.getInstance("wss40badca.properties"), secHeader);
+        
+        if (LOG.isDebugEnabled()) {
+            String outputString = 
+                
org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(signedDoc);
+            LOG.debug(outputString);
+        }
+        //
+        // Verify the signature
+        //
+        try {
+            verify(signedDoc, 
CryptoFactory.getInstance("wss40badcatrust.properties"));
+            fail("Failure expected on bad CA cert!");
+        } catch (WSSecurityException ex) {
+            // expected
+        }
+    }
+    
+    /**
+     * A test for "SignatureAction does not set DigestAlgorithm on 
WSSecSignature instance"
+     */
+    public void testMultipleCertsWSHandler() throws Exception {
+        final WSSConfig cfg = WSSConfig.getNewInstance();
+        final int action = WSConstants.SIGN;
+        final RequestData reqData = new RequestData();
+        reqData.setWssConfig(cfg);
+        reqData.setUsername("wss40");
+        java.util.Map config = new java.util.TreeMap();
+        config.put(WSHandlerConstants.SIG_PROP_FILE, "wss40.properties");
+        config.put("password", "security");
+        config.put(WSHandlerConstants.SIG_KEY_ID, "DirectReference");
+        config.put(WSHandlerConstants.USE_SINGLE_CERTIFICATE, "false");
+        reqData.setMsgContext(config);
+        
+        final java.util.Vector actions = new java.util.Vector();
+        actions.add(new Integer(action));
+        Document doc = unsignedEnvelope.getAsDocument();
+        MyHandler handler = new MyHandler();
+        handler.send(
+            action, 
+            doc, 
+            reqData, 
+            actions,
+            true
+        );
+        
+        //
+        // Verify the signature
+        //
+        Vector results = verify(doc, cryptoCA);
+        WSSecurityEngineResult result = 
+            WSSecurityUtil.fetchActionResult(results, WSConstants.SIGN);
+        X509Certificate cert = 
+            
(X509Certificate)result.get(WSSecurityEngineResult.TAG_X509_CERTIFICATE);
+        assertTrue (cert != null);
+        X509Certificate[] certs = 
+            
(X509Certificate[])result.get(WSSecurityEngineResult.TAG_X509_CERTIFICATES);
+        assertTrue (certs != null && certs.length == 2);
+        
+        assertTrue(handler.verifyTrust(certs, reqData));
+    }
+    
+    
+    /**
+     * Verifies the soap envelope
+     * <p/>
+     * 
+     * @param doc 
+     * @throws Exception Thrown when there is a problem in verification
+     */
+    private Vector verify(Document doc, Crypto crypto) throws 
WSSecurityException {
+        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)
+        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("security");
+            } else {
+                throw new UnsupportedCallbackException(callbacks[i], 
"Unrecognized Callback");
+            }
+        }
+    }
+    
+}



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

Reply via email to