summary refs log tree commit diff
path: root/crypto/src/asn1/Asn1OutputStream.cs
diff options
context:
space:
mode:
authorPeter Dettman <peter.dettman@bouncycastle.org>2021-11-16 22:37:52 +0700
committerPeter Dettman <peter.dettman@bouncycastle.org>2021-11-16 22:37:52 +0700
commitbe15049124860ccb7335b92215e8b8dfa1821bf9 (patch)
tree7a86ed2110021307465a617076d601ca812c69ed /crypto/src/asn1/Asn1OutputStream.cs
parentMake cast more specific (diff)
downloadBouncyCastle.NET-ed25519-be15049124860ccb7335b92215e8b8dfa1821bf9.tar.xz
ASN.1: Staged encoding
Diffstat (limited to 'crypto/src/asn1/Asn1OutputStream.cs')
-rw-r--r--crypto/src/asn1/Asn1OutputStream.cs179
1 files changed, 54 insertions, 125 deletions
diff --git a/crypto/src/asn1/Asn1OutputStream.cs b/crypto/src/asn1/Asn1OutputStream.cs
index eeca2754c..096b569e3 100644
--- a/crypto/src/asn1/Asn1OutputStream.cs
+++ b/crypto/src/asn1/Asn1OutputStream.cs
@@ -37,7 +37,7 @@ namespace Org.BouncyCastle.Asn1
             if (null == asn1Encodable)
                 throw new ArgumentNullException("asn1Encodable");
 
-            asn1Encodable.ToAsn1Object().Encode(this, true);
+            asn1Encodable.ToAsn1Object().GetEncoding(this.Encoding).Encode(this);
             FlushInternal();
         }
 
@@ -46,18 +46,16 @@ namespace Org.BouncyCastle.Asn1
             if (null == asn1Object)
                 throw new ArgumentNullException("asn1Object");
 
-            asn1Object.Encode(this, true);
+            asn1Object.GetEncoding(this.Encoding).Encode(this);
             FlushInternal();
         }
 
-        internal void FlushInternal()
+        internal void EncodeContents(IAsn1Encoding[] contentsEncodings)
         {
-            // Placeholder to support future internal buffering
-        }
-
-        internal virtual DerOutputStreamNew GetDerSubStream()
-        {
-            return new DerOutputStreamNew(s);
+            for (int i = 0, count = contentsEncodings.Length; i < count; ++i)
+            {
+                contentsEncodings[i].Encode(this);
+            }
         }
 
         internal virtual int Encoding
@@ -65,136 +63,77 @@ namespace Org.BouncyCastle.Asn1
             get { return EncodingBer; }
         }
 
-        internal void WriteDL(int length)
+        internal void FlushInternal()
         {
-            if (length < 128)
-            {
-                WriteByte((byte)length);
-            }
-            else
-            {
-                byte[] stack = new byte[5];
-                int pos = stack.Length;
-
-                do
-                {
-                    stack[--pos] = (byte)length;
-                    length >>= 8;
-                }
-                while (length > 0);
-
-                int count = stack.Length - pos;
-                stack[--pos] = (byte)(0x80 | count);
-
-                Write(stack, pos, count + 1);
-            }
+            // Placeholder to support future internal buffering
         }
 
-        internal virtual void WriteElements(Asn1Encodable[] elements)
+        internal void WriteDL(int dl)
         {
-            for (int i = 0, count = elements.Length; i < count; ++i)
+            if (dl < 128)
             {
-                elements[i].ToAsn1Object().Encode(this, true);
+                WriteByte((byte)dl);
+                return;
             }
-        }
 
-        internal void WriteEncodingDL(bool withID, int identifier, byte contents)
-        {
-            WriteIdentifier(withID, identifier);
-            WriteDL(1);
-            WriteByte(contents);
-        }
-
-        internal void WriteEncodingDL(bool withID, int identifier, byte[] contents)
-        {
-            WriteIdentifier(withID, identifier);
-            WriteDL(contents.Length);
-            Write(contents, 0, contents.Length);
-        }
-
-        internal void WriteEncodingDL(bool withID, int identifier, byte[] contents, int contentsOff, int contentsLen)
-        {
-            WriteIdentifier(withID, identifier);
-            WriteDL(contentsLen);
-            Write(contents, contentsOff, contentsLen);
-        }
+            byte[] stack = new byte[5];
+            int pos = stack.Length;
 
-        internal void WriteEncodingDL(bool withID, int identifier, byte contentsPrefix, byte[] contents,
-            int contentsOff, int contentsLen)
-        {
-            WriteIdentifier(withID, identifier);
-            WriteDL(1 + contentsLen);
-            WriteByte(contentsPrefix);
-            Write(contents, contentsOff, contentsLen);
-        }
+            do
+            {
+                stack[--pos] = (byte)dl;
+                dl >>= 8;
+            }
+            while (dl > 0);
 
