1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.apache.james.mailet.crypto.mailet;
23
24 import java.io.IOException;
25 import java.security.GeneralSecurityException;
26 import java.util.ArrayList;
27 import java.util.Collection;
28 import java.util.Iterator;
29
30 import javax.mail.MessagingException;
31 import javax.mail.Multipart;
32 import javax.mail.Part;
33 import javax.mail.internet.MimeBodyPart;
34 import javax.mail.internet.MimeMessage;
35
36 import org.apache.james.mailet.crypto.SMIMEKeyHolder;
37 import org.apache.mailet.base.GenericMailet;
38 import org.apache.mailet.Mail;
39 import org.apache.mailet.MailetConfig;
40 import org.bouncycastle.cms.CMSException;
41 import org.bouncycastle.cms.RecipientId;
42 import org.bouncycastle.cms.RecipientInformation;
43 import org.bouncycastle.mail.smime.SMIMEEnveloped;
44 import org.bouncycastle.mail.smime.SMIMEUtil;
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71 public class SMIMEDecrypt extends GenericMailet {
72
73 private SMIMEKeyHolder keyHolder;
74 protected String mailAttribute = "org.apache.james.SMIMEDecrypt";
75
76 public void init() throws MessagingException {
77 super.init();
78
79 MailetConfig config = getMailetConfig();
80
81 String privateStoreType = config.getInitParameter("keyStoreType");
82
83 String privateStoreFile = config.getInitParameter("keyStoreFileName");
84 if (privateStoreFile == null) throw new MessagingException("No keyStoreFileName specified");
85
86 String privateStorePass = config.getInitParameter("keyStorePassword");
87
88 String keyAlias= config.getInitParameter("keyAlias");
89 String keyPass = config.getInitParameter("keyAliasPassword");
90
91 String mailAttributeConf = config.getInitParameter("mailAttribute");
92 if (mailAttributeConf != null) mailAttribute = mailAttributeConf;
93
94 try {
95 keyHolder = new SMIMEKeyHolder(privateStoreFile, privateStorePass, keyAlias, keyPass, privateStoreType);
96 } catch (IOException e) {
97 throw new MessagingException("Error loading keystore", e);
98 } catch (GeneralSecurityException e) {
99 throw new MessagingException("Error loading keystore", e);
100 }
101
102
103 }
104
105
106
107
108 public void service(Mail mail) throws MessagingException {
109 MimeMessage message = mail.getMessage();
110 Part strippedMessage = null;
111 log("Starting message decryption..");
112 if (message.isMimeType("application/x-pkcs7-mime") || message.isMimeType("application/pkcs7-mime")) {
113 try {
114 SMIMEEnveloped env = new SMIMEEnveloped(message);
115 Collection recipients = env.getRecipientInfos().getRecipients();
116 for (Iterator iter = recipients.iterator();iter.hasNext();) {
117 RecipientInformation info = (RecipientInformation) iter.next();
118 RecipientId id = info.getRID();
119 if (id.match(keyHolder.getCertificate())) {
120 try {
121 MimeBodyPart part = SMIMEUtil.toMimeBodyPart(info.getContent(keyHolder.getPrivateKey(), "BC"));
122
123 strippedMessage = part;
124 log("Encrypted message decrypted");
125 } catch (Exception e) {
126 throw new MessagingException("Error during the decryption of the message", e); }
127 } else {
128 log("Found an encrypted message but it isn't encrypted for the supplied key");
129 }
130 }
131 } catch (CMSException e) { throw new MessagingException("Error during the decryption of the message",e); }
132 }
133
134
135 if (strippedMessage != null) {
136
137
138
139
140
141 ArrayList list = new ArrayList(1);
142 list.add(keyHolder.getCertificate());
143 mail.setAttribute(mailAttribute, list);
144
145
146 try {
147 MimeMessage newmex = new MimeMessage(message);
148 Object obj = strippedMessage.getContent();
149 if (obj instanceof Multipart) {
150 log("The message is multipart, content type "+((Multipart)obj).getContentType());
151 newmex.setContent((Multipart)obj);
152 } else {
153 newmex.setContent(obj, strippedMessage.getContentType());
154 newmex.setDisposition(null);
155 }
156 newmex.saveChanges();
157 mail.setMessage(newmex);
158 } catch (IOException e) {
159 log("Error during the strip of the encrypted message");
160 throw new MessagingException("Error during the stripping of the encrypted message",e);
161 }
162 }
163 }
164 }