Esempio n. 1
0
 public void Length()
 {
     using (TruncatedStream stream = CreateTruncatedStream(5))
     {
         Assert.AreEqual(5, stream.Length);
     }
 }
Esempio n. 2
0
 public void Read()
 {
     using (TruncatedStream stream = CreateTruncatedStream(5))
     {
         byte[] buffer = new byte[16];
         Assert.AreEqual(5, stream.Read(buffer, 0, buffer.Length));
         CollectionAssert.AreEqual(new byte[] { 1, 2, 3, 4, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, buffer);
     }
 }
 public async Task ReadAsync()
 {
     using (TruncatedStream stream = CreateTruncatedStream(5))
     {
         byte[] buffer = new byte[16];
         Assert.AreEqual(5, await stream.ReadAsync(buffer, 0, buffer.Length));
         CollectionAssert.AreEqual(new byte[] { 1, 2, 3, 4, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, buffer);
     }
 }
 public void CopyTo()
 {
     using (TruncatedStream stream = CreateTruncatedStream(5))
     {
         byte[] buffer      = new byte[16];
         var    destination = new MemoryStream(buffer);
         stream.CopyTo(destination);
         CollectionAssert.AreEqual(new byte[] { 1, 2, 3, 4, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, buffer);
     }
 }
Esempio n. 5
0
 internal Stream DoGetDataStream(byte[] rawPassPhrase, bool clearPassPhrase)
 {
     //IL_012b: Unknown result type (might be due to invalid IL or missing references)
     //IL_015a: Unknown result type (might be due to invalid IL or missing references)
     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 = (Stream)(object)BcpgInputStream.Wrap((Stream)(object)new CipherStream((Stream)(object)encData.GetInputStream(), bufferedCipher, null));
         if (encData is SymmetricEncIntegrityPacket)
         {
             truncStream = new TruncatedStream(encStream);
             string  digestName = PgpUtilities.GetDigestName(HashAlgorithmTag.Sha1);
             IDigest digest     = DigestUtilities.GetDigest(digestName);
             encStream = (Stream)(object)new DigestStream((Stream)(object)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[array2.Length - 2] == (byte)num && array2[array2.Length - 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 (global::System.Exception exception)
     {
         throw new PgpException("Exception creating cipher", exception);
     }
 }
Esempio n. 6
0
        public void Seek()
        {
            using (TruncatedStream stream = CreateTruncatedStream(5))
            {
                Assert.AreEqual(2, stream.Seek(2, SeekOrigin.Begin));
                Assert.AreEqual(2, stream.Position);
                Assert.AreEqual(2, m_stream.Position);

                Assert.AreEqual(3, stream.Seek(1, SeekOrigin.Current));
                Assert.AreEqual(3, stream.Position);
                Assert.AreEqual(3, m_stream.Position);

                Assert.AreEqual(4, stream.Seek(-1, SeekOrigin.End));
                Assert.AreEqual(4, stream.Position);
                Assert.AreEqual(4, m_stream.Position);
            }
        }
        /// <summary>Return the decrypted input stream, using the passed in passphrase.</summary>
        public Stream GetDataStream(char[] passPhrase)
        {
            try
            {
                var keyAlgorithm = _keyData.EncAlgorithm;

                var key = PgpUtilities.MakeKeyFromPassPhrase(
                    keyAlgorithm, _keyData.S2K, passPhrase);


                var secKeyData = _keyData.GetSecKeyData();
                if (secKeyData != null && secKeyData.Length > 0)
                {
                    var keyCipher = CipherUtilities.GetCipher(
                        PgpUtilities.GetSymmetricCipherName(keyAlgorithm) + "/CFB/NoPadding");

                    keyCipher.Init(false,
                                   new ParametersWithIV(key, new byte[keyCipher.GetBlockSize()]));

                    var keyBytes = keyCipher.DoFinal(secKeyData);

                    keyAlgorithm = (SymmetricKeyAlgorithmTag)keyBytes[0];

                    key = ParameterUtilities.CreateKeyParameter(
                        PgpUtilities.GetSymmetricCipherName(keyAlgorithm),
                        keyBytes, 1, keyBytes.Length - 1);
                }


                var c = CreateStreamCipher(keyAlgorithm);

                var iv = new byte[c.GetBlockSize()];

                c.Init(false, new ParametersWithIV(key, iv));

                EncStream = BcpgInputStream.Wrap(new CipherStream(EncData.GetInputStream(), c, null));

                if (EncData is SymmetricEncIntegrityPacket)
                {
                    TruncStream = new TruncatedStream(EncStream);

                    var digestName = PgpUtilities.GetDigestName(HashAlgorithmTag.Sha1);
                    var digest     = DigestUtilities.GetDigest(digestName);

                    EncStream = new DigestStream(TruncStream, digest, null);
                }

                if (Streams.ReadFully(EncStream, iv, 0, iv.Length) < iv.Length)
                {
                    throw new EndOfStreamException("unexpected end of stream.");
                }

                var v1 = EncStream.ReadByte();
                var v2 = EncStream.ReadByte();

                if (v1 < 0 || v2 < 0)
                {
                    throw new EndOfStreamException("unexpected end of stream.");
                }


                // Note: the oracle attack on the "quick check" bytes is not deemed
                // a security risk for PBE (see PgpPublicKeyEncryptedData)

                var repeatCheckPassed =
                    iv[iv.Length - 2] == (byte)v1 &&
                    iv[iv.Length - 1] == (byte)v2;

                // Note: some versions of PGP appear to produce 0 for the extra
                // bytes rather than repeating the two previous bytes
                var zeroesCheckPassed = v1 == 0 && v2 == 0;
                if (!repeatCheckPassed && !zeroesCheckPassed)
                {
                    throw new PgpDataValidationException("quick check failed.");
                }


                return(EncStream);
            }
            catch (PgpException)
            {
                throw;
            }
            catch (Exception e)
            {
                throw new PgpException("Exception creating cipher", e);
            }
        }
        internal Stream DoGetDataStream(byte[] rawPassPhrase, bool clearPassPhrase)
        {
			try
			{
				SymmetricKeyAlgorithmTag keyAlgorithm = keyData.EncAlgorithm;

				KeyParameter key = PgpUtilities.DoMakeKeyFromPassPhrase(
					keyAlgorithm, keyData.S2k, rawPassPhrase, clearPassPhrase);

                byte[] secKeyData = keyData.GetSecKeyData();
				if (secKeyData != null && secKeyData.Length > 0)
				{
					IBufferedCipher keyCipher = CipherUtilities.GetCipher(
						PgpUtilities.GetSymmetricCipherName(keyAlgorithm) + "/CFB/NoPadding");

					keyCipher.Init(false,
						new ParametersWithIV(key, new byte[keyCipher.GetBlockSize()]));

					byte[] keyBytes = keyCipher.DoFinal(secKeyData);

					keyAlgorithm = (SymmetricKeyAlgorithmTag) keyBytes[0];

					key = ParameterUtilities.CreateKeyParameter(
						PgpUtilities.GetSymmetricCipherName(keyAlgorithm),
						keyBytes, 1, keyBytes.Length - 1);
				}


				IBufferedCipher c = CreateStreamCipher(keyAlgorithm);

				byte[] iv = new byte[c.GetBlockSize()];

				c.Init(false, new ParametersWithIV(key, iv));

				encStream = BcpgInputStream.Wrap(new CipherStream(encData.GetInputStream(), c, 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, iv, 0, iv.Length) < iv.Length)
					throw new EndOfStreamException("unexpected end of stream.");

				int v1 = encStream.ReadByte();
				int v2 = encStream.ReadByte();

				if (v1 < 0 || v2 < 0)
					throw new EndOfStreamException("unexpected end of stream.");


				// Note: the oracle attack on the "quick check" bytes is not deemed
				// a security risk for PBE (see PgpPublicKeyEncryptedData)

				bool repeatCheckPassed =
						iv[iv.Length - 2] == (byte)v1
					&&	iv[iv.Length - 1] == (byte)v2;

				// Note: some versions of PGP appear to produce 0 for the extra
				// bytes rather than repeating the two previous bytes
				bool zeroesCheckPassed =
						v1 == 0
					&&	v2 == 0;

				if (!repeatCheckPassed && !zeroesCheckPassed)
				{
					throw new PgpDataValidationException("quick check failed.");
				}


				return encStream;
			}
			catch (PgpException e)
			{
				throw e;
			}
			catch (Exception e)
			{
				throw new PgpException("Exception creating cipher", e);
			}
		}
        /// <summary>Return the decrypted data stream for the packet.</summary>
        public Stream GetDataStream(
            PgpPrivateKey privKey)
        {
            byte[] plain = fetchSymmetricKeyData(privKey);

            IBufferedCipher c2;
            string          cipherName = PgpUtilities.GetSymmetricCipherName((SymmetricKeyAlgorithmTag)plain[0]);
            string          cName      = cipherName;

            try
            {
                if (encData is SymmetricEncIntegrityPacket)
                {
                    cName += "/CFB/NoPadding";
                }
                else
                {
                    cName += "/OpenPGPCFB/NoPadding";
                }

                c2 = CipherUtilities.GetCipher(cName);
            }
            catch (PgpException e)
            {
                throw e;
            }
            catch (Exception e)
            {
                throw new PgpException("exception creating cipher", e);
            }

            if (c2 == null)
            {
                return(encData.GetInputStream());
            }

            try
            {
                KeyParameter key = ParameterUtilities.CreateKeyParameter(
                    cipherName, plain, 1, plain.Length - 3);

                byte[] iv = new byte[c2.GetBlockSize()];

                c2.Init(false, new ParametersWithIV(key, iv));

                encStream = BcpgInputStream.Wrap(new CipherStream(encData.GetInputStream(), c2, 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, iv, 0, iv.Length) < iv.Length)
                {
                    throw new EndOfStreamException("unexpected end of stream.");
                }

                int v1 = encStream.ReadByte();
                int v2 = encStream.ReadByte();

                if (v1 < 0 || v2 < 0)
                {
                    throw new EndOfStreamException("unexpected end of stream.");
                }

                // Note: the oracle attack on the "quick check" bytes is deemed
                // a security risk for typical public key encryption usages,
                // therefore we do not perform the check.

//				bool repeatCheckPassed =
//					iv[iv.Length - 2] == (byte)v1
//					&&	iv[iv.Length - 1] == (byte)v2;
//
//				// Note: some versions of PGP appear to produce 0 for the extra
//				// bytes rather than repeating the two previous bytes
//				bool zeroesCheckPassed =
//					v1 == 0
//					&&	v2 == 0;
//
//				if (!repeatCheckPassed && !zeroesCheckPassed)
//				{
//					throw new PgpDataValidationException("quick check failed.");
//				}

                return(encStream);
            }
            catch (PgpException e)
            {
                throw e;
            }
            catch (Exception e)
            {
                throw new PgpException("Exception starting decryption", e);
            }
        }
		/// <summary>Return the decrypted data stream for the packet.</summary>
        public Stream GetDataStream(
            PgpPrivateKey privKey)
        {
			byte[] plain = fetchSymmetricKeyData(privKey);

			IBufferedCipher c2;
			string cipherName = PgpUtilities.GetSymmetricCipherName((SymmetricKeyAlgorithmTag) plain[0]);
			string cName = cipherName;

			try
            {
                if (encData is SymmetricEncIntegrityPacket)
                {
					cName += "/CFB/NoPadding";
                }
                else
                {
					cName += "/OpenPGPCFB/NoPadding";
                }

				c2 = CipherUtilities.GetCipher(cName);
			}
            catch (PgpException e)
            {
                throw e;
            }
            catch (Exception e)
            {
                throw new PgpException("exception creating cipher", e);
            }

			if (c2 == null)
				return encData.GetInputStream();

			try
            {
				KeyParameter key = ParameterUtilities.CreateKeyParameter(
					cipherName, plain, 1, plain.Length - 3);

				byte[] iv = new byte[c2.GetBlockSize()];

				c2.Init(false, new ParametersWithIV(key, iv));

                encStream = BcpgInputStream.Wrap(new CipherStream(encData.GetInputStream(), c2, 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, iv, 0, iv.Length) < iv.Length)
					throw new EndOfStreamException("unexpected end of stream.");

				int v1 = encStream.ReadByte();
                int v2 = encStream.ReadByte();

				if (v1 < 0 || v2 < 0)
                    throw new EndOfStreamException("unexpected end of stream.");

				// Note: the oracle attack on the "quick check" bytes is deemed
				// a security risk for typical public key encryption usages,
				// therefore we do not perform the check.

//				bool repeatCheckPassed =
//					iv[iv.Length - 2] == (byte)v1
//					&&	iv[iv.Length - 1] == (byte)v2;
//
//				// Note: some versions of PGP appear to produce 0 for the extra
//				// bytes rather than repeating the two previous bytes
//				bool zeroesCheckPassed =
//					v1 == 0
//					&&	v2 == 0;
//
//				if (!repeatCheckPassed && !zeroesCheckPassed)
//				{
//					throw new PgpDataValidationException("quick check failed.");
//				}

				return encStream;
            }
            catch (PgpException e)
            {
                throw e;
            }
            catch (Exception e)
            {
                throw new PgpException("Exception starting decryption", e);
            }
		}
        /// <summary>Return the decrypted input stream, using the passed in passphrase.</summary>
        public Stream GetDataStream(
            char[] passPhrase)
        {
            IBufferedCipher c;

            try
            {
                SymmetricKeyAlgorithmTag alg = keyData.EncAlgorithm;

                string cName = PgpUtilities.GetSymmetricCipherName(alg);

                if (encData is SymmetricEncIntegrityPacket)
                {
                    cName += "/CFB/NoPadding";
                }
                else
                {
                    cName += "/OpenPGPCFB/NoPadding";
                }

                c = CipherUtilities.GetCipher(cName);
            }
            catch (PgpException e)
            {
                throw e;
            }
            catch (Exception e)
            {
                throw new PgpException("exception creating cipher", e);
            }

            if (c != null)
            {
                try
                {
                    KeyParameter key = PgpUtilities.MakeKeyFromPassPhrase(
                        keyData.EncAlgorithm, keyData.S2k, passPhrase);

                    byte[] iv = new byte[c.GetBlockSize()];

                    c.Init(false, new ParametersWithIV(key, iv));

                    encStream = BcpgInputStream.Wrap(new CipherStream(encData.GetInputStream(), c, 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);
                    }

                    for (int i = 0; i != iv.Length; i++)
                    {
                        int ch = encStream.ReadByte();

                        if (ch < 0)
                        {
                            throw new EndOfStreamException("unexpected end of stream.");
                        }

                        iv[i] = (byte)ch;
                    }

                    int v1 = encStream.ReadByte();
                    int v2 = encStream.ReadByte();

                    if (v1 < 0 || v2 < 0)
                    {
                        throw new EndOfStreamException("unexpected end of stream.");
                    }


                    // Note: the oracle attack on the "quick check" bytes is not deemed
                    // a security risk for PBE (see PgpPublicKeyEncryptedData)

                    bool repeatCheckPassed =
                        iv[iv.Length - 2] == (byte)v1 &&
                        iv[iv.Length - 1] == (byte)v2;

                    // Note: some versions of PGP appear to produce 0 for the extra
                    // bytes rather than repeating the two previous bytes
                    bool zeroesCheckPassed =
                        v1 == 0 &&
                        v2 == 0;

                    if (!repeatCheckPassed && !zeroesCheckPassed)
                    {
                        throw new PgpDataValidationException("quick check failed.");
                    }


                    return(encStream);
                }
                catch (PgpException e)
                {
                    throw e;
                }
                catch (Exception e)
                {
                    throw new PgpException("Exception creating cipher", e);
                }
            }
            else
            {
                return(encData.GetInputStream());
            }
        }
        /// <summary>Return the decrypted data stream for the packet.</summary>
        public Stream GetDataStream(
            PgpPrivateKey privKey)
        {
            IBufferedCipher c1 = GetKeyCipher(keyData.Algorithm);

            try
            {
                c1.Init(false, privKey.Key);
            }
            catch (InvalidKeyException e)
            {
                throw new PgpException("error setting asymmetric cipher", e);
            }

            BigInteger[] keyD = keyData.GetEncSessionKey();

            if (keyData.Algorithm == PublicKeyAlgorithmTag.RsaEncrypt
                || keyData.Algorithm == PublicKeyAlgorithmTag.RsaGeneral)
            {
                byte[] bi = keyD[0].ToByteArray();

                if (bi[0] == 0)
                {
                    c1.ProcessBytes(bi, 1, bi.Length - 1);
                }
                else
                {
                    c1.ProcessBytes(bi, 0, bi.Length);
                }
            }
            else
            {
                ElGamalPrivateKeyParameters k = (ElGamalPrivateKeyParameters)privKey.Key;
                int size = (k.Parameters.P.BitLength + 7) / 8;

                byte[] bi = keyD[0].ToByteArray();

                int diff = bi.Length - size;
                if (diff >= 0)
                {
                    c1.ProcessBytes(bi, diff, size);
                }
                else
                {
                    byte[] zeros = new byte[-diff];
                    c1.ProcessBytes(zeros);
                    c1.ProcessBytes(bi);
                }

                bi = keyD[1].ToByteArray();

                diff = bi.Length - size;
                if (diff >= 0)
                {
                    c1.ProcessBytes(bi, diff, size);
                }
                else
                {
                    byte[] zeros = new byte[-diff];
                    c1.ProcessBytes(zeros);
                    c1.ProcessBytes(bi);
                }
            }

            byte[] plain;
            try
            {
                plain = c1.DoFinal();
            }
            catch (Exception e)
            {
                throw new PgpException("exception decrypting secret key", e);
            }

            if (!ConfirmCheckSum(plain))
            {
                throw new PgpKeyValidationException("key checksum failed");
            }

            IBufferedCipher c2;
            string cipherName = PgpUtilities.GetSymmetricCipherName((SymmetricKeyAlgorithmTag) plain[0]);
            string cName = cipherName;

            try
            {
                if (encData is SymmetricEncIntegrityPacket)
                {
                    cName += "/CFB/NoPadding";
                }
                else
                {
                    cName += "/OpenPGPCFB/NoPadding";
                }

                c2 = CipherUtilities.GetCipher(cName);
            }
            catch (PgpException e)
            {
                throw e;
            }
            catch (Exception e)
            {
                throw new PgpException("exception creating cipher", e);
            }

            if (c2 == null)
            {
                return encData.GetInputStream();
            }

            try
            {
                byte[] keyBytes = new byte[plain.Length - 3];
                Array.Copy(plain, 1, keyBytes, 0, keyBytes.Length);

                KeyParameter key = ParameterUtilities.CreateKeyParameter(
                    cipherName, keyBytes);

                byte[] iv = new byte[c2.GetBlockSize()];

                c2.Init(false, new ParametersWithIV(key, iv));

                encStream = BcpgInputStream.Wrap(new CipherStream(encData.GetInputStream(), c2, null));

                if (encData is SymmetricEncIntegrityPacket)
                {
                    truncStream = new TruncatedStream(encStream);
                    encStream = new DigestStream(truncStream,
                        DigestUtilities.GetDigest(PgpUtilities.GetDigestName(HashAlgorithmTag.Sha1)), null);
                }

                for (int i = 0; i != iv.Length; i++)
                {
                    int ch = encStream.ReadByte();

                    if (ch < 0)
                    {
                        throw new EndOfStreamException("unexpected end of stream.");
                    }

                    iv[i] = (byte)ch;
                }

                int v1 = encStream.ReadByte();
                int v2 = encStream.ReadByte();

                if (v1 < 0 || v2 < 0)
                {
                    throw new EndOfStreamException("unexpected end of stream.");
                }

                // Note: the oracle attack on the "quick check" bytes is deemed
                // a security risk for typical public key encryption usages,
                // therefore we do not perform the check.

            //				bool repeatCheckPassed =
            //					iv[iv.Length - 2] == (byte)v1
            //					&&	iv[iv.Length - 1] == (byte)v2;
            //
            //				// Note: some versions of PGP appear to produce 0 for the extra
            //				// bytes rather than repeating the two previous bytes
            //				bool zeroesCheckPassed =
            //					v1 == 0
            //					&&	v2 == 0;
            //
            //				if (!repeatCheckPassed && !zeroesCheckPassed)
            //				{
            //					throw new PgpDataValidationException("quick check failed.");
            //				}

                return encStream;
            }
            catch (PgpException e)
            {
                throw e;
            }
            catch (Exception e)
            {
                throw new PgpException("Exception starting decryption", e);
            }
        }
        /// <summary>Return the decrypted data stream for the packet.</summary>
        public Stream GetDataStream(
            PgpPrivateKey privKey)
        {
            IBufferedCipher c1 = GetKeyCipher(keyData.Algorithm);

            try
            {
                c1.Init(false, privKey.Key);
            }
            catch (InvalidKeyException e)
            {
                throw new PgpException("error setting asymmetric cipher", e);
            }

            BigInteger[] keyD = keyData.GetEncSessionKey();

            if (keyData.Algorithm == PublicKeyAlgorithmTag.RsaEncrypt ||
                keyData.Algorithm == PublicKeyAlgorithmTag.RsaGeneral)
            {
                byte[] bi = keyD[0].ToByteArray();

                if (bi[0] == 0)
                {
                    c1.ProcessBytes(bi, 1, bi.Length - 1);
                }
                else
                {
                    c1.ProcessBytes(bi, 0, bi.Length);
                }
            }
            else
            {
                ElGamalPrivateKeyParameters k = (ElGamalPrivateKeyParameters)privKey.Key;
                int size = (k.Parameters.P.BitLength + 7) / 8;

                byte[] bi = keyD[0].ToByteArray();

                int diff = bi.Length - size;
                if (diff >= 0)
                {
                    c1.ProcessBytes(bi, diff, size);
                }
                else
                {
                    byte[] zeros = new byte[-diff];
                    c1.ProcessBytes(zeros);
                    c1.ProcessBytes(bi);
                }

                bi = keyD[1].ToByteArray();

                diff = bi.Length - size;
                if (diff >= 0)
                {
                    c1.ProcessBytes(bi, diff, size);
                }
                else
                {
                    byte[] zeros = new byte[-diff];
                    c1.ProcessBytes(zeros);
                    c1.ProcessBytes(bi);
                }
            }

            byte[] plain;
            try
            {
                plain = c1.DoFinal();
            }
            catch (Exception e)
            {
                throw new PgpException("exception decrypting secret key", e);
            }

            if (!ConfirmCheckSum(plain))
            {
                throw new PgpKeyValidationException("key checksum failed");
            }

            IBufferedCipher c2;
            string          cipherName = PgpUtilities.GetSymmetricCipherName((SymmetricKeyAlgorithmTag)plain[0]);
            string          cName      = cipherName;

            try
            {
                if (encData is SymmetricEncIntegrityPacket)
                {
                    cName += "/CFB/NoPadding";
                }
                else
                {
                    cName += "/OpenPGPCFB/NoPadding";
                }

                c2 = CipherUtilities.GetCipher(cName);
            }
//            catch (NoSuchProviderException e)
            catch (PgpException e)
            {
                throw e;
            }
            catch (Exception e)
            {
                throw new PgpException("exception creating cipher", e);
            }

            if (c2 == null)
            {
                return(encData.GetInputStream());
            }

            try
            {
                byte[] keyBytes = new byte[plain.Length - 3];
                Array.Copy(plain, 1, keyBytes, 0, keyBytes.Length);

                KeyParameter key = ParameterUtilities.CreateKeyParameter(
                    cipherName, keyBytes);

                byte[] iv = new byte[c2.GetBlockSize()];

                c2.Init(false, new ParametersWithIV(key, iv));

                encStream = BcpgInputStream.Wrap(new CipherStream(encData.GetInputStream(), c2, null));

                if (encData is SymmetricEncIntegrityPacket)
                {
                    truncStream = new TruncatedStream(encStream);
                    encStream   = new DigestStream(truncStream,
                                                   DigestUtilities.GetDigest(PgpUtilities.GetDigestName(HashAlgorithmTag.Sha1)), null);
                }

                for (int i = 0; i != iv.Length; i++)
                {
                    int ch = encStream.ReadByte();

                    if (ch < 0)
                    {
                        throw new EndOfStreamException("unexpected end of stream.");
                    }

                    iv[i] = (byte)ch;
                }

                int v1 = encStream.ReadByte();
                int v2 = encStream.ReadByte();

                if (v1 < 0 || v2 < 0)
                {
                    throw new EndOfStreamException("unexpected end of stream.");
                }

                // Note: the oracle attack on the "quick check" bytes is deemed
                // a security risk for typical public key encryption usages,
                // therefore we do not perform the check.

//				bool repeatCheckPassed =
//					iv[iv.Length - 2] == (byte)v1
//					&&	iv[iv.Length - 1] == (byte)v2;
//
//				// Note: some versions of PGP appear to produce 0 for the extra
//				// bytes rather than repeating the two previous bytes
//				bool zeroesCheckPassed =
//					v1 == 0
//					&&	v2 == 0;
//
//				if (!repeatCheckPassed && !zeroesCheckPassed)
//				{
//					throw new PgpDataValidationException("quick check failed.");
//				}

                return(encStream);
            }
            catch (PgpException e)
            {
                throw e;
            }
            catch (Exception e)
            {
                throw new PgpException("Exception starting decryption", e);
            }
        }
        public Stream GetDataStream(PgpPrivateKey privKey)
        {
            //IL_012b: Unknown result type (might be due to invalid IL or missing references)
            //IL_015a: Unknown result type (might be due to invalid IL or missing references)
            byte[] array = RecoverSessionData(privKey);
            if (!ConfirmCheckSum(array))
            {
                throw new PgpKeyValidationException("key checksum failed");
            }
            SymmetricKeyAlgorithmTag symmetricKeyAlgorithmTag = (SymmetricKeyAlgorithmTag)array[0];

            if (symmetricKeyAlgorithmTag == SymmetricKeyAlgorithmTag.Null)
            {
                return((Stream)(object)encData.GetInputStream());
            }
            string          symmetricCipherName = PgpUtilities.GetSymmetricCipherName(symmetricKeyAlgorithmTag);
            string          text = symmetricCipherName;
            IBufferedCipher cipher;

            try
            {
                text   = ((!(encData is SymmetricEncIntegrityPacket)) ? (text + "/OpenPGPCFB/NoPadding") : (text + "/CFB/NoPadding"));
                cipher = CipherUtilities.GetCipher(text);
            }
            catch (PgpException ex)
            {
                throw ex;
            }
            catch (global::System.Exception exception)
            {
                throw new PgpException("exception creating cipher", exception);
            }
            try
            {
                KeyParameter parameters = ParameterUtilities.CreateKeyParameter(symmetricCipherName, array, 1, array.Length - 3);
                byte[]       array2     = new byte[cipher.GetBlockSize()];
                cipher.Init(forEncryption: false, new ParametersWithIV(parameters, array2));
                encStream = (Stream)(object)BcpgInputStream.Wrap((Stream)(object)new CipherStream((Stream)(object)encData.GetInputStream(), cipher, null));
                if (encData is SymmetricEncIntegrityPacket)
                {
                    truncStream = new TruncatedStream(encStream);
                    string  digestName = PgpUtilities.GetDigestName(HashAlgorithmTag.Sha1);
                    IDigest digest     = DigestUtilities.GetDigest(digestName);
                    encStream = (Stream)(object)new DigestStream((Stream)(object)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.");
                }
                return(encStream);
            }
            catch (PgpException ex2)
            {
                throw ex2;
            }
            catch (global::System.Exception exception2)
            {
                throw new PgpException("Exception starting decryption", exception2);
            }
        }