コード例 #1
0
        public static async Task <AsyncBinaryWriter> WriteHeaderAsync(Stream stream, byte[] messageHeader, Ack ack)
        {
            /*
             * UInt16 Message Header Length
             * byte[] Message Header
             * UInt32 Version
             * UInt64 Ack
             * UInt32 Empty
             * UInt32 Content Length
             * byte[] Content
             */

            uint version = 0;

            var asyncBinaryWriter   = new AsyncBinaryWriter(stream);
            var messageHeaderLength = (ushort)messageHeader.Length;
            await asyncBinaryWriter.WriteAsync(messageHeaderLength);

            await stream.WriteAsync(messageHeader);

            await asyncBinaryWriter.WriteAsync(version);

            await asyncBinaryWriter.WriteAsync(ack.Value);

            // Empty
            await asyncBinaryWriter.WriteAsync(uint.MinValue);

            return(asyncBinaryWriter);
        }
コード例 #2
0
        async Task <TResponse> AsyncCallAsync <TRequest, TResponse>(
            Method <TRequest, TResponse> method, TRequest request)
        {
            await pipeLock.WaitAsync();

            PipePair pipePair;

            availablePipePairs.TryTake(out pipePair);
            Debug.Assert(pipePair != null);
            try
            {
                var writer = new AsyncBinaryWriter(pipePair.OutPipe);
                var reader = new AsyncBinaryReader(pipePair.InPipe);

                // Send the RPC name.
                await writer.WriteAsync(method.FullName.Length);

                await writer.WriteAsync(Encoding.ASCII.GetBytes(method.FullName));

                // Send the request.
                using (var serializationContext = new SimpleSerializationContext())
                {
                    method.RequestMarshaller.ContextualSerializer(request, serializationContext);
                    byte[] requestBytes = serializationContext.GetPayload();
                    await writer.WriteAsync(requestBytes.Length);

                    await writer.WriteAsync(requestBytes);
                }

                // Read the response.
                int size = await reader.ReadInt32Async();

                byte[] responseBytes = await reader.ReadBytesAsync(size);

                var deserializationContext = new SimpleDeserializationContext(responseBytes);
                return(method.ResponseMarshaller.ContextualDeserializer(deserializationContext));
            }
            // Unfortunately, RpcExceptions can't be nested with InnerException.
            catch (EndOfStreamException e)
            {
                throw new RpcException(new Status(StatusCode.Unknown, e.ToString()),
                                       "Connection to server lost. Did it shut down?");
            }
            catch (Exception e) when(!(e is RpcException))
            {
                throw new RpcException(new Status(StatusCode.Unknown, e.ToString()),
                                       "Unknown failure: " + e);
            }
            finally
            {
                availablePipePairs.Add(pipePair);
                pipeLock.Release();
            }
        }
コード例 #3
0
        /// <summary>
        /// This takes an input file and encrypts it into the output file
        /// </summary>
        /// <param name="outStream"></param>
        /// <param name="password">the password for use as the key</param>
        /// <param name="fileStream"></param>
        public static async Task EncryptFileAsync(Stream fileStream, Stream outStream, string password)
        {
            long lSize = fileStream.Length;       // the size of the input file for storing

            byte[] bytes = new byte[BUFFER_SIZE]; // the buffer
            int    read  = -1;                    // the amount of bytes read from the input file
            int    value = 0;                     // the amount overall read from the input file for progress

            // generate IV and Salt
            byte[] IV   = GenerateRandomBytes(16);
            byte[] salt = GenerateRandomBytes(16);

            // create the crypting object
            SymmetricAlgorithm sma = CryptoHelper.CreateRijndael(password, salt);

            sma.IV = IV;

            // write the IV and salt to the beginning of the file
            await outStream.WriteAsync(IV, 0, IV.Length);

            await outStream.WriteAsync(salt, 0, salt.Length);

            // create the hashing and crypto streams
            HashAlgorithm hasher = SHA256.Create();

            await using var cout = new CryptoStream(outStream, sma.CreateEncryptor(), CryptoStreamMode.Write);
            await using (var chash = new CryptoStream(Stream.Null, hasher, CryptoStreamMode.Write))
            {
                // write the size of the file to the output file
                var bw = new AsyncBinaryWriter(cout);
                await bw.WriteAsync(lSize);

                // write the file cryptor tag to the file
                await bw.WriteAsync(FC_TAG);

                // read and the write the bytes to the crypto stream in BUFFER_SIZEd chunks
                while ((read = await fileStream.ReadAsync(bytes, 0, bytes.Length)) != 0)
                {
                    await cout.WriteAsync(bytes, 0, read);

                    await chash.WriteAsync(bytes, 0, read);

                    value += read;
                }

                // flush and close the hashing object
            }

            // read the hash
            byte[] hash = hasher.Hash;

            // write the hash to the end of the file
            await cout.WriteAsync(hash, 0, hash.Length);
        }
