summary refs log tree commit diff
path: root/Crypto/src/asn1/DerOutputStream.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Crypto/src/asn1/DerOutputStream.cs')
-rw-r--r--Crypto/src/asn1/DerOutputStream.cs160
1 files changed, 160 insertions, 0 deletions
diff --git a/Crypto/src/asn1/DerOutputStream.cs b/Crypto/src/asn1/DerOutputStream.cs
new file mode 100644
index 000000000..f95d123f9
--- /dev/null
+++ b/Crypto/src/asn1/DerOutputStream.cs
@@ -0,0 +1,160 @@
+using System;
+using System.IO;
+
+using Org.BouncyCastle.Asn1.Utilities;
+
+namespace Org.BouncyCastle.Asn1
+{
+	public class DerOutputStream
+		: FilterStream
+	{
+		public DerOutputStream(Stream os)
+			: base(os)
+		{
+		}
+
+		private void WriteLength(
+			int length)
+		{
+			if (length > 127)
+			{
+				int size = 1;
+				uint val = (uint) length;
+
+				while ((val >>= 8) != 0)
+				{
+					size++;
+				}
+
+				WriteByte((byte)(size | 0x80));
+
+				for (int i = (size - 1) * 8; i >= 0; i -= 8)
+				{
+					WriteByte((byte)(length >> i));
+				}
+			}
+			else
+			{
+				WriteByte((byte)length);
+			}
+		}
+
+		internal void WriteEncoded(
+			int		tag,
+			byte[]	bytes)
+		{
+			WriteByte((byte) tag);
+			WriteLength(bytes.Length);
+			Write(bytes, 0, bytes.Length);
+		}
+
+		internal void WriteEncoded(
+			int		tag,
+			byte[]	bytes,
+			int		offset,
+			int		length)
+		{
+			WriteByte((byte) tag);
+			WriteLength(length);
+			Write(bytes, offset, length);
+		}
+
+		internal void WriteTag(
+			int	flags,
+			int	tagNo)
+		{
+			if (tagNo < 31)
+			{
+				WriteByte((byte)(flags | tagNo));
+			}
+			else
+			{
+				WriteByte((byte)(flags | 0x1f));
+				if (tagNo < 128)
+				{
+					WriteByte((byte)tagNo);
+				}
+				else
+				{
+					byte[] stack = new byte[5];
+					int pos = stack.Length;
+
+					stack[--pos] = (byte)(tagNo & 0x7F);
+
+					do
+					{
+						tagNo >>= 7;
+						stack[--pos] = (byte)(tagNo & 0x7F | 0x80);
+					}
+					while (tagNo > 127);
+
+					Write(stack, pos, stack.Length - pos);
+				}
+			}
+		}
+
+		internal void WriteEncoded(
+			int		flags,
+			int		tagNo,
+			byte[]	bytes)
+		{
+			WriteTag(flags, tagNo);
+			WriteLength(bytes.Length);
+			Write(bytes, 0, bytes.Length);
+		}
+
+		protected void WriteNull()
+		{
+			WriteByte(Asn1Tags.Null);
+			WriteByte(0x00);
+		}
+
+		[Obsolete("Use version taking an Asn1Encodable arg instead")]
+		public virtual void WriteObject(
+			object obj)
+		{
+			if (obj == null)
+			{
+				WriteNull();
+			}
+			else if (obj is Asn1Object)
+			{
+				((Asn1Object)obj).Encode(this);
+			}
+			else if (obj is Asn1Encodable)
+			{
+				((Asn1Encodable)obj).ToAsn1Object().Encode(this);
+			}
+			else
+			{
+				throw new IOException("object not Asn1Object");
+			}
+		}
+
+		public virtual void WriteObject(
+			Asn1Encodable obj)
+		{
+			if (obj == null)
+			{
+				WriteNull();
+			}
+			else
+			{
+				obj.ToAsn1Object().Encode(this);
+			}
+		}
+
+		public virtual void WriteObject(
+			Asn1Object obj)
+		{
+			if (obj == null)
+			{
+				WriteNull();
+			}
+			else
+			{
+				obj.Encode(this);
+			}
+		}
+	}
+}