You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@abdera.apache.org by jm...@apache.org on 2012/02/01 19:04:48 UTC

svn commit: r1239242 - in /abdera/abdera2-server/server/src/main/java/org/apache/abdera2/security: ./ util/ util/filters/

Author: jmsnell
Date: Wed Feb  1 18:04:48 2012
New Revision: 1239242

URL: http://svn.apache.org/viewvc?rev=1239242&view=rev
Log:
Moving the security filters to the server package since that's where they're generally used... we can reevaluate later whether any of these need to be in the core or not.. but I doubt it.

Added:
    abdera/abdera2-server/server/src/main/java/org/apache/abdera2/security/
    abdera/abdera2-server/server/src/main/java/org/apache/abdera2/security/util/
    abdera/abdera2-server/server/src/main/java/org/apache/abdera2/security/util/filters/
    abdera/abdera2-server/server/src/main/java/org/apache/abdera2/security/util/filters/AESEncryptedResponseFilter.java   (with props)
    abdera/abdera2-server/server/src/main/java/org/apache/abdera2/security/util/filters/AbstractEncryptedRequestFilter.java   (with props)
    abdera/abdera2-server/server/src/main/java/org/apache/abdera2/security/util/filters/AbstractEncryptedResponseFilter.java   (with props)
    abdera/abdera2-server/server/src/main/java/org/apache/abdera2/security/util/filters/DHEncryptedRequestFilter.java   (with props)
    abdera/abdera2-server/server/src/main/java/org/apache/abdera2/security/util/filters/DHEncryptedResponseFilter.java   (with props)
    abdera/abdera2-server/server/src/main/java/org/apache/abdera2/security/util/filters/SignedRequestFilter.java   (with props)
    abdera/abdera2-server/server/src/main/java/org/apache/abdera2/security/util/filters/SignedResponseFilter.java   (with props)

Added: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/security/util/filters/AESEncryptedResponseFilter.java
URL: http://svn.apache.org/viewvc/abdera/abdera2-server/server/src/main/java/org/apache/abdera2/security/util/filters/AESEncryptedResponseFilter.java?rev=1239242&view=auto
==============================================================================
--- abdera/abdera2-server/server/src/main/java/org/apache/abdera2/security/util/filters/AESEncryptedResponseFilter.java (added)
+++ abdera/abdera2-server/server/src/main/java/org/apache/abdera2/security/util/filters/AESEncryptedResponseFilter.java Wed Feb  1 18:04:48 2012
@@ -0,0 +1,88 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  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.  For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ */
+package org.apache.abdera2.security.util.filters;
+
+import java.security.PublicKey;
+import java.security.cert.X509Certificate;
+import java.security.interfaces.RSAPublicKey;
+
+import org.apache.abdera2.common.protocol.RequestContext;
+import org.apache.abdera2.common.protocol.RequestContext.Scope;
+import org.apache.abdera2.common.protocol.ResponseContext;
+import org.apache.abdera2.common.security.KeyHelper;
+import org.apache.abdera2.security.Encryption;
+import org.apache.abdera2.security.EncryptionOptions;
+import org.apache.xml.security.encryption.XMLCipher;
+
+/**
+ * <pre>
+ * &lt;filter>
+ *   &lt;filter-name>enc filter&lt;/filter-name>
+ *   &lt;filter-class>com.test.EncryptedResponseFilter&lt;/filter-class>
+ * &lt;/filter>
+ * &lt;filter-mapping>
+ *   &lt;filter-name>enc filter&lt;/filter-name>
+ *   &lt;servlet-name>TestServlet&lt;/servlet-name>
+ * &lt;/filter-mapping>
+ * </pre>
+ */
+public class AESEncryptedResponseFilter extends AbstractEncryptedResponseFilter {
+
+    public static final String PUBLICKEY = "X-PublicKey";
+
+    protected X509Certificate[] getCerts(RequestContext request) {
+        return (X509Certificate[])request.getAttribute(Scope.REQUEST, "javax.servlet.request.X509Certificate");
+    }
+
+    protected PublicKey getPublicKey(RequestContext request) {
+        String header = request.getHeader(PUBLICKEY);
+        PublicKey pkey = KeyHelper.generatePublicKey(header);
+        if (pkey == null)
+            pkey = retrievePublicKey(request);
+        return pkey;
+    }
+
+    protected boolean doEncryption(RequestContext request, Object arg) {
+        return arg != null && arg instanceof RSAPublicKey;
+    }
+
+    protected Object initArg(RequestContext request) {
+        return getPublicKey(request);
+    }
+
+    protected PublicKey retrievePublicKey(RequestContext request) {
+        X509Certificate[] cert = getCerts(request);
+        return cert != null ? cert[0].getPublicKey() : null;
+    }
+
+    protected EncryptionOptions initEncryptionOptions(RequestContext request,
+                                                      ResponseContext response,
+                                                      Encryption enc,
+                                                      Object arg) {
+        try {
+          return enc.getDefaultEncryptionOptions()
+            .dataEncryptionKey(KeyHelper.generateKey("AES"))
+            .keyEncryptionKey((PublicKey)arg)
+            .keyCipherAlgorithm(XMLCipher.RSA_v1dot5)
+            .includeKeyInfo()
+            .get();
+        } catch (Exception e) {
+            return null;
+        }
+    }
+}

