diff options
author | Peter Dettman <peter.dettman@bouncycastle.org> | 2023-03-05 14:45:49 +0700 |
---|---|---|
committer | Peter Dettman <peter.dettman@bouncycastle.org> | 2023-03-05 14:45:49 +0700 |
commit | 6b59dbbece3b1509b83b8479259a3c6059e9a60b (patch) | |
tree | 3dca66ea9a1e8aa02ac6099cde5844155783bd7b /crypto/src | |
parent | Refactor Asn1Set classes (diff) | |
download | BouncyCastle.NET-ed25519-6b59dbbece3b1509b83b8479259a3c6059e9a60b.tar.xz |
Support 'leaveOpen' in Asn1 streams
Diffstat (limited to 'crypto/src')
-rw-r--r-- | crypto/src/asn1/Asn1InputStream.cs | 43 | ||||
-rw-r--r-- | crypto/src/asn1/Asn1OutputStream.cs | 46 | ||||
-rw-r--r-- | crypto/src/asn1/BEROctetStringGenerator.cs | 4 | ||||
-rw-r--r-- | crypto/src/asn1/DerOutputStream.cs | 4 | ||||
-rw-r--r-- | crypto/src/asn1/LazyASN1InputStream.cs | 19 | ||||
-rw-r--r-- | crypto/src/asn1/util/Asn1Dump.cs | 10 | ||||
-rw-r--r-- | crypto/src/cms/CMSUtils.cs | 25 | ||||
-rw-r--r-- | crypto/src/tls/TlsUtilities.cs | 17 | ||||
-rw-r--r-- | crypto/src/x509/X509CertPairParser.cs | 11 | ||||
-rw-r--r-- | crypto/src/x509/X509CertificateParser.cs | 5 | ||||
-rw-r--r-- | crypto/src/x509/X509CrlParser.cs | 11 |
11 files changed, 138 insertions, 57 deletions
diff --git a/crypto/src/asn1/Asn1InputStream.cs b/crypto/src/asn1/Asn1InputStream.cs index 33db1e6d7..e250fe500 100644 --- a/crypto/src/asn1/Asn1InputStream.cs +++ b/crypto/src/asn1/Asn1InputStream.cs @@ -19,6 +19,7 @@ namespace Org.BouncyCastle.Asn1 : FilterStream { private readonly int limit; + private readonly bool m_leaveOpen; internal byte[][] tmpBuffers; @@ -36,11 +37,6 @@ namespace Org.BouncyCastle.Asn1 return int.MaxValue; } - public Asn1InputStream(Stream input) - : this(input, FindLimit(input)) - { - } - /** * Create an ASN1InputStream based on the input byte array. The length of DER objects in * the stream is automatically limited to the length of the input array. @@ -52,6 +48,11 @@ namespace Org.BouncyCastle.Asn1 { } + public Asn1InputStream(Stream input) + : this(input, FindLimit(input)) + { + } + /** * Create an ASN1InputStream where no DER object will be longer than limit. * @@ -59,22 +60,41 @@ namespace Org.BouncyCastle.Asn1 * @param limit maximum size of a DER encoded object. */ public Asn1InputStream(Stream input, int limit) - : this(input, limit, new byte[16][]) + : this(input, limit, false) + { + } + + public Asn1InputStream(Stream input, int limit, bool leaveOpen) + : this(input, limit, leaveOpen, new byte[16][]) { } - internal Asn1InputStream(Stream input, int limit, byte[][] tmpBuffers) + internal Asn1InputStream(Stream input, int limit, bool leaveOpen, byte[][] tmpBuffers) : base(input) { + if (!input.CanRead) + throw new ArgumentException("Expected stream to be readable", nameof(input)); + this.limit = limit; + m_leaveOpen = leaveOpen; this.tmpBuffers = tmpBuffers; } protected override void Dispose(bool disposing) { - tmpBuffers = null; + if (disposing) + { + tmpBuffers = null; + } - base.Dispose(disposing); + if (m_leaveOpen) + { + base.Detach(disposing); + } + else + { + base.Dispose(disposing); + } } /** @@ -146,7 +166,10 @@ namespace Org.BouncyCastle.Asn1 if (remaining < 1) return new Asn1EncodableVector(0); - return new Asn1InputStream(defIn, remaining, tmpBuffers).ReadVector(); + using (var sub = new Asn1InputStream(defIn, remaining, leaveOpen: true, tmpBuffers)) + { + return sub.ReadVector(); + } } internal virtual Asn1Sequence CreateDLSequence(DefiniteLengthInputStream defIn) diff --git a/crypto/src/asn1/Asn1OutputStream.cs b/crypto/src/asn1/Asn1OutputStream.cs index 745674930..588c3733d 100644 --- a/crypto/src/asn1/Asn1OutputStream.cs +++ b/crypto/src/asn1/Asn1OutputStream.cs @@ -18,20 +18,56 @@ namespace Org.BouncyCastle.Asn1 public static Asn1OutputStream Create(Stream output) { - return new Asn1OutputStream(output); + return Create(output, Asn1Encodable.Ber); } public static Asn1OutputStream Create(Stream output, string encoding) { + return Create(output, encoding, false); + } + + public static Asn1OutputStream Create(Stream output, string encoding, bool leaveOpen) + { + if (Asn1Encodable.Der.Equals(encoding)) + return new DerOutputStream(output, leaveOpen); + + return new Asn1OutputStream(output, leaveOpen); + } + + internal static int GetEncodingType(string encoding) + { if (Asn1Encodable.Der.Equals(encoding)) - return new DerOutputStream(output); + return EncodingDer; + + return EncodingBer; + } - return new Asn1OutputStream(output); + private readonly bool m_leaveOpen; + + internal Asn1OutputStream(Stream output, bool leaveOpen) + : base(output) + { + if (!output.CanWrite) + throw new ArgumentException("Expected stream to be writable", nameof(output)); + + m_leaveOpen = leaveOpen; } - internal Asn1OutputStream(Stream os) - : base(os) + protected override void Dispose(bool disposing) { + if (disposing) + { + FlushInternal(); + } + + if (m_leaveOpen) + { + base.Detach(disposing); + } + else + { + base.Dispose(disposing); + } } public virtual void WriteObject(Asn1Encodable asn1Encodable) diff --git a/crypto/src/asn1/BEROctetStringGenerator.cs b/crypto/src/asn1/BEROctetStringGenerator.cs index 5472802a2..ed2b85010 100644 --- a/crypto/src/asn1/BEROctetStringGenerator.cs +++ b/crypto/src/asn1/BEROctetStringGenerator.cs @@ -54,7 +54,7 @@ namespace Org.BouncyCastle.Asn1 { _buf = buf; _off = 0; - _derOut = Asn1OutputStream.Create(outStream, Asn1Encodable.Der); + _derOut = Asn1OutputStream.Create(outStream, Asn1Encodable.Der, leaveOpen: true); } public override void Write(byte[] buffer, int offset, int count) @@ -145,7 +145,7 @@ namespace Org.BouncyCastle.Asn1 _off = 0; } - _derOut.FlushInternal(); + _derOut.Dispose(); } base.Dispose(disposing); } diff --git a/crypto/src/asn1/DerOutputStream.cs b/crypto/src/asn1/DerOutputStream.cs index 6304ca852..509bd436b 100644 --- a/crypto/src/asn1/DerOutputStream.cs +++ b/crypto/src/asn1/DerOutputStream.cs @@ -6,8 +6,8 @@ namespace Org.BouncyCastle.Asn1 internal class DerOutputStream : Asn1OutputStream { - internal DerOutputStream(Stream os) - : base(os) + internal DerOutputStream(Stream os, bool leaveOpen) + : base(os, leaveOpen) { } diff --git a/crypto/src/asn1/LazyASN1InputStream.cs b/crypto/src/asn1/LazyASN1InputStream.cs index 8dfbba122..8807416f4 100644 --- a/crypto/src/asn1/LazyASN1InputStream.cs +++ b/crypto/src/asn1/LazyASN1InputStream.cs @@ -16,8 +16,18 @@ namespace Org.BouncyCastle.Asn1 { } - internal LazyAsn1InputStream(Stream input, int limit, byte[][] tmpBuffers) - : base(input, limit, tmpBuffers) + public LazyAsn1InputStream(Stream input, int limit) + : base(input, limit) + { + } + + public LazyAsn1InputStream(Stream input, int limit, bool leaveOpen) + : base(input, limit, leaveOpen) + { + } + + internal LazyAsn1InputStream(Stream input, int limit, bool leaveOpen, byte[][] tmpBuffers) + : base(input, limit, leaveOpen, tmpBuffers) { } @@ -37,7 +47,10 @@ namespace Org.BouncyCastle.Asn1 if (remaining < 1) return new Asn1EncodableVector(0); - return new LazyAsn1InputStream(defIn, remaining, tmpBuffers).ReadVector(); + using (var sub = new LazyAsn1InputStream(defIn, remaining, leaveOpen: true, tmpBuffers)) + { + return sub.ReadVector(); + } } } } diff --git a/crypto/src/asn1/util/Asn1Dump.cs b/crypto/src/asn1/util/Asn1Dump.cs index 3a19f1276..67fbba979 100644 --- a/crypto/src/asn1/util/Asn1Dump.cs +++ b/crypto/src/asn1/util/Asn1Dump.cs @@ -256,11 +256,13 @@ namespace Org.BouncyCastle.Asn1.Utilities /// <summary>Parse ASN.1 objects from input <see cref="Stream"/>, and write them to the output.</summary> public static void Dump(Stream input, TextWriter output) { - Asn1InputStream asn1InputStream = new Asn1InputStream(input); - Asn1Object asn1Object; - while ((asn1Object = asn1InputStream.ReadObject()) != null) + using (var asn1In = new Asn1InputStream(input, int.MaxValue, leaveOpen: true)) { - output.Write(DumpAsString(asn1Object)); + Asn1Object asn1Object; + while ((asn1Object = asn1In.ReadObject()) != null) + { + output.Write(DumpAsString(asn1Object)); + } } } diff --git a/crypto/src/cms/CMSUtils.cs b/crypto/src/cms/CMSUtils.cs index 281e1e73a..0041d2fac 100644 --- a/crypto/src/cms/CMSUtils.cs +++ b/crypto/src/cms/CMSUtils.cs @@ -33,26 +33,27 @@ namespace Org.BouncyCastle.Cms } } - internal static ContentInfo ReadContentInfo( - byte[] input) + internal static ContentInfo ReadContentInfo(byte[] input) { - // enforce limit checking as from a byte array - return ReadContentInfo(new Asn1InputStream(input)); - } + using (var asn1In = new Asn1InputStream(input)) + { + return ReadContentInfo(asn1In); + } + } - internal static ContentInfo ReadContentInfo( - Stream input) + internal static ContentInfo ReadContentInfo(Stream input) { - // enforce some limit checking - return ReadContentInfo(new Asn1InputStream(input, MaximumMemory)); + using (var asn1In = new Asn1InputStream(input, MaximumMemory, leaveOpen: true)) + { + return ReadContentInfo(asn1In); + } } - private static ContentInfo ReadContentInfo( - Asn1InputStream aIn) + private static ContentInfo ReadContentInfo(Asn1InputStream asn1In) { try { - return ContentInfo.GetInstance(aIn.ReadObject()); + return ContentInfo.GetInstance(asn1In.ReadObject()); } catch (IOException e) { diff --git a/crypto/src/tls/TlsUtilities.cs b/crypto/src/tls/TlsUtilities.cs index 7a601bebf..d187aeed2 100644 --- a/crypto/src/tls/TlsUtilities.cs +++ b/crypto/src/tls/TlsUtilities.cs @@ -966,14 +966,15 @@ namespace Org.BouncyCastle.Tls public static Asn1Object ReadAsn1Object(byte[] encoding) { - Asn1InputStream asn1 = new Asn1InputStream(encoding); - Asn1Object result = asn1.ReadObject(); - if (null == result) - throw new TlsFatalAlert(AlertDescription.decode_error); - if (null != asn1.ReadObject()) - throw new TlsFatalAlert(AlertDescription.decode_error); - - return result; + using (var asn1In = new Asn1InputStream(encoding)) + { + Asn1Object result = asn1In.ReadObject(); + if (null == result) + throw new TlsFatalAlert(AlertDescription.decode_error); + if (asn1In.Length != asn1In.Position) + throw new TlsFatalAlert(AlertDescription.decode_error); + return result; + } } /// <exception cref="IOException"/> diff --git a/crypto/src/x509/X509CertPairParser.cs b/crypto/src/x509/X509CertPairParser.cs index 26b417898..95ba522c8 100644 --- a/crypto/src/x509/X509CertPairParser.cs +++ b/crypto/src/x509/X509CertPairParser.cs @@ -13,13 +13,12 @@ namespace Org.BouncyCastle.X509 { private Stream currentStream; - private X509CertificatePair ReadDerCrossCertificatePair( - Stream inStream) + private X509CertificatePair ReadDerCrossCertificatePair(Stream inStream) { - Asn1InputStream dIn = new Asn1InputStream(inStream);//, ProviderUtil.getReadLimit(in)); - Asn1Sequence seq = (Asn1Sequence)dIn.ReadObject(); - CertificatePair pair = CertificatePair.GetInstance(seq); - return new X509CertificatePair(pair); + using (var asn1In = new Asn1InputStream(inStream, int.MaxValue, leaveOpen: true)) + { + return new X509CertificatePair(CertificatePair.GetInstance(asn1In.ReadObject())); + } } /// <summary> diff --git a/crypto/src/x509/X509CertificateParser.cs b/crypto/src/x509/X509CertificateParser.cs index ce50dc8ed..6fc1b3ff4 100644 --- a/crypto/src/x509/X509CertificateParser.cs +++ b/crypto/src/x509/X509CertificateParser.cs @@ -138,7 +138,10 @@ namespace Org.BouncyCastle.X509 if (tag != 0x30) // assume ascii PEM encoded. return ReadPemCertificate(inStream); - return ReadDerCertificate(new Asn1InputStream(inStream)); + using (var asn1In = new Asn1InputStream(inStream, int.MaxValue, leaveOpen: true)) + { + return ReadDerCertificate(asn1In); + } } catch (Exception e) { diff --git a/crypto/src/x509/X509CrlParser.cs b/crypto/src/x509/X509CrlParser.cs index ad2b4f704..a60a591c4 100644 --- a/crypto/src/x509/X509CrlParser.cs +++ b/crypto/src/x509/X509CrlParser.cs @@ -131,11 +131,14 @@ namespace Org.BouncyCastle.X509 return ReadPemCrl(inStream); Asn1InputStream asn1 = lazyAsn1 - ? new LazyAsn1InputStream(inStream) - : new Asn1InputStream(inStream); + ? new LazyAsn1InputStream(inStream, int.MaxValue, leaveOpen: true) + : new Asn1InputStream(inStream, int.MaxValue, leaveOpen: true); - return ReadDerCrl(asn1); - } + using (asn1) + { + return ReadDerCrl(asn1); + } + } catch (CrlException e) { throw e; |