KickJava   Java API By Example, From Geeks To Geeks.

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


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.CMSSignedDataSource;
12 import javax.mail.internet.MimeMessage JavaDoc;
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.Vector JavaDoc;
19 import java.util.TimeZone JavaDoc;
20 import java.util.GregorianCalendar JavaDoc;
21 import java.io.FileInputStream JavaDoc;
22 import java.security.PrivateKey JavaDoc;
23 import java.security.KeyStore JavaDoc;
24 import java.security.cert.X509Certificate JavaDoc;
25
26 /**
27  * SignedSMIME class is used for creating and sending signed S/MIME 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  * specific requrements. For more information refer to addAttachmenttent()
67  * method.<BR>
68  * <BR>
69  * Message can be external (explicit) or internal (implicit) signed. External
70  * signing allows email receiving clients wihouth implemented SMIME
71  * capabilities to preview the signed SMIME email messages.<BR>
72  * <BR>
73  * Message can be signed with or without Signed Attributes. Signed Attributes
74  * are one optional part of CMS (Cryptographic Message Syntax) signed objects,
75  * and consist of some atributes used in the process of signing (date and time
76  * of signing, capabilities of sending email client, message digest value...).
77  * If those attributes are ommited, only pure message is taken in the process
78  * of signing.<BR>
79  * <BR>
80  * Digest algorithm can be SHA1, MD2 or MD5 which depends on selected signing algorithm.<BR>
81  * <BR>
82  * Capabilities Attributes are one of Signed Attributes, and in the process of
83  * signing (if Signed Attributes are involved) can be set. This attributes
84  * indicate to recipient email client which encipher, symmetric and/or signature
85  * algorithms signer's email client preferes, and they can be used in the next
86  * communication between each others. Setting this posibilities is optional, but
87  * if it is set, order of adding gives the information about most preferes algorithms
88  * within paricular group of algorithms. Defined Capabilities Attributes in this version
89  * of Signed SMIME can be from group: RC2 40, RC2 64, RC2 128, DES and DES_EDE3 for
90  * symmetric encryption algorihms, from group: MD2 with RSA, MD5 with RSA, SHA1 with RSA
91  * and SHA1 with DSA for signing algorithms, and RSA for encipher algorithm. For more
92  * information see setCapabilities method in this class.<BR>
93  * <BR>
94  * Certificates of signers and their root authorities can be included in the
95  * signed message. This posibilities allow the recipient of signed SMIME
96  * message to automatically include signer's certificates as trusted, and verify
97  * signed message. This posibilities are optional.<BR>
98  * <BR>
99  * More than one signer can perform signing of message and they can use
100  * different signing algorithms. Digital signing can be performed by SHA1_WITH_RSA,
101  * MD2_WITH_RSA, MD5_WITH_RSA or SHA1_WITH_DSA.<BR>
102  * <BR>
103  */

