Exemplo n.º 1
0
        private static async Task CheckPrefix(BinaryDataStream dataStream)
        {
            byte[] buffer = new byte[HeaderPrefix.Length];
            int    readed = await dataStream.ReadAsync(buffer, 0, buffer.Length);

            if (readed != buffer.Length || !string.Equals(HeaderPrefix, Encoding.ASCII.GetString(buffer), StringComparison.Ordinal))
            {
                throw new InvalidOperationException("Can not find encryption file header.");
            }
        }
        public async Task <string> ReadFileName()
        {
            if (this.fileName != null)
            {
                return(this.fileName);
            }

            ContainerHeader header = await ContainerHeader.ReadFromStream(this.readerStream);

            byte[]? aesKey = null;
            try
            {
                aesKey = await this.cryptoAccessor.AsymetricDecrypt(header.CertificateThumbprint, header.EncryptedKey, RSAEncryptionPadding.Pkcs1);  //RSA Padding

                this.aesDecryptor = this.aes.CreateDecryptor(aesKey, header.InitializeVector);
                this.cryptoStream = new CryptoStream(this.readerStream, this.aesDecryptor, CryptoStreamMode.Read);

                using (BinaryDataStream bds = new BinaryDataStream(this.cryptoStream, false))
                {
                    //TODO: Optimalization
                    for (uint i = 0; i < 16; i++)
                    {
                        bds.ReadByte();
                    }

                    uint randomDataSize = await bds.Read4BitNumber();

                    uint stringLen = await bds.Read4BitNumber();

                    //TODO: Optimalization
                    for (uint i = 0; i < randomDataSize; i++)
                    {
                        bds.ReadByte();
                    }

                    string fileName = await bds.ReadConstatntString((int)stringLen, Encoding.UTF8);

                    FileNameHelper.CheckFileName(fileName, nameof(fileName));
                    this.fileName = fileName;

                    return(fileName);
                }
            }
            finally
            {
                if (aesKey != null)
                {
                    for (int i = 0; i < aesKey.Length; i++)
                    {
                        aesKey[i] = 0x00;
                        aesKey[i] = 0xFF;
                    }
                }
            }
        }
Exemplo n.º 3
0
        private static void SetBinaryDataStream(int threadId, MemoryStream binaryData = null)
        {
            lock (BinaryDataStreams)
            {
                if (BinaryDataStreams.ContainsKey(threadId))
                {
                    throw new FormatException($"Binary data steam for thread '{threadId}' already exists");
                }

                BinaryDataStreams[threadId] = new BinaryDataStream(binaryData);
            }
        }
        private async Task WriteRandomBytes(BinaryDataStream bds, long count)
        {
            byte[] buffer = new byte[2048];
            while (count > 0)
            {
                this.randomSource.NextBytes(buffer);
                int writeBytes = (count > buffer.Length) ? buffer.Length : (int)count;
                await bds.WriteAsync(buffer, 0, writeBytes).ConfigureAwait(false);

                count -= writeBytes;
            }
        }
        public async Task WriteRead8ByteNumber(ulong value)
        {
            using MemoryStream ms         = new MemoryStream();
            using BinaryDataStream stream = new BinaryDataStream(ms);
            await stream.Write8BitNumber(value);

            await stream.FlushAsync();

            stream.Position = 0;

            ulong readedValue = await stream.Read8BitNumber();

            Assert.AreEqual(value, readedValue);
        }
        public async Task WriteConstantString()
        {
            const string text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras a dignissim nunc. Sed nec dapibus ex. Sed a ex non diam ornare scelerisque nec ut lectus. Duis faucibus, lacus nec venenatis placerat, eros nulla consequat ligula, quis interdum eros lacus sit amet purus. Phasellus ac ex id tortor vulputate dignissim. Cras rutrum leo libero, in mattis nulla finibus id. Nunc sed turpis nulla. Sed eget augue vitae enim imperdiet fermentum sed id massa. Fusce vulputate, lacus in interdum venenatis, sapien eros interdum orci, id malesuada ex ligula id nunc. Aenean in dapibus arcu. Vestibulum mollis feugiat justo, bibendum malesuada velit aliquet a. Mauris id venenatis tellus, et condimentum elit.";

            using MemoryStream ms         = new MemoryStream();
            using BinaryDataStream stream = new BinaryDataStream(ms);

            await stream.WriteConstantString(text, Encoding.UTF8);

            stream.Position = 0;

            string response = await stream.ReadConstatntString(Encoding.UTF8.GetByteCount(text), Encoding.UTF8);

            Assert.AreEqual(text, response);
        }
