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 }