1
2
3
4
5
6
7
8
9
10
11 package org.mule.module.pgp;
12
13 import java.io.IOException;
14 import java.io.InputStream;
15 import java.io.OutputStream;
16 import java.security.SecureRandom;
17 import java.util.Date;
18
19 import edu.emory.mathcs.backport.java.util.concurrent.atomic.AtomicLong;
20
21 import org.bouncycastle.bcpg.ArmoredOutputStream;
22 import org.bouncycastle.openpgp.PGPCompressedData;
23 import org.bouncycastle.openpgp.PGPCompressedDataGenerator;
24 import org.bouncycastle.openpgp.PGPEncryptedData;
25 import org.bouncycastle.openpgp.PGPEncryptedDataGenerator;
26 import org.bouncycastle.openpgp.PGPLiteralData;
27 import org.bouncycastle.openpgp.PGPLiteralDataGenerator;
28 import org.bouncycastle.openpgp.PGPPublicKey;
29
30 public class EncryptOutputStreamWriter implements OutputStreamWriter
31 {
32 private static final long offset = 1 << 24;
33
34 private InputStream toBeEncrypted;
35 private PGPPublicKey publicKey;
36
37 private OutputStream pgpOutputStream;
38 private OutputStream compressedEncryptedOutputStream;
39 private OutputStream encryptedOutputStream;
40 private OutputStream armoredOut;
41 private long bytesWrote;
42
43 public EncryptOutputStreamWriter(InputStream toBeEncrypted, PGPPublicKey publicKey) throws IOException
44 {
45 this.toBeEncrypted = toBeEncrypted;
46 this.publicKey = publicKey;
47 this.bytesWrote = 0;
48 }
49
50
51
52
53 public void initialize(OutputStream out) throws Exception
54 {
55 armoredOut = new ArmoredOutputStream(out);
56 PGPEncryptedDataGenerator encrDataGen = new PGPEncryptedDataGenerator(PGPEncryptedData.CAST5, false,
57 new SecureRandom(), "BC");
58 encrDataGen.addMethod(this.publicKey);
59 encryptedOutputStream = encrDataGen.open(armoredOut, new byte[1 << 16]);
60
61 PGPCompressedDataGenerator comprDataGen = new PGPCompressedDataGenerator(PGPCompressedData.ZIP);
62 compressedEncryptedOutputStream = comprDataGen.open(encryptedOutputStream);
63
64 PGPLiteralDataGenerator lData = new PGPLiteralDataGenerator();
65 pgpOutputStream = lData.open(compressedEncryptedOutputStream, PGPLiteralData.BINARY, "stream",
66 new Date(), new byte[1 << 16]);
67 }
68
69
70
71
72 public boolean write(OutputStream out, AtomicLong bytesRequested) throws Exception
73 {
74 int len = 0;
75 byte[] buf = new byte[1 << 16];
76 boolean wroteSomething = false;
77
78 while (bytesRequested.get() + offset > bytesWrote && (len = this.toBeEncrypted.read(buf)) > 0)
79 {
80 pgpOutputStream.write(buf, 0, len);
81 bytesWrote = bytesWrote + len;
82 wroteSomething = true;
83 }
84
85 if (wroteSomething && len <= 0)
86 {
87 pgpOutputStream.close();
88 compressedEncryptedOutputStream.close();
89 encryptedOutputStream.close();
90 armoredOut.close();
91 return true;
92 }
93
94 return false;
95 }
96 }