Description
Description
This scenario was enabled, including a unit test in .NET 5. It is broken again since .NET 7. I've observed this issue on .NET 8 Windows x64, but looking over the source it appears the issue is still present in higher versions.
The desired capability is being able to call Stream.SslProtocol/CipherAlogrithm from the SslStream's RemoteCertificateValidationCallback as described here: #919.
Original fix was #37580. It included a unit test named ClientAsyncAuthenticate_ConnectionInfoInCallback_DoesNotThrow.
Later #68678 changed the implementation of SslStream.ThrowIfExceptionalOrNotHandshake
. This broke the property access scenario, but at some point the test method ClientAsyncAuthenticateTest.ClientAsyncSslHelper
was refactored a bit and the ClientAsyncAuthenticate_ConnectionInfoInCallback_DoesNotThrow unit test was no longer using its special remote certificate validation callback to verify property access.
Reproduction Steps
Either of:
-
This could easily be reproduced by fixing the ClientAsyncAuthenticate_ConnectionInfoInCallback_DoesNotThrow unit test and running that. That update would be to change ClientAsyncSslHelper(EncryptionPolicy, SslProtocols, SslProtocols, RemoteCertificateValidationCallback) to honor the RemoteCertificateValidationCallback parameter. AllowAnyServerCertificateAndVerifyConnectionInfo would then attempt to access the properties and the test would fail.
-
The desired capability is being able to call Stream.SslProtocol/CipherAlogrithm from the SslStream's RemoteCertificateValidationCallback as described here: SslStream RemoteCertificateValidationCallback cannot access protocol/cipher info #919:
static bool ValidateRemoteCertificate(object Sender, X509Certificate Certificate, X509Chain Chain, SslPolicyErrors PolicyErrors)
{
var stream = (SslStream)Sender;
// The linked docs imply that these properties should be accessible at this point but
// they throw InvalidOperationException when accessed
return stream.CipherAlgorithm != CipherAlgorithmType.Rc4 &&
stream.HashAlgorithm != HashAlgorithmType.Md5 &&
stream.SslProtocol != SslProtocols.Tls13;
}
Expected behavior
SslStream.SslProtocol should be accessible from the RemoteCertificateValidationCallback
Actual behavior
System.InvalidOperationException: This operation is only allowed using a successfully authenticated context.
at System.Net.Security.SslStream.ThrowNotAuthenticated()
at System.Net.Security.SslStream.get_CipherAlgorithm()
at Microsoft.Azure.SomeProcduct.RemoteServerValidationCallback(Object, X509Certificate, X509Chain, SslPolicyErrors)
Regression?
Crypto properties were accessible at RemoteCertificateValidationCallback time in .NET 5 and 6. Since .NET 7 that scenario has been broken.
Known Workarounds
I couldn't quickly come up with anything.
Configuration
.NET 7+ is broken. I tested with .NET 8, Windows 11, x64.
Other information
No response