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); } }