コード例 #4
0
 public async Task When_writing_an_Int32()
 {
     var ms = new MemoryStream();
     var sut = new AsyncBinaryWriter(ms);
     await sut.WriteAsync(100, CancellationToken.None);
     Assert.Equal(new byte[] { 100, 0, 0, 0 }, ms.ToArray());
 }
コード例 #5
0
ファイル: PlcClientSending.cs プロジェクト: hcoona/OneDotNet
        private static async Task WriteFrame(
            AsyncBinaryWriter writer,
            byte type,
            byte seqNum,
            int streamId,
            byte[] contents)
        {
            uint contentChecksum = 0;

            // TODO(zhangshuai.ustc): Support other platform
            if (Environment.OSVersion.Platform == PlatformID.Win32NT ||
                Environment.OSVersion.Platform == PlatformID.Win32Windows)
            {
                contentChecksum = Crc32C.Crc32CAlgorithm.Compute(contents);
            }

            var frameHeader = new FrameHeader(
                version: 1,
                type: type,
                sequenceNumber: seqNum,
                streamId: (uint)streamId,
                contentOffset: 20,
                contentLength: (ushort)contents.Length,
                contentChecksum: contentChecksum);
            await frameHeader.WriteTo(writer).ConfigureAwait(false);

            await writer.WriteAsync(contents).ConfigureAwait(false);
        }
コード例 #6
0
ファイル: PlcClientSending.cs プロジェクト: hcoona/OneDotNet
        private async Task WriteUnifiedFrameContent(
            AsyncBinaryWriter writer,
            int streamId,
            UnifiedFrameContent unifiedFrameContent)
        {
            if (this.logger.IsEnabled(LogLevel.Debug))
            {
                using var memoryStream = new MemoryStream();
                using var memoryWriter = new AsyncBinaryWriter(memoryStream, Encoding.ASCII, false);

                await WriteFrame(memoryWriter, 2, 0, streamId, unifiedFrameContent.ToByteArray())
                .ConfigureAwait(false);

                byte[] sendingBytes = memoryStream.ToArray();

                this.logger.LogDebug(
                    "Sending to {0} with streamId={1}:" + Environment.NewLine + "{2}",
                    unifiedFrameContent.Header.Path,
                    streamId,
                    HexUtils.Dump(new ReadOnlyMemory <byte>(sendingBytes)));
                await writer.WriteAsync(sendingBytes).ConfigureAwait(false);
            }
            else
            {
                await WriteFrame(writer, 2, 0, streamId, unifiedFrameContent.ToByteArray())
                .ConfigureAwait(false);
            }
        }
コード例 #7
0
        public async Task The_WriteAsync_Method_Throws_When_Data_Is_Null()
        {
            var writer = new AsyncBinaryWriter(new MemoryStream());

            await Assert.ThrowsAsync <ArgumentNullException>(async() =>
            {
                await writer.WriteAsync(null);
            });
        }
