diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/SslStream.Implementation.cs b/src/libraries/System.Net.Security/src/System/Net/Security/SslStream.Implementation.cs index 9d510fc3af19b..97ed6dcc26feb 100644 --- a/src/libraries/System.Net.Security/src/System/Net/Security/SslStream.Implementation.cs +++ b/src/libraries/System.Net.Security/src/System/Net/Security/SslStream.Implementation.cs @@ -54,10 +54,6 @@ private enum FrameType : byte AppData = 23 } - // This block is used by re-handshake code to buffer data decrypted with the old key. - private byte[] _queuedReadData; - private int _queuedReadCount; - // // This block is used to rule the >>re-handshakes<< that are concurrent with read/write I/O requests. // @@ -202,35 +198,6 @@ private SecurityStatusPal PrivateDecryptData(byte[] buffer, ref int offset, ref return _context.Decrypt(buffer, ref offset, ref count); } - // - // When re-handshaking the "old" key decrypted data are queued until the handshake is done. - // When stream calls for decryption we will feed it queued data left from "old" encryption key. - // - // Must be called under the lock in case concurrent handshake is going. - // - private int CheckOldKeyDecryptedData(Memory buffer) - { - ThrowIfExceptionalOrNotAuthenticated(); - if (_queuedReadData != null) - { - // This is inefficient yet simple and should be a REALLY rare case. - int toCopy = Math.Min(_queuedReadCount, buffer.Length); - new Span(_queuedReadData, 0, toCopy).CopyTo(buffer.Span); - _queuedReadCount -= toCopy; - if (_queuedReadCount == 0) - { - _queuedReadData = null; - } - else - { - Buffer.BlockCopy(_queuedReadData, toCopy, _queuedReadData, 0, _queuedReadCount); - } - - return toCopy; - } - return -1; - } - // // This method assumes that a SSPI context is already in a good shape. // For example it is either a fresh context or already authenticated context that needs renegotiation. @@ -602,23 +569,18 @@ private void FinishHandshakeRead(int newState) // X - some bytes are ready, no need for IO private int CheckEnqueueRead(Memory buffer) { - int lockState = Interlocked.CompareExchange(ref _lockReadState, LockRead, LockNone); + ThrowIfExceptionalOrNotAuthenticated(); + int lockState = Interlocked.CompareExchange(ref _lockReadState, LockRead, LockNone); if (lockState != LockHandshake) { // Proceed, no concurrent handshake is ongoing so no need for a lock. - return CheckOldKeyDecryptedData(buffer); + return -1; } LazyAsyncResult lazyResult = null; lock (SyncLock) { - int result = CheckOldKeyDecryptedData(buffer); - if (result != -1) - { - return result; - } - // Check again under lock. if (_lockReadState != LockHandshake) { @@ -631,30 +593,23 @@ private int CheckEnqueueRead(Memory buffer) } // Need to exit from lock before waiting. lazyResult.InternalWaitForCompletion(); - lock (SyncLock) - { - return CheckOldKeyDecryptedData(buffer); - } + ThrowIfExceptionalOrNotAuthenticated(); + return -1; } private ValueTask CheckEnqueueReadAsync(Memory buffer) { - int lockState = Interlocked.CompareExchange(ref _lockReadState, LockRead, LockNone); + ThrowIfExceptionalOrNotAuthenticated(); + int lockState = Interlocked.CompareExchange(ref _lockReadState, LockRead, LockNone); if (lockState != LockHandshake) { // Proceed, no concurrent handshake is ongoing so no need for a lock. - return new ValueTask(CheckOldKeyDecryptedData(buffer)); + return new ValueTask(-1); } lock (SyncLock) { - int result = CheckOldKeyDecryptedData(buffer); - if (result != -1) - { - return new ValueTask(result); - } - // Check again under lock. if (_lockReadState != LockHandshake) { @@ -671,6 +626,8 @@ private ValueTask CheckEnqueueReadAsync(Memory buffer) private Task CheckEnqueueWriteAsync() { + ThrowIfExceptionalOrNotAuthenticated(); + // Clear previous request. int lockState = Interlocked.CompareExchange(ref _lockWriteState, LockWrite, LockNone); if (lockState != LockHandshake)