summary refs log tree commit diff
path: root/Crypto/src/openpgp/PgpObjectFactory.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Crypto/src/openpgp/PgpObjectFactory.cs')
-rw-r--r--Crypto/src/openpgp/PgpObjectFactory.cs143
1 files changed, 143 insertions, 0 deletions
diff --git a/Crypto/src/openpgp/PgpObjectFactory.cs b/Crypto/src/openpgp/PgpObjectFactory.cs
new file mode 100644
index 000000000..c5c6fcb68
--- /dev/null
+++ b/Crypto/src/openpgp/PgpObjectFactory.cs
@@ -0,0 +1,143 @@
+using System;
+using System.Collections;
+using System.IO;
+
+using Org.BouncyCastle.Utilities;
+
+namespace Org.BouncyCastle.Bcpg.OpenPgp
+{
+	/// <remarks>
+    /// General class for reading a PGP object stream.
+    /// <p>
+    /// Note: if this class finds a PgpPublicKey or a PgpSecretKey it
+    /// will create a PgpPublicKeyRing, or a PgpSecretKeyRing for each
+    /// key found. If all you are trying to do is read a key ring file use
+    /// either PgpPublicKeyRingBundle or PgpSecretKeyRingBundle.</p>
+	/// </remarks>
+	public class PgpObjectFactory
+    {
+        private readonly BcpgInputStream bcpgIn;
+
+		public PgpObjectFactory(
+            Stream inputStream)
+        {
+            this.bcpgIn = BcpgInputStream.Wrap(inputStream);
+        }
+
+        public PgpObjectFactory(
+            byte[] bytes)
+            : this(new MemoryStream(bytes, false))
+        {
+        }
+
+		/// <summary>Return the next object in the stream, or null if the end is reached.</summary>
+		/// <exception cref="IOException">On a parse error</exception>
+        public PgpObject NextPgpObject()
+        {
+            PacketTag tag = bcpgIn.NextPacketTag();
+
+            if ((int) tag == -1) return null;
+
+            switch (tag)
+            {
+                case PacketTag.Signature:
+                {
+                    IList l = Platform.CreateArrayList();
+
+                    while (bcpgIn.NextPacketTag() == PacketTag.Signature)
+                    {
+                        try
+                        {
+                            l.Add(new PgpSignature(bcpgIn));
+                        }
+                        catch (PgpException e)
+                        {
+                            throw new IOException("can't create signature object: " + e);
+                        }
+                    }
+
+                    PgpSignature[] sigs = new PgpSignature[l.Count];
+                    for (int i = 0; i < l.Count; ++i)
+                    {
+                        sigs[i] = (PgpSignature)l[i];
+                    }
+					return new PgpSignatureList(sigs);
+                }
+                case PacketTag.SecretKey:
+                    try
+                    {
+                        return new PgpSecretKeyRing(bcpgIn);
+                    }
+                    catch (PgpException e)
+                    {
+                        throw new IOException("can't create secret key object: " + e);
+                    }
+                case PacketTag.PublicKey:
+                    return new PgpPublicKeyRing(bcpgIn);
+				// TODO Make PgpPublicKey a PgpObject or return a PgpPublicKeyRing
+//				case PacketTag.PublicSubkey:
+//					return PgpPublicKeyRing.ReadSubkey(bcpgIn);
+                case PacketTag.CompressedData:
+                    return new PgpCompressedData(bcpgIn);
+                case PacketTag.LiteralData:
+                    return new PgpLiteralData(bcpgIn);
+                case PacketTag.PublicKeyEncryptedSession:
+                case PacketTag.SymmetricKeyEncryptedSessionKey:
+                    return new PgpEncryptedDataList(bcpgIn);
+                case PacketTag.OnePassSignature:
+                {
+                    IList l = Platform.CreateArrayList();
+
+                    while (bcpgIn.NextPacketTag() == PacketTag.OnePassSignature)
+                    {
+                        try
+                        {
+                            l.Add(new PgpOnePassSignature(bcpgIn));
+                        }
+                        catch (PgpException e)
+                        {
+							throw new IOException("can't create one pass signature object: " + e);
+						}
+                    }
+
+                    PgpOnePassSignature[] sigs = new PgpOnePassSignature[l.Count];
+                    for (int i = 0; i < l.Count; ++i)
+                    {
+                        sigs[i] = (PgpOnePassSignature)l[i];
+                    }
+					return new PgpOnePassSignatureList(sigs);
+                }
+                case PacketTag.Marker:
+                    return new PgpMarker(bcpgIn);
+                case PacketTag.Experimental1:
+                case PacketTag.Experimental2:
+                case PacketTag.Experimental3:
+                case PacketTag.Experimental4:
+					return new PgpExperimental(bcpgIn);
+            }
+
+            throw new IOException("unknown object in stream " + bcpgIn.NextPacketTag());
+        }
+
+		[Obsolete("Use NextPgpObject() instead")]
+		public object NextObject()
+		{
+			return NextPgpObject();
+		}
+
+		/// <summary>
+		/// Return all available objects in a list.
+		/// </summary>
+		/// <returns>An <c>IList</c> containing all objects from this factory, in order.</returns>
+		public IList AllPgpObjects()
+		{
+            IList result = Platform.CreateArrayList();
+			PgpObject pgpObject;
+			while ((pgpObject = NextPgpObject()) != null)
+			{
+				result.Add(pgpObject);
+			}
+			return result;
+		}
+	}
+}