コード例 #8
0
        public async Task The_WriteAsync_Method_Works()
        {
            var stream   = new MemoryStream();
            var writer   = new AsyncBinaryWriter(stream);
            var expected = Encoding.UTF8.GetBytes("123456");

            await writer.WriteAsync(expected);

            var actual = stream.ToArray();

            Assert.Equal(expected, actual);
        }
コード例 #9
0
        public static async Task <AsyncBinaryWriter> WriteHeaderAsync(Stream stream, byte[] messageHeader, Ack ack,
                                                                      IpcMessageCommandType ipcMessageCommandType)
        {
            /*
             * UInt16 Message Header Length 消息头的长度
             * byte[] Message Header        消息头的内容
             * UInt32 Version        当前IPC服务的版本
             * UInt64 Ack            用于给对方确认收到消息使用
             * UInt32 Empty          给以后版本使用的值
             * UInt16 Command Type   命令类型,业务端的值将会是 0 而框架层采用其他值
             * UInt32 Content Length 这条消息的内容长度
             * byte[] Content        实际的内容
             */

            // 当前版本默认是 1 版本,这个值用来后续如果有协议上的更改时,兼容旧版本使用
            // - 版本是 0 的版本,每条消息都有回复 ack 的值
            const uint version = 1;

            var asyncBinaryWriter   = new AsyncBinaryWriter(stream);
            var messageHeaderLength = (ushort)messageHeader.Length;
            await asyncBinaryWriter.WriteAsync(messageHeaderLength);

            await stream.WriteAsync(messageHeader);

            // UInt32 Version
            await asyncBinaryWriter.WriteAsync(version);

            // UInt64 Ack
            await asyncBinaryWriter.WriteAsync(ack.Value);

            // UInt32 Empty
            await asyncBinaryWriter.WriteAsync(uint.MinValue);

            // UInt16 Command Type   命令类型,业务端的值将会是 0 而框架层采用其他值
            ushort commandType = (ushort)ipcMessageCommandType;
            await asyncBinaryWriter.WriteAsync(commandType);

            return(asyncBinaryWriter);
        }
コード例 #10
0
        private static async Task <TcpClient> StartPlcAsync(ILogger logger, string hostname, int port)
        {
            var fakePlc = new TcpClient(hostname, port);

            logger.LogInformation("Fake PLC connected.");

            NetworkStream networkStream = fakePlc.GetStream();

            using var reader = new AsyncBinaryReader(networkStream, Encoding.ASCII, true);
            using var writer = new AsyncBinaryWriter(networkStream, Encoding.ASCII, true);

            logger.LogDebug("Receiving TestRequest frame...");
            byte[] receivedBytes = await reader.ReadBytesAsync(0x53).ConfigureAwait(false);

            logger.LogInformation("Received {0} bytes.", 0x53);

            byte[] sendingPayload = new UnifiedFrameContent
            {
                Header = new Header {
                    Status = 0
                },
                Payload = new TestResponse
                {
                    A = 42,
                    B = 3.1415926F,
                    C = "Hello World!",
                    D = Timestamp.FromDateTimeOffset(DateTimeOffset.Parse("2019-10-29T21:42:13.00000+8:00", CultureInfo.InvariantCulture)),
                }.ToByteString(),
            }.ToByteArray();
            var sendingHeader = new FrameHeader(
                version: 1,
                type: 2,
                sequenceNumber: 0,
                streamId: 1,
                contentOffset: 20,
                contentLength: (ushort)sendingPayload.Length,
                contentChecksum: Crc32C.Crc32CAlgorithm.Compute(sendingPayload));

            logger.LogDebug("Sending TestResponse frame header...");
            await sendingHeader.WriteTo(writer).ConfigureAwait(false);

            logger.LogDebug("Sending TestResponse frame body...");
            await writer.WriteAsync(sendingPayload).ConfigureAwait(false);

            logger.LogInformation("Sent TestResponse.");

            return(fakePlc);
        }
