Source Code Cross Referenced for CMSSignedDataSource.java in  » Web-Mail » oyster » org » enhydra » oyster » activation » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Web Mail » oyster » org.enhydra.oyster.activation 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Title:        Oyster Project
003:         * Description:  S/MIME email sending capabilities
004:         * @Author       Vladimir Radisic
005:         * @Version      2.1.6
006:         */
007:
008:        package org.enhydra.oyster.activation;
009:
010:        import org.enhydra.oyster.cms.*;
011:        import org.enhydra.oyster.cms.consts.CapabilitiesConstants;
012:        import org.enhydra.oyster.util.MimeAssist;
013:        import org.enhydra.oyster.util.PFXUtils;
014:        import org.enhydra.oyster.util.MimeAssist;
015:        import org.enhydra.oyster.exception.SMIMEException;
016:        import org.enhydra.oyster.exception.SMIMEIOException;
017:        import javax.mail.internet.MimeMessage;
018:        import javax.activation.DataSource;
019:        import java.io.*;
020:        import java.util.Vector;
021:        import java.security.PrivateKey;
022:        import java.security.KeyStore;
023:        import java.security.cert.X509Certificate;
024:
025:        /**
026:         * CMSSignedDataSource represents implementation of DataSource interfaces. It is
027:         * used within MimeMessage as a source of data. Also, object of this class is
028:         * used to create DER encoded Cryptographic Message Syntax (CMS) object
029:         * represented in ASN.1 notation according to RFC2630. This object (CMS) is used
030:         * as the source of data for MimeMessage in the process of sending signed message.
031:         */
032:        public class CMSSignedDataSource implements  DataSource {
033:
034:            /**
035:             * Container for messages.
036:             */
037:            private byte[] message;
038:
039:            /**
040:             * Container for SignerInfos.
041:             */
042:            private SignerInfos sInfo;
043:
044:            /**
045:             * Certificates container.
046:             */
047:            private Certificates certif;
048:
049:            /**
050:             * Number of certificates stored in certificates container.
051:             */
052:            private int countCert = 0;
053:
054:            /**
055:             * Capabilities attributes and their order
056:             */
057:            private Vector capabilities;
058:
059:            /**
060:             * Decision: external (true) / internal (false) signing
061:             */
062:            private boolean externalSignature = true;
063:
064:            /**
065:             * Used in setting digestAlgorithms field in Signed Data sequence:
066:             * {SHA1,MD2,MD5}
067:             */
068:            private boolean[] typeOfDigest = { false, false, false };
069:
070:            /**
071:             * Boundary used in process of generation external signed message.
072:             */
073:            private String boundary = null;
074:
075:            /**
076:             * Constructs CMS object for signing with Mime Message in form of
077:             * byte array and with given value for type of CMSSignedDataSource (type of signing).
078:             * Type can be external or internal signing.
079:             * @param message0 message for encryption
080:             * @param externalSignature0 true = external signing, false = internal
081:             * signing
082:             * @exception SMIMEException  in case of failure in MimeMessageConvertor
083:             * class which performes transformation from MimeMessage object to byte array.
084:             * Also, it can be caused by problems in construction or work with some
085:             * inner objects instantiated from classes that belong to
086:             * org.enhydra.oyster.der or org.enhydra.oyster.cms packages used
087:             * in other CMSEnvelopedObject constructor.
088:             */
089:            public CMSSignedDataSource(byte[] message0,
090:                    boolean externalSignature0) throws SMIMEException {
091:                message = message0;
092:                externalSignature = externalSignature0;
093:                if (externalSignature)
094:                    boundary = "smime_bondary_"
095:                            + Long.toString(System.currentTimeMillis());
096:                sInfo = new SignerInfos();
097:                certif = new Certificates();
098:                capabilities = new Vector(0, 1);
099:            }
100:
101:            /**
102:             * Constructs CMS object for signing with Mime Message in form of
103:             * instance of MimeMessage class and with given value for type of CMSSignedDataSource
104:             * (type of signing). Type can be external or internal signing.
105:             * @param message0 message for encryption
106:             * @param externalSignature0 true = external signing, false = internal
107:             * signing
108:             * @exception SMIMEException caused by problems in construction or work with
109:             * some inner objects instantiated from classes that belong to
110:             * org.enhydra.oyster.der or org.enhydra.oyster.cms packages used
111:             * in other CMSEnvelopedObject constructor.
112:             */
113:            public CMSSignedDataSource(MimeMessage message0,
114:                    boolean externalSignature0) throws SMIMEException {
115:                this (MimeAssist.messageConvertor(message0), externalSignature0);
116:            }
117:
118:            /**
119:             * Sets Capabilities Attributes (method is optional, but if exists, must be
120:             * performed before addSigner method). Depending on parameter type0 (algorithm
121:             * group type), other parameter contains array of algoriithms from specific
122:             * group of algorithms in client prefered usage order. Groups of algorithms
123:             * are:<BR>
124:             * SIGNATURE - MD2 with RSA, MD5 with RSA, SHA1 with RSA, SHA1 with DSA<BR>
125:             * SYMMETRIC - RC2 40 bits, RC2 64 bits, RC2 128 bits, DES, DES_EDE3<BR>
126:             * ENCIPHER  - RSA<BR>
127:             * DEFAULT   - sets the default values for all three algorithm group types<BR>
128:             * <BR>
129:             * It is free to decide which algorithm will be included, or which group of algorithm
130:             * will be included in Capabilities Attributes. If no groups are added, capabilities
131:             * attributes won't be added to Signed Attributes. If two or more signers will
132:             * sign the message, and their capabilities are different, this method should
133:             * be performed before every signing if we wish to specify Capabilities
134:             * Attributes for all particular signers. If type0 parameter is set as:<BR>
135:             * <BR>
136:             * setCapabilities (CapabilitiesConstants.DEFAULT, new String[0])<BR>
137:             * <BR>
138:             * it is equivalent to:<BR>
139:             * <BR>
140:             * setCapabilities(CapabilitiesConstants.SYMMETRIC, new String[] {CapabilitiesConstants.RC2_CBC_40});<BR>
141:             * setCapabilities(CapabilitiesConstants.ENCIPHER, new String[] {CapabilitiesConstants.RSA });<BR>
142:             * setCapabilities(CapabilitiesConstants.SIGNATURE, new String[] {CapabilitiesConstants.SHA1_WITH_RSA });<BR>
143:             * <BR>
144:             * @param type0 sets group of algorithms for capabilities attributes. It can be set
145:             * with values: SIGNATURE, SYMMETRIC, ENCIPHER or DEFAULT.
146:             * @param capabil0 array of user prefered algorithms in user prrefered
147:             * order for each capabilityes group.
148:             * @exception SMIMEException if same group is added more than once, invalid
149:             * group type is used, or group is added after DEFAULT option.
150:             */
151:            public void setCapabilities(String type0, String[] capabil0)
152:                    throws SMIMEException {
153:
154:                if (type0.equalsIgnoreCase(CapabilitiesConstants.SYMMETRIC)
155:                        || type0
156:                                .equalsIgnoreCase(CapabilitiesConstants.SIGNATURE)
157:                        || type0
158:                                .equalsIgnoreCase(CapabilitiesConstants.ENCIPHER)) {
159:
160:                    for (int i = 0; i < capabil0.length; i++) {
161:                        if (capabil0[i] == null)
162:                            continue;
163:                        capabilities.add(capabil0[i]);
164:                    }
165:                } else if (type0.equals(CapabilitiesConstants.DEFAULT)) {
166:
167:                    capabilities.add(CapabilitiesConstants.RC2_CBC_40); // RC2 40 bits algorithm
168:                    capabilities.add(CapabilitiesConstants.SHA1_WITH_RSA); // SHA1 with RSA algorithm
169:                    capabilities.add(CapabilitiesConstants.RSA); // RSA Encription
170:                } else
171:                    throw new SMIMEException(1030);
172:            }
173:
174:            /**
175:             * Adds Signer. This method must be performed at least once.
176:             * @param pfx0 contains information from signer's .pfx or .p12 file
177:             * @param includingCert0 true = automatically including all certificates from pfx0
178:             * false = no certificate will be added
179:             * @param includingSignAttrib0 true = signed attributes will be included, false
180:             * = signed attributes will not be included
181:             * @param signingAlg0 used for signing (can be SHA1_WITH_RSA, MD2_WITH_RSA,
182:             * MD5_WITH_RSA or SHA1_WITH_DSA)
183:             * @exception SMIMEException in case of wrong type of digest algorithm, or in
184:             * case of problems with manipulation with .pfx or .p12 file in PFXUtils class.
185:             * Also, it can be caused by problems in construction or work with some inner
186:             * objects from org.enhydra.oyster.der or org.enhydra.oyster.cms package.
187:             */
188:            public void addSigner(KeyStore pfx0, boolean includingCert0,
189:                    boolean includingSignAttrib0, String signingAlg0)
190:                    throws SMIMEException {
191:
192:                X509Certificate[] chain = PFXUtils.getCertificateChain(pfx0);
193:                if (chain == null)
194:                    chain = PFXUtils.getAllX509Certificate(pfx0);
195:
196:                PrivateKey pKey = PFXUtils.getPrivateKey(pfx0);
197:
198:                this .addSigner(chain, pKey, includingCert0,
199:                        includingSignAttrib0, signingAlg0);
200:            }
201:
202:            /**
203:             * Adds Signer. This method must be performed at least once.
204:             * @param chain0 signer's certificates chain. First certificate in chain
205:             * must be owner's.
206:             * @param privKey0 signer's private key (DSA or RSA depend on type of signing)
207:             * @param includingCert0 true = automatically including all certificates from pfx0
208:             * false = no certificate will be added
209:             * @param includingSignAttrib0 true = signed attributes will be included, false
210:             * = signed attributes will not be included
211:             * @param signingAlg0 used for signing (can be SHA1_WITH_RSA, MD2_WITH_RSA,
212:             * MD5_WITH_RSA or SHA1_WITH_DSA)
213:             * @exception SMIMEException in case of wrong type of digest algorithm. Also,
214:             * it can be caused by problems in construction or work with some inner
215:             * objects from org.enhydra.oyster.der or org.enhydra.oyster.cms package.
216:             */
217:            public void addSigner(X509Certificate[] chain0,
218:                    PrivateKey privKey0, boolean includingCert0,
219:                    boolean includingSignAttrib0, String signingAlg0)
220:                    throws SMIMEException {
221:                String digestAlg = null;
222:                if (signingAlg0.equalsIgnoreCase("SHA1_WITH_RSA")) {
223:                    typeOfDigest[0] = true;
224:                    digestAlg = "SHA1";
225:                } else if (signingAlg0.equalsIgnoreCase("SHA1_WITH_DSA")) {
226:                    typeOfDigest[0] = true;
227:                    digestAlg = "SHA1";
228:                } else if (signingAlg0.equalsIgnoreCase("MD2_WITH_RSA")) {
229:                    typeOfDigest[1] = true;
230:                    digestAlg = "MD2";
231:                } else if (signingAlg0.equalsIgnoreCase("MD5_WITH_RSA")) {
232:                    typeOfDigest[2] = true;
233:                    digestAlg = "MD5";
234:                } else
235:                    throw new SMIMEException(1031);
236:                SignedAttributes attrib = null; // Signed attributes remain null if includingSignAttrib0==false
237:                if (includingSignAttrib0 == true) { // Creating signers info with signed attributes
238:                    attrib = new SignedAttributes(); // Creating container of signed attrinutes
239:                    ContentTypeAttribute cont = new ContentTypeAttribute(
240:                            "ID_DATA", "NAME_STRING");
241:                    attrib.addSignedAttribute(cont.getDEREncoded());
242:                    SigningTimeAttribute time = new SigningTimeAttribute();
243:                    attrib.addSignedAttribute(time.getDEREncoded());
244:                    boolean include = false; // Check for capabilities attributes existing
245:                    if (capabilities.size() > 0)
246:                        include = true;
247:
248:                    if (include == true) {
249:                        CapabilitiesAttribute cap = new CapabilitiesAttribute(
250:                                (String[]) (capabilities.toArray(new String[1])));
251:                        attrib.addSignedAttribute(cap.getDEREncoded());
252:                        capabilities.clear(); // resets capabilities
253:                    }
254:                    MessageDigestAttribute dig = new MessageDigestAttribute(
255:                            message, digestAlg);
256:                    attrib.addSignedAttribute(dig.getDEREncoded());
257:                }
258:                sInfo.addSigner(message, chain0[0], privKey0, attrib,
259:                        signingAlg0); // First certificate in chain must be certificate asociated with owners of private key
260:                if (includingCert0 == true) {
261:                    for (int i = 0; i != chain0.length; i++) { // Adding certificates from certificate chain
262:                        certif.addCertificate(chain0[i]);
263:                        countCert++;
264:                    }
265:                }
266:            }
267:
268:            /**
269:             * Adds the Certificate
270:             * @param cert0 X509 certificate
271:             * @exception SMIMEException thrown in inner object which is instance of the class
272:             * org.enhydra.oyster.cms.Certificates.
273:             */
274:            public void addCertificate(X509Certificate cert0)
275:                    throws SMIMEException {
276:                certif.addCertificate(cert0);
277:                countCert++;
278:            }
279:
280:            /**
281:             * Returns complete DER encoded CMS Signed Object
282:             * @return DER encoded CMS Signed Object represented as byte array
283:             * @exception SMIMEException caused by problems in construction or dealing
284:             * with some inner objects instantiated from classes that belong to
285:             * org.enhydra.oyster.der or org.enhydra.oyster.cms packages.
286:             */
287:            public byte[] getCMSSignedObject() throws SMIMEException {
288:                SignedData signData = new SignedData(); // Container for signed data sub object
289:                signData.addCMSVersion(new CMSVersion(1).getDEREncoded());
290:                DigestAlgorithmIdentifiers digAlg = new DigestAlgorithmIdentifiers();
291:                if (typeOfDigest[0] == true)
292:                    digAlg.addDigestAlgIdNullPar("SHA1", "NAME_STRING");
293:                if (typeOfDigest[1] == true)
294:                    digAlg.addDigestAlgIdNullPar("MD2", "NAME_STRING");
295:                if (typeOfDigest[2] == true)
296:                    digAlg.addDigestAlgIdNullPar("MD5", "NAME_STRING");
297:                signData.addDigestAlgorithm(digAlg.getDEREncoded());
298:                EncapsulatedContentInfo enc = new EncapsulatedContentInfo();
299:                ContentTypeIdentifier cont = new ContentTypeIdentifier(
300:                        "ID_DATA", "NAME_STRING");
301:                enc.addContentType(cont.getDEREncoded());
302:                if (externalSignature == false) {
303:                    enc.addEncapsulatedContent(message);
304:                }
305:                signData.addEncapsulatedContentInfo(enc.getDEREncoded());
306:                if (countCert != 0)
307:                    signData.addCertificate(certif.getDEREncoded());
308:                signData.addSignerInfos(sInfo.getDEREncoded());
309:                Content signedContent = new Content(signData.getDEREncoded(),
310:                        true); // Filling signed data content in context specific DER object
311:                ContentInfo cmsObjectSignedData = new ContentInfo();
312:                ContentTypeIdentifier contentTypeSignDataId = new ContentTypeIdentifier(
313:                        "ID_SIGNEDDATA", "NAME_STRING"); // Creating the Content Type
314:                cmsObjectSignedData.addContentType(contentTypeSignDataId
315:                        .getDEREncoded());
316:                cmsObjectSignedData.addContent(signedContent.getDEREncoded());
317:                return cmsObjectSignedData.getDEREncoded();
318:            }
319:
320:            /**
321:             * Returns complete DER encoded CMS Signed Object with BASE64 encoding
322:             * @return DER encoded CMS Signed Object represented as byte array with
323:             * performed BASE64 encoding.
324:             * @exception SMIMEException in case of failure in Base64 encoding performed
325:             * on the generated SMIME message byte array by method ofMimeAssist class. Also,
326:             * it can be caused by problems in construction or work with some inner objects
327:             * instantiated from classes that belong to org.enhydra.oyster.der or
328:             * org.enhydra.oyster.cms packages used in getCMSSignedDataSource() method.
329:             */
330:            public byte[] getBASE64CMSSignedObject() throws SMIMEException {
331:                return MimeAssist.getBASE64WithBreakOn76(this 
332:                        .getCMSSignedObject());
333:            }
334:
335:            /**
336:             * Returns "micalg" parameter used in Content-Type of external signing
337:             * @return String representation of micalg parameter.
338:             */
339:            private String getMicalg() {
340:                int sum = 0;
341:                if (typeOfDigest[0])
342:                    sum = sum + 1;
343:                if (typeOfDigest[1])
344:                    sum = sum + 10;
345:                if (typeOfDigest[2])
346:                    sum = sum + 100;
347:
348:                switch (sum) {
349:                case 0:
350:                    return "\"unknown\"";
351:                case 1:
352:                    return "\"sha1\"";
353:                case 10:
354:                    return "\"md2\"";
355:                case 100:
356:                    return "\"md5\"";
357:                case 11:
358:                    return "\"sha1,md2\"";
359:                case 101:
360:                    return "\"sha1,md5\"";
361:                case 110:
362:                    return "\"md2,md5\"";
363:                case 111:
364:                    return "\"sha1,md2,md5\"";
365:                }
366:                return "\"unknown\"";
367:            }
368:
369:            /**
370:             * Returns composed message for external signing.
371:             * @return External signed message represented as byte array.
372:             * @exception SMIMEException in case of failure in Base64 encoding performed
373:             * on the generated SMIME message byte array by method ofMimeAssist class. Also,
374:             * it can be caused by problems in construction or work with some inner objects
375:             * instantiated from classes that belong to org.enhydra.oyster.der or
376:             * org.enhydra.oyster.cms packages used in getCMSSignedDataSource() method.
377:             */
378:            private byte[] getExternalSignedMessage() throws SMIMEException {
379:
380:                try {
381:                    String extMessage = "--"
382:                            + boundary
383:                            + "\r\n"
384:                            + new String(this .message, "ISO-8859-1")
385:                            + "\r\n"
386:                            + "--"
387:                            + boundary
388:                            + "\r\n"
389:                            + "Content-Type: application/x-pkcs7-signature; name=smime.p7s"
390:                            + "\r\n"
391:                            + "Content-Transfer-Encoding: base64"
392:                            + "\r\n"
393:                            + "Content-Disposition: attachment; filename=smime.p7s"
394:                            + "\r\n"
395:                            + "\r\n"
396:                            + new String(this .getBASE64CMSSignedObject(),
397:                                    "ISO-8859-1") + "\r\n" + "--" + boundary
398:                            + "--";
399:
400:                    return extMessage.getBytes("ISO-8859-1");
401:                } catch (Exception e) {
402:                    throw new SMIMEException(e);
403:                }
404:            }
405:
406:            /**
407:             * Implements getContentType method from DataSource interface
408:             * @return Content-Type for MIME message header field
409:             */
410:            public String getContentType() {
411:                if (!externalSignature)
412:
413:                    // For new version of mail clients: "application/pkcs7-mime; smime-type=signed-data; name=\"smime.p7m\""
414:                    return "application/x-pkcs7-mime; smime-type=signed-data; name=\"smime.p7m\"";
415:                else
416:
417:                    // For new version of mail clients protocol: "application/pkcs7-signature; name=\"smime.p7s\""
418:                    return "multipart/signed;"
419:                            + "\r\n"
420:                            + "     protocol=\"application/x-pkcs7-signature\";"
421:                            + "\r\n" + "     micalg=" + this .getMicalg()
422:                            + "; boundary=" + boundary;
423:
424:            }
425:
426:            /**
427:             * Implements getInputStream method from DataSource interface
428:             * @return CMS signed object
429:             * @exception SMIMEIOException thrown as result of SMIMEException
430:             */
431:            public InputStream getInputStream() throws SMIMEIOException {
432:                try {
433:                    if (!externalSignature)
434:                        return new ByteArrayInputStream(getCMSSignedObject());
435:                    else
436:                        return new ByteArrayInputStream(
437:                                getExternalSignedMessage());
438:                } catch (SMIMEException e) {
439:                    throw new SMIMEIOException(e);
440:                }
441:            }
442:
443:            /**
444:             * Implements getName method from DataSource interface
445:             * @return Name: SignedDataContentInfo
446:             */
447:            public String getName() {
448:                return "SignedDataContentInfo";
449:            }
450:
451:            /**
452:             * Implements getOutputStream method from DataSource interface. This
453:             * method is not in use.
454:             * @return nothing
455:             * @exception IOException is always thrown when this method is used.
456:             */
457:            public OutputStream getOutputStream() throws IOException {
458:                throw new IOException(
459:                        "SignedDataContentInfo does not support getOutputStream()");
460:            }
461:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.