public BlockReaderWriter(EncryptionSettings encryptionSettings, string key, Stream stream, int defaultBlockSize) { if (encryptionSettings == null) throw new ArgumentNullException("encryptionSettings"); if (key == null) throw new ArgumentNullException("key"); if (stream == null) throw new ArgumentNullException("stream"); if (!stream.CanRead) throw new ArgumentException("The Underlying stream for a BlockReaderWriter must always be either read-only or read-write. Write only streams are not supported."); if (!stream.CanSeek) throw new ArgumentException("The Underlying stream for a BlockReaderWriter must be seekable."); isReadonly = !stream.CanWrite; this.settings = encryptionSettings; this.key = key; this.stream = stream; this.header = ReadOrWriteEmptyHeader(defaultBlockSize); this.footer = ReadOrWriteFooter(); totalUnencryptedSize = 0; }
private EncryptedFile.Footer ReadOrWriteFooter() { lock (locker) { if (stream.Length >= EncryptedFile.Header.HeaderSize + EncryptedFile.Footer.FooterSize) { // Read footer stream.Position = stream.Length - EncryptedFile.Footer.FooterSize; var footerBytes = stream.ReadEntireBlock(EncryptedFile.Footer.FooterSize); var footer = StructConverter.ConvertBitsToStruct <EncryptedFile.Footer>(footerBytes); // Sanity check that the footer has some value that could be correct var streamBlockLength = (stream.Length - (EncryptedFile.Header.HeaderSize + EncryptedFile.Footer.FooterSize)) / header.DiskBlockSize; var footerBlockLength = footer.TotalLength / header.DecryptedBlockSize; if (footerBlockLength != streamBlockLength - 1 && footerBlockLength != streamBlockLength) { throw new InvalidDataException("File is corrupted: the length written to the file doesn't match the number of blocks in it."); } return(footer); } else { // Write footer stream.Position = EncryptedFile.Header.HeaderSize; var footer = new EncryptedFile.Footer { TotalLength = 0 }; WriteFooterInCurrentPosition(footer); return(footer); } } }
public BlockReaderWriter(EncryptionSettings encryptionSettings, string key, Stream stream, int defaultBlockSize) { if (encryptionSettings == null) { throw new ArgumentNullException("encryptionSettings"); } if (key == null) { throw new ArgumentNullException("key"); } if (stream == null) { throw new ArgumentNullException("stream"); } if (!stream.CanRead) { throw new ArgumentException("The Underlying stream for a BlockReaderWriter must always be either read-only or read-write. Write only streams are not supported."); } if (!stream.CanSeek) { throw new ArgumentException("The Underlying stream for a BlockReaderWriter must be seekable."); } isReadonly = !stream.CanWrite; this.settings = encryptionSettings; this.key = key; this.stream = stream; this.header = ReadOrWriteHeader(defaultBlockSize); this.footer = ReadOrWriteFooter(); }
private void WriteFooterInCurrentPosition(EncryptedFile.Footer footer) { var footerBytes = StructConverter.ConvertStructToBits(footer); if (!isReadonly) { stream.Write(footerBytes, 0, EncryptedFile.Footer.FooterSize); } }
private EncryptedFile.Footer ReadOrWriteFooter() { lock (locker) { if (stream.Length >= EncryptedFile.Header.HeaderSize + EncryptedFile.Footer.FooterSize) { // Read footer stream.Position = stream.Length - EncryptedFile.Footer.FooterSize; var footerBytes = stream.ReadEntireBlock(EncryptedFile.Footer.FooterSize); var footer = StructConverter.ConvertBitsToStruct<EncryptedFile.Footer>(footerBytes); // Sanity check that the footer has some value that could be correct var streamBlockLength = (stream.Length - (EncryptedFile.Header.HeaderSize + EncryptedFile.Footer.FooterSize)) / header.DiskBlockSize; var footerBlockLength = footer.TotalLength / header.DecryptedBlockSize; if (footerBlockLength != streamBlockLength - 1 && footerBlockLength != streamBlockLength) throw new InvalidDataException("File is corrupted: the length written to the file doesn't match the number of blocks in it."); return footer; } else { // Write footer stream.Position = EncryptedFile.Header.HeaderSize; var footer = new EncryptedFile.Footer { TotalLength = 0 }; WriteFooterInCurrentPosition(footer); return footer; } } }