summary refs log tree commit diff
path: root/crypto/src/asn1/tsp/PartialHashtree.cs
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/src/asn1/tsp/PartialHashtree.cs')
-rw-r--r--crypto/src/asn1/tsp/PartialHashtree.cs86
1 files changed, 86 insertions, 0 deletions
diff --git a/crypto/src/asn1/tsp/PartialHashtree.cs b/crypto/src/asn1/tsp/PartialHashtree.cs
new file mode 100644
index 000000000..dea7c9e37
--- /dev/null
+++ b/crypto/src/asn1/tsp/PartialHashtree.cs
@@ -0,0 +1,86 @@
+using System;
+
+using Org.BouncyCastle.Utilities;
+using Org.BouncyCastle.Utilities.Collections;
+
+namespace Org.BouncyCastle.Asn1.Tsp
+{
+    /**
+     * Implementation of PartialHashtree, as defined in RFC 4998.
+     * <p/>
+     * The ASN.1 notation for a PartialHashTree is:
+     * <p/>
+     * PartialHashtree ::= SEQUENCE OF OCTET STRING
+     */
+    public class PartialHashtree
+        : Asn1Encodable
+    {
+        /**
+         * Return a PartialHashtree from the given object.
+         *
+         * @param obj the object we want converted.
+         * @return a PartialHashtree instance, or null.
+         * @throws IllegalArgumentException if the object cannot be converted.
+         */
+        public static PartialHashtree GetInstance(object obj)
+        {
+            if (obj == null)
+                return null;
+            if (obj is PartialHashtree partialHashtree)
+                return partialHashtree;
+            return new PartialHashtree(Asn1Sequence.GetInstance(obj));
+        }
+
+        public static PartialHashtree GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit)
+        {
+            return new PartialHashtree(Asn1Sequence.GetInstance(taggedObject, declaredExplicit));
+        }
+
+        /**
+         * Hash values that constitute the hash tree, as ASN.1 Octet Strings.
+         */
+        private readonly Asn1Sequence m_values;
+
+        private PartialHashtree(Asn1Sequence values)
+        {
+            for (int i = 0; i != values.Count; i++)
+            {
+                if (!(values[i] is Asn1OctetString))
+                    throw new ArgumentException("unknown object in constructor: " + Platform.GetTypeName(values[i]));
+            }
+            m_values = values;
+        }
+
+        public PartialHashtree(params byte[][] values)
+        {
+            Asn1EncodableVector v = new Asn1EncodableVector(values.Length);
+
+            for (int i = 0; i != values.Length; i++)
+            {
+                v.Add(new DerOctetString(Arrays.Clone(values[i])));
+            }
+
+            m_values = new DerSequence(v);
+        }
+
+        public virtual int ValueCount => m_values.Count;
+
+        public virtual byte[][] GetValues() => m_values.MapElements(
+            element => Arrays.Clone(Asn1OctetString.GetInstance(element).GetOctets()));
+
+        public virtual bool ContainsHash(byte[] hash)
+        {
+            foreach (Asn1OctetString octetString in m_values)
+            {
+                byte[] currentHash = octetString.GetOctets();
+
+                if (Arrays.FixedTimeEquals(hash, currentHash))
+                    return true;
+            }
+
+            return false;
+        }
+
+        public override Asn1Object ToAsn1Object() => m_values;
+    }
+}