summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--crypto/src/asn1/ASN1StreamParser.cs30
-rw-r--r--crypto/src/asn1/Asn1InputStream.cs16
-rw-r--r--crypto/src/asn1/Asn1TaggedObject.cs32
3 files changed, 40 insertions, 38 deletions
diff --git a/crypto/src/asn1/ASN1StreamParser.cs b/crypto/src/asn1/ASN1StreamParser.cs
index 5c6854e1d..f896227f8 100644
--- a/crypto/src/asn1/ASN1StreamParser.cs
+++ b/crypto/src/asn1/ASN1StreamParser.cs
@@ -98,33 +98,13 @@ namespace Org.BouncyCastle.Asn1
             if (!constructed)
 			{
                 // Note: !CONSTRUCTED => IMPLICIT
-                DefiniteLengthInputStream defIn = (DefiniteLengthInputStream)_in;
-                byte[] contentsOctets = defIn.ToArray();
-
-                if (Asn1Tags.Application == tagClass)
-                    return new DerApplicationSpecific(false, tagNo, contentsOctets);
-
-                return new DLTaggedObject(false, tagNo, new DerOctetString(contentsOctets));
+                byte[] contentsOctets = ((DefiniteLengthInputStream)_in).ToArray();
+                return Asn1TaggedObject.CreatePrimitive(tagClass, tagNo, contentsOctets);
 			}
 
-			Asn1EncodableVector contentsElements = ReadVector();
-
-			if (_in is IndefiniteLengthInputStream)
-			{
-                if (Asn1Tags.Application == tagClass)
-                    return new BerApplicationSpecific(tagNo, contentsElements);
-
-                return contentsElements.Count == 1
-					?   new BerTaggedObject(true, tagNo, contentsElements[0])
-					:   new BerTaggedObject(false, tagNo, BerSequence.FromVector(contentsElements));
-			}
-
-            if (Asn1Tags.Application == tagClass)
-                return new DerApplicationSpecific(tagNo, contentsElements);
-
-            return contentsElements.Count == 1
-				?   new DLTaggedObject(true, tagNo, contentsElements[0])
-				:   new DLTaggedObject(false, tagNo, DLSequence.FromVector(contentsElements));
+            bool isIL = (_in is IndefiniteLengthInputStream);
+            Asn1EncodableVector contentsElements = ReadVector();
+            return Asn1TaggedObject.CreateConstructed(tagClass, tagNo, isIL, contentsElements);
 		}
 
 		public virtual IAsn1Convertible ReadObject()
diff --git a/crypto/src/asn1/Asn1InputStream.cs b/crypto/src/asn1/Asn1InputStream.cs
index 6e097e86d..3f7a65cc9 100644
--- a/crypto/src/asn1/Asn1InputStream.cs
+++ b/crypto/src/asn1/Asn1InputStream.cs
@@ -107,23 +107,13 @@ namespace Org.BouncyCastle.Asn1
         {
             if (!constructed)
             {
-                // Note: !CONSTRUCTED => IMPLICIT
                 byte[] contentsOctets = defIn.ToArray();
-
-                if (Asn1Tags.Application == tagClass)
-                    return new DerApplicationSpecific(false, tagNo, contentsOctets);
-
-                return new DLTaggedObject(false, tagNo, new DerOctetString(contentsOctets));
+                return Asn1TaggedObject.CreatePrimitive(tagClass, tagNo, contentsOctets);
             }
 
+            bool isIL = false;
             Asn1EncodableVector contentsElements = ReadVector(defIn);
-
-            if (Asn1Tags.Application == tagClass)
-                return new DerApplicationSpecific(tagNo, contentsElements);
-
-            return contentsElements.Count == 1
-                ? new DLTaggedObject(true, tagNo, contentsElements[0])
-                : new DLTaggedObject(false, tagNo, DLSequence.FromVector(contentsElements));
+            return Asn1TaggedObject.CreateConstructed(tagClass, tagNo, isIL, contentsElements);
         }
 
         internal virtual Asn1EncodableVector ReadVector()
diff --git a/crypto/src/asn1/Asn1TaggedObject.cs b/crypto/src/asn1/Asn1TaggedObject.cs
index 9f7eab576..aaa719ecc 100644
--- a/crypto/src/asn1/Asn1TaggedObject.cs
+++ b/crypto/src/asn1/Asn1TaggedObject.cs
@@ -284,6 +284,38 @@ namespace Org.BouncyCastle.Asn1
 
         internal abstract Asn1Sequence RebuildConstructed(Asn1Object asn1Object);
 
+        internal static Asn1Object CreateConstructed(int tagClass, int tagNo, bool isIL,
+            Asn1EncodableVector contentsElements)
+        {
+            bool maybeExplicit = (contentsElements.Count == 1);
+
+            if (isIL)
+            {
+                if (Asn1Tags.Application == tagClass)
+                    return new BerApplicationSpecific(tagNo, contentsElements);
+
+                return maybeExplicit
+                    ? new BerTaggedObject(true, tagNo, contentsElements[0])
+                    : new BerTaggedObject(false, tagNo, BerSequence.FromVector(contentsElements));
+            }
+
+            if (Asn1Tags.Application == tagClass)
+                return new DerApplicationSpecific(tagNo, contentsElements);
+
+            return maybeExplicit
+                ? new DLTaggedObject(true, tagNo, contentsElements[0])
+                : new DLTaggedObject(false, tagNo, DLSequence.FromVector(contentsElements));
+        }
+
+        internal static Asn1Object CreatePrimitive(int tagClass, int tagNo, byte[] contentsOctets)
+        {
+            // Note: !CONSTRUCTED => IMPLICIT
+            if (Asn1Tags.Application == tagClass)
+                return new DerApplicationSpecific(false, tagNo, contentsOctets);
+
+            return new DLTaggedObject(false, tagNo, new DerOctetString(contentsOctets));
+        }
+
         private static Asn1TaggedObject CheckedCast(Asn1Object asn1Object)
         {
             Asn1TaggedObject taggedObject = asn1Object as Asn1TaggedObject;