diff options
author | Peter Dettman <peter.dettman@bouncycastle.org> | 2021-10-15 14:18:36 +0700 |
---|---|---|
committer | Peter Dettman <peter.dettman@bouncycastle.org> | 2021-10-15 14:18:36 +0700 |
commit | e3acb177d13bfe158aca5aff2b5a9d8cef269d5d (patch) | |
tree | 27dc72e89c7c29857f4787b9a328b1d06b331b2c /crypto/src/asn1/ASN1StreamParser.cs | |
parent | ASN1InputStream updates from bc-java (diff) | |
download | BouncyCastle.NET-ed25519-e3acb177d13bfe158aca5aff2b5a9d8cef269d5d.tar.xz |
Improve ASN.1 substream handling
Diffstat (limited to 'crypto/src/asn1/ASN1StreamParser.cs')
-rw-r--r-- | crypto/src/asn1/ASN1StreamParser.cs | 112 |
1 files changed, 58 insertions, 54 deletions
diff --git a/crypto/src/asn1/ASN1StreamParser.cs b/crypto/src/asn1/ASN1StreamParser.cs index 860dc99b1..cca333412 100644 --- a/crypto/src/asn1/ASN1StreamParser.cs +++ b/crypto/src/asn1/ASN1StreamParser.cs @@ -10,31 +10,32 @@ namespace Org.BouncyCastle.Asn1 private readonly byte[][] tmpBuffers; - public Asn1StreamParser( - Stream inStream) - : this(inStream, Asn1InputStream.FindLimit(inStream)) + public Asn1StreamParser(Stream input) + : this(input, Asn1InputStream.FindLimit(input)) { } - public Asn1StreamParser( - Stream inStream, - int limit) - { - if (!inStream.CanRead) - throw new ArgumentException("Expected stream to be readable", "inStream"); - - this._in = inStream; - this._limit = limit; - this.tmpBuffers = new byte[16][]; + public Asn1StreamParser(byte[] encoding) + : this(new MemoryStream(encoding, false), encoding.Length) + { } - public Asn1StreamParser( - byte[] encoding) - : this(new MemoryStream(encoding, false), encoding.Length) + public Asn1StreamParser(Stream input, int limit) + : this(input, limit, new byte[16][]) { - } + } + + internal Asn1StreamParser(Stream input, int limit, byte[][] tmpBuffers) + { + if (!input.CanRead) + throw new ArgumentException("Expected stream to be readable", "input"); + + this._in = input; + this._limit = limit; + this.tmpBuffers = tmpBuffers; + } - internal IAsn1Convertible ReadIndef(int tagValue) + internal IAsn1Convertible ReadIndef(int tagValue) { // Note: INDEF => CONSTRUCTED @@ -142,10 +143,10 @@ namespace Org.BouncyCastle.Asn1 if (!isConstructed) throw new IOException("indefinite-length primitive encoding encountered"); - IndefiniteLengthInputStream indIn = new IndefiniteLengthInputStream(_in, _limit); - Asn1StreamParser sp = new Asn1StreamParser(indIn, _limit); + IndefiniteLengthInputStream indIn = new IndefiniteLengthInputStream(_in, _limit); + Asn1StreamParser sp = new Asn1StreamParser(indIn, _limit, tmpBuffers); - if ((tag & Asn1Tags.Application) != 0) + if ((tag & Asn1Tags.Application) != 0) { return new BerApplicationSpecificParser(tagNo, sp); } @@ -168,45 +169,48 @@ namespace Org.BouncyCastle.Asn1 if ((tag & Asn1Tags.Tagged) != 0) { - return new BerTaggedObjectParser(isConstructed, tagNo, new Asn1StreamParser(defIn)); + return new BerTaggedObjectParser(isConstructed, tagNo, + new Asn1StreamParser(defIn, defIn.Remaining, tmpBuffers)); } - if (isConstructed) - { - // TODO There are other tags that may be constructed (e.g. BitString) - switch (tagNo) - { - case Asn1Tags.OctetString: - // - // yes, people actually do this... - // - return new BerOctetStringParser(new Asn1StreamParser(defIn)); - case Asn1Tags.Sequence: - return new DerSequenceParser(new Asn1StreamParser(defIn)); - case Asn1Tags.Set: - return new DerSetParser(new Asn1StreamParser(defIn)); - case Asn1Tags.External: - return new DerExternalParser(new Asn1StreamParser(defIn)); - default: - throw new IOException("unknown tag " + tagNo + " encountered"); + if (!isConstructed) + { + // Some primitive encodings can be handled by parsers too... + switch (tagNo) + { + case Asn1Tags.OctetString: + return new DerOctetStringParser(defIn); } - } - // Some primitive encodings can be handled by parsers too... - switch (tagNo) - { - case Asn1Tags.OctetString: - return new DerOctetStringParser(defIn); - } + try + { + return Asn1InputStream.CreatePrimitiveDerObject(tagNo, defIn, tmpBuffers); + } + catch (ArgumentException e) + { + throw new Asn1Exception("corrupted stream detected", e); + } + } - try - { - return Asn1InputStream.CreatePrimitiveDerObject(tagNo, defIn, tmpBuffers); - } - catch (ArgumentException e) + Asn1StreamParser sp = new Asn1StreamParser(defIn, defIn.Remaining, tmpBuffers); + + // TODO There are other tags that may be constructed (e.g. BitString) + switch (tagNo) { - throw new Asn1Exception("corrupted stream detected", e); - } + case Asn1Tags.OctetString: + // + // yes, people actually do this... + // + return new BerOctetStringParser(sp); + case Asn1Tags.Sequence: + return new DerSequenceParser(sp); + case Asn1Tags.Set: + return new DerSetParser(sp); + case Asn1Tags.External: + return new DerExternalParser(sp); + default: + throw new IOException("unknown tag " + tagNo + " encountered"); + } } } |