summary refs log tree commit diff
diff options
context:
space:
mode:
authorPeter Dettman <peter.dettman@bouncycastle.org>2021-11-10 00:38:54 +0700
committerPeter Dettman <peter.dettman@bouncycastle.org>2021-11-10 00:38:54 +0700
commit212ec41dd10152391c5218c0a6c98af31ff02d6f (patch)
tree5ebbddb7d80684c586884939b990e274f51d4558
parentAdd DLSequence, DLSet for internal use (diff)
downloadBouncyCastle.NET-ed25519-212ec41dd10152391c5218c0a6c98af31ff02d6f.tar.xz
Handle high tag numbers
-rw-r--r--crypto/src/asn1/DerTaggedObject.cs34
-rw-r--r--crypto/test/src/asn1/test/TagTest.cs13
2 files changed, 32 insertions, 15 deletions
diff --git a/crypto/src/asn1/DerTaggedObject.cs b/crypto/src/asn1/DerTaggedObject.cs
index 125d30ff2..b75e0879d 100644
--- a/crypto/src/asn1/DerTaggedObject.cs
+++ b/crypto/src/asn1/DerTaggedObject.cs
@@ -64,25 +64,33 @@ namespace Org.BouncyCastle.Asn1
         }
 
         internal override void Encode(Asn1OutputStream asn1Out, bool withID)
-		{
-			byte[] bytes = obj.GetDerEncoded();
+        {
+            byte[] bytes = obj.GetDerEncoded();
+
+            if (explicitly)
+            {
+                asn1Out.WriteEncodingDL(withID, Asn1Tags.Constructed | TagClass, TagNo, bytes);
+            }
+            else
+            {
+                int tagHdr = bytes[0], tagLen = 1;
+                if ((tagHdr & 0x1F) == 0x1F)
+                {
+                    while ((bytes[tagLen++] & 0x80) != 0)
+                    {
+                    }
+                }
 
-			if (explicitly)
-			{
-				asn1Out.WriteEncodingDL(withID, Asn1Tags.Constructed | TagClass, TagNo, bytes);
-			}
-			else
-			{
                 if (withID)
                 {
-                    // need to mark constructed types... (preserve Constructed tag)
-                    int flags = (bytes[0] & Asn1Tags.Constructed) | TagClass;
+                    int flags = (tagHdr & Asn1Tags.Constructed) | TagClass;
+
                     asn1Out.WriteIdentifier(true, flags, TagNo);
                 }
 
-                asn1Out.Write(bytes, 1, bytes.Length - 1);
-			}
-		}
+                asn1Out.Write(bytes, tagLen, bytes.Length - tagLen);
+            }
+        }
 
         internal override Asn1Sequence RebuildConstructed(Asn1Object asn1Object)
         {
diff --git a/crypto/test/src/asn1/test/TagTest.cs b/crypto/test/src/asn1/test/TagTest.cs
index 80ca2c0ea..fd6995c44 100644
--- a/crypto/test/src/asn1/test/TagTest.cs
+++ b/crypto/test/src/asn1/test/TagTest.cs
@@ -27,6 +27,8 @@ namespace Org.BouncyCastle.Asn1.Tests
 
 		private static readonly byte[] longAppSpecificTag = Hex.Decode("5F610101");
 
+        private static readonly byte[] taggedInteger = Hex.Decode("BF2203020101");
+
 		public override string Name
 		{
 			get { return "Tag"; }
@@ -100,9 +102,16 @@ namespace Org.BouncyCastle.Asn1.Tests
 					Fail("incorrect tag number read on recode (random test value: " + testTag + ")");
 				}
 			}
-		}
 
-		public static void Main(
+            tagged = new DerTaggedObject(false, 34, new DerTaggedObject(true, 1000, new DerInteger(1)));
+
+            if (!AreEqual(taggedInteger, tagged.GetEncoded()))
+            {
+                Fail("incorrect encoding for implicit explicit tagged integer");
+            }
+        }
+
+        public static void Main(
 			string[] args)
 		{
 			RunTest(new TagTest());