Propchange: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/security/util/filters/AESEncryptedResponseFilter.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/security/util/filters/AbstractEncryptedRequestFilter.java
URL: http://svn.apache.org/viewvc/abdera/abdera2-server/server/src/main/java/org/apache/abdera2/security/util/filters/AbstractEncryptedRequestFilter.java?rev=1239242&view=auto
==============================================================================
--- abdera/abdera2-server/server/src/main/java/org/apache/abdera2/security/util/filters/AbstractEncryptedRequestFilter.java (added)
+++ abdera/abdera2-server/server/src/main/java/org/apache/abdera2/security/util/filters/AbstractEncryptedRequestFilter.java Wed Feb  1 18:04:48 2012
@@ -0,0 +1,100 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  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.  For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ */
+package org.apache.abdera2.security.util.filters;
+
+import java.security.Provider;
+import java.security.Security;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.abdera2.Abdera;
+import org.apache.abdera2.common.misc.Chain;
+import org.apache.abdera2.common.misc.ExceptionHelper;
+import org.apache.abdera2.common.misc.Task;
+import org.apache.abdera2.common.protocol.RequestContext;
+import org.apache.abdera2.common.protocol.ResponseContext;
+import org.apache.abdera2.model.Document;
+import org.apache.abdera2.model.Element;
+import org.apache.abdera2.protocol.server.impl.AbstractAtompubProvider;
+import org.apache.abdera2.security.Encryption;
+import org.apache.abdera2.security.EncryptionOptions;
+
+public abstract class AbstractEncryptedRequestFilter implements Task<RequestContext,ResponseContext> {
+
+    // The methods that allow encrypted bodies
+    protected final List<String> methods = new ArrayList<String>();
+
+    protected AbstractEncryptedRequestFilter() {
+        this("POST", "PUT");
+    }
+
+    protected AbstractEncryptedRequestFilter(String... methods) {
+        for (String method : methods)
+            this.methods.add(method);
+        initProvider();
+    }
+
+    protected void initProvider() {
+    }
+
+    protected void addProvider(Provider provider) {
+        if (Security.getProvider(provider.getName()) == null)
+            Security.addProvider(provider);
+    }
+
+    public ResponseContext apply(RequestContext request, Chain<RequestContext,ResponseContext> chain) {
+        bootstrap(request);
+        String method = request.getMethod();
+        if (methods.contains(method.toUpperCase())) {
+            return chain.next(setDecryptedDocument(request));
+        } else
+            return chain.next(request);
+    }
+
+    protected RequestContext setDecryptedDocument(RequestContext request) {
+      try {
+        Document<Element> doc = AbstractAtompubProvider.getDocument(request);
+        if (doc != null) {
+          Abdera abdera = Abdera.getInstance();
+          Encryption enc = new org.apache.abdera2.security.Security(abdera).getEncryption();
+          if (enc.isEncrypted(doc)) {
+            Object arg = initArg(request);
+            EncryptionOptions encoptions = 
+              initEncryptionOptions(request, enc, arg);
+            doc = enc.decrypt(doc, encoptions);
+            if (doc != null) 
+              request.setAttribute(
+                Document.class.getName(), doc);
+          }
+        }
+      } catch (Exception e) {
+        throw ExceptionHelper.propogate(e);
+      }
+      return request;
+    }
+    
+    protected abstract void bootstrap(RequestContext request);
+
+    protected abstract Object initArg(RequestContext request);
+
+    protected abstract EncryptionOptions initEncryptionOptions(
+      RequestContext request, 
+      Encryption encryption, 
+      Object arg);
+
+}

