示例#1
0
        /// <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);
        }
示例#2
0
 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;
 }
示例#3
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;
        }
示例#4
0
 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);
 }