/// <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> private int InitialRead(byte[] destination, int offset, int count) { if (!CanDecompressEntry) { throw new ZipException("Library cannot extract this entry. Version required is (" + entry.Version + ")"); } // Handle encryption if required. if (entry.IsCrypted) { #if NETCF_1_0 throw new ZipException("Encryption 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(ZipConstants.ConvertToArray(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; } else if ((entry.Flags & (int) GeneralBitFlags.Descriptor) == 0) { throw new ZipException(string.Format("Entry compressed size {0} too small for encryption", csize)); } #endif } else { #if !NETCF_1_0 inputBuffer.CryptoTransform = null; #endif } if ((method == (int) CompressionMethod.Deflated) && (inputBuffer.Available > 0)) { inputBuffer.SetInflaterInput(inf); } internalReader = BodyRead; return BodyRead(destination, offset, count); }
private 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; }