Files
SuperVPN/output/Libraries/BouncyCastle.Crypto/Org/BouncyCastle/Bcpg/BcpgInputStream.cs
2025-10-09 09:57:24 +09:00

310 lines
6.3 KiB
C#

using System;
using System.IO;
using Org.BouncyCastle.Utilities;
using Org.BouncyCastle.Utilities.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)
{
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;
}
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 & 0x1F);
}
return 0;
}
}
private Stream m_in;
private bool next = false;
private int nextB;
internal static BcpgInputStream Wrap(Stream inStr)
{
if (inStr is BcpgInputStream)
{
return (BcpgInputStream)inStr;
}
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);
}
if (nextB < 0)
{
return 0;
}
if (buffer == null)
{
throw new ArgumentNullException("buffer");
}
buffer[offset] = (byte)nextB;
next = false;
return 1;
}
public byte[] ReadAll()
{
return Streams.ReadAll(this);
}
public void ReadFully(byte[] buffer, int off, int len)
{
if (Streams.ReadFully(this, buffer, off, len) < len)
{
throw new EndOfStreamException();
}
}
public void ReadFully(byte[] buffer)
{
ReadFully(buffer, 0, buffer.Length);
}
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 & 0x3F;
if ((nextB & 0x40) == 0)
{
num >>= 2;
}
return (PacketTag)num;
}
public Packet ReadPacket()
{
int num = ReadByte();
if (num < 0)
{
return null;
}
if ((num & 0x80) == 0)
{
throw new IOException("invalid header encountered");
}
bool flag = (num & 0x40) != 0;
PacketTag packetTag = PacketTag.Reserved;
int num2 = 0;
bool flag2 = false;
if (flag)
{
packetTag = (PacketTag)(num & 0x3F);
int num3 = ReadByte();
if (num3 < 192)
{
num2 = num3;
}
else if (num3 <= 223)
{
int num4 = m_in.ReadByte();
num2 = (num3 - 192 << 8) + num4 + 192;
}
else if (num3 == 255)
{
num2 = (m_in.ReadByte() << 24) | (m_in.ReadByte() << 16) | (m_in.ReadByte() << 8) | m_in.ReadByte();
}
else
{
flag2 = true;
num2 = 1 << (num3 & 0x1F);
}
}
else
{
int num5 = num & 3;
packetTag = (PacketTag)((num & 0x3F) >> 2);
switch (num5)
{
case 0:
num2 = ReadByte();
break;
case 1:
num2 = (ReadByte() << 8) | ReadByte();
break;
case 2:
num2 = (ReadByte() << 24) | (ReadByte() << 16) | (ReadByte() << 8) | ReadByte();
break;
case 3:
flag2 = true;
break;
default:
throw new IOException("unknown length type encountered");
}
}
BcpgInputStream bcpgIn;
if (num2 == 0 && flag2)
{
bcpgIn = this;
}
else
{
PartialInputStream inputStream = new PartialInputStream(this, flag2, num2);
bcpgIn = new BcpgInputStream(inputStream);
}
switch (packetTag)
{
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.Experimental1:
case PacketTag.Experimental2:
case PacketTag.Experimental3:
case PacketTag.Experimental4:
return new ExperimentalPacket(packetTag, bcpgIn);
default:
throw new IOException("unknown packet type encountered: " + packetTag);
}
}
public override void Close()
{
Platform.Dispose(m_in);
base.Close();
}
}