001 package org.apache.commons.openpgp;
002
003 /*
004 * Licensed to the Apache Software Foundation (ASF) under one or more
005 * contributor license agreements. See the NOTICE file distributed with
006 * this work for additional information regarding copyright ownership.
007 * The ASF licenses this file to You under the Apache License, Version 2.0
008 * (the "License"); you may not use this file except in compliance with
009 * the License. You may obtain a copy of the License at
010 *
011 * http://www.apache.org/licenses/LICENSE-2.0
012 *
013 * Unless required by applicable law or agreed to in writing, software
014 * distributed under the License is distributed on an "AS IS" BASIS,
015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
016 * See the License for the specific language governing permissions and
017 * limitations under the License.
018 */
019
020 import java.io.IOException;
021 import java.io.InputStream;
022 import java.util.HashMap;
023 import java.util.Map;
024
025 import org.bouncycastle.openpgp.PGPException;
026 import org.bouncycastle.openpgp.PGPObjectFactory;
027 import org.bouncycastle.openpgp.PGPPublicKey;
028 import org.bouncycastle.openpgp.PGPPublicKeyRing;
029 import org.bouncycastle.openpgp.PGPSecretKey;
030 import org.bouncycastle.openpgp.PGPSecretKeyRing;
031 import org.bouncycastle.openpgp.PGPUtil;
032
033 /**
034 * Bouncy Castle implementation of the OpenPGP key ring.
035 *
036 * @author <a href="mailto:brett@apache.org">Brett Porter</a>
037 * @todo password is not secure
038 */
039 public class BouncyCastleKeyRing implements KeyRing
040 {
041 private String firstKeyId;
042
043 private final Map<Long, PGPSecretKey> pgpSec = new HashMap<Long, PGPSecretKey>();
044
045 private char[] password;
046
047 private final Map<Long, PGPPublicKey> pgpPub = new HashMap<Long, PGPPublicKey>();
048
049 private static final long MASK = 0xFFFFFFFFL;
050
051 public BouncyCastleKeyRing()
052 {
053 }
054
055 public BouncyCastleKeyRing( InputStream secretKeyRingStream, InputStream publicKeyRingStream, char[] password )
056 throws IOException, PGPException
057 {
058 addSecretKeyRing( secretKeyRingStream, password );
059
060 addPublicKeyRing( publicKeyRingStream );
061 }
062
063 public void addPublicKeyRing( InputStream publicKeyRingStream )
064 throws IOException, PGPException
065 {
066 PGPObjectFactory pgpFact = new PGPObjectFactory( PGPUtil.getDecoderStream( publicKeyRingStream ) );
067 Object obj;
068
069 while ( ( obj = pgpFact.nextObject() ) != null )
070 {
071 if ( !( obj instanceof PGPPublicKeyRing ) )
072 {
073 throw new PGPException( obj.getClass().getName() + " found where PGPPublicKeyRing expected" );
074 }
075
076 PGPPublicKeyRing keyRing = (PGPPublicKeyRing) obj;
077 long key = keyRing.getPublicKey().getKeyID() & MASK;
078
079 pgpPub.put( key, keyRing.getPublicKey() );
080 }
081 }
082
083 public void addSecretKeyRing( InputStream secretKeyRingStream, char[] password )
084 throws IOException, PGPException
085 {
086 PGPObjectFactory pgpFact = new PGPObjectFactory( PGPUtil.getDecoderStream( secretKeyRingStream ) );
087 Object obj;
088
089 while ( ( obj = pgpFact.nextObject() ) != null )
090 {
091 if ( !( obj instanceof PGPSecretKeyRing ) )
092 {
093 throw new PGPException( obj.getClass().getName() + " found where PGPSecretKeyRing expected" );
094 }
095
096 PGPSecretKeyRing pgpSecret = (PGPSecretKeyRing) obj;
097 long key = pgpSecret.getSecretKey().getKeyID() & MASK;
098 if ( pgpSec.isEmpty() )
099 {
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 }