From 39f33f785250b544610c429fb9d4e50c521cd493 Mon Sep 17 00:00:00 2001 From: Peter Dettman Date: Thu, 11 Nov 2021 21:13:22 +0700 Subject: Refactor tagged object parsing --- crypto/src/asn1/ASN1StreamParser.cs | 30 +++++------------------------- crypto/src/asn1/Asn1InputStream.cs | 16 +++------------- crypto/src/asn1/Asn1TaggedObject.cs | 32 ++++++++++++++++++++++++++++++++ 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; -- cgit 1.4.1