summary refs log tree commit diff
path: root/crypto/src/asn1
diff options
context:
space:
mode:
authorPeter Dettman <peter.dettman@bouncycastle.org>2013-11-03 16:12:13 +0700
committerPeter Dettman <peter.dettman@bouncycastle.org>2013-11-03 16:12:13 +0700
commite346df986347cead043ca0fe952447bd484a5db3 (patch)
tree4738910f42ae60eb9b58aa618daabaed1fc5354e /crypto/src/asn1
parentAdd Poly1305 contributors entry (diff)
downloadBouncyCastle.NET-ed25519-e346df986347cead043ca0fe952447bd484a5db3.tar.xz
Port from Java of improvements to DerBoolean and DerEnumerated
Diffstat (limited to 'crypto/src/asn1')
-rw-r--r--crypto/src/asn1/Asn1InputStream.cs4
-rw-r--r--crypto/src/asn1/DerBoolean.cs86
-rw-r--r--crypto/src/asn1/DerEnumerated.cs68
3 files changed, 97 insertions, 61 deletions
diff --git a/crypto/src/asn1/Asn1InputStream.cs b/crypto/src/asn1/Asn1InputStream.cs
index a72049b56..5d5590655 100644
--- a/crypto/src/asn1/Asn1InputStream.cs
+++ b/crypto/src/asn1/Asn1InputStream.cs
@@ -319,9 +319,9 @@ namespace Org.BouncyCastle.Asn1
             switch (tagNo)
             {
                 case Asn1Tags.Boolean:
-                    return new DerBoolean(GetBuffer(defIn, tmpBuffers));
+                    return DerBoolean.FromOctetString(GetBuffer(defIn, tmpBuffers));
                 case Asn1Tags.Enumerated:
-                    return new DerEnumerated(GetBuffer(defIn, tmpBuffers));
+                    return DerEnumerated.FromOctetString(GetBuffer(defIn, tmpBuffers));
                 case Asn1Tags.ObjectIdentifier:
                     return DerObjectIdentifier.FromOctetString(GetBuffer(defIn, tmpBuffers));
             }