Propchange: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/security/util/filters/AbstractEncryptedRequestFilter.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/security/util/filters/AbstractEncryptedResponseFilter.java
URL: http://svn.apache.org/viewvc/abdera/abdera2-server/server/src/main/java/org/apache/abdera2/security/util/filters/AbstractEncryptedResponseFilter.java?rev=1239242&view=auto
==============================================================================
--- abdera/abdera2-server/server/src/main/java/org/apache/abdera2/security/util/filters/AbstractEncryptedResponseFilter.java (added)
+++ abdera/abdera2-server/server/src/main/java/org/apache/abdera2/security/util/filters/AbstractEncryptedResponseFilter.java Wed Feb  1 18:04:48 2012
@@ -0,0 +1,125 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  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.  For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ */
+package org.apache.abdera2.security.util.filters;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.security.Provider;
+import java.security.Security;
+
+import org.apache.abdera2.Abdera;
+import org.apache.abdera2.common.misc.Chain;
+import org.apache.abdera2.common.misc.Task;
+import org.apache.abdera2.common.protocol.RequestContext;
+import org.apache.abdera2.common.protocol.ResponseContext;
+import org.apache.abdera2.model.Document;
+import org.apache.abdera2.model.Element;
+import org.apache.abdera2.protocol.server.AtompubResponseContext;
+import org.apache.abdera2.protocol.server.context.ResponseContextWrapper;
+import org.apache.abdera2.protocol.server.impl.AbstractAtompubProvider;
+import org.apache.abdera2.security.Encryption;
+import org.apache.abdera2.security.EncryptionOptions;
+import org.apache.abdera2.writer.Writer;
+
+public abstract class AbstractEncryptedResponseFilter implements Task<RequestContext,ResponseContext> {
+
+    public AbstractEncryptedResponseFilter() {
+        initProvider();
+    }
+
+    protected void initProvider() {
+    }
+
+    protected void addProvider(Provider provider) {
+        if (Security.getProvider(provider.getName()) == null)
+            Security.addProvider(provider);
+    }
+
+    public ResponseContext apply(RequestContext request, Chain<RequestContext,ResponseContext> chain) {
+        Object arg = initArg(request);
+        if (doEncryption(request, arg)) {
+            return new EncryptingResponseContext(AbstractAtompubProvider.getAbdera(request), request, chain.next(request), arg);
+        } else {
+            return chain.next(request);
+        }
+    }
+
+    protected abstract boolean doEncryption(RequestContext request, Object arg);
+
+    protected abstract EncryptionOptions initEncryptionOptions(RequestContext request,
+                                                               ResponseContext response,
+                                                               Encryption enc,
+                                                               Object arg);
+
+    protected abstract Object initArg(RequestContext request);
+
+    private class EncryptingResponseContext extends ResponseContextWrapper {
+
+        private final RequestContext request;
+        private final Abdera abdera;
+        private final Object arg;
+
+        public EncryptingResponseContext(Abdera abdera, RequestContext request, ResponseContext response, Object arg) {
+            super((AtompubResponseContext)response);
+            this.abdera = abdera;
+            this.request = request;
+            this.arg = arg;
+        }
+
+        public void writeTo(OutputStream out, Writer writer) throws IOException {
+            try {
+                encrypt(out, null);
+            } catch (Exception se) {
+                throw new RuntimeException(se);
+            }
+        }
+
+        public void writeTo(OutputStream out) throws IOException {
+            try {
+                encrypt(out, null);
+            } catch (Exception se) {
+                throw new RuntimeException(se);
+            }
+        }
+
+        private void encrypt(OutputStream aout, Writer writer) throws Exception {
+            Document<Element> doc = null;
+            try {
+                ByteArrayOutputStream out = new ByteArrayOutputStream();
+                if (writer == null)
+                    super.writeTo(out);
+                else
+                    super.writeTo(out, writer);
+                ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
+                doc = abdera.getParser().parse(in);
+            } catch (Exception e) {
+            }
+            if (doc != null) {
+                Encryption enc = new org.apache.abdera2.security.Security(abdera).getEncryption();
+                EncryptionOptions options = initEncryptionOptions(request, response, enc, arg);
+                doc = enc.encrypt(doc, options);
+            }
+            if (doc != null)
+                doc.writeTo(aout);
+            else
+                throw new RuntimeException("There was an error encrypting the response");
+        }
+    }
+}

