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

BcpgInputStream

using Org.BouncyCastle.Utilities.IO; using System; using System.IO; namespace Org.BouncyCastle.Bcpg { public class BcpgInputStream : BaseInputStream { private class PartialInputStream : BaseInputStream { private BcpgInputStream m_in; private bool partial; private int dataLength; internal PartialInputStream(BcpgInputStream bcpgIn, bool partial, int dataLength) { m_in = bcpgIn; this.partial = partial; this.dataLength = dataLength; } public override int ReadByte() { do { if (dataLength != 0) { int num = m_in.ReadByte(); if (num < 0) throw new EndOfStreamException("Premature end of stream in PartialInputStream"); dataLength--; return num; } } while (partial && ReadPartialDataLength() >= 0); return -1; } public override int Read(byte[] buffer, int offset, int count) { Streams.ValidateBufferArguments(buffer, offset, count); do { if (dataLength != 0) { int count2 = (dataLength > count || dataLength < 0) ? count : dataLength; int num = m_in.Read(buffer, offset, count2); if (num < 1) throw new EndOfStreamException("Premature end of stream in PartialInputStream"); dataLength -= num; return num; } } while (partial && ReadPartialDataLength() >= 0); return 0; } public override int Read(Span<byte> buffer) { do { if (dataLength != 0) { int length = buffer.Length; int length2 = (dataLength > length || dataLength < 0) ? length : dataLength; int num = m_in.Read(buffer.Slice(0, length2)); if (num < 1) throw new EndOfStreamException("Premature end of stream in PartialInputStream"); dataLength -= num; return num; } } while (partial && ReadPartialDataLength() >= 0); return 0; } private int ReadPartialDataLength() { int num = m_in.ReadByte(); if (num < 0) return -1; partial = false; if (num < 192) dataLength = num; else if (num <= 223) { dataLength = (num - 192 << 8) + m_in.ReadByte() + 192; } else if (num == 255) { dataLength = ((m_in.ReadByte() << 24) | (m_in.ReadByte() << 16) | (m_in.ReadByte() << 8) | m_in.ReadByte()); } else { partial = true; dataLength = 1 << (num & 31); } return 0; } } private Stream m_in; private bool next; private int nextB; internal static BcpgInputStream Wrap(Stream inStr) { BcpgInputStream bcpgInputStream = inStr as BcpgInputStream; if (bcpgInputStream != null) return bcpgInputStream; return new BcpgInputStream(inStr); } private BcpgInputStream(Stream inputStream) { m_in = inputStream; } public override int ReadByte() { if (next) { next = false; return nextB; } return m_in.ReadByte(); } public override int Read(byte[] buffer, int offset, int count) { if (!next) return m_in.Read(buffer, offset, count); Streams.ValidateBufferArguments(buffer, offset, count); if (nextB < 0) return 0; buffer[offset] = (byte)nextB; next = false; return 1; } public override int Read(Span<byte> buffer) { if (!next) return m_in.Read(buffer); if (nextB < 0) return 0; buffer[0] = (byte)nextB; next = false; return 1; } public byte[] ReadAll() { return Streams.ReadAll(this); } public void ReadFully(byte[] buffer, int offset, int count) { if (Streams.ReadFully(this, buffer, offset, count) < count) throw new EndOfStreamException(); } public void ReadFully(byte[] buffer) { ReadFully(buffer, 0, buffer.Length); } public void ReadFully(Span<byte> buffer) { if (Streams.ReadFully(this, buffer) < buffer.Length) throw new EndOfStreamException(); } public PacketTag NextPacketTag() { if (!next) { try { nextB = m_in.ReadByte(); } catch (EndOfStreamException) { nextB = -1; } next = true; } if (nextB < 0) return (PacketTag)nextB; int num = nextB & 63; if ((nextB & 64) == 0) num >>= 2; return (PacketTag)num; } public Packet ReadPacket() { int num = ReadByte(); if (num < 0) return null; if ((num & 128) == 0) throw new IOException("invalid header encountered"); bool num2 = (num & 64) != 0; PacketTag packetTag = PacketTag.Reserved; int num3 = 0; bool flag = false; if (num2) { packetTag = (PacketTag)(num & 63); int num4 = ReadByte(); if (num4 < 192) num3 = num4; else if (num4 <= 223) { int num5 = m_in.ReadByte(); num3 = (num4 - 192 << 8) + num5 + 192; } else if (num4 == 255) { num3 = ((m_in.ReadByte() << 24) | (m_in.ReadByte() << 16) | (m_in.ReadByte() << 8) | m_in.ReadByte()); } else { flag = true; num3 = 1 << (num4 & 31); } } else { int num6 = num & 3; packetTag = (PacketTag)((num & 63) >> 2); switch (num6) { case 0: num3 = ReadByte(); break; case 1: num3 = ((ReadByte() << 8) | ReadByte()); break; case 2: num3 = ((ReadByte() << 24) | (ReadByte() << 16) | (ReadByte() << 8) | ReadByte()); break; case 3: flag = true; break; default: throw new IOException("unknown length type encountered"); } } BcpgInputStream bcpgIn = (!((num3 == 0) & flag)) ? new BcpgInputStream(new BufferedStream(new PartialInputStream(this, flag, num3))) : this; switch (packetTag) { default: if ((uint)(packetTag - 60) <= 3) return new ExperimentalPacket(packetTag, bcpgIn); break; case PacketTag.Reserved: return new InputStreamPacket(bcpgIn); case PacketTag.PublicKeyEncryptedSession: return new PublicKeyEncSessionPacket(bcpgIn); case PacketTag.Signature: return new SignaturePacket(bcpgIn); case PacketTag.SymmetricKeyEncryptedSessionKey: return new SymmetricKeyEncSessionPacket(bcpgIn); case PacketTag.OnePassSignature: return new OnePassSignaturePacket(bcpgIn); case PacketTag.SecretKey: return new SecretKeyPacket(bcpgIn); case PacketTag.PublicKey: return new PublicKeyPacket(bcpgIn); case PacketTag.SecretSubkey: return new SecretSubkeyPacket(bcpgIn); case PacketTag.CompressedData: return new CompressedDataPacket(bcpgIn); case PacketTag.SymmetricKeyEncrypted: return new SymmetricEncDataPacket(bcpgIn); case PacketTag.Marker: return new MarkerPacket(bcpgIn); case PacketTag.LiteralData: return new LiteralDataPacket(bcpgIn); case PacketTag.Trust: return new TrustPacket(bcpgIn); case PacketTag.UserId: return new UserIdPacket(bcpgIn); case PacketTag.UserAttribute: return new UserAttributePacket(bcpgIn); case PacketTag.PublicSubkey: return new PublicSubkeyPacket(bcpgIn); case PacketTag.SymmetricEncryptedIntegrityProtected: return new SymmetricEncIntegrityPacket(bcpgIn); case PacketTag.ModificationDetectionCode: return new ModDetectionCodePacket(bcpgIn); case (PacketTag)15: case (PacketTag)16: break; } throw new IOException("unknown packet type encountered: " + packetTag.ToString()); } public PacketTag SkipMarkerPackets() { PacketTag result; while ((result = NextPacketTag()) == PacketTag.Marker) { ReadPacket(); } return result; } protected override void Dispose(bool disposing) { if (disposing) m_in.Dispose(); base.Dispose(disposing); } } }