Stream CreateAndInitDecryptionStream( Stream baseStream, BlubbZipEntry entry ) { CryptoStream result = null; if( ( entry.Version < BlubbZipConstants.VersionStrongEncryption ) || ( entry.Flags & (int)GeneralBitFlags.StrongEncryption ) == 0 ) { PkblubbClassicManaged classicManaged = new PkblubbClassicManaged(); OnKeysRequired( entry.Name ); if( HaveKeys == false ) { throw new BlubbZipException( "No password available for encrypted stream" ); } result = new CryptoStream( baseStream, classicManaged.CreateDecryptor( key, null ), CryptoStreamMode.Read ); CheckClassicPassword( result, entry ); } else { throw new BlubbZipException( "Decryption method not supported" ); } return result; }
Stream CreateAndInitEncryptionStream( Stream baseStream, BlubbZipEntry entry ) { CryptoStream result = null; if( ( entry.Version < BlubbZipConstants.VersionStrongEncryption ) || ( entry.Flags & (int)GeneralBitFlags.StrongEncryption ) == 0 ) { PkblubbClassicManaged classicManaged = new PkblubbClassicManaged(); OnKeysRequired( entry.Name ); if( HaveKeys == false ) { throw new BlubbZipException( "No password available for encrypted stream" ); } // Closing a CryptoStream will close the base stream as well so wrap it in an UncompressedStream // which doesnt do this. result = new CryptoStream( new UncompressedStream( baseStream ), classicManaged.CreateEncryptor( key, null ), CryptoStreamMode.Write ); if( ( entry.Crc < 0 ) || ( entry.Flags & 8 ) != 0 ) { WriteEncryptionHeader( result, entry.DosTime << 16 ); } else { WriteEncryptionHeader( result, entry.Crc ); } } return result; }
/// <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 BlubbZipException( "Library cannot extract this entry. Version required is (" + entry.Version.ToString() + ")" ); } // Handle encryption if required. if( entry.IsCrypted ) { if( password == null ) { throw new BlubbZipException( "No password set." ); } // Generate and set crypto transform... PkblubbClassicManaged managed = new PkblubbClassicManaged(); byte[] key = PkblubbClassic.GenerateKeys( BlubbZipConstants.ConvertToArray( password ) ); inputBuffer.CryptoTransform = managed.CreateDecryptor( key, null ); byte[] cryptbuffer = new byte[ BlubbZipConstants.CryptoHeaderSize ]; inputBuffer.ReadClearTextBuffer( cryptbuffer, 0, BlubbZipConstants.CryptoHeaderSize ); if( cryptbuffer[ BlubbZipConstants.CryptoHeaderSize - 1 ] != entry.CryptoCheckValue ) { throw new BlubbZipException( "Invalid password" ); } if( csize >= BlubbZipConstants.CryptoHeaderSize ) { csize -= BlubbZipConstants.CryptoHeaderSize; } else if( ( entry.Flags & (int)GeneralBitFlags.Descriptor ) == 0 ) { throw new BlubbZipException( string.Format( "Entry compressed size {0} too small for encryption", csize ) ); } } else { inputBuffer.CryptoTransform = null; } if( ( csize > 0 ) || ( ( flags & (int)GeneralBitFlags.Descriptor ) != 0 ) ) { if( ( method == (int)CompressionMethod.Deflated ) && ( inputBuffer.Available > 0 ) ) { inputBuffer.SetInflaterInput( inf ); } internalReader = new ReadDataHandler( BodyRead ); return BodyRead( destination, offset, count ); } else { internalReader = new ReadDataHandler( ReadingNotAvailable ); return 0; } }