Propchange: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/security/util/filters/AbstractEncryptedResponseFilter.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/security/util/filters/DHEncryptedRequestFilter.java
URL: http://svn.apache.org/viewvc/abdera/abdera2-server/server/src/main/java/org/apache/abdera2/security/util/filters/DHEncryptedRequestFilter.java?rev=1239242&view=auto
==============================================================================
--- abdera/abdera2-server/server/src/main/java/org/apache/abdera2/security/util/filters/DHEncryptedRequestFilter.java (added)
+++ abdera/abdera2-server/server/src/main/java/org/apache/abdera2/security/util/filters/DHEncryptedRequestFilter.java Wed Feb  1 18:04:48 2012
@@ -0,0 +1,87 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  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.  For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ */
+package org.apache.abdera2.security.util.filters;
+
+import org.apache.abdera2.common.misc.Chain;
+import org.apache.abdera2.common.protocol.RequestContext.Scope;
+import org.apache.abdera2.common.protocol.RequestContext;
+import org.apache.abdera2.common.protocol.ResponseContext;
+import org.apache.abdera2.security.Encryption;
+import org.apache.abdera2.security.EncryptionOptions;
+import org.apache.abdera2.security.util.Constants;
+import org.apache.abdera2.security.util.DHContext;
+
+/**
+ * A filter implementation that allows requests to be encrypted using Diffie-Hellman key negotiation. A client first
+ * uses GET/HEAD/OPTIONS to get the servers DH information, then sends an encrypted request containing it's DH
+ * information. The server can then decrypt and process the request. Note: this is currently untested.
+ */
+public class DHEncryptedRequestFilter extends AbstractEncryptedRequestFilter {
+
+    public DHEncryptedRequestFilter() {
+        super();
+    }
+
+    public DHEncryptedRequestFilter(String... methods) {
+        super(methods);
+    }
+
+    public void bootstrap(RequestContext request) {
+    }
+
+    public ResponseContext apply(RequestContext request, Chain<RequestContext,ResponseContext> chain) {
+        ResponseContext response = super.apply(request, chain);
+        String method = request.getMethod();
+        // include a Accept-Encryption header in the response to GET, HEAD and OPTIONS requests
+        // the header will specify all the information the client needs to construct
+        // it's own DH context and encrypt the request
+        if ("GET".equalsIgnoreCase(method) || "HEAD".equalsIgnoreCase(method) || "OPTIONS".equalsIgnoreCase(method)) {
+            DHContext context = (DHContext)request.getAttribute(Scope.SESSION, "dhcontext");
+            if (context == null) {
+                context = new DHContext();
+                request.setAttribute(Scope.SESSION, "dhcontext", context);
+            }
+            response.setHeader(Constants.ACCEPT_ENCRYPTION, context.getRequestString());
+        }
+        return response;
+    }
+
+    protected Object initArg(RequestContext request) {
+        DHContext context = (DHContext)request.getAttribute(Scope.SESSION, "dhcontext");
+        String dh = request.getHeader(Constants.CONTENT_ENCRYPTED);
+        if (context != null && dh != null && dh.length() > 0) {
+            try {
+                context.setPublicKey(dh);
+            } catch (Exception e) {
+            }
+        }
+        return context;
+    }
+
+    protected EncryptionOptions initEncryptionOptions(RequestContext request, Encryption encryption, Object arg) {
+        EncryptionOptions options = null;
+        if (arg != null && arg instanceof DHContext) {
+            try {
+                options = ((DHContext)arg).getEncryptionOptions(encryption);
+            } catch (Exception e) {
+            }
+        }
+        return options;
+    }
+
+}

