Skip to content

Commit 4bdf468

Browse files
authored
rework locking in SslStream to support TLS1.3 (#32925)
* initial locking * feedback from review * update _handshakeWaiter * feedback from review * feedback from review * feedback from review
1 parent 7ae0add commit 4bdf468

File tree

4 files changed

+128
-239
lines changed

4 files changed

+128
-239
lines changed

src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.OpenSsl.cs

Lines changed: 15 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -333,14 +333,11 @@ internal static int Encrypt(SafeSslHandle context, ReadOnlySpan<byte> input, ref
333333
int retVal;
334334
Exception? innerError = null;
335335

336-
lock (context)
337-
{
338-
retVal = Ssl.SslWrite(context, ref MemoryMarshal.GetReference(input), input.Length);
336+
retVal = Ssl.SslWrite(context, ref MemoryMarshal.GetReference(input), input.Length);
339337

340-
if (retVal != input.Length)
341-
{
342-
errorCode = GetSslError(context, retVal, out innerError);
343-
}
338+
if (retVal != input.Length)
339+
{
340+
errorCode = GetSslError(context, retVal, out innerError);
344341
}
345342

346343
if (retVal != input.Length)
@@ -390,30 +387,27 @@ internal static int Decrypt(SafeSslHandle context, byte[] outBuffer, int offset,
390387
int retVal = BioWrite(context.InputBio!, outBuffer, offset, count);
391388
Exception? innerError = null;
392389

393-
lock (context)
390+
if (retVal == count)
394391
{
395-
if (retVal == count)
392+
unsafe
396393
{
397-
unsafe
394+
fixed (byte* fixedBuffer = outBuffer)
398395
{
399-
fixed (byte* fixedBuffer = outBuffer)
400-
{
401-
retVal = Ssl.SslRead(context, fixedBuffer + offset, outBuffer.Length);
402-
}
403-
}
404-
405-
if (retVal > 0)
406-
{
407-
count = retVal;
396+
retVal = Ssl.SslRead(context, fixedBuffer + offset, outBuffer.Length);
408397
}
409398
}
410399

411-
if (retVal != count)
400+
if (retVal > 0)
412401
{
413-
errorCode = GetSslError(context, retVal, out innerError);
402+
count = retVal;
414403
}
415404
}
416405

406+
if (retVal != count)
407+
{
408+
errorCode = GetSslError(context, retVal, out innerError);
409+
}
410+
417411
if (retVal != count)
418412
{
419413
retVal = 0;

src/libraries/Common/src/System/Net/SecurityStatusPal.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ internal enum SecurityStatusPalErrorCode
3535
ContextExpired,
3636
CredentialsNeeded,
3737
Renegotiate,
38+
TryAgain,
3839

3940
// Errors
4041
OutOfMemory,

src/libraries/System.Net.Security/src/System/Net/Security/SslStream.Implementation.Adapters.cs

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,8 @@ public partial class SslStream
1212
private interface ISslIOAdapter
1313
{
1414
ValueTask<int> ReadAsync(Memory<byte> buffer);
15-
ValueTask<int> ReadLockAsync(Memory<byte> buffer);
16-
Task WriteLockAsync();
1715
ValueTask WriteAsync(byte[] buffer, int offset, int count);
16+
Task WaitAsync(TaskCompletionSource<bool> waiter);
1817
CancellationToken CancellationToken { get; }
1918
}
2019

@@ -31,12 +30,10 @@ public AsyncSslIOAdapter(SslStream sslStream, CancellationToken cancellationToke
3130

3231
public ValueTask<int> ReadAsync(Memory<byte> buffer) => _sslStream.InnerStream.ReadAsync(buffer, _cancellationToken);
3332

34-
public ValueTask<int> ReadLockAsync(Memory<byte> buffer) => _sslStream.CheckEnqueueReadAsync(buffer);
35-
36-
public Task WriteLockAsync() => _sslStream.CheckEnqueueWriteAsync();
37-
3833
public ValueTask WriteAsync(byte[] buffer, int offset, int count) => _sslStream.InnerStream.WriteAsync(new ReadOnlyMemory<byte>(buffer, offset, count), _cancellationToken);
3934

35+
public Task WaitAsync(TaskCompletionSource<bool> waiter) => waiter.Task;
36+
4037
public CancellationToken CancellationToken => _cancellationToken;
4138
}
4239

@@ -48,17 +45,15 @@ public AsyncSslIOAdapter(SslStream sslStream, CancellationToken cancellationToke
4845

4946
public ValueTask<int> ReadAsync(Memory<byte> buffer) => new ValueTask<int>(_sslStream.InnerStream.Read(buffer.Span));
5047

51-
public ValueTask<int> ReadLockAsync(Memory<byte> buffer) => new ValueTask<int>(_sslStream.CheckEnqueueRead(buffer));
52-
5348
public ValueTask WriteAsync(byte[] buffer, int offset, int count)
5449
{
5550
_sslStream.InnerStream.Write(buffer, offset, count);
5651
return default;
5752
}
5853

59-
public Task WriteLockAsync()
54+
public Task WaitAsync(TaskCompletionSource<bool> waiter)
6055
{
61-
_sslStream.CheckEnqueueWrite();
56+
waiter.Task.Wait();
6257
return Task.CompletedTask;
6358
}
6459

0 commit comments

Comments
 (0)