summary refs log tree commit diff
diff options
context:
space:
mode:
authorPeter Dettman <peter.dettman@bouncycastle.org>2023-01-16 18:36:02 +0700
committerPeter Dettman <peter.dettman@bouncycastle.org>2023-01-16 18:36:02 +0700
commitc93162764c5097f65f2792c577f8a7658c6ee0dc (patch)
tree52bc090595bcb81e2db276c9023176deb02897b1
parentRefactoring in RsaCoreEngine (diff)
downloadBouncyCastle.NET-ed25519-c93162764c5097f65f2792c577f8a7658c6ee0dc.tar.xz
Refactoring in PEM classes
-rw-r--r--crypto/src/openssl/MiscPemGenerator.cs10
-rw-r--r--crypto/src/openssl/PEMReader.cs30
-rw-r--r--crypto/src/openssl/PEMWriter.cs30
-rw-r--r--crypto/src/util/io/pem/PemObject.cs18
-rw-r--r--crypto/src/util/io/pem/PemReader.cs253
-rw-r--r--crypto/src/util/io/pem/PemWriter.cs42
6 files changed, 151 insertions, 232 deletions
diff --git a/crypto/src/openssl/MiscPemGenerator.cs b/crypto/src/openssl/MiscPemGenerator.cs
index 0e918f793..fe2583063 100644
--- a/crypto/src/openssl/MiscPemGenerator.cs
+++ b/crypto/src/openssl/MiscPemGenerator.cs
@@ -32,15 +32,11 @@ namespace Org.BouncyCastle.OpenSsl
         private readonly SecureRandom random;
 
         public MiscPemGenerator(object obj)
+            : this(obj, null, null, null)
         {
-            this.obj = obj;
         }
 
-        public MiscPemGenerator(
-            object			obj,
-            string			algorithm,
-            char[]			password,
-            SecureRandom	random)
+        public MiscPemGenerator(object obj, string algorithm, char[] password, SecureRandom random)
         {
             this.obj = obj;
             this.algorithm = algorithm;
@@ -54,9 +50,7 @@ namespace Org.BouncyCastle.OpenSsl
                 throw new ArgumentNullException("obj");
 
             if (obj is AsymmetricCipherKeyPair keyPair)
-            {
                 return CreatePemObject(keyPair.Private);
-            }
 
             string type;
             byte[] encoding;
diff --git a/crypto/src/openssl/PEMReader.cs b/crypto/src/openssl/PEMReader.cs
index d2354dbe3..a2c4fd1d6 100644
--- a/crypto/src/openssl/PEMReader.cs
+++ b/crypto/src/openssl/PEMReader.cs
@@ -367,23 +367,17 @@ namespace Org.BouncyCastle.OpenSsl
             }
         }
 
-        // TODO Add an equivalent class for ECNamedCurveParameterSpec?
-        //private ECNamedCurveParameterSpec ReadECParameters(
-//		private X9ECParameters ReadECParameters(PemObject pemObject)
-//		{
-//			DerObjectIdentifier oid = (DerObjectIdentifier)Asn1Object.FromByteArray(pemObject.Content);
-//
-//			//return ECNamedCurveTable.getParameterSpec(oid.Id);
-//			return GetCurveParameters(oid.Id);
-//		}
-
-        private static X9ECParameters GetCurveParameters(string name)
-        {
-            X9ECParameters ecP = ECKeyPairGenerator.FindECCurveByName(name);
-            if (ecP == null)
-                throw new Exception("unknown curve name: " + name);
-
-            return ecP;
-        }
+        //private X9ECParameters ReadECParameters(PemObject pemObject)
+        //{
+        //    DerObjectIdentifier oid = (DerObjectIdentifier)Asn1Object.FromByteArray(pemObject.Content);
+
+        //    //return ECNamedCurveTable.getParameterSpec(oid.Id);
+        //    return GetCurveParameters(oid.Id);
+        //}
+
+        //private static X9ECParameters GetCurveParameters(string name)
+        //{
+        //    return ECKeyPairGenerator.FindECCurveByName(name) ?? throw new Exception("unknown curve name: " + name);
+        //}
     }
 }
diff --git a/crypto/src/openssl/PEMWriter.cs b/crypto/src/openssl/PEMWriter.cs
index 043869cc3..58b6156d5 100644
--- a/crypto/src/openssl/PEMWriter.cs
+++ b/crypto/src/openssl/PEMWriter.cs
@@ -17,26 +17,22 @@ namespace Org.BouncyCastle.OpenSsl
 
 		public void WriteObject(object obj) 
 		{
-			try
-			{
-				base.WriteObject(new MiscPemGenerator(obj));
-			}
-			catch (PemGenerationException e)
-			{
-				if (e.InnerException is IOException inner)
-					throw inner;
-
-				throw e;
-			}
+			WriteObject(obj, null, null, null);
 		}
 
-		public void WriteObject(
-			object			obj,
-			string			algorithm,
-			char[]			password,
-			SecureRandom	random)
+		public void WriteObject(object obj, string algorithm, char[] password, SecureRandom random)
 		{
-			base.WriteObject(new MiscPemGenerator(obj, algorithm, password, random));
+            try
+            {
+                base.WriteObject(new MiscPemGenerator(obj, algorithm, password, random));
+            }
+            catch (PemGenerationException e)
+            {
+                if (e.InnerException is IOException inner)
+                    throw inner;
+
+                throw e;
+            }
 		}
 	}
 }