コード例 #11
0
ファイル: MiscTests.cs プロジェクト: encodeous/wstream
        public async Task ValidateReadWriteStatistics()
        {
            InterceptData clientData = null, serverData = null;
            var           server = new WsServer();
            await server.StartAsync(new IPEndPoint(IPAddress.Loopback, 0), async stream =>
            {
                await stream.WrapSocketAsync(x =>
                                             Task.FromResult <WStreamSocket>(new Interceptor(x, out serverData))
                                             );
                var abr = new AsyncBinaryReader(stream);
                for (int i = 0; i < 100000; i++)
                {
                    Assert.Equal(i, await abr.ReadInt32Async());
                }
                await stream.CloseAsync();
            });

            var client     = new WsClient();
            var connection = await client.ConnectAsync(new Uri("ws://" + server.ListeningAddresses[0].Substring(7)));

            await connection.WrapSocketAsync(x =>
                                             Task.FromResult <WStreamSocket>(new Interceptor(x, out clientData))
                                             );

            var abw = new AsyncBinaryWriter(connection);

            for (int i = 0; i < 100000; i++)
            {
                await abw.WriteAsync(i);
            }

            await abw.FlushAsync();

            await Task.Delay(1000);

            Assert.Equal(4 * 100000, clientData.BytesWritten);
            Assert.Equal(4 * 100000, serverData.BytesRead);

            client.Dispose();
            server.Dispose();
        }
コード例 #12
0
        public async Task TestAsyncBinaryWriter()
        {
            byte customByte = 39;
            bool customBool = Unsafe.As <byte, bool>(ref customByte);

            object[] expectedResults =
            {
                true,
                false,
                customBool,
                (byte)42,
                (sbyte)-28,
                (short)-279,
                (ushort)64221,
                (int)-288888,
                (uint)3310229011,
                (float)3811.55f,
                (long)-19195205991011,
                (ulong)11223372036854775807,
                (double)Math.PI,
                (decimal)295222.2811m
            };

            using (var ms = new MemoryStream())
            {
                using (var wr = new AsyncBinaryWriter(ms, Encoding.Default, leaveOpen: true))
                {
                    foreach (dynamic obj in expectedResults)
                    {
                        await wr.WriteAsync(obj).ConfigureAwait(false);
                    }
                }

                ms.Position = 0;

                using (var rd = new BinaryReader(ms, Encoding.Default, leaveOpen: true))
                {
                    foreach (var obj in expectedResults)
                    {
                        switch (obj)
                        {
                        case bool b8:
                            ////Assert.Equal(b8, rd.ReadBoolean());
                            if (b8)
                            {
                                Assert.True(rd.ReadBoolean());
                            }
                            else
                            {
                                Assert.False(rd.ReadBoolean());
                            }

                            break;

                        case byte u8:
                            Assert.Equal(u8, rd.ReadByte());
                            break;

                        case sbyte s8:
                            Assert.Equal(s8, rd.ReadSByte());
                            break;

                        case short s16:
                            Assert.Equal(s16, rd.ReadInt16());
                            break;

                        case ushort u16:
                            Assert.Equal(u16, rd.ReadUInt16());
                            break;

                        case int s32:
                            Assert.Equal(s32, rd.ReadInt32());
                            break;

                        case uint u32:
                            Assert.Equal(u32, rd.ReadUInt32());
                            break;

                        case long s64:
                            Assert.Equal(s64, rd.ReadInt64());
                            break;

                        case ulong u64:
                            Assert.Equal(u64, rd.ReadUInt64());
                            break;

                        case float f32:
                            Assert.Equal(f32, rd.ReadSingle());
                            break;

                        case double f64:
                            Assert.Equal(f64, rd.ReadDouble());
                            break;

                        case decimal d128:
                            Assert.Equal(d128, rd.ReadDecimal());
                            break;
                        }
                    }
                }
            }
        }