diff --git a/crypto/src/asn1/DerBoolean.cs b/crypto/src/asn1/DerBoolean.cs
index 41ccae8a1..66791d16c 100644
--- a/crypto/src/asn1/DerBoolean.cs
+++ b/crypto/src/asn1/DerBoolean.cs
@@ -7,10 +7,10 @@ namespace Org.BouncyCastle.Asn1
     {
         private readonly byte value;
 
-		public static readonly DerBoolean False = new DerBoolean(false);
+        public static readonly DerBoolean False = new DerBoolean(false);
         public static readonly DerBoolean True  = new DerBoolean(true);
 
-		/**
+        /**
          * return a bool from the passed in object.
          *
          * @exception ArgumentException if the object cannot be converted.
@@ -23,10 +23,10 @@ namespace Org.BouncyCastle.Asn1
                 return (DerBoolean) obj;
             }
 
-			throw new ArgumentException("illegal object in GetInstance: " + obj.GetType().Name);
+            throw new ArgumentException("illegal object in GetInstance: " + obj.GetType().Name);
         }
 
-		/**
+        /**
          * return a DerBoolean from the passed in bool.
          */
         public static DerBoolean GetInstance(
@@ -35,7 +35,7 @@ namespace Org.BouncyCastle.Asn1
             return value ? True : False;
         }
 
-		/**
+        /**
          * return a Boolean from a tagged object.
          *
          * @param obj the tagged object holding the object we want
@@ -48,63 +48,75 @@ namespace Org.BouncyCastle.Asn1
             Asn1TaggedObject	obj,
             bool				isExplicit)
         {
-			Asn1Object o = obj.GetObject();
+            Asn1Object o = obj.GetObject();
 
-			if (isExplicit || o is DerBoolean)
-			{
-				return GetInstance(o);
-			}
+            if (isExplicit || o is DerBoolean)
+            {
+                return GetInstance(o);
+            }
 
-			return new DerBoolean(((Asn1OctetString)o).GetOctets());
+            return FromOctetString(((Asn1OctetString)o).GetOctets());
         }
 
-		public DerBoolean(
+        public DerBoolean(
             byte[] val)
         {
-			if (val.Length != 1)
-				throw new ArgumentException("byte value should have 1 byte in it", "val");
+            if (val.Length != 1)
+                throw new ArgumentException("byte value should have 1 byte in it", "val");
 
-			// TODO Are there any constraints on the possible byte values?
+            // TODO Are there any constraints on the possible byte values?
             this.value = val[0];
         }
 
-		private DerBoolean(
+        private DerBoolean(
             bool value)
         {
             this.value = value ? (byte)0xff : (byte)0;
         }
 
-		public bool IsTrue
-		{
-			get { return value != 0; }
-		}
+        public bool IsTrue
+        {
+            get { return value != 0; }
+        }
 
-		internal override void Encode(
+        internal override void Encode(
             DerOutputStream derOut)
         {
-			// TODO Should we make sure the byte value is one of '0' or '0xff' here?
-			derOut.WriteEncoded(Asn1Tags.Boolean, new byte[]{ value });
+            // TODO Should we make sure the byte value is one of '0' or '0xff' here?
+            derOut.WriteEncoded(Asn1Tags.Boolean, new byte[]{ value });
         }
 
-		protected override bool Asn1Equals(
-			Asn1Object asn1Object)
+        protected override bool Asn1Equals(
+            Asn1Object asn1Object)
         {
-			DerBoolean other = asn1Object as DerBoolean;
+            DerBoolean other = asn1Object as DerBoolean;
 
-			if (other == null)
-				return false;
+            if (other == null)
+                return false;
 
-			return IsTrue == other.IsTrue;
+            return IsTrue == other.IsTrue;
+        }
+
+        protected override int Asn1GetHashCode()
+        {
+            return IsTrue.GetHashCode();
         }
 
-		protected override int Asn1GetHashCode()
-		{
-			return IsTrue.GetHashCode();
+        public override string ToString()
+        {
+            return IsTrue ? "TRUE" : "FALSE";
         }
 
-		public override string ToString()
-		{
-			return IsTrue ? "TRUE" : "FALSE";
-		}
-	}
+        internal static DerBoolean FromOctetString(byte[] value)
+        {
+            if (value.Length != 1)
+            {
+                throw new ArgumentException("BOOLEAN value should have 1 byte in it", "value");
+            }
+
+            byte b = value[0];
+
+            return b == 0 ? False : b == 0xFF ? True : new DerBoolean(value);
+        }
+    }
 }
diff --git a/crypto/src/asn1/DerEnumerated.cs b/crypto/src/asn1/DerEnumerated.cs
index a62afb301..2638b0205 100644
--- a/crypto/src/asn1/DerEnumerated.cs
+++ b/crypto/src/asn1/DerEnumerated.cs
@@ -10,7 +10,7 @@ namespace Org.BouncyCastle.Asn1
     {
         private readonly byte[] bytes;
 
-		/**
+        /**
          * return an integer from the passed in object
          *
          * @exception ArgumentException if the object cannot be converted.
@@ -39,14 +39,14 @@ namespace Org.BouncyCastle.Asn1
             Asn1TaggedObject	obj,
             bool				isExplicit)
         {
-			Asn1Object o = obj.GetObject();
+            Asn1Object o = obj.GetObject();
 
-			if (isExplicit || o is DerEnumerated)
-			{
-				return GetInstance(o);
-			}
+            if (isExplicit || o is DerEnumerated)
+            {
+                return GetInstance(o);
+            }
 
-			return new DerEnumerated(((Asn1OctetString)o).GetOctets());
+            return FromOctetString(((Asn1OctetString)o).GetOctets());
         }
 
         public DerEnumerated(
@@ -64,37 +64,61 @@ namespace Org.BouncyCastle.Asn1
         public DerEnumerated(
             byte[]   bytes)
         {
-            this.bytes = Arrays.Clone(bytes);
+            this.bytes = bytes;
         }
 
         public BigInteger Value
         {
-            get
-            {
-                return new BigInteger(bytes);
-            }
+            get { return new BigInteger(bytes); }
         }
 
-		internal override void Encode(
+        internal override void Encode(
             DerOutputStream derOut)
         {
             derOut.WriteEncoded(Asn1Tags.Enumerated, bytes);
         }
 
-		protected override bool Asn1Equals(
-			Asn1Object asn1Object)
+        protected override bool Asn1Equals(
+            Asn1Object asn1Object)
         {
-			DerEnumerated other = asn1Object as DerEnumerated;
+            DerEnumerated other = asn1Object as DerEnumerated;
+
+            if (other == null)
+                return false;
 
-			if (other == null)
-				return false;
+            return Arrays.AreEqual(this.bytes, other.bytes);
+        }
 
-			return Arrays.AreEqual(this.bytes, other.bytes);
+        protected override int Asn1GetHashCode()
+        {
+            return Arrays.GetHashCode(bytes);
         }
 
-		protected override int Asn1GetHashCode()
-		{
-			return Arrays.GetHashCode(bytes);
+        private static readonly DerEnumerated[] cache = new DerEnumerated[12];
+
+        internal static DerEnumerated FromOctetString(byte[] enc)
+        {
+            if (enc.Length == 0)
+            {
+                throw new ArgumentException("ENUMERATED has zero length", "enc");
+            }
+
+            if (enc.Length == 1)
+            {
+                int value = enc[0];
+                if (value < cache.Length)
+                {
+                    DerEnumerated cached = cache[value];
+                    if (cached != null)
+                    {
+                        return cached;
+                    }
+
+                    return cache[value] = new DerEnumerated(Arrays.Clone(enc));
+                }
+            }
+
+            return new DerEnumerated(Arrays.Clone(enc));
         }
     }
 }