-        internal void WriteEncodingDL(bool withID, int identifier, byte[] contents, int contentsOff, int contentsLen,
-            byte contentsSuffix)
-        {
-            WriteIdentifier(withID, identifier);
-            WriteDL(contentsLen + 1);
-            Write(contents, contentsOff, contentsLen);
-            WriteByte(contentsSuffix);
-        }
+            int count = stack.Length - pos;
+            stack[--pos] = (byte)(0x80 | count);
 
-        internal void WriteEncodingDL(bool withID, int flags, int tag, byte[] contents)
-        {
-            WriteIdentifier(withID, flags, tag);
-            WriteDL(contents.Length);
-            Write(contents, 0, contents.Length);
+            Write(stack, pos, count + 1);
         }
 
-        internal void WriteEncodingIL(bool withID, int identifier, Asn1Encodable[] elements)
+        internal void WriteIdentifier(int tagClass, int tagNo)
         {
-            WriteIdentifier(withID, identifier);
-            WriteByte(0x80);
-            WriteElements(elements);
-            WriteByte(0x00);
-            WriteByte(0x00);
-        }
-
-        internal void WriteIdentifier(bool withID, int identifier)
-        {
-            if (withID)
+            if (tagNo < 31)
             {
-                WriteByte((byte)identifier);
+                WriteByte((byte)(tagClass | tagNo));
+                return;
             }
-        }
 
-        internal void WriteIdentifier(bool withID, int flags, int tag)
-        {
-            if (!withID)
-            {
-                // Don't write the identifier
-            }
-            else if (tag < 31)
+            byte[] stack = new byte[6];
+            int pos = stack.Length;
+
+            stack[--pos] = (byte)(tagNo & 0x7F);
+            while (tagNo > 127)
             {
-                WriteByte((byte)(flags | tag));
+                tagNo >>= 7;
+                stack[--pos] = (byte)(tagNo & 0x7F | 0x80);
             }
-            else
-            {
-                byte[] stack = new byte[6];
-                int pos = stack.Length;
 
-                stack[--pos] = (byte)(tag & 0x7F);
-                while (tag > 127)
-                {
-                    tag >>= 7;
-                    stack[--pos] = (byte)(tag & 0x7F | 0x80);
-                }
+            stack[--pos] = (byte)(tagClass | 0x1F);
 
-                stack[--pos] = (byte)(flags | 0x1F);
+            Write(stack, pos, stack.Length - pos);
+        }
 
-                Write(stack, pos, stack.Length - pos);
+        internal static IAsn1Encoding[] GetContentsEncodings(int encoding, Asn1Encodable[] elements)
+        {
+            int count = elements.Length;
+            IAsn1Encoding[] contentsEncodings = new IAsn1Encoding[count];
+            for (int i = 0; i < count; ++i)
+            {
+                contentsEncodings[i] = elements[i].ToAsn1Object().GetEncoding(encoding);
             }
+            return contentsEncodings;
         }
 
-        internal void WritePrimitives(Asn1Object[] primitives)
+        internal static int GetLengthOfContents(IAsn1Encoding[] contentsEncodings)
         {
-            for (int i = 0, count = primitives.Length; i < count; ++i)
+            int contentsLength = 0;
+            for (int i = 0, count = contentsEncodings.Length; i < count; ++i)
             {
-                primitives[i].Encode(this, true);
+                contentsLength += contentsEncodings[i].GetLength();
             }
+            return contentsLength;
         }
 
         internal static int GetLengthOfDL(int dl)
@@ -210,23 +149,13 @@ namespace Org.BouncyCastle.Asn1
             return length;
         }
 
-        internal static int GetLengthOfEncodingDL(bool withID, int contentsLength)
-        {
-            return (withID ? 1 : 0) + GetLengthOfDL(contentsLength) + contentsLength;
-        }
-
-        internal static int GetLengthOfEncodingDL(bool withID, int tag, int contentsLength)
-        {
-            return (withID ? GetLengthOfIdentifier(tag) : 0) + GetLengthOfDL(contentsLength) + contentsLength;
-        }
-
-        internal static int GetLengthOfIdentifier(int tag)
+        internal static int GetLengthOfIdentifier(int tagNo)
         {
-            if (tag < 31)
+            if (tagNo < 31)
                 return 1;
 
             int length = 2;
-            while ((tag >>= 7) > 0)
+            while ((tagNo >>= 7) > 0)
             {
                 ++length;
             }