You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by se...@apache.org on 2011/07/22 00:32:13 UTC

svn commit: r1149391 - in /cxf/trunk/systests/rs-security/src/test: java/org/apache/cxf/systest/jaxrs/security/saml/ java/org/apache/cxf/systest/jaxrs/security/xml/ resources/org/apache/cxf/systest/jaxrs/security/ resources/org/apache/cxf/systest/jaxrs...

Author: sergeyb
Date: Thu Jul 21 22:32:11 2011
New Revision: 1149391

URL: http://svn.apache.org/viewvc?rev=1149391&view=rev
Log:
[CXF-3661] Prototyping XML Encryption handlers in systests - refactoring to follow

Added:
    cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/JAXRSXmlSecTest.java
      - copied, changed from r1148954, cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/JAXRSXmlSigTest.java
    cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/XmlEncInHandler.java   (with props)
    cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/XmlEncOutInterceptor.java   (with props)
    cxf/trunk/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/bob.properties   (with props)
    cxf/trunk/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/certs/bob.jks   (with props)
Removed:
    cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/JAXRSXmlSigTest.java
Modified:
    cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/saml/AbstractSamlInHandler.java
    cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/BookServerXmlSec.java
    cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/XmlSigInHandler.java
    cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/XmlSigOutInterceptor.java
    cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/server.xml

Modified: cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/saml/AbstractSamlInHandler.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/saml/AbstractSamlInHandler.java?rev=1149391&r1=1149390&r2=1149391&view=diff
==============================================================================
--- cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/saml/AbstractSamlInHandler.java (original)
+++ cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/saml/AbstractSamlInHandler.java Thu Jul 21 22:32:11 2011
@@ -65,6 +65,10 @@ public abstract class AbstractSamlInHand
     private static final Logger LOG = 
         LogUtils.getL7dLogger(AbstractSamlInHandler.class);
     
