diff options
author | Peter Dettman <peter.dettman@bouncycastle.org> | 2021-11-11 15:24:08 +0700 |
---|---|---|
committer | Peter Dettman <peter.dettman@bouncycastle.org> | 2021-11-11 15:24:08 +0700 |
commit | 46222a965fb85dfd5fdaf0ad273bb98e232d2b81 (patch) | |
tree | 1132d2f8523b3589b266b41c3505369482e76b8a | |
parent | ASN.1: Update encoding in line with bc-java (diff) | |
download | BouncyCastle.NET-ed25519-46222a965fb85dfd5fdaf0ad273bb98e232d2b81.tar.xz |
Add DLTaggedObject and use from parser
-rw-r--r-- | crypto/BouncyCastle.Android.csproj | 1 | ||||
-rw-r--r-- | crypto/BouncyCastle.csproj | 1 | ||||
-rw-r--r-- | crypto/BouncyCastle.iOS.csproj | 1 | ||||
-rw-r--r-- | crypto/crypto.csproj | 5 | ||||
-rw-r--r-- | crypto/src/asn1/ASN1StreamParser.cs | 6 | ||||
-rw-r--r-- | crypto/src/asn1/DLTaggedObject.cs | 110 | ||||
-rw-r--r-- | crypto/test/src/asn1/test/InputStreamTest.cs | 2 |
7 files changed, 122 insertions, 4 deletions
diff --git a/crypto/BouncyCastle.Android.csproj b/crypto/BouncyCastle.Android.csproj index 8d7900444..0cececb3f 100644 --- a/crypto/BouncyCastle.Android.csproj +++ b/crypto/BouncyCastle.Android.csproj @@ -134,6 +134,7 @@ <Compile Include="src\asn1\DerVisibleString.cs" /> <Compile Include="src\asn1\DLSequence.cs" /> <Compile Include="src\asn1\DLSet.cs" /> + <Compile Include="src\asn1\DLTaggedObject.cs" /> <Compile Include="src\asn1\IAsn1ApplicationSpecificParser.cs" /> <Compile Include="src\asn1\IAsn1Choice.cs" /> <Compile Include="src\asn1\IAsn1Convertible.cs" /> diff --git a/crypto/BouncyCastle.csproj b/crypto/BouncyCastle.csproj index 495b55220..2e82e2432 100644 --- a/crypto/BouncyCastle.csproj +++ b/crypto/BouncyCastle.csproj @@ -128,6 +128,7 @@ <Compile Include="src\asn1\DerVisibleString.cs" /> <Compile Include="src\asn1\DLSequence.cs" /> <Compile Include="src\asn1\DLSet.cs" /> + <Compile Include="src\asn1\DLTaggedObject.cs" /> <Compile Include="src\asn1\IAsn1ApplicationSpecificParser.cs" /> <Compile Include="src\asn1\IAsn1Choice.cs" /> <Compile Include="src\asn1\IAsn1Convertible.cs" /> diff --git a/crypto/BouncyCastle.iOS.csproj b/crypto/BouncyCastle.iOS.csproj index 9333ba1e5..29031b947 100644 --- a/crypto/BouncyCastle.iOS.csproj +++ b/crypto/BouncyCastle.iOS.csproj @@ -129,6 +129,7 @@ <Compile Include="src\asn1\DerVisibleString.cs" /> <Compile Include="src\asn1\DLSequence.cs" /> <Compile Include="src\asn1\DLSet.cs" /> + <Compile Include="src\asn1\DLTaggedObject.cs" /> <Compile Include="src\asn1\IAsn1ApplicationSpecificParser.cs" /> <Compile Include="src\asn1\IAsn1Choice.cs" /> <Compile Include="src\asn1\IAsn1Convertible.cs" /> diff --git a/crypto/crypto.csproj b/crypto/crypto.csproj index 8c5f70e30..b490065e0 100644 --- a/crypto/crypto.csproj +++ b/crypto/crypto.csproj @@ -529,6 +529,11 @@ BuildAction = "Compile" /> <File + RelPath = "src\asn1\DLTaggedObject.cs" + SubType = "Code" + BuildAction = "Compile" + /> + <File RelPath = "src\asn1\IAsn1ApplicationSpecificParser.cs" SubType = "Code" BuildAction = "Compile" diff --git a/crypto/src/asn1/ASN1StreamParser.cs b/crypto/src/asn1/ASN1StreamParser.cs index 0a575c8c5..55b5bc656 100644 --- a/crypto/src/asn1/ASN1StreamParser.cs +++ b/crypto/src/asn1/ASN1StreamParser.cs @@ -99,7 +99,7 @@ namespace Org.BouncyCastle.Asn1 { // Note: !CONSTRUCTED => IMPLICIT DefiniteLengthInputStream defIn = (DefiniteLengthInputStream)_in; - return new DerTaggedObject(false, tag, new DerOctetString(defIn.ToArray())); + return new DLTaggedObject(false, tag, new DerOctetString(defIn.ToArray())); } Asn1EncodableVector v = ReadVector(); @@ -112,8 +112,8 @@ namespace Org.BouncyCastle.Asn1 } return v.Count == 1 - ? new DerTaggedObject(true, tag, v[0]) - : new DerTaggedObject(false, tag, DLSequence.FromVector(v)); + ? new DLTaggedObject(true, tag, v[0]) + : new DLTaggedObject(false, tag, DLSequence.FromVector(v)); } public virtual IAsn1Convertible ReadObject() diff --git a/crypto/src/asn1/DLTaggedObject.cs b/crypto/src/asn1/DLTaggedObject.cs new file mode 100644 index 000000000..a5135f2a5 --- /dev/null +++ b/crypto/src/asn1/DLTaggedObject.cs @@ -0,0 +1,110 @@ +using System; + +namespace Org.BouncyCastle.Asn1 +{ + internal class DLTaggedObject + : DerTaggedObject + { + private int m_contentsLengthDL = -1; + + internal DLTaggedObject(int tagNo, Asn1Encodable obj) + : base(tagNo, obj) + { + } + + internal DLTaggedObject(bool explicitly, int tagNo, Asn1Encodable obj) + : base(explicitly, tagNo, obj) + { + } + + internal DLTaggedObject(int tagNo) + : base(false, tagNo, BerSequence.Empty) + { + } + + internal override string Asn1Encoding + { + // TODO[asn1] Use DL encoding when supported + get { return Ber; } + } + + internal override bool EncodeConstructed(int encoding) + { + if (Asn1OutputStream.EncodingDer == encoding) + return base.EncodeConstructed(encoding); + + // TODO[asn1] Use DL encoding when supported + //encoding = Asn1OutputStream.EncodingDL; + + return IsExplicit() || GetBaseObject().ToAsn1Object().EncodeConstructed(encoding); + } + + internal override int EncodedLength(int encoding, bool withID) + { + if (Asn1OutputStream.EncodingDer == encoding) + return base.EncodedLength(encoding, withID); + + Asn1Object baseObject = GetBaseObject().ToAsn1Object(); + bool withBaseID = IsExplicit(); + + int length = GetContentsLengthDL(baseObject, withBaseID); + + if (withBaseID) + { + length += Asn1OutputStream.GetLengthOfDL(length); + } + + length += withID ? Asn1OutputStream.GetLengthOfIdentifier(TagNo) : 0; + + return length; + } + + internal override void Encode(Asn1OutputStream asn1Out, bool withID) + { + if (Asn1OutputStream.EncodingDer == asn1Out.Encoding) + { + base.Encode(asn1Out, withID); + return; + } + + // TODO[asn1] Use DL encoding when supported + //asn1Out = asn1Out.GetDLSubStream(); + + Asn1Object baseObject = GetBaseObject().ToAsn1Object(); + bool withBaseID = IsExplicit(); + + if (withID) + { + int flags = TagClass; + if (withBaseID || baseObject.EncodeConstructed(asn1Out.Encoding)) + { + flags |= Asn1Tags.Constructed; + } + + asn1Out.WriteIdentifier(true, flags, TagNo); + } + + if (withBaseID) + { + asn1Out.WriteDL(GetContentsLengthDL(baseObject, true)); + } + + baseObject.Encode(asn1Out, withBaseID); + } + + internal override Asn1Sequence RebuildConstructed(Asn1Object asn1Object) + { + return new BerSequence(asn1Object); + } + + private int GetContentsLengthDL(Asn1Object baseObject, bool withBaseID) + { + if (m_contentsLengthDL < 0) + { + // TODO[asn1] Use DL encoding when supported + m_contentsLengthDL = baseObject.EncodedLength(Asn1OutputStream.EncodingBer, withBaseID); + } + return m_contentsLengthDL; + } + } +} diff --git a/crypto/test/src/asn1/test/InputStreamTest.cs b/crypto/test/src/asn1/test/InputStreamTest.cs index 9505db379..ab5200905 100644 --- a/crypto/test/src/asn1/test/InputStreamTest.cs +++ b/crypto/test/src/asn1/test/InputStreamTest.cs @@ -78,7 +78,7 @@ namespace Org.BouncyCastle.Asn1.Tests // TODO Test data has length issues too; needs to be reworked //DoTestWithByteArray(classCast1, "unknown object encountered: Org.BouncyCastle.Asn1.DerApplicationSpecific"); DoTestWithByteArray(classCast2, "unknown object encountered: Org.BouncyCastle.Asn1.BerTaggedObjectParser"); - DoTestWithByteArray(classCast3, "unknown object encountered in constructed OCTET STRING: Org.BouncyCastle.Asn1.DerTaggedObject"); + DoTestWithByteArray(classCast3, "unknown object encountered in constructed OCTET STRING: Org.BouncyCastle.Asn1.DLTaggedObject"); // TODO Error dependent on parser choices; needs to be reworked //DoTestWithByteArray(memoryError1, "corrupted stream - out of bounds length found: 2078365180 >= 39"); |