You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by rd...@apache.org on 2007/01/09 22:08:13 UTC

svn commit: r494577 [1/2] - in /james/server/sandbox/rfc3156: ./ lib/ src/java/org/apache/james/security/openpgp/ src/java/org/apache/james/security/openpgp/bc/ src/java/org/apache/james/util/mail/handlers/ src/test/org/apache/james/mailboxmanager/ src...

Author: rdonkin
Date: Tue Jan  9 13:08:11 2007
New Revision: 494577

URL: http://svn.apache.org/viewvc?view=rev&rev=494577
Log:
Initial code drop for OpenPGP/SMIME. Still some tricky work needed but it's good to have the code in a repository.

Added:
    james/server/sandbox/rfc3156/lib/bcmail-jdk14-133.jar   (with props)
    james/server/sandbox/rfc3156/lib/bcpg-jdk14-133.jar   (with props)
    james/server/sandbox/rfc3156/lib/bcprov-jdk14-133.jar   (with props)
    james/server/sandbox/rfc3156/src/java/org/apache/james/security/openpgp/
    james/server/sandbox/rfc3156/src/java/org/apache/james/security/openpgp/OpenPGPMIMEConstants.java
    james/server/sandbox/rfc3156/src/java/org/apache/james/security/openpgp/OpenPGPMIMEGenerator.java
    james/server/sandbox/rfc3156/src/java/org/apache/james/security/openpgp/OpenPGPMIMEKeyHolder.java
    james/server/sandbox/rfc3156/src/java/org/apache/james/security/openpgp/OpenPGPSignatureFactory.java
    james/server/sandbox/rfc3156/src/java/org/apache/james/security/openpgp/OpenPGPSignatureType.java
    james/server/sandbox/rfc3156/src/java/org/apache/james/security/openpgp/OpenPGPStreamer.java
    james/server/sandbox/rfc3156/src/java/org/apache/james/security/openpgp/OpenPGPUtils.java
    james/server/sandbox/rfc3156/src/java/org/apache/james/security/openpgp/Writable.java
    james/server/sandbox/rfc3156/src/java/org/apache/james/security/openpgp/WritableMimeBodyPart.java
    james/server/sandbox/rfc3156/src/java/org/apache/james/security/openpgp/bc/
    james/server/sandbox/rfc3156/src/java/org/apache/james/security/openpgp/bc/BCOpenPGPSignatureFactory.java
    james/server/sandbox/rfc3156/src/java/org/apache/james/security/openpgp/bc/BCOpenPGPSignatureStreamer.java
    james/server/sandbox/rfc3156/src/java/org/apache/james/security/openpgp/bc/GeneratorOutputStream.java
    james/server/sandbox/rfc3156/src/java/org/apache/james/security/openpgp/bc/SignatureFailureException.java
    james/server/sandbox/rfc3156/src/java/org/apache/james/util/mail/handlers/pgp_signature.java
    james/server/sandbox/rfc3156/src/test/org/apache/james/security/
    james/server/sandbox/rfc3156/src/test/org/apache/james/security/openpgp/
    james/server/sandbox/rfc3156/src/test/org/apache/james/security/openpgp/MockOpenPGPSignatureGenerator.java
    james/server/sandbox/rfc3156/src/test/org/apache/james/security/openpgp/MockOpenPGPStreamer.java
    james/server/sandbox/rfc3156/src/test/org/apache/james/security/openpgp/OpenPGPMIMEGeneratorTest.java
    james/server/sandbox/rfc3156/src/test/org/apache/james/security/openpgp/WritableContentTest.java
    james/server/sandbox/rfc3156/src/test/org/apache/james/security/openpgp/bc/
    james/server/sandbox/rfc3156/src/test/org/apache/james/security/openpgp/bc/BCOpenPGPSignatureFactoryTest.java
    james/server/sandbox/rfc3156/src/test/org/apache/james/security/openpgp/bc/BCOpenPGPSignatureStreamerTest.java
    james/server/sandbox/rfc3156/src/test/org/apache/james/security/openpgp/bc/BCTestHelper.java
    james/server/sandbox/rfc3156/src/test/org/apache/james/security/openpgp/bc/WritableFileContent.java
    james/server/sandbox/rfc3156/src/test/org/apache/james/security/openpgp/bc/message.txt
    james/server/sandbox/rfc3156/src/test/org/apache/james/security/openpgp/bc/pubring.gpg   (with props)
    james/server/sandbox/rfc3156/src/test/org/apache/james/security/openpgp/bc/random_seed   (with props)
    james/server/sandbox/rfc3156/src/test/org/apache/james/security/openpgp/bc/secring.gpg   (with props)
    james/server/sandbox/rfc3156/src/test/org/apache/james/security/openpgp/bc/trustdb.gpg   (with props)
    james/server/sandbox/rfc3156/src/test/org/apache/james/security/openpgp/simple-message.txt
    james/server/sandbox/rfc3156/src/test/org/apache/james/util/mail/
    james/server/sandbox/rfc3156/src/test/org/apache/james/util/mail/handlers/
    james/server/sandbox/rfc3156/src/test/org/apache/james/util/mail/handlers/pgp_signatureTest.java
Removed:
    james/server/sandbox/rfc3156/lib/bcmail-jdk14-129.jar
Modified:
    james/server/sandbox/rfc3156/build.xml
    james/server/sandbox/rfc3156/include.properties
    james/server/sandbox/rfc3156/src/test/org/apache/james/mailboxmanager/TestUtil.java

Modified: james/server/sandbox/rfc3156/build.xml
URL: http://svn.apache.org/viewvc/james/server/sandbox/rfc3156/build.xml?view=diff&rev=494577&r1=494576&r2=494577
==============================================================================
--- james/server/sandbox/rfc3156/build.xml (original)
+++ james/server/sandbox/rfc3156/build.xml Tue Jan  9 13:08:11 2007
@@ -83,7 +83,8 @@
             <include name="${javax-mail.jar}"/>
             <include name="${javax-activation.jar}"/>
             <include name="${bcmail.jar}"/>
-            <include name="${bcmail-workaround.jar}"/>
+            <include name="${bcpg.jar}"/>
+        	<include name="${bcprov.jar}"/>
             <include name="${javax.management}"/>
             <include name="${jspf.jar}"/>
             <include name="${mstor.jar}"/>

Modified: james/server/sandbox/rfc3156/include.properties
URL: http://svn.apache.org/viewvc/james/server/sandbox/rfc3156/include.properties?view=diff&rev=494577&r1=494576&r2=494577
==============================================================================
--- james/server/sandbox/rfc3156/include.properties (original)
+++ james/server/sandbox/rfc3156/include.properties Tue Jan  9 13:08:11 2007
@@ -84,8 +84,9 @@
 
 derby.jar=derby.jar
 
-bcmail.jar=bcmail-jdk14-129.jar
-bcmail-workaround.jar=bcmail-jdk14-129-workaround.jar
+bcmail.jar=bcmail-jdk14-133.jar
+bcpg.jar=bcpg-jdk14-133.jar
+bcprov.jar=bcprov-jdk14-133.jar
 
 # ----- jSPF -----
 jspf.jar=jspf-0.9-SNAPSHOT.jar

Added: james/server/sandbox/rfc3156/lib/bcmail-jdk14-133.jar
URL: http://svn.apache.org/viewvc/james/server/sandbox/rfc3156/lib/bcmail-jdk14-133.jar?view=auto&rev=494577
==============================================================================
Binary file - no diff available.

Propchange: james/server/sandbox/rfc3156/lib/bcmail-jdk14-133.jar
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: james/server/sandbox/rfc3156/lib/bcpg-jdk14-133.jar
URL: http://svn.apache.org/viewvc/james/server/sandbox/rfc3156/lib/bcpg-jdk14-133.jar?view=auto&rev=494577
==============================================================================
Binary file - no diff available.

Propchange: james/server/sandbox/rfc3156/lib/bcpg-jdk14-133.jar
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: james/server/sandbox/rfc3156/lib/bcprov-jdk14-133.jar
URL: http://svn.apache.org/viewvc/james/server/sandbox/rfc3156/lib/bcprov-jdk14-133.jar?view=auto&rev=494577
==============================================================================
Binary file - no diff available.