コード例 #13
0
        private static async Task CompressFileAsL33TZipAsync(
            Stream inputStream,
            Stream outputStream,
            IProgress <double> progress = null,
            CancellationToken ct        = default)
        {
            //
            var fileLength = inputStream.Length;

            //Write L33T Header
            using (var writer = new AsyncBinaryWriter(inputStream))
            {
                //Write L33T Header & File Length
                if (fileLength > int.MaxValue)
                {
                    await writer.WriteAsync(L66THeader.ToCharArray(), ct);

                    await writer.WriteAsync(fileLength, ct);
                }
                else
                {
                    await writer.WriteAsync(L33THeader.ToCharArray(), ct);

                    await writer.WriteAsync(Convert.ToInt32(fileLength), ct);
                }

                //Write Deflate specification (2 Byte)
                await writer.WriteAsync(new byte[] { 0x78, 0x9C }, ct);
            }

            //Write Content
            var buffer         = new byte[BufferSize];
            var totalBytesRead = 0L;
            var lastProgress   = 0d;
            int bytesRead;

            using var compressedStream = new DeflateStream(outputStream, CompressionLevel.Optimal);
            while ((bytesRead = await inputStream.ReadAsync(buffer, 0, buffer.Length, ct)) > 0)
            {
                ct.ThrowIfCancellationRequested();

                if (bytesRead > fileLength)
                {
                    totalBytesRead += fileLength;
                    await compressedStream.WriteAsync(buffer, 0, Convert.ToInt32(fileLength), ct);
                }
                else if (totalBytesRead + bytesRead <= fileLength)
                {
                    totalBytesRead += bytesRead;
                    await compressedStream.WriteAsync(buffer, 0, bytesRead, ct);
                }
                else if (totalBytesRead + bytesRead > fileLength)
                {
                    var leftToRead = fileLength - totalBytesRead;
                    totalBytesRead += leftToRead;
                    await compressedStream.WriteAsync(buffer, 0, Convert.ToInt32(leftToRead), ct);
                }

                var newProgress = (double)totalBytesRead / fileLength * 100;

                if (newProgress - lastProgress > 1)
                {
                    progress?.Report(newProgress);
                    lastProgress = newProgress;
                }

                if (totalBytesRead >= fileLength)
                {
                    break;
                }
            }
        }
コード例 #14
0
ファイル: Pdb70BitSet.cs プロジェクト: tmr232/symblr
 /// <summary>
 /// Asynchronously writes the bit set to the specified writer.
 /// </summary>
 /// <param name="writer">The writer.</param>
 /// <param name="cancellationToken">The cancellation token.</param>
 /// <returns>
 /// A <see cref="Task"/> that represents the asynchronous write operation.
 /// </returns>
 public async Task WriteAsync(AsyncBinaryWriter writer, CancellationToken cancellationToken)
 {
     await writer.WriteAsync(Words.Length, cancellationToken);
     var bytes = new byte[Words.Length * sizeof(int)];
     Buffer.BlockCopy(Words, 0, bytes, 0, bytes.Length);
     await writer.BaseStream.WriteAsync(bytes, 0, bytes.Length, cancellationToken);
 }
