示例#1
0
        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();
        }
示例#2
0
        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;
        }
示例#3
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);
                }
            }
        }
示例#4
0
        private void WriteHeaderInCurrentPositionIfNotReadonly(EncryptedFile.Header fileHeader)
        {
            if (isReadonly)
            {
                return;
            }

            var headerBytes = StructConverter.ConvertStructToBits(fileHeader);

            stream.Write(headerBytes, 0, EncryptedFile.Header.HeaderSize);
        }
示例#5
0
        private void WriteHeaderInCurrentPositionIfNotReadonly(EncryptedFile.Header fileHeader, ulong magicNumber)
        {
            if (isReadonly)
            {
                return;
            }

            var headerSize  = GetHeaderSizeByMagicNumber(magicNumber);
            var headerBytes = StructConverter.ConvertStructToBits(fileHeader, headerSize);

            stream.Write(headerBytes, 0, headerSize);
        }
示例#6
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);
                }
            }
        }
示例#7
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);
                }
            }
        }
示例#8
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;
                }
            }
        }
示例#9
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 encrypted 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;
				}
			}
		}
示例#10
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;
				}
			}
		}