private async ValueTask<ProtocolToken> ReceiveBlobAsync<TIOAdapter>(TIOAdapter adapter)
where TIOAdapter : IReadWriteAdapter
{
- int readBytes = await FillHandshakeBufferAsync(adapter, SecureChannel.ReadHeaderSize).ConfigureAwait(false);
- if (readBytes == 0)
- {
- throw new IOException(SR.net_io_eof);
- }
-
+ await FillHandshakeBufferAsync(adapter, SecureChannel.ReadHeaderSize).ConfigureAwait(false);
if (_framing == Framing.Unified || _framing == Framing.Unknown)
{
_framing = DetectFraming(_handshakeBuffer.ActiveReadOnlySpan);
// This function tries to make sure buffer has at least minSize bytes available.
// If we have enough data, it returns synchronously. If not, it will try to read
- // remaining bytes from given stream.
- private ValueTask<int> FillHandshakeBufferAsync<TIOAdapter>(TIOAdapter adapter, int minSize)
+ // remaining bytes from given stream. It will throw if unable to fulfill minSize.
+ private ValueTask FillHandshakeBufferAsync<TIOAdapter>(TIOAdapter adapter, int minSize)
where TIOAdapter : IReadWriteAdapter
{
if (_handshakeBuffer.ActiveLength >= minSize)
{
- return new ValueTask<int>(minSize);
+ return ValueTask.CompletedTask;
}
int bytesNeeded = minSize - _handshakeBuffer.ActiveLength;
int bytesRead = t.Result;
if (bytesRead == 0)
{
- return new ValueTask<int>(0);
+ throw new IOException(SR.net_io_eof);
}
_handshakeBuffer.Commit(bytesRead);
}
- return new ValueTask<int>(minSize);
+ return ValueTask.CompletedTask;
- async ValueTask<int> InternalFillHandshakeBufferAsync(TIOAdapter adap, ValueTask<int> task, int minSize)
+ async ValueTask InternalFillHandshakeBufferAsync(TIOAdapter adap, ValueTask<int> task, int minSize)
{
while (true)
{
_handshakeBuffer.Commit(bytesRead);
if (_handshakeBuffer.ActiveLength >= minSize)
{
- return minSize;
+ return;
}
task = adap.ReadAsync(_handshakeBuffer.AvailableMemory);
}
}
- private async ValueTask FillBufferAsync<TIOAdapter>(TIOAdapter adapter, int numBytesRequired)
- where TIOAdapter : IReadWriteAdapter
- {
- Debug.Assert(_internalBufferCount > 0);
- Debug.Assert(_internalBufferCount < numBytesRequired);
-
- while (_internalBufferCount < numBytesRequired)
- {
- int bytesRead = await adapter.ReadAsync(_internalBuffer.AsMemory(_internalBufferCount)).ConfigureAwait(false);
- if (bytesRead == 0)
- {
- throw new IOException(SR.net_io_eof);
- }
-
- _internalBufferCount += bytesRead;
- }
- }
-
private async ValueTask WriteAsyncInternal<TIOAdapter>(TIOAdapter writeAdapter, ReadOnlyMemory<byte> buffer)
where TIOAdapter : struct, IReadWriteAdapter
{
}
}
+ [Theory]
+ [InlineData(true)]
+ [InlineData(false)]
+ public async Task ServerAsyncAuthenticate_InvalidHello_Throws(bool close)
+ {
+ (NetworkStream client, NetworkStream server) = TestHelper.GetConnectedTcpStreams();
+ using (client)
+ using (SslStream ssl = new SslStream(server))
+ {
+ byte[] buffer = new byte[182];
+ buffer[0] = 178;
+ buffer[1] = 0;
+ buffer[2] = 0;
+ buffer[3] = 1;
+ buffer[4] = 133;
+ buffer[5] = 166;
+
+ Task t1 = ssl.AuthenticateAsServerAsync(_serverCertificate, false, false);
+ Task t2 = client.WriteAsync(buffer).AsTask();
+ if (close)
+ {
+ await t2.WaitAsync(TestConfiguration.PassingTestTimeout);
+ client.Socket.Shutdown(SocketShutdown.Send);
+ }
+ else
+ {
+ // Write enough data to full frame size
+ buffer = new byte[13000];
+ t2 = client.WriteAsync(buffer).AsTask();
+ await t2.WaitAsync(TestConfiguration.PassingTestTimeout);
+ }
+
+ if (close)
+ {
+ await Assert.ThrowsAsync<IOException>(() => t1);
+ }
+ else
+ {
+ await Assert.ThrowsAsync<AuthenticationException>(() => t1);
+ }
+ }
+ }
+
public static IEnumerable<object[]> ProtocolMismatchData()
{
if (PlatformDetection.SupportsSsl3)