diff --git a/crypto/src/util/io/pem/PemObject.cs b/crypto/src/util/io/pem/PemObject.cs
index 2a152f81d..ccba962af 100644
--- a/crypto/src/util/io/pem/PemObject.cs
+++ b/crypto/src/util/io/pem/PemObject.cs
@@ -6,9 +6,9 @@ namespace Org.BouncyCastle.Utilities.IO.Pem
 	public class PemObject
 		: PemObjectGenerator
 	{
-		private string type;
-		private IList<PemHeader> headers;
-		private byte[] content;
+		private readonly string m_type;
+		private readonly IList<PemHeader> m_headers;
+		private readonly byte[] m_content;
 
 		public PemObject(string type, byte[] content)
 			: this(type, new List<PemHeader>(), content)
@@ -17,24 +17,24 @@ namespace Org.BouncyCastle.Utilities.IO.Pem
 
 		public PemObject(string type, IList<PemHeader> headers, byte[] content)
 		{
-			this.type = type;
-            this.headers = new List<PemHeader>(headers);
-			this.content = content;
+			m_type = type;
+            m_headers = new List<PemHeader>(headers);
+			m_content = content;
 		}
 
 		public string Type
 		{
-			get { return type; }
+			get { return m_type; }
 		}
 
 		public IList<PemHeader> Headers
 		{
-			get { return headers; }
+			get { return m_headers; }
 		}
 
 		public byte[] Content
 		{
-			get { return content; }
+			get { return m_content; }
 		}
 
 		public PemObject Generate()
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();
         }
 	}
 }
diff --git a/crypto/src/util/io/pem/PemWriter.cs b/crypto/src/util/io/pem/PemWriter.cs
index ee92556c7..ce7b38821 100644
--- a/crypto/src/util/io/pem/PemWriter.cs
+++ b/crypto/src/util/io/pem/PemWriter.cs
@@ -13,9 +13,9 @@ namespace Org.BouncyCastle.Utilities.IO.Pem
 	{
 		private const int LineLength = 64;
 
-		private readonly TextWriter	writer;
-		private readonly int		nlLength;
-		private char[]				buf = new char[LineLength];
+		private readonly TextWriter m_writer;
+		private readonly int m_nlLength;
+		private readonly char[] m_buf = new char[LineLength];
 
 		/**
 		 * Base constructor.
@@ -24,8 +24,8 @@ namespace Org.BouncyCastle.Utilities.IO.Pem
 		 */
 		public PemWriter(TextWriter writer)
 		{
-			this.writer = writer ?? throw new ArgumentNullException(nameof(writer));
-            this.nlLength = Environment.NewLine.Length;
+			m_writer = writer ?? throw new ArgumentNullException(nameof(writer));
+            m_nlLength = Environment.NewLine.Length;
 		}
 
         #region IDisposable
@@ -40,7 +40,7 @@ namespace Org.BouncyCastle.Utilities.IO.Pem
         {
             if (disposing)
             {
-                writer.Dispose();
+                m_writer.Dispose();
             }
         }
 
@@ -48,7 +48,7 @@ namespace Org.BouncyCastle.Utilities.IO.Pem
 
         public TextWriter Writer
 		{
-			get { return writer; }
+			get { return m_writer; }
 		}
 
 		/**
@@ -61,22 +61,22 @@ namespace Org.BouncyCastle.Utilities.IO.Pem
 		public int GetOutputSize(PemObject obj)
 		{
 			// BEGIN and END boundaries.
-			int size = (2 * (obj.Type.Length + 10 + nlLength)) + 6 + 4;
+			int size = (2 * (obj.Type.Length + 10 + m_nlLength)) + 6 + 4;
 
 			if (obj.Headers.Count > 0)
 			{
 				foreach (PemHeader header in obj.Headers)
 				{
-					size += header.Name.Length + ": ".Length + header.Value.Length + nlLength;
+					size += header.Name.Length + ": ".Length + header.Value.Length + m_nlLength;
 				}
 
-				size += nlLength;
+				size += m_nlLength;
 			}
 
 			// base64 encoding
 			int dataLen = ((obj.Content.Length + 2) / 3) * 4;
 
-			size += dataLen + (((dataLen + LineLength - 1) / LineLength) * nlLength);
+			size += dataLen + (((dataLen + LineLength - 1) / LineLength) * m_nlLength);
 
 			return size;
 		}
@@ -91,12 +91,12 @@ namespace Org.BouncyCastle.Utilities.IO.Pem
 			{
 				foreach (PemHeader header in obj.Headers)
 				{
-					writer.Write(header.Name);
-					writer.Write(": ");
-					writer.WriteLine(header.Value);
+					m_writer.Write(header.Name);
+					m_writer.Write(": ");
+					m_writer.WriteLine(header.Value);
 				}
 
-				writer.WriteLine();
+				m_writer.WriteLine();
 			}
 
 			WriteEncoded(obj.Content);
@@ -107,29 +107,29 @@ namespace Org.BouncyCastle.Utilities.IO.Pem
 		{
 			bytes = Base64.Encode(bytes);
 
-			for (int i = 0; i < bytes.Length; i += buf.Length)
+			for (int i = 0; i < bytes.Length; i += m_buf.Length)
 			{
 				int index = 0;
-				while (index != buf.Length)
+				while (index != m_buf.Length)
 				{
 					if ((i + index) >= bytes.Length)
 						break;
 
-					buf[index] = (char)bytes[i + index];
+					m_buf[index] = (char)bytes[i + index];
 					index++;
 				}
-				writer.WriteLine(buf, 0, index);
+				m_writer.WriteLine(m_buf, 0, index);
 			}
 		}
 
 		private void WritePreEncapsulationBoundary(string type)
 		{
-			writer.WriteLine("-----BEGIN " + type + "-----");
+			m_writer.WriteLine("-----BEGIN " + type + "-----");
 		}
 
 		private void WritePostEncapsulationBoundary(string type)
 		{
-			writer.WriteLine("-----END " + type + "-----");
+			m_writer.WriteLine("-----END " + type + "-----");
 		}
     }
 }