+    static {
+        WSSConfig.init();
+    }
+    
     private Validator samlValidator = new SamlAssertionValidator();
     
     public void setValidator(Validator validator) {
@@ -84,7 +88,7 @@ public abstract class AbstractSamlInHand
             AssertionWrapper assertion = new AssertionWrapper(doc.getDocumentElement());
             if (assertion.isSigned()) {
                 RequestData data = new RequestData();
-                WSSConfig cfg = new WSSConfig(); 
+                WSSConfig cfg = WSSConfig.getNewInstance(); 
                 data.setWssConfig(cfg);
                 data.setCallbackHandler(getCallbackHandler(message));
                 try {

Modified: cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/BookServerXmlSec.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/BookServerXmlSec.java?rev=1149391&r1=1149390&r2=1149391&view=diff
==============================================================================
--- cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/BookServerXmlSec.java (original)
+++ cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/BookServerXmlSec.java Thu Jul 21 22:32:11 2011
@@ -19,20 +19,14 @@
 
 package org.apache.cxf.systest.jaxrs.security.xml;
 
-import java.util.HashMap;
-import java.util.Map;
-
 import org.apache.cxf.Bus;
 import org.apache.cxf.BusFactory;
 import org.apache.cxf.bus.spring.SpringBusFactory;
-import org.apache.cxf.jaxrs.JAXRSServerFactoryBean;
-import org.apache.cxf.jaxrs.lifecycle.SingletonResourceProvider;
-import org.apache.cxf.systest.jaxrs.security.BookStore;
 import org.apache.cxf.testutil.common.AbstractBusTestServerBase;
 import org.apache.cxf.testutil.common.TestUtil;
     
 public class BookServerXmlSec extends AbstractBusTestServerBase {
-    public static final String PORT = TestUtil.getPortNumber("jaxrs-xmlsig");
+    public static final String PORT = TestUtil.getPortNumber("jaxrs-xmlsec");
     private static final String SERVER_CONFIG_FILE =
         "org/apache/cxf/systest/jaxrs/security/xml/server.xml";
     
@@ -40,25 +34,13 @@ public class BookServerXmlSec extends Ab
         SpringBusFactory bf = new SpringBusFactory();
         Bus springBus = bf.createBus(SERVER_CONFIG_FILE);
         BusFactory.setDefaultBus(springBus);
+        setBus(springBus);
         
-        JAXRSServerFactoryBean sf = new JAXRSServerFactoryBean();
-        
-        sf.setResourceClasses(BookStore.class);
-        
-        sf.setProvider(new XmlSigInHandler());
-        
-        sf.setResourceProvider(BookStore.class,
-                               new SingletonResourceProvider(new BookStore(), true));
-        sf.setAddress("https://localhost:" + PORT + "/");
-
-        Map<String, Object> properties = new HashMap<String, Object>();
-        properties.put("ws-security.callback-handler", 
-                       "org.apache.cxf.systest.jaxrs.security.saml.KeystorePasswordCallback");
-        properties.put("ws-security.signature.properties", 
-                       "org/apache/cxf/systest/jaxrs/security/alice.properties");
-        sf.setProperties(properties);
-        
-        sf.create();        
+        try {
+            new BookServerXmlSec();
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
     }
 
     public static void main(String[] args) {

Copied: cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/JAXRSXmlSecTest.java (from r1148954, cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/JAXRSXmlSigTest.java)
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/JAXRSXmlSecTest.java?p2=cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/JAXRSXmlSecTest.java&p1=cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/JAXRSXmlSigTest.java&r1=1148954&r2=1149391&rev=1149391&view=diff
==============================================================================
--- cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/JAXRSXmlSigTest.java (original)
+++ cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/JAXRSXmlSecTest.java Thu Jul 21 22:32:11 2011
@@ -35,7 +35,7 @@ import org.apache.cxf.testutil.common.Ab
 import org.junit.BeforeClass;
 import org.junit.Test;
 
-public class JAXRSXmlSigTest extends AbstractBusClientServerTestBase {
+public class JAXRSXmlSecTest extends AbstractBusClientServerTestBase {
     public static final String PORT = BookServerXmlSec.PORT;
 
     @BeforeClass
@@ -46,12 +46,12 @@ public class JAXRSXmlSigTest extends Abs
     
     @Test
     public void testPostBookWithEnvelopedSig() throws Exception {
-        String address = "https://localhost:" + PORT + "/bookstore/books";
+        String address = "https://localhost:" + PORT + "/xmlsig/bookstore/books";
         JAXRSClientFactoryBean bean = new JAXRSClientFactoryBean();
         bean.setAddress(address);
         
         SpringBusFactory bf = new SpringBusFactory();
-        URL busFile = JAXRSXmlSigTest.class.getResource("client.xml");
+        URL busFile = JAXRSXmlSecTest.class.getResource("client.xml");
         Bus springBus = bf.createBus(busFile.toString());
         bean.setBus(springBus);
 
@@ -81,5 +81,83 @@ public class JAXRSXmlSigTest extends Abs
         
     }
     
+    @Test
+    public void testPostEncryptedBook() throws Exception {
+        String address = "https://localhost:" + PORT + "/xmlenc/bookstore/books";
+        JAXRSClientFactoryBean bean = new JAXRSClientFactoryBean();
+        bean.setAddress(address);
+        
+        SpringBusFactory bf = new SpringBusFactory();
+        URL busFile = JAXRSXmlSecTest.class.getResource("client.xml");
+        Bus springBus = bf.createBus(busFile.toString());
+        bean.setBus(springBus);
+
+        Map<String, Object> properties = new HashMap<String, Object>();
+        properties.put("ws-security.callback-handler", 
+                       "org.apache.cxf.systest.jaxrs.security.saml.KeystorePasswordCallback");
+        properties.put("ws-security.encryption.username", "bob");
+        properties.put("ws-security.encryption.properties", 
+                       "org/apache/cxf/systest/jaxrs/security/bob.properties");
+        bean.setProperties(properties);
+        bean.getOutInterceptors().add(new XmlEncOutInterceptor());
+        
+        
+        WebClient wc = bean.createWebClient();
+        try {
+            Book book = wc.post(new Book("CXF", 126L), Book.class);
+            assertEquals(126L, book.getId());
+        } catch (ServerWebApplicationException ex) {
+            fail(ex.getMessage());
+        } catch (ClientWebApplicationException ex) {
+            if (ex.getCause() != null && ex.getCause().getMessage() != null) {
+                fail(ex.getCause().getMessage());
+            } else {
+                fail(ex.getMessage());
+            }
+        }
+        
+    }
+    
+    @Test
+    public void testPostEncryptedSignedBook() throws Exception {
+        String address = "https://localhost:" + PORT + "/xmlsec/bookstore/books";
+        JAXRSClientFactoryBean bean = new JAXRSClientFactoryBean();
+        bean.setAddress(address);
+        
+        SpringBusFactory bf = new SpringBusFactory();
+        URL busFile = JAXRSXmlSecTest.class.getResource("client.xml");
+        Bus springBus = bf.createBus(busFile.toString());
+        bean.setBus(springBus);
+
+        Map<String, Object> properties = new HashMap<String, Object>();
+        properties.put("ws-security.callback-handler", 
+                       "org.apache.cxf.systest.jaxrs.security.saml.KeystorePasswordCallback");
+        properties.put("ws-security.encryption.username", "bob");
+        properties.put("ws-security.encryption.properties", 
+                       "org/apache/cxf/systest/jaxrs/security/bob.properties");
+        properties.put("ws-security.signature.username", "alice");
+        properties.put("ws-security.signature.properties", 
+                       "org/apache/cxf/systest/jaxrs/security/alice.properties");
+        bean.setProperties(properties);
+        bean.getOutInterceptors().add(new XmlSigOutInterceptor());
+        bean.getOutInterceptors().add(new XmlEncOutInterceptor());
+        
+        
+        WebClient wc = bean.createWebClient();
+        try {
+            Book book = wc.post(new Book("CXF", 126L), Book.class);
+            assertEquals(126L, book.getId());
+        } catch (ServerWebApplicationException ex) {
+            fail(ex.getMessage());
+        } catch (ClientWebApplicationException ex) {
+            if (ex.getCause() != null && ex.getCause().getMessage() != null) {
+                fail(ex.getCause().getMessage());
+            } else {
+                fail(ex.getMessage());
+            }
+        }
+        
+    }
+    
     
 }

Added: cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/XmlEncInHandler.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/XmlEncInHandler.java?rev=1149391&view=auto
==============================================================================
--- cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/XmlEncInHandler.java (added)
+++ cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/XmlEncInHandler.java Thu Jul 21 22:32:11 2011
@@ -0,0 +1,339 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.cxf.systest.jaxrs.security.xml;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.security.InvalidKeyException;
+import java.security.PrivateKey;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.util.Properties;
+import java.util.logging.Logger;
+
+import javax.crypto.Cipher;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.IvParameterSpec;
+import javax.security.auth.callback.CallbackHandler;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.Response;
+import javax.xml.stream.XMLStreamReader;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
+import org.apache.cxf.common.classloader.ClassLoaderUtils;
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.common.util.Base64Exception;
+import org.apache.cxf.common.util.Base64Utility;
+import org.apache.cxf.helpers.DOMUtils;
+import org.apache.cxf.jaxrs.ext.RequestHandler;
+import org.apache.cxf.jaxrs.model.ClassResourceInfo;
+import org.apache.cxf.message.Message;
+import org.apache.cxf.resource.ResourceManager;
+import org.apache.cxf.staxutils.W3CDOMStreamReader;
+import org.apache.cxf.ws.security.SecurityConstants;
+import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.WSSConfig;
+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.util.WSSecurityUtil;
+import org.apache.ws.security.validate.Credential;
+import org.apache.ws.security.validate.SignatureTrustValidator;
+import org.apache.xml.security.utils.Constants;
+
+public class XmlEncInHandler implements RequestHandler {
+    private static final Logger LOG = 
+        LogUtils.getL7dLogger(XmlEncInHandler.class);
+    
+    static {
+        WSSConfig.init();
+    }
+    
+    public Response handleRequest(Message message, ClassResourceInfo resourceClass) {
+        
+        String method = (String)message.get(Message.HTTP_REQUEST_METHOD);
+        if ("GET".equals(method)) {
+            return null;
+        }
+        
+        InputStream is = message.getContent(InputStream.class);
+        Document doc = null;
+        try {
+            doc = DOMUtils.readXml(is);
+        } catch (Exception ex) {
+            throwFault("Invalid XML payload", ex);
+        }
+        
+
+        Element root = doc.getDocumentElement();
+        Element encKeyElement = getNode(root, WSConstants.ENC_NS, "EncryptedKey", 0);
+        if (encKeyElement == null) {
+            throwFault("EncryptedKey element is not available", null);
+        }
+        byte[] symmetricKeyBytes = getSymmetricKey(message, encKeyElement);
+                
+        String algorithm = getEncodingMethodAlgorithm(root);
+        Element cipherValue = getNode(root, WSConstants.ENC_NS, "CipherValue", 1);
+        if (cipherValue == null) {
+            throwFault("CipherValue element is not available", null);
+        }
+        
+        byte[] decrypedPayload = null;
+        try {
+            decrypedPayload = decryptPayload(symmetricKeyBytes, cipherValue.getTextContent().trim(),
+                                                algorithm);
+        } catch (Exception ex) {
+            throwFault("Payload can not be decrypted", ex);
+        }
+        
+        Document payloadDoc = null;
+        try {
+            payloadDoc = DOMUtils.readXml(new InputStreamReader(new ByteArrayInputStream(decrypedPayload),
+                                               "UTF-8"));
+        } catch (Exception ex) {
+            throwFault("Payload document can not be created", ex);
+        }
+        message.setContent(XMLStreamReader.class, 
+                           new W3CDOMStreamReader(payloadDoc));
+        message.setContent(InputStream.class, null);
+        return null;
+    }
+    
+    private byte[] getSymmetricKey(Message message, Element encKeyElement) {
+        Element certNode = getNode(encKeyElement, 
+                                      Constants.SignatureSpecNS, "X509Certificate", 0);
+        if (certNode == null) {
+            throwFault("Certificate is missing", null);
+        }
+        byte[] certBytes = null;
+        try {
+            certBytes = Base64Utility.decode(certNode.getTextContent().trim());
+        } catch (Base64Exception ex) {
+            throwFault("Base64 decoding has failed", ex);
+        }
+        
+        X509Certificate cert = null;
+        try {
+            CertificateFactory cf = CertificateFactory.getInstance("X.509");
+            cert = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(certBytes));
+        } catch (Exception ex) {
+            throwFault("X509Certificate can not be created", ex);
+        }
+        
+        Crypto crypto = null;
+        try {
+            crypto = getCrypto(message, SecurityConstants.ENCRYPT_PROPERTIES);
+        } catch (Exception ex) {
+            throwFault("Crypto can not be loaded", ex);
+        }
+        
+            
+        Credential trustCredential = new Credential();
+        trustCredential.setPublicKey(null);
+        trustCredential.setCertificates(new X509Certificate[]{cert});
+        try {
+            validateTrust(trustCredential, crypto);
+        } catch (Exception ex) {
+            throwFault(ex.getMessage(), ex);
+        }
+        
+        // now start decrypting
+        String algorithm = getEncodingMethodAlgorithm(encKeyElement);
+        Element cipherValue = getNode(encKeyElement, WSConstants.ENC_NS, 
+                                               "CipherValue", 0);
+        if (cipherValue == null) {
+            throwFault("CipherValue element is not available", null);
+        }
+        try {
+            return decryptSymmetricKey(cipherValue.getTextContent().trim(),
+                                       cert,
+                                       crypto,
+                                       algorithm,
+                                       message);
+        } catch (Exception ex) {
+            throwFault(ex.getMessage(), ex);
+        }
+        return null;
+    }
+    
+    private String getEncodingMethodAlgorithm(Element parent) {
+        Element encMethod = getNode(parent, WSConstants.ENC_NS, "EncryptionMethod", 0);
+        if (encMethod == null) {
+            throwFault("EncryptionMethod element is not available", null);
+        }
+        return encMethod.getAttribute("Algorithm");
+    }
+    
+    protected byte[] decryptSymmetricKey(String base64EncodedKey, 
+                                         X509Certificate cert,
+                                         Crypto crypto,
+                                         String keyEncAlgo,
+                                         Message message) throws WSSecurityException {
+        CallbackHandler callback = getCallbackHandler(message);
+        PrivateKey key = null;
+        try {
+            key = crypto.getPrivateKey(cert, callback);
+        } catch (Exception ex) {
+            throwFault("Encrypted key can not be decrypted", ex);
+        }
+        Cipher cipher = WSSecurityUtil.getCipherInstance(keyEncAlgo);
+        try {
+            // see more: WSS4J EncryptedDataProcessor
+            cipher.init(Cipher.DECRYPT_MODE, key);
+        } catch (InvalidKeyException e) {
+            throw new WSSecurityException(
+                WSSecurityException.FAILED_ENCRYPTION, null, null, e
+            );
+        }
+        try {
+            byte[] encryptedBytes = Base64Utility.decode(base64EncodedKey);
+            return doDecrypt(cipher, encryptedBytes); 
+        } catch (Base64Exception ex) {
+            throwFault("Base64 decoding has failed", ex);
+        } catch (Exception ex) {
+            throwFault("Encrypted key can not be decrypted", ex);
+        }
+        return null;
+        
+    }
+    
+    protected byte[] decryptPayload(byte[] secretKeyBytes,
+                                    String base64EncodedPayload, 
+                                    String symEncAlgo) throws WSSecurityException {
+        byte[] encryptedBytes = null;
+        try {
+            encryptedBytes = Base64Utility.decode(base64EncodedPayload);
+        } catch (Base64Exception ex) {
+            throwFault("Base64 decoding has failed", ex);
+        }
+        
+        Cipher cipher = WSSecurityUtil.getCipherInstance(symEncAlgo);
+        try {
+            // see more: WSS4J EncryptedDataProcessor
+            SecretKey key = WSSecurityUtil.prepareSecretKey(symEncAlgo, secretKeyBytes);
+            // IV spec
+            int ivLen = cipher.getBlockSize();
+            byte[] ivBytes = new byte[ivLen];
+            System.arraycopy(encryptedBytes, 0, ivBytes, 0, ivLen);
+            IvParameterSpec iv = new IvParameterSpec(ivBytes);
+            
+            cipher.init(Cipher.DECRYPT_MODE, key, iv);
+            
+            return cipher.doFinal(encryptedBytes, 
+                             ivLen, 
+                             encryptedBytes.length - ivLen);
+            
+        } catch (InvalidKeyException e) {
+            throw new WSSecurityException(
+                WSSecurityException.FAILED_ENCRYPTION, null, null, e
+            );
+        } catch (Exception e) {
+            throw new WSSecurityException(
+                 WSSecurityException.FAILED_ENCRYPTION, null, null, e);
+        }
+    }
+    
+    private byte[] doDecrypt(Cipher cipher, byte[] encryptedBytes) throws Exception {
+        return cipher.doFinal(encryptedBytes);
+    }
+    
+    private Element getNode(Element parent, String ns, String name, int index) {
+        NodeList list = parent.getElementsByTagNameNS(ns, name);
+        if (list != null && list.getLength() >= index + 1) {
+            return (Element)list.item(index);
+        } 
+        return null;
+    }
+    
+    private void validateTrust(Credential cred, Crypto crypto) throws Exception {
+        SignatureTrustValidator validator = new SignatureTrustValidator();
+        RequestData data = new RequestData();
+        data.setSigCrypto(crypto);
+        validator.validate(cred, data);
+    }
+    
+    protected void throwFault(String error, Exception ex) {
+        // TODO: get bundle resource message once this filter is moved 
+        // to rt/rs/security
+        LOG.warning(error);
+        Response response = Response.status(401).entity(error).build();
+        throw ex != null ? new WebApplicationException(ex, response) : new WebApplicationException(response);
+    }
+    
+    // this code will be moved to a common utility class
+    protected Crypto getCrypto(Message message, String propKey) 
+        throws IOException, WSSecurityException {
+        
+        Object o = message.getContextualProperty(propKey);
+        if (o == null) {
+            return null;
+        }
+        
+        ClassLoader orig = Thread.currentThread().getContextClassLoader();
+        try {
+            URL url = ClassLoaderUtils.getResource((String)o, this.getClass());
+            if (url == null) {
+                ResourceManager manager = message.getExchange()
+                        .getBus().getExtension(ResourceManager.class);
+                ClassLoader loader = manager.resolveResource("", ClassLoader.class);
+                if (loader != null) {
+                    Thread.currentThread().setContextClassLoader(loader);
+                }
+                url = manager.resolveResource((String)o, URL.class);
+            }
+            if (url != null) {
+                Properties props = new Properties();
+                InputStream in = url.openStream(); 
+                props.load(in);
+                in.close();
+                return CryptoFactory.getInstance(props);
+            } else {
+                return CryptoFactory.getInstance((String)o);
+            }
+        } finally {
+            Thread.currentThread().setContextClassLoader(orig);
+        }
+    }
+    
+    private CallbackHandler getCallbackHandler(Message message) {
+        //Then try to get the password from the given callback handler
+        Object o = message.getContextualProperty(SecurityConstants.CALLBACK_HANDLER);
+    
+        CallbackHandler handler = null;
+        if (o instanceof CallbackHandler) {
+            handler = (CallbackHandler)o;
+        } else if (o instanceof String) {
+            try {
+                handler = (CallbackHandler)ClassLoaderUtils
+                    .loadClass((String)o, this.getClass()).newInstance();
+            } catch (Exception e) {
+                handler = null;
+            }
+        }
+        return handler;
+    }
+}

Propchange: cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/XmlEncInHandler.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/XmlEncInHandler.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/XmlEncOutInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/XmlEncOutInterceptor.java?rev=1149391&view=auto
==============================================================================
--- cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/XmlEncOutInterceptor.java (added)
+++ cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/XmlEncOutInterceptor.java Thu Jul 21 22:32:11 2011
@@ -0,0 +1,501 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.systest.jaxrs.security.xml;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.lang.annotation.Annotation;
+import java.net.URL;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.X509Certificate;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.logging.Logger;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.KeyGenerator;
+import javax.crypto.SecretKey;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.xml.stream.XMLStreamWriter;
+import javax.xml.transform.dom.DOMSource;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.Text;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.common.classloader.ClassLoaderUtils;
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.common.util.Base64Utility;
+import org.apache.cxf.common.util.StringUtils;
+import org.apache.cxf.endpoint.Endpoint;
+import org.apache.cxf.helpers.CastUtils;
+import org.apache.cxf.helpers.DOMUtils;
+import org.apache.cxf.interceptor.Fault;
+import org.apache.cxf.jaxrs.provider.JAXBElementProvider;
+import org.apache.cxf.jaxrs.provider.ProviderFactory;
+import org.apache.cxf.message.Message;
+import org.apache.cxf.message.MessageContentsList;
+import org.apache.cxf.phase.AbstractPhaseInterceptor;
+import org.apache.cxf.phase.Phase;
+import org.apache.cxf.resource.ResourceManager;
+import org.apache.cxf.service.model.EndpointInfo;
+import org.apache.cxf.staxutils.W3CDOMStreamWriter;
+import org.apache.cxf.ws.security.SecurityConstants;
+import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.WSSConfig;
+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.components.crypto.CryptoType;
+import org.apache.ws.security.message.token.DOMX509Data;
+import org.apache.ws.security.message.token.DOMX509IssuerSerial;
+import org.apache.ws.security.util.Base64;
+import org.apache.ws.security.util.UUIDGenerator;
+import org.apache.ws.security.util.WSSecurityUtil;
+import org.apache.xml.security.algorithms.JCEMapper;
+import org.apache.xml.security.encryption.XMLCipher;
+import org.apache.xml.security.encryption.XMLEncryptionException;
+
+public class XmlEncOutInterceptor extends AbstractPhaseInterceptor<Message> {
+    private static final Logger LOG = 
+        LogUtils.getL7dLogger(XmlEncOutInterceptor.class);
+    private static final String CRYPTO_CACHE = "ws-security.crypto.cache";
+    
+    static {
+        WSSConfig.init();
+    }
+    
+    private boolean encryptSymmetricKey = true;
+    private SecretKey symmetricKey;
+    private String keyEncAlgo = XMLCipher.RSA_OAEP; 
+    private String symEncAlgo = XMLCipher.AES_256;
+    
+    public XmlEncOutInterceptor() {
+        super(Phase.WRITE);
+        addAfter(XmlSigOutInterceptor.class.getName());
+    } 
+
+    public void handleMessage(Message message) throws Fault {
+        try {
+            Object body = getRequestBody(message);
+            if (body == null) {
+                return;
+            }
+            Document doc = getDomDocument(body, message);
+            if (doc == null) {
+                return;
+            }
+ 
+            Document encryptedDataDoc = encryptDocument(message, doc);
+            message.setContent(List.class, 
+                new MessageContentsList(new DOMSource(encryptedDataDoc)));
+        } catch (Exception ex) {
+            StringWriter sw = new StringWriter();
+            ex.printStackTrace(new PrintWriter(sw));
+            LOG.warning(sw.toString());
+            throw new Fault(new RuntimeException(ex.getMessage() + ", stacktrace: " + sw.toString()));
+        }
+    }
+    
+    // at the moment all the doc gets encrypted
+    private Document encryptDocument(Message message, Document payloadDoc) 
+        throws Exception {
+        
+        byte[] secretKey = getSymmetricKey();
+
+        Document encryptedDataDoc = DOMUtils.createDocument();
+        Element encryptedDataElement = createEncryptedDataElement(encryptedDataDoc);
+        if (encryptSymmetricKey) {
+            Crypto crypto = getCrypto(message, 
+                                      SecurityConstants.ENCRYPT_CRYPTO,
+                                      SecurityConstants.ENCRYPT_PROPERTIES);
+            
+            String user = getUserName(message, crypto);
+            if (StringUtils.isEmpty(user)) {
+                return null;
+            }
+            X509Certificate cert = getReceiverCertificate(crypto, user);
+            byte[] encryptedSecretKey = encryptSymmetricKey(secretKey, cert, crypto);
+
+            addEncryptedKeyElement(encryptedDataElement, cert, encryptedSecretKey);
+        }
+               
+        // encrypt payloadDoc
+        XMLCipher xmlCipher = null;
+        try {
+            xmlCipher = XMLCipher.getInstance(symEncAlgo);
+        } catch (XMLEncryptionException ex) {
+            throw new WSSecurityException(
+                WSSecurityException.UNSUPPORTED_ALGORITHM, null, null, ex
+            );
+        }
+        xmlCipher.init(XMLCipher.ENCRYPT_MODE, symmetricKey);
+        Document result = xmlCipher.doFinal(payloadDoc, payloadDoc.getDocumentElement(), false);
+        NodeList list = result.getElementsByTagNameNS(WSConstants.ENC_NS, "CipherValue");
+        if (list.getLength() != 1) {
+            throw new WSSecurityException("Payload CipherData is missing", null);
+        }
+        String cipherText = ((Element)list.item(0)).getTextContent().trim();
+        Element cipherValue = 
+            createCipherValue(encryptedDataDoc, encryptedDataDoc.getDocumentElement());
+        cipherValue.appendChild(encryptedDataDoc.createTextNode(cipherText));
+         
+        //StaxUtils.copy(new DOMSource(encryptedDataDoc), System.out);
+        return encryptedDataDoc;
+    }
+    
+    private byte[] getSymmetricKey() throws Exception {
+        synchronized (this) {
+            if (symmetricKey == null) {
+                KeyGenerator keyGen = getKeyGenerator();
+                symmetricKey = keyGen.generateKey();
+            } 
+        }
+        return symmetricKey.getEncoded();
+    }
+    
+    private X509Certificate getReceiverCertificate(Crypto crypto, String user) throws Exception {
+        CryptoType cryptoType = new CryptoType(CryptoType.TYPE.ALIAS);
+        cryptoType.setAlias(user);
+        X509Certificate[] certs = crypto.getX509Certificates(cryptoType);
+        if (certs == null || certs.length <= 0) {
+            throw new WSSecurityException(
+                WSSecurityException.FAILURE,
+                "noUserCertsFound",  
+                new Object[] {user, "encryption"}
+            );
+        }
+        return certs[0];
+    }
+    
+    private KeyGenerator getKeyGenerator() throws WSSecurityException {
+        try {
+            //
+            // Assume AES as default, so initialize it
+            //
+            String keyAlgorithm = JCEMapper.getJCEKeyAlgorithmFromURI(symEncAlgo);
+            KeyGenerator keyGen = KeyGenerator.getInstance(keyAlgorithm);
+            if (symEncAlgo.equalsIgnoreCase(WSConstants.AES_128)) {
+                keyGen.init(128);
+            } else if (symEncAlgo.equalsIgnoreCase(WSConstants.AES_192)) {
+                keyGen.init(192);
+            } else if (symEncAlgo.equalsIgnoreCase(WSConstants.AES_256)) {
+                keyGen.init(256);
+            }
+            return keyGen;
+        } catch (NoSuchAlgorithmException e) {
+            throw new WSSecurityException(
+                WSSecurityException.UNSUPPORTED_ALGORITHM, null, null, e
+            );
+        }
+    }
+    
+    // Apache Security XMLCipher does not support 
+    // Certificates for encrypting the keys
+    protected byte[] encryptSymmetricKey(byte[] keyBytes, 
+                                         X509Certificate remoteCert,
+                                         Crypto crypto) throws WSSecurityException {
+        Cipher cipher = WSSecurityUtil.getCipherInstance(keyEncAlgo);
+        try {
+            cipher.init(Cipher.ENCRYPT_MODE, remoteCert);
+        } catch (InvalidKeyException e) {
+            throw new WSSecurityException(
+                WSSecurityException.FAILED_ENCRYPTION, null, null, e
+            );
+        }
+        int blockSize = cipher.getBlockSize();
+        if (blockSize > 0 && blockSize < keyBytes.length) {
+            throw new WSSecurityException(
+                WSSecurityException.FAILURE,
+                "unsupportedKeyTransp",
+                new Object[] {"public key algorithm too weak to encrypt symmetric key"}
+            );
+        }
+        byte[] encryptedEphemeralKey = null;
+        try {
+            encryptedEphemeralKey = cipher.doFinal(keyBytes);
+        } catch (IllegalStateException ex) {
+            throw new WSSecurityException(
+                WSSecurityException.FAILED_ENCRYPTION, null, null, ex
+            );
+        } catch (IllegalBlockSizeException ex) {
+            throw new WSSecurityException(
+                WSSecurityException.FAILED_ENCRYPTION, null, null, ex
+            );
+        } catch (BadPaddingException ex) {
+            throw new WSSecurityException(
+                WSSecurityException.FAILED_ENCRYPTION, null, null, ex
+            );
+        }
+       
+        return encryptedEphemeralKey;
+       
+    }
+    
+    private void addEncryptedKeyElement(Element encryptedDataElement,
+                                        X509Certificate cert,
+                                        byte[] encryptedKey) throws Exception {
+        
+        Document doc = encryptedDataElement.getOwnerDocument();
+        
+        String encodedKey = Base64Utility.encode(encryptedKey);
+        Element encryptedKeyElement = createEncryptedKeyElement(doc);
+        String encKeyId = "EK-" + UUIDGenerator.getUUID();
+        encryptedKeyElement.setAttributeNS(null, "Id", encKeyId);
+                
+        Element keyInfoElement = createKeyInfoElement(doc, cert, WSConstants.X509_KEY_IDENTIFIER);
+        encryptedKeyElement.appendChild(keyInfoElement);
+        
+        Element xencCipherValue = createCipherValue(doc, encryptedKeyElement);
+        xencCipherValue.appendChild(doc.createTextNode(encodedKey));
+        
+        
+        encryptedDataElement.appendChild(encryptedKeyElement);
+    }
+    
+    protected Element createCipherValue(Document doc, Element encryptedKey) {
+        Element cipherData = 
+            doc.createElementNS(WSConstants.ENC_NS, WSConstants.ENC_PREFIX + ":CipherData");
+        Element cipherValue = 
+            doc.createElementNS(WSConstants.ENC_NS, WSConstants.ENC_PREFIX + ":CipherValue");
+        cipherData.appendChild(cipherValue);
+        encryptedKey.appendChild(cipherData);
+        return cipherValue;
+    }
+    
+    private Element createKeyInfoElement(Document encryptedDataDoc,
+                                         X509Certificate remoteCert,
+                                         int keyIdentifierType) throws Exception {
+        Element keyInfoElement = 
+            encryptedDataDoc.createElementNS(
+                WSConstants.SIG_NS, WSConstants.SIG_PREFIX + ":" + WSConstants.KEYINFO_LN
+            );
+        
+        Node keyIdentifierNode = null; 
+        switch (keyIdentifierType) {
+        case WSConstants.X509_KEY_IDENTIFIER:
+            byte data[] = null;
+            try {
+                data = remoteCert.getEncoded();
+            } catch (CertificateEncodingException e) {
+                throw new WSSecurityException(
+                    WSSecurityException.SECURITY_TOKEN_UNAVAILABLE, "encodeError", null, e
+                );
+            }
+            Text text = encryptedDataDoc.createTextNode(Base64.encode(data));
+            Element cert = encryptedDataDoc.createElementNS(
+                WSConstants.SIG_NS, WSConstants.SIG_PREFIX + ":" + WSConstants.X509_CERT_LN);
+            cert.appendChild(text);
+            Element x509Data = encryptedDataDoc.createElementNS(
+                WSConstants.SIG_NS, WSConstants.SIG_PREFIX + ":" + WSConstants.X509_DATA_LN);
+            
+            x509Data.appendChild(cert);
+            keyIdentifierNode = x509Data; 
+            break;
+
+        case WSConstants.ISSUER_SERIAL:
+            String issuer = remoteCert.getIssuerDN().getName();
+            java.math.BigInteger serialNumber = remoteCert.getSerialNumber();
+            DOMX509IssuerSerial domIssuerSerial = 
+                new DOMX509IssuerSerial(
+                    encryptedDataDoc, issuer, serialNumber
+                );
+            DOMX509Data domX509Data = new DOMX509Data(encryptedDataDoc, domIssuerSerial);
+            keyIdentifierNode = domX509Data.getElement();
+            break;
+        default:
+            throw new WSSecurityException("Unsupported key identifier:" + keyIdentifierType);
+        }
+ 
+        keyInfoElement.appendChild(keyIdentifierNode);
+        
+        return keyInfoElement;
+    }
+    
+    protected Element createEncryptedKeyElement(Document encryptedDataDoc) {
+        Element encryptedKey = 
+            encryptedDataDoc.createElementNS(WSConstants.ENC_NS, WSConstants.ENC_PREFIX + ":EncryptedKey");
+
+        Element encryptionMethod = 
+            encryptedDataDoc.createElementNS(WSConstants.ENC_NS, WSConstants.ENC_PREFIX 
+                                             + ":EncryptionMethod");
+        encryptionMethod.setAttributeNS(null, "Algorithm", keyEncAlgo);
+        encryptedKey.appendChild(encryptionMethod);
+        return encryptedKey;
+    }
+    
+    protected Element createEncryptedDataElement(Document encryptedDataDoc) {
+        Element encryptedData = 
+            encryptedDataDoc.createElementNS(WSConstants.ENC_NS, WSConstants.ENC_PREFIX + ":EncryptedData");
+
+        WSSecurityUtil.setNamespace(encryptedData, WSConstants.ENC_NS, WSConstants.ENC_PREFIX);
+        
+        Element encryptionMethod = 
+            encryptedDataDoc.createElementNS(WSConstants.ENC_NS, WSConstants.ENC_PREFIX 
+                                             + ":EncryptionMethod");
+        encryptionMethod.setAttributeNS(null, "Algorithm", symEncAlgo);
+        encryptedData.appendChild(encryptionMethod);
+        encryptedDataDoc.appendChild(encryptedData);
+        
+        return encryptedData;
+    }
+    
+    
+    private Object getRequestBody(Message message) {
+        MessageContentsList objs = MessageContentsList.getContentsList(message);
+        if (objs == null || objs.size() == 0) {
+            return null;
+        } else {
+            return objs.get(0);
+        }
+    }
+    
+    @SuppressWarnings("unchecked")
+    private Document getDomDocument(Object body, Message m) throws Exception {
+        
+        if (body instanceof Document) {
+            return (Document)body;
+        }
+        if (body instanceof DOMSource) {
+            return (Document)((DOMSource)body).getNode();
+        }
+        
+        ProviderFactory pf = ProviderFactory.getInstance(m);
+        
+        Object providerObject = pf.createMessageBodyWriter(body.getClass(), 
+                                   body.getClass(), new Annotation[]{}, 
+                                   MediaType.APPLICATION_XML_TYPE, m);
+        if (!(providerObject instanceof JAXBElementProvider)) {
+            return null;
+        }
+        JAXBElementProvider provider = (JAXBElementProvider)providerObject;
+        W3CDOMStreamWriter writer = new W3CDOMStreamWriter();
+        m.setContent(XMLStreamWriter.class, writer);
+        provider.writeTo(body, body.getClass(), 
+                         body.getClass(), new Annotation[]{},
+                         MediaType.APPLICATION_XML_TYPE,
+                         (MultivaluedMap)m.get(Message.PROTOCOL_HEADERS), null);
+        return writer.getDocument();
+    }
+    
+ // This code will be moved to a common utility class
+    private String getUserName(Message message, Crypto crypto) {
+        String userNameKey = SecurityConstants.ENCRYPT_USERNAME;
+        String user = (String)message.getContextualProperty(userNameKey);
+        if (crypto != null && StringUtils.isEmpty(user)) {
+            try {
+                user = crypto.getDefaultX509Identifier();
+            } catch (WSSecurityException e1) {
+                throw new Fault(e1);
+            }
+        }
+        return user;
+    }
+    
+        
+    private Crypto getCrypto(Message message,
+                             String cryptoKey, 
+                             String propKey) {
+        Crypto crypto = (Crypto)message.getContextualProperty(cryptoKey);
+        if (crypto != null) {
+            return crypto;
+        }
+        
+        Object o = message.getContextualProperty(propKey);
+        if (o == null) {
+            return null;
+        }
+        
+        crypto = getCryptoCache(message).get(o);
+        if (crypto != null) {
+            return crypto;
+        }
+        Properties properties = null;
+        if (o instanceof Properties) {
+            properties = (Properties)o;
+        } else if (o instanceof String) {
+            ResourceManager rm = message.getExchange().get(Bus.class).getExtension(ResourceManager.class);
+            URL url = rm.resolveResource((String)o, URL.class);
+            try {
+                if (url == null) {
+                    url = ClassLoaderUtils.getResource((String)o, this.getClass());
+                }
+                if (url == null) {
+                    try {
+                        url = new URL((String)o);
+                    } catch (Exception ex) {
+                        throw new RuntimeException(ex);
+                    }
+                }
+                if (url != null) {
+                    InputStream ins = url.openStream();
+                    properties = new Properties();
+                    properties.load(ins);
+                    ins.close();
+                }
+            } catch (IOException e) {
+                throw new RuntimeException(e);
+            }
+        } else if (o instanceof URL) {
+            properties = new Properties();
+            try {
+                InputStream ins = ((URL)o).openStream();
+                properties.load(ins);
+                ins.close();
+            } catch (IOException e) {
+                throw new RuntimeException(e);
+            }            
+        }
+        
+        if (properties != null) {
+            try {
+                crypto = CryptoFactory.getInstance(properties);
+            } catch (Exception ex) {
+                return null;
+            }
+            getCryptoCache(message).put(o, crypto);
+        }
+        return crypto;
+    }
+    
+    protected final Map<Object, Crypto> getCryptoCache(Message message) {
+        EndpointInfo info = message.getExchange().get(Endpoint.class).getEndpointInfo();
+        synchronized (info) {
+            Map<Object, Crypto> o = 
+                CastUtils.cast((Map<?, ?>)message.getContextualProperty(CRYPTO_CACHE));
+            if (o == null) {
+                o = new ConcurrentHashMap<Object, Crypto>();
+                info.setProperty(CRYPTO_CACHE, o);
+            }
+            return o;
+        }
+    }
+}

Propchange: cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/XmlEncOutInterceptor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/XmlEncOutInterceptor.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Modified: cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/XmlSigInHandler.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/XmlSigInHandler.java?rev=1149391&r1=1149390&r2=1149391&view=diff
==============================================================================
--- cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/XmlSigInHandler.java (original)
+++ cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/XmlSigInHandler.java Thu Jul 21 22:32:11 2011
@@ -44,6 +44,7 @@ import org.apache.cxf.message.Message;
 import org.apache.cxf.resource.ResourceManager;
 import org.apache.cxf.staxutils.W3CDOMStreamReader;
 import org.apache.cxf.ws.security.SecurityConstants;
+import org.apache.ws.security.WSSConfig;
 import org.apache.ws.security.WSSecurityException;
 import org.apache.ws.security.components.crypto.Crypto;
 import org.apache.ws.security.components.crypto.CryptoFactory;
@@ -63,7 +64,7 @@ public class XmlSigInHandler implements 
         LogUtils.getL7dLogger(XmlSigInHandler.class);
     
     static {
-        org.apache.xml.security.Init.init();
+        WSSConfig.init();
     }
     
     public Response handleRequest(Message message, ClassResourceInfo resourceClass) {
@@ -73,14 +74,23 @@ public class XmlSigInHandler implements 
             return null;
         }
         
-        InputStream is = message.getContent(InputStream.class);
         Document doc = null;
-        try {
-            doc = DOMUtils.readXml(is);
-        } catch (Exception ex) {
-            throwFault("Invalid XML payload", ex);
+        InputStream is = message.getContent(InputStream.class);
+        if (is != null) {
+            try {
+                doc = DOMUtils.readXml(is);
+            } catch (Exception ex) {
+                throwFault("Invalid XML payload", ex);
+            }
+        } else {
+            XMLStreamReader reader = message.getContent(XMLStreamReader.class);
+            if (reader instanceof W3CDOMStreamReader) {
+                doc = ((W3CDOMStreamReader)reader).getDocument();
+            }
+        }
+        if (doc == null) {
+            throwFault("No payload is available", null);
         }
-        
 
         Element root = doc.getDocumentElement();
         Element sigElement = getSignatureElement(root);

Modified: cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/XmlSigOutInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/XmlSigOutInterceptor.java?rev=1149391&r1=1149390&r2=1149391&view=diff
==============================================================================
--- cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/XmlSigOutInterceptor.java (original)
+++ cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/XmlSigOutInterceptor.java Thu Jul 21 22:32:11 2011
@@ -59,6 +59,7 @@ import org.apache.cxf.service.model.Endp
 import org.apache.cxf.staxutils.W3CDOMStreamWriter;
 import org.apache.cxf.ws.security.SecurityConstants;
 import org.apache.ws.security.WSPasswordCallback;
+import org.apache.ws.security.WSSConfig;
 import org.apache.ws.security.WSSecurityException;
 import org.apache.ws.security.components.crypto.Crypto;
 import org.apache.ws.security.components.crypto.CryptoFactory;
@@ -75,7 +76,7 @@ public class XmlSigOutInterceptor extend
     private static final String CRYPTO_CACHE = "ws-security.crypto.cache";
     
     static {
-        org.apache.xml.security.Init.init();
+        WSSConfig.init();
     }
     
     private boolean createReferenceId = true;
@@ -182,6 +183,10 @@ public class XmlSigOutInterceptor extend
     @SuppressWarnings("unchecked")
     private Document getDomDocument(Object body, Message m) throws Exception {
         
+        if (body instanceof Document) {
+            return (Document)body;
+        }
+        
         ProviderFactory pf = ProviderFactory.getInstance(m);
         
         Object providerObject = pf.createMessageBodyWriter(body.getClass(), 

Modified: cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/server.xml
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/server.xml?rev=1149391&r1=1149390&r2=1149391&view=diff
==============================================================================
--- cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/server.xml (original)
+++ cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/server.xml Thu Jul 21 22:32:11 2011
@@ -23,7 +23,9 @@ under the License.
        xmlns:httpj="http://cxf.apache.org/transports/http-jetty/configuration"
        xmlns:sec="http://cxf.apache.org/configuration/security"
        xmlns:cxf="http://cxf.apache.org/core"
+       xmlns:jaxrs="http://cxf.apache.org/jaxrs"
        xsi:schemaLocation="
+        http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd
         http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd
         http://www.springframework.org/schema/beans                 http://www.springframework.org/schema/beans/spring-beans.xsd
         http://cxf.apache.org/transports/http/configuration         http://cxf.apache.org/schemas/configuration/http-conf.xsd
@@ -40,7 +42,7 @@ under the License.
     </cxf:bus>
 
     <httpj:engine-factory id="port-9095-tls-config">
-        <httpj:engine port="${testutil.ports.jaxrs-xmlsig}">
+        <httpj:engine port="${testutil.ports.jaxrs-xmlsec}">
             <httpj:tlsServerParameters>
                <sec:keyManagers keyPassword="password">
 	           <sec:keyStore type="JKS" password="password" 
@@ -61,5 +63,61 @@ under the License.
             </httpj:tlsServerParameters>
         </httpj:engine>
     </httpj:engine-factory>
+    
+    <bean id="serviceBean" class="org.apache.cxf.systest.jaxrs.security.BookStore"/>
+    <bean id="xmlSigHandler" class="org.apache.cxf.systest.jaxrs.security.xml.XmlSigInHandler"/>
+    <bean id="xmlEncHandler" class="org.apache.cxf.systest.jaxrs.security.xml.XmlEncInHandler"/>
+    
+    <jaxrs:server 
+       address="https://localhost:${testutil.ports.jaxrs-xmlsec}/xmlsig"> 
+       <jaxrs:serviceBeans>
+          <ref bean="serviceBean"/>
+       </jaxrs:serviceBeans>
+       <jaxrs:providers>
+          <ref bean="xmlSigHandler"/>
+       </jaxrs:providers> 
+       <jaxrs:properties>
+           <entry key="ws-security.signature.properties" 
+                  value="org/apache/cxf/systest/jaxrs/security/alice.properties"/>
+       </jaxrs:properties> 
+     
+    </jaxrs:server>
+    
+    <jaxrs:server 
+       address="https://localhost:${testutil.ports.jaxrs-xmlsec}/xmlenc"> 
+       <jaxrs:serviceBeans>
+          <ref bean="serviceBean"/>
+       </jaxrs:serviceBeans>
+       <jaxrs:providers>
+          <ref bean="xmlEncHandler"/>
+       </jaxrs:providers> 
+       <jaxrs:properties>
+           <entry key="ws-security.callback-handler" 
+                  value="org.apache.cxf.systest.jaxrs.security.saml.KeystorePasswordCallback"/>
+           <entry key="ws-security.encryption.properties" 
+                  value="org/apache/cxf/systest/jaxrs/security/bob.properties"/>
+       </jaxrs:properties> 
+     
+    </jaxrs:server>
+    
+    <jaxrs:server 
+       address="https://localhost:${testutil.ports.jaxrs-xmlsec}/xmlsec"> 
+       <jaxrs:serviceBeans>
+          <ref bean="serviceBean"/>
+       </jaxrs:serviceBeans>
+       <jaxrs:providers>
+          <ref bean="xmlEncHandler"/>
+          <ref bean="xmlSigHandler"/>
+       </jaxrs:providers> 
+       <jaxrs:properties>
+           <entry key="ws-security.callback-handler" 
+                  value="org.apache.cxf.systest.jaxrs.security.saml.KeystorePasswordCallback"/>
+           <entry key="ws-security.encryption.properties" 
+                  value="org/apache/cxf/systest/jaxrs/security/bob.properties"/>
+           <entry key="ws-security.signature.properties" 
+                  value="org/apache/cxf/systest/jaxrs/security/alice.properties"/>       
+       </jaxrs:properties> 
+     
+    </jaxrs:server>
 
 </beans>

Added: cxf/trunk/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/bob.properties
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/bob.properties?rev=1149391&view=auto
==============================================================================
--- cxf/trunk/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/bob.properties (added)
+++ cxf/trunk/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/bob.properties Thu Jul 21 22:32:11 2011
@@ -0,0 +1,23 @@
+#
+#    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.
+#
+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=password
+org.apache.ws.security.crypto.merlin.keystore.alias=bob
+org.apache.ws.security.crypto.merlin.keystore.file=org/apache/cxf/systest/jaxrs/security/certs/bob.jks

Propchange: cxf/trunk/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/bob.properties
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/trunk/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/bob.properties
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Propchange: cxf/trunk/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/bob.properties
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: cxf/trunk/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/certs/bob.jks
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/certs/bob.jks?rev=1149391&view=auto
==============================================================================
Binary file - no diff available.

Propchange: cxf/trunk/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/certs/bob.jks
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream