Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.
/ corefx Public archive

Commit e2a2174

Browse files
committed
Block zero-byte calls to encrypt for Unix SslStream
SSL_write is described as having an undefined behavior for this input. The observed behavior is that it returns 0 (which is ambiguous for "wrote 0/0 bytes" or "writing failed"), and that we then try to read the framed message and the message buffer is empty. Trying to detect this case once inside the PAL seemed to violate assumptions of the common code, so instead a PAL-capability check is done in SslStreamInternal.StartWriting. Windows will continue to write the framed empty message, non-Windows will do nothing.
1 parent 8c5ebe1 commit e2a2174

File tree

5 files changed

+42
-1
lines changed

5 files changed

+42
-1
lines changed

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ internal static int Encrypt(SafeSslHandle context, byte[] input, int offset, int
185185
{
186186
Debug.Assert(input != null);
187187
Debug.Assert(offset >= 0);
188-
Debug.Assert(count >= 0);
188+
Debug.Assert(count > 0);
189189
Debug.Assert(offset <= input.Length);
190190
Debug.Assert(input.Length - offset >= count);
191191

src/System.Net.Security/src/System/Net/SecureProtocols/SslStreamInternal.cs

+7
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,13 @@ private void StartWriting(byte[] buffer, int offset, int count, AsyncProtocolReq
394394

395395
do
396396
{
397+
if (count == 0 && !SslStreamPal.CanEncryptEmptyMessage)
398+
{
399+
// If it's an empty message and the PAL doesn't support that,
400+
// we're done.
401+
return;
402+
}
403+
397404
// Request a write IO slot.
398405
if (_sslState.CheckEnqueueWrite(asyncRequest))
399406
{

src/System.Net.Security/src/System/Net/SslStreamPal.Unix.cs

+1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ public static Exception GetException(SecurityStatusPal status)
2222
}
2323

2424
internal const bool StartMutualAuthAsAnonymous = false;
25+
internal const bool CanEncryptEmptyMessage = false;
2526

2627
public static void VerifyPackageInfo()
2728
{

src/System.Net.Security/src/System/Net/SslStreamPal.Windows.cs

+1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ public static Exception GetException(SecurityStatusPal status)
3333
}
3434

3535
internal const bool StartMutualAuthAsAnonymous = true;
36+
internal const bool CanEncryptEmptyMessage = true;
3637

3738
public static void VerifyPackageInfo()
3839
{

src/System.Net.Security/tests/FunctionalTests/SslStreamStreamToStreamTest.cs

+32
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,38 @@ public void SslStream_StreamToStream_Successive_ClientWrite_Sync_Success()
9393
}
9494
}
9595

96+
[OuterLoop] // TODO: Issue #11345
97+
[Fact]
98+
public void SslStream_StreamToStream_Successive_ClientWrite_Sync_WithZeroBytes_Success()
99+
{
100+
byte[] recvBuf = new byte[_sampleMsg.Length];
101+
VirtualNetwork network = new VirtualNetwork();
102+
103+
using (var clientStream = new VirtualNetworkStream(network, isServer: false))
104+
using (var serverStream = new VirtualNetworkStream(network, isServer: true))
105+
using (var clientSslStream = new SslStream(clientStream, false, AllowAnyServerCertificate))
106+
using (var serverSslStream = new SslStream(serverStream))
107+
{
108+
bool result = DoHandshake(clientSslStream, serverSslStream);
109+
110+
Assert.True(result, "Handshake completed.");
111+
112+
clientSslStream.Write(Array.Empty<byte>());
113+
clientSslStream.Write(_sampleMsg);
114+
115+
serverSslStream.Read(recvBuf, 0, _sampleMsg.Length);
116+
117+
Assert.True(VerifyOutput(recvBuf, _sampleMsg), "verify first read data is as expected.");
118+
119+
clientSslStream.Write(_sampleMsg);
120+
clientSslStream.Write(Array.Empty<byte>());
121+
122+
serverSslStream.Read(recvBuf, 0, _sampleMsg.Length);
123+
124+
Assert.True(VerifyOutput(recvBuf, _sampleMsg), "verify second read data is as expected.");
125+
}
126+
}
127+
96128
[OuterLoop] // TODO: Issue #11345
97129
[Theory]
98130
[InlineData(false)]

0 commit comments

Comments
 (0)