Propchange: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/security/util/filters/DHEncryptedRequestFilter.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/security/util/filters/DHEncryptedResponseFilter.java
URL: http://svn.apache.org/viewvc/abdera/abdera2-server/server/src/main/java/org/apache/abdera2/security/util/filters/DHEncryptedResponseFilter.java?rev=1239242&view=auto
==============================================================================
--- abdera/abdera2-server/server/src/main/java/org/apache/abdera2/security/util/filters/DHEncryptedResponseFilter.java (added)
+++ abdera/abdera2-server/server/src/main/java/org/apache/abdera2/security/util/filters/DHEncryptedResponseFilter.java Wed Feb  1 18:04:48 2012
@@ -0,0 +1,115 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  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.  For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ */
+package org.apache.abdera2.security.util.filters;
+
+import org.apache.abdera2.common.misc.Chain;
+import org.apache.abdera2.common.protocol.RequestContext;
+import org.apache.abdera2.common.protocol.ResponseContext;
+import org.apache.abdera2.security.Encryption;
+import org.apache.abdera2.security.EncryptionOptions;
+import org.apache.abdera2.security.util.Constants;
+import org.apache.abdera2.security.util.DHContext;
+
+/**
+ * A Servlet Filter that uses Diffie-Hellman Key Exchange to encrypt Atom documents. The HTTP request must include an
+ * Accept-Encryption header in the form: Accept-Encryption: DH p={dh_p}, g={dh_g}, l={dh_l}, k={base64_pubkey} Example
+ * AbderaClient Code:
+ * 
+ * <pre>
+ * DHContext context = new DHContext();
+ * Abdera abdera = Abdera.getInstance();
+ * CommonsClient client = new CommonsClient(abdera);
+ * RequestOptions options = client.getDefaultRequestOptions();
+ * options.setHeader(&quot;Accept-Encryption&quot;, context.getRequestString());
+ * 
+ * ClientResponse response = client.get(&quot;http://localhost:8080/TestWeb/test&quot;, options);
+ * Document&lt;Element&gt; doc = response.getDocument();
+ * 
+ * String dh_ret = response.getHeader(&quot;Content-Encrypted&quot;);
+ * if (dh_ret != null) {
+ *     context.setPublicKey(dh_ret);
+ *     AbderaSecurity absec = new AbderaSecurity(abdera);
+ *     Encryption enc = absec.getEncryption();
+ *     EncryptionOptions encoptions = context.getEncryptionOptions(enc);
+ *     doc = enc.decrypt(doc, encoptions);
+ * }
+ * 
+ * doc.writeTo(System.out);
+ * </pre>
+ * 
+ * Webapp Deployment:
+ * 
+ * <pre>
+ * &lt;filter>
+ *   &lt;filter-name>enc filter&lt;/filter-name>
+ *   &lt;filter-class>com.test.EncryptedResponseFilter&lt;/filter-class>
+ * &lt;/filter>
+ * &lt;filter-mapping>
+ *   &lt;filter-name>enc filter&lt;/filter-name>
+ *   &lt;servlet-name>TestServlet&lt;/servlet-name>
+ * &lt;/filter-mapping>
+ * </pre>
+ */
+public class DHEncryptedResponseFilter extends AbstractEncryptedResponseFilter {
+
+    protected boolean doEncryption(RequestContext request, Object arg) {
+        return arg != null;
+    }
+
+    protected Object initArg(RequestContext request) {
+        return getDHContext(request);
+    }
+
+    protected EncryptionOptions initEncryptionOptions(RequestContext request,
+                                                      ResponseContext response,
+                                                      Encryption enc,
+                                                      Object arg) {
+        EncryptionOptions options = null;
+        try {
+            DHContext context = (DHContext)arg;
+            options = context.getEncryptionOptions(enc);
+            returnPublicKey(response, context);
+        } catch (Exception e) {
+        }
+        return options;
+
+    }
+
+    public ResponseContext apply(RequestContext request, Chain<RequestContext,ResponseContext> chain) {
+        ResponseContext response = super.apply(request, chain);
+        DHContext context = getDHContext(request);
+        response.setHeader(Constants.CONTENT_ENCRYPTED, context.getResponseString());
+        return response;
+    }
+
+    private void returnPublicKey(ResponseContext response, DHContext context) {
+        response.setHeader(Constants.CONTENT_ENCRYPTED, context.getResponseString());
+    }
+
+    private DHContext getDHContext(RequestContext request) {
+        try {
+            String dh_req = request.getHeader(Constants.ACCEPT_ENCRYPTION);
+            if (dh_req == null || dh_req.length() == 0)
+                return null;
+            return new DHContext(dh_req);
+        } catch (Exception e) {
+            return null;
+        }
+    }
+
+}

