<PackageReference Include="BouncyCastle.Cryptography" Version="2.4.0" />

ConstructedBitStream

using Org.BouncyCastle.Utilities; using Org.BouncyCastle.Utilities.IO; using System.IO; namespace Org.BouncyCastle.Asn1 { internal class ConstructedBitStream : BaseInputStream { private readonly Asn1StreamParser m_parser; private readonly bool m_octetAligned; private bool m_first = true; private int m_padBits; private Asn1BitStringParser m_currentParser; private Stream m_currentStream; internal int PadBits => m_padBits; internal ConstructedBitStream(Asn1StreamParser parser, bool octetAligned) { m_parser = parser; m_octetAligned = octetAligned; } public override int Read(byte[] buffer, int offset, int count) { Streams.ValidateBufferArguments(buffer, offset, count); if (count < 1) return 0; if (m_currentStream == null) { if (!m_first) return 0; m_currentParser = GetNextParser(); if (m_currentParser == null) return 0; m_first = false; m_currentStream = m_currentParser.GetBitStream(); } int num = 0; while (true) { int num2 = m_currentStream.Read(buffer, offset + num, count - num); if (num2 > 0) { num += num2; if (num == count) return num; } else { m_padBits = m_currentParser.PadBits; m_currentParser = GetNextParser(); if (m_currentParser == null) break; m_currentStream = m_currentParser.GetBitStream(); } } m_currentStream = null; return num; } public override int ReadByte() { if (m_currentStream == null) { if (!m_first) return -1; m_currentParser = GetNextParser(); if (m_currentParser == null) return -1; m_first = false; m_currentStream = m_currentParser.GetBitStream(); } while (true) { int num = m_currentStream.ReadByte(); if (num >= 0) return num; m_padBits = m_currentParser.PadBits; m_currentParser = GetNextParser(); if (m_currentParser == null) break; m_currentStream = m_currentParser.GetBitStream(); } m_currentStream = null; return -1; } private Asn1BitStringParser GetNextParser() { IAsn1Convertible asn1Convertible = m_parser.ReadObject(); if (asn1Convertible == null) { if (m_octetAligned && m_padBits != 0) throw new IOException("expected octet-aligned bitstring, but found padBits: " + m_padBits.ToString()); return null; } if (asn1Convertible is Asn1BitStringParser) { if (m_padBits != 0) throw new IOException("only the last nested bitstring can have padding"); return (Asn1BitStringParser)asn1Convertible; } throw new IOException("unknown object encountered: " + Platform.GetTypeName(asn1Convertible)); } } }