123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383 |
- #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
- #pragma warning disable
- using System;
- using System.IO;
- using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1;
- using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
- using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.IO;
- namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Bcpg
- {
- /// <remarks>Reader for PGP objects.</remarks>
- public class BcpgInputStream
- : BaseInputStream
- {
- 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)
- {
- this.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)
- {
- // Strangely, when count == 0, we should still attempt to read a byte
- // if (count == 0)
- // return 0;
- if (!next)
- return m_in.Read(buffer, offset, count);
- // We have next byte waiting, so return it
- if (nextB < 0)
- return 0; // EndOfStream
- 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);
- }
- /// <summary>Returns the next packet tag in the stream.</summary>
- public PacketTag NextPacketTag()
- {
- if (!next)
- {
- try
- {
- nextB = m_in.ReadByte();
- }
- catch (EndOfStreamException)
- {
- nextB = -1;
- }
- next = true;
- }
- if (nextB < 0)
- return (PacketTag)nextB;
- int maskB = nextB & 0x3f;
- if ((nextB & 0x40) == 0) // old
- {
- maskB >>= 2;
- }
- return (PacketTag)maskB;
- }
- public Packet ReadPacket()
- {
- int hdr = this.ReadByte();
- if (hdr < 0)
- {
- return null;
- }
- if ((hdr & 0x80) == 0)
- {
- throw new IOException("invalid header encountered");
- }
- bool newPacket = (hdr & 0x40) != 0;
- PacketTag tag = 0;
- int bodyLen = 0;
- bool partial = false;
- if (newPacket)
- {
- tag = (PacketTag)(hdr & 0x3f);
- int l = this.ReadByte();
- if (l < 192)
- {
- bodyLen = l;
- }
- else if (l <= 223)
- {
- int b = m_in.ReadByte();
- bodyLen = ((l - 192) << 8) + (b) + 192;
- }
- else if (l == 255)
- {
- bodyLen = (m_in.ReadByte() << 24) | (m_in.ReadByte() << 16)
- | (m_in.ReadByte() << 8) | m_in.ReadByte();
- }
- else
- {
- partial = true;
- bodyLen = 1 << (l & 0x1f);
- }
- }
- else
- {
- int lengthType = hdr & 0x3;
- tag = (PacketTag)((hdr & 0x3f) >> 2);
- switch (lengthType)
- {
- case 0:
- bodyLen = this.ReadByte();
- break;
- case 1:
- bodyLen = (this.ReadByte() << 8) | this.ReadByte();
- break;
- case 2:
- bodyLen = (this.ReadByte() << 24) | (this.ReadByte() << 16)
- | (this.ReadByte() << 8) | this.ReadByte();
- break;
- case 3:
- partial = true;
- break;
- default:
- throw new IOException("unknown length type encountered");
- }
- }
- BcpgInputStream objStream;
- if (bodyLen == 0 && partial)
- {
- objStream = this;
- }
- else
- {
- PartialInputStream pis = new PartialInputStream(this, partial, bodyLen);
- #if NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE || NETFX_CORE
- Stream buf = pis;
- #else
- Stream buf = new BufferedStream(pis);
- #endif
- objStream = new BcpgInputStream(buf);
- }
- switch (tag)
- {
- case PacketTag.Reserved:
- return new InputStreamPacket(objStream);
- case PacketTag.PublicKeyEncryptedSession:
- return new PublicKeyEncSessionPacket(objStream);
- case PacketTag.Signature:
- return new SignaturePacket(objStream);
- case PacketTag.SymmetricKeyEncryptedSessionKey:
- return new SymmetricKeyEncSessionPacket(objStream);
- case PacketTag.OnePassSignature:
- return new OnePassSignaturePacket(objStream);
- case PacketTag.SecretKey:
- return new SecretKeyPacket(objStream);
- case PacketTag.PublicKey:
- return new PublicKeyPacket(objStream);
- case PacketTag.SecretSubkey:
- return new SecretSubkeyPacket(objStream);
- case PacketTag.CompressedData:
- return new CompressedDataPacket(objStream);
- case PacketTag.SymmetricKeyEncrypted:
- return new SymmetricEncDataPacket(objStream);
- case PacketTag.Marker:
- return new MarkerPacket(objStream);
- case PacketTag.LiteralData:
- return new LiteralDataPacket(objStream);
- case PacketTag.Trust:
- return new TrustPacket(objStream);
- case PacketTag.UserId:
- return new UserIdPacket(objStream);
- case PacketTag.UserAttribute:
- return new UserAttributePacket(objStream);
- case PacketTag.PublicSubkey:
- return new PublicSubkeyPacket(objStream);
- case PacketTag.SymmetricEncryptedIntegrityProtected:
- return new SymmetricEncIntegrityPacket(objStream);
- case PacketTag.ModificationDetectionCode:
- return new ModDetectionCodePacket(objStream);
- case PacketTag.Experimental1:
- case PacketTag.Experimental2:
- case PacketTag.Experimental3:
- case PacketTag.Experimental4:
- return new ExperimentalPacket(tag, objStream);
- default:
- throw new IOException("unknown packet type encountered: " + tag);
- }
- }
- public PacketTag SkipMarkerPackets()
- {
- PacketTag tag;
- while ((tag = NextPacketTag()) == PacketTag.Marker)
- {
- ReadPacket();
- }
- return tag;
- }
- #if PORTABLE || NETFX_CORE
- protected override void Dispose(bool disposing)
- {
- if (disposing)
- {
- BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.Dispose(m_in);
- }
- base.Dispose(disposing);
- }
- #else
- public override void Close()
- {
- BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.Dispose(m_in);
- base.Close();
- }
- #endif
- /// <summary>
- /// A stream that overlays our input stream, allowing the user to only read a segment of it.
- /// NB: dataLength will be negative if the segment length is in the upper range above 2**31.
- /// </summary>
- private class PartialInputStream
- : BaseInputStream
- {
- private BcpgInputStream m_in;
- private bool partial;
- private int dataLength;
- internal PartialInputStream(
- BcpgInputStream bcpgIn,
- bool partial,
- int dataLength)
- {
- this.m_in = bcpgIn;
- this.partial = partial;
- this.dataLength = dataLength;
- }
- public override int ReadByte()
- {
- do
- {
- if (dataLength != 0)
- {
- int ch = m_in.ReadByte();
- if (ch < 0)
- {
- throw new EndOfStreamException("Premature end of stream in PartialInputStream");
- }
- dataLength--;
- return ch;
- }
- }
- while (partial && ReadPartialDataLength() >= 0);
- return -1;
- }
- public override int Read(byte[] buffer, int offset, int count)
- {
- do
- {
- if (dataLength != 0)
- {
- int readLen = (dataLength > count || dataLength < 0) ? count : dataLength;
- int len = m_in.Read(buffer, offset, readLen);
- if (len < 1)
- {
- throw new EndOfStreamException("Premature end of stream in PartialInputStream");
- }
- dataLength -= len;
- return len;
- }
- }
- while (partial && ReadPartialDataLength() >= 0);
- return 0;
- }
- private int ReadPartialDataLength()
- {
- int l = m_in.ReadByte();
- if (l < 0)
- {
- return -1;
- }
- partial = false;
- if (l < 192)
- {
- dataLength = l;
- }
- else if (l <= 223)
- {
- dataLength = ((l - 192) << 8) + (m_in.ReadByte()) + 192;
- }
- else if (l == 255)
- {
- dataLength = (m_in.ReadByte() << 24) | (m_in.ReadByte() << 16)
- | (m_in.ReadByte() << 8) | m_in.ReadByte();
- }
- else
- {
- partial = true;
- dataLength = 1 << (l & 0x1f);
- }
- return 0;
- }
- }
- }
- }
- #pragma warning restore
- #endif
|