Propchange: james/server/sandbox/rfc3156/lib/bcprov-jdk14-133.jar
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: james/server/sandbox/rfc3156/src/java/org/apache/james/security/openpgp/OpenPGPMIMEConstants.java
URL: http://svn.apache.org/viewvc/james/server/sandbox/rfc3156/src/java/org/apache/james/security/openpgp/OpenPGPMIMEConstants.java?view=auto&rev=494577
==============================================================================
--- james/server/sandbox/rfc3156/src/java/org/apache/james/security/openpgp/OpenPGPMIMEConstants.java (added)
+++ james/server/sandbox/rfc3156/src/java/org/apache/james/security/openpgp/OpenPGPMIMEConstants.java Tue Jan  9 13:08:11 2007
@@ -0,0 +1,44 @@
+/****************************************************************
+ * 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.james.security.openpgp;
+
+/**
+ * <p>
+ * Constants specified in <code>RFC 3156 OpenPGP/MIME</code>
+ * </p>
+ * 
+ */
+public final class OpenPGPMIMEConstants {
+
+    /**
+     * MIME type for RFC-3156 OpenPGP/MIME signature content.
+     */
+    public static final String MIME_TYPE_OPENPGP_SIGNATURE = "application/pgp-signature";
+    
+    /**
+     * Content type for RFC-3156 OpenPGP/MIME signed mail messages;
+     */
+    public static final String SIGNED_MESSAGE_CONTENT_TYPE = "multipart/signed";
+
+    /**
+     * RFC-3156 OpenPGP/MIME  signature protocol for content type.
+     */
+    public static final String OPENPGP_PROTOCOL_TYPE = "application/pgp-signature";
+}

