/// <summary> /// Perform the initial read on an entry which may include /// reading encryption headers and setting up inflation. /// </summary> /// <param name="destination">The destination to fill with data read.</param> /// <param name="offset">The offset to start reading at.</param> /// <param name="count">The maximum number of bytes to read.</param> /// <returns>The actual number of bytes read.</returns> int InitialRead(byte[] destination, int offset, int count) { if ( !CanDecompressEntry ) { throw new ZipException("Library cannot extract this entry. Version required is (" + entry.Version.ToString() + ")"); } // Handle encryption if required. if (entry.IsCrypted) { #if COMPACT_FRAMEWORK_V10 throw new ZipException("Encyptiong not supported for Compact Framework 1.0"); #else if (password == null) { throw new ZipException("No password set."); } // Generate and set crypto transform... PkzipClassicManaged managed = new PkzipClassicManaged(); byte[] key = PkzipClassic.GenerateKeys(Encoding.ASCII.GetBytes(password)); inputBuffer.CryptoTransform = managed.CreateDecryptor(key, null); byte[] cryptbuffer = new byte[ZipConstants.CryptoHeaderSize]; inputBuffer.ReadClearTextBuffer(cryptbuffer, 0, ZipConstants.CryptoHeaderSize); if (cryptbuffer[ZipConstants.CryptoHeaderSize - 1] != entry.CryptoCheckValue) { throw new ZipException("Invalid password"); } if (csize >= ZipConstants.CryptoHeaderSize) { csize -= ZipConstants.CryptoHeaderSize; } #endif } else { #if !COMPACT_FRAMEWORK_V10 inputBuffer.CryptoTransform = null; #endif } if ( (method == (int)CompressionMethod.Deflated) && (inputBuffer.Available > 0) ) { inputBuffer.SetInflaterInput(inf); } internalReader = new ReaderDelegate(BodyRead); return BodyRead(destination, offset, count); }
private int InitialRead(byte[] destination, int offset, int count) { if (!CanDecompressEntry) { throw new ZipException("Library cannot extract this entry. Version required is (" + _entry.Version + ")"); } if (_entry.IsCrypted) { if (_password == null) { throw new ZipException("No password set."); } var managed = new PkzipClassicManaged(); var rgbKey = PkzipClassic.GenerateKeys(ZipConstants.ConvertToArray(_password)); InputBuffer.CryptoTransform = managed.CreateDecryptor(rgbKey, null); var outBuffer = new byte[12]; InputBuffer.ReadClearTextBuffer(outBuffer, 0, 12); if (outBuffer[11] != _entry.CryptoCheckValue) { throw new ZipException("Invalid password"); } if (Csize < 12L) { if ((_entry.Flags & 8) == 0) { throw new ZipException($"Entry compressed size {Csize} too small for encryption"); } } else { Csize -= 12L; } } else { InputBuffer.CryptoTransform = null; } if ((Csize > 0L) || ((_flags & 8) != 0)) { if ((_method == 8) && (InputBuffer.Available > 0)) { InputBuffer.SetInflaterInput(Inf); } _internalReader = BodyRead; return BodyRead(destination, offset, count); } _internalReader = ReadingNotAvailable; return 0; }
Stream CreateAndInitDecryptionStream(Stream baseStream, ZipEntry entry) { CryptoStream result = null; if ( (entry.Version < ZipConstants.VersionStrongEncryption) || (entry.Flags & (int)GeneralBitFlags.StrongEncryption) == 0) { PkzipClassicManaged classicManaged = new PkzipClassicManaged(); OnKeysRequired(entry.Name); if (HaveKeys == false) { throw new ZipException("No password available for encrypted stream"); } result = new CryptoStream(baseStream, classicManaged.CreateDecryptor(key, null), CryptoStreamMode.Read); CheckClassicPassword(result, entry); } else { throw new ZipException("Decryption method not supported"); } return result; }
private Stream CreateAndInitDecryptionStream(Stream baseStream, ZipEntry entry) { if ((entry.Version < 50) || ((entry.Flags & 0x40) == 0)) { var managed = new PkzipClassicManaged(); OnKeysRequired(entry.Name); if (!HaveKeys) { throw new ZipException("No password available for encrypted stream"); } var classicCryptoStream = new CryptoStream(baseStream, managed.CreateDecryptor(_key, null), CryptoStreamMode.Read); CheckClassicPassword(classicCryptoStream, entry); return classicCryptoStream; } if (entry.Version != 0x33) { throw new ZipException("Decryption method not supported"); } OnKeysRequired(entry.Name); if (!HaveKeys) { throw new ZipException("No password available for AES encrypted stream"); } var aEsSaltLen = entry.AesSaltLen; var buffer = new byte[aEsSaltLen]; var num2 = baseStream.Read(buffer, 0, aEsSaltLen); if (num2 != aEsSaltLen) { throw new ZipException(string.Concat(new object[] { "AES Salt expected ", aEsSaltLen, " got ", num2 })); } var buffer2 = new byte[2]; baseStream.Read(buffer2, 0, 2); var blockSize = entry.AesKeySize / 8; var transform = new ZipAESTransform(_rawPassword, buffer, blockSize, false); var 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); }