104 public class SignedSMIME extends BaseSignedSMIMEObject
105 {
106
107   /**
108    * Simple constructor. Dynamically loads the BC and SUN provider necessary for
109    * cryptography processing. This constructor does not create MIME message
110    * object, so it is obligatory to invoke initMimeMessage() method after this
111    * constructor.
112    */

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

144   public SignedSMIME (String JavaDoc smtpHost, String JavaDoc fromAddress, String JavaDoc subject,
145                           String JavaDoc content, String JavaDoc charset) throws SMIMEException
146   {
147     super(smtpHost, fromAddress, subject, content, charset);
148   }
149
150
151   /**
152    * Initializes the JavaMail session for SMTP and the MimeMessage object for message
153    * which will be sent. Dynamically loads the BC and SUN provider necessary for
154    * cryptography processing. This constructor does not create content of message
155    * and it can be set later with one of setContent methods. Also, message can be
156    * left withouth content, but then at least one attachement must be added.
157    * @param smtpHost name of SMTP host used for sending email
158    * @param fromAddress email address of sender (FROM field in email header)
159    * @param subject subject of email (SUBJECT field in email header). This
160    * argument can be null, but email message will be sent withouth SUBJECT.
161    * @param charset character set for passed subject and content. The given
162    * Unicode string will be charset-encoded using the specified charset. The
163    * charset is also used to set the "charset" parameter. For example German
164    * letters should be encoded by usage of 'ISO-8859-1' charset. If charset
165    * parameter is null and subject or content contains non US-ASCII characters,
166    * it will be encoded using the platform's default charset.
167    * @exception SMIMEException if smtpHost or fromAddress parameters are null.
168    * Also, it can be caused by non SMIMEException which is MessagingException.
169    */

170   public SignedSMIME (String JavaDoc smtpHost, String JavaDoc fromAddress, String JavaDoc subject,
171                           String JavaDoc charset) throws SMIMEException
172   {
173     super(smtpHost, fromAddress, subject, null, charset);
174   }
175
176
177   /**
178    * Construction of message with external prepared MimeMessage object. Usage of
179    * this constructor disables usage of setContent() and addAttachment() methods.
180    * Also, all recipients (TO, CC or BCC type) must be declared again via
181    * setRecipient() method, even if they were previously set. Be very carefull
182    * with usage of this constructor because all MimeBodyPart objects and
183    * MimeMultipart objects used in construction of given MimeMessage object,
184    * must have correct defined Content header arguments, and contents. Contents
185    * must be formed in format which can be recognised and appropriate interpreted
186    * in the process of sending mail. If there is any special content object
187    * added to MimeBodyPart object or MimeMultipart object, the appropriate
188    * DataContent handler must be created for that object and set to corresponding
189    * BodyPart.
190    * @param mimeMessage external created MimeMessage object
191    * @exception SMIMEException if smtpHost or fromAddress parameter is null.
192    * Also, it can be caused by non SMIMEException which is MessagingException.
193    */

194   public SignedSMIME (MimeMessage JavaDoc mimeMessage) throws SMIMEException
195   {
196     super(mimeMessage);
197   }
198
199
200 /**
201  * Adds recipient email address and type. At least one recipient must be declared
202  * as TO type.
203  * @param recipientAddress email address of recipent (fields TO or CC or BCC
204  * in email message header)
205  * @param type should be TO, CC or BCC.
206  * @exception SMIMEException if type of addressing of the messages is not TO, CC,
207  * or BCC. Also it can be caused by non SMIMEException which is MessagingException.
208  */

209   public void addRecipient (String JavaDoc recipientAddress, String JavaDoc type) throws SMIMEException
210   {
211     super.addRecipient(recipientAddress, type, null);
212   }
213
214 /**
215  * Creates and signes the message with default implicit signing.
216  * @exception SMIMEException if one of recipients is not declared as TO
217  * recipient, or if there is no message for signing. Also, it can be caused
218  * by non SMIMEException which can be one of the following: MessagingException
219  * or IOException.
220  */

221   public void signing() throws SMIMEException {
222     this.signing(false);
223   }
224
225 /**
226  * Creates and signes the message.
227  * @param externalSignature choice between implicit and explicit signing
228  * (true = explicit or external signing, false = implicit or internal signing).
229  * @exception SMIMEException if one of recipients is not declared as TO
230  * recipient, or if there is no message for signing. Also, it can be caused
231  * by non SMIMEException which can be one of the following: MessagingException,
232  * or IOException.
233  */

234   public void signing (boolean externalSignature) throws SMIMEException {
235     try {
236       if (super.indicatorTo != true)
237         throw new SMIMEException(this, 1043);
238
239       if(!super.externalMessagePresence) { // external MimeMessage object presence cheking
240

241         if (super.contentPresence & super.bodyPartArray.size() == 1) { // message contains only content
242
if(super.bodyPartArray.elementAt(0) instanceof MimeBodyPart JavaDoc) { // text/plain message
243
MimeBodyPart JavaDoc contentBody = (MimeBodyPart JavaDoc)super.bodyPartArray.elementAt(0);
244             super.message.setContent((String JavaDoc)contentBody.getContent(), contentBody.getContentType());
245             super.message.setDisposition(super.message.INLINE);
246           }
247           else // text/html message
248
super.message.setContent((MimeMultipart JavaDoc)super.bodyPartArray.elementAt(0));
249         }
250         else if ( super.bodyPartArray.size() != 0) {
251           Multipart JavaDoc mp = new MimeMultipart JavaDoc();
252           for (int i = 0; i != super.bodyPartArray.size(); i++) {
253             if(super.bodyPartArray.elementAt(i) instanceof MimeMultipart JavaDoc) {
254               MimeBodyPart JavaDoc forMulti = new MimeBodyPart JavaDoc();
255               forMulti.setContent((MimeMultipart JavaDoc)super.bodyPartArray.elementAt(i));
256               mp.addBodyPart(forMulti);
257             }
258             else
259               mp.addBodyPart((MimeBodyPart JavaDoc)super.bodyPartArray.elementAt(i));
260           }
261           super.message.setContent(mp);
262         }
263         else
264           throw new SMIMEException(this, 1044);
265
266       }
267
268       CMSSignedDataSource ss = new CMSSignedDataSource(super.message, externalSignature);
269       for (int i = 0; i < super.ksArray.size(); i++) {
270         boolean[] incl = (boolean[])super.including.elementAt(i);
271         for (int j = 6*i; j != (6*(i + 1)) && super.capabilities.elementAt(j) != null; j = j + 2) {
272           int[] capabil = (int[])super.capabilities.elementAt(j + 1);
273           ss.setCapabilities((String JavaDoc)super.capabilities.elementAt(j), capabil[0], capabil[1], capabil[2], capabil[3], capabil[4]);
274         }
275         ss.addSigner((KeyStore JavaDoc)super.ksArray.elementAt(i), incl[0], incl[1], (String JavaDoc)super.digestArray.elementAt(i));
276       }
277       for (int i = 0; i < super.certChainArray.size(); i++) {
278         boolean[] incl2 = (boolean[])super.including2.elementAt(i);
279         for (int j = 6*i; j != (6*(i + 1)) && super.capabilities2.elementAt(j) != null; j = j + 2) {
280           int[] capabil = (int[])super.capabilities2.elementAt(j + 1);
281           ss.setCapabilities((String JavaDoc)super.capabilities2.elementAt(j), capabil[0], capabil[1], capabil[2], capabil[3], capabil[4]);
282         }
283         ss.addSigner((X509Certificate JavaDoc[])certChainArray.elementAt(i), (PrivateKey JavaDoc)super.privKeyArray.elementAt(i), incl2[0], incl2[1], (String JavaDoc)super.digestArray2.elementAt(i));
284       }
285       for (int i = 0; i < super.aditionalCerts.size(); i++) {
286         ss.addCertificate((X509Certificate JavaDoc)super.aditionalCerts.elementAt(i));
287       }
288       super.message.setDataHandler(new DataHandler JavaDoc(ss));
289       super.message.saveChanges();
290       super.message.setDescription("Signed SMIME message.");
291
292       super.message.setDisposition(super.message.ATTACHMENT);
293       TimeZone JavaDoc tz = TimeZone.getDefault(); // Sets date and time
294
GregorianCalendar JavaDoc cal = new GregorianCalendar JavaDoc(tz);
295       super.message.setSentDate(cal.getTime());
296       clean();
297     }
298     catch(Exception JavaDoc e) {
299       throw SMIMEException.getInstance(this, e, "signing");
300     }
301
302   }
303
304 /**
305  * Returns SMIME Message. This method returns same object as getMimeMessage()
306  * method located in super class and will be removed in future release.
307  * @deprecated
308  * @return Signed S/MIME message
309  */

310   public MimeMessage JavaDoc getSignedMessage () {
311     return super.message;
312   }
313
314
315 /**
316  * Releases unnecessary memory.
317  */

318   private void clean () {
319     super.reset();
320     System.gc(); // Calling garbage collector
321
}
322 }
323
324
325
326
Popular Tags