Exemplo n.º 7
0
        public static async Task <ContainerHeader> ReadFromStream(Stream stream)
        {
            using (BinaryDataStream dataStream = new BinaryDataStream(stream, false))
            {
                await CheckPrefix(dataStream);

                ContainerHeader header = new ContainerHeader();
                header.Version = await dataStream.Read2BitNumber();

                if (header.Version != DefaultVersion)
                {
                    throw new InvalidOperationException($"Encryption file version {header.Version} is not supported.");
                }

                header.Reserved = await dataStream.Read4BitNumber();

                header.KeyType = (ContainerKeyType)await dataStream.Read4BitNumber();

                int encryptedKeySize = header.KeyType switch
                {
                    ContainerKeyType.Rsa2048 => 256,
                    ContainerKeyType.Rsa3072 => 384,
                    ContainerKeyType.Rsa4096 => 512,
                    _ => throw new NotSupportedException($"Not support key type {header.KeyType}")
                };

                header.EncryptedDataSize = await dataStream.Read8BitNumber();

                header.CertificateThumbprint = await dataStream.ReadConstatntString(40, Encoding.ASCII);

                header.EncryptedKey     = new byte[encryptedKeySize];
                header.InitializeVector = new byte[16];

                await dataStream.ReadAsync(header.EncryptedKey, 0, header.EncryptedKey.Length);

                await dataStream.ReadAsync(header.InitializeVector, 0, header.InitializeVector.Length);

                return(header);
            }
        }
        private async Task EnshureInitialize()
        {
            if (!this.headerWrited)
            {
                await this.header.WriteToStream(this.writeStream);

                this.headerWrited = true;
                this.cryptoStream = new CryptoStream(this.writeStream, this.encryptor, CryptoStreamMode.Write);

                using (BinaryDataStream bds = new BinaryDataStream(this.cryptoStream, false))
                {
                    await this.WriteRandomBytes(bds, 16).ConfigureAwait(false);

                    await bds.Write4BitNumber(this.AdditionalPadingSize).ConfigureAwait(false);

                    await bds.Write4BitNumber((uint)Encoding.UTF8.GetByteCount(this.fileName)).ConfigureAwait(false);

                    await this.WriteRandomBytes(bds, this.AdditionalPadingSize).ConfigureAwait(false);

                    await bds.WriteConstantString(this.fileName, Encoding.UTF8).ConfigureAwait(false);
                }
            }
        }
Exemplo n.º 9
0
        public async Task WriteToStream(Stream stream)
        {
            using (BinaryDataStream dataStream = new BinaryDataStream(stream, false))
            {
                await dataStream.WriteConstantString(HeaderPrefix, Encoding.ASCII);

                await dataStream.Write2BitNumber(this.Version);

                await dataStream.Write4BitNumber(0);

                await dataStream.Write4BitNumber((uint)this.KeyType);

                await dataStream.Write8BitNumber(this.EncryptedDataSize);

                await dataStream.WriteConstantString(this.CertificateThumbprint, Encoding.ASCII);

                await dataStream.WriteAsync(this.EncryptedKey, 0, this.EncryptedKey.Length);

                await dataStream.WriteAsync(this.InitializeVector, 0, this.InitializeVector.Length);

                await dataStream.FlushAsync();
            }
        }