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); } } }
private EncryptedFile.Header ReadOrWriteEmptyHeader(int defaultBlockSize) { lock (locker) { stream.Position = 0; if (stream.Length >= EncryptedFile.Header.HeaderSize) { // Read header int headerSize; var magicNumber = stream.ReadUInt64(); switch (magicNumber) { case EncryptedFile.DefaultMagicNumber: //old header struct --> without the last field headerSize = EncryptedFile.Header.HeaderSize - Marshal.SizeOf(typeof(long)); break; case EncryptedFile.WithTotalSizeMagicNumber: headerSize = EncryptedFile.Header.HeaderSize; break; default: throw new ApplicationException("Invalid magic number"); } stream.Position = 0; var headerBytes = stream.ReadEntireBlock(headerSize); var fileHeader = StructConverter.ConvertBitsToStruct <EncryptedFile.Header>(headerBytes); if (fileHeader.MagicNumber != EncryptedFile.DefaultMagicNumber && fileHeader.MagicNumber != EncryptedFile.WithTotalSizeMagicNumber) { throw new InvalidDataException("The magic number in the file doesn't match the expected magic number for encrypted files. Perhaps this file isn't encrypted?"); } return(fileHeader); } else { // Write empty header var sizeTest = settings.Codec.EncodeBlock("Dummy key", new byte[defaultBlockSize]); var fileHeader = new EncryptedFile.Header { MagicNumber = EncryptedFile.WithTotalSizeMagicNumber, DecryptedBlockSize = defaultBlockSize, IVSize = sizeTest.IV.Length, EncryptedBlockSize = sizeTest.Data.Length, TotalUnencryptedSize = EncryptedFile.Header.HeaderSize + EncryptedFile.Footer.FooterSize }; WriteHeaderInCurrentPositionIfNotReadonly(fileHeader); return(fileHeader); } } }
private EncryptedFile.Header ReadOrWriteHeader(int defaultBlockSize) { lock (locker) { stream.Position = 0; if (stream.Length >= EncryptedFile.Header.HeaderSize) { // Read header var headerBytes = stream.ReadEntireBlock(EncryptedFile.Header.HeaderSize); var header = StructConverter.ConvertBitsToStruct <EncryptedFile.Header>(headerBytes); if (header.MagicNumber != EncryptedFile.DefaultMagicNumber) { throw new InvalidDataException("The magic number in the file doesn't match the expected magic number for encypted files. Perhaps this file isn't encrypted?"); } return(header); } else { // Write header var sizeTest = settings.Codec.EncodeBlock("Dummy key", new byte[defaultBlockSize]); var header = new EncryptedFile.Header { MagicNumber = EncryptedFile.DefaultMagicNumber, DecryptedBlockSize = defaultBlockSize, IVSize = sizeTest.IV.Length, EncryptedBlockSize = sizeTest.Data.Length }; var headerBytes = StructConverter.ConvertStructToBits(header); if (!isReadonly) { stream.Write(headerBytes, 0, EncryptedFile.Header.HeaderSize); } return(header); } } }
private EncryptedFile.Header ReadOrWriteEmptyHeader(int defaultBlockSize) { lock (locker) { stream.Position = 0; if (stream.Length >= EncryptedFile.Header.HeaderSize) { // Read header var magicNumber = stream.ReadUInt64(); var headerSize = GetHeaderSizeByMagicNumber(magicNumber); stream.Position = 0; var headerBytes = stream.ReadEntireBlock(headerSize); var fileHeader = StructConverter.ConvertBitsToStruct <EncryptedFile.Header>(headerBytes, headerSize); if (fileHeader.MagicNumber != EncryptedFile.DefaultMagicNumber && fileHeader.MagicNumber != EncryptedFile.WithTotalSizeMagicNumber) { throw new InvalidDataException("The magic number in the file doesn't match the expected magic number for encrypted files. Perhaps this file isn't encrypted?"); } return(fileHeader); } else { // Write empty header var sizeTest = settings.Codec.EncodeBlock("Dummy key", new byte[defaultBlockSize]); var fileHeader = new EncryptedFile.Header { MagicNumber = EncryptedFile.WithTotalSizeMagicNumber, DecryptedBlockSize = defaultBlockSize, IVSize = sizeTest.IV.Length, EncryptedBlockSize = sizeTest.Data.Length, TotalUnencryptedSize = 0 }; WriteHeaderInCurrentPositionIfNotReadonly(fileHeader, fileHeader.MagicNumber); return(fileHeader); } } }