summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--crypto/src/asn1/Asn1InputStream.cs3
-rw-r--r--crypto/src/asn1/DerObjectIdentifier.cs41
2 files changed, 24 insertions, 20 deletions
diff --git a/crypto/src/asn1/Asn1InputStream.cs b/crypto/src/asn1/Asn1InputStream.cs
index d7edae9e0..1791e5356 100644
--- a/crypto/src/asn1/Asn1InputStream.cs
+++ b/crypto/src/asn1/Asn1InputStream.cs
@@ -392,7 +392,8 @@ namespace Org.BouncyCastle.Asn1
                 case Asn1Tags.Enumerated:
                     return DerEnumerated.FromOctetString(GetBuffer(defIn, tmpBuffers));
                 case Asn1Tags.ObjectIdentifier:
-                    return DerObjectIdentifier.FromOctetString(GetBuffer(defIn, tmpBuffers));
+                    // TODO Ideally only clone if we used a buffer
+                    return DerObjectIdentifier.CreatePrimitive(GetBuffer(defIn, tmpBuffers), true);
             }
 
             byte[] bytes = defIn.ToArray();
diff --git a/crypto/src/asn1/DerObjectIdentifier.cs b/crypto/src/asn1/DerObjectIdentifier.cs
index 9a0571b57..29bd35e84 100644
--- a/crypto/src/asn1/DerObjectIdentifier.cs
+++ b/crypto/src/asn1/DerObjectIdentifier.cs
@@ -11,9 +11,13 @@ namespace Org.BouncyCastle.Asn1
     public class DerObjectIdentifier
         : Asn1Object
     {
-        private readonly string identifier;
+        public static DerObjectIdentifier FromContents(byte[] contents)
+        {
+            return CreatePrimitive(contents, true);
+        }
 
-        private byte[] body = null;
+        private readonly string identifier;
+        private byte[] contents;
 
         /**
          * return an Oid from the passed in object
@@ -34,7 +38,7 @@ namespace Org.BouncyCastle.Asn1
             }
 
             if (obj is byte[])
-                return FromOctetString((byte[])obj);
+                return (DerObjectIdentifier)FromByteArray((byte[])obj);
 
             throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj), "obj");
         }
@@ -59,7 +63,7 @@ namespace Org.BouncyCastle.Asn1
                 return GetInstance(o);
             }
 
-            return FromOctetString(Asn1OctetString.GetInstance(o).GetOctets());
+            return FromContents(Asn1OctetString.GetInstance(o).GetOctets());
         }
 
         public DerObjectIdentifier(
@@ -103,10 +107,10 @@ namespace Org.BouncyCastle.Asn1
             return id.Length > stemId.Length && id[stemId.Length] == '.' && Platform.StartsWith(id, stemId);
         }
 
-        internal DerObjectIdentifier(byte[] bytes)
+        internal DerObjectIdentifier(byte[] contents, bool clone)
         {
-            this.identifier = MakeOidStringFromBytes(bytes);
-            this.body = Arrays.Clone(bytes);
+            this.identifier = MakeOidStringFromBytes(contents);
+            this.contents = clone ? Arrays.Clone(contents) : contents;
         }
 
         private void WriteField(
@@ -178,25 +182,24 @@ namespace Org.BouncyCastle.Asn1
             }
         }
 
-        internal byte[] GetBody()
+        private byte[] GetContents()
         {
             lock (this)
             {
-                if (body == null)
+                if (contents == null)
                 {
                     MemoryStream bOut = new MemoryStream();
                     DoOutput(bOut);
-                    body = bOut.ToArray();
+                    contents = bOut.ToArray();
                 }
-            }
 
-            return body;
+                return contents;
+            }
         }
 
-        internal override void Encode(
-            DerOutputStream derOut)
+        internal override void Encode(DerOutputStream derOut)
         {
-            derOut.WriteEncoded(Asn1Tags.ObjectIdentifier, GetBody());
+            derOut.WriteEncoded(Asn1Tags.ObjectIdentifier, GetContents());
         }
 
         protected override int Asn1GetHashCode()
@@ -344,20 +347,20 @@ namespace Org.BouncyCastle.Asn1
 
         private static readonly DerObjectIdentifier[] cache = new DerObjectIdentifier[1024];
 
-        internal static DerObjectIdentifier FromOctetString(byte[] enc)
+        internal static DerObjectIdentifier CreatePrimitive(byte[] contents, bool clone)
         {
-            int hashCode = Arrays.GetHashCode(enc);
+            int hashCode = Arrays.GetHashCode(contents);
             int first = hashCode & 1023;
 
             lock (cache)
             {
                 DerObjectIdentifier entry = cache[first];
-                if (entry != null && Arrays.AreEqual(enc, entry.GetBody()))
+                if (entry != null && Arrays.AreEqual(contents, entry.GetContents()))
                 {
                     return entry;
                 }
 
-                return cache[first] = new DerObjectIdentifier(enc);
+                return cache[first] = new DerObjectIdentifier(contents, clone);
             }
         }
     }