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 import java.util.concurrent.atomic.AtomicLong;
19
20 import org.apache.commons.lang.Validate;
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 EncryptStreamTransformer implements StreamTransformer
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 EncryptStreamTransformer(InputStream toBeEncrypted, PGPPublicKey publicKey) throws IOException
44 {
45 Validate.notNull(toBeEncrypted, "The toBeEncrypted should not be null");
46 Validate.notNull(publicKey, "The publicKey should not be null");
47
48 this.toBeEncrypted = toBeEncrypted;
49 this.publicKey = publicKey;
50 this.bytesWrote = 0;
51 }
52
53
54
55
56 @Override
57 public void initialize(OutputStream out) throws Exception
58 {
59 armoredOut = new ArmoredOutputStream(out);
60 PGPEncryptedDataGenerator encrDataGen = new PGPEncryptedDataGenerator(PGPEncryptedData.CAST5, false,
61 new SecureRandom(), "BC");
62 encrDataGen.addMethod(this.publicKey);
63 encryptedOutputStream = encrDataGen.open(armoredOut, new byte[1 << 16]);
64
65 PGPCompressedDataGenerator comprDataGen = new PGPCompressedDataGenerator(PGPCompressedData.ZIP);
66 compressedEncryptedOutputStream = comprDataGen.open(encryptedOutputStream);
67
68 PGPLiteralDataGenerator lData = new PGPLiteralDataGenerator();
69 pgpOutputStream = lData.open(compressedEncryptedOutputStream, PGPLiteralData.BINARY, "stream",
70 new Date(), new byte[1 << 16]);
71 }
72
73
74
75
76 @Override
77 public boolean write(OutputStream out, AtomicLong bytesRequested) throws Exception
78 {
79 int len = 0;
80 byte[] buf = new byte[1 << 16];
81 boolean wroteSomething = false;
82
83 while (bytesRequested.get() + offset > bytesWrote && (len = this.toBeEncrypted.read(buf)) > 0)
84 {
85 pgpOutputStream.write(buf, 0, len);
86 bytesWrote = bytesWrote + len;
87 wroteSomething = true;
88 }
89
90 if (wroteSomething && len <= 0)
91 {
92 pgpOutputStream.close();
93 compressedEncryptedOutputStream.close();
94 encryptedOutputStream.close();
95 armoredOut.close();
96 return true;
97 }
98
99 return false;
100 }
101 }