001: package org.bouncycastle.openpgp;
002:
003: import org.bouncycastle.bcpg.BCPGInputStream;
004: import org.bouncycastle.bcpg.PacketTags;
005:
006: import java.io.ByteArrayInputStream;
007: import java.io.IOException;
008: import java.io.InputStream;
009: import java.util.ArrayList;
010: import java.util.List;
011:
012: /**
013: * General class for reading a PGP object stream.
014: * <p>
015: * Note: if this class finds a PGPPublicKey or a PGPSecretKey it
016: * will create a PGPPublicKeyRing, or a PGPSecretKeyRing for each
017: * key found. If all you are trying to do is read a key ring file use
018: * either PGPPublicKeyRingCollection or PGPSecretKeyRingCollection.
019: */
020: public class PGPObjectFactory {
021: BCPGInputStream in;
022:
023: public PGPObjectFactory(InputStream in) {
024: this .in = new BCPGInputStream(in);
025: }
026:
027: public PGPObjectFactory(byte[] bytes) {
028: this (new ByteArrayInputStream(bytes));
029: }
030:
031: /**
032: * Return the next object in the stream, or null if the end is reached.
033: *
034: * @return Object
035: * @throws IOException on a parse error
036: */
037: public Object nextObject() throws IOException {
038: List l;
039:
040: switch (in.nextPacketTag()) {
041: case -1:
042: return null;
043: case PacketTags.SIGNATURE:
044: l = new ArrayList();
045:
046: while (in.nextPacketTag() == PacketTags.SIGNATURE) {
047: try {
048: l.add(new PGPSignature(in));
049: } catch (PGPException e) {
050: throw new IOException(
051: "can't create signature object: " + e);
052: }
053: }
054:
055: return new PGPSignatureList((PGPSignature[]) l
056: .toArray(new PGPSignature[l.size()]));
057: case PacketTags.SECRET_KEY:
058: try {
059: return new PGPSecretKeyRing(in);
060: } catch (PGPException e) {
061: throw new IOException(
062: "can't create secret key object: " + e);
063: }
064: case PacketTags.PUBLIC_KEY:
065: return new PGPPublicKeyRing(in);
066: case PacketTags.COMPRESSED_DATA:
067: return new PGPCompressedData(in);
068: case PacketTags.LITERAL_DATA:
069: return new PGPLiteralData(in);
070: case PacketTags.PUBLIC_KEY_ENC_SESSION:
071: case PacketTags.SYMMETRIC_KEY_ENC_SESSION:
072: return new PGPEncryptedDataList(in);
073: case PacketTags.ONE_PASS_SIGNATURE:
074: l = new ArrayList();
075:
076: while (in.nextPacketTag() == PacketTags.ONE_PASS_SIGNATURE) {
077: try {
078: l.add(new PGPOnePassSignature(in));
079: } catch (PGPException e) {
080: throw new IOException(
081: "can't create one pass signature object: "
082: + e);
083: }
084: }
085:
086: return new PGPOnePassSignatureList(
087: (PGPOnePassSignature[]) l
088: .toArray(new PGPOnePassSignature[l.size()]));
089: case PacketTags.MARKER:
090: return new PGPMarker(in);
091: case PacketTags.EXPERIMENTAL_1:
092: case PacketTags.EXPERIMENTAL_2:
093: case PacketTags.EXPERIMENTAL_3:
094: case PacketTags.EXPERIMENTAL_4:
095: return in.readPacket();
096: }
097:
098: throw new IOException("unknown object in stream "
099: + in.nextPacketTag());
100: }
101: }
|