Author: vincenzo Date: Wed Sep 6 05:34:29 2006 New Revision: 440702 URL: http://svn.apache.org/viewvc?view=rev&rev=440702 Log: Begin of JAMES-596 (Reorganize SMIME crypto support code to share it with future new PGP support code).
Added: james/server/trunk/src/java/org/apache/james/security/KeyHolder.java (with props) james/server/trunk/src/java/org/apache/james/security/SMIMEKeyHolder.java - copied, changed from r432829, james/server/trunk/src/java/org/apache/james/security/KeyHolder.java james/server/trunk/src/java/org/apache/james/transport/mailets/smime/AbstractSign.java - copied, changed from r432829, james/server/trunk/src/java/org/apache/james/transport/mailets/smime/SMIMEAbstractSign.java james/server/trunk/src/java/org/apache/james/transport/mailets/smime/SMIMESign.java (with props) james/server/trunk/src/java/org/apache/james/transport/mailets/smime/Sign.java - copied, changed from r432829, james/server/trunk/src/java/org/apache/james/transport/mailets/smime/SMIMESign.java Removed: james/server/trunk/src/java/org/apache/james/transport/mailets/smime/SMIMEAbstractSign.java Modified: james/server/trunk/src/java/org/apache/james/transport/mailets/smime/SMIMEDecrypt.java Added: james/server/trunk/src/java/org/apache/james/security/KeyHolder.java URL: http://svn.apache.org/viewvc/james/server/trunk/src/java/org/apache/james/security/KeyHolder.java?view=auto&rev=440702 ============================================================================== --- james/server/trunk/src/java/org/apache/james/security/KeyHolder.java (added) +++ james/server/trunk/src/java/org/apache/james/security/KeyHolder.java Wed Sep 6 05:34:29 2006 @@ -0,0 +1,70 @@ +/**************************************************************** + * 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; + +import javax.mail.internet.MimeBodyPart; +import javax.mail.internet.MimeMessage; +import javax.mail.internet.MimeMultipart; + +/** + * <p>Loads a [EMAIL PROTECTED] java.security.KeyStore} in memory and keeps it ready for the + * cryptographic activity.</p> + * <p>It has the role of being a simpler intermediate to the crypto libraries. + * Uses specifically the <a href="http://www.bouncycastle.org/">Legion of the Bouncy Castle</a> + * libraries, particularly for the SMIME activity.</p> + * @version CVS $Revision:$ $Date:$ + * @since 3.0 + */ +public interface KeyHolder { + + /** + * Generates a signed MimeMultipart from a MimeMessage. + * @param message The message to sign. + * @return The signed <CODE>MimeMultipart</CODE>. + */ + public MimeMultipart generate(MimeMessage message) throws Exception; + + /** + * Generates a signed MimeMultipart from a MimeBodyPart. + * @param content The content to sign. + * @return The signed <CODE>MimeMultipart</CODE>. + */ + public MimeMultipart generate(MimeBodyPart content) throws Exception; + + /** + * Getter for property signerDistinguishedName. + * @return Value of property signerDistinguishedName. + */ + public String getSignerDistinguishedName(); + + /** + * Getter for property signerCN. + * @return Value of property signerCN. + */ + public String getSignerCN(); + + /** + * Getter for property signerAddress. + * @return Value of property signerMailAddress. + */ + public String getSignerAddress(); + +} Propchange: james/server/trunk/src/java/org/apache/james/security/KeyHolder.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: james/server/trunk/src/java/org/apache/james/security/KeyHolder.java ------------------------------------------------------------------------------ svn:keywords = Author Date Id Revision Copied: james/server/trunk/src/java/org/apache/james/security/SMIMEKeyHolder.java (from r432829, james/server/trunk/src/java/org/apache/james/security/KeyHolder.java) URL: http://svn.apache.org/viewvc/james/server/trunk/src/java/org/apache/james/security/SMIMEKeyHolder.java?view=diff&rev=440702&p1=james/server/trunk/src/java/org/apache/james/security/KeyHolder.java&r1=432829&p2=james/server/trunk/src/java/org/apache/james/security/SMIMEKeyHolder.java&r2=440702 ============================================================================== --- james/server/trunk/src/java/org/apache/james/security/KeyHolder.java (original) +++ james/server/trunk/src/java/org/apache/james/security/SMIMEKeyHolder.java Wed Sep 6 05:34:29 2006 @@ -53,10 +53,10 @@ * <p>It has the role of being a simpler intermediate to the crypto libraries. * Uses specifically the <a href="http://www.bouncycastle.org/">Legion of the Bouncy Castle</a> * libraries, particularly for the SMIME activity.</p> - * @version CVS $Revision$ $Date$ - * @since 2.2.1 + * @version CVS $Revision:$ $Date:$ + * @since 3.0 */ -public class KeyHolder { +public class SMIMEKeyHolder implements KeyHolder{ /** * Returns the default keystore type as specified in the Java security properties file, @@ -83,7 +83,7 @@ private CertStore certStore; /** Creates a new instance of KeyHolder */ - private KeyHolder() { + private SMIMEKeyHolder() { } /** @@ -107,7 +107,7 @@ * @see java.security.KeyStore#getKey * @see java.security.KeyStore#getCertificate */ - public KeyHolder(String keyStoreFileName, String keyStorePassword, String keyAlias, String keyAliasPassword, String keyStoreType) + public SMIMEKeyHolder(String keyStoreFileName, String keyStorePassword, String keyAlias, String keyAliasPassword, String keyStoreType) throws KeyStoreException, FileNotFoundException, IOException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, CertificateException, UnrecoverableKeyException, NoSuchProviderException { Copied: james/server/trunk/src/java/org/apache/james/transport/mailets/smime/AbstractSign.java (from r432829, james/server/trunk/src/java/org/apache/james/transport/mailets/smime/SMIMEAbstractSign.java) URL: http://svn.apache.org/viewvc/james/server/trunk/src/java/org/apache/james/transport/mailets/smime/AbstractSign.java?view=diff&rev=440702&p1=james/server/trunk/src/java/org/apache/james/transport/mailets/smime/SMIMEAbstractSign.java&r1=432829&p2=james/server/trunk/src/java/org/apache/james/transport/mailets/smime/AbstractSign.java&r2=440702 ============================================================================== --- james/server/trunk/src/java/org/apache/james/transport/mailets/smime/SMIMEAbstractSign.java (original) +++ james/server/trunk/src/java/org/apache/james/transport/mailets/smime/AbstractSign.java Wed Sep 6 05:34:29 2006 @@ -38,6 +38,7 @@ import java.io.IOException; import java.util.Enumeration; +import java.lang.reflect.Constructor; /** * <P>Abstract mailet providing common SMIME signature services.<BR> @@ -65,6 +66,8 @@ * * <P>Handles the following init parameters:</P> * <ul> + * <li><keyHolderClass>: Sets the class of the KeyHolder object that will handle the cryptography functions, + * for example org.apache.james.security.SMIMEKeyHolder for SMIME.</li> * <li><debug>: if <CODE>true</CODE> some useful information is logged. * The default is <CODE>false</CODE>.</li> * <li><keyStoreFileName>: the [EMAIL PROTECTED] java.security.KeyStore} full file name.</li> @@ -95,7 +98,7 @@ * @version CVS $Revision$ $Date$ * @since 2.2.1 */ -public abstract class SMIMEAbstractSign extends GenericMailet { +public abstract class AbstractSign extends GenericMailet { private static final String HEADERS_PATTERN = "[headers]"; @@ -111,6 +114,11 @@ private boolean debug; /** + * Holds value of property keyHolderClass. + */ + private Class keyHolderClass; + + /** * Holds value of property explanationText. */ private String explanationText; @@ -169,6 +177,40 @@ } /** + * Initializer for property keyHolderClass. + */ + protected void initKeyHolderClass() throws MessagingException { + String keyHolderClassName = getInitParameter("keyHolderClass"); + if (keyHolderClassName == null) { + throw new MessagingException("<keyHolderClass> parameter missing."); + } + try { + setKeyHolderClass(Class.forName(keyHolderClassName)); + } catch (ClassNotFoundException cnfe) { + throw new MessagingException("The specified <keyHolderClass> does not exist: " + keyHolderClassName); + } + if (isDebug()) { + log("keyHolderClass: " + getKeyHolderClass()); + } + } + + /** + * Getter for property keyHolderClass. + * @return Value of property keyHolderClass. + */ + public Class getKeyHolderClass() { + return this.keyHolderClass; + } + + /** + * Setter for property keyHolderClass. + * @param signerName New value of property keyHolderClass. + */ + public void setKeyHolderClass(Class keyHolderClass) { + this.keyHolderClass = keyHolderClass; + } + + /** * Initializer for property explanationText. */ protected void initExplanationText() { @@ -199,6 +241,15 @@ * Initializer for property keyHolder. */ protected void initKeyHolder() throws Exception { + Constructor keyHolderConstructor = null; + try { + keyHolderConstructor = keyHolderClass.getConstructor(new Class[] {String.class, String.class, String.class, String.class, String.class}); + } catch (NoSuchMethodException nsme) { + throw new MessagingException("The needed constructor does not exist: " + + keyHolderClass + "(String, String, String, String, String)"); + } + + String keyStoreFileName = getInitParameter("keyStoreFileName"); if (keyStoreFileName == null) { throw new MessagingException("<keyStoreFileName> parameter missing."); @@ -219,7 +270,7 @@ String keyStoreType = getInitParameter("keyStoreType"); if (keyStoreType == null) { if (isDebug()) { - log("<type> parameter not specified: will default to \"" + KeyHolder.getDefaultType() + "\"."); + log("<keyStoreType> parameter not specified: the default will be as appropriate to the keyStore requested."); } } @@ -242,7 +293,8 @@ } // Certificate preparation - setKeyHolder(new KeyHolder(keyStoreFileName, keyStorePassword, keyAlias, keyAliasPassword, keyStoreType)); + String[] parameters = {keyStoreFileName, keyStorePassword, keyAlias, keyAliasPassword, keyStoreType}; + setKeyHolder((KeyHolder)keyHolderConstructor.newInstance(parameters)); if (isDebug()) { log("Subject Distinguished Name: " + getKeyHolder().getSignerDistinguishedName()); @@ -383,6 +435,7 @@ log("Initializing"); } + initKeyHolderClass(); initKeyHolder(); initSignerName(); initPostmasterSigns(); Modified: james/server/trunk/src/java/org/apache/james/transport/mailets/smime/SMIMEDecrypt.java URL: http://svn.apache.org/viewvc/james/server/trunk/src/java/org/apache/james/transport/mailets/smime/SMIMEDecrypt.java?view=diff&rev=440702&r1=440701&r2=440702 ============================================================================== --- james/server/trunk/src/java/org/apache/james/transport/mailets/smime/SMIMEDecrypt.java (original) +++ james/server/trunk/src/java/org/apache/james/transport/mailets/smime/SMIMEDecrypt.java Wed Sep 6 05:34:29 2006 @@ -33,7 +33,7 @@ import javax.mail.internet.MimeBodyPart; import javax.mail.internet.MimeMessage; -import org.apache.james.security.KeyHolder; +import org.apache.james.security.SMIMEKeyHolder; import org.apache.mailet.GenericMailet; import org.apache.mailet.Mail; import org.apache.mailet.MailetConfig; @@ -70,7 +70,7 @@ */ public class SMIMEDecrypt extends GenericMailet { - private KeyHolder keyHolder; + private SMIMEKeyHolder keyHolder; protected String mailAttribute = "org.apache.james.SMIMEDecrypt"; public void init() throws MessagingException { @@ -92,7 +92,7 @@ if (mailAttributeConf != null) mailAttribute = mailAttributeConf; try { - keyHolder = new KeyHolder(privateStoreFile, privateStorePass, keyAlias, keyPass, privateStoreType); + keyHolder = new SMIMEKeyHolder(privateStoreFile, privateStorePass, keyAlias, keyPass, privateStoreType); } catch (IOException e) { throw new MessagingException("Error loading keystore", e); } catch (GeneralSecurityException e) { Added: james/server/trunk/src/java/org/apache/james/transport/mailets/smime/SMIMESign.java URL: http://svn.apache.org/viewvc/james/server/trunk/src/java/org/apache/james/transport/mailets/smime/SMIMESign.java?view=auto&rev=440702 ============================================================================== --- james/server/trunk/src/java/org/apache/james/transport/mailets/smime/SMIMESign.java (added) +++ james/server/trunk/src/java/org/apache/james/transport/mailets/smime/SMIMESign.java Wed Sep 6 05:34:29 2006 @@ -0,0 +1,216 @@ +/**************************************************************** + * 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.transport.mailets.smime; + +import org.apache.mailet.Mail; + +import javax.mail.MessagingException; +import javax.mail.internet.MimeBodyPart; +import javax.mail.internet.MimeMessage; +import javax.mail.internet.MimeMultipart; + +import java.io.IOException; + +/** + * <p>Puts a <I>server-side</I> SMIME signature on a message.<br> + * It is a concrete subclass of [EMAIL PROTECTED] Sign}, with very few modifications to it, + * to specialize for SMIME.</p> + * + * <P>Handles the following init parameters (will comment only the differences from [EMAIL PROTECTED] SMIMEAbstractSign}):</P> + * <ul> + * <li><debug>.</li> + * <li><keyStoreFileName>.</li> + * <li><keyStorePassword>.</li> + * <li><keyAlias>.</li> + * <li><keyAliasPassword>.</li> + * <li><keyStoreType>.</li> + * <li><postmasterSigns>. The default is <CODE>true</CODE>.</li> + * <li><rebuildFrom>. The default is <CODE>true</CODE>.</li> + * <li><signerName>.</li> + * <li><explanationText>. There is a default explanation string template in English, + * displaying also all the headers of the original message (see [EMAIL PROTECTED] #getExplanationText}).</li> + * </ul> + * @version CVS $Revision:$ $Date:$ + * @since 2.3.0 + */ +public class SMIMESign extends Sign { + + /** + * Return a string describing this mailet. + * + * @return a string describing this mailet + */ + public String getMailetInfo() { + return "SMIME Signature Mailet"; + } + + /** + * + */ + protected String[] getAllowedInitParameters() { + String[] allowedArray = { + "debug", + "keyStoreFileName", + "keyStorePassword", + "keyStoreType", + "keyAlias", + "keyAliasPassword", + "signerName", + "postmasterSigns", + "rebuildFrom", + "explanationText" + }; + return allowedArray; + } + + /* ******************************************************************** */ + /* ****************** Begin of setters and getters ******************** */ + /* ******************************************************************** */ + + /** + * If the <CODE><explanationText></CODE> init parameter is missing + * returns the following default explanation template string: + * <pre><code> + * The message this file is attached to has been signed on the server by + * "[signerName]" <[signerAddress]> + * to certify that the sender is known and truly has the following address (reverse-path): + * [reversePath] + * and that the original message has the following message headers: + * + * [headers] + * + * The signature envelopes this attachment too. + * Please check the signature integrity. + * + * "[signerName]" <[signerAddress]> + * </code></pre> + */ + public String getExplanationText() { + String explanationText = super.getExplanationText(); + if (explanationText == null) { + explanationText = "The message this file is attached to has been signed on the server by\r\n" + + "\t\"[signerName]\" <[signerAddress]>" + + "\r\nto certify that the sender is known and truly has the following address (reverse-path):\r\n" + + "\t[reversePath]" + + "\r\nand that the original message has the following message headers:\r\n" + + "\r\n[headers]" + + "\r\n\r\nThe signature envelopes this attachment too." + + "\r\nPlease check the signature integrity." + + "\r\n\r\n" + + "\t\"[signerName]\" <[signerAddress]>"; + } + + return explanationText; + } + + /** + * Initializer for property keyHolderClass. + * Hardcodes it to [EMAIL PROTECTED] org.apache.james.security.SMIMEKeyHolder}. + */ + protected void initKeyHolderClass() throws MessagingException { + String keyHolderClassName = "org.apache.james.security.SMIMEKeyHolder"; + try { + setKeyHolderClass(Class.forName(keyHolderClassName)); + } catch (ClassNotFoundException cnfe) { + throw new MessagingException(keyHolderClassName + "does not exist."); + } + if (isDebug()) { + log("keyHolderClass: " + getKeyHolderClass()); + } + } + + /** + * If the <CODE><postmasterSigns></CODE> init parameter is missing sets it to <I>true</I>. + */ + protected void initPostmasterSigns() { + setPostmasterSigns((getInitParameter("postmasterSigns") == null) ? true : new Boolean(getInitParameter("postmasterSigns")).booleanValue()); + } + + /** + * If the <CODE><rebuildFrom></CODE> init parameter is missing sets it to <I>true</I>. + */ + protected void initRebuildFrom() throws MessagingException { + setRebuildFrom((getInitParameter("rebuildFrom") == null) ? true : new Boolean(getInitParameter("rebuildFrom")).booleanValue()); + if (isDebug()) { + if (isRebuildFrom()) { + log("Will modify the \"From:\" header."); + } else { + log("Will leave the \"From:\" header unchanged."); + } + } + } + + /* ******************************************************************** */ + /* ****************** End of setters and getters ********************** */ + /* ******************************************************************** */ + + /** + * A text file with the massaged contents of [EMAIL PROTECTED] #getExplanationText} + * is attached to the original message. + */ + protected MimeBodyPart getWrapperBodyPart(Mail mail) throws MessagingException, IOException { + + String explanationText = getExplanationText(); + + // if there is no explanation text there should be no wrapping + if (explanationText == null) { + return null; + } + + MimeMessage originalMessage = mail.getMessage(); + + MimeBodyPart messagePart = new MimeBodyPart(); + MimeBodyPart signatureReason = new MimeBodyPart(); + + String contentType = originalMessage.getContentType(); + Object content = originalMessage.getContent(); + + if (contentType != null && content != null) { + messagePart.setContent(content, contentType); + } else { + throw new MessagingException("Either the content type or the content is null"); + } + + String headers = getMessageHeaders(originalMessage); + + signatureReason.setText(getReplacedExplanationText(getExplanationText(), + getSignerName(), + getKeyHolder().getSignerAddress(), + mail.getSender().toString(), + headers)); + + signatureReason.setFileName("SignatureExplanation.txt"); + + MimeMultipart wrapperMultiPart = new MimeMultipart(); + + wrapperMultiPart.addBodyPart(messagePart); + wrapperMultiPart.addBodyPart(signatureReason); + + MimeBodyPart wrapperBodyPart = new MimeBodyPart(); + + wrapperBodyPart.setContent(wrapperMultiPart); + + return wrapperBodyPart; + } + +} + Propchange: james/server/trunk/src/java/org/apache/james/transport/mailets/smime/SMIMESign.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: james/server/trunk/src/java/org/apache/james/transport/mailets/smime/SMIMESign.java ------------------------------------------------------------------------------ svn:keywords = Author Date Id Revision Copied: james/server/trunk/src/java/org/apache/james/transport/mailets/smime/Sign.java (from r432829, james/server/trunk/src/java/org/apache/james/transport/mailets/smime/SMIMESign.java) URL: http://svn.apache.org/viewvc/james/server/trunk/src/java/org/apache/james/transport/mailets/smime/Sign.java?view=diff&rev=440702&p1=james/server/trunk/src/java/org/apache/james/transport/mailets/smime/SMIMESign.java&r1=432829&p2=james/server/trunk/src/java/org/apache/james/transport/mailets/smime/Sign.java&r2=440702 ============================================================================== --- james/server/trunk/src/java/org/apache/james/transport/mailets/smime/SMIMESign.java (original) +++ james/server/trunk/src/java/org/apache/james/transport/mailets/smime/Sign.java Wed Sep 6 05:34:29 2006 @@ -31,15 +31,18 @@ import java.io.IOException; /** - * <p>Puts a <I>server-side</I> SMIME signature on a message.<br> - * It is a concrete subclass of [EMAIL PROTECTED] SMIMEAbstractSign}, with very few modifications to it.</p> + * <p>Puts a <I>server-side</I> signature on a message.<br> + * It is a concrete subclass of [EMAIL PROTECTED] AbstractSign}, with very few modifications to it.</p> * <p>A text file with an explanation text is attached to the original message, * and the resulting message with all its attachments is signed. * The resulting appearence of the message is almost unchanged: only an extra attachment * and the signature are added.</p> + *<p>The kind of signuture depends on the value of the <keyHolderClass> init parameter. * * <P>Handles the following init parameters (will comment only the differences from [EMAIL PROTECTED] SMIMEAbstractSign}):</P> * <ul> + * <li><keyHolderClass>: Sets the class of the KeyHolder object that will handle the cryptography functions, + * for example org.apache.james.security.SMIMEKeyHolder for SMIME.</li> * <li><debug>.</li> * <li><keyStoreFileName>.</li> * <li><keyStorePassword>.</li> @@ -55,7 +58,7 @@ * @version CVS $Revision$ $Date$ * @since 2.2.1 */ -public class SMIMESign extends SMIMEAbstractSign { +public class Sign extends AbstractSign { /** * Return a string describing this mailet. @@ -63,7 +66,7 @@ * @return a string describing this mailet */ public String getMailetInfo() { - return "SMIME Signature Mailet"; + return "Signature Mailet"; } /** @@ -71,6 +74,7 @@ */ protected String[] getAllowedInitParameters() { String[] allowedArray = { + "keyHolderClass", "debug", "keyStoreFileName", "keyStorePassword", --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]