1
2
3
4
5
6
7 package org.mule.module.pgp;
8
9 import java.io.IOException;
10 import java.io.InputStream;
11 import java.io.OutputStream;
12 import java.security.SecureRandom;
13 import java.util.Date;
14
15 import edu.emory.mathcs.backport.java.util.concurrent.atomic.AtomicLong;
16
17 import org.apache.commons.lang.Validate;
18 import org.bouncycastle.bcpg.ArmoredOutputStream;
19 import org.bouncycastle.openpgp.PGPCompressedData;
20 import org.bouncycastle.openpgp.PGPCompressedDataGenerator;
21 import org.bouncycastle.openpgp.PGPEncryptedData;
22 import org.bouncycastle.openpgp.PGPEncryptedDataGenerator;
23 import org.bouncycastle.openpgp.PGPLiteralData;
24 import org.bouncycastle.openpgp.PGPLiteralDataGenerator;
25 import org.bouncycastle.openpgp.PGPPublicKey;
26
27 public class EncryptStreamTransformer implements StreamTransformer
28 {
29 private static final long offset = 1 << 24;
30
31 private InputStream toBeEncrypted;
32 private PGPPublicKey publicKey;
33
34 private OutputStream pgpOutputStream;
35 private OutputStream compressedEncryptedOutputStream;
36 private OutputStream encryptedOutputStream;
37 private OutputStream armoredOut;
38 private long bytesWrote;
39
40 public EncryptStreamTransformer(InputStream toBeEncrypted, PGPPublicKey publicKey) throws IOException
41 {
42 Validate.notNull(toBeEncrypted, "The toBeEncrypted should not be null");
43 Validate.notNull(publicKey, "The publicKey should not be null");
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 toBeEncrypted.close();
92 return true;
93 }
94
95 return false;
96 }
97 }