public async Task Test(object value, Func <AsyncBinaryWriter, object, Task> awriteFunc, Action <BinaryWriter, object> swriteFunc, Func <BinaryReader, object> readFunc, Encoding encoding = null) { encoding = encoding ?? Encoding.UTF8; var sstream = new MemoryStream(); var swriter = new BinaryWriter(sstream, encoding); swriteFunc(swriter, value); swriter.Flush(); sstream.Position = 0; var astream = new MemoryStream(); var awriter = new AsyncBinaryWriter(astream, encoding); await awriteFunc(awriter, value); await awriter.FlushAsync(); astream.Position = 0; // The following 2 assertions seem redundant. That's okay, though. // did AsyncBinaryWriter and BinaryWriter produce same bytes? Assert.Equal(sstream.ToArray(), astream.ToArray()); // did AsyncBinaryWriter produce bytes that can be read by BinaryReader? var reader = new BinaryReader(astream, encoding); var result = readFunc(reader); Assert.Equal(value, result); }
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); } }
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()); }
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); }
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); }
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); }); }
public async Task TestWriterCancellation(Func <AsyncBinaryWriter, CancellationToken, Task> f) { using (var cts = new CancellationTokenSource()) { var ct = cts.Token; var writer = new AsyncBinaryWriter(new SlowStream()); cts.Cancel(); await Assert.ThrowsAsync <TaskCanceledException>(() => f(writer, ct)); } }
/// <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); }
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(); } }
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); }
public async Task The_WriteValueAsync_Method_Paddes_With_Zeroes() { var expected = Encoding.UTF8.GetBytes("123456"); Array.Resize(ref expected, 12); var stream = new MemoryStream(); var writer = new AsyncBinaryWriter(stream); var value = new StringPalmValue(expected.Length, Encoding.UTF8, true); await value.WriteValueAsync(writer, "123456"); var actual = stream.ToArray(); Assert.Equal(expected, actual); }
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); }
public void Connect(Stream stream) { if (stream == null) { throw new ArgumentNullException(nameof(stream)); } stream.ReadTimeout = RECEIVE_TIMEOUT; // set read timeout to (15s default) stream.WriteTimeout = SEND_TIMEOUT; // set write timeout to (15s default) // Most of the RFB protocol uses Big-Endian byte order, while // .NET uses Little-Endian. These wrappers convert between the // two. See BigEndianReader and BigEndianWriter below for more details. Reader = new BigEndianBinaryReader(stream); writer = new BigEndianBinaryWriter(stream); ZrleReader = new ZRLECompressedReader(stream); }
public IntegrityTestFixture() { // create the server var server = new WsServer(); server.StartAsync(new IPEndPoint(IPAddress.Loopback, 0), async stream => { Server = stream; }).GetAwaiter().GetResult(); // start client var client = new WsClient(); Client = client.ConnectAsync(new Uri("ws://" + server.ListeningAddresses[0].Substring(7))).GetAwaiter().GetResult(); Thread.Sleep(1000); Reader = new AsyncBinaryReader(Client); Writer = new AsyncBinaryWriter(Server); }
private async void BackgroundSendingTaskEntryPoint() { try { using var binaryWriter = new AsyncBinaryWriter(this.client.GetStream(), Encoding.ASCII, true); while (await this.requestQueue .OutputAvailableAsync() .ConfigureAwait(false)) { await this.DrainSendingRequestContexts(binaryWriter).ConfigureAwait(false); } } catch (IOException e) { this.logger.LogError(e, "Error when receiving data from {0}", this.client.Client.RemoteEndPoint); this.client.Close(); this.ConnectionClosed?.Invoke(this, new EventArgs()); } }
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(); }
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); }
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); }
private async Task DrainSendingRequestContexts(AsyncBinaryWriter binaryWriter) { while (this.requestQueue.TryReceive(out RequestContext requestContext)) { if (requestContext.CancellationToken.IsCancellationRequested || DateTime.Now > requestContext.Deadline) { requestContext.TaskCompletionSource.SetResult(new UnifiedFrameContent { Header = new Header { Status = (int)StatusCode.DeadlineExceeded, StatusMessage = Status.DefaultCancelled.Detail, }, }); } var unifiedFrameContent = new UnifiedFrameContent() { Header = new Header() { Path = requestContext.Path, }, Payload = requestContext.Message.ToByteString(), }; int streamId = Interlocked.Increment(ref this.counter); await this.WriteUnifiedFrameContent(binaryWriter, streamId, unifiedFrameContent) .ConfigureAwait(false); if (!this.receivingContexts.TryAdd(streamId, requestContext)) { throw new InvalidOperationException("Impossible"); } this.logger.LogDebug("Request recorded as streamId={0}: {1}", streamId, requestContext.Message); } }
public async Task When_writing_a_structure() { var ms = new MemoryStream(); var sut = new AsyncBinaryWriter(ms); await sut.WriteStructureAsync(new Symblr.Symbols.Pdb70.Pdb70Header() { PageSize = 0, BitmapPage = 1, PageCount = 2, IndexBytes = 3, Reserved = 4, IndexPage = 5 }, CancellationToken.None); Assert.Equal(new byte[] { 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, }, ms.ToArray()); }
/// <summary> /// Writes the specified <paramref name="database"/> into the specified <paramref name="stream"/>. /// </summary> /// <param name="database">The palm database.</param> /// <param name="stream">The stream to write the database to.</param> public static async Task WriteAsync(PalmDatabase database, Stream stream) { Guard.NotNull(stream, nameof(stream)); Guard.Not(stream.CanSeek == false, nameof(stream.CanSeek)); Guard.Not(stream.CanWrite == false, nameof(stream.CanWrite)); var writer = new AsyncBinaryWriter(stream); var nameValue = new StringPalmValue(32, Encoding.UTF8, zeroTerminated: true); await nameValue.WriteValueAsync(writer, database.Name); var attributesValue = new EnumPalmValue <PalmDatabaseAttributes>(2); await attributesValue.WriteValueAsync(writer, database.Attributes); var versionValue = new UIntPalmValue(2); await versionValue.WriteValueAsync(writer, (uint)database.Version); var creationDateValue = new DateTimeOffsetPalmValue(); await creationDateValue.WriteValueAsync(writer, database.CreationDate); var modificationDateValue = new DateTimeOffsetPalmValue(); await modificationDateValue.WriteValueAsync(writer, database.ModificationDate); var lastBackupDateValue = new DateTimeOffsetPalmValue(); await lastBackupDateValue.WriteValueAsync(writer, database.LastBackupDate); var modificationNumberValue = new UIntPalmValue(4); await modificationNumberValue.WriteValueAsync(writer, database.ModificationNumber); var appInfoIdValue = new UIntPalmValue(4); var offsetOfAppInfoId = writer.Stream.Position; await appInfoIdValue.WriteValueAsync(writer, 0); var sortInfoIdValue = new UIntPalmValue(4); var offsetOfSortInfoId = writer.Stream.Position; await sortInfoIdValue.WriteValueAsync(writer, 0); var typeValue = new StringPalmValue(4, Encoding.UTF8, zeroTerminated: false); await typeValue.WriteValueAsync(writer, database.Type); var creatorValue = new StringPalmValue(4, Encoding.UTF8, zeroTerminated: false); await creatorValue.WriteValueAsync(writer, database.Creator); var uniqueIdSeedValue = new UIntPalmValue(4); await uniqueIdSeedValue.WriteValueAsync(writer, database.UniqueIdSeed); var nextRecordListIdValue = new UIntPalmValue(4); await nextRecordListIdValue.WriteValueAsync(writer, database.NextRecordListId); var numberOfRecordsValue = new UIntPalmValue(2); await numberOfRecordsValue.WriteValueAsync(writer, (uint)database.Records.Count); var recordUniqueIdsAndOffsetOfDataOffsets = new Dictionary <uint, long>(); //Write the records uint uniqueId = 0; foreach (var record in database.Records) { recordUniqueIdsAndOffsetOfDataOffsets.Add(uniqueId, stream.Position); var recordDataOffsetValue = new UIntPalmValue(4); await recordDataOffsetValue.WriteValueAsync(writer, 0); var recordAttributeValue = new ByteArrayPalmValue(1); await recordAttributeValue.WriteValueAsync(writer, new[] { record.Attributes }); var uniqueIdValue = new UIntPalmValue(3); await uniqueIdValue.WriteValueAsync(writer, uniqueId); record.UniqueId = uniqueId; uniqueId++; } var fillerValue = new ByteArrayPalmValue(2); await fillerValue.WriteValueAsync(writer, new byte[2]); //Write appInfo if (database.AppInfo.Any()) { var appInfoId = (uint)writer.Stream.Position; var dataValue = new ByteArrayPalmValue(database.AppInfo.Length); await dataValue.WriteValueAsync(writer, database.AppInfo); var previousOffset = writer.Stream.Position; writer.Stream.Seek(offsetOfAppInfoId, SeekOrigin.Begin); await appInfoIdValue.WriteValueAsync(writer, appInfoId); writer.Stream.Seek(previousOffset, SeekOrigin.Begin); } //Write sortInfo if (database.SortInfo.Any()) { var sortInfoId = (uint)writer.Stream.Position; var dataValue = new ByteArrayPalmValue(database.SortInfo.Length); await dataValue.WriteValueAsync(writer, database.SortInfo); var previousOffset = writer.Stream.Position; writer.Stream.Seek(offsetOfSortInfoId, SeekOrigin.Begin); await sortInfoIdValue.WriteValueAsync(writer, sortInfoId); writer.Stream.Seek(previousOffset, SeekOrigin.Begin); } //Write the record content foreach (var record in database.Records) { var offsetOfDataOffset = recordUniqueIdsAndOffsetOfDataOffsets[record.UniqueId]; var dataOffset = (uint)writer.Stream.Position; var dataValue = new ByteArrayPalmValue(record.Data.Length); await dataValue.WriteValueAsync(writer, record.Data); var endOffset = writer.Stream.Position; writer.Stream.Seek(offsetOfDataOffset, SeekOrigin.Begin); var recordDataOffsetValue = new UIntPalmValue(4); await recordDataOffsetValue.WriteValueAsync(writer, dataOffset); writer.Stream.Seek(endOffset, SeekOrigin.Begin); } }
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; } } } } }
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; } } }
/// <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); }
/// <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); }
public async Task When_writing_a_bit_set() { var sut = new Pdb70BitSet(); sut[0x0] = true; sut[0x28] = true; var ms = new MemoryStream(); var writer = new AsyncBinaryWriter(new TestStream(ms)); await sut.WriteAsync(writer, CancellationToken.None); Assert.Equal(new byte[] { 2, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0 }, ms.ToArray()); }
public AuthWriter(Stream input) { _writer = new AsyncBinaryWriter(input); }
/// <inheritdoc /> public JSONStreamEntryInserter([NotNull] AsyncBinaryWriter writer, [NotNull] ILogger <JSONStreamEntryInserter <TDbcEntryType> > logger) { Writer = writer ?? throw new ArgumentNullException(nameof(writer)); Logger = logger ?? throw new ArgumentNullException(nameof(logger)); }