aboutsummaryrefslogtreecommitdiffstats
path: root/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/SMIMECompressedGenerator.java
blob: 06ad6c2113e5e0698b890ada4367165204f28699 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
package org.bouncycastle.mail.smime;

import java.io.IOException;
import java.io.OutputStream;

import javax.activation.CommandMap;
import javax.activation.MailcapCommandMap;
import javax.mail.MessagingException;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;

import org.bouncycastle.cms.CMSCompressedDataGenerator;
import org.bouncycastle.cms.CMSCompressedDataStreamGenerator;
import org.bouncycastle.operator.OutputCompressor;

/**
 * General class for generating a pkcs7-mime compressed message.
 *
 * A simple example of usage.
 *
 * <pre>
 *      SMIMECompressedGenerator  fact = new SMIMECompressedGenerator();
 *
 *      MimeBodyPart           smime = fact.generate(content, algorithm);
 * </pre>
 *
 * <b>Note:<b> Most clients expect the MimeBodyPart to be in a MimeMultipart
 * when it's sent.
 */
public class SMIMECompressedGenerator
    extends SMIMEGenerator
{
    public static final String  ZLIB    = CMSCompressedDataGenerator.ZLIB;

    private static final String COMPRESSED_CONTENT_TYPE = "application/pkcs7-mime; name=\"smime.p7z\"; smime-type=compressed-data";

    static
    {
        MailcapCommandMap mc = (MailcapCommandMap)CommandMap.getDefaultCommandMap();

        mc.addMailcap("application/pkcs7-mime;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.pkcs7_mime");
        mc.addMailcap("application/x-pkcs7-mime;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.x_pkcs7_mime");

        CommandMap.setDefaultCommandMap(mc);
    }

    /**
     * generate an compressed object that contains an SMIME Compressed
     * object using the given compression algorithm.
     */
    private MimeBodyPart make(
        MimeBodyPart    content,
        OutputCompressor compressor)
        throws SMIMEException
    {
        try
        {  
            MimeBodyPart data = new MimeBodyPart();
        
            data.setContent(new ContentCompressor(content, compressor), COMPRESSED_CONTENT_TYPE);
            data.addHeader("Content-Type", COMPRESSED_CONTENT_TYPE);
            data.addHeader("Content-Disposition", "attachment; filename=\"smime.p7z\"");
            data.addHeader("Content-Description", "S/MIME Compressed Message");
            data.addHeader("Content-Transfer-Encoding", encoding);

            return data;
        }
        catch (MessagingException e)
        {
            throw new SMIMEException("exception putting multi-part together.", e);
        }
    }

    /**
     * generate an compressed object that contains an SMIME Compressed
     * object using the given provider from the contents of the passed in
     * message
     */
    public MimeBodyPart generate(
        MimeBodyPart    content,
        OutputCompressor compressor)
        throws SMIMEException
    {
        return make(makeContentBodyPart(content), compressor);
    }

    /**
     * generate an compressed object that contains an SMIME Compressed
     * object using the given provider from the contents of the passed in
     * message
     */
    public MimeBodyPart generate(
        MimeMessage     message,
        OutputCompressor compressor)
        throws SMIMEException
    {
        try
        {
            message.saveChanges();      // make sure we're up to date.
        }
        catch (MessagingException e)
        {
            throw new SMIMEException("unable to save message", e);
        }
                        
        return make(makeContentBodyPart(message), compressor);
    }
    
    private class ContentCompressor
        implements SMIMEStreamingProcessor
    {
        private final MimeBodyPart content;
        private final OutputCompressor compressor;
        
        ContentCompressor(
            MimeBodyPart content,
            OutputCompressor compressor)
        {
            this.content = content;
            this.compressor = compressor;
        }

        public void write(OutputStream out)
            throws IOException
        {
            CMSCompressedDataStreamGenerator cGen = new CMSCompressedDataStreamGenerator();
            
            OutputStream compressed = cGen.open(out, compressor);
            
            try
            {
                content.writeTo(compressed);
                
                compressed.close();
            }
            catch (MessagingException e)
            {
                throw new IOException(e.toString());
            }
        }
    }
}