KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > enhydra > oyster > smime > EnvelopedSMIME


1 /*
2  * Title: Oyster Project
3  * Description: S/MIME email sending capabilities
4  * @Author Vladan Obradovic
5  * @Version 2.1.5
6  */

7
8 package org.enhydra.oyster.smime;
9
10 import org.enhydra.oyster.exception.SMIMEException;
11 import org.enhydra.oyster.activation.CMSEnvelopedDataSource;
12 import org.enhydra.oyster.crypto.consts.EnvelopedConstants;
13 import javax.mail.Multipart JavaDoc;
14 import javax.mail.internet.MimeMessage JavaDoc;
15 import javax.mail.internet.MimeBodyPart JavaDoc;
16 import javax.mail.internet.MimeMultipart JavaDoc;
17 import javax.activation.DataHandler JavaDoc;
18 import java.util.TimeZone JavaDoc;
19 import java.util.GregorianCalendar JavaDoc;
20 import java.io.FileInputStream JavaDoc;
21 import java.io.InputStream JavaDoc;
22 import java.security.cert.X509Certificate JavaDoc;
23 import java.security.KeyStore JavaDoc;
24
25 /**
26  * EnvelopedSMIME class is used for creating and sending encrypted S/MIME
27  * message.<BR>
28  * <BR>
29  * Email message is in general composed of the content of the message and of one or
30  * more attachments. The content is visible part of the message, and attacments are
31  * mostly files or other binary data, which are not visible parts of message and
32  * which are used by email as a transport medium. In this implementation content
33  * can be represented in two different forms: <BR>
34  * <BR>
35  * <UL><LI>
36  * text/plain (only text withouth any formating) or
37  * </LI> <LI>
38  * text/html (html coded view of message)
39  * </LI></UL>
40  * Also, content can be absent, but than at least one attachment must be added.
41  * Content can be set on few manners. For text/plain type it can be done in time
42  * of construction with constructor designed special for creation of text/plain
43  * messages. Also, text content can be created by any of setContent() methods,
44  * if construction of object was done by other constructor which creates object
45  * with empty content. Construction with other constructor offers a few different
46  * posibilities for importing content data (File, InputStream, String) by using
47  * appropriate setContent() method. If method with four parameters is used, 3rd
48  * ant 4th parameters are not in use for text/plain message and could be set to
49  * null. For setting text/html content, construction of object should be done
50  * only by second mentioned constructor, which creates object with empty content.
51  * Content should be populated by html code with setContent() method. 3rd
52  * parameter is used for resolving relative addresses of resources in html
53  * code (images, movies...) and 4th parameter serves as data source for resources
54  * that are on special way addressed in html code. Also, there is a setContent()
55  * method which doesn't care about resources and which creates message content
56  * withouth them. For more information refer to setContent() methods.<BR>
57  * <BR>
58  * Message can contain any number of attachments. Also, message can
59  * be wihouth any attachment, but then content must be present. Every attachment
60  * should be added by performing single addAttachment() method. Attachments
61  * can be added from file or from InputStream. Mime-type which corresponds to
62  * particular attachment is obtained according to extension of file name
63  * (virtual or real file name) passed to addAttachment() method. File mime.types
64  * in META_INF directory contains list of mime-types and corresponding extensions
65  * which are used in determination of mime-type. File can be changed to satisfy
66  * secific requrements. For more information refer to addAttachmenttent()
67  * method.<BR>
68  * <BR>
69  * Encryption of message is performed by symmetric encryption with random
70  * generated symmetric key. This key is then encrypted by assymetric encryption
71  * with a recipient's public key, and sent together with encrypted message to
72  * recipient in CMS (Cryptographic Message Syntax) enveloped object. For all
73  * recipients of the message (if there is more than one) operation of encrypting
74  * symmetric key must be performed with his corresponding public key (from .cer
75  * file). Encryption can be performed by following algorithms and corresponding
76  * key sizes:<BR>
77  * <BR>
78  * RC2_CBC, 40 bits (default encryption)<BR>
79  * RC2_CBC, 64 bits<BR>
80  * RC2_CBC, 128 bits<BR>
81  * DES, 56 bits<BR>
82  * DES_EDE3_CBC, 128 bits<BR>
83  * DES_EDE3_CBC, 192 bits<BR>
84  * <BR>
85  * As a asymmetric algorithm, RSA algorithm is used.<BR>
86  * <BR>
87  */

