PgpEncryptedData
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.IO;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.Utilities;
using Org.BouncyCastle.Utilities.IO;
using System;
using System.IO;
namespace Org.BouncyCastle.Bcpg.OpenPgp
{
public abstract class PgpEncryptedData
{
internal class TruncatedStream : BaseInputStream
{
private const int LookAheadSize = 22;
private const int LookAheadBufSize = 512;
private const int LookAheadBufLimit = 490;
private readonly byte[] m_lookAhead = new byte[512];
private readonly Stream m_inStr;
private int m_bufStart;
private int m_bufEnd;
internal TruncatedStream(Stream inStr)
{
int num = Streams.ReadFully(inStr, m_lookAhead);
if (num < 22)
throw new EndOfStreamException();
m_inStr = inStr;
m_bufStart = 0;
m_bufEnd = num - 22;
}
private int FillBuffer()
{
if (m_bufEnd < 490)
return 0;
Array.Copy(m_lookAhead, 490, m_lookAhead, 0, 22);
m_bufEnd = Streams.ReadFully(m_inStr, m_lookAhead, 22, 490);
m_bufStart = 0;
return m_bufEnd;
}
public override int Read(byte[] buffer, int offset, int count)
{
Streams.ValidateBufferArguments(buffer, offset, count);
return Read(buffer.AsSpan(offset, count));
}
public override int Read(Span<byte> buffer)
{
int num = m_bufEnd - m_bufStart;
int num2 = 0;
int num3 = buffer.Length;
Span<byte> span;
int num4;
while (num3 > num) {
span = m_lookAhead.AsSpan(m_bufStart, num);
num4 = num2;
span.CopyTo(buffer.Slice(num4, buffer.Length - num4));
m_bufStart += num;
num2 += num;
num3 -= num;
if ((num = FillBuffer()) < 1)
return num2;
}
span = m_lookAhead.AsSpan(m_bufStart, num3);
num4 = num2;
span.CopyTo(buffer.Slice(num4, buffer.Length - num4));
m_bufStart += num3;
return num2 + num3;
}
public override int ReadByte()
{
if (m_bufStart >= m_bufEnd && FillBuffer() < 1)
return -1;
return m_lookAhead[m_bufStart++];
}
internal bool CheckMdc(IDigest digest)
{
byte[] array = DigestUtilities.DoFinal(digest, m_lookAhead, m_bufStart, 2);
return Arrays.FixedTimeEquals(array.Length, array, 0, m_lookAhead, m_bufStart + 2);
}
}
private readonly InputStreamPacket m_encData;
private Stream m_decStream;
internal PgpEncryptedData(InputStreamPacket encData)
{
m_encData = encData;
}
public virtual Stream GetInputStream()
{
return m_encData.GetInputStream();
}
public bool IsIntegrityProtected()
{
return m_encData is SymmetricEncIntegrityPacket;
}
public bool Verify()
{
if (!IsIntegrityProtected())
throw new PgpException("data not integrity protected.");
DigestStream digestStream = (DigestStream)m_decStream;
if (digestStream.ReadByte() >= 0)
Streams.Drain(digestStream);
return ((TruncatedStream)digestStream.Stream).CheckMdc(digestStream.ReadDigest);
}
internal IBufferedCipher CreateBufferedCipher(string cipherName)
{
string str = IsIntegrityProtected() ? "CFB" : "OpenPGPCFB";
return CipherUtilities.GetCipher(cipherName + "/" + str + "/NoPadding");
}
internal Stream InitDecStream(Stream decStream)
{
if (IsIntegrityProtected()) {
TruncatedStream stream = new TruncatedStream(decStream);
IDigest readDigest = PgpUtilities.CreateDigest(HashAlgorithmTag.Sha1);
decStream = new DigestStream(stream, readDigest, null);
}
m_decStream = decStream;
return decStream;
}
internal static void QuickCheck(byte[] prefix)
{
int num = prefix.Length;
byte b = prefix[num - 4];
byte b2 = prefix[num - 3];
byte num2 = prefix[num - 2];
byte b3 = prefix[num - 1];
bool flag = num2 == b && b3 == b2;
bool flag2 = num2 == 0 && b3 == 0;
if (!flag && !flag2)
throw new PgpDataValidationException("quick check failed.");
}
}
}