Esempio n. 1
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);
                }
            }
        }
Esempio n. 2
0
        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);
                }
            }
        }
Esempio n. 3
0
        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);
                }
            }
        }
Esempio n. 4
0
        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);
                }
            }
        }