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 java.io.IOException;
21  import java.io.InputStream;
22  import java.util.HashMap;
23  import java.util.Map;
24  
25  import org.bouncycastle.openpgp.PGPException;
26  import org.bouncycastle.openpgp.PGPObjectFactory;
27  import org.bouncycastle.openpgp.PGPPublicKey;
28  import org.bouncycastle.openpgp.PGPPublicKeyRing;
29  import org.bouncycastle.openpgp.PGPSecretKey;
30  import org.bouncycastle.openpgp.PGPSecretKeyRing;
31  import org.bouncycastle.openpgp.PGPUtil;
32  
33  /**
34   * Bouncy Castle implementation of the OpenPGP key ring.
35   * 
36   * @author <a href="mailto:brett@apache.org">Brett Porter</a>
37   * @todo password is not secure
38   */
39  public class BouncyCastleKeyRing implements KeyRing
40  {
41      private String firstKeyId;
42  
43      private final Map<Long, PGPSecretKey> pgpSec = new HashMap<Long, PGPSecretKey>();
44  
45      private char[] password;
46  
47      private final Map<Long, PGPPublicKey> pgpPub = new HashMap<Long, PGPPublicKey>();
48  
49      private static final long MASK = 0xFFFFFFFFL;
50  
51      public BouncyCastleKeyRing()
52      {
53      }
54      
55      public BouncyCastleKeyRing( InputStream secretKeyRingStream, InputStream publicKeyRingStream, char[] password )
56          throws IOException, PGPException
57      {
58          addSecretKeyRing( secretKeyRingStream, password );
59  
60          addPublicKeyRing( publicKeyRingStream );
61      }
62  
63      public void addPublicKeyRing( InputStream publicKeyRingStream )
64          throws IOException, PGPException
65      {
66          PGPObjectFactory pgpFact = new PGPObjectFactory( PGPUtil.getDecoderStream( publicKeyRingStream ) );
67          Object obj;
68  
69          while ( ( obj = pgpFact.nextObject() ) != null )
70          {
71              if ( !( obj instanceof PGPPublicKeyRing ) )
72              {
73                  throw new PGPException( obj.getClass().getName() + " found where PGPPublicKeyRing expected" );
74              }
75  
76              PGPPublicKeyRing keyRing = (PGPPublicKeyRing) obj;
77              long key = keyRing.getPublicKey().getKeyID() & MASK;
78  
79              pgpPub.put( key, keyRing.getPublicKey() );
80          }
81      }
82  
83      public void addSecretKeyRing( InputStream secretKeyRingStream, char[] password )
84          throws IOException, PGPException
85      {
86          PGPObjectFactory pgpFact = new PGPObjectFactory( PGPUtil.getDecoderStream( secretKeyRingStream ) );
87          Object obj;
88  
89          while ( ( obj = pgpFact.nextObject() ) != null )
90          {
91              if ( !( obj instanceof PGPSecretKeyRing ) )
92              {
93                  throw new PGPException( obj.getClass().getName() + " found where PGPSecretKeyRing expected" );
94              }
95  
96              PGPSecretKeyRing pgpSecret = (PGPSecretKeyRing) obj;
97              long key = pgpSecret.getSecretKey().getKeyID() & MASK;
98              if ( pgpSec.isEmpty() )
99              {
100                 // Convert the keyId to a hexadecimal upper case String
101                 firstKeyId = Long.toHexString( key ).toUpperCase();
102             }
103 
104             pgpSec.put( key, pgpSecret.getSecretKey() );
105         }
106 
107         this.password = password;
108     }
109 
110     public String getFirstKeyId()
111     {
112         return firstKeyId.toString();
113     }
114 
115     public char[] getPassword()
116     {
117         return password;
118     }
119 
120     public PGPSecretKey getSecretKey( String keyId )
121     {
122         return pgpSec.get( Long.valueOf( keyId, 16 ) );
123     }
124 
125     public PGPPublicKey getPublicKey( String keyId )
126     {
127         return pgpPub.get( Long.valueOf( keyId, 16 ) );
128     }
129 
130     public PGPSecretKey getSecretKey( long keyId )
131     {
132         return pgpSec.get(keyId & MASK);
133     }
134 
135     public PGPPublicKey getPublicKey( long keyId )
136     {
137         return pgpPub.get(keyId & MASK);
138     }
139 }