Coverage Report - org.mule.module.pgp.DecryptOutputStreamWriter
 
Classes in this File Line Coverage Branch Coverage Complexity
DecryptOutputStreamWriter
0%
0/63
0%
0/28
5
 
 1  
 /*
 2  
  * $Id: DecryptOutputStreamWriter.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.BufferedInputStream;
 14  
 import java.io.IOException;
 15  
 import java.io.InputStream;
 16  
 import java.io.OutputStream;
 17  
 import java.security.NoSuchProviderException;
 18  
 import java.util.Iterator;
 19  
 
 20  
 import edu.emory.mathcs.backport.java.util.concurrent.atomic.AtomicLong;
 21  
 
 22  
 import org.bouncycastle.openpgp.PGPCompressedData;
 23  
 import org.bouncycastle.openpgp.PGPEncryptedDataList;
 24  
 import org.bouncycastle.openpgp.PGPException;
 25  
 import org.bouncycastle.openpgp.PGPLiteralData;
 26  
 import org.bouncycastle.openpgp.PGPObjectFactory;
 27  
 import org.bouncycastle.openpgp.PGPOnePassSignature;
 28  
 import org.bouncycastle.openpgp.PGPOnePassSignatureList;
 29  
 import org.bouncycastle.openpgp.PGPPrivateKey;
 30  
 import org.bouncycastle.openpgp.PGPPublicKey;
 31  
 import org.bouncycastle.openpgp.PGPPublicKeyEncryptedData;
 32  
 import org.bouncycastle.openpgp.PGPSecretKey;
 33  
 import org.bouncycastle.openpgp.PGPUtil;
 34  
 
 35  
 public class DecryptOutputStreamWriter implements OutputStreamWriter
 36  
 {
 37  
     private static final long offset = 1 << 24;
 38  
     
 39  
     private InputStream toBeDecrypted;
 40  
     private PGPPublicKey publicKey;
 41  
     private PGPSecretKey secretKey;
 42  
     private String password;
 43  
 
 44  
     private InputStream uncStream;
 45  
     private InputStream compressedStream;
 46  
     private InputStream clearStream;
 47  
     private long bytesWrote;
 48  
 
 49  
     public DecryptOutputStreamWriter(InputStream toBeDecrypted,
 50  
                                      PGPPublicKey publicKey,
 51  
                                      PGPSecretKey secretKey,
 52  
                                      String password) throws IOException
 53  0
     {
 54  0
         this.toBeDecrypted = toBeDecrypted;
 55  0
         this.publicKey = publicKey;
 56  0
         this.secretKey = secretKey;
 57  0
         this.password = password;
 58  0
         this.bytesWrote = 0;
 59  0
     }
 60  
 
 61  
     /**
 62  
      * {@inheritDoc}
 63  
      */
 64  
     public void initialize(OutputStream out) throws Exception
 65  
     {
 66  0
         InputStream decodedInputStream = PGPUtil.getDecoderStream(this.toBeDecrypted);
 67  0
         PGPObjectFactory pgpF = new PGPObjectFactory(decodedInputStream);
 68  0
         Object o = pgpF.nextObject();
 69  
 
 70  0
         if (o == null)
 71  
         {
 72  0
             throw new IllegalArgumentException("Invalid PGP message");
 73  
         }
 74  
 
 75  
         // the first object might be a PGP marker packet.
 76  
         PGPEncryptedDataList enc;
 77  0
         if (o instanceof PGPEncryptedDataList)
 78  
         {
 79  0
             enc = (PGPEncryptedDataList) o;
 80  
 
 81  
         }
 82  
         else
 83  
         {
 84  0
             enc = (PGPEncryptedDataList) pgpF.nextObject();
 85  
         }
 86  
 
 87  
         // This loop looks like it is ready for multiple encrypted
 88  
         // objects, but really only one is expected.
 89  0
         Iterator it = enc.getEncryptedDataObjects();
 90  0
         PGPPublicKeyEncryptedData pbe = null;
 91  0
         PGPPrivateKey privateKey = null;
 92  0
         while (privateKey == null && it.hasNext())
 93  
         {
 94  0
             pbe = (PGPPublicKeyEncryptedData) it.next();
 95  0
             privateKey = getPrivateKey(pbe.getKeyID(), this.password);
 96  0
             if (privateKey == null)
 97  
             {
 98  0
                 throw new IllegalArgumentException("Failed to find private key with ID " + pbe.getKeyID());
 99  
             }
 100  
         }
 101  
 
 102  0
         clearStream = pbe.getDataStream(privateKey, "BC");
 103  0
         PGPObjectFactory plainFact = new PGPObjectFactory(clearStream);
 104  
 
 105  0
         o = plainFact.nextObject();
 106  0
         PGPOnePassSignature signature = null;
 107  0
         if (o instanceof PGPOnePassSignatureList)
 108  
         {
 109  0
             PGPOnePassSignatureList list = (PGPOnePassSignatureList) o;
 110  0
             signature = list.get(0);
 111  0
             signature.initVerify(this.publicKey, "BC");
 112  
             // TODO verify signature
 113  
             // signature.verify(null);
 114  0
             o = plainFact.nextObject();
 115  
         }
 116  
 
 117  0
         compressedStream = null;
 118  0
         if (o instanceof PGPCompressedData)
 119  
         {
 120  0
             PGPCompressedData cData = (PGPCompressedData) o;
 121  0
             compressedStream = new BufferedInputStream(cData.getDataStream());
 122  0
             PGPObjectFactory pgpFact = new PGPObjectFactory(compressedStream);
 123  0
             Object streamData = pgpFact.nextObject();
 124  0
             o = streamData;
 125  
         }
 126  
 
 127  0
         if (o instanceof PGPLiteralData)
 128  
         {
 129  0
             PGPLiteralData ld = (PGPLiteralData) o;
 130  0
             uncStream = ld.getInputStream();
 131  0
         }
 132  
         else
 133  
         {
 134  0
             throw new PGPException("input is not PGPLiteralData - type unknown.");
 135  
         }
 136  0
     }
 137  
 
 138  
     /**
 139  
      * {@inheritDoc}
 140  
      */
 141  
     public boolean write(OutputStream out, AtomicLong bytesRequested) throws Exception
 142  
     {
 143  0
         int len = 0;
 144  0
         byte[] buf = new byte[1 << 16];
 145  0
         boolean wroteSomething = false;
 146  
 
 147  0
         while (bytesRequested.get() + offset > bytesWrote && (len = uncStream.read(buf)) > 0)
 148  
         {
 149  0
             out.write(buf, 0, len);
 150  0
             bytesWrote = bytesWrote + len;
 151  0
             wroteSomething = true;
 152  
         }
 153  
 
 154  0
         if (wroteSomething && len <= 0)
 155  
         {
 156  0
             uncStream.close();
 157  0
             if (compressedStream != null)
 158  
             {
 159  0
                 compressedStream.close();
 160  
             }
 161  0
             clearStream.close();
 162  0
             return true;
 163  
         }
 164  
 
 165  0
         return false;
 166  
     }
 167  
 
 168  
     private PGPPrivateKey getPrivateKey(long keyID, String pass) throws PGPException, NoSuchProviderException
 169  
     {
 170  0
         PGPSecretKey pgpSecKey = this.secretKey;
 171  0
         if (pgpSecKey == null)
 172  
         {
 173  0
             return null;
 174  
         }
 175  
         else
 176  
         {
 177  0
             return pgpSecKey.extractPrivateKey(pass.toCharArray(), "BC");
 178  
         }
 179  
     }
 180  
 }