init commit
This commit is contained in:
@@ -0,0 +1,101 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using Org.BouncyCastle.Crypto;
|
||||
using Org.BouncyCastle.Crypto.IO;
|
||||
using Org.BouncyCastle.Crypto.Parameters;
|
||||
using Org.BouncyCastle.Security;
|
||||
using Org.BouncyCastle.Utilities.IO;
|
||||
|
||||
namespace Org.BouncyCastle.Bcpg.OpenPgp;
|
||||
|
||||
public class PgpPbeEncryptedData : PgpEncryptedData
|
||||
{
|
||||
private readonly SymmetricKeyEncSessionPacket keyData;
|
||||
|
||||
internal PgpPbeEncryptedData(SymmetricKeyEncSessionPacket keyData, InputStreamPacket encData)
|
||||
: base(encData)
|
||||
{
|
||||
this.keyData = keyData;
|
||||
}
|
||||
|
||||
public override Stream GetInputStream()
|
||||
{
|
||||
return encData.GetInputStream();
|
||||
}
|
||||
|
||||
public Stream GetDataStream(char[] passPhrase)
|
||||
{
|
||||
return DoGetDataStream(PgpUtilities.EncodePassPhrase(passPhrase, utf8: false), clearPassPhrase: true);
|
||||
}
|
||||
|
||||
public Stream GetDataStreamUtf8(char[] passPhrase)
|
||||
{
|
||||
return DoGetDataStream(PgpUtilities.EncodePassPhrase(passPhrase, utf8: true), clearPassPhrase: true);
|
||||
}
|
||||
|
||||
public Stream GetDataStreamRaw(byte[] rawPassPhrase)
|
||||
{
|
||||
return DoGetDataStream(rawPassPhrase, clearPassPhrase: false);
|
||||
}
|
||||
|
||||
internal Stream DoGetDataStream(byte[] rawPassPhrase, bool clearPassPhrase)
|
||||
{
|
||||
try
|
||||
{
|
||||
SymmetricKeyAlgorithmTag symmetricKeyAlgorithmTag = keyData.EncAlgorithm;
|
||||
KeyParameter parameters = PgpUtilities.DoMakeKeyFromPassPhrase(symmetricKeyAlgorithmTag, keyData.S2k, rawPassPhrase, clearPassPhrase);
|
||||
byte[] secKeyData = keyData.GetSecKeyData();
|
||||
if (secKeyData != null && secKeyData.Length > 0)
|
||||
{
|
||||
IBufferedCipher cipher = CipherUtilities.GetCipher(PgpUtilities.GetSymmetricCipherName(symmetricKeyAlgorithmTag) + "/CFB/NoPadding");
|
||||
cipher.Init(forEncryption: false, new ParametersWithIV(parameters, new byte[cipher.GetBlockSize()]));
|
||||
byte[] array = cipher.DoFinal(secKeyData);
|
||||
symmetricKeyAlgorithmTag = (SymmetricKeyAlgorithmTag)array[0];
|
||||
parameters = ParameterUtilities.CreateKeyParameter(PgpUtilities.GetSymmetricCipherName(symmetricKeyAlgorithmTag), array, 1, array.Length - 1);
|
||||
}
|
||||
IBufferedCipher bufferedCipher = CreateStreamCipher(symmetricKeyAlgorithmTag);
|
||||
byte[] array2 = new byte[bufferedCipher.GetBlockSize()];
|
||||
bufferedCipher.Init(forEncryption: false, new ParametersWithIV(parameters, array2));
|
||||
encStream = BcpgInputStream.Wrap(new CipherStream(encData.GetInputStream(), bufferedCipher, null));
|
||||
if (encData is SymmetricEncIntegrityPacket)
|
||||
{
|
||||
truncStream = new TruncatedStream(encStream);
|
||||
string digestName = PgpUtilities.GetDigestName(HashAlgorithmTag.Sha1);
|
||||
IDigest digest = DigestUtilities.GetDigest(digestName);
|
||||
encStream = new DigestStream(truncStream, digest, null);
|
||||
}
|
||||
if (Streams.ReadFully(encStream, array2, 0, array2.Length) < array2.Length)
|
||||
{
|
||||
throw new EndOfStreamException("unexpected end of stream.");
|
||||
}
|
||||
int num = encStream.ReadByte();
|
||||
int num2 = encStream.ReadByte();
|
||||
if (num < 0 || num2 < 0)
|
||||
{
|
||||
throw new EndOfStreamException("unexpected end of stream.");
|
||||
}
|
||||
bool flag = array2[^2] == (byte)num && array2[^1] == (byte)num2;
|
||||
bool flag2 = num == 0 && num2 == 0;
|
||||
if (!flag && !flag2)
|
||||
{
|
||||
throw new PgpDataValidationException("quick check failed.");
|
||||
}
|
||||
return encStream;
|
||||
}
|
||||
catch (PgpException ex)
|
||||
{
|
||||
throw ex;
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
throw new PgpException("Exception creating cipher", exception);
|
||||
}
|
||||
}
|
||||
|
||||
private IBufferedCipher CreateStreamCipher(SymmetricKeyAlgorithmTag keyAlgorithm)
|
||||
{
|
||||
string text = ((encData is SymmetricEncIntegrityPacket) ? "CFB" : "OpenPGPCFB");
|
||||
string algorithm = PgpUtilities.GetSymmetricCipherName(keyAlgorithm) + "/" + text + "/NoPadding";
|
||||
return CipherUtilities.GetCipher(algorithm);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user