View Javadoc

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 org.bouncycastle.bcpg.BCPGOutputStream;
21  import org.bouncycastle.bcpg.ArmoredInputStream;
22  import org.bouncycastle.jce.provider.BouncyCastleProvider;
23  import org.bouncycastle.openpgp.PGPException;
24  import org.bouncycastle.openpgp.PGPSignature;
25  import org.bouncycastle.openpgp.PGPSignatureGenerator;
26  import org.bouncycastle.openpgp.PGPUtil;
27  import org.bouncycastle.openpgp.PGPObjectFactory;
28  import org.bouncycastle.openpgp.PGPSignatureList;
29  import org.bouncycastle.openpgp.PGPCompressedData;
30  import org.bouncycastle.openpgp.PGPPublicKey;
31  
32  import java.io.ByteArrayOutputStream;
33  import java.io.IOException;
34  import java.io.OutputStream;
35  import java.io.InputStream;
36  import java.security.NoSuchProviderException;
37  import java.security.Security;
38  import java.security.SignatureException;
39  
40  /**
41   * Bouncy Castle implementation of the OpenPGP signer.
42   *
43   * @author <a href="mailto:brett@apache.org">Brett Porter</a>
44   */
45  public class BouncyCastleOpenPgpStreamingSignatureVerifier
46      implements OpenPgpStreamingSignatureVerifier
47  {
48      private static final String PROVIDER = "BC";
49  
50      private PGPSignature sig;
51  
52      public BouncyCastleOpenPgpStreamingSignatureVerifier( InputStream signature, KeyRing keyRing, boolean asciiArmor )
53          throws OpenPgpException, IOException
54      {
55          init( asciiArmor, signature, keyRing );
56      }
57  
58      private void init( boolean asciiArmor, InputStream signature, KeyRing keyRing )
59          throws OpenPgpException, IOException
60      {
61          // TODO: better location for this?
62          Security.addProvider( new BouncyCastleProvider() );
63  
64          try
65          {
66              signature = PGPUtil.getDecoderStream( signature );
67              if ( asciiArmor )
68              {
69                  signature = new ArmoredInputStream( signature );
70              }
71  
72              PGPObjectFactory pgpFact = new PGPObjectFactory( signature );
73              PGPSignatureList p3;
74  
75              Object o = pgpFact.nextObject();
76              if ( o instanceof PGPCompressedData )
77              {
78                  PGPCompressedData c1 = (PGPCompressedData) o;
79  
80                  pgpFact = new PGPObjectFactory( c1.getDataStream() );
81  
82                  p3 = (PGPSignatureList) pgpFact.nextObject();
83              }
84              else
85              {
86                  p3 = (PGPSignatureList) o;
87              }
88  
89              sig = p3.get( 0 );
90              PGPPublicKey key = keyRing.getPublicKey( sig.getKeyID() );
91  
92              sig.initVerify( key, "BC" );
93          }
94          catch ( NoSuchProviderException e )
95          {
96              throw new OpenPgpException(
97                  "Unable to find the correct provider for PGP - check that the Bouncy Castle provider is correctly installed",
98                  e );
99          }
100         catch ( PGPException e )
101         {
102             // TODO: more details
103             throw new OpenPgpException( "Error calculating detached signature", e );
104         }
105     }
106 
107     public void update( byte[] buf )
108         throws OpenPgpException
109     {
110         update( buf, 0, buf.length );
111     }
112 
113     public void update( byte[] buf, int offset, int length )
114         throws OpenPgpException
115     {
116         try
117         {
118             sig.update( buf, offset, length );
119         }
120         catch ( SignatureException e )
121         {
122             // TODO: more details
123             throw new OpenPgpException( "Error calculating detached signature", e );
124         }
125     }
126 
127     public SignatureStatus finish()
128         throws OpenPgpException, IOException
129     {
130         try
131         {
132             if ( sig.verify() )
133             {
134                 // TODO: how do we assess trust?
135                 return SignatureStatus.VALID_UNTRUSTED;
136             }
137             else
138             {
139                 return SignatureStatus.INVALID;
140             }
141         }
142         catch ( PGPException e )
143         {
144             // TODO: more details
145             throw new OpenPgpException( "Error calculating detached signature", e );
146         }
147         catch ( SignatureException e )
148         {
149             // TODO: more details
150             throw new OpenPgpException( "Error calculating detached signature", e );
151         }
152     }
153 
154     public SignatureStatus verify()
155     {
156         return null;  //To change body of implemented methods use File | Settings | File Templates.
157     }
158 }