diff --git a/src/Common/src/Interop/Windows/SChannel/SslConnectionInfo.cs b/src/Common/src/Interop/Windows/SChannel/SslConnectionInfo.cs index c2a598b8d94c..f522d8b84867 100644 --- a/src/Common/src/Interop/Windows/SChannel/SslConnectionInfo.cs +++ b/src/Common/src/Interop/Windows/SChannel/SslConnectionInfo.cs @@ -42,6 +42,7 @@ internal unsafe SslConnectionInfo(byte[] nativeBuffer) { GlobalLog.Assert("SslConnectionInfo::.ctor", "Negative size."); } + Debug.Fail("SslConnectionInfo::.ctor", "Negative size."); throw; } diff --git a/src/Common/src/Interop/Windows/sspicli/SSPIAuthType.cs b/src/Common/src/Interop/Windows/sspicli/SSPIAuthType.cs index 3eefec76898c..f836b94d27ae 100644 --- a/src/Common/src/Interop/Windows/sspicli/SSPIAuthType.cs +++ b/src/Common/src/Interop/Windows/sspicli/SSPIAuthType.cs @@ -105,13 +105,13 @@ public unsafe int DecryptMessage(SafeDeleteContext context, Interop.SspiCli.Secu context.DangerousRelease(); } - if (status == 0 && qop == Interop.SspiCli.SECQOP_WRAP_NO_ENCRYPT) { if (GlobalLog.IsEnabled) { GlobalLog.Assert("SspiCli.DecryptMessage", "Expected qop = 0, returned value = " + qop.ToString("x", CultureInfo.InvariantCulture)); } + Debug.Fail("SspiCli.DecryptMessage", "Expected qop = 0, returned value = " + qop.ToString("x", CultureInfo.InvariantCulture)); throw new InvalidOperationException(SR.net_auth_message_not_encrypted); } diff --git a/src/Common/src/Interop/Windows/sspicli/SSPIWrapper.cs b/src/Common/src/Interop/Windows/sspicli/SSPIWrapper.cs index cf9efeb94764..7d8ed059ac40 100644 --- a/src/Common/src/Interop/Windows/sspicli/SSPIWrapper.cs +++ b/src/Common/src/Interop/Windows/sspicli/SSPIWrapper.cs @@ -413,6 +413,7 @@ private unsafe static int EncryptDecryptHelper(OP op, SSPIInterface secModule, S { GlobalLog.Assert("SSPIWrapper::EncryptDecryptHelper", "Unknown OP: " + op); } + Debug.Fail("SSPIWrapper::EncryptDecryptHelper", "Unknown OP: " + op); throw NotImplemented.ByDesignWithMessage(SR.net_MethodNotImplementedException); } @@ -458,6 +459,7 @@ private unsafe static int EncryptDecryptHelper(OP op, SSPIInterface secModule, S { GlobalLog.Assert("SSPIWrapper::EncryptDecryptHelper", "Output buffer out of range."); } + Debug.Fail("SSPIWrapper::EncryptDecryptHelper", "Output buffer out of range."); iBuffer.size = 0; iBuffer.offset = 0; @@ -473,14 +475,17 @@ private unsafe static int EncryptDecryptHelper(OP op, SSPIInterface secModule, S { GlobalLog.AssertFormat("SSPIWrapper::EncryptDecryptHelper|'offset' out of range. [{0}]", iBuffer.offset); } + Debug.Fail("SSPIWrapper::EncryptDecryptHelper|'offset' out of range. [" + iBuffer.offset + "]"); } + if (iBuffer.size < 0 || iBuffer.size > (iBuffer.token == null ? 0 : iBuffer.token.Length - iBuffer.offset)) { if (GlobalLog.IsEnabled) { GlobalLog.AssertFormat("SSPIWrapper::EncryptDecryptHelper|'size' out of range. [{0}]", iBuffer.size); } + Debug.Fail("SSPIWrapper::EncryptDecryptHelper|'size' out of range. [" + iBuffer.size + "]"); } } diff --git a/src/Common/src/Interop/Windows/sspicli/SecSizes.cs b/src/Common/src/Interop/Windows/sspicli/SecSizes.cs index 0ea0e9568bc0..4d796a0ea5e8 100644 --- a/src/Common/src/Interop/Windows/sspicli/SecSizes.cs +++ b/src/Common/src/Interop/Windows/sspicli/SecSizes.cs @@ -34,6 +34,7 @@ internal unsafe SecSizes(byte[] memory) { GlobalLog.Assert("SecSizes::.ctor", "Negative size."); } + Debug.Fail("SecSizes::.ctor", "Negative size."); throw; } diff --git a/src/Common/src/Interop/Windows/sspicli/SecuritySafeHandles.cs b/src/Common/src/Interop/Windows/sspicli/SecuritySafeHandles.cs index 4b610f4ebac5..6655301f803a 100644 --- a/src/Common/src/Interop/Windows/sspicli/SecuritySafeHandles.cs +++ b/src/Common/src/Interop/Windows/sspicli/SecuritySafeHandles.cs @@ -549,6 +549,7 @@ internal unsafe static int InitializeSecurityContext( { GlobalLog.Assert("SafeDeleteContext::InitializeSecurityContext()|outSecBuffer != null"); } + Debug.Fail("SafeDeleteContext::InitializeSecurityContext()|outSecBuffer != null"); } if (inSecBuffer != null && inSecBuffers != null) @@ -557,6 +558,7 @@ internal unsafe static int InitializeSecurityContext( { GlobalLog.Assert("SafeDeleteContext::InitializeSecurityContext()|inSecBuffer == null || inSecBuffers == null"); } + Debug.Fail("SafeDeleteContext::InitializeSecurityContext()|inSecBuffer == null || inSecBuffers == null"); } @@ -859,6 +861,7 @@ internal unsafe static int AcceptSecurityContext( { GlobalLog.Assert("SafeDeleteContext::AcceptSecurityContext()|outSecBuffer != null"); } + Debug.Fail("SafeDeleteContext::AcceptSecurityContext()|outSecBuffer != null"); } if (inSecBuffer != null && inSecBuffers != null) @@ -867,6 +870,7 @@ internal unsafe static int AcceptSecurityContext( { GlobalLog.Assert("SafeDeleteContext::AcceptSecurityContext()|inSecBuffer == null || inSecBuffers == null"); } + Debug.Fail("SafeDeleteContext::AcceptSecurityContext()|outSecBuffer != null"); } @@ -1142,6 +1146,7 @@ internal unsafe static int CompleteAuthToken( { GlobalLog.Assert("SafeDeleteContext::CompleteAuthToken()|inSecBuffers == null"); } + Debug.Fail("SafeDeleteContext::CompleteAuthToken()|inSecBuffers == null"); } diff --git a/src/Common/src/Interop/Windows/sspicli/StreamSizes.cs b/src/Common/src/Interop/Windows/sspicli/StreamSizes.cs index 68db80ad31b3..fe1906d76052 100644 --- a/src/Common/src/Interop/Windows/sspicli/StreamSizes.cs +++ b/src/Common/src/Interop/Windows/sspicli/StreamSizes.cs @@ -36,6 +36,7 @@ internal unsafe StreamSizes(byte[] memory) { GlobalLog.Assert("StreamSizes::.ctor", "Negative size."); } + Debug.Fail("StreamSizes::.ctor", "Negative size."); throw; } diff --git a/src/Common/src/System/Net/ContextAwareResult.Windows.cs b/src/Common/src/System/Net/ContextAwareResult.Windows.cs index 4530d83ddf0a..ca2345e727a2 100644 --- a/src/Common/src/System/Net/ContextAwareResult.Windows.cs +++ b/src/Common/src/System/Net/ContextAwareResult.Windows.cs @@ -31,6 +31,7 @@ internal WindowsIdentity Identity { GlobalLog.AssertFormat("ContextAwareResult#{0}::Identity|Called on completed result.", LoggingHash.HashString(this)); } + Debug.Fail("ContextAwareResult#" + LoggingHash.HashString(this) + "::Identity |Called on completed result."); } @@ -49,6 +50,7 @@ internal WindowsIdentity Identity { GlobalLog.AssertFormat("ContextAwareResult#{0}::Identity|No identity captured - specify captureIdentity.", LoggingHash.HashString(this)); } + Debug.Fail("ContextAwareResult#" + LoggingHash.HashString(this) + "::Identity |No identity captured - specify captureIdentity."); } @@ -62,8 +64,10 @@ internal WindowsIdentity Identity { GlobalLog.AssertFormat("ContextAwareResult#{0}::Identity|Must lock (StartPostingAsyncOp()) { ... FinishPostingAsyncOp(); } when calling Identity (unless it's only called after FinishPostingAsyncOp).", LoggingHash.HashString(this)); } + Debug.Fail("ContextAwareResult#" + LoggingHash.HashString(this) + "::Identity |Must lock (StartPostingAsyncOp()) { ... FinishPostingAsyncOp(); } when calling Identity (unless it's only called after FinishPostingAsyncOp)."); } + lock (_lock) { } } @@ -75,6 +79,7 @@ internal WindowsIdentity Identity { GlobalLog.AssertFormat("ContextAwareResult#{0}::Identity|Result became completed during call.", LoggingHash.HashString(this)); } + Debug.Fail("ContextAwareResult#" + LoggingHash.HashString(this) + "::Identity |Result became completed during call."); } diff --git a/src/Common/src/System/Net/ContextAwareResult.cs b/src/Common/src/System/Net/ContextAwareResult.cs index e275cd288abf..8e048d5c531e 100644 --- a/src/Common/src/System/Net/ContextAwareResult.cs +++ b/src/Common/src/System/Net/ContextAwareResult.cs @@ -138,6 +138,7 @@ internal ExecutionContext ContextCopy { GlobalLog.AssertFormat("ContextAwareResult#{0}::ContextCopy|Called on completed result.", LoggingHash.HashString(this)); } + Debug.Fail("ContextAwareResult#" + LoggingHash.HashString(this) + "::ContextCopy |Called on completed result."); } @@ -157,6 +158,7 @@ internal ExecutionContext ContextCopy { GlobalLog.AssertFormat("ContextAwareResult#{0}::ContextCopy|No context captured - specify a callback or forceCaptureContext.", LoggingHash.HashString(this)); } + Debug.Fail("ContextAwareResult#" + LoggingHash.HashString(this) + "::ContextCopy |No context captured - specify a callback or forceCaptureContext."); } @@ -170,6 +172,7 @@ internal ExecutionContext ContextCopy { GlobalLog.AssertFormat("ContextAwareResult#{0}::ContextCopy|Must lock (StartPostingAsyncOp()) { ... FinishPostingAsyncOp(); } when calling ContextCopy (unless it's only called after FinishPostingAsyncOp).", LoggingHash.HashString(this)); } + Debug.Fail("ContextAwareResult#" + LoggingHash.HashString(this) +"::ContextCopy |Must lock (StartPostingAsyncOp()) { ... FinishPostingAsyncOp(); } when calling ContextCopy (unless it's only called after FinishPostingAsyncOp)."); } lock (_lock) { } @@ -183,6 +186,7 @@ internal ExecutionContext ContextCopy { GlobalLog.AssertFormat("ContextAwareResult#{0}::ContextCopy|Result became completed during call.", LoggingHash.HashString(this)); } + Debug.Fail("ContextAwareResult#" + LoggingHash.HashString(this) + "::ContextCopy |Result became completed during call."); } @@ -221,6 +225,7 @@ internal object StartPostingAsyncOp(bool lockCapture) { GlobalLog.AssertFormat("ContextAwareResult#{0}::StartPostingAsyncOp|Called on completed result.", LoggingHash.HashString(this)); } + Debug.Fail("ContextAwareResult#" + LoggingHash.HashString(this) + "::StartPostingAsyncOp |Called on completed result."); } @@ -318,6 +323,7 @@ private bool CaptureOrComplete(ref ExecutionContext cachedContext, bool returnCo { GlobalLog.AssertFormat("ContextAwareResult#{0}::CaptureOrComplete|Called without calling StartPostingAsyncOp.", LoggingHash.HashString(this)); } + Debug.Fail("ContextAwareResult#" + LoggingHash.HashString(this) + "::CaptureOrComplete |Called without calling StartPostingAsyncOp."); } @@ -384,6 +390,7 @@ private bool CaptureOrComplete(ref ExecutionContext cachedContext, bool returnCo { GlobalLog.AssertFormat("ContextAwareResult#{0}::CaptureOrComplete|Didn't capture context, but didn't complete synchronously!", LoggingHash.HashString(this)); } + Debug.Fail("ContextAwareResult#" + LoggingHash.HashString(this) + "::CaptureOrComplete |Didn't capture context, but didn't complete synchronously!"); } } diff --git a/src/Common/src/System/Net/InternalException.cs b/src/Common/src/System/Net/InternalException.cs index b009611b51a7..ce4d86aa2dd4 100644 --- a/src/Common/src/System/Net/InternalException.cs +++ b/src/Common/src/System/Net/InternalException.cs @@ -13,6 +13,7 @@ internal InternalException() { GlobalLog.Assert("InternalException thrown."); } + Debug.Fail("InternalException thrown."); } } diff --git a/src/Common/src/System/Net/LazyAsyncResult.cs b/src/Common/src/System/Net/LazyAsyncResult.cs index 84216bd8c342..80ae6c101167 100644 --- a/src/Common/src/System/Net/LazyAsyncResult.cs +++ b/src/Common/src/System/Net/LazyAsyncResult.cs @@ -79,6 +79,7 @@ internal LazyAsyncResult(object myObject, object myState, AsyncCallback myCallBa { GlobalLog.AssertFormat("LazyAsyncResult#{0}::.ctor()|Result can't be set to DBNull - it's a special internal value.", LoggingHash.HashString(this)); } + Debug.Fail("LazyAsyncResult#" + LoggingHash.HashString(this) + "::.ctor()|Result can't be set to DBNull - it's a special internal value."); } @@ -335,14 +336,17 @@ internal object Result { GlobalLog.AssertFormat("LazyAsyncResult#{0}::set_Result()|Result can't be set to DBNull - it's a special internal value.", LoggingHash.HashString(this)); } + Debug.Fail("LazyAsyncResult#" + LoggingHash.HashString(this) + "::set_Result()|Result can't be set to DBNull - it's a special internal value."); } + if (InternalPeekCompleted) { if (GlobalLog.IsEnabled) { GlobalLog.AssertFormat("LazyAsyncResult#{0}::set_Result()|Called on completed result.", LoggingHash.HashString(this)); } + Debug.Fail("LazyAsyncResult#" + LoggingHash.HashString(this) + "::set_Result()|Called on completed result."); } _result = value; diff --git a/src/System.Net.Security/System.Net.Security.sln b/src/System.Net.Security/System.Net.Security.sln index 03afd91ac1ef..fd6566223585 100644 --- a/src/System.Net.Security/System.Net.Security.sln +++ b/src/System.Net.Security/System.Net.Security.sln @@ -65,22 +65,22 @@ Global {89F37791-6254-4D60-AB96-ACD3CCA0E771}.Windows_Debug|Any CPU.Build.0 = Windows_Debug|Any CPU {89F37791-6254-4D60-AB96-ACD3CCA0E771}.Windows_Release|Any CPU.ActiveCfg = Windows_Release|Any CPU {89F37791-6254-4D60-AB96-ACD3CCA0E771}.Windows_Release|Any CPU.Build.0 = Windows_Release|Any CPU - {A55A2B9A-830F-4330-A0E7-02A9FB30ABD2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A55A2B9A-830F-4330-A0E7-02A9FB30ABD2}.Debug|Any CPU.Build.0 = Debug|Any CPU - {A55A2B9A-830F-4330-A0E7-02A9FB30ABD2}.Linux_Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A55A2B9A-830F-4330-A0E7-02A9FB30ABD2}.Linux_Debug|Any CPU.Build.0 = Debug|Any CPU - {A55A2B9A-830F-4330-A0E7-02A9FB30ABD2}.Linux_Release|Any CPU.ActiveCfg = Release|Any CPU - {A55A2B9A-830F-4330-A0E7-02A9FB30ABD2}.Linux_Release|Any CPU.Build.0 = Release|Any CPU - {A55A2B9A-830F-4330-A0E7-02A9FB30ABD2}.OSX_Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A55A2B9A-830F-4330-A0E7-02A9FB30ABD2}.OSX_Debug|Any CPU.Build.0 = Debug|Any CPU - {A55A2B9A-830F-4330-A0E7-02A9FB30ABD2}.OSX_Release|Any CPU.ActiveCfg = Release|Any CPU - {A55A2B9A-830F-4330-A0E7-02A9FB30ABD2}.OSX_Release|Any CPU.Build.0 = Release|Any CPU - {A55A2B9A-830F-4330-A0E7-02A9FB30ABD2}.Release|Any CPU.ActiveCfg = Release|Any CPU - {A55A2B9A-830F-4330-A0E7-02A9FB30ABD2}.Release|Any CPU.Build.0 = Release|Any CPU - {A55A2B9A-830F-4330-A0E7-02A9FB30ABD2}.Windows_Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A55A2B9A-830F-4330-A0E7-02A9FB30ABD2}.Windows_Debug|Any CPU.Build.0 = Debug|Any CPU - {A55A2B9A-830F-4330-A0E7-02A9FB30ABD2}.Windows_Release|Any CPU.ActiveCfg = Release|Any CPU - {A55A2B9A-830F-4330-A0E7-02A9FB30ABD2}.Windows_Release|Any CPU.Build.0 = Release|Any CPU + {A55A2B9A-830F-4330-A0E7-02A9FB30ABD2}.Debug|Any CPU.ActiveCfg = Windows_Debug|Any CPU + {A55A2B9A-830F-4330-A0E7-02A9FB30ABD2}.Debug|Any CPU.Build.0 = Windows_Debug|Any CPU + {A55A2B9A-830F-4330-A0E7-02A9FB30ABD2}.Linux_Debug|Any CPU.ActiveCfg = Linux_Debug|Any CPU + {A55A2B9A-830F-4330-A0E7-02A9FB30ABD2}.Linux_Debug|Any CPU.Build.0 = Linux_Debug|Any CPU + {A55A2B9A-830F-4330-A0E7-02A9FB30ABD2}.Linux_Release|Any CPU.ActiveCfg = Linux_Release|Any CPU + {A55A2B9A-830F-4330-A0E7-02A9FB30ABD2}.Linux_Release|Any CPU.Build.0 = Linux_Release|Any CPU + {A55A2B9A-830F-4330-A0E7-02A9FB30ABD2}.OSX_Debug|Any CPU.ActiveCfg = OSX_Debug|Any CPU + {A55A2B9A-830F-4330-A0E7-02A9FB30ABD2}.OSX_Debug|Any CPU.Build.0 = OSX_Debug|Any CPU + {A55A2B9A-830F-4330-A0E7-02A9FB30ABD2}.OSX_Release|Any CPU.ActiveCfg = OSX_Release|Any CPU + {A55A2B9A-830F-4330-A0E7-02A9FB30ABD2}.OSX_Release|Any CPU.Build.0 = OSX_Release|Any CPU + {A55A2B9A-830F-4330-A0E7-02A9FB30ABD2}.Release|Any CPU.ActiveCfg = Windows_Release|Any CPU + {A55A2B9A-830F-4330-A0E7-02A9FB30ABD2}.Release|Any CPU.Build.0 = Windows_Release|Any CPU + {A55A2B9A-830F-4330-A0E7-02A9FB30ABD2}.Windows_Debug|Any CPU.ActiveCfg = Windows_Debug|Any CPU + {A55A2B9A-830F-4330-A0E7-02A9FB30ABD2}.Windows_Debug|Any CPU.Build.0 = Windows_Debug|Any CPU + {A55A2B9A-830F-4330-A0E7-02A9FB30ABD2}.Windows_Release|Any CPU.ActiveCfg = Windows_Release|Any CPU + {A55A2B9A-830F-4330-A0E7-02A9FB30ABD2}.Windows_Release|Any CPU.Build.0 = Windows_Release|Any CPU {0D174EA9-9E61-4519-8D31-7BD2331A1982}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {0D174EA9-9E61-4519-8D31-7BD2331A1982}.Debug|Any CPU.Build.0 = Debug|Any CPU {0D174EA9-9E61-4519-8D31-7BD2331A1982}.Linux_Debug|Any CPU.ActiveCfg = Debug|Any CPU diff --git a/src/System.Net.Security/src/System/Net/CertificateValidationPal.Windows.cs b/src/System.Net.Security/src/System/Net/CertificateValidationPal.Windows.cs index 941e71e080ad..b83569955be4 100644 --- a/src/System.Net.Security/src/System/Net/CertificateValidationPal.Windows.cs +++ b/src/System.Net.Security/src/System/Net/CertificateValidationPal.Windows.cs @@ -163,6 +163,7 @@ internal static string[] GetRequestCertificateAuthorities(SafeDeleteContext secu { GlobalLog.Assert("SecureChannel::GetIssuers()", "Interop.SspiCli._CERT_CHAIN_ELEMENT size is not positive: " + pIL2->cbSize.ToString()); } + Debug.Fail("SecureChannel::GetIssuers()", "Interop.SspiCli._CERT_CHAIN_ELEMENT size is not positive: " + pIL2->cbSize.ToString()); } @@ -254,6 +255,7 @@ internal static X509Store EnsureStoreOpened(bool isMachineStore) { GlobalLog.Assert("SecureChannel::EnsureStoreOpened()", "Failed to open cert store, location:" + storeLocation + " exception:" + exception); } + Debug.Fail("SecureChannel::EnsureStoreOpened()", "Failed to open cert store, location:" + storeLocation + " exception:" + exception); return null; } diff --git a/src/System.Net.Security/src/System/Net/NTAuthentication.cs b/src/System.Net.Security/src/System/Net/NTAuthentication.cs index bfe544f1d140..a92dbc7282b5 100644 --- a/src/System.Net.Security/src/System/Net/NTAuthentication.cs +++ b/src/System.Net.Security/src/System/Net/NTAuthentication.cs @@ -200,12 +200,13 @@ internal SecSizes Sizes { get { - if ((IsCompleted && IsValidContext)) + if (!(IsCompleted && IsValidContext)) { if (GlobalLog.IsEnabled) { - GlobalLog.Assert("NTAuthentication#{0}::MaxDataSize|The context is not completed or invalid.", LoggingHash.HashString(this)); + GlobalLog.AssertFormat("NTAuthentication#{0}::MaxDataSize|The context is not completed or invalid.", LoggingHash.HashString(this)); } + Debug.Fail("NTAuthentication#" + LoggingHash.HashString(this) + "::MaxDataSize |The context is not completed or invalid."); } @@ -339,21 +340,23 @@ private void Initialize(bool isServer, string package, NetworkCredential credent // This token can be used for impersonation. We use it to create a WindowsIdentity and hand it out to the server app. internal SecurityContextTokenHandle GetContextToken(out Interop.SecurityStatus status) { - if ((IsCompleted && IsValidContext)) + if (!(IsCompleted && IsValidContext)) { if (GlobalLog.IsEnabled) { GlobalLog.AssertFormat("NTAuthentication#{0}::GetContextToken|Should be called only when completed with success, currently is not!", LoggingHash.HashString(this)); } + Debug.Fail("NTAuthentication#" + LoggingHash.HashString(this) + "::GetContextToken |Should be called only when completed with success, currently is not!"); } - if (IsServer) + if (!IsServer) { if (GlobalLog.IsEnabled) { GlobalLog.AssertFormat("NTAuthentication#{0}::GetContextToken|The method must not be called by the client side!", LoggingHash.HashString(this)); } + Debug.Fail("NTAuthentication#" + LoggingHash.HashString(this) + "::GetContextToken |The method must not be called by the client side!"); } @@ -525,12 +528,13 @@ internal byte[] GetOutgoingBlob(byte[] incomingBlob, bool throwOnError, out Inte if (statusCode == Interop.SecurityStatus.OK) { // Success. - if ((statusCode == Interop.SecurityStatus.OK)) + if (statusCode != Interop.SecurityStatus.OK) { if (GlobalLog.IsEnabled) { GlobalLog.AssertFormat("NTAuthentication#{0}::GetOutgoingBlob()|statusCode:[0x{1:x8}] ({2}) m_SecurityContext#{3}::Handle:[{4}] [STATUS != OK]", LoggingHash.HashString(this), (int)statusCode, statusCode, LoggingHash.HashString(_securityContext), LoggingHash.ObjectToString(_securityContext)); } + Debug.Fail("NTAuthentication#" + LoggingHash.HashString(this) + "::GetOutgoingBlob()|statusCode:[0x" + ((int)statusCode).ToString("x8") + "] (" + statusCode + ") m_SecurityContext#" + LoggingHash.HashString(_securityContext) + "::Handle:[" + LoggingHash.ObjectToString(_securityContext) + "] [STATUS != OK]"); } @@ -571,6 +575,7 @@ internal int Encrypt(byte[] buffer, int offset, int count, ref byte[] output, ui { GlobalLog.Assert("NTAuthentication#" + LoggingHash.HashString(this) + "::Encrypt", "Arguments out of range."); } + Debug.Fail("NTAuthentication#" + LoggingHash.HashString(this) + "::Encrypt", "Arguments out of range."); } @@ -652,6 +657,7 @@ internal int Decrypt(byte[] payload, int offset, int count, out int newOffset, u { GlobalLog.Assert("NTAuthentication#" + LoggingHash.HashString(this) + "::Decrypt", "Argument 'offset' out of range."); } + Debug.Fail("NTAuthentication#" + LoggingHash.HashString(this) + "::Decrypt", "Argument 'offset' out of range."); throw new ArgumentOutOfRangeException("offset"); @@ -663,6 +669,7 @@ internal int Decrypt(byte[] payload, int offset, int count, out int newOffset, u { GlobalLog.Assert("NTAuthentication#" + LoggingHash.HashString(this) + "::Decrypt", "Argument 'count' out of range."); } + Debug.Fail("NTAuthentication#" + LoggingHash.HashString(this) + "::Decrypt", "Argument 'count' out of range."); throw new ArgumentOutOfRangeException("count"); @@ -710,12 +717,13 @@ internal int Decrypt(byte[] payload, int offset, int count, out int newOffset, u private string GetClientSpecifiedSpn() { - if ((IsValidContext && IsCompleted)) + if (!(IsValidContext && IsCompleted)) { if (GlobalLog.IsEnabled) { GlobalLog.Assert("NTAuthentication: Trying to get the client SPN before handshaking is done!"); } + Debug.Fail("NTAuthentication: Trying to get the client SPN before handshaking is done!"); } @@ -738,6 +746,7 @@ private int DecryptNtlm(byte[] payload, int offset, int count, out int newOffset { GlobalLog.Assert("NTAuthentication#" + LoggingHash.HashString(this) + "::DecryptNtlm", "Argument 'count' out of range."); } + Debug.Fail("NTAuthentication#" + LoggingHash.HashString(this) + "::DecryptNtlm", "Argument 'count' out of range."); throw new ArgumentOutOfRangeException("count"); @@ -767,6 +776,7 @@ private int DecryptNtlm(byte[] payload, int offset, int count, out int newOffset { GlobalLog.Print("NTAuthentication#" + LoggingHash.HashString(this) + "::Decrypt() throw Error = " + errorCode.ToString("x", NumberFormatInfo.InvariantInfo)); } + throw new Win32Exception(errorCode); } diff --git a/src/System.Net.Security/src/System/Net/SSPIHandleCache.cs b/src/System.Net.Security/src/System/Net/SSPIHandleCache.cs index cf28a556582b..92e0c8e0e4b9 100644 --- a/src/System.Net.Security/src/System/Net/SSPIHandleCache.cs +++ b/src/System.Net.Security/src/System/Net/SSPIHandleCache.cs @@ -46,6 +46,7 @@ internal static void CacheCredential(SafeFreeCredentials newHandle) { GlobalLog.Assert("SSPIHandlCache", "Attempted to throw: " + e.ToString()); } + Debug.Fail("SSPIHandlCache", "Attempted to throw: " + e.ToString()); } } diff --git a/src/System.Net.Security/src/System/Net/SecureChannel.cs b/src/System.Net.Security/src/System/Net/SecureChannel.cs index 7cdb5bbaf23b..d2762b2af36d 100644 --- a/src/System.Net.Security/src/System/Net/SecureChannel.cs +++ b/src/System.Net.Security/src/System/Net/SecureChannel.cs @@ -74,6 +74,7 @@ internal SecureChannel(string hostname, bool serverMode, SslProtocols sslProtoco { GlobalLog.AssertFormat("SecureChannel#{0}::.ctor()|hostname == null", LoggingHash.HashString(this)); } + Debug.Fail("SecureChannel#" + LoggingHash.HashString(this) + "::.ctor()|hostname == null"); } _hostName = hostname; @@ -623,6 +624,7 @@ private bool AcquireClientCredentials(ref byte[] thumbPrint) { GlobalLog.Assert("AcquireClientCredentials()|'selectedCert' does not match 'clientCertificate'."); } + Debug.Fail("AcquireClientCredentials()|'selectedCert' does not match 'clientCertificate'."); } @@ -749,6 +751,7 @@ private bool AcquireServerCredentials(ref byte[] thumbPrint) { GlobalLog.Assert("AcquireServerCredentials()|'selectedCert' does not match 'localCertificate'."); } + Debug.Fail("AcquireServerCredentials()|'selectedCert' does not match 'localCertificate'."); } @@ -849,6 +852,7 @@ private SecurityStatusPal GenerateToken(byte[] input, int offset, int count, ref { GlobalLog.Assert("SecureChannel#" + LoggingHash.HashString(this) + "::GenerateToken", "Argument 'offset' out of range."); } + Debug.Fail("SecureChannel#" + LoggingHash.HashString(this) + "::GenerateToken", "Argument 'offset' out of range."); throw new ArgumentOutOfRangeException("offset"); } @@ -859,6 +863,7 @@ private SecurityStatusPal GenerateToken(byte[] input, int offset, int count, ref { GlobalLog.Assert("SecureChannel#" + LoggingHash.HashString(this) + "::GenerateToken", "Argument 'count' out of range."); } + Debug.Fail("SecureChannel#" + LoggingHash.HashString(this) + "::GenerateToken", "Argument 'count' out of range."); throw new ArgumentOutOfRangeException("count"); } @@ -1001,6 +1006,7 @@ internal void ProcessHandshakeSuccess() { GlobalLog.Assert("SecureChannel#" + LoggingHash.HashString(this) + "::ProcessHandshakeSuccess", "StreamSizes out of range."); } + Debug.Fail("SecureChannel#" + LoggingHash.HashString(this) + "::ProcessHandshakeSuccess", "StreamSizes out of range."); } @@ -1073,6 +1079,7 @@ internal SecurityStatusPal Encrypt(byte[] buffer, int offset, int size, ref byte { GlobalLog.Assert("SecureChannel#" + LoggingHash.HashString(this) + "::Encrypt", "Arguments out of range."); } + Debug.Fail("SecureChannel#" + LoggingHash.HashString(this) + "::Encrypt", "Arguments out of range."); } @@ -1113,6 +1120,7 @@ internal SecurityStatusPal Decrypt(byte[] payload, ref int offset, ref int count { GlobalLog.Assert("SecureChannel#" + LoggingHash.HashString(this) + "::Encrypt", "Argument 'offset' out of range."); } + Debug.Fail("SecureChannel#" + LoggingHash.HashString(this) + "::Encrypt", "Argument 'offset' out of range."); throw new ArgumentOutOfRangeException("offset"); } @@ -1123,6 +1131,7 @@ internal SecurityStatusPal Decrypt(byte[] payload, ref int offset, ref int count { GlobalLog.Assert("SecureChannel#" + LoggingHash.HashString(this) + "::Encrypt", "Argument 'count' out of range."); } + Debug.Fail("SecureChannel#" + LoggingHash.HashString(this) + "::Encrypt", "Argument 'count' out of range."); throw new ArgumentOutOfRangeException("count"); } diff --git a/src/System.Net.Security/src/System/Net/SecureProtocols/FixedSizeReader.cs b/src/System.Net.Security/src/System/Net/SecureProtocols/FixedSizeReader.cs index 58b80042e64b..0ea9e00f2458 100644 --- a/src/System.Net.Security/src/System/Net/SecureProtocols/FixedSizeReader.cs +++ b/src/System.Net.Security/src/System/Net/SecureProtocols/FixedSizeReader.cs @@ -111,6 +111,7 @@ private bool CheckCompletionBeforeNextRead(int bytes) { GlobalLog.AssertFormat("FixedSizeReader::CheckCompletion()|State got out of range. Total:{0} Count:{1}", _totalRead + bytes, _request.Count); } + Debug.Fail("FixedSizeReader::CheckCompletion()|State got out of range. Total:" + (_totalRead + bytes) + " Count:" + _request.Count); } @@ -131,6 +132,7 @@ private static void ReadCallback(IAsyncResult transportResult) { GlobalLog.Assert("ReadCallback|State type is wrong, expected FixedSizeReader."); } + Debug.Fail("ReadCallback|State type is wrong, expected FixedSizeReader."); } diff --git a/src/System.Net.Security/src/System/Net/SecureProtocols/HelperAsyncResults.cs b/src/System.Net.Security/src/System/Net/SecureProtocols/HelperAsyncResults.cs index f5e85b8cb756..9a11f0c48e5a 100644 --- a/src/System.Net.Security/src/System/Net/SecureProtocols/HelperAsyncResults.cs +++ b/src/System.Net.Security/src/System/Net/SecureProtocols/HelperAsyncResults.cs @@ -47,6 +47,7 @@ public AsyncProtocolRequest(LazyAsyncResult userAsyncResult) { GlobalLog.Assert("AsyncProtocolRequest()|userAsyncResult == null"); } + Debug.Fail("AsyncProtocolRequest()|userAsyncResult == null"); } if (userAsyncResult.InternalPeekCompleted) @@ -55,6 +56,7 @@ public AsyncProtocolRequest(LazyAsyncResult userAsyncResult) { GlobalLog.Assert("AsyncProtocolRequest()|userAsyncResult is already completed."); } + Debug.Fail("AsyncProtocolRequest()|userAsyncResult is already completed."); } UserAsyncResult = userAsyncResult; diff --git a/src/System.Net.Security/src/System/Net/SecureProtocols/InternalNegotiateStream.cs b/src/System.Net.Security/src/System/Net/SecureProtocols/InternalNegotiateStream.cs index fc9925967d42..3f7672dc8504 100644 --- a/src/System.Net.Security/src/System/Net/SecureProtocols/InternalNegotiateStream.cs +++ b/src/System.Net.Security/src/System/Net/SecureProtocols/InternalNegotiateStream.cs @@ -301,12 +301,13 @@ private int StartFrameBody(int readBytes, byte[] buffer, int offset, int count, return 0; } - if ((readBytes == _ReadHeader.Length)) + if (!(readBytes == _ReadHeader.Length)) { if (GlobalLog.IsEnabled) { GlobalLog.AssertFormat("NegoStream::ProcessHeader()|Frame size must be 4 but received {0} bytes.", readBytes); } + Debug.Fail("NegoStream::ProcessHeader()|Frame size must be 4 but received " + readBytes + " bytes."); } @@ -398,12 +399,13 @@ private static void WriteCallback(IAsyncResult transportResult) return; } - if ((transportResult.AsyncState is AsyncProtocolRequest)) + if (!(transportResult.AsyncState is AsyncProtocolRequest)) { if (GlobalLog.IsEnabled) { GlobalLog.Assert("NegotiateSteam::WriteCallback|State type is wrong, expected AsyncProtocolRequest."); } + Debug.Fail("NegotiateSteam::WriteCallback|State type is wrong, expected AsyncProtocolRequest."); } diff --git a/src/System.Net.Security/src/System/Net/SecureProtocols/NegoState.Windows.cs b/src/System.Net.Security/src/System/Net/SecureProtocols/NegoState.Windows.cs index e07415ee00f9..69168c16ac2d 100644 --- a/src/System.Net.Security/src/System/Net/SecureProtocols/NegoState.Windows.cs +++ b/src/System.Net.Security/src/System/Net/SecureProtocols/NegoState.Windows.cs @@ -755,12 +755,13 @@ private void StartSendAuthResetSignal(LazyAsyncResult lazyResult, byte[] message private static void WriteCallback(IAsyncResult transportResult) { - if ((transportResult.AsyncState is LazyAsyncResult)) + if (!(transportResult.AsyncState is LazyAsyncResult)) { if (GlobalLog.IsEnabled) { GlobalLog.Assert("WriteCallback|State type is wrong, expected LazyAsyncResult."); } + Debug.Fail("WriteCallback|State type is wrong, expected LazyAsyncResult."); } @@ -800,12 +801,13 @@ private static void WriteCallback(IAsyncResult transportResult) private static void ReadCallback(IAsyncResult transportResult) { - if ((transportResult.AsyncState is LazyAsyncResult)) + if (!(transportResult.AsyncState is LazyAsyncResult)) { if (GlobalLog.IsEnabled) { GlobalLog.Assert("ReadCallback|State type is wrong, expected LazyAsyncResult."); } + Debug.Fail("ReadCallback|State type is wrong, expected LazyAsyncResult."); } diff --git a/src/System.Net.Security/src/System/Net/SecureProtocols/SslState.cs b/src/System.Net.Security/src/System/Net/SecureProtocols/SslState.cs index 585ff8b8128e..bcad4a3024fe 100644 --- a/src/System.Net.Security/src/System/Net/SecureProtocols/SslState.cs +++ b/src/System.Net.Security/src/System/Net/SecureProtocols/SslState.cs @@ -1057,6 +1057,7 @@ private static void WriteCallback(IAsyncResult transportResult) { GlobalLog.Assert("SslState::WriteCallback", "Exception while decoding context. type:" + exception.GetType().ToString() + " message:" + exception.Message); } + Debug.Fail("SslState::WriteCallback", "Exception while decoding context. type:" + exception.GetType().ToString() + " message:" + exception.Message); } @@ -1576,13 +1577,14 @@ private Framing DetectFraming(byte[] bytes, int length) int version = -1; - if ((bytes == null || bytes.Length == 0)) + if ((bytes == null || bytes.Length <= 0)) { if (GlobalLog.IsEnabled) { - GlobalLog.Assert("SslState::DetectFraming()|Header buffer is not allocated will boom shortly."); + GlobalLog.Assert("SslState::DetectFraming()|Header buffer is not allocated."); } - Debug.Fail("SslState::DetectFraming()|Header buffer is not allocated will boom shortly."); + + Debug.Fail("SslState::DetectFraming()|Header buffer is not allocated."); } // If the first byte is SSL3 HandShake, then check if we have a SSLv3 Type3 client hello. @@ -1807,14 +1809,17 @@ private void RehandshakeCompleteCallback(IAsyncResult result) { GlobalLog.Assert("SslState::RehandshakeCompleteCallback()|result is null!"); } + Debug.Fail("SslState::RehandshakeCompleteCallback()|result is null!"); } + if (!lazyAsyncResult.InternalPeekCompleted) { if (GlobalLog.IsEnabled) { GlobalLog.Assert("SslState::RehandshakeCompleteCallback()|result is not completed!"); } + Debug.Fail("SslState::RehandshakeCompleteCallback()|result is not completed!"); } diff --git a/src/System.Net.Security/src/System/Net/SecureProtocols/SslStream.cs b/src/System.Net.Security/src/System/Net/SecureProtocols/SslStream.cs index 9074362eaba4..4a7b2f48494c 100644 --- a/src/System.Net.Security/src/System/Net/SecureProtocols/SslStream.cs +++ b/src/System.Net.Security/src/System/Net/SecureProtocols/SslStream.cs @@ -5,6 +5,7 @@ using System.Security.Authentication; using System.Security.Authentication.ExtendedProtection; using System.Security.Cryptography.X509Certificates; +using System.Threading; using System.Threading.Tasks; namespace System.Net.Security @@ -439,5 +440,87 @@ public override void Write(byte[] buffer, int offset, int count) { _sslState.SecureStream.Write(buffer, offset, count); } + + private IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback asyncCallback, object asyncState) + { + return _sslState.SecureStream.BeginRead(buffer, offset, count, asyncCallback, asyncState); + } + + private int EndRead(IAsyncResult asyncResult) + { + return _sslState.SecureStream.EndRead(asyncResult); + } + + private IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback asyncCallback, object asyncState) + { + return _sslState.SecureStream.BeginWrite(buffer, offset, count, asyncCallback, asyncState); + } + + private void EndWrite(IAsyncResult asyncResult) + { + _sslState.SecureStream.EndWrite(asyncResult); + } + + // ReadAsync - provide async read functionality. + // + // This method provides async read functionality. All we do is + // call through to the Begin/EndRead methods. + // + // Input: + // + // buffer - Buffer to read into. + // offset - Offset into the buffer where we're to read. + // size - Number of bytes to read. + // cancellationtoken - Token used to request cancellation of the operation + // + // Returns: + // + // A Task representing the read. + public override Task ReadAsync(byte[] buffer, int offset, int size, CancellationToken cancellationToken) + { + if (cancellationToken.IsCancellationRequested) + { + return Task.FromCanceled(cancellationToken); + } + + return Task.Factory.FromAsync( + (bufferArg, offsetArg, sizeArg, callback, state) => ((SslStream)state).BeginRead(bufferArg, offsetArg, sizeArg, callback, state), + iar => ((SslStream)iar.AsyncState).EndRead(iar), + buffer, + offset, + size, + this); + } + + // WriteAsync - provide async write functionality. + // + // This method provides async write functionality. All we do is + // call through to the Begin/EndWrite methods. + // + // Input: + // + // buffer - Buffer to write into. + // offset - Offset into the buffer where we're to write. + // size - Number of bytes to write. + // cancellationtoken - Token used to request cancellation of the operation + // + // Returns: + // + // A Task representing the write. + public override Task WriteAsync(byte[] buffer, int offset, int size, CancellationToken cancellationToken) + { + if (cancellationToken.IsCancellationRequested) + { + return Task.FromCanceled(cancellationToken); + } + + return Task.Factory.FromAsync( + (bufferArg, offsetArg, sizeArg, callback, state) => ((SslStream)state).BeginWrite(bufferArg, offsetArg, sizeArg, callback, state), + iar => ((SslStream)iar.AsyncState).EndWrite(iar), + buffer, + offset, + size, + this); + } } } diff --git a/src/System.Net.Security/src/System/Net/SecureProtocols/SslStreamContext.cs b/src/System.Net.Security/src/System/Net/SecureProtocols/SslStreamContext.cs index 559c0239a43c..d6358405b3ac 100644 --- a/src/System.Net.Security/src/System/Net/SecureProtocols/SslStreamContext.cs +++ b/src/System.Net.Security/src/System/Net/SecureProtocols/SslStreamContext.cs @@ -17,6 +17,7 @@ internal SslStreamContext(SslStream sslStream) { GlobalLog.Assert("SslStreamContext..ctor(): Not expecting a null sslStream!"); } + Debug.Fail("SslStreamContext..ctor(): Not expecting a null sslStream!"); } diff --git a/src/System.Net.Security/src/System/Net/SecureProtocols/SslStreamInternal.cs b/src/System.Net.Security/src/System/Net/SecureProtocols/SslStreamInternal.cs index 69550be0b142..8d08fd2d4365 100644 --- a/src/System.Net.Security/src/System/Net/SecureProtocols/SslStreamInternal.cs +++ b/src/System.Net.Security/src/System/Net/SecureProtocols/SslStreamInternal.cs @@ -12,26 +12,32 @@ namespace System.Net.Security // internal class SslStreamInternal { + private static readonly AsyncCallback s_writeCallback = new AsyncCallback(WriteCallback); + private static readonly AsyncProtocolCallback s_resumeAsyncWriteCallback = new AsyncProtocolCallback(ResumeAsyncWriteCallback); + private static readonly AsyncProtocolCallback s_resumeAsyncReadCallback = new AsyncProtocolCallback(ResumeAsyncReadCallback); + private static readonly AsyncProtocolCallback s_readHeaderCallback = new AsyncProtocolCallback(ReadHeaderCallback); + private static readonly AsyncProtocolCallback s_readFrameCallback = new AsyncProtocolCallback(ReadFrameCallback); + private const int PinnableReadBufferSize = 4096 * 4 + 32; // We read in 16K chunks + headers. private static PinnableBufferCache s_PinnableReadBufferCache = new PinnableBufferCache("System.Net.SslStream", PinnableReadBufferSize); private const int PinnableWriteBufferSize = 4096 + 1024; // We write in 4K chunks + encryption overhead. private static PinnableBufferCache s_PinnableWriteBufferCache = new PinnableBufferCache("System.Net.SslStream", PinnableWriteBufferSize); - private SslState _SslState; - private int _NestedWrite; - private int _NestedRead; + private SslState _sslState; + private int _nestedWrite; + private int _nestedRead; // Never updated directly, special properties are used. This is the read buffer. - private byte[] _InternalBuffer; - private bool _InternalBufferFromPinnableCache; + private byte[] _internalBuffer; + private bool _internalBufferFromPinnableCache; - private byte[] _PinnableOutputBuffer; // Used for writes when we can do it. - private byte[] _PinnableOutputBufferInUse; // Remembers what UNENCRYPTED buffer is using _PinnableOutputBuffer. + private byte[] _pinnableOutputBuffer; // Used for writes when we can do it. + private byte[] _pinnableOutputBufferInUse; // Remembers what UNENCRYPTED buffer is using _PinnableOutputBuffer. - private int _InternalOffset; - private int _InternalBufferCount; + private int _internalOffset; + private int _internalBufferCount; - private FixedSizeReader _Reader; + private FixedSizeReader _reader; internal SslStreamInternal(SslState sslState) { @@ -40,52 +46,134 @@ internal SslStreamInternal(SslState sslState) PinnableBufferCacheEventSource.Log.DebugMessage1("CTOR: In System.Net._SslStream.SslStream", this.GetHashCode()); } - _SslState = sslState; - _Reader = new FixedSizeReader(_SslState.InnerStream); + _sslState = sslState; + _reader = new FixedSizeReader(_sslState.InnerStream); } // If we have a read buffer from the pinnable cache, return it. private void FreeReadBuffer() { - if (_InternalBufferFromPinnableCache) + if (_internalBufferFromPinnableCache) { - s_PinnableReadBufferCache.FreeBuffer(_InternalBuffer); - _InternalBufferFromPinnableCache = false; + s_PinnableReadBufferCache.FreeBuffer(_internalBuffer); + _internalBufferFromPinnableCache = false; } - _InternalBuffer = null; + _internalBuffer = null; } ~SslStreamInternal() { - if (_InternalBufferFromPinnableCache) + if (_internalBufferFromPinnableCache) { if (PinnableBufferCacheEventSource.Log.IsEnabled()) { - PinnableBufferCacheEventSource.Log.DebugMessage2("DTOR: In System.Net._SslStream.~SslStream Freeing Read Buffer", this.GetHashCode(), PinnableBufferCacheEventSource.AddressOfByteArray(_InternalBuffer)); + PinnableBufferCacheEventSource.Log.DebugMessage2("DTOR: In System.Net._SslStream.~SslStream Freeing Read Buffer", this.GetHashCode(), PinnableBufferCacheEventSource.AddressOfByteArray(_internalBuffer)); } FreeReadBuffer(); } - if (_PinnableOutputBuffer != null) + if (_pinnableOutputBuffer != null) { if (PinnableBufferCacheEventSource.Log.IsEnabled()) { - PinnableBufferCacheEventSource.Log.DebugMessage2("DTOR: In System.Net._SslStream.~SslStream Freeing Write Buffer", this.GetHashCode(), PinnableBufferCacheEventSource.AddressOfByteArray(_PinnableOutputBuffer)); + PinnableBufferCacheEventSource.Log.DebugMessage2("DTOR: In System.Net._SslStream.~SslStream Freeing Write Buffer", this.GetHashCode(), PinnableBufferCacheEventSource.AddressOfByteArray(_pinnableOutputBuffer)); } - s_PinnableWriteBufferCache.FreeBuffer(_PinnableOutputBuffer); + s_PinnableWriteBufferCache.FreeBuffer(_pinnableOutputBuffer); } } internal int Read(byte[] buffer, int offset, int count) { - return ProcessRead(buffer, offset, count); + return ProcessRead(buffer, offset, count, null); } internal void Write(byte[] buffer, int offset, int count) { - ProcessWrite(buffer, offset, count); + ProcessWrite(buffer, offset, count, null); + } + + internal IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback asyncCallback, object asyncState) + { + BufferAsyncResult bufferResult = new BufferAsyncResult(this, buffer, offset, count, asyncState, asyncCallback); + AsyncProtocolRequest asyncRequest = new AsyncProtocolRequest(bufferResult); + ProcessRead(buffer, offset, count, asyncRequest); + return bufferResult; + } + + internal int EndRead(IAsyncResult asyncResult) + { + if (asyncResult == null) + { + throw new ArgumentNullException("asyncResult"); + } + + BufferAsyncResult bufferResult = asyncResult as BufferAsyncResult; + if (bufferResult == null) + { + throw new ArgumentException(SR.Format(SR.net_io_async_result, asyncResult.GetType().FullName), "asyncResult"); + } + + if (Interlocked.Exchange(ref _nestedRead, 0) == 0) + { + throw new InvalidOperationException(SR.Format(SR.net_io_invalidendcall, "EndRead")); + } + + // No "artificial" timeouts implemented so far, InnerStream controls timeout. + bufferResult.InternalWaitForCompletion(); + + if (bufferResult.Result is Exception) + { + if (bufferResult.Result is IOException) + { + throw (Exception)bufferResult.Result; + } + + throw new IOException(SR.net_io_read, (Exception)bufferResult.Result); + } + + return (int)bufferResult.Result; + } + + internal IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback asyncCallback, object asyncState) + { + LazyAsyncResult lazyResult = new LazyAsyncResult(this, asyncState, asyncCallback); + AsyncProtocolRequest asyncRequest = new AsyncProtocolRequest(lazyResult); + ProcessWrite(buffer, offset, count, asyncRequest); + return lazyResult; + } + + internal void EndWrite(IAsyncResult asyncResult) + { + if (asyncResult == null) + { + throw new ArgumentNullException("asyncResult"); + } + + LazyAsyncResult lazyResult = asyncResult as LazyAsyncResult; + if (lazyResult == null) + { + throw new ArgumentException(SR.Format(SR.net_io_async_result, asyncResult.GetType().FullName), "asyncResult"); + } + + if (Interlocked.Exchange(ref _nestedWrite, 0) == 0) + { + throw new InvalidOperationException(SR.Format(SR.net_io_invalidendcall, "EndWrite")); + } + + // No "artificial" timeouts implemented so far, InnerStream controls timeout. + lazyResult.InternalWaitForCompletion(); + + if (lazyResult.Result is Exception) + { + if (lazyResult.Result is IOException) + { + throw (Exception)lazyResult.Result; + } + + throw new IOException(SR.net_io_write, (Exception)lazyResult.Result); + } } internal bool DataAvailable @@ -97,7 +185,7 @@ private byte[] InternalBuffer { get { - return _InternalBuffer; + return _internalBuffer; } } @@ -105,7 +193,7 @@ private int InternalOffset { get { - return _InternalOffset; + return _internalOffset; } } @@ -113,14 +201,14 @@ private int InternalBufferCount { get { - return _InternalBufferCount; + return _internalBufferCount; } } private void SkipBytes(int decrCount) { - _InternalOffset += decrCount; - _InternalBufferCount -= decrCount; + _internalOffset += decrCount; + _internalBufferCount -= decrCount; } // @@ -129,10 +217,10 @@ private void SkipBytes(int decrCount) // private void EnsureInternalBufferSize(int curOffset, int addSize) { - if (_InternalBuffer == null || _InternalBuffer.Length < addSize + curOffset) + if (_internalBuffer == null || _internalBuffer.Length < addSize + curOffset) { - bool wasPinnable = _InternalBufferFromPinnableCache; - byte[] saved = _InternalBuffer; + bool wasPinnable = _internalBufferFromPinnableCache; + byte[] saved = _internalBuffer; int newSize = addSize + curOffset; if (newSize <= PinnableReadBufferSize) @@ -142,8 +230,8 @@ private void EnsureInternalBufferSize(int curOffset, int addSize) PinnableBufferCacheEventSource.Log.DebugMessage2("In System.Net._SslStream.EnsureInternalBufferSize IS pinnable", this.GetHashCode(), newSize); } - _InternalBufferFromPinnableCache = true; - _InternalBuffer = s_PinnableReadBufferCache.AllocateBuffer(); + _internalBufferFromPinnableCache = true; + _internalBuffer = s_PinnableReadBufferCache.AllocateBuffer(); } else { @@ -152,13 +240,13 @@ private void EnsureInternalBufferSize(int curOffset, int addSize) PinnableBufferCacheEventSource.Log.DebugMessage2("In System.Net._SslStream.EnsureInternalBufferSize NOT pinnable", this.GetHashCode(), newSize); } - _InternalBufferFromPinnableCache = false; - _InternalBuffer = new byte[newSize]; + _internalBufferFromPinnableCache = false; + _internalBuffer = new byte[newSize]; } if (saved != null && curOffset != 0) { - Buffer.BlockCopy(saved, 0, _InternalBuffer, 0, curOffset); + Buffer.BlockCopy(saved, 0, _internalBuffer, 0, curOffset); } if (wasPinnable) @@ -166,8 +254,8 @@ private void EnsureInternalBufferSize(int curOffset, int addSize) s_PinnableReadBufferCache.FreeBuffer(saved); } } - _InternalOffset = curOffset; - _InternalBufferCount = curOffset + addSize; + _internalOffset = curOffset; + _internalBufferCount = curOffset + addSize; } // @@ -199,23 +287,26 @@ private void ValidateParameters(byte[] buffer, int offset, int count) // // Sync write method. // - private void ProcessWrite(byte[] buffer, int offset, int count) + private void ProcessWrite(byte[] buffer, int offset, int count, AsyncProtocolRequest asyncRequest) { ValidateParameters(buffer, offset, count); - if (Interlocked.Exchange(ref _NestedWrite, 1) == 1) + if (Interlocked.Exchange(ref _nestedWrite, 1) == 1) { throw new NotSupportedException(SR.Format(SR.net_io_invalidnestedcall, "Write", "write")); } + bool failed = false; + try { - StartWriting(buffer, offset, count); + StartWriting(buffer, offset, count, asyncRequest); } catch (Exception e) { - _SslState.FinishWrite(); + _sslState.FinishWrite(); + failed = true; if (e is IOException) { throw; @@ -225,26 +316,34 @@ private void ProcessWrite(byte[] buffer, int offset, int count) } finally { - _NestedWrite = 0; + if (asyncRequest == null || failed) + { + _nestedWrite = 0; + } } } - private void StartWriting(byte[] buffer, int offset, int count) + private void StartWriting(byte[] buffer, int offset, int count, AsyncProtocolRequest asyncRequest) { + if (asyncRequest != null) + { + asyncRequest.SetNextRequest(buffer, offset, count, s_resumeAsyncWriteCallback); + } + // We loop to this method from the callback. // If the last chunk was just completed from async callback (count < 0), we complete user request. - if (count >= 0) + if (count >= 0 ) { byte[] outBuffer = null; - if (_PinnableOutputBufferInUse == null) + if (_pinnableOutputBufferInUse == null) { - if (_PinnableOutputBuffer == null) + if (_pinnableOutputBuffer == null) { - _PinnableOutputBuffer = s_PinnableWriteBufferCache.AllocateBuffer(); + _pinnableOutputBuffer = s_PinnableWriteBufferCache.AllocateBuffer(); } - _PinnableOutputBufferInUse = buffer; - outBuffer = _PinnableOutputBuffer; + _pinnableOutputBufferInUse = buffer; + outBuffer = _pinnableOutputBuffer; if (PinnableBufferCacheEventSource.Log.IsEnabled()) { PinnableBufferCacheEventSource.Log.DebugMessage3("In System.Net._SslStream.StartWriting Trying Pinnable", this.GetHashCode(), count, PinnableBufferCacheEventSource.AddressOfByteArray(outBuffer)); @@ -261,17 +360,18 @@ private void StartWriting(byte[] buffer, int offset, int count) do { // Request a write IO slot. - if (_SslState.CheckEnqueueWrite(null)) + if (_sslState.CheckEnqueueWrite(asyncRequest)) { // Operation is async and has been queued, return. return; } - int chunkBytes = Math.Min(count, _SslState.MaxDataSize); + int chunkBytes = Math.Min(count, _sslState.MaxDataSize); int encryptedBytes; - SecurityStatusPal errorCode = _SslState.EncryptData(buffer, offset, chunkBytes, ref outBuffer, out encryptedBytes); + SecurityStatusPal errorCode = _sslState.EncryptData(buffer, offset, chunkBytes, ref outBuffer, out encryptedBytes); if (errorCode != SecurityStatusPal.OK) { + // Re-handshake status is not supported. ProtocolToken message = new ProtocolToken(null, errorCode); throw new IOException(SR.net_io_encrypt, message.GetException()); } @@ -282,19 +382,41 @@ private void StartWriting(byte[] buffer, int offset, int count) this.GetHashCode(), encryptedBytes, PinnableBufferCacheEventSource.AddressOfByteArray(outBuffer)); } - _SslState.InnerStream.Write(outBuffer, 0, encryptedBytes); + if (asyncRequest != null) + { + // Prepare for the next request. + asyncRequest.SetNextRequest(buffer, offset + chunkBytes, count - chunkBytes, s_resumeAsyncWriteCallback); + IAsyncResult ar = _sslState.InnerStreamAPM.BeginWrite(outBuffer, 0, encryptedBytes, s_writeCallback, asyncRequest); + if (!ar.CompletedSynchronously) + { + return; + } + + _sslState.InnerStreamAPM.EndWrite(ar); + + } + else + { + _sslState.InnerStream.Write(outBuffer, 0, encryptedBytes); + } offset += chunkBytes; count -= chunkBytes; // Release write IO slot. - _SslState.FinishWrite(); + _sslState.FinishWrite(); + } while (count != 0); } - if (buffer == _PinnableOutputBufferInUse) + if (asyncRequest != null) + { + asyncRequest.CompleteUser(); + } + + if (buffer == _pinnableOutputBufferInUse) { - _PinnableOutputBufferInUse = null; + _pinnableOutputBufferInUse = null; if (PinnableBufferCacheEventSource.Log.IsEnabled()) { PinnableBufferCacheEventSource.Log.DebugMessage1("In System.Net._SslStream.StartWriting Freeing buffer.", this.GetHashCode()); @@ -303,17 +425,19 @@ private void StartWriting(byte[] buffer, int offset, int count) } // - // Sync read method. + // Combined sync/async read method. For sync requet asyncRequest==null. // - private int ProcessRead(byte[] buffer, int offset, int count) + private int ProcessRead(byte[] buffer, int offset, int count, AsyncProtocolRequest asyncRequest) { ValidateParameters(buffer, offset, count); - if (Interlocked.Exchange(ref _NestedRead, 1) == 1) + if (Interlocked.Exchange(ref _nestedRead, 1) == 1) { - throw new NotSupportedException(SR.Format(SR.net_io_invalidnestedcall, "Read", "read")); + throw new NotSupportedException(SR.Format(SR.net_io_invalidnestedcall, (asyncRequest!=null? "BeginRead":"Read"), "read")); } + bool failed = false; + try { int copyBytes; @@ -325,15 +449,21 @@ private int ProcessRead(byte[] buffer, int offset, int count) Buffer.BlockCopy(InternalBuffer, InternalOffset, buffer, offset, copyBytes); SkipBytes(copyBytes); } - + + if (asyncRequest != null) { + asyncRequest.CompleteUser((object) copyBytes); + } + return copyBytes; } - return StartReading(buffer, offset, count); + return StartReading(buffer, offset, count, asyncRequest); } catch (Exception e) { - _SslState.FinishRead(null); + _sslState.FinishRead(null); + failed = true; + if (e is IOException) { throw; @@ -343,14 +473,17 @@ private int ProcessRead(byte[] buffer, int offset, int count) } finally { - _NestedRead = 0; + if (asyncRequest == null || failed) + { + _nestedRead = 0; + } } } // // To avoid recursion when decrypted 0 bytes this method will loop until a decrypted result at least 1 byte. // - private int StartReading(byte[] buffer, int offset, int count) + private int StartReading(byte[] buffer, int offset, int count, AsyncProtocolRequest asyncRequest) { int result = 0; @@ -360,34 +493,42 @@ private int StartReading(byte[] buffer, int offset, int count) { GlobalLog.AssertFormat("SslStream::StartReading()|Previous frame was not consumed. InternalBufferCount:{0}", InternalBufferCount); } + Debug.Fail("SslStream::StartReading()|Previous frame was not consumed. InternalBufferCount:" + InternalBufferCount); } do { - int copyBytes = _SslState.CheckEnqueueRead(buffer, offset, count, null); + if (asyncRequest != null) + { + asyncRequest.SetNextRequest(buffer, offset, count, s_resumeAsyncReadCallback); + } + + int copyBytes = _sslState.CheckEnqueueRead(buffer, offset, count, asyncRequest); if (copyBytes == 0) { - //Queued but not completed! + // Queued but not completed! return 0; } if (copyBytes != -1) { + if (asyncRequest != null) + { + asyncRequest.CompleteUser((object)copyBytes); + } + return copyBytes; } } // When we read -1 bytes means we have decrypted 0 bytes or rehandshaking, need looping. - while ((result = StartFrameHeader(buffer, offset, count)) == -1); + while ((result = StartFrameHeader(buffer, offset, count, asyncRequest)) == -1); return result; } - // - // Need read frame size first - // - private int StartFrameHeader(byte[] buffer, int offset, int count) + private int StartFrameHeader(byte[] buffer, int offset, int count, AsyncProtocolRequest asyncRequest) { int readBytes = 0; @@ -399,22 +540,42 @@ private int StartFrameHeader(byte[] buffer, int offset, int count) // Reset internal buffer for a new frame. EnsureInternalBufferSize(0, SecureChannel.ReadHeaderSize); - readBytes = _Reader.ReadPacket(InternalBuffer, 0, SecureChannel.ReadHeaderSize); + if (asyncRequest != null) + { + asyncRequest.SetNextRequest(InternalBuffer, 0, SecureChannel.ReadHeaderSize, s_readHeaderCallback); + _reader.AsyncReadPacket(asyncRequest); + + if (!asyncRequest.MustCompleteSynchronously) + { + return 0; + } - return StartFrameBody(readBytes, buffer, offset, count); + readBytes = asyncRequest.Result; + } + else + { + readBytes = _reader.ReadPacket(InternalBuffer, 0, SecureChannel.ReadHeaderSize); + } + + return StartFrameBody(readBytes, buffer, offset, count, asyncRequest); } - private int StartFrameBody(int readBytes, byte[] buffer, int offset, int count) + private int StartFrameBody(int readBytes, byte[] buffer, int offset, int count, AsyncProtocolRequest asyncRequest) { if (readBytes == 0) { //EOF : Reset the buffer as we did not read anything into it. SkipBytes(InternalBufferCount); + if (asyncRequest != null) + { + asyncRequest.CompleteUser((object)0); + } + return 0; } // Now readBytes is a payload size. - readBytes = _SslState.GetRemainingFrameSize(InternalBuffer, readBytes); + readBytes = _sslState.GetRemainingFrameSize(InternalBuffer, readBytes); if (readBytes < 0) { @@ -423,15 +584,31 @@ private int StartFrameBody(int readBytes, byte[] buffer, int offset, int count) EnsureInternalBufferSize(SecureChannel.ReadHeaderSize, readBytes); - readBytes = _Reader.ReadPacket(InternalBuffer, SecureChannel.ReadHeaderSize, readBytes); + if (asyncRequest != null) + { + asyncRequest.SetNextRequest(InternalBuffer, SecureChannel.ReadHeaderSize, readBytes, s_readFrameCallback); + + _reader.AsyncReadPacket(asyncRequest); - return ProcessFrameBody(readBytes, buffer, offset, count); + if (!asyncRequest.MustCompleteSynchronously) + { + return 0; + } + + readBytes = asyncRequest.Result; + } + else + { + readBytes = _reader.ReadPacket(InternalBuffer, SecureChannel.ReadHeaderSize, readBytes); + } + + return ProcessFrameBody(readBytes, buffer, offset, count, asyncRequest); } // - // readBytes == SSL Data Payload size on input or 0 on EOF + // readBytes == SSL Data Payload size on input or 0 on EOF. // - private int ProcessFrameBody(int readBytes, byte[] buffer, int offset, int count) + private int ProcessFrameBody(int readBytes, byte[] buffer, int offset, int count, AsyncProtocolRequest asyncRequest) { if (readBytes == 0) { @@ -445,7 +622,7 @@ private int ProcessFrameBody(int readBytes, byte[] buffer, int offset, int count // Decrypt into internal buffer, change "readBytes" to count now _Decrypted Bytes_. int data_offset = 0; - SecurityStatusPal errorCode = _SslState.DecryptData(InternalBuffer, ref data_offset, ref readBytes); + SecurityStatusPal errorCode = _sslState.DecryptData(InternalBuffer, ref data_offset, ref readBytes); if (errorCode != SecurityStatusPal.OK) { @@ -458,7 +635,7 @@ private int ProcessFrameBody(int readBytes, byte[] buffer, int offset, int count // Reset internal buffer count. SkipBytes(InternalBufferCount); - return ProcessReadErrorCode(errorCode, buffer, offset, count, extraBuffer); + return ProcessReadErrorCode(errorCode, buffer, offset, count, asyncRequest, extraBuffer); } @@ -483,7 +660,11 @@ private int ProcessFrameBody(int readBytes, byte[] buffer, int offset, int count // This will adjust both the remaining internal buffer count and the offset. SkipBytes(readBytes); - _SslState.FinishRead(null); + _sslState.FinishRead(null); + if (asyncRequest != null) + { + asyncRequest.CompleteUser((object)readBytes); + } return readBytes; } @@ -491,9 +672,8 @@ private int ProcessFrameBody(int readBytes, byte[] buffer, int offset, int count // // Only processing SEC_I_RENEGOTIATE. // - private int ProcessReadErrorCode(SecurityStatusPal errorCode, byte[] buffer, int offset, int count, byte[] extraBuffer) + private int ProcessReadErrorCode(SecurityStatusPal errorCode, byte[] buffer, int offset, int count, AsyncProtocolRequest asyncRequest, byte[] extraBuffer) { - // ERROR - examine what kind ProtocolToken message = new ProtocolToken(null, errorCode); if (GlobalLog.IsEnabled) @@ -503,7 +683,7 @@ private int ProcessReadErrorCode(SecurityStatusPal errorCode, byte[] buffer, int if (message.Renegotiate) { - _SslState.ReplyOnReAuthentication(extraBuffer); + _sslState.ReplyOnReAuthentication(extraBuffer); // Loop on read. return -1; @@ -511,11 +691,155 @@ private int ProcessReadErrorCode(SecurityStatusPal errorCode, byte[] buffer, int if (message.CloseConnection) { - _SslState.FinishRead(null); + _sslState.FinishRead(null); + if (asyncRequest != null) + { + asyncRequest.CompleteUser((object)0); + } + return 0; } throw new IOException(SR.net_io_decrypt, message.GetException()); } + + private static void WriteCallback(IAsyncResult transportResult) + { + if (transportResult.CompletedSynchronously) + { + return; + } + + if (!(transportResult.AsyncState is AsyncProtocolRequest)) + { + if (GlobalLog.IsEnabled) + { + GlobalLog.Assert("SslStream::WriteCallback | State type is wrong, expected AsyncProtocolRequest."); + } + + Debug.Fail("SslStream::WriteCallback|State type is wrong, expected AsyncProtocolRequest."); + } + + AsyncProtocolRequest asyncRequest = (AsyncProtocolRequest)transportResult.AsyncState; + + var sslStream = (SslStreamInternal)asyncRequest.AsyncObject; + + try + { + sslStream._sslState.InnerStreamAPM.EndWrite(transportResult); + sslStream._sslState.FinishWrite(); + + if (asyncRequest.Count == 0) + { + // This was the last chunk. + asyncRequest.Count = -1; + } + + sslStream.StartWriting(asyncRequest.Buffer, asyncRequest.Offset, asyncRequest.Count, asyncRequest); + } + catch (Exception e) + { + if (asyncRequest.IsUserCompleted) + { + // This will throw on a worker thread. + throw; + } + + sslStream._sslState.FinishWrite(); + asyncRequest.CompleteWithError(e); + } + } + + // + // This is used in a rare situation when async Read is resumed from completed handshake. + // + private static void ResumeAsyncReadCallback(AsyncProtocolRequest request) + { + try + { + ((SslStreamInternal)request.AsyncObject).StartReading(request.Buffer, request.Offset, request.Count, request); + } + catch (Exception e) + { + if (request.IsUserCompleted) + { + // This will throw on a worker thread. + throw; + } + + ((SslStreamInternal)request.AsyncObject)._sslState.FinishRead(null); + request.CompleteWithError(e); + } + } + + // + // This is used in a rare situation when async Write is resumed from completed handshake. + // + private static void ResumeAsyncWriteCallback(AsyncProtocolRequest asyncRequest) + { + try + { + ((SslStreamInternal)asyncRequest.AsyncObject).StartWriting(asyncRequest.Buffer, asyncRequest.Offset, asyncRequest.Count, asyncRequest); + } + catch (Exception e) + { + if (asyncRequest.IsUserCompleted) + { + // This will throw on a worker thread. + throw; + } + + ((SslStreamInternal)asyncRequest.AsyncObject)._sslState.FinishWrite(); + asyncRequest.CompleteWithError(e); + } + } + + private static void ReadHeaderCallback(AsyncProtocolRequest asyncRequest) + { + try + { + SslStreamInternal sslStream = (SslStreamInternal)asyncRequest.AsyncObject; + BufferAsyncResult bufferResult = (BufferAsyncResult)asyncRequest.UserAsyncResult; + if (-1 == sslStream.StartFrameBody(asyncRequest.Result, bufferResult.Buffer, bufferResult.Offset, bufferResult.Count, asyncRequest)) + { + // in case we decrypted 0 bytes start another reading. + sslStream.StartReading(bufferResult.Buffer, bufferResult.Offset, bufferResult.Count, asyncRequest); + } + } + catch (Exception e) + { + if (asyncRequest.IsUserCompleted) + { + // This will throw on a worker thread. + throw; + } + + asyncRequest.CompleteWithError(e); + } + } + + private static void ReadFrameCallback(AsyncProtocolRequest asyncRequest) + { + try + { + SslStreamInternal sslStream = (SslStreamInternal)asyncRequest.AsyncObject; + BufferAsyncResult bufferResult = (BufferAsyncResult)asyncRequest.UserAsyncResult; + if (-1 == sslStream.ProcessFrameBody(asyncRequest.Result, bufferResult.Buffer, bufferResult.Offset, bufferResult.Count, asyncRequest)) + { + // in case we decrypted 0 bytes start another reading. + sslStream.StartReading(bufferResult.Buffer, bufferResult.Offset, bufferResult.Count, asyncRequest); + } + } + catch (Exception e) + { + if (asyncRequest.IsUserCompleted) + { + // This will throw on a worker thread. + throw; + } + + asyncRequest.CompleteWithError(e); + } + } } } diff --git a/src/System.Net.Security/src/System/Net/SecurityBuffer.cs b/src/System.Net.Security/src/System/Net/SecurityBuffer.cs index 731cd041111f..2e84603ee539 100644 --- a/src/System.Net.Security/src/System/Net/SecurityBuffer.cs +++ b/src/System.Net.Security/src/System/Net/SecurityBuffer.cs @@ -23,14 +23,17 @@ public SecurityBuffer(byte[] data, int offset, int size, SecurityBufferType toke { GlobalLog.Assert("SecurityBuffer::.ctor", "'offset' out of range. [" + offset + "]"); } + Debug.Fail("SecurityBuffer::.ctor", "'offset' out of range. [" + offset + "]"); } + if (size < 0 || size > (data == null ? 0 : data.Length - offset)) { if (GlobalLog.IsEnabled) { GlobalLog.Assert("SecurityBuffer::.ctor", "'size' out of range. [" + size + "]"); } + Debug.Fail("SecurityBuffer::.ctor", "'size' out of range. [" + size + "]"); } @@ -55,6 +58,7 @@ public SecurityBuffer(int size, SecurityBufferType tokentype) { GlobalLog.Assert("SecurityBuffer::.ctor", "'size' out of range. [" + size + "]"); } + Debug.Fail("SecurityBuffer::.ctor", "'size' out of range. [" + size + "]"); } diff --git a/src/System.Net.Security/src/System/Net/SslSessionsCache.cs b/src/System.Net.Security/src/System/Net/SslSessionsCache.cs index 82ee197d0a24..2c2ca1c29618 100644 --- a/src/System.Net.Security/src/System/Net/SslSessionsCache.cs +++ b/src/System.Net.Security/src/System/Net/SslSessionsCache.cs @@ -169,6 +169,7 @@ internal static void CacheCredential(SafeFreeCredentials creds, byte[] thumbPrin { GlobalLog.Assert("CacheCredential|creds == null"); } + Debug.Fail("CacheCredential|creds == null"); } @@ -178,6 +179,7 @@ internal static void CacheCredential(SafeFreeCredentials creds, byte[] thumbPrin { GlobalLog.Print("CacheCredential() Refused to cache an Invalid Handle = " + creds.ToString() + ", Current Cache Count = " + s_CachedCreds.Count); } + return; } diff --git a/src/System.Net.Security/src/System/Net/StreamFramer.cs b/src/System.Net.Security/src/System/Net/StreamFramer.cs index 821301f79e71..0d8980450a01 100644 --- a/src/System.Net.Security/src/System/Net/StreamFramer.cs +++ b/src/System.Net.Security/src/System/Net/StreamFramer.cs @@ -153,12 +153,13 @@ public IAsyncResult BeginReadMessage(AsyncCallback asyncCallback, object stateOb private void ReadFrameCallback(IAsyncResult transportResult) { - if ((transportResult.AsyncState is WorkerAsyncResult)) + if (!(transportResult.AsyncState is WorkerAsyncResult)) { if (GlobalLog.IsEnabled) { GlobalLog.Assert("StreamFramer::ReadFrameCallback|The state expected to be WorkerAsyncResult, received:{0}.", transportResult.GetType().FullName); } + Debug.Fail("StreamFramer::ReadFrameCallback|The state expected to be WorkerAsyncResult, received:" + transportResult.GetType().FullName + "."); } @@ -200,12 +201,13 @@ private void ReadFrameComplete(IAsyncResult transportResult) { do { - if ((transportResult.AsyncState is WorkerAsyncResult)) + if (!(transportResult.AsyncState is WorkerAsyncResult)) { if (GlobalLog.IsEnabled) { GlobalLog.AssertFormat("StreamFramer::ReadFrameComplete|The state expected to be WorkerAsyncResult, received:{0}.", transportResult.GetType().FullName); } + Debug.Fail("StreamFramer::ReadFrameComplete|The state expected to be WorkerAsyncResult, received:" + transportResult.GetType().FullName + "."); } @@ -214,12 +216,13 @@ private void ReadFrameComplete(IAsyncResult transportResult) int bytesRead = _transportAPM.EndRead(transportResult); workerResult.Offset += bytesRead; - if ((workerResult.Offset <= workerResult.End)) + if (!(workerResult.Offset <= workerResult.End)) { if (GlobalLog.IsEnabled) { GlobalLog.AssertFormat("StreamFramer::ReadFrameCallback|WRONG: offset - end = {0}", workerResult.Offset - workerResult.End); } + Debug.Fail("StreamFramer::ReadFrameCallback|WRONG: offset - end = " + (workerResult.Offset - workerResult.End)); } @@ -390,12 +393,13 @@ public IAsyncResult BeginWriteMessage(byte[] message, AsyncCallback asyncCallbac private void BeginWriteCallback(IAsyncResult transportResult) { - if ((transportResult.AsyncState is WorkerAsyncResult)) + if (!(transportResult.AsyncState is WorkerAsyncResult)) { if (GlobalLog.IsEnabled) { GlobalLog.AssertFormat("StreamFramer::BeginWriteCallback|The state expected to be WorkerAsyncResult, received:{0}.", transportResult.AsyncState.GetType().FullName); } + Debug.Fail("StreamFramer::BeginWriteCallback|The state expected to be WorkerAsyncResult, received:" + transportResult.AsyncState.GetType().FullName + "."); } diff --git a/src/System.Net.Security/src/System/PinnableBufferCache.cs b/src/System.Net.Security/src/System/PinnableBufferCache.cs index ebe02a06e967..adee0034505d 100644 --- a/src/System.Net.Security/src/System/PinnableBufferCache.cs +++ b/src/System.Net.Security/src/System/PinnableBufferCache.cs @@ -151,7 +151,6 @@ private void Restock(out object returnBuffer) } // We have no buffers in the aged freelist, so get one from the newer list. Try to pick the best one. - // Debug.Assert(_notGen2.Count != 0); int idx = _notGen2.Count - 1; if (GC.GetGeneration(_notGen2[idx]) < GC.MaxGeneration && GC.GetGeneration(_notGen2[0]) == GC.MaxGeneration) { diff --git a/src/System.Net.Security/tests/FunctionalTests/NegotiateStreamStreamToStreamTest.cs b/src/System.Net.Security/tests/FunctionalTests/NegotiateStreamStreamToStreamTest.cs index 45e88d85dd58..651fa908279f 100644 --- a/src/System.Net.Security/tests/FunctionalTests/NegotiateStreamStreamToStreamTest.cs +++ b/src/System.Net.Security/tests/FunctionalTests/NegotiateStreamStreamToStreamTest.cs @@ -152,6 +152,7 @@ public void NegotiateStream_StreamToStream_Authentication_EmptyCredentials_Fails auth[1] = server.AuthenticateAsServerAsync(); bool finished = Task.WaitAll(auth, TestConfiguration.PassingTestTimeoutMilliseconds); + Assert.True(finished, "Handshake completed in the allotted time"); // Expected Client property values: Assert.True(client.IsAuthenticated); diff --git a/src/System.Net.Security/tests/FunctionalTests/SslStreamNetworkStreamTest.cs b/src/System.Net.Security/tests/FunctionalTests/SslStreamNetworkStreamTest.cs new file mode 100644 index 000000000000..d8cb5b955127 --- /dev/null +++ b/src/System.Net.Security/tests/FunctionalTests/SslStreamNetworkStreamTest.cs @@ -0,0 +1,84 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System.Net.Sockets; +using System.Security.Authentication; +using System.Security.Cryptography.X509Certificates; +using System.Threading.Tasks; + +using Xunit; + +namespace System.Net.Security.Tests +{ + public class SslStreamNetworkStreamTest + { + [Fact] + public async void SslStream_SendReceiveOverNetworkStream_Ok() + { + X509Certificate2 serverCertificate = TestConfiguration.GetServerCertificate(); + TcpListener listener = new TcpListener(IPAddress.Any, 0); + + using (TcpClient client = new TcpClient()) + { + listener.Start(); + + Task clientConnectTask = client.ConnectAsync(IPAddress.Loopback, ((IPEndPoint)listener.LocalEndpoint).Port); + Task listenerAcceptTask = listener.AcceptTcpClientAsync(); + + await Task.WhenAll(clientConnectTask, listenerAcceptTask); + + TcpClient server = listenerAcceptTask.Result; + using (SslStream clientStream = new SslStream( + client.GetStream(), + false, + new RemoteCertificateValidationCallback(ValidateServerCertificate), + null, + EncryptionPolicy.RequireEncryption)) + using (SslStream serverStream = new SslStream( + server.GetStream(), + false, + null, + null, + EncryptionPolicy.RequireEncryption)) + { + + Task clientAuthenticationTask = clientStream.AuthenticateAsClientAsync( + serverCertificate.GetNameInfo(X509NameType.SimpleName, false), + null, + SslProtocols.Tls12, + false); + + Task serverAuthenticationTask = serverStream.AuthenticateAsServerAsync( + serverCertificate, + false, + SslProtocols.Tls12, + false); + + await Task.WhenAll(clientAuthenticationTask, serverAuthenticationTask); + + byte[] readBuffer = new byte[256]; + Task readTask = clientStream.ReadAsync(readBuffer, 0, readBuffer.Length); + + byte[] writeBuffer = new byte[256]; + Task writeTask = clientStream.WriteAsync(writeBuffer, 0, writeBuffer.Length); + + bool result = Task.WaitAll( + new Task[1] { writeTask }, + TestConfiguration.PassingTestTimeoutMilliseconds); + + Assert.True(result, "WriteAsync timed-out."); + } + } + } + + private static bool ValidateServerCertificate( + object sender, + X509Certificate retrievedServerPublicCertificate, + X509Chain chain, + SslPolicyErrors sslPolicyErrors) + { + // Accept any certificate. + return true; + } + } +} diff --git a/src/System.Net.Security/tests/FunctionalTests/SslStreamStreamToStreamTest.cs b/src/System.Net.Security/tests/FunctionalTests/SslStreamStreamToStreamTest.cs index 70906d35065b..20106795d3b2 100644 --- a/src/System.Net.Security/tests/FunctionalTests/SslStreamStreamToStreamTest.cs +++ b/src/System.Net.Security/tests/FunctionalTests/SslStreamStreamToStreamTest.cs @@ -106,14 +106,14 @@ public void SslStream_StreamToStream_Successive_ClientWrite_Async_Success() Task[] tasks = new Task[2]; - tasks[0] = clientSslStream.WriteAsync(_sampleMsg, 0, _sampleMsg.Length); - tasks[1] = serverSslStream.ReadAsync(recvBuf, 0, _sampleMsg.Length); + tasks[0] = serverSslStream.ReadAsync(recvBuf, 0, _sampleMsg.Length); + tasks[1] = clientSslStream.WriteAsync(_sampleMsg, 0, _sampleMsg.Length); bool finished = Task.WaitAll(tasks, TestConfiguration.PassingTestTimeoutMilliseconds); Assert.True(finished, "Send/receive completed in the allotted time"); Assert.True(VerifyOutput(recvBuf, _sampleMsg), "verify first read data is as expected."); - tasks[0] = clientSslStream.WriteAsync(_sampleMsg, 0, _sampleMsg.Length); - tasks[1] = serverSslStream.ReadAsync(recvBuf, 0, _sampleMsg.Length); + tasks[0] = serverSslStream.ReadAsync(recvBuf, 0, _sampleMsg.Length); + tasks[1] = clientSslStream.WriteAsync(_sampleMsg, 0, _sampleMsg.Length); finished = Task.WaitAll(tasks, TestConfiguration.PassingTestTimeoutMilliseconds); Assert.True(finished, "Send/receive completed in the allotted time"); Assert.True(VerifyOutput(recvBuf, _sampleMsg), "verify second read data is as expected."); diff --git a/src/System.Net.Security/tests/FunctionalTests/System.Net.Security.Tests.csproj b/src/System.Net.Security/tests/FunctionalTests/System.Net.Security.Tests.csproj index 0b73f7084e45..682ec013c823 100644 --- a/src/System.Net.Security/tests/FunctionalTests/System.Net.Security.Tests.csproj +++ b/src/System.Net.Security/tests/FunctionalTests/System.Net.Security.Tests.csproj @@ -21,7 +21,7 @@ unix\project.lock.json - + @@ -47,6 +47,7 @@ + diff --git a/src/System.Net.Security/tests/FunctionalTests/TestConfiguration.cs b/src/System.Net.Security/tests/FunctionalTests/TestConfiguration.cs index 4e490d9101ca..dbb3bbfd745d 100644 --- a/src/System.Net.Security/tests/FunctionalTests/TestConfiguration.cs +++ b/src/System.Net.Security/tests/FunctionalTests/TestConfiguration.cs @@ -38,6 +38,7 @@ public static X509Certificate2Collection GetClientCertificateCollection() { return GetCertificateCollection("testclient1_at_contoso.com.pfx"); } + private static X509Certificate2Collection GetCertificateCollection(string certificateFileName) { var certCollection = new X509Certificate2Collection(); diff --git a/src/System.Net.Security/tests/UnitTests/Fakes/FakeSslState.cs b/src/System.Net.Security/tests/UnitTests/Fakes/FakeSslState.cs index 9df1682896fb..5a75ec514ee4 100644 --- a/src/System.Net.Security/tests/UnitTests/Fakes/FakeSslState.cs +++ b/src/System.Net.Security/tests/UnitTests/Fakes/FakeSslState.cs @@ -243,5 +243,25 @@ public override void Write(byte[] buffer, int offset, int count) { throw new NotImplementedException(); } + + internal IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback asyncCallback, object asyncState) + { + throw new NotImplementedException(); + } + + internal int EndRead(IAsyncResult asyncResult) + { + throw new NotImplementedException(); + } + + internal IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback asyncCallback, object asyncState) + { + throw new NotImplementedException(); + } + + internal void EndWrite(IAsyncResult asyncResult) + { + throw new NotImplementedException(); + } } }