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.cs253
1 files changed, 94 insertions, 159 deletions
diff --git a/crypto/src/util/io/pem/PemReader.cs b/crypto/src/util/io/pem/PemReader.cs
index 77b457338..6e27a3749 100644
--- a/crypto/src/util/io/pem/PemReader.cs
+++ b/crypto/src/util/io/pem/PemReader.cs
@@ -1,6 +1,7 @@
 using System;
 using System.Collections.Generic;
 using System.IO;
+using System.Text;
 
 using Org.BouncyCastle.Utilities.Encoders;
 
@@ -8,18 +9,19 @@ namespace Org.BouncyCastle.Utilities.IO.Pem
 {
 	public class PemReader
 		: IDisposable
-	{		
-		private readonly TextReader reader;
-		private readonly MemoryStream buffer;
-		private readonly StreamWriter textBuffer;
-		private readonly List<int> pushback = new List<int>();
-		int c = 0;
+	{
+        private const int LineLength = 64;
+
+        private readonly TextReader m_reader;
+		private readonly MemoryStream m_buffer;
+		private readonly StreamWriter m_textBuffer;
+		private readonly Stack<int> m_pushback = new Stack<int>();
 
 		public PemReader(TextReader reader)
 		{
-			this.reader = reader ?? throw new ArgumentNullException(nameof(reader));
-            this.buffer = new MemoryStream();
-            this.textBuffer = new StreamWriter(buffer);
+			m_reader = reader ?? throw new ArgumentNullException(nameof(reader));
+            m_buffer = new MemoryStream();
+            m_textBuffer = new StreamWriter(m_buffer);
 		}
 
         #region IDisposable
@@ -34,15 +36,15 @@ namespace Org.BouncyCastle.Utilities.IO.Pem
         {
             if (disposing)
             {
-                reader.Dispose();
+                m_reader.Dispose();
             }
         }
 
         #endregion
 
-        public TextReader Reader
+        public TextReader Reader 
 		{
-			get { return reader; }
+			get { return m_reader; }
 		}
 
 
@@ -52,65 +54,43 @@ namespace Org.BouncyCastle.Utilities.IO.Pem
 		/// <exception cref="IOException"></exception>	
 		public PemObject ReadPemObject()
         {
-
 			//
 			// Look for BEGIN
 			//
 
 			for (;;)
 			{
-
 				// Seek a leading dash, ignore anything up to that point.
-				if (!seekDash())
-				{
-					// There are no pem objects here.
+				if (!SeekDash())
 					return null; 
-				}
-
 
 				// consume dash [-----]BEGIN ...
-				if (!consumeDash())
-				{
+				if (!ConsumeDash())
 					throw new IOException("no data after consuming leading dashes");
-				}
-
-
-				skipWhiteSpace();
-
-
-				if (!expect("BEGIN"))
-				{
-					continue;
-				}
 
-				break;
+				SkipWhiteSpace();
 
+				if (Expect("BEGIN"))
+					break;
 			}
 
-
-			skipWhiteSpace();
+			SkipWhiteSpace();
 
 			//
 			// Consume type, accepting whitespace
 			//
 
-			if (!bufferUntilStopChar('-',false) )
-            {
+			if (!BufferUntilStopChar('-', false))
 				throw new IOException("ran out of data before consuming type");
-			}
-
-			string type = bufferedString().Trim();
 
+			string type = BufferedString().Trim();
 
 			// Consume dashes after type.
 
-			if (!consumeDash())
-            {
+			if (!ConsumeDash())
 				throw new IOException("ran out of data consuming header");
-			}
-
-			skipWhiteSpace();
 
+			SkipWhiteSpace();
 
 			//
 			// Read ahead looking for headers.
@@ -119,127 +99,106 @@ namespace Org.BouncyCastle.Utilities.IO.Pem
 
 			var headers = new List<PemHeader>();
 
-			while (seekColon(64))
+			while (SeekColon(LineLength))
             {
-
-				if (!bufferUntilStopChar(':',false))
-                {
+				if (!BufferUntilStopChar(':', false))
 					throw new IOException("ran out of data reading header key value");
-				}
-
-				string key = bufferedString().Trim();
 
+				string key = BufferedString().Trim();
 
-				c = Read();
+				int c = Read();
 				if (c != ':')
-                {
 					throw new IOException("expected colon");
-                }
-				
 
 				//
 				// We are going to look for well formed headers, if they do not end with a "LF" we cannot
 				// discern where they end.
 				//
-			
-				if (!bufferUntilStopChar('\n', false)) // Now read to the end of the line.
-                {
+
+				if (!BufferUntilStopChar('\n', false)) // Now read to the end of the line.
 					throw new IOException("ran out of data before consuming header value");
-				}
 
-				skipWhiteSpace();
+				SkipWhiteSpace();
 
-				string value = bufferedString().Trim();
-				headers.Add(new PemHeader(key,value));
+				string value = BufferedString().Trim();
+				headers.Add(new PemHeader(key, value));
 			}
 
-
 			//
 			// Consume payload, ignoring all white space until we encounter a '-'
 			//
 
-			skipWhiteSpace();
+			SkipWhiteSpace();
 
-			if (!bufferUntilStopChar('-',true))
-			{
+			if (!BufferUntilStopChar('-', true))
 				throw new IOException("ran out of data before consuming payload");
-			}
 
-			string payload = bufferedString();
-		
+			string payload = BufferedString();
+
 			// Seek the start of the end.
-			if (!seekDash())
-			{
+			if (!SeekDash())
 				throw new IOException("did not find leading '-'");
-			}
 
-			if (!consumeDash())
-			{
+			if (!ConsumeDash())
 				throw new IOException("no data after consuming trailing dashes");
-			}
-
-			if (!expect("END "+type))
-			{
-				throw new IOException("END "+type+" was not found.");
-			}
-
 
+			if (!Expect("END " + type))
+				throw new IOException("END " + type + " was not found.");
 
-			if (!seekDash())
-			{
+			if (!SeekDash())
 				throw new IOException("did not find ending '-'");
-			}
-
 
 			// consume trailing dashes.
-			consumeDash();
-			
+			ConsumeDash();
 
 			return new PemObject(type, headers, Base64.Decode(payload));
-
 		}
 
-
-	
-		private string bufferedString()
+		private string BufferedString()
         {
-			textBuffer.Flush();
-			string value = Strings.FromUtf8ByteArray(buffer.ToArray());
-			buffer.Position = 0;
-			buffer.SetLength(0);
+			m_textBuffer.Flush();
+
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+            if (!m_buffer.TryGetBuffer(out var data))
+                throw new InvalidOperationException();
+
+            string value = Encoding.UTF8.GetString(data);
+#else
+            string value = Strings.FromUtf8ByteArray(m_buffer.ToArray());
+#endif
+
+            m_buffer.Position = 0;
+			m_buffer.SetLength(0);
+
 			return value;
         }
 
-
-		private bool seekDash()
+		private bool SeekDash()
         {
-			c = 0;
-			while((c = Read()) >=0)
+			int c;
+			while ((c = Read()) >= 0)
             {
 				if (c == '-')
-                {
 					break;
-                }
             }
 
 			PushBack(c);
 
-			return c == '-';
+			return c >= 0;
         }
 
-
 		/// <summary>
 		/// Seek ':" up to the limit.
 		/// </summary>
 		/// <param name="upTo"></param>
 		/// <returns></returns>
-		private bool seekColon(int upTo)
+		private bool SeekColon(int upTo)
 		{
-			c = 0;
+			int c = 0;
 			bool colonFound = false;
 			var read = new List<int>();
 
-			for (; upTo>=0 && c >=0; upTo--)
+			for (; upTo >= 0 && c >= 0; upTo--)
             {
 				c = Read();
 				read.Add(c);
@@ -250,49 +209,45 @@ namespace Org.BouncyCastle.Utilities.IO.Pem
                 }
             }
 
-			while(read.Count>0)
-            {
-				PushBack((int)read[read.Count-1]);
-				read.RemoveAt(read.Count-1);
-            }
+			int readPos = read.Count;
+			while (--readPos >= 0)
+			{
+				PushBack(read[readPos]);
+			}
 
 			return colonFound;
 		}
 
-
-
 		/// <summary>
 		/// Consume the dashes
 		/// </summary>
 		/// <returns></returns>
-		private bool consumeDash()
+		private bool ConsumeDash()
         {
-			c = 0;
+			int c;
 			while ((c = Read()) >= 0)
 			{
 				if (c != '-')
-				{
 					break;
-				}
 			}
 
 			PushBack(c);
 
-			return c != -1;
+			return c >= 0;
 		}
 
 		/// <summary>
 		/// Skip white space leave char in stream.
 		/// </summary>
-		private void skipWhiteSpace()
+		private void SkipWhiteSpace()
         {
+			int c;
 			while ((c = Read()) >= 0)
 			{
 				if (c > ' ')
-				{
 					break;
-				}
 			}
+
 			PushBack(c);
 		}
 
@@ -301,19 +256,12 @@ namespace Org.BouncyCastle.Utilities.IO.Pem
 		/// </summary>
 		/// <param name="value">expected string</param>
 		/// <returns>false if not consumed</returns>
-
-		private bool expect(string value)
+		private bool Expect(string value)
         {
-			for (int t=0; t<value.Length; t++)
+			for (int t = 0; t < value.Length; t++)
             {
-				c = Read();
-				if (c == value[t])
-                {
-					continue;
-                } else
-                {
+				if (Read() != value[t])
 					return false;
-                }
             }
 
 			return true;
@@ -323,51 +271,38 @@ namespace Org.BouncyCastle.Utilities.IO.Pem
 		/// Consume until dash.
 		/// </summary>
 		/// <returns>true if stream end not met</returns>
-		private bool bufferUntilStopChar(char stopChar,   bool skipWhiteSpace)
+		private bool BufferUntilStopChar(char stopChar, bool skipWhiteSpace)
         {
+			int c;
 			while ((c = Read()) >= 0)
 			{	
-				if (skipWhiteSpace && c <=' ')
-                {
+				if (skipWhiteSpace && c <= ' ')
 					continue;
-                }
 
-				if (c != stopChar)
+				if (c == stopChar)
 				{
-					textBuffer.Write((char)c);
-					textBuffer.Flush();
-					
-				} else
-                {
-					  PushBack(c);
-					break;
+                    PushBack(c);
+                    break;
                 }
+
+				m_textBuffer.Write((char)c);
+				m_textBuffer.Flush();
 			}
-			
-			return c > -1;
+
+			return c >= 0;
 		}
 
 		private void PushBack(int value)
         {
-			if (pushback.Count == 0)
-            {
-				pushback.Add(value);
-            } else
-            {
-				pushback.Insert(0, value);
-            }
+			m_pushback.Push(value);
         }
 
 		private int Read()
         {
-			if (pushback.Count > 0)
-            {
-				int i = pushback[0];
-				pushback.RemoveAt(0);
-				return i;
-            }
+			if (m_pushback.Count > 0)
+				return m_pushback.Pop();
 
-			return reader.Read();
+			return m_reader.Read();
         }
 	}
 }