summary refs log tree commit diff
path: root/crypto/src/asn1/DerInteger.cs
diff options
context:
space:
mode:
authorPeter Dettman <peter.dettman@bouncycastle.org>2019-08-09 16:50:54 +0700
committerPeter Dettman <peter.dettman@bouncycastle.org>2019-08-09 16:50:54 +0700
commita66c5d53fe0a051caacffe5daaf5cead5b482c09 (patch)
tree36e45bce1e4de9d951b4ea17d467a045f2437da9 /crypto/src/asn1/DerInteger.cs
parentAdd IntValueExact and LongValueExact to BigInteger (diff)
downloadBouncyCastle.NET-ed25519-a66c5d53fe0a051caacffe5daaf5cead5b482c09.tar.xz
ASN.1 updates from bc-java
- Integer cannot have empty contents octets
- Enumerated values can't be negative
Diffstat (limited to 'crypto/src/asn1/DerInteger.cs')
-rw-r--r--crypto/src/asn1/DerInteger.cs55
1 files changed, 35 insertions, 20 deletions
diff --git a/crypto/src/asn1/DerInteger.cs b/crypto/src/asn1/DerInteger.cs
index ae14d2a9f..fec7b9420 100644
--- a/crypto/src/asn1/DerInteger.cs
+++ b/crypto/src/asn1/DerInteger.cs
@@ -60,14 +60,12 @@ namespace Org.BouncyCastle.Asn1
 			return new DerInteger(Asn1OctetString.GetInstance(o).GetOctets());
         }
 
-		public DerInteger(
-            int value)
+		public DerInteger(int value)
         {
             bytes = BigInteger.ValueOf(value).ToByteArray();
         }
 
-		public DerInteger(
-            BigInteger value)
+		public DerInteger(BigInteger value)
         {
             if (value == null)
                 throw new ArgumentNullException("value");
@@ -75,27 +73,20 @@ namespace Org.BouncyCastle.Asn1
 			bytes = value.ToByteArray();
         }
 
-		public DerInteger(
-            byte[] bytes)
+        public DerInteger(byte[] bytes)
+            : this(bytes, true)
         {
-            if (bytes.Length > 1)
-            {
-                if ((bytes[0] == 0 && (bytes[1] & 0x80) == 0)
-                    || (bytes[0] == (byte)0xff && (bytes[1] & 0x80) != 0))
-                {
-                    if (!AllowUnsafe())
-                        throw new ArgumentException("malformed integer");
-                }
-            }
-            this.bytes = Arrays.Clone(bytes);
         }
 
-		public BigInteger Value
+        internal DerInteger(byte[] bytes, bool clone)
         {
-            get { return new BigInteger(bytes); }
+            if (IsMalformed(bytes))
+                throw new ArgumentException("malformed integer", "bytes");
+
+            this.bytes = clone ? Arrays.Clone(bytes) : bytes;
         }
 
-		/**
+        /**
          * in some cases positive values Get crammed into a space,
          * that's not quite big enough...
          */
@@ -104,6 +95,11 @@ namespace Org.BouncyCastle.Asn1
             get { return new BigInteger(1, bytes); }
         }
 
+        public BigInteger Value
+        {
+            get { return new BigInteger(bytes); }
+        }
+
         internal override void Encode(
             DerOutputStream derOut)
         {
@@ -130,5 +126,24 @@ namespace Org.BouncyCastle.Asn1
 		{
 			return Value.ToString();
 		}
-	}
+
+        /**
+         * Apply the correct validation for an INTEGER primitive following the BER rules.
+         *
+         * @param bytes The raw encoding of the integer.
+         * @return true if the (in)put fails this validation.
+         */
+        internal static bool IsMalformed(byte[] bytes)
+        {
+            switch (bytes.Length)
+            {
+            case 0:
+                return true;
+            case 1:
+                return false;
+            default:
+                return (sbyte)bytes[0] == ((sbyte)bytes[1] >> 7) && !AllowUnsafe();
+            }
+        }
+    }
 }