Beispiel #1
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);
     }
 }
        /// <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);
            }
        }