/// <summary> /// Test an archive for integrity/validity /// </summary> /// <param name="testData">Perform low level data Crc check</param> /// <param name="strategy">The <see cref="TestStrategy"></see> to apply.</param> /// <param name="resultHandler">The <see cref="ZipTestResultHandler"></see> handler to call during testing.</param> /// <returns>true if all tests pass, false otherwise</returns> /// <exception cref="ObjectDisposedException">The object has already been closed.</exception> public bool TestArchive(bool testData, TestStrategy strategy, ZipTestResultHandler resultHandler) { if (isDisposed_) { throw new ObjectDisposedException("ZipFile"); } TestStatus status = new TestStatus(this); if ( resultHandler != null ) { resultHandler(status, null); } HeaderTest test = testData ? (HeaderTest.Header | HeaderTest.Extract) : HeaderTest.Header; bool testing = true; try { int entryIndex = 0; while ( testing && (entryIndex < Count) ) { if ( resultHandler != null ) { status.SetEntry(this[entryIndex]); status.SetOperation(TestOperation.EntryHeader); resultHandler(status, null); } try { TestLocalHeader(this[entryIndex], test); } catch(ZipException ex) { status.AddError(); if ( resultHandler != null ) { resultHandler(status, string.Format("Exception during test - '{0}'", ex.Message)); } if ( strategy == TestStrategy.FindFirstError ) { testing = false; } } if ( testing && testData && this[entryIndex].IsFile ) { if ( resultHandler != null ) { status.SetOperation(TestOperation.EntryData); resultHandler(status, null); } Crc32 crc = new Crc32(); using (Stream entryStream = this.GetInputStream(this[entryIndex])) { byte[] buffer = new byte[4096]; long totalBytes = 0; int bytesRead; while ((bytesRead = entryStream.Read(buffer, 0, buffer.Length)) > 0) { crc.Update(buffer, 0, bytesRead); if (resultHandler != null) { totalBytes += bytesRead; status.SetBytesTested(totalBytes); resultHandler(status, null); } } } if (this[entryIndex].Crc != crc.Value) { status.AddError(); if ( resultHandler != null ) { resultHandler(status, "CRC mismatch"); } if ( strategy == TestStrategy.FindFirstError ) { testing = false; } } if (( this[entryIndex].Flags & (int)GeneralBitFlags.Descriptor) != 0 ) { ZipHelperStream helper = new ZipHelperStream(baseStream_); DescriptorData data = new DescriptorData(); helper.ReadDataDescriptor(this[entryIndex].LocalHeaderRequiresZip64, data); if (this[entryIndex].Crc != data.Crc) { status.AddError(); } if (this[entryIndex].CompressedSize != data.CompressedSize) { status.AddError(); } if (this[entryIndex].Size != data.Size) { status.AddError(); } } } if ( resultHandler != null ) { status.SetOperation(TestOperation.EntryComplete); resultHandler(status, null); } entryIndex += 1; } if ( resultHandler != null ) { status.SetOperation(TestOperation.MiscellaneousTests); resultHandler(status, null); } // TODO: the 'Corrina Johns' test where local headers are missing from // the central directory. They are therefore invisible to many archivers. } catch (Exception ex) { status.AddError(); if ( resultHandler != null ) { resultHandler(status, string.Format("Exception during test - '{0}'", ex.Message)); } } if ( resultHandler != null ) { status.SetOperation(TestOperation.Complete); status.SetEntry(null); resultHandler(status, null); } return (status.ErrorCount == 0); }
private byte[] IV(Salt secret, Salt salt) { // Long story, this has been a little difficult to finally settle upon an algorithm. // We know we don't want to the same value each time, and we prefer not to use only // the public salt. My biggest concern is not generating a IV value that interacts // with AES in a way that might divulge information unintentionally. Since we are // using the same values (salt+secret) to derive the IV this is a very real risk. // To mitigate this risk the primary interaction of secret in the derivation of this // value is compressed into a CRC of both the salt and secret. This value is then // masked with computations of salt to produce the 16 IV bytes needed. byte[] sbytes = salt.ToArray(); byte[] result = new byte[16]; // compute a mask from CRC32(salt + secret) int mask = new Crc32(_salt.GetData(secret.ToArray()).ToArray()).Value; // xor part of the mask with the sum of two salt bytes for (int i = 0; i < 16; i++) result[i] = (byte)((mask >> i) ^ (sbytes[i] + sbytes[i + 16])); return result; }
void CopyEntryDataDirect(ZipUpdate update, Stream stream, bool updateCrc, ref long destinationPosition, ref long sourcePosition) { long bytesToCopy = update.Entry.CompressedSize; // NOTE: Compressed size is updated elsewhere. Crc32 crc = new Crc32(); byte[] buffer = GetBuffer(); long targetBytes = bytesToCopy; long totalBytesRead = 0; int bytesRead; do { int readSize = buffer.Length; if ( bytesToCopy < readSize ) { readSize = (int)bytesToCopy; } stream.Position = sourcePosition; bytesRead = stream.Read(buffer, 0, readSize); if ( bytesRead > 0 ) { if ( updateCrc ) { crc.Update(buffer, 0, bytesRead); } stream.Position = destinationPosition; stream.Write(buffer, 0, bytesRead); destinationPosition += bytesRead; sourcePosition += bytesRead; bytesToCopy -= bytesRead; totalBytesRead += bytesRead; } } while ( (bytesRead > 0) && (bytesToCopy > 0) ); if ( totalBytesRead != targetBytes ) { throw new ZipException(string.Format("Failed to copy bytes expected {0} read {1}", targetBytes, totalBytesRead)); } if ( updateCrc ) { update.OutEntry.Crc = crc.Value; } }
void CopyBytes(ZipUpdate update, Stream destination, Stream source, long bytesToCopy, bool updateCrc) { if ( destination == source ) { throw new InvalidOperationException("Destination and source are the same"); } // NOTE: Compressed size is updated elsewhere. Crc32 crc = new Crc32(); byte[] buffer = GetBuffer(); long targetBytes = bytesToCopy; long totalBytesRead = 0; int bytesRead; do { int readSize = buffer.Length; if ( bytesToCopy < readSize ) { readSize = (int)bytesToCopy; } bytesRead = source.Read(buffer, 0, readSize); if ( bytesRead > 0 ) { if ( updateCrc ) { crc.Update(buffer, 0, bytesRead); } destination.Write(buffer, 0, bytesRead); bytesToCopy -= bytesRead; totalBytesRead += bytesRead; } } while ( (bytesRead > 0) && (bytesToCopy > 0) ); if ( totalBytesRead != targetBytes ) { throw new ZipException(string.Format("Failed to copy bytes expected {0} read {1}", targetBytes, totalBytesRead)); } if ( updateCrc ) { update.OutEntry.Crc = crc.Value; } }
public static int getCRC(string inputString) { Crc32 crc = new Crc32(); crc.ComputeHash(System.Text.ASCIIEncoding.ASCII.GetBytes(inputString)); return (int)crc.CrcValue; }
protected static UInt32 ComputeFingerprint(byte[] bytes, int length) { // Length correction is requred like in ComputeMessageIntegrity, but // I assume that Fingerprint is last item always. It's true in most cases. using (Crc32 crc32 = new Crc32()) { crc32.ComputeHash(bytes, 0, length); return crc32.CrcValue ^ 0x5354554e; } }
public static int CRC(byte[] bytes) { Crc32 crc32 = new Crc32(); return BitConverter.ToInt32(crc32.ComputeHash(bytes), 0); }