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


Reply via email to