private int InitialRead(byte[] destination, int offset, int count) { if (!this.CanDecompressEntry) { throw new ZipException("Library cannot extract this entry. Version required is (" + this.entry.Version.ToString() + ")"); } if (this.entry.IsCrypted) { if (this.password == null) { throw new ZipException("No password set."); } PkzipClassicManaged managed = new PkzipClassicManaged(); byte[] rgbKey = PkzipClassic.GenerateKeys(ZipConstants.ConvertToArray(this.password)); base.inputBuffer.CryptoTransform = managed.CreateDecryptor(rgbKey, null); byte[] outBuffer = new byte[12]; base.inputBuffer.ReadClearTextBuffer(outBuffer, 0, 12); if (outBuffer[11] != this.entry.CryptoCheckValue) { throw new ZipException("Invalid password"); } if (base.csize >= 12L) { base.csize -= 12L; } else if ((this.entry.Flags & 8) == 0) { throw new ZipException(string.Format("Entry compressed size {0} too small for encryption", base.csize)); } } else { base.inputBuffer.CryptoTransform = null; } if ((base.csize > 0L) || ((this.flags & 8) != 0)) { if ((this.method == 8) && (base.inputBuffer.Available > 0)) { base.inputBuffer.SetInflaterInput(base.inf); } this.internalReader = new ReadDataHandler(this.BodyRead); return this.BodyRead(destination, offset, count); } this.internalReader = new ReadDataHandler(this.ReadingNotAvailable); return 0; }
private Stream CreateAndInitDecryptionStream(Stream baseStream, ZipEntry entry) { CryptoStream classicCryptoStream = null; if ((entry.Version < 50) || ((entry.Flags & 0x40) == 0)) { PkzipClassicManaged managed = new PkzipClassicManaged(); this.OnKeysRequired(entry.Name); if (!this.HaveKeys) { throw new ZipException("No password available for encrypted stream"); } classicCryptoStream = new CryptoStream(baseStream, managed.CreateDecryptor(this.key, null), CryptoStreamMode.Read); CheckClassicPassword(classicCryptoStream, entry); return classicCryptoStream; } if (entry.Version != 0x33) { throw new ZipException("Decryption method not supported"); } this.OnKeysRequired(entry.Name); if (!this.HaveKeys) { throw new ZipException("No password available for AES encrypted stream"); } int aESSaltLen = entry.AESSaltLen; byte[] buffer = new byte[aESSaltLen]; int num2 = baseStream.Read(buffer, 0, aESSaltLen); if (num2 != aESSaltLen) { throw new ZipException(string.Concat(new object[] { "AES Salt expected ", aESSaltLen, " got ", num2 })); } byte[] buffer2 = new byte[2]; baseStream.Read(buffer2, 0, 2); int blockSize = entry.AESKeySize / 8; ZipAESTransform transform = new ZipAESTransform(this.rawPassword_, buffer, blockSize, false); byte[] pwdVerifier = transform.PwdVerifier; if ((pwdVerifier[0] != buffer2[0]) || (pwdVerifier[1] != buffer2[1])) { throw new Exception("Invalid password for AES"); } return new ZipAESStream(baseStream, transform, CryptoStreamMode.Read); }