コード例 #15
0
ファイル: FrameHeader.cs プロジェクト: hcoona/OneDotNet
        public async Task WriteTo(AsyncBinaryWriter binaryWriter)
        {
            // Write magic signature.
            await binaryWriter.WriteAsync((byte)'D').ConfigureAwait(false);

            await binaryWriter.WriteAsync((byte)'R').ConfigureAwait(false);

            await binaryWriter.WriteAsync((byte)'Y').ConfigureAwait(false);

            await binaryWriter.WriteAsync((byte)0).ConfigureAwait(false);

            // Write version, type, sequence number.
            await binaryWriter.WriteAsync((byte)this.Version).ConfigureAwait(false);

            await binaryWriter.WriteAsync((byte)this.Type).ConfigureAwait(false);

            await binaryWriter.WriteAsync((byte)this.SequenceNumber).ConfigureAwait(false);

            await binaryWriter.WriteAsync((byte)0).ConfigureAwait(false);

            // Write stream id.
            await binaryWriter
            .WriteAsync(BinaryPrimitives.ReverseEndianness((uint)this.StreamId))
            .ConfigureAwait(false);

            // Write content offset & size.
            await binaryWriter
            .WriteAsync(BinaryPrimitives.ReverseEndianness((ushort)this.ContentOffset))
            .ConfigureAwait(false);

            await binaryWriter
            .WriteAsync(BinaryPrimitives.ReverseEndianness((ushort)this.ContentLength))
            .ConfigureAwait(false);

            // Write content checksum.
            await binaryWriter
            .WriteAsync(BinaryPrimitives.ReverseEndianness((uint)this.ContentChecksum))
            .ConfigureAwait(false);
        }
コード例 #16
0
ファイル: CryptoExtensions.cs プロジェクト: encodeous/wstream
        /// <summary>
        /// Securely exchanges a secret key
        /// </summary>
        /// <param name="stream"></param>
        /// <param name="ecParams">ECDSA public / private keypair used for signing</param>
        /// <returns>A tuple containing a 256 bit hashed secret key, and the fingerprint of the remote</returns>
        /// <exception cref="CryptographicException"></exception>
        /// <exception cref="InvalidDataException">Thrown when the remote sends invalid data</exception>
        public static async Task <(byte[], ECPoint)> ExchangeKeyAsync(this WsStream stream, ECParameters ecParams)
        {
            if (ecParams.D is null)
            {
                throw new CryptographicException("Private key must be provided");
            }
            ECDsa ecDsa = ECDsa.Create(ecParams);
            // TODO: Harden security (prevent abuse, double check everything)
            // host authentication
            var pubBytes = ecDsa.ExportSubjectPublicKeyInfo();

            // key exchange
            var ecdh       = ECDiffieHellman.Create();
            var kePubBytes = ecdh.ExportSubjectPublicKeyInfo();

            // sign ecdh key to authenticate
            var signed = ecDsa.SignData(kePubBytes, HashAlgorithmName.SHA256);

            var bw = new AsyncBinaryWriter(stream);
            var br = new AsyncBinaryReader(stream);
            //1
            await bw.WriteAsync(pubBytes.Length);

            await bw.WriteAsync(pubBytes);

            //2
            await bw.WriteAsync(signed.Length);

            await bw.WriteAsync(signed);

            //3
            await bw.WriteAsync(kePubBytes.Length);

            await bw.WriteAsync(kePubBytes);

            // read remote public key and verify signature
            //1
            var remotePubKey   = ECDsa.Create();
            var remotePubBytes = await br.ReadBytesAsync(await br.ReadAssertAsync(120));

            remotePubKey.ImportSubjectPublicKeyInfo(remotePubBytes, out _);
            //2
            var remoteSignature = await br.ReadBytesAsync(await br.ReadAssertAsync(96));

            //3
            var remoteKePub = await br.ReadBytesAsync(await br.ReadAssertAsync(158));

            var remoteEcdh = ECDiffieHellman.Create();

            remoteEcdh.ImportSubjectPublicKeyInfo(remoteKePub, out _);

            // verify signed public key exchange key
            if (!remotePubKey.VerifyData(remoteKePub, remoteSignature, HashAlgorithmName.SHA256))
            {
                throw new CryptographicException("Remote public key does not match hash!");
            }
            // derive shared secret
            var sharedSecret = ecdh.DeriveKeyMaterial(remoteEcdh.PublicKey);

            // return the public key (fingerprint) of the remote, and the hashed shared secret
            return(SHA256.HashData(sharedSecret), remotePubKey.ExportParameters(false).Q);
        }