001: package org.bouncycastle.mail.smime;
002:
003: import org.bouncycastle.cms.CMSEnvelopedGenerator;
004: import org.bouncycastle.util.Strings;
005:
006: import javax.crypto.KeyGenerator;
007: import javax.mail.Header;
008: import javax.mail.MessagingException;
009: import javax.mail.Session;
010: import javax.mail.internet.MimeBodyPart;
011: import javax.mail.internet.MimeMessage;
012: import java.io.IOException;
013: import java.security.NoSuchAlgorithmException;
014: import java.security.NoSuchProviderException;
015: import java.util.Enumeration;
016: import java.util.HashMap;
017: import java.util.Map;
018:
019: /**
020: * super class of the various generators.
021: */
022: public class SMIMEGenerator {
023: private static Map BASE_CIPHER_NAMES = new HashMap();
024:
025: static {
026: BASE_CIPHER_NAMES.put(CMSEnvelopedGenerator.DES_EDE3_CBC,
027: "DESEDE");
028: BASE_CIPHER_NAMES.put(CMSEnvelopedGenerator.AES128_CBC, "AES");
029: BASE_CIPHER_NAMES.put(CMSEnvelopedGenerator.AES192_CBC, "AES");
030: BASE_CIPHER_NAMES.put(CMSEnvelopedGenerator.AES256_CBC, "AES");
031: }
032:
033: protected boolean useBase64 = true;
034: protected String encoding = "base64"; // default sets base64
035:
036: /**
037: * base constructor
038: */
039: protected SMIMEGenerator() {
040: }
041:
042: /**
043: * set the content-transfer-encoding for the signature.
044: */
045: public void setContentTransferEncoding(String encoding) {
046: this .encoding = encoding;
047: this .useBase64 = Strings.toLowerCase(encoding).equals("base64");
048: }
049:
050: /**
051: * Make sure we have a valid content body part - setting the headers
052: * with defaults if neccessary.
053: */
054: protected MimeBodyPart makeContentBodyPart(MimeBodyPart content)
055: throws SMIMEException {
056: //
057: // add the headers to the body part - if they are missing, in
058: // the event they have already been set the content settings override
059: // any defaults that might be set.
060: //
061: try {
062: MimeMessage msg = new MimeMessage((Session) null);
063:
064: Enumeration e = content.getAllHeaders();
065:
066: msg.setDataHandler(content.getDataHandler());
067:
068: while (e.hasMoreElements()) {
069: Header hdr = (Header) e.nextElement();
070:
071: msg.setHeader(hdr.getName(), hdr.getValue());
072: }
073:
074: msg.saveChanges();
075:
076: //
077: // we do this to make sure at least the default headers are
078: // set in the body part.
079: //
080: e = msg.getAllHeaders();
081:
082: while (e.hasMoreElements()) {
083: Header hdr = (Header) e.nextElement();
084:
085: if (Strings.toLowerCase(hdr.getName()).startsWith(
086: "content-")) {
087: content.setHeader(hdr.getName(), hdr.getValue());
088: }
089: }
090: } catch (MessagingException e) {
091: throw new SMIMEException("exception saving message state.",
092: e);
093: }
094:
095: return content;
096: }
097:
098: /**
099: * extract an appropriate body part from the passed in MimeMessage
100: */
101: protected MimeBodyPart makeContentBodyPart(MimeMessage message)
102: throws SMIMEException {
103: MimeBodyPart content = new MimeBodyPart();
104:
105: //
106: // add the headers to the body part.
107: //
108: try {
109:
110: message.removeHeader("Message-Id");
111: message.removeHeader("Mime-Version");
112:
113: content.setContent(message.getContent(), message
114: .getContentType());
115:
116: Enumeration e = message.getAllHeaders();
117:
118: while (e.hasMoreElements()) {
119: Header hdr = (Header) e.nextElement();
120:
121: content.setHeader(hdr.getName(), hdr.getValue());
122: }
123: } catch (MessagingException e) {
124: throw new SMIMEException("exception saving message state.",
125: e);
126: } catch (IOException e) {
127: throw new SMIMEException(
128: "exception getting message content.", e);
129: }
130:
131: return content;
132: }
133:
134: protected KeyGenerator createSymmetricKeyGenerator(
135: String encryptionOID, String provider)
136: throws NoSuchProviderException, NoSuchAlgorithmException {
137: try {
138: return createKeyGenerator(encryptionOID, provider);
139: } catch (NoSuchAlgorithmException e) {
140: try {
141: String algName = (String) BASE_CIPHER_NAMES
142: .get(encryptionOID);
143: if (algName != null) {
144: return createKeyGenerator(algName, provider);
145: }
146: } catch (NoSuchAlgorithmException ex) {
147: // ignore
148: }
149: if (provider != null) {
150: return createSymmetricKeyGenerator(encryptionOID, null);
151: }
152: throw e;
153: }
154: }
155:
156: private KeyGenerator createKeyGenerator(String algName,
157: String provider) throws NoSuchProviderException,
158: NoSuchAlgorithmException {
159: if (provider != null) {
160: return KeyGenerator.getInstance(algName, provider);
161: } else {
162: return KeyGenerator.getInstance(algName);
163: }
164: }
165: }
|