All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.bouncycastle.openpgp.PGPSecretKeyRingCollection Maven / Gradle / Ivy

Go to download

The Bouncy Castle Java APIs for the OpenPGP Protocol. The APIs are designed primarily to be used in conjunction with the BC FIPS provider. The APIs may also be used with other providers although if being used in a FIPS context it is the responsibility of the user to ensure that any other providers used are FIPS certified and used appropriately.

There is a newer version: 2.0.9
Show newest version
package org.bouncycastle.openpgp;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.bouncycastle.bcpg.BCPGOutputStream;
import org.bouncycastle.openpgp.operator.KeyFingerPrintCalculator;
import org.bouncycastle.util.Iterable;
import org.bouncycastle.util.Longs;
import org.bouncycastle.util.Strings;

/**
 * Often a PGP key ring file is made up of a succession of master/sub-key key rings.
 * If you want to read an entire secret key file in one hit this is the class for you.
 */
public class PGPSecretKeyRingCollection
    implements Iterable
{
    private Map secretRings = new HashMap();
    private List order = new ArrayList();

    private PGPSecretKeyRingCollection(
        Map secretRings,
        List order)
    {
        this.secretRings = secretRings;
        this.order = order;
    }

    public PGPSecretKeyRingCollection(
        byte[] encoding,
        KeyFingerPrintCalculator fingerPrintCalculator)
        throws IOException, PGPException
    {
        this(new ByteArrayInputStream(encoding), fingerPrintCalculator);
    }

    /**
     * Build a PGPSecretKeyRingCollection from the passed in input stream.
     *
     * @param in input stream containing data
     * @throws IOException if a problem parsing the base stream occurs
     * @throws PGPException if an object is encountered which isn't a PGPSecretKeyRing
     */
    public PGPSecretKeyRingCollection(
        InputStream in,
        KeyFingerPrintCalculator fingerPrintCalculator)
        throws IOException, PGPException
    {
        PGPObjectFactory pgpFact = new PGPObjectFactory(in, fingerPrintCalculator);
        Object obj;

        while ((obj = pgpFact.nextObject()) != null)
        {
            // Marker packets must be ignored
            if (obj instanceof PGPMarker || obj instanceof PGPPadding)
            {
                continue;
            }
            if (!(obj instanceof PGPSecretKeyRing))
            {
                throw new PGPException(obj.getClass().getName() + " found where PGPSecretKeyRing expected");
            }

            PGPSecretKeyRing pgpSecret = (PGPSecretKeyRing)obj;
            Long key = Longs.valueOf(pgpSecret.getPublicKey().getKeyID());

            secretRings.put(key, pgpSecret);
            order.add(key);
        }
    }

    public PGPSecretKeyRingCollection(
        Collection collection)
    {
        Iterator it = collection.iterator();

        while (it.hasNext())
        {
            PGPSecretKeyRing pgpSecret = (PGPSecretKeyRing)it.next();
            Long key = Longs.valueOf(pgpSecret.getPublicKey().getKeyID());

            secretRings.put(key, pgpSecret);
            order.add(key);
        }
    }

    /**
     * Return the number of rings in this collection.
     *
     * @return size of the collection
     */
    public int size()
    {
        return order.size();
    }

    /**
     * return the secret key rings making up this collection.
     */
    public Iterator getKeyRings()
    {
        return secretRings.values().iterator();
    }

    /**
     * Return an iterator of the key rings associated with the passed in userID.
     *
     * @param userID the user ID to be matched.
     * @return an iterator (possibly empty) of key rings which matched.
     */
    public Iterator getKeyRings(
        String userID)
    {
        return getKeyRings(userID, false, false);
    }

    /**
     * Return an iterator of the key rings associated with the passed in userID.
     * 

* * @param userID the user ID to be matched. * @param matchPartial if true userID need only be a substring of an actual ID string to match. * @return an iterator (possibly empty) of key rings which matched. */ public Iterator getKeyRings( String userID, boolean matchPartial) { return getKeyRings(userID, matchPartial, false); } /** * Return an iterator of the key rings associated with the passed in userID. *

* * @param userID the user ID to be matched. * @param matchPartial if true userID need only be a substring of an actual ID string to match. * @param ignoreCase if true case is ignored in user ID comparisons. * @return an iterator (possibly empty) of key rings which matched. */ public Iterator getKeyRings( String userID, boolean matchPartial, boolean ignoreCase) { Iterator it = this.getKeyRings(); List rings = new ArrayList(); if (ignoreCase) { userID = Strings.toLowerCase(userID); } while (it.hasNext()) { PGPSecretKeyRing secRing = (PGPSecretKeyRing)it.next(); Iterator uIt = secRing.getSecretKey().getUserIDs(); while (uIt.hasNext()) { String next = (String)uIt.next(); if (ignoreCase) { next = Strings.toLowerCase(next); } if (matchPartial) { if (next.indexOf(userID) >= 0) { rings.add(secRing); } } else { if (next.equals(userID)) { rings.add(secRing); } } } } return rings.iterator(); } /** * Return the PGP secret key associated with the given key id. * * @param keyID id of the secret key * @return the secret key */ public PGPSecretKey getSecretKey( long keyID) { Iterator it = this.getKeyRings(); while (it.hasNext()) { PGPSecretKeyRing secRing = (PGPSecretKeyRing)it.next(); PGPSecretKey sec = secRing.getSecretKey(keyID); if (sec != null) { return sec; } } return null; } /** * Return the secret key ring which contains the key referred to by keyID. * * @param keyID id of a secret key * @return the secret key ring */ public PGPSecretKeyRing getSecretKeyRing( long keyID) { Long id = Longs.valueOf(keyID); if (secretRings.containsKey(id)) { return (PGPSecretKeyRing)secretRings.get(id); } Iterator it = this.getKeyRings(); while (it.hasNext()) { PGPSecretKeyRing secretRing = (PGPSecretKeyRing)it.next(); PGPSecretKey secret = secretRing.getSecretKey(keyID); if (secret != null) { return secretRing; } } return null; } /** * Return true if a key matching the passed in key ID is present, false otherwise. * * @param keyID key ID to look for. * @return true if keyID present, false otherwise. */ public boolean contains(long keyID) { return getSecretKey(keyID) != null; } public byte[] getEncoded() throws IOException { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); this.encode(bOut); return bOut.toByteArray(); } public void encode(OutputStream outStream) throws IOException { BCPGOutputStream out = BCPGOutputStream.wrap(outStream); Iterator it = order.iterator(); while (it.hasNext()) { PGPSecretKeyRing sr = (PGPSecretKeyRing)secretRings.get(it.next()); sr.encode(out); } } /** * Return a new collection object containing the contents of the passed in collection and * the passed in secret key ring. * * @param ringCollection the collection the ring to be added to. * @param secretKeyRing the key ring to be added. * @return a new collection merging the current one with the passed in ring. * @throws IllegalArgumentException if the keyID for the passed in ring is already present. */ public static PGPSecretKeyRingCollection addSecretKeyRing( PGPSecretKeyRingCollection ringCollection, PGPSecretKeyRing secretKeyRing) { Long key = Longs.valueOf(secretKeyRing.getPublicKey().getKeyID()); if (ringCollection.secretRings.containsKey(key)) { throw new IllegalArgumentException("Collection already contains a key with a keyID for the passed in ring."); } Map newSecretRings = new HashMap(ringCollection.secretRings); List newOrder = new ArrayList(ringCollection.order); newSecretRings.put(key, secretKeyRing); newOrder.add(key); return new PGPSecretKeyRingCollection(newSecretRings, newOrder); } /** * Return a new collection object containing the contents of this collection with * the passed in secret key ring removed. * * @param ringCollection the collection the ring to be removed from. * @param secretKeyRing the key ring to be removed. * @return a new collection merging the current one with the passed in ring. * @throws IllegalArgumentException if the keyID for the passed in ring is not present. */ public static PGPSecretKeyRingCollection removeSecretKeyRing( PGPSecretKeyRingCollection ringCollection, PGPSecretKeyRing secretKeyRing) { Long key = Longs.valueOf(secretKeyRing.getPublicKey().getKeyID()); if (!ringCollection.secretRings.containsKey(key)) { throw new IllegalArgumentException("Collection does not contain a key with a keyID for the passed in ring."); } Map newSecretRings = new HashMap(ringCollection.secretRings); List newOrder = new ArrayList(ringCollection.order); newSecretRings.remove(key); for (int i = 0; i < newOrder.size(); i++) { Long r = (Long)newOrder.get(i); if (r.longValue() == key.longValue()) { newOrder.remove(i); break; } } return new PGPSecretKeyRingCollection(newSecretRings, newOrder); } /** * Support method for Iterable where available. */ public Iterator iterator() { return new KeyRingIterator(order, secretRings); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy