Coverage Report - org.apache.commons.openpgp.BouncyCastleOpenPgpStreamingSignatureVerifier
 
Classes in this File Line Coverage Branch Coverage Complexity
BouncyCastleOpenPgpStreamingSignatureVerifier
65%
29/44
87%
14/16
4,8
 
 1  
 package org.apache.commons.openpgp;
 2  
 
 3  
 /*
 4  
  * Licensed to the Apache Software Foundation (ASF) under one or more
 5  
  * contributor license agreements.  See the NOTICE file distributed with
 6  
  * this work for additional information regarding copyright ownership.
 7  
  * The ASF licenses this file to You under the Apache License, Version 2.0
 8  
  * (the "License"); you may not use this file except in compliance with
 9  
  * the License.  You may obtain a copy of the License at
 10  
  *
 11  
  *      http://www.apache.org/licenses/LICENSE-2.0
 12  
  *
 13  
  * Unless required by applicable law or agreed to in writing, software
 14  
  * distributed under the License is distributed on an "AS IS" BASIS,
 15  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 16  
  * See the License for the specific language governing permissions and
 17  
  * limitations under the License.
 18  
  */
 19  
 
 20  
 import java.io.IOException;
 21  
 import java.io.InputStream;
 22  
 import java.security.Security;
 23  
 import java.security.SignatureException;
 24  
 
 25  
 import org.bouncycastle.jce.provider.BouncyCastleProvider;
 26  
 import org.bouncycastle.openpgp.PGPCompressedData;
 27  
 import org.bouncycastle.openpgp.PGPException;
 28  
 import org.bouncycastle.openpgp.PGPObjectFactory;
 29  
 import org.bouncycastle.openpgp.PGPPublicKey;
 30  
 import org.bouncycastle.openpgp.PGPSignature;
 31  
 import org.bouncycastle.openpgp.PGPSignatureList;
 32  
 import org.bouncycastle.openpgp.PGPUtil;
 33  
 import org.bouncycastle.openpgp.operator.jcajce.JcaPGPContentVerifierBuilderProvider;
 34  
 
 35  
 /**
 36  
  * Bouncy Castle implementation of the OpenPGP signer.
 37  
  * 
 38  
  * @author <a href="mailto:brett@apache.org">Brett Porter</a>
 39  
  */
 40  
 public class BouncyCastleOpenPgpStreamingSignatureVerifier
 41  
     implements OpenPgpStreamingSignatureVerifier
 42  
 {
 43  
     private PGPSignature sig;
 44  
 
 45  
     public BouncyCastleOpenPgpStreamingSignatureVerifier( InputStream signature, KeyRing keyRing )
 46  
         throws OpenPgpException, IOException
 47  20
     {
 48  20
         init( signature, keyRing );
 49  18
     }
 50  
 
 51  
     private void init( InputStream signature, KeyRing keyRing )
 52  
         throws OpenPgpException, IOException
 53  
     {
 54  
         // TODO: better location for this?
 55  20
         Security.addProvider( new BouncyCastleProvider() );
 56  
 
 57  
         try
 58  
         {
 59  20
             signature = PGPUtil.getDecoderStream( signature );
 60  
 
 61  20
             PGPPublicKey key = null;
 62  41
             while ( key == null && signature.available() > 0 )
 63  
             {
 64  21
                 PGPObjectFactory pgpFact = new PGPObjectFactory( signature );
 65  
 
 66  
                 PGPSignatureList p3;
 67  
 
 68  21
                 Object o = pgpFact.nextObject();
 69  21
                 if ( o == null )
 70  
                 {
 71  0
                     break;
 72  
                 }
 73  
                 
 74  21
                 if ( o instanceof PGPCompressedData )
 75  
                 {
 76  0
                     PGPCompressedData c1 = (PGPCompressedData) o;
 77  
 
 78  0
                     pgpFact = new PGPObjectFactory( c1.getDataStream() );
 79  
 
 80  0
                     p3 = (PGPSignatureList) pgpFact.nextObject();
 81  0
                 }
 82  
                 else
 83  
                 {
 84  21
                     p3 = (PGPSignatureList) o;
 85  
                 }
 86  
 
 87  26
                 for ( int i = 0; i < p3.size(); i++ )
 88  
                 {
 89  23
                     sig = p3.get( i );
 90  23
                     key = keyRing.getPublicKey( sig.getKeyID() );
 91  23
                     if ( key != null )
 92  
                     {
 93  18
                         break;
 94  
                     }
 95  
                     else
 96  
                     {
 97  
                         // TODO: log them all
 98  
                     }
 99  
                 }
 100  
 
 101  21
             }
 102  
 
 103  20
             if ( key == null )
 104  
             {
 105  2
                 throw new UnknownKeyException( "Unable to find key with key ID '"
 106  
                     + Long.toHexString( sig.getKeyID() ).toUpperCase() + "' in public key ring" );
 107  
             }
 108  
 
 109  18
             sig.init(new JcaPGPContentVerifierBuilderProvider().setProvider("BC"), key);
 110  
         }
 111  0
         catch ( PGPException e )
 112  
         {
 113  
             // TODO: more details
 114  0
             throw new OpenPgpException( "Error calculating detached signature", e );
 115  18
         }
 116  18
     }
 117  
 
 118  
     public void update( byte[] buf )
 119  
         throws OpenPgpException
 120  
     {
 121  0
         update( buf, 0, buf.length );
 122  0
     }
 123  
 
 124  
     public void update( byte[] buf, int offset, int length )
 125  
         throws OpenPgpException
 126  
     {
 127  
         try
 128  
         {
 129  18
             sig.update( buf, offset, length );
 130  
         }
 131  0
         catch ( SignatureException e )
 132  
         {
 133  
             // TODO: more details
 134  0
             throw new OpenPgpException( "Error calculating detached signature", e );
 135  18
         }
 136  18
     }
 137  
 
 138  
     public SignatureStatus finish()
 139  
         throws OpenPgpException, IOException
 140  
     {
 141  
         try
 142  
         {
 143  18
             if ( sig.verify() )
 144  
             {
 145  
                 // TODO: how do we assess trust?
 146  16
                 return SignatureStatus.VALID_UNTRUSTED;
 147  
             }
 148  
             else
 149  
             {
 150  2
                 return SignatureStatus.INVALID;
 151  
             }
 152  
         }
 153  0
         catch ( PGPException e )
 154  
         {
 155  
             // TODO: more details
 156  0
             throw new OpenPgpException( "Error calculating detached signature", e );
 157  
         }
 158  0
         catch ( SignatureException e )
 159  
         {
 160  
             // TODO: more details
 161  0
             throw new OpenPgpException( "Error calculating detached signature", e );
 162  
         }
 163  
     }
 164  
 }