View Javadoc

1   /*
2    * $Id: EncryptStreamTransformer.java 22865 2011-09-05 17:23:45Z dfeist $
3    * --------------------------------------------------------------------------------------
4    * Copyright (c) MuleSource, Inc.  All rights reserved.  http://www.mulesource.com
5    *
6    * The software in this package is published under the terms of the CPAL v1.0
7    * license, a copy of which has been included with this distribution in the
8    * LICENSE.txt file.
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       * {@inheritDoc}
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       * {@inheritDoc}
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 }