Added: james/server/sandbox/rfc3156/src/java/org/apache/james/security/openpgp/OpenPGPMIMEGenerator.java
URL: http://svn.apache.org/viewvc/james/server/sandbox/rfc3156/src/java/org/apache/james/security/openpgp/OpenPGPMIMEGenerator.java?view=auto&rev=494577
==============================================================================
--- james/server/sandbox/rfc3156/src/java/org/apache/james/security/openpgp/OpenPGPMIMEGenerator.java (added)
+++ james/server/sandbox/rfc3156/src/java/org/apache/james/security/openpgp/OpenPGPMIMEGenerator.java Tue Jan  9 13:08:11 2007
@@ -0,0 +1,133 @@
+/****************************************************************
+ * 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.james.security.openpgp;
+
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+
+import javax.mail.internet.ContentType;
+import javax.mail.internet.MimeBodyPart;
+import javax.mail.internet.MimeMessage;
+import javax.mail.internet.MimeMultipart;
+import javax.mail.internet.ParseException;
+
+/**
+ * <p>Generates <code>RFC3156 OpenPGP/MIME</code> signatures.</p>
+ * <p>
+ * Contains a general OpenPGP/MIME implementation decoupled
+ * from both cryptographic implementation and mail server.
+ * </p>
+ */
+public class OpenPGPMIMEGenerator {
+
+    private static final String OPENPGP_SIGNED_MESSAGE_CONTENT_TYPE 
+        = "signed;  protocol=\"" 
+        + OpenPGPMIMEConstants.OPENPGP_PROTOCOL_TYPE + "\"; micalg=";
+    
+    private static final String SIGNATURE_PART_CONTENT_TYPE 
+        = OpenPGPMIMEConstants.MIME_TYPE_OPENPGP_SIGNATURE + "; name=";
+    
+    public static final String DEFAULT_SIGNATURE_FILE_NAME = "signature.asc";
+    
+    private final OpenPGPSignatureFactory signatureGenerator;
+    private final String contentType;
+    private final String signatureContentType;
+    
+    public OpenPGPMIMEGenerator(final OpenPGPSignatureFactory signatureGenerator) {
+        this(signatureGenerator, DEFAULT_SIGNATURE_FILE_NAME);
+    }
+    
+    /**
+     * Constucts an <code>RFC3156 OpenPGP/MIME</code> generator.
+     * @param signatureGenerator <code>OpenPGPSignatureGenerator</code>, not null
+     * @param signatureName the display name to be used for the signature attachment.
+     * Used to populate the name field of the signature part content-type
+     */
+    public OpenPGPMIMEGenerator(final OpenPGPSignatureFactory signatureGenerator, final String signatureName) {
+        this.signatureGenerator = signatureGenerator;
+        contentType = createContentType();
+        this.signatureContentType = SIGNATURE_PART_CONTENT_TYPE + signatureName;
+    }
+
+    public MimeMultipart generate(MimeMessage message) throws Exception {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    public MimeMultipart generate(MimeBodyPart content) throws Exception {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /**
+     * Generates a OpenPGP signed message MIME message from the given content.
+     * @param content <code>MimeBodyPart</code> content, not null
+     * @return <code>MimeMultipart</code> RFC-3156 OpenPGP/MIME format signed message
+     * @throws Exception
+     */
+    public MimeMultipart generateSignedMessage(final MimeBodyPart content) throws Exception {
+        final MimeMultipart result = new MimeMultipart(contentType);
+        MimeBodyPart canonicalised = canonicalise(content);
+        result.addBodyPart(canonicalised);
+        final MimeBodyPart signaturePart = createSignaturePart(canonicalised);
+        result.addBodyPart(signaturePart);
+        return result;
+    }
+
+    private MimeBodyPart canonicalise(final MimeBodyPart content) throws Exception {
+        MimeBodyPart result = content;
+        final String contentTypeString = content.getContentType();
+        final ContentType contentType = new ContentType(contentTypeString);
+        // OpenPGP/MIME: text should be canonicalised
+        if (contentType.match("text/*")) {
+
+        }
+        return result;
+    }
+
+    private String createContentType() {
+        final OpenPGPSignatureType signatureType = signatureGenerator.getSignatureType();
+        final String micAlgorithm = signatureType.getMessageIntegrityCheckAlgorithmCode();
+        final String contentType = OPENPGP_SIGNED_MESSAGE_CONTENT_TYPE + micAlgorithm;
+        return contentType;
+    }
+    
+    /**
+     * <p>Creates the signature part of the message from the given content.</p>
+     * <p>
+     * <strong>Note</strong> that the content should be already processed into
+     * the form required OpenPGP/MIME. In particular, it must have been 
+     * canonicalised and transfer encoded (if necessary).
+     * </p>
+     * @param content <code>MimeBodyPart</code> containing the processed content to be signed
+     * @return <code>MimeBodyPart</code> encoding the OpenPGP/MIME detached signature
+     * @throws Exception
+     */
+    private MimeBodyPart createSignaturePart(final MimeBodyPart content) throws Exception
+    {
+        final MimeBodyPart result = new MimeBodyPart();
+        final WritableMimeBodyPart writableMimeBodyPart = new WritableMimeBodyPart(content);
+        OpenPGPStreamer signatureContent = signatureGenerator.createSignatureStreamer(writableMimeBodyPart);
+        result.setContent(signatureContent, OpenPGPMIMEConstants.MIME_TYPE_OPENPGP_SIGNATURE);
+        result.addHeader("Content-Type", signatureContentType);
+        return result;
+    }
+}

Added: james/server/sandbox/rfc3156/src/java/org/apache/james/security/openpgp/OpenPGPMIMEKeyHolder.java
URL: http://svn.apache.org/viewvc/james/server/sandbox/rfc3156/src/java/org/apache/james/security/openpgp/OpenPGPMIMEKeyHolder.java?view=auto&rev=494577
==============================================================================
--- james/server/sandbox/rfc3156/src/java/org/apache/james/security/openpgp/OpenPGPMIMEKeyHolder.java (added)
+++ james/server/sandbox/rfc3156/src/java/org/apache/james/security/openpgp/OpenPGPMIMEKeyHolder.java Tue Jan  9 13:08:11 2007
@@ -0,0 +1,69 @@
+/****************************************************************
+ * 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.james.security.openpgp;
+
+import javax.mail.internet.MimeBodyPart;
+import javax.mail.internet.MimeMessage;
+import javax.mail.internet.MimeMultipart;
+
+import org.apache.james.security.KeyHolder;
+
+/**
+ * <p>Holds a OpenPGP private key used to sign email.</p>
+ * <p><strong>Note</strong> that this class is an implementation of 
+ * <code>RFC3156 - OpenPGP/MIME</code> only. Older PGP forms are
+ * not supported.
+ * </p>
+ * <p>
+ * </p>
+ */
+public class OpenPGPMIMEKeyHolder extends OpenPGPMIMEGenerator implements KeyHolder {
+
+    public OpenPGPMIMEKeyHolder(OpenPGPSignatureFactory signatureGenerator) {
+        super(signatureGenerator);
+    }
+
+    /**
+     * Gets the signer address as requested.
+     * An OpenPGP key may be associated with more than one
+     * email address. 
+     * @return an email address associated with the key
+     */
+    public String getSignerAddress() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /**
+     * Not available.
+     * @return null
+     */
+    public String getSignerCN() {
+        return null;
+    }
+
+    /**
+     * Not available.
+     * @return null
+     */
+    public String getSignerDistinguishedName() {
+        return null;
+    }
+}

Added: james/server/sandbox/rfc3156/src/java/org/apache/james/security/openpgp/OpenPGPSignatureFactory.java
URL: http://svn.apache.org/viewvc/james/server/sandbox/rfc3156/src/java/org/apache/james/security/openpgp/OpenPGPSignatureFactory.java?view=auto&rev=494577
==============================================================================
--- james/server/sandbox/rfc3156/src/java/org/apache/james/security/openpgp/OpenPGPSignatureFactory.java (added)
+++ james/server/sandbox/rfc3156/src/java/org/apache/james/security/openpgp/OpenPGPSignatureFactory.java Tue Jan  9 13:08:11 2007
@@ -0,0 +1,42 @@
+/****************************************************************
+ * 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.james.security.openpgp;
+
+/**
+ * Generates signatures for content.
+ * Factors code that necessarily depends on the
+ * crytography implementation used from the 
+ * mail binding code.
+ */
+public interface OpenPGPSignatureFactory {
+
+    /**
+     * Gets the type of signature that will be generated.
+     * @return <code>OpenPGPSignatureType</code>, not null
+     */
+    public OpenPGPSignatureType getSignatureType();
+    
+    /**
+     * Creates a signature streamer.
+     * @param content TODO
+     * @return <code>OpenPGPStreamer</code>, not null
+     */
+    public OpenPGPStreamer createSignatureStreamer(Writable content) throws Exception;
+}

Added: james/server/sandbox/rfc3156/src/java/org/apache/james/security/openpgp/OpenPGPSignatureType.java
URL: http://svn.apache.org/viewvc/james/server/sandbox/rfc3156/src/java/org/apache/james/security/openpgp/OpenPGPSignatureType.java?view=auto&rev=494577
==============================================================================
--- james/server/sandbox/rfc3156/src/java/org/apache/james/security/openpgp/OpenPGPSignatureType.java (added)
+++ james/server/sandbox/rfc3156/src/java/org/apache/james/security/openpgp/OpenPGPSignatureType.java Tue Jan  9 13:08:11 2007
@@ -0,0 +1,84 @@
+/****************************************************************
+ * 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.james.security.openpgp;
+
+/**
+ * Enumerates the types of signature enumerated in 
+ * <code>RFC-3156 OpenPGG/MIME</code>.
+ *
+ */
+public final class OpenPGPSignatureType {
+    
+    /** OpenPGP using MD5 as the hash algorithm. */
+    public static final OpenPGPSignatureType PGP_MD5 = new OpenPGPSignatureType("pgp-md5");
+    /** OpenPGP using MD2 as the hash algorithm. */
+    public static final OpenPGPSignatureType PGP_MD2 = new OpenPGPSignatureType("pgp-md2");
+    /** OpenPGP using SHA1 as the hash algorithm. */
+    public static final OpenPGPSignatureType PGP_SHA1 = new OpenPGPSignatureType("pgp-sha1");
+    /** OpenPGP using RIPE 160 as the hash algorithm. */
+    public static final OpenPGPSignatureType PGP_RIPE_MD_160 = new OpenPGPSignatureType("pgp-ripemd160");
+    /** OpenPGP using TIGER 192 as the hash algorithm. */
+    public static final OpenPGPSignatureType PGP_TIGER_192 = new OpenPGPSignatureType("pgp-tiger192");
+    /** OpenPGP using HAVEL 5 160 as the hash algorithm. */
+    public static final OpenPGPSignatureType PGP_HAVEL_5_160 = new OpenPGPSignatureType("pgp-haval-5-160");
+    
+    private final String code;
+    
+    private OpenPGPSignatureType(final String code) {
+        this.code = code;
+    }
+    
+    /**
+     * Gets the <code>micalg</code> value for this algorithm 
+     * as defined in <code>RFC-3156 OpenPGG/MIME</code>
+     * @return the algorithm name, not null
+     */
+    public String getMessageIntegrityCheckAlgorithmCode() {
+        return code;
+    }
+
+    public int hashCode() {
+        final int PRIME = 31;
+        int result = 1;
+        result = PRIME * result + code.hashCode();
+        return result;
+    }
+
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        final OpenPGPSignatureType other = (OpenPGPSignatureType) obj;
+        if (code == null) {
+            if (other.code != null)
+                return false;
+        } else if (!code.equals(other.code))
+            return false;
+        return true;
+    }
+    
+    public String toString()
+    {
+        return code;
+    }
+}

Added: james/server/sandbox/rfc3156/src/java/org/apache/james/security/openpgp/OpenPGPStreamer.java
URL: http://svn.apache.org/viewvc/james/server/sandbox/rfc3156/src/java/org/apache/james/security/openpgp/OpenPGPStreamer.java?view=auto&rev=494577
==============================================================================
--- james/server/sandbox/rfc3156/src/java/org/apache/james/security/openpgp/OpenPGPStreamer.java (added)
+++ james/server/sandbox/rfc3156/src/java/org/apache/james/security/openpgp/OpenPGPStreamer.java Tue Jan  9 13:08:11 2007
@@ -0,0 +1,45 @@
+/****************************************************************
+ * 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.james.security.openpgp;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * <p>Streams out OpenPGP/MIME content.</p>
+ * <p>
+ * <strong>Usage:</strong> content for body parts.
+ * An appropriate <code>DataContentHandler</code> should be 
+ * registered for this type.
+ * </p>
+ */
+public interface OpenPGPStreamer {
+
+    /**
+     * Writes out content to the given stream.
+     * Checked exceptions specific to the 
+     * crytographic operations should be handled or adapted by
+     * the implementation.
+     * @param out <code>OutputStream</code>, not null
+     * @throws IOException throw following an IO failure
+     * or an irrecoverable cryptographic issue
+     */
+    void writeOpenPGPContent(OutputStream out) throws IOException;
+}

Added: james/server/sandbox/rfc3156/src/java/org/apache/james/security/openpgp/OpenPGPUtils.java
URL: http://svn.apache.org/viewvc/james/server/sandbox/rfc3156/src/java/org/apache/james/security/openpgp/OpenPGPUtils.java?view=auto&rev=494577
==============================================================================
--- james/server/sandbox/rfc3156/src/java/org/apache/james/security/openpgp/OpenPGPUtils.java (added)
+++ james/server/sandbox/rfc3156/src/java/org/apache/james/security/openpgp/OpenPGPUtils.java Tue Jan  9 13:08:11 2007
@@ -0,0 +1,61 @@
+/****************************************************************
+ * 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.james.security.openpgp;
+
+/**
+ * Utility methods.
+ *
+ */
+public class OpenPGPUtils {
+
+    
+    /**
+     * Converts the given string into an array of bytes
+     * without performing platform dependent encoding.
+     * Takes only the bottom 8 bits.
+     * @param string <code>String</code>, not null
+     * @return <code>byte</code> array, not null
+     */
+    public static final byte[] toBytes(final String string) {
+        final char[] characters = string.toCharArray();
+        final int length = characters.length;
+        final byte[] results = new byte[length];
+        for (int i=0;i<length;i++) {
+            results[i] = (byte) characters[i];
+        }
+        return results;
+    }
+    
+    /**
+     * Converts an array of 8 bit bytes into a string
+     * without performing platform dependent encoding.
+     * @param bytes <code>byte</code> array, not null
+     * @return <code>String</code> representation
+     */
+    public static final String toString(final byte[] bytes) {
+        final int length = bytes.length;
+        final char[] characters = new char[length];
+        for (int i=0;i<length;i++) {
+            characters[i] = (char) (bytes[i] & 255);
+        }
+        final String result = new String(characters);
+        return result;
+    }
+}

Added: james/server/sandbox/rfc3156/src/java/org/apache/james/security/openpgp/Writable.java
URL: http://svn.apache.org/viewvc/james/server/sandbox/rfc3156/src/java/org/apache/james/security/openpgp/Writable.java?view=auto&rev=494577
==============================================================================
--- james/server/sandbox/rfc3156/src/java/org/apache/james/security/openpgp/Writable.java (added)
+++ james/server/sandbox/rfc3156/src/java/org/apache/james/security/openpgp/Writable.java Tue Jan  9 13:08:11 2007
@@ -0,0 +1,35 @@
+/****************************************************************
+ * 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.james.security.openpgp;
+
+import java.io.OutputStream;
+
+/**
+ * Content which can be written to an output stream.
+ */
+public interface Writable {
+
+    /**
+     * Writes content to output stream.
+     * @param out  <code>OutputStream</code>, not null
+     * @throws Exception 
+     */
+    public void write(OutputStream out) throws Exception;
+}

Added: james/server/sandbox/rfc3156/src/java/org/apache/james/security/openpgp/WritableMimeBodyPart.java
URL: http://svn.apache.org/viewvc/james/server/sandbox/rfc3156/src/java/org/apache/james/security/openpgp/WritableMimeBodyPart.java?view=auto&rev=494577
==============================================================================
--- james/server/sandbox/rfc3156/src/java/org/apache/james/security/openpgp/WritableMimeBodyPart.java (added)
+++ james/server/sandbox/rfc3156/src/java/org/apache/james/security/openpgp/WritableMimeBodyPart.java Tue Jan  9 13:08:11 2007
@@ -0,0 +1,40 @@
+/****************************************************************
+ * 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.james.security.openpgp;
+
+import java.io.OutputStream;
+
+import javax.mail.internet.MimeBodyPart;
+
+/**
+ * Adapts MIME message part to form expected by generator.
+ */
+class WritableMimeBodyPart implements Writable {
+
+    private final MimeBodyPart part;
+    
+    public WritableMimeBodyPart(final MimeBodyPart part) {
+        this.part = part;
+    }
+    
+    public void write(OutputStream out) throws Exception {
+        part.writeTo(out);
+    }
+}

Added: james/server/sandbox/rfc3156/src/java/org/apache/james/security/openpgp/bc/BCOpenPGPSignatureFactory.java
URL: http://svn.apache.org/viewvc/james/server/sandbox/rfc3156/src/java/org/apache/james/security/openpgp/bc/BCOpenPGPSignatureFactory.java?view=auto&rev=494577
==============================================================================
--- james/server/sandbox/rfc3156/src/java/org/apache/james/security/openpgp/bc/BCOpenPGPSignatureFactory.java (added)
+++ james/server/sandbox/rfc3156/src/java/org/apache/james/security/openpgp/bc/BCOpenPGPSignatureFactory.java Tue Jan  9 13:08:11 2007
@@ -0,0 +1,107 @@
+/****************************************************************
+ * 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.james.security.openpgp.bc;
+
+import java.security.NoSuchProviderException;
+
+import org.apache.james.security.openpgp.OpenPGPSignatureFactory;
+import org.apache.james.security.openpgp.OpenPGPSignatureType;
+import org.apache.james.security.openpgp.OpenPGPStreamer;
+import org.apache.james.security.openpgp.Writable;
+import org.bouncycastle.openpgp.PGPException;
+import org.bouncycastle.openpgp.PGPPrivateKey;
+import org.bouncycastle.openpgp.PGPSecretKey;
+import org.bouncycastle.openpgp.PGPSignature;
+import org.bouncycastle.openpgp.PGPSignatureGenerator;
+import org.bouncycastle.openpgp.PGPUtil;
+
+/**
+ * Creates OpenPGP/MIME signatures using Bouncy Castle.
+ */
+public class BCOpenPGPSignatureFactory implements OpenPGPSignatureFactory {
+
+    private static final String PROVIDER_ID = "BC";
+
+    private final PGPPrivateKey signingKey;
+    private final OpenPGPSignatureType signatureType;
+    private final int hashAlgorithm;
+    private final int keyAlgorithm;
+    private final int pgpSignatureType;
+    
+    public BCOpenPGPSignatureFactory(final PGPSecretKey signingKey, 
+            final OpenPGPSignatureType signatureType, char[] passPhrase, boolean useTextSignatureType) throws NoSuchProviderException, PGPException {
+        super();
+        this.signingKey = signingKey.extractPrivateKey(passPhrase, PROVIDER_ID);
+        this.signatureType = signatureType;
+        this.hashAlgorithm = toBCHashAlgorithm(signatureType);
+        this.keyAlgorithm = signingKey.getPublicKey().getAlgorithm();
+        this.pgpSignatureType = getOpenPGPSignatureType(useTextSignatureType);
+    }
+    
+    private int toBCHashAlgorithm(OpenPGPSignatureType signatureType) throws PGPException {
+        int result = -1;
+        if (OpenPGPSignatureType.PGP_HAVEL_5_160.equals(signatureType)) {
+            result = PGPUtil.HAVAL_5_160;
+        } else if (OpenPGPSignatureType.PGP_MD2.equals(signatureType)) {
+            result = PGPUtil.MD2;
+        } else if (OpenPGPSignatureType.PGP_MD5.equals(signatureType)) {
+            result = PGPUtil.MD5;
+        } else if (OpenPGPSignatureType.PGP_SHA1.equals(signatureType)) {
+            result = PGPUtil.SHA1;
+        } else if (OpenPGPSignatureType.PGP_TIGER_192.equals(signatureType)) {
+            result = PGPUtil.TIGER_192;
+        } else if (OpenPGPSignatureType.PGP_RIPE_MD_160.equals(signatureType)) {
+            result = PGPUtil.RIPEMD160;
+        }
+        if (result == -1) {
+            throw new PGPException("Unsupported hash algorithm");
+        }
+        return result;
+    }
+
+    private int getOpenPGPSignatureType(boolean useTextSignatureType) {
+        int result = PGPSignature.BINARY_DOCUMENT;
+        if (useTextSignatureType) {
+            result = PGPSignature.CANONICAL_TEXT_DOCUMENT;
+        }
+        return result;
+    }
+    
+    public OpenPGPStreamer createSignatureStreamer(final Writable content)
+            throws Exception {
+        final PGPSignatureGenerator generator 
+            = new PGPSignatureGenerator(keyAlgorithm, hashAlgorithm, PROVIDER_ID);
+        generator.initSign(pgpSignatureType, signingKey);
+        final GeneratorOutputStream stream = new GeneratorOutputStream(generator);
+        content.write(stream);
+        stream.close();
+        final PGPSignature signature = generator.generate();
+        final BCOpenPGPSignatureStreamer result = new BCOpenPGPSignatureStreamer(signature);
+        return result;
+    }
+
+    public OpenPGPSignatureType getSignatureType() {
+        return signatureType;
+    }
+
+    public int getBCKeyAlgorithm() {
+        return hashAlgorithm;
+    }
+}

Added: james/server/sandbox/rfc3156/src/java/org/apache/james/security/openpgp/bc/BCOpenPGPSignatureStreamer.java
URL: http://svn.apache.org/viewvc/james/server/sandbox/rfc3156/src/java/org/apache/james/security/openpgp/bc/BCOpenPGPSignatureStreamer.java?view=auto&rev=494577
==============================================================================
--- james/server/sandbox/rfc3156/src/java/org/apache/james/security/openpgp/bc/BCOpenPGPSignatureStreamer.java (added)
+++ james/server/sandbox/rfc3156/src/java/org/apache/james/security/openpgp/bc/BCOpenPGPSignatureStreamer.java Tue Jan  9 13:08:11 2007
@@ -0,0 +1,50 @@
+/****************************************************************
+ * 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.james.security.openpgp.bc;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import org.apache.james.security.openpgp.OpenPGPStreamer;
+import org.bouncycastle.bcpg.ArmoredOutputStream;
+import org.bouncycastle.bcpg.BCPGOutputStream;
+import org.bouncycastle.openpgp.PGPSignature;
+
+/**
+ * Writes a signature for the content using BouncyCastle.
+ *
+ */
+public class BCOpenPGPSignatureStreamer implements OpenPGPStreamer {
+
+    private final PGPSignature signature;
+    
+    public BCOpenPGPSignatureStreamer(final PGPSignature signature) {
+        this.signature = signature;
+    }
+    
+    public void writeOpenPGPContent(OutputStream out) throws IOException {
+        final ArmoredOutputStream armoredOut = new ArmoredOutputStream(out);
+        final BCPGOutputStream pgOut = new BCPGOutputStream(armoredOut);
+        signature.encode(pgOut);
+        pgOut.close();
+        armoredOut.close();
+    }
+
+}

Added: james/server/sandbox/rfc3156/src/java/org/apache/james/security/openpgp/bc/GeneratorOutputStream.java
URL: http://svn.apache.org/viewvc/james/server/sandbox/rfc3156/src/java/org/apache/james/security/openpgp/bc/GeneratorOutputStream.java?view=auto&rev=494577
==============================================================================
--- james/server/sandbox/rfc3156/src/java/org/apache/james/security/openpgp/bc/GeneratorOutputStream.java (added)
+++ james/server/sandbox/rfc3156/src/java/org/apache/james/security/openpgp/bc/GeneratorOutputStream.java Tue Jan  9 13:08:11 2007
@@ -0,0 +1,49 @@
+/****************************************************************
+ * 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.james.security.openpgp.bc;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.security.SignatureException;
+
+import org.bouncycastle.openpgp.PGPSignatureGenerator;
+
+/**
+ * Uses output to update signature.
+ *
+ */
+class GeneratorOutputStream extends OutputStream {
+
+    private final PGPSignatureGenerator generator;
+       
+    public GeneratorOutputStream(final PGPSignatureGenerator generator) {
+        super();
+        this.generator = generator;
+    }
+
+    public void write(int b) throws IOException {
+        try {
+            generator.update((byte) b);
+        } catch (SignatureException e) {
+            throw new SignatureFailureException(e);
+        }
+    }
+
+}

Added: james/server/sandbox/rfc3156/src/java/org/apache/james/security/openpgp/bc/SignatureFailureException.java
URL: http://svn.apache.org/viewvc/james/server/sandbox/rfc3156/src/java/org/apache/james/security/openpgp/bc/SignatureFailureException.java?view=auto&rev=494577
==============================================================================
--- james/server/sandbox/rfc3156/src/java/org/apache/james/security/openpgp/bc/SignatureFailureException.java (added)
+++ james/server/sandbox/rfc3156/src/java/org/apache/james/security/openpgp/bc/SignatureFailureException.java Tue Jan  9 13:08:11 2007
@@ -0,0 +1,43 @@
+/****************************************************************
+ * 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.james.security.openpgp.bc;
+
+import java.io.IOException;
+import java.security.SignatureException;
+
+/**
+ * Adapts a {@link SignatureException} to an {@link IOException}.
+ *
+ */
+class SignatureFailureException extends IOException {
+
+    private static final long serialVersionUID = 1897641750746256833L;
+
+    private final SignatureException cause;
+    
+    public SignatureFailureException(SignatureException e) {
+        super(e.getMessage());
+        cause = e;
+    }
+    
+    public Throwable getCause() {
+        return cause;
+    }
+}

Added: james/server/sandbox/rfc3156/src/java/org/apache/james/util/mail/handlers/pgp_signature.java
URL: http://svn.apache.org/viewvc/james/server/sandbox/rfc3156/src/java/org/apache/james/util/mail/handlers/pgp_signature.java?view=auto&rev=494577
==============================================================================
--- james/server/sandbox/rfc3156/src/java/org/apache/james/util/mail/handlers/pgp_signature.java (added)
+++ james/server/sandbox/rfc3156/src/java/org/apache/james/util/mail/handlers/pgp_signature.java Tue Jan  9 13:08:11 2007
@@ -0,0 +1,78 @@
+/****************************************************************
+ * 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.james.util.mail.handlers;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import javax.activation.ActivationDataFlavor;
+import javax.activation.DataSource;
+import javax.mail.MessagingException;
+
+import org.apache.james.security.openpgp.OpenPGPMIMEConstants;
+import org.apache.james.security.openpgp.OpenPGPStreamer;
+
+/**
+ * <p>Handles OpenPGP/MIME signatures.</p>
+ * <p>
+ * Content for signatures should implement {@link OpenPGPStreamer}.
+ * </p>
+ * @see OpenPGPStreamer
+ */
+public class pgp_signature extends AbstractDataContentHandler {
+
+    private static final String DISPLAY_NAME = "RFC 3156 OpenPGP/MIME Signature";
+
+    protected Object computeContent(DataSource aDataSource)
+    throws MessagingException {
+        // TODO perhaps return a wrapper object implementing an 
+        // org.apache.james.security.openpgp interface suitable for signing
+        return null;
+    }
+
+    /**
+     * Computes the data flavor.
+     * @return <code>application/pgp-signature</code?
+     */
+    protected ActivationDataFlavor computeDataFlavor() {
+        final ActivationDataFlavor result 
+        = new ActivationDataFlavor(pgp_signature.class, 
+                OpenPGPMIMEConstants.MIME_TYPE_OPENPGP_SIGNATURE, DISPLAY_NAME);
+        return result;
+    }
+
+    public void writeTo(Object part, String mimeType, OutputStream out)
+    throws IOException {
+        if (OpenPGPMIMEConstants.MIME_TYPE_OPENPGP_SIGNATURE.equals(mimeType))
+        {
+            if (part instanceof OpenPGPStreamer) {
+                OpenPGPStreamer streamer = (OpenPGPStreamer) part;
+                streamer.writeOpenPGPContent(out);
+            } else {
+                throw new IOException("Type \"" + part.getClass().getName()
+                        + "\" is not supported.");
+            }
+        }
+        else {
+            throw new IOException("MIME type \"" + mimeType + "\" is not supported.");
+        }
+    }
+
+}

Modified: james/server/sandbox/rfc3156/src/test/org/apache/james/mailboxmanager/TestUtil.java
URL: http://svn.apache.org/viewvc/james/server/sandbox/rfc3156/src/test/org/apache/james/mailboxmanager/TestUtil.java?view=diff&rev=494577&r1=494576&r2=494577
==============================================================================
--- james/server/sandbox/rfc3156/src/test/org/apache/james/mailboxmanager/TestUtil.java (original)
+++ james/server/sandbox/rfc3156/src/test/org/apache/james/mailboxmanager/TestUtil.java Tue Jan  9 13:08:11 2007
@@ -38,8 +38,8 @@
             for (int i=0; i< size; i++) {
                 if (b1[i]!=b2[i]) {
                     System.out.println("I: "+i+" B1: "+b1[i]+" B2 "+b2[i]);
-                    System.out.println("B1:"+new String(b1,0,i+1)+"°");
-                    System.out.println("B2:"+new String(b2,0,i+1)+"°");
+                    System.out.println("B1:"+new String(b1,0,i+1)+"??");
+                    System.out.println("B2:"+new String(b2,0,i+1)+"??");
                     break;
                 }
             }

Added: james/server/sandbox/rfc3156/src/test/org/apache/james/security/openpgp/MockOpenPGPSignatureGenerator.java
URL: http://svn.apache.org/viewvc/james/server/sandbox/rfc3156/src/test/org/apache/james/security/openpgp/MockOpenPGPSignatureGenerator.java?view=auto&rev=494577
==============================================================================
--- james/server/sandbox/rfc3156/src/test/org/apache/james/security/openpgp/MockOpenPGPSignatureGenerator.java (added)
+++ james/server/sandbox/rfc3156/src/test/org/apache/james/security/openpgp/MockOpenPGPSignatureGenerator.java Tue Jan  9 13:08:11 2007
@@ -0,0 +1,44 @@
+/****************************************************************
+ * 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.james.security.openpgp;
+
+public class MockOpenPGPSignatureGenerator implements OpenPGPSignatureFactory {
+
+    public OpenPGPSignatureType type;
+    
+    public OpenPGPStreamer streamer;
+    
+    public Writable content;
+    
+    public MockOpenPGPSignatureGenerator(OpenPGPSignatureType type) {
+        this.type = type;
+        streamer = new MockOpenPGPStreamer();
+    }
+    
+    public OpenPGPSignatureType getSignatureType() {
+        return type;
+    }
+
+    public OpenPGPStreamer createSignatureStreamer(Writable content) throws Exception {
+        this.content = content;
+        return streamer;
+    }
+
+}

Added: james/server/sandbox/rfc3156/src/test/org/apache/james/security/openpgp/MockOpenPGPStreamer.java
URL: http://svn.apache.org/viewvc/james/server/sandbox/rfc3156/src/test/org/apache/james/security/openpgp/MockOpenPGPStreamer.java?view=auto&rev=494577
==============================================================================
--- james/server/sandbox/rfc3156/src/test/org/apache/james/security/openpgp/MockOpenPGPStreamer.java (added)
+++ james/server/sandbox/rfc3156/src/test/org/apache/james/security/openpgp/MockOpenPGPStreamer.java Tue Jan  9 13:08:11 2007
@@ -0,0 +1,34 @@
+/****************************************************************
+ * 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.james.security.openpgp;
+
+import java.util.List;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayList;
+
+public class MockOpenPGPStreamer implements OpenPGPStreamer {
+    
+    public final List streams = new ArrayList();
+    
+    public void writeOpenPGPContent(OutputStream out) throws IOException {
+        streams.add(out);
+    }
+}

Added: james/server/sandbox/rfc3156/src/test/org/apache/james/security/openpgp/OpenPGPMIMEGeneratorTest.java
URL: http://svn.apache.org/viewvc/james/server/sandbox/rfc3156/src/test/org/apache/james/security/openpgp/OpenPGPMIMEGeneratorTest.java?view=auto&rev=494577
==============================================================================
--- james/server/sandbox/rfc3156/src/test/org/apache/james/security/openpgp/OpenPGPMIMEGeneratorTest.java (added)
+++ james/server/sandbox/rfc3156/src/test/org/apache/james/security/openpgp/OpenPGPMIMEGeneratorTest.java Tue Jan  9 13:08:11 2007
@@ -0,0 +1,101 @@
+/****************************************************************
+ * 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.james.security.openpgp;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.util.Arrays;
+
+import javax.mail.BodyPart;
+import javax.mail.internet.MimeBodyPart;
+import javax.mail.internet.MimeMultipart;
+
+import org.apache.james.security.openpgp.bc.BCTestHelper;
+
+import junit.framework.TestCase;
+
+public class OpenPGPMIMEGeneratorTest extends TestCase {
+
+    OpenPGPMIMEGenerator generator;
+    MockOpenPGPSignatureGenerator signatureGenerator;
+    
+    protected void setUp() throws Exception {
+        super.setUp();
+        signatureGenerator = new MockOpenPGPSignatureGenerator(OpenPGPSignatureType.PGP_MD5);
+        generator = new OpenPGPMIMEGenerator(signatureGenerator);
+    }
+
+
+
+    protected void tearDown() throws Exception {
+        super.tearDown();
+    }
+    
+    private MimeBodyPart createSimpleContent() throws Exception {
+        final MimeBodyPart mimeBodyPart = new MimeBodyPart();
+        mimeBodyPart.attachFile(new File("src/test/org/apache/james/security/openpgp/simple-message.txt"));
+        return mimeBodyPart;
+    }
+
+    public void testRFC3156RequiredHeadersMessage() throws Exception {
+        MimeBodyPart content = createSimpleContent();
+        MimeMultipart message = generator.generateSignedMessage(content);
+        assertNotNull("Multipart message should be generated", message);
+        String[] contentTypeParts = message.getContentType().split(";");
+        for (int i=0;i<contentTypeParts.length;i++) {
+            contentTypeParts[i] = contentTypeParts[i].trim();
+        }
+        Arrays.sort(contentTypeParts);
+        assertEquals("Expect four required parts", 4, contentTypeParts.length);
+        assertEquals("Content type is multipart/signed", "multipart/signed",contentTypeParts[2]);
+        assertEquals("Message Integriry Check description is present and correct", 
+                "micalg=pgp-md5",contentTypeParts[1]);        
+        assertEquals("protocol is present and correct", "protocol=\"application/pgp-signature\"",contentTypeParts[3]);
+    }
+    
+    public void testContentPartBasics() throws Exception {
+        MimeBodyPart content = createSimpleContent();
+        MimeMultipart message = generator.generateSignedMessage(content);
+        assertNotNull("Multipart message should be generated", message);
+        assertEquals("Expect signature and content parts", 2, message.getCount());
+        BodyPart contentPart = message.getBodyPart(0);
+        assertTrue("Content should be MIME encoded", contentPart instanceof MimeBodyPart);
+        MimeBodyPart mimeContent = (MimeBodyPart) contentPart;
+        assertEquals("Same as the contents of the file", 
+                "This is a simple message.", mimeContent.getContent());
+        assertEquals("text/plain",mimeContent.getContentType());
+    }
+     
+
+    public void testSignaturePartHeaders() throws Exception {
+        MimeBodyPart content = createSimpleContent();
+        MimeMultipart message = generator.generateSignedMessage(content);
+        assertNotNull("Multipart message should be generated", message);
+        assertEquals("Expect signature and content parts", 2, message.getCount());
+        BodyPart contentPart = message.getBodyPart(1);
+        assertTrue("Content should be MIME encoded", contentPart instanceof MimeBodyPart);
+        MimeBodyPart mimeContent = (MimeBodyPart) contentPart;
+        assertEquals("Content type present and correct", 
+                "application/pgp-signature; name=" + OpenPGPMIMEGenerator.DEFAULT_SIGNATURE_FILE_NAME, 
+                mimeContent.getContentType());
+        assertEquals("Content is streamer since no mailcap registered", 
+                signatureGenerator.streamer, mimeContent.getContent());
+    }
+}

Added: james/server/sandbox/rfc3156/src/test/org/apache/james/security/openpgp/WritableContentTest.java
URL: http://svn.apache.org/viewvc/james/server/sandbox/rfc3156/src/test/org/apache/james/security/openpgp/WritableContentTest.java?view=auto&rev=494577
==============================================================================
--- james/server/sandbox/rfc3156/src/test/org/apache/james/security/openpgp/WritableContentTest.java (added)
+++ james/server/sandbox/rfc3156/src/test/org/apache/james/security/openpgp/WritableContentTest.java Tue Jan  9 13:08:11 2007
@@ -0,0 +1,64 @@
+/****************************************************************
+ * 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.james.security.openpgp;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+
+import javax.mail.internet.MimeBodyPart;
+
+
+import junit.framework.TestCase;
+
+public class WritableContentTest extends TestCase {
+    
+    private static final String CONTENT = 
+            "Content-Type: text/plain; charset=us-ascii\r\n" +
+            "Far from the madding Crowd's ignoble Strife,\r\n" +
+            "Their sober Wishes never learn'd to stray;\r\n" +
+            "Along the cool sequester'd Vale of Life\r\n" +
+            "They ket the noiseless Tenor of their Way.\r\n" +
+            "Thomas Grey, 1716-1771\r\n\r\n"; // Note: Adopting OpenGPG convention 
+                                              // ensuring JavaMail does not insert
+                                              // extra CRLF
+    private static final byte[] CONTENT_BYTES = OpenPGPUtils.toBytes(CONTENT);
+    
+    OpenPGPMIMEGenerator generator;
+    MockOpenPGPSignatureGenerator signatureGenerator;
+    
+    protected void setUp() throws Exception {
+        super.setUp();
+        signatureGenerator = new MockOpenPGPSignatureGenerator(OpenPGPSignatureType.PGP_MD5);
+        generator = new OpenPGPMIMEGenerator(signatureGenerator);
+    }
+
+    public void testWriteContent() throws Exception {
+        ByteArrayInputStream in = new ByteArrayInputStream(CONTENT_BYTES);
+        MimeBodyPart content = new MimeBodyPart(in);
+        generator.generateSignedMessage(content);
+        Writable writable = signatureGenerator.content;
+        assertNotNull("Writable content should be set on generator", writable);
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        writable.write(out);
+        byte[] output = out.toByteArray();
+        String contentAsString = OpenPGPUtils.toString(output);
+        assertEquals("Content set by generator", CONTENT, contentAsString);
+    }
+}

Added: james/server/sandbox/rfc3156/src/test/org/apache/james/security/openpgp/bc/BCOpenPGPSignatureFactoryTest.java
URL: http://svn.apache.org/viewvc/james/server/sandbox/rfc3156/src/test/org/apache/james/security/openpgp/bc/BCOpenPGPSignatureFactoryTest.java?view=auto&rev=494577
==============================================================================
--- james/server/sandbox/rfc3156/src/test/org/apache/james/security/openpgp/bc/BCOpenPGPSignatureFactoryTest.java (added)
+++ james/server/sandbox/rfc3156/src/test/org/apache/james/security/openpgp/bc/BCOpenPGPSignatureFactoryTest.java Tue Jan  9 13:08:11 2007
@@ -0,0 +1,114 @@
+/****************************************************************
+ * 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.james.security.openpgp.bc;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+
+import org.apache.james.security.openpgp.OpenPGPSignatureType;
+import org.apache.james.security.openpgp.OpenPGPStreamer;
+import org.bouncycastle.openpgp.PGPSignature;
+import org.bouncycastle.openpgp.PGPUtil;
+
+import junit.framework.TestCase;
+
+public class BCOpenPGPSignatureFactoryTest extends TestCase {
+
+    OpenPGPSignatureType signatureType = OpenPGPSignatureType.PGP_SHA1;
+    BCOpenPGPSignatureFactory factory;
+    
+    protected void setUp() throws Exception {
+        super.setUp();
+        factory = new BCOpenPGPSignatureFactory(
+                BCTestHelper.loadStandardPGPSecretKey(), signatureType, 
+                BCTestHelper.password(), false);    
+        // Note since data is NOT CANONICAL must use binary algorithm
+    }
+
+    protected void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    public void testCreateSignatureStreamer() throws Exception {
+        final String document = "src/test/org/apache/james/security/openpgp/bc/message.txt";     
+        OpenPGPStreamer streamer = factory.createSignatureStreamer(new WritableFileContent(document));
+        assertNotNull("Factory should either return a streamer or throw an exception", 
+                streamer);
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        streamer.writeOpenPGPContent(out);
+        String asc = out.toString("ASCII");
+        
+        boolean success = BCTestHelper.isValidSignature(asc, new File(document));
+        assertTrue("Expected signature to be verified by GNU PG", success);
+    }
+
+    public void testGetSignatureType() {
+        assertEquals("Signature is set at construction", signatureType, 
+                factory.getSignatureType());
+    }
+
+    public void testSHA1HashAlgorithm() throws Exception {
+        factory = new BCOpenPGPSignatureFactory(
+                BCTestHelper.loadStandardPGPSecretKey(), OpenPGPSignatureType.PGP_SHA1, 
+                BCTestHelper.password(), false);
+        assertEquals("BC hash algorithm is derived from signature type", 
+                PGPUtil.SHA1, factory.getBCKeyAlgorithm());
+    }
+    
+    public void testRipeHashAlgorithm() throws Exception {
+        factory = new BCOpenPGPSignatureFactory(
+                BCTestHelper.loadStandardPGPSecretKey(), OpenPGPSignatureType.PGP_RIPE_MD_160, 
+                BCTestHelper.password(), false);
+        assertEquals("BC hash algorithm is derived from signature type", 
+                PGPUtil.RIPEMD160, factory.getBCKeyAlgorithm());
+    }
+    
+    public void testHavelHashAlgorithm() throws Exception {
+        factory = new BCOpenPGPSignatureFactory(
+                BCTestHelper.loadStandardPGPSecretKey(), OpenPGPSignatureType.PGP_HAVEL_5_160, 
+                BCTestHelper.password(), false);
+        assertEquals("BC hash algorithm is derived from signature type", 
+                PGPUtil.HAVAL_5_160, factory.getBCKeyAlgorithm());
+    }
+    
+    public void testTiger192HashAlgorithm() throws Exception {
+        factory = new BCOpenPGPSignatureFactory(
+                BCTestHelper.loadStandardPGPSecretKey(), OpenPGPSignatureType.PGP_TIGER_192, 
+                BCTestHelper.password(), false);
+        assertEquals("BC hash algorithm is derived from signature type", 
+                PGPUtil.TIGER_192, factory.getBCKeyAlgorithm());
+    }
+    
+    public void testMD2HashAlgorithm() throws Exception {
+        factory = new BCOpenPGPSignatureFactory(
+                BCTestHelper.loadStandardPGPSecretKey(), OpenPGPSignatureType.PGP_MD2, 
+                BCTestHelper.password(), false);
+        assertEquals("BC hash algorithm is derived from signature type", 
+                PGPUtil.MD2, factory.getBCKeyAlgorithm());
+    }
+    
+    public void testMD5HashAlgorithm() throws Exception {
+        factory = new BCOpenPGPSignatureFactory(
+                BCTestHelper.loadStandardPGPSecretKey(), OpenPGPSignatureType.PGP_MD5, 
+                BCTestHelper.password(), false);
+        assertEquals("BC hash algorithm is derived from signature type", 
+                PGPUtil.MD5, factory.getBCKeyAlgorithm());
+    }
+}

Added: james/server/sandbox/rfc3156/src/test/org/apache/james/security/openpgp/bc/BCOpenPGPSignatureStreamerTest.java
URL: http://svn.apache.org/viewvc/james/server/sandbox/rfc3156/src/test/org/apache/james/security/openpgp/bc/BCOpenPGPSignatureStreamerTest.java?view=auto&rev=494577
==============================================================================
--- james/server/sandbox/rfc3156/src/test/org/apache/james/security/openpgp/bc/BCOpenPGPSignatureStreamerTest.java (added)
+++ james/server/sandbox/rfc3156/src/test/org/apache/james/security/openpgp/bc/BCOpenPGPSignatureStreamerTest.java Tue Jan  9 13:08:11 2007
@@ -0,0 +1,63 @@
+/****************************************************************
+ * 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.james.security.openpgp.bc;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+
+import junit.framework.TestCase;
+
+import org.bouncycastle.openpgp.PGPSignature;
+
+/**
+ * There are issues testing OpenPGP cryptographic. Various
+ * additional components are included together with the
+ * document in the hash. This includes a timestamp for the
+ * signature. This means that simple string comparisions
+ * cannot be used.
+ *
+ */
+public class BCOpenPGPSignatureStreamerTest extends TestCase {
+
+    
+    BCOpenPGPSignatureStreamer streamer;
+
+    protected void setUp() throws Exception {
+        super.setUp();
+        
+    }
+
+    protected void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    public void testWriteOpenPGPContent() throws Exception {
+        final String document = "src/test/org/apache/james/security/openpgp/bc/message.txt";
+        PGPSignature signature = BCTestHelper.createSignature(document);
+        streamer = new BCOpenPGPSignatureStreamer(signature);
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        streamer.writeOpenPGPContent(out);
+        String asc = out.toString("ASCII");
+        
+        boolean success = BCTestHelper.isValidSignature(asc, new File(document));
+        assertTrue("Expected signature to be verified by GNU PG", success);
+    }
+
+}

Added: james/server/sandbox/rfc3156/src/test/org/apache/james/security/openpgp/bc/BCTestHelper.java
URL: http://svn.apache.org/viewvc/james/server/sandbox/rfc3156/src/test/org/apache/james/security/openpgp/bc/BCTestHelper.java?view=auto&rev=494577
==============================================================================
--- james/server/sandbox/rfc3156/src/test/org/apache/james/security/openpgp/bc/BCTestHelper.java (added)
+++ james/server/sandbox/rfc3156/src/test/org/apache/james/security/openpgp/bc/BCTestHelper.java Tue Jan  9 13:08:11 2007
@@ -0,0 +1,133 @@
+/****************************************************************
+ * 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.james.security.openpgp.bc;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.security.Security;
+
+import javax.activation.CommandMap;
+import javax.activation.MailcapCommandMap;
+
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.bouncycastle.openpgp.PGPPrivateKey;
+import org.bouncycastle.openpgp.PGPSecretKey;
+import org.bouncycastle.openpgp.PGPSecretKeyRingCollection;
+import org.bouncycastle.openpgp.PGPSignature;
+import org.bouncycastle.openpgp.PGPSignatureGenerator;
+import org.bouncycastle.openpgp.PGPUtil;
+
+public class BCTestHelper {
+    
+    public static final void registerDataHandlers() throws Exception {
+          MailcapCommandMap commandMap = (MailcapCommandMap) CommandMap.getDefaultCommandMap();
+          commandMap.addMailcap("application/pgp-signature;; org.apache.james.util.mail.handlers.pgp_signature");
+    }
+    
+    public static final PGPSecretKey loadStandardPGPSecretKey() throws Exception {
+        if (Security.getProvider("BC") == null) {
+            Security.addProvider(new BouncyCastleProvider());
+        }
+        InputStream in = PGPUtil.getDecoderStream(new BufferedInputStream(
+                new FileInputStream("src/test/org/apache/james/security/openpgp/bc/secring.gpg")));
+        PGPSecretKeyRingCollection rings = new PGPSecretKeyRingCollection(in);
+        PGPSecretKey result = rings.getSecretKey(8203466815430217482l);
+        return result;
+    }
+    
+    public static final PGPPrivateKey loadStandardPGPPrivateKey() throws Exception {
+        PGPSecretKey secretKey = loadStandardPGPSecretKey();
+        PGPPrivateKey result = secretKey.extractPrivateKey(password(), "BC");
+        return result;
+    }
+
+    public static char[] password() {
+        return "password".toCharArray();
+    }
+    
+    public static final PGPSignature createSignature(String fileName) throws Exception {
+        PGPSecretKey secretKey = loadStandardPGPSecretKey();
+        PGPPrivateKey privateKey = secretKey.extractPrivateKey(password(), "BC");
+        PGPSignatureGenerator generator = new PGPSignatureGenerator(secretKey.getPublicKey().getAlgorithm(),
+                PGPUtil.SHA1, "BC");
+        generator.initSign(PGPSignature.BINARY_DOCUMENT, privateKey);
+        File file = new File(fileName);
+        FileInputStream in = new FileInputStream(file);
+        int nextByte = in.read();
+        while(nextByte >= 0) {
+            generator.update((byte) nextByte);
+            nextByte = in.read();
+        }
+        PGPSignature result = generator.generate();
+        return result;
+    }
+    
+
+    public static final boolean isValidSignature(String signature, File document) throws IOException, InterruptedException {
+        File file = File.createTempFile("james", "asc");
+        try
+        {
+            FileWriter writer = new FileWriter(file);
+            writer.write(signature);
+            writer.close();
+            
+            File home = new File("src/test/org/apache/james/security/openpgp/bc");
+            
+            final String command = "gpg --homedir " 
+                + home.getAbsolutePath() + " --verify " + file.getAbsolutePath() + " " + document.getAbsolutePath();
+            boolean result = true;
+            Process process = null;
+            try {
+                process = Runtime.getRuntime().exec(command);
+            } catch (IOException e) {
+                System.out.println("This test requires Gnu Privacy Guard. Ignoring test.");
+            }
+            if (process != null) {
+                result = interpretResults(process);
+            }
+            return result;
+        } finally {
+            file.delete();
+        }
+    }
+
+    private static boolean interpretResults(Process process) throws InterruptedException, IOException {
+        final int exitValue = process.waitFor();
+        final boolean success = exitValue == 0;
+        if (!success)
+        {
+            System.out.println("FAILURE");
+            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
+            String line = reader.readLine();
+            while(line != null) {
+                System.out.println(line);
+                line = reader.readLine();
+            }
+        }
+        return success;
+    }
+
+}

Added: james/server/sandbox/rfc3156/src/test/org/apache/james/security/openpgp/bc/WritableFileContent.java
URL: http://svn.apache.org/viewvc/james/server/sandbox/rfc3156/src/test/org/apache/james/security/openpgp/bc/WritableFileContent.java?view=auto&rev=494577
==============================================================================
--- james/server/sandbox/rfc3156/src/test/org/apache/james/security/openpgp/bc/WritableFileContent.java (added)
+++ james/server/sandbox/rfc3156/src/test/org/apache/james/security/openpgp/bc/WritableFileContent.java Tue Jan  9 13:08:11 2007
@@ -0,0 +1,50 @@
+/****************************************************************
+ * 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.james.security.openpgp.bc;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.OutputStream;
+
+import org.apache.james.security.openpgp.Writable;
+
+public class WritableFileContent implements Writable {
+
+    private final File file;
+    
+    public WritableFileContent(String fileName) throws Exception {
+        this(new File(fileName));
+    }
+        
+    public WritableFileContent(final File file) {
+        super();
+        this.file = file;
+    }
+
+    public void write(OutputStream out) throws Exception {
+        FileInputStream in = new FileInputStream(file);
+        int nextByte = in.read();
+        while(nextByte >= 0) {
+            out.write(nextByte);
+            nextByte = in.read();
+        }
+    }
+
+}

Added: james/server/sandbox/rfc3156/src/test/org/apache/james/security/openpgp/bc/message.txt
URL: http://svn.apache.org/viewvc/james/server/sandbox/rfc3156/src/test/org/apache/james/security/openpgp/bc/message.txt?view=auto&rev=494577
==============================================================================
--- james/server/sandbox/rfc3156/src/test/org/apache/james/security/openpgp/bc/message.txt (added)
+++ james/server/sandbox/rfc3156/src/test/org/apache/james/security/openpgp/bc/message.txt Tue Jan  9 13:08:11 2007
@@ -0,0 +1 @@
+This is a basic test message. 
\ No newline at end of file

Added: james/server/sandbox/rfc3156/src/test/org/apache/james/security/openpgp/bc/pubring.gpg
URL: http://svn.apache.org/viewvc/james/server/sandbox/rfc3156/src/test/org/apache/james/security/openpgp/bc/pubring.gpg?view=auto&rev=494577
==============================================================================
Binary file - no diff available.

Propchange: james/server/sandbox/rfc3156/src/test/org/apache/james/security/openpgp/bc/pubring.gpg
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: james/server/sandbox/rfc3156/src/test/org/apache/james/security/openpgp/bc/random_seed
URL: http://svn.apache.org/viewvc/james/server/sandbox/rfc3156/src/test/org/apache/james/security/openpgp/bc/random_seed?view=auto&rev=494577
==============================================================================
Binary file - no diff available.

Propchange: james/server/sandbox/rfc3156/src/test/org/apache/james/security/openpgp/bc/random_seed
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: james/server/sandbox/rfc3156/src/test/org/apache/james/security/openpgp/bc/secring.gpg
URL: http://svn.apache.org/viewvc/james/server/sandbox/rfc3156/src/test/org/apache/james/security/openpgp/bc/secring.gpg?view=auto&rev=494577
==============================================================================
Binary file - no diff available.

Propchange: james/server/sandbox/rfc3156/src/test/org/apache/james/security/openpgp/bc/secring.gpg
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: james/server/sandbox/rfc3156/src/test/org/apache/james/security/openpgp/bc/trustdb.gpg
URL: http://svn.apache.org/viewvc/james/server/sandbox/rfc3156/src/test/org/apache/james/security/openpgp/bc/trustdb.gpg?view=auto&rev=494577
==============================================================================
Binary file - no diff available.

Propchange: james/server/sandbox/rfc3156/src/test/org/apache/james/security/openpgp/bc/trustdb.gpg
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream



---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org