Propchange: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/security/util/filters/DHEncryptedResponseFilter.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/security/util/filters/SignedRequestFilter.java
URL: http://svn.apache.org/viewvc/abdera/abdera2-server/server/src/main/java/org/apache/abdera2/security/util/filters/SignedRequestFilter.java?rev=1239242&view=auto
==============================================================================
--- abdera/abdera2-server/server/src/main/java/org/apache/abdera2/security/util/filters/SignedRequestFilter.java (added)
+++ abdera/abdera2-server/server/src/main/java/org/apache/abdera2/security/util/filters/SignedRequestFilter.java Wed Feb  1 18:04:48 2012
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  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.  For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ */
+package org.apache.abdera2.security.util.filters;
+
+import org.apache.abdera2.Abdera;
+import org.apache.abdera2.common.Localizer;
+import org.apache.abdera2.common.misc.Chain;
+import org.apache.abdera2.common.misc.Task;
+import org.apache.abdera2.common.protocol.RequestContext;
+import org.apache.abdera2.common.protocol.ResponseContext;
+import org.apache.abdera2.common.protocol.ProviderHelper;
+import org.apache.abdera2.model.Document;
+import org.apache.abdera2.model.Element;
+import org.apache.abdera2.protocol.server.impl.AbstractAtompubProvider;
+import org.apache.abdera2.security.Security;
+import org.apache.abdera2.security.Signature;
+
+/**
+ * Servlet Filter that verifies that an Atom document received by the server via PUT or POST contains a valid XML
+ * Digital Signature.
+ */
+public class SignedRequestFilter implements Task<RequestContext,ResponseContext> {
+
+    public static final String VALID = "org.apache.abdera.security.util.servlet.SignedRequestFilter.valid";
+    public static final String CERTS = "org.apache.abdera.security.util.servlet.SignedRequestFilter.certs";
+
+    public ResponseContext apply(RequestContext request, Chain<RequestContext,ResponseContext> chain) {
+        Security security = new Security(Abdera.getInstance());
+        Signature sig = security.getSignature();
+        String method = request.getMethod();
+        if (method.equals("POST") || method.equals("PUT")) {
+            try {
+                Document<Element> doc = AbstractAtompubProvider.getDocument(request);
+                if (security.notVerified(doc))
+                    return ProviderHelper.badrequest(
+                      request, 
+                      Localizer.get("VALID.SIGNATURE.REQUIRED"));
+                request.setAttribute(
+                  VALID, true);
+                request.setAttribute(
+                  CERTS, 
+                  sig.getValidSignatureCertificates(doc.getRoot(), null));
+            } catch (Exception e) {
+            }
+        }
+        return chain.next(request);
+    }
+
+}

