View Javadoc

1   /*
2    * $Id: EncryptOutputStreamWriter.java 20320 2010-11-24 15:03:31Z 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  
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       * {@inheritDoc}
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       * {@inheritDoc}
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  }