<PackageReference Include="BouncyCastle.Cryptography" Version="2.7.0-beta.98" />

BcpgInputStream

using Org.BouncyCastle.Utilities.IO; using System.IO; namespace Org.BouncyCastle.Bcpg { public class BcpgInputStream : BaseInputStream { private class PartialInputStream : BaseInputStream { private readonly Stream m_in; private bool m_partial; private uint m_dataLength; internal PartialInputStream(Stream inStr, bool partial, uint dataLength) { m_in = inStr; m_partial = partial; m_dataLength = dataLength; } public override int ReadByte() { do { if (m_dataLength != 0) { int num = m_in.ReadByte(); if (num < 0) throw new EndOfStreamException("Premature end of stream in PartialInputStream"); m_dataLength--; return num; } } while (m_partial && ReadPartialDataLength()); return -1; } public override int Read(byte[] buffer, int offset, int count) { Streams.ValidateBufferArguments(buffer, offset, count); do { if (m_dataLength != 0) { int count2 = ((uint)count < m_dataLength) ? count : ((int)m_dataLength); int num = m_in.Read(buffer, offset, count2); if (num < 1) throw new EndOfStreamException("Premature end of stream in PartialInputStream"); m_dataLength -= (uint)num; return num; } } while (m_partial && ReadPartialDataLength()); return 0; } private bool ReadPartialDataLength() { StreamUtilities.StreamFlags flags; uint dataLength = StreamUtilities.ReadBodyLen(m_in, out flags); if (flags.HasFlag(StreamUtilities.StreamFlags.Eof)) { m_partial = false; m_dataLength = 0; return false; } m_partial = flags.HasFlag(StreamUtilities.StreamFlags.Partial); m_dataLength = dataLength; return true; } } private readonly 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 byte[] ReadAll() { return Streams.ReadAll(this); } public void ReadFully(byte[] buffer, int offset, int count) { StreamUtilities.RequireBytes(this, buffer, offset, count); } public void ReadFully(byte[] buffer) { StreamUtilities.RequireBytes(this, buffer); } public byte RequireByte() { return StreamUtilities.RequireByte(this); } 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; bool flag = false; uint num3; if (num2) { packetTag = (PacketTag)(num & 63); num3 = StreamUtilities.RequireBodyLen(this, out StreamUtilities.StreamFlags streamFlags); flag = streamFlags.HasFlag(StreamUtilities.StreamFlags.Partial); } else { int num4 = num & 3; packetTag = (PacketTag)((num & 63) >> 2); switch (num4) { case 0: num3 = StreamUtilities.RequireByte(this); break; case 1: num3 = StreamUtilities.RequireUInt16BE(this); break; case 2: num3 = StreamUtilities.RequireUInt32BE(this); break; case 3: num3 = 0; flag = true; break; default: throw new IOException("unknown length type encountered"); } } BcpgInputStream bcpgIn = (!((num3 == 0) & flag)) ? new BcpgInputStream(new BufferedStream(new PartialInputStream(m_in, 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); } } }