Propchange: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/security/util/filters/SignedRequestFilter.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/security/util/filters/SignedResponseFilter.java
URL: http://svn.apache.org/viewvc/abdera/abdera2-server/server/src/main/java/org/apache/abdera2/security/util/filters/SignedResponseFilter.java?rev=1239242&view=auto
==============================================================================
--- abdera/abdera2-server/server/src/main/java/org/apache/abdera2/security/util/filters/SignedResponseFilter.java (added)
+++ abdera/abdera2-server/server/src/main/java/org/apache/abdera2/security/util/filters/SignedResponseFilter.java Wed Feb  1 18:04:48 2012
@@ -0,0 +1,254 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  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.  For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ */
+package org.apache.abdera2.security.util.filters;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.security.KeyStore;
+import java.security.PrivateKey;
+import java.security.cert.X509Certificate;
+
+import org.apache.abdera2.Abdera;
+import org.apache.abdera2.common.misc.Chain;
+import org.apache.abdera2.common.misc.Task;
+import org.apache.abdera2.common.protocol.RequestContext;
+import org.apache.abdera2.common.protocol.ResponseContext;
+import org.apache.abdera2.model.Document;
+import org.apache.abdera2.model.Element;
+import org.apache.abdera2.protocol.server.AtompubResponseContext;
+import org.apache.abdera2.protocol.server.context.ResponseContextWrapper;
+import org.apache.abdera2.protocol.server.impl.AbstractAtompubProvider;
+import org.apache.abdera2.security.Security;
+import org.apache.abdera2.security.SecurityException;
+import org.apache.abdera2.security.Signature;
+import org.apache.abdera2.security.SignatureOptions.SignatureOptionsBuilder;
+import org.apache.abdera2.writer.Writer;
+
+/**
+ * <p>
+ * This HTTP Servlet Filter will add an XML Digital Signature to Abdera documents
+ * </p>
+ * 
+ * <pre>
+ * &lt;filter>
+ *   &lt;filter-name>signing filter&lt;/filter-name>
+ *   &lt;filter-class>org.apache.abdera.security.util.servlet.SignedResponseFilter&lt;/filter-class>
+ *   &lt;init-param>
+ *     &lt;param-name>org.apache.abdera.security.util.servlet.Keystore&lt;/param-name>
+ *     &lt;param-value>/key.jks&lt;/param-value>
+ *   &lt;/init-param>
+ *   &lt;init-param>
+ *     &lt;param-name>org.apache.abdera.security.util.servlet.KeystorePassword&lt;/param-name>
+ *     &lt;param-value>testing&lt;/param-value>
+ *   &lt;/init-param>
+ *   &lt;init-param>
+ *     &lt;param-name>org.apache.abdera.security.util.servlet.PrivateKeyAlias&lt;/param-name>
+ *     &lt;param-value>James&lt;/param-value>
+ *   &lt;/init-param>
+ *   &lt;init-param>
+ *     &lt;param-name>org.apache.abdera.security.util.servlet.PrivateKeyPassword&lt;/param-name>
+ *     &lt;param-value>testing&lt;/param-value>
+ *   &lt;/init-param>
+ *   &lt;init-param>
+ *     &lt;param-name>org.apache.abdera.security.util.servlet.CertificateAlias&lt;/param-name>
+ *     &lt;param-value>James&lt;/param-value>
+ *   &lt;/init-param>
+ *   &lt;init-param>
+ *     &lt;param-name>org.apache.abdera.security.util.servlet.SigningAlgorithm&lt;/param-name>
+ *     &lt;param-value>http://www.w3.org/2000/09/xmldsig#rsa-sha1&lt;/param-value>
+ *   &lt;/init-param>
+ * &lt;/filter>
+ * &lt;filter-mapping id="signing-filter">
+ *   &lt;filter-name>signing filter&lt;/filter-name>
+ *   &lt;servlet-name>Abdera&lt;/servlet-name>
+ * &lt;/filter-mapping>
+ * </pre>
+ */
+public class SignedResponseFilter implements Task<RequestContext,ResponseContext> {
+
+    private static final String keystoreType = "JKS";
+
+    private String keystoreFile = null;
+    private String keystorePass = null;
+    private String privateKeyAlias = null;
+    private String privateKeyPass = null;
+    private String certificateAlias = null;
+    private String algorithm = null;
+    private PrivateKey signingKey = null;
+    private X509Certificate cert = null;
+
+    public SignedResponseFilter(String keystoreFile,
+                                String keystorePass,
+                                String privateKeyAlias,
+                                String privateKeyPass,
+                                String certificateAlias,
+                                String algorithm) {
+        this.keystoreFile = keystoreFile;
+        this.keystorePass = keystorePass;
+        this.privateKeyAlias = privateKeyAlias;
+        this.privateKeyPass = privateKeyPass;
+        this.certificateAlias = certificateAlias;
+        this.algorithm = algorithm;
+        try {
+            KeyStore ks = KeyStore.getInstance(keystoreType);
+            InputStream in = SignedResponseFilter.class.getResourceAsStream(keystoreFile);
+            ks.load(in, keystorePass.toCharArray());
+            signingKey = (PrivateKey)ks.getKey(privateKeyAlias, privateKeyPass.toCharArray());
+            cert = (X509Certificate)ks.getCertificate(certificateAlias);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    public ResponseContext apply(RequestContext request, Chain<RequestContext,ResponseContext> chain) {
+        return new SigningResponseContextWrapper(AbstractAtompubProvider.getAbdera(request), chain.next(request));
+    }
+
+    private Document<Element> signDocument(Abdera abdera, Document<Element> doc) throws SecurityException {
+        Security security = new Security(abdera);
+        if (signingKey == null || cert == null)
+            return doc; // pass through
+        Signature sig = security.getSignature();
+        SignatureOptionsBuilder options = 
+          sig.getDefaultSignatureOptions()
+            .certificate(cert)
+            .signingKey(signingKey);
+        if (algorithm != null)
+            options.signingAlgorithm(algorithm);
+        Element element = doc.getRoot();
+        element = sig.sign(element, options.get());
+        return element.getDocument();
+    }
+
+    private class SigningResponseContextWrapper extends ResponseContextWrapper {
+
+        private final Abdera abdera;
+
+        public SigningResponseContextWrapper(Abdera abdera, ResponseContext response) {
+            super((AtompubResponseContext)response);
+            this.abdera = abdera;
+        }
+
+        public void writeTo(OutputStream out, Writer writer) throws IOException {
+            try {
+                sign(out, null);
+            } catch (Exception se) {
+                throw new RuntimeException(se);
+            }
+        }
+
+        public void writeTo(OutputStream out) throws IOException {
+            try {
+                sign(out, null);
+            } catch (Exception se) {
+                throw new RuntimeException(se);
+            }
+        }
+
+        private void sign(OutputStream aout, Writer writer) throws Exception {
+            Document<Element> doc = null;
+            try {
+                ByteArrayOutputStream out = new ByteArrayOutputStream();
+                if (writer == null)
+                    super.writeTo(out);
+                else
+                    super.writeTo(out, writer);
+                ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
+                doc = abdera.getParser().parse(in);
+            } catch (Exception e) {
+            }
+            if (doc != null) {
+                doc = signDocument(abdera, doc);
+                doc.writeTo(aout);
+            } else {
+                super.writeTo(aout);
+            }
+        }
+    }
+
+    public String getKeystoreFile() {
+        return keystoreFile;
+    }
+
+    public void setKeystoreFile(String keystoreFile) {
+        this.keystoreFile = keystoreFile;
+    }
+
+    public String getKeystorePass() {
+        return keystorePass;
+    }
+
+    public void setKeystorePass(String keystorePass) {
+        this.keystorePass = keystorePass;
+    }
+
+    public String getPrivateKeyAlias() {
+        return privateKeyAlias;
+    }
+
+    public void setPrivateKeyAlias(String privateKeyAlias) {
+        this.privateKeyAlias = privateKeyAlias;
+    }
+
+    public String getPrivateKeyPass() {
+        return privateKeyPass;
+    }
+
+    public void setPrivateKeyPass(String privateKeyPass) {
+        this.privateKeyPass = privateKeyPass;
+    }
+
+    public String getCertificateAlias() {
+        return certificateAlias;
+    }
+
+    public void setCertificateAlias(String certificateAlias) {
+        this.certificateAlias = certificateAlias;
+    }
+
+    public String getAlgorithm() {
+        return algorithm;
+    }
+
+    public void setAlgorithm(String algorithm) {
+        this.algorithm = algorithm;
+    }
+
+    public PrivateKey getSigningKey() {
+        return signingKey;
+    }
+
+    public void setSigningKey(PrivateKey signingKey) {
+        this.signingKey = signingKey;
+    }
+
+    public X509Certificate getCert() {
+        return cert;
+    }
+
+    public void setCert(X509Certificate cert) {
+        this.cert = cert;
+    }
+
+    public static String getKeystoreType() {
+        return keystoreType;
+    }
+}

Propchange: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/security/util/filters/SignedResponseFilter.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain