summary refs log tree commit diff
path: root/crypto/src/util/io/pem/PemReader.cs
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/src/util/io/pem/PemReader.cs')
-rw-r--r--crypto/src/util/io/pem/PemReader.cs94
1 files changed, 94 insertions, 0 deletions
diff --git a/crypto/src/util/io/pem/PemReader.cs b/crypto/src/util/io/pem/PemReader.cs
new file mode 100644
index 000000000..b3284705d
--- /dev/null
+++ b/crypto/src/util/io/pem/PemReader.cs
@@ -0,0 +1,94 @@
+using System;
+using System.Collections;
+using System.IO;
+using System.Text;
+
+using Org.BouncyCastle.Utilities.Encoders;
+
+namespace Org.BouncyCastle.Utilities.IO.Pem
+{
+	public class PemReader
+	{
+		private const string BeginString = "-----BEGIN ";
+		private const string EndString = "-----END ";
+
+		private readonly TextReader reader;
+
+		public PemReader(TextReader reader)
+		{
+			if (reader == null)
+				throw new ArgumentNullException("reader");
+
+			this.reader = reader;
+		}
+
+		public TextReader Reader
+		{
+			get { return reader; }
+		}
+
+		/// <returns>
+		/// A <see cref="PemObject"/>
+		/// </returns>
+		/// <exception cref="IOException"></exception>
+		public PemObject ReadPemObject()
+		{
+			string line = reader.ReadLine();
+
+			if (line != null && line.StartsWith(BeginString))
+			{
+				line = line.Substring(BeginString.Length);
+				int index = line.IndexOf('-');
+				string type = line.Substring(0, index);
+
+				if (index > 0)
+					return LoadObject(type);
+			}
+
+			return null;
+		}
+
+		private PemObject LoadObject(string type)
+		{
+			string endMarker = EndString + type;
+			IList headers = Platform.CreateArrayList();
+			StringBuilder buf = new StringBuilder();
+
+			string line;
+			while ((line = reader.ReadLine()) != null
+				&& line.IndexOf(endMarker) == -1)
+			{
+				int colonPos = line.IndexOf(':');
+
+				if (colonPos == -1)
+				{
+					buf.Append(line.Trim());
+				}
+				else
+				{
+					// Process field
+					string fieldName = line.Substring(0, colonPos).Trim();
+
+					if (fieldName.StartsWith("X-"))
+						fieldName = fieldName.Substring(2);
+
+					string fieldValue = line.Substring(colonPos + 1).Trim();
+
+					headers.Add(new PemHeader(fieldName, fieldValue));
+				}
+			}
+
+			if (line == null)
+			{
+				throw new IOException(endMarker + " not found");
+			}
+
+			if (buf.Length % 4 != 0)
+			{
+				throw new IOException("base64 data appears to be truncated");
+			}
+
+			return new PemObject(type, headers, Base64.Decode(buf.ToString()));
+		}
+	}
+}