88 public class EnvelopedSMIME extends BaseSMIMEObject implements EnvelopedConstants
89 {
90
91   /**
92    * Simple constructor. Dynamically loads the BC and SUN provider necessary for
93    * cryptography processing. This constructor does not create MIME message
94    * object, so it is obligatory to invoke initMimeMessage() method after this
95    * constructor.
96    */

97   protected EnvelopedSMIME ()
98   {
99     super();
100   }
101
102
103   /**
104    * Initializes the JavaMail session for SMTP and the MimeMessage object for message
105    * which will be sent. Dynamically loads the BC and SUN provider necessary for
106    * cryptography processing. This constructor is used for creating message with
107    * text/plain content. For creating html formated content (text/html), other
108    * constructor should be used in combination with one of setContent methods.
109    * Note that after using this constructor setContent method can be used only
110    * if "content" argument of constructor was given as null, otherwise setContent
111    * method can't be used because content is already set as text/plain.
112    * @param smtpHost name of SMTP host used for sending email
113    * @param fromAddress email address of sender (FROM field in email header)
114    * @param subject subject of email (SUBJECT field in email header). This
115    * argument can be null, but email message will be sent withouth SUBJECT.
116    * @param content text/plain content of email message. This argument can be
117    * null, but later one of setContent() methods or one of addAttachment()
118    * methods should be called
119    * @param charset character set for passed subject and content. The given
120    * Unicode string will be charset-encoded using the specified charset. The
121    * charset is also used to set the "charset" parameter. For example German
122    * letters should be encoded by usage of 'ISO-8859-1' charset. If charset
123    * parameter is null and subject or content contains non US-ASCII characters,
124    * it will be encoded using the platform's default charset.
125    * @exception SMIMEException if smtpHost or fromAddress parameters are null.
126    * Also, it can be caused by non SMIMEException which is MessagingException.
127    */

128   public EnvelopedSMIME (String JavaDoc smtpHost, String JavaDoc fromAddress, String JavaDoc subject,
129                           String JavaDoc content, String JavaDoc charset) throws SMIMEException
130   {
131     super(smtpHost, fromAddress, subject, content, charset);
132   }
133
134
135   /**
136    * Initializes the JavaMail session for SMTP and the MimeMessage object for message
137    * which will be sent. Dynamically loads the BC and SUN provider necessary for
138    * cryptography processing. This constructor does not create content of message
139    * and it can be set later with one of setContent methods. Also, message can be
140    * left withouth content, but then at least one attachement must be added.
141    * @param smtpHost name of SMTP host used for sending email
142    * @param fromAddress email address of sender (FROM field in email header)
143    * @param subject subject of email (SUBJECT field in email header). This
144    * argument can be null, but email message will be sent withouth SUBJECT.
145    * @param charset character set for passed subject and content. The given
146    * Unicode string will be charset-encoded using the specified charset. The
147    * charset is also used to set the "charset" parameter. For example German
148    * letters should be encoded by usage of 'ISO-8859-1' charset. If charset
149    * parameter is null and subject or content contains non US-ASCII characters,
150    * it will be encoded using the platform's default charset.
151    * @exception SMIMEException if smtpHost or fromAddress parameters are null.
152    * Also, it can be caused by non SMIMEException which is MessagingException.
153    */

154   public EnvelopedSMIME (String JavaDoc smtpHost, String JavaDoc fromAddress, String JavaDoc subject,
155                           String JavaDoc charset) throws SMIMEException
156   {
157     super(smtpHost, fromAddress, subject, null, charset);
158   }
159
160
161   /**
162    * Construction of message with external prepared MimeMessage object. Usage of
163    * this constructor disables usage of setContent() and addAttachment() methods.
164    * Also, all recipients (TO, CC or BCC type) must be declared again via
165    * setRecipient() method, even if they were previously set. Be very carefull
166    * with usage of this constructor because all MimeBodyPart objects and
167    * MimeMultipart objects used in construction of given MimeMessage object,
168    * must have correct defined Content header arguments, and contents. Contents
169    * must be formed in format which can be recognised and appropriate interpreted
170    * in the process of sending mail. If there is any special content object
171    * added to MimeBodyPart object or MimeMultipart object, the appropriate
172    * DataContent handler must be created for that object and set to corresponding
173    * BodyPart.
174    * @param mimeMessage external created MimeMessage object
175    * @exception SMIMEException if smtpHost or fromAddress parameter is null.
176    * Also, it can be caused by non SMIMEException which is MessagingException.
177    */

178   public EnvelopedSMIME (MimeMessage JavaDoc mimeMessage) throws SMIMEException
179   {
180     super(mimeMessage);
181   }
182
183
184   /**
185    * Adds recipient address, type and .cer file of email recipient to encrypted
186    * message. At least one recipient must be declared as TO type.
187    * @param recipientAddress email address of recipent (fields TO or CC or BCC
188    * in email message header)
189    * @param type should be TO, CC or BCC
190    * @param cerFileName path and file name with certificate corresponding
191    * to recipient (file with .cer extension)
192    * @exception SMIMEException if type of addressing of the messages is not TO, CC,
193    * or BCC. Also it can be caused by non SMIMEException which is MessagingException.
194    */

195   public void addRecipient (String JavaDoc recipientAddress, String JavaDoc type, String JavaDoc cerFileName)
196       throws SMIMEException
197   {
198     super.addRecipient(recipientAddress, type, cerFileName);
199   }
200
201   /**
202    * Adds recipient address, type and recipient's certificate via KeyStore
203    * object and apropriate alias. Certificate information should be passed only
204    * in the case of Enveloped message or Signed and Enveloped message. Otherwise
205    * those arguments represent redundance values and they should be given as
206    * null.
207    * @param recipientAddress email address of recipent (fields TO or CC or BCC
208    * in email message header)
209    * @param type should be TO, CC or BCC
210    * @param kStore instance of KeyStore class which represents an in-memory
211    * collection of keys and certificates.
212    * @param alias alias name which corresponds to desired certificate. If alias
213    * is given as null, then reading results are unpredictable.
214    * @exception SMIMEException if type of addressing of messages is not TO, CC
215    * or BCC. Also, it can be caused by non SMIMEException which can be one of
216    * the following: IOException, MessagingException, FileNotFoundException,
217    * NoSuchProviderException, CertificateException.
218    */

219   public void addRecipient (String JavaDoc recipientAddress, String JavaDoc type, KeyStore JavaDoc kStore, String JavaDoc alias)
220       throws SMIMEException
221   {
222     super.addRecipient(recipientAddress, type, kStore, alias);
223   }
224
225
226   /**
227    * Adds recipient address, type and recipient's certificate via path to the
228    * KeyStore file, KeyStore type, password and apropriate alias. Certificate
229    * information should be passed only in the case of Enveloped message or
230    * Signed and Enveloped message. Otherwise those arguments represent
231    * redundance values and they should be given as null.
232    * @param recipientAddress email address of recipent (fields TO or CC or BCC
233    * in email message header)
234    * @param type should be TO, CC or BCC
235    * @param ksPath is path to the file representation of KeyStore which holds
236    * collection of keys and certificates. This file can be PKCS12 type (file
237    * with .p12 or .pfx extension) or can be key store of other types readable
238    * by 'BouncyCastle' or 'Sun' KeyStore implementation.
239    * @param ksType is type of KeyStore. It can be one of the following types:
240    * JKS for 'Sun' KeyStore, 'BKS', 'PKCS12' or 'UBER') for 'BouncyCastle'
241    * KeyStore. If ksType is given as null it will be assumed that .cer file is
242    * in use, and alias parameter will be ignored, so this method becomes
243    * equivalent to addRecipient() method which deal only with .cer files.
244    * @param password password used to access the corresponding private key,
245    * stored in given KeyStore file.
246    * @param alias alias name which corresponds to desired private key. If alias
247    * is given as null, then reading results are unpredictable.
248    * to recipient (file with .cer extension)
249    * @exception SMIMEException if type of addressing of messages is not TO, CC
250    * or BCC. Also, it can be caused by non SMIMEException which can be one of
251    * the following: IOException, MessagingException, FileNotFoundException,
252    * NoSuchProviderException, CertificateException.
253    */

254   public void addRecipient (String JavaDoc recipientAddress, String JavaDoc type, String JavaDoc ksPath,
255                                String JavaDoc ksType, String JavaDoc password, String JavaDoc alias ) throws SMIMEException
256   {
257     super.addRecipient (recipientAddress, type, ksPath, ksType, password, alias );
258   }
259
260
261
262 /**
263  * Envelopes message with default algorithm RC2_CBC, 40 bits.
264  * @exception SMIMEException if one of recipients is not declared as TO
265  * recipient, or if there is no message for enveloping. Also, it can be caused
266  * by non SMIMEException which can be one of the following: CertificateException,
267  * IOException, MessagingException or FileNotFoundException.
268  */

269   public void enveloping () throws SMIMEException
270   {
271     this.enveloping("RC2_CBC", 40);
272   }
273
274 /**
275  * Envelopes message with given algorithm name and key length.
276  * @param algorithmName name of chosen algorithm used for encryption
277  * @param keyLength key size in bits
278  * @exception SMIMEException if one of recipients is not declared as TO
279  * recipient, or if there is no message for enveloping. Also, it can be caused
280  * by non SMIMEException which can be one of the following: CertificateException,
281  * IOException, MessagingException or FileNotFoundException.
282  */

283   public void enveloping (String JavaDoc algorithmName, int keyLength) throws SMIMEException
284   {
285     try {
286       if (super.indicatorTo != true)
287         throw new SMIMEException(this, 1043);
288
289       if(!super.externalMessagePresence) { // external MimeMessage object presence cheking
290

291         if (super.contentPresence & super.bodyPartArray.size() == 1) { // message contains only content
292
if(super.bodyPartArray.elementAt(0) instanceof MimeBodyPart JavaDoc) { // text/plain message
293
MimeBodyPart JavaDoc contentBody = (MimeBodyPart JavaDoc)super.bodyPartArray.elementAt(0);
294             super.message.setContent((String JavaDoc)contentBody.getContent(), contentBody.getContentType());
295             super.message.setDisposition(super.message.INLINE);
296           }
297           else // text/html message
298
super.message.setContent((MimeMultipart JavaDoc)super.bodyPartArray.elementAt(0));
299         }
300         else if ( super.bodyPartArray.size() != 0) {
301           Multipart JavaDoc mp = new MimeMultipart JavaDoc();
302           for (int i = 0; i != super.bodyPartArray.size(); i++) {
303             if(super.bodyPartArray.elementAt(i) instanceof MimeMultipart JavaDoc) {
304               MimeBodyPart JavaDoc forMulti = new MimeBodyPart JavaDoc();
305               forMulti.setContent((MimeMultipart JavaDoc)super.bodyPartArray.elementAt(i));
306               mp.addBodyPart(forMulti);
307             }
308             else
309               mp.addBodyPart((MimeBodyPart JavaDoc)super.bodyPartArray.elementAt(i));
310           }
311           super.message.setContent(mp);
312         }
313         else
314           throw new SMIMEException(this, 1044);
315
316       }
317
318       CMSEnvelopedDataSource es = new CMSEnvelopedDataSource(super.message, algorithmName, keyLength);
319       for (int i = 0; i != super.certArray.size(); i++) {
320         X509Certificate JavaDoc cert = (X509Certificate JavaDoc)super.certArray.elementAt(i);
321         es.addRecipient(cert);
322       }
323
324       super.message.setDataHandler(new DataHandler JavaDoc(es));
325       super.message.saveChanges();
326
327       super.message.setDescription("Enveloped SMIME message.");
328       super.message.setDisposition(super.message.ATTACHMENT);
329       TimeZone JavaDoc tz = TimeZone.getDefault(); // Sets date and time
330
GregorianCalendar JavaDoc cal = new GregorianCalendar JavaDoc(tz);
331       super.message.setSentDate(cal.getTime());
332
333       clean();
334     }
335     catch (Exception JavaDoc e) {
336       throw SMIMEException.getInstance(this, e, "enveloping");
337     }
338   }
339
340 /**
341  * Returns SMIME Message. This method returns same object as getMimeMessage()
342  * method located in super class and will be removed in future release.
343  * @deprecated
344  * @return Enveloped S/MIME message
345  */

346   public MimeMessage JavaDoc getEnvelopedMessage () {
347     return super.message;
348   }
349
350
351 /**
352  * Releases unnecessary memory.
353  */

354   private void clean () {
355     super.reset();
356     System.gc(); // Calling garbage collector
357
}
358
359 }
360
361
362
363
Popular Tags