summary refs log tree commit diff
path: root/crypto/src/asn1/ConstructedDerEncoding.cs
diff options
context:
space:
mode:
authorPeter Dettman <peter.dettman@bouncycastle.org>2023-03-07 16:24:01 +0700
committerPeter Dettman <peter.dettman@bouncycastle.org>2023-03-07 16:24:01 +0700
commite78d715bfd0c981d5f11dfae4442491289ad5690 (patch)
tree58550dec8481292a828d50b41d558602f0ff22ec /crypto/src/asn1/ConstructedDerEncoding.cs
parentRemove lazy ASN.1 behaviour (diff)
downloadBouncyCastle.NET-ed25519-e78d715bfd0c981d5f11dfae4442491289ad5690.tar.xz
Sort DER sets without encoding elements
Diffstat (limited to 'crypto/src/asn1/ConstructedDerEncoding.cs')
-rw-r--r--crypto/src/asn1/ConstructedDerEncoding.cs52
1 files changed, 52 insertions, 0 deletions
diff --git a/crypto/src/asn1/ConstructedDerEncoding.cs b/crypto/src/asn1/ConstructedDerEncoding.cs
new file mode 100644
index 000000000..3df7841e8
--- /dev/null
+++ b/crypto/src/asn1/ConstructedDerEncoding.cs
@@ -0,0 +1,52 @@
+using System;
+using System.Diagnostics;
+
+namespace Org.BouncyCastle.Asn1
+{
+    internal class ConstructedDerEncoding
+        : DerEncoding
+    {
+        private readonly DerEncoding[] m_contentsElements;
+        private readonly int m_contentsLength;
+
+        internal ConstructedDerEncoding(int tagClass, int tagNo, DerEncoding[] contentsElements)
+            : base(tagClass, tagNo)
+        {
+            Debug.Assert(contentsElements != null);
+            m_contentsElements = contentsElements;
+            m_contentsLength = Asn1OutputStream.GetLengthOfContents(contentsElements);
+        }
+
+        protected internal override int CompareLengthAndContents(DerEncoding other)
+        {
+            if (!(other is ConstructedDerEncoding that))
+                throw new InvalidOperationException();
+
+            if (this.m_contentsLength != that.m_contentsLength)
+                return this.m_contentsLength - that.m_contentsLength;
+
+            int length = System.Math.Min(this.m_contentsElements.Length, that.m_contentsElements.Length);
+            for (int i = 0; i < length; i++)
+            {
+                int c = this.m_contentsElements[i].CompareTo(that.m_contentsElements[i]);
+                if (c != 0)
+                    return c;
+            }
+
+            Debug.Assert(this.m_contentsElements.Length == that.m_contentsElements.Length);
+            return this.m_contentsElements.Length - that.m_contentsElements.Length;
+        }
+
+        public override void Encode(Asn1OutputStream asn1Out)
+        {
+            asn1Out.WriteIdentifier(Asn1Tags.Constructed | m_tagClass, m_tagNo);
+            asn1Out.WriteDL(m_contentsLength);
+            asn1Out.EncodeContents(m_contentsElements);
+        }
+
+        public override int GetLength()
+        {
+            return Asn1OutputStream.GetLengthOfEncodingDL(m_tagNo, m_contentsLength);
+        }
+    }
+}