-
Notifications
You must be signed in to change notification settings - Fork 341
SSL Support #101
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SSL Support #101
Conversation
I'm getting the following exception under
(I think my local MySQL server is configured correctly because I'm able to connect with |
I'm seeing this also, running from Windows against the same MySQL database that is passing on linux, so I don't think it's your server configuration. Let me try to get some decrypted packet captures. |
new RemoteCertificateValidationCallback(remoteCertificateCb), | ||
new LocalCertificateSelectionCallback(localCertificateCb)); | ||
var clientCertificates = new X509CertificateCollection { certificate }; | ||
var sslProtocols = SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is where the error on Windows is coming from. My MySQL server only speaks TLS1.1 but the handshake is trying to initiate with TLS1.2. Need to look into how to handle this properly. Changing to var sslProtocols = SslProtocols.Tls | SslProtocols.Tls11
on Windows works, but is not the correct solution.
MySQL doesn't like the I don't know if this is an issue with the In the short-term, our options are to:
|
I'm not very familiar with the specifics of TLS negotiation, but here's what I noticed when looking at the captures (thanks for grabbing them!):
My assumption would be that if your protocols are One other option would be to catch this exception and then renegotiate with just
This seems like the best approach. TLS 1.2 wasn't available in MySQL Server until 5.7.10 (and isn't in Community Server) so it may not even be widely deployed. (This might become an issue if cloud MySQL providers started requiring TLS 1.2, but I haven't found any indication that this might happen after a quick search.) |
From RFC 5246 Appendix E:
It appears that the client code is permitted to send "TLS 1.2" as its record layer version number (as Windows does). However, it's also noted that this doesn't "guarantee interoperability". Certainly it appears that MySQL Server is not "compliant with this specification" because it doesn't accept any value as the record layer version number. |
Neither the Windows .NET client nor MySQL Server are following these recommendations; this combination is breaking protocol negotiation. |
Here's someone reporting essentially the same issue in Schannel (the native Windows SSL provider), but the problem doesn't seem to have been understood on the Microsoft side and no resolution was posted. |
Very nice find. While the Schannel side isn't a bug, it's still not following a best practice. I'm not sure if it's worth trying to send them a bug report. The MySQL side is definitely a bug and should be reported upstream. I can report it or you can - let me know. Working on disabling TLS 1.2 on windows now. Getting the runtime information is turning out to be a pretty difficult task, this is the first language I've dealt with where it's not a one-liner. |
This potentially problematic behaviour in Schannel was reported five years ago; I'm not sure we're going to see it changed any time soon... I wouldn't be surprised if there would be significant interoperability problems caused by changing it; presumably Microsoft has good reasons for keeping it the way it is. |
I did not know (until now) that they took away |
I ended up importing System.Runtime.InteropServices.RuntimeInformation in both Netstandard 1.3 and Net45 so we'd have a common runtime information API Tests are passing for me from Windows after the latest commit |
TLS 1.2 bug opened upstream to MySQL at http://bugs.mysql.com/bug.php?id=83347 |
IPayloadHandler.SetByteHandler
andIPacketHandler.SetByteHandler
methods to their respective interfaces. Needed to switch the underlying byte handler to SSL once the TLS handshake has been completedTcpClient
instead ofSocket
inMySqlSession
Socket
level usingTcpClient.Client
,SocketByteHandler
, andSocketAwaitable
NetworkStream
level usingTcpClient.GetStream()
,SslByteHandler
, and